]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Use a string instead of a fixed 65k buffer for TCP connections
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 20 Jul 2018 13:15:15 +0000 (15:15 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 6 Aug 2018 08:00:22 +0000 (10:00 +0200)
pdns/pdns_recursor.cc
pdns/syncres.hh

index 3f8a29f33584b3aa62a76fdbe89f8bc2616addef..e6ac33fc06976fee8822247b4bb8ed30ecd03ae2 100644 (file)
@@ -234,8 +234,9 @@ bool g_logRPZChanges{false};
 
 //! used to send information to a newborn mthread
 struct DNSComboWriter {
-  DNSComboWriter(const char* data, uint16_t len, const struct timeval& now): d_mdp(true, data, len), d_now(now)
-  {}
+  DNSComboWriter(const std::string& query, const struct timeval& now): d_mdp(true, query.c_str(), query.size()), d_now(now)
+  {
+  }
 
   DNSComboWriter(const std::string& query, const struct timeval& now, std::vector<std::string>&& policyTags, LuaContext::LuaObject&& data): d_mdp(true, query.c_str(), query.size()), d_now(now), d_policyTags(std::move(policyTags)), d_data(std::move(data))
   {
@@ -705,7 +706,7 @@ static void writePid(void)
     g_log<<Logger::Error<<"Writing pid for "<<Utility::getpid()<<" to "<<s_pidfname<<" failed: "<<strerror(errno)<<endl;
 }
 
-TCPConnection::TCPConnection(int fd, const ComboAddress& addr) : d_remote(addr), d_fd(fd)
+TCPConnection::TCPConnection(int fd, const ComboAddress& addr) : data(2, 0), d_remote(addr), d_fd(fd)
 {
   ++s_currentConnections;
   (*t_tcpClientCounts)[d_remote]++;
@@ -1697,11 +1698,12 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var)
   shared_ptr<TCPConnection> conn=any_cast<shared_ptr<TCPConnection> >(var);
 
   if(conn->state==TCPConnection::BYTE0) {
-    ssize_t bytes=recv(conn->getFD(), conn->data, 2, 0);
+    ssize_t bytes=recv(conn->getFD(), &conn->data[0], 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);
       conn->bytesread=0;
       conn->state=TCPConnection::GETQUESTION;
     }
@@ -1711,10 +1713,11 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var)
     }
   }
   else if(conn->state==TCPConnection::BYTE1) {
-    ssize_t bytes=recv(conn->getFD(), conn->data+1, 1, 0);
+    ssize_t bytes=recv(conn->getFD(), &conn->data[1], 1, 0);
     if(bytes==1) {
       conn->state=TCPConnection::GETQUESTION;
       conn->qlen=(((unsigned char)conn->data[0]) << 8)+ (unsigned char)conn->data[1];
+      conn->data.resize(conn->qlen);
       conn->bytesread=0;
     }
     if(!bytes || bytes < 0) {
@@ -1725,7 +1728,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var)
     }
   }
   else if(conn->state==TCPConnection::GETQUESTION) {
-    ssize_t bytes=recv(conn->getFD(), conn->data + conn->bytesread, conn->qlen - conn->bytesread, 0);
+    ssize_t bytes=recv(conn->getFD(), &conn->data[conn->bytesread], conn->qlen - conn->bytesread, 0);
     if(!bytes || bytes < 0 || bytes > std::numeric_limits<std::uint16_t>::max()) {
       g_log<<Logger::Error<<"TCP client "<< conn->d_remote.toStringWithPort() <<" disconnected while reading question body"<<endl;
       t_fdm->removeReadFD(fd);
@@ -1737,7 +1740,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var)
 
       DNSComboWriter* dc=nullptr;
       try {
-        dc=new DNSComboWriter(conn->data, conn->qlen, g_now);
+        dc=new DNSComboWriter(conn->data, g_now);
       }
       catch(MOADNSException &mde) {
         g_stats.clientParseError++;
@@ -1779,7 +1782,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var)
           bool xpfFound = false;
           dc->d_ecsParsed = true;
           dc->d_ecsFound = false;
-          getQNameAndSubnet(std::string(conn->data, conn->qlen), &qname, &qtype, &qclass,
+          getQNameAndSubnet(conn->data, &qname, &qtype, &qclass,
                             dc->d_ecsFound, &dc->d_ednssubnet, g_gettagNeedsEDNSOptions ? &ednsOptions : nullptr,
                             xpfFound, needXPF ? &dc->d_source : nullptr, needXPF ? &dc->d_destination : nullptr);
 
@@ -1813,7 +1816,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var)
 
       if(t_protobufServer) {
         try {
-          const struct dnsheader* dh = (const struct dnsheader*) conn->data;
+          const struct dnsheader* dh = reinterpret_cast<const struct dnsheader*>(&conn->data[0]);
 
           if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && dc->d_policyTags.empty())) {
             protobufLogQuery(t_protobufServer, luaconfsLocal->protobufMaskV4, luaconfsLocal->protobufMaskV6, dc->d_uuid, dc->d_source, dc->d_destination, dc->d_ednssubnet.source, true, dh->id, conn->qlen, qname, qtype, qclass, dc->d_policyTags, dc->d_requestorId, dc->d_deviceId);
index cfd5c4314abba0d8730b3f0d38f9b2aee5557b26..3fc515d79c66a809fd60698f3111ecec7cd5583b 100644 (file)
@@ -940,12 +940,13 @@ public:
   {
     return d_fd;
   }
+
+  std::string data;
+  const ComboAddress d_remote;
+  size_t queriesCount{0};
   enum stateenum {BYTE0, BYTE1, GETQUESTION, DONE} state{BYTE0};
   uint16_t qlen{0};
   uint16_t bytesread{0};
-  const ComboAddress d_remote;
-  char data[65535]; // damn
-  size_t queriesCount{0};
 
   static unsigned int getCurrentConnections() { return s_currentConnections; }
 private: