[Date Prev][Date Next] [Chronological] [Thread] [Top]

(ITS#4714) 'Connection' object not throwing LDAPException upon sudden server connection loss



Full_Name: Alejandro Robles
Version: n/a
OS: Solaris 8
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (82.182.141.229)


SUMMARY
This issue relates to JLDAP software package
(novell-jldap-devel-2006.06.22-1unix.zip) whereby during a sudden server
connection loss the Connection object doesn't through an LDAPException upon an
LDAP Search operation. If this situation isn't detectec it causes the running
thread to hang where retrieving results by first invoking hasMoreElements()
method.

DETAILS
A client program of the form:

 1{
 2   Connect;
 3   Bind;
 4   
 5   <being loop>
 6      try {Search;}
 7      catch (LDAPException) {<do something>}
 8      while(hasMoreElements()) {
 9         retrieve;
10      }
11      Sleep 10secs;
12   <end loop>
13
14   Unbind;
15   Disconnect;
16}

If a connection loss is simulated while the program is sleeping (line 11), when
the thread wakes up and invokes the Search method (line 6) is doesn't through an
exception and thereafter the thread gets locked when running hasMoreElements()
on the results (line 8).

SOLUTION
The cause of the problem is belived to be within the Connection object in the
method 'writeMessage' (below extract from /com/novell/ldap/Connection.java
object version 1.88):


            /*
             * IOException could be due to a server shutdown notification which
             * caused our Connection to quit.  If so we send back a slightly
             * different error message.  We could have checked this a little
             * earlier in the method but that would be an expensive check each
             * time we send out a message.  Since this shutdown request is
             * going to be an infrequent occurence we check for it only when
             * we get an IOException.  shutdown() will do the cleanup.
             */
            if( clientActive) { // We beliefe the connection was alive
                if (unsolSvrShutDnNotification) { // got server shutdown
                    throw new LDAPException(
ExceptionMessages.SERVER_SHUTDOWN_REQ,
                        new Object[] { host, new Integer(port)},
                        LDAPException.CONNECT_ERROR, null,
                        ioe);
                }

                // Other I/O Exceptions on host:port are reported as is
                throw new LDAPException(ExceptionMessages.IO_EXCEPTION,
                    new Object[] {host, new Integer(port)},
                LDAPException.CONNECT_ERROR, null, ioe);
            }

The fact that the Connection has been lost causes prior to issuing a search to
the server to set the value of clietActive to false. The latter in turn causes
that any IOExceptions within the method not be handled properly (not thrown at
all) causing the mentioned problem.

PROPOSED FIX
To add a default Exception throwing code for the cases where 'clientActive' is
false.

            /*
             * IOException could be due to a server shutdown notification which
             * caused our Connection to quit.  If so we send back a slightly
             * different error message.  We could have checked this a little
             * earlier in the method but that would be an expensive check each
             * time we send out a message.  Since this shutdown request is
             * going to be an infrequent occurence we check for it only when
             * we get an IOException.  shutdown() will do the cleanup.
             */
            if( clientActive) { // We beliefe the connection was alive
                if (unsolSvrShutDnNotification) { // got server shutdown
                    throw new LDAPException(
ExceptionMessages.SERVER_SHUTDOWN_REQ,
                        new Object[] { host, new Integer(port)},
                        LDAPException.CONNECT_ERROR, null,
                        ioe);
                }
                // Other I/O Exceptions on host:port are reported as is
                throw new LDAPException(ExceptionMessages.IO_EXCEPTION,
                    new Object[] {host, new Integer(port)},
                LDAPException.CONNECT_ERROR, null, ioe);
            } else 
                // Other I/O Exceptions on host:port are reported as is
                throw new LDAPException(ExceptionMessages.IO_EXCEPTION,
                    new Object[] {host, new Integer(port)},
                LDAPException.CONNECT_ERROR, null, ioe);
            }