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/26 21:17:24 UTC

svn commit: r328711 - in /directory/network/trunk/src: examples/org/apache/mina/examples/echoserver/ java/org/apache/mina/common/support/ java/org/apache/mina/filter/ java/org/apache/mina/filter/support/ java/org/apache/mina/transport/socket/nio/suppor...

Author: trustin
Date: Wed Oct 26 12:17:07 2005
New Revision: 328711

URL: http://svn.apache.org/viewcvs?rev=328711&view=rev
Log:
* org.apache.mina.examples.echoserver.AbstractTest now supports StartTLS test.
* Fixed bugs related with StartTLS and TLS closure

Modified:
    directory/network/trunk/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java
    directory/network/trunk/src/java/org/apache/mina/common/support/AbstractIoFilterChain.java
    directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java
    directory/network/trunk/src/java/org/apache/mina/filter/support/SSLHandler.java
    directory/network/trunk/src/java/org/apache/mina/transport/socket/nio/support/SocketIoProcessor.java
    directory/network/trunk/src/test/org/apache/mina/examples/echoserver/AbstractTest.java
    directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java

Modified: directory/network/trunk/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java?rev=328711&r1=328710&r2=328711&view=diff
==============================================================================
--- directory/network/trunk/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java (original)
+++ directory/network/trunk/src/examples/org/apache/mina/examples/echoserver/EchoProtocolHandler.java Wed Oct 26 12:17:07 2005
@@ -60,7 +60,7 @@
         session.close();
     }
 
-    public void messageReceived( IoSession session, Object message )
+    public void messageReceived( IoSession session, Object message ) throws Exception
     {
         ByteBuffer rb = ( ByteBuffer ) message;
         // Write the received data back to remote peer

Modified: directory/network/trunk/src/java/org/apache/mina/common/support/AbstractIoFilterChain.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/common/support/AbstractIoFilterChain.java?rev=328711&r1=328710&r2=328711&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/common/support/AbstractIoFilterChain.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/common/support/AbstractIoFilterChain.java Wed Oct 26 12:17:07 2005
@@ -33,6 +33,8 @@
 import org.apache.mina.common.IoFilter.NextFilter;
 import org.apache.mina.common.IoFilter.WriteRequest;
 import org.apache.mina.util.ByteBufferUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * An abstract implementation of {@link IoFilterChain} that provides
@@ -49,6 +51,8 @@
  */
 public abstract class AbstractIoFilterChain implements IoFilterChain
 {
+    private static final Logger log = LoggerFactory.getLogger( IoFilterChain.class );
+    
     private final Object parent;
 
     private final Map name2entry = new HashMap();
@@ -553,7 +557,7 @@
         }
         catch( Throwable e )
         {
-            e.printStackTrace();
+            log.warn( "Uncaught exception.", e );
         }
     }
     

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=328711&r1=328710&r2=328711&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 Wed Oct 26 12:17:07 2005
@@ -147,16 +147,16 @@
                 throw new IllegalArgumentException( "Not managed by this filter." );
             }
 
-            synchronized( handler )
+            if( handler.isOutboundDone() )
             {
-                if( handler.isOutboundDone() )
+                synchronized( session )
                 {
                     session.removeAttribute( SSL_HANDLER );
                 }
-                else
-                {
-                    return false;
-                }
+            }
+            else
+            {
+                return false;
             }
         }
         
@@ -175,12 +175,12 @@
         SSLHandler handler = getSSLSessionHandler( session );
         if( handler == null )
         {
-            return false;
+            return true;
         }
         
         synchronized( handler )
         {
-            return handler.isOutboundDone();
+            return !handler.isOutboundDone();
         }
     }
 
@@ -354,7 +354,7 @@
         // release resources
         try
         {
-            removeSSLSessionHandler( session );
+            releaseSSLSessionHandler( session );
         }
         finally
         {
@@ -366,14 +366,19 @@
     public void messageReceived( NextFilter nextFilter, IoSession session,
                                  Object message ) throws SSLException
     {
+        SSLHandler sslHandler = createSSLSessionHandler( nextFilter, session );
+
         if( !isSSLStarted( session ) )
         {
-            nextFilter.messageReceived( session, message );
-            return;
+            if( sslHandler != null && sslHandler.isInboundDone() )
+            {
+                nextFilter.messageReceived( session, message );
+                return;
+            }
         }
 
         ByteBuffer buf = ( ByteBuffer ) message;
-        SSLHandler sslHandler = createSSLSessionHandler( nextFilter, session );
+        sslHandler = createSSLSessionHandler( nextFilter, session );
         if( sslHandler != null )
         {
             if( log.isDebugEnabled() )
@@ -400,18 +405,17 @@
                                          session + " SSL Session closed." );
                             }
                             
-                            SessionLog.info( session, "MSGRCVD: DONE" );
-
-                            removeSSLSessionHandler( session );
-                            if( buf.hasRemaining() )
-                            {
-                                nextFilter.messageReceived( session, buf );
-                            }
+                            releaseSSLSessionHandler( session );
                         }
                         else
                         {
                             initiateClosure( nextFilter, session );
                         }
