I created a posting yesterday related to a potential deadlock in a Mina
Gateway, which was root cause of the hanging behavior.  After taking several
thread dumps and looking at the Mina DEBUG logs it looks like there is the
risk of an endless loop in SSLHandler.unwrap.  The code within
SSLHandler.unwrap that is at risk is below:

        do {
            if (SessionLog.isDebugEnabled(session)) {
                SessionLog.debug(session, "   inNetBuffer: " + inNetBuffer);
                SessionLog.debug(session, "   appBuffer: " + appBuffer);
            }
            res = sslEngine.unwrap(inNetBuffer, appBuffer);
            if (SessionLog.isDebugEnabled(session)) {
                SessionLog.debug(session, " Unwrap res:" + res);
            }
        } while (res.getStatus() == SSLEngineResult.Status.OK);


The following are DEBUG logs produced when the Gateway is in a hung state,
where all of the service threads are in this endless loop:

20070728 210259 pool-2-thread-40 ote-srsgate4 -1
com.verisign.cag.protocol.srsepp.SRSEPPSourceHandler LOG4J DEBUG
[/66.113.128.10:45567]  Unwrap res:Status = OK HandshakeStatus = NEED_TASK
20070728 210259 pool-2-thread-40 ote-srsgate4 -1
com.verisign.cag.protocol.srsepp.SRSEPPSourceHandler LOG4J DEBUG
[/66.113.128.10:45567]    inNetBuffer: java.nio.DirectByteBuffer[pos=126
lim=126 cap=16665]
20070728 210259 pool-2-thread-40 ote-srsgate4 -1
com.verisign.cag.protocol.srsepp.SRSEPPSourceHandler LOG4J DEBUG
[/66.113.128.10:45567]    appBuffer: java.nio.DirectByteBuffer[pos=0
lim=33330 cap=33330]

If you notice, it will continue in the loop as long as the res.getStatus()
is OK, which is always the case.  There is no check for the handshake status
which continues to be NEED_TASK.  In looking at the Sun JDK
SSLEngineImpl.readNetRecord(EngineArgs) it will return OK without doing
anything if the handshake status is NEED_TASK.  

    private SSLEngineResult readNetRecord(EngineArgs engineargs)
        throws IOException
    {
        javax.net.ssl.SSLEngineResult.Status status = null;
        javax.net.ssl.SSLEngineResult.HandshakeStatus handshakestatus =
null;
        checkTaskThrown();
        if(isInboundDone())
            return new
SSLEngineResult(javax.net.ssl.SSLEngineResult.Status.CLOSED,
getHSStatus(null), 0, 0);
        int i = getConnectionState();
        if(i == 1 || i == 0)
        {
            kickstartHandshake();
            handshakestatus = getHSStatus(null);
            if(handshakestatus ==
javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_WRAP)
                return new
SSLEngineResult(javax.net.ssl.SSLEngineResult.Status.OK, handshakestatus, 0,
0);
        }
        if(handshakestatus == null)
            handshakestatus = getHSStatus(null);
        if(handshakestatus ==
javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_TASK)
            return new
SSLEngineResult(javax.net.ssl.SSLEngineResult.Status.OK, handshakestatus, 0,
0);

I know the initial handshake was successful.  I have the following
questions:

1. How did the handshake status get into the NEED_TASK status after a
successful initial handshake?  Is this due to a SSL session re-negotiation?  
2. Has anyone else come across a similar endless loop scenario?  

I believe that the handshake status needs to be also checked within
SSLHandler.unwrap to mitigate this issue, but I want to ensure that it
eventually addresses the handshake NEED_TASK status issue correctly.  

Any advice is greatly appreciated.


-- 
View this message in context: 
http://www.nabble.com/Endless-Loop-in-SSLHandler.unwrap-causing-Mina-Gateway-to-Hang-tf4166136s16868.html#a11852995
Sent from the Apache MINA Support Forum mailing list archive at Nabble.com.

Reply via email to