From e6de9287a317004ab46335956d14942fd3387e75 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Tue, 07 Apr 2009 18:22:16 +0000
Subject: [PATCH] Fix issue 3915 - Abandon operations can block request handlers for 5 seconds.

---
 opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java |   39 +++++++++++++++++++++++++++++++++------
 1 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java b/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
index 1f8c977..3ee4010 100644
--- a/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
+++ b/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
@@ -88,6 +88,7 @@
 import org.opends.server.types.DisconnectReason;
 import org.opends.server.types.IntermediateResponse;
 import org.opends.server.types.Operation;
+import org.opends.server.types.OperationType;
 import org.opends.server.types.ResultCode;
 import org.opends.server.types.SearchResultEntry;
 import org.opends.server.types.SearchResultReference;
@@ -1151,11 +1152,18 @@
     {
       return false;
     }
-    else
+
+    if (operation.getOperationType() == OperationType.ABANDON)
     {
-      lastCompletionTime.set(TimeThread.getTime());
-      return true;
+      if (keepStats
+          && (operation.getResultCode() == ResultCode.CANCELED))
+      {
+        statTracker.updateAbandonedOperation();
+      }
     }
+
+    lastCompletionTime.set(TimeThread.getTime());
+    return true;
   }
 
 
@@ -1669,6 +1677,16 @@
   private boolean processAbandonRequest(LDAPMessage message,
       List<Control> controls)
   {
+    if ((ldapVersion == 2) && (controls != null)
+        && (!controls.isEmpty()))
+    {
+      // LDAPv2 clients aren't allowed to send controls.
+      disconnect(DisconnectReason.PROTOCOL_ERROR, false,
+          ERR_LDAPV2_CONTROLS_NOT_ALLOWED.get());
+      return false;
+    }
+
+    // Create the abandon operation and add it into the work queue.
     AbandonRequestProtocolOp protocolOp =
         message.getAbandonRequestProtocolOp();
     AbandonOperationBasis abandonOp =
@@ -1676,10 +1694,19 @@
             .getAndIncrement(), message.getMessageID(), controls,
             protocolOp.getIDToAbandon());
 
-    abandonOp.run();
-    if (keepStats && (abandonOp.getResultCode() == ResultCode.CANCELED))
+    try
     {
-      statTracker.updateAbandonedOperation();
+      addOperationInProgress(abandonOp);
+    }
+    catch (DirectoryException de)
+    {
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, de);
+      }
+
+      // Don't send an error response since abandon operations
+      // don't have a response.
     }
 
     return connectionValid;

--
Gitblit v1.10.0