+
+                        if( buf.hasRemaining() )
+                        {
+                            nextFilter.messageReceived( session, buf );
+                        }
                     }
                 }
                 catch( SSLException ssle )
@@ -456,9 +460,9 @@
             nextFilter.filterWrite( session, writeRequest );
             return;
         }
-
+        
         // Don't encrypt the data if encryption is disabled.
-        if( session.getAttribute( DISABLE_ENCRYPTION_ONCE ) != null )
+        if( session.containsAttribute( DISABLE_ENCRYPTION_ONCE ) )
         {
             // Remove the marker attribute because it is temporary.
             session.removeAttribute( DISABLE_ENCRYPTION_ONCE );
@@ -568,7 +572,7 @@
             
             if( handler.isInboundDone() )
             {
-                removeSSLSessionHandler( session );
+                releaseSSLSessionHandler( session );
             }
 
             return future;
@@ -652,7 +656,7 @@
         return ( SSLHandler ) session.getAttribute( SSL_HANDLER );
     }
 
-    private void removeSSLSessionHandler( IoSession session )
+    private void releaseSSLSessionHandler( IoSession session )
     {
         SSLHandler sslHandler = getSSLSessionHandler( session );
         if( sslHandler != null )

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=328711&r1=328710&r2=328711&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 Wed Oct 26 12:17:07 2005
@@ -239,6 +239,13 @@
         {
             doDecrypt();
         }
+
+        if( isInboundDone() )
+        {
+            // Rewind the MINA buffer if not all data is processed and inbound is finished.
+            buf.position( buf.position() - inNetBuffer.position() );
+            inNetBuffer.clear();
+        }
     }
 
     /**
@@ -641,7 +648,7 @@
 
         initialHandshakeStatus = res.getHandshakeStatus();
 	
-	// If handshake finished, no data was produced, and the status is still ok,
+	    // If handshake finished, no data was produced, and the status is still ok,
 		// try to unwrap more
 		if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED
 				&& appBuffer.position() == 0

Modified: directory/network/trunk/src/java/org/apache/mina/transport/socket/nio/support/SocketIoProcessor.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/transport/socket/nio/support/SocketIoProcessor.java?rev=328711&r1=328710&r2=328711&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/transport/socket/nio/support/SocketIoProcessor.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/transport/socket/nio/support/SocketIoProcessor.java Wed Oct 26 12:17:07 2005
@@ -31,6 +31,8 @@
 import org.apache.mina.common.WriteTimeoutException;
 import org.apache.mina.common.IoFilter.WriteRequest;
 import org.apache.mina.util.Queue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Performs all I/O operations for sockets which is connected or bound.
@@ -41,6 +43,7 @@
  */
 class SocketIoProcessor
 {
+    private static final Logger log = LoggerFactory.getLogger( SocketIoProcessor.class ); 
     private static final SocketIoProcessor instance;
 
     static
@@ -562,9 +565,9 @@
                         }
                     }
                 }
