Author: trustin
Date: Tue Jul 17 20:12:23 2007
New Revision: 557130

URL: http://svn.apache.org/viewvc?view=rev&rev=557130
Log:
Fixed 'bad record MAC' message integrity error in SSLFilter, which is caused by 
simultaneous write that breaks message order.


Modified:
    
mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
    
mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
    
mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
    
mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
    mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
    
mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java

Modified: 
mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
URL: 
http://svn.apache.org/viewvc/mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java?view=diff&rev=557130&r1=557129&r2=557130
==============================================================================
--- 
mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
 (original)
+++ 
mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
 Tue Jul 17 20:12:23 2007
@@ -189,7 +189,7 @@
             }
         }
 
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
         return started;
     }
 
@@ -226,7 +226,7 @@
             future = initiateClosure(nextFilter, session);
         }
 
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
 
         return future;
     }
@@ -339,7 +339,7 @@
         synchronized (handler) {
             handler.handshake(nextFilter);
         }
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
     }
 
     public void onPreRemove(IoFilterChain parent, String name,
@@ -367,7 +367,7 @@
                 handler.destroy();
             }
 
-            handler.flushPostHandshakeEvents();
+            handler.flushScheduledEvents();
         } finally {
             // notify closed session
             nextFilter.sessionClosed(session);
@@ -379,7 +379,7 @@
         SSLHandler handler = getSSLSessionHandler(session);
         synchronized (handler) {
             if (!isSSLStarted(session) && handler.isInboundDone()) {
-                handler.schedulePostHandshakeMessage(nextFilter, message);
+                handler.scheduleMessageReceived(nextFilter, message);
             } else {
                 ByteBuffer buf = (ByteBuffer) message;
                 if (SessionLog.isDebugEnabled(session)) {
@@ -407,7 +407,7 @@
                         }
 
                         if (buf.hasRemaining()) {
-                            handler.schedulePostHandshakeMessage(nextFilter,
+                            handler.scheduleMessageReceived(nextFilter,
                                     buf);
                         }
                     }
@@ -424,7 +424,7 @@
             }
         }
 
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
     }
 
     public void messageSent(NextFilter nextFilter, IoSession session,
@@ -444,14 +444,14 @@
         SSLHandler handler = getSSLSessionHandler(session);
         synchronized (handler) {
             if (!isSSLStarted(session)) {
-                handler.schedulePostHandshakeWriteRequest(nextFilter,
+                handler.scheduleFilterWrite(nextFilter,
                         writeRequest);
             }
             // Don't encrypt the data if encryption is disabled.
             else if (session.containsAttribute(DISABLE_ENCRYPTION_ONCE)) {
                 // Remove the marker attribute because it is temporary.
                 session.removeAttribute(DISABLE_ENCRYPTION_ONCE);
-                handler.schedulePostHandshakeWriteRequest(nextFilter,
+                handler.scheduleFilterWrite(nextFilter,
                         writeRequest);
             } else {
                 // Otherwise, encrypt the buffer.
@@ -467,7 +467,7 @@
                         SessionLog.debug(session, "   already encrypted: "
                                 + buf);
                     }
-                    handler.schedulePostHandshakeWriteRequest(nextFilter,
+                    handler.scheduleFilterWrite(nextFilter,
                             writeRequest);
                 } else if (handler.isInitialHandshakeComplete()) {
                     // SSL encrypt
@@ -485,7 +485,7 @@
                         SessionLog.debug(session, " encrypted buf: "
                                 + encryptedBuffer);
                     }
-                    handler.schedulePostHandshakeWriteRequest(nextFilter,
+                    handler.scheduleFilterWrite(nextFilter,
                             new WriteRequest(encryptedBuffer, writeRequest
                                     .getFuture()));
                 } else {
@@ -509,7 +509,7 @@
         }
 
         if (needsFlush) {
-            handler.flushPostHandshakeEvents();
+            handler.flushScheduledEvents();
         }
     }
 
@@ -531,7 +531,7 @@
                 }
             }
 
-            handler.flushPostHandshakeEvents();
+            handler.flushScheduledEvents();
         } finally {
             if (future == null) {
                 nextFilter.filterClose(session);
@@ -561,7 +561,7 @@
         }
 
         if (session.containsAttribute(USE_NOTIFICATION)) {
-            handler.schedulePostHandshakeMessage(nextFilter, 
SESSION_UNSECURED);
+            handler.scheduleMessageReceived(nextFilter, SESSION_UNSECURED);
         }
 
         return future;
@@ -600,7 +600,7 @@
                     + readBuffer.getHexDump() + ')');
         }
 
