mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Merge branch '628-bring-protocols-into-line-with-spec' into 'master'
Bring protocols in line with spec Closes #628 See merge request !465
This commit is contained in:
@@ -3,7 +3,7 @@ package org.briarproject.bramble.api.sync;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A packet acknowledging receipt of one or more {@link Message Messages}.
|
||||
* A record acknowledging receipt of one or more {@link Message Messages}.
|
||||
*/
|
||||
public class Ack {
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.briarproject.bramble.api.sync;
|
||||
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
||||
|
||||
public class Group {
|
||||
|
||||
public enum Visibility {
|
||||
@@ -13,6 +15,8 @@ public class Group {
|
||||
private final byte[] descriptor;
|
||||
|
||||
public Group(GroupId id, ClientId clientId, byte[] descriptor) {
|
||||
if (descriptor.length > MAX_GROUP_DESCRIPTOR_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
this.id = id;
|
||||
this.clientId = clientId;
|
||||
this.descriptor = descriptor;
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.briarproject.bramble.api.sync;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A packet offering the recipient one or more {@link Message Messages}.
|
||||
* A record offering the recipient one or more {@link Message Messages}.
|
||||
*/
|
||||
public class Offer {
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import java.io.IOException;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface PacketReader {
|
||||
public interface RecordReader {
|
||||
|
||||
boolean eof() throws IOException;
|
||||
|
||||
@@ -24,4 +24,5 @@ public interface PacketReader {
|
||||
boolean hasRequest() throws IOException;
|
||||
|
||||
Request readRequest() throws IOException;
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import java.io.InputStream;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface PacketReaderFactory {
|
||||
public interface RecordReaderFactory {
|
||||
|
||||
PacketReader createPacketReader(InputStream in);
|
||||
RecordReader createRecordReader(InputStream in);
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
package org.briarproject.bramble.api.sync;
|
||||
|
||||
/**
|
||||
* Packet types for the sync protocol.
|
||||
* Record types for the sync protocol.
|
||||
*/
|
||||
public interface PacketTypes {
|
||||
public interface RecordTypes {
|
||||
|
||||
byte ACK = 0;
|
||||
byte MESSAGE = 1;
|
||||
byte OFFER = 2;
|
||||
byte REQUEST = 3;
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import java.io.IOException;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface PacketWriter {
|
||||
public interface RecordWriter {
|
||||
|
||||
void writeAck(Ack a) throws IOException;
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import java.io.OutputStream;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface PacketWriterFactory {
|
||||
public interface RecordWriterFactory {
|
||||
|
||||
PacketWriter createPacketWriter(OutputStream out);
|
||||
RecordWriter createRecordWriter(OutputStream out);
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package org.briarproject.bramble.api.sync;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A packet requesting one or more {@link Message Messages} from the recipient.
|
||||
* A record requesting one or more {@link Message Messages} from the recipient.
|
||||
*/
|
||||
public class Request {
|
||||
|
||||
|
||||
@@ -10,19 +10,17 @@ public interface SyncConstants {
|
||||
byte PROTOCOL_VERSION = 0;
|
||||
|
||||
/**
|
||||
* The length of the packet header in bytes.
|
||||
* The length of the record header in bytes.
|
||||
*/
|
||||
int PACKET_HEADER_LENGTH = 4;
|
||||
int RECORD_HEADER_LENGTH = 4;
|
||||
|
||||
/**
|
||||
* The maximum length of the packet payload in bytes.
|
||||
* The maximum length of the record payload in bytes.
|
||||
*/
|
||||
int MAX_PACKET_PAYLOAD_LENGTH = 32 * 1024; // 32 KiB
|
||||
int MAX_RECORD_PAYLOAD_LENGTH = 48 * 1024; // 48 KiB
|
||||
|
||||
/**
|
||||
* The maximum length of a message in bytes.
|
||||
*/
|
||||
int MAX_MESSAGE_LENGTH = MAX_PACKET_PAYLOAD_LENGTH - PACKET_HEADER_LENGTH;
|
||||
/** The maximum length of a group descriptor in bytes. */
|
||||
int MAX_GROUP_DESCRIPTOR_LENGTH = 16 * 1024; // 16 KiB
|
||||
|
||||
/**
|
||||
* The length of the message header in bytes.
|
||||
@@ -32,10 +30,15 @@ public interface SyncConstants {
|
||||
/**
|
||||
* The maximum length of a message body in bytes.
|
||||
*/
|
||||
int MAX_MESSAGE_BODY_LENGTH = MAX_MESSAGE_LENGTH - MESSAGE_HEADER_LENGTH;
|
||||
int MAX_MESSAGE_BODY_LENGTH = 32 * 1024; // 32 KiB
|
||||
|
||||
/**
|
||||
* The maximum number of message IDs in an ack, offer or request packet.
|
||||
* The maximum length of a message in bytes.
|
||||
*/
|
||||
int MAX_MESSAGE_IDS = MAX_PACKET_PAYLOAD_LENGTH / UniqueId.LENGTH;
|
||||
int MAX_MESSAGE_LENGTH = MESSAGE_HEADER_LENGTH + MAX_MESSAGE_BODY_LENGTH;
|
||||
|
||||
/**
|
||||
* The maximum number of message IDs in an ack, offer or request record.
|
||||
*/
|
||||
int MAX_MESSAGE_IDS = MAX_RECORD_PAYLOAD_LENGTH / UniqueId.LENGTH;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import java.io.IOException;
|
||||
public interface SyncSession {
|
||||
|
||||
/**
|
||||
* Runs the session. This method returns when there are no more packets to
|
||||
* Runs the session. This method returns when there are no more records to
|
||||
* send or receive, or when the {@link #interrupt()} method has been called.
|
||||
*/
|
||||
void run() throws IOException;
|
||||
|
||||
@@ -52,7 +52,7 @@ class KeyAgreementProtocol {
|
||||
|
||||
void connectionWaiting();
|
||||
|
||||
void initialPacketReceived();
|
||||
void initialRecordReceived();
|
||||
}
|
||||
|
||||
private final Callbacks callbacks;
|
||||
@@ -117,7 +117,7 @@ class KeyAgreementProtocol {
|
||||
|
||||
private byte[] receiveKey() throws AbortException {
|
||||
byte[] publicKey = transport.receiveKey();
|
||||
callbacks.initialPacketReceived();
|
||||
callbacks.initialRecordReceived();
|
||||
byte[] expected = crypto.deriveKeyCommitment(publicKey);
|
||||
if (!Arrays.equals(expected, theirPayload.getCommitment()))
|
||||
throw new AbortException();
|
||||
|
||||
@@ -129,7 +129,7 @@ class KeyAgreementTaskImpl extends Thread implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialPacketReceived() {
|
||||
public void initialRecordReceived() {
|
||||
// We send this here instead of when we create the protocol, so that
|
||||
// if device A makes a connection after getting device B's payload and
|
||||
// starts its protocol, device A's UI doesn't change to prevent device B
|
||||
|
||||
@@ -95,20 +95,34 @@ class KeyAgreementTransport {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
private byte[] readRecord(byte type) throws AbortException {
|
||||
byte[] header = readHeader();
|
||||
if (header[0] != PROTOCOL_VERSION)
|
||||
throw new AbortException(); // TODO handle?
|
||||
if (header[1] != type) {
|
||||
// Unexpected packet
|
||||
throw new AbortException(header[1] == ABORT);
|
||||
}
|
||||
int len = ByteUtils.readUint16(header,
|
||||
RECORD_HEADER_PAYLOAD_LENGTH_OFFSET);
|
||||
try {
|
||||
return readData(len);
|
||||
} catch (IOException e) {
|
||||
throw new AbortException(e);
|
||||
private byte[] readRecord(byte expectedType) throws AbortException {
|
||||
while (true) {
|
||||
byte[] header = readHeader();
|
||||
int len = ByteUtils.readUint16(header,
|
||||
RECORD_HEADER_PAYLOAD_LENGTH_OFFSET);
|
||||
if (header[0] != PROTOCOL_VERSION) {
|
||||
throw new AbortException(false);
|
||||
}
|
||||
byte type = header[1];
|
||||
if (type == ABORT) throw new AbortException(true);
|
||||
if (type != expectedType) {
|
||||
if (type != KEY && type != CONFIRM) {
|
||||
// ignore unrecognised record and try next
|
||||
try {
|
||||
readData(len);
|
||||
} catch (IOException e) {
|
||||
throw new AbortException(e);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
throw new AbortException(false);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return readData(len);
|
||||
} catch (IOException e) {
|
||||
throw new AbortException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.briarproject.bramble.api.lifecycle.event.ShutdownEvent;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Ack;
|
||||
import org.briarproject.bramble.api.sync.Offer;
|
||||
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
||||
import org.briarproject.bramble.api.sync.Request;
|
||||
import org.briarproject.bramble.api.sync.SyncSession;
|
||||
import org.briarproject.bramble.api.sync.event.GroupVisibilityUpdatedEvent;
|
||||
@@ -37,19 +37,19 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
||||
|
||||
/**
|
||||
* An outgoing {@link SyncSession} suitable for duplex transports. The session
|
||||
* offers messages before sending them, keeps its output stream open when there
|
||||
* are no packets to send, and reacts to events that make packets available to
|
||||
* are no records to send, and reacts to events that make records available to
|
||||
* send.
|
||||
*/
|
||||
@ThreadSafe
|
||||
@NotNullByDefault
|
||||
class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
|
||||
// Check for retransmittable packets once every 60 seconds
|
||||
// Check for retransmittable records once every 60 seconds
|
||||
private static final int RETX_QUERY_INTERVAL = 60 * 1000;
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(DuplexOutgoingSession.class.getName());
|
||||
@@ -67,14 +67,14 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
private final Clock clock;
|
||||
private final ContactId contactId;
|
||||
private final int maxLatency, maxIdleTime;
|
||||
private final PacketWriter packetWriter;
|
||||
private final RecordWriter recordWriter;
|
||||
private final BlockingQueue<ThrowingRunnable<IOException>> writerTasks;
|
||||
|
||||
private volatile boolean interrupted = false;
|
||||
|
||||
DuplexOutgoingSession(DatabaseComponent db, Executor dbExecutor,
|
||||
EventBus eventBus, Clock clock, ContactId contactId, int maxLatency,
|
||||
int maxIdleTime, PacketWriter packetWriter) {
|
||||
int maxIdleTime, RecordWriter recordWriter) {
|
||||
this.db = db;
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.eventBus = eventBus;
|
||||
@@ -82,7 +82,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
this.contactId = contactId;
|
||||
this.maxLatency = maxLatency;
|
||||
this.maxIdleTime = maxIdleTime;
|
||||
this.packetWriter = packetWriter;
|
||||
this.recordWriter = recordWriter;
|
||||
writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
public void run() throws IOException {
|
||||
eventBus.addListener(this);
|
||||
try {
|
||||
// Start a query for each type of packet
|
||||
// Start a query for each type of record
|
||||
dbExecutor.execute(new GenerateAck());
|
||||
dbExecutor.execute(new GenerateBatch());
|
||||
dbExecutor.execute(new GenerateOffer());
|
||||
@@ -100,33 +100,33 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
long nextKeepalive = now + maxIdleTime;
|
||||
long nextRetxQuery = now + RETX_QUERY_INTERVAL;
|
||||
boolean dataToFlush = true;
|
||||
// Write packets until interrupted
|
||||
// Write records until interrupted
|
||||
try {
|
||||
while (!interrupted) {
|
||||
// Work out how long we should wait for a packet
|
||||
// Work out how long we should wait for a record
|
||||
now = clock.currentTimeMillis();
|
||||
long wait = Math.min(nextKeepalive, nextRetxQuery) - now;
|
||||
if (wait < 0) wait = 0;
|
||||
// Flush any unflushed data if we're going to wait
|
||||
if (wait > 0 && dataToFlush && writerTasks.isEmpty()) {
|
||||
packetWriter.flush();
|
||||
recordWriter.flush();
|
||||
dataToFlush = false;
|
||||
nextKeepalive = now + maxIdleTime;
|
||||
}
|
||||
// Wait for a packet
|
||||
// Wait for a record
|
||||
ThrowingRunnable<IOException> task = writerTasks.poll(wait,
|
||||
MILLISECONDS);
|
||||
if (task == null) {
|
||||
now = clock.currentTimeMillis();
|
||||
if (now >= nextRetxQuery) {
|
||||
// Check for retransmittable packets
|
||||
// Check for retransmittable records
|
||||
dbExecutor.execute(new GenerateBatch());
|
||||
dbExecutor.execute(new GenerateOffer());
|
||||
nextRetxQuery = now + RETX_QUERY_INTERVAL;
|
||||
}
|
||||
if (now >= nextKeepalive) {
|
||||
// Flush the stream to keep it alive
|
||||
packetWriter.flush();
|
||||
recordWriter.flush();
|
||||
dataToFlush = false;
|
||||
nextKeepalive = now + maxIdleTime;
|
||||
}
|
||||
@@ -137,9 +137,9 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
dataToFlush = true;
|
||||
}
|
||||
}
|
||||
if (dataToFlush) packetWriter.flush();
|
||||
if (dataToFlush) recordWriter.flush();
|
||||
} catch (InterruptedException e) {
|
||||
LOG.info("Interrupted while waiting for a packet to write");
|
||||
LOG.info("Interrupted while waiting for a record to write");
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
} finally {
|
||||
@@ -215,7 +215,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
if (interrupted) return;
|
||||
packetWriter.writeAck(ack);
|
||||
recordWriter.writeAck(ack);
|
||||
LOG.info("Sent ack");
|
||||
dbExecutor.execute(new GenerateAck());
|
||||
}
|
||||
@@ -232,7 +232,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
b = db.generateRequestedBatch(txn, contactId,
|
||||
MAX_PACKET_PAYLOAD_LENGTH, maxLatency);
|
||||
MAX_RECORD_PAYLOAD_LENGTH, maxLatency);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
@@ -259,7 +259,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
if (interrupted) return;
|
||||
for (byte[] raw : batch) packetWriter.writeMessage(raw);
|
||||
for (byte[] raw : batch) recordWriter.writeMessage(raw);
|
||||
LOG.info("Sent batch");
|
||||
dbExecutor.execute(new GenerateBatch());
|
||||
}
|
||||
@@ -303,7 +303,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
if (interrupted) return;
|
||||
packetWriter.writeOffer(offer);
|
||||
recordWriter.writeOffer(offer);
|
||||
LOG.info("Sent offer");
|
||||
dbExecutor.execute(new GenerateOffer());
|
||||
}
|
||||
@@ -346,7 +346,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
if (interrupted) return;
|
||||
packetWriter.writeRequest(request);
|
||||
recordWriter.writeRequest(request);
|
||||
LOG.info("Sent request");
|
||||
dbExecutor.execute(new GenerateRequest());
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Ack;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.Offer;
|
||||
import org.briarproject.bramble.api.sync.PacketReader;
|
||||
import org.briarproject.bramble.api.sync.RecordReader;
|
||||
import org.briarproject.bramble.api.sync.Request;
|
||||
import org.briarproject.bramble.api.sync.SyncSession;
|
||||
|
||||
@@ -42,18 +42,18 @@ class IncomingSession implements SyncSession, EventListener {
|
||||
private final Executor dbExecutor;
|
||||
private final EventBus eventBus;
|
||||
private final ContactId contactId;
|
||||
private final PacketReader packetReader;
|
||||
private final RecordReader recordReader;
|
||||
|
||||
private volatile boolean interrupted = false;
|
||||
|
||||
IncomingSession(DatabaseComponent db, Executor dbExecutor,
|
||||
EventBus eventBus, ContactId contactId,
|
||||
PacketReader packetReader) {
|
||||
RecordReader recordReader) {
|
||||
this.db = db;
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.eventBus = eventBus;
|
||||
this.contactId = contactId;
|
||||
this.packetReader = packetReader;
|
||||
this.recordReader = recordReader;
|
||||
}
|
||||
|
||||
@IoExecutor
|
||||
@@ -61,21 +61,22 @@ class IncomingSession implements SyncSession, EventListener {
|
||||
public void run() throws IOException {
|
||||
eventBus.addListener(this);
|
||||
try {
|
||||
// Read packets until interrupted or EOF
|
||||
while (!interrupted && !packetReader.eof()) {
|
||||
if (packetReader.hasAck()) {
|
||||
Ack a = packetReader.readAck();
|
||||
// Read records until interrupted or EOF
|
||||
while (!interrupted && !recordReader.eof()) {
|
||||
if (recordReader.hasAck()) {
|
||||
Ack a = recordReader.readAck();
|
||||
dbExecutor.execute(new ReceiveAck(a));
|
||||
} else if (packetReader.hasMessage()) {
|
||||
Message m = packetReader.readMessage();
|
||||
} else if (recordReader.hasMessage()) {
|
||||
Message m = recordReader.readMessage();
|
||||
dbExecutor.execute(new ReceiveMessage(m));
|
||||
} else if (packetReader.hasOffer()) {
|
||||
Offer o = packetReader.readOffer();
|
||||
} else if (recordReader.hasOffer()) {
|
||||
Offer o = recordReader.readOffer();
|
||||
dbExecutor.execute(new ReceiveOffer(o));
|
||||
} else if (packetReader.hasRequest()) {
|
||||
Request r = packetReader.readRequest();
|
||||
} else if (recordReader.hasRequest()) {
|
||||
Request r = recordReader.readRequest();
|
||||
dbExecutor.execute(new ReceiveRequest(r));
|
||||
} else {
|
||||
// unknown records are ignored in RecordReader#eof()
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,15 @@ class MessageFactoryImpl implements MessageFactory {
|
||||
public Message createMessage(GroupId g, long timestamp, byte[] body) {
|
||||
if (body.length > MAX_MESSAGE_BODY_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
byte[] timeBytes = new byte[ByteUtils.INT_64_BYTES];
|
||||
ByteUtils.writeUint64(timestamp, timeBytes, 0);
|
||||
byte[] idHash =
|
||||
crypto.hash(MessageId.LABEL, g.getBytes(), timeBytes, body);
|
||||
MessageId id = new MessageId(idHash);
|
||||
byte[] raw = new byte[MESSAGE_HEADER_LENGTH + body.length];
|
||||
System.arraycopy(g.getBytes(), 0, raw, 0, UniqueId.LENGTH);
|
||||
ByteUtils.writeUint64(timestamp, raw, UniqueId.LENGTH);
|
||||
System.arraycopy(body, 0, raw, MESSAGE_HEADER_LENGTH, body.length);
|
||||
MessageId id = new MessageId(crypto.hash(MessageId.LABEL, raw));
|
||||
return new Message(id, g, timestamp, raw);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package org.briarproject.bramble.sync;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.PacketReader;
|
||||
import org.briarproject.bramble.api.sync.PacketReaderFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class PacketReaderFactoryImpl implements PacketReaderFactory {
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
|
||||
@Inject
|
||||
PacketReaderFactoryImpl(CryptoComponent crypto) {
|
||||
this.crypto = crypto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketReader createPacketReader(InputStream in) {
|
||||
return new PacketReaderImpl(crypto, in);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package org.briarproject.bramble.sync;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||
import org.briarproject.bramble.api.sync.PacketWriterFactory;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
@NotNullByDefault
|
||||
class PacketWriterFactoryImpl implements PacketWriterFactory {
|
||||
|
||||
@Override
|
||||
public PacketWriter createPacketWriter(OutputStream out) {
|
||||
return new PacketWriterImpl(out);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.briarproject.bramble.sync;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||
import org.briarproject.bramble.api.sync.RecordReader;
|
||||
import org.briarproject.bramble.api.sync.RecordReaderFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class RecordReaderFactoryImpl implements RecordReaderFactory {
|
||||
|
||||
private final MessageFactory messageFactory;
|
||||
|
||||
@Inject
|
||||
RecordReaderFactoryImpl(MessageFactory messageFactory) {
|
||||
this.messageFactory = messageFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecordReader createRecordReader(InputStream in) {
|
||||
return new RecordReaderImpl(messageFactory, in);
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,14 @@ package org.briarproject.bramble.sync;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.UniqueId;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Ack;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.sync.Offer;
|
||||
import org.briarproject.bramble.api.sync.PacketReader;
|
||||
import org.briarproject.bramble.api.sync.RecordReader;
|
||||
import org.briarproject.bramble.api.sync.Request;
|
||||
import org.briarproject.bramble.util.ByteUtils;
|
||||
|
||||
@@ -20,66 +20,83 @@ import java.util.List;
|
||||
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
import static org.briarproject.bramble.api.sync.PacketTypes.ACK;
|
||||
import static org.briarproject.bramble.api.sync.PacketTypes.MESSAGE;
|
||||
import static org.briarproject.bramble.api.sync.PacketTypes.OFFER;
|
||||
import static org.briarproject.bramble.api.sync.PacketTypes.REQUEST;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.RecordTypes.ACK;
|
||||
import static org.briarproject.bramble.api.sync.RecordTypes.MESSAGE;
|
||||
import static org.briarproject.bramble.api.sync.RecordTypes.OFFER;
|
||||
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.PACKET_HEADER_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.RECORD_HEADER_LENGTH;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
class PacketReaderImpl implements PacketReader {
|
||||
class RecordReaderImpl implements RecordReader {
|
||||
|
||||
private enum State { BUFFER_EMPTY, BUFFER_FULL, EOF }
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final MessageFactory messageFactory;
|
||||
private final InputStream in;
|
||||
private final byte[] header, payload;
|
||||
|
||||
private State state = State.BUFFER_EMPTY;
|
||||
private int payloadLength = 0;
|
||||
|
||||
PacketReaderImpl(CryptoComponent crypto, InputStream in) {
|
||||
this.crypto = crypto;
|
||||
RecordReaderImpl(MessageFactory messageFactory, InputStream in) {
|
||||
this.messageFactory = messageFactory;
|
||||
this.in = in;
|
||||
header = new byte[PACKET_HEADER_LENGTH];
|
||||
payload = new byte[MAX_PACKET_PAYLOAD_LENGTH];
|
||||
header = new byte[RECORD_HEADER_LENGTH];
|
||||
payload = new byte[MAX_RECORD_PAYLOAD_LENGTH];
|
||||
}
|
||||
|
||||
private void readPacket() throws IOException {
|
||||
private void readRecord() throws IOException {
|
||||
if (state != State.BUFFER_EMPTY) throw new IllegalStateException();
|
||||
// Read the header
|
||||
int offset = 0;
|
||||
while (offset < PACKET_HEADER_LENGTH) {
|
||||
int read = in.read(header, offset, PACKET_HEADER_LENGTH - offset);
|
||||
if (read == -1) {
|
||||
if (offset > 0) throw new FormatException();
|
||||
state = State.EOF;
|
||||
while (true) {
|
||||
// Read the header
|
||||
int offset = 0;
|
||||
while (offset < RECORD_HEADER_LENGTH) {
|
||||
int read =
|
||||
in.read(header, offset, RECORD_HEADER_LENGTH - offset);
|
||||
if (read == -1) {
|
||||
if (offset > 0) throw new FormatException();
|
||||
state = State.EOF;
|
||||
return;
|
||||
}
|
||||
offset += read;
|
||||
}
|
||||
// Check the protocol version
|
||||
if (header[0] != PROTOCOL_VERSION) throw new FormatException();
|
||||
// Read the payload length
|
||||
payloadLength = ByteUtils.readUint16(header, 2);
|
||||
if (payloadLength > MAX_RECORD_PAYLOAD_LENGTH)
|
||||
throw new FormatException();
|
||||
// Read the payload
|
||||
offset = 0;
|
||||
while (offset < payloadLength) {
|
||||
int read = in.read(payload, offset, payloadLength - offset);
|
||||
if (read == -1) throw new FormatException();
|
||||
offset += read;
|
||||
}
|
||||
state = State.BUFFER_FULL;
|
||||
// Return if this is a known record type
|
||||
if (header[1] == ACK || header[1] == MESSAGE ||
|
||||
header[1] == OFFER || header[1] == REQUEST) {
|
||||
return;
|
||||
}
|
||||
offset += read;
|
||||
}
|
||||
// Check the protocol version
|
||||
if (header[0] != PROTOCOL_VERSION) throw new FormatException();
|
||||
// Read the payload length
|
||||
payloadLength = ByteUtils.readUint16(header, 2);
|
||||
if (payloadLength > MAX_PACKET_PAYLOAD_LENGTH) throw new FormatException();
|
||||
// Read the payload
|
||||
offset = 0;
|
||||
while (offset < payloadLength) {
|
||||
int read = in.read(payload, offset, payloadLength - offset);
|
||||
if (read == -1) throw new FormatException();
|
||||
offset += read;
|
||||
}
|
||||
state = State.BUFFER_FULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* The return value indicates whether there's another record available
|
||||
* or whether we've reached the end of the input stream.
|
||||
* If a record is available,
|
||||
* it's been read into the buffer by the time eof() returns,
|
||||
* so the method that called eof() can access the record from the buffer,
|
||||
* for example to check its type or extract its payload.
|
||||
*/
|
||||
@Override
|
||||
public boolean eof() throws IOException {
|
||||
if (state == State.BUFFER_EMPTY) readPacket();
|
||||
if (state == State.BUFFER_EMPTY) readRecord();
|
||||
if (state == State.BUFFER_EMPTY) throw new IllegalStateException();
|
||||
return state == State.EOF;
|
||||
}
|
||||
@@ -124,13 +141,12 @@ class PacketReaderImpl implements PacketReader {
|
||||
// Timestamp
|
||||
long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH);
|
||||
if (timestamp < 0) throw new FormatException();
|
||||
// Raw message
|
||||
byte[] raw = new byte[payloadLength];
|
||||
System.arraycopy(payload, 0, raw, 0, payloadLength);
|
||||
// Body
|
||||
byte[] body = new byte[payloadLength - MESSAGE_HEADER_LENGTH];
|
||||
System.arraycopy(payload, MESSAGE_HEADER_LENGTH, body, 0,
|
||||
payloadLength - MESSAGE_HEADER_LENGTH);
|
||||
state = State.BUFFER_EMPTY;
|
||||
// Message ID
|
||||
MessageId messageId = new MessageId(crypto.hash(MessageId.LABEL, raw));
|
||||
return new Message(messageId, groupId, timestamp, raw);
|
||||
return messageFactory.createMessage(groupId, timestamp, body);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,4 +170,5 @@ class PacketReaderImpl implements PacketReader {
|
||||
if (!hasRequest()) throw new FormatException();
|
||||
return new Request(readMessageIds());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.bramble.sync;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
||||
import org.briarproject.bramble.api.sync.RecordWriterFactory;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
@NotNullByDefault
|
||||
class RecordWriterFactoryImpl implements RecordWriterFactory {
|
||||
|
||||
@Override
|
||||
public RecordWriter createRecordWriter(OutputStream out) {
|
||||
return new RecordWriterImpl(out);
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,8 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Ack;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.sync.Offer;
|
||||
import org.briarproject.bramble.api.sync.PacketTypes;
|
||||
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||
import org.briarproject.bramble.api.sync.RecordTypes;
|
||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
||||
import org.briarproject.bramble.api.sync.Request;
|
||||
import org.briarproject.bramble.util.ByteUtils;
|
||||
|
||||
@@ -15,30 +15,30 @@ import java.io.OutputStream;
|
||||
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
import static org.briarproject.bramble.api.sync.PacketTypes.ACK;
|
||||
import static org.briarproject.bramble.api.sync.PacketTypes.OFFER;
|
||||
import static org.briarproject.bramble.api.sync.PacketTypes.REQUEST;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.PACKET_HEADER_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.RecordTypes.ACK;
|
||||
import static org.briarproject.bramble.api.sync.RecordTypes.OFFER;
|
||||
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.RECORD_HEADER_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
class PacketWriterImpl implements PacketWriter {
|
||||
class RecordWriterImpl implements RecordWriter {
|
||||
|
||||
private final OutputStream out;
|
||||
private final byte[] header;
|
||||
private final ByteArrayOutputStream payload;
|
||||
|
||||
PacketWriterImpl(OutputStream out) {
|
||||
RecordWriterImpl(OutputStream out) {
|
||||
this.out = out;
|
||||
header = new byte[PACKET_HEADER_LENGTH];
|
||||
header = new byte[RECORD_HEADER_LENGTH];
|
||||
header[0] = PROTOCOL_VERSION;
|
||||
payload = new ByteArrayOutputStream(MAX_PACKET_PAYLOAD_LENGTH);
|
||||
payload = new ByteArrayOutputStream(MAX_RECORD_PAYLOAD_LENGTH);
|
||||
}
|
||||
|
||||
private void writePacket(byte packetType) throws IOException {
|
||||
header[1] = packetType;
|
||||
private void writeRecord(byte recordType) throws IOException {
|
||||
header[1] = recordType;
|
||||
ByteUtils.writeUint16(payload.size(), header, 2);
|
||||
out.write(header);
|
||||
payload.writeTo(out);
|
||||
@@ -49,12 +49,12 @@ class PacketWriterImpl implements PacketWriter {
|
||||
public void writeAck(Ack a) throws IOException {
|
||||
if (payload.size() != 0) throw new IllegalStateException();
|
||||
for (MessageId m : a.getMessageIds()) payload.write(m.getBytes());
|
||||
writePacket(ACK);
|
||||
writeRecord(ACK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeMessage(byte[] raw) throws IOException {
|
||||
header[1] = PacketTypes.MESSAGE;
|
||||
header[1] = RecordTypes.MESSAGE;
|
||||
ByteUtils.writeUint16(raw.length, header, 2);
|
||||
out.write(header);
|
||||
out.write(raw);
|
||||
@@ -64,14 +64,14 @@ class PacketWriterImpl implements PacketWriter {
|
||||
public void writeOffer(Offer o) throws IOException {
|
||||
if (payload.size() != 0) throw new IllegalStateException();
|
||||
for (MessageId m : o.getMessageIds()) payload.write(m.getBytes());
|
||||
writePacket(OFFER);
|
||||
writeRecord(OFFER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeRequest(Request r) throws IOException {
|
||||
if (payload.size() != 0) throw new IllegalStateException();
|
||||
for (MessageId m : r.getMessageIds()) payload.write(m.getBytes());
|
||||
writePacket(REQUEST);
|
||||
writeRecord(REQUEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -13,7 +13,7 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.lifecycle.event.ShutdownEvent;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Ack;
|
||||
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
||||
import org.briarproject.bramble.api.sync.SyncSession;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -29,12 +29,12 @@ import javax.annotation.concurrent.ThreadSafe;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
||||
|
||||
/**
|
||||
* An outgoing {@link SyncSession} suitable for simplex transports. The session
|
||||
* sends messages without offering them first, and closes its output stream
|
||||
* when there are no more packets to send.
|
||||
* when there are no more records to send.
|
||||
*/
|
||||
@ThreadSafe
|
||||
@NotNullByDefault
|
||||
@@ -55,7 +55,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
||||
private final EventBus eventBus;
|
||||
private final ContactId contactId;
|
||||
private final int maxLatency;
|
||||
private final PacketWriter packetWriter;
|
||||
private final RecordWriter recordWriter;
|
||||
private final AtomicInteger outstandingQueries;
|
||||
private final BlockingQueue<ThrowingRunnable<IOException>> writerTasks;
|
||||
|
||||
@@ -63,14 +63,14 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
||||
|
||||
SimplexOutgoingSession(DatabaseComponent db, Executor dbExecutor,
|
||||
EventBus eventBus, ContactId contactId,
|
||||
int maxLatency, PacketWriter packetWriter) {
|
||||
int maxLatency, RecordWriter recordWriter) {
|
||||
this.db = db;
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.eventBus = eventBus;
|
||||
this.contactId = contactId;
|
||||
this.maxLatency = maxLatency;
|
||||
this.packetWriter = packetWriter;
|
||||
outstandingQueries = new AtomicInteger(2); // One per type of packet
|
||||
this.recordWriter = recordWriter;
|
||||
outstandingQueries = new AtomicInteger(2); // One per type of record
|
||||
writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
|
||||
}
|
||||
|
||||
@@ -79,19 +79,19 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
||||
public void run() throws IOException {
|
||||
eventBus.addListener(this);
|
||||
try {
|
||||
// Start a query for each type of packet
|
||||
// Start a query for each type of record
|
||||
dbExecutor.execute(new GenerateAck());
|
||||
dbExecutor.execute(new GenerateBatch());
|
||||
// Write packets until interrupted or no more packets to write
|
||||
// Write records until interrupted or no more records to write
|
||||
try {
|
||||
while (!interrupted) {
|
||||
ThrowingRunnable<IOException> task = writerTasks.take();
|
||||
if (task == CLOSE) break;
|
||||
task.run();
|
||||
}
|
||||
packetWriter.flush();
|
||||
recordWriter.flush();
|
||||
} catch (InterruptedException e) {
|
||||
LOG.info("Interrupted while waiting for a packet to write");
|
||||
LOG.info("Interrupted while waiting for a record to write");
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
} finally {
|
||||
@@ -157,7 +157,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
if (interrupted) return;
|
||||
packetWriter.writeAck(ack);
|
||||
recordWriter.writeAck(ack);
|
||||
LOG.info("Sent ack");
|
||||
dbExecutor.execute(new GenerateAck());
|
||||
}
|
||||
@@ -174,7 +174,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
b = db.generateBatch(txn, contactId,
|
||||
MAX_PACKET_PAYLOAD_LENGTH, maxLatency);
|
||||
MAX_RECORD_PAYLOAD_LENGTH, maxLatency);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
@@ -202,7 +202,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
if (interrupted) return;
|
||||
for (byte[] raw : batch) packetWriter.writeMessage(raw);
|
||||
for (byte[] raw : batch) recordWriter.writeMessage(raw);
|
||||
LOG.info("Sent batch");
|
||||
dbExecutor.execute(new GenerateBatch());
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.api.sync.GroupFactory;
|
||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||
import org.briarproject.bramble.api.sync.PacketReaderFactory;
|
||||
import org.briarproject.bramble.api.sync.PacketWriterFactory;
|
||||
import org.briarproject.bramble.api.sync.RecordReaderFactory;
|
||||
import org.briarproject.bramble.api.sync.RecordWriterFactory;
|
||||
import org.briarproject.bramble.api.sync.SyncSessionFactory;
|
||||
import org.briarproject.bramble.api.sync.ValidationManager;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
@@ -40,23 +40,24 @@ public class SyncModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
PacketReaderFactory providePacketReaderFactory(CryptoComponent crypto) {
|
||||
return new PacketReaderFactoryImpl(crypto);
|
||||
RecordReaderFactory provideRecordReaderFactory(
|
||||
RecordReaderFactoryImpl recordReaderFactory) {
|
||||
return recordReaderFactory;
|
||||
}
|
||||
|
||||
@Provides
|
||||
PacketWriterFactory providePacketWriterFactory() {
|
||||
return new PacketWriterFactoryImpl();
|
||||
RecordWriterFactory provideRecordWriterFactory() {
|
||||
return new RecordWriterFactoryImpl();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
SyncSessionFactory provideSyncSessionFactory(DatabaseComponent db,
|
||||
@DatabaseExecutor Executor dbExecutor, EventBus eventBus,
|
||||
Clock clock, PacketReaderFactory packetReaderFactory,
|
||||
PacketWriterFactory packetWriterFactory) {
|
||||
Clock clock, RecordReaderFactory recordReaderFactory,
|
||||
RecordWriterFactory recordWriterFactory) {
|
||||
return new SyncSessionFactoryImpl(db, dbExecutor, eventBus, clock,
|
||||
packetReaderFactory, packetWriterFactory);
|
||||
recordReaderFactory, recordWriterFactory);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -5,10 +5,10 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.PacketReader;
|
||||
import org.briarproject.bramble.api.sync.PacketReaderFactory;
|
||||
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||
import org.briarproject.bramble.api.sync.PacketWriterFactory;
|
||||
import org.briarproject.bramble.api.sync.RecordReader;
|
||||
import org.briarproject.bramble.api.sync.RecordReaderFactory;
|
||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
||||
import org.briarproject.bramble.api.sync.RecordWriterFactory;
|
||||
import org.briarproject.bramble.api.sync.SyncSession;
|
||||
import org.briarproject.bramble.api.sync.SyncSessionFactory;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
@@ -28,41 +28,41 @@ class SyncSessionFactoryImpl implements SyncSessionFactory {
|
||||
private final Executor dbExecutor;
|
||||
private final EventBus eventBus;
|
||||
private final Clock clock;
|
||||
private final PacketReaderFactory packetReaderFactory;
|
||||
private final PacketWriterFactory packetWriterFactory;
|
||||
private final RecordReaderFactory recordReaderFactory;
|
||||
private final RecordWriterFactory recordWriterFactory;
|
||||
|
||||
@Inject
|
||||
SyncSessionFactoryImpl(DatabaseComponent db,
|
||||
@DatabaseExecutor Executor dbExecutor, EventBus eventBus,
|
||||
Clock clock, PacketReaderFactory packetReaderFactory,
|
||||
PacketWriterFactory packetWriterFactory) {
|
||||
Clock clock, RecordReaderFactory recordReaderFactory,
|
||||
RecordWriterFactory recordWriterFactory) {
|
||||
this.db = db;
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.eventBus = eventBus;
|
||||
this.clock = clock;
|
||||
this.packetReaderFactory = packetReaderFactory;
|
||||
this.packetWriterFactory = packetWriterFactory;
|
||||
this.recordReaderFactory = recordReaderFactory;
|
||||
this.recordWriterFactory = recordWriterFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncSession createIncomingSession(ContactId c, InputStream in) {
|
||||
PacketReader packetReader = packetReaderFactory.createPacketReader(in);
|
||||
return new IncomingSession(db, dbExecutor, eventBus, c, packetReader);
|
||||
RecordReader recordReader = recordReaderFactory.createRecordReader(in);
|
||||
return new IncomingSession(db, dbExecutor, eventBus, c, recordReader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncSession createSimplexOutgoingSession(ContactId c,
|
||||
int maxLatency, OutputStream out) {
|
||||
PacketWriter packetWriter = packetWriterFactory.createPacketWriter(out);
|
||||
RecordWriter recordWriter = recordWriterFactory.createRecordWriter(out);
|
||||
return new SimplexOutgoingSession(db, dbExecutor, eventBus, c,
|
||||
maxLatency, packetWriter);
|
||||
maxLatency, recordWriter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncSession createDuplexOutgoingSession(ContactId c, int maxLatency,
|
||||
int maxIdleTime, OutputStream out) {
|
||||
PacketWriter packetWriter = packetWriterFactory.createPacketWriter(out);
|
||||
RecordWriter recordWriter = recordWriterFactory.createRecordWriter(out);
|
||||
return new DuplexOutgoingSession(db, dbExecutor, eventBus, clock, c,
|
||||
maxLatency, maxIdleTime, packetWriter);
|
||||
maxLatency, maxIdleTime, recordWriter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_K
|
||||
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
|
||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
|
||||
@@ -95,7 +96,7 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
public DatabaseComponentImplTest() {
|
||||
clientId = new ClientId(TestUtils.getRandomString(5));
|
||||
groupId = new GroupId(TestUtils.getRandomId());
|
||||
byte[] descriptor = new byte[0];
|
||||
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
|
||||
group = new Group(groupId, clientId, descriptor);
|
||||
authorId = new AuthorId(TestUtils.getRandomId());
|
||||
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
|
||||
@@ -47,6 +47,7 @@ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_K
|
||||
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
|
||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
|
||||
@@ -84,7 +85,7 @@ public class H2DatabaseTest extends BrambleTestCase {
|
||||
public H2DatabaseTest() throws Exception {
|
||||
groupId = new GroupId(TestUtils.getRandomId());
|
||||
clientId = new ClientId(TestUtils.getRandomString(5));
|
||||
byte[] descriptor = new byte[0];
|
||||
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
|
||||
group = new Group(groupId, clientId, descriptor);
|
||||
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
|
||||
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
@@ -1316,7 +1317,7 @@ public class H2DatabaseTest extends BrambleTestCase {
|
||||
// Add a second group
|
||||
GroupId groupId1 = new GroupId(TestUtils.getRandomId());
|
||||
Group group1 = new Group(groupId1, clientId,
|
||||
TestUtils.getRandomBytes(42));
|
||||
TestUtils.getRandomBytes(MAX_GROUP_DESCRIPTOR_LENGTH));
|
||||
db.addGroup(txn, group1);
|
||||
|
||||
// Add a message to the second group
|
||||
|
||||
@@ -92,7 +92,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
oneOf(callbacks).connectionWaiting();
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(BOB_PUBKEY));
|
||||
oneOf(callbacks).initialPacketReceived();
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
|
||||
// Alice verifies Bob's public key
|
||||
oneOf(crypto).deriveKeyCommitment(BOB_PUBKEY);
|
||||
@@ -152,7 +152,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
// Bob receives Alice's public key
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(ALICE_PUBKEY));
|
||||
oneOf(callbacks).initialPacketReceived();
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
|
||||
// Bob verifies Alice's public key
|
||||
oneOf(crypto).deriveKeyCommitment(ALICE_PUBKEY);
|
||||
@@ -213,7 +213,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
oneOf(callbacks).connectionWaiting();
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(BAD_PUBKEY));
|
||||
oneOf(callbacks).initialPacketReceived();
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
|
||||
// Alice verifies Bob's public key
|
||||
oneOf(crypto).deriveKeyCommitment(BAD_PUBKEY);
|
||||
@@ -250,7 +250,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
// Bob receives a bad public key
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(BAD_PUBKEY));
|
||||
oneOf(callbacks).initialPacketReceived();
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
|
||||
// Bob verifies Alice's public key
|
||||
oneOf(crypto).deriveKeyCommitment(BAD_PUBKEY);
|
||||
@@ -296,7 +296,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
oneOf(callbacks).connectionWaiting();
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(BOB_PUBKEY));
|
||||
oneOf(callbacks).initialPacketReceived();
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
|
||||
// Alice verifies Bob's public key
|
||||
oneOf(crypto).deriveKeyCommitment(BOB_PUBKEY);
|
||||
@@ -357,7 +357,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
// Bob receives Alice's public key
|
||||
oneOf(transport).receiveKey();
|
||||
will(returnValue(ALICE_PUBKEY));
|
||||
oneOf(callbacks).initialPacketReceived();
|
||||
oneOf(callbacks).initialRecordReceived();
|
||||
|
||||
// Bob verifies Alice's public key
|
||||
oneOf(crypto).deriveKeyCommitment(ALICE_PUBKEY);
|
||||
|
||||
@@ -10,20 +10,20 @@ import org.junit.Test;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import static org.briarproject.bramble.api.sync.PacketTypes.ACK;
|
||||
import static org.briarproject.bramble.api.sync.PacketTypes.OFFER;
|
||||
import static org.briarproject.bramble.api.sync.PacketTypes.REQUEST;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.PACKET_HEADER_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.RecordTypes.ACK;
|
||||
import static org.briarproject.bramble.api.sync.RecordTypes.OFFER;
|
||||
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.RECORD_HEADER_LENGTH;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class PacketReaderImplTest extends BrambleTestCase {
|
||||
public class RecordReaderImplTest extends BrambleTestCase {
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testFormatExceptionIfAckIsTooLarge() throws Exception {
|
||||
byte[] b = createAck(true);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
||||
PacketReaderImpl reader = new PacketReaderImpl(null, in);
|
||||
RecordReaderImpl reader = new RecordReaderImpl(null, in);
|
||||
reader.readAck();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class PacketReaderImplTest extends BrambleTestCase {
|
||||
public void testNoFormatExceptionIfAckIsMaximumSize() throws Exception {
|
||||
byte[] b = createAck(false);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
||||
PacketReaderImpl reader = new PacketReaderImpl(null, in);
|
||||
RecordReaderImpl reader = new RecordReaderImpl(null, in);
|
||||
reader.readAck();
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class PacketReaderImplTest extends BrambleTestCase {
|
||||
public void testEmptyAck() throws Exception {
|
||||
byte[] b = createEmptyAck();
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
||||
PacketReaderImpl reader = new PacketReaderImpl(null, in);
|
||||
RecordReaderImpl reader = new RecordReaderImpl(null, in);
|
||||
reader.readAck();
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class PacketReaderImplTest extends BrambleTestCase {
|
||||
public void testFormatExceptionIfOfferIsTooLarge() throws Exception {
|
||||
byte[] b = createOffer(true);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
||||
PacketReaderImpl reader = new PacketReaderImpl(null, in);
|
||||
RecordReaderImpl reader = new RecordReaderImpl(null, in);
|
||||
reader.readOffer();
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class PacketReaderImplTest extends BrambleTestCase {
|
||||
public void testNoFormatExceptionIfOfferIsMaximumSize() throws Exception {
|
||||
byte[] b = createOffer(false);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
||||
PacketReaderImpl reader = new PacketReaderImpl(null, in);
|
||||
RecordReaderImpl reader = new RecordReaderImpl(null, in);
|
||||
reader.readOffer();
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class PacketReaderImplTest extends BrambleTestCase {
|
||||
public void testEmptyOffer() throws Exception {
|
||||
byte[] b = createEmptyOffer();
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
||||
PacketReaderImpl reader = new PacketReaderImpl(null, in);
|
||||
RecordReaderImpl reader = new RecordReaderImpl(null, in);
|
||||
reader.readOffer();
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class PacketReaderImplTest extends BrambleTestCase {
|
||||
public void testFormatExceptionIfRequestIsTooLarge() throws Exception {
|
||||
byte[] b = createRequest(true);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
||||
PacketReaderImpl reader = new PacketReaderImpl(null, in);
|
||||
RecordReaderImpl reader = new RecordReaderImpl(null, in);
|
||||
reader.readRequest();
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public class PacketReaderImplTest extends BrambleTestCase {
|
||||
public void testNoFormatExceptionIfRequestIsMaximumSize() throws Exception {
|
||||
byte[] b = createRequest(false);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
||||
PacketReaderImpl reader = new PacketReaderImpl(null, in);
|
||||
RecordReaderImpl reader = new RecordReaderImpl(null, in);
|
||||
reader.readRequest();
|
||||
}
|
||||
|
||||
@@ -87,76 +87,76 @@ public class PacketReaderImplTest extends BrambleTestCase {
|
||||
public void testEmptyRequest() throws Exception {
|
||||
byte[] b = createEmptyRequest();
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(b);
|
||||
PacketReaderImpl reader = new PacketReaderImpl(null, in);
|
||||
RecordReaderImpl reader = new RecordReaderImpl(null, in);
|
||||
reader.readRequest();
|
||||
}
|
||||
|
||||
private byte[] createAck(boolean tooBig) throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(new byte[PACKET_HEADER_LENGTH]);
|
||||
while (out.size() + UniqueId.LENGTH <= PACKET_HEADER_LENGTH
|
||||
+ MAX_PACKET_PAYLOAD_LENGTH) {
|
||||
out.write(new byte[RECORD_HEADER_LENGTH]);
|
||||
while (out.size() + UniqueId.LENGTH <= RECORD_HEADER_LENGTH
|
||||
+ MAX_RECORD_PAYLOAD_LENGTH) {
|
||||
out.write(TestUtils.getRandomId());
|
||||
}
|
||||
if (tooBig) out.write(TestUtils.getRandomId());
|
||||
assertEquals(tooBig, out.size() > PACKET_HEADER_LENGTH +
|
||||
MAX_PACKET_PAYLOAD_LENGTH);
|
||||
byte[] packet = out.toByteArray();
|
||||
packet[1] = ACK;
|
||||
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
|
||||
return packet;
|
||||
assertEquals(tooBig, out.size() > RECORD_HEADER_LENGTH +
|
||||
MAX_RECORD_PAYLOAD_LENGTH);
|
||||
byte[] record = out.toByteArray();
|
||||
record[1] = ACK;
|
||||
ByteUtils.writeUint16(record.length - RECORD_HEADER_LENGTH, record, 2);
|
||||
return record;
|
||||
}
|
||||
|
||||
private byte[] createEmptyAck() throws Exception {
|
||||
byte[] packet = new byte[PACKET_HEADER_LENGTH];
|
||||
packet[1] = ACK;
|
||||
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
|
||||
return packet;
|
||||
byte[] record = new byte[RECORD_HEADER_LENGTH];
|
||||
record[1] = ACK;
|
||||
ByteUtils.writeUint16(record.length - RECORD_HEADER_LENGTH, record, 2);
|
||||
return record;
|
||||
}
|
||||
|
||||
private byte[] createOffer(boolean tooBig) throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(new byte[PACKET_HEADER_LENGTH]);
|
||||
while (out.size() + UniqueId.LENGTH <= PACKET_HEADER_LENGTH
|
||||
+ MAX_PACKET_PAYLOAD_LENGTH) {
|
||||
out.write(new byte[RECORD_HEADER_LENGTH]);
|
||||
while (out.size() + UniqueId.LENGTH <= RECORD_HEADER_LENGTH
|
||||
+ MAX_RECORD_PAYLOAD_LENGTH) {
|
||||
out.write(TestUtils.getRandomId());
|
||||
}
|
||||
if (tooBig) out.write(TestUtils.getRandomId());
|
||||
assertEquals(tooBig, out.size() > PACKET_HEADER_LENGTH +
|
||||
MAX_PACKET_PAYLOAD_LENGTH);
|
||||
byte[] packet = out.toByteArray();
|
||||
packet[1] = OFFER;
|
||||
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
|
||||
return packet;
|
||||
assertEquals(tooBig, out.size() > RECORD_HEADER_LENGTH +
|
||||
MAX_RECORD_PAYLOAD_LENGTH);
|
||||
byte[] record = out.toByteArray();
|
||||
record[1] = OFFER;
|
||||
ByteUtils.writeUint16(record.length - RECORD_HEADER_LENGTH, record, 2);
|
||||
return record;
|
||||
}
|
||||
|
||||
private byte[] createEmptyOffer() throws Exception {
|
||||
byte[] packet = new byte[PACKET_HEADER_LENGTH];
|
||||
packet[1] = OFFER;
|
||||
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
|
||||
return packet;
|
||||
byte[] record = new byte[RECORD_HEADER_LENGTH];
|
||||
record[1] = OFFER;
|
||||
ByteUtils.writeUint16(record.length - RECORD_HEADER_LENGTH, record, 2);
|
||||
return record;
|
||||
}
|
||||
|
||||
private byte[] createRequest(boolean tooBig) throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(new byte[PACKET_HEADER_LENGTH]);
|
||||
while (out.size() + UniqueId.LENGTH <= PACKET_HEADER_LENGTH
|
||||
+ MAX_PACKET_PAYLOAD_LENGTH) {
|
||||
out.write(new byte[RECORD_HEADER_LENGTH]);
|
||||
while (out.size() + UniqueId.LENGTH <= RECORD_HEADER_LENGTH
|
||||
+ MAX_RECORD_PAYLOAD_LENGTH) {
|
||||
out.write(TestUtils.getRandomId());
|
||||
}
|
||||
if (tooBig) out.write(TestUtils.getRandomId());
|
||||
assertEquals(tooBig, out.size() > PACKET_HEADER_LENGTH +
|
||||
MAX_PACKET_PAYLOAD_LENGTH);
|
||||
byte[] packet = out.toByteArray();
|
||||
packet[1] = REQUEST;
|
||||
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
|
||||
return packet;
|
||||
assertEquals(tooBig, out.size() > RECORD_HEADER_LENGTH +
|
||||
MAX_RECORD_PAYLOAD_LENGTH);
|
||||
byte[] record = out.toByteArray();
|
||||
record[1] = REQUEST;
|
||||
ByteUtils.writeUint16(record.length - RECORD_HEADER_LENGTH, record, 2);
|
||||
return record;
|
||||
}
|
||||
|
||||
private byte[] createEmptyRequest() throws Exception {
|
||||
byte[] packet = new byte[PACKET_HEADER_LENGTH];
|
||||
packet[1] = REQUEST;
|
||||
ByteUtils.writeUint16(packet.length - PACKET_HEADER_LENGTH, packet, 2);
|
||||
return packet;
|
||||
byte[] record = new byte[RECORD_HEADER_LENGTH];
|
||||
record[1] = REQUEST;
|
||||
ByteUtils.writeUint16(record.length - RECORD_HEADER_LENGTH, record, 2);
|
||||
return record;
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,10 @@ import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.sync.Ack;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.ImmediateExecutor;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.junit.Test;
|
||||
@@ -29,14 +29,14 @@ public class SimplexOutgoingSessionTest extends BrambleTestCase {
|
||||
private final ContactId contactId;
|
||||
private final MessageId messageId;
|
||||
private final int maxLatency;
|
||||
private final PacketWriter packetWriter;
|
||||
private final RecordWriter recordWriter;
|
||||
|
||||
public SimplexOutgoingSessionTest() {
|
||||
context = new Mockery();
|
||||
db = context.mock(DatabaseComponent.class);
|
||||
dbExecutor = new ImmediateExecutor();
|
||||
eventBus = context.mock(EventBus.class);
|
||||
packetWriter = context.mock(PacketWriter.class);
|
||||
recordWriter = context.mock(RecordWriter.class);
|
||||
contactId = new ContactId(234);
|
||||
messageId = new MessageId(TestUtils.getRandomId());
|
||||
maxLatency = Integer.MAX_VALUE;
|
||||
@@ -45,7 +45,7 @@ public class SimplexOutgoingSessionTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testNothingToSend() throws Exception {
|
||||
final SimplexOutgoingSession session = new SimplexOutgoingSession(db,
|
||||
dbExecutor, eventBus, contactId, maxLatency, packetWriter);
|
||||
dbExecutor, eventBus, contactId, maxLatency, recordWriter);
|
||||
final Transaction noAckTxn = new Transaction(null, false);
|
||||
final Transaction noMsgTxn = new Transaction(null, false);
|
||||
|
||||
@@ -68,7 +68,7 @@ public class SimplexOutgoingSessionTest extends BrambleTestCase {
|
||||
oneOf(db).commitTransaction(noMsgTxn);
|
||||
oneOf(db).endTransaction(noMsgTxn);
|
||||
// Flush the output stream
|
||||
oneOf(packetWriter).flush();
|
||||
oneOf(recordWriter).flush();
|
||||
// Remove listener
|
||||
oneOf(eventBus).removeListener(session);
|
||||
}});
|
||||
@@ -83,7 +83,7 @@ public class SimplexOutgoingSessionTest extends BrambleTestCase {
|
||||
final Ack ack = new Ack(Collections.singletonList(messageId));
|
||||
final byte[] raw = new byte[1234];
|
||||
final SimplexOutgoingSession session = new SimplexOutgoingSession(db,
|
||||
dbExecutor, eventBus, contactId, maxLatency, packetWriter);
|
||||
dbExecutor, eventBus, contactId, maxLatency, recordWriter);
|
||||
final Transaction ackTxn = new Transaction(null, false);
|
||||
final Transaction noAckTxn = new Transaction(null, false);
|
||||
final Transaction msgTxn = new Transaction(null, false);
|
||||
@@ -99,7 +99,7 @@ public class SimplexOutgoingSessionTest extends BrambleTestCase {
|
||||
will(returnValue(ack));
|
||||
oneOf(db).commitTransaction(ackTxn);
|
||||
oneOf(db).endTransaction(ackTxn);
|
||||
oneOf(packetWriter).writeAck(ack);
|
||||
oneOf(recordWriter).writeAck(ack);
|
||||
// One message to send
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(msgTxn));
|
||||
@@ -108,7 +108,7 @@ public class SimplexOutgoingSessionTest extends BrambleTestCase {
|
||||
will(returnValue(Arrays.asList(raw)));
|
||||
oneOf(db).commitTransaction(msgTxn);
|
||||
oneOf(db).endTransaction(msgTxn);
|
||||
oneOf(packetWriter).writeMessage(raw);
|
||||
oneOf(recordWriter).writeMessage(raw);
|
||||
// No more acks
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(noAckTxn));
|
||||
@@ -125,7 +125,7 @@ public class SimplexOutgoingSessionTest extends BrambleTestCase {
|
||||
oneOf(db).commitTransaction(noMsgTxn);
|
||||
oneOf(db).endTransaction(noMsgTxn);
|
||||
// Flush the output stream
|
||||
oneOf(packetWriter).flush();
|
||||
oneOf(recordWriter).flush();
|
||||
// Remove listener
|
||||
oneOf(eventBus).removeListener(session);
|
||||
}});
|
||||
|
||||
@@ -12,10 +12,10 @@ import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.sync.Offer;
|
||||
import org.briarproject.bramble.api.sync.PacketReader;
|
||||
import org.briarproject.bramble.api.sync.PacketReaderFactory;
|
||||
import org.briarproject.bramble.api.sync.PacketWriter;
|
||||
import org.briarproject.bramble.api.sync.PacketWriterFactory;
|
||||
import org.briarproject.bramble.api.sync.RecordReader;
|
||||
import org.briarproject.bramble.api.sync.RecordReaderFactory;
|
||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
||||
import org.briarproject.bramble.api.sync.RecordWriterFactory;
|
||||
import org.briarproject.bramble.api.sync.Request;
|
||||
import org.briarproject.bramble.api.transport.StreamContext;
|
||||
import org.briarproject.bramble.api.transport.StreamReaderFactory;
|
||||
@@ -33,6 +33,7 @@ import java.util.Collection;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -50,9 +51,9 @@ public class SyncIntegrationTest extends BrambleTestCase {
|
||||
@Inject
|
||||
StreamWriterFactory streamWriterFactory;
|
||||
@Inject
|
||||
PacketReaderFactory packetReaderFactory;
|
||||
RecordReaderFactory recordReaderFactory;
|
||||
@Inject
|
||||
PacketWriterFactory packetWriterFactory;
|
||||
RecordWriterFactory recordWriterFactory;
|
||||
@Inject
|
||||
CryptoComponent crypto;
|
||||
|
||||
@@ -77,7 +78,7 @@ public class SyncIntegrationTest extends BrambleTestCase {
|
||||
streamNumber = 123;
|
||||
// Create a group
|
||||
ClientId clientId = new ClientId(TestUtils.getRandomString(5));
|
||||
byte[] descriptor = new byte[0];
|
||||
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
|
||||
Group group = groupFactory.createGroup(clientId, descriptor);
|
||||
// Add two messages to the group
|
||||
long timestamp = System.currentTimeMillis();
|
||||
@@ -98,14 +99,14 @@ public class SyncIntegrationTest extends BrambleTestCase {
|
||||
headerKey, streamNumber);
|
||||
OutputStream streamWriter = streamWriterFactory.createStreamWriter(out,
|
||||
ctx);
|
||||
PacketWriter packetWriter = packetWriterFactory.createPacketWriter(
|
||||
RecordWriter recordWriter = recordWriterFactory.createRecordWriter(
|
||||
streamWriter);
|
||||
|
||||
packetWriter.writeAck(new Ack(messageIds));
|
||||
packetWriter.writeMessage(message.getRaw());
|
||||
packetWriter.writeMessage(message1.getRaw());
|
||||
packetWriter.writeOffer(new Offer(messageIds));
|
||||
packetWriter.writeRequest(new Request(messageIds));
|
||||
recordWriter.writeAck(new Ack(messageIds));
|
||||
recordWriter.writeMessage(message.getRaw());
|
||||
recordWriter.writeMessage(message1.getRaw());
|
||||
recordWriter.writeOffer(new Offer(messageIds));
|
||||
recordWriter.writeRequest(new Request(messageIds));
|
||||
|
||||
streamWriter.flush();
|
||||
return out.toByteArray();
|
||||
@@ -127,31 +128,31 @@ public class SyncIntegrationTest extends BrambleTestCase {
|
||||
headerKey, streamNumber);
|
||||
InputStream streamReader = streamReaderFactory.createStreamReader(in,
|
||||
ctx);
|
||||
PacketReader packetReader = packetReaderFactory.createPacketReader(
|
||||
RecordReader recordReader = recordReaderFactory.createRecordReader(
|
||||
streamReader);
|
||||
|
||||
// Read the ack
|
||||
assertTrue(packetReader.hasAck());
|
||||
Ack a = packetReader.readAck();
|
||||
assertTrue(recordReader.hasAck());
|
||||
Ack a = recordReader.readAck();
|
||||
assertEquals(messageIds, a.getMessageIds());
|
||||
|
||||
// Read the messages
|
||||
assertTrue(packetReader.hasMessage());
|
||||
Message m = packetReader.readMessage();
|
||||
assertTrue(recordReader.hasMessage());
|
||||
Message m = recordReader.readMessage();
|
||||
checkMessageEquality(message, m);
|
||||
assertTrue(packetReader.hasMessage());
|
||||
m = packetReader.readMessage();
|
||||
assertTrue(recordReader.hasMessage());
|
||||
m = recordReader.readMessage();
|
||||
checkMessageEquality(message1, m);
|
||||
assertFalse(packetReader.hasMessage());
|
||||
assertFalse(recordReader.hasMessage());
|
||||
|
||||
// Read the offer
|
||||
assertTrue(packetReader.hasOffer());
|
||||
Offer o = packetReader.readOffer();
|
||||
assertTrue(recordReader.hasOffer());
|
||||
Offer o = recordReader.readOffer();
|
||||
assertEquals(messageIds, o.getMessageIds());
|
||||
|
||||
// Read the request
|
||||
assertTrue(packetReader.hasRequest());
|
||||
Request req = packetReader.readRequest();
|
||||
assertTrue(recordReader.hasRequest());
|
||||
Request req = recordReader.readRequest();
|
||||
assertEquals(messageIds, req.getMessageIds());
|
||||
|
||||
in.close();
|
||||
|
||||
@@ -39,7 +39,11 @@ class QueueMessageFactoryImpl implements QueueMessageFactory {
|
||||
ByteUtils.writeUint64(queuePosition, raw, MESSAGE_HEADER_LENGTH);
|
||||
System.arraycopy(body, 0, raw, QUEUE_MESSAGE_HEADER_LENGTH,
|
||||
body.length);
|
||||
MessageId id = new MessageId(crypto.hash(MessageId.LABEL, raw));
|
||||
byte[] timeBytes = new byte[ByteUtils.INT_64_BYTES];
|
||||
ByteUtils.writeUint64(timestamp, timeBytes, 0);
|
||||
MessageId id = new MessageId(
|
||||
crypto.hash(MessageId.LABEL, groupId.getBytes(), timeBytes,
|
||||
body));
|
||||
return new QueueMessage(id, groupId, timestamp, queuePosition, raw);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
|
||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@@ -59,7 +59,7 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
||||
int length = message.getMessage().getRaw().length;
|
||||
assertTrue(
|
||||
length > UniqueId.LENGTH + 8 + MAX_PRIVATE_MESSAGE_BODY_LENGTH);
|
||||
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
|
||||
assertTrue(length <= MAX_RECORD_PAYLOAD_LENGTH);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -85,7 +85,7 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
||||
+ MAX_AUTHOR_NAME_LENGTH + MAX_PUBLIC_KEY_LENGTH
|
||||
+ ForumConstants.MAX_CONTENT_TYPE_LENGTH
|
||||
+ MAX_FORUM_POST_BODY_LENGTH);
|
||||
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
|
||||
assertTrue(length <= MAX_RECORD_PAYLOAD_LENGTH);
|
||||
}
|
||||
|
||||
private static void injectEagerSingletons(
|
||||
|
||||
Reference in New Issue
Block a user