Author: trustin
Date: Fri Apr 22 19:41:04 2005
New Revision: 164314
URL: http://svn.apache.org/viewcvs?rev=164314&view=rev
Log:
Fixed: SSLFilter doesn't defer write requests until handshaking is complete.
Modified:
directory/network/trunk/src/java/org/apache/mina/io/filter/SSLFilter.java
directory/network/trunk/src/java/org/apache/mina/io/filter/SSLHandler.java
Modified:
directory/network/trunk/src/java/org/apache/mina/io/filter/SSLFilter.java
URL:
http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/io/filter/SSLFilter.java?rev=164314&r1=164313&r2=164314&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/io/filter/SSLFilter.java
(original)
+++ directory/network/trunk/src/java/org/apache/mina/io/filter/SSLFilter.java
Fri Apr 22 19:41:04 2005
@@ -228,10 +228,7 @@
public void sessionOpened( NextFilter nextFilter, IoSession session )
{
// Create an SSL handler
- if( createSSLSessionHandler( session ) == null )
- {
- throw new InternalError();
- }
+ createSSLSessionHandler( session );
nextFilter.sessionOpened( session );
}
@@ -332,68 +329,89 @@
public void filterWrite( NextFilter nextFilter, IoSession session,
ByteBuffer buf, Object marker )
{
- SSLHandler sslHandler = getSSLSessionHandler( session );
+ SSLHandler handler = createSSLSessionHandler( session );
if( debug != null )
{
- debug.print( this, "Filtered Write: " + sslHandler );
+ debug.print( this, "Filtered Write: " + handler );
}
- if( sslHandler != null )
+ synchronized( handler )
{
- synchronized( sslHandler )
+ if( handler.isWritingEncryptedData() )
{
- if( sslHandler.isWritingEncryptedData() )
+ // data already encrypted; simply return buffer
+ if( debug != null )
+ {
+ debug.print( this, " already encrypted: " + buf );
+ }
+ nextFilter.filterWrite( session, buf, marker );
+ return;
+ }
+
+ if( handler.isInitialHandshakeComplete() )
+ {
+ // SSL encrypt
+ try
{
- // data already encrypted; simply return buffer
if( debug != null )
{
- debug.print( this, " already encrypted: " + buf );
+ debug.print( this, "encrypt: " + buf );
}
- nextFilter.filterWrite( session, buf, marker );
+ handler.encrypt( buf.buf() );
+ ByteBuffer encryptedBuffer = copy( handler
+ .getOutNetBuffer() );
+
+ if( debug != null )
+ {
+ debug.print( this, "encrypted buf: " +
encryptedBuffer);
+ }
+ buf.release();
+ nextFilter.filterWrite( session, encryptedBuffer, marker );
return;
}
- if( sslHandler.isInitialHandshakeComplete() )
+ catch( SSLException ssle )
{
- // SSL encrypt
- try
+ throw new RuntimeException(
+ "Unexpected SSLException.", ssle );
+ }
+ }
+ else
+ {
+ if( !session.isConnected() )
+ {
+ if( debug != null )
{
- if( debug != null )
- {
- debug.print( this, "encrypt: " + buf );
- }
- sslHandler.encrypt( buf.buf() );
- ByteBuffer encryptedBuffer = copy( sslHandler
- .getOutNetBuffer() );
-
- if( debug != null )
- {
- debug.print( this, "encrypted buf: " +
encryptedBuffer);
- }
- buf.release();
- nextFilter.filterWrite( session, encryptedBuffer,
marker );
- return;
+ debug.print( this, "Write request on closed session."
);
}
- catch( SSLException ssle )
+ }
+ else
+ {
+ if( debug != null )
{
- throw new RuntimeException(
- "Unexpected SSLException.", ssle );
+ debug.print( this, "Handshaking is not complete yet.
Buffering write request." );
}
+ handler.scheduleWrite( nextFilter, buf, marker );
}
}
}
-
- nextFilter.filterWrite( session, buf, marker );
}
// Utiliities
private void handleSSLData( NextFilter nextFilter, IoSession session,
- SSLHandler sslHandler ) throws SSLException
+ SSLHandler handler ) throws SSLException
{
- // First write encrypted data to be written (if any)
- writeNetBuffer( session, sslHandler );
+ // Flush any buffered write requests occurred before handshaking.
+ if( handler.isInitialHandshakeComplete() )
+ {
+ handler.flushScheduledWrites();
+ }
+
+ // Write encrypted data to be written (if any)
+ writeNetBuffer( session, handler );
+
// handle app. data read (if any)
- handleAppDataRead( nextFilter, session, sslHandler );
+ handleAppDataRead( nextFilter, session, handler );
}
private void handleAppDataRead( NextFilter nextFilter, IoSession session,
@@ -418,7 +436,7 @@
void writeNetBuffer( IoSession session, SSLHandler sslHandler )
throws SSLException
{
- // first check if any net data needed to be writen
+ // Check if any net data needed to be writen
if( !sslHandler.getOutNetBuffer().hasRemaining() )
{
// no; bail out
@@ -521,10 +539,7 @@
handler =
new SSLHandler( this, sslContext, session );
sslSessionHandlerMap.put( session, handler );
- if( isUseClientMode() )
- {
- handler.doHandshake();
- }
+ handler.doHandshake();
}
catch( SSLException e )
{
Modified:
directory/network/trunk/src/java/org/apache/mina/io/filter/SSLHandler.java
URL:
http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/io/filter/SSLHandler.java?rev=164314&r1=164313&r2=164314&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/io/filter/SSLHandler.java
(original)
+++ directory/network/trunk/src/java/org/apache/mina/io/filter/SSLHandler.java
Fri Apr 22 19:41:04 2005
@@ -25,7 +25,10 @@
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
+
import org.apache.mina.io.IoSession;
+import org.apache.mina.io.IoHandlerFilter.NextFilter;
+import org.apache.mina.util.Queue;
/**
* A helper class using the SSLEngine API to decrypt/encrypt data.
@@ -42,6 +45,14 @@
{
private final SSLFilter parent;
+ private final IoSession session;
+
+ private final Queue nextFilterQueue = new Queue();
+
+ private final Queue writeBufferQueue = new Queue();
+
+ private final Queue writeMarkerQueue = new Queue();
+
private SSLEngine sslEngine;
/**
@@ -83,8 +94,7 @@
private boolean closed = false;
private boolean isWritingEncryptedData = false;
- private IoSession session = null;
-
+
/**
* Constuctor.
*
@@ -164,6 +174,31 @@
public boolean needToCompleteInitialHandshake()
{
return ( initialHandshakeStatus ==
SSLEngineResult.HandshakeStatus.NEED_WRAP && !closed );
+ }
+
+ public synchronized void scheduleWrite( NextFilter nextFilter,
org.apache.mina.common.ByteBuffer buf, Object marker )
+ {
+ nextFilterQueue.push( nextFilter );
+ writeBufferQueue.push( buf );
+ writeMarkerQueue.push( marker );
+ }
+
+ public synchronized void flushScheduledWrites()
+ {
+ NextFilter nextFilter;
+ org.apache.mina.common.ByteBuffer scheduledBuf;
+ Object scheduledMarker;
+
+ while( ( scheduledBuf = ( org.apache.mina.common.ByteBuffer )
writeBufferQueue.pop() ) != null )
+ {
+ if( parent.debug != null )
+ {
+ parent.debug.print( parent, "Flushing buffered write request:
" + scheduledBuf );
+ }
+ nextFilter = ( NextFilter ) nextFilterQueue.pop();
+ scheduledMarker = writeMarkerQueue.pop();
+ parent.filterWrite( nextFilter, session, scheduledBuf,
scheduledMarker );
+ }
}
/**