From 30fc6c1a927c94e6dd344e3cc81d3a7062b81851 Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Mon, 18 Jul 2011 17:44:18 +0100 Subject: [PATCH] Defined some user-defined tags for protocol elements. Currently they're just adding redundancy, but in future they'll be used for parsing nested elements. --- api/net/sf/briar/api/protocol/AuthorId.java | 8 +++ api/net/sf/briar/api/protocol/BatchId.java | 8 +++ api/net/sf/briar/api/protocol/GroupId.java | 8 +++ api/net/sf/briar/api/protocol/MessageId.java | 8 +++ api/net/sf/briar/api/protocol/Tags.java | 16 ++++++ api/net/sf/briar/api/protocol/UniqueId.java | 3 +- api/net/sf/briar/api/serial/Reader.java | 1 + api/net/sf/briar/api/serial/Tag.java | 48 +++++++++--------- api/net/sf/briar/api/serial/Writable.java | 8 +++ .../sf/briar/protocol/BundleReaderImpl.java | 33 +++++++++++-- .../sf/briar/protocol/BundleWriterImpl.java | 49 +++++++++++-------- .../net/sf/briar/serial/ReaderImpl.java | 4 ++ test/net/sf/briar/serial/ReaderImplTest.java | 2 +- test/net/sf/briar/serial/WriterImplTest.java | 2 +- 14 files changed, 146 insertions(+), 52 deletions(-) create mode 100644 api/net/sf/briar/api/protocol/Tags.java create mode 100644 api/net/sf/briar/api/serial/Writable.java diff --git a/api/net/sf/briar/api/protocol/AuthorId.java b/api/net/sf/briar/api/protocol/AuthorId.java index 578c89c2ac..4f50e2ae22 100644 --- a/api/net/sf/briar/api/protocol/AuthorId.java +++ b/api/net/sf/briar/api/protocol/AuthorId.java @@ -1,7 +1,10 @@ package net.sf.briar.api.protocol; +import java.io.IOException; import java.util.Arrays; +import net.sf.briar.api.serial.Writer; + /** Type-safe wrapper for a byte array that uniquely identifies an author. */ public class AuthorId extends UniqueId { @@ -9,6 +12,11 @@ public class AuthorId extends UniqueId { super(id); } + public void writeTo(Writer w) throws IOException { + w.writeUserDefinedTag(Tags.AUTHOR_ID); + w.writeRaw(id); + } + @Override public boolean equals(Object o) { if(o instanceof AuthorId) diff --git a/api/net/sf/briar/api/protocol/BatchId.java b/api/net/sf/briar/api/protocol/BatchId.java index ab33800761..a1640913d6 100644 --- a/api/net/sf/briar/api/protocol/BatchId.java +++ b/api/net/sf/briar/api/protocol/BatchId.java @@ -1,7 +1,10 @@ package net.sf.briar.api.protocol; +import java.io.IOException; import java.util.Arrays; +import net.sf.briar.api.serial.Writer; + /** * Type-safe wrapper for a byte array that uniquely identifies a batch of * messages. @@ -12,6 +15,11 @@ public class BatchId extends UniqueId { super(id); } + public void writeTo(Writer w) throws IOException { + w.writeUserDefinedTag(Tags.BATCH_ID); + w.writeRaw(id); + } + @Override public boolean equals(Object o) { if(o instanceof BatchId) diff --git a/api/net/sf/briar/api/protocol/GroupId.java b/api/net/sf/briar/api/protocol/GroupId.java index 5329418679..0cf267d16c 100644 --- a/api/net/sf/briar/api/protocol/GroupId.java +++ b/api/net/sf/briar/api/protocol/GroupId.java @@ -1,7 +1,10 @@ package net.sf.briar.api.protocol; +import java.io.IOException; import java.util.Arrays; +import net.sf.briar.api.serial.Writer; + /** * Type-safe wrapper for a byte array that uniquely identifies a group to which * users may subscribe. @@ -12,6 +15,11 @@ public class GroupId extends UniqueId { super(id); } + public void writeTo(Writer w) throws IOException { + w.writeUserDefinedTag(Tags.GROUP_ID); + w.writeRaw(id); + } + @Override public boolean equals(Object o) { if(o instanceof GroupId) diff --git a/api/net/sf/briar/api/protocol/MessageId.java b/api/net/sf/briar/api/protocol/MessageId.java index 64e0fd0369..41cfecc3db 100644 --- a/api/net/sf/briar/api/protocol/MessageId.java +++ b/api/net/sf/briar/api/protocol/MessageId.java @@ -1,7 +1,10 @@ package net.sf.briar.api.protocol; +import java.io.IOException; import java.util.Arrays; +import net.sf.briar.api.serial.Writer; + /** Type-safe wrapper for a byte array that uniquely identifies a message. */ public class MessageId extends UniqueId { @@ -15,6 +18,11 @@ public class MessageId extends UniqueId { super(id); } + public void writeTo(Writer w) throws IOException { + w.writeUserDefinedTag(Tags.MESSAGE_ID); + w.writeRaw(id); + } + @Override public boolean equals(Object o) { if(o instanceof MessageId) diff --git a/api/net/sf/briar/api/protocol/Tags.java b/api/net/sf/briar/api/protocol/Tags.java new file mode 100644 index 0000000000..f2767b1ac9 --- /dev/null +++ b/api/net/sf/briar/api/protocol/Tags.java @@ -0,0 +1,16 @@ +package net.sf.briar.api.protocol; + +public interface Tags { + + static final int HEADER = 0; + static final int BATCH_ID = 1; + static final int GROUP_ID = 2; + static final int TIMESTAMP = 3; + static final int SIGNATURE = 4; + static final int BATCH = 5; + static final int MESSAGE = 6; + static final int MESSAGE_ID = 7; + static final int AUTHOR = 8; + static final int MESSAGE_BODY = 9; + static final int AUTHOR_ID = 10; +} diff --git a/api/net/sf/briar/api/protocol/UniqueId.java b/api/net/sf/briar/api/protocol/UniqueId.java index 22f57dfe2b..170dc0c5a6 100644 --- a/api/net/sf/briar/api/protocol/UniqueId.java +++ b/api/net/sf/briar/api/protocol/UniqueId.java @@ -3,8 +3,9 @@ package net.sf.briar.api.protocol; import java.util.Arrays; import net.sf.briar.api.serial.Raw; +import net.sf.briar.api.serial.Writable; -public abstract class UniqueId implements Raw { +public abstract class UniqueId implements Raw, Writable { public static final int LENGTH = 32; diff --git a/api/net/sf/briar/api/serial/Reader.java b/api/net/sf/briar/api/serial/Reader.java index bcac81bde5..5e06136cf3 100644 --- a/api/net/sf/briar/api/serial/Reader.java +++ b/api/net/sf/briar/api/serial/Reader.java @@ -59,4 +59,5 @@ public interface Reader { boolean hasUserDefinedTag() throws IOException; int readUserDefinedTag() throws IOException; + void readUserDefinedTag(int i) throws IOException; } diff --git a/api/net/sf/briar/api/serial/Tag.java b/api/net/sf/briar/api/serial/Tag.java index 09528efaf0..e924d6a506 100644 --- a/api/net/sf/briar/api/serial/Tag.java +++ b/api/net/sf/briar/api/serial/Tag.java @@ -2,30 +2,30 @@ package net.sf.briar.api.serial; public interface Tag { - public static final byte FALSE = -1; // 1111 1111 - public static final byte TRUE = -2; // 1111 1110 - public static final byte INT8 = -3; // 1111 1101 - public static final byte INT16 = -4; // 1111 1100 - public static final byte INT32 = -5; // 1111 1011 - public static final byte INT64 = -6; // 1111 1010 - public static final byte FLOAT32 = -7; // 1111 1001 - public static final byte FLOAT64 = -8; // 1111 1000 - public static final byte STRING = -9; // 1111 0111 - public static final byte RAW = -10; // 1111 0110 - public static final byte LIST = -11; // 1111 0101 - public static final byte MAP = -12; // 1111 0100 - public static final byte LIST_START = -13; // 1111 0011 - public static final byte MAP_START = -14; // 1111 0010 - public static final byte END = -15; // 1111 0001 - public static final byte NULL = -16; // 1111 0000 + static final byte FALSE = -1; // 1111 1111 + static final byte TRUE = -2; // 1111 1110 + static final byte INT8 = -3; // 1111 1101 + static final byte INT16 = -4; // 1111 1100 + static final byte INT32 = -5; // 1111 1011 + static final byte INT64 = -6; // 1111 1010 + static final byte FLOAT32 = -7; // 1111 1001 + static final byte FLOAT64 = -8; // 1111 1000 + static final byte STRING = -9; // 1111 0111 + static final byte RAW = -10; // 1111 0110 + static final byte LIST = -11; // 1111 0101 + static final byte MAP = -12; // 1111 0100 + static final byte LIST_START = -13; // 1111 0011 + static final byte MAP_START = -14; // 1111 0010 + static final byte END = -15; // 1111 0001 + static final byte NULL = -16; // 1111 0000 + static final byte USER = -17; // 1110 1111 - public static final byte USER = -32; // 1110 0000 + static final int SHORT_MASK = 0xF0; // Match first four bits + static final int SHORT_STRING = 0x80; // 1000 xxxx + static final int SHORT_RAW = 0x90; // 1001 xxxx + static final int SHORT_LIST = 0xA0; // 1010 xxxx + static final int SHORT_MAP = 0xB0; // 1011 xxxx - public static final int SHORT_MASK = 0xF0; // Match first four bits - public static final int SHORT_STRING = 0x80; // 1000 xxxx - public static final int SHORT_RAW = 0x90; // 1001 xxxx - public static final int SHORT_LIST = 0xA0; // 1010 xxxx - public static final int SHORT_MAP = 0xB0; // 1011 xxxx - public static final int SHORT_USER_MASK = 0xE0; // Match first three bits - public static final int SHORT_USER = 0xC0; // 110x xxxx + static final int SHORT_USER_MASK = 0xE0; // Match first three bits + static final int SHORT_USER = 0xC0; // 110x xxxx } diff --git a/api/net/sf/briar/api/serial/Writable.java b/api/net/sf/briar/api/serial/Writable.java new file mode 100644 index 0000000000..7e75aa5435 --- /dev/null +++ b/api/net/sf/briar/api/serial/Writable.java @@ -0,0 +1,8 @@ +package net.sf.briar.api.serial; + +import java.io.IOException; + +public interface Writable { + + void writeTo(Writer w) throws IOException; +} diff --git a/components/net/sf/briar/protocol/BundleReaderImpl.java b/components/net/sf/briar/protocol/BundleReaderImpl.java index 006886728d..219d131161 100644 --- a/components/net/sf/briar/protocol/BundleReaderImpl.java +++ b/components/net/sf/briar/protocol/BundleReaderImpl.java @@ -20,8 +20,10 @@ import net.sf.briar.api.protocol.Header; import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.MessageParser; import net.sf.briar.api.protocol.UniqueId; +import net.sf.briar.api.protocol.Tags; import net.sf.briar.api.serial.FormatException; import net.sf.briar.api.serial.Raw; +import net.sf.briar.api.serial.RawByteArray; import net.sf.briar.api.serial.Reader; class BundleReaderImpl implements BundleReader { @@ -59,23 +61,36 @@ class BundleReaderImpl implements BundleReader { // Read the signed data reader.addConsumer(counting); reader.addConsumer(signing); + reader.readUserDefinedTag(Tags.HEADER); + // Acks Set<BatchId> acks = new HashSet<BatchId>(); - for(Raw raw : reader.readList(Raw.class)) { - byte[] b = raw.getBytes(); + reader.readListStart(); + while(!reader.hasListEnd()) { + reader.readUserDefinedTag(Tags.BATCH_ID); + byte[] b = reader.readRaw(); if(b.length != UniqueId.LENGTH) throw new FormatException(); acks.add(new BatchId(b)); } + reader.readListEnd(); + // Subs Set<GroupId> subs = new HashSet<GroupId>(); - for(Raw raw : reader.readList(Raw.class)) { - byte[] b = raw.getBytes(); + reader.readListStart(); + while(!reader.hasListEnd()) { + reader.readUserDefinedTag(Tags.GROUP_ID); + byte[] b = reader.readRaw(); if(b.length != UniqueId.LENGTH) throw new FormatException(); subs.add(new GroupId(b)); } + reader.readListEnd(); + // Transports Map<String, String> transports = reader.readMap(String.class, String.class); + // Timestamp + reader.readUserDefinedTag(Tags.TIMESTAMP); long timestamp = reader.readInt64(); reader.removeConsumer(signing); // Read and verify the signature + reader.readUserDefinedTag(Tags.SIGNATURE); byte[] sig = reader.readRaw(); reader.removeConsumer(counting); if(!signature.verify(sig)) throw new SignatureException(); @@ -106,9 +121,17 @@ class BundleReaderImpl implements BundleReader { reader.addConsumer(counting); reader.addConsumer(digesting); reader.addConsumer(signing); - List<Raw> rawMessages = reader.readList(Raw.class); + reader.readUserDefinedTag(Tags.BATCH); + List<Raw> rawMessages = new ArrayList<Raw>(); + reader.readListStart(); + while(!reader.hasListEnd()) { + reader.readUserDefinedTag(Tags.MESSAGE); + rawMessages.add(new RawByteArray(reader.readRaw())); + } + reader.readListEnd(); reader.removeConsumer(signing); // Read and verify the signature + reader.readUserDefinedTag(Tags.SIGNATURE); byte[] sig = reader.readRaw(); reader.removeConsumer(digesting); reader.removeConsumer(counting); diff --git a/components/net/sf/briar/protocol/BundleWriterImpl.java b/components/net/sf/briar/protocol/BundleWriterImpl.java index cef906ab76..6454192636 100644 --- a/components/net/sf/briar/protocol/BundleWriterImpl.java +++ b/components/net/sf/briar/protocol/BundleWriterImpl.java @@ -11,6 +11,7 @@ import java.util.Map; import net.sf.briar.api.protocol.BatchId; import net.sf.briar.api.protocol.BundleWriter; import net.sf.briar.api.protocol.GroupId; +import net.sf.briar.api.protocol.Tags; import net.sf.briar.api.serial.Raw; import net.sf.briar.api.serial.Writer; import net.sf.briar.api.serial.WriterFactory; @@ -20,7 +21,7 @@ class BundleWriterImpl implements BundleWriter { private static enum State { START, FIRST_BATCH, MORE_BATCHES, END }; private final SigningDigestingOutputStream out; - private final Writer w; + private final Writer writer; private final PrivateKey privateKey; private final Signature signature; private final MessageDigest messageDigest; @@ -32,7 +33,7 @@ class BundleWriterImpl implements BundleWriter { MessageDigest messageDigest, long capacity) { this.out = new SigningDigestingOutputStream(out, signature, messageDigest); - w = writerFactory.createWriter(this.out); + writer = writerFactory.createWriter(this.out); this.privateKey = privateKey; this.signature = signature; this.messageDigest = messageDigest; @@ -40,7 +41,7 @@ class BundleWriterImpl implements BundleWriter { } public long getRemainingCapacity() { - return capacity - w.getBytesWritten(); + return capacity - writer.getBytesWritten(); } public void addHeader(Iterable<BatchId> acks, Iterable<GroupId> subs, @@ -51,18 +52,21 @@ class BundleWriterImpl implements BundleWriter { signature.initSign(privateKey); // Write the data to be signed out.setSigning(true); - w.writeListStart(); - for(BatchId ack : acks) w.writeRaw(ack); - w.writeListEnd(); - w.writeListStart(); - for(GroupId sub : subs) w.writeRaw(sub); - w.writeListEnd(); - w.writeMap(transports); - w.writeInt64(System.currentTimeMillis()); + writer.writeUserDefinedTag(Tags.HEADER); + writer.writeListStart(); + for(BatchId ack : acks) ack.writeTo(writer); + writer.writeListEnd(); + writer.writeListStart(); + for(GroupId sub : subs) sub.writeTo(writer); + writer.writeListEnd(); + writer.writeMap(transports); + writer.writeUserDefinedTag(Tags.TIMESTAMP); + writer.writeInt64(System.currentTimeMillis()); out.setSigning(false); // Create and write the signature byte[] sig = signature.sign(); - w.writeRaw(sig); + writer.writeUserDefinedTag(Tags.SIGNATURE); + writer.writeRaw(sig); // Expect a (possibly empty) list of batches state = State.FIRST_BATCH; } @@ -70,7 +74,7 @@ class BundleWriterImpl implements BundleWriter { public BatchId addBatch(Iterable<Raw> messages) throws IOException, GeneralSecurityException { if(state == State.FIRST_BATCH) { - w.writeListStart(); + writer.writeListStart(); state = State.MORE_BATCHES; } if(state != State.MORE_BATCHES) throw new IllegalStateException(); @@ -80,13 +84,18 @@ class BundleWriterImpl implements BundleWriter { // Write the data to be signed out.setDigesting(true); out.setSigning(true); - w.writeListStart(); - for(Raw message : messages) w.writeRaw(message); - w.writeListEnd(); + writer.writeUserDefinedTag(Tags.BATCH); + writer.writeListStart(); + for(Raw message : messages) { + writer.writeUserDefinedTag(Tags.MESSAGE); + writer.writeRaw(message); + } + writer.writeListEnd(); out.setSigning(false); // Create and write the signature byte[] sig = signature.sign(); - w.writeRaw(sig); + writer.writeUserDefinedTag(Tags.SIGNATURE); + writer.writeRaw(sig); out.setDigesting(false); // Calculate and return the ID return new BatchId(messageDigest.digest()); @@ -94,12 +103,12 @@ class BundleWriterImpl implements BundleWriter { public void finish() throws IOException { if(state == State.FIRST_BATCH) { - w.writeListStart(); + writer.writeListStart(); state = State.MORE_BATCHES; } if(state != State.MORE_BATCHES) throw new IllegalStateException(); - w.writeListEnd(); - w.close(); + writer.writeListEnd(); + writer.close(); state = State.END; } } diff --git a/components/net/sf/briar/serial/ReaderImpl.java b/components/net/sf/briar/serial/ReaderImpl.java index 89ca72441d..a04112e1e3 100644 --- a/components/net/sf/briar/serial/ReaderImpl.java +++ b/components/net/sf/briar/serial/ReaderImpl.java @@ -478,4 +478,8 @@ class ReaderImpl implements Reader { return tag; } } + + public void readUserDefinedTag(int i) throws IOException { + if(readUserDefinedTag() != i) throw new FormatException(); + } } diff --git a/test/net/sf/briar/serial/ReaderImplTest.java b/test/net/sf/briar/serial/ReaderImplTest.java index 0636a85b28..9a1281b800 100644 --- a/test/net/sf/briar/serial/ReaderImplTest.java +++ b/test/net/sf/briar/serial/ReaderImplTest.java @@ -318,7 +318,7 @@ public class ReaderImplTest extends TestCase { @Test public void testReadUserDefinedTag() throws IOException { - setContents("C0" + "DF" + "E0" + "20" + "E0" + "FB7FFFFFFF"); + setContents("C0" + "DF" + "EF" + "20" + "EF" + "FB7FFFFFFF"); assertEquals(0, r.readUserDefinedTag()); assertEquals(31, r.readUserDefinedTag()); assertEquals(32, r.readUserDefinedTag()); diff --git a/test/net/sf/briar/serial/WriterImplTest.java b/test/net/sf/briar/serial/WriterImplTest.java index a6f364d07a..c45983d123 100644 --- a/test/net/sf/briar/serial/WriterImplTest.java +++ b/test/net/sf/briar/serial/WriterImplTest.java @@ -297,7 +297,7 @@ public class WriterImplTest extends TestCase { w.writeUserDefinedTag(32); w.writeUserDefinedTag(Integer.MAX_VALUE); // USER tag, 32 as uint7, USER tag, 2147483647 as int32 - checkContents("E0" + "20" + "E0" + "FB7FFFFFFF"); + checkContents("EF" + "20" + "EF" + "FB7FFFFFFF"); } private void checkContents(String hex) throws IOException { -- GitLab