Skip to content
Snippets Groups Projects
Verified Commit 7c9b12a1 authored by bontric's avatar bontric Committed by Julian Dehm
Browse files

Implement END request to gravefully terminate mailbox sessions

parent 0054cd48
No related branches found
No related tags found
No related merge requests found
...@@ -11,6 +11,7 @@ import org.briarproject.bramble.api.transport.StreamWriter; ...@@ -11,6 +11,7 @@ import org.briarproject.bramble.api.transport.StreamWriter;
import org.briarproject.bramble.api.transport.StreamWriterFactory; import org.briarproject.bramble.api.transport.StreamWriterFactory;
import org.briarproject.bramble.mailbox.protocol.MailboxProtocol; import org.briarproject.bramble.mailbox.protocol.MailboxProtocol;
import org.briarproject.bramble.mailbox.protocol.MailboxRequest; import org.briarproject.bramble.mailbox.protocol.MailboxRequest;
import org.briarproject.bramble.mailbox.protocol.MailboxRequestEnd;
import org.briarproject.bramble.mailbox.protocol.MailboxRequestStore; import org.briarproject.bramble.mailbox.protocol.MailboxRequestStore;
import org.briarproject.bramble.mailbox.protocol.MailboxRequestSync; import org.briarproject.bramble.mailbox.protocol.MailboxRequestSync;
import org.briarproject.bramble.mailbox.protocol.MailboxRequestTake; import org.briarproject.bramble.mailbox.protocol.MailboxRequestTake;
...@@ -21,9 +22,11 @@ import java.io.EOFException; ...@@ -21,9 +22,11 @@ import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH; import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
...@@ -39,6 +42,10 @@ abstract class MailboxSession implements Runnable { ...@@ -39,6 +42,10 @@ abstract class MailboxSession implements Runnable {
private MailboxProtocol mailboxProtocol; private MailboxProtocol mailboxProtocol;
protected ContactId contactId; protected ContactId contactId;
// Used to handle graceful session termination with END request
private AtomicBoolean sessionFinished = new AtomicBoolean(false);
private boolean remoteSessionFinished = false;
public MailboxSession(Executor ioExecutor, KeyManager keyManager, public MailboxSession(Executor ioExecutor, KeyManager keyManager,
SyncSessionFactory syncSessionFactory, SyncSessionFactory syncSessionFactory,
StreamWriterFactory streamWriterFactory, StreamWriterFactory streamWriterFactory,
...@@ -97,53 +104,98 @@ abstract class MailboxSession implements Runnable { ...@@ -97,53 +104,98 @@ abstract class MailboxSession implements Runnable {
.run(); .run();
} }
public void run() {
//TODO: this is a little ugly..
ioExecutor.execute(() -> handleRequests());
}
private void handleRequests() {
MailboxRequest req;
/**
* Must be called if the session wants to receive and handle requests
*/
private void readRequests() {
while (running) { while (running) {
try { try {
req = mailboxProtocol.readNextRequest(); MailboxRequest req = mailboxProtocol.readNextRequest();
ioExecutor.execute(() -> handleRequest(req));
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
logException(LOG, INFO, e); logException(LOG, INFO, e);
running = false; running = false;
return; return;
} }
}
}
try { private void handleRequest(MailboxRequest req) {
switch (req.getType()) { try {
case STORE: switch (req.getType()) {
handleStore((MailboxRequestStore) req); case STORE:
case TAKE: handleStore((MailboxRequestStore) req);
handleTake((MailboxRequestTake) req); case TAKE:
break; handleTake((MailboxRequestTake) req);
case SYNC: break;
handleSync((MailboxRequestSync) req); case SYNC:
break; handleSync((MailboxRequestSync) req);
default: break;
throw new MailboxSessionHandleException( case END:
"Unsupported request type"); handleEnd((MailboxRequestEnd) req);
} default:
} catch (MailboxSessionHandleException e) { throw new MailboxSessionHandleException(
mailboxProtocol.writeErrorResponse(req, e.toString()); "Unsupported request type");
continue;
} }
} catch (MailboxSessionHandleException e) {
mailboxProtocol.writeErrorResponse(req, e.toString());
return;
}
mailboxProtocol.writeSucessResponse(req);
}
private void handleEnd(MailboxRequestEnd req) {
synchronized (sessionFinished) {
remoteSessionFinished = true;
while (!sessionFinished.get()) {
try {
sessionFinished.wait();
} catch (InterruptedException e) {
logException(LOG, WARNING, e);
mailboxProtocol.writeErrorResponse(req, e.toString());
return;
}
}
mailboxProtocol.writeSucessResponse(req); mailboxProtocol.writeSucessResponse(req);
} }
} }
public abstract void handleSync(MailboxRequestSync mailboxRequestSync) /**
* Must be called once at the end of a MailboxSession to signal the end to
* the peer. This call blocks until the remote session signals that
* the session has ended.
*/
protected void endSession()
throws InterruptedException, MailboxSessionHandleException {
synchronized (sessionFinished) {
sessionFinished.set(true);
sessionFinished.notifyAll();
if (remoteSessionFinished)
return;
}
MailboxRequest req = new MailboxRequestEnd();
req.awaitResponse();
if (!req.wasSuccessfull()) {
throw new MailboxSessionHandleException(req.getResponseError());
}
return;
}
public abstract void handleSync(MailboxRequestSync req)
throws MailboxSessionHandleException; throws MailboxSessionHandleException;
public abstract void handleStore(MailboxRequestStore mailboxRequestStore) public abstract void handleStore(MailboxRequestStore req)
throws MailboxSessionHandleException; throws MailboxSessionHandleException;
public abstract void handleTake(MailboxRequestTake mailboxRequestTake) public abstract void handleTake(MailboxRequestTake req)
throws MailboxSessionHandleException; throws MailboxSessionHandleException;
protected class MailboxSessionHandleException extends Exception { protected class MailboxSessionHandleException extends Exception {
......
...@@ -6,7 +6,7 @@ import org.briarproject.bramble.api.data.BdfList; ...@@ -6,7 +6,7 @@ import org.briarproject.bramble.api.data.BdfList;
/** /**
* This messages signals that the other party wishes to end the session * This messages signals that the other party wishes to end the session
*/ */
class MailboxRequestEnd extends MailboxRequest { public class MailboxRequestEnd extends MailboxRequest {
public MailboxRequestEnd() { public MailboxRequestEnd() {
super(TYPE.END); super(TYPE.END);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment