Commit 64c735bc authored by Tom Evans's avatar Tom Evans Committed by Dave Cridland

OF-857: Synchronize I/O for C2S connection

Use a lock to ensure the integrity of IoSession (MINA), especially when
using compression or TLS filters
parent ea81dc86
......@@ -19,9 +19,9 @@
package org.jivesoftware.openfire.nio;
import static org.jivesoftware.openfire.spi.ConnectionManagerImpl.COMPRESSION_FILTER_NAME;
import static org.jivesoftware.openfire.spi.ConnectionManagerImpl.EXECUTOR_FILTER_NAME;
import static org.jivesoftware.openfire.spi.ConnectionManagerImpl.TLS_FILTER_NAME;
import static org.jivesoftware.openfire.spi.ConnectionManagerImpl.COMPRESSION_FILTER_NAME;
import java.io.IOException;
import java.net.InetSocketAddress;
......@@ -31,6 +31,7 @@ import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.util.concurrent.Semaphore;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
......@@ -113,12 +114,18 @@ public class NIOConnection implements Connection {
* closed.
*/
private boolean closed;
/**
* Lock used to ensure the integrity of the underlying IoSession
* (refer to https://issues.apache.org/jira/browse/DIRMINA-653 for details)
*/
private Semaphore ioSessionLock;
public NIOConnection(IoSession session, PacketDeliverer packetDeliverer) {
this.ioSession = session;
this.backupDeliverer = packetDeliverer;
closed = false;
ioSessionLock = new Semaphore(1, true);
}
public boolean validate() {
......@@ -253,11 +260,13 @@ public class NIOConnection implements Connection {
backupDeliverer.deliver(packet);
}
else {
IoBuffer buffer = IoBuffer.allocate(4096);
buffer.setAutoExpand(true);
boolean errorDelivering = false;
try {
ioSessionLock.acquire();
IoBuffer buffer = IoBuffer.allocate(4096);
buffer.setAutoExpand(true);
// OF-464: if the connection has been dropped, fail over to backupDeliverer (offline)
if (!ioSession.isConnected()) {
throw new IOException("Connection reset/closed by peer");
......@@ -276,6 +285,9 @@ public class NIOConnection implements Connection {
Log.debug("Error delivering packet:\n" + packet, e);
errorDelivering = true;
}
finally {
ioSessionLock.release();
}
if (errorDelivering) {
close();
// Retry sending the packet again. Most probably if the packet is a
......@@ -295,11 +307,14 @@ public class NIOConnection implements Connection {
private void deliverRawText(String text, boolean asynchronous) {
if (!isClosed()) {
IoBuffer buffer = IoBuffer.allocate(text.length());
buffer.setAutoExpand(true);
boolean errorDelivering = false;
try {
ioSessionLock.acquire();
IoBuffer buffer = IoBuffer.allocate(text.length());
buffer.setAutoExpand(true);
//Charset charset = Charset.forName(CHARSET);
//buffer.putString(text, charset.newEncoder());
buffer.put(text.getBytes(CHARSET));
......@@ -327,6 +342,9 @@ public class NIOConnection implements Connection {
Log.debug("Error delivering raw text:\n" + text, e);
errorDelivering = true;
}
finally {
ioSessionLock.release();
}
// Close the connection if delivering text fails and we are already not closing the connection
if (errorDelivering && asynchronous) {
close();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment