Increased the maximum packet size to 1 MiB.

This should provide acceptable memory usage and database locking
granularity, while making subscription and transport updates large
enough for the incremental update issue to be kicked into the long
grass.

Removed awareness of the serialisation format from the protocol
component wherever possible, and added tests to ensure that the
constants defined in the protocol package's API are compatible with
the serialisation format.
This commit is contained in:
akwizgran
2011-09-07 13:51:30 +01:00
parent 1ac1609dc2
commit 331e7e0547
18 changed files with 258 additions and 42 deletions

View File

@@ -3,6 +3,7 @@ package net.sf.briar.protocol;
import java.io.IOException;
import java.util.Collection;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.protocol.Ack;
import net.sf.briar.api.protocol.BatchId;
import net.sf.briar.api.protocol.ProtocolConstants;
@@ -30,6 +31,7 @@ class AckReader implements ObjectReader<Ack> {
r.readUserDefinedTag(Tags.ACK);
r.addObjectReader(Tags.BATCH_ID, batchIdReader);
Collection<BatchId> batches = r.readList(BatchId.class);
if(batches.size() > Ack.MAX_IDS_PER_ACK) throw new FormatException();
r.removeObjectReader(Tags.BATCH_ID);
r.removeConsumer(counting);
// Build and return the ack

View File

@@ -78,7 +78,10 @@ class MessageEncoderImpl implements MessageEncoder {
} else {
signature.initSign(authorKey);
signature.update(out.toByteArray());
w.writeBytes(signature.sign());
byte[] sig = signature.sign();
if(sig.length > Message.MAX_SIGNATURE_LENGTH)
throw new IllegalArgumentException();
w.writeBytes(sig);
}
// Sign the message with the group's private key, if there is one
if(groupKey == null) {
@@ -86,7 +89,10 @@ class MessageEncoderImpl implements MessageEncoder {
} else {
signature.initSign(groupKey);
signature.update(out.toByteArray());
w.writeBytes(signature.sign());
byte[] sig = signature.sign();
if(sig.length > Message.MAX_SIGNATURE_LENGTH)
throw new IllegalArgumentException();
w.writeBytes(sig);
}
// Hash the message, including the signatures, to get the message ID
byte[] raw = out.toByteArray();

View File

@@ -14,6 +14,7 @@ import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.Group;
import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.ProtocolConstants;
import net.sf.briar.api.protocol.Tags;
import net.sf.briar.api.serial.ObjectReader;
import net.sf.briar.api.serial.Reader;
@@ -41,7 +42,8 @@ class MessageReader implements ObjectReader<Message> {
public Message readObject(Reader r) throws IOException {
CopyingConsumer copying = new CopyingConsumer();
CountingConsumer counting = new CountingConsumer(Message.MAX_LENGTH);
CountingConsumer counting =
new CountingConsumer(ProtocolConstants.MAX_PACKET_LENGTH);
r.addConsumer(copying);
r.addConsumer(counting);
// Read the initial tag
@@ -64,7 +66,7 @@ class MessageReader implements ObjectReader<Message> {
long timestamp = r.readInt64();
if(timestamp < 0L) throw new FormatException();
// Skip the message body
r.readBytes(Message.MAX_LENGTH);
r.readBytes(Message.MAX_BODY_LENGTH);
// Record the length of the data covered by the author's signature
int signedByAuthor = (int) counting.getCount();
// Read the author's signature, if there is one

View File

@@ -4,6 +4,7 @@ import java.io.IOException;
import java.security.MessageDigest;
import java.util.Collection;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer;
@@ -39,6 +40,8 @@ class OfferReader implements ObjectReader<Offer> {
r.readUserDefinedTag(Tags.OFFER);
r.addObjectReader(Tags.MESSAGE_ID, messageIdReader);
Collection<MessageId> messages = r.readList(MessageId.class);
if(messages.size() > Offer.MAX_IDS_PER_OFFER)
throw new FormatException();
r.removeObjectReader(Tags.MESSAGE_ID);
r.removeConsumer(digesting);
r.removeConsumer(counting);

View File

@@ -5,6 +5,7 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.protocol.ProtocolConstants;
import net.sf.briar.api.protocol.Tags;
import net.sf.briar.api.protocol.TransportUpdate;
@@ -34,9 +35,14 @@ class TransportReader implements ObjectReader<TransportUpdate> {
List<TransportProperties> l = r.readList(TransportProperties.class);
r.resetMaxStringLength();
r.removeObjectReader(Tags.TRANSPORT_PROPERTIES);
if(l.size() > TransportUpdate.MAX_PLUGINS_PER_UPDATE)
throw new FormatException();
Map<String, Map<String, String>> transports =
new TreeMap<String, Map<String, String>>();
for(TransportProperties t : l) transports.put(t.name, t.properties);
for(TransportProperties t : l) {
if(transports.put(t.name, t.properties) != null)
throw new FormatException(); // Duplicate plugin name
}
long timestamp = r.readInt64();
r.removeConsumer(counting);
// Build and return the transport update
@@ -59,9 +65,13 @@ class TransportReader implements ObjectReader<TransportUpdate> {
public TransportProperties readObject(Reader r) throws IOException {
r.readUserDefinedTag(Tags.TRANSPORT_PROPERTIES);
String name = r.readString();
String name = r.readString(TransportUpdate.MAX_NAME_LENGTH);
r.setMaxStringLength(TransportUpdate.MAX_KEY_OR_VALUE_LENGTH);
Map<String, String> properties =
r.readMap(String.class, String.class);
r.resetMaxStringLength();
if(properties.size() > TransportUpdate.MAX_PROPERTIES_PER_PLUGIN)
throw new FormatException();
return new TransportProperties(name, properties);
}
}

View File

@@ -3,8 +3,8 @@ package net.sf.briar.protocol.writers;
import java.io.IOException;
import java.io.OutputStream;
import net.sf.briar.api.protocol.Ack;
import net.sf.briar.api.protocol.BatchId;
import net.sf.briar.api.protocol.ProtocolConstants;
import net.sf.briar.api.protocol.Tags;
import net.sf.briar.api.protocol.writers.AckWriter;
import net.sf.briar.api.serial.Writer;
@@ -16,6 +16,7 @@ class AckWriterImpl implements AckWriter {
private final Writer w;
private boolean started = false;
private int idsWritten = 0;
AckWriterImpl(OutputStream out, WriterFactory writerFactory) {
this.out = out;
@@ -28,12 +29,9 @@ class AckWriterImpl implements AckWriter {
w.writeListStart();
started = true;
}
int capacity = ProtocolConstants.MAX_PACKET_LENGTH
- (int) w.getBytesWritten() - 1;
// Allow one byte for the BATCH_ID tag, one byte for the BYTES tag and
// one byte for the length as a uint7
if(capacity < BatchId.LENGTH + 3) return false;
if(idsWritten >= Ack.MAX_IDS_PER_ACK) return false;
b.writeTo(w);
idsWritten++;
return true;
}

View File

@@ -40,6 +40,7 @@ class BatchWriterImpl implements BatchWriter {
w.writeListStart();
started = true;
}
// Allow one byte for the list end tag
int capacity = ProtocolConstants.MAX_PACKET_LENGTH
- (int) w.getBytesWritten() - 1;
if(capacity < message.length) return false;

View File

@@ -6,8 +6,8 @@ import java.security.DigestOutputStream;
import java.security.MessageDigest;
import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.OfferId;
import net.sf.briar.api.protocol.ProtocolConstants;
import net.sf.briar.api.protocol.Tags;
import net.sf.briar.api.protocol.writers.OfferWriter;
import net.sf.briar.api.serial.Writer;
@@ -20,6 +20,7 @@ class OfferWriterImpl implements OfferWriter {
private final MessageDigest messageDigest;
private boolean started = false;
private int idsWritten = 0;
OfferWriterImpl(OutputStream out, WriterFactory writerFactory,
MessageDigest messageDigest) {
@@ -35,12 +36,9 @@ class OfferWriterImpl implements OfferWriter {
w.writeListStart();
started = true;
}
int capacity = ProtocolConstants.MAX_PACKET_LENGTH
- (int) w.getBytesWritten() - 1;
// Allow one byte for the MESSAGE_ID tag, one byte for the BYTES tag
// and one byte for the length as a uint7
if(capacity < MessageId.LENGTH + 3) return false;
if(idsWritten >= Offer.MAX_IDS_PER_OFFER) return false;
m.writeTo(w);
idsWritten++;
return true;
}