mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user