Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8357708

com.sun.jndi.ldap.Connection ignores queued LDAP replies if Connection is subsequently closed

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • 26
    • 14
    • core-libs
    • None

      The com.sun.jndi.ldap.LdapClient class uses the com.sun.jndi.ldap.Connection for sending LDAP requests and receiving their replies over a Socket. The replies may be read by the LdapClient asynchronously - i.e. the LdapClient may send a LDAP request, then some later moment in time, it may invoke the Connection.readReply() method for that particular request (identified by a message id) to read any available replies or wait for those replies to arrive.

      To allow for this asynchronous nature of request/reply, the implementation in the Connection, whenever it reads any reply off the Socket, will queue that reply in a per request specific queue. That queue is maintained in the com.sun.jndi.ldap.LdapRequest.

      If/when the corresponding Socket is closed, for example, if the LDAP server sends the LDAP reply and then closes the Socket's OutputStream indicating no more data to be sent, then the implementation in the (in this client side) Connection will mark its own internal state to indicate that the connection has been closed.

      It may so happen that the LdapClient, which has previously issued a LDAP request through the Connection will then come ask the Connection for the LDAP reply/replies for that request. These replies may have arrived and may have been queued in the LdapRequest before the Connection was closed. Ideally, these replies should be returned to the LdapClient. Instead, due to the way the implementation in Connection currently works, the queued replies are ignored because the Connection state is marked as closed and instead an exception gets thrown from Connection.readReply(). The exception is of the form:

      Caused by: javax.naming.ServiceUnavailableException: 127.0.0.1:12345; socket closed; remaining name 'CN=foobar'
      at java.naming/com.sun.jndi.ldap.Connection.readReply(Connection.java:448)
      at java.naming/com.sun.jndi.ldap.LdapClient.getSearchReply(LdapClient.java:664)
      at java.naming/com.sun.jndi.ldap.LdapClient.search(LdapClient.java:587)
      at java.naming/com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:2013)
      at java.naming/com.sun.jndi.ldap.LdapCtx.doSearchOnce(LdapCtx.java:1961)
      at java.naming/com.sun.jndi.ldap.LdapCtx.c_getAttributes(LdapCtx.java:1354)
      at java.naming/com.sun.jndi.toolkit.ctx.ComponentDirContext.p_getAttributes(ComponentDirContext.java:235)
      at java.naming/com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.getAttributes(PartialCompositeDirContext.java:141)
      at java.naming/javax.naming.directory.InitialDirContext.getAttributes(InitialDirContext.java:181)


      This current implementation appears to be an unintended side-effect of the change that was done in JDK-8223727. That change was prompted by a hang where the LdapClient could have called the Connection.readReply() after the Connection was closed and when there were no replies queued. That call would then block forever waiting on the replies queue in LdapRequest, hoping for some reply to be offered to the queue. Since the Connection is already closed, no reply arrives on that Connection and thus that code would block forever.

      To address the current issue where the queued replies may get ignored and at the same time not reintroduce the JDK-8223727 issue, the Connection implementation in co-ordination with the implementation in LdapRequest should be updated to make sure that calls to Connection.readReply() don't block forever and at the same time don't ignore already queued replies.

            jpai Jaikiran Pai
            jpai Jaikiran Pai
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: