Author: astitcher
Date: Thu Jun 28 20:08:04 2012
New Revision: 1355142

URL: http://svn.apache.org/viewvc?rev=1355142&view=rev
Log:
QPID-4021: Badly behaved clients can still clog up the broker
Ameliorate the problem by only turning timeout off after receiving 3 frames
from the sender. This avoids an unauthenticed client causing a DoS by just
hanging before completing authentication in most cases.
This is far from a good fix, but should mostly avoid the issue until it can
be fixed in a neat way.

Modified:
    qpid/trunk/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp
    qpid/trunk/qpid/cpp/src/qpid/sys/AsynchIOHandler.h

Modified: qpid/trunk/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp?rev=1355142&r1=1355141&r2=1355142&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp Thu Jun 28 20:08:04 
2012
@@ -65,12 +65,15 @@ AsynchIOHandler::AsynchIOHandler(const s
     aio(0),
     factory(f),
     codec(0),
+    reads(0),
     readError(false),
     isClient(false),
     readCredit(InfiniteCredit)
 {}
 
 AsynchIOHandler::~AsynchIOHandler() {
+    if (timeoutTimerTask)
+        timeoutTimerTask->cancel();
     if (codec)
         codec->closed();
     if (timeoutTimerTask)
@@ -154,10 +157,18 @@ void AsynchIOHandler::readbuff(AsynchIO&
         }
     }
 
+    ++reads;
     size_t decoded = 0;
     if (codec) {                // Already initiated
         try {
             decoded = codec->decode(buff->bytes+buff->dataStart, 
buff->dataCount);
+            // When we've decoded 3 reads (probably frames) we will have 
authenticated and
+            // started heartbeats, if specified, in many (but not all) cases 
so now we will cancel
+            // the idle connection timeout - this is really hacky, and would 
be better implemented
+            // in the connection, but that isn't actually created until the 
first decode.
+            if (reads == 3) {
+                timeoutTimerTask->cancel();
+            }
         }catch(const std::exception& e){
             QPID_LOG(error, e.what());
             readError = true;
@@ -168,8 +179,6 @@ void AsynchIOHandler::readbuff(AsynchIO&
         framing::ProtocolInitiation protocolInit;
         if (protocolInit.decode(in)) {
             decoded = in.getPosition();
-            // We've just got the protocol negotiation so we can cancel the 
timeout for that
-            timeoutTimerTask->cancel();
 
             QPID_LOG(debug, "RECV [" << identifier << "]: INIT(" << 
protocolInit << ")");
             try {

Modified: qpid/trunk/qpid/cpp/src/qpid/sys/AsynchIOHandler.h
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/sys/AsynchIOHandler.h?rev=1355142&r1=1355141&r2=1355142&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/sys/AsynchIOHandler.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/sys/AsynchIOHandler.h Thu Jun 28 20:08:04 2012
@@ -48,6 +48,7 @@ class AsynchIOHandler : public OutputCon
     AsynchIO* aio;
     ConnectionCodec::Factory* factory;
     ConnectionCodec* codec;
+    uint32_t reads;
     bool readError;
     bool isClient;
     AtomicValue<int32_t> readCredit;



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to