From 3c685926df93073d5c5088434132a6f3f844ba32 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 06 Oct 2011 14:15:09 +0000
Subject: [PATCH] Fix OPENDJ-306: Misleading access log error message when client resets the connection.

---
 opends/src/messages/messages/protocol.properties                              |    3 +++
 opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java  |   22 +++++++++++++++++++---
 opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelReader.java |   26 +++++++++++++++++++++++---
 3 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/opends/src/messages/messages/protocol.properties b/opends/src/messages/messages/protocol.properties
index 4808a1d..4856b29 100644
--- a/opends/src/messages/messages/protocol.properties
+++ b/opends/src/messages/messages/protocol.properties
@@ -1428,3 +1428,6 @@
 Server was closed while waiting for a response
 INFO_ERGONOMIC_SIZING_OF_REQUEST_HANDLER_THREADS_1512=Connection handler '%s' \
  does not specify the number of request handler threads: defaulting to %d threads
+MILD_ERR_LDAP_CLIENT_IO_ERROR_DURING_READ_1513=An IO error occurred while \
+ reading a request from the client: %s
+MILD_ERR_LDAP_CLIENT_IO_ERROR_BEFORE_READ_1514=Connection reset by client
diff --git a/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelReader.java b/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelReader.java
index 5325a38..baa94ad 100644
--- a/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelReader.java
+++ b/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelReader.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2006-2009 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 package org.opends.server.protocols.asn1;
 
@@ -330,9 +331,18 @@
     }
 
     byteBuffer.clear();
-    int read = byteChannel.read(byteBuffer);
-    byteBuffer.flip();
-    return read;
+    try
+    {
+      int read = byteChannel.read(byteBuffer);
+      return read;
+    }
+    finally
+    {
+      // Make sure that the buffer is flipped even if the read fails in order to
+      // ensure that subsequent calls which query the remaining data return
+      // valid results.
+      byteBuffer.flip();
+    }
   }
 
   /**
@@ -362,6 +372,16 @@
   }
 
   /**
+   * Returns {@code true} if this ASN.1 reader contains unread data.
+   *
+   * @return {@code true} if this ASN.1 reader contains unread data.
+   */
+  public boolean hasRemainingData()
+  {
+    return (saveBufferReader.remaining() != 0) || (byteBuffer.remaining() != 0);
+  }
+
+  /**
    * {@inheritDoc}
    */
   public int peekLength() throws ASN1Exception {
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 c31f5cd..b67cc3a 100644
--- a/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
+++ b/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
@@ -1587,9 +1587,25 @@
       {
         TRACER.debugCaught(DebugLogLevel.ERROR, e);
       }
-      Message m =
-        ERR_LDAP_CLIENT_DECODE_LDAP_MESSAGE_FAILED.get(String.valueOf(e));
-      disconnect(DisconnectReason.PROTOCOL_ERROR, true, m);
+
+      if (asn1Reader.hasRemainingData())
+      {
+        // The connection failed, but there was an unread partial message so
+        // interpret this as an IO error.
+        Message m = ERR_LDAP_CLIENT_IO_ERROR_DURING_READ.get(String
+            .valueOf(e));
+        disconnect(DisconnectReason.IO_ERROR, true, m);
+      }
+      else
+      {
+        // The connection failed and there was no unread data, so interpret this
+        // as indicating that the client aborted (reset) the connection. This
+        // happens when a client configures closes a connection which has been
+        // configured with SO_LINGER set to 0.
+        Message m = ERR_LDAP_CLIENT_IO_ERROR_BEFORE_READ.get();
+        disconnect(DisconnectReason.CLIENT_DISCONNECT, true, m);
+      }
+
       return -1;
     }
   }

--
Gitblit v1.10.0