The following is the code snippet within SSLHandler.unwrap() to ensure that
handshake tasks are taken care of instead of causing an infinite loop.  Any
thoughts or comments?

        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);
            }
            
            // Need to execute handshake tasks?
            if (res.getHandshakeStatus() ==
SSLEngineResult.HandshakeStatus.NEED_TASK) {
                if (SessionLog.isDebugEnabled(session)) {
                    SessionLog.debug(session, " Unwrap
HandshakeStatus.NEED_TASK, calling doTasks()");
                }
                doTasks();
            }
            
        } while (res.getStatus() == SSLEngineResult.Status.OK);



James Gould wrote:
> 
> 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#a11855350
Sent from the Apache MINA Support Forum mailing list archive at Nabble.com.

Reply via email to