Your message dated Mon, 20 Jul 2009 16:23:25 +0200
with message-id <[email protected]>
and subject line Re: UI-Patch: Please add support for maximum TCP request time
has caused the Debian Bug report #510865,
regarding UI-Patch: Please add support for maximum TCP request time
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
510865: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=510865
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: pdns
Severity: wishlist
Tags: patch

Hi pdns maintainers,

the attached dpatch

## DP: Adds support for maximum TCP request time (command line arg).

is used here (UI) to improve pdns. It applies cleanly to 2.9.21.2-1
after the existing dpatches.

We would be enlightened if you could review it and eventually consider 
adding it to the Debian package.      

Thanks!

Stephan

-- System Information:
Debian Release: 5.0
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.26-1-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
#! /bin/sh /usr/share/dpatch/dpatch-run
## ui-20_max-tcp-request-time.dpatch by Stephan Suerken <[email protected]>
##
## All lines beginning with `## DP:' are a description of the patch.
##
## DP: Adds support for maximum TCP request time (command line arg).

@DPATCH@
diff -urNad trunk~/pdns/common_startup.cc trunk/pdns/common_startup.cc
--- trunk~/pdns/common_startup.cc	2009-01-05 13:14:42.000000000 +0000
+++ trunk/pdns/common_startup.cc	2009-01-05 13:14:42.000000000 +0000
@@ -111,6 +111,7 @@
   arg().set("soa-expire-default","Default SOA expire")="604800";
 
   arg().set("default-ttl","Seconds a result is valid if not set otherwise")="3600";
+  arg().set("max-tcp-request-time","Maximum number of seconds a TCP client may take completing a request")="120";
   arg().set("max-tcp-connections","Maximum number of TCP connections")="10";
   arg().set("tcp-idle-timeout","Number of seconds a TCP client can be idle during a request")="10";
   arg().setSwitch("no-shuffle","Set this to prevent random shuffling of answers - for regression testing")="off";
diff -urNad trunk~/pdns/misc.cc trunk/pdns/misc.cc
--- trunk~/pdns/misc.cc	2009-01-05 13:14:42.000000000 +0000
+++ trunk/pdns/misc.cc	2009-01-05 13:14:42.000000000 +0000
@@ -597,3 +597,23 @@
 
   return dom.substr(0,dom.size()-1);
 }
+
+void addTimeval(struct timeval & tv, const struct timeval & add)
+{
+  tv.tv_usec += add.tv_usec;
+  if (tv.tv_usec >= 1000000) {
+    tv.tv_usec -= 1000000;
+    ++tv.tv_sec;
+  }
+  tv.tv_sec += add.tv_sec;
+}
+
+void subTimeval(struct timeval & tv, const struct timeval & sub)
+{
+  if (tv.tv_usec < sub.tv_usec) {
+    tv.tv_usec += 1000000;
+    --tv.tv_sec;
+  }
+  tv.tv_usec -= sub.tv_usec;
+  tv.tv_sec -= sub.tv_sec;
+}
diff -urNad trunk~/pdns/misc.hh trunk/pdns/misc.hh
--- trunk~/pdns/misc.hh	2009-01-05 13:14:42.000000000 +0000
+++ trunk/pdns/misc.hh	2009-01-05 13:14:42.000000000 +0000
@@ -91,6 +91,18 @@
 uint32_t getLong(const unsigned char *p);
 uint32_t getLong(const char *p);
 boost::optional<int> logFacilityToLOG(unsigned int facility);
+void addTimeval(struct timeval & tv, const struct timeval & add);
+void subTimeval(struct timeval & tv, const struct timeval & sub);
+
+inline bool timevalZero(const struct timeval & tv)
+{
+  return (tv.tv_sec<0 || (tv.tv_sec==0 && tv.tv_usec==0));
+}
+
+inline int waitForData(int fd, const struct timeval & tv)
+{
+   return waitForData(fd, tv.tv_sec, tv.tv_usec);
+}
 
 inline void putLong(unsigned char* p, uint32_t val)
 {
diff -urNad trunk~/pdns/pdns.conf-dist trunk/pdns/pdns.conf-dist
--- trunk~/pdns/pdns.conf-dist	2009-01-05 13:14:42.000000000 +0000
+++ trunk/pdns/pdns.conf-dist	2009-01-05 13:14:42.000000000 +0000
@@ -334,4 +334,8 @@
 #
 # wildcards=
 
+#################################
+# max-tcp-request-time Maximum number of seconds a TCP client may take completing a request
+#
+# max-tcp-request-time=120
 
diff -urNad trunk~/pdns/resolver.cc trunk/pdns/resolver.cc
--- trunk~/pdns/resolver.cc	2009-01-05 13:14:42.000000000 +0000
+++ trunk/pdns/resolver.cc	2009-01-05 13:14:42.000000000 +0000
@@ -111,30 +111,6 @@
   }
 }
 