-        handler.schedulePostHandshakeMessage(nextFilter, readBuffer);
+        handler.scheduleMessageReceived(nextFilter, readBuffer);
     }
 
     private SSLHandler getSSLSessionHandler(IoSession session) {

Modified: 
mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
URL: 
http://svn.apache.org/viewvc/mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java?view=diff&rev=557130&r1=557129&r2=557130
==============================================================================
--- 
mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
 (original)
+++ 
mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
 Tue Jul 17 20:12:23 2007
@@ -60,7 +60,9 @@
 
     private final Queue preHandshakeEventQueue = new LinkedList();
 
-    private final Queue postHandshakeEventQueue = new ConcurrentLinkedQueue();
+    private final Queue filterWriteEventQueue = new ConcurrentLinkedQueue();
+
+    private final Queue messageReceivedEventQueue = new 
ConcurrentLinkedQueue();
 
     private SSLEngine sslEngine;
 
@@ -240,33 +242,37 @@
         }
     }
 
-    public void schedulePostHandshakeWriteRequest(NextFilter nextFilter,
+    public void scheduleFilterWrite(NextFilter nextFilter,
             WriteRequest writeRequest) {
-        postHandshakeEventQueue.offer(new Event(EventType.FILTER_WRITE,
+        filterWriteEventQueue.offer(new Event(EventType.FILTER_WRITE,
                 nextFilter, writeRequest));
     }
 
-    public void schedulePostHandshakeMessage(NextFilter nextFilter,
+    public void scheduleMessageReceived(NextFilter nextFilter,
             Object message) {
-        postHandshakeEventQueue.offer(new Event(EventType.RECEIVED, nextFilter,
+        messageReceivedEventQueue.offer(new Event(EventType.RECEIVED, 
nextFilter,
                 message));
     }
 
-    public void flushPostHandshakeEvents() {
+    public void flushScheduledEvents() {
         // Fire events only when no lock is hold for this handler.
         if (Thread.holdsLock(this)) {
             return;
         }
 
         Event e;
-
-        while ((e = (Event) postHandshakeEventQueue.poll()) != null) {
-            if (EventType.RECEIVED == e.type) {
-                e.nextFilter.messageReceived(session, e.data);
-            } else {
+         
+        // We need synchronization here inevitably because filterWrite can be
+        // called simultaneously and cause 'bad record MAC' integrity error.
+        synchronized (this) {
+            while ((e = (Event) filterWriteEventQueue.poll()) != null) {
                 e.nextFilter.filterWrite(session, (WriteRequest) e.data);
             }
         }
+ 
+        while ((e = (Event) messageReceivedEventQueue.poll()) != null) {
+            e.nextFilter.messageReceived(session, e.data);
+        }
     }
 
     /**
@@ -466,7 +472,7 @@
                 }
                 initialHandshakeComplete = true;
                 if (session.containsAttribute(SSLFilter.USE_NOTIFICATION)) {
-                    schedulePostHandshakeMessage(nextFilter,
+                    scheduleMessageReceived(nextFilter,
                             SSLFilter.SESSION_SECURED);
                 }
                 break;

Modified: 
mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
URL: 
http://svn.apache.org/viewvc/mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java?view=diff&rev=557130&r1=557129&r2=557130
==============================================================================
--- 
mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
 (original)
+++ 
mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
 Tue Jul 17 20:12:23 2007
@@ -189,7 +189,7 @@
             }
         }
 
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
         return started;
     }
 
@@ -226,7 +226,7 @@
             future = initiateClosure(nextFilter, session);
         }
 
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
 
         return future;
     }
@@ -339,7 +339,7 @@
         synchronized (handler) {
             handler.handshake(nextFilter);
         }
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
     }
 
     public void onPreRemove(IoFilterChain parent, String name,
@@ -367,7 +367,7 @@
                 handler.destroy();
             }
 
-            handler.flushPostHandshakeEvents();
+            handler.flushScheduledEvents();
         } finally {
             // notify closed session
             nextFilter.sessionClosed(session);
@@ -379,7 +379,7 @@
         SSLHandler handler = getSSLSessionHandler(session);
         synchronized (handler) {
             if (!isSSLStarted(session) && handler.isInboundDone()) {
-                handler.schedulePostHandshakeMessage(nextFilter, message);
+                handler.scheduleMessageReceived(nextFilter, message);
             } else {
                 ByteBuffer buf = (ByteBuffer) message;
                 if (SessionLog.isDebugEnabled(session)) {
@@ -407,7 +407,7 @@
                         }
 
                         if (buf.hasRemaining()) {
-                            handler.schedulePostHandshakeMessage(nextFilter,
+                            handler.scheduleMessageReceived(nextFilter,
                                     buf);
                         }
                     }
@@ -424,7 +424,7 @@
             }
         }
 
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
     }
 
     public void messageSent(NextFilter nextFilter, IoSession session,
@@ -444,14 +444,14 @@
         SSLHandler handler = getSSLSessionHandler(session);
         synchronized (handler) {
             if (!isSSLStarted(session)) {
-                handler.schedulePostHandshakeWriteRequest(nextFilter,
+                handler.scheduleFilterWrite(nextFilter,
                         writeRequest);
             }
             // Don't encrypt the data if encryption is disabled.
             else if (session.containsAttribute(DISABLE_ENCRYPTION_ONCE)) {
                 // Remove the marker attribute because it is temporary.
                 session.removeAttribute(DISABLE_ENCRYPTION_ONCE);
-                handler.schedulePostHandshakeWriteRequest(nextFilter,
+                handler.scheduleFilterWrite(nextFilter,
                         writeRequest);
             } else {
                 // Otherwise, encrypt the buffer.
@@ -467,7 +467,7 @@
                         SessionLog.debug(session, "   already encrypted: "
                                 + buf);
                     }
-                    handler.schedulePostHandshakeWriteRequest(nextFilter,
+                    handler.scheduleFilterWrite(nextFilter,
                             writeRequest);
                 } else if (handler.isInitialHandshakeComplete()) {
                     // SSL encrypt
@@ -485,7 +485,7 @@
                         SessionLog.debug(session, " encrypted buf: "
                                 + encryptedBuffer);
                     }
-                    handler.schedulePostHandshakeWriteRequest(nextFilter,
+                    handler.scheduleFilterWrite(nextFilter,
                             new WriteRequest(encryptedBuffer, writeRequest
                                     .getFuture()));
                 } else {
@@ -509,7 +509,7 @@
         }
 
         if (needsFlush) {
-            handler.flushPostHandshakeEvents();
+            handler.flushScheduledEvents();
         }
     }
 
@@ -531,7 +531,7 @@
                 }
             }
 
-            handler.flushPostHandshakeEvents();
+            handler.flushScheduledEvents();
         } finally {
             if (future == null) {
                 nextFilter.filterClose(session);
@@ -561,7 +561,7 @@
         }
 
         if (session.containsAttribute(USE_NOTIFICATION)) {
-            handler.schedulePostHandshakeMessage(nextFilter, 
SESSION_UNSECURED);
+            handler.scheduleMessageReceived(nextFilter, SESSION_UNSECURED);
         }
 
         return future;
@@ -600,7 +600,7 @@
                     + readBuffer.getHexDump() + ')');
         }
 
-        handler.schedulePostHandshakeMessage(nextFilter, readBuffer);
+        handler.scheduleMessageReceived(nextFilter, readBuffer);
     }
 
     private SSLHandler getSSLSessionHandler(IoSession session) {

Modified: 
mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
URL: 
http://svn.apache.org/viewvc/mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java?view=diff&rev=557130&r1=557129&r2=557130
==============================================================================
--- 
mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
 (original)
+++ 
mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
 Tue Jul 17 20:12:23 2007
@@ -59,7 +59,9 @@
 
     private final Queue<Event> preHandshakeEventQueue = new 
LinkedList<Event>();
 
-    private final Queue<Event> postHandshakeEventQueue = new 
ConcurrentLinkedQueue<Event>();
+    private final Queue<Event> filterWriteEventQueue = new 
ConcurrentLinkedQueue<Event>();
+
+    private final Queue<Event> messageReceivedEventQueue = new 
ConcurrentLinkedQueue<Event>();
 
     private SSLEngine sslEngine;
 
@@ -239,33 +241,37 @@
         }
     }
 
-    public void schedulePostHandshakeWriteRequest(NextFilter nextFilter,
+    public void scheduleFilterWrite(NextFilter nextFilter,
             WriteRequest writeRequest) {
-        postHandshakeEventQueue.offer(new Event(EventType.FILTER_WRITE,
+        filterWriteEventQueue.offer(new Event(EventType.FILTER_WRITE,
                 nextFilter, writeRequest));
     }
 
-    public void schedulePostHandshakeMessage(NextFilter nextFilter,
+    public void scheduleMessageReceived(NextFilter nextFilter,
             Object message) {
-        postHandshakeEventQueue.offer(new Event(EventType.RECEIVED, nextFilter,
+        messageReceivedEventQueue.offer(new Event(EventType.RECEIVED, 
nextFilter,
                 message));
     }
-
-    public void flushPostHandshakeEvents() {
+    
+    public void flushScheduledEvents() {
         // Fire events only when no lock is hold for this handler.
         if (Thread.holdsLock(this)) {
             return;
         }
 
         Event e;
-
-        while ((e = postHandshakeEventQueue.poll()) != null) {
-            if (EventType.RECEIVED == e.type) {
-                e.nextFilter.messageReceived(session, e.data);
-            } else {
+        
+        // We need synchronization here inevitably because filterWrite can be
+        // called simultaneously and cause 'bad record MAC' integrity error.
+        synchronized (this) {
+            while ((e = filterWriteEventQueue.poll()) != null) {
                 e.nextFilter.filterWrite(session, (WriteRequest) e.data);
             }
         }
+
+        while ((e = messageReceivedEventQueue.poll()) != null) {
+            e.nextFilter.messageReceived(session, e.data);
+        }
     }
 
     /**
@@ -463,7 +469,7 @@
                 }
                 initialHandshakeComplete = true;
                 if (session.containsAttribute(SSLFilter.USE_NOTIFICATION)) {
-                    schedulePostHandshakeMessage(nextFilter,
+                    scheduleMessageReceived(nextFilter,
                             SSLFilter.SESSION_SECURED);
                 }
                 break;

Modified: 
mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java?view=diff&rev=557130&r1=557129&r2=557130
==============================================================================
--- mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java 
(original)
+++ mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java 
Tue Jul 17 20:12:23 2007
@@ -220,7 +220,7 @@
             }
         }
 
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
         return started;
     }
 
@@ -257,7 +257,7 @@
             future = initiateClosure(nextFilter, session);
         }
 
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
 
         return future;
     }
@@ -400,7 +400,7 @@
                 handler.destroy();
             }
 
-            handler.flushPostHandshakeEvents();
+            handler.flushScheduledEvents();
         } finally {
             // notify closed session
             nextFilter.sessionClosed(session);
@@ -413,7 +413,7 @@
         SSLHandler handler = getSSLSessionHandler(session);
         synchronized (handler) {
             if (!isSSLStarted(session) && handler.isInboundDone()) {
-                handler.schedulePostHandshakeMessage(nextFilter, message);
+                handler.scheduleMessageReceived(nextFilter, message);
             } else {
                 ByteBuffer buf = (ByteBuffer) message;
                 if (SessionLog.isDebugEnabled(session)) {
@@ -441,7 +441,7 @@
                         }
 
                         if (buf.hasRemaining()) {
-                            handler.schedulePostHandshakeMessage(nextFilter,
+                            handler.scheduleMessageReceived(nextFilter,
                                     buf);
                         }
                     }
@@ -458,7 +458,7 @@
             }
         }
 
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
     }
 
     @Override
@@ -479,14 +479,14 @@
         SSLHandler handler = getSSLSessionHandler(session);
         synchronized (handler) {
             if (!isSSLStarted(session)) {
-                handler.schedulePostHandshakeWriteRequest(nextFilter,
+                handler.scheduleFilterWrite(nextFilter,
                         writeRequest);
             }
             // Don't encrypt the data if encryption is disabled.
             else if (session.containsAttribute(DISABLE_ENCRYPTION_ONCE)) {
                 // Remove the marker attribute because it is temporary.
                 session.removeAttribute(DISABLE_ENCRYPTION_ONCE);
-                handler.schedulePostHandshakeWriteRequest(nextFilter,
+                handler.scheduleFilterWrite(nextFilter,
                         writeRequest);
             } else {
                 // Otherwise, encrypt the buffer.
@@ -502,7 +502,7 @@
                         SessionLog.debug(session, "   already encrypted: "
                                 + buf);
                     }
-                    handler.schedulePostHandshakeWriteRequest(nextFilter,
+                    handler.scheduleFilterWrite(nextFilter,
                             writeRequest);
                 } else if (handler.isInitialHandshakeComplete()) {
                     // SSL encrypt
@@ -520,7 +520,7 @@
                         SessionLog.debug(session, " encrypted buf: "
                                 + encryptedBuffer);
                     }
-                    handler.schedulePostHandshakeWriteRequest(nextFilter,
+                    handler.scheduleFilterWrite(nextFilter,
                             new EncryptedWriteRequest(writeRequest,
                                     encryptedBuffer));
                 } else {
@@ -544,7 +544,7 @@
         }
 
         if (needsFlush) {
-            handler.flushPostHandshakeEvents();
+            handler.flushScheduledEvents();
         }
     }
 
@@ -567,7 +567,7 @@
                 }
             }
 
-            handler.flushPostHandshakeEvents();
+            handler.flushScheduledEvents();
         } finally {
             if (future == null) {
                 nextFilter.filterClose(session);
@@ -587,7 +587,7 @@
         synchronized (handler) {
             handler.handshake(nextFilter);
         }
-        handler.flushPostHandshakeEvents();
+        handler.flushScheduledEvents();
     }
     
     private WriteFuture initiateClosure(NextFilter nextFilter, IoSession 
session)
@@ -606,7 +606,7 @@
         }
 
         if (session.containsAttribute(USE_NOTIFICATION)) {
-            handler.schedulePostHandshakeMessage(nextFilter, 
SESSION_UNSECURED);
+            handler.scheduleMessageReceived(nextFilter, SESSION_UNSECURED);
         }
 
         return future;
@@ -645,7 +645,7 @@
                     + readBuffer.getHexDump() + ')');
         }
 
-        handler.schedulePostHandshakeMessage(nextFilter, readBuffer);
+        handler.scheduleMessageReceived(nextFilter, readBuffer);
     }
 
     private SSLHandler getSSLSessionHandler(IoSession session) {

Modified: 
mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java?view=diff&rev=557130&r1=557129&r2=557130
==============================================================================
--- 
mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
 (original)
+++ 
mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
 Tue Jul 17 20:12:23 2007
@@ -63,7 +63,9 @@
 
     private final Queue<IoFilterEvent> preHandshakeEventQueue = new 
LinkedList<IoFilterEvent>();
 
-    private final Queue<IoFilterEvent> postHandshakeEventQueue = new 
ConcurrentLinkedQueue<IoFilterEvent>();
+    private final Queue<IoFilterEvent> filterWriteEventQueue = new 
ConcurrentLinkedQueue<IoFilterEvent>();
+    
+    private final Queue<IoFilterEvent> messageReceivedEventQueue = new 
ConcurrentLinkedQueue<IoFilterEvent>();
 
     private SSLEngine sslEngine;
 
@@ -246,34 +248,37 @@
         }
     }
 
-    public void schedulePostHandshakeWriteRequest(NextFilter nextFilter,
+    public void scheduleFilterWrite(NextFilter nextFilter,
             WriteRequest writeRequest) {
-        postHandshakeEventQueue.offer(new IoFilterEvent(nextFilter,
+        filterWriteEventQueue.offer(new IoFilterEvent(nextFilter,
                 IoEventType.WRITE, session, writeRequest));
     }
 
-    public void schedulePostHandshakeMessage(NextFilter nextFilter,
+    public void scheduleMessageReceived(NextFilter nextFilter,
             Object message) {
-        postHandshakeEventQueue.offer(new IoFilterEvent(nextFilter,
+        messageReceivedEventQueue.offer(new IoFilterEvent(nextFilter,
                 IoEventType.MESSAGE_RECEIVED, session, message));
     }
 
-    public void flushPostHandshakeEvents() {
+    public void flushScheduledEvents() {
         // Fire events only when no lock is hold for this handler.
         if (Thread.holdsLock(this)) {
             return;
         }
 
         IoFilterEvent e;
-
-        while ((e = postHandshakeEventQueue.poll()) != null) {
-            if (IoEventType.MESSAGE_RECEIVED == e.getType()) {
-                e.getNextFilter().messageReceived(session, e.getParameter());
-            } else {
-                e.getNextFilter().filterWrite(session,
-                        (WriteRequest) e.getParameter());
+        
+        // We need synchronization here inevitably because filterWrite can be
+        // called simultaneously and cause 'bad record MAC' integrity error.
+        synchronized (this) {
+            while ((e = filterWriteEventQueue.poll()) != null) {
+                e.getNextFilter().filterWrite(session, (WriteRequest) 
e.getParameter());
             }
         }
+
+        while ((e = messageReceivedEventQueue.poll()) != null) {
+            e.getNextFilter().messageReceived(session, e.getParameter());
+        }
     }
 
     /**
@@ -471,7 +476,7 @@
                 }
                 initialHandshakeComplete = true;
                 if (session.containsAttribute(SSLFilter.USE_NOTIFICATION)) {
-                    schedulePostHandshakeMessage(nextFilter,
+                    scheduleMessageReceived(nextFilter,
                             SSLFilter.SESSION_SECURED);
                 }
                 break;


Reply via email to