Allow the max packet length to be reduced from the default.

This commit is contained in:
akwizgran
2011-09-21 13:47:06 +01:00
parent 77d61e0aea
commit 7e58b25618
7 changed files with 108 additions and 17 deletions

View File

@@ -7,6 +7,12 @@ import net.sf.briar.api.protocol.BatchId;
/** An interface for creating an ack packet. */ /** An interface for creating an ack packet. */
public interface AckWriter { public interface AckWriter {
/**
* Sets the maximum length of the serialised ack. If this method is not
* called, the default is ProtocolConstants.MAX_PACKET_LENGTH;
*/
void setMaxPacketLength(int length);
/** /**
* Attempts to add the given BatchId to the ack and returns true if it * Attempts to add the given BatchId to the ack and returns true if it
* was added. * was added.

View File

@@ -7,6 +7,12 @@ import net.sf.briar.api.protocol.BatchId;
/** An interface for creating a batch packet. */ /** An interface for creating a batch packet. */
public interface BatchWriter { public interface BatchWriter {
/**
* Sets the maximum length of the serialised batch. If this method is not
* called, the default is ProtocolConstants.MAX_PACKET_LENGTH;
*/
void setMaxPacketLength(int length);
/** /**
* Attempts to add the given raw message to the batch and returns true if * Attempts to add the given raw message to the batch and returns true if
* it was added. * it was added.

View File

@@ -7,6 +7,12 @@ import net.sf.briar.api.protocol.MessageId;
/** An interface for creating an offer packet. */ /** An interface for creating an offer packet. */
public interface OfferWriter { public interface OfferWriter {
/**
* Sets the maximum length of the serialised offer. If this method is not
* called, the default is ProtocolConstants.MAX_PACKET_LENGTH;
*/
void setMaxPacketLength(int length);
/** /**
* Attempts to add the given message ID to the offer and returns true if it * Attempts to add the given message ID to the offer and returns true if it
* was added. * was added.

View File

@@ -18,7 +18,7 @@ class AckWriterImpl implements AckWriter {
private final Writer w; private final Writer w;
private boolean started = false; private boolean started = false;
private int capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME private int capacity = ProtocolConstants.MAX_PACKET_LENGTH;
AckWriterImpl(OutputStream out, SerialComponent serial, AckWriterImpl(OutputStream out, SerialComponent serial,
WriterFactory writerFactory) { WriterFactory writerFactory) {
@@ -30,6 +30,13 @@ class AckWriterImpl implements AckWriter {
w = writerFactory.createWriter(out); w = writerFactory.createWriter(out);
} }
public void setMaxPacketLength(int length) {
if(started) throw new IllegalStateException();
if(length < 0 || length > ProtocolConstants.MAX_PACKET_LENGTH)
throw new IllegalArgumentException();
capacity = length;
}
public boolean writeBatchId(BatchId b) throws IOException { public boolean writeBatchId(BatchId b) throws IOException {
int overhead = started ? footerLength : headerLength + footerLength; int overhead = started ? footerLength : headerLength + footerLength;
if(capacity < idLength + overhead) return false; if(capacity < idLength + overhead) return false;
@@ -43,7 +50,7 @@ class AckWriterImpl implements AckWriter {
if(!started) start(); if(!started) start();
w.writeListEnd(); w.writeListEnd();
out.flush(); out.flush();
capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME capacity = ProtocolConstants.MAX_PACKET_LENGTH;
started = false; started = false;
} }

View File

@@ -21,7 +21,7 @@ class BatchWriterImpl implements BatchWriter {
private final MessageDigest messageDigest; private final MessageDigest messageDigest;
private boolean started = false; private boolean started = false;
private int capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME private int capacity = ProtocolConstants.MAX_PACKET_LENGTH;
BatchWriterImpl(OutputStream out, SerialComponent serial, BatchWriterImpl(OutputStream out, SerialComponent serial,
WriterFactory writerFactory, MessageDigest messageDigest) { WriterFactory writerFactory, MessageDigest messageDigest) {
@@ -33,6 +33,13 @@ class BatchWriterImpl implements BatchWriter {
this.messageDigest = messageDigest; this.messageDigest = messageDigest;
} }
public void setMaxPacketLength(int length) {
if(started) throw new IllegalStateException();
if(length < 0 || length > ProtocolConstants.MAX_PACKET_LENGTH)
throw new IllegalArgumentException();
capacity = length;
}
public boolean writeMessage(byte[] message) throws IOException { public boolean writeMessage(byte[] message) throws IOException {
int overhead = started ? footerLength : headerLength + footerLength; int overhead = started ? footerLength : headerLength + footerLength;
if(capacity < message.length + overhead) return false; if(capacity < message.length + overhead) return false;
@@ -47,7 +54,7 @@ class BatchWriterImpl implements BatchWriter {
if(!started) start(); if(!started) start();
w.writeListEnd(); w.writeListEnd();
out.flush(); out.flush();
capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME capacity = ProtocolConstants.MAX_PACKET_LENGTH;
started = false; started = false;
return new BatchId(messageDigest.digest()); return new BatchId(messageDigest.digest());
} }

View File

@@ -18,7 +18,7 @@ class OfferWriterImpl implements OfferWriter {
private final Writer w; private final Writer w;
private boolean started = false; private boolean started = false;
private int capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME private int capacity = ProtocolConstants.MAX_PACKET_LENGTH;
OfferWriterImpl(OutputStream out, SerialComponent serial, OfferWriterImpl(OutputStream out, SerialComponent serial,
WriterFactory writerFactory) { WriterFactory writerFactory) {
@@ -30,6 +30,13 @@ class OfferWriterImpl implements OfferWriter {
w = writerFactory.createWriter(out); w = writerFactory.createWriter(out);
} }
public void setMaxPacketLength(int length) {
if(started) throw new IllegalStateException();
if(length < 0 || length > ProtocolConstants.MAX_PACKET_LENGTH)
throw new IllegalArgumentException();
capacity = length;
}
public boolean writeMessageId(MessageId m) throws IOException { public boolean writeMessageId(MessageId m) throws IOException {
int overhead = started ? footerLength : headerLength + footerLength; int overhead = started ? footerLength : headerLength + footerLength;
if(capacity < idLength + overhead) return false; if(capacity < idLength + overhead) return false;
@@ -43,7 +50,7 @@ class OfferWriterImpl implements OfferWriter {
if(!started) start(); if(!started) start();
w.writeListEnd(); w.writeListEnd();
out.flush(); out.flush();
capacity = ProtocolConstants.MAX_PACKET_LENGTH; // FIXME capacity = ProtocolConstants.MAX_PACKET_LENGTH;
started = false; started = false;
} }

View File

@@ -58,15 +58,35 @@ public class ConstantsTest extends TestCase {
} }
@Test @Test
public void testBatchesFitIntoAck() throws Exception { public void testBatchesFitIntoLargeAck() throws Exception {
// Create an ack with the maximum number of batch IDs testBatchesFitIntoAck(ProtocolConstants.MAX_PACKET_LENGTH);
ByteArrayOutputStream out = new ByteArrayOutputStream( }
ProtocolConstants.MAX_PACKET_LENGTH);
@Test
public void testBatchesFitIntoSmallAck() throws Exception {
testBatchesFitIntoAck(1000);
}
private void testBatchesFitIntoAck(int length) throws Exception {
// Create an ack with as many batch IDs as possible
ByteArrayOutputStream out = new ByteArrayOutputStream(length);
AckWriter a = new AckWriterImpl(out, serial, writerFactory); AckWriter a = new AckWriterImpl(out, serial, writerFactory);
a.setMaxPacketLength(length);
while(a.writeBatchId(new BatchId(TestUtils.getRandomId()))); while(a.writeBatchId(new BatchId(TestUtils.getRandomId())));
a.finish(); a.finish();
// Check the size of the serialised ack // Check the size of the serialised ack
assertTrue(out.size() <= ProtocolConstants.MAX_PACKET_LENGTH); assertTrue(out.size() <= length);
}
@Test
public void testEmptyAck() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
AckWriter a = new AckWriterImpl(out, serial, writerFactory);
// There's not enough room for a batch ID
a.setMaxPacketLength(4);
assertFalse(a.writeBatchId(new BatchId(TestUtils.getRandomId())));
// Check that nothing was written
assertEquals(0, out.size());
} }
@Test @Test
@@ -90,7 +110,7 @@ public class ConstantsTest extends TestCase {
ProtocolConstants.MAX_PACKET_LENGTH); ProtocolConstants.MAX_PACKET_LENGTH);
BatchWriter b = new BatchWriterImpl(out, serial, writerFactory, BatchWriter b = new BatchWriterImpl(out, serial, writerFactory,
crypto.getMessageDigest()); crypto.getMessageDigest());
b.writeMessage(message.getBytes()); assertTrue(b.writeMessage(message.getBytes()));
b.finish(); b.finish();
// Check the size of the serialised batch // Check the size of the serialised batch
assertTrue(out.size() > UniqueId.LENGTH + Group.MAX_NAME_LENGTH + assertTrue(out.size() > UniqueId.LENGTH + Group.MAX_NAME_LENGTH +
@@ -100,15 +120,47 @@ public class ConstantsTest extends TestCase {
} }
@Test @Test
public void testMessagesFitIntoOffer() throws Exception { public void testEmptyBatch() throws Exception {
// Create an offer with the maximum number of message IDs ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream( BatchWriter b = new BatchWriterImpl(out, serial, writerFactory,
ProtocolConstants.MAX_PACKET_LENGTH); crypto.getMessageDigest());
// There's not enough room for a message
b.setMaxPacketLength(4);
assertFalse(b.writeMessage(new byte[4]));
// Check that nothing was written
assertEquals(0, out.size());
}
@Test
public void testMessagesFitIntoLargeOffer() throws Exception {
testMessagesFitIntoOffer(ProtocolConstants.MAX_PACKET_LENGTH);
}
@Test
public void testMessagesFitIntoSmallOffer() throws Exception {
testMessagesFitIntoOffer(1000);
}
private void testMessagesFitIntoOffer(int length) throws Exception {
// Create an offer with as many message IDs as possible
ByteArrayOutputStream out = new ByteArrayOutputStream(length);
OfferWriter o = new OfferWriterImpl(out, serial, writerFactory); OfferWriter o = new OfferWriterImpl(out, serial, writerFactory);
o.setMaxPacketLength(length);
while(o.writeMessageId(new MessageId(TestUtils.getRandomId()))); while(o.writeMessageId(new MessageId(TestUtils.getRandomId())));
o.finish(); o.finish();
// Check the size of the serialised offer // Check the size of the serialised offer
assertTrue(out.size() <= ProtocolConstants.MAX_PACKET_LENGTH); assertTrue(out.size() <= length);
}
@Test
public void testEmptyOffer() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
OfferWriter o = new OfferWriterImpl(out, serial, writerFactory);
// There's not enough room for a message ID
o.setMaxPacketLength(4);
assertFalse(o.writeMessageId(new MessageId(TestUtils.getRandomId())));
// Check that nothing was written
assertEquals(0, out.size());
} }
@Test @Test