-char* Resolver::sendReceive(const string &ip, uint16_t remotePort, const char *packet, int length, unsigned int *replen)
-{
-  makeTCPSocket(ip, remotePort);
-
-  if(sendData(packet,length,d_sock)<0) 
-    throw ResolverException("Unable to send packet to remote nameserver "+ip+": "+stringerror());
-
-  int plen=getLength();
-  if(plen<0)
-    throw ResolverException("EOF trying to get length of answer from remote TCP server");
-
-  char *answer=new char[plen];
-  try {
-    timeoutReadn(answer,plen);
-    *replen=plen;
-    return answer;
-  }
-  catch(...) {
-    delete answer;
-    throw; // whop!
-  }
-  return 0;
-}
-
 int Resolver::notify(int sock, const string &domain, const string &ip, uint16_t id)
 {
   vector<uint8_t> packet;
@@ -337,15 +313,21 @@
   return 1;
 }
 
-int Resolver::getLength()
+int Resolver::getLength(struct timeval &req_time)
 {
   int bytesLeft=2;
   unsigned char buf[2];
   
   while(bytesLeft) {
+    // FIXED, check for expired request time 
+    if(timevalZero(req_time))
+      throw ResolverException("Closing connection to remote TCP client max. request time reached");
+    // FIXED, decrease request time
+    struct timeval tv={10,0};
+    subTimeval(req_time, tv);
     // FIXED, select timeout was not handled
     int ret=0;
-    if(waitForData(d_sock, 10)<1) {
+    if(waitForData(d_sock, tv)<1) {
       Utility::closesocket(d_sock);
       d_sock=-1;
       throw ResolverException("Waiting on data from remote TCP client: "+stringerror());
@@ -357,6 +339,8 @@
     if(!ret) 
       return -1;
     
+    // FIXED, increase request time again 
+    addTimeval(req_time, tv);
     bytesLeft-=ret;
   }
   return buf[0]*256+buf[1];
@@ -371,7 +355,9 @@
   }
 
   // d_sock is connected and is about to spit out a packet
-  int len=getLength();
+  // FIXED, get and pass max request time 
+  struct timeval time_left={arg().asNum("max-tcp-request-time"),0};
+  int len=getLength(time_left);
   if(len<0)
     throw ResolverException("EOF trying to read axfr chunk from remote TCP client");
   
diff -urNad trunk~/pdns/resolver.hh trunk/pdns/resolver.hh
--- trunk~/pdns/resolver.hh	2007-04-21 13:56:36.000000000 +0000
+++ trunk/pdns/resolver.hh	2009-01-05 13:14:42.000000000 +0000
@@ -60,7 +60,6 @@
   void sendResolve(const string &ip, const char *domain, int type);
 
   int receiveResolve(struct sockaddr* fromaddr, Utility::socklen_t addrlen);
-  char* sendReceive(const string &ip, uint16_t remotePort, const char *packet, int length, unsigned int *replylen);
   void getSoaSerial(const string &, const string &, uint32_t *);
   int axfrChunk(Resolver::res_t &res);
   vector<DNSResourceRecord> result();
@@ -72,7 +71,7 @@
   void timeoutReadn(char *buffer, int bytes);
   int d_sock;
   unsigned char *d_buf;
-  int getLength();
+  int getLength(struct timeval &req_time);
   int d_len;
   int d_soacount;
   string d_domain;
diff -urNad trunk~/pdns/tcpreceiver.cc trunk/pdns/tcpreceiver.cc
--- trunk~/pdns/tcpreceiver.cc	2009-01-05 13:14:42.000000000 +0000
+++ trunk/pdns/tcpreceiver.cc	2009-01-05 13:14:42.000000000 +0000
@@ -76,16 +76,22 @@
 }
 
 // throws AhuException if things didn't go according to plan, returns 0 if really 0 bytes were read
-int readnWithTimeout(int fd, void* buffer, unsigned int n, bool throwOnEOF=true)
+int readnWithTimeout(int fd, void* buffer, unsigned int n, struct timeval &req_time, bool throwOnEOF=true)
 {
   unsigned int bytes=n;
   char *ptr = (char*)buffer;
   int ret;
   while(bytes) {
+    // FIXED, check for expired request time 
+    if(timevalZero(req_time))
+      throw AhuException("Closing connection to remote TCP client. Maximum request time reached");
+    // FIXED, decrease request time
+    struct timeval tv={5,0};
+    subTimeval(req_time, tv);
     ret=read(fd, ptr, bytes);
     if(ret < 0) {
       if(errno==EAGAIN) {
-	ret=waitForData(fd, 5);
+	ret=waitForData(fd, tv);
 	if(ret < 0)
 	  throw AhuException("Waiting for data read");
 	if(!ret)
@@ -102,6 +108,8 @@
 	throw AhuException("Did not fulfill read from TCP due to EOF");
     }
     
+    // FIXED, increase request time again 
+    addTimeval(req_time, tv);
     ptr += ret;
     bytes -= ret;
   }
@@ -177,16 +185,16 @@
 }
 
 
-void TCPNameserver::getQuestion(int fd, char *mesg, int pktlen, const ComboAddress &remote)
+void TCPNameserver::getQuestion(int fd, char *mesg, int pktlen, const ComboAddress& remote, struct timeval &req_time)
 try
 {
-  readnWithTimeout(fd, mesg, pktlen);
+  readnWithTimeout(fd, mesg, pktlen, req_time);
 }
 catch(AhuException& ae) {
     throw AhuException("Error reading DNS data from TCP client "+remote.toString()+": "+ae.reason);
 }
 
-static void proxyQuestion(shared_ptr<DNSPacket> packet)
+static void proxyQuestion(shared_ptr<DNSPacket> packet, struct timeval &req_time)
 {
   int sock=socket(AF_INET, SOCK_STREAM, 0);
   if(sock < 0)
@@ -209,11 +217,13 @@
     
     int ret;
     
-    ret=readnWithTimeout(sock, &len, 2);
+  // FIXED, pass max request time to readnWithTimeout call
+  ret=readnWithTimeout(sock, &len, 2, req_time);
     len=ntohs(len);
 
     char answer[len];
-    ret=readnWithTimeout(sock, answer, len);
+  // FIXED, pass max request time to readnWithTimeout call
+  ret=readnWithTimeout(sock, answer, len, req_time);
 
     slen=htons(len);
     writenWithTimeout(packet->getSocket(), &slen, 2);
@@ -241,6 +251,8 @@
     DLOG(L<<"TCP Connection accepted on fd "<<fd<<endl);
     
     for(;;) {
+      // FIXED, getting max request value
+      struct timeval time_left={arg().asNum("max-tcp-request-time"),0};
       ComboAddress remote;
       socklen_t remotelen=sizeof(remote);
       if(getpeername(fd, (struct sockaddr *)&remote, &remotelen) < 0) {
@@ -249,7 +261,8 @@
       }
 
       uint16_t pktlen;
-      if(!readnWithTimeout(fd, &pktlen, 2, false))
+	  // fix, passing max request time to readnWithTimeout call
+      if(!readnWithTimeout(fd, &pktlen, 2, time_left, false))
 	break;
       else
 	pktlen=ntohs(pktlen);
@@ -259,7 +272,8 @@
 	break;
       }
       
-      getQuestion(fd,mesg,pktlen,remote);
+	  // fix, passing max request time to getQuestion call
+      getQuestion(fd,mesg,pktlen,remote,time_left);
       S.inc("tcp-queries");      
 
       packet=shared_ptr<DNSPacket>(new DNSPacket);
@@ -297,7 +311,7 @@
 	reply=shared_ptr<DNSPacket>(s_P->questionOrRecurse(packet.get(), &shouldRecurse)); // we really need to ask the backend :-)
 
 	if(shouldRecurse) {
-	  proxyQuestion(packet);
+	  proxyQuestion(packet,time_left);
 	  continue;
 	}
       }
diff -urNad trunk~/pdns/tcpreceiver.hh trunk/pdns/tcpreceiver.hh
--- trunk~/pdns/tcpreceiver.hh	2007-04-21 13:56:36.000000000 +0000
+++ trunk/pdns/tcpreceiver.hh	2009-01-05 13:14:42.000000000 +0000
@@ -50,7 +50,7 @@
 
   static void sendPacket(boost::shared_ptr<DNSPacket> p, int outsock);
   static int readLength(int fd, ComboAddress *remote);
-  static void getQuestion(int fd, char *mesg, int pktlen, const ComboAddress& remote);
+  static void getQuestion(int fd, char *mesg, int pktlen, const ComboAddress& remote, struct timeval &req_time);
   static int doAXFR(const string &target, boost::shared_ptr<DNSPacket> q, int outsock);
   static bool canDoAXFR(boost::shared_ptr<DNSPacket> q);
   static void *doConnection(void *data);

--- End Message ---
--- Begin Message ---
On Mon, 2009-01-05 at 15:01 +0100, Stephan S� wrote:
> Package: pdns
> Severity: wishlist
> Tags: patch
> 
> Hi pdns maintainers,
> 
> the attached dpatch
> 
> ## DP: Adds support for maximum TCP request time (command line arg).

this patch does not apply any more for upstream 2.9.22, and won't be
updated, so I am closing this bug.

Sorry for the noise,

Stephan
-- 
Stephan Sürken <absurd at debian.org>


--- End Message ---

Reply via email to