mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 12:19:54 +01:00
Massive refactoring to merge handling of simplex and duplex connections.
This commit is contained in:
@@ -45,8 +45,6 @@ import org.briarproject.crypto.CryptoModule;
|
||||
import org.briarproject.db.DatabaseModule;
|
||||
import org.briarproject.event.EventModule;
|
||||
import org.briarproject.messaging.MessagingModule;
|
||||
import org.briarproject.messaging.duplex.DuplexMessagingModule;
|
||||
import org.briarproject.messaging.simplex.SimplexMessagingModule;
|
||||
import org.briarproject.reliability.ReliabilityModule;
|
||||
import org.briarproject.serial.SerialModule;
|
||||
import org.briarproject.transport.TransportModule;
|
||||
@@ -81,7 +79,6 @@ public class ProtocolIntegrationTest extends BriarTestCase {
|
||||
new TestLifecycleModule(), new TestSystemModule(),
|
||||
new TestUiModule(), new CryptoModule(), new DatabaseModule(),
|
||||
new EventModule(), new MessagingModule(),
|
||||
new DuplexMessagingModule(), new SimplexMessagingModule(),
|
||||
new ReliabilityModule(), new SerialModule(),
|
||||
new TransportModule());
|
||||
streamReaderFactory = i.getInstance(StreamReaderFactory.class);
|
||||
@@ -125,29 +122,29 @@ public class ProtocolIntegrationTest extends BriarTestCase {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamContext ctx = new StreamContext(contactId, transportId,
|
||||
secret.clone(), 0, true);
|
||||
StreamWriter conn = streamWriterFactory.createStreamWriter(
|
||||
out, MAX_FRAME_LENGTH, Long.MAX_VALUE, ctx, false, true);
|
||||
OutputStream out1 = conn.getOutputStream();
|
||||
PacketWriter writer = packetWriterFactory.createPacketWriter(out1,
|
||||
StreamWriter streamWriter = streamWriterFactory.createStreamWriter(out,
|
||||
MAX_FRAME_LENGTH, ctx);
|
||||
OutputStream out1 = streamWriter.getOutputStream();
|
||||
PacketWriter packetWriter = packetWriterFactory.createPacketWriter(out1,
|
||||
false);
|
||||
|
||||
writer.writeAck(new Ack(messageIds));
|
||||
packetWriter.writeAck(new Ack(messageIds));
|
||||
|
||||
writer.writeMessage(message.getSerialised());
|
||||
writer.writeMessage(message1.getSerialised());
|
||||
packetWriter.writeMessage(message.getSerialised());
|
||||
packetWriter.writeMessage(message1.getSerialised());
|
||||
|
||||
writer.writeOffer(new Offer(messageIds));
|
||||
packetWriter.writeOffer(new Offer(messageIds));
|
||||
|
||||
writer.writeRequest(new Request(messageIds));
|
||||
packetWriter.writeRequest(new Request(messageIds));
|
||||
|
||||
SubscriptionUpdate su = new SubscriptionUpdate(Arrays.asList(group), 1);
|
||||
writer.writeSubscriptionUpdate(su);
|
||||
packetWriter.writeSubscriptionUpdate(su);
|
||||
|
||||
TransportUpdate tu = new TransportUpdate(transportId,
|
||||
transportProperties, 1);
|
||||
writer.writeTransportUpdate(tu);
|
||||
packetWriter.writeTransportUpdate(tu);
|
||||
|
||||
writer.flush();
|
||||
packetWriter.flush();
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
@@ -158,44 +155,44 @@ public class ProtocolIntegrationTest extends BriarTestCase {
|
||||
// FIXME: Check that the expected tag was received
|
||||
StreamContext ctx = new StreamContext(contactId, transportId,
|
||||
secret.clone(), 0, false);
|
||||
StreamReader conn = streamReaderFactory.createStreamReader(
|
||||
in, MAX_FRAME_LENGTH, ctx, true, true);
|
||||
InputStream in1 = conn.getInputStream();
|
||||
PacketReader reader = packetReaderFactory.createPacketReader(in1);
|
||||
StreamReader streamReader = streamReaderFactory.createStreamReader(in,
|
||||
MAX_FRAME_LENGTH, ctx);
|
||||
InputStream in1 = streamReader.getInputStream();
|
||||
PacketReader packetReader = packetReaderFactory.createPacketReader(in1);
|
||||
|
||||
// Read the ack
|
||||
assertTrue(reader.hasAck());
|
||||
Ack a = reader.readAck();
|
||||
assertTrue(packetReader.hasAck());
|
||||
Ack a = packetReader.readAck();
|
||||
assertEquals(messageIds, a.getMessageIds());
|
||||
|
||||
// Read and verify the messages
|
||||
assertTrue(reader.hasMessage());
|
||||
UnverifiedMessage m = reader.readMessage();
|
||||
assertTrue(packetReader.hasMessage());
|
||||
UnverifiedMessage m = packetReader.readMessage();
|
||||
checkMessageEquality(message, messageVerifier.verifyMessage(m));
|
||||
assertTrue(reader.hasMessage());
|
||||
m = reader.readMessage();
|
||||
assertTrue(packetReader.hasMessage());
|
||||
m = packetReader.readMessage();
|
||||
checkMessageEquality(message1, messageVerifier.verifyMessage(m));
|
||||
assertFalse(reader.hasMessage());
|
||||
assertFalse(packetReader.hasMessage());
|
||||
|
||||
// Read the offer
|
||||
assertTrue(reader.hasOffer());
|
||||
Offer o = reader.readOffer();
|
||||
assertTrue(packetReader.hasOffer());
|
||||
Offer o = packetReader.readOffer();
|
||||
assertEquals(messageIds, o.getMessageIds());
|
||||
|
||||
// Read the request
|
||||
assertTrue(reader.hasRequest());
|
||||
Request req = reader.readRequest();
|
||||
assertTrue(packetReader.hasRequest());
|
||||
Request req = packetReader.readRequest();
|
||||
assertEquals(messageIds, req.getMessageIds());
|
||||
|
||||
// Read the subscription update
|
||||
assertTrue(reader.hasSubscriptionUpdate());
|
||||
SubscriptionUpdate su = reader.readSubscriptionUpdate();
|
||||
assertTrue(packetReader.hasSubscriptionUpdate());
|
||||
SubscriptionUpdate su = packetReader.readSubscriptionUpdate();
|
||||
assertEquals(Arrays.asList(group), su.getGroups());
|
||||
assertEquals(1, su.getVersion());
|
||||
|
||||
// Read the transport update
|
||||
assertTrue(reader.hasTransportUpdate());
|
||||
TransportUpdate tu = reader.readTransportUpdate();
|
||||
assertTrue(packetReader.hasTransportUpdate());
|
||||
TransportUpdate tu = packetReader.readTransportUpdate();
|
||||
assertEquals(transportId, tu.getId());
|
||||
assertEquals(transportProperties, tu.getProperties());
|
||||
assertEquals(1, tu.getVersion());
|
||||
|
||||
@@ -25,10 +25,8 @@ public class KeyDerivationTest extends BriarTestCase {
|
||||
@Test
|
||||
public void testKeysAreDistinct() {
|
||||
List<SecretKey> keys = new ArrayList<SecretKey>();
|
||||
keys.add(crypto.deriveFrameKey(secret, 0, false, false));
|
||||
keys.add(crypto.deriveFrameKey(secret, 0, false, true));
|
||||
keys.add(crypto.deriveFrameKey(secret, 0, true, false));
|
||||
keys.add(crypto.deriveFrameKey(secret, 0, true, true));
|
||||
keys.add(crypto.deriveFrameKey(secret, 0, true));
|
||||
keys.add(crypto.deriveFrameKey(secret, 0, false));
|
||||
keys.add(crypto.deriveTagKey(secret, true));
|
||||
keys.add(crypto.deriveTagKey(secret, false));
|
||||
for(int i = 0; i < 4; i++) {
|
||||
|
||||
@@ -46,8 +46,6 @@ import org.briarproject.api.messaging.TransportUpdate;
|
||||
import org.briarproject.crypto.CryptoModule;
|
||||
import org.briarproject.db.DatabaseModule;
|
||||
import org.briarproject.event.EventModule;
|
||||
import org.briarproject.messaging.duplex.DuplexMessagingModule;
|
||||
import org.briarproject.messaging.simplex.SimplexMessagingModule;
|
||||
import org.briarproject.serial.SerialModule;
|
||||
import org.briarproject.transport.TransportModule;
|
||||
import org.junit.Test;
|
||||
@@ -67,8 +65,7 @@ public class ConstantsTest extends BriarTestCase {
|
||||
Injector i = Guice.createInjector(new TestDatabaseModule(),
|
||||
new TestLifecycleModule(), new TestSystemModule(),
|
||||
new CryptoModule(), new DatabaseModule(), new EventModule(),
|
||||
new MessagingModule(), new DuplexMessagingModule(),
|
||||
new SimplexMessagingModule(), new SerialModule(),
|
||||
new MessagingModule(), new SerialModule(),
|
||||
new TransportModule());
|
||||
crypto = i.getInstance(CryptoComponent.class);
|
||||
groupFactory = i.getInstance(GroupFactory.class);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.briarproject.messaging.simplex;
|
||||
package org.briarproject.messaging;
|
||||
|
||||
import static org.briarproject.api.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.api.messaging.MessagingConstants.GROUP_SALT_LENGTH;
|
||||
@@ -30,9 +30,9 @@ import org.briarproject.api.messaging.GroupFactory;
|
||||
import org.briarproject.api.messaging.Message;
|
||||
import org.briarproject.api.messaging.MessageFactory;
|
||||
import org.briarproject.api.messaging.MessageVerifier;
|
||||
import org.briarproject.api.messaging.MessagingSession;
|
||||
import org.briarproject.api.messaging.PacketReaderFactory;
|
||||
import org.briarproject.api.messaging.PacketWriterFactory;
|
||||
import org.briarproject.api.transport.ConnectionRegistry;
|
||||
import org.briarproject.api.transport.Endpoint;
|
||||
import org.briarproject.api.transport.StreamContext;
|
||||
import org.briarproject.api.transport.StreamReaderFactory;
|
||||
@@ -41,8 +41,6 @@ import org.briarproject.api.transport.TagRecogniser;
|
||||
import org.briarproject.crypto.CryptoModule;
|
||||
import org.briarproject.db.DatabaseModule;
|
||||
import org.briarproject.event.EventModule;
|
||||
import org.briarproject.messaging.MessagingModule;
|
||||
import org.briarproject.messaging.duplex.DuplexMessagingModule;
|
||||
import org.briarproject.plugins.ImmediateExecutor;
|
||||
import org.briarproject.serial.SerialModule;
|
||||
import org.briarproject.transport.TransportModule;
|
||||
@@ -88,8 +86,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||
return Guice.createInjector(new TestDatabaseModule(dir),
|
||||
new TestLifecycleModule(), new TestSystemModule(),
|
||||
new CryptoModule(), new DatabaseModule(), new EventModule(),
|
||||
new MessagingModule(), new DuplexMessagingModule(),
|
||||
new SimplexMessagingModule(), new SerialModule(),
|
||||
new MessagingModule(), new SerialModule(),
|
||||
new TransportModule());
|
||||
}
|
||||
|
||||
@@ -140,29 +137,26 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||
Message message = messageFactory.createAnonymousMessage(null, group,
|
||||
contentType, timestamp, body);
|
||||
db.addLocalMessage(message);
|
||||
// Create an outgoing simplex connection
|
||||
// Create an outgoing messaging session
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ConnectionRegistry connRegistry =
|
||||
alice.getInstance(ConnectionRegistry.class);
|
||||
StreamWriterFactory connWriterFactory =
|
||||
StreamWriterFactory streamWriterFactory =
|
||||
alice.getInstance(StreamWriterFactory.class);
|
||||
PacketWriterFactory packetWriterFactory =
|
||||
alice.getInstance(PacketWriterFactory.class);
|
||||
TestSimplexTransportWriter transport = new TestSimplexTransportWriter(
|
||||
out, Long.MAX_VALUE, Long.MAX_VALUE);
|
||||
TestTransportConnectionWriter transport =
|
||||
new TestTransportConnectionWriter(out);
|
||||
StreamContext ctx = km.getStreamContext(contactId, transportId);
|
||||
assertNotNull(ctx);
|
||||
OutgoingSimplexConnection simplex = new OutgoingSimplexConnection(db,
|
||||
connRegistry, connWriterFactory, packetWriterFactory, ctx,
|
||||
transport);
|
||||
MessagingSession session = new SinglePassOutgoingSession(db,
|
||||
new ImmediateExecutor(), streamWriterFactory,
|
||||
packetWriterFactory, ctx, transport);
|
||||
// Write whatever needs to be written
|
||||
simplex.write();
|
||||
assertTrue(transport.getDisposed());
|
||||
assertFalse(transport.getException());
|
||||
session.run();
|
||||
transport.dispose(false);
|
||||
// Clean up
|
||||
km.stop();
|
||||
db.close();
|
||||
// Return the contents of the simplex connection
|
||||
// Return the contents of the stream
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
@@ -204,28 +198,24 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||
assertEquals(tag.length, read);
|
||||
StreamContext ctx = rec.recogniseTag(transportId, tag);
|
||||
assertNotNull(ctx);
|
||||
// Create an incoming simplex connection
|
||||
// Create an incoming messaging session
|
||||
MessageVerifier messageVerifier =
|
||||
bob.getInstance(MessageVerifier.class);
|
||||
ConnectionRegistry connRegistry =
|
||||
bob.getInstance(ConnectionRegistry.class);
|
||||
StreamReaderFactory connWriterFactory =
|
||||
StreamReaderFactory streamReaderFactory =
|
||||
bob.getInstance(StreamReaderFactory.class);
|
||||
PacketReaderFactory packetWriterFactory =
|
||||
PacketReaderFactory packetReaderFactory =
|
||||
bob.getInstance(PacketReaderFactory.class);
|
||||
TestSimplexTransportReader transport =
|
||||
new TestSimplexTransportReader(in);
|
||||
IncomingSimplexConnection simplex = new IncomingSimplexConnection(
|
||||
TestTransportConnectionReader transport =
|
||||
new TestTransportConnectionReader(in);
|
||||
MessagingSession session = new IncomingSession(db,
|
||||
new ImmediateExecutor(), new ImmediateExecutor(),
|
||||
messageVerifier, db, connRegistry, connWriterFactory,
|
||||
packetWriterFactory, ctx, transport);
|
||||
messageVerifier, streamReaderFactory, packetReaderFactory,
|
||||
ctx, transport);
|
||||
// No messages should have been added yet
|
||||
assertFalse(listener.messageAdded);
|
||||
// Read whatever needs to be read
|
||||
simplex.read();
|
||||
assertTrue(transport.getDisposed());
|
||||
assertFalse(transport.getException());
|
||||
assertTrue(transport.getRecognised());
|
||||
session.run();
|
||||
transport.dispose(false, true);
|
||||
// The private message from Alice should have been added
|
||||
assertTrue(listener.messageAdded);
|
||||
// Clean up
|
||||
@@ -1,9 +1,7 @@
|
||||
package org.briarproject.messaging.simplex;
|
||||
package org.briarproject.messaging;
|
||||
|
||||
import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH;
|
||||
import static org.briarproject.api.transport.TransportConstants.HEADER_LENGTH;
|
||||
import static org.briarproject.api.transport.TransportConstants.MAC_LENGTH;
|
||||
import static org.briarproject.api.transport.TransportConstants.MIN_STREAM_LENGTH;
|
||||
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -23,14 +21,12 @@ import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DatabaseExecutor;
|
||||
import org.briarproject.api.messaging.Ack;
|
||||
import org.briarproject.api.messaging.MessageId;
|
||||
import org.briarproject.api.messaging.MessagingSession;
|
||||
import org.briarproject.api.messaging.PacketWriterFactory;
|
||||
import org.briarproject.api.transport.ConnectionRegistry;
|
||||
import org.briarproject.api.transport.StreamContext;
|
||||
import org.briarproject.api.transport.StreamWriterFactory;
|
||||
import org.briarproject.crypto.CryptoModule;
|
||||
import org.briarproject.event.EventModule;
|
||||
import org.briarproject.messaging.MessagingModule;
|
||||
import org.briarproject.messaging.duplex.DuplexMessagingModule;
|
||||
import org.briarproject.serial.SerialModule;
|
||||
import org.briarproject.transport.TransportModule;
|
||||
import org.jmock.Expectations;
|
||||
@@ -42,39 +38,37 @@ import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
|
||||
public class OutgoingSimplexConnectionTest extends BriarTestCase {
|
||||
public class SinglePassOutgoingSessionTest extends BriarTestCase {
|
||||
|
||||
// FIXME: This is an integration test, not a unit test
|
||||
|
||||
private final Mockery context;
|
||||
private final DatabaseComponent db;
|
||||
private final ConnectionRegistry connRegistry;
|
||||
private final StreamWriterFactory connWriterFactory;
|
||||
private final Executor dbExecutor;
|
||||
private final StreamWriterFactory streamWriterFactory;
|
||||
private final PacketWriterFactory packetWriterFactory;
|
||||
private final ContactId contactId;
|
||||
private final MessageId messageId;
|
||||
private final TransportId transportId;
|
||||
private final byte[] secret;
|
||||
|
||||
public OutgoingSimplexConnectionTest() {
|
||||
public SinglePassOutgoingSessionTest() {
|
||||
context = new Mockery();
|
||||
db = context.mock(DatabaseComponent.class);
|
||||
dbExecutor = Executors.newSingleThreadExecutor();
|
||||
Module testModule = new AbstractModule() {
|
||||
@Override
|
||||
public void configure() {
|
||||
bind(DatabaseComponent.class).toInstance(db);
|
||||
bind(Executor.class).annotatedWith(
|
||||
DatabaseExecutor.class).toInstance(
|
||||
Executors.newCachedThreadPool());
|
||||
DatabaseExecutor.class).toInstance(dbExecutor);
|
||||
}
|
||||
};
|
||||
Injector i = Guice.createInjector(testModule,
|
||||
new TestLifecycleModule(), new TestSystemModule(),
|
||||
new CryptoModule(), new EventModule(), new MessagingModule(),
|
||||
new DuplexMessagingModule(), new SimplexMessagingModule(),
|
||||
new SerialModule(), new TransportModule());
|
||||
connRegistry = i.getInstance(ConnectionRegistry.class);
|
||||
connWriterFactory = i.getInstance(StreamWriterFactory.class);
|
||||
streamWriterFactory = i.getInstance(StreamWriterFactory.class);
|
||||
packetWriterFactory = i.getInstance(PacketWriterFactory.class);
|
||||
contactId = new ContactId(234);
|
||||
messageId = new MessageId(TestUtils.getRandomId());
|
||||
@@ -83,34 +77,15 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase {
|
||||
new Random().nextBytes(secret);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionTooShort() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
TestSimplexTransportWriter transport = new TestSimplexTransportWriter(
|
||||
out, MAX_PACKET_LENGTH, Long.MAX_VALUE);
|
||||
StreamContext ctx = new StreamContext(contactId, transportId,
|
||||
secret, 0, true);
|
||||
OutgoingSimplexConnection connection = new OutgoingSimplexConnection(db,
|
||||
connRegistry, connWriterFactory, packetWriterFactory, ctx,
|
||||
transport);
|
||||
connection.write();
|
||||
// Nothing should have been written
|
||||
assertEquals(0, out.size());
|
||||
// The transport should have been disposed with exception == true
|
||||
assertTrue(transport.getDisposed());
|
||||
assertTrue(transport.getException());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNothingToSend() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
TestSimplexTransportWriter transport = new TestSimplexTransportWriter(
|
||||
out, MIN_STREAM_LENGTH, Long.MAX_VALUE);
|
||||
TestTransportConnectionWriter writer =
|
||||
new TestTransportConnectionWriter(out);
|
||||
StreamContext ctx = new StreamContext(contactId, transportId,
|
||||
secret, 0, true);
|
||||
OutgoingSimplexConnection connection = new OutgoingSimplexConnection(db,
|
||||
connRegistry, connWriterFactory, packetWriterFactory, ctx,
|
||||
transport);
|
||||
MessagingSession session = new SinglePassOutgoingSession(db, dbExecutor,
|
||||
streamWriterFactory, packetWriterFactory, ctx, writer);
|
||||
context.checking(new Expectations() {{
|
||||
// No transport acks to send
|
||||
oneOf(db).generateTransportAcks(contactId);
|
||||
@@ -141,25 +116,22 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase {
|
||||
with(any(long.class)));
|
||||
will(returnValue(null));
|
||||
}});
|
||||
connection.write();
|
||||
session.run();
|
||||
// Only the tag and an empty final frame should have been written
|
||||
assertEquals(TAG_LENGTH + HEADER_LENGTH + MAC_LENGTH, out.size());
|
||||
// The transport should have been disposed with exception == false
|
||||
assertTrue(transport.getDisposed());
|
||||
assertFalse(transport.getException());
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSomethingToSend() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
TestSimplexTransportWriter transport = new TestSimplexTransportWriter(
|
||||
out, MIN_STREAM_LENGTH, Long.MAX_VALUE);
|
||||
TestTransportConnectionWriter writer =
|
||||
new TestTransportConnectionWriter(out);
|
||||
StreamContext ctx = new StreamContext(contactId, transportId,
|
||||
secret, 0, true);
|
||||
OutgoingSimplexConnection connection = new OutgoingSimplexConnection(db,
|
||||
connRegistry, connWriterFactory, packetWriterFactory, ctx,
|
||||
transport);
|
||||
MessagingSession session = new SinglePassOutgoingSession(db, dbExecutor,
|
||||
streamWriterFactory, packetWriterFactory,
|
||||
ctx, writer);
|
||||
final byte[] raw = new byte[1234];
|
||||
context.checking(new Expectations() {{
|
||||
// No transport acks to send
|
||||
@@ -198,13 +170,10 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase {
|
||||
with(any(long.class)));
|
||||
will(returnValue(null));
|
||||
}});
|
||||
connection.write();
|
||||
session.run();
|
||||
// Something should have been written
|
||||
int overhead = TAG_LENGTH + HEADER_LENGTH + MAC_LENGTH;
|
||||
assertTrue(out.size() > overhead + UniqueId.LENGTH + raw.length);
|
||||
// The transport should have been disposed with exception == false
|
||||
assertTrue(transport.getDisposed());
|
||||
assertFalse(transport.getException());
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.briarproject.messaging;
|
||||
|
||||
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.briarproject.api.plugins.TransportConnectionReader;
|
||||
|
||||
class TestTransportConnectionReader implements TransportConnectionReader {
|
||||
|
||||
private final InputStream in;
|
||||
|
||||
private boolean disposed = false;
|
||||
|
||||
TestTransportConnectionReader(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
public int getMaxFrameLength() {
|
||||
return MAX_FRAME_LENGTH;
|
||||
}
|
||||
|
||||
public long getMaxLatency() {
|
||||
return Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return in;
|
||||
}
|
||||
|
||||
public void dispose(boolean exception, boolean recognised) {
|
||||
assert !disposed;
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.briarproject.messaging;
|
||||
|
||||
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.briarproject.api.plugins.TransportConnectionWriter;
|
||||
|
||||
class TestTransportConnectionWriter implements TransportConnectionWriter {
|
||||
|
||||
private final ByteArrayOutputStream out;
|
||||
|
||||
private boolean disposed = false;
|
||||
|
||||
TestTransportConnectionWriter(ByteArrayOutputStream out) {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
public long getCapacity() {
|
||||
return Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
public int getMaxFrameLength() {
|
||||
return MAX_FRAME_LENGTH;
|
||||
}
|
||||
|
||||
public long getMaxLatency() {
|
||||
return Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
return out;
|
||||
}
|
||||
|
||||
public void dispose(boolean exception) {
|
||||
assert !disposed;
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package org.briarproject.messaging.simplex;
|
||||
|
||||
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.briarproject.api.plugins.simplex.SimplexTransportReader;
|
||||
|
||||
class TestSimplexTransportReader implements SimplexTransportReader {
|
||||
|
||||
private final InputStream in;
|
||||
|
||||
private boolean disposed = false, exception = false, recognised = false;
|
||||
|
||||
TestSimplexTransportReader(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
public int getMaxFrameLength() {
|
||||
return MAX_FRAME_LENGTH;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return in;
|
||||
}
|
||||
|
||||
public void dispose(boolean exception, boolean recognised) {
|
||||
assert !disposed;
|
||||
disposed = true;
|
||||
this.exception = exception;
|
||||
this.recognised = recognised;
|
||||
}
|
||||
|
||||
boolean getDisposed() {
|
||||
return disposed;
|
||||
}
|
||||
|
||||
boolean getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
boolean getRecognised() {
|
||||
return recognised;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package org.briarproject.messaging.simplex;
|
||||
|
||||
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.briarproject.api.plugins.simplex.SimplexTransportWriter;
|
||||
|
||||
class TestSimplexTransportWriter implements SimplexTransportWriter {
|
||||
|
||||
private final ByteArrayOutputStream out;
|
||||
private final long capacity, maxLatency;
|
||||
|
||||
private boolean disposed = false, exception = false;
|
||||
|
||||
TestSimplexTransportWriter(ByteArrayOutputStream out, long capacity,
|
||||
long maxLatency) {
|
||||
this.out = out;
|
||||
this.capacity = capacity;
|
||||
this.maxLatency = maxLatency;
|
||||
}
|
||||
|
||||
public long getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
public int getMaxFrameLength() {
|
||||
return MAX_FRAME_LENGTH;
|
||||
}
|
||||
|
||||
public long getMaxLatency() {
|
||||
return maxLatency;
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
return out;
|
||||
}
|
||||
|
||||
public void dispose(boolean exception) {
|
||||
assert !disposed;
|
||||
disposed = true;
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
boolean getDisposed() {
|
||||
return disposed;
|
||||
}
|
||||
|
||||
boolean getException() {
|
||||
return exception;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import java.util.Scanner;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.crypto.PseudoRandom;
|
||||
import org.briarproject.api.plugins.TransportConnectionReader;
|
||||
import org.briarproject.api.plugins.TransportConnectionWriter;
|
||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
||||
|
||||
@@ -21,12 +23,14 @@ abstract class DuplexTest {
|
||||
|
||||
protected void sendChallengeReceiveResponse(DuplexTransportConnection d) {
|
||||
assert plugin != null;
|
||||
TransportConnectionReader r = d.getReader();
|
||||
TransportConnectionWriter w = d.getWriter();
|
||||
try {
|
||||
PrintStream out = new PrintStream(d.getOutputStream());
|
||||
PrintStream out = new PrintStream(w.getOutputStream());
|
||||
out.println(CHALLENGE);
|
||||
out.flush();
|
||||
System.out.println("Sent challenge: " + CHALLENGE);
|
||||
Scanner in = new Scanner(d.getInputStream());
|
||||
Scanner in = new Scanner(r.getInputStream());
|
||||
if(in.hasNextLine()) {
|
||||
String response = in.nextLine();
|
||||
System.out.println("Received response: " + response);
|
||||
@@ -38,11 +42,13 @@ abstract class DuplexTest {
|
||||
} else {
|
||||
System.out.println("No response");
|
||||
}
|
||||
d.dispose(false, true);
|
||||
r.dispose(false, true);
|
||||
w.dispose(false);
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
d.dispose(true, true);
|
||||
r.dispose(true, true);
|
||||
w.dispose(true);
|
||||
} catch(IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
@@ -51,13 +57,16 @@ abstract class DuplexTest {
|
||||
|
||||
protected void receiveChallengeSendResponse(DuplexTransportConnection d) {
|
||||
assert plugin != null;
|
||||
TransportConnectionReader r = d.getReader();
|
||||
TransportConnectionWriter w = d.getWriter();
|
||||
try {
|
||||
Scanner in = new Scanner(d.getInputStream());
|
||||
Scanner in = new Scanner(r.getInputStream());
|
||||
if(in.hasNextLine()) {
|
||||
String challenge = in.nextLine();
|
||||
System.out.println("Received challenge: " + challenge);
|
||||
if(CHALLENGE.equals(challenge)) {
|
||||
PrintStream out = new PrintStream(d.getOutputStream());
|
||||
|
||||
PrintStream out = new PrintStream(w.getOutputStream());
|
||||
out.println(RESPONSE);
|
||||
out.flush();
|
||||
System.out.println("Sent response: " + RESPONSE);
|
||||
@@ -67,11 +76,13 @@ abstract class DuplexTest {
|
||||
} else {
|
||||
System.out.println("No challenge");
|
||||
}
|
||||
d.dispose(false, true);
|
||||
r.dispose(false, true);
|
||||
w.dispose(false);
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
d.dispose(true, true);
|
||||
r.dispose(true, true);
|
||||
w.dispose(true);
|
||||
} catch(IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ import org.briarproject.BriarTestCase;
|
||||
import org.briarproject.TestFileUtils;
|
||||
import org.briarproject.TestUtils;
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.plugins.TransportConnectionWriter;
|
||||
import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
|
||||
import org.briarproject.api.plugins.simplex.SimplexTransportWriter;
|
||||
import org.briarproject.api.system.FileUtils;
|
||||
import org.briarproject.plugins.ImmediateExecutor;
|
||||
import org.briarproject.plugins.file.RemovableDriveMonitor.Callback;
|
||||
@@ -32,6 +32,7 @@ public class RemovableDrivePluginTest extends BriarTestCase {
|
||||
private final ContactId contactId = new ContactId(234);
|
||||
private final FileUtils fileUtils = new TestFileUtils();
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() {
|
||||
testDir.mkdirs();
|
||||
@@ -253,7 +254,7 @@ public class RemovableDrivePluginTest extends BriarTestCase {
|
||||
fileUtils, callback, finder, monitor, MAX_FRAME_LENGTH, 0);
|
||||
plugin.start();
|
||||
|
||||
SimplexTransportWriter writer = plugin.createWriter(contactId);
|
||||
TransportConnectionWriter writer = plugin.createWriter(contactId);
|
||||
assertNotNull(writer);
|
||||
// The output file should exist and should be empty
|
||||
File[] files = drive1.listFiles();
|
||||
@@ -352,6 +353,7 @@ public class RemovableDrivePluginTest extends BriarTestCase {
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Override
|
||||
@After
|
||||
public void tearDown() {
|
||||
TestUtils.deleteTestDirectory(testDir);
|
||||
|
||||
@@ -278,7 +278,8 @@ public class ModemPluginTest extends BriarTestCase {
|
||||
public Object invoke(Invocation invocation) throws Throwable {
|
||||
DuplexTransportConnection conn =
|
||||
(DuplexTransportConnection) invocation.getParameter(1);
|
||||
conn.dispose(false, true);
|
||||
conn.getReader().dispose(false, true);
|
||||
conn.getWriter().dispose(false);
|
||||
invoked.countDown();
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,8 @@ public class LanTcpPluginTest extends BriarTestCase {
|
||||
assertTrue(latch.await(5, SECONDS));
|
||||
assertFalse(error.get());
|
||||
// Clean up
|
||||
d.dispose(false, true);
|
||||
d.getReader().dispose(false, true);
|
||||
d.getWriter().dispose(false);
|
||||
ss.close();
|
||||
plugin.stop();
|
||||
}
|
||||
|
||||
@@ -25,8 +25,6 @@ public class OutgoingEncryptionLayerTest extends BriarTestCase {
|
||||
// FIXME: This is an integration test, not a unit test
|
||||
|
||||
private static final int FRAME_LENGTH = 1024;
|
||||
private static final int MAX_PAYLOAD_LENGTH =
|
||||
FRAME_LENGTH - HEADER_LENGTH - MAC_LENGTH;
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final AuthenticatedCipher frameCipher;
|
||||
@@ -56,7 +54,7 @@ public class OutgoingEncryptionLayerTest extends BriarTestCase {
|
||||
// Check that the actual tag and ciphertext match what's expected
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
OutgoingEncryptionLayer o = new OutgoingEncryptionLayer(out,
|
||||
10 * FRAME_LENGTH, frameCipher, frameKey, FRAME_LENGTH, tag);
|
||||
frameCipher, frameKey, FRAME_LENGTH, tag);
|
||||
o.writeFrame(new byte[FRAME_LENGTH - MAC_LENGTH], payloadLength, false);
|
||||
byte[] actual = out.toByteArray();
|
||||
assertEquals(TAG_LENGTH + FRAME_LENGTH, actual.length);
|
||||
@@ -67,93 +65,14 @@ public class OutgoingEncryptionLayerTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitiatorClosesConnectionWithoutWriting() throws Exception {
|
||||
public void testCloseConnectionWithoutWriting() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
// Initiator's constructor
|
||||
OutgoingEncryptionLayer o = new OutgoingEncryptionLayer(out,
|
||||
10 * FRAME_LENGTH, frameCipher, crypto.generateSecretKey(),
|
||||
FRAME_LENGTH, tag);
|
||||
frameCipher, crypto.generateSecretKey(), FRAME_LENGTH, tag);
|
||||
// Write an empty final frame without having written any other frames
|
||||
o.writeFrame(new byte[FRAME_LENGTH - MAC_LENGTH], 0, true);
|
||||
// The tag and the empty frame should be written to the output stream
|
||||
assertEquals(TAG_LENGTH + HEADER_LENGTH + MAC_LENGTH, out.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponderClosesConnectionWithoutWriting() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
// Responder's constructor
|
||||
OutgoingEncryptionLayer o = new OutgoingEncryptionLayer(out,
|
||||
10 * FRAME_LENGTH, frameCipher, crypto.generateSecretKey(),
|
||||
FRAME_LENGTH);
|
||||
// Write an empty final frame without having written any other frames
|
||||
o.writeFrame(new byte[FRAME_LENGTH - MAC_LENGTH], 0, true);
|
||||
// An empty final frame should be written to the output stream
|
||||
assertEquals(HEADER_LENGTH + MAC_LENGTH, out.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemainingCapacityWithTag() throws Exception {
|
||||
int MAX_PAYLOAD_LENGTH = FRAME_LENGTH - HEADER_LENGTH - MAC_LENGTH;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
// Initiator's constructor
|
||||
OutgoingEncryptionLayer o = new OutgoingEncryptionLayer(out,
|
||||
10 * FRAME_LENGTH, frameCipher, crypto.generateSecretKey(),
|
||||
FRAME_LENGTH, tag);
|
||||
// There should be space for nine full frames and one partial frame
|
||||
byte[] frame = new byte[FRAME_LENGTH - MAC_LENGTH];
|
||||
assertEquals(10 * MAX_PAYLOAD_LENGTH - TAG_LENGTH,
|
||||
o.getRemainingCapacity());
|
||||
// Write nine frames, each containing a partial payload
|
||||
for(int i = 0; i < 9; i++) {
|
||||
o.writeFrame(frame, 123, false);
|
||||
assertEquals((9 - i) * MAX_PAYLOAD_LENGTH - TAG_LENGTH,
|
||||
o.getRemainingCapacity());
|
||||
}
|
||||
// Write the final frame, which will not be padded
|
||||
o.writeFrame(frame, 123, true);
|
||||
int finalFrameLength = HEADER_LENGTH + 123 + MAC_LENGTH;
|
||||
assertEquals(MAX_PAYLOAD_LENGTH - TAG_LENGTH - finalFrameLength,
|
||||
o.getRemainingCapacity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemainingCapacityWithoutTag() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
// Responder's constructor
|
||||
OutgoingEncryptionLayer o = new OutgoingEncryptionLayer(out,
|
||||
10 * FRAME_LENGTH, frameCipher, crypto.generateSecretKey(),
|
||||
FRAME_LENGTH);
|
||||
// There should be space for ten full frames
|
||||
assertEquals(10 * MAX_PAYLOAD_LENGTH, o.getRemainingCapacity());
|
||||
// Write nine frames, each containing a partial payload
|
||||
byte[] frame = new byte[FRAME_LENGTH - MAC_LENGTH];
|
||||
for(int i = 0; i < 9; i++) {
|
||||
o.writeFrame(frame, 123, false);
|
||||
assertEquals((9 - i) * MAX_PAYLOAD_LENGTH,
|
||||
o.getRemainingCapacity());
|
||||
}
|
||||
// Write the final frame, which will not be padded
|
||||
o.writeFrame(frame, 123, true);
|
||||
int finalFrameLength = HEADER_LENGTH + 123 + MAC_LENGTH;
|
||||
assertEquals(MAX_PAYLOAD_LENGTH - finalFrameLength,
|
||||
o.getRemainingCapacity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemainingCapacityLimitedByFrameNumbers() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
// The connection has plenty of space so we're limited by frame numbers
|
||||
OutgoingEncryptionLayer o = new OutgoingEncryptionLayer(out,
|
||||
Long.MAX_VALUE, frameCipher, crypto.generateSecretKey(),
|
||||
FRAME_LENGTH);
|
||||
// There should be enough frame numbers for 2^32 frames
|
||||
assertEquals((1L << 32) * MAX_PAYLOAD_LENGTH, o.getRemainingCapacity());
|
||||
// Write a frame containing a partial payload
|
||||
byte[] frame = new byte[FRAME_LENGTH - MAC_LENGTH];
|
||||
o.writeFrame(frame, 123, false);
|
||||
// There should be enough frame numbers for 2^32 - 1 frames
|
||||
assertEquals(((1L << 32) - 1) * MAX_PAYLOAD_LENGTH,
|
||||
o.getRemainingCapacity());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package org.briarproject.transport;
|
||||
|
||||
import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH;
|
||||
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
|
||||
import static org.briarproject.api.transport.TransportConstants.MIN_STREAM_LENGTH;
|
||||
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Random;
|
||||
@@ -14,13 +13,9 @@ import java.util.Random;
|
||||
import org.briarproject.BriarTestCase;
|
||||
import org.briarproject.TestLifecycleModule;
|
||||
import org.briarproject.TestSystemModule;
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.TransportId;
|
||||
import org.briarproject.api.crypto.AuthenticatedCipher;
|
||||
import org.briarproject.api.crypto.CryptoComponent;
|
||||
import org.briarproject.api.crypto.SecretKey;
|
||||
import org.briarproject.api.transport.StreamContext;
|
||||
import org.briarproject.api.transport.StreamWriter;
|
||||
import org.briarproject.api.transport.StreamWriterFactory;
|
||||
import org.briarproject.crypto.CryptoModule;
|
||||
import org.junit.Test;
|
||||
@@ -35,13 +30,10 @@ public class TransportIntegrationTest extends BriarTestCase {
|
||||
private final int FRAME_LENGTH = 2048;
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final StreamWriterFactory streamWriterFactory;
|
||||
private final ContactId contactId;
|
||||
private final TransportId transportId;
|
||||
private final AuthenticatedCipher frameCipher;
|
||||
private final Random random;
|
||||
private final byte[] secret;
|
||||
private final SecretKey frameKey;
|
||||
private final SecretKey tagKey, frameKey;
|
||||
|
||||
public TransportIntegrationTest() {
|
||||
Module testModule = new AbstractModule() {
|
||||
@@ -54,15 +46,13 @@ public class TransportIntegrationTest extends BriarTestCase {
|
||||
Injector i = Guice.createInjector(testModule, new CryptoModule(),
|
||||
new TestLifecycleModule(), new TestSystemModule());
|
||||
crypto = i.getInstance(CryptoComponent.class);
|
||||
streamWriterFactory = i.getInstance(StreamWriterFactory.class);
|
||||
contactId = new ContactId(234);
|
||||
transportId = new TransportId("id");
|
||||
frameCipher = crypto.getFrameCipher();
|
||||
random = new Random();
|
||||
// Since we're sending frames to ourselves, we only need outgoing keys
|
||||
secret = new byte[32];
|
||||
random.nextBytes(secret);
|
||||
frameKey = crypto.deriveFrameKey(secret, 0, true, true);
|
||||
tagKey = crypto.deriveTagKey(secret, true);
|
||||
frameKey = crypto.deriveFrameKey(secret, 0, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -76,6 +66,9 @@ public class TransportIntegrationTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
private void testWriteAndRead(boolean initiator) throws Exception {
|
||||
// Encode the tag
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(tag, tagKey, 0);
|
||||
// Generate two random frames
|
||||
byte[] frame = new byte[1234];
|
||||
random.nextBytes(frame);
|
||||
@@ -83,87 +76,46 @@ public class TransportIntegrationTest extends BriarTestCase {
|
||||
random.nextBytes(frame1);
|
||||
// Copy the frame key - the copy will be erased
|
||||
SecretKey frameCopy = frameKey.copy();
|
||||
// Write the frames
|
||||
// Write the tag and the frames
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
FrameWriter encryptionOut = new OutgoingEncryptionLayer(out,
|
||||
Long.MAX_VALUE, frameCipher, frameCopy, FRAME_LENGTH);
|
||||
StreamWriterImpl writer = new StreamWriterImpl(encryptionOut,
|
||||
FrameWriter frameWriter = new OutgoingEncryptionLayer(out,
|
||||
frameCipher, frameCopy, FRAME_LENGTH, tag);
|
||||
StreamWriterImpl streamWriter = new StreamWriterImpl(frameWriter,
|
||||
FRAME_LENGTH);
|
||||
OutputStream out1 = writer.getOutputStream();
|
||||
OutputStream out1 = streamWriter.getOutputStream();
|
||||
out1.write(frame);
|
||||
out1.flush();
|
||||
out1.write(frame1);
|
||||
out1.flush();
|
||||
byte[] output = out.toByteArray();
|
||||
assertEquals(FRAME_LENGTH * 2, output.length);
|
||||
// Read the tag and the frames back
|
||||
assertEquals(TAG_LENGTH + FRAME_LENGTH * 2, output.length);
|
||||
// Read the tag back
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(output);
|
||||
FrameReader encryptionIn = new IncomingEncryptionLayer(in, frameCipher,
|
||||
byte[] recoveredTag = new byte[tag.length];
|
||||
read(in, recoveredTag);
|
||||
assertArrayEquals(tag, recoveredTag);
|
||||
// Read the frames back
|
||||
FrameReader frameReader = new IncomingEncryptionLayer(in, frameCipher,
|
||||
frameKey, FRAME_LENGTH);
|
||||
StreamReaderImpl reader = new StreamReaderImpl(encryptionIn,
|
||||
StreamReaderImpl streamReader = new StreamReaderImpl(frameReader,
|
||||
FRAME_LENGTH);
|
||||
InputStream in1 = reader.getInputStream();
|
||||
byte[] recovered = new byte[frame.length];
|
||||
InputStream in1 = streamReader.getInputStream();
|
||||
byte[] recoveredFrame = new byte[frame.length];
|
||||
read(in1, recoveredFrame);
|
||||
assertArrayEquals(frame, recoveredFrame);
|
||||
byte[] recoveredFrame1 = new byte[frame1.length];
|
||||
read(in1, recoveredFrame1);
|
||||
assertArrayEquals(frame1, recoveredFrame1);
|
||||
streamWriter.close();
|
||||
streamReader.close();
|
||||
}
|
||||
|
||||
private void read(InputStream in, byte[] dest) throws IOException {
|
||||
int offset = 0;
|
||||
while(offset < recovered.length) {
|
||||
int read = in1.read(recovered, offset, recovered.length - offset);
|
||||
while(offset < dest.length) {
|
||||
int read = in.read(dest, offset, dest.length - offset);
|
||||
if(read == -1) break;
|
||||
offset += read;
|
||||
}
|
||||
assertEquals(recovered.length, offset);
|
||||
assertArrayEquals(frame, recovered);
|
||||
byte[] recovered1 = new byte[frame1.length];
|
||||
offset = 0;
|
||||
while(offset < recovered1.length) {
|
||||
int read = in1.read(recovered1, offset, recovered1.length - offset);
|
||||
if(read == -1) break;
|
||||
offset += read;
|
||||
}
|
||||
assertEquals(recovered1.length, offset);
|
||||
assertArrayEquals(frame1, recovered1);
|
||||
writer.close();
|
||||
reader.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverheadWithTag() throws Exception {
|
||||
ByteArrayOutputStream out =
|
||||
new ByteArrayOutputStream(MIN_STREAM_LENGTH);
|
||||
StreamContext ctx = new StreamContext(contactId, transportId,
|
||||
secret, 0, true);
|
||||
StreamWriter w = streamWriterFactory.createStreamWriter(out,
|
||||
MAX_FRAME_LENGTH, MIN_STREAM_LENGTH, ctx, false, true);
|
||||
// Check that the connection writer thinks there's room for a packet
|
||||
long capacity = w.getRemainingCapacity();
|
||||
assertTrue(capacity > MAX_PACKET_LENGTH);
|
||||
assertTrue(capacity < MIN_STREAM_LENGTH);
|
||||
// Check that there really is room for a packet
|
||||
byte[] payload = new byte[MAX_PACKET_LENGTH];
|
||||
w.getOutputStream().write(payload);
|
||||
w.getOutputStream().close();
|
||||
long used = out.size();
|
||||
assertTrue(used > MAX_PACKET_LENGTH);
|
||||
assertTrue(used <= MIN_STREAM_LENGTH);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverheadWithoutTag() throws Exception {
|
||||
ByteArrayOutputStream out =
|
||||
new ByteArrayOutputStream(MIN_STREAM_LENGTH);
|
||||
StreamContext ctx = new StreamContext(contactId, transportId,
|
||||
secret, 0, true);
|
||||
StreamWriter w = streamWriterFactory.createStreamWriter(out,
|
||||
MAX_FRAME_LENGTH, MIN_STREAM_LENGTH, ctx, false, false);
|
||||
// Check that the connection writer thinks there's room for a packet
|
||||
long capacity = w.getRemainingCapacity();
|
||||
assertTrue(capacity > MAX_PACKET_LENGTH);
|
||||
assertTrue(capacity < MIN_STREAM_LENGTH);
|
||||
// Check that there really is room for a packet
|
||||
byte[] payload = new byte[MAX_PACKET_LENGTH];
|
||||
w.getOutputStream().write(payload);
|
||||
w.getOutputStream().close();
|
||||
long used = out.size();
|
||||
assertTrue(used > MAX_PACKET_LENGTH);
|
||||
assertTrue(used <= MIN_STREAM_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user