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;