-                catch( IOException e )
+                catch( Throwable t )
                 {
-                    e.printStackTrace();
+                    log.warn( "Unexpected exception.", t );
 
                     try
                     {

Modified: directory/network/trunk/src/test/org/apache/mina/examples/echoserver/AbstractTest.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/test/org/apache/mina/examples/echoserver/AbstractTest.java?rev=328711&r1=328710&r2=328711&view=diff
==============================================================================
--- directory/network/trunk/src/test/org/apache/mina/examples/echoserver/AbstractTest.java (original)
+++ directory/network/trunk/src/test/org/apache/mina/examples/echoserver/AbstractTest.java Wed Oct 26 12:17:07 2005
@@ -23,11 +23,15 @@
 import junit.framework.TestCase;
 
 import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoSession;
 import org.apache.mina.common.TransportType;
 import org.apache.mina.filter.LoggingFilter;
+import org.apache.mina.filter.SSLFilter;
 import org.apache.mina.registry.Service;
 import org.apache.mina.registry.ServiceRegistry;
 import org.apache.mina.registry.SimpleServiceRegistry;
+import org.apache.mina.util.SessionLog;
 
 /**
  * Tests echo server example.
@@ -92,7 +96,31 @@
             
             try
             {
-                registry.bind( socketService, new EchoProtocolHandler() );
+                final IoAcceptor acceptor = registry.getAcceptor( TransportType.SOCKET );
+                registry.bind( socketService, new EchoProtocolHandler()
+                {
+                    // This is for TLS reentrance test
+                    public void messageReceived( IoSession session, Object message ) throws Exception
+                    {
+                        ByteBuffer buf = ( ByteBuffer ) message;
+                        if( buf.remaining() == 1 && buf.get() == ( byte ) '.' )
+                        {
+                            SessionLog.info( session, "TLS Reentrance" );
+                            ( ( SSLFilter ) acceptor.getFilterChain().get( "SSL" ) ).startSSL( session );
+
+                            // Send a response
+                            buf = ByteBuffer.allocate( 1 );
+                            buf.put( ( byte ) '.' );
+                            buf.flip();
+                            session.setAttribute( SSLFilter.DISABLE_ENCRYPTION_ONCE );
+                            session.write( buf );
+                        }
+                        else
+                        {
+                            super.messageReceived( session, message );
+                        }
+                    }
+                } );
                 socketBound = true;
 
                 registry.bind( datagramService, new EchoProtocolHandler() );

Modified: directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java?rev=328711&r1=328710&r2=328711&view=diff
==============================================================================
--- directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java (original)
+++ directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java Wed Oct 26 12:17:07 2005
@@ -33,10 +33,12 @@
 import org.apache.mina.common.TransportType;
 import org.apache.mina.common.WriteFuture;
 import org.apache.mina.examples.echoserver.ssl.BogusSSLContextFactory;
+import org.apache.mina.filter.LoggingFilter;
 import org.apache.mina.filter.SSLFilter;
 import org.apache.mina.transport.socket.nio.DatagramConnector;
 import org.apache.mina.transport.socket.nio.SocketConnector;
 import org.apache.mina.util.AvailablePortFinder;
+import org.apache.mina.util.SessionLog;
 
 /**
  * Tests echo server example.
@@ -128,7 +130,6 @@
     private void testConnector( IoConnector connector, SocketAddress localAddress ) throws Exception
     {
         EchoConnectorHandler handler = new EchoConnectorHandler();
-        ByteBuffer readBuf = handler.readBuf;
         ConnectFuture future = connector.connect(
                 new InetSocketAddress( InetAddress.getLocalHost(), port ),
                 localAddress,
@@ -136,32 +137,87 @@
         
         future.join();
         IoSession session = future.getSession();
+        testConnector0( session );
         
-        WriteFuture writeFuture = null;
-        for( int i = 0; i < 10; i ++ )
+        // Send closeNotify to test TLS closure if it is TLS connection.
+        SSLFilter sslf = ( SSLFilter ) connector.getFilterChain().get("SSL");
+        if( sslf != null )
         {
-            ByteBuffer buf = ByteBuffer.allocate( 16 );
-            buf.limit( 16 );
-            fillWriteBuffer( buf, i );
+            connector.getFilterChain().addFirst( "log", new LoggingFilter() );
+            sslf.stopSSL( session ).join();
+            
+            System.out.println( "-------------------------------------------------------------------------------" );
+            // Test again after we finished TLS session.
+            testConnector0( session );
+            
+            System.out.println( "-------------------------------------------------------------------------------" );
+            
+            // Test if we can enter TLS mode again.
+            //// Send StartTLS request.
+            handler.readBuf.clear();
+            ByteBuffer buf = ByteBuffer.allocate( 1 );
+            buf.put( ( byte ) '.' );
             buf.flip();
-
-            writeFuture = session.write( buf );
-
-            // This will align message arrival order in UDP
+            session.write( buf ).join();
+            
+            //// Wait for StartTLS response.
             for( int j = 0; j < 30; j ++ )
             {
-                if( readBuf.position() == ( i + 1 ) * 16 )
+                if( handler.readBuf.position() >= 1 )
                 {
                     break;
                 }
                 Thread.sleep( 10 );
             }
+
+            handler.readBuf.flip();
+            Assert.assertEquals( 1, handler.readBuf.remaining() );
+            Assert.assertEquals( ( byte ) '.', handler.readBuf.get() );
+            
+            // Now start TLS connection
+            Assert.assertTrue( sslf.startSSL( session ) );
+            testConnector0( session );
+            connector.getFilterChain().remove( "log" );
+        }
+        
+        session.close();
+    }
+    
+    private void testConnector0( IoSession session ) throws InterruptedException
+    {
+        final int COUNT = 10;
+        final int DATA_SIZE = 16;
+        EchoConnectorHandler handler = ( EchoConnectorHandler ) session.getHandler();
+        ByteBuffer readBuf = handler.readBuf;
+        readBuf.clear();
+        WriteFuture writeFuture = null;
+        for( int i = 0; i < COUNT; i ++ )
+        {
+            ByteBuffer buf = ByteBuffer.allocate( DATA_SIZE );
+            buf.limit( DATA_SIZE );
+            fillWriteBuffer( buf, i );
+            buf.flip();
+            
+            writeFuture = session.write( buf );
+            
+            if( session.getTransportType().isConnectionless() ) 
+            {
+                // This will align message arrival order in connectionless transport types
+                for( int j = 0; j < 30; j ++ )
+                {
+                    if( readBuf.position() == ( i + 1 ) * DATA_SIZE )
+                    {
+                        break;
+                    }
+                    Thread.sleep( 10 );
+                }
+            }
         }
         
         writeFuture.join();
 
         for( int i = 0; i < 30; i++ ) {
-            if( readBuf.position() >= 160 )
+            if( readBuf.position() >= DATA_SIZE * COUNT )
             {
                 break;
             }
@@ -172,66 +228,20 @@
         }
 
         // Assert data
-        Assert.assertEquals( 160, readBuf.position() );
+        //// Please note that BufferOverflowException can be thrown
+        //// in SocketIoProcessor if there was a read timeout because
+        //// we share readBuf.
         readBuf.flip();
-        ByteBuffer expectedBuf = ByteBuffer.allocate( 160 );
-        for( int i = 0; i < 10; i ++ ) {
-            expectedBuf.limit( ( i + 1 ) * 16 );
+        SessionLog.info( session, "readBuf: " + readBuf );
+        Assert.assertEquals( DATA_SIZE * COUNT, readBuf.remaining() );
+        ByteBuffer expectedBuf = ByteBuffer.allocate( DATA_SIZE * COUNT );
+        for( int i = 0; i < COUNT; i ++ ) {
+            expectedBuf.limit( ( i + 1 ) * DATA_SIZE );
             fillWriteBuffer( expectedBuf, i );
         }
         expectedBuf.position( 0 );
-        assertEquals(expectedBuf, readBuf);
-        
-        // Send closeNotify to test TLS closure.
-        SSLFilter sslf = ( SSLFilter ) connector.getFilterChain().get("SSL");
-        if( sslf != null )
-        {
-            //connector.getFilterChain().addFirst( "log", new LoggingFilter() );
-            sslf.stopSSL( session ).join();
-            //Thread.sleep( 1000 );
-            
-            // Test again after we finished SSL session.
-            readBuf.clear();
-            writeFuture = null;
-            for( int i = 0; i < 10; i ++ )
-            {
-                ByteBuffer buf = ByteBuffer.allocate( 16 );
-                buf.limit( 16 );
-                fillWriteBuffer( buf, i );
-                buf.flip();
-                
-                writeFuture = session.write( buf );
-            }
-            
-            writeFuture.join();
-
-            for( int i = 0; i < 30; i++ ) {
-                if( readBuf.position() >= 160 )
-                {
-                    break;
-                }
-                else
-                {
-                    Thread.sleep( 100 );
-                }
-            }
-
-            // Assert data
-            readBuf.flip();
-            System.out.println( readBuf );
-            Assert.assertEquals( 160, readBuf.remaining() );
-            expectedBuf = ByteBuffer.allocate( 160 );
-            for( int i = 0; i < 10; i ++ ) {
-                expectedBuf.limit( ( i + 1 ) * 16 );
-                fillWriteBuffer( expectedBuf, i );
-            }
-            expectedBuf.position( 0 );
-            
-            assertEquals(expectedBuf, readBuf);
-        }
         
-        
-        session.close();
+        assertEquals(expectedBuf, readBuf);
     }
 
     private void fillWriteBuffer( ByteBuffer writeBuf, int i )
@@ -249,7 +259,7 @@
     
     private static class EchoConnectorHandler extends IoHandlerAdapter
     {
-        private ByteBuffer readBuf = ByteBuffer.allocate( 1024 );
+        private ByteBuffer readBuf = ByteBuffer.allocate( 8192 );
 
         public void messageReceived( IoSession session, Object message )
         {