From c51c551e6b6165c7023c045a929d52a5362a4d4f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 11 Oct 2019 11:38:50 +0000 Subject: [PATCH] Tests, docs and validation of OOO setting. Test required some framework work to allow for auths having more than 1 thread. --- .circleci/config.yml | 2 +- build-scripts/travis.sh | 1 + docs/manpages/sdig.1.rst | 4 +- pdns/pdns_recursor.cc | 26 ++-- pdns/recursordist/docs/settings.rst | 5 +- pdns/syncres.hh | 2 +- .../recursortests.py | 83 ++++++++++-- .../test_OOOTCP.py | 56 ++++++++ .../test_SimpleTCP.py | 125 ++++++++++++++++++ 9 files changed, 279 insertions(+), 25 deletions(-) create mode 100644 regression-tests.recursor-dnssec/test_OOOTCP.py create mode 100644 regression-tests.recursor-dnssec/test_SimpleTCP.py diff --git a/.circleci/config.yml b/.circleci/config.yml index 3d6d3ddf3..6a7697b2f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -897,7 +897,7 @@ jobs: - image: debian:buster steps: - add-auth-repo - - run: apt-get --no-install-recommends install -qq -y pdns-server pdns-backend-bind pdns-tools daemontools authbind jq libfaketime lua-posix moreutils bc virtualenv protobuf-compiler + - run: apt-get --no-install-recommends install -qq -y pdns-server pdns-backend-bind pdns-tools daemontools authbind jq libfaketime lua-posix lua-socket moreutils bc virtualenv protobuf-compiler - install-recursor-deps - run: name: Set up authbind diff --git a/build-scripts/travis.sh b/build-scripts/travis.sh index aa6934c62..c2d8a3092 100755 --- a/build-scripts/travis.sh +++ b/build-scripts/travis.sh @@ -343,6 +343,7 @@ install_recursor() { libfaketime \ libsnmp-dev \ lua-posix \ + lua-socket \ moreutils \ snmpd" run "cd .." diff --git a/docs/manpages/sdig.1.rst b/docs/manpages/sdig.1.rst index 8d144357b..cddacafa7 100644 --- a/docs/manpages/sdig.1.rst +++ b/docs/manpages/sdig.1.rst @@ -12,6 +12,8 @@ Description :program:`sdig` sends a DNS query to *IP-ADDRESS-OR-DOH-URL* on port *PORT* and displays the answer in a formatted way. If the address starts with an ``h``, it is assumed to be a DoH endpoint, and *PORT* is ignored. +If qname and qtype are both `-` and tcp is used, multiple lines are read +form stdin, where each line contains a qname and a type. Options ------- @@ -34,4 +36,4 @@ showflags tcp Use TCP instead of UDP to send the query. xpf *XPFCODE* *XPFVERSION* *XPFPROTO* *XPFSRC* *XPFSRC* - Send an *XPF* additional with these parameters. \ No newline at end of file + Send an *XPF* additional with these parameters. diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index adcbee595..a6077c378 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -746,16 +746,16 @@ static void writePid(void) } } +uint16_t TCPConnection::s_maxInFlight; + TCPConnection::TCPConnection(int fd, const ComboAddress& addr) : data(2, 0), d_remote(addr), d_fd(fd) { - d_maxInFlight = ::arg().asNum("max-concurrent-requests-per-tcp-connection"); ++s_currentConnections; (*t_tcpClientCounts)[d_remote]++; } TCPConnection::~TCPConnection() { - g_log<d_tcpConnection->d_requestsInFlight--; + if (dc->d_tcpConnection->d_requestsInFlight > 0) { + dc->d_tcpConnection->d_requestsInFlight--; + } // In the code below, we try to remove the fd from the set, but // we don't know if another mthread already did the remove, so we can get a @@ -1779,11 +1780,11 @@ static void startDoResolve(void *p) else { Utility::gettimeofday(&g_now, 0); // needs to be updated struct timeval ttd = g_now; - if (dc->d_tcpConnection->d_requestsInFlight == dc->d_tcpConnection->d_maxInFlight - 1) { + // If we cross from max to max-1 in flight requests, the fd was not listened to, add it back + if (dc->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. - cerr << "Reenabling " << dc->d_socket << ' ' << dc->d_tcpConnection->d_requestsInFlight << endl; ttd.tv_sec += g_tcpTimeout; t_fdm->addReadFD(dc->d_socket, handleRunningTCPQuestion, dc->d_tcpConnection, &ttd); } else { @@ -2165,8 +2166,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) ++g_stats.qcounter; ++g_stats.tcpqcounter; ++conn->d_requestsInFlight; - if (conn->d_requestsInFlight >= conn->d_maxInFlight) { - cerr << "Disabling " << fd << ' ' << conn->d_requestsInFlight << endl; + if (conn->d_requestsInFlight >= TCPConnection::s_maxInFlight) { t_fdm->removeReadFD(fd); // should no longer awake ourselves when there is data to read } else { Utility::gettimeofday(&g_now, 0); // needed? @@ -4013,6 +4013,16 @@ static int serviceMain(int argc, char*argv[]) g_numThreads = g_numDistributorThreads + g_numWorkerThreads; 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) { + g_log<