You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tr...@apache.org on 2005/10/28 08:00:26 UTC
svn commit: r329113 - in
/directory/network/trunk/src/java/org/apache/mina/filter: SSLFilter.java
support/SSLHandler.java
Author: trustin
Date: Thu Oct 27 23:00:16 2005
New Revision: 329113
URL: http://svn.apache.org/viewcvs?rev=329113&view=rev
Log:
Fixed some concurrency issues of SSLFilter in a multi-processor machine.
Modified:
directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java
directory/network/trunk/src/java/org/apache/mina/filter/support/SSLHandler.java
Modified: directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java?rev=329113&r1=329112&r2=329113&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java Thu Oct 27 23:00:16 2005
@@ -149,10 +149,7 @@
if( handler.isOutboundDone() )
{
- synchronized( session )
- {
- session.removeAttribute( SSL_HANDLER );
- }
+ session.removeAttribute( SSL_HANDLER );
}
else
{
@@ -178,10 +175,7 @@
return true;
}
- synchronized( handler )
- {
- return !handler.isOutboundDone();
- }
+ return !handler.isOutboundDone();
}
/**
@@ -393,7 +387,7 @@
sslHandler.messageReceived( nextFilter, buf.buf() );
// Handle data to be forwarded to application or written to net
- handleSSLData( nextFilter, session, sslHandler );
+ handleSSLData( nextFilter, sslHandler );
if( sslHandler.isInboundDone() )
{
@@ -559,16 +553,14 @@
synchronized( handler )
{
- if( handler.isOutboundDone() )
+ // shut down
+ if( !handler.closeOutbound() )
{
return WriteFuture.newNotWrittenFuture();
}
-
- // shut down
- handler.closeOutbound();
// there might be data to write out here?
- WriteFuture future = handler.writeNetBuffer( nextFilter, session );
+ WriteFuture future = handler.writeNetBuffer( nextFilter );
if( handler.isInboundDone() )
{
@@ -581,8 +573,7 @@
// Utiliities
- private void handleSSLData( NextFilter nextFilter, IoSession session,
- SSLHandler handler ) throws SSLException
+ private void handleSSLData( NextFilter nextFilter, SSLHandler handler ) throws SSLException
{
// Flush any buffered write requests occurred before handshaking.
if( handler.isInitialHandshakeComplete() )
@@ -591,29 +582,32 @@
}
// Write encrypted data to be written (if any)
- handler.writeNetBuffer( nextFilter, session );
+ handler.writeNetBuffer( nextFilter );
// handle app. data read (if any)
- handleAppDataRead( nextFilter, session, handler );
+ handleAppDataRead( nextFilter, handler );
}
- private void handleAppDataRead( NextFilter nextFilter, IoSession session,
- SSLHandler sslHandler )
+ private void handleAppDataRead( NextFilter nextFilter, SSLHandler sslHandler )
{
+ IoSession session = sslHandler.getSession();
+ if( !sslHandler.getAppBuffer().hasRemaining() )
+ {
+ return;
+ }
+
if( log.isDebugEnabled() )
{
log.debug( session + " appBuffer: " + sslHandler.getAppBuffer() );
}
- if( sslHandler.getAppBuffer().hasRemaining() )
+
+ // forward read app data
+ ByteBuffer readBuffer = SSLHandler.copy( sslHandler.getAppBuffer() );
+ if( log.isDebugEnabled() )
{
- // forward read app data
- ByteBuffer readBuffer = SSLHandler.copy( sslHandler.getAppBuffer() );
- if( log.isDebugEnabled() )
- {
- log.debug( session + " app data read: " + readBuffer + " (" + readBuffer.getHexDump() + ')' );
- }
- nextFilter.messageReceived( session, readBuffer );
+ log.debug( session + " app data read: " + readBuffer + " (" + readBuffer.getHexDump() + ')' );
}
+ nextFilter.messageReceived( session, readBuffer );
}
// Utilities to mainpulate SSLHandler based on IoSession
@@ -661,11 +655,8 @@
SSLHandler sslHandler = getSSLSessionHandler( session );
if( sslHandler != null )
{
- synchronized( sslHandler )
- {
- // release resources
- sslHandler.release();
- }
+ // release resources
+ sslHandler.release();
}
}
Modified: directory/network/trunk/src/java/org/apache/mina/filter/support/SSLHandler.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/filter/support/SSLHandler.java?rev=329113&r1=329112&r2=329113&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/filter/support/SSLHandler.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/filter/support/SSLHandler.java Thu Oct 27 23:00:16 2005
@@ -86,7 +86,7 @@
*/
private boolean initialHandshakeComplete;
- private boolean isWritingEncryptedData = false;
+ private boolean writingEncryptedData = false;
/**
* Constuctor.
@@ -139,38 +139,34 @@
{
return parent;
}
-
- /**
- * Indicate that we are writing encrypted data.
- * Only used as a flag by IoSSLFiler
- */
- public void setWritingEncryptedData( boolean flag )
+
+ public IoSession getSession()
{
- isWritingEncryptedData = flag;
+ return session;
}
/**
* Check we are writing encrypted data.
*/
- public boolean isWritingEncryptedData()
+ public synchronized boolean isWritingEncryptedData()
{
- return isWritingEncryptedData;
+ return writingEncryptedData;
}
/**
* Check if initial handshake is completed.
*/
- public boolean isInitialHandshakeComplete()
+ public synchronized boolean isInitialHandshakeComplete()
{
return initialHandshakeComplete;
}
- public boolean isInboundDone()
+ public synchronized boolean isInboundDone()
{
return sslEngine.isInboundDone();
}
- public boolean isOutboundDone()
+ public synchronized boolean isOutboundDone()
{
return sslEngine.isOutboundDone();
}
@@ -178,7 +174,7 @@
/**
* Check if there is any need to complete initial handshake.
*/
- public boolean needToCompleteInitialHandshake()
+ public synchronized boolean needToCompleteInitialHandshake()
{
return ( initialHandshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP && !isInboundDone() );
}
@@ -210,7 +206,7 @@
* @param buf buffer to decrypt
* @throws SSLException on errors
*/
- public void messageReceived( NextFilter nextFilter, ByteBuffer buf ) throws SSLException
+ public synchronized void messageReceived( NextFilter nextFilter, ByteBuffer buf ) throws SSLException
{
if ( buf.limit() > inNetBuffer.remaining() ) {
// We have to expand inNetBuffer
@@ -237,7 +233,7 @@
}
else
{
- doDecrypt();
+ decrypt();
}
if( isInboundDone() )
@@ -253,7 +249,7 @@
*
* @throws SSLException on errors
*/
- public void continueHandshake( NextFilter nextFilter ) throws SSLException
+ public synchronized void continueHandshake( NextFilter nextFilter ) throws SSLException
{
if( log.isDebugEnabled() )
{
@@ -285,31 +281,87 @@
/**
* Encrypt provided buffer. Encytpted data reurned by getOutNetBuffer().
*
- * @param buf data to encrypt
+ * @param src data to encrypt
* @throws SSLException on errors
*/
- public void encrypt( ByteBuffer buf ) throws SSLException
+ public synchronized void encrypt( ByteBuffer src ) throws SSLException
{
- doEncrypt( buf );
+ if( !initialHandshakeComplete )
+ {
+ throw new IllegalStateException();
+ }
+
+ // The data buffer is (must be) empty, we can reuse the entire
+ // buffer.
+ outNetBuffer.clear();
+
+ SSLEngineResult result;
+
+ // Loop until there is no more data in src
+ while ( src.hasRemaining() ) {
+
+ if ( src.remaining() > ( ( outNetBuffer.capacity() - outNetBuffer.position() ) / 2 ) ) {
+ // We have to expand outNetBuffer
+ // Note: there is no way to know the exact size required, but enrypted data
+ // shouln't need to be larger than twice the source data size?
+ outNetBuffer = SSLByteBufferPool.expandBuffer( outNetBuffer, src.capacity() * 2 );
+ if ( log.isDebugEnabled() ) {
+ log.debug( session + " expanded outNetBuffer:" + outNetBuffer );
+ }
+ }
+
+ result = sslEngine.wrap( src, outNetBuffer );
+ if ( log.isDebugEnabled() ) {
+ log.debug( session + " Wrap res:" + result );
+ }
+
+ if ( result.getStatus() == SSLEngineResult.Status.OK ) {
+ if ( result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK ) {
+ doTasks();
+ }
+ } else {
+ throw new SSLException( "SSLEngine error during encrypt: "
+ + result.getStatus() +
+ " src: " + src + "outNetBuffer: " + outNetBuffer);
+ }
+ }
+
+ outNetBuffer.flip();
}
/**
- * Start SSL shutdown process
+ * Start SSL shutdown process.
+ *
+ * @return <tt>true</tt> if shutdown process is started.
+ * <tt>false</tt> if shutdown process is already finished.
*
* @throws SSLException on errors
*/
- public void closeOutbound() throws SSLException
+ public synchronized boolean closeOutbound() throws SSLException
{
- if( !sslEngine.isOutboundDone() )
+ if( sslEngine.isOutboundDone() )
{
- doShutdown();
+ return false;
}
+
+ sslEngine.closeOutbound();
+
+ // By RFC 2616, we can "fire and forget" our close_notify
+ // message, so that's what we'll do here.
+ outNetBuffer.clear();
+ SSLEngineResult result = sslEngine.wrap( hsBB, outNetBuffer );
+ if( result.getStatus() != SSLEngineResult.Status.CLOSED )
+ {
+ throw new SSLException( "Improper close state: " + result );
+ }
+ outNetBuffer.flip();
+ return true;
}
/**
* Release allocated ByteBuffers.
*/
- public void release()
+ public synchronized void release()
{
SSLByteBufferPool.release( appBuffer );
SSLByteBufferPool.release( inNetBuffer );
@@ -321,7 +373,7 @@
*
* @throws SSLException
*/
- private void doDecrypt() throws SSLException
+ private void decrypt() throws SSLException
{
if( !initialHandshakeComplete )
@@ -359,51 +411,6 @@
return status;
}
- private void doEncrypt( ByteBuffer src ) throws SSLException
- {
- if( !initialHandshakeComplete )
- {
- throw new IllegalStateException();
- }
-
- // The data buffer is (must be) empty, we can reuse the entire
- // buffer.
- outNetBuffer.clear();
-
- SSLEngineResult result;
-
- // Loop until there is no more data in src
- while ( src.hasRemaining() ) {
-
- if ( src.remaining() > ( ( outNetBuffer.capacity() - outNetBuffer.position() ) / 2 ) ) {
- // We have to expand outNetBuffer
- // Note: there is no way to know the exact size required, but enrypted data
- // shouln't need to be larger than twice the source data size?
- outNetBuffer = SSLByteBufferPool.expandBuffer( outNetBuffer, src.capacity() * 2 );
- if ( log.isDebugEnabled() ) {
- log.debug( session + " expanded outNetBuffer:" + outNetBuffer );
- }
- }
-
- result = sslEngine.wrap( src, outNetBuffer );
- if ( log.isDebugEnabled() ) {
- log.debug( session + " Wrap res:" + result );
- }
-
- if ( result.getStatus() == SSLEngineResult.Status.OK ) {
- if ( result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK ) {
- doTasks();
- }
- } else {
- throw new SSLException( "SSLEngine error during encrypt: "
- + result.getStatus() +
- " src: " + src + "outNetBuffer: " + outNetBuffer);
- }
- }
-
- outNetBuffer.flip();
- }
-
/**
* Perform any handshaking processing.
*/
@@ -479,7 +486,7 @@
outNetBuffer.flip();
initialHandshakeStatus = result.getHandshakeStatus();
- writeNetBuffer( nextFilter, session );
+ writeNetBuffer( nextFilter );
// return to allow data on out buffer being sent
// TODO: We might want to send more data immidiatley?
}
@@ -491,7 +498,7 @@
}
}
- public WriteFuture writeNetBuffer( NextFilter nextFilter, IoSession session ) throws SSLException
+ public synchronized WriteFuture writeNetBuffer( NextFilter nextFilter ) throws SSLException
{
// Check if any net data needed to be writen
if( !getOutNetBuffer().hasRemaining() )
@@ -506,10 +513,7 @@
// set flag that we are writing encrypted data
// (used in SSLFilter.filterWrite())
- synchronized( this )
- {
- setWritingEncryptedData( true );
- }
+ writingEncryptedData = true;
try
{
@@ -555,10 +559,7 @@
}
finally
{
- synchronized( this )
- {
- setWritingEncryptedData( false );
- }
+ writingEncryptedData = false;
}
if( writeFuture != null )
@@ -572,7 +573,7 @@
}
- SSLEngineResult.Status unwrap() throws SSLException
+ private SSLEngineResult.Status unwrap() throws SSLException
{
if( log.isDebugEnabled() )
{
@@ -716,29 +717,6 @@
return sslEngine.getHandshakeStatus();
}
- /**
- * Begin the shutdown process.
- */
- void doShutdown() throws SSLException
- {
-
- if( !sslEngine.isOutboundDone() )
- {
- sslEngine.closeOutbound();
- }
-
- // By RFC 2616, we can "fire and forget" our close_notify
- // message, so that's what we'll do here.
-
- outNetBuffer.clear();
- SSLEngineResult result = sslEngine.wrap( hsBB, outNetBuffer );
- if( result.getStatus() != SSLEngineResult.Status.CLOSED )
- {
- throw new SSLException( "Improper close state: " + result );
- }
- outNetBuffer.flip();
- }
-
private static class ScheduledWrite
{
private final NextFilter nextFilter;