]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix "keyword 'try' is not allowed in global scope" warning 9616/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 11 Jan 2021 10:06:42 +0000 (11:06 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 11 Jan 2021 10:06:42 +0000 (11:06 +0100)
Reported by cppcheck. Using a proper block function also makes the
code easier to read.
The diff looks huge but that's mostly indentation changes, getting
rid of the changed whitespaces yields a very small diff.

pdns/dnsdist-carbon.cc
pdns/dnsdist-console.cc
pdns/dnsdist.cc
pdns/dnsdistdist/doh.cc
pdns/dnsparser.cc
pdns/remote_logger.cc

index 53475dfa9e60823920bdc088113fd1becd457443..b22e7dc58194790056ccef3f086ef2773d03e402 100644 (file)
 #include "threadname.hh"
 
 GlobalStateHolder<vector<CarbonConfig> > g_carbon;
-static time_t s_start=time(0);
+static time_t s_start = time(nullptr);
+
 uint64_t uptimeOfProcess(const std::string& str)
 {
-  return time(0) - s_start;
+  return time(nullptr) - s_start;
 }
 
 void carbonDumpThread()
-try
 {
-  setThreadName("dnsdist/carbon");
-  auto localCarbon = g_carbon.getLocal();
-  for(int numloops=0;;++numloops) {
-    if(localCarbon->empty()) {
-      sleep(1);
-      continue;
-    }
-    /* this is wrong, we use the interval of the first server
-       for every single one of them */
-    if(numloops) {
-      const unsigned int interval = localCarbon->at(0).interval;
-      sleep(interval);
-    }
-
-    for (const auto& conf : *localCarbon) {
-      const auto& server = conf.server;
-      const std::string& namespace_name = conf.namespace_name;
-      std::string hostname = conf.ourname;
-      if (hostname.empty()) {
-        try {
-          hostname = getCarbonHostName();
-        }
-        catch(const std::exception& e) {
-          throw std::runtime_error(std::string("The 'ourname' setting in 'carbonServer()' has not been set and we are unable to determine the system's hostname: ") + e.what());
-        }
+  try
+  {
+    setThreadName("dnsdist/carbon");
+    auto localCarbon = g_carbon.getLocal();
+    for(int numloops=0;;++numloops) {
+      if(localCarbon->empty()) {
+        sleep(1);
+        continue;
+      }
+      /* this is wrong, we use the interval of the first server
+         for every single one of them */
+      if(numloops) {
+        const unsigned int interval = localCarbon->at(0).interval;
+        sleep(interval);
       }
-      const std::string& instance_name = conf.instance_name;
-
-      try {
-        Socket s(server.sin4.sin_family, SOCK_STREAM);
-        s.setNonBlocking();
-        s.connect(server);  // we do the connect so the attempt happens while we gather stats
-        ostringstream str;
-        time_t now=time(0);
-        for(const auto& e : g_stats.entries) {
-          str<<namespace_name<<"."<<hostname<<"."<<instance_name<<"."<<e.first<<' ';
-          if(const auto& val = boost::get<DNSDistStats::stat_t*>(&e.second))
-            str<<(*val)->load();
-          else if (const auto& dval = boost::get<double*>(&e.second))
-            str<<**dval;
-          else
-            str<<(*boost::get<DNSDistStats::statfunction_t>(&e.second))(e.first);
-          str<<' '<<now<<"\r\n";
-        }
-        auto states = g_dstates.getLocal();
-        for(const auto& state : *states) {
-          string serverName = state->getName().empty() ? state->remote.toStringWithPort() : state->getName();
-          boost::replace_all(serverName, ".", "_");
-          const string base = namespace_name + "." + hostname + "." + instance_name + ".servers." + serverName + ".";
-          str<<base<<"queries" << ' ' << state->queries.load() << " " << now << "\r\n";
-          str<<base<<"responses" << ' ' << state->responses.load() << " " << now << "\r\n";
-          str<<base<<"drops" << ' ' << state->reuseds.load() << " " << now << "\r\n";
-          str<<base<<"latency" << ' ' << (state->availability != DownstreamState::Availability::Down ? state->latencyUsec/1000.0 : 0) << " " << now << "\r\n";
-          str<<base<<"senderrors" << ' ' << state->sendErrors.load() << " " << now << "\r\n";
-          str<<base<<"outstanding" << ' ' << state->outstanding.load() << " " << now << "\r\n";
-          str<<base<<"tcpdiedsendingquery" << ' '<< state->tcpDiedSendingQuery.load() << " " << now << "\r\n";
-          str<<base<<"tcpdiedreaddingresponse" << ' '<< state->tcpDiedReadingResponse.load() << " " << now << "\r\n";
-          str<<base<<"tcpgaveup" << ' '<< state->tcpGaveUp.load() << " " << now << "\r\n";
-          str<<base<<"tcpreadimeouts" << ' '<< state->tcpReadTimeouts.load() << " " << now << "\r\n";
-          str<<base<<"tcpwritetimeouts" << ' '<< state->tcpWriteTimeouts.load() << " " << now << "\r\n";
-          str<<base<<"tcpcurrentconnections" << ' '<< state->tcpCurrentConnections.load() << " " << now << "\r\n";
-          str<<base<<"tcpavgqueriesperconnection" << ' '<< state->tcpAvgQueriesPerConnection.load() << " " << now << "\r\n";
-          str<<base<<"tcpavgconnectionduration" << ' '<< state->tcpAvgConnectionDuration.load() << " " << now << "\r\n";
-        }
-
-        std::map<std::string,uint64_t> frontendDuplicates;
-        for(const auto& front : g_frontends) {
-          if (front->udpFD == -1 && front->tcpFD == -1)
-            continue;
-
-          string frontName = front->local.toStringWithPort() + (front->udpFD >= 0 ? "_udp" : "_tcp");
-          boost::replace_all(frontName, ".", "_");
-          auto dupPair = frontendDuplicates.insert({frontName, 1});
-          if (!dupPair.second) {
-            frontName = frontName + "_" + std::to_string(dupPair.first->second);
-            ++(dupPair.first->second);
-          }
 
-          const string base = namespace_name + "." + hostname + "." + instance_name + ".frontends." + frontName + ".";
-          str<<base<<"queries" << ' ' << front->queries.load() << " " << now << "\r\n";
-          str<<base<<"responses" << ' ' << front->responses.load() << " " << now << "\r\n";
-          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<<"tcpdownstreamtimeouts" << ' '<< front->tcpDownstreamTimeouts.load() << " " << now << "\r\n";
-          str<<base<<"tcpcurrentconnections" << ' '<< front->tcpCurrentConnections.load() << " " << now << "\r\n";
-          str<<base<<"tcpavgqueriesperconnection" << ' '<< front->tcpAvgQueriesPerConnection.load() << " " << now << "\r\n";
-          str<<base<<"tcpavgconnectionduration" << ' '<< front->tcpAvgConnectionDuration.load() << " " << now << "\r\n";
-          str<<base<<"tls10-queries" << ' ' << front->tls10queries.load() << " " << now << "\r\n";
-          str<<base<<"tls11-queries" << ' ' << front->tls11queries.load() << " " << now << "\r\n";
-          str<<base<<"tls12-queries" << ' ' << front->tls12queries.load() << " " << now << "\r\n";
-          str<<base<<"tls13-queries" << ' ' << front->tls13queries.load() << " " << now << "\r\n";
-          str<<base<<"tls-unknown-queries" << ' ' << front->tlsUnknownqueries.load() << " " << now << "\r\n";
-          str<<base<<"tlsnewsessions" << ' ' << front->tlsNewSessions.load() << " " << now << "\r\n";
-          str<<base<<"tlsresumptions" << ' ' << front->tlsResumptions.load() << " " << now << "\r\n";
-          str<<base<<"tlsunknownticketkeys" << ' ' << front->tlsUnknownTicketKey.load() << " " << now << "\r\n";
-          str<<base<<"tlsinactiveticketkeys" << ' ' << front->tlsInactiveTicketKey.load() << " " << now << "\r\n";
-          const TLSErrorCounters* errorCounters = nullptr;
-          if (front->tlsFrontend != nullptr) {
-            errorCounters = &front->tlsFrontend->d_tlsCounters;
+      for (const auto& conf : *localCarbon) {
+        const auto& server = conf.server;
+        const std::string& namespace_name = conf.namespace_name;
+        std::string hostname = conf.ourname;
+        if (hostname.empty()) {
+          try {
+            hostname = getCarbonHostName();
           }
-          else if (front->dohFrontend != nullptr) {
-            errorCounters = &front->dohFrontend->d_tlsCounters;
-          }
-          if (errorCounters != nullptr) {
-            str<<base<<"tlsdhkeytoosmall" << ' ' << errorCounters->d_dhKeyTooSmall << " " << now << "\r\n";
-            str<<base<<"tlsinappropriatefallback" << ' ' << errorCounters->d_inappropriateFallBack << " " << now << "\r\n";
-            str<<base<<"tlsnosharedcipher" << ' ' << errorCounters->d_noSharedCipher << " " << now << "\r\n";
-            str<<base<<"tlsunknownciphertype" << ' ' << errorCounters->d_unknownCipherType << " " << now << "\r\n";
-            str<<base<<"tlsunknownkeyexchangetype" << ' ' << errorCounters->d_unknownKeyExchangeType << " " << now << "\r\n";
-            str<<base<<"tlsunknownprotocol" << ' ' << errorCounters->d_unknownProtocol << " " << now << "\r\n";
-            str<<base<<"tlsunsupportedec" << ' ' << errorCounters->d_unsupportedEC << " " << now << "\r\n";
-            str<<base<<"tlsunsupportedprotocol" << ' ' << errorCounters->d_unsupportedProtocol << " " << now << "\r\n";
+          catch(const std::exception& e) {
+            throw std::runtime_error(std::string("The 'ourname' setting in 'carbonServer()' has not been set and we are unable to determine the system's hostname: ") + e.what());
           }
         }
+        const std::string& instance_name = conf.instance_name;
 
-        auto localPools = g_pools.getLocal();
-        for (const auto& entry : *localPools) {
-          string poolName = entry.first;
-          boost::replace_all(poolName, ".", "_");
-          if (poolName.empty()) {
-            poolName = "_default_";
+        try {
+          Socket s(server.sin4.sin_family, SOCK_STREAM);
+          s.setNonBlocking();
+          s.connect(server);  // we do the connect so the attempt happens while we gather stats
+          ostringstream str;
+          time_t now=time(0);
+          for(const auto& e : g_stats.entries) {
+            str<<namespace_name<<"."<<hostname<<"."<<instance_name<<"."<<e.first<<' ';
+            if(const auto& val = boost::get<DNSDistStats::stat_t*>(&e.second))
+              str<<(*val)->load();
+            else if (const auto& dval = boost::get<double*>(&e.second))
+              str<<**dval;
+            else
+              str<<(*boost::get<DNSDistStats::statfunction_t>(&e.second))(e.first);
+            str<<' '<<now<<"\r\n";
           }
-          const string base = namespace_name + "." + hostname + "." + instance_name + ".pools." + poolName + ".";
-          const std::shared_ptr<ServerPool> pool = entry.second;
-          str<<base<<"servers" << " " << pool->countServers(false) << " " << now << "\r\n";
-          str<<base<<"servers-up" << " " << pool->countServers(true) << " " << now << "\r\n";
-          if (pool->packetCache != nullptr) {
-            const auto& cache = pool->packetCache;
-            str<<base<<"cache-size" << " " << cache->getMaxEntries() << " " << now << "\r\n";
-            str<<base<<"cache-entries" << " " << cache->getEntriesCount() << " " << now << "\r\n";
-            str<<base<<"cache-hits" << " " << cache->getHits() << " " << now << "\r\n";
-            str<<base<<"cache-misses" << " " << cache->getMisses() << " " << now << "\r\n";
-            str<<base<<"cache-deferred-inserts" << " " << cache->getDeferredInserts() << " " << now << "\r\n";
-            str<<base<<"cache-deferred-lookups" << " " << cache->getDeferredLookups() << " " << now << "\r\n";
-            str<<base<<"cache-lookup-collisions" << " " << cache->getLookupCollisions() << " " << now << "\r\n";
-            str<<base<<"cache-insert-collisions" << " " << cache->getInsertCollisions() << " " << now << "\r\n";
-            str<<base<<"cache-ttl-too-shorts" << " " << cache->getTTLTooShorts() << " " << now << "\r\n";
+          auto states = g_dstates.getLocal();
+          for(const auto& state : *states) {
+            string serverName = state->getName().empty() ? state->remote.toStringWithPort() : state->getName();
+            boost::replace_all(serverName, ".", "_");
+            const string base = namespace_name + "." + hostname + "." + instance_name + ".servers." + serverName + ".";
+            str<<base<<"queries" << ' ' << state->queries.load() << " " << now << "\r\n";
+            str<<base<<"responses" << ' ' << state->responses.load() << " " << now << "\r\n";
+            str<<base<<"drops" << ' ' << state->reuseds.load() << " " << now << "\r\n";
+            str<<base<<"latency" << ' ' << (state->availability != DownstreamState::Availability::Down ? state->latencyUsec/1000.0 : 0) << " " << now << "\r\n";
+            str<<base<<"senderrors" << ' ' << state->sendErrors.load() << " " << now << "\r\n";
+            str<<base<<"outstanding" << ' ' << state->outstanding.load() << " " << now << "\r\n";
+            str<<base<<"tcpdiedsendingquery" << ' '<< state->tcpDiedSendingQuery.load() << " " << now << "\r\n";
+            str<<base<<"tcpdiedreaddingresponse" << ' '<< state->tcpDiedReadingResponse.load() << " " << now << "\r\n";
+            str<<base<<"tcpgaveup" << ' '<< state->tcpGaveUp.load() << " " << now << "\r\n";
+            str<<base<<"tcpreadimeouts" << ' '<< state->tcpReadTimeouts.load() << " " << now << "\r\n";
+            str<<base<<"tcpwritetimeouts" << ' '<< state->tcpWriteTimeouts.load() << " " << now << "\r\n";
+            str<<base<<"tcpcurrentconnections" << ' '<< state->tcpCurrentConnections.load() << " " << now << "\r\n";
+            str<<base<<"tcpavgqueriesperconnection" << ' '<< state->tcpAvgQueriesPerConnection.load() << " " << now << "\r\n";
+            str<<base<<"tcpavgconnectionduration" << ' '<< state->tcpAvgConnectionDuration.load() << " " << now << "\r\n";
           }
-        }
 
-#ifdef HAVE_DNS_OVER_HTTPS
-        {
-          std::map<std::string,uint64_t> dohFrontendDuplicates;
-          const string base = "dnsdist." + hostname + ".main.doh.";
-          for(const auto& doh : g_dohlocals) {
-            string name = doh->d_local.toStringWithPort();
-            boost::replace_all(name, ".", "_");
-            boost::replace_all(name, ":", "_");
-            boost::replace_all(name, "[", "_");
-            boost::replace_all(name, "]", "_");
+          std::map<std::string,uint64_t> frontendDuplicates;
+          for(const auto& front : g_frontends) {
+            if (front->udpFD == -1 && front->tcpFD == -1)
+              continue;
 
-            auto dupPair = dohFrontendDuplicates.insert({name, 1});
+            string frontName = front->local.toStringWithPort() + (front->udpFD >= 0 ? "_udp" : "_tcp");
+            boost::replace_all(frontName, ".", "_");
+            auto dupPair = frontendDuplicates.insert({frontName, 1});
             if (!dupPair.second) {
-              name = name + "_" + std::to_string(dupPair.first->second);
+              frontName = frontName + "_" + std::to_string(dupPair.first->second);
               ++(dupPair.first->second);
             }
 
-            vector<pair<const char*, const std::atomic<uint64_t>&>> v{
-              {"http-connects", doh->d_httpconnects},
-              {"http1-queries", doh->d_http1Stats.d_nbQueries},
-              {"http2-queries", doh->d_http2Stats.d_nbQueries},
-              {"http1-200-responses", doh->d_http1Stats.d_nb200Responses},
-              {"http2-200-responses", doh->d_http2Stats.d_nb200Responses},
-              {"http1-400-responses", doh->d_http1Stats.d_nb400Responses},
-              {"http2-400-responses", doh->d_http2Stats.d_nb400Responses},
-              {"http1-403-responses", doh->d_http1Stats.d_nb403Responses},
-              {"http2-403-responses", doh->d_http2Stats.d_nb403Responses},
-              {"http1-500-responses", doh->d_http1Stats.d_nb500Responses},
-              {"http2-500-responses", doh->d_http2Stats.d_nb500Responses},
-              {"http1-502-responses", doh->d_http1Stats.d_nb502Responses},
-              {"http2-502-responses", doh->d_http2Stats.d_nb502Responses},
-              {"http1-other-responses", doh->d_http1Stats.d_nbOtherResponses},
-              {"http2-other-responses", doh->d_http2Stats.d_nbOtherResponses},
-              {"get-queries", doh->d_getqueries},
-              {"post-queries", doh->d_postqueries},
-              {"bad-requests", doh->d_badrequests},
-              {"error-responses", doh->d_errorresponses},
-              {"redirect-responses", doh->d_redirectresponses},
-              {"valid-responses", doh->d_validresponses}
-            };
+            const string base = namespace_name + "." + hostname + "." + instance_name + ".frontends." + frontName + ".";
+            str<<base<<"queries" << ' ' << front->queries.load() << " " << now << "\r\n";
+            str<<base<<"responses" << ' ' << front->responses.load() << " " << now << "\r\n";
+            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<<"tcpdownstreamtimeouts" << ' '<< front->tcpDownstreamTimeouts.load() << " " << now << "\r\n";
+            str<<base<<"tcpcurrentconnections" << ' '<< front->tcpCurrentConnections.load() << " " << now << "\r\n";
+            str<<base<<"tcpavgqueriesperconnection" << ' '<< front->tcpAvgQueriesPerConnection.load() << " " << now << "\r\n";
+            str<<base<<"tcpavgconnectionduration" << ' '<< front->tcpAvgConnectionDuration.load() << " " << now << "\r\n";
+            str<<base<<"tls10-queries" << ' ' << front->tls10queries.load() << " " << now << "\r\n";
+            str<<base<<"tls11-queries" << ' ' << front->tls11queries.load() << " " << now << "\r\n";
+            str<<base<<"tls12-queries" << ' ' << front->tls12queries.load() << " " << now << "\r\n";
+            str<<base<<"tls13-queries" << ' ' << front->tls13queries.load() << " " << now << "\r\n";
+            str<<base<<"tls-unknown-queries" << ' ' << front->tlsUnknownqueries.load() << " " << now << "\r\n";
+            str<<base<<"tlsnewsessions" << ' ' << front->tlsNewSessions.load() << " " << now << "\r\n";
+            str<<base<<"tlsresumptions" << ' ' << front->tlsResumptions.load() << " " << now << "\r\n";
+            str<<base<<"tlsunknownticketkeys" << ' ' << front->tlsUnknownTicketKey.load() << " " << now << "\r\n";
+            str<<base<<"tlsinactiveticketkeys" << ' ' << front->tlsInactiveTicketKey.load() << " " << now << "\r\n";
+            const TLSErrorCounters* errorCounters = nullptr;
+            if (front->tlsFrontend != nullptr) {
+              errorCounters = &front->tlsFrontend->d_tlsCounters;
+            }
+            else if (front->dohFrontend != nullptr) {
+              errorCounters = &front->dohFrontend->d_tlsCounters;
+            }
+            if (errorCounters != nullptr) {
+              str<<base<<"tlsdhkeytoosmall" << ' ' << errorCounters->d_dhKeyTooSmall << " " << now << "\r\n";
+              str<<base<<"tlsinappropriatefallback" << ' ' << errorCounters->d_inappropriateFallBack << " " << now << "\r\n";
+              str<<base<<"tlsnosharedcipher" << ' ' << errorCounters->d_noSharedCipher << " " << now << "\r\n";
+              str<<base<<"tlsunknownciphertype" << ' ' << errorCounters->d_unknownCipherType << " " << now << "\r\n";
+              str<<base<<"tlsunknownkeyexchangetype" << ' ' << errorCounters->d_unknownKeyExchangeType << " " << now << "\r\n";
+              str<<base<<"tlsunknownprotocol" << ' ' << errorCounters->d_unknownProtocol << " " << now << "\r\n";
+              str<<base<<"tlsunsupportedec" << ' ' << errorCounters->d_unsupportedEC << " " << now << "\r\n";
+              str<<base<<"tlsunsupportedprotocol" << ' ' << errorCounters->d_unsupportedProtocol << " " << now << "\r\n";
+            }
+          }
 
-            for(const auto& item : v) {
-              str<<base<<name<<"."<<item.first << " " << item.second << " " << now <<"\r\n";
+          auto localPools = g_pools.getLocal();
+          for (const auto& entry : *localPools) {
+            string poolName = entry.first;
+            boost::replace_all(poolName, ".", "_");
+            if (poolName.empty()) {
+              poolName = "_default_";
+            }
+            const string base = namespace_name + "." + hostname + "." + instance_name + ".pools." + poolName + ".";
+            const std::shared_ptr<ServerPool> pool = entry.second;
+            str<<base<<"servers" << " " << pool->countServers(false) << " " << now << "\r\n";
+            str<<base<<"servers-up" << " " << pool->countServers(true) << " " << now << "\r\n";
+            if (pool->packetCache != nullptr) {
+              const auto& cache = pool->packetCache;
+              str<<base<<"cache-size" << " " << cache->getMaxEntries() << " " << now << "\r\n";
+              str<<base<<"cache-entries" << " " << cache->getEntriesCount() << " " << now << "\r\n";
+              str<<base<<"cache-hits" << " " << cache->getHits() << " " << now << "\r\n";
+              str<<base<<"cache-misses" << " " << cache->getMisses() << " " << now << "\r\n";
+              str<<base<<"cache-deferred-inserts" << " " << cache->getDeferredInserts() << " " << now << "\r\n";
+              str<<base<<"cache-deferred-lookups" << " " << cache->getDeferredLookups() << " " << now << "\r\n";
+              str<<base<<"cache-lookup-collisions" << " " << cache->getLookupCollisions() << " " << now << "\r\n";
+              str<<base<<"cache-insert-collisions" << " " << cache->getInsertCollisions() << " " << now << "\r\n";
+              str<<base<<"cache-ttl-too-shorts" << " " << cache->getTTLTooShorts() << " " << now << "\r\n";
+            }
+          }
+
+#ifdef HAVE_DNS_OVER_HTTPS
+          {
+            std::map<std::string,uint64_t> dohFrontendDuplicates;
+            const string base = "dnsdist." + hostname + ".main.doh.";
+            for(const auto& doh : g_dohlocals) {
+              string name = doh->d_local.toStringWithPort();
+              boost::replace_all(name, ".", "_");
+              boost::replace_all(name, ":", "_");
+              boost::replace_all(name, "[", "_");
+              boost::replace_all(name, "]", "_");
+
+              auto dupPair = dohFrontendDuplicates.insert({name, 1});
+              if (!dupPair.second) {
+                name = name + "_" + std::to_string(dupPair.first->second);
+                ++(dupPair.first->second);
+              }
+
+              vector<pair<const char*, const std::atomic<uint64_t>&>> v{
+                {"http-connects", doh->d_httpconnects},
+                {"http1-queries", doh->d_http1Stats.d_nbQueries},
+                {"http2-queries", doh->d_http2Stats.d_nbQueries},
+                {"http1-200-responses", doh->d_http1Stats.d_nb200Responses},
+                {"http2-200-responses", doh->d_http2Stats.d_nb200Responses},
+                {"http1-400-responses", doh->d_http1Stats.d_nb400Responses},
+                {"http2-400-responses", doh->d_http2Stats.d_nb400Responses},
+                {"http1-403-responses", doh->d_http1Stats.d_nb403Responses},
+                {"http2-403-responses", doh->d_http2Stats.d_nb403Responses},
+                {"http1-500-responses", doh->d_http1Stats.d_nb500Responses},
+                {"http2-500-responses", doh->d_http2Stats.d_nb500Responses},
+                {"http1-502-responses", doh->d_http1Stats.d_nb502Responses},
+                {"http2-502-responses", doh->d_http2Stats.d_nb502Responses},
+                {"http1-other-responses", doh->d_http1Stats.d_nbOtherResponses},
+                {"http2-other-responses", doh->d_http2Stats.d_nbOtherResponses},
+                {"get-queries", doh->d_getqueries},
+                {"post-queries", doh->d_postqueries},
+                {"bad-requests", doh->d_badrequests},
+                {"error-responses", doh->d_errorresponses},
+                {"redirect-responses", doh->d_redirectresponses},
+                {"valid-responses", doh->d_validresponses}
+              };
+
+              for(const auto& item : v) {
+                str<<base<<name<<"."<<item.first << " " << item.second << " " << now <<"\r\n";
+              }
             }
           }
-        }
 #endif /* HAVE_DNS_OVER_HTTPS */
 
-        {
-          WriteLock wl(&g_qcount.queryLock);
-          std::string qname;
-          for(auto &record: g_qcount.records) {
-            qname = record.first;
-            boost::replace_all(qname, ".", "_");
-            str<<"dnsdist.querycount." << qname << ".queries " << record.second << " " << now << "\r\n";
+          {
+            WriteLock wl(&g_qcount.queryLock);
+            std::string qname;
+            for(auto &record: g_qcount.records) {
+              qname = record.first;
+              boost::replace_all(qname, ".", "_");
+              str<<"dnsdist.querycount." << qname << ".queries " << record.second << " " << now << "\r\n";
+            }
+            g_qcount.records.clear();
           }
-          g_qcount.records.clear();
-        }
 
-        const string msg = str.str();
+          const string msg = str.str();
 
-        int ret = waitForRWData(s.getHandle(), false, 1 , 0);
-        if(ret <= 0 ) {
-          vinfolog("Unable to write data to carbon server on %s: %s", server.toStringWithPort(), (ret<0 ? stringerror() : "Timeout"));
-          continue;
+          int ret = waitForRWData(s.getHandle(), false, 1 , 0);
+          if(ret <= 0 ) {
+            vinfolog("Unable to write data to carbon server on %s: %s", server.toStringWithPort(), (ret<0 ? stringerror() : "Timeout"));
+            continue;
+          }
+          s.setBlocking();
+          writen2(s.getHandle(), msg.c_str(), msg.size());
+        }
+        catch(const std::exception& e) {
+          warnlog("Problem sending carbon data: %s", e.what());
         }
-        s.setBlocking();
-        writen2(s.getHandle(), msg.c_str(), msg.size());
-      }
-      catch(std::exception& e) {
-        warnlog("Problem sending carbon data: %s", e.what());
       }
     }
   }
-}
-catch(std::exception& e)
-{
-  errlog("Carbon thread died: %s", e.what());
-}
-catch(PDNSException& e)
-{
-  errlog("Carbon thread died, PDNSException: %s", e.reason);
-}
-catch(...)
-{
-  errlog("Carbon thread died");
+  catch(const std::exception& e)
+  {
+    errlog("Carbon thread died: %s", e.what());
+  }
+  catch(const PDNSException& e)
+  {
+    errlog("Carbon thread died, PDNSException: %s", e.reason);
+  }
+  catch(...)
+  {
+    errlog("Carbon thread died");
+  }
 }
index 008ca01840a9bd73c1dfd6f9b372b342e90e2531..c2ac58bed05b3e5c0df3523847fce170324ff464 100644 (file)
@@ -80,30 +80,39 @@ static string historyFile(const bool &ignoreHOME = false)
 }
 
 static bool getMsgLen32(int fd, uint32_t* len)
-try
 {
-  uint32_t raw;
-  size_t ret = readn2(fd, &raw, sizeof raw);
-  if(ret != sizeof raw)
-    return false;
-  *len = ntohl(raw);
-  if(*len > g_consoleOutputMsgMaxSize)
+  try
+  {
+    uint32_t raw;
+    size_t ret = readn2(fd, &raw, sizeof raw);
+
+    if (ret != sizeof raw) {
+      return false;
+    }
+
+    *len = ntohl(raw);
+    if (*len > g_consoleOutputMsgMaxSize) {
+      return false;
+    }
+
+    return true;
+  }
+  catch(...) {
     return false;
-  return true;
-}
-catch(...) {
-   return false;
+  }
 }
 
 static bool putMsgLen32(int fd, uint32_t len)
-try
 {
-  uint32_t raw = htonl(len);
-  size_t ret = writen2(fd, &raw, sizeof raw);
-  return ret==sizeof raw;
-}
-catch(...) {
-  return false;
+  try
+  {
+    uint32_t raw = htonl(len);
+    size_t ret = writen2(fd, &raw, sizeof raw);
+    return ret == sizeof raw;
+  }
+  catch(...) {
+    return false;
+  }
 }
 
 static bool sendMessageToServer(int fd, const std::string& line, SodiumNonce& readingNonce, SodiumNonce& writingNonce, const bool outputEmptyLine)
@@ -673,171 +682,175 @@ char** my_completion( const char * text , int start,  int end)
 }
 
 static void controlClientThread(int fd, ComboAddress client)
-try
 {
-  setThreadName("dnsdist/conscli");
-  setTCPNoDelay(fd);
-  SodiumNonce theirs, ours, readingNonce, writingNonce;
-  ours.init();
-  readn2(fd, (char*)theirs.value, sizeof(theirs.value));
-  writen2(fd, (char*)ours.value, sizeof(ours.value));
-  readingNonce.merge(ours, theirs);
-  writingNonce.merge(theirs, ours);
-
-  for(;;) {
-    uint32_t len;
-    if(!getMsgLen32(fd, &len))
-      break;
-
-    if (len == 0) {
-      /* just ACK an empty message
-         with an empty response */
-      putMsgLen32(fd, 0);
-      continue;
-    }
+  try
+  {
+    setThreadName("dnsdist/conscli");
+    setTCPNoDelay(fd);
+    SodiumNonce theirs, ours, readingNonce, writingNonce;
+    ours.init();
+    readn2(fd, (char*)theirs.value, sizeof(theirs.value));
+    writen2(fd, (char*)ours.value, sizeof(ours.value));
+    readingNonce.merge(ours, theirs);
+    writingNonce.merge(theirs, ours);
+
+    for(;;) {
+      uint32_t len;
+      if(!getMsgLen32(fd, &len))
+        break;
+
+      if (len == 0) {
+        /* just ACK an empty message
+           with an empty response */
+        putMsgLen32(fd, 0);
+        continue;
+      }
 
-    boost::scoped_array<char> msg(new char[len]);
-    readn2(fd, msg.get(), len);
+      boost::scoped_array<char> msg(new char[len]);
+      readn2(fd, msg.get(), len);
 
-    string line(msg.get(), len);
+      string line(msg.get(), len);
 
-    line = sodDecryptSym(line, g_consoleKey, readingNonce);
-    //    cerr<<"Have decrypted line: "<<line<<endl;
-    string response;
-    try {
-      bool withReturn=true;
-    retry:;
+      line = sodDecryptSym(line, g_consoleKey, readingNonce);
+      //    cerr<<"Have decrypted line: "<<line<<endl;
+      string response;
       try {
-        std::lock_guard<std::mutex> lock(g_luamutex);
+        bool withReturn=true;
+      retry:;
+        try {
+          std::lock_guard<std::mutex> lock(g_luamutex);
         
-        g_outputBuffer.clear();
-        resetLuaSideEffect();
-        auto ret=g_lua.executeCode<
-          boost::optional<
-            boost::variant<
-              string, 
-              shared_ptr<DownstreamState>,
-              ClientState*,
-              std::unordered_map<string, double>
+          g_outputBuffer.clear();
+          resetLuaSideEffect();
+          auto ret=g_lua.executeCode<
+            boost::optional<
+              boost::variant<
+                string, 
+                shared_ptr<DownstreamState>,
+                ClientState*,
+                std::unordered_map<string, double>
+                >
               >
-            >
-          >(withReturn ? ("return "+line) : line);
-
-      if(ret) {
-        if (const auto dsValue = boost::get<shared_ptr<DownstreamState>>(&*ret)) {
-          if (*dsValue) {
-            response=(*dsValue)->getName()+"\n";
-          } else {
-            response="";
+            >(withReturn ? ("return "+line) : line);
+
+          if(ret) {
+            if (const auto dsValue = boost::get<shared_ptr<DownstreamState>>(&*ret)) {
+              if (*dsValue) {
+                response=(*dsValue)->getName()+"\n";
+              } else {
+                response="";
+              }
+            }
+            else if (const auto csValue = boost::get<ClientState*>(&*ret)) {
+              if (*csValue) {
+                response=(*csValue)->local.toStringWithPort()+"\n";
+              } else {
+                response="";
+              }
+            }
+            else if (const auto strValue = boost::get<string>(&*ret)) {
+              response=*strValue+"\n";
+            }
+            else if(const auto um = boost::get<std::unordered_map<string, double> >(&*ret)) {
+              using namespace json11;
+              Json::object o;
+              for(const auto& v : *um)
+                o[v.first]=v.second;
+              Json out = o;
+              response=out.dump()+"\n";
+            }
           }
+          else
+            response=g_outputBuffer;
+          if(!getLuaNoSideEffect())
+            feedConfigDelta(line);
         }
-        else if (const auto csValue = boost::get<ClientState*>(&*ret)) {
-          if (*csValue) {
-            response=(*csValue)->local.toStringWithPort()+"\n";
-          } else {
-            response="";
+        catch(const LuaContext::SyntaxErrorException&) {
+          if(withReturn) {
+            withReturn=false;
+            goto retry;
           }
-        }
-        else if (const auto strValue = boost::get<string>(&*ret)) {
-          response=*strValue+"\n";
-        }
-        else if(const auto um = boost::get<std::unordered_map<string, double> >(&*ret)) {
-          using namespace json11;
-          Json::object o;
-          for(const auto& v : *um)
-            o[v.first]=v.second;
-          Json out = o;
-          response=out.dump()+"\n";
+          throw;
         }
       }
-      else
-       response=g_outputBuffer;
-      if(!getLuaNoSideEffect())
-        feedConfigDelta(line);
+      catch(const LuaContext::WrongTypeException& e) {
+        response = "Command returned an object we can't print: " +std::string(e.what()) + "\n";
+        // tried to return something we don't understand
       }
-      catch(const LuaContext::SyntaxErrorException&) {
-        if(withReturn) {
-          withReturn=false;
-          goto retry;
+      catch(const LuaContext::ExecutionErrorException& e) {
+        if(!strcmp(e.what(),"invalid key to 'next'"))
+          response = "Error: Parsing function parameters, did you forget parameter name?";
+        else
+          response = "Error: " + string(e.what());
+        try {
+          std::rethrow_if_nested(e);
+        } catch(const std::exception& ne) {
+          // ne is the exception that was thrown from inside the lambda
+          response+= ": " + string(ne.what());
+        }
+        catch(const PDNSException& ne) {
+          // ne is the exception that was thrown from inside the lambda
+          response += ": " + string(ne.reason);
         }
-        throw;
-      }
-    }
-    catch(const LuaContext::WrongTypeException& e) {
-      response = "Command returned an object we can't print: " +std::string(e.what()) + "\n";
-      // tried to return something we don't understand
-    }
-    catch(const LuaContext::ExecutionErrorException& e) {
-      if(!strcmp(e.what(),"invalid key to 'next'"))
-        response = "Error: Parsing function parameters, did you forget parameter name?";
-      else
-        response = "Error: " + string(e.what());
-      try {
-        std::rethrow_if_nested(e);
-      } catch(const std::exception& ne) {
-        // ne is the exception that was thrown from inside the lambda
-        response+= ": " + string(ne.what());
       }
-      catch(const PDNSException& ne) {
-        // ne is the exception that was thrown from inside the lambda
-        response += ": " + string(ne.reason);
+      catch(const LuaContext::SyntaxErrorException& e) {
+        response = "Error: " + string(e.what()) + ": ";
       }
+      response = sodEncryptSym(response, g_consoleKey, writingNonce);
+      putMsgLen32(fd, response.length());
+      writen2(fd, response.c_str(), response.length());
     }
-    catch(const LuaContext::SyntaxErrorException& e) {
-      response = "Error: " + string(e.what()) + ": ";
+    if (g_logConsoleConnections) {
+      infolog("Closed control connection from %s", client.toStringWithPort());
     }
-    response = sodEncryptSym(response, g_consoleKey, writingNonce);
-    putMsgLen32(fd, response.length());
-    writen2(fd, response.c_str(), response.length());
+    close(fd);
+    fd=-1;
   }
-  if (g_logConsoleConnections) {
-    infolog("Closed control connection from %s", client.toStringWithPort());
+  catch (const std::exception& e)
+  {
+    errlog("Got an exception in client connection from %s: %s", client.toStringWithPort(), e.what());
+    if(fd >= 0)
+      close(fd);
   }
-  close(fd);
-  fd=-1;
-}
-catch(std::exception& e)
-{
-  errlog("Got an exception in client connection from %s: %s", client.toStringWithPort(), e.what());
-  if(fd >= 0)
-    close(fd);
 }
 
 void controlThread(int fd, ComboAddress local)
-try
 {
-  setThreadName("dnsdist/control");
-  ComboAddress client;
-  int sock;
-  auto localACL = g_consoleACL.getLocal();
-  infolog("Accepting control connections on %s", local.toStringWithPort());
-
-  while ((sock = SAccept(fd, client)) >= 0) {
+  try
+  {
+    setThreadName("dnsdist/control");
+    ComboAddress client;
+    int sock;
+    auto localACL = g_consoleACL.getLocal();
+    infolog("Accepting control connections on %s", local.toStringWithPort());
+
+    while ((sock = SAccept(fd, client)) >= 0) {
+
+      if (!sodIsValidKey(g_consoleKey)) {
+        vinfolog("Control connection from %s dropped because we don't have a valid key configured, please configure one using setKey()", client.toStringWithPort());
+        close(sock);
+        continue;
+      }
 
-    if (!sodIsValidKey(g_consoleKey)) {
-      vinfolog("Control connection from %s dropped because we don't have a valid key configured, please configure one using setKey()", client.toStringWithPort());
-      close(sock);
-      continue;
-    }
+      if (!localACL->match(client)) {
+        vinfolog("Control connection from %s dropped because of ACL", client.toStringWithPort());
+        close(sock);
+        continue;
+      }
 
-    if (!localACL->match(client)) {
-      vinfolog("Control connection from %s dropped because of ACL", client.toStringWithPort());
-      close(sock);
-      continue;
-    }
+      if (g_logConsoleConnections) {
+        warnlog("Got control connection from %s", client.toStringWithPort());
+      }
 
-    if (g_logConsoleConnections) {
-      warnlog("Got control connection from %s", client.toStringWithPort());
+      std::thread t(controlClientThread, sock, client);
+      t.detach();
     }
-
-    std::thread t(controlClientThread, sock, client);
-    t.detach();
   }
-}
-catch(const std::exception& e)
-{
-  close(fd);
-  errlog("Control connection died: %s", e.what());
+  catch (const std::exception& e)
+  {
+    close(fd);
+    errlog("Control connection died: %s", e.what());
+  }
 }
 
 void clearConsoleHistory()
index 568fd0c2db3cd3ba83fa8318c9205cd124a46ef2..b42aaf7f436b353088415ac0a392507d5b025886 100644 (file)
@@ -1498,8 +1498,7 @@ static void MultipleMessagesUDPClientThread(ClientState* cs, LocalHolders& holde
 // listens to incoming queries, sends out to downstream servers, noting the intended return path
 static void udpClientThread(ClientState* cs)
 {
-  try
-  {
+  try {
     setThreadName("dnsdist/udpClie");
     LocalHolders holders;
 
@@ -2000,477 +1999,478 @@ static void usage()
 }
 
 int main(int argc, char** argv)
-try
 {
-  size_t udpBindsCount = 0;
-  size_t tcpBindsCount = 0;
-  rl_attempted_completion_function = my_completion;
-  rl_completion_append_character = 0;
+  try {
+    size_t udpBindsCount = 0;
+    size_t tcpBindsCount = 0;
+    rl_attempted_completion_function = my_completion;
+    rl_completion_append_character = 0;
 
-  signal(SIGPIPE, SIG_IGN);
-  signal(SIGCHLD, SIG_IGN);
-  openlog("dnsdist", LOG_PID|LOG_NDELAY, LOG_DAEMON);
+    signal(SIGPIPE, SIG_IGN);
+    signal(SIGCHLD, SIG_IGN);
+    openlog("dnsdist", LOG_PID|LOG_NDELAY, LOG_DAEMON);
 
 #ifdef HAVE_LIBSODIUM
-  if (sodium_init() == -1) {
-    cerr<<"Unable to initialize crypto library"<<endl;
-    exit(EXIT_FAILURE);
-  }
-  g_hashperturb=randombytes_uniform(0xffffffff);
-  srandom(randombytes_uniform(0xffffffff));
+    if (sodium_init() == -1) {
+      cerr<<"Unable to initialize crypto library"<<endl;
+      exit(EXIT_FAILURE);
+    }
+    g_hashperturb=randombytes_uniform(0xffffffff);
+    srandom(randombytes_uniform(0xffffffff));
 #else
-  {
-    struct timeval tv;
-    gettimeofday(&tv, 0);
-    srandom(tv.tv_sec ^ tv.tv_usec ^ getpid());
-    g_hashperturb=random();
-  }
+    {
+      struct timeval tv;
+      gettimeofday(&tv, 0);
+      srandom(tv.tv_sec ^ tv.tv_usec ^ getpid());
+      g_hashperturb=random();
+    }
   
 #endif
-  ComboAddress clientAddress = ComboAddress();
-  g_cmdLine.config=SYSCONFDIR "/dnsdist.conf";
-  struct option longopts[]={
-    {"acl", required_argument, 0, 'a'},
-    {"check-config", no_argument, 0, 1},
-    {"client", no_argument, 0, 'c'},
-    {"config", required_argument, 0, 'C'},
-    {"disable-syslog", no_argument, 0, 2},
-    {"execute", required_argument, 0, 'e'},
-    {"gid", required_argument, 0, 'g'},
-    {"help", no_argument, 0, 'h'},
-    {"local", required_argument, 0, 'l'},
-    {"setkey", required_argument, 0, 'k'},
-    {"supervised", no_argument, 0, 3},
-    {"uid", required_argument, 0, 'u'},
-    {"verbose", no_argument, 0, 'v'},
-    {"version", no_argument, 0, 'V'},
-    {0,0,0,0}
-  };
-  int longindex=0;
-  string optstring;
-  for(;;) {
-    int c=getopt_long(argc, argv, "a:cC:e:g:hk:l:u:vV", longopts, &longindex);
-    if(c==-1)
-      break;
-    switch(c) {
-    case 1:
-      g_cmdLine.checkConfig=true;
-      break;
-    case 2:
-      g_syslog=false;
-      break;
-    case 3:
-      g_cmdLine.beSupervised=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 "<<VERSION<<endl;
-      usage();
-      cout<<"\n";
-      exit(EXIT_SUCCESS);
-      break;
-    case 'a':
-      optstring=optarg;
-      g_ACL.modify([optstring](NetmaskGroup& nmg) { nmg.addMask(optstring); });
-      break;
-    case 'k':
+    ComboAddress clientAddress = ComboAddress();
+    g_cmdLine.config=SYSCONFDIR "/dnsdist.conf";
+    struct option longopts[]={
+      {"acl", required_argument, 0, 'a'},
+      {"check-config", no_argument, 0, 1},
+      {"client", no_argument, 0, 'c'},
+      {"config", required_argument, 0, 'C'},
+      {"disable-syslog", no_argument, 0, 2},
+      {"execute", required_argument, 0, 'e'},
+      {"gid", required_argument, 0, 'g'},
+      {"help", no_argument, 0, 'h'},
+      {"local", required_argument, 0, 'l'},
+      {"setkey", required_argument, 0, 'k'},
+      {"supervised", no_argument, 0, 3},
+      {"uid", required_argument, 0, 'u'},
+      {"verbose", no_argument, 0, 'v'},
+      {"version", no_argument, 0, 'V'},
+      {0,0,0,0}
+    };
+    int longindex=0;
+    string optstring;
+    for(;;) {
+      int c=getopt_long(argc, argv, "a:cC:e:g:hk:l:u:vV", longopts, &longindex);
+      if(c==-1)
+        break;
+      switch(c) {
+      case 1:
+        g_cmdLine.checkConfig=true;
+        break;
+      case 2:
+        g_syslog=false;
+        break;
+      case 3:
+        g_cmdLine.beSupervised=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 "<<VERSION<<endl;
+        usage();
+        cout<<"\n";
+        exit(EXIT_SUCCESS);
+        break;
+      case 'a':
+        optstring=optarg;
+        g_ACL.modify([optstring](NetmaskGroup& nmg) { nmg.addMask(optstring); });
+        break;
+      case 'k':
 #ifdef HAVE_LIBSODIUM
-      if (B64Decode(string(optarg), g_consoleKey) < 0) {
-        cerr<<"Unable to decode key '"<<optarg<<"'."<<endl;
-        exit(EXIT_FAILURE);
-      }
+        if (B64Decode(string(optarg), g_consoleKey) < 0) {
+          cerr<<"Unable to decode key '"<<optarg<<"'."<<endl;
+          exit(EXIT_FAILURE);
+        }
 #else
-      cerr<<"dnsdist has been built without libsodium, -k/--setkey is unsupported."<<endl;
-      exit(EXIT_FAILURE);
+        cerr<<"dnsdist has been built without libsodium, -k/--setkey is unsupported."<<endl;
+        exit(EXIT_FAILURE);
 #endif
-      break;
-    case 'l':
-      g_cmdLine.locals.push_back(boost::trim_copy(string(optarg)));
-      break;
-    case 'u':
-      g_cmdLine.uid=optarg;
-      break;
-    case 'v':
-      g_verbose=true;
-      break;
-    case 'V':
+        break;
+      case 'l':
+        g_cmdLine.locals.push_back(boost::trim_copy(string(optarg)));
+        break;
+      case 'u':
+        g_cmdLine.uid=optarg;
+        break;
+      case 'v':
+        g_verbose=true;
+        break;
+      case 'V':
 #ifdef LUAJIT_VERSION
-      cout<<"dnsdist "<<VERSION<<" ("<<LUA_RELEASE<<" ["<<LUAJIT_VERSION<<"])"<<endl;
+        cout<<"dnsdist "<<VERSION<<" ("<<LUA_RELEASE<<" ["<<LUAJIT_VERSION<<"])"<<endl;
 #else
-      cout<<"dnsdist "<<VERSION<<" ("<<LUA_RELEASE<<")"<<endl;
+        cout<<"dnsdist "<<VERSION<<" ("<<LUA_RELEASE<<")"<<endl;
 #endif
-      cout<<"Enabled features: ";
+        cout<<"Enabled features: ";
 #ifdef HAVE_CDB
-      cout<<"cdb ";
+        cout<<"cdb ";
 #endif
 #ifdef HAVE_DNS_OVER_TLS
-      cout<<"dns-over-tls(";
+        cout<<"dns-over-tls(";
 #ifdef HAVE_GNUTLS
-      cout<<"gnutls";
-  #ifdef HAVE_LIBSSL
-      cout<<" ";
-  #endif
+        cout<<"gnutls";
+#ifdef HAVE_LIBSSL
+        cout<<" ";
+#endif
 #endif
 #ifdef HAVE_LIBSSL
-      cout<<"openssl";
+        cout<<"openssl";
 #endif
-      cout<<") ";
+        cout<<") ";
 #endif
 #ifdef HAVE_DNS_OVER_HTTPS
-      cout<<"dns-over-https(DOH) ";
+        cout<<"dns-over-https(DOH) ";
 #endif
 #ifdef HAVE_DNSCRYPT
-      cout<<"dnscrypt ";
+        cout<<"dnscrypt ";
 #endif
 #ifdef HAVE_EBPF
-      cout<<"ebpf ";
+        cout<<"ebpf ";
 #endif
 #ifdef HAVE_FSTRM
-      cout<<"fstrm ";
+        cout<<"fstrm ";
 #endif
 #ifdef HAVE_LIBCRYPTO
-      cout<<"ipcipher ";
+        cout<<"ipcipher ";
 #endif
 #ifdef HAVE_LIBSODIUM
-      cout<<"libsodium ";
+        cout<<"libsodium ";
 #endif
 #ifdef HAVE_LMDB
-      cout<<"lmdb ";
+        cout<<"lmdb ";
 #endif
-      cout<<"protobuf ";
+        cout<<"protobuf ";
 #ifdef HAVE_RE2
-      cout<<"re2 ";
+        cout<<"re2 ";
 #endif
 #if defined(HAVE_RECVMMSG) && defined(HAVE_SENDMMSG) && defined(MSG_WAITFORONE)
-      cout<<"recvmmsg/sendmmsg ";
+        cout<<"recvmmsg/sendmmsg ";
 #endif
 #ifdef HAVE_NET_SNMP
-      cout<<"snmp ";
+        cout<<"snmp ";
 #endif
 #ifdef HAVE_SYSTEMD
-      cout<<"systemd";
+        cout<<"systemd";
 #endif
-      cout<<endl;
-      exit(EXIT_SUCCESS);
-      break;
-    case '?':
-      //getopt_long printed an error message.
-      usage();
-      exit(EXIT_FAILURE);
-      break;
+        cout<<endl;
+        exit(EXIT_SUCCESS);
+        break;
+      case '?':
+        //getopt_long printed an error message.
+        usage();
+        exit(EXIT_FAILURE);
+        break;
+      }
     }
-  }
 
-  argc-=optind;
-  argv+=optind;
-  for(auto p = argv; *p; ++p) {
-    if(g_cmdLine.beClient) {
-      clientAddress = ComboAddress(*p, 5199);
-    } else {
-      g_cmdLine.remotes.push_back(*p);
+    argc-=optind;
+    argv+=optind;
+    for(auto p = argv; *p; ++p) {
+      if(g_cmdLine.beClient) {
+        clientAddress = ComboAddress(*p, 5199);
+      } else {
+        g_cmdLine.remotes.push_back(*p);
+      }
     }
-  }
 
-  ServerPolicy leastOutstandingPol{"leastOutstanding", leastOutstanding, false};
+    ServerPolicy leastOutstandingPol{"leastOutstanding", leastOutstanding, false};
 
-  g_policy.setState(leastOutstandingPol);
-  if(g_cmdLine.beClient || !g_cmdLine.command.empty()) {
-    setupLua(g_lua, true, false, g_cmdLine.config);
-    if (clientAddress != ComboAddress())
-      g_serverControl = clientAddress;
-    doClient(g_serverControl, g_cmdLine.command);
-    _exit(EXIT_SUCCESS);
-  }
+    g_policy.setState(leastOutstandingPol);
+    if(g_cmdLine.beClient || !g_cmdLine.command.empty()) {
+      setupLua(g_lua, true, false, g_cmdLine.config);
+      if (clientAddress != ComboAddress())
+        g_serverControl = clientAddress;
+      doClient(g_serverControl, g_cmdLine.command);
+      _exit(EXIT_SUCCESS);
+    }
 
-  auto acl = g_ACL.getCopy();
-  if(acl.empty()) {
-    for(auto& addr : {"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"})
-      acl.addMask(addr);
-    g_ACL.setState(acl);
-  }
+    auto acl = g_ACL.getCopy();
+    if(acl.empty()) {
+      for(auto& addr : {"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"})
+        acl.addMask(addr);
+      g_ACL.setState(acl);
+    }
 
-  auto consoleACL = g_consoleACL.getCopy();
-  for (const auto& mask : { "127.0.0.1/8", "::1/128" }) {
-    consoleACL.addMask(mask);
-  }
-  g_consoleACL.setState(consoleACL);
-  registerBuiltInWebHandlers();
+    auto consoleACL = g_consoleACL.getCopy();
+    for (const auto& mask : { "127.0.0.1/8", "::1/128" }) {
+      consoleACL.addMask(mask);
+    }
+    g_consoleACL.setState(consoleACL);
+    registerBuiltInWebHandlers();
 
-  if (g_cmdLine.checkConfig) {
-    setupLua(g_lua, false, true, g_cmdLine.config);
-    // No exception was thrown
-    infolog("Configuration '%s' OK!", g_cmdLine.config);
-    _exit(EXIT_SUCCESS);
-  }
+    if (g_cmdLine.checkConfig) {
+      setupLua(g_lua, false, true, g_cmdLine.config);
+      // No exception was thrown
+      infolog("Configuration '%s' OK!", g_cmdLine.config);
+      _exit(EXIT_SUCCESS);
+    }
 
-  auto todo = setupLua(g_lua, false, false, g_cmdLine.config);
+    auto todo = setupLua(g_lua, false, false, g_cmdLine.config);
 
-  auto localPools = g_pools.getCopy();
-  {
-    bool precompute = false;
-    if (g_policy.getLocal()->getName() == "chashed") {
-      precompute = true;
-    } else {
-      for (const auto& entry: localPools) {
-        if (entry.second->policy != nullptr && entry.second->policy->getName() == "chashed") {
-          precompute = true;
-          break ;
+    auto localPools = g_pools.getCopy();
+    {
+      bool precompute = false;
+      if (g_policy.getLocal()->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->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->weight);
-        }
+      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->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->weight);
+          }
 
-        backend->hash();
+          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 = g_frontends.erase(it);
+    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 = g_frontends.erase(it);
+        }
+        else {
+          ++it;
+        }
       }
-      else {
-        ++it;
+
+      for(const auto& loc : g_cmdLine.locals) {
+        /* UDP */
+        g_frontends.push_back(std::unique_ptr<ClientState>(new ClientState(ComboAddress(loc, 53), false, false, 0, "", {})));
+        /* TCP */
+        g_frontends.push_back(std::unique_ptr<ClientState>(new ClientState(ComboAddress(loc, 53), true, false, 0, "", {})));
       }
     }
 
-    for(const auto& loc : g_cmdLine.locals) {
+    if (g_frontends.empty()) {
       /* UDP */
-      g_frontends.push_back(std::unique_ptr<ClientState>(new ClientState(ComboAddress(loc, 53), false, false, 0, "", {})));
+      g_frontends.push_back(std::unique_ptr<ClientState>(new ClientState(ComboAddress("127.0.0.1", 53), false, false, 0, "", {})));
       /* TCP */
-      g_frontends.push_back(std::unique_ptr<ClientState>(new ClientState(ComboAddress(loc, 53), true, false, 0, "", {})));
+      g_frontends.push_back(std::unique_ptr<ClientState>(new ClientState(ComboAddress("127.0.0.1", 53), true, false, 0, "", {})));
     }
-  }
 
-  if (g_frontends.empty()) {
-    /* UDP */
-    g_frontends.push_back(std::unique_ptr<ClientState>(new ClientState(ComboAddress("127.0.0.1", 53), false, false, 0, "", {})));
-    /* TCP */
-    g_frontends.push_back(std::unique_ptr<ClientState>(new ClientState(ComboAddress("127.0.0.1", 53), true, false, 0, "", {})));
-  }
-
-  g_configurationDone = true;
+    g_configurationDone = true;
 
-  for(auto& frontend : g_frontends) {
-    setUpLocalBind(frontend);
+    for(auto& frontend : g_frontends) {
+      setUpLocalBind(frontend);
 
-    if (frontend->tcp == false) {
-      ++udpBindsCount;
-    }
-    else {
-      ++tcpBindsCount;
+      if (frontend->tcp == false) {
+        ++udpBindsCount;
+      }
+      else {
+        ++tcpBindsCount;
+      }
     }
-  }
 
-  warnlog("dnsdist %s comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms of the GPL version 2", VERSION);
+    warnlog("dnsdist %s comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms of the GPL version 2", VERSION);
 
-  vector<string> vec;
-  std::string acls;
-  g_ACL.getLocal()->toStringVector(&vec);
-  for(const auto& s : vec) {
-    if (!acls.empty())
-      acls += ", ";
-    acls += s;
-  }
-  infolog("ACL allowing queries from: %s", acls.c_str());
-  vec.clear();
-  acls.clear();
-  g_consoleACL.getLocal()->toStringVector(&vec);
-  for (const auto& entry : vec) {
-    if (!acls.empty()) {
-      acls += ", ";
+    vector<string> vec;
+    std::string acls;
+    g_ACL.getLocal()->toStringVector(&vec);
+    for(const auto& s : vec) {
+      if (!acls.empty())
+        acls += ", ";
+      acls += s;
     }
-    acls += entry;
-  }
-  infolog("Console ACL allowing connections from: %s", acls.c_str());
+    infolog("ACL allowing queries from: %s", acls.c_str());
+    vec.clear();
+    acls.clear();
+    g_consoleACL.getLocal()->toStringVector(&vec);
+    for (const auto& entry : vec) {
+      if (!acls.empty()) {
+        acls += ", ";
+      }
+      acls += entry;
+    }
+    infolog("Console ACL allowing connections from: %s", acls.c_str());
 
 #ifdef HAVE_LIBSODIUM
-  if (g_consoleEnabled && g_consoleKey.empty()) {
-    warnlog("Warning, the console has been enabled via 'controlSocket()' but no key has been set with 'setKey()' so all connections will fail until a key has been set");
-  }
+    if (g_consoleEnabled && g_consoleKey.empty()) {
+      warnlog("Warning, the console has been enabled via 'controlSocket()' but no key has been set with 'setKey()' so all connections will fail until a key has been set");
+    }
 #endif
 
-  uid_t newgid=getegid();
-  gid_t newuid=geteuid();
+    uid_t newgid=getegid();
+    gid_t newuid=geteuid();
 
-  if(!g_cmdLine.gid.empty())
-    newgid = strToGID(g_cmdLine.gid.c_str());
+    if(!g_cmdLine.gid.empty())
+      newgid = strToGID(g_cmdLine.gid.c_str());
 
-  if(!g_cmdLine.uid.empty())
-    newuid = strToUID(g_cmdLine.uid.c_str());
+    if(!g_cmdLine.uid.empty())
+      newuid = strToUID(g_cmdLine.uid.c_str());
 
-  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);
+    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);
     }
-    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);
+    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);
     }
-    dropUserPrivs(newuid);
-  }
 
-  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());
-  }
+    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());
+    }
 
-  /* this need to be done _after_ dropping privileges */
-  g_delay = new DelayPipe<DelayedPacket>();
+    /* this need to be done _after_ dropping privileges */
+    g_delay = new DelayPipe<DelayedPacket>();
 
-  if (g_snmpAgent) {
-    g_snmpAgent->run();
-  }
+    if (g_snmpAgent) {
+      g_snmpAgent->run();
+    }
 
-  g_tcpclientthreads = std::unique_ptr<TCPClientCollection>(new TCPClientCollection(g_maxTCPClientThreads, g_useTCPSinglePipe));
+    g_tcpclientthreads = std::unique_ptr<TCPClientCollection>(new TCPClientCollection(g_maxTCPClientThreads, g_useTCPSinglePipe));
 
-  for(auto& t : todo)
-    t();
+    for(auto& t : todo)
+      t();
 
-  localPools = g_pools.getCopy();
-  /* create the default pool no matter what */
-  createPoolIfNotExists(localPools, "");
-  if(g_cmdLine.remotes.size()) {
-    for(const auto& address : g_cmdLine.remotes) {
-      auto ret=std::make_shared<DownstreamState>(ComboAddress(address, 53));
-      addServerToPool(localPools, "", ret);
-      if (ret->connected && !ret->threadStarted.test_and_set()) {
-        ret->tid = thread(responderThread, ret);
+    localPools = g_pools.getCopy();
+    /* create the default pool no matter what */
+    createPoolIfNotExists(localPools, "");
+    if(g_cmdLine.remotes.size()) {
+      for(const auto& address : g_cmdLine.remotes) {
+        auto ret=std::make_shared<DownstreamState>(ComboAddress(address, 53));
+        addServerToPool(localPools, "", ret);
+        if (ret->connected && !ret->threadStarted.test_and_set()) {
+          ret->tid = thread(responderThread, ret);
+        }
+        g_dstates.modify([ret](servers_t& servers) { servers.push_back(ret); });
       }
-      g_dstates.modify([ret](servers_t& servers) { servers.push_back(ret); });
     }
-  }
-  g_pools.setState(localPools);
+    g_pools.setState(localPools);
 
-  if(g_dstates.getLocal()->empty()) {
-    errlog("No downstream servers defined: all packets will get dropped");
-    // you might define them later, but you need to know
-  }
+    if(g_dstates.getLocal()->empty()) {
+      errlog("No downstream servers defined: all packets will get dropped");
+      // you might define them later, but you need to know
+    }
 
-  checkFileDescriptorsLimits(udpBindsCount, tcpBindsCount);
+    checkFileDescriptorsLimits(udpBindsCount, tcpBindsCount);
 
-  auto mplexer = std::shared_ptr<FDMultiplexer>(FDMultiplexer::getMultiplexerSilent());
-  for(auto& dss : g_dstates.getCopy()) { // it is a copy, but the internal shared_ptrs are the real deal
-    if (dss->availability == DownstreamState::Availability::Auto) {
-      if (!queueHealthCheck(mplexer, dss, true)) {
-        dss->upStatus = false;
-        warnlog("Marking downstream %s as 'down'", dss->getNameWithAddr());
+    auto mplexer = std::shared_ptr<FDMultiplexer>(FDMultiplexer::getMultiplexerSilent());
+    for(auto& dss : g_dstates.getCopy()) { // it is a copy, but the internal shared_ptrs are the real deal
+      if (dss->availability == DownstreamState::Availability::Auto) {
+        if (!queueHealthCheck(mplexer, dss, true)) {
+          dss->upStatus = false;
+          warnlog("Marking downstream %s as 'down'", dss->getNameWithAddr());
+        }
       }
     }
-  }
-  handleQueuedHealthChecks(mplexer, true);
+    handleQueuedHealthChecks(mplexer, true);
 
-  for(auto& cs : g_frontends) {
-    if (cs->dohFrontend != nullptr) {
+    for(auto& cs : g_frontends) {
+      if (cs->dohFrontend != nullptr) {
 #ifdef HAVE_DNS_OVER_HTTPS
-      std::thread t1(dohThread, cs.get());
-      if (!cs->cpus.empty()) {
-        mapThreadToCPUList(t1.native_handle(), cs->cpus);
-      }
-      t1.detach();
+        std::thread t1(dohThread, cs.get());
+        if (!cs->cpus.empty()) {
+          mapThreadToCPUList(t1.native_handle(), cs->cpus);
+        }
+        t1.detach();
 #endif /* HAVE_DNS_OVER_HTTPS */
-      continue;
-    }
-    if (cs->udpFD >= 0) {
-      thread t1(udpClientThread, cs.get());
-      if (!cs->cpus.empty()) {
-        mapThreadToCPUList(t1.native_handle(), cs->cpus);
+        continue;
       }
-      t1.detach();
-    }
-    else if (cs->tcpFD >= 0) {
-      thread t1(tcpAcceptorThread, cs.get());
-      if (!cs->cpus.empty()) {
-        mapThreadToCPUList(t1.native_handle(), cs->cpus);
+      if (cs->udpFD >= 0) {
+        thread t1(udpClientThread, cs.get());
+        if (!cs->cpus.empty()) {
+          mapThreadToCPUList(t1.native_handle(), cs->cpus);
+        }
+        t1.detach();
+      }
+      else if (cs->tcpFD >= 0) {
+        thread t1(tcpAcceptorThread, cs.get());
+        if (!cs->cpus.empty()) {
+          mapThreadToCPUList(t1.native_handle(), cs->cpus);
+        }
+        t1.detach();
       }
-      t1.detach();
     }
-  }
 
-  thread carbonthread(carbonDumpThread);
-  carbonthread.detach();
+    thread carbonthread(carbonDumpThread);
+    carbonthread.detach();
 
-  thread stattid(maintThread);
-  stattid.detach();
+    thread stattid(maintThread);
+    stattid.detach();
   
-  thread healththread(healthChecksThread);
+    thread healththread(healthChecksThread);
 
-  thread dynBlockMaintThread(dynBlockMaintenanceThread);
-  dynBlockMaintThread.detach();
+    thread dynBlockMaintThread(dynBlockMaintenanceThread);
+    dynBlockMaintThread.detach();
 
-  if (!g_secPollSuffix.empty()) {
-    thread secpollthread(secPollThread);
-    secpollthread.detach();
-  }
+    if (!g_secPollSuffix.empty()) {
+      thread secpollthread(secPollThread);
+      secpollthread.detach();
+    }
 
-  if(g_cmdLine.beSupervised) {
+    if(g_cmdLine.beSupervised) {
 #ifdef HAVE_SYSTEMD
-    sd_notify(0, "READY=1");
+      sd_notify(0, "READY=1");
 #endif
-    healththread.join();
+      healththread.join();
+    }
+    else {
+      healththread.detach();
+      doConsole();
+    }
+    _exit(EXIT_SUCCESS);
+
   }
-  else {
-    healththread.detach();
-    doConsole();
+  catch (const LuaContext::ExecutionErrorException& e) {
+    try {
+      errlog("Fatal Lua error: %s", e.what());
+      std::rethrow_if_nested(e);
+    } catch(const std::exception& ne) {
+      errlog("Details: %s", ne.what());
+    }
+    catch (const PDNSException &ae)
+    {
+      errlog("Fatal pdns error: %s", ae.reason);
+    }
+    _exit(EXIT_FAILURE);
   }
-  _exit(EXIT_SUCCESS);
-
-}
-catch(const LuaContext::ExecutionErrorException& e) {
-  try {
-    errlog("Fatal Lua error: %s", e.what());
-    std::rethrow_if_nested(e);
-  } catch(const std::exception& ne) {
-    errlog("Details: %s", ne.what());
+  catch (const std::exception &e)
+  {
+    errlog("Fatal error: %s", e.what());
+    _exit(EXIT_FAILURE);
   }
-  catch(PDNSException &ae)
+  catch (const PDNSException &ae)
   {
     errlog("Fatal pdns error: %s", ae.reason);
+    _exit(EXIT_FAILURE);
   }
-  _exit(EXIT_FAILURE);
-}
-catch(std::exception &e)
-{
-  errlog("Fatal error: %s", e.what());
-  _exit(EXIT_FAILURE);
-}
-catch(PDNSException &ae)
-{
-  errlog("Fatal pdns error: %s", ae.reason);
-  _exit(EXIT_FAILURE);
 }
 
 uint64_t getLatencyCount(const std::string&)
index 60c8487b96facb63b0a5ff355406b59fe1d80310..b1a0c4c02759d08c9d01deba801643dc6e5a39b1 100644 (file)
@@ -775,156 +775,157 @@ static void processForwardedForHeader(const h2o_req_t* req, ComboAddress& remote
   For POST, the payload is the payload.
  */
 static int doh_handler(h2o_handler_t *self, h2o_req_t *req)
-try
 {
-  if (!req->conn->ctx->storage.size) {
-    return 0; // although we might was well crash on this
-  }
-  h2o_socket_t* sock = req->conn->callbacks->get_socket(req->conn);
-  ComboAddress remote;
-  ComboAddress local;
+  try {
+    if (!req->conn->ctx->storage.size) {
+      return 0; // although we might was well crash on this
+    }
+    h2o_socket_t* sock = req->conn->callbacks->get_socket(req->conn);
+    ComboAddress remote;
+    ComboAddress local;
 
-  if (h2o_socket_getpeername(sock, reinterpret_cast<struct sockaddr*>(&remote)) == 0) {
-    /* getpeername failed, likely because the connection has already been closed,
-       but anyway that means we can't get the remote address, which could allow an ACL bypass */
-    h2o_send_error_500(req, getReasonFromStatusCode(500).c_str(), "Internal Server Error - Unable to get remote address", 0);
-    return 0;
-  }
+    if (h2o_socket_getpeername(sock, reinterpret_cast<struct sockaddr*>(&remote)) == 0) {
+      /* getpeername failed, likely because the connection has already been closed,
+         but anyway that means we can't get the remote address, which could allow an ACL bypass */
+      h2o_send_error_500(req, getReasonFromStatusCode(500).c_str(), "Internal Server Error - Unable to get remote address", 0);
+      return 0;
+    }
 
-  h2o_socket_getsockname(sock, reinterpret_cast<struct sockaddr*>(&local));
-  DOHServerConfig* dsc = reinterpret_cast<DOHServerConfig*>(req->conn->ctx->storage.entries[0].data);
+    h2o_socket_getsockname(sock, reinterpret_cast<struct sockaddr*>(&local));
+    DOHServerConfig* dsc = reinterpret_cast<DOHServerConfig*>(req->conn->ctx->storage.entries[0].data);
 
-  if (dsc->df->d_trustForwardedForHeader) {
-    processForwardedForHeader(req, remote);
-  }
+    if (dsc->df->d_trustForwardedForHeader) {
+      processForwardedForHeader(req, remote);
+    }
 
-  auto& holders = dsc->holders;
-  if (!holders.acl->match(remote)) {
-    ++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);
-    return 0;
-  }
+    auto& holders = dsc->holders;
+    if (!holders.acl->match(remote)) {
+      ++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);
+      return 0;
+    }
 
-  if (h2o_socket_get_ssl_session_reused(sock) == 0) {
-    ++dsc->cs->tlsNewSessions;
-  }
-  else {
-    ++dsc->cs->tlsResumptions;
-  }
+    if (h2o_socket_get_ssl_session_reused(sock) == 0) {
+      ++dsc->cs->tlsNewSessions;
+    }
+    else {
+      ++dsc->cs->tlsResumptions;
+    }
 
-  const int descriptor = h2o_socket_get_fd(sock);
-  if (descriptor != -1) {
-    ++t_conns.at(descriptor).d_nbQueries;
-  }
-
-  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;
-  }
-
-  // would be nice to be able to use a pdns_string_view there, but we would need heterogeneous lookups
-  // (having string in the set and compare them to string_view, for example. Note that comparing
-  // two boost::string_view uses the pointer, not the content).
-  const std::string 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);
-    return 0;
-  }
+    const int descriptor = h2o_socket_get_fd(sock);
+    if (descriptor != -1) {
+      ++t_conns.at(descriptor).d_nbQueries;
+    }
 
-  // would be nice to be able to use a pdns_string_view there,
-  // but regex (called by matches() internally) requires a null-terminated string
-  string path(req->path.base, req->path.len);
-  for (const auto& entry : dsc->df->d_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);
+    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;
+    }
+
+    // would be nice to be able to use a pdns_string_view there, but we would need heterogeneous lookups
+    // (having string in the set and compare them to string_view, for example. Note that comparing
+    // two boost::string_view uses the pointer, not the content).
+    const std::string 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);
       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;
-
-    PacketBuffer query;
-    /* We reserve at least 512 additional bytes to be able to add EDNS, but we also want
-       at least s_maxPacketCacheEntrySize bytes to be able to fill the answer from the packet cache */
-    query.reserve(std::max(req->entity.len + 512, s_maxPacketCacheEntrySize));
-    query.resize(req->entity.len);
-    memcpy(query.data(), req->entity.base, req->entity.len);
-    doh_dispatch_query(dsc, self, req, std::move(query), local, remote, std::move(path));
-  }
-  else if(req->query_at != SIZE_MAX && (req->path.len - req->query_at > 5)) {
-    auto pos = path.find("?dns=");
-    if(pos == string::npos)
-      pos = path.find("&dns=");
-    if(pos != string::npos) {
-      // 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;
+    // would be nice to be able to use a pdns_string_view there,
+    // but regex (called by matches() internally) requires a null-terminated string
+    string path(req->path.base, req->path.len);
+    for (const auto& entry : dsc->df->d_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);
+        return 0;
       }
+    }
 
-      PacketBuffer decoded;
+    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;
 
-      /* rough estimate so we hopefully don't need a new allocation later */
+      PacketBuffer query;
       /* We reserve at least 512 additional bytes to be able to add EDNS, but we also want
          at least s_maxPacketCacheEntrySize bytes to be able to fill the answer from the packet cache */
-      const size_t estimate = ((sdns.size() * 3) / 4);
-      decoded.reserve(std::max(estimate + 512, s_maxPacketCacheEntrySize));
-      if(B64Decode(sdns, decoded) < 0) {
-        h2o_send_error_400(req, "Bad Request", "Unable to decode BASE64-URL", 0);
+      query.reserve(std::max(req->entity.len + 512, s_maxPacketCacheEntrySize));
+      query.resize(req->entity.len);
+      memcpy(query.data(), req->entity.base, req->entity.len);
+      doh_dispatch_query(dsc, self, req, std::move(query), local, remote, std::move(path));
+    }
+    else if(req->query_at != SIZE_MAX && (req->path.len - req->query_at > 5)) {
+      auto pos = path.find("?dns=");
+      if(pos == string::npos)
+        pos = path.find("&dns=");
+      if(pos != string::npos) {
+        // 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 least 512 additional bytes to be able to add EDNS, but we also want
+           at least s_maxPacketCacheEntrySize bytes to be able to fill the answer from the packet cache */
+        const size_t estimate = ((sdns.size() * 3) / 4);
+        decoded.reserve(std::max(estimate + 512, s_maxPacketCacheEntrySize));
+        if(B64Decode(sdns, decoded) < 0) {
+          h2o_send_error_400(req, "Bad Request", "Unable to decode BASE64-URL", 0);
+          ++dsc->df->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), 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;
         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), 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);
+    else {
+      h2o_send_error_400(req, "Bad Request", "Unable to parse the request", 0);
       ++dsc->df->d_badrequests;
-      return 0;
     }
+    return 0;
   }
-  else {
-    h2o_send_error_400(req, "Bad Request", "Unable to parse the request", 0);
-    ++dsc->df->d_badrequests;
+  catch(const std::exception& e)
+  {
+    errlog("DOH Handler function failed with error %s", e.what());
+    return 0;
   }
-  return 0;
-}
- catch(const std::exception& e)
-{
-  errlog("DOH Handler function failed with error %s", e.what());
-  return 0;
 }
 
 HTTPHeaderRule::HTTPHeaderRule(const std::string& header, const std::string& regex)
@@ -1391,65 +1392,66 @@ static h2o_pathconf_t *register_handler(h2o_hostconf_t *hostconf, const char *pa
 
 // this is the entrypoint from dnsdist.cc
 void dohThread(ClientState* cs)
-try
 {
-  std::shared_ptr<DOHFrontend>& df = cs->dohFrontend;
-  auto& dsc = df->d_dsc;
-  dsc->cs = cs;
-  dsc->df = cs->dohFrontend;
-  dsc->h2o_config.server_name = h2o_iovec_init(df->d_serverTokens.c_str(), df->d_serverTokens.size());
+  try {
+    std::shared_ptr<DOHFrontend>& df = cs->dohFrontend;
+    auto& dsc = df->d_dsc;
+    dsc->cs = cs;
+    dsc->df = cs->dohFrontend;
+    dsc->h2o_config.server_name = h2o_iovec_init(df->d_serverTokens.c_str(), df->d_serverTokens.size());
 
 
-  std::thread dnsdistThread(dnsdistclient, dsc->dohquerypair[1]);
-  dnsdistThread.detach(); // gets us better error reporting
+    std::thread dnsdistThread(dnsdistclient, dsc->dohquerypair[1]);
+    dnsdistThread.detach(); // gets us better error reporting
 
-  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);
+    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);
 
-  for(const auto& url : df->d_urls) {
-    register_handler(hostconf, url.c_str(), doh_handler);
-    dsc->paths.insert(url);
-  }
+    for(const auto& url : df->d_urls) {
+      register_handler(hostconf, url.c_str(), doh_handler);
+      dsc->paths.insert(url);
+    }
 
-  h2o_context_init(&dsc->h2o_ctx, h2o_evloop_create(), &dsc->h2o_config);
+    h2o_context_init(&dsc->h2o_ctx, h2o_evloop_create(), &dsc->h2o_config);
 
-  // in this complicated way we insert the DOHServerConfig pointer in there
-  h2o_vector_reserve(nullptr, &dsc->h2o_ctx.storage, 1);
-  dsc->h2o_ctx.storage.entries[0].data = dsc.get();
-  ++dsc->h2o_ctx.storage.size;
+    // in this complicated way we insert the DOHServerConfig pointer in there
+    h2o_vector_reserve(nullptr, &dsc->h2o_ctx.storage, 1);
+    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);
-  sock->data = dsc.get();
+    auto sock = h2o_evloop_socket_create(dsc->h2o_ctx.loop, dsc->dohresponsepair[1], H2O_SOCKET_FLAG_DONT_READ);
+    sock->data = dsc.get();
 
-  // this listens to responses from dnsdist to turn into http responses
-  h2o_socket_read_start(sock, on_dnsdist);
+    // this listens to responses from dnsdist to turn into http responses
+    h2o_socket_read_start(sock, on_dnsdist);
 
-  setupAcceptContext(*dsc->accept_ctx, *dsc, false);
+    setupAcceptContext(*dsc->accept_ctx, *dsc, false);
 
-  if (create_listener(df->d_local, dsc, cs->tcpFD) != 0) {
-    throw std::runtime_error("DOH server failed to listen on " + df->d_local.toStringWithPort() + ": " + strerror(errno));
-  }
+    if (create_listener(df->d_local, dsc, cs->tcpFD) != 0) {
+      throw std::runtime_error("DOH server failed to listen on " + df->d_local.toStringWithPort() + ": " + strerror(errno));
+    }
 
-  bool stop = false;
-  do {
-    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));
-        stop = true;
+    bool stop = false;
+    do {
+      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));
+          stop = true;
+        }
       }
     }
-  }
-  while (stop == false);
+    while (stop == false);
 
-}
-catch(const std::exception& e) {
-  throw runtime_error("DOH thread failed to launch: " + std::string(e.what()));
-}
-catch(...) {
-  throw runtime_error("DOH thread failed to launch");
+  }
+  catch (const std::exception& e) {
+    throw runtime_error("DOH thread failed to launch: " + std::string(e.what()));
+  }
+  catch (...) {
+    throw runtime_error("DOH thread failed to launch");
+  }
 }
 
 #else /* HAVE_DNS_OVER_HTTPS */
index f8755b4934dd3a13f4856bdf8d09f474d7a664c8..808872761ddb64699610dbbc008269308e170c8c 100644 (file)
@@ -516,23 +516,24 @@ string PacketReader::getUnquotedText(bool lenField)
 }
 
 void PacketReader::xfrBlob(string& blob)
-try
 {
-  if(d_recordlen && !(d_pos == (d_startrecordpos + d_recordlen))) {
-    if (d_pos > (d_startrecordpos + d_recordlen)) {
-      throw std::out_of_range("xfrBlob out of record range");
+  try {
+    if(d_recordlen && !(d_pos == (d_startrecordpos + d_recordlen))) {
+      if (d_pos > (d_startrecordpos + d_recordlen)) {
+        throw std::out_of_range("xfrBlob out of record range");
+      }
+      blob.assign(&d_content.at(d_pos), &d_content.at(d_startrecordpos + d_recordlen - 1 ) + 1);
+    }
+    else {
+      blob.clear();
     }
-    blob.assign(&d_content.at(d_pos), &d_content.at(d_startrecordpos + d_recordlen - 1 ) + 1);
+
+    d_pos = d_startrecordpos + d_recordlen;
   }
-  else {
-    blob.clear();
+  catch(...)
+  {
+    throw std::out_of_range("xfrBlob out of range");
   }
-
-  d_pos = d_startrecordpos + d_recordlen;
-}
-catch(...)
-{
-  throw std::out_of_range("xfrBlob out of range");
 }
 
 void PacketReader::xfrBlobNoSpaces(string& blob, int length) {
index 081610523809c3562c4fac5b58fbf29101378881..f5d9e47a4e7e1f8737150bc012aa3c0858b66c04 100644 (file)
@@ -173,62 +173,63 @@ void RemoteLogger::queueData(const std::string& data)
   ++d_queued;
 }
 
-void RemoteLogger::maintenanceThread()
-try
+void RemoteLogger::maintenanceThread() 
 {
+  try {
 #ifdef WE_ARE_RECURSOR
-  string threadName = "pdns-r/remLog";
+    string threadName = "pdns-r/remLog";
 #else
-  string threadName = "dnsdist/remLog";
+    string threadName = "dnsdist/remLog";
 #endif
-  setThreadName(threadName);
+    setThreadName(threadName);
 
-  for (;;) {
-    if (d_exiting) {
-      break;
-    }
+    for (;;) {
+      if (d_exiting) {
+        break;
+      }
 
-    bool connected = true;
-    if (d_socket == nullptr) {
-      // if it was unset, it will remain so, we are the only ones setting it!
-      connected = reconnect();
-    }
+      bool connected = true;
+      if (d_socket == nullptr) {
+        // if it was unset, it will remain so, we are the only ones setting it!
+        connected = reconnect();
+      }
 
-    /* we will just go to sleep if the reconnection just failed */
-    if (connected) {
-      try {
-        /* we don't want to take the lock while trying to reconnect */
-        std::lock_guard<std::mutex> lock(d_mutex);
-        if (d_socket) { // check if it is set
-          /* if flush() returns false, it means that we couldn't flush anything yet
-             either because there is nothing to flush, or because the outgoing TCP
-             buffer is full. That's fine by us */
-          d_writer.flush(d_socket->getHandle());
+      /* we will just go to sleep if the reconnection just failed */
+      if (connected) {
+        try {
+          /* we don't want to take the lock while trying to reconnect */
+          std::lock_guard<std::mutex> lock(d_mutex);
+          if (d_socket) { // check if it is set
+            /* if flush() returns false, it means that we couldn't flush anything yet
+               either because there is nothing to flush, or because the outgoing TCP
+               buffer is full. That's fine by us */
+            d_writer.flush(d_socket->getHandle());
+          }
+          else {
+            connected = false;
+          }
         }
-        else {
+        catch(const std::exception& e) {
+          d_socket.reset();
           connected = false;
         }
-      }
-      catch(const std::exception& e) {
-        d_socket.reset();
-        connected = false;
-      }
 
-      if (!connected) {
-        /* let's try to reconnect right away, we are about to sleep anyway */
-        reconnect();
+        if (!connected) {
+          /* let's try to reconnect right away, we are about to sleep anyway */
+          reconnect();
+        }
       }
-    }
 
-    sleep(d_reconnectWaitTime);
+      sleep(d_reconnectWaitTime);
+    }
+  }
+  catch (const std::exception& e)
+  {
+    cerr << "Remote Logger's maintenance thead died on: " << e.what() << endl;
+  }
+  catch (...) {
+    cerr << "Remote Logger's maintenance thead died on unknown exception" << endl;
   }
-}
-catch(const std::exception& e)
-{
-  cerr << "Remote Logger's maintenance thead died on: " << e.what() << endl;
-}
-catch(...) {
-  cerr << "Remote Logger's maintenance thead died on unknown exception" << endl;
 }
 
 RemoteLogger::~RemoteLogger()