briar-commits Mailing List for Briar
Brought to you by:
akwizgran
You can subscribe to this list here.
2014 |
Jan
|
Feb
(28) |
Mar
(35) |
Apr
(37) |
May
(19) |
Jun
(10) |
Jul
(4) |
Aug
|
Sep
|
Oct
(9) |
Nov
(11) |
Dec
(9) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2015 |
Jan
(7) |
Feb
(1) |
Mar
(7) |
Apr
(10) |
May
(3) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: akwizgran <gi...@br...> - 2015-05-02 20:14:21
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="41c4c4d8" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/41c4c4d8086163dc729f3383d190fe0e2ac500d3">41c4c4d8</a> by akwizgran Renamed raw data type. - - - - - <a href="d519c543" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/d519c543a6abdcbaddaa920bcd1d71583d399121">d519c543</a> by akwizgran Represent booleans with a single byte. - - - - - Changes: ===================================== briar-api/src/org/briarproject/api/data/Reader.java ===================================== --- a/briar-api/src/org/briarproject/api/data/Reader.java +++ b/briar-api/src/org/briarproject/api/data/Reader.java @@ -30,9 +30,9 @@ public interface Reader { String readString(int maxLength) throws IOException; void skipString() throws IOException; - boolean hasBytes() throws IOException; - byte[] readBytes(int maxLength) throws IOException; - void skipBytes() throws IOException; + boolean hasRaw() throws IOException; + byte[] readRaw(int maxLength) throws IOException; + void skipRaw() throws IOException; boolean hasList() throws IOException; void readListStart() throws IOException; ===================================== briar-api/src/org/briarproject/api/data/Writer.java ===================================== --- a/briar-api/src/org/briarproject/api/data/Writer.java +++ b/briar-api/src/org/briarproject/api/data/Writer.java @@ -17,7 +17,7 @@ public interface Writer { void writeInteger(long l) throws IOException; void writeFloat(double d) throws IOException; void writeString(String s) throws IOException; - void writeBytes(byte[] b) throws IOException; + void writeRaw(byte[] b) throws IOException; void writeList(Collection<?> c) throws IOException; void writeListStart() throws IOException; ===================================== briar-core/src/org/briarproject/data/ReaderImpl.java ===================================== --- a/briar-core/src/org/briarproject/data/ReaderImpl.java +++ b/briar-core/src/org/briarproject/data/ReaderImpl.java @@ -1,6 +1,7 @@ package org.briarproject.data; import static org.briarproject.data.Types.END; +import static org.briarproject.data.Types.FALSE; import static org.briarproject.data.Types.FLOAT_64; import static org.briarproject.data.Types.INT_16; import static org.briarproject.data.Types.INT_32; @@ -15,6 +16,7 @@ import static org.briarproject.data.Types.RAW_8; import static org.briarproject.data.Types.STRING_16; import static org.briarproject.data.Types.STRING_32; import static org.briarproject.data.Types.STRING_8; +import static org.briarproject.data.Types.TRUE; import java.io.IOException; import java.io.InputStream; @@ -90,7 +92,7 @@ class ReaderImpl implements Reader { else if(hasInteger()) skipInteger(); else if(hasFloat()) skipFloat(); else if(hasString()) skipString(); - else if(hasBytes()) skipBytes(); + else if(hasRaw()) skipRaw(); else if(hasList()) skipList(); else if(hasMap()) skipMap(); else if(hasNull()) skipNull(); @@ -133,24 +135,18 @@ class ReaderImpl implements Reader { public boolean hasBoolean() throws IOException { if(!hasLookahead) readLookahead(); if(eof) return false; - return next == Types.BOOLEAN; + return next == FALSE || next == TRUE; } public boolean readBoolean() throws IOException { if(!hasBoolean()) throw new FormatException(); + boolean bool = next == TRUE; consumeLookahead(); - return readBoolean(true); - } - - private boolean readBoolean(boolean consume) throws IOException { - readIntoBuffer(1, consume); - if(buf[0] != 0 && buf[0] != 1) throw new FormatException(); - return buf[0] == 1; + return bool; } public void skipBoolean() throws IOException { if(!hasBoolean()) throw new FormatException(); - skip(1); hasLookahead = false; } @@ -262,16 +258,16 @@ class ReaderImpl implements Reader { hasLookahead = false; } - public boolean hasBytes() throws IOException { + public boolean hasRaw() throws IOException { if(!hasLookahead) readLookahead(); if(eof) return false; return next == RAW_8 || next == RAW_16 || next == RAW_32; } - public byte[] readBytes(int maxLength) throws IOException { - if(!hasBytes()) throw new FormatException(); + public byte[] readRaw(int maxLength) throws IOException { + if(!hasRaw()) throw new FormatException(); consumeLookahead(); - int length = readBytesLength(true); + int length = readRawLength(true); if(length < 0 || length > maxLength) throw new FormatException(); if(length == 0) return EMPTY_BUFFER; byte[] b = new byte[length]; @@ -279,16 +275,16 @@ class ReaderImpl implements Reader { return b; } - private int readBytesLength(boolean consume) throws IOException { + private int readRawLength(boolean consume) throws IOException { if(next == RAW_8) return readInt8(consume); if(next == RAW_16) return readInt16(consume); if(next == RAW_32) return readInt32(consume); throw new FormatException(); } - public void skipBytes() throws IOException { - if(!hasBytes()) throw new FormatException(); - int length = readBytesLength(false); + public void skipRaw() throws IOException { + if(!hasRaw()) throw new FormatException(); + int length = readRawLength(false); if(length < 0) throw new FormatException(); skip(length); hasLookahead = false; ===================================== briar-core/src/org/briarproject/data/Types.java ===================================== --- a/briar-core/src/org/briarproject/data/Types.java +++ b/briar-core/src/org/briarproject/data/Types.java @@ -3,7 +3,8 @@ package org.briarproject.data; interface Types { byte NULL = 0x00; - byte BOOLEAN = 0x11; + byte FALSE = 0x10; + byte TRUE = 0x11; byte INT_8 = 0x21; byte INT_16 = 0x22; byte INT_32 = 0x24; ===================================== briar-core/src/org/briarproject/data/WriterImpl.java ===================================== --- a/briar-core/src/org/briarproject/data/WriterImpl.java +++ b/briar-core/src/org/briarproject/data/WriterImpl.java @@ -1,7 +1,7 @@ package org.briarproject.data; -import static org.briarproject.data.Types.BOOLEAN; import static org.briarproject.data.Types.END; +import static org.briarproject.data.Types.FALSE; import static org.briarproject.data.Types.FLOAT_64; import static org.briarproject.data.Types.INT_16; import static org.briarproject.data.Types.INT_32; @@ -16,6 +16,7 @@ import static org.briarproject.data.Types.RAW_8; import static org.briarproject.data.Types.STRING_16; import static org.briarproject.data.Types.STRING_32; import static org.briarproject.data.Types.STRING_8; +import static org.briarproject.data.Types.TRUE; import java.io.IOException; import java.io.OutputStream; @@ -60,9 +61,8 @@ class WriterImpl implements Writer { } public void writeBoolean(boolean b) throws IOException { - write(BOOLEAN); - if(b) write((byte) 1); - else write((byte) 0); + if(b) write(TRUE); + else write(FALSE); } public void writeInteger(long i) throws IOException { @@ -124,7 +124,7 @@ class WriterImpl implements Writer { write(b); } - public void writeBytes(byte[] b) throws IOException { + public void writeRaw(byte[] b) throws IOException { if(b.length <= Byte.MAX_VALUE) { write(RAW_8); write((byte) b.length); @@ -139,9 +139,9 @@ class WriterImpl implements Writer { } public void writeList(Collection<?> c) throws IOException { - write(Types.LIST); + write(LIST); for(Object o : c) writeObject(o); - write(Types.END); + write(END); } private void writeObject(Object o) throws IOException { @@ -153,8 +153,8 @@ class WriterImpl implements Writer { else if(o instanceof Float) writeFloat((Float) o); else if(o instanceof Double) writeFloat((Double) o); else if(o instanceof String) writeString((String) o); - else if(o instanceof byte[]) writeBytes((byte[]) o); - else if(o instanceof Bytes) writeBytes(((Bytes) o).getBytes()); + else if(o instanceof byte[]) writeRaw((byte[]) o); + else if(o instanceof Bytes) writeRaw(((Bytes) o).getBytes()); else if(o instanceof List<?>) writeList((List<?>) o); else if(o instanceof Map<?, ?>) writeMap((Map<?, ?>) o); else if(o == null) writeNull(); ===================================== briar-core/src/org/briarproject/invitation/Connector.java ===================================== --- a/briar-core/src/org/briarproject/invitation/Connector.java +++ b/briar-core/src/org/briarproject/invitation/Connector.java @@ -124,14 +124,14 @@ abstract class Connector extends Thread { } protected void sendPublicKeyHash(Writer w) throws IOException { - w.writeBytes(messageDigest.digest(keyPair.getPublic().getEncoded())); + w.writeRaw(messageDigest.digest(keyPair.getPublic().getEncoded())); w.flush(); if(LOG.isLoggable(INFO)) LOG.info(pluginName + " sent hash"); } protected byte[] receivePublicKeyHash(Reader r) throws IOException { int hashLength = messageDigest.getDigestLength(); - byte[] b = r.readBytes(hashLength); + byte[] b = r.readRaw(hashLength); if(b.length < hashLength) throw new FormatException(); if(LOG.isLoggable(INFO)) LOG.info(pluginName + " received hash"); return b; @@ -139,14 +139,14 @@ abstract class Connector extends Thread { protected void sendPublicKey(Writer w) throws IOException { byte[] key = keyPair.getPublic().getEncoded(); - w.writeBytes(key); + w.writeRaw(key); w.flush(); if(LOG.isLoggable(INFO)) LOG.info(pluginName + " sent key"); } protected byte[] receivePublicKey(Reader r) throws GeneralSecurityException, IOException { - byte[] b = r.readBytes(MAX_PUBLIC_KEY_LENGTH); + byte[] b = r.readRaw(MAX_PUBLIC_KEY_LENGTH); keyParser.parsePublicKey(b); if(LOG.isLoggable(INFO)) LOG.info(pluginName + " received key"); return b; @@ -192,8 +192,8 @@ abstract class Connector extends Thread { byte[] sig = signature.sign(); // Write the name, public key and signature w.writeString(localAuthor.getName()); - w.writeBytes(localAuthor.getPublicKey()); - w.writeBytes(sig); + w.writeRaw(localAuthor.getPublicKey()); + w.writeRaw(sig); w.flush(); if(LOG.isLoggable(INFO)) LOG.info(pluginName + " sent pseudonym"); } @@ -202,8 +202,8 @@ abstract class Connector extends Thread { throws GeneralSecurityException, IOException { // Read the name, public key and signature String name = r.readString(MAX_AUTHOR_NAME_LENGTH); - byte[] publicKey = r.readBytes(MAX_PUBLIC_KEY_LENGTH); - byte[] sig = r.readBytes(MAX_SIGNATURE_LENGTH); + byte[] publicKey = r.readRaw(MAX_PUBLIC_KEY_LENGTH); + byte[] sig = r.readRaw(MAX_SIGNATURE_LENGTH); if(LOG.isLoggable(INFO)) LOG.info(pluginName + " received pseudonym"); // Verify the signature Signature signature = crypto.getSignature(); ===================================== briar-core/src/org/briarproject/messaging/AuthorFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/AuthorFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/AuthorFactoryImpl.java @@ -45,7 +45,7 @@ class AuthorFactoryImpl implements AuthorFactory { try { w.writeListStart(); w.writeString(name); - w.writeBytes(publicKey); + w.writeRaw(publicKey); w.writeListEnd(); } catch(IOException e) { // Shouldn't happen with ByteArrayOutputStream ===================================== briar-core/src/org/briarproject/messaging/AuthorReader.java ===================================== --- a/briar-core/src/org/briarproject/messaging/AuthorReader.java +++ b/briar-core/src/org/briarproject/messaging/AuthorReader.java @@ -29,7 +29,7 @@ class AuthorReader implements ObjectReader<Author> { r.readListStart(); String name = r.readString(MAX_AUTHOR_NAME_LENGTH); if(name.length() == 0) throw new FormatException(); - byte[] publicKey = r.readBytes(MAX_PUBLIC_KEY_LENGTH); + byte[] publicKey = r.readRaw(MAX_PUBLIC_KEY_LENGTH); r.readListEnd(); // Reset the reader r.removeConsumer(digesting); ===================================== briar-core/src/org/briarproject/messaging/GroupFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/GroupFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/GroupFactoryImpl.java @@ -38,7 +38,7 @@ class GroupFactoryImpl implements GroupFactory { try { w.writeListStart(); w.writeString(name); - w.writeBytes(salt); + w.writeRaw(salt); w.writeListEnd(); } catch(IOException e) { // Shouldn't happen with ByteArrayOutputStream ===================================== briar-core/src/org/briarproject/messaging/GroupReader.java ===================================== --- a/briar-core/src/org/briarproject/messaging/GroupReader.java +++ b/briar-core/src/org/briarproject/messaging/GroupReader.java @@ -28,7 +28,7 @@ class GroupReader implements ObjectReader<Group> { r.readListStart(); String name = r.readString(MAX_GROUP_NAME_LENGTH); if(name.length() == 0) throw new FormatException(); - byte[] salt = r.readBytes(GROUP_SALT_LENGTH); + byte[] salt = r.readRaw(GROUP_SALT_LENGTH); if(salt.length != GROUP_SALT_LENGTH) throw new FormatException(); r.readListEnd(); r.removeConsumer(digesting); ===================================== briar-core/src/org/briarproject/messaging/MessageFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/MessageFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/MessageFactoryImpl.java @@ -84,7 +84,7 @@ class MessageFactoryImpl implements MessageFactory { // Write the message w.writeListStart(); if(parent == null) w.writeNull(); - else w.writeBytes(parent.getBytes()); + else w.writeRaw(parent.getBytes()); writeGroup(w, group); if(author == null) w.writeNull(); else writeAuthor(w, author); @@ -92,8 +92,8 @@ class MessageFactoryImpl implements MessageFactory { w.writeInteger(timestamp); byte[] salt = new byte[MESSAGE_SALT_LENGTH]; random.nextBytes(salt); - w.writeBytes(salt); - w.writeBytes(body); + w.writeRaw(salt); + w.writeRaw(body); int bodyStart = (int) counting.getCount() - body.length; // Sign the message with the author's private key, if there is one if(privateKey == null) { @@ -103,7 +103,7 @@ class MessageFactoryImpl implements MessageFactory { byte[] sig = signature.sign(); if(sig.length > MAX_SIGNATURE_LENGTH) throw new IllegalArgumentException(); - w.writeBytes(sig); + w.writeRaw(sig); } w.writeListEnd(); // Hash the message, including the signature, to get the message ID @@ -116,14 +116,14 @@ class MessageFactoryImpl implements MessageFactory { private void writeGroup(Writer w, Group g) throws IOException { w.writeListStart(); w.writeString(g.getName()); - w.writeBytes(g.getSalt()); + w.writeRaw(g.getSalt()); w.writeListEnd(); } private void writeAuthor(Writer w, Author a) throws IOException { w.writeListStart(); w.writeString(a.getName()); - w.writeBytes(a.getPublicKey()); + w.writeRaw(a.getPublicKey()); w.writeListEnd(); } } ===================================== briar-core/src/org/briarproject/messaging/MessageReader.java ===================================== --- a/briar-core/src/org/briarproject/messaging/MessageReader.java +++ b/briar-core/src/org/briarproject/messaging/MessageReader.java @@ -40,7 +40,7 @@ class MessageReader implements ObjectReader<UnverifiedMessage> { if(r.hasNull()) { r.readNull(); } else { - byte[] b = r.readBytes(UniqueId.LENGTH); + byte[] b = r.readRaw(UniqueId.LENGTH); if(b.length < UniqueId.LENGTH) throw new FormatException(); parent = new MessageId(b); } @@ -56,10 +56,10 @@ class MessageReader implements ObjectReader<UnverifiedMessage> { long timestamp = r.readInteger(); if(timestamp < 0) throw new FormatException(); // Read the salt - byte[] salt = r.readBytes(MESSAGE_SALT_LENGTH); + byte[] salt = r.readRaw(MESSAGE_SALT_LENGTH); if(salt.length < MESSAGE_SALT_LENGTH) throw new FormatException(); // Read the message body - byte[] body = r.readBytes(MAX_BODY_LENGTH); + byte[] body = r.readRaw(MAX_BODY_LENGTH); // Record the offset of the body within the message int bodyStart = (int) counting.getCount() - body.length; // Record the length of the data covered by the author's signature @@ -67,7 +67,7 @@ class MessageReader implements ObjectReader<UnverifiedMessage> { // Read the author's signature, if there is one byte[] signature = null; if(author == null) r.readNull(); - else signature = r.readBytes(MAX_SIGNATURE_LENGTH); + else signature = r.readRaw(MAX_SIGNATURE_LENGTH); // Read the end of the message r.readListEnd(); // Reset the reader ===================================== briar-core/src/org/briarproject/messaging/PacketReaderImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/PacketReaderImpl.java +++ b/briar-core/src/org/briarproject/messaging/PacketReaderImpl.java @@ -122,7 +122,7 @@ class PacketReaderImpl implements PacketReader { List<MessageId> acked = new ArrayList<MessageId>(); r.readListStart(); while(!r.hasListEnd()) { - byte[] b = r.readBytes(UniqueId.LENGTH); + byte[] b = r.readRaw(UniqueId.LENGTH); if(b.length != UniqueId.LENGTH) throw new FormatException(); acked.add(new MessageId(b)); @@ -168,7 +168,7 @@ class PacketReaderImpl implements PacketReader { List<MessageId> offered = new ArrayList<MessageId>(); r.readListStart(); while(!r.hasListEnd()) { - byte[] b = r.readBytes(UniqueId.LENGTH); + byte[] b = r.readRaw(UniqueId.LENGTH); if(b.length != UniqueId.LENGTH) throw new FormatException(); offered.add(new MessageId(b)); @@ -198,7 +198,7 @@ class PacketReaderImpl implements PacketReader { r.readListStart(); List<MessageId> requested = new ArrayList<MessageId>(); while(!r.hasListEnd()) { - byte[] b = r.readBytes(UniqueId.LENGTH); + byte[] b = r.readRaw(UniqueId.LENGTH); if(b.length != UniqueId.LENGTH) throw new FormatException(); requested.add(new MessageId(b)); ===================================== briar-core/src/org/briarproject/messaging/PacketWriterImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/PacketWriterImpl.java +++ b/briar-core/src/org/briarproject/messaging/PacketWriterImpl.java @@ -85,7 +85,7 @@ class PacketWriterImpl implements PacketWriter { Writer w = writerFactory.createWriter(payload); w.writeListStart(); w.writeListStart(); - for(MessageId m : a.getMessageIds()) w.writeBytes(m.getBytes()); + for(MessageId m : a.getMessageIds()) w.writeRaw(m.getBytes()); w.writeListEnd(); w.writeListEnd(); writePacket(ACK); @@ -103,7 +103,7 @@ class PacketWriterImpl implements PacketWriter { Writer w = writerFactory.createWriter(payload); w.writeListStart(); w.writeListStart(); - for(MessageId m : o.getMessageIds()) w.writeBytes(m.getBytes()); + for(MessageId m : o.getMessageIds()) w.writeRaw(m.getBytes()); w.writeListEnd(); w.writeListEnd(); writePacket(OFFER); @@ -114,7 +114,7 @@ class PacketWriterImpl implements PacketWriter { Writer w = writerFactory.createWriter(payload); w.writeListStart(); w.writeListStart(); - for(MessageId m : r.getMessageIds()) w.writeBytes(m.getBytes()); + for(MessageId m : r.getMessageIds()) w.writeRaw(m.getBytes()); w.writeListEnd(); w.writeListEnd(); writePacket(REQUEST); @@ -157,7 +157,7 @@ class PacketWriterImpl implements PacketWriter { for(Group g : u.getGroups()) { w.writeListStart(); w.writeString(g.getName()); - w.writeBytes(g.getSalt()); + w.writeRaw(g.getSalt()); w.writeListEnd(); } w.writeListEnd(); ===================================== briar-tests/src/org/briarproject/data/ReaderImplTest.java ===================================== --- a/briar-tests/src/org/briarproject/data/ReaderImplTest.java +++ b/briar-tests/src/org/briarproject/data/ReaderImplTest.java @@ -37,7 +37,7 @@ public class ReaderImplTest extends BriarTestCase { @Test public void testReadBoolean() throws Exception { - setContents("11" + "00" + "11" + "01"); + setContents("10" + "11"); assertFalse(r.readBoolean()); assertTrue(r.readBoolean()); assertTrue(r.eof()); @@ -45,7 +45,7 @@ public class ReaderImplTest extends BriarTestCase { @Test public void testSkipBoolean() throws Exception { - setContents("11" + "00" + "11" + "01"); + setContents("10" + "11"); r.skipBoolean(); r.skipBoolean(); assertTrue(r.eof()); @@ -330,138 +330,138 @@ public class ReaderImplTest extends BriarTestCase { } @Test - public void testReadBytes8() throws Exception { + public void testReadRaw8() throws Exception { byte[] longest = new byte[Byte.MAX_VALUE]; String longHex = StringUtils.toHexString(longest); // {1, 2, 3}, {}, and 127 zero bytes setContents("51" + "03" + "010203" + "51" + "00" + "51" + "7F" + longHex); - assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes(Integer.MAX_VALUE)); - assertArrayEquals(new byte[0], r.readBytes(Integer.MAX_VALUE)); - assertArrayEquals(longest, r.readBytes(Integer.MAX_VALUE)); + assertArrayEquals(new byte[] {1, 2, 3}, r.readRaw(Integer.MAX_VALUE)); + assertArrayEquals(new byte[0], r.readRaw(Integer.MAX_VALUE)); + assertArrayEquals(longest, r.readRaw(Integer.MAX_VALUE)); assertTrue(r.eof()); } @Test - public void testReadBytes8ChecksMaxLength() throws Exception { + public void testReadRaw8ChecksMaxLength() throws Exception { // {1, 2, 3} twice setContents("51" + "03" + "010203" + "51" + "03" + "010203"); - assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes(3)); - assertTrue(r.hasBytes()); + assertArrayEquals(new byte[] {1, 2, 3}, r.readRaw(3)); + assertTrue(r.hasRaw()); try { - r.readBytes(2); + r.readRaw(2); fail(); } catch(FormatException expected) {} } @Test - public void testSkipBytes8() throws Exception { + public void testSkipRaw8() throws Exception { byte[] longest = new byte[Byte.MAX_VALUE]; String longHex = StringUtils.toHexString(longest); // {1, 2, 3}, {}, and 127 zero bytes setContents("51" + "03" + "010203" + "51" + "00" + "51" + "7F" + longHex); - r.skipBytes(); - r.skipBytes(); - r.skipBytes(); + r.skipRaw(); + r.skipRaw(); + r.skipRaw(); assertTrue(r.eof()); } @Test - public void testReadBytes16() throws Exception { + public void testReadRaw16() throws Exception { byte[] shortest = new byte[Byte.MAX_VALUE + 1]; String shortHex = StringUtils.toHexString(shortest); byte[] longest = new byte[Short.MAX_VALUE]; String longHex = StringUtils.toHexString(longest); // 128 zero bytes and 2^15 - 1 zero bytes setContents("52" + "0080" + shortHex + "52" + "7FFF" + longHex); - assertArrayEquals(shortest, r.readBytes(Integer.MAX_VALUE)); - assertArrayEquals(longest, r.readBytes(Integer.MAX_VALUE)); + assertArrayEquals(shortest, r.readRaw(Integer.MAX_VALUE)); + assertArrayEquals(longest, r.readRaw(Integer.MAX_VALUE)); assertTrue(r.eof()); } @Test - public void testReadBytes16ChecksMaxLength() throws Exception { + public void testReadRaw16ChecksMaxLength() throws Exception { byte[] shortest = new byte[Byte.MAX_VALUE + 1]; String shortHex = StringUtils.toHexString(shortest); // 128 zero bytes, twice setContents("52" + "0080" + shortHex + "52" + "0080" + shortHex); - assertArrayEquals(shortest, r.readBytes(Byte.MAX_VALUE + 1)); - assertTrue(r.hasBytes()); + assertArrayEquals(shortest, r.readRaw(Byte.MAX_VALUE + 1)); + assertTrue(r.hasRaw()); try { - r.readBytes(Byte.MAX_VALUE); + r.readRaw(Byte.MAX_VALUE); fail(); } catch(FormatException expected) {} } @Test - public void testSkipBytes16() throws Exception { + public void testSkipRaw16() throws Exception { byte[] shortest = new byte[Byte.MAX_VALUE + 1]; String shortHex = StringUtils.toHexString(shortest); byte[] longest = new byte[Short.MAX_VALUE]; String longHex = StringUtils.toHexString(longest); // 128 zero bytes and 2^15 - 1 zero bytes setContents("52" + "0080" + shortHex + "52" + "7FFF" + longHex); - r.skipBytes(); - r.skipBytes(); + r.skipRaw(); + r.skipRaw(); assertTrue(r.eof()); } @Test - public void testReadBytes32() throws Exception { + public void testReadRaw32() throws Exception { byte[] shortest = new byte[Short.MAX_VALUE + 1]; String shortHex = StringUtils.toHexString(shortest); // 2^15 zero bytes setContents("54" + "00008000" + shortHex); - assertArrayEquals(shortest, r.readBytes(Integer.MAX_VALUE)); + assertArrayEquals(shortest, r.readRaw(Integer.MAX_VALUE)); assertTrue(r.eof()); } @Test - public void testReadBytes32ChecksMaxLength() throws Exception { + public void testReadRaw32ChecksMaxLength() throws Exception { byte[] shortest = new byte[Short.MAX_VALUE + 1]; String shortHex = StringUtils.toHexString(shortest); // 2^15 zero bytes, twice setContents("54" + "00008000" + shortHex + "54" + "00008000" + shortHex); - assertArrayEquals(shortest, r.readBytes(Short.MAX_VALUE + 1)); - assertTrue(r.hasBytes()); + assertArrayEquals(shortest, r.readRaw(Short.MAX_VALUE + 1)); + assertTrue(r.hasRaw()); try { - r.readBytes(Short.MAX_VALUE); + r.readRaw(Short.MAX_VALUE); fail(); } catch(FormatException expected) {} } @Test - public void testSkipBytes32() throws Exception { + public void testSkipRaw32() throws Exception { byte[] shortest = new byte[Short.MAX_VALUE + 1]; String shortHex = StringUtils.toHexString(shortest); // 2^15 zero bytes, twice setContents("54" + "00008000" + shortHex + "54" + "00008000" + shortHex); - r.skipBytes(); - r.skipBytes(); + r.skipRaw(); + r.skipRaw(); assertTrue(r.eof()); } @Test - public void testBytesMustHaveMinimalLength() throws Exception { + public void testRawMustHaveMinimalLength() throws Exception { // RAW_16 could be encoded as RAW_8 byte[] longest8 = new byte[Byte.MAX_VALUE]; String long8Hex = StringUtils.toHexString(longest8); setContents("51" + "7F" + long8Hex + "52" + "007F" + long8Hex); - assertArrayEquals(longest8, r.readBytes(Integer.MAX_VALUE)); + assertArrayEquals(longest8, r.readRaw(Integer.MAX_VALUE)); try { - r.readBytes(Integer.MAX_VALUE); + r.readRaw(Integer.MAX_VALUE); fail(); } catch(FormatException expected) {} // RAW_32 could be encoded as RAW_16 byte[] longest16 = new byte[Short.MAX_VALUE]; String long16Hex = StringUtils.toHexString(longest16); setContents("52" + "7FFF" + long16Hex + "54" + "00007FFF" + long16Hex); - assertArrayEquals(longest16, r.readBytes(Integer.MAX_VALUE)); + assertArrayEquals(longest16, r.readRaw(Integer.MAX_VALUE)); try { - r.readBytes(Integer.MAX_VALUE); + r.readRaw(Integer.MAX_VALUE); fail(); } catch(FormatException expected) {} } ===================================== briar-tests/src/org/briarproject/data/WriterImplTest.java ===================================== --- a/briar-tests/src/org/briarproject/data/WriterImplTest.java +++ b/briar-tests/src/org/briarproject/data/WriterImplTest.java @@ -36,8 +36,8 @@ public class WriterImplTest extends BriarTestCase { public void testWriteBoolean() throws IOException { w.writeBoolean(true); w.writeBoolean(false); - // BOOLEAN tag, 1, BOOLEAN tag, 0 - checkContents("11" + "01" + "11" + "00"); + // TRUE tag, FALSE tag + checkContents("11" + "10"); } @Test @@ -116,8 +116,8 @@ public class WriterImplTest extends BriarTestCase { public void testWriteBytes8() throws IOException { byte[] longest = new byte[Byte.MAX_VALUE]; String longHex = StringUtils.toHexString(longest); - w.writeBytes(new byte[] {1, 2, 3}); - w.writeBytes(longest); + w.writeRaw(new byte[] {1, 2, 3}); + w.writeRaw(longest); // RAW_8 tag, length 3, bytes, RAW_8 tag, length 127, bytes checkContents("51" + "03" + "010203" + "51" + "7F" + longHex); } @@ -128,8 +128,8 @@ public class WriterImplTest extends BriarTestCase { String shortHex = StringUtils.toHexString(shortest); byte[] longest = new byte[Short.MAX_VALUE]; String longHex = StringUtils.toHexString(longest); - w.writeBytes(shortest); - w.writeBytes(longest); + w.writeRaw(shortest); + w.writeRaw(longest); // RAW_16 tag, length 128, bytes, RAW_16 tag, length 2^15 - 1, bytes checkContents("52" + "0080" + shortHex + "52" + "7FFF" + longHex); } @@ -138,7 +138,7 @@ public class WriterImplTest extends BriarTestCase { public void testWriteBytes32() throws IOException { byte[] shortest = new byte[Short.MAX_VALUE + 1]; String shortHex = StringUtils.toHexString(shortest); - w.writeBytes(shortest); + w.writeRaw(shortest); // RAW_32 tag, length 2^15, bytes checkContents("54" + "00008000" + shortHex); } ===================================== briar-tests/src/org/briarproject/messaging/PacketReaderImplTest.java ===================================== --- a/briar-tests/src/org/briarproject/messaging/PacketReaderImplTest.java +++ b/briar-tests/src/org/briarproject/messaging/PacketReaderImplTest.java @@ -144,9 +144,9 @@ public class PacketReaderImplTest extends BriarTestCase { w.writeListStart(); while(out.size() + UNIQUE_ID_LENGTH + LIST_END_LENGTH * 2 < HEADER_LENGTH + MAX_PAYLOAD_LENGTH) { - w.writeBytes(TestUtils.getRandomId()); + w.writeRaw(TestUtils.getRandomId()); } - if(tooBig) w.writeBytes(TestUtils.getRandomId()); + if(tooBig) w.writeRaw(TestUtils.getRandomId()); w.writeListEnd(); w.writeListEnd(); assertEquals(tooBig, out.size() > HEADER_LENGTH + MAX_PAYLOAD_LENGTH); @@ -178,9 +178,9 @@ public class PacketReaderImplTest extends BriarTestCase { w.writeListStart(); while(out.size() + UNIQUE_ID_LENGTH + LIST_END_LENGTH * 2 < HEADER_LENGTH + MAX_PAYLOAD_LENGTH) { - w.writeBytes(TestUtils.getRandomId()); + w.writeRaw(TestUtils.getRandomId()); } - if(tooBig) w.writeBytes(TestUtils.getRandomId()); + if(tooBig) w.writeRaw(TestUtils.getRandomId()); w.writeListEnd(); w.writeListEnd(); assertEquals(tooBig, out.size() > HEADER_LENGTH + MAX_PAYLOAD_LENGTH); @@ -212,9 +212,9 @@ public class PacketReaderImplTest extends BriarTestCase { w.writeListStart(); while(out.size() + UNIQUE_ID_LENGTH + LIST_END_LENGTH * 2 < HEADER_LENGTH + MAX_PAYLOAD_LENGTH) { - w.writeBytes(TestUtils.getRandomId()); + w.writeRaw(TestUtils.getRandomId()); } - if(tooBig) w.writeBytes(TestUtils.getRandomId()); + if(tooBig) w.writeRaw(TestUtils.getRandomId()); w.writeListEnd(); w.writeListEnd(); assertEquals(tooBig, out.size() > HEADER_LENGTH + MAX_PAYLOAD_LENGTH); |
From: akwizgran <gi...@br...> - 2015-05-02 19:41:36
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="416719e3" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/416719e3d9fcc450fc7356c90d810b4eb33c2a35">416719e3</a> by akwizgran Removed silly SerialComponent interface. - - - - - <a href="b8e37a54" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/b8e37a5421dfb165b268f682d7b63a38672a67ee">b8e37a54</a> by akwizgran Renamed serial component to data, moved consumers to briar-core. - - - - - Changes: ===================================== briar-api/src/org/briarproject/api/data/Consumer.java ===================================== --- /dev/null +++ b/briar-api/src/org/briarproject/api/data/Consumer.java @@ -0,0 +1,10 @@ +package org.briarproject.api.data; + +import java.io.IOException; + +public interface Consumer { + + void write(byte b) throws IOException; + + void write(byte[] b, int off, int len) throws IOException; +} ===================================== briar-api/src/org/briarproject/api/data/DataConstants.java ===================================== --- /dev/null +++ b/briar-api/src/org/briarproject/api/data/DataConstants.java @@ -0,0 +1,12 @@ +package org.briarproject.api.data; + +import org.briarproject.api.UniqueId; + +public interface DataConstants { + + int LIST_START_LENGTH = 1; + + int LIST_END_LENGTH = 1; + + int UNIQUE_ID_LENGTH = 2 + UniqueId.LENGTH; +} ===================================== briar-api/src/org/briarproject/api/data/ObjectReader.java ===================================== --- /dev/null +++ b/briar-api/src/org/briarproject/api/data/ObjectReader.java @@ -0,0 +1,8 @@ +package org.briarproject.api.data; + +import java.io.IOException; + +public interface ObjectReader<T> { + + T readObject(Reader r) throws IOException; +} ===================================== briar-api/src/org/briarproject/api/data/Reader.java ===================================== --- /dev/null +++ b/briar-api/src/org/briarproject/api/data/Reader.java @@ -0,0 +1,48 @@ +package org.briarproject.api.data; + +import java.io.IOException; + +public interface Reader { + + boolean eof() throws IOException; + void close() throws IOException; + + void addConsumer(Consumer c); + void removeConsumer(Consumer c); + + boolean hasNull() throws IOException; + void readNull() throws IOException; + void skipNull() throws IOException; + + boolean hasBoolean() throws IOException; + boolean readBoolean() throws IOException; + void skipBoolean() throws IOException; + + boolean hasInteger() throws IOException; + long readInteger() throws IOException; + void skipInteger() throws IOException; + + boolean hasFloat() throws IOException; + double readFloat() throws IOException; + void skipFloat() throws IOException; + + boolean hasString() throws IOException; + String readString(int maxLength) throws IOException; + void skipString() throws IOException; + + boolean hasBytes() throws IOException; + byte[] readBytes(int maxLength) throws IOException; + void skipBytes() throws IOException; + + boolean hasList() throws IOException; + void readListStart() throws IOException; + boolean hasListEnd() throws IOException; + void readListEnd() throws IOException; + void skipList() throws IOException; + + boolean hasMap() throws IOException; + void readMapStart() throws IOException; + boolean hasMapEnd() throws IOException; + void readMapEnd() throws IOException; + void skipMap() throws IOException; +} ===================================== briar-api/src/org/briarproject/api/data/ReaderFactory.java ===================================== --- /dev/null +++ b/briar-api/src/org/briarproject/api/data/ReaderFactory.java @@ -0,0 +1,8 @@ +package org.briarproject.api.data; + +import java.io.InputStream; + +public interface ReaderFactory { + + Reader createReader(InputStream in); +} ===================================== briar-api/src/org/briarproject/api/data/Writer.java ===================================== --- /dev/null +++ b/briar-api/src/org/briarproject/api/data/Writer.java @@ -0,0 +1,29 @@ +package org.briarproject.api.data; + +import java.io.IOException; +import java.util.Collection; +import java.util.Map; + +public interface Writer { + + void flush() throws IOException; + void close() throws IOException; + + void addConsumer(Consumer c); + void removeConsumer(Consumer c); + + void writeNull() throws IOException; + void writeBoolean(boolean b) throws IOException; + void writeInteger(long l) throws IOException; + void writeFloat(double d) throws IOException; + void writeString(String s) throws IOException; + void writeBytes(byte[] b) throws IOException; + + void writeList(Collection<?> c) throws IOException; + void writeListStart() throws IOException; + void writeListEnd() throws IOException; + + void writeMap(Map<?, ?> m) throws IOException; + void writeMapStart() throws IOException; + void writeMapEnd() throws IOException; +} ===================================== briar-api/src/org/briarproject/api/data/WriterFactory.java ===================================== --- /dev/null +++ b/briar-api/src/org/briarproject/api/data/WriterFactory.java @@ -0,0 +1,8 @@ +package org.briarproject.api.data; + +import java.io.OutputStream; + +public interface WriterFactory { + + Writer createWriter(OutputStream out); +} ===================================== briar-api/src/org/briarproject/api/serial/Consumer.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/Consumer.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.briarproject.api.serial; - -import java.io.IOException; - -public interface Consumer { - - void write(byte b) throws IOException; - - void write(byte[] b, int off, int len) throws IOException; -} ===================================== briar-api/src/org/briarproject/api/serial/CopyingConsumer.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/CopyingConsumer.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.briarproject.api.serial; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -/** A consumer that makes a copy of the bytes consumed. */ -public class CopyingConsumer implements Consumer { - - private final ByteArrayOutputStream out = new ByteArrayOutputStream(); - - public byte[] getCopy() { - return out.toByteArray(); - } - - public void write(byte b) throws IOException { - out.write(b); - } - - public void write(byte[] b, int off, int len) throws IOException { - out.write(b, off, len); - } -} ===================================== briar-api/src/org/briarproject/api/serial/CountingConsumer.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/CountingConsumer.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.briarproject.api.serial; - -import java.io.IOException; - -import org.briarproject.api.FormatException; - -/** - * A consumer that counts the number of bytes consumed and throws a - * FormatException if the count exceeds a given limit. - */ -public class CountingConsumer implements Consumer { - - private final long limit; - private long count = 0; - - public CountingConsumer(long limit) { - this.limit = limit; - } - - public long getCount() { - return count; - } - - public void write(byte b) throws IOException { - count++; - if(count > limit) throw new FormatException(); - } - - public void write(byte[] b, int off, int len) throws IOException { - count += len; - if(count > limit) throw new FormatException(); - } -} ===================================== briar-api/src/org/briarproject/api/serial/DigestingConsumer.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/DigestingConsumer.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.briarproject.api.serial; - -import org.briarproject.api.crypto.MessageDigest; - -/** A consumer that passes its input through a message digest. */ -public class DigestingConsumer implements Consumer { - - private final MessageDigest messageDigest; - - public DigestingConsumer(MessageDigest messageDigest) { - this.messageDigest = messageDigest; - } - - public void write(byte b) { - messageDigest.update(b); - } - - public void write(byte[] b, int off, int len) { - messageDigest.update(b, off, len); - } -} ===================================== briar-api/src/org/briarproject/api/serial/ObjectReader.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/ObjectReader.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.briarproject.api.serial; - -import java.io.IOException; - -public interface ObjectReader<T> { - - T readObject(Reader r) throws IOException; -} ===================================== briar-api/src/org/briarproject/api/serial/Reader.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/Reader.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.briarproject.api.serial; - -import java.io.IOException; - -public interface Reader { - - boolean eof() throws IOException; - void close() throws IOException; - - void addConsumer(Consumer c); - void removeConsumer(Consumer c); - - boolean hasNull() throws IOException; - void readNull() throws IOException; - void skipNull() throws IOException; - - boolean hasBoolean() throws IOException; - boolean readBoolean() throws IOException; - void skipBoolean() throws IOException; - - boolean hasInteger() throws IOException; - long readInteger() throws IOException; - void skipInteger() throws IOException; - - boolean hasFloat() throws IOException; - double readFloat() throws IOException; - void skipFloat() throws IOException; - - boolean hasString() throws IOException; - String readString(int maxLength) throws IOException; - void skipString() throws IOException; - - boolean hasBytes() throws IOException; - byte[] readBytes(int maxLength) throws IOException; - void skipBytes() throws IOException; - - boolean hasList() throws IOException; - void readListStart() throws IOException; - boolean hasListEnd() throws IOException; - void readListEnd() throws IOException; - void skipList() throws IOException; - - boolean hasMap() throws IOException; - void readMapStart() throws IOException; - boolean hasMapEnd() throws IOException; - void readMapEnd() throws IOException; - void skipMap() throws IOException; -} ===================================== briar-api/src/org/briarproject/api/serial/ReaderFactory.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/ReaderFactory.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.briarproject.api.serial; - -import java.io.InputStream; - -public interface ReaderFactory { - - Reader createReader(InputStream in); -} ===================================== briar-api/src/org/briarproject/api/serial/SerialComponent.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/SerialComponent.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.briarproject.api.serial; - -public interface SerialComponent { - - int getSerialisedListStartLength(); - - int getSerialisedListEndLength(); - - int getSerialisedUniqueIdLength(); -} ===================================== briar-api/src/org/briarproject/api/serial/SigningConsumer.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/SigningConsumer.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.briarproject.api.serial; - -import org.briarproject.api.crypto.Signature; - -/** A consumer that passes its input through a signature. */ -public class SigningConsumer implements Consumer { - - private final Signature signature; - - public SigningConsumer(Signature signature) { - this.signature = signature; - } - - public void write(byte b) { - signature.update(b); - } - - public void write(byte[] b, int off, int len) { - signature.update(b, off, len); - } -} ===================================== briar-api/src/org/briarproject/api/serial/Writer.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/Writer.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.briarproject.api.serial; - -import java.io.IOException; -import java.util.Collection; -import java.util.Map; - -public interface Writer { - - void flush() throws IOException; - void close() throws IOException; - - void addConsumer(Consumer c); - void removeConsumer(Consumer c); - - void writeNull() throws IOException; - void writeBoolean(boolean b) throws IOException; - void writeInteger(long l) throws IOException; - void writeFloat(double d) throws IOException; - void writeString(String s) throws IOException; - void writeBytes(byte[] b) throws IOException; - - void writeList(Collection<?> c) throws IOException; - void writeListStart() throws IOException; - void writeListEnd() throws IOException; - - void writeMap(Map<?, ?> m) throws IOException; - void writeMapStart() throws IOException; - void writeMapEnd() throws IOException; -} ===================================== briar-api/src/org/briarproject/api/serial/WriterFactory.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/WriterFactory.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.briarproject.api.serial; - -import java.io.OutputStream; - -public interface WriterFactory { - - Writer createWriter(OutputStream out); -} ===================================== briar-core/src/org/briarproject/data/ReaderFactoryImpl.java ===================================== --- /dev/null +++ b/briar-core/src/org/briarproject/data/ReaderFactoryImpl.java @@ -0,0 +1,13 @@ +package org.briarproject.data; + +import java.io.InputStream; + +import org.briarproject.api.data.Reader; +import org.briarproject.api.data.ReaderFactory; + +class ReaderFactoryImpl implements ReaderFactory { + + public Reader createReader(InputStream in) { + return new ReaderImpl(in); + } +} ===================================== briar-core/src/org/briarproject/data/ReaderImpl.java ===================================== --- /dev/null +++ b/briar-core/src/org/briarproject/data/ReaderImpl.java @@ -0,0 +1,362 @@ +package org.briarproject.data; + +import static org.briarproject.data.Types.END; +import static org.briarproject.data.Types.FLOAT_64; +import static org.briarproject.data.Types.INT_16; +import static org.briarproject.data.Types.INT_32; +import static org.briarproject.data.Types.INT_64; +import static org.briarproject.data.Types.INT_8; +import static org.briarproject.data.Types.LIST; +import static org.briarproject.data.Types.MAP; +import static org.briarproject.data.Types.NULL; +import static org.briarproject.data.Types.RAW_16; +import static org.briarproject.data.Types.RAW_32; +import static org.briarproject.data.Types.RAW_8; +import static org.briarproject.data.Types.STRING_16; +import static org.briarproject.data.Types.STRING_32; +import static org.briarproject.data.Types.STRING_8; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; + +import org.briarproject.api.FormatException; +import org.briarproject.api.data.Consumer; +import org.briarproject.api.data.Reader; + +// This class is not thread-safe +class ReaderImpl implements Reader { + + private static final byte[] EMPTY_BUFFER = new byte[] {}; + + private final InputStream in; + private final Collection<Consumer> consumers = new ArrayList<Consumer>(0); + + private boolean hasLookahead = false, eof = false; + private byte next; + private byte[] buf = new byte[8]; + + ReaderImpl(InputStream in) { + this.in = in; + } + + private void readLookahead() throws IOException { + assert !eof; + assert !hasLookahead; + // Read a lookahead byte + int i = in.read(); + if(i == -1) { + eof = true; + return; + } + next = (byte) i; + hasLookahead = true; + } + + private void consumeLookahead() throws IOException { + assert hasLookahead; + for(Consumer c : consumers) c.write(next); + hasLookahead = false; + } + + private void readIntoBuffer(byte[] b, int length, boolean consume) + throws IOException { + int offset = 0; + while(offset < length) { + int read = in.read(b, offset, length - offset); + if(read == -1) throw new FormatException(); + offset += read; + } + if(consume) for(Consumer c : consumers) c.write(b, 0, length); + } + + private void readIntoBuffer(int length, boolean consume) + throws IOException { + if(buf.length < length) buf = new byte[length]; + readIntoBuffer(buf, length, consume); + } + + private void skip(int length) throws IOException { + while(length > 0) { + int read = in.read(buf, 0, Math.min(length, buf.length)); + if(read == -1) throw new FormatException(); + length -= read; + } + } + + private void skipObject() throws IOException { + if(hasBoolean()) skipBoolean(); + else if(hasInteger()) skipInteger(); + else if(hasFloat()) skipFloat(); + else if(hasString()) skipString(); + else if(hasBytes()) skipBytes(); + else if(hasList()) skipList(); + else if(hasMap()) skipMap(); + else if(hasNull()) skipNull(); + else throw new FormatException(); + } + + public boolean eof() throws IOException { + if(!hasLookahead) readLookahead(); + return eof; + } + + public void close() throws IOException { + in.close(); + } + + public void addConsumer(Consumer c) { + consumers.add(c); + } + + public void removeConsumer(Consumer c) { + if(!consumers.remove(c)) throw new IllegalArgumentException(); + } + + public boolean hasNull() throws IOException { + if(!hasLookahead) readLookahead(); + if(eof) return false; + return next == NULL; + } + + public void readNull() throws IOException { + if(!hasNull()) throw new FormatException(); + consumeLookahead(); + } + + public void skipNull() throws IOException { + if(!hasNull()) throw new FormatException(); + hasLookahead = false; + } + + public boolean hasBoolean() throws IOException { + if(!hasLookahead) readLookahead(); + if(eof) return false; + return next == Types.BOOLEAN; + } + + public boolean readBoolean() throws IOException { + if(!hasBoolean()) throw new FormatException(); + consumeLookahead(); + return readBoolean(true); + } + + private boolean readBoolean(boolean consume) throws IOException { + readIntoBuffer(1, consume); + if(buf[0] != 0 && buf[0] != 1) throw new FormatException(); + return buf[0] == 1; + } + + public void skipBoolean() throws IOException { + if(!hasBoolean()) throw new FormatException(); + skip(1); + hasLookahead = false; + } + + public boolean hasInteger() throws IOException { + if(!hasLookahead) readLookahead(); + if(eof) return false; + return next == INT_8 || next == INT_16 || next == INT_32 || + next == INT_64; + } + + public long readInteger() throws IOException { + if(!hasInteger()) throw new FormatException(); + consumeLookahead(); + if(next == INT_8) return readInt8(true); + if(next == INT_16) return readInt16(true); + if(next == INT_32) return readInt32(true); + return readInt64(true); + } + + private int readInt8(boolean consume) throws IOException { + readIntoBuffer(1, consume); + return buf[0]; + } + + private short readInt16(boolean consume) throws IOException { + readIntoBuffer(2, consume); + short value = (short) (((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF)); + if(value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) + throw new FormatException(); + return value; + } + + private int readInt32(boolean consume) throws IOException { + readIntoBuffer(4, consume); + int value = 0; + for(int i = 0; i < 4; i++) value |= (buf[i] & 0xFF) << (24 - i * 8); + if(value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) + throw new FormatException(); + return value; + } + + private long readInt64(boolean consume) throws IOException { + readIntoBuffer(8, consume); + long value = 0; + for(int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8); + if(value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE) + throw new FormatException(); + return value; + } + + public void skipInteger() throws IOException { + if(!hasInteger()) throw new FormatException(); + if(next == INT_8) skip(1); + else if(next == INT_16) skip(2); + else if(next == INT_32) skip(4); + else skip(8); + hasLookahead = false; + } + + public boolean hasFloat() throws IOException { + if(!hasLookahead) readLookahead(); + if(eof) return false; + return next == FLOAT_64; + } + + public double readFloat() throws IOException { + if(!hasFloat()) throw new FormatException(); + consumeLookahead(); + readIntoBuffer(8, true); + long value = 0; + for(int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8); + return Double.longBitsToDouble(value); + } + + public void skipFloat() throws IOException { + if(!hasFloat()) throw new FormatException(); + skip(8); + hasLookahead = false; + } + + public boolean hasString() throws IOException { + if(!hasLookahead) readLookahead(); + if(eof) return false; + return next == STRING_8 || next == STRING_16 || next == STRING_32; + } + + public String readString(int maxLength) throws IOException { + if(!hasString()) throw new FormatException(); + consumeLookahead(); + int length = readStringLength(true); + if(length < 0 || length > maxLength) throw new FormatException(); + if(length == 0) return ""; + readIntoBuffer(length, true); + return new String(buf, 0, length, "UTF-8"); + } + + private int readStringLength(boolean consume) throws IOException { + if(next == STRING_8) return readInt8(consume); + if(next == STRING_16) return readInt16(consume); + if(next == STRING_32) return readInt32(consume); + throw new FormatException(); + } + + public void skipString() throws IOException { + if(!hasString()) throw new FormatException(); + int length = readStringLength(false); + if(length < 0) throw new FormatException(); + skip(length); + hasLookahead = false; + } + + public boolean hasBytes() throws IOException { + if(!hasLookahead) readLookahead(); + if(eof) return false; + return next == RAW_8 || next == RAW_16 || next == RAW_32; + } + + public byte[] readBytes(int maxLength) throws IOException { + if(!hasBytes()) throw new FormatException(); + consumeLookahead(); + int length = readBytesLength(true); + if(length < 0 || length > maxLength) throw new FormatException(); + if(length == 0) return EMPTY_BUFFER; + byte[] b = new byte[length]; + readIntoBuffer(b, length, true); + return b; + } + + private int readBytesLength(boolean consume) throws IOException { + if(next == RAW_8) return readInt8(consume); + if(next == RAW_16) return readInt16(consume); + if(next == RAW_32) return readInt32(consume); + throw new FormatException(); + } + + public void skipBytes() throws IOException { + if(!hasBytes()) throw new FormatException(); + int length = readBytesLength(false); + if(length < 0) throw new FormatException(); + skip(length); + hasLookahead = false; + } + + public boolean hasList() throws IOException { + if(!hasLookahead) readLookahead(); + if(eof) return false; + return next == LIST; + } + + public void readListStart() throws IOException { + if(!hasList()) throw new FormatException(); + consumeLookahead(); + } + + public boolean hasListEnd() throws IOException { + return hasEnd(); + } + + private boolean hasEnd() throws IOException { + if(!hasLookahead) readLookahead(); + if(eof) return false; + return next == END; + } + + public void readListEnd() throws IOException { + readEnd(); + } + + private void readEnd() throws IOException { + if(!hasEnd()) throw new FormatException(); + consumeLookahead(); + } + + public void skipList() throws IOException { + if(!hasList()) throw new FormatException(); + hasLookahead = false; + while(!hasListEnd()) skipObject(); + hasLookahead = false; + } + + public boolean hasMap() throws IOException { + if(!hasLookahead) readLookahead(); + if(eof) return false; + return next == MAP; + } + + public void readMapStart() throws IOException { + if(!hasMap()) throw new FormatException(); + consumeLookahead(); + } + + public boolean hasMapEnd() throws IOException { + return hasEnd(); + } + + public void readMapEnd() throws IOException { + readEnd(); + } + + public void skipMap() throws IOException { + if(!hasMap()) throw new FormatException(); + hasLookahead = false; + while(!hasMapEnd()) { + skipObject(); + skipObject(); + } + hasLookahead = false; + } +} ===================================== briar-core/src/org/briarproject/data/SerialModule.java ===================================== --- /dev/null +++ b/briar-core/src/org/briarproject/data/SerialModule.java @@ -0,0 +1,15 @@ +package org.briarproject.data; + +import org.briarproject.api.data.ReaderFactory; +import org.briarproject.api.data.WriterFactory; + +import com.google.inject.AbstractModule; + +public class SerialModule extends AbstractModule { + + @Override + protected void configure() { + bind(ReaderFactory.class).to(ReaderFactoryImpl.class); + bind(WriterFactory.class).to(WriterFactoryImpl.class); + } +} ===================================== briar-core/src/org/briarproject/data/Types.java ===================================== --- /dev/null +++ b/briar-core/src/org/briarproject/data/Types.java @@ -0,0 +1,21 @@ +package org.briarproject.data; + +interface Types { + + byte NULL = 0x00; + byte BOOLEAN = 0x11; + byte INT_8 = 0x21; + byte INT_16 = 0x22; + byte INT_32 = 0x24; + byte INT_64 = 0x28; + byte FLOAT_64 = 0x38; + byte STRING_8 = 0x41; + byte STRING_16 = 0x42; + byte STRING_32 = 0x44; + byte RAW_8 = 0x51; + byte RAW_16 = 0x52; + byte RAW_32 = 0x54; + byte LIST = 0x60; + byte MAP = 0x70; + byte END = (byte) 0x80; +} ===================================== briar-core/src/org/briarproject/data/WriterFactoryImpl.java ===================================== --- /dev/null +++ b/briar-core/src/org/briarproject/data/WriterFactoryImpl.java @@ -0,0 +1,13 @@ +package org.briarproject.data; + +import java.io.OutputStream; + +import org.briarproject.api.data.Writer; +import org.briarproject.api.data.WriterFactory; + +class WriterFactoryImpl implements WriterFactory { + + public Writer createWriter(OutputStream out) { + return new WriterImpl(out); + } +} ===================================== briar-core/src/org/briarproject/data/WriterImpl.java ===================================== --- /dev/null +++ b/briar-core/src/org/briarproject/data/WriterImpl.java @@ -0,0 +1,198 @@ +package org.briarproject.data; + +import static org.briarproject.data.Types.BOOLEAN; +import static org.briarproject.data.Types.END; +import static org.briarproject.data.Types.FLOAT_64; +import static org.briarproject.data.Types.INT_16; +import static org.briarproject.data.Types.INT_32; +import static org.briarproject.data.Types.INT_64; +import static org.briarproject.data.Types.INT_8; +import static org.briarproject.data.Types.LIST; +import static org.briarproject.data.Types.MAP; +import static org.briarproject.data.Types.NULL; +import static org.briarproject.data.Types.RAW_16; +import static org.briarproject.data.Types.RAW_32; +import static org.briarproject.data.Types.RAW_8; +import static org.briarproject.data.Types.STRING_16; +import static org.briarproject.data.Types.STRING_32; +import static org.briarproject.data.Types.STRING_8; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.briarproject.api.Bytes; +import org.briarproject.api.data.Consumer; +import org.briarproject.api.data.Writer; + +// This class is not thread-safe +class WriterImpl implements Writer { + + private final OutputStream out; + private final Collection<Consumer> consumers = new ArrayList<Consumer>(0); + + WriterImpl(OutputStream out) { + this.out = out; + } + + public void flush() throws IOException { + out.flush(); + } + + public void close() throws IOException { + out.close(); + } + + public void addConsumer(Consumer c) { + consumers.add(c); + } + + public void removeConsumer(Consumer c) { + if(!consumers.remove(c)) throw new IllegalArgumentException(); + } + + public void writeNull() throws IOException { + write(NULL); + } + + public void writeBoolean(boolean b) throws IOException { + write(BOOLEAN); + if(b) write((byte) 1); + else write((byte) 0); + } + + public void writeInteger(long i) throws IOException { + if(i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) { + write(INT_8); + write((byte) i); + } else if(i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) { + write(INT_16); + writeInt16((short) i); + } else if(i >= Integer.MIN_VALUE && i <= Integer.MAX_VALUE) { + write(INT_32); + writeInt32((int) i); + } else { + write(INT_64); + writeInt64(i); + } + } + + private void writeInt16(short i) throws IOException { + write((byte) (i >> 8)); + write((byte) ((i << 8) >> 8)); + } + + private void writeInt32(int i) throws IOException { + write((byte) (i >> 24)); + write((byte) ((i << 8) >> 24)); + write((byte) ((i << 16) >> 24)); + write((byte) ((i << 24) >> 24)); + } + + private void writeInt64(long i) throws IOException { + write((byte) (i >> 56)); + write((byte) ((i << 8) >> 56)); + write((byte) ((i << 16) >> 56)); + write((byte) ((i << 24) >> 56)); + write((byte) ((i << 32) >> 56)); + write((byte) ((i << 40) >> 56)); + write((byte) ((i << 48) >> 56)); + write((byte) ((i << 56) >> 56)); + } + + public void writeFloat(double d) throws IOException { + write(FLOAT_64); + writeInt64(Double.doubleToRawLongBits(d)); + } + + public void writeString(String s) throws IOException { + byte[] b = s.getBytes("UTF-8"); + if(b.length <= Byte.MAX_VALUE) { + write(STRING_8); + write((byte) b.length); + } else if(b.length <= Short.MAX_VALUE) { + write(STRING_16); + writeInt16((short) b.length); + } else { + write(STRING_32); + writeInt32(b.length); + } + write(b); + } + + public void writeBytes(byte[] b) throws IOException { + if(b.length <= Byte.MAX_VALUE) { + write(RAW_8); + write((byte) b.length); + } else if(b.length <= Short.MAX_VALUE) { + write(RAW_16); + writeInt16((short) b.length); + } else { + write(RAW_32); + writeInt32(b.length); + } + write(b); + } + + public void writeList(Collection<?> c) throws IOException { + write(Types.LIST); + for(Object o : c) writeObject(o); + write(Types.END); + } + + private void writeObject(Object o) throws IOException { + if(o instanceof Boolean) writeBoolean((Boolean) o); + else if(o instanceof Byte) writeInteger((Byte) o); + else if(o instanceof Short) writeInteger((Short) o); + else if(o instanceof Integer) writeInteger((Integer) o); + else if(o instanceof Long) writeInteger((Long) o); + else if(o instanceof Float) writeFloat((Float) o); + else if(o instanceof Double) writeFloat((Double) o); + else if(o instanceof String) writeString((String) o); + else if(o instanceof byte[]) writeBytes((byte[]) o); + else if(o instanceof Bytes) writeBytes(((Bytes) o).getBytes()); + else if(o instanceof List<?>) writeList((List<?>) o); + else if(o instanceof Map<?, ?>) writeMap((Map<?, ?>) o); + else if(o == null) writeNull(); + else throw new IllegalStateException(); + } + + public void writeListStart() throws IOException { + write(LIST); + } + + public void writeListEnd() throws IOException { + write(END); + } + + public void writeMap(Map<?, ?> m) throws IOException { + write(MAP); + for(Entry<?, ?> e : m.entrySet()) { + writeObject(e.getKey()); + writeObject(e.getValue()); + } + write(END); + } + + public void writeMapStart() throws IOException { + write(MAP); + } + + public void writeMapEnd() throws IOException { + write(END); + } + + private void write(byte b) throws IOException { + out.write(b); + for(Consumer c : consumers) c.write(b); + } + + private void write(byte[] b) throws IOException { + out.write(b); + for(Consumer c : consumers) c.write(b, 0, b.length); + } +} ===================================== briar-core/src/org/briarproject/invitation/AliceConnector.java ===================================== --- a/briar-core/src/org/briarproject/invitation/AliceConnector.java +++ b/briar-core/src/org/briarproject/invitation/AliceConnector.java @@ -18,16 +18,16 @@ import org.briarproject.api.TransportProperties; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.KeyManager; import org.briarproject.api.crypto.PseudoRandom; +import org.briarproject.api.data.Reader; +import org.briarproject.api.data.ReaderFactory; +import org.briarproject.api.data.Writer; +import org.briarproject.api.data.WriterFactory; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DbException; import org.briarproject.api.messaging.GroupFactory; import org.briarproject.api.plugins.ConnectionManager; import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexTransportConnection; -import org.briarproject.api.serial.Reader; -import org.briarproject.api.serial.ReaderFactory; -import org.briarproject.api.serial.Writer; -import org.briarproject.api.serial.WriterFactory; import org.briarproject.api.system.Clock; import org.briarproject.api.transport.StreamReaderFactory; import org.briarproject.api.transport.StreamWriterFactory; ===================================== briar-core/src/org/briarproject/invitation/BobConnector.java ===================================== --- a/briar-core/src/org/briarproject/invitation/BobConnector.java +++ b/briar-core/src/org/briarproject/invitation/BobConnector.java @@ -18,16 +18,16 @@ import org.briarproject.api.TransportProperties; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.KeyManager; import org.briarproject.api.crypto.PseudoRandom; +import org.briarproject.api.data.Reader; +import org.briarproject.api.data.ReaderFactory; +import org.briarproject.api.data.Writer; +import org.briarproject.api.data.WriterFactory; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DbException; import org.briarproject.api.messaging.GroupFactory; import org.briarproject.api.plugins.ConnectionManager; import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexTransportConnection; -import org.briarproject.api.serial.Reader; -import org.briarproject.api.serial.ReaderFactory; -import org.briarproject.api.serial.Writer; -import org.briarproject.api.serial.WriterFactory; import org.briarproject.api.system.Clock; import org.briarproject.api.transport.StreamReaderFactory; import org.briarproject.api.transport.StreamWriterFactory; ===================================== briar-core/src/org/briarproject/invitation/Connector.java ===================================== --- a/briar-core/src/org/briarproject/invitation/Connector.java +++ b/briar-core/src/org/briarproject/invitation/Connector.java @@ -36,6 +36,10 @@ import org.briarproject.api.crypto.KeyParser; import org.briarproject.api.crypto.MessageDigest; import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.api.crypto.Signature; +import org.briarproject.api.data.Reader; +import org.briarproject.api.data.ReaderFactory; +import org.briarproject.api.data.Writer; +import org.briarproject.api.data.WriterFactory; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DbException; import org.briarproject.api.db.NoSuchTransportException; @@ -44,10 +48,6 @@ import org.briarproject.api.messaging.GroupFactory; import org.briarproject.api.plugins.ConnectionManager; import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexTransportConnection; -import org.briarproject.api.serial.Reader; -import org.briarproject.api.serial.ReaderFactory; -import org.briarproject.api.serial.Writer; -import org.briarproject.api.serial.WriterFactory; import org.briarproject.api.system.Clock; import org.briarproject.api.transport.Endpoint; import org.briarproject.api.transport.StreamReaderFactory; ===================================== briar-core/src/org/briarproject/invitation/ConnectorGroup.java ===================================== --- a/briar-core/src/org/briarproject/invitation/ConnectorGroup.java +++ b/briar-core/src/org/briarproject/invitation/ConnectorGroup.java @@ -23,6 +23,8 @@ import org.briarproject.api.TransportProperties; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.KeyManager; import org.briarproject.api.crypto.PseudoRandom; +import org.briarproject.api.data.ReaderFactory; +import org.briarproject.api.data.WriterFactory; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DbException; import org.briarproject.api.invitation.InvitationListener; @@ -32,8 +34,6 @@ import org.briarproject.api.messaging.GroupFactory; import org.briarproject.api.plugins.ConnectionManager; import org.briarproject.api.plugins.PluginManager; import org.briarproject.api.plugins.duplex.DuplexPlugin; -import org.briarproject.api.serial.ReaderFactory; -import org.briarproject.api.serial.WriterFactory; import org.briarproject.api.system.Clock; import org.briarproject.api.transport.StreamReaderFactory; import org.briarproject.api.transport.StreamWriterFactory; ===================================== briar-core/src/org/briarproject/invitation/InvitationTaskFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/invitation/InvitationTaskFactoryImpl.java +++ b/briar-core/src/org/briarproject/invitation/InvitationTaskFactoryImpl.java @@ -6,14 +6,14 @@ import org.briarproject.api.AuthorFactory; import org.briarproject.api.AuthorId; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.KeyManager; +import org.briarproject.api.data.ReaderFactory; +import org.briarproject.api.data.WriterFactory; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.invitation.InvitationTask; import org.briarproject.api.invitation.InvitationTaskFactory; import org.briarproject.api.messaging.GroupFactory; import org.briarproject.api.plugins.ConnectionManager; import org.briarproject.api.plugins.PluginManager; -import org.briarproject.api.serial.ReaderFactory; -import org.briarproject.api.serial.WriterFactory; import org.briarproject.api.system.Clock; import org.briarproject.api.transport.StreamReaderFactory; import org.briarproject.api.transport.StreamWriterFactory; ===================================== briar-core/src/org/briarproject/messaging/AuthorFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/AuthorFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/AuthorFactoryImpl.java @@ -11,8 +11,8 @@ import org.briarproject.api.AuthorId; import org.briarproject.api.LocalAuthor; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.MessageDigest; -import org.briarproject.api.serial.Writer; -import org.briarproject.api.serial.WriterFactory; +import org.briarproject.api.data.Writer; +import org.briarproject.api.data.WriterFactory; import org.briarproject.api.system.Clock; class AuthorFactoryImpl implements AuthorFactory { ===================================== briar-core/src/org/briarproject/messaging/AuthorReader.java ===================================== --- a/briar-core/src/org/briarproject/messaging/AuthorReader.java +++ b/briar-core/src/org/briarproject/messaging/AuthorReader.java @@ -10,9 +10,8 @@ import org.briarproject.api.AuthorId; import org.briarproject.api.FormatException; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.MessageDigest; -import org.briarproject.api.serial.DigestingConsumer; -import org.briarproject.api.serial.Reader; -import org.briarproject.api.serial.ObjectReader; +import org.briarproject.api.data.ObjectReader; +import org.briarproject.api.data.Reader; class AuthorReader implements ObjectReader<Author> { ===================================== briar-core/src/org/briarproject/messaging/CopyingConsumer.java ===================================== --- /dev/null +++ b/briar-core/src/org/briarproject/messaging/CopyingConsumer.java @@ -0,0 +1,24 @@ +package org.briarproject.messaging; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.briarproject.api.data.Consumer; + +/** A consumer that makes a copy of the bytes consumed. */ +class CopyingConsumer implements Consumer { + + private final ByteArrayOutputStream out = new ByteArrayOutputStream(); + + public byte[] getCopy() { + return out.toByteArray(); + } + + public void write(byte b) throws IOException { + out.write(b); + } + + public void write(byte[] b, int off, int len) throws IOException { + out.write(b, off, len); + } +} ===================================== briar-core/src/org/briarproject/messaging/CountingConsumer.java ===================================== --- /dev/null +++ b/briar-core/src/org/briarproject/messaging/CountingConsumer.java @@ -0,0 +1,34 @@ +package org.briarproject.messaging; + +import java.io.IOException; + +import org.briarproject.api.FormatException; +import org.briarproject.api.data.Consumer; + +/** + * A consumer that counts the number of bytes consumed and throws a + * FormatException if the count exceeds a given limit. + */ +class CountingConsumer implements Consumer { + + private final long limit; + private long count = 0; + + public CountingConsumer(long limit) { + this.limit = limit; + } + + public long getCount() { + return count; + } + + public void write(byte b) throws IOException { + count++; + if(count > limit) throw new FormatException(); + } + + public void write(byte[] b, int off, int len) throws IOException { + count += len; + if(count > limit) throw new FormatException(); + } +} ===================================== briar-core/src/org/briarproject/messaging/DigestingConsumer.java ===================================== --- /dev/null +++ b/briar-core/src/org/briarproject/messaging/DigestingConsumer.java @@ -0,0 +1,22 @@ +package org.briarproject.messaging; + +import org.briarproject.api.crypto.MessageDigest; +import org.briarproject.api.data.Consumer; + +/** A consumer that passes its input through a message digest. */ +class DigestingConsumer implements Consumer { + + private final MessageDigest messageDigest; + + public DigestingConsumer(MessageDigest messageDigest) { + this.messageDigest = messageDigest; + } + + public void write(byte b) { + messageDigest.update(b); + } + + public void write(byte[] b, int off, int len) { + messageDigest.update(b, off, len); + } +} ===================================== briar-core/src/org/briarproject/messaging/GroupFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/GroupFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/GroupFactoryImpl.java @@ -9,11 +9,11 @@ import javax.inject.Inject; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.MessageDigest; +import org.briarproject.api.data.Writer; +import org.briarproject.api.data.WriterFactory; import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.GroupFactory; import org.briarproject.api.messaging.GroupId; -import org.briarproject.api.serial.Writer; -import org.briarproject.api.serial.WriterFactory; class GroupFactoryImpl implements GroupFactory { ===================================== briar-core/src/org/briarproject/messaging/GroupReader.java ===================================== --- a/briar-core/src/org/briarproject/messaging/GroupReader.java +++ b/briar-core/src/org/briarproject/messaging/GroupReader.java @@ -8,11 +8,10 @@ import java.io.IOException; import org.briarproject.api.FormatException; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.MessageDigest; +import org.briarproject.api.data.ObjectReader; +import org.briarproject.api.data.Reader; import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.GroupId; -import org.briarproject.api.serial.DigestingConsumer; -import org.briarproject.api.serial.Reader; -import org.briarproject.api.serial.ObjectReader; class GroupReader implements ObjectReader<Group> { ===================================== briar-core/src/org/briarproject/messaging/MessageFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/MessageFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/MessageFactoryImpl.java @@ -18,16 +18,13 @@ import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.MessageDigest; import org.briarproject.api.crypto.PrivateKey; import org.briarproject.api.crypto.Signature; +import org.briarproject.api.data.Consumer; +import org.briarproject.api.data.Writer; +import org.briarproject.api.data.WriterFactory; import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.Message; import org.briarproject.api.messaging.MessageFactory; import org.briarproject.api.messaging.MessageId; -import org.briarproject.api.serial.Consumer; -import org.briarproject.api.serial.CountingConsumer; -import org.briarproject.api.serial.DigestingConsumer; -import org.briarproject.api.serial.SigningConsumer; -import org.briarproject.api.serial.Writer; -import org.briarproject.api.serial.WriterFactory; import org.briarproject.util.StringUtils; class MessageFactoryImpl implements MessageFactory { ===================================== briar-core/src/org/briarproject/messaging/MessageReader.java ===================================== --- a/briar-core/src/org/briarproject/messaging/MessageReader.java +++ b/briar-core/src/org/briarproject/messaging/MessageReader.java @@ -11,13 +11,11 @@ import java.io.IOException; import org.briarproject.api.Author; import org.briarproject.api.FormatException; import org.briarproject.api.UniqueId; +import org.briarproject.api.data.ObjectReader; +import org.briarproject.api.data.Reader; import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.MessageId; import org.briarproject.api.messaging.UnverifiedMessage; -import org.briarproject.api.serial.CopyingConsumer; -import org.briarproject.api.serial.CountingConsumer; -import org.briarproject.api.serial.ObjectReader; -import org.briarproject.api.serial.Reader; class MessageReader implements ObjectReader<UnverifiedMessage> { ===================================== briar-core/src/org/briarproject/messaging/MessagingModule.java ===================================== --- a/briar-core/src/org/briarproject/messaging/MessagingModule.java +++ b/briar-core/src/org/briarproject/messaging/MessagingModule.java @@ -5,6 +5,7 @@ import javax.inject.Singleton; import org.briarproject.api.Author; import org.briarproject.api.AuthorFactory; import org.briarproject.api.crypto.CryptoComponent; +import org.briarproject.api.data.ObjectReader; import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.GroupFactory; import org.briarproject.api.messaging.MessageFactory; @@ -14,7 +15,6 @@ import org.briarproject.api.messaging.PacketReaderFactory; import org.briarproject.api.messaging.PacketWriterFactory; import org.briarproject.api.messaging.SubscriptionUpdate; import org.briarproject.api.messaging.UnverifiedMessage; -import org.briarproject.api.serial.ObjectReader; import com.google.inject.AbstractModule; import com.google.inject.Provides; ===================================== briar-core/src/org/briarproject/messaging/PacketReaderFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/PacketReaderFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/PacketReaderFactoryImpl.java @@ -4,12 +4,12 @@ import java.io.InputStream; import javax.inject.Inject; +import org.briarproject.api.data.ObjectReader; +import org.briarproject.api.data.ReaderFactory; import org.briarproject.api.messaging.PacketReader; import org.briarproject.api.messaging.PacketReaderFactory; import org.briarproject.api.messaging.SubscriptionUpdate; import org.briarproject.api.messaging.UnverifiedMessage; -import org.briarproject.api.serial.ReaderFactory; -import org.briarproject.api.serial.ObjectReader; class PacketReaderFactoryImpl implements PacketReaderFactory { ===================================== briar-core/src/org/briarproject/messaging/PacketReaderImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/PacketReaderImpl.java +++ b/briar-core/src/org/briarproject/messaging/PacketReaderImpl.java @@ -30,6 +30,9 @@ import org.briarproject.api.FormatException; import org.briarproject.api.TransportId; import org.briarproject.api.TransportProperties; import org.briarproject.api.UniqueId; +import org.briarproject.api.data.ObjectReader; +import org.briarproject.api.data.Reader; +import org.briarproject.api.data.ReaderFactory; import org.briarproject.api.messaging.Ack; import org.briarproject.api.messaging.MessageId; import org.briarproject.api.messaging.Offer; @@ -42,9 +45,6 @@ import org.briarproject.api.messaging.SubscriptionUpdate; import org.briarproject.api.messaging.TransportAck; import org.briarproject.api.messaging.TransportUpdate; import org.briarproject.api.messaging.UnverifiedMessage; -import org.briarproject.api.serial.Reader; -import org.briarproject.api.serial.ReaderFactory; -import org.briarproject.api.serial.ObjectReader; import org.briarproject.util.ByteUtils; // This class is not thread-safe ===================================== briar-core/src/org/briarproject/messaging/PacketWriterFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/PacketWriterFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/PacketWriterFactoryImpl.java @@ -4,24 +4,20 @@ import java.io.OutputStream; import javax.inject.Inject; +import org.briarproject.api.data.WriterFactory; import org.briarproject.api.messaging.PacketWriter; import org.briarproject.api.messaging.PacketWriterFactory; -import org.briarproject.api.serial.SerialComponent; -import org.briarproject.api.serial.WriterFactory; class PacketWriterFactoryImpl implements PacketWriterFactory { - private final SerialComponent serial; private final WriterFactory writerFactory; @Inject - PacketWriterFactoryImpl(SerialComponent serial, - WriterFactory writerFactory) { - this.serial = serial; + PacketWriterFactoryImpl(WriterFactory writerFactory) { this.writerFactory = writerFactory; } public PacketWriter createPacketWriter(OutputStream out) { - return new PacketWriterImpl(serial, writerFactory, out); + return new PacketWriterImpl(writerFactory, out); } } ===================================== briar-core/src/org/briarproject/messaging/PacketWriterImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/PacketWriterImpl.java +++ b/briar-core/src/org/briarproject/messaging/PacketWriterImpl.java @@ -1,5 +1,8 @@ package org.briarproject.messaging; +import static org.briarproject.api.data.DataConstants.LIST_END_LENGTH; +import static org.briarproject.api.data.DataConstants.LIST_START_LENGTH; +import static org.briarproject.api.data.DataConstants.UNIQUE_ID_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.HEADER_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MAX_PAYLOAD_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.PROTOCOL_VERSION; @@ -17,6 +20,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import org.briarproject.api.data.Writer; +import org.briarproject.api.data.WriterFactory; import org.briarproject.api.messaging.Ack; import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.MessageId; @@ -30,23 +35,17 @@ import org.briarproject.api.messaging.SubscriptionAck; import org.briarproject.api.messaging.SubscriptionUpdate; import org.briarproject.api.messaging.TransportAck; import org.briarproject.api.messaging.TransportUpdate; -import org.briarproject.api.serial.SerialComponent; -import org.briarproject.api.serial.Writer; -import org.briarproject.api.serial.WriterFactory; import org.briarproject.util.ByteUtils; // This class is not thread-safe class PacketWriterImpl implements PacketWriter { - private final SerialComponent serial; private final WriterFactory writerFactory; private final OutputStream out; private final byte[] header; private final ByteArrayOutputStream payload; - PacketWriterImpl(SerialComponent serial, WriterFactory writerFactory, - OutputStream out) { - this.serial = serial; + PacketWriterImpl(WriterFactory writerFactory, OutputStream out) { this.writerFactory = writerFactory; this.out = out; header = new byte[HEADER_LENGTH]; @@ -69,10 +68,8 @@ class PacketWriterImpl implements PacketWriter { private int getMaxMessagesForPacket(long capacity) { int payload = (int) Math.min(capacity - HEADER_LENGTH, MAX_PAYLOAD_LENGTH); - int overhead = serial.getSerialisedListStartLength() * 2 - + serial.getSerialisedListEndLength() * 2; - int idLength = serial.getSerialisedUniqueIdLength(); - return (payload - overhead) / idLength; + int overhead = LIST_START_LENGTH * 2 + LIST_END_LENGTH * 2; + return (payload - overhead) / UNIQUE_ID_LENGTH; } private void writePacket(byte packetType) throws IOException { ===================================== briar-core/src/org/briarproject/messaging/SigningConsumer.java ===================================== --- /dev/null +++ b/briar-core/src/org/briarproject/messaging/SigningConsumer.java @@ -0,0 +1,22 @@ +package org.briarproject.messaging; + +import org.briarproject.api.crypto.Signature; +import org.briarproject.api.data.Consumer; + +/** A consumer that passes its input through a signature. */ +class SigningConsumer implements Consumer { + + private final Signature signature; + + public SigningConsumer(Signature signature) { + this.signature = signature; + } + + public void write(byte b) { + signature.update(b); + } + + public void write(byte[] b, int off, int len) { + signature.update(b, off, len); + } +} ===================================== briar-core/src/org/briarproject/messaging/SubscriptionUpdateReader.java ===================================== --- a/briar-core/src/org/briarproject/messaging/SubscriptionUpdateReader.java +++ b/briar-core/src/org/briarproject/messaging/SubscriptionUpdateReader.java @@ -11,13 +11,12 @@ import java.util.List; import java.util.Set; import org.briarproject.api.FormatException; +import org.briarproject.api.data.Consumer; +import org.briarproject.api.data.ObjectReader; +import org.briarproject.api.data.Reader; import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.GroupId; import org.briarproject.api.messaging.SubscriptionUpdate; -import org.briarproject.api.serial.Consumer; -import org.briarproject.api.serial.CountingConsumer; -import org.briarproject.api.serial.ObjectReader; -import org.briarproject.api.serial.Reader; class SubscriptionUpdateReader implements ObjectReader<SubscriptionUpdate> { ===================================== briar-core/src/org/briarproject/serial/ObjectTypes.java ===================================== --- a/briar-core/src/org/briarproject/serial/ObjectTypes.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.briarproject.serial; - -interface ObjectTypes { - - byte NULL = 0x00; - byte BOOLEAN = 0x11; - byte INT_8 = 0x21; - byte INT_16 = 0x22; - byte INT_32 = 0x24; - byte INT_64 = 0x28; - byte FLOAT_64 = 0x38; - byte STRING_8 = 0x41; - byte STRING_16 = 0x42; - byte STRING_32 = 0x44; - byte RAW_8 = 0x51; - byte RAW_16 = 0x52; - byte RAW_32 = 0x54; - byte LIST = 0x60; - byte MAP = 0x70; - byte END = (byte) 0x80; -} ===================================== briar-core/src/org/briarproject/serial/ReaderFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/serial/ReaderFactoryImpl.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.briarproject.serial; - -import java.io.InputStream; - -import org.briarproject.api.serial.Reader; -import org.briarproject.api.serial.ReaderFactory; - -class ReaderFactoryImpl implements ReaderFactory { - - public Reader createReader(InputStream in) { - return new ReaderImpl(in); - } -} ===================================== briar-core/src/org/briarproject/serial/ReaderImpl.java ===================================== --- a/briar-core/src/org/briarproject/serial/ReaderImpl.java +++ /dev/null @@ -1,362 +0,0 @@ -package org.briarproject.serial; - -import static org.briarproject.serial.ObjectTypes.END; -import static org.briarproject.serial.ObjectTypes.FLOAT_64; -import static org.briarproject.serial.ObjectTypes.INT_16; -import static org.briarproject.serial.ObjectTypes.INT_32; -import static org.briarproject.serial.ObjectTypes.INT_64; -import static org.briarproject.serial.ObjectTypes.INT_8; -import static org.briarproject.serial.ObjectTypes.LIST; -import static org.briarproject.serial.ObjectTypes.MAP; -import static org.briarproject.serial.ObjectTypes.NULL; -import static org.briarproject.serial.ObjectTypes.RAW_16; -import static org.briarproject.serial.ObjectTypes.RAW_32; -import static org.briarproject.serial.ObjectTypes.RAW_8; -import static org.briarproject.serial.ObjectTypes.STRING_16; -import static org.briarproject.serial.ObjectTypes.STRING_32; -import static org.briarproject.serial.ObjectTypes.STRING_8; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; - -import org.briarproject.api.FormatException; -import org.briarproject.api.serial.Consumer; -import org.briarproject.api.serial.Reader; - -// This class is not thread-safe -class ReaderImpl implements Reader { - - private static final byte[] EMPTY_BUFFER = new byte[] {}; - - private final InputStream in; - private final Collection<Consumer> consumers = new ArrayList<Consumer>(0); - - private boolean hasLookahead = false, eof = false; - private byte next; - private byte[] buf = new byte[8]; - - ReaderImpl(InputStream in) { - this.in = in; - } - - private void readLookahead() throws IOException { - assert !eof; - assert !hasLookahead; - // Read a lookahead byte - int i = in.read(); - if(i == -1) { - eof = true; - return; - } - next = (byte) i; - hasLookahead = true; - } - - private void consumeLookahead() throws IOException { - assert hasLookahead; - for(Consumer c : consumers) c.write(next); - hasLookahead = false; - } - - private void readIntoBuffer(byte[] b, int length, boolean consume) - throws IOException { - int offset = 0; - while(offset < length) { - int read = in.read(b, offset, length - offset); - if(read == -1) throw new FormatException(); - offset += read; - } - if(consume) for(Consumer c : consumers) c.write(b, 0, length); - } - - private void readIntoBuffer(int length, boolean consume) - throws IOException { - if(buf.length < length) buf = new byte[length]; - readIntoBuffer(buf, length, consume); - } - - private void skip(int length) throws IOException { - while(length > 0) { - int read = in.read(buf, 0, Math.min(length, buf.length)); - if(read == -1) throw new FormatException(); - length -= read; - } - } - - private void skipObject() throws IOException { - if(hasBoolean()) skipBoolean(); - else if(hasInteger()) skipInteger(); - else if(hasFloat()) skipFloat(); - else if(hasString()) skipString(); - else if(hasBytes()) skipBytes(); - else if(hasList()) skipList(); - else if(hasMap()) skipMap(); - else if(hasNull()) skipNull(); - else throw new FormatException(); - } - - public boolean eof() throws IOException { - if(!hasLookahead) readLookahead(); - return eof; - } - - public void close() throws IOException { - in.close(); - } - - public void addConsumer(Consumer c) { - consumers.add(c); - } - - public void removeConsumer(Consumer c) { - if(!consumers.remove(c)) throw new IllegalArgumentException(); - } - - public boolean hasNull() throws IOException { - if(!hasLookahead) readLookahead(); - if(eof) return false; - return next == NULL; - } - - public void readNull() throws IOException { - if(!hasNull()) throw new FormatException(); - consumeLookahead(); - } - - public void skipNull() throws IOException { - if(!hasNull()) throw new FormatException(); - hasLookahead = false; - } - - public boolean hasBoolean() throws IOException { - if(!hasLookahead) readLookahead(); - if(eof) return false; - return next == ObjectTypes.BOOLEAN; - } - - public boolean readBoolean() th... [truncated message content] |
From: akwizgran <gi...@br...> - 2015-05-01 20:06:29
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="32c9ce50" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/32c9ce50d98f00e3485f9aed04b3d43fdb80ca45">32c9ce50</a> by akwizgran Moved the messaging protocol one step closer to BSP. This breaks backward compatibility for the wire protocol and messages stored in the database. The database schema version has been incremented. - - - - - Changes: ===================================== briar-android/AndroidManifest.xml ===================================== --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.briarproject" - android:versionCode="9" - android:versionName="0.9" > + android:versionCode="10" + android:versionName="0.10" > <uses-sdk android:minSdkVersion="7" ===================================== briar-api/src/org/briarproject/api/messaging/MessagingConstants.java ===================================== --- a/briar-api/src/org/briarproject/api/messaging/MessagingConstants.java +++ b/briar-api/src/org/briarproject/api/messaging/MessagingConstants.java @@ -1,18 +1,19 @@ package org.briarproject.api.messaging; -import static org.briarproject.api.transport.TransportConstants.MIN_STREAM_LENGTH; public interface MessagingConstants { - /** - * The maximum length of a serialised packet in bytes. To allow for future - * changes in the protocol, this is smaller than the minimum stream length - * minus the maximum encryption and authentication overhead. - */ - int MAX_PACKET_LENGTH = MIN_STREAM_LENGTH / 2; + /** The current version of the messaging protocol. */ + byte PROTOCOL_VERSION = 0; + + /** The length of the packet header in bytes. */ + int HEADER_LENGTH = 4; + + /** The maximum length of the packet payload in bytes. */ + int MAX_PAYLOAD_LENGTH = 32 * 1024; // 32 KiB /** The maximum number of public groups a user may subscribe to. */ - int MAX_SUBSCRIPTIONS = 3000; + int MAX_SUBSCRIPTIONS = 300; /** The maximum length of a group's name in UTF-8 bytes. */ int MAX_GROUP_NAME_LENGTH = 50; @@ -22,10 +23,10 @@ public interface MessagingConstants { /** * The maximum length of a message body in bytes. To allow for future - * changes in the protocol, this is smaller than the maximum packet length + * changes in the protocol, this is smaller than the maximum payload length * even when all the message's other fields have their maximum lengths. */ - int MAX_BODY_LENGTH = MAX_PACKET_LENGTH - 1024; + int MAX_BODY_LENGTH = MAX_PAYLOAD_LENGTH - 1024; /** The maximum length of a message's content type in UTF-8 bytes. */ int MAX_CONTENT_TYPE_LENGTH = 50; ===================================== briar-api/src/org/briarproject/api/messaging/PacketTypes.java ===================================== --- /dev/null +++ b/briar-api/src/org/briarproject/api/messaging/PacketTypes.java @@ -0,0 +1,16 @@ +package org.briarproject.api.messaging; + +/** Packet types for the messaging protocol. */ +public interface PacketTypes { + + byte ACK = 0; + byte MESSAGE = 1; + byte OFFER = 2; + byte REQUEST = 3; + byte RETENTION_ACK = 4; + byte RETENTION_UPDATE = 5; + byte SUBSCRIPTION_ACK = 6; + byte SUBSCRIPTION_UPDATE = 7; + byte TRANSPORT_ACK = 8; + byte TRANSPORT_UPDATE = 9; +} ===================================== briar-api/src/org/briarproject/api/messaging/Types.java ===================================== --- a/briar-api/src/org/briarproject/api/messaging/Types.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.briarproject.api.messaging; - -/** Struct identifiers for encoding and decoding protocol objects. */ -public interface Types { - - int AUTHOR = 0; - int GROUP = 1; - int ACK = 2; - int MESSAGE = 3; - int OFFER = 4; - int REQUEST = 5; - int RETENTION_ACK = 6; - int RETENTION_UPDATE = 7; - int SUBSCRIPTION_ACK = 8; - int SUBSCRIPTION_UPDATE = 9; - int TRANSPORT_ACK = 10; - int TRANSPORT_UPDATE = 11; -} ===================================== briar-api/src/org/briarproject/api/serial/ObjectReader.java ===================================== --- /dev/null +++ b/briar-api/src/org/briarproject/api/serial/ObjectReader.java @@ -0,0 +1,8 @@ +package org.briarproject.api.serial; + +import java.io.IOException; + +public interface ObjectReader<T> { + + T readObject(Reader r) throws IOException; +} ===================================== briar-api/src/org/briarproject/api/serial/Reader.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/Reader.java +++ b/briar-api/src/org/briarproject/api/serial/Reader.java @@ -10,6 +10,10 @@ public interface Reader { void addConsumer(Consumer c); void removeConsumer(Consumer c); + boolean hasNull() throws IOException; + void readNull() throws IOException; + void skipNull() throws IOException; + boolean hasBoolean() throws IOException; boolean readBoolean() throws IOException; void skipBoolean() throws IOException; @@ -24,11 +28,11 @@ public interface Reader { boolean hasString() throws IOException; String readString(int maxLength) throws IOException; - void skipString(int maxLength) throws IOException; + void skipString() throws IOException; boolean hasBytes() throws IOException; byte[] readBytes(int maxLength) throws IOException; - void skipBytes(int maxLength) throws IOException; + void skipBytes() throws IOException; boolean hasList() throws IOException; void readListStart() throws IOException; @@ -41,15 +45,4 @@ public interface Reader { boolean hasMapEnd() throws IOException; void readMapEnd() throws IOException; void skipMap() throws IOException; - - boolean hasStruct() throws IOException; - boolean hasStruct(int id) throws IOException; - void readStructStart(int id) throws IOException; - boolean hasStructEnd() throws IOException; - void readStructEnd() throws IOException; - void skipStruct() throws IOException; - - boolean hasNull() throws IOException; - void readNull() throws IOException; - void skipNull() throws IOException; } ===================================== briar-api/src/org/briarproject/api/serial/SerialComponent.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/SerialComponent.java +++ b/briar-api/src/org/briarproject/api/serial/SerialComponent.java @@ -6,9 +6,5 @@ public interface SerialComponent { int getSerialisedListEndLength(); - int getSerialisedStructStartLength(int id); - - int getSerialisedStructEndLength(); - int getSerialisedUniqueIdLength(); } ===================================== briar-api/src/org/briarproject/api/serial/StructReader.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/StructReader.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.briarproject.api.serial; - -import java.io.IOException; - -public interface StructReader<T> { - - T readStruct(Reader r) throws IOException; -} ===================================== briar-api/src/org/briarproject/api/serial/Writer.java ===================================== --- a/briar-api/src/org/briarproject/api/serial/Writer.java +++ b/briar-api/src/org/briarproject/api/serial/Writer.java @@ -12,6 +12,7 @@ public interface Writer { void addConsumer(Consumer c); void removeConsumer(Consumer c); + void writeNull() throws IOException; void writeBoolean(boolean b) throws IOException; void writeInteger(long l) throws IOException; void writeFloat(double d) throws IOException; @@ -25,9 +26,4 @@ public interface Writer { void writeMap(Map<?, ?> m) throws IOException; void writeMapStart() throws IOException; void writeMapEnd() throws IOException; - - void writeStructStart(int id) throws IOException; - void writeStructEnd() throws IOException; - - void writeNull() throws IOException; } ===================================== briar-api/src/org/briarproject/api/transport/TransportConstants.java ===================================== --- a/briar-api/src/org/briarproject/api/transport/TransportConstants.java +++ b/briar-api/src/org/briarproject/api/transport/TransportConstants.java @@ -26,7 +26,7 @@ public interface TransportConstants { * support. Streams may be shorter than this length, but all transport * plugins must support streams of at least this length. */ - int MIN_STREAM_LENGTH = 1024 * 1024; // 2^20, 1 MiB + int MIN_STREAM_LENGTH = 64 * 1024; // 64 KiB /** The maximum difference between two communicating devices' clocks. */ int MAX_CLOCK_DIFFERENCE = 60 * 60 * 1000; // 1 hour ===================================== briar-core/src/org/briarproject/db/JdbcDatabase.java ===================================== --- a/briar-core/src/org/briarproject/db/JdbcDatabase.java +++ b/briar-core/src/org/briarproject/db/JdbcDatabase.java @@ -64,8 +64,8 @@ import org.briarproject.api.transport.TemporarySecret; */ abstract class JdbcDatabase implements Database<Connection> { - private static final int SCHEMA_VERSION = 8; - private static final int MIN_SCHEMA_VERSION = 8; + private static final int SCHEMA_VERSION = 9; + private static final int MIN_SCHEMA_VERSION = 9; private static final String CREATE_SETTINGS = "CREATE TABLE settings" ===================================== briar-core/src/org/briarproject/messaging/AuthorFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/AuthorFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/AuthorFactoryImpl.java @@ -1,7 +1,5 @@ package org.briarproject.messaging; -import static org.briarproject.api.messaging.Types.AUTHOR; - import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -45,10 +43,10 @@ class AuthorFactoryImpl implements AuthorFactory { ByteArrayOutputStream out = new ByteArrayOutputStream(); Writer w = writerFactory.createWriter(out); try { - w.writeStructStart(AUTHOR); + w.writeListStart(); w.writeString(name); w.writeBytes(publicKey); - w.writeStructEnd(); + w.writeListEnd(); } catch(IOException e) { // Shouldn't happen with ByteArrayOutputStream throw new RuntimeException(); ===================================== briar-core/src/org/briarproject/messaging/AuthorReader.java ===================================== --- a/briar-core/src/org/briarproject/messaging/AuthorReader.java +++ b/briar-core/src/org/briarproject/messaging/AuthorReader.java @@ -2,7 +2,6 @@ package org.briarproject.messaging; import static org.briarproject.api.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.api.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; -import static org.briarproject.api.messaging.Types.AUTHOR; import java.io.IOException; @@ -13,9 +12,9 @@ import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.MessageDigest; import org.briarproject.api.serial.DigestingConsumer; import org.briarproject.api.serial.Reader; -import org.briarproject.api.serial.StructReader; +import org.briarproject.api.serial.ObjectReader; -class AuthorReader implements StructReader<Author> { +class AuthorReader implements ObjectReader<Author> { private final MessageDigest messageDigest; @@ -23,16 +22,16 @@ class AuthorReader implements StructReader<Author> { messageDigest = crypto.getMessageDigest(); } - public Author readStruct(Reader r) throws IOException { + public Author readObject(Reader r) throws IOException { // Set up the reader DigestingConsumer digesting = new DigestingConsumer(messageDigest); r.addConsumer(digesting); // Read and digest the data - r.readStructStart(AUTHOR); + r.readListStart(); String name = r.readString(MAX_AUTHOR_NAME_LENGTH); if(name.length() == 0) throw new FormatException(); byte[] publicKey = r.readBytes(MAX_PUBLIC_KEY_LENGTH); - r.readStructEnd(); + r.readListEnd(); // Reset the reader r.removeConsumer(digesting); // Build and return the author ===================================== briar-core/src/org/briarproject/messaging/DuplexOutgoingSession.java ===================================== --- a/briar-core/src/org/briarproject/messaging/DuplexOutgoingSession.java +++ b/briar-core/src/org/briarproject/messaging/DuplexOutgoingSession.java @@ -3,7 +3,7 @@ package org.briarproject.messaging; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH; +import static org.briarproject.api.messaging.MessagingConstants.MAX_PAYLOAD_LENGTH; import java.io.IOException; import java.util.Collection; @@ -260,7 +260,7 @@ class DuplexOutgoingSession implements MessagingSession, EventListener { if(interrupted) return; try { Collection<byte[]> b = db.generateRequestedBatch(contactId, - MAX_PACKET_LENGTH, maxLatency); + MAX_PAYLOAD_LENGTH, maxLatency); if(LOG.isLoggable(INFO)) LOG.info("Generated batch: " + (b != null)); if(b != null) writerTasks.add(new WriteBatch(b)); ===================================== briar-core/src/org/briarproject/messaging/GroupFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/GroupFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/GroupFactoryImpl.java @@ -1,7 +1,6 @@ package org.briarproject.messaging; import static org.briarproject.api.messaging.MessagingConstants.GROUP_SALT_LENGTH; -import static org.briarproject.api.messaging.Types.GROUP; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -37,10 +36,10 @@ class GroupFactoryImpl implements GroupFactory { ByteArrayOutputStream out = new ByteArrayOutputStream(); Writer w = writerFactory.createWriter(out); try { - w.writeStructStart(GROUP); + w.writeListStart(); w.writeString(name); w.writeBytes(salt); - w.writeStructEnd(); + w.writeListEnd(); } catch(IOException e) { // Shouldn't happen with ByteArrayOutputStream throw new RuntimeException(); ===================================== briar-core/src/org/briarproject/messaging/GroupReader.java ===================================== --- a/briar-core/src/org/briarproject/messaging/GroupReader.java +++ b/briar-core/src/org/briarproject/messaging/GroupReader.java @@ -2,7 +2,6 @@ package org.briarproject.messaging; import static org.briarproject.api.messaging.MessagingConstants.GROUP_SALT_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MAX_GROUP_NAME_LENGTH; -import static org.briarproject.api.messaging.Types.GROUP; import java.io.IOException; @@ -13,9 +12,9 @@ import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.GroupId; import org.briarproject.api.serial.DigestingConsumer; import org.briarproject.api.serial.Reader; -import org.briarproject.api.serial.StructReader; +import org.briarproject.api.serial.ObjectReader; -class GroupReader implements StructReader<Group> { +class GroupReader implements ObjectReader<Group> { private final MessageDigest messageDigest; @@ -23,16 +22,16 @@ class GroupReader implements StructReader<Group> { messageDigest = crypto.getMessageDigest(); } - public Group readStruct(Reader r) throws IOException { + public Group readObject(Reader r) throws IOException { DigestingConsumer digesting = new DigestingConsumer(messageDigest); // Read and digest the data r.addConsumer(digesting); - r.readStructStart(GROUP); + r.readListStart(); String name = r.readString(MAX_GROUP_NAME_LENGTH); if(name.length() == 0) throw new FormatException(); byte[] salt = r.readBytes(GROUP_SALT_LENGTH); if(salt.length != GROUP_SALT_LENGTH) throw new FormatException(); - r.readStructEnd(); + r.readListEnd(); r.removeConsumer(digesting); // Build and return the group GroupId id = new GroupId(messageDigest.digest()); ===================================== briar-core/src/org/briarproject/messaging/MessageFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/MessageFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/MessageFactoryImpl.java @@ -3,11 +3,8 @@ package org.briarproject.messaging; import static org.briarproject.api.AuthorConstants.MAX_SIGNATURE_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MAX_BODY_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_LENGTH; -import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH; +import static org.briarproject.api.messaging.MessagingConstants.MAX_PAYLOAD_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MESSAGE_SALT_LENGTH; -import static org.briarproject.api.messaging.Types.AUTHOR; -import static org.briarproject.api.messaging.Types.GROUP; -import static org.briarproject.api.messaging.Types.MESSAGE; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -77,7 +74,7 @@ class MessageFactoryImpl implements MessageFactory { ByteArrayOutputStream out = new ByteArrayOutputStream(); Writer w = writerFactory.createWriter(out); // Initialise the consumers - CountingConsumer counting = new CountingConsumer(MAX_PACKET_LENGTH); + CountingConsumer counting = new CountingConsumer(MAX_PAYLOAD_LENGTH); w.addConsumer(counting); Consumer digestingConsumer = new DigestingConsumer(messageDigest); w.addConsumer(digestingConsumer); @@ -88,7 +85,7 @@ class MessageFactoryImpl implements MessageFactory { w.addConsumer(signingConsumer); } // Write the message - w.writeStructStart(MESSAGE); + w.writeListStart(); if(parent == null) w.writeNull(); else w.writeBytes(parent.getBytes()); writeGroup(w, group); @@ -111,7 +108,7 @@ class MessageFactoryImpl implements MessageFactory { throw new IllegalArgumentException(); w.writeBytes(sig); } - w.writeStructEnd(); + w.writeListEnd(); // Hash the message, including the signature, to get the message ID w.removeConsumer(digestingConsumer); MessageId id = new MessageId(messageDigest.digest()); @@ -120,16 +117,16 @@ class MessageFactoryImpl implements MessageFactory { } private void writeGroup(Writer w, Group g) throws IOException { - w.writeStructStart(GROUP); + w.writeListStart(); w.writeString(g.getName()); w.writeBytes(g.getSalt()); - w.writeStructEnd(); + w.writeListEnd(); } private void writeAuthor(Writer w, Author a) throws IOException { - w.writeStructStart(AUTHOR); + w.writeListStart(); w.writeString(a.getName()); w.writeBytes(a.getPublicKey()); - w.writeStructEnd(); + w.writeListEnd(); } } ===================================== briar-core/src/org/briarproject/messaging/MessageReader.java ===================================== --- a/briar-core/src/org/briarproject/messaging/MessageReader.java +++ b/briar-core/src/org/briarproject/messaging/MessageReader.java @@ -3,9 +3,8 @@ package org.briarproject.messaging; import static org.briarproject.api.AuthorConstants.MAX_SIGNATURE_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MAX_BODY_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_LENGTH; -import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH; +import static org.briarproject.api.messaging.MessagingConstants.MAX_PAYLOAD_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MESSAGE_SALT_LENGTH; -import static org.briarproject.api.messaging.Types.MESSAGE; import java.io.IOException; @@ -17,27 +16,27 @@ import org.briarproject.api.messaging.MessageId; import org.briarproject.api.messaging.UnverifiedMessage; import org.briarproject.api.serial.CopyingConsumer; import org.briarproject.api.serial.CountingConsumer; +import org.briarproject.api.serial.ObjectReader; import org.briarproject.api.serial.Reader; -import org.briarproject.api.serial.StructReader; -class MessageReader implements StructReader<UnverifiedMessage> { +class MessageReader implements ObjectReader<UnverifiedMessage> { - private final StructReader<Group> groupReader; - private final StructReader<Author> authorReader; + private final ObjectReader<Group> groupReader; + private final ObjectReader<Author> authorReader; - MessageReader(StructReader<Group> groupReader, - StructReader<Author> authorReader) { + MessageReader(ObjectReader<Group> groupReader, + ObjectReader<Author> authorReader) { this.groupReader = groupReader; this.authorReader = authorReader; } - public UnverifiedMessage readStruct(Reader r) throws IOException { + public UnverifiedMessage readObject(Reader r) throws IOException { CopyingConsumer copying = new CopyingConsumer(); - CountingConsumer counting = new CountingConsumer(MAX_PACKET_LENGTH); + CountingConsumer counting = new CountingConsumer(MAX_PAYLOAD_LENGTH); r.addConsumer(copying); r.addConsumer(counting); - // Read the start of the struct - r.readStructStart(MESSAGE); + // Read the start of the message + r.readListStart(); // Read the parent's message ID, if there is one MessageId parent = null; if(r.hasNull()) { @@ -48,11 +47,11 @@ class MessageReader implements StructReader<UnverifiedMessage> { parent = new MessageId(b); } // Read the group - Group group = groupReader.readStruct(r); + Group group = groupReader.readObject(r); // Read the author, if there is one Author author = null; if(r.hasNull()) r.readNull(); - else author = authorReader.readStruct(r); + else author = authorReader.readObject(r); // Read the content type String contentType = r.readString(MAX_CONTENT_TYPE_LENGTH); // Read the timestamp @@ -71,11 +70,12 @@ class MessageReader implements StructReader<UnverifiedMessage> { byte[] signature = null; if(author == null) r.readNull(); else signature = r.readBytes(MAX_SIGNATURE_LENGTH); - // Read the end of the struct - r.readStructEnd(); - // The signature will be verified later + // Read the end of the message + r.readListEnd(); + // Reset the reader r.removeConsumer(counting); r.removeConsumer(copying); + // Build and return the unverified message byte[] raw = copying.getCopy(); return new UnverifiedMessage(parent, group, author, contentType, timestamp, raw, signature, bodyStart, body.length, ===================================== briar-core/src/org/briarproject/messaging/MessagingModule.java ===================================== --- a/briar-core/src/org/briarproject/messaging/MessagingModule.java +++ b/briar-core/src/org/briarproject/messaging/MessagingModule.java @@ -14,7 +14,7 @@ import org.briarproject.api.messaging.PacketReaderFactory; import org.briarproject.api.messaging.PacketWriterFactory; import org.briarproject.api.messaging.SubscriptionUpdate; import org.briarproject.api.messaging.UnverifiedMessage; -import org.briarproject.api.serial.StructReader; +import org.briarproject.api.serial.ObjectReader; import com.google.inject.AbstractModule; import com.google.inject.Provides; @@ -34,25 +34,25 @@ public class MessagingModule extends AbstractModule { } @Provides - StructReader<Author> getAuthorReader(CryptoComponent crypto) { + ObjectReader<Author> getAuthorReader(CryptoComponent crypto) { return new AuthorReader(crypto); } @Provides - StructReader<Group> getGroupReader(CryptoComponent crypto) { + ObjectReader<Group> getGroupReader(CryptoComponent crypto) { return new GroupReader(crypto); } @Provides - StructReader<UnverifiedMessage> getMessageReader( - StructReader<Group> groupReader, - StructReader<Author> authorReader) { + ObjectReader<UnverifiedMessage> getMessageReader( + ObjectReader<Group> groupReader, + ObjectReader<Author> authorReader) { return new MessageReader(groupReader, authorReader); } @Provides - StructReader<SubscriptionUpdate> getSubscriptionUpdateReader( - StructReader<Group> groupReader) { + ObjectReader<SubscriptionUpdate> getSubscriptionUpdateReader( + ObjectReader<Group> groupReader) { return new SubscriptionUpdateReader(groupReader); } } ===================================== briar-core/src/org/briarproject/messaging/PacketReaderFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/PacketReaderFactoryImpl.java +++ b/briar-core/src/org/briarproject/messaging/PacketReaderFactoryImpl.java @@ -9,18 +9,18 @@ import org.briarproject.api.messaging.PacketReaderFactory; import org.briarproject.api.messaging.SubscriptionUpdate; import org.briarproject.api.messaging.UnverifiedMessage; import org.briarproject.api.serial.ReaderFactory; -import org.briarproject.api.serial.StructReader; +import org.briarproject.api.serial.ObjectReader; class PacketReaderFactoryImpl implements PacketReaderFactory { private final ReaderFactory readerFactory; - private final StructReader<UnverifiedMessage> messageReader; - private final StructReader<SubscriptionUpdate> subscriptionUpdateReader; + private final ObjectReader<UnverifiedMessage> messageReader; + private final ObjectReader<SubscriptionUpdate> subscriptionUpdateReader; @Inject PacketReaderFactoryImpl(ReaderFactory readerFactory, - StructReader<UnverifiedMessage> messageReader, - StructReader<SubscriptionUpdate> subscriptionUpdateReader) { + ObjectReader<UnverifiedMessage> messageReader, + ObjectReader<SubscriptionUpdate> subscriptionUpdateReader) { this.readerFactory = readerFactory; this.messageReader = messageReader; this.subscriptionUpdateReader = subscriptionUpdateReader; ===================================== briar-core/src/org/briarproject/messaging/PacketReaderImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/PacketReaderImpl.java +++ b/briar-core/src/org/briarproject/messaging/PacketReaderImpl.java @@ -3,18 +3,21 @@ package org.briarproject.messaging; import static org.briarproject.api.TransportPropertyConstants.MAX_PROPERTIES_PER_TRANSPORT; import static org.briarproject.api.TransportPropertyConstants.MAX_PROPERTY_LENGTH; import static org.briarproject.api.TransportPropertyConstants.MAX_TRANSPORT_ID_LENGTH; -import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH; -import static org.briarproject.api.messaging.Types.ACK; -import static org.briarproject.api.messaging.Types.MESSAGE; -import static org.briarproject.api.messaging.Types.OFFER; -import static org.briarproject.api.messaging.Types.REQUEST; -import static org.briarproject.api.messaging.Types.RETENTION_ACK; -import static org.briarproject.api.messaging.Types.RETENTION_UPDATE; -import static org.briarproject.api.messaging.Types.SUBSCRIPTION_ACK; -import static org.briarproject.api.messaging.Types.SUBSCRIPTION_UPDATE; -import static org.briarproject.api.messaging.Types.TRANSPORT_ACK; -import static org.briarproject.api.messaging.Types.TRANSPORT_UPDATE; +import static org.briarproject.api.messaging.MessagingConstants.HEADER_LENGTH; +import static org.briarproject.api.messaging.MessagingConstants.MAX_PAYLOAD_LENGTH; +import static org.briarproject.api.messaging.MessagingConstants.PROTOCOL_VERSION; +import static org.briarproject.api.messaging.PacketTypes.ACK; +import static org.briarproject.api.messaging.PacketTypes.MESSAGE; +import static org.briarproject.api.messaging.PacketTypes.OFFER; +import static org.briarproject.api.messaging.PacketTypes.REQUEST; +import static org.briarproject.api.messaging.PacketTypes.RETENTION_ACK; +import static org.briarproject.api.messaging.PacketTypes.RETENTION_UPDATE; +import static org.briarproject.api.messaging.PacketTypes.SUBSCRIPTION_ACK; +import static org.briarproject.api.messaging.PacketTypes.SUBSCRIPTION_UPDATE; +import static org.briarproject.api.messaging.PacketTypes.TRANSPORT_ACK; +import static org.briarproject.api.messaging.PacketTypes.TRANSPORT_UPDATE; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -39,42 +42,82 @@ import org.briarproject.api.messaging.SubscriptionUpdate; import org.briarproject.api.messaging.TransportAck; import org.briarproject.api.messaging.TransportUpdate; import org.briarproject.api.messaging.UnverifiedMessage; -import org.briarproject.api.serial.Consumer; -import org.briarproject.api.serial.CountingConsumer; import org.briarproject.api.serial.Reader; import org.briarproject.api.serial.ReaderFactory; -import org.briarproject.api.serial.StructReader; +import org.briarproject.api.serial.ObjectReader; +import org.briarproject.util.ByteUtils; // This class is not thread-safe class PacketReaderImpl implements PacketReader { - private final StructReader<UnverifiedMessage> messageReader; - private final StructReader<SubscriptionUpdate> subscriptionUpdateReader; - private final Reader r; + private enum State { BUFFER_EMPTY, BUFFER_FULL, EOF }; + + private final ReaderFactory readerFactory; + private final ObjectReader<UnverifiedMessage> messageReader; + private final ObjectReader<SubscriptionUpdate> subscriptionUpdateReader; + private final InputStream in; + private final byte[] header, payload; + + private State state = State.BUFFER_EMPTY; + private int payloadLength = 0; PacketReaderImpl(ReaderFactory readerFactory, - StructReader<UnverifiedMessage> messageReader, - StructReader<SubscriptionUpdate> subscriptionUpdateReader, + ObjectReader<UnverifiedMessage> messageReader, + ObjectReader<SubscriptionUpdate> subscriptionUpdateReader, InputStream in) { + this.readerFactory = readerFactory; this.messageReader = messageReader; this.subscriptionUpdateReader = subscriptionUpdateReader; - r = readerFactory.createReader(in); + this.in = in; + header = new byte[HEADER_LENGTH]; + payload = new byte[MAX_PAYLOAD_LENGTH]; + } + + private void readPacket() throws IOException { + assert state == State.BUFFER_EMPTY; + // Read the header + int offset = 0; + while(offset < HEADER_LENGTH) { + int read = in.read(header, offset, HEADER_LENGTH - offset); + if(read == -1) { + if(offset > 0) throw new FormatException(); + state = State.EOF; + return; + } + offset += read; + } + // Check the protocol version + if(header[0] != PROTOCOL_VERSION) throw new FormatException(); + // Read the payload length + payloadLength = ByteUtils.readUint16(header, 2); + if(payloadLength > MAX_PAYLOAD_LENGTH) throw new FormatException(); + // Read the payload + offset = 0; + while(offset < payloadLength) { + int read = in.read(payload, offset, payloadLength - offset); + if(read == -1) throw new FormatException(); + offset += read; + } + state = State.BUFFER_FULL; } public boolean eof() throws IOException { - return r.eof(); + if(state == State.BUFFER_EMPTY) readPacket(); + assert state != State.BUFFER_EMPTY; + return state == State.EOF; } public boolean hasAck() throws IOException { - return r.hasStruct(ACK); + return !eof() && header[1] == ACK; } public Ack readAck() throws IOException { + if(!hasAck()) throw new FormatException(); // Set up the reader - Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH); - r.addConsumer(counting); - // Read the start of the struct - r.readStructStart(ACK); + InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength); + Reader r = readerFactory.createReader(bais); + // Read the start of the payload + r.readListStart(); // Read the message IDs List<MessageId> acked = new ArrayList<MessageId>(); r.readListStart(); @@ -86,32 +129,41 @@ class PacketReaderImpl implements PacketReader { } if(acked.isEmpty()) throw new FormatException(); r.readListEnd(); - // Read the end of the struct - r.readStructEnd(); - // Reset the reader - r.removeConsumer(counting); + // Read the end of the payload + r.readListEnd(); + if(!r.eof()) throw new FormatException(); + state = State.BUFFER_EMPTY; // Build and return the ack return new Ack(Collections.unmodifiableList(acked)); } public boolean hasMessage() throws IOException { - return r.hasStruct(MESSAGE); + return !eof() && header[1] == MESSAGE; } public UnverifiedMessage readMessage() throws IOException { - return messageReader.readStruct(r); + if(!hasMessage()) throw new FormatException(); + // Set up the reader + InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength); + Reader r = readerFactory.createReader(bais); + // Read and build the message + UnverifiedMessage m = messageReader.readObject(r); + if(!r.eof()) throw new FormatException(); + state = State.BUFFER_EMPTY; + return m; } public boolean hasOffer() throws IOException { - return r.hasStruct(OFFER); + return !eof() && header[1] == OFFER; } public Offer readOffer() throws IOException { + if(!hasOffer()) throw new FormatException(); // Set up the reader - Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH); - r.addConsumer(counting); - // Read the start of the struct - r.readStructStart(OFFER); + InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength); + Reader r = readerFactory.createReader(bais); + // Read the start of the payload + r.readListStart(); // Read the message IDs List<MessageId> offered = new ArrayList<MessageId>(); r.readListStart(); @@ -123,27 +175,28 @@ class PacketReaderImpl implements PacketReader { } if(offered.isEmpty()) throw new FormatException(); r.readListEnd(); - // Read the end of the struct - r.readStructEnd(); - // Reset the reader - r.removeConsumer(counting); + // Read the end of the payload + r.readListEnd(); + if(!r.eof()) throw new FormatException(); + state = State.BUFFER_EMPTY; // Build and return the offer return new Offer(Collections.unmodifiableList(offered)); } public boolean hasRequest() throws IOException { - return r.hasStruct(REQUEST); + return !eof() && header[1] == REQUEST; } public Request readRequest() throws IOException { + if(!hasRequest()) throw new FormatException(); // Set up the reader - Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH); - r.addConsumer(counting); - // Read the start of the struct - r.readStructStart(REQUEST); + InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength); + Reader r = readerFactory.createReader(bais); + // Read the start of the payload + r.readListStart(); // Read the message IDs - List<MessageId> requested = new ArrayList<MessageId>(); r.readListStart(); + List<MessageId> requested = new ArrayList<MessageId>(); while(!r.hasListEnd()) { byte[] b = r.readBytes(UniqueId.LENGTH); if(b.length != UniqueId.LENGTH) @@ -152,85 +205,134 @@ class PacketReaderImpl implements PacketReader { } if(requested.isEmpty()) throw new FormatException(); r.readListEnd(); - // Read the end of the struct - r.readStructEnd(); - // Reset the reader - r.removeConsumer(counting); + // Read the end of the payload + r.readListEnd(); + if(!r.eof()) throw new FormatException(); + state = State.BUFFER_EMPTY; // Build and return the request return new Request(Collections.unmodifiableList(requested)); } public boolean hasRetentionAck() throws IOException { - return r.hasStruct(RETENTION_ACK); + return !eof() && header[1] == RETENTION_ACK; } public RetentionAck readRetentionAck() throws IOException { - r.readStructStart(RETENTION_ACK); + if(!hasRetentionAck()) throw new FormatException(); + // Set up the reader + InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength); + Reader r = readerFactory.createReader(bais); + // Read the start of the payload + r.readListStart(); + // Read the version long version = r.readInteger(); if(version < 0) throw new FormatException(); - r.readStructEnd(); + // Read the end of the payload + r.readListEnd(); + if(!r.eof()) throw new FormatException(); + state = State.BUFFER_EMPTY; + // Build and return the retention ack return new RetentionAck(version); } public boolean hasRetentionUpdate() throws IOException { - return r.hasStruct(RETENTION_UPDATE); + return !eof() && header[1] == RETENTION_UPDATE; } public RetentionUpdate readRetentionUpdate() throws IOException { - r.readStructStart(RETENTION_UPDATE); + if(!hasRetentionUpdate()) throw new FormatException(); + // Set up the reader + InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength); + Reader r = readerFactory.createReader(bais); + // Read the start of the payload + r.readListStart(); + // Read the retention time and version long retention = r.readInteger(); if(retention < 0) throw new FormatException(); long version = r.readInteger(); if(version < 0) throw new FormatException(); - r.readStructEnd(); + // Read the end of the payload + r.readListEnd(); + if(!r.eof()) throw new FormatException(); + state = State.BUFFER_EMPTY; + // Build and return the retention update return new RetentionUpdate(retention, version); } public boolean hasSubscriptionAck() throws IOException { - return r.hasStruct(SUBSCRIPTION_ACK); + return !eof() && header[1] == SUBSCRIPTION_ACK; } public SubscriptionAck readSubscriptionAck() throws IOException { - r.readStructStart(SUBSCRIPTION_ACK); + if(!hasSubscriptionAck()) throw new FormatException(); + // Set up the reader + InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength); + Reader r = readerFactory.createReader(bais); + // Read the start of the payload + r.readListStart(); + // Read the version long version = r.readInteger(); if(version < 0) throw new FormatException(); - r.readStructEnd(); + // Read the end of the payload + r.readListEnd(); + if(!r.eof()) throw new FormatException(); + state = State.BUFFER_EMPTY; + // Build and return the subscription ack return new SubscriptionAck(version); } public boolean hasSubscriptionUpdate() throws IOException { - return r.hasStruct(SUBSCRIPTION_UPDATE); + return !eof() && header[1] == SUBSCRIPTION_UPDATE; } public SubscriptionUpdate readSubscriptionUpdate() throws IOException { - return subscriptionUpdateReader.readStruct(r); + if(!hasSubscriptionUpdate()) throw new FormatException(); + // Set up the reader + InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength); + Reader r = readerFactory.createReader(bais); + // Read and build the subscription update + SubscriptionUpdate u = subscriptionUpdateReader.readObject(r); + if(!r.eof()) throw new FormatException(); + state = State.BUFFER_EMPTY; + return u; } public boolean hasTransportAck() throws IOException { - return r.hasStruct(TRANSPORT_ACK); + return !eof() && header[1] == TRANSPORT_ACK; } public TransportAck readTransportAck() throws IOException { - r.readStructStart(TRANSPORT_ACK); + if(!hasTransportAck()) throw new FormatException(); + // Set up the reader + InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength); + Reader r = readerFactory.createReader(bais); + // Read the start of the payload + r.readListStart(); + // Read the transport ID and version String idString = r.readString(MAX_TRANSPORT_ID_LENGTH); if(idString.length() == 0) throw new FormatException(); TransportId id = new TransportId(idString); long version = r.readInteger(); if(version < 0) throw new FormatException(); - r.readStructEnd(); + // Read the end of the payload + r.readListEnd(); + if(!r.eof()) throw new FormatException(); + state = State.BUFFER_EMPTY; + // Build and return the transport ack return new TransportAck(id, version); } public boolean hasTransportUpdate() throws IOException { - return r.hasStruct(TRANSPORT_UPDATE); + return !eof() && header[1] == TRANSPORT_UPDATE; } public TransportUpdate readTransportUpdate() throws IOException { + if(!hasTransportUpdate()) throw new FormatException(); // Set up the reader - Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH); - r.addConsumer(counting); - // Read the start of the struct - r.readStructStart(TRANSPORT_UPDATE); + InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength); + Reader r = readerFactory.createReader(bais); + // Read the start of the payload + r.readListStart(); // Read the transport ID String idString = r.readString(MAX_TRANSPORT_ID_LENGTH); if(idString.length() == 0) throw new FormatException(); @@ -249,10 +351,10 @@ class PacketReaderImpl implements PacketReader { // Read the version number long version = r.readInteger(); if(version < 0) throw new FormatException(); - // Read the end of the struct - r.readStructEnd(); - // Reset the reader - r.removeConsumer(counting); + // Read the end of the payload + r.readListEnd(); + if(!r.eof()) throw new FormatException(); + state = State.BUFFER_EMPTY; // Build and return the transport update return new TransportUpdate(id, new TransportProperties(p), version); } ===================================== briar-core/src/org/briarproject/messaging/PacketWriterImpl.java ===================================== --- a/briar-core/src/org/briarproject/messaging/PacketWriterImpl.java +++ b/briar-core/src/org/briarproject/messaging/PacketWriterImpl.java @@ -1,17 +1,19 @@ package org.briarproject.messaging; -import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH; -import static org.briarproject.api.messaging.Types.ACK; -import static org.briarproject.api.messaging.Types.GROUP; -import static org.briarproject.api.messaging.Types.OFFER; -import static org.briarproject.api.messaging.Types.REQUEST; -import static org.briarproject.api.messaging.Types.RETENTION_ACK; -import static org.briarproject.api.messaging.Types.RETENTION_UPDATE; -import static org.briarproject.api.messaging.Types.SUBSCRIPTION_ACK; -import static org.briarproject.api.messaging.Types.SUBSCRIPTION_UPDATE; -import static org.briarproject.api.messaging.Types.TRANSPORT_ACK; -import static org.briarproject.api.messaging.Types.TRANSPORT_UPDATE; - +import static org.briarproject.api.messaging.MessagingConstants.HEADER_LENGTH; +import static org.briarproject.api.messaging.MessagingConstants.MAX_PAYLOAD_LENGTH; +import static org.briarproject.api.messaging.MessagingConstants.PROTOCOL_VERSION; +import static org.briarproject.api.messaging.PacketTypes.ACK; +import static org.briarproject.api.messaging.PacketTypes.OFFER; +import static org.briarproject.api.messaging.PacketTypes.REQUEST; +import static org.briarproject.api.messaging.PacketTypes.RETENTION_ACK; +import static org.briarproject.api.messaging.PacketTypes.RETENTION_UPDATE; +import static org.briarproject.api.messaging.PacketTypes.SUBSCRIPTION_ACK; +import static org.briarproject.api.messaging.PacketTypes.SUBSCRIPTION_UPDATE; +import static org.briarproject.api.messaging.PacketTypes.TRANSPORT_ACK; +import static org.briarproject.api.messaging.PacketTypes.TRANSPORT_UPDATE; + +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -19,6 +21,7 @@ import org.briarproject.api.messaging.Ack; import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.MessageId; import org.briarproject.api.messaging.Offer; +import org.briarproject.api.messaging.PacketTypes; import org.briarproject.api.messaging.PacketWriter; import org.briarproject.api.messaging.Request; import org.briarproject.api.messaging.RetentionAck; @@ -30,118 +33,161 @@ import org.briarproject.api.messaging.TransportUpdate; import org.briarproject.api.serial.SerialComponent; import org.briarproject.api.serial.Writer; import org.briarproject.api.serial.WriterFactory; +import org.briarproject.util.ByteUtils; // This class is not thread-safe class PacketWriterImpl implements PacketWriter { private final SerialComponent serial; + private final WriterFactory writerFactory; private final OutputStream out; - private final Writer w; + private final byte[] header; + private final ByteArrayOutputStream payload; PacketWriterImpl(SerialComponent serial, WriterFactory writerFactory, OutputStream out) { this.serial = serial; + this.writerFactory = writerFactory; this.out = out; - w = writerFactory.createWriter(out); + header = new byte[HEADER_LENGTH]; + header[0] = PROTOCOL_VERSION; + payload = new ByteArrayOutputStream(MAX_PAYLOAD_LENGTH); } public int getMaxMessagesForAck(long capacity) { - return getMaxMessagesForPacket(capacity, ACK); + return getMaxMessagesForPacket(capacity); } public int getMaxMessagesForRequest(long capacity) { - return getMaxMessagesForPacket(capacity, REQUEST); + return getMaxMessagesForPacket(capacity); } public int getMaxMessagesForOffer(long capacity) { - return getMaxMessagesForPacket(capacity, OFFER); + return getMaxMessagesForPacket(capacity); } - private int getMaxMessagesForPacket(long capacity, int structId) { - int packet = (int) Math.min(capacity, MAX_PACKET_LENGTH); - int overhead = serial.getSerialisedStructStartLength(structId) - + serial.getSerialisedListStartLength() - + serial.getSerialisedListEndLength() - + serial.getSerialisedStructEndLength(); + private int getMaxMessagesForPacket(long capacity) { + int payload = (int) Math.min(capacity - HEADER_LENGTH, + MAX_PAYLOAD_LENGTH); + int overhead = serial.getSerialisedListStartLength() * 2 + + serial.getSerialisedListEndLength() * 2; int idLength = serial.getSerialisedUniqueIdLength(); - return (packet - overhead) / idLength; + return (payload - overhead) / idLength; + } + + private void writePacket(byte packetType) throws IOException { + header[1] = packetType; + ByteUtils.writeUint16(payload.size(), header, 2); + out.write(header); + payload.writeTo(out); + payload.reset(); } public void writeAck(Ack a) throws IOException { - w.writeStructStart(ACK); + assert payload.size() == 0; + Writer w = writerFactory.createWriter(payload); + w.writeListStart(); w.writeListStart(); for(MessageId m : a.getMessageIds()) w.writeBytes(m.getBytes()); w.writeListEnd(); - w.writeStructEnd(); + w.writeListEnd(); + writePacket(ACK); } public void writeMessage(byte[] raw) throws IOException { + header[1] = PacketTypes.MESSAGE; + ByteUtils.writeUint16(raw.length, header, 2); + out.write(header); out.write(raw); } public void writeOffer(Offer o) throws IOException { - w.writeStructStart(OFFER); + assert payload.size() == 0; + Writer w = writerFactory.createWriter(payload); + w.writeListStart(); w.writeListStart(); for(MessageId m : o.getMessageIds()) w.writeBytes(m.getBytes()); w.writeListEnd(); - w.writeStructEnd(); + w.writeListEnd(); + writePacket(OFFER); } public void writeRequest(Request r) throws IOException { - w.writeStructStart(REQUEST); + assert payload.size() == 0; + Writer w = writerFactory.createWriter(payload); + w.writeListStart(); w.writeListStart(); for(MessageId m : r.getMessageIds()) w.writeBytes(m.getBytes()); w.writeListEnd(); - w.writeStructEnd(); + w.writeListEnd(); + writePacket(REQUEST); } public void writeRetentionAck(RetentionAck a) throws IOException { - w.writeStructStart(RETENTION_ACK); + assert payload.size() == 0; + Writer w = writerFactory.createWriter(payload); + w.writeListStart(); w.writeInteger(a.getVersion()); - w.writeStructEnd(); + w.writeListEnd(); + writePacket(RETENTION_ACK); } public void writeRetentionUpdate(RetentionUpdate u) throws IOException { - w.writeStructStart(RETENTION_UPDATE); + assert payload.size() == 0; + Writer w = writerFactory.createWriter(payload); + w.writeListStart(); w.writeInteger(u.getRetentionTime()); w.writeInteger(u.getVersion()); - w.writeStructEnd(); + w.writeListEnd(); + writePacket(RETENTION_UPDATE); } public void writeSubscriptionAck(SubscriptionAck a) throws IOException { - w.writeStructStart(SUBSCRIPTION_ACK); + assert payload.size() == 0; + Writer w = writerFactory.createWriter(payload); + w.writeListStart(); w.writeInteger(a.getVersion()); - w.writeStructEnd(); + w.writeListEnd(); + writePacket(SUBSCRIPTION_ACK); } public void writeSubscriptionUpdate(SubscriptionUpdate u) throws IOException { - w.writeStructStart(SUBSCRIPTION_UPDATE); + assert payload.size() == 0; + Writer w = writerFactory.createWriter(payload); + w.writeListStart(); w.writeListStart(); for(Group g : u.getGroups()) { - w.writeStructStart(GROUP); + w.writeListStart(); w.writeString(g.getName()); w.writeBytes(g.getSalt()); - w.writeStructEnd(); + w.writeListEnd(); } w.writeListEnd(); w.writeInteger(u.getVersion()); - w.writeStructEnd(); + w.writeListEnd(); + writePacket(SUBSCRIPTION_UPDATE); } public void writeTransportAck(TransportAck a) throws IOException { - w.writeStructStart(TRANSPORT_ACK); + assert payload.size() == 0; + Writer w = writerFactory.createWriter(payload); + w.writeListStart(); w.writeString(a.getId().getString()); w.writeInteger(a.getVersion()); - w.writeStructEnd(); + w.writeListEnd(); + writePacket(TRANSPORT_ACK); } public void writeTransportUpdate(TransportUpdate u) throws IOException { - w.writeStructStart(TRANSPORT_UPDATE); + assert payload.size() == 0; + Writer w = writerFactory.createWriter(payload); + w.writeListStart(); w.writeString(u.getId().getString()); w.writeMap(u.getProperties()); w.writeInteger(u.getVersion()); - w.writeStructEnd(); + w.writeListEnd(); + writePacket(TRANSPORT_UPDATE); } public void flush() throws IOException { ===================================== briar-core/src/org/briarproject/messaging/SimplexOutgoingSession.java ===================================== --- a/briar-core/src/org/briarproject/messaging/SimplexOutgoingSession.java +++ b/briar-core/src/org/briarproject/messaging/SimplexOutgoingSession.java @@ -2,7 +2,7 @@ package org.briarproject.messaging; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH; +import static org.briarproject.api.messaging.MessagingConstants.MAX_PAYLOAD_LENGTH; import java.io.IOException; import java.util.Collection; @@ -167,7 +167,7 @@ class SimplexOutgoingSession implements MessagingSession, EventListener { if(interrupted) return; try { Collection<byte[]> b = db.generateBatch(contactId, - MAX_PACKET_LENGTH, maxLatency); + MAX_PAYLOAD_LENGTH, maxLatency); if(LOG.isLoggable(INFO)) LOG.info("Generated batch: " + (b != null)); if(b == null) decrementOutstandingQueries(); ===================================== briar-core/src/org/briarproject/messaging/SubscriptionUpdateReader.java ===================================== --- a/briar-core/src/org/briarproject/messaging/SubscriptionUpdateReader.java +++ b/briar-core/src/org/briarproject/messaging/SubscriptionUpdateReader.java @@ -1,8 +1,7 @@ package org.briarproject.messaging; -import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH; +import static org.briarproject.api.messaging.MessagingConstants.MAX_PAYLOAD_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MAX_SUBSCRIPTIONS; -import static org.briarproject.api.messaging.Types.SUBSCRIPTION_UPDATE; import java.io.IOException; import java.util.ArrayList; @@ -17,29 +16,29 @@ import org.briarproject.api.messaging.GroupId; import org.briarproject.api.messaging.SubscriptionUpdate; import org.briarproject.api.serial.Consumer; import org.briarproject.api.serial.CountingConsumer; +import org.briarproject.api.serial.ObjectReader; import org.briarproject.api.serial.Reader; -import org.briarproject.api.serial.StructReader; -class SubscriptionUpdateReader implements StructReader<SubscriptionUpdate> { +class SubscriptionUpdateReader implements ObjectReader<SubscriptionUpdate> { - private final StructReader<Group> groupReader; + private final ObjectReader<Group> groupReader; - SubscriptionUpdateReader(StructReader<Group> groupReader) { + SubscriptionUpdateReader(ObjectReader<Group> groupReader) { this.groupReader = groupReader; } - public SubscriptionUpdate readStruct(Reader r) throws IOException { + public SubscriptionUpdate readObject(Reader r) throws IOException { // Set up the reader - Consumer counting = new CountingConsumer(MAX_PACKET_LENGTH); + Consumer counting = new CountingConsumer(MAX_PAYLOAD_LENGTH); r.addConsumer(counting); - // Read the start of the struct - r.readStructStart(SUBSCRIPTION_UPDATE); + // Read the start of the update + r.readListStart(); // Read the subscriptions, rejecting duplicates List<Group> groups = new ArrayList<Group>(); Set<GroupId> ids = new HashSet<GroupId>(); r.readListStart(); for(int i = 0; i < MAX_SUBSCRIPTIONS && !r.hasListEnd(); i++) { - Group g = groupReader.readStruct(r); + Group g = groupReader.readObject(r); if(!ids.add(g.getId())) throw new FormatException(); // Duplicate groups.add(g); } @@ -47,8 +46,8 @@ class SubscriptionUpdateReader implements StructReader<SubscriptionUpdate> { // Read the version number long version = r.readInteger(); if(version < 0) throw new FormatException(); - // Read the end of the struct - r.readStructEnd(); + // Read the end of the update + r.readListEnd(); // Reset the reader r.removeConsumer(counting); // Build and return the subscription update ===================================== briar-core/src/org/briarproject/serial/ObjectTypes.java ===================================== --- /dev/null +++ b/briar-core/src/org/briarproject/serial/ObjectTypes.java @@ -0,0 +1,21 @@ +package org.briarproject.serial; + +interface ObjectTypes { + + byte NULL = 0x00; + byte BOOLEAN = 0x11; + byte INT_8 = 0x21; + byte INT_16 = 0x22; + byte INT_32 = 0x24; + byte INT_64 = 0x28; + byte FLOAT_64 = 0x38; + byte STRING_8 = 0x41; + byte STRING_16 = 0x42; + byte STRING_32 = 0x44; + byte RAW_8 = 0x51; + byte RAW_16 = 0x52; + byte RAW_32 = 0x54; + byte LIST = 0x60; + byte MAP = 0x70; + byte END = (byte) 0x80; +} ===================================== briar-core/src/org/briarproject/serial/ReaderImpl.java ===================================== --- a/briar-core/src/org/briarproject/serial/ReaderImpl.java +++ b/briar-core/src/org/briarproject/serial/ReaderImpl.java @@ -1,23 +1,20 @@ package org.briarproject.serial; -import static org.briarproject.serial.Tag.BYTES_16; -import static org.briarproject.serial.Tag.BYTES_32; -import static org.briarproject.serial.Tag.BYTES_8; -import static org.briarproject.serial.Tag.END; -import static org.briarproject.serial.Tag.FALSE; -import static org.briarproject.serial.Tag.FLOAT; -import static org.briarproject.serial.Tag.INTEGER_16; -import static org.briarproject.serial.Tag.INTEGER_32; -import static org.briarproject.serial.Tag.INTEGER_64; -import static org.briarproject.serial.Tag.INTEGER_8; -import static org.briarproject.serial.Tag.LIST; -import static org.briarproject.serial.Tag.MAP; -import static org.briarproject.serial.Tag.NULL; -import static org.briarproject.serial.Tag.STRING_16; -import static org.briarproject.serial.Tag.STRING_32; -import static org.briarproject.serial.Tag.STRING_8; -import static org.briarproject.serial.Tag.STRUCT; -import static org.briarproject.serial.Tag.TRUE; +import static org.briarproject.serial.ObjectTypes.END; +import static org.briarproject.serial.ObjectTypes.FLOAT_64; +import static org.briarproject.serial.ObjectTypes.INT_16; +import static org.briarproject.serial.ObjectTypes.INT_32; +import static org.briarproject.serial.ObjectTypes.INT_64; +import static org.briarproject.serial.ObjectTypes.INT_8; +import static org.briarproject.serial.ObjectTypes.LIST; +import static org.briarproject.serial.ObjectTypes.MAP; +import static org.briarproject.serial.ObjectTypes.NULL; +import static org.briarproject.serial.ObjectTypes.RAW_16; +import static org.briarproject.serial.ObjectTypes.RAW_32; +import static org.briarproject.serial.ObjectTypes.RAW_8; +import static org.briarproject.serial.ObjectTypes.STRING_16; +import static org.briarproject.serial.ObjectTypes.STRING_32; +import static org.briarproject.serial.ObjectTypes.STRING_8; import java.io.IOException; import java.io.InputStream; @@ -37,7 +34,7 @@ class ReaderImpl implements Reader { private final Collection<Consumer> consumers = new ArrayList<Consumer>(0); private boolean hasLookahead = false, eof = false; - private byte next, nextStructId; + private byte next; private byte[] buf = new byte[8]; ReaderImpl(InputStream in) { @@ -54,21 +51,12 @@ class ReaderImpl implements Reader { return; } next = (byte) i; - // If necessary, read another lookahead byte - if(next == STRUCT) { - i = in.read(); - if(i == -1) throw new FormatException(); - nextStructId = (byte) i; - } hasLookahead = true; } private void consumeLookahead() throws IOException { assert hasLookahead; - for(Consumer c : consumers) { - c.write(next); - if(next == STRUCT) c.write(nextStructId); - } + for(Consumer c : consumers) c.write(next); hasLookahead = false; } @@ -101,11 +89,10 @@ class ReaderImpl implements Reader { if(hasBoolean()) skipBoolean(); else if(hasInteger()) skipInteger(); else if(hasFloat()) skipFloat(); - else if(hasString()) skipString(Integer.MAX_VALUE); - else if(hasBytes()) skipBytes(Integer.MAX_VALUE); + else if(hasString()) skipString(); + else if(hasBytes()) skipBytes(); else if(hasList()) skipList(); else if(hasMap()) skipMap(); - else if(hasStruct()) skipStruct(); else if(hasNull()) skipNull(); else throw new FormatException(); } @@ -127,36 +114,59 @@ class ReaderImpl implements Reader { if(!consumers.remove(c)) throw new IllegalArgumentException(); } + public boolean hasNull() throws IOException { + if(!hasLookahead) readLookahead(); + if(eof) return false; + return next == NULL; + } + + public void readNull() throws IOException { + if(!hasNull()) throw new FormatException(); + consumeLookahead(); + } + + public void skipNull() throws IOException { + if(!hasNull()) throw new FormatException(); + hasLookahead = false; + } + public boolean hasBoolean() throws IOException { if(!hasLookahead) readLookahead(); if(eof) return false; - return next == FALSE || next == TRUE; + return next == ObjectTypes.BOOLEAN; } public boolean readBoolean() throws IOException { if(!hasBoolean()) throw new FormatException(); consumeLookahead(); - return next == TRUE; + return readBoolean(true); + } + + private boolean readBoolean(boolean consume) throws IOException { + readIntoBuffer(1, consume); + if(buf[0] != 0 && buf[0] != 1) throw new FormatException(); + return buf[0] == 1; } public void skipBoolean() throws IOException { if(!hasBoolean()) throw new FormatException(); + skip(1); hasLookahead = false; } public boolean hasInteger() throws IOException { if(!hasLookahead) readLookahead(); if(eof) return false; - return next == INTEGER_8 || next == INTEGER_16 || next == INTEGER_32 || - next == INTEGER_64; + return next == INT_8 || next == INT_16 || next == INT_32 || + next == INT_64; } public long readInteger() throws IOException { if(!hasInteger()) throw new FormatException(); consumeLookahead(); - if(next == INTEGER_8) return readInt8(true); - if(next == INTEGER_16) return readInt16(true); - if(next == INTEGER_32) return readInt32(true); + if(next == INT_8) return readInt8(true); + if(next == INT_16) return readInt16(true); + if(next == INT_32) return readInt32(true); return readInt64(true); } @@ -193,9 +203,9 @@ class ReaderImpl implements Reader { public void skipInteger() throws IOException { if(!hasInteger()) throw new FormatException(); - if(next == INTEGER_8) skip(1); - else if(next == INTEGER_16) skip(2); - else if(next == INTEGER_32) skip(4); + if(next == INT_8) skip(1); + else if(next == INT_16) skip(2); + else if(next == INT_32) skip(4); else skip(8); hasLookahead = false; } @@ -203,7 +213,7 @@ class ReaderImpl implements Reader { public boolean hasFloat() throws IOException { if(!hasLookahead) readLookahead(); if(eof) return false; - return next == FLOAT; + return next == FLOAT_64; } public double readFloat() throws IOException { @@ -244,10 +254,10 @@ class ReaderImpl implements Reader { throw new FormatException(); } - public void skipString(int maxLength) throws IOException { + public void skip... [truncated message content] |
From: akwizgran <gi...@br...> - 2015-04-29 14:13:19
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="ffcc8b6b" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/ffcc8b6b38572b4aaace38408fda991f97599933">ffcc8b6b</a> by akwizgran Bumped version to 0.9. - - - - - Changes: ===================================== briar-android/AndroidManifest.xml ===================================== --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.briarproject" - android:versionCode="8" - android:versionName="0.8" > + android:versionCode="9" + android:versionName="0.9" > <uses-sdk android:minSdkVersion="7" |
From: akwizgran <gi...@br...> - 2015-04-29 14:11:18
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="ec7eb386" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/ec7eb386f5930146b258debeb984e39dd124761e">ec7eb386</a> by akwizgran Bumped expiry date to 15 May 2015. - - - - - <a href="dea5a447" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/dea5a4472411f8399693305fe1f8bd2aa21d77e7">dea5a447</a> by akwizgran Simpler forum sharing UX. - - - - - Changes: ===================================== briar-android/AndroidManifest.xml ===================================== --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -132,9 +132,9 @@ /> </activity> <activity - android:name=".android.groups.ConfigureGroupActivity" + android:name=".android.groups.AvailableGroupsActivity" android:logo="@drawable/logo" - android:label="@string/app_name" + android:label="@string/available_forums_title" android:parentActivityName=".android.groups.GroupListActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" @@ -173,9 +173,9 @@ /> </activity> <activity - android:name=".android.groups.ManageGroupsActivity" + android:name=".android.groups.ReadGroupPostActivity" android:logo="@drawable/logo" - android:label="@string/manage_forums_title" + android:label="@string/app_name" android:parentActivityName=".android.groups.GroupListActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" @@ -183,7 +183,7 @@ /> </activity> <activity - android:name=".android.groups.ReadGroupPostActivity" + android:name=".android.groups.ShareGroupActivity" android:logo="@drawable/logo" android:label="@string/app_name" android:parentActivityName=".android.groups.GroupListActivity" > ===================================== briar-android/res/values/color.xml ===================================== --- a/briar-android/res/values/color.xml +++ b/briar-android/res/values/color.xml @@ -9,7 +9,7 @@ <color name="private_message_date">#AAAAAA</color> <color name="unread_background">#FFFFFF</color> <color name="horizontal_border">#CCCCCC</color> - <color name="groups_available_background">#FCCF1C</color> + <color name="forums_available_background">#FCCF1C</color> <color name="no_private_messages">#AAAAAA</color> <color name="no_posts">#AAAAAA</color> <color name="settings_title_text">#2D3E50</color> ===================================== briar-android/res/values/strings.xml ===================================== --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -11,8 +11,10 @@ <string name="name_too_long">Name is too long</string> <string name="password_too_weak">Password is too weak</string> <string name="passwords_do_not_match">Passwords do not match</string> + <string name="create_account_button">Create Account</string> <string name="enter_password">Enter your password:</string> <string name="try_again">Wrong password, try again:</string> + <string name="sign_in_button">Sign In</string> <string name="startup_failed_notification_title">Briar could not start</string> <string name="startup_failed_notification_text">You may need to reinstall Briar.</string> <string name="expiry_warning">This software has expired.\nPlease install a newer version.</string> @@ -33,7 +35,7 @@ <string name="searching_format">Searching for %06d\u2026</string> <string name="connection_failed">Connection failed</string> <string name="could_not_find_contact">Briar could not find your contact nearby</string> - <string name="try_again_button">Try again</string> + <string name="try_again_button">Try Again</string> <string name="connected_to_contact">Connected to contact</string> <string name="calculating_confirmation_code">Calculating confirmation code\u2026</string> <string name="your_confirmation_code">Your confirmation code is</string> @@ -49,45 +51,40 @@ <string name="format_from">From: %s</string> <string name="forums_title">Forums</string> <string name="no_forums">No forums</string> - <plurals name="forums_available"> - <item quantity="one">%d forum available from contacts</item> - <item quantity="other">%d forums available from contacts</item> + <plurals name="forums_shared"> + <item quantity="one">%d forum shared by contacts</item> + <item quantity="other">%d forums shared by contacts</item> </plurals> - <string name="no_posts">No posts</string> - <string name="subscribe_to_this_forum">Subscribe to this forum</string> - <string name="no_subscribers">No contacts subscribe to this forum</string> - <plurals name="subscribers"> - <item quantity="one">%d contact subscribes to this forum:</item> - <item quantity="other">%d contacts subscribe to this forum:</item> - </plurals> - <string name="public_space_warning">Forums are public spaces. There may be other subscribers who are not your contacts.</string> + <string name="unsubscribe">Unsubscribe</string> + <string name="unsubscribed_toast">Unsubscribed</string> + <string name="no_forum_posts">No posts</string> <string name="create_forum_title">New Forum</string> <string name="choose_forum_name">Choose a name for your forum:</string> - <string name="forum_visible_to_all">Share this forum with all contacts</string> - <string name="forum_visible_to_some">Share this forum with chosen contacts</string> - <string name="done_button">Done</string> + <string name="create_forum_button">Create Forum</string> <string name="forum_created_toast">Forum created</string> + <string name="forum_share_with_all">Share this forum with all contacts</string> + <string name="forum_share_with_some">Share this forum with chosen contacts</string> + <string name="share_button">Share Forum</string> <string name="from">From:</string> <string name="anonymous">Anonymous</string> <string name="new_identity_item">New identity\u2026</string> - <string name="group_post_hint">Type forum post</string> - <string name="manage_forums_title">Available Forums</string> - <string name="no_forums_available">No forums available</string> - <string name="subscribed_all">Subscribed, shared with all contacts</string> - <string name="subscribed_some">Subscribed, shared with chosen contacts</string> - <string name="not_subscribed">Not subscribed</string> <string name="new_identity_title">New Identity</string> - <string name="create_button">Create</string> + <string name="create_identity_button">Create Identity</string> <string name="identity_created_toast">Identity created</string> + <string name="forum_post_hint">Type forum post</string> + <string name="available_forums_title">Available Forums</string> + <string name="subscribed_toast">Subscribed</string> + <string name="shared_by_format">Shared by %s</string> <string name="no_contacts_prompt">You don\'t have any contacts. Add a contact now?</string> <string name="add_button">Add</string> <string name="cancel_button">Cancel</string> - <string name="post_sent_toast">Post sent</string> + <string name="done_button">Done</string> + <string name="post_sent_toast">Forum post sent</string> <plurals name="private_message_notification_text"> <item quantity="one">New private message.</item> <item quantity="other">%d new private messages.</item> </plurals> - <plurals name="group_post_notification_text"> + <plurals name="forum_post_notification_text"> <item quantity="one">New forum post.</item> <item quantity="other">%d new forum posts.</item> </plurals> ===================================== briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java ===================================== --- a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java +++ b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java @@ -236,7 +236,7 @@ Service, EventListener { b.setSmallIcon(R.drawable.message_notification_icon); b.setContentTitle(appContext.getText(R.string.app_name)); b.setContentText(appContext.getResources().getQuantityString( - R.plurals.group_post_notification_text, groupTotal, + R.plurals.forum_post_notification_text, groupTotal, groupTotal)); String ringtoneUri = settings.get("notifyRingtoneUri"); if(!StringUtils.isNullOrEmpty(ringtoneUri)) ===================================== briar-android/src/org/briarproject/android/PasswordActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/PasswordActivity.java +++ b/briar-android/src/org/briarproject/android/PasswordActivity.java @@ -47,7 +47,7 @@ public class PasswordActivity extends RoboActivity { @Inject @CryptoExecutor private Executor cryptoExecutor; private TextView enterPassword = null; - private Button continueButton = null; + private Button signInButton = null; private ProgressBar progress = null; // Fields that are accessed from background threads must be volatile @@ -102,15 +102,15 @@ public class PasswordActivity extends RoboActivity { // Adjusting the padding of buttons and EditTexts has the wrong results layout.addView(new FixedVerticalSpace(this)); - continueButton = new Button(this); - continueButton.setLayoutParams(WRAP_WRAP); - continueButton.setText(R.string.continue_button); - continueButton.setOnClickListener(new OnClickListener() { + signInButton = new Button(this); + signInButton.setLayoutParams(WRAP_WRAP); + signInButton.setText(R.string.sign_in_button); + signInButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { validatePassword(encrypted, passwordEntry.getText()); } }); - layout.addView(continueButton); + layout.addView(signInButton); progress = new ProgressBar(this); progress.setLayoutParams(WRAP_WRAP); @@ -131,7 +131,7 @@ public class PasswordActivity extends RoboActivity { Object o = getSystemService(INPUT_METHOD_SERVICE); ((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0); // Replace the button with a progress bar - continueButton.setVisibility(GONE); + signInButton.setVisibility(GONE); progress.setVisibility(VISIBLE); // Decrypt the database key in a background thread final String password = e.toString(); @@ -152,7 +152,7 @@ public class PasswordActivity extends RoboActivity { runOnUiThread(new Runnable() { public void run() { enterPassword.setText(R.string.try_again); - continueButton.setVisibility(VISIBLE); + signInButton.setVisibility(VISIBLE); progress.setVisibility(GONE); } }); ===================================== briar-android/src/org/briarproject/android/SetupActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -67,7 +67,7 @@ OnEditorActionListener { private EditText passwordEntry = null, passwordConfirmation = null; private StrengthMeter strengthMeter = null; private TextView feedback = null; - private Button continueButton = null; + private Button createAccountButton = null; private ProgressBar progress = null; // Fields that are accessed from background threads must be volatile @@ -160,12 +160,12 @@ OnEditorActionListener { feedback.setText(""); layout.addView(feedback); - continueButton = new Button(this); - continueButton.setLayoutParams(WRAP_WRAP); - continueButton.setText(R.string.continue_button); - continueButton.setEnabled(false); - continueButton.setOnClickListener(this); - layout.addView(continueButton); + createAccountButton = new Button(this); + createAccountButton.setLayoutParams(WRAP_WRAP); + createAccountButton.setText(R.string.create_account_button); + createAccountButton.setEnabled(false); + createAccountButton.setOnClickListener(this); + layout.addView(createAccountButton); progress = new ProgressBar(this); progress.setLayoutParams(WRAP_WRAP); @@ -205,7 +205,7 @@ OnEditorActionListener { } else { feedback.setText(""); } - continueButton.setEnabled(nicknameLength > 0 + createAccountButton.setEnabled(nicknameLength > 0 && nicknameLength <= MAX_AUTHOR_NAME_LENGTH && passwordsMatch && strength >= WEAK); } @@ -220,7 +220,7 @@ OnEditorActionListener { public void onClick(View view) { // Replace the feedback text and button with a progress bar feedback.setVisibility(GONE); - continueButton.setVisibility(GONE); + createAccountButton.setVisibility(GONE); progress.setVisibility(VISIBLE); final String nickname = nicknameEntry.getText().toString(); final String password = passwordEntry.getText().toString(); ===================================== briar-android/src/org/briarproject/android/SplashScreenActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/SplashScreenActivity.java +++ b/briar-android/src/org/briarproject/android/SplashScreenActivity.java @@ -36,8 +36,8 @@ public class SplashScreenActivity extends RoboSplashActivity { private static final Logger LOG = Logger.getLogger(SplashScreenActivity.class.getName()); - // This build expires on 1 May 2015 - private static final long EXPIRY_DATE = 1430438400 * 1000L; + // This build expires on 15 May 2015 + private static final long EXPIRY_DATE = 1431648000 * 1000L; private long now = System.currentTimeMillis(); ===================================== briar-android/src/org/briarproject/android/groups/AvailableGroupsActivity.java ===================================== --- /dev/null +++ b/briar-android/src/org/briarproject/android/groups/AvailableGroupsActivity.java @@ -0,0 +1,163 @@ +package org.briarproject.android.groups; + +import static android.widget.Toast.LENGTH_SHORT; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; +import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.logging.Logger; + +import javax.inject.Inject; + +import org.briarproject.R; +import org.briarproject.android.BriarActivity; +import org.briarproject.android.util.ListLoadingProgressBar; +import org.briarproject.api.Contact; +import org.briarproject.api.ContactId; +import org.briarproject.api.db.DatabaseComponent; +import org.briarproject.api.db.DbException; +import org.briarproject.api.db.NoSuchSubscriptionException; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventBus; +import org.briarproject.api.event.EventListener; +import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent; +import org.briarproject.api.event.SubscriptionAddedEvent; +import org.briarproject.api.event.SubscriptionRemovedEvent; +import org.briarproject.api.messaging.Group; +import org.briarproject.api.messaging.GroupId; + +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ListView; +import android.widget.Toast; + +public class AvailableGroupsActivity extends BriarActivity +implements EventListener, OnItemClickListener { + + private static final Logger LOG = + Logger.getLogger(AvailableGroupsActivity.class.getName()); + + private AvailableGroupsAdapter adapter = null; + private ListView list = null; + private ListLoadingProgressBar loading = null; + + // Fields that are accessed from background threads must be volatile + @Inject private volatile DatabaseComponent db; + @Inject private volatile EventBus eventBus; + + @Override + public void onCreate(Bundle state) { + super.onCreate(state); + + adapter = new AvailableGroupsAdapter(this); + list = new ListView(this); + list.setLayoutParams(MATCH_MATCH); + list.setAdapter(adapter); + list.setOnItemClickListener(this); + + // Show a progress bar while the list is loading + loading = new ListLoadingProgressBar(this); + setContentView(loading); + } + + @Override + public void onResume() { + super.onResume(); + eventBus.addListener(this); + loadGroups(); + } + + private void loadGroups() { + runOnDbThread(new Runnable() { + public void run() { + try { + Collection<GroupContacts> available = + new ArrayList<GroupContacts>(); + long now = System.currentTimeMillis(); + for(Group g : db.getAvailableGroups()) { + try { + GroupId id = g.getId(); + Collection<Contact> c = db.getSubscribers(id); + available.add(new GroupContacts(g, c)); + } catch(NoSuchSubscriptionException e) { + continue; + } + } + long duration = System.currentTimeMillis() - now; + if(LOG.isLoggable(INFO)) + LOG.info("Load took " + duration + " ms"); + displayGroups(available); + } catch(DbException e) { + if(LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + }); + } + + private void displayGroups(final Collection<GroupContacts> available) { + runOnUiThread(new Runnable() { + public void run() { + if(available.isEmpty()) { + LOG.info("No groups available, finishing"); + finish(); + } else { + setContentView(list); + adapter.clear(); + for(GroupContacts g : available) + adapter.add(new AvailableGroupsItem(g)); + adapter.sort(AvailableGroupsItemComparator.INSTANCE); + adapter.notifyDataSetChanged(); + } + } + }); + } + + @Override + public void onPause() { + super.onPause(); + eventBus.removeListener(this); + } + + public void eventOccurred(Event e) { + if(e instanceof RemoteSubscriptionsUpdatedEvent) { + LOG.info("Remote subscriptions changed, reloading"); + loadGroups(); + } else if(e instanceof SubscriptionAddedEvent) { + LOG.info("Subscription added, reloading"); + loadGroups(); + } else if(e instanceof SubscriptionRemovedEvent) { + LOG.info("Subscription removed, reloading"); + loadGroups(); + } + } + + public void onItemClick(AdapterView<?> parent, View view, int position, + long id) { + AvailableGroupsItem item = adapter.getItem(position); + Collection<ContactId> visible = new ArrayList<ContactId>(); + for(Contact c : item.getContacts()) visible.add(c.getId()); + addSubscription(item.getGroup(), visible); + String subscribed = getString(R.string.subscribed_toast); + Toast.makeText(this, subscribed, LENGTH_SHORT).show(); + } + + private void addSubscription(final Group g, + final Collection<ContactId> visible) { + runOnDbThread(new Runnable() { + public void run() { + try { + db.addGroup(g); + db.setVisibility(g.getId(), visible); + } catch(DbException e) { + if(LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + }); + } +} ===================================== briar-android/src/org/briarproject/android/groups/AvailableGroupsAdapter.java ===================================== --- /dev/null +++ b/briar-android/src/org/briarproject/android/groups/AvailableGroupsAdapter.java @@ -0,0 +1,57 @@ +package org.briarproject.android.groups; + +import static android.text.TextUtils.TruncateAt.END; +import static android.widget.LinearLayout.VERTICAL; + +import java.util.ArrayList; +import java.util.Collection; + +import org.briarproject.R; +import org.briarproject.android.util.LayoutUtils; +import org.briarproject.api.Contact; +import org.briarproject.util.StringUtils; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.LinearLayout; +import android.widget.TextView; + +class AvailableGroupsAdapter extends ArrayAdapter<AvailableGroupsItem> { + + private final int pad; + + AvailableGroupsAdapter(Context ctx) { + super(ctx, android.R.layout.simple_expandable_list_item_1, + new ArrayList<AvailableGroupsItem>()); + pad = LayoutUtils.getPadding(ctx); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + AvailableGroupsItem item = getItem(position); + Context ctx = getContext(); + + LinearLayout layout = new LinearLayout(ctx); + layout.setOrientation(VERTICAL); + + TextView name = new TextView(ctx); + name.setTextSize(18); + name.setSingleLine(); + name.setEllipsize(END); + name.setPadding(pad, pad, pad, pad); + name.setText(item.getGroup().getName()); + layout.addView(name); + + TextView status = new TextView(ctx); + status.setPadding(pad, 0, pad, pad); + Collection<String> names = new ArrayList<String>(); + for(Contact c : item.getContacts()) names.add(c.getAuthor().getName()); + String format = ctx.getString(R.string.shared_by_format); + status.setText(String.format(format, StringUtils.join(names, ", "))); + layout.addView(status); + + return layout; + } +} ===================================== briar-android/src/org/briarproject/android/groups/AvailableGroupsItem.java ===================================== --- /dev/null +++ b/briar-android/src/org/briarproject/android/groups/AvailableGroupsItem.java @@ -0,0 +1,23 @@ +package org.briarproject.android.groups; + +import java.util.Collection; + +import org.briarproject.api.Contact; +import org.briarproject.api.messaging.Group; + +class AvailableGroupsItem { + + private final GroupContacts groupContacts; + + AvailableGroupsItem(GroupContacts groupContacts) { + this.groupContacts = groupContacts; + } + + Group getGroup() { + return groupContacts.getGroup(); + } + + Collection<Contact> getContacts() { + return groupContacts.getContacts(); + } +} ===================================== briar-android/src/org/briarproject/android/groups/AvailableGroupsItemComparator.java ===================================== --- /dev/null +++ b/briar-android/src/org/briarproject/android/groups/AvailableGroupsItemComparator.java @@ -0,0 +1,16 @@ +package org.briarproject.android.groups; + +import java.util.Comparator; + +class AvailableGroupsItemComparator implements Comparator<AvailableGroupsItem> { + + static final AvailableGroupsItemComparator INSTANCE = + new AvailableGroupsItemComparator(); + + public int compare(AvailableGroupsItem a, AvailableGroupsItem b) { + if(a == b) return 0; + String aName = a.getGroup().getName(); + String bName = b.getGroup().getName(); + return String.CASE_INSENSITIVE_ORDER.compare(aName, bName); + } +} ===================================== briar-android/src/org/briarproject/android/groups/ConfigureGroupActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/groups/ConfigureGroupActivity.java +++ /dev/null @@ -1,356 +0,0 @@ -package org.briarproject.android.groups; - -import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; -import static android.view.Gravity.CENTER; -import static android.view.Gravity.CENTER_HORIZONTAL; -import static android.view.View.GONE; -import static android.view.View.VISIBLE; -import static android.widget.LinearLayout.HORIZONTAL; -import static android.widget.LinearLayout.VERTICAL; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; -import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH; -import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.logging.Logger; - -import javax.inject.Inject; - -import org.briarproject.R; -import org.briarproject.android.BriarActivity; -import org.briarproject.android.contact.SelectContactsDialog; -import org.briarproject.android.invitation.AddContactActivity; -import org.briarproject.android.util.LayoutUtils; -import org.briarproject.api.Contact; -import org.briarproject.api.ContactId; -import org.briarproject.api.db.DatabaseComponent; -import org.briarproject.api.db.DbException; -import org.briarproject.api.event.Event; -import org.briarproject.api.event.EventBus; -import org.briarproject.api.event.EventListener; -import org.briarproject.api.event.LocalSubscriptionsUpdatedEvent; -import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent; -import org.briarproject.api.messaging.Group; -import org.briarproject.api.messaging.GroupId; - -import android.content.Intent; -import android.content.res.Resources; -import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.RadioButton; -import android.widget.RadioGroup; -import android.widget.TextView; - -public class ConfigureGroupActivity extends BriarActivity -implements OnClickListener, EventListener, NoContactsDialog.Listener, -SelectContactsDialog.Listener { - - private static final Logger LOG = - Logger.getLogger(ConfigureGroupActivity.class.getName()); - - private String groupName = null; - private CheckBox subscribeCheckBox = null; - private RadioGroup radioGroup = null; - private RadioButton visibleToAll = null, visibleToSome = null; - private Button doneButton = null; - private TextView subscribers = null; - private TextView subscriberNames = null; - private ProgressBar progress = null; - private boolean changed = false; - - // Fields that are accessed from background threads must be volatile - @Inject private volatile DatabaseComponent db; - @Inject private volatile EventBus eventBus; - private volatile GroupId groupId = null; - private volatile Group group = null; - private volatile boolean subscribed = false; - private volatile Collection<Contact> contacts = null; - private volatile Collection<ContactId> selected = null; - - @Override - public void onCreate(Bundle state) { - super.onCreate(state); - - Intent i = getIntent(); - byte[] b = i.getByteArrayExtra("briar.GROUP_ID"); - if(b == null) throw new IllegalStateException(); - groupId = new GroupId(b); - groupName = i.getStringExtra("briar.GROUP_NAME"); - if(groupName == null) throw new IllegalStateException(); - setTitle(groupName); - b = i.getByteArrayExtra("briar.GROUP_SALT"); - if(b == null) throw new IllegalStateException(); - group = new Group(groupId, groupName, b); - subscribed = i.getBooleanExtra("briar.SUBSCRIBED", false); - boolean all = i.getBooleanExtra("briar.VISIBLE_TO_ALL", false); - - LinearLayout layout = new LinearLayout(this); - layout.setLayoutParams(MATCH_MATCH); - layout.setOrientation(VERTICAL); - layout.setGravity(CENTER_HORIZONTAL); - int pad = LayoutUtils.getPadding(this); - layout.setPadding(pad, pad, pad, pad); - - subscribers = new TextView(this); - subscribers.setGravity(CENTER); - subscribers.setTextSize(18); - subscribers.setText("\u2026"); - layout.addView(subscribers); - - subscriberNames = new TextView(this); - subscriberNames.setGravity(CENTER); - subscriberNames.setTextSize(18); - subscriberNames.setVisibility(GONE); - layout.addView(subscriberNames); - - LinearLayout warning = new LinearLayout(this); - warning.setOrientation(HORIZONTAL); - warning.setPadding(pad, pad, pad, pad); - - ImageView icon = new ImageView(this); - icon.setImageResource(R.drawable.action_about); - warning.addView(icon); - - TextView publicSpace = new TextView(this); - publicSpace.setPadding(pad, 0, 0, 0); - publicSpace.setText(R.string.public_space_warning); - warning.addView(publicSpace); - layout.addView(warning); - - subscribeCheckBox = new CheckBox(this); - subscribeCheckBox.setId(1); - subscribeCheckBox.setText(R.string.subscribe_to_this_forum); - subscribeCheckBox.setChecked(subscribed); - subscribeCheckBox.setOnClickListener(this); - layout.addView(subscribeCheckBox); - - radioGroup = new RadioGroup(this); - radioGroup.setOrientation(VERTICAL); - - visibleToAll = new RadioButton(this); - visibleToAll.setId(2); - visibleToAll.setText(R.string.forum_visible_to_all); - visibleToAll.setEnabled(subscribed); - visibleToAll.setOnClickListener(this); - radioGroup.addView(visibleToAll); - - visibleToSome = new RadioButton(this); - visibleToSome.setId(3); - visibleToSome.setText(R.string.forum_visible_to_some); - visibleToSome.setEnabled(subscribed); - visibleToSome.setOnClickListener(this); - radioGroup.addView(visibleToSome); - - if(!subscribed || all) radioGroup.check(visibleToAll.getId()); - else radioGroup.check(visibleToSome.getId()); - layout.addView(radioGroup); - - doneButton = new Button(this); - doneButton.setLayoutParams(WRAP_WRAP); - doneButton.setText(R.string.done_button); - doneButton.setOnClickListener(this); - layout.addView(doneButton); - - progress = new ProgressBar(this); - progress.setLayoutParams(WRAP_WRAP); - progress.setIndeterminate(true); - progress.setVisibility(GONE); - layout.addView(progress); - - setContentView(layout); - } - - @Override - public void onResume() { - super.onResume(); - eventBus.addListener(this); - loadSubscribers(); - } - - private void loadSubscribers() { - runOnDbThread(new Runnable() { - public void run() { - try { - long now = System.currentTimeMillis(); - Collection<Contact> contacts = db.getSubscribers(groupId); - long duration = System.currentTimeMillis() - now; - if(LOG.isLoggable(INFO)) - LOG.info("Load took " + duration + " ms"); - displaySubscribers(contacts); - } catch(DbException e) { - if(LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); - } - - private void displaySubscribers(final Collection<Contact> contacts) { - runOnUiThread(new Runnable() { - public void run() { - if(contacts.isEmpty()) { - subscribers.setText(R.string.no_subscribers); - subscriberNames.setVisibility(GONE); - } else { - int count = contacts.size(); - Resources res = getResources(); - String title = res.getQuantityString(R.plurals.subscribers, - count, count); - subscribers.setText(title); - List<String> names = new ArrayList<String>(); - for(Contact c : contacts) - names.add(c.getAuthor().getName()); - Collections.sort(names, String.CASE_INSENSITIVE_ORDER); - StringBuilder s = new StringBuilder(); - for(int i = 0; i < count; i++) { - s.append(names.get(i)); - if(i + 1 < count) s.append(", "); - } - subscriberNames.setText(s.toString()); - subscriberNames.setVisibility(VISIBLE); - } - } - }); - } - - @Override - public void onPause() { - super.onPause(); - eventBus.removeListener(this); - } - - public void onClick(View view) { - if(view == subscribeCheckBox) { - changed = true; - boolean subscribe = subscribeCheckBox.isChecked(); - visibleToAll.setEnabled(subscribe); - visibleToSome.setEnabled(subscribe); - } else if(view == visibleToAll) { - changed = true; - } else if(view == visibleToSome) { - changed = true; - if(contacts == null) loadVisibleContacts(); - else displayVisibleContacts(); - } else if(view == doneButton) { - if(changed) { - // Replace the button with a progress bar - doneButton.setVisibility(GONE); - progress.setVisibility(VISIBLE); - // Update the group in a background thread - boolean subscribe = subscribeCheckBox.isChecked(); - boolean all = visibleToAll.isChecked(); - updateGroup(subscribe, all); - } else { - finish(); - } - } - } - - private void loadVisibleContacts() { - runOnDbThread(new Runnable() { - public void run() { - try { - long now = System.currentTimeMillis(); - contacts = db.getContacts(); - selected = db.getVisibility(groupId); - long duration = System.currentTimeMillis() - now; - if(LOG.isLoggable(INFO)) - LOG.info("Load took " + duration + " ms"); - displayVisibleContacts(); - } catch(DbException e) { - if(LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); - } - - private void displayVisibleContacts() { - runOnUiThread(new Runnable() { - public void run() { - if(contacts.isEmpty()) { - NoContactsDialog builder = new NoContactsDialog(); - builder.setListener(ConfigureGroupActivity.this); - builder.build(ConfigureGroupActivity.this).show(); - } else { - SelectContactsDialog builder = new SelectContactsDialog(); - builder.setListener(ConfigureGroupActivity.this); - builder.setContacts(contacts); - builder.setSelected(selected); - builder.build(ConfigureGroupActivity.this).show(); - } - } - }); - } - - private void updateGroup(final boolean subscribe, final boolean all) { - runOnDbThread(new Runnable() { - public void run() { - try { - long now = System.currentTimeMillis(); - if(subscribe) { - if(!subscribed) db.addGroup(group); - db.setVisibleToAll(groupId, all); - if(!all) db.setVisibility(groupId, selected); - } else if(subscribed) { - db.removeGroup(group); - } - long duration = System.currentTimeMillis() - now; - if(LOG.isLoggable(INFO)) - LOG.info("Update took " + duration + " ms"); - } catch(DbException e) { - if(LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - if(subscribe) showGroup(); - else finishOnUiThread(); - } - }); - } - - private void showGroup() { - runOnUiThread(new Runnable() { - public void run() { - Intent i = new Intent(ConfigureGroupActivity.this, - GroupActivity.class); - i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); - i.putExtra("briar.GROUP_ID", groupId.getBytes()); - i.putExtra("briar.GROUP_NAME", groupName); - startActivity(i); - finish(); - } - }); - } - - public void eventOccurred(Event e) { - if(e instanceof LocalSubscriptionsUpdatedEvent) { - LOG.info("Local subscriptions updated, reloading"); - loadSubscribers(); - } else if(e instanceof RemoteSubscriptionsUpdatedEvent) { - LOG.info("Remote subscriptions updated, reloading"); - loadSubscribers(); - } - } - - public void contactCreationSelected() { - startActivity(new Intent(this, AddContactActivity.class)); - } - - public void contactCreationCancelled() {} - - public void contactsSelected(Collection<ContactId> selected) { - this.selected = Collections.unmodifiableCollection(selected); - } - - public void contactSelectionCancelled() {} -} ===================================== briar-android/src/org/briarproject/android/groups/CreateGroupActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/groups/CreateGroupActivity.java +++ b/briar-android/src/org/briarproject/android/groups/CreateGroupActivity.java @@ -14,19 +14,13 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH; import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP; import static org.briarproject.api.messaging.MessagingConstants.MAX_GROUP_NAME_LENGTH; -import java.util.Collection; -import java.util.Collections; import java.util.logging.Logger; import javax.inject.Inject; import org.briarproject.R; import org.briarproject.android.BriarActivity; -import org.briarproject.android.contact.SelectContactsDialog; -import org.briarproject.android.invitation.AddContactActivity; import org.briarproject.android.util.LayoutUtils; -import org.briarproject.api.Contact; -import org.briarproject.api.ContactId; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DbException; import org.briarproject.api.messaging.Group; @@ -42,31 +36,24 @@ import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ProgressBar; -import android.widget.RadioButton; -import android.widget.RadioGroup; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import android.widget.Toast; public class CreateGroupActivity extends BriarActivity -implements OnEditorActionListener, OnClickListener, NoContactsDialog.Listener, -SelectContactsDialog.Listener { +implements OnEditorActionListener, OnClickListener { private static final Logger LOG = Logger.getLogger(CreateGroupActivity.class.getName()); private EditText nameEntry = null; - private RadioGroup radioGroup = null; - private RadioButton visibleToAll = null, visibleToSome = null; - private Button createButton = null; + private Button createForumButton = null; private ProgressBar progress = null; private TextView feedback = null; // Fields that are accessed from background threads must be volatile @Inject private volatile GroupFactory groupFactory; @Inject private volatile DatabaseComponent db; - private volatile Collection<Contact> contacts = null; - private volatile Collection<ContactId> selected = Collections.emptySet(); @Override public void onCreate(Bundle state) { @@ -97,32 +84,16 @@ SelectContactsDialog.Listener { nameEntry.setOnEditorActionListener(this); layout.addView(nameEntry); - radioGroup = new RadioGroup(this); - radioGroup.setOrientation(VERTICAL); - - visibleToAll = new RadioButton(this); - visibleToAll.setId(2); - visibleToAll.setText(R.string.forum_visible_to_all); - visibleToAll.setOnClickListener(this); - radioGroup.addView(visibleToAll); - - visibleToSome = new RadioButton(this); - visibleToSome.setId(3); - visibleToSome.setText(R.string.forum_visible_to_some); - visibleToSome.setOnClickListener(this); - radioGroup.addView(visibleToSome); - layout.addView(radioGroup); - feedback = new TextView(this); feedback.setGravity(CENTER); feedback.setPadding(0, pad, 0, pad); layout.addView(feedback); - createButton = new Button(this); - createButton.setLayoutParams(WRAP_WRAP); - createButton.setText(R.string.create_button); - createButton.setOnClickListener(this); - layout.addView(createButton); + createForumButton = new Button(this); + createForumButton.setLayoutParams(WRAP_WRAP); + createForumButton.setText(R.string.create_forum_button); + createForumButton.setOnClickListener(this); + layout.addView(createForumButton); progress = new ProgressBar(this); progress.setLayoutParams(WRAP_WRAP); @@ -135,9 +106,7 @@ SelectContactsDialog.Listener { private void enableOrDisableCreateButton() { if(progress == null) return; // Not created yet - boolean nameValid = validateName(); - boolean visibilitySelected = radioGroup.getCheckedRadioButtonId() != -1; - createButton.setEnabled(nameValid && visibilitySelected); + createForumButton.setEnabled(validateName()); } public boolean onEditorAction(TextView textView, int actionId, KeyEvent e) { @@ -156,67 +125,22 @@ SelectContactsDialog.Listener { } public void onClick(View view) { - if(view == visibleToAll) { - enableOrDisableCreateButton(); - } else if(view == visibleToSome) { - if(contacts == null) loadContacts(); - else displayContacts(); - } else if(view == createButton) { + if(view == createForumButton) { hideSoftKeyboard(); if(!validateName()) return; - createButton.setVisibility(GONE); + createForumButton.setVisibility(GONE); progress.setVisibility(VISIBLE); - String name = nameEntry.getText().toString(); - boolean all = visibleToAll.isChecked(); - storeGroup(name, all); + storeGroup(nameEntry.getText().toString()); } } - private void loadContacts() { - runOnDbThread(new Runnable() { - public void run() { - try { - long now = System.currentTimeMillis(); - contacts = db.getContacts(); - long duration = System.currentTimeMillis() - now; - if(LOG.isLoggable(INFO)) - LOG.info("Load took " + duration + " ms"); - displayContacts(); - } catch(DbException e) { - if(LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); - } - - private void displayContacts() { - runOnUiThread(new Runnable() { - public void run() { - if(contacts.isEmpty()) { - NoContactsDialog builder = new NoContactsDialog(); - builder.setListener(CreateGroupActivity.this); - builder.build(CreateGroupActivity.this).show(); - } else { - SelectContactsDialog builder = new SelectContactsDialog(); - builder.setListener(CreateGroupActivity.this); - builder.setContacts(contacts); - builder.setSelected(selected); - builder.build(CreateGroupActivity.this).show(); - } - } - }); - } - - private void storeGroup(final String name, final boolean all) { + private void storeGroup(final String name) { runOnDbThread(new Runnable() { public void run() { try { Group g = groupFactory.createGroup(name); long now = System.currentTimeMillis(); db.addGroup(g); - if(all) db.setVisibleToAll(g.getId(), true); - else db.setVisibility(g.getId(), selected); long duration = System.currentTimeMillis() - now; if(LOG.isLoggable(INFO)) LOG.info("Storing group took " + duration + " ms"); @@ -244,21 +168,4 @@ SelectContactsDialog.Listener { } }); } - - public void contactCreationSelected() { - startActivity(new Intent(this, AddContactActivity.class)); - } - - public void contactCreationCancelled() { - enableOrDisableCreateButton(); - } - - public void contactsSelected(Collection<ContactId> selected) { - this.selected = Collections.unmodifiableCollection(selected); - enableOrDisableCreateButton(); - } - - public void contactSelectionCancelled() { - enableOrDisableCreateButton(); - } } ===================================== briar-android/src/org/briarproject/android/groups/GroupActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/groups/GroupActivity.java +++ b/briar-android/src/org/briarproject/android/groups/GroupActivity.java @@ -69,7 +69,7 @@ OnClickListener, OnItemClickListener { private GroupAdapter adapter = null; private ListView list = null; private ListLoadingProgressBar loading = null; - private ImageButton composeButton = null, configureButton = null; + private ImageButton composeButton = null, shareButton = null; // Fields that are accessed from background threads must be volatile @Inject private volatile DatabaseComponent db; @@ -85,6 +85,8 @@ OnClickListener, OnItemClickListener { byte[] b = i.getByteArrayExtra("briar.GROUP_ID"); if(b == null) throw new IllegalStateException(); groupId = new GroupId(b); + String name = i.getStringExtra("briar.GROUP_NAME"); + if(name != null) setTitle(name); LinearLayout layout = new LinearLayout(this); layout.setLayoutParams(MATCH_MATCH); @@ -95,7 +97,7 @@ OnClickListener, OnItemClickListener { empty.setLayoutParams(MATCH_WRAP_1); empty.setGravity(CENTER); empty.setTextSize(18); - empty.setText(R.string.no_posts); + empty.setText(R.string.no_forum_posts); empty.setVisibility(GONE); layout.addView(empty); @@ -127,11 +129,11 @@ OnClickListener, OnItemClickListener { footer.addView(composeButton); footer.addView(new ElasticHorizontalSpace(this)); - configureButton = new ImageButton(this); - configureButton.setBackgroundResource(0); - configureButton.setImageResource(R.drawable.action_settings); - configureButton.setOnClickListener(this); - footer.addView(configureButton); + shareButton = new ImageButton(this); + shareButton.setBackgroundResource(0); + shareButton.setImageResource(R.drawable.social_share); + shareButton.setOnClickListener(this); + footer.addView(shareButton); footer.addView(new ElasticHorizontalSpace(this)); layout.addView(footer); @@ -334,12 +336,10 @@ OnClickListener, OnItemClickListener { i.putExtra("briar.GROUP_NAME", group.getName()); i.putExtra("briar.MIN_TIMESTAMP", getMinTimestampForNewMessage()); startActivity(i); - } else if(view == configureButton) { - Intent i = new Intent(this, ConfigureGroupActivity.class); + } else if(view == shareButton) { + Intent i = new Intent(this, ShareGroupActivity.class); i.putExtra("briar.GROUP_ID", groupId.getBytes()); i.putExtra("briar.GROUP_NAME", group.getName()); - i.putExtra("briar.GROUP_SALT", group.getSalt()); - i.putExtra("briar.SUBSCRIBED", true); startActivity(i); } } ===================================== briar-android/src/org/briarproject/android/groups/GroupContacts.java ===================================== --- /dev/null +++ b/briar-android/src/org/briarproject/android/groups/GroupContacts.java @@ -0,0 +1,25 @@ +package org.briarproject.android.groups; + +import java.util.Collection; + +import org.briarproject.api.Contact; +import org.briarproject.api.messaging.Group; + +class GroupContacts { + + private final Group group; + private final Collection<Contact> contacts; + + GroupContacts(Group group, Collection<Contact> contacts) { + this.group = group; + this.contacts = contacts; + } + + Group getGroup() { + return group; + } + + Collection<Contact> getContacts() { + return contacts; + } +} ===================================== briar-android/src/org/briarproject/android/groups/GroupListActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/groups/GroupListActivity.java +++ b/briar-android/src/org/briarproject/android/groups/GroupListActivity.java @@ -2,10 +2,12 @@ package org.briarproject.android.groups; import static android.view.Gravity.CENTER; import static android.view.Gravity.CENTER_HORIZONTAL; +import static android.view.Menu.NONE; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static android.widget.LinearLayout.HORIZONTAL; import static android.widget.LinearLayout.VERTICAL; +import static android.widget.Toast.LENGTH_SHORT; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH; @@ -21,7 +23,6 @@ import javax.inject.Inject; import org.briarproject.R; import org.briarproject.android.BriarActivity; -import org.briarproject.android.util.ElasticHorizontalSpace; import org.briarproject.android.util.HorizontalBorder; import org.briarproject.android.util.LayoutUtils; import org.briarproject.android.util.ListLoadingProgressBar; @@ -39,23 +40,30 @@ import org.briarproject.api.event.SubscriptionAddedEvent; import org.briarproject.api.event.SubscriptionRemovedEvent; import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.GroupId; -import org.briarproject.api.messaging.GroupStatus; import android.content.Intent; import android.content.res.Resources; import android.os.Bundle; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; +import android.view.View.OnCreateContextMenuListener; import android.widget.AdapterView; +import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.OnItemClickListener; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; +import android.widget.Toast; public class GroupListActivity extends BriarActivity -implements EventListener, OnClickListener, OnItemClickListener { +implements EventListener, OnClickListener, OnItemClickListener, +OnCreateContextMenuListener { + private static final int MENU_ITEM_UNSUBSCRIBE = 1; private static final Logger LOG = Logger.getLogger(GroupListActivity.class.getName()); @@ -67,7 +75,7 @@ implements EventListener, OnClickListener, OnItemClickListener { private ListView list = null; private ListLoadingProgressBar loading = null; private TextView available = null; - private ImageButton newGroupButton = null, manageGroupsButton = null; + private ImageButton newGroupButton = null; // Fields that are accessed from background threads must be volatile @Inject private volatile DatabaseComponent db; @@ -96,6 +104,7 @@ implements EventListener, OnClickListener, OnItemClickListener { list.setLayoutParams(MATCH_WRAP_1); list.setAdapter(adapter); list.setOnItemClickListener(this); + list.setOnCreateContextMenuListener(this); list.setVisibility(GONE); layout.addView(list); @@ -107,10 +116,10 @@ implements EventListener, OnClickListener, OnItemClickListener { available.setLayoutParams(MATCH_WRAP); available.setGravity(CENTER); available.setTextSize(18); + available.setPadding(pad, pad, pad, pad); Resources res = getResources(); - int background = res.getColor(R.color.groups_available_background); + int background = res.getColor(R.color.forums_available_background); available.setBackgroundColor(background); - available.setPadding(pad, pad, pad, pad); available.setOnClickListener(this); available.setVisibility(GONE); layout.addView(available); @@ -122,21 +131,11 @@ implements EventListener, OnClickListener, OnItemClickListener { footer.setOrientation(HORIZONTAL); footer.setGravity(CENTER); footer.setBackgroundColor(res.getColor(R.color.button_bar_background)); - footer.addView(new ElasticHorizontalSpace(this)); - newGroupButton = new ImageButton(this); newGroupButton.setBackgroundResource(0); newGroupButton.setImageResource(R.drawable.social_new_chat); newGroupButton.setOnClickListener(this); footer.addView(newGroupButton); - footer.addView(new ElasticHorizontalSpace(this)); - - manageGroupsButton = new ImageButton(this); - manageGroupsButton.setBackgroundResource(0); - manageGroupsButton.setImageResource(R.drawable.action_settings); - manageGroupsButton.setOnClickListener(this); - footer.addView(manageGroupsButton); - footer.addView(new ElasticHorizontalSpace(this)); layout.addView(footer); setContentView(layout); @@ -154,26 +153,19 @@ implements EventListener, OnClickListener, OnItemClickListener { runOnDbThread(new Runnable() { public void run() { try { - int availableCount = 0; long now = System.currentTimeMillis(); - for(GroupStatus s : db.getAvailableGroups()) { - Group g = s.getGroup(); - if(s.isSubscribed()) { - try { - Collection<MessageHeader> headers = - db.getMessageHeaders(g.getId()); - displayHeaders(g, headers); - } catch(NoSuchSubscriptionException e) { - // Continue - } - } else { - availableCount++; + for(Group g : db.getGroups()) { + try { + displayHeaders(g, db.getMessageHeaders(g.getId())); + } catch(NoSuchSubscriptionException e) { + // Continue } } + int available = db.getAvailableGroups().size(); long duration = System.currentTimeMillis() - now; if(LOG.isLoggable(INFO)) LOG.info("Full load took " + duration + " ms"); - displayAvailable(availableCount); + displayAvailable(available); } catch(DbException e) { if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); @@ -226,7 +218,7 @@ implements EventListener, OnClickListener, OnItemClickListener { } else { available.setVisibility(VISIBLE); available.setText(getResources().getQuantityString( - R.plurals.forums_available, availableCount, + R.plurals.forums_shared, availableCount, availableCount)); } } @@ -279,9 +271,8 @@ implements EventListener, OnClickListener, OnItemClickListener { } else if(e instanceof SubscriptionRemovedEvent) { Group g = ((SubscriptionRemovedEvent) e).getGroup(); if(groups.containsKey(g.getId())) { - // Reload the group, expecting NoSuchSubscriptionException LOG.info("Group removed, reloading"); - loadHeaders(g); + loadHeaders(); } } } @@ -330,10 +321,8 @@ implements EventListener, OnClickListener, OnItemClickListener { runOnDbThread(new Runnable() { public void run() { try { - int available = 0; long now = System.currentTimeMillis(); - for(GroupStatus s : db.getAvailableGroups()) - if(!s.isSubscribed()) available++; + int available = db.getAvailableGroups().size(); long duration = System.currentTimeMillis() - now; if(LOG.isLoggable(INFO)) LOG.info("Loading available took " + duration + " ms"); @@ -348,11 +337,9 @@ implements EventListener, OnClickListener, OnItemClickListener { public void onClick(View view) { if(view == available) { - startActivity(new Intent(this, ManageGroupsActivity.class)); + startActivity(new Intent(this, AvailableGroupsActivity.class)); } else if(view == newGroupButton) { startActivity(new Intent(this, CreateGroupActivity.class)); - } else if(view == manageGroupsButton) { - startActivity(new Intent(this, ManageGroupsActivity.class)); } } @@ -364,4 +351,41 @@ implements EventListener, OnClickListener, OnItemClickListener { i.putExtra("briar.GROUP_NAME", g.getName()); startActivity(i); } + + @Override + public void onCreateContextMenu(ContextMenu menu, View view, + ContextMenu.ContextMenuInfo info) { + String delete = getString(R.string.unsubscribe); + menu.add(NONE, MENU_ITEM_UNSUBSCRIBE, NONE, delete); + } + + @Override + public boolean onContextItemSelected(MenuItem menuItem) { + if(menuItem.getItemId() == MENU_ITEM_UNSUBSCRIBE) { + ContextMenuInfo info = menuItem.getMenuInfo(); + int position = ((AdapterContextMenuInfo) info).position; + GroupListItem item = adapter.getItem(position); + removeSubscription(item.getGroup()); + String unsubscribed = getString(R.string.unsubscribed_toast); + Toast.makeText(this, unsubscribed, LENGTH_SHORT).show(); + } + return true; + } + + private void removeSubscription(final Group g) { + runOnDbThread(new Runnable() { + public void run() { + try { + long now = System.currentTimeMillis(); + db.removeGroup(g); + long duration = System.currentTimeMillis() - now; + if(LOG.isLoggable(INFO)) + LOG.info("Removing group took " + duration + " ms"); + } catch(DbException e) { + if(LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + }); + } } \ No newline at end of file ===================================== briar-android/src/org/briarproject/android/groups/GroupListAdapter.java ===================================== --- a/briar-android/src/org/briarproject/android/groups/GroupListAdapter.java +++ b/briar-android/src/org/briarproject/android/groups/GroupListAdapter.java @@ -55,7 +55,7 @@ class GroupListAdapter extends ArrayAdapter<GroupListItem> { TextView noPosts = new TextView(ctx); noPosts.setPadding(pad, 0, pad, pad); noPosts.setTextColor(res.getColor(R.color.no_posts)); - noPosts.setText(R.string.no_posts); + noPosts.setText(R.string.no_forum_posts); layout.addView(noPosts); } else { TextView date = new TextView(ctx); ===================================== briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.briarproject.android.groups; - -import static android.view.Gravity.CENTER; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; -import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH; - -import java.util.Collection; -import java.util.logging.Logger; - -import javax.inject.Inject; - -import org.briarproject.R; -import org.briarproject.android.BriarActivity; -import org.briarproject.android.util.ListLoadingProgressBar; -import org.briarproject.api.db.DatabaseComponent; -import org.briarproject.api.db.DbException; -import org.briarproject.api.event.Event; -import org.briarproject.api.event.EventBus; -import org.briarproject.api.event.EventListener; -import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent; -import org.briarproject.api.event.SubscriptionAddedEvent; -import org.briarproject.api.event.SubscriptionRemovedEvent; -import org.briarproject.api.messaging.Group; -import org.briarproject.api.messaging.GroupStatus; - -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; -import android.widget.TextView; - -public class ManageGroupsActivity extends BriarActivity -implements EventListener, OnItemClickListener { - - private static final Logger LOG = - Logger.getLogger(ManageGroupsActivity.class.getName()); - - private TextView empty = null; - private ManageGroupsAdapter adapter = null; - private ListView list = null; - private ListLoadingProgressBar loading = null; - - // Fields that are accessed from background threads must be volatile - @Inject private volatile DatabaseComponent db; - @Inject private volatile EventBus eventBus; - - @Override - public void onCreate(Bundle state) { - super.onCreate(state); - - empty = new TextView(this); - empty.setLayoutParams(MATCH_MATCH); - empty.setGravity(CENTER); - empty.setTextSize(18); - empty.setText(R.string.no_forums_available); - - adapter = new ManageGroupsAdapter(this); - list = new ListView(this); - list.setLayoutParams(MATCH_MATCH); - list.setAdapter(adapter); - list.setOnItemClickListener(this); - - // Show a progress bar while the list is loading - loading = new ListLoadingProgressBar(this); - setContentView(loading); - } - - @Override - public void onResume() { - super.onResume(); - eventBus.addListener(this); - loadGroups(); - } - - private void loadGroups() { - runOnDbThread(new Runnable() { - public void run() { - try { - long now = System.currentTimeMillis(); - Collection<GroupStatus> available = db.getAvailableGroups(); - long duration = System.currentTimeMillis() - now; - if(LOG.isLoggable(INFO)) - LOG.info("Load took " + duration + " ms"); - displayGroups(available); - } catch(DbException e) { - if(LOG.isLoggable(WARNING)) - LOG.log(WARNING, e.toString(), e); - } - } - }); - } - - private void displayGroups(final Collection<GroupStatus> available) { - runOnUiThread(new Runnable() { - public void run() { - if(available.isEmpty()) { - setContentView(empty); - } else { - setContentView(list); - adapter.clear(); - for(GroupStatus s : available) - adapter.add(new ManageGroupsItem(s)); - adapter.sort(ManageGroupsItemComparator.INSTANCE); - adapter.notifyDataSetChanged(); - } - } - }); - } - - @Override - public void onPause() { - super.onPause(); - eventBus.removeListener(this); - } - - public void eventOccurred(Event e) { - if(e instanceof RemoteSubscriptionsUpdatedEvent) { - LOG.info("Remote subscriptions changed, reloading"); - loadGroups(); - } else if(e instanceof SubscriptionAddedEvent) { - LOG.info("Group added, reloading"); - loadGroups(); - } else if(e instanceof SubscriptionRemovedEvent) { - LOG.info("Group removed, reloading"); - loadGroups(); - } - } - - public void onItemClick(AdapterView<?> parent, View view, int position, - long id) { - ManageGroupsItem item = adapter.getItem(position); - GroupStatus s = item.getGroupStatus(); - Group g = s.getGroup(); - Intent i = new Intent(this, ConfigureGroupActivity.class); - i.putExtra("briar.GROUP_ID", g.getId().getBytes()); - i.putExtra("briar.GROUP_NAME", g.getName()); - i.putExtra("briar.GROUP_SALT", g.getSalt()); - i.putExtra("briar.SUBSCRIBED", s.isSubscribed()); - i.putExtra("briar.VISIBLE_TO_ALL", s.isVisibleToAll()); - startActivity(i); - } -} ===================================== briar-android/src/org/briarproject/android/groups/ManageGroupsAdapter.java ===================================== --- a/briar-android/src/org/briarproject/android/groups/ManageGroupsAdapter.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.briarproject.android.groups; - -import static android.text.TextUtils.TruncateAt.END; -import static android.view.View.INVISIBLE; -import static android.widget.LinearLayout.HORIZONTAL; -import static android.widget.LinearLayout.VERTICAL; - -import java.util.ArrayList; - -import org.briarproject.R; -import org.briarproject.android.util.LayoutUtils; -import org.briarproject.api.messaging.GroupStatus; - -import android.content.Context; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -class ManageGroupsAdapter extends ArrayAdapter<ManageGroupsItem> { - - private final int pad; - - ManageGroupsAdapter(Context ctx) {... [truncated message content] |
From: akwizgran <gi...@br...> - 2015-04-16 07:03:55
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="6135bea2" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/6135bea2b435823fb4f858002e6761cfad4f00f7">6135bea2</a> by akwizgran Support Tor on Android x86 (thanks to n8fr8). - - - - - Changes: ===================================== briar-android/assets/tor-arm-pie.zip ===================================== Binary files /dev/null and b/briar-android/assets/tor-arm-pie.zip differ ===================================== briar-android/assets/tor-arm.zip ===================================== Binary files /dev/null and b/briar-android/assets/tor-arm.zip differ ===================================== briar-android/assets/tor-pie.zip ===================================== Binary files a/briar-android/assets/tor-pie.zip and /dev/null differ ===================================== briar-android/assets/tor-x86-pie.zip ===================================== Binary files /dev/null and b/briar-android/assets/tor-x86-pie.zip differ ===================================== briar-android/assets/tor-x86.zip ===================================== Binary files /dev/null and b/briar-android/assets/tor-x86.zip differ ===================================== briar-android/assets/tor.zip ===================================== Binary files a/briar-android/assets/tor.zip and /dev/null differ ===================================== briar-android/src/org/briarproject/android/CrashReportActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/CrashReportActivity.java +++ b/briar-android/src/org/briarproject/android/CrashReportActivity.java @@ -27,6 +27,7 @@ import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; @@ -38,6 +39,7 @@ import java.util.logging.Logger; import java.util.regex.Pattern; import org.briarproject.R; +import org.briarproject.android.util.AndroidUtils; import org.briarproject.android.util.HorizontalBorder; import org.briarproject.android.util.LayoutUtils; import org.briarproject.android.util.ListLoadingProgressBar; @@ -181,7 +183,6 @@ public class CrashReportActivity extends Activity implements OnClickListener { // FIXME: Load strings from resources if we're keeping this activity @SuppressLint("NewApi") - @SuppressWarnings("deprecation") private Map<String, String> getStatusMap() { Map<String, String> statusMap = new LinkedHashMap<String, String>(); @@ -202,19 +203,9 @@ public class CrashReportActivity extends Activity implements OnClickListener { statusMap.put("Android version:", release + " (" + sdk + ")"); // CPU architectures - String arch = null; - if(Build.VERSION.SDK_INT >= 21) { - for(String abi : Build.SUPPORTED_ABIS) { - if(arch == null) arch = abi; - else arch = arch + ", " + abi; - } - } else if(Build.VERSION.SDK_INT >= 8) { - if(Build.CPU_ABI2 == null) arch = Build.CPU_ABI; - else arch = Build.CPU_ABI + ", " + Build.CPU_ABI2; - } else { - arch = Build.CPU_ABI; - } - statusMap.put("Architecture:", arch); + Collection<String> abis = AndroidUtils.getSupportedArchitectures(); + String joined = StringUtils.join(abis, ", "); + statusMap.put("Architecture:", joined); // System memory Object o = getSystemService(ACTIVITY_SERVICE); ===================================== briar-android/src/org/briarproject/android/TestingActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/TestingActivity.java +++ b/briar-android/src/org/briarproject/android/TestingActivity.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; @@ -39,6 +40,7 @@ import java.util.regex.Pattern; import javax.inject.Inject; import org.briarproject.R; +import org.briarproject.android.util.AndroidUtils; import org.briarproject.android.util.ElasticHorizontalSpace; import org.briarproject.android.util.HorizontalBorder; import org.briarproject.android.util.LayoutUtils; @@ -192,7 +194,6 @@ public class TestingActivity extends BriarActivity implements OnClickListener { // FIXME: Load strings from resources if we're keeping this activity @SuppressLint("NewApi") - @SuppressWarnings("deprecation") private Map<String, String> getStatusMap() { Map<String, String> statusMap = new LinkedHashMap<String, String>(); @@ -212,18 +213,10 @@ public class TestingActivity extends BriarActivity implements OnClickListener { int sdk = Build.VERSION.SDK_INT; statusMap.put("Android version:", release + " (" + sdk + ")"); - // CPU architecture - String arch = null; - if(Build.VERSION.SDK_INT >= 21) { - for(String abi : Build.SUPPORTED_ABIS) { - if(arch == null) arch = abi; - else arch = arch + ", " + abi; - } - } else { - if(Build.CPU_ABI2 == null) arch = Build.CPU_ABI; - else arch = Build.CPU_ABI + ", " + Build.CPU_ABI2; - } - statusMap.put("Architecture:", arch); + // CPU architectures + Collection<String> abis = AndroidUtils.getSupportedArchitectures(); + String joined = StringUtils.join(abis, ", "); + statusMap.put("Architecture:", joined); // System memory Object o = getSystemService(ACTIVITY_SERVICE); ===================================== briar-android/src/org/briarproject/android/util/AndroidUtils.java ===================================== --- /dev/null +++ b/briar-android/src/org/briarproject/android/util/AndroidUtils.java @@ -0,0 +1,27 @@ +package org.briarproject.android.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import android.annotation.SuppressLint; +import android.os.Build; + +public class AndroidUtils { + + @SuppressLint("NewApi") + @SuppressWarnings("deprecation") + public static Collection<String> getSupportedArchitectures() { + List<String> abis = new ArrayList<String>(); + if(Build.VERSION.SDK_INT >= 21) { + for(String abi : Build.SUPPORTED_ABIS) abis.add(abi); + } else if(Build.VERSION.SDK_INT >= 8) { + abis.add(Build.CPU_ABI); + if(Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2); + } else { + abis.add(Build.CPU_ABI); + } + return Collections.unmodifiableList(abis); + } +} ===================================== briar-android/src/org/briarproject/plugins/tor/TorPlugin.java ===================================== --- a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java +++ b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java @@ -75,6 +75,7 @@ class TorPlugin implements DuplexPlugin, EventHandler { private final Context appContext; private final LocationUtils locationUtils; private final DuplexPluginCallback callback; + private final String architecture; private final int maxLatency, maxIdleTime, pollingInterval, socketTimeout; private final File torDirectory, torFile, geoIpFile, configFile, doneFile; private final File cookieFile, hostnameFile; @@ -89,11 +90,13 @@ class TorPlugin implements DuplexPlugin, EventHandler { TorPlugin(Executor ioExecutor, Context appContext, LocationUtils locationUtils, DuplexPluginCallback callback, - int maxLatency, int maxIdleTime, int pollingInterval) { + String architecture, int maxLatency, int maxIdleTime, + int pollingInterval) { this.ioExecutor = ioExecutor; this.appContext = appContext; this.locationUtils = locationUtils; this.callback = callback; + this.architecture = architecture; this.maxLatency = maxLatency; this.maxIdleTime = maxIdleTime; this.pollingInterval = pollingInterval; @@ -266,14 +269,9 @@ class TorPlugin implements DuplexPlugin, EventHandler { } private InputStream getTorInputStream() throws IOException { - String filename; - if(Build.VERSION.SDK_INT >= 16) { - LOG.info("Installing PIE Tor binary"); - filename = "tor-pie.zip"; - } else { - LOG.info("Installing non-PIE Tor binary"); - filename = "tor.zip"; - } + if(LOG.isLoggable(INFO)) + LOG.info("Installing Tor binary for " + architecture); + String filename = "tor-" + architecture + ".zip"; InputStream in = appContext.getResources().getAssets().open(filename); ZipInputStream zin = new ZipInputStream(in); if(zin.getNextEntry() == null) throw new IOException(); ===================================== briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java ===================================== --- a/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java +++ b/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java @@ -1,17 +1,15 @@ package org.briarproject.plugins.tor; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.Executor; import java.util.logging.Logger; +import org.briarproject.android.util.AndroidUtils; import org.briarproject.api.TransportId; import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPluginCallback; import org.briarproject.api.plugins.duplex.DuplexPluginFactory; import org.briarproject.api.system.LocationUtils; -import android.annotation.SuppressLint; import android.content.Context; import android.os.Build; @@ -39,26 +37,25 @@ public class TorPluginFactory implements DuplexPluginFactory { return TorPlugin.ID; } - @SuppressLint("NewApi") - @SuppressWarnings("deprecation") public DuplexPlugin createPlugin(DuplexPluginCallback callback) { // Check that we have a Tor binary for this architecture - List<String> abis = new ArrayList<String>(); - if(Build.VERSION.SDK_INT >= 21) { - for(String abi : Build.SUPPORTED_ABIS) abis.add(abi); - } else if(Build.VERSION.SDK_INT >= 8) { - abis.add(Build.CPU_ABI); - if(Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2); - } else { - abis.add(Build.CPU_ABI); + String architecture = null; + for(String abi : AndroidUtils.getSupportedArchitectures()) { + if(abi.startsWith("x86")) { + architecture = "x86"; + break; + } else if(abi.startsWith("armeabi")) { + architecture = "arm"; + break; + } } - boolean supported = false; - for(String abi : abis) if(abi.startsWith("armeabi")) supported = true; - if(!supported) { + if(architecture == null) { LOG.info("Tor is not supported on this architecture"); return null; } + // Use position-independent executable for SDK >= 16 + if(Build.VERSION.SDK_INT >= 16) architecture += "-pie"; return new TorPlugin(ioExecutor,appContext, locationUtils, callback, - MAX_LATENCY, MAX_IDLE_TIME, POLLING_INTERVAL); + architecture, MAX_LATENCY, MAX_IDLE_TIME, POLLING_INTERVAL); } } ===================================== briar-core/src/org/briarproject/util/StringUtils.java ===================================== --- a/briar-core/src/org/briarproject/util/StringUtils.java +++ b/briar-core/src/org/briarproject/util/StringUtils.java @@ -1,6 +1,7 @@ package org.briarproject.util; import java.io.UnsupportedEncodingException; +import java.util.Collection; public class StringUtils { @@ -13,6 +14,15 @@ public class StringUtils { return s == null || s.length() == 0; } + public static String join(Collection<String> strings, String separator) { + StringBuilder joined = new StringBuilder(); + for(String s : strings) { + if(joined.length() > 0) joined.append(separator); + joined.append(s); + } + return joined.toString(); + } + public static byte[] toUtf8(String s) { try { return s.getBytes("UTF-8"); |
From: akwizgran <gi...@br...> - 2015-04-08 07:51:31
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="18503af6" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/18503af66553f6367e0efc891de2e822826d84b0">18503af6</a> by akwizgran Updated Bouncy Castle source jar. - - - - - <a href="aa70900e" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/aa70900ed9d7db95a8c4ca2b0651617113ee787c">aa70900e</a> by akwizgran Fixed Eclipse classpath to export new Bouncy Castle jar. - - - - - <a href="92d26f78" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/92d26f7867d65fa16779ac9d90624aec73cbaa44">92d26f78</a> by akwizgran Use strict mode to log potential problems with testing builds. - - - - - Changes: ===================================== briar-android/.classpath ===================================== --- a/briar-android/.classpath +++ b/briar-android/.classpath @@ -2,15 +2,15 @@ <classpath> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="gen"/> - <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> - <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> <classpathentry combineaccessrules="false" exported="true" kind="src" path="/briar-core"/> <classpathentry combineaccessrules="false" exported="true" kind="src" path="/briar-api"/> <classpathentry exported="true" kind="lib" path="/briar-api/libs/guice-3.0-no_aop.jar"/> - <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/> <classpathentry exported="true" kind="lib" path="/briar-api/libs/javax.inject.jar"/> <classpathentry exported="true" kind="lib" path="/briar-core/libs/h2small-1.3.170.jar"/> <classpathentry exported="true" kind="lib" path="/briar-core/libs/weupnp-0.1.3-SNAPSHOT-briar.jar"/> - <classpathentry kind="lib" path="/briar-core/libs/lcrypto-jdk15on-152.jar"/> + <classpathentry exported="true" kind="lib" path="/briar-core/libs/lcrypto-jdk15on-152.jar"/> + <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> + <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/> + <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> <classpathentry kind="output" path="bin/classes"/> </classpath> ===================================== briar-android/src/org/briarproject/android/SplashScreenActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/SplashScreenActivity.java +++ b/briar-android/src/org/briarproject/android/SplashScreenActivity.java @@ -5,6 +5,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static java.util.logging.Level.INFO; import static org.briarproject.android.TestingConstants.DEFAULT_LOG_LEVEL; import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS; +import static org.briarproject.android.TestingConstants.TESTING; import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH; import java.io.File; @@ -16,10 +17,15 @@ import org.briarproject.api.db.DatabaseConfig; import roboguice.RoboGuice; import roboguice.activity.RoboSplashActivity; +import android.annotation.SuppressLint; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; +import android.os.Build; import android.os.Bundle; +import android.os.StrictMode; +import android.os.StrictMode.ThreadPolicy; +import android.os.StrictMode.VmPolicy; import android.widget.ImageView; import android.widget.LinearLayout; @@ -37,6 +43,7 @@ public class SplashScreenActivity extends RoboSplashActivity { public SplashScreenActivity() { Logger.getLogger("").setLevel(DEFAULT_LOG_LEVEL); + enableStrictMode(); minDisplayMs = 500; } @@ -84,6 +91,20 @@ public class SplashScreenActivity extends RoboSplashActivity { } } + @SuppressLint("NewApi") + private void enableStrictMode() { + if(TESTING && Build.VERSION.SDK_INT >= 9) { + ThreadPolicy.Builder threadPolicy = new ThreadPolicy.Builder(); + threadPolicy.detectAll(); + threadPolicy.penaltyLog(); + StrictMode.setThreadPolicy(threadPolicy.build()); + VmPolicy.Builder vmPolicy = new VmPolicy.Builder(); + vmPolicy.detectAll(); + vmPolicy.penaltyLog(); + StrictMode.setVmPolicy(vmPolicy.build()); + } + } + private void delete(File f) { if(f.isFile()) f.delete(); else if(f.isDirectory()) for(File child : f.listFiles()) delete(child); ===================================== briar-android/src/org/briarproject/android/TestingConstants.java ===================================== --- a/briar-android/src/org/briarproject/android/TestingConstants.java +++ b/briar-android/src/org/briarproject/android/TestingConstants.java @@ -1,31 +1,34 @@ package org.briarproject.android; import static java.util.logging.Level.INFO; +import static java.util.logging.Level.OFF; import java.util.logging.Level; interface TestingConstants { - /** Default log level - this should be OFF for release builds. */ - Level DEFAULT_LOG_LEVEL = INFO; - /** - * Whether to prevent screenshots from being taken. This should be true for - * release builds, to prevent Recent Apps from storing screenshots of - * private information. Unfortunately this also prevents the user from - * taking screenshots intentionally. + * Whether this is an alpha or beta build. This should be set to false for + * release builds. */ - boolean PREVENT_SCREENSHOTS = false; + boolean TESTING = true; + + /** Default log level. */ + Level DEFAULT_LOG_LEVEL = TESTING ? INFO : OFF; /** - * Whether to allow TestingActivity to be launched from SettingsActivity. - * This should be false for release builds. + * Whether to prevent screenshots from being taken. Setting this to true + * prevents Recent Apps from storing screenshots of private information. + * Unfortunately this also prevents the user from taking screenshots + * intentionally. */ - boolean SHOW_TESTING_ACTIVITY = true; + boolean PREVENT_SCREENSHOTS = TESTING ? false : true; /** - * Whether to allow crash reports to be submitted by email. This should - * be false for release builds. + * Whether to allow TestingActivity to be launched from SettingsActivity. */ - boolean SHARE_CRASH_REPORTS = true; + boolean SHOW_TESTING_ACTIVITY = TESTING ? true : false; + + /** Whether to allow crash reports to be submitted by email. */ + boolean SHARE_CRASH_REPORTS = TESTING ? true : false; } ===================================== briar-core/.classpath ===================================== --- a/briar-core/.classpath +++ b/briar-core/.classpath @@ -7,6 +7,6 @@ <classpathentry kind="lib" path="libs/h2small-1.3.170.jar"/> <classpathentry kind="lib" path="libs/weupnp-0.1.3-SNAPSHOT-briar.jar"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> - <classpathentry kind="lib" path="libs/lcrypto-jdk15on-152.jar"/> + <classpathentry kind="lib" path="libs/lcrypto-jdk15on-152.jar" sourcepath="libs/source/lcrypto-jdk15on-152-src.jar"/> <classpathentry kind="output" path="bin"/> </classpath> ===================================== briar-core/libs/source/lcrypto-jdk15on-151-source.jar ===================================== Binary files a/briar-core/libs/source/lcrypto-jdk15on-151-source.jar and /dev/null differ ===================================== briar-core/libs/source/lcrypto-jdk15on-152-src.jar ===================================== Binary files /dev/null and b/briar-core/libs/source/lcrypto-jdk15on-152-src.jar differ |
From: akwizgran <gi...@br...> - 2015-04-07 22:02:14
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="8f068807" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/8f06880708b6b348260898d8ec6b68d064eff97e">8f068807</a> by akwizgran Upgraded Tor to 0.2.5.12 with libevent 2.0.22. - - - - - Changes: ===================================== briar-android/assets/tor-pie.zip ===================================== Binary files a/briar-android/assets/tor-pie.zip and b/briar-android/assets/tor-pie.zip differ ===================================== briar-android/assets/tor.zip ===================================== Binary files a/briar-android/assets/tor.zip and b/briar-android/assets/tor.zip differ |
From: akwizgran <gi...@br...> - 2015-04-07 18:17:22
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="f2d3e4cb" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/f2d3e4cb8111966f0371ae9541e930a3c12f93a8">f2d3e4cb</a> by akwizgran Remove crash handler when handling first crash. Fixes bug #76. - - - - - <a href="6e7578a0" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/6e7578a0e08abdd38c9d8114308e0737c2b99346">6e7578a0</a> by akwizgran Don't try to access Build.CPU_ABI2 on API version 7. - - - - - Changes: ===================================== briar-android/src/org/briarproject/android/CrashHandler.java ===================================== --- a/briar-android/src/org/briarproject/android/CrashHandler.java +++ b/briar-android/src/org/briarproject/android/CrashHandler.java @@ -26,6 +26,8 @@ class CrashHandler implements UncaughtExceptionHandler { public void uncaughtException(Thread thread, Throwable throwable) { LOG.log(WARNING, "Uncaught exception", throwable); + // Don't handle more than one exception + Thread.setDefaultUncaughtExceptionHandler(delegate); // Get the stack trace StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); ===================================== briar-android/src/org/briarproject/android/CrashReportActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/CrashReportActivity.java +++ b/briar-android/src/org/briarproject/android/CrashReportActivity.java @@ -201,16 +201,18 @@ public class CrashReportActivity extends Activity implements OnClickListener { int sdk = Build.VERSION.SDK_INT; statusMap.put("Android version:", release + " (" + sdk + ")"); - // CPU architecture + // CPU architectures String arch = null; if(Build.VERSION.SDK_INT >= 21) { for(String abi : Build.SUPPORTED_ABIS) { if(arch == null) arch = abi; else arch = arch + ", " + abi; } - } else { + } else if(Build.VERSION.SDK_INT >= 8) { if(Build.CPU_ABI2 == null) arch = Build.CPU_ABI; else arch = Build.CPU_ABI + ", " + Build.CPU_ABI2; + } else { + arch = Build.CPU_ABI; } statusMap.put("Architecture:", arch); ===================================== briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java ===================================== --- a/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java +++ b/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java @@ -46,9 +46,11 @@ public class TorPluginFactory implements DuplexPluginFactory { List<String> abis = new ArrayList<String>(); if(Build.VERSION.SDK_INT >= 21) { for(String abi : Build.SUPPORTED_ABIS) abis.add(abi); - } else { + } else if(Build.VERSION.SDK_INT >= 8) { abis.add(Build.CPU_ABI); if(Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2); + } else { + abis.add(Build.CPU_ABI); } boolean supported = false; for(String abi : abis) if(abi.startsWith("armeabi")) supported = true; |
From: akwizgran <gi...@br...> - 2015-04-05 16:42:58
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="e4a79b81" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/e4a79b8125e4ca144c1779ef77769d848fbf7787">e4a79b81</a> by akwizgran Bumped APK version to 0.8. - - - - - Changes: ===================================== briar-android/AndroidManifest.xml ===================================== --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.briarproject" - android:versionCode="7" - android:versionName="0.7" > + android:versionCode="8" + android:versionName="0.8" > <uses-sdk android:minSdkVersion="7" |
From: akwizgran <gi...@br...> - 2015-04-05 16:38:19
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="84596bad" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/84596baddb9f0db1a6da207901921bcb1f82e273">84596bad</a> by akwizgran Bumped expiry date to 1 May 2015. - - - - - Changes: ===================================== briar-android/src/org/briarproject/android/SplashScreenActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/SplashScreenActivity.java +++ b/briar-android/src/org/briarproject/android/SplashScreenActivity.java @@ -30,8 +30,8 @@ public class SplashScreenActivity extends RoboSplashActivity { private static final Logger LOG = Logger.getLogger(SplashScreenActivity.class.getName()); - // This build expires on 1 April 2015 - private static final long EXPIRY_DATE = 1427846400 * 1000L; + // This build expires on 1 May 2015 + private static final long EXPIRY_DATE = 1430438400 * 1000L; private long now = System.currentTimeMillis(); |
From: akwizgran <gi...@br...> - 2015-04-04 12:20:50
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="b558218d" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/b558218d4845c16f837296954388d7a909fbabc1">b558218d</a> by akwizgran Upgraded Bouncy Castle to 1.52. - - - - - <a href="56f24d46" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/56f24d462ea38aaba0337605f5fe0affa5490fab">56f24d46</a> by akwizgran Change target of gradle build to Android 5.1. - - - - - Changes: ===================================== briar-android/.classpath ===================================== --- a/briar-android/.classpath +++ b/briar-android/.classpath @@ -10,7 +10,7 @@ <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/> <classpathentry exported="true" kind="lib" path="/briar-api/libs/javax.inject.jar"/> <classpathentry exported="true" kind="lib" path="/briar-core/libs/h2small-1.3.170.jar"/> - <classpathentry exported="true" kind="lib" path="/briar-core/libs/lcrypto-jdk15on-151.jar" sourcepath="/briar-core/libs/source/lcrypto-jdk15on-151-source.jar"/> <classpathentry exported="true" kind="lib" path="/briar-core/libs/weupnp-0.1.3-SNAPSHOT-briar.jar"/> + <classpathentry kind="lib" path="/briar-core/libs/lcrypto-jdk15on-152.jar"/> <classpathentry kind="output" path="bin/classes"/> </classpath> ===================================== briar-android/build.gradle ===================================== --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -9,8 +9,8 @@ dependencies { } android { - compileSdkVersion 20 - buildToolsVersion "20.0.0" + compileSdkVersion 22 + buildToolsVersion "22.0.1" sourceSets { main { ===================================== briar-core/.classpath ===================================== --- a/briar-core/.classpath +++ b/briar-core/.classpath @@ -3,10 +3,10 @@ <classpathentry kind="src" path="src"/> <classpathentry combineaccessrules="false" kind="src" path="/briar-api"/> <classpathentry kind="lib" path="/briar-api/libs/guice-3.0-no_aop.jar"/> - <classpathentry kind="lib" path="libs/lcrypto-jdk15on-151.jar"/> <classpathentry kind="lib" path="/briar-api/libs/javax.inject.jar"/> <classpathentry kind="lib" path="libs/h2small-1.3.170.jar"/> <classpathentry kind="lib" path="libs/weupnp-0.1.3-SNAPSHOT-briar.jar"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="lib" path="libs/lcrypto-jdk15on-152.jar"/> <classpathentry kind="output" path="bin"/> </classpath> ===================================== briar-core/libs/lcrypto-jdk15on-151.jar ===================================== Binary files a/briar-core/libs/lcrypto-jdk15on-151.jar and /dev/null differ ===================================== briar-core/libs/lcrypto-jdk15on-152.jar ===================================== Binary files /dev/null and b/briar-core/libs/lcrypto-jdk15on-152.jar differ ===================================== briar-tests/.classpath ===================================== --- a/briar-tests/.classpath +++ b/briar-tests/.classpath @@ -11,7 +11,7 @@ <classpathentry kind="lib" path="libs/hamcrest-library-1.1.jar"/> <classpathentry kind="lib" path="libs/jmock-2.5.1.jar"/> <classpathentry kind="lib" path="libs/junit-4.9b3.jar"/> - <classpathentry kind="lib" path="/briar-core/libs/lcrypto-jdk15on-151.jar"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="lib" path="/briar-core/libs/lcrypto-jdk15on-152.jar"/> <classpathentry kind="output" path="bin"/> </classpath> |
From: akwizgran <gi...@br...> - 2015-04-03 20:57:02
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="a1d2aaf1" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/a1d2aaf10eea5076929792dddd2d842a03ab4c5b">a1d2aaf1</a> by akwizgran Use JDK 1.7, target Android 5.1. - - - - - Changes: ===================================== briar-android/AndroidManifest.xml ===================================== --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -6,7 +6,7 @@ <uses-sdk android:minSdkVersion="7" - android:targetSdkVersion="20" + android:targetSdkVersion="22" /> <uses-feature android:name="android.hardware.bluetooth" /> ===================================== briar-android/project.properties ===================================== --- a/briar-android/project.properties +++ b/briar-android/project.properties @@ -11,4 +11,4 @@ #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. -target=android-20 +target=android-22 ===================================== briar-android/src/org/briarproject/android/CrashReportActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/CrashReportActivity.java +++ b/briar-android/src/org/briarproject/android/CrashReportActivity.java @@ -154,10 +154,12 @@ public class CrashReportActivity extends Activity implements OnClickListener { progress.setVisibility(VISIBLE); new AsyncTask<Void, Void, Map<String, String>>() { + @Override protected Map<String, String> doInBackground(Void... args) { return getStatusMap(); } + @Override protected void onPostExecute(Map<String, String> result) { Context ctx = CrashReportActivity.this; int pad = LayoutUtils.getPadding(ctx); @@ -179,6 +181,7 @@ public class CrashReportActivity extends Activity implements OnClickListener { // FIXME: Load strings from resources if we're keeping this activity @SuppressLint("NewApi") + @SuppressWarnings("deprecation") private Map<String, String> getStatusMap() { Map<String, String> statusMap = new LinkedHashMap<String, String>(); @@ -199,7 +202,17 @@ public class CrashReportActivity extends Activity implements OnClickListener { statusMap.put("Android version:", release + " (" + sdk + ")"); // CPU architecture - statusMap.put("Architecture:", Build.CPU_ABI); + String arch = null; + if(Build.VERSION.SDK_INT >= 21) { + for(String abi : Build.SUPPORTED_ABIS) { + if(arch == null) arch = abi; + else arch = arch + ", " + abi; + } + } else { + if(Build.CPU_ABI2 == null) arch = Build.CPU_ABI; + else arch = Build.CPU_ABI + ", " + Build.CPU_ABI2; + } + statusMap.put("Architecture:", arch); // System memory Object o = getSystemService(ACTIVITY_SERVICE); @@ -392,10 +405,12 @@ public class CrashReportActivity extends Activity implements OnClickListener { private void share() { new AsyncTask<Void, Void, Map<String, String>>() { + @Override protected Map<String, String> doInBackground(Void... args) { return getStatusMap(); } + @Override protected void onPostExecute(Map<String, String> result) { try { File shared = Environment.getExternalStorageDirectory(); ===================================== briar-android/src/org/briarproject/android/TestingActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/TestingActivity.java +++ b/briar-android/src/org/briarproject/android/TestingActivity.java @@ -165,10 +165,12 @@ public class TestingActivity extends BriarActivity implements OnClickListener { progress.setVisibility(VISIBLE); new AsyncTask<Void, Void, Map<String, String>>() { + @Override protected Map<String, String> doInBackground(Void... args) { return getStatusMap(); } + @Override protected void onPostExecute(Map<String, String> result) { int pad = LayoutUtils.getPadding(TestingActivity.this); for(Entry<String, String> e : result.entrySet()) { @@ -190,6 +192,7 @@ public class TestingActivity extends BriarActivity implements OnClickListener { // FIXME: Load strings from resources if we're keeping this activity @SuppressLint("NewApi") + @SuppressWarnings("deprecation") private Map<String, String> getStatusMap() { Map<String, String> statusMap = new LinkedHashMap<String, String>(); @@ -210,7 +213,17 @@ public class TestingActivity extends BriarActivity implements OnClickListener { statusMap.put("Android version:", release + " (" + sdk + ")"); // CPU architecture - statusMap.put("Architecture:", Build.CPU_ABI); + String arch = null; + if(Build.VERSION.SDK_INT >= 21) { + for(String abi : Build.SUPPORTED_ABIS) { + if(arch == null) arch = abi; + else arch = arch + ", " + abi; + } + } else { + if(Build.CPU_ABI2 == null) arch = Build.CPU_ABI; + else arch = Build.CPU_ABI + ", " + Build.CPU_ABI2; + } + statusMap.put("Architecture:", arch); // System memory Object o = getSystemService(ACTIVITY_SERVICE); @@ -452,10 +465,12 @@ public class TestingActivity extends BriarActivity implements OnClickListener { private void share() { new AsyncTask<Void, Void, Map<String, String>>() { + @Override protected Map<String, String> doInBackground(Void... args) { return getStatusMap(); } + @Override protected void onPostExecute(Map<String, String> result) { try { File shared = Environment.getExternalStorageDirectory(); ===================================== briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java ===================================== --- a/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java +++ b/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java @@ -1,5 +1,7 @@ package org.briarproject.plugins.tor; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.Executor; import java.util.logging.Logger; @@ -9,6 +11,7 @@ import org.briarproject.api.plugins.duplex.DuplexPluginCallback; import org.briarproject.api.plugins.duplex.DuplexPluginFactory; import org.briarproject.api.system.LocationUtils; +import android.annotation.SuppressLint; import android.content.Context; import android.os.Build; @@ -36,9 +39,20 @@ public class TorPluginFactory implements DuplexPluginFactory { return TorPlugin.ID; } + @SuppressLint("NewApi") + @SuppressWarnings("deprecation") public DuplexPlugin createPlugin(DuplexPluginCallback callback) { // Check that we have a Tor binary for this architecture - if(!Build.CPU_ABI.startsWith("armeabi")) { + List<String> abis = new ArrayList<String>(); + if(Build.VERSION.SDK_INT >= 21) { + for(String abi : Build.SUPPORTED_ABIS) abis.add(abi); + } else { + abis.add(Build.CPU_ABI); + if(Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2); + } + boolean supported = false; + for(String abi : abis) if(abi.startsWith("armeabi")) supported = true; + if(!supported) { LOG.info("Tor is not supported on this architecture"); return null; } ===================================== briar-api/.classpath ===================================== --- a/briar-api/.classpath +++ b/briar-api/.classpath @@ -2,6 +2,6 @@ <classpath> <classpathentry kind="src" path="src"/> <classpathentry kind="lib" path="libs/guice-3.0-no_aop.jar"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> <classpathentry kind="output" path="bin"/> </classpath> ===================================== briar-core/.classpath ===================================== --- a/briar-core/.classpath +++ b/briar-core/.classpath @@ -4,9 +4,9 @@ <classpathentry combineaccessrules="false" kind="src" path="/briar-api"/> <classpathentry kind="lib" path="/briar-api/libs/guice-3.0-no_aop.jar"/> <classpathentry kind="lib" path="libs/lcrypto-jdk15on-151.jar"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> <classpathentry kind="lib" path="/briar-api/libs/javax.inject.jar"/> <classpathentry kind="lib" path="libs/h2small-1.3.170.jar"/> <classpathentry kind="lib" path="libs/weupnp-0.1.3-SNAPSHOT-briar.jar"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> <classpathentry kind="output" path="bin"/> </classpath> ===================================== briar-desktop/.classpath ===================================== --- a/briar-desktop/.classpath +++ b/briar-desktop/.classpath @@ -10,6 +10,6 @@ <classpathentry kind="lib" path="libs/jssc-0.9-briar.jar" sourcepath="libs/source/jssc-0.9-briar-source.jar"/> <classpathentry kind="lib" path="libs/jna-4.1.0.jar"/> <classpathentry kind="lib" path="libs/jna-platform-4.1.0.jar"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> <classpathentry kind="output" path="bin"/> </classpath> ===================================== briar-tests/.classpath ===================================== --- a/briar-tests/.classpath +++ b/briar-tests/.classpath @@ -11,7 +11,7 @@ <classpathentry kind="lib" path="libs/hamcrest-library-1.1.jar"/> <classpathentry kind="lib" path="libs/jmock-2.5.1.jar"/> <classpathentry kind="lib" path="libs/junit-4.9b3.jar"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> <classpathentry kind="lib" path="/briar-core/libs/lcrypto-jdk15on-151.jar"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> <classpathentry kind="output" path="bin"/> </classpath> |
From: akwizgran <gi...@br...> - 2015-03-23 11:06:18
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="b791ce02" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/b791ce02b60b2c7197946e04c30c4e1cccffa857">b791ce02</a> by akwizgran Insert padding between password strength meter and progress spinner. - - - - - <a href="0be467f4" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/0be467f4f502c49ace37ded94c76de4357244136">0be467f4</a> by akwizgran Updated Tor GeoIP database. - - - - - <a href="10924709" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/10924709d0ebd8fe90b82584b09918a97520f74c">10924709</a> by akwizgran Use PIE Tor binary on API version 16+. - - - - - Changes: ===================================== briar-android/AndroidManifest.xml ===================================== --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -7,7 +7,6 @@ <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="20" - android:maxSdkVersion="20" /> <uses-feature android:name="android.hardware.bluetooth" /> ===================================== briar-android/assets/geoip.zip ===================================== Binary files a/briar-android/assets/geoip.zip and b/briar-android/assets/geoip.zip differ ===================================== briar-android/assets/tor-pie.zip ===================================== Binary files /dev/null and b/briar-android/assets/tor-pie.zip differ ===================================== briar-android/src/org/briarproject/android/SetupActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -169,6 +169,7 @@ OnEditorActionListener { progress = new ProgressBar(this); progress.setLayoutParams(WRAP_WRAP); + progress.setPadding(0, pad, 0, 0); progress.setIndeterminate(true); progress.setVisibility(GONE); layout.addView(progress); ===================================== briar-android/src/org/briarproject/plugins/tor/TorPlugin.java ===================================== --- a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java +++ b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java @@ -226,7 +226,7 @@ class TorPlugin implements DuplexPlugin, EventHandler { copy(in, out); // Make the Tor binary executable if(!setExecutable(torFile)) { - LOG.warning("Could not make Tor executable"); + LOG.warning("Could not make Tor binary executable"); return false; } return true; @@ -266,14 +266,23 @@ class TorPlugin implements DuplexPlugin, EventHandler { } private InputStream getTorInputStream() throws IOException { - InputStream in = appContext.getResources().getAssets().open("tor.zip"); + String filename; + if(Build.VERSION.SDK_INT >= 16) { + LOG.info("Installing PIE Tor binary"); + filename = "tor-pie.zip"; + } else { + LOG.info("Installing non-PIE Tor binary"); + filename = "tor.zip"; + } + InputStream in = appContext.getResources().getAssets().open(filename); ZipInputStream zin = new ZipInputStream(in); if(zin.getNextEntry() == null) throw new IOException(); return zin; } private InputStream getGeoIpInputStream() throws IOException { - InputStream in = appContext.getResources().getAssets().open("geoip.zip"); + String filename = "geoip.zip"; + InputStream in = appContext.getResources().getAssets().open(filename); ZipInputStream zin = new ZipInputStream(in); if(zin.getNextEntry() == null) throw new IOException(); return zin; |
From: akwizgran <gi...@br...> - 2015-03-20 14:24:38
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="a9489a51" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/a9489a519b879c093e2b385d0ea7a4d1bada33de">a9489a51</a> by akwizgran Upgraded Tor to 0.2.5.11 with OpenSSL 1.0.2a. - - - - - Changes: ===================================== briar-android/assets/tor.zip ===================================== Binary files a/briar-android/assets/tor.zip and b/briar-android/assets/tor.zip differ |
From: akwizgran <gi...@br...> - 2015-03-11 10:25:19
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="a5b1d92e" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/a5b1d92eaed1718123a05df16aa7170873d47574">a5b1d92e</a> by akwizgran Log discovered devices to track down discovery bugs. - - - - - Changes: ===================================== briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java ===================================== --- a/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java +++ b/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java @@ -461,6 +461,8 @@ class DroidtoothPlugin implements DuplexPlugin { finished.countDown(); } else if(action.equals(FOUND)) { BluetoothDevice d = intent.getParcelableExtra(EXTRA_DEVICE); + if(LOG.isLoggable(INFO)) + LOG.info("Discovered device: " + d.getAddress()); addresses.add(d.getAddress()); } } |
From: akwizgran <gi...@br...> - 2015-03-09 16:50:31
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="afb6a185" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/afb6a185e38c0223f955b21ef234ae88ed8441ff">afb6a185</a> by akwizgran Added Android Studio's local.properties to .gitignore. - - - - - Changes: ===================================== .gitignore ===================================== --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ build *.tmp .idea *.iml +local.properties |
From: akwizgran <gi...@br...> - 2015-03-09 16:45:49
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="4630137c" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/4630137c942e68c1ecb017c1179e8156bab56e0e">4630137c</a> by akwizgran Added Android Studio files to .gitignore. - - - - - Changes: ===================================== .gitignore ===================================== --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ build .gradle .metadata *.tmp +.idea +*.iml |
From: akwizgran <gi...@br...> - 2015-03-09 16:12:25
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="37138d7a" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/37138d7a943f71078cb7b49d181e9d229d35f6a5">37138d7a</a> by akwizgran Updated Gradle and Android Gradle wrapper. - - - - - Changes: ===================================== build.gradle ===================================== --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,6 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:0.12.+' + classpath 'com.android.tools.build:gradle:1.0.0' } } ===================================== gradle/wrapper/gradle-wrapper.properties ===================================== --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Apr 10 15:27:10 PDT 2013 +#Mon Mar 09 16:07:23 GMT 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip |
From: akwizgran <gi...@br...> - 2015-03-05 16:19:07
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="35212a49" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/35212a49dc44fcfd1c3a5ab47798ccf56edbdeb8">35212a49</a> by Alexander Løvik Stevenson Bumped expiry date to 1 PAril 2015. - - - - - <a href="50f87127" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/50f8712743b8c3cba8b6626ed43ad0d4691fe5da">50f87127</a> by akwizgran Bumped expiry date to 1 April 2015. - - - - - Changes: ===================================== briar-android/src/org/briarproject/android/SplashScreenActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/SplashScreenActivity.java +++ b/briar-android/src/org/briarproject/android/SplashScreenActivity.java @@ -30,8 +30,8 @@ public class SplashScreenActivity extends RoboSplashActivity { private static final Logger LOG = Logger.getLogger(SplashScreenActivity.class.getName()); - // This build expires on 1 March 2015 - private static final long EXPIRY_DATE = 1425168000 * 1000L; + // This build expires on 1 April 2015 + private static final long EXPIRY_DATE = 1427846400 * 1000L; private long now = System.currentTimeMillis(); |
From: akwizgran <gi...@br...> - 2015-02-12 09:12:31
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="c026a07a" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/c026a07a433326b5aa2d5b316637dc9e6e983c22">c026a07a</a> by akwizgran Bump the version number, indicate that Bluetooth is required. - - - - - <a href="316e4c88" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/316e4c88fdae1a50d6e980606c5804d1ab743d47">316e4c88</a> by akwizgran Bumped expiry date to 1 March 2015. - - - - - Changes: ===================================== briar-android/AndroidManifest.xml ===================================== --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -1,15 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.briarproject" - android:versionCode="6" - android:versionName="0.6" > + android:versionCode="7" + android:versionName="0.7" > <uses-sdk - android:minSdkVersion="7" - android:targetSdkVersion="20" - android:maxSdkVersion="20" + android:minSdkVersion="7" + android:targetSdkVersion="20" + android:maxSdkVersion="20" /> + <uses-feature android:name="android.hardware.bluetooth" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.BLUETOOTH" /> ===================================== briar-android/src/org/briarproject/android/SplashScreenActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/SplashScreenActivity.java +++ b/briar-android/src/org/briarproject/android/SplashScreenActivity.java @@ -30,8 +30,8 @@ public class SplashScreenActivity extends RoboSplashActivity { private static final Logger LOG = Logger.getLogger(SplashScreenActivity.class.getName()); - // This build expires on 1 February 2015 - private static final long EXPIRY_DATE = 1422748800 * 1000L; + // This build expires on 1 March 2015 + private static final long EXPIRY_DATE = 1425168000 * 1000L; private long now = System.currentTimeMillis(); |
From: akwizgran <gi...@br...> - 2015-01-30 20:00:52
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="4fcc3092" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/4fcc3092aedc9b63862a995f8e7ab06f726ad6d6">4fcc3092</a> by akwizgran Remove vuln.pub manifest, we're not getting any useful notifications. - - - - - <a href="c1469797" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/c14697972a4e4dfc5c4d1d9d2311463746e8c0e2">c1469797</a> by akwizgran Upgraded Tor to 0.2.5.10 with OpenSSL 1.0.2. - - - - - Changes: ===================================== briar-android/assets/geoip ===================================== Binary files a/briar-android/assets/geoip and /dev/null differ ===================================== briar-android/assets/geoip.zip ===================================== Binary files /dev/null and b/briar-android/assets/geoip.zip differ ===================================== briar-android/assets/tor ===================================== Binary files a/briar-android/assets/tor and /dev/null differ ===================================== briar-android/assets/tor.zip ===================================== Binary files /dev/null and b/briar-android/assets/tor.zip differ ===================================== briar-android/src/org/briarproject/plugins/tor/TorPlugin.java ===================================== --- a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java +++ b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java @@ -266,14 +266,14 @@ class TorPlugin implements DuplexPlugin, EventHandler { } private InputStream getTorInputStream() throws IOException { - InputStream in = appContext.getResources().getAssets().open("tor"); + InputStream in = appContext.getResources().getAssets().open("tor.zip"); ZipInputStream zin = new ZipInputStream(in); if(zin.getNextEntry() == null) throw new IOException(); return zin; } private InputStream getGeoIpInputStream() throws IOException { - InputStream in = appContext.getResources().getAssets().open("geoip"); + InputStream in = appContext.getResources().getAssets().open("geoip.zip"); ZipInputStream zin = new ZipInputStream(in); if(zin.getNextEntry() == null) throw new IOException(); return zin; ===================================== vulnpub.json ===================================== --- a/vulnpub.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "managed": {} - "unmanaged": [ - { - "name": "bluecove", - "version": "2.1.0", - "homepage": "https://code.google.com/p/bluecove/" - }, - { - "name": "jnotify", - "version": "0.94", - "homepage": "http://sourceforge.net/projects/jnotify/" - }, - { - "name": "jSSC", - "version": "0.9.0", - "homepage": "https://code.google.com/p/java-simple-serial-connector/" - }, - { - "name": "jtorctl", - "version": "*", - "homepage": "https://github.com/guardianproject/jtorctl" - } - ] -} |
From: akwizgran <gi...@br...> - 2015-01-30 19:27:50
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="540a399b" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/540a399b77d6bb64b4c37937d97ff9457113324a">540a399b</a> by akwizgran Moved patches to their own directory. - - - - - Changes: ===================================== bluecove-2.1.1-SNAPSHOT.patch ===================================== --- a/bluecove-2.1.1-SNAPSHOT.patch +++ /dev/null @@ -1,63 +0,0 @@ -diff -Bbur bluecove-2.1.1-SNAPSHOT/bluecove/pom.xml bluecove-2.1.1-SNAPSHOT-briar/bluecove/pom.xml ---- bluecove-2.1.1-SNAPSHOT/bluecove/pom.xml 2013-01-04 00:43:17.961294408 +0000 -+++ bluecove-2.1.1-SNAPSHOT-briar/bluecove/pom.xml 2013-01-03 23:17:37.549293571 +0000 -@@ -126,8 +126,8 @@ - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> -- <source>1.3</source> -- <target>1.1</target> -+ <source>1.5</source> -+ <target>1.5</target> - </configuration> - </plugin> - -@@ -355,7 +355,7 @@ - <configuration> - <linkXref>true</linkXref> - <minimumTokens>100</minimumTokens> -- <targetJdk>1.4</targetJdk> -+ <targetJdk>1.5</targetJdk> - </configuration> - </plugin> - <plugin> -diff -Bbur bluecove-2.1.1-SNAPSHOT/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm bluecove-2.1.1-SNAPSHOT-briar/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm ---- bluecove-2.1.1-SNAPSHOT/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm 2013-01-04 00:43:17.549293781 +0000 -+++ bluecove-2.1.1-SNAPSHOT-briar/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm 2013-01-03 23:19:02.269295705 +0000 -@@ -280,6 +280,10 @@ - ndebug(("fail to get IOBluetoothRFCOMMChannel")); - return; - } -+ if(![rfcommChannel isIncoming]) { -+ ndebug(("ignoring outgoing connection")); -+ return; -+ } - if (comm->authenticate) { - IOBluetoothDevice* device = [rfcommChannel getDevice]; - if (device == NULL) { -diff -Bbur bluecove-2.1.1-SNAPSHOT/bluecove-gpl/pom.xml bluecove-2.1.1-SNAPSHOT-briar/bluecove-gpl/pom.xml ---- bluecove-2.1.1-SNAPSHOT/bluecove-gpl/pom.xml 2013-01-04 00:43:14.509294005 +0000 -+++ bluecove-2.1.1-SNAPSHOT-briar/bluecove-gpl/pom.xml 2013-01-03 23:17:52.181293751 +0000 -@@ -81,8 +81,8 @@ - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> -- <source>1.3</source> -- <target>1.1</target> -+ <source>1.5</source> -+ <target>1.5</target> - </configuration> - </plugin> - -diff -Bbur bluecove-2.1.1-SNAPSHOT/pom.xml bluecove-2.1.1-SNAPSHOT-briar/pom.xml ---- bluecove-2.1.1-SNAPSHOT/pom.xml 2013-01-04 00:43:19.721293788 +0000 -+++ bluecove-2.1.1-SNAPSHOT-briar/pom.xml 2013-01-03 23:17:18.713293930 +0000 -@@ -436,7 +436,7 @@ - <configuration> - <linkXref>true</linkXref> - <minimumTokens>100</minimumTokens> -- <targetJdk>1.4</targetJdk> -+ <targetJdk>1.5</targetJdk> - </configuration> - </plugin> - <plugin> ===================================== jnotify-0.94.patch ===================================== --- a/jnotify-0.94.patch +++ /dev/null @@ -1,113 +0,0 @@ -briar-desktop/libs/jnotify-0.94.jar is built via: -$ wget "http://downloads.sourceforge.net/project/jnotify/jnotify/jnotify-0.94/jnotify-lib-0.94.zip?r=&ts=$(date +%s)" -$ unzip -d jnotify-lib-0.94 jnotify-lib-0.94.zip && cd jnotify-lib-0.94 -$ unzip -d src jnotify-0.94-src.zip -$ wget -O build.xml "http://jnotify.cvs.sourceforge.net/viewvc/jnotify/jnotify/build.xml?revision=1.7&pathrev=HEAD" -$ wget -O build.properties "http://jnotify.cvs.sourceforge.net/viewvc/jnotify/jnotify/build.properties?revision=1.13" -$ patch -lp1 < /path/to/this/patch -$ ant build_java # if this fails with invalid flag: -g:{lines,vars,source}, try removing the debug attributes from <javac> - -diff -ru jnotify-0.94/net/contentobjects/jnotify/linux/JNotify_linux.java jnotify-0.94-briar/net/contentobjects/jnotify/linux/JNotify_linux.java ---- jnotify-0.94/net/contentobjects/jnotify/linux/JNotify_linux.java 2012-04-25 00:03:54.000000000 +0100 -+++ jnotify-0.94-briar/net/contentobjects/jnotify/linux/JNotify_linux.java 2014-01-30 12:31:41.959082350 +0000 -@@ -37,6 +37,7 @@ - package net.contentobjects.jnotify.linux; - - import net.contentobjects.jnotify.JNotifyException; -+import net.contentobjects.jnotify.Util; - - public class JNotify_linux - { -@@ -45,7 +46,7 @@ - - static - { -- System.loadLibrary("jnotify"); -+ Util.loadNative(); - int res = nativeInit(); - if (res != 0) - { -diff -ru jnotify-0.94/net/contentobjects/jnotify/macosx/JNotify_macosx.java jnotify-0.94-briar/net/contentobjects/jnotify/macosx/JNotify_macosx.java ---- jnotify-0.94/net/contentobjects/jnotify/macosx/JNotify_macosx.java 2010-01-26 19:43:42.000000000 +0000 -+++ jnotify-0.94-briar/net/contentobjects/jnotify/macosx/JNotify_macosx.java 2014-01-30 12:31:41.959082350 +0000 -@@ -1,6 +1,7 @@ - package net.contentobjects.jnotify.macosx; - - import net.contentobjects.jnotify.JNotifyException; -+import net.contentobjects.jnotify.Util; - - public class JNotify_macosx - { -@@ -10,7 +11,7 @@ - - static - { -- System.loadLibrary("jnotify"); //$NON-NLS-1$ -+ Util.loadNative(); - Thread thread = new Thread("FSEvent thread") //$NON-NLS-1$ - { - public void run() -diff -ru jnotify-0.94/net/contentobjects/jnotify/Util.java jnotify-0.94-briar/net/contentobjects/jnotify/Util.java ---- jnotify-0.94/net/contentobjects/jnotify/Util.java 2006-02-14 08:18:10.000000000 +0000 -+++ jnotify-0.94-briar/net/contentobjects/jnotify/Util.java 2014-01-30 12:31:41.959082350 +0000 -@@ -30,4 +30,26 @@ - return "UNKNOWN"; - } - } -+ -+ public static void loadNative() throws UnsatisfiedLinkError { -+ try -+ { -+ try -+ { -+ System.loadLibrary("jnotify"); -+ } -+ catch (UnsatisfiedLinkError e) { -+ System.loadLibrary("jnotify-" + System.getProperty("os.arch")); -+ } -+ } -+ catch (UnsatisfiedLinkError e) -+ { -+ // add some extra debugging info -+ String msg = "Error loading library, os.arch=" + System.getProperty("os.arch") + -+ ", java.library.path=" + System.getProperty("java.library.path"); -+ UnsatisfiedLinkError e2 = new UnsatisfiedLinkError(msg); -+ e2.initCause(e); -+ throw e2; -+ } -+ } - } -diff -ru jnotify-0.94/net/contentobjects/jnotify/win32/JNotify_win32.java jnotify-0.94-briar/net/contentobjects/jnotify/win32/JNotify_win32.java ---- jnotify-0.94/net/contentobjects/jnotify/win32/JNotify_win32.java 2012-04-25 00:04:50.000000000 +0100 -+++ jnotify-0.94-briar/net/contentobjects/jnotify/win32/JNotify_win32.java 2014-01-30 12:31:41.959082350 +0000 -@@ -39,28 +39,13 @@ - package net.contentobjects.jnotify.win32; - - import net.contentobjects.jnotify.JNotifyException; -- -+import net.contentobjects.jnotify.Util; - - public class JNotify_win32 - { - static - { -- try -- { -- if (System.getProperty("os.arch").equals("amd64")) -- { -- System.loadLibrary("jnotify_64bit"); -- } -- else -- { -- System.loadLibrary("jnotify"); -- } -- } -- catch (UnsatisfiedLinkError e) -- { -- System.err.println("Error loading library, java.library.path=" + System.getProperty("java.library.path")); -- throw e; -- } -+ Util.loadNative(); - int res = nativeInit(); - if (res != 0) - { ===================================== jssc-0.9.patch ===================================== --- a/jssc-0.9.patch +++ /dev/null @@ -1,84 +0,0 @@ -diff -Bbur jSSC-0.9.0-Release/src/jssc/SerialPort.java jSSC-0.9.0-briar/src/jssc/SerialPort.java ---- jSSC-0.9.0-Release/src/jssc/SerialPort.java 2011-12-21 13:29:10.000000000 +0000 -+++ jSSC-0.9.0-briar/src/jssc/SerialPort.java 2012-12-06 15:07:37.786033300 +0000 -@@ -30,13 +30,13 @@ - */ - public class SerialPort { - -- private SerialNativeInterface serialInterface; -- private SerialPortEventListener eventListener; -- private int portHandle; -- private String portName; -- private boolean portOpened = false; -- private boolean maskAssigned = false; -- private boolean eventListenerAdded = false; -+ private volatile SerialNativeInterface serialInterface; -+ private volatile SerialPortEventListener eventListener; -+ private volatile int portHandle; -+ private volatile String portName; -+ private volatile boolean portOpened = false; -+ private volatile boolean maskAssigned = false; -+ private volatile boolean eventListenerAdded = false; - - - public static final int BAUDRATE_110 = 110; -@@ -915,7 +915,7 @@ - - private class EventThread extends Thread { - -- private boolean threadTerminated = false; -+ private volatile boolean threadTerminated = false; - - @Override - public void run() { -diff -Bbur jSSC-0.9.0-Release/src/jssc/SerialPortList.java jSSC-0.9.0-briar/src/jssc/SerialPortList.java ---- jSSC-0.9.0-Release/src/jssc/SerialPortList.java 2011-12-21 13:30:30.000000000 +0000 -+++ jSSC-0.9.0-briar/src/jssc/SerialPortList.java 2012-12-06 14:31:50.142033801 +0000 -@@ -97,20 +97,15 @@ - */ - private static String[] getLinuxPortNames() { - String[] returnArray = new String[]{}; -- try { -- Process dmesgProcess = Runtime.getRuntime().exec("dmesg"); -- BufferedReader reader = new BufferedReader(new InputStreamReader(dmesgProcess.getInputStream())); -+ File dir = new File("/dev"); -+ if(dir.exists() && dir.isDirectory()){ -+ File[] files = dir.listFiles(); -+ if(files.length > 0){ - TreeSet<String> portsTree = new TreeSet<String>(); - ArrayList<String> portsList = new ArrayList<String>(); -- String buffer = ""; -- while((buffer = reader.readLine()) != null && !buffer.isEmpty()){ -- if(buffer.matches(".*(ttyS|ttyUSB)[0-9]{1,3}.*")){ -- String[] tmp = buffer.split(" "); -- for(String value : tmp){ -- if(value.matches("(ttyS|ttyUSB)[0-9]{1,3}")){ -- portsTree.add("/dev/" + value); -- } -- } -+ for(File file : files){ -+ if(!file.isDirectory() && !file.isFile() && file.getName().matches(".*(ttyS|ttyUSB|ttyACM)[0-9]{1,3}.*")){ -+ portsTree.add("/dev/" + file.getName()); - } - } - for(String portName : portsTree){ -@@ -130,10 +125,7 @@ - } - } - returnArray = portsList.toArray(returnArray); -- reader.close(); - } -- catch (IOException ex) { -- //Do nothing - } - return returnArray; - } -@@ -179,7 +171,7 @@ - TreeSet<String> portsTree = new TreeSet<String>(); - ArrayList<String> portsList = new ArrayList<String>(); - for(File file : files){ -- if(!file.isDirectory() && !file.isFile() && file.getName().matches("tty.(serial.*|usbserial.*)")){ -+ if(!file.isDirectory() && !file.isFile() && file.getName().matches("tty.(modem.*|usbmodem.*|serial.*|usbserial.*)")){ - portsTree.add("/dev/" + file.getName()); - } - } ===================================== jtorctl.patch ===================================== --- a/jtorctl.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff -Bbur jtorctl/net/freehaven/tor/control/TorControlConnection.java jtorctl-briar/net/freehaven/tor/control/TorControlConnection.java ---- jtorctl/net/freehaven/tor/control/TorControlConnection.java 2014-10-03 12:21:51.883098440 +0100 -+++ jtorctl-briar/net/freehaven/tor/control/TorControlConnection.java 2014-10-06 16:28:53.516851714 +0100 -@@ -728,5 +728,19 @@ - sendAndWaitForResponse("CLOSECIRCUIT "+circID+ - (ifUnused?" IFUNUSED":"")+"\r\n", null); - } -+ -+ /** Tells Tor to exit when this control connection is closed. This command -+ * was added in Tor 0.2.2.28-beta. -+ */ -+ public void takeOwnership() throws IOException { -+ sendAndWaitForResponse("TAKEOWNERSHIP\r\n", null); -+ } -+ -+ /** Tells Tor to forget any cached client state relating to the hidden -+ * service with the given hostname (excluding the .onion extension). -+ */ -+ public void forgetHiddenService(String hostname) throws IOException { -+ sendAndWaitForResponse("FORGETHS " + hostname + "\r\n", null); -+ } - } - ===================================== patches/bluecove-2.1.1-SNAPSHOT.patch ===================================== --- /dev/null +++ b/patches/bluecove-2.1.1-SNAPSHOT.patch @@ -0,0 +1,63 @@ +diff -Bbur bluecove-2.1.1-SNAPSHOT/bluecove/pom.xml bluecove-2.1.1-SNAPSHOT-briar/bluecove/pom.xml +--- bluecove-2.1.1-SNAPSHOT/bluecove/pom.xml 2013-01-04 00:43:17.961294408 +0000 ++++ bluecove-2.1.1-SNAPSHOT-briar/bluecove/pom.xml 2013-01-03 23:17:37.549293571 +0000 +@@ -126,8 +126,8 @@ + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> +- <source>1.3</source> +- <target>1.1</target> ++ <source>1.5</source> ++ <target>1.5</target> + </configuration> + </plugin> + +@@ -355,7 +355,7 @@ + <configuration> + <linkXref>true</linkXref> + <minimumTokens>100</minimumTokens> +- <targetJdk>1.4</targetJdk> ++ <targetJdk>1.5</targetJdk> + </configuration> + </plugin> + <plugin> +diff -Bbur bluecove-2.1.1-SNAPSHOT/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm bluecove-2.1.1-SNAPSHOT-briar/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm +--- bluecove-2.1.1-SNAPSHOT/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm 2013-01-04 00:43:17.549293781 +0000 ++++ bluecove-2.1.1-SNAPSHOT-briar/bluecove/src/main/c/intelbth/OSXStackRFCOMMServer.mm 2013-01-03 23:19:02.269295705 +0000 +@@ -280,6 +280,10 @@ + ndebug(("fail to get IOBluetoothRFCOMMChannel")); + return; + } ++ if(![rfcommChannel isIncoming]) { ++ ndebug(("ignoring outgoing connection")); ++ return; ++ } + if (comm->authenticate) { + IOBluetoothDevice* device = [rfcommChannel getDevice]; + if (device == NULL) { +diff -Bbur bluecove-2.1.1-SNAPSHOT/bluecove-gpl/pom.xml bluecove-2.1.1-SNAPSHOT-briar/bluecove-gpl/pom.xml +--- bluecove-2.1.1-SNAPSHOT/bluecove-gpl/pom.xml 2013-01-04 00:43:14.509294005 +0000 ++++ bluecove-2.1.1-SNAPSHOT-briar/bluecove-gpl/pom.xml 2013-01-03 23:17:52.181293751 +0000 +@@ -81,8 +81,8 @@ + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> +- <source>1.3</source> +- <target>1.1</target> ++ <source>1.5</source> ++ <target>1.5</target> + </configuration> + </plugin> + +diff -Bbur bluecove-2.1.1-SNAPSHOT/pom.xml bluecove-2.1.1-SNAPSHOT-briar/pom.xml +--- bluecove-2.1.1-SNAPSHOT/pom.xml 2013-01-04 00:43:19.721293788 +0000 ++++ bluecove-2.1.1-SNAPSHOT-briar/pom.xml 2013-01-03 23:17:18.713293930 +0000 +@@ -436,7 +436,7 @@ + <configuration> + <linkXref>true</linkXref> + <minimumTokens>100</minimumTokens> +- <targetJdk>1.4</targetJdk> ++ <targetJdk>1.5</targetJdk> + </configuration> + </plugin> + <plugin> ===================================== patches/jnotify-0.94.patch ===================================== --- /dev/null +++ b/patches/jnotify-0.94.patch @@ -0,0 +1,113 @@ +briar-desktop/libs/jnotify-0.94.jar is built via: +$ wget "http://downloads.sourceforge.net/project/jnotify/jnotify/jnotify-0.94/jnotify-lib-0.94.zip?r=&ts=$(date +%s)" +$ unzip -d jnotify-lib-0.94 jnotify-lib-0.94.zip && cd jnotify-lib-0.94 +$ unzip -d src jnotify-0.94-src.zip +$ wget -O build.xml "http://jnotify.cvs.sourceforge.net/viewvc/jnotify/jnotify/build.xml?revision=1.7&pathrev=HEAD" +$ wget -O build.properties "http://jnotify.cvs.sourceforge.net/viewvc/jnotify/jnotify/build.properties?revision=1.13" +$ patch -lp1 < /path/to/this/patch +$ ant build_java # if this fails with invalid flag: -g:{lines,vars,source}, try removing the debug attributes from <javac> + +diff -ru jnotify-0.94/net/contentobjects/jnotify/linux/JNotify_linux.java jnotify-0.94-briar/net/contentobjects/jnotify/linux/JNotify_linux.java +--- jnotify-0.94/net/contentobjects/jnotify/linux/JNotify_linux.java 2012-04-25 00:03:54.000000000 +0100 ++++ jnotify-0.94-briar/net/contentobjects/jnotify/linux/JNotify_linux.java 2014-01-30 12:31:41.959082350 +0000 +@@ -37,6 +37,7 @@ + package net.contentobjects.jnotify.linux; + + import net.contentobjects.jnotify.JNotifyException; ++import net.contentobjects.jnotify.Util; + + public class JNotify_linux + { +@@ -45,7 +46,7 @@ + + static + { +- System.loadLibrary("jnotify"); ++ Util.loadNative(); + int res = nativeInit(); + if (res != 0) + { +diff -ru jnotify-0.94/net/contentobjects/jnotify/macosx/JNotify_macosx.java jnotify-0.94-briar/net/contentobjects/jnotify/macosx/JNotify_macosx.java +--- jnotify-0.94/net/contentobjects/jnotify/macosx/JNotify_macosx.java 2010-01-26 19:43:42.000000000 +0000 ++++ jnotify-0.94-briar/net/contentobjects/jnotify/macosx/JNotify_macosx.java 2014-01-30 12:31:41.959082350 +0000 +@@ -1,6 +1,7 @@ + package net.contentobjects.jnotify.macosx; + + import net.contentobjects.jnotify.JNotifyException; ++import net.contentobjects.jnotify.Util; + + public class JNotify_macosx + { +@@ -10,7 +11,7 @@ + + static + { +- System.loadLibrary("jnotify"); //$NON-NLS-1$ ++ Util.loadNative(); + Thread thread = new Thread("FSEvent thread") //$NON-NLS-1$ + { + public void run() +diff -ru jnotify-0.94/net/contentobjects/jnotify/Util.java jnotify-0.94-briar/net/contentobjects/jnotify/Util.java +--- jnotify-0.94/net/contentobjects/jnotify/Util.java 2006-02-14 08:18:10.000000000 +0000 ++++ jnotify-0.94-briar/net/contentobjects/jnotify/Util.java 2014-01-30 12:31:41.959082350 +0000 +@@ -30,4 +30,26 @@ + return "UNKNOWN"; + } + } ++ ++ public static void loadNative() throws UnsatisfiedLinkError { ++ try ++ { ++ try ++ { ++ System.loadLibrary("jnotify"); ++ } ++ catch (UnsatisfiedLinkError e) { ++ System.loadLibrary("jnotify-" + System.getProperty("os.arch")); ++ } ++ } ++ catch (UnsatisfiedLinkError e) ++ { ++ // add some extra debugging info ++ String msg = "Error loading library, os.arch=" + System.getProperty("os.arch") + ++ ", java.library.path=" + System.getProperty("java.library.path"); ++ UnsatisfiedLinkError e2 = new UnsatisfiedLinkError(msg); ++ e2.initCause(e); ++ throw e2; ++ } ++ } + } +diff -ru jnotify-0.94/net/contentobjects/jnotify/win32/JNotify_win32.java jnotify-0.94-briar/net/contentobjects/jnotify/win32/JNotify_win32.java +--- jnotify-0.94/net/contentobjects/jnotify/win32/JNotify_win32.java 2012-04-25 00:04:50.000000000 +0100 ++++ jnotify-0.94-briar/net/contentobjects/jnotify/win32/JNotify_win32.java 2014-01-30 12:31:41.959082350 +0000 +@@ -39,28 +39,13 @@ + package net.contentobjects.jnotify.win32; + + import net.contentobjects.jnotify.JNotifyException; +- ++import net.contentobjects.jnotify.Util; + + public class JNotify_win32 + { + static + { +- try +- { +- if (System.getProperty("os.arch").equals("amd64")) +- { +- System.loadLibrary("jnotify_64bit"); +- } +- else +- { +- System.loadLibrary("jnotify"); +- } +- } +- catch (UnsatisfiedLinkError e) +- { +- System.err.println("Error loading library, java.library.path=" + System.getProperty("java.library.path")); +- throw e; +- } ++ Util.loadNative(); + int res = nativeInit(); + if (res != 0) + { ===================================== patches/jssc-0.9.patch ===================================== --- /dev/null +++ b/patches/jssc-0.9.patch @@ -0,0 +1,84 @@ +diff -Bbur jSSC-0.9.0-Release/src/jssc/SerialPort.java jSSC-0.9.0-briar/src/jssc/SerialPort.java +--- jSSC-0.9.0-Release/src/jssc/SerialPort.java 2011-12-21 13:29:10.000000000 +0000 ++++ jSSC-0.9.0-briar/src/jssc/SerialPort.java 2012-12-06 15:07:37.786033300 +0000 +@@ -30,13 +30,13 @@ + */ + public class SerialPort { + +- private SerialNativeInterface serialInterface; +- private SerialPortEventListener eventListener; +- private int portHandle; +- private String portName; +- private boolean portOpened = false; +- private boolean maskAssigned = false; +- private boolean eventListenerAdded = false; ++ private volatile SerialNativeInterface serialInterface; ++ private volatile SerialPortEventListener eventListener; ++ private volatile int portHandle; ++ private volatile String portName; ++ private volatile boolean portOpened = false; ++ private volatile boolean maskAssigned = false; ++ private volatile boolean eventListenerAdded = false; + + + public static final int BAUDRATE_110 = 110; +@@ -915,7 +915,7 @@ + + private class EventThread extends Thread { + +- private boolean threadTerminated = false; ++ private volatile boolean threadTerminated = false; + + @Override + public void run() { +diff -Bbur jSSC-0.9.0-Release/src/jssc/SerialPortList.java jSSC-0.9.0-briar/src/jssc/SerialPortList.java +--- jSSC-0.9.0-Release/src/jssc/SerialPortList.java 2011-12-21 13:30:30.000000000 +0000 ++++ jSSC-0.9.0-briar/src/jssc/SerialPortList.java 2012-12-06 14:31:50.142033801 +0000 +@@ -97,20 +97,15 @@ + */ + private static String[] getLinuxPortNames() { + String[] returnArray = new String[]{}; +- try { +- Process dmesgProcess = Runtime.getRuntime().exec("dmesg"); +- BufferedReader reader = new BufferedReader(new InputStreamReader(dmesgProcess.getInputStream())); ++ File dir = new File("/dev"); ++ if(dir.exists() && dir.isDirectory()){ ++ File[] files = dir.listFiles(); ++ if(files.length > 0){ + TreeSet<String> portsTree = new TreeSet<String>(); + ArrayList<String> portsList = new ArrayList<String>(); +- String buffer = ""; +- while((buffer = reader.readLine()) != null && !buffer.isEmpty()){ +- if(buffer.matches(".*(ttyS|ttyUSB)[0-9]{1,3}.*")){ +- String[] tmp = buffer.split(" "); +- for(String value : tmp){ +- if(value.matches("(ttyS|ttyUSB)[0-9]{1,3}")){ +- portsTree.add("/dev/" + value); +- } +- } ++ for(File file : files){ ++ if(!file.isDirectory() && !file.isFile() && file.getName().matches(".*(ttyS|ttyUSB|ttyACM)[0-9]{1,3}.*")){ ++ portsTree.add("/dev/" + file.getName()); + } + } + for(String portName : portsTree){ +@@ -130,10 +125,7 @@ + } + } + returnArray = portsList.toArray(returnArray); +- reader.close(); + } +- catch (IOException ex) { +- //Do nothing + } + return returnArray; + } +@@ -179,7 +171,7 @@ + TreeSet<String> portsTree = new TreeSet<String>(); + ArrayList<String> portsList = new ArrayList<String>(); + for(File file : files){ +- if(!file.isDirectory() && !file.isFile() && file.getName().matches("tty.(serial.*|usbserial.*)")){ ++ if(!file.isDirectory() && !file.isFile() && file.getName().matches("tty.(modem.*|usbmodem.*|serial.*|usbserial.*)")){ + portsTree.add("/dev/" + file.getName()); + } + } ===================================== patches/jtorctl.patch ===================================== --- /dev/null +++ b/patches/jtorctl.patch @@ -0,0 +1,23 @@ +diff -Bbur jtorctl/net/freehaven/tor/control/TorControlConnection.java jtorctl-briar/net/freehaven/tor/control/TorControlConnection.java +--- jtorctl/net/freehaven/tor/control/TorControlConnection.java 2014-10-03 12:21:51.883098440 +0100 ++++ jtorctl-briar/net/freehaven/tor/control/TorControlConnection.java 2014-10-06 16:28:53.516851714 +0100 +@@ -728,5 +728,19 @@ + sendAndWaitForResponse("CLOSECIRCUIT "+circID+ + (ifUnused?" IFUNUSED":"")+"\r\n", null); + } ++ ++ /** Tells Tor to exit when this control connection is closed. This command ++ * was added in Tor 0.2.2.28-beta. ++ */ ++ public void takeOwnership() throws IOException { ++ sendAndWaitForResponse("TAKEOWNERSHIP\r\n", null); ++ } ++ ++ /** Tells Tor to forget any cached client state relating to the hidden ++ * service with the given hostname (excluding the .onion extension). ++ */ ++ public void forgetHiddenService(String hostname) throws IOException { ++ sendAndWaitForResponse("FORGETHS " + hostname + "\r\n", null); ++ } + } + ===================================== patches/spongy.sh ===================================== --- /dev/null +++ b/patches/spongy.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +dirs=(ant core docs jce mail pg pkix prov) + +for file in `find ${dirs[@]} -name bouncycastle` +do + path=`dirname $file` + echo "Moving $file to $path/spongycastle" + mv $file $path/spongycastle +done + +for file in `grep -Rl bouncycastle ${dirs[@]}` +do + echo "Replacing string bouncycastle in $file" + sed -i 's/bouncycastle/spongycastle/g' $file +done + ===================================== patches/tor.patch ===================================== --- /dev/null +++ b/patches/tor.patch @@ -0,0 +1,194 @@ +diff --git a/src/or/config.c b/src/or/config.c +index 39b85aa..ff42d27 100644 +--- a/src/or/config.c ++++ b/src/or/config.c +@@ -1096,6 +1096,8 @@ options_act_reversible(const or_options_t *old_options, char **msg) + "non-control network connections. Shutting down all existing " + "connections."); + connection_mark_all_noncontrol_connections(); ++ /* We can't complete circuits until the network is re-enabled. */ ++ can_complete_circuit = 0; + } + } + +diff --git a/src/or/control.c b/src/or/control.c +index 9378f38..17d2a46 100644 +--- a/src/or/control.c ++++ b/src/or/control.c +@@ -37,6 +37,8 @@ + #include "nodelist.h" + #include "policies.h" + #include "reasons.h" ++#include "rendclient.h" ++#include "rendcommon.h" + #include "rephist.h" + #include "router.h" + #include "routerlist.h" +@@ -156,6 +158,8 @@ static int handle_control_resolve(control_connection_t *conn, uint32_t len, + static int handle_control_usefeature(control_connection_t *conn, + uint32_t len, + const char *body); ++static int handle_control_forgeths(control_connection_t *conn, uint32_t len, ++ const char *body); + static int write_stream_target_to_buf(entry_connection_t *conn, char *buf, + size_t len); + static void orconn_target_get_name(char *buf, size_t len, +@@ -3164,6 +3168,33 @@ handle_control_dropguards(control_connection_t *conn, + return 0; + } + ++/** Called when we get a FORGETHS command: parse the hidden service's onion ++ * address and purge any cached state related to the service. */ ++static int ++handle_control_forgeths(control_connection_t *conn, uint32_t len, ++ const char *body) ++{ ++ smartlist_t *args; ++ char *onion_address; ++ ++ args = getargs_helper("FORGETHS", conn, body, 1, 1); ++ if (!args) ++ return -1; ++ onion_address = smartlist_get(args, 0); ++ smartlist_free(args); ++ ++ if (!rend_valid_service_id(onion_address)) { ++ connection_write_str_to_buf("513 Invalid hidden service address\r\n", conn); ++ tor_free(onion_address); ++ return -1; ++ } ++ ++ rend_client_purge_hidden_service(onion_address); ++ tor_free(onion_address); ++ send_control_done(conn); ++ return 0; ++} ++ + /** Called when <b>conn</b> has no more bytes left on its outbuf. */ + int + connection_control_finished_flushing(control_connection_t *conn) +@@ -3461,6 +3492,9 @@ connection_control_process_inbuf(control_connection_t *conn) + } else if (!strcasecmp(conn->incoming_cmd, "DROPGUARDS")) { + if (handle_control_dropguards(conn, cmd_data_len, args)) + return -1; ++ } else if (!strcasecmp(conn->incoming_cmd, "FORGETHS")) { ++ if (handle_control_forgeths(conn, cmd_data_len, args)) ++ return -1; + } else { + connection_printf_to_buf(conn, "510 Unrecognized command \"%s\"\r\n", + conn->incoming_cmd); +diff --git a/src/or/rendclient.c b/src/or/rendclient.c +index 19a8cef..c17439d 100644 +--- a/src/or/rendclient.c ++++ b/src/or/rendclient.c +@@ -31,6 +31,8 @@ + static extend_info_t *rend_client_get_random_intro_impl( + const rend_cache_entry_t *rend_query, + const int strict, const int warnings); ++static void purge_hid_serv_from_last_hid_serv_requests( ++ const char *onion_address); + + /** Purge all potentially remotely-detectable state held in the hidden + * service client code. Called on SIGNAL NEWNYM. */ +@@ -42,6 +44,16 @@ rend_client_purge_state(void) + rend_client_purge_last_hid_serv_requests(); + } + ++/** Purge all cached state relating to the given hidden service. */ ++void ++rend_client_purge_hidden_service(const char *onion_address) ++{ ++ tor_assert(rend_valid_service_id(onion_address)); ++ ++ rend_cache_remove_entry(onion_address); ++ purge_hid_serv_from_last_hid_serv_requests(onion_address); ++} ++ + /** Called when we've established a circuit to an introduction point: + * send the introduction request. */ + void +diff --git a/src/or/rendclient.h b/src/or/rendclient.h +index 1f731d0..7084aef 100644 +--- a/src/or/rendclient.h ++++ b/src/or/rendclient.h +@@ -13,6 +13,7 @@ + #define TOR_RENDCLIENT_H + + void rend_client_purge_state(void); ++void rend_client_purge_hidden_service(const char *onion_address); + + void rend_client_introcirc_has_opened(origin_circuit_t *circ); + void rend_client_rendcirc_has_opened(origin_circuit_t *circ); +diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c +index a664b5d..70d7283 100644 +--- a/src/or/rendcommon.c ++++ b/src/or/rendcommon.c +@@ -881,6 +881,34 @@ rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e) + return 1; + } + ++/** Remove any cached descriptors for <b>service_id/b>. */ ++void ++rend_cache_remove_entry(const char *service_id) ++{ ++ char key[REND_SERVICE_ID_LEN_BASE32+2]; /* <version><service_id>\0 */ ++ rend_cache_entry_t *removed; ++ ++ tor_assert(rend_valid_service_id(service_id)); ++ if (!rend_cache) ++ return; ++ ++ tor_snprintf(key, sizeof(key), "2%s", service_id); ++ removed = (rend_cache_entry_t *)strmap_remove_lc(rend_cache, key); ++ if (removed) { ++ log_info(LD_REND, "Removed cached v2 descriptor for service %s.", ++ safe_str_client(service_id)); ++ rend_cache_entry_free(removed); ++ } ++ ++ tor_snprintf(key, sizeof(key), "0%s", service_id); ++ removed = (rend_cache_entry_t *)strmap_remove_lc(rend_cache, key); ++ if (removed) { ++ log_info(LD_REND, "Removed cached v0 descriptor for service %s.", ++ safe_str_client(service_id)); ++ rend_cache_entry_free(removed); ++ } ++} ++ + /** Lookup the v2 service descriptor with base32-encoded <b>desc_id</b> and + * copy the pointer to it to *<b>desc</b>. Return 1 on success, 0 on + * well-formed-but-not-found, and -1 on failure. +diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h +index 07a47ac..0a3160d 100644 +--- a/src/or/rendcommon.h ++++ b/src/or/rendcommon.h +@@ -39,6 +39,7 @@ void rend_cache_free_all(void); + int rend_valid_service_id(const char *query); + int rend_cache_lookup_entry(const char *query, int version, + rend_cache_entry_t **entry_out); ++void rend_cache_remove_entry(const char *service_id); + int rend_cache_lookup_v2_desc_as_dir(const char *query, const char **desc); + /** Return value from rend_cache_store_v2_desc_as_{dir,client}. */ + typedef enum { +diff --git a/src/or/rendservice.c b/src/or/rendservice.c +index a7c1e32..cc9c0f8 100644 +--- a/src/or/rendservice.c ++++ b/src/or/rendservice.c +@@ -16,6 +16,7 @@ + #include "circuituse.h" + #include "config.h" + #include "directory.h" ++#include "main.h" + #include "networkstatus.h" + #include "nodelist.h" + #include "rendclient.h" +@@ -3033,6 +3034,9 @@ rend_services_introduce(void) + time_t now; + const or_options_t *options = get_options(); + ++ if (!can_complete_circuit) ++ return; ++ + intro_nodes = smartlist_new(); + now = time(NULL); + ===================================== patches/weupnp-0.1.3-SNAPSHOT.patch ===================================== --- /dev/null +++ b/patches/weupnp-0.1.3-SNAPSHOT.patch @@ -0,0 +1,40 @@ +diff -Bbur weupnp-0.1.3-SNAPSHOT/src/main/java/org/bitlet/weupnp/GatewayDiscover.java weupnp-0.1.3-SNAPSHOT-briar/src/main/java/org/bitlet/weupnp/GatewayDiscover.java +--- weupnp-0.1.3-SNAPSHOT/src/main/java/org/bitlet/weupnp/GatewayDiscover.java 2013-05-01 21:09:27.000000000 +0100 ++++ weupnp-0.1.3-SNAPSHOT-briar/src/main/java/org/bitlet/weupnp/GatewayDiscover.java 2013-12-05 20:49:00.000000000 +0000 +@@ -253,7 +253,7 @@ + while (st.hasMoreTokens()) { + String line = st.nextToken().trim(); + +- if (line.isEmpty()) ++ if (line.equals("")) + continue; + + if (line.startsWith("HTTP/1.") || line.startsWith("NOTIFY *")) +@@ -331,16 +331,6 @@ + // For every suitable network interface, get all IP addresses + while (networkInterfaces.hasMoreElements()) { + NetworkInterface card = networkInterfaces.nextElement(); +- +- try { +- // skip devices, not suitable to search gateways for +- if (card.isLoopback() || card.isPointToPoint() || +- card.isVirtual() || !card.isUp()) +- continue; +- } catch (SocketException e) { +- continue; +- } +- + Enumeration<InetAddress> addresses = card.getInetAddresses(); + + if (addresses == null) +@@ -348,6 +338,10 @@ + + while (addresses.hasMoreElements()) { + InetAddress inetAddress = addresses.nextElement(); ++ ++ if (inetAddress.isLoopbackAddress()) ++ continue; ++ + int index = arrayIPAddress.size(); + + if (!getIPv4 || !getIPv6) { ===================================== spongy.sh ===================================== --- a/spongy.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -dirs=(ant core docs jce mail pg pkix prov) - -for file in `find ${dirs[@]} -name bouncycastle` -do - path=`dirname $file` - echo "Moving $file to $path/spongycastle" - mv $file $path/spongycastle -done - -for file in `grep -Rl bouncycastle ${dirs[@]}` -do - echo "Replacing string bouncycastle in $file" - sed -i 's/bouncycastle/spongycastle/g' $file -done - ===================================== tor.patch ===================================== --- a/tor.patch +++ /dev/null @@ -1,194 +0,0 @@ -diff --git a/src/or/config.c b/src/or/config.c -index 39b85aa..ff42d27 100644 ---- a/src/or/config.c -+++ b/src/or/config.c -@@ -1096,6 +1096,8 @@ options_act_reversible(const or_options_t *old_options, char **msg) - "non-control network connections. Shutting down all existing " - "connections."); - connection_mark_all_noncontrol_connections(); -+ /* We can't complete circuits until the network is re-enabled. */ -+ can_complete_circuit = 0; - } - } - -diff --git a/src/or/control.c b/src/or/control.c -index 9378f38..17d2a46 100644 ---- a/src/or/control.c -+++ b/src/or/control.c -@@ -37,6 +37,8 @@ - #include "nodelist.h" - #include "policies.h" - #include "reasons.h" -+#include "rendclient.h" -+#include "rendcommon.h" - #include "rephist.h" - #include "router.h" - #include "routerlist.h" -@@ -156,6 +158,8 @@ static int handle_control_resolve(control_connection_t *conn, uint32_t len, - static int handle_control_usefeature(control_connection_t *conn, - uint32_t len, - const char *body); -+static int handle_control_forgeths(control_connection_t *conn, uint32_t len, -+ const char *body); - static int write_stream_target_to_buf(entry_connection_t *conn, char *buf, - size_t len); - static void orconn_target_get_name(char *buf, size_t len, -@@ -3164,6 +3168,33 @@ handle_control_dropguards(control_connection_t *conn, - return 0; - } - -+/** Called when we get a FORGETHS command: parse the hidden service's onion -+ * address and purge any cached state related to the service. */ -+static int -+handle_control_forgeths(control_connection_t *conn, uint32_t len, -+ const char *body) -+{ -+ smartlist_t *args; -+ char *onion_address; -+ -+ args = getargs_helper("FORGETHS", conn, body, 1, 1); -+ if (!args) -+ return -1; -+ onion_address = smartlist_get(args, 0); -+ smartlist_free(args); -+ -+ if (!rend_valid_service_id(onion_address)) { -+ connection_write_str_to_buf("513 Invalid hidden service address\r\n", conn); -+ tor_free(onion_address); -+ return -1; -+ } -+ -+ rend_client_purge_hidden_service(onion_address); -+ tor_free(onion_address); -+ send_control_done(conn); -+ return 0; -+} -+ - /** Called when <b>conn</b> has no more bytes left on its outbuf. */ - int - connection_control_finished_flushing(control_connection_t *conn) -@@ -3461,6 +3492,9 @@ connection_control_process_inbuf(control_connection_t *conn) - } else if (!strcasecmp(conn->incoming_cmd, "DROPGUARDS")) { - if (handle_control_dropguards(conn, cmd_data_len, args)) - return -1; -+ } else if (!strcasecmp(conn->incoming_cmd, "FORGETHS")) { -+ if (handle_control_forgeths(conn, cmd_data_len, args)) -+ return -1; - } else { - connection_printf_to_buf(conn, "510 Unrecognized command \"%s\"\r\n", - conn->incoming_cmd); -diff --git a/src/or/rendclient.c b/src/or/rendclient.c -index 19a8cef..c17439d 100644 ---- a/src/or/rendclient.c -+++ b/src/or/rendclient.c -@@ -31,6 +31,8 @@ - static extend_info_t *rend_client_get_random_intro_impl( - const rend_cache_entry_t *rend_query, - const int strict, const int warnings); -+static void purge_hid_serv_from_last_hid_serv_requests( -+ const char *onion_address); - - /** Purge all potentially remotely-detectable state held in the hidden - * service client code. Called on SIGNAL NEWNYM. */ -@@ -42,6 +44,16 @@ rend_client_purge_state(void) - rend_client_purge_last_hid_serv_requests(); - } - -+/** Purge all cached state relating to the given hidden service. */ -+void -+rend_client_purge_hidden_service(const char *onion_address) -+{ -+ tor_assert(rend_valid_service_id(onion_address)); -+ -+ rend_cache_remove_entry(onion_address); -+ purge_hid_serv_from_last_hid_serv_requests(onion_address); -+} -+ - /** Called when we've established a circuit to an introduction point: - * send the introduction request. */ - void -diff --git a/src/or/rendclient.h b/src/or/rendclient.h -index 1f731d0..7084aef 100644 ---- a/src/or/rendclient.h -+++ b/src/or/rendclient.h -@@ -13,6 +13,7 @@ - #define TOR_RENDCLIENT_H - - void rend_client_purge_state(void); -+void rend_client_purge_hidden_service(const char *onion_address); - - void rend_client_introcirc_has_opened(origin_circuit_t *circ); - void rend_client_rendcirc_has_opened(origin_circuit_t *circ); -diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c -index a664b5d..70d7283 100644 ---- a/src/or/rendcommon.c -+++ b/src/or/rendcommon.c -@@ -881,6 +881,34 @@ rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e) - return 1; - } - -+/** Remove any cached descriptors for <b>service_id/b>. */ -+void -+rend_cache_remove_entry(const char *service_id) -+{ -+ char key[REND_SERVICE_ID_LEN_BASE32+2]; /* <version><service_id>\0 */ -+ rend_cache_entry_t *removed; -+ -+ tor_assert(rend_valid_service_id(service_id)); -+ if (!rend_cache) -+ return; -+ -+ tor_snprintf(key, sizeof(key), "2%s", service_id); -+ removed = (rend_cache_entry_t *)strmap_remove_lc(rend_cache, key); -+ if (removed) { -+ log_info(LD_REND, "Removed cached v2 descriptor for service %s.", -+ safe_str_client(service_id)); -+ rend_cache_entry_free(removed); -+ } -+ -+ tor_snprintf(key, sizeof(key), "0%s", service_id); -+ removed = (rend_cache_entry_t *)strmap_remove_lc(rend_cache, key); -+ if (removed) { -+ log_info(LD_REND, "Removed cached v0 descriptor for service %s.", -+ safe_str_client(service_id)); -+ rend_cache_entry_free(removed); -+ } -+} -+ - /** Lookup the v2 service descriptor with base32-encoded <b>desc_id</b> and - * copy the pointer to it to *<b>desc</b>. Return 1 on success, 0 on - * well-formed-but-not-found, and -1 on failure. -diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h -index 07a47ac..0a3160d 100644 ---- a/src/or/rendcommon.h -+++ b/src/or/rendcommon.h -@@ -39,6 +39,7 @@ void rend_cache_free_all(void); - int rend_valid_service_id(const char *query); - int rend_cache_lookup_entry(const char *query, int version, - rend_cache_entry_t **entry_out); -+void rend_cache_remove_entry(const char *service_id); - int rend_cache_lookup_v2_desc_as_dir(const char *query, const char **desc); - /** Return value from rend_cache_store_v2_desc_as_{dir,client}. */ - typedef enum { -diff --git a/src/or/rendservice.c b/src/or/rendservice.c -index a7c1e32..cc9c0f8 100644 ---- a/src/or/rendservice.c -+++ b/src/or/rendservice.c -@@ -16,6 +16,7 @@ - #include "circuituse.h" - #include "config.h" - #include "directory.h" -+#include "main.h" - #include "networkstatus.h" - #include "nodelist.h" - #include "rendclient.h" -@@ -3033,6 +3034,9 @@ rend_services_introduce(void) - time_t now; - const or_options_t *options = get_options(); - -+ if (!can_complete_circuit) -+ return; -+ - intro_nodes = smartlist_new(); - now = time(NULL); - ===================================== weupnp-0.1.3-SNAPSHOT.patch ===================================== --- a/weupnp-0.1.3-SNAPSHOT.patch +++ /dev/null @@ -1,40 +0,0 @@ -diff -Bbur weupnp-0.1.3-SNAPSHOT/src/main/java/org/bitlet/weupnp/GatewayDiscover.java weupnp-0.1.3-SNAPSHOT-briar/src/main/java/org/bitlet/weupnp/GatewayDiscover.java ---- weupnp-0.1.3-SNAPSHOT/src/main/java/org/bitlet/weupnp/GatewayDiscover.java 2013-05-01 21:09:27.000000000 +0100 -+++ weupnp-0.1.3-SNAPSHOT-briar/src/main/java/org/bitlet/weupnp/GatewayDiscover.java 2013-12-05 20:49:00.000000000 +0000 -@@ -253,7 +253,7 @@ - while (st.hasMoreTokens()) { - String line = st.nextToken().trim(); - -- if (line.isEmpty()) -+ if (line.equals("")) - continue; - - if (line.startsWith("HTTP/1.") || line.startsWith("NOTIFY *")) -@@ -331,16 +331,6 @@ - // For every suitable network interface, get all IP addresses - while (networkInterfaces.hasMoreElements()) { - NetworkInterface card = networkInterfaces.nextElement(); -- -- try { -- // skip devices, not suitable to search gateways for -- if (card.isLoopback() || card.isPointToPoint() || -- card.isVirtual() || !card.isUp()) -- continue; -- } catch (SocketException e) { -- continue; -- } -- - Enumeration<InetAddress> addresses = card.getInetAddresses(); - - if (addresses == null) -@@ -348,6 +338,10 @@ - - while (addresses.hasMoreElements()) { - InetAddress inetAddress = addresses.nextElement(); -+ -+ if (inetAddress.isLoopbackAddress()) -+ continue; -+ - int index = arrayIPAddress.size(); - - if (!getIPv4 || !getIPv6) { |
From: akwizgran <gi...@br...> - 2015-01-29 11:30:40
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="7fbad8dc" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/7fbad8dc26cfe27535ba2d7d5ac0360abd374ff6">7fbad8dc</a> by akwizgran Use FortunaGenerator to implement PseudoRandom. - - - - - <a href="bb3ec5a2" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/bb3ec5a2d69c1ffbfd439e733410c8710929f107">bb3ec5a2</a> by Abraham Kiggundu Abe#1 fixed link to generated folder - - - - - <a href="7af25fc7" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/7af25fc74d089ad0967c85495780cccb23276df5">7af25fc7</a> by Abraham Kiggundu Revert "Abe#1 fixed link to generated folder" This reverts commit bb3ec5a2d69c1ffbfd439e733410c8710929f107. - - - - - <a href="5b7938ac" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/5b7938ac4ddafc22be123022ba679527104ed221">5b7938ac</a> by Abraham Kiggundu fixed missing linked folder resource - - - - - <a href="f0f5daf6" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/f0f5daf607c32e758d5da8a67c7a0f508a301109">f0f5daf6</a> by akwizgran Updated Bouncy Castle source code. - - - - - <a href="c1d24d05" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/c1d24d050aeb7a5f1d2a7365a77b9174e63e3f6c">c1d24d05</a> by akwizgran Skip platform-specific tests when testing on another platform. - - - - - <a href="6cc864db" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/6cc864db2c52eabeba32de2b9521e5e9ba109cd4">6cc864db</a> by akwizgran Bumped expiry date to 1 January 2015. - - - - - <a href="f591a22a" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/f591a22af86959f707fd2df385bf243e75e2e325">f591a22a</a> by Abraham Kiggundu Added travis CI build - - - - - <a href="b8ad7542" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/b8ad75426e5091e1e84dd0d0414f418ed7b86a33">b8ad7542</a> by Abraham Kiggundu Added CI info to Readme - - - - - <a href="a076940f" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/a076940f73b1152d5d717d545b6d55fcadcdf1d5">a076940f</a> by Abraham Kiggundu Fixed Travis build - - - - - <a href="5c754f5c" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/5c754f5c5639f6cb62e0eb6baa807e017bb44138">5c754f5c</a> by Abraham Kiggundu Fixed Travis Build - - - - - <a href="9d0f871b" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/9d0f871bcdab10063a0eed87124c8c05504ff09d">9d0f871b</a> by Abraham Kiggundu Fix travis build - - - - - <a href="0bd07020" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/0bd07020596e7a804c05dffe4e61eb894e3354ae">0bd07020</a> by Abraham Kiggundu Fixed Travis build status markdown - - - - - <a href="b9436aaa" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/b9436aaaa9fcd2f14ae7adbd5ccf7885e37888cf">b9436aaa</a> by Abraham Kiggundu Fixed Travis build - - - - - <a href="0f8baf77" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/0f8baf7726c5a471d40a2d16920c7eb78c595376">0f8baf77</a> by Abraham Kiggundu Fix Travis Build - - - - - <a href="276dcb10" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/276dcb1038be6810c16d3da624a12a9b9f10ae07">276dcb10</a> by Abraham Kiggundu undo unnecessary changes to .project file and ignore eclipse metadata - - - - - <a href="b0749784" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/b074978472f4b4df5809676b251261d3ac2bc0e6">b0749784</a> by Abraham Kiggundu Improved encapsulation of thread synchronisation as follows - replaced use of Object instance mutex with a private final Lock object - replaced Object signaling with specific condition signalling - - - - - <a href="9a2e93eb" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/9a2e93ebb91ad12ce4db38f6f4d80259e832e623">9a2e93eb</a> by Abraham Kiggundu cleanup - - - - - <a href="8b79d840" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/8b79d8402948803d21092c67dcf80485ef6b480c">8b79d840</a> by Abraham Kiggundu Fix to travis android build tools version - - - - - <a href="2b9c4690" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/2b9c46906373f23ef8a51c67fd4342c110b6b48a">2b9c4690</a> by Abraham Kiggundu Merge branch 'improve-thread-encapsulation' into upstream - - - - - <a href="2933f1a8" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/2933f1a8747d09317e388d0a1ea6725699b4c045">2933f1a8</a> by Abraham Kiggundu Reverted inadvertent downgrade of gradle version - - - - - <a href="be2a92d6" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/be2a92d6c29410b4e03235620141e055a97a3a59">be2a92d6</a> by Abraham Kiggundu Revert lock variable rename for clarity - - - - - <a href="8d25840a" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/8d25840a1d5c936a53c62fa2cc6630b1cc2b6baf">8d25840a</a> by Abraham Kiggundu Fixed bug calling notifyAll instead of signalAll - - - - - <a href="85115104" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/851151041ece26bcd03f7a3d35dcbc4a2d258642">85115104</a> by Abraham Kiggundu Pull-Merge of latest changes from main repo - - - - - <a href="686d5fd2" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/686d5fd206b5f7f5c4f42800bf7abf3d37a4f671">686d5fd2</a> by Abraham Kiggundu bug#49 Fixed by ensuring that intents for different contacts/groups can be distinguished from each other when resolving PendingIntent refs - - - - - <a href="fcb983a6" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/fcb983a651e3a75cd77fc4b8db736c576a563666">fcb983a6</a> by Abraham Kiggundu Bug#49 https://sourceforge.net/p/briar/bugs/49/ Fixed by ensuring that the generated contact and group intents are uniquely identified - - - - - <a href="47bd8412" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/47bd84122e5a490582924792700b4e0265e9f8ad">47bd8412</a> by akwizgran Code formatting and small cleanups. - - - - - <a href="0dbfd707" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/0dbfd7073f8edf6e3b9afde05da7ff16bedc8f2d">0dbfd707</a> by akwizgran Comments to indicate which locks guard which variables. - - - - - <a href="f8a4a492" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/f8a4a4920d06f2b35b5b0fd73c2b0cdf77008815">f8a4a492</a> by akwizgran Merge branch 'AbrahamKiggundu/briar-master': better lock encapsulation - - - - - Changes: ===================================== .gitignore ===================================== --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ build .gradle +.metadata +*.tmp ===================================== briar-android/src/org/briarproject/android/AndroidModule.java ===================================== --- a/briar-android/src/org/briarproject/android/AndroidModule.java +++ b/briar-android/src/org/briarproject/android/AndroidModule.java @@ -9,6 +9,7 @@ import javax.inject.Singleton; import org.briarproject.api.android.AndroidExecutor; import org.briarproject.api.android.AndroidNotificationManager; import org.briarproject.api.android.ReferenceManager; +import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.db.DatabaseConfig; import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.ui.UiCallback; @@ -54,7 +55,7 @@ public class AndroidModule extends AbstractModule { final File dir = app.getApplicationContext().getDir("db", MODE_PRIVATE); return new DatabaseConfig() { - private volatile byte[] key = null; + private volatile SecretKey key = null; public boolean databaseExists() { return dir.isDirectory() && dir.listFiles().length > 0; @@ -64,11 +65,11 @@ public class AndroidModule extends AbstractModule { return dir; } - public void setEncryptionKey(byte[] key) { + public void setEncryptionKey(SecretKey key) { this.key = key; } - public byte[] getEncryptionKey() { + public SecretKey getEncryptionKey() { return key; } ===================================== briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java ===================================== --- a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java +++ b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java @@ -11,6 +11,8 @@ import static java.util.logging.Level.WARNING; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Executor; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; import javax.inject.Inject; @@ -47,6 +49,10 @@ Service, EventListener { private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3; private static final int GROUP_POST_NOTIFICATION_ID = 4; + private static final String CONTACT_URI = + "content://org.briarproject/contact"; + private static final String GROUP_URI = + "content://org.briarproject/group"; private static final Logger LOG = Logger.getLogger(AndroidNotificationManagerImpl.class.getName()); @@ -55,13 +61,15 @@ Service, EventListener { private final Executor dbExecutor; private final EventBus eventBus; private final Context appContext; + private final Lock synchLock = new ReentrantLock(); + + // The following are locking: synchLock private final Map<ContactId, Integer> contactCounts = - new HashMap<ContactId, Integer>(); // Locking: this + new HashMap<ContactId, Integer>(); private final Map<GroupId, Integer> groupCounts = - new HashMap<GroupId, Integer>(); // Locking: this - - private int privateTotal = 0, groupTotal = 0; // Locking: this - private int nextRequestId = 0; // Locking: this + new HashMap<GroupId, Integer>(); + private int privateTotal = 0, groupTotal = 0; + private int nextRequestId = 0; private volatile Settings settings = new Settings(); @@ -103,22 +111,32 @@ Service, EventListener { if(e instanceof SettingsUpdatedEvent) loadSettings(); } - public synchronized void showPrivateMessageNotification(ContactId c) { - Integer count = contactCounts.get(c); - if(count == null) contactCounts.put(c, 1); - else contactCounts.put(c, count + 1); - privateTotal++; - updatePrivateMessageNotification(); + public void showPrivateMessageNotification(ContactId c) { + synchLock.lock(); + try { + Integer count = contactCounts.get(c); + if(count == null) contactCounts.put(c, 1); + else contactCounts.put(c, count + 1); + privateTotal++; + updatePrivateMessageNotification(); + } finally { + synchLock.unlock(); + } } - public synchronized void clearPrivateMessageNotification(ContactId c) { - Integer count = contactCounts.remove(c); - if(count == null) return; // Already cleared - privateTotal -= count; - updatePrivateMessageNotification(); + public void clearPrivateMessageNotification(ContactId c) { + synchLock.lock(); + try { + Integer count = contactCounts.remove(c); + if(count == null) return; // Already cleared + privateTotal -= count; + updatePrivateMessageNotification(); + } finally { + synchLock.unlock(); + } } - // Locking: this + // Locking: synchLock private void updatePrivateMessageNotification() { if(privateTotal == 0) { clearPrivateMessageNotification(); @@ -143,6 +161,7 @@ Service, EventListener { Intent i = new Intent(appContext, ConversationActivity.class); ContactId c = contactCounts.keySet().iterator().next(); i.putExtra("briar.CONTACT_ID", c.getInt()); + i.setData(Uri.parse(CONTACT_URI + "/" + c.getInt())); i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); TaskStackBuilder t = TaskStackBuilder.create(appContext); t.addParentStack(ConversationActivity.class); @@ -162,7 +181,7 @@ Service, EventListener { } } - // Locking: this + // Locking: synchLock private void clearPrivateMessageNotification() { Object o = appContext.getSystemService(NOTIFICATION_SERVICE); NotificationManager nm = (NotificationManager) o; @@ -180,22 +199,32 @@ Service, EventListener { return defaults; } - public synchronized void showGroupPostNotification(GroupId g) { - Integer count = groupCounts.get(g); - if(count == null) groupCounts.put(g, 1); - else groupCounts.put(g, count + 1); - groupTotal++; - updateGroupPostNotification(); + public void showGroupPostNotification(GroupId g) { + synchLock.lock(); + try { + Integer count = groupCounts.get(g); + if(count == null) groupCounts.put(g, 1); + else groupCounts.put(g, count + 1); + groupTotal++; + updateGroupPostNotification(); + } finally { + synchLock.unlock(); + } } - public synchronized void clearGroupPostNotification(GroupId g) { - Integer count = groupCounts.remove(g); - if(count == null) return; // Already cleared - groupTotal -= count; - updateGroupPostNotification(); + public void clearGroupPostNotification(GroupId g) { + synchLock.lock(); + try { + Integer count = groupCounts.remove(g); + if(count == null) return; // Already cleared + groupTotal -= count; + updateGroupPostNotification(); + } finally { + synchLock.unlock(); + } } - // Locking: this + // Locking: synchLock private void updateGroupPostNotification() { if(groupTotal == 0) { clearGroupPostNotification(); @@ -219,6 +248,8 @@ Service, EventListener { Intent i = new Intent(appContext, GroupActivity.class); GroupId g = groupCounts.keySet().iterator().next(); i.putExtra("briar.GROUP_ID", g.getBytes()); + String idHex = StringUtils.toHexString(g.getBytes()); + i.setData(Uri.parse(GROUP_URI + "/" + idHex)); i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); TaskStackBuilder t = TaskStackBuilder.create(appContext); t.addParentStack(GroupActivity.class); @@ -238,18 +269,23 @@ Service, EventListener { } } - // Locking: this + // Locking: synchLock private void clearGroupPostNotification() { Object o = appContext.getSystemService(NOTIFICATION_SERVICE); NotificationManager nm = (NotificationManager) o; nm.cancel(GROUP_POST_NOTIFICATION_ID); } - public synchronized void clearNotifications() { - contactCounts.clear(); - groupCounts.clear(); - privateTotal = groupTotal = 0; - clearPrivateMessageNotification(); - clearGroupPostNotification(); + public void clearNotifications() { + synchLock.lock(); + try { + contactCounts.clear(); + groupCounts.clear(); + privateTotal = groupTotal = 0; + clearPrivateMessageNotification(); + clearGroupPostNotification(); + } finally { + synchLock.unlock(); + } } } ===================================== briar-android/src/org/briarproject/android/PasswordActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/PasswordActivity.java +++ b/briar-android/src/org/briarproject/android/PasswordActivity.java @@ -23,6 +23,7 @@ import org.briarproject.android.util.FixedVerticalSpace; import org.briarproject.android.util.LayoutUtils; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoExecutor; +import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.db.DatabaseConfig; import org.briarproject.util.StringUtils; @@ -140,7 +141,7 @@ public class PasswordActivity extends RoboActivity { if(key == null) { tryAgain(); } else { - databaseConfig.setEncryptionKey(key); + databaseConfig.setEncryptionKey(new SecretKey(key)); setResultAndFinish(); } } ===================================== briar-android/src/org/briarproject/android/ReferenceManagerImpl.java ===================================== --- a/briar-android/src/org/briarproject/android/ReferenceManagerImpl.java +++ b/briar-android/src/org/briarproject/android/ReferenceManagerImpl.java @@ -4,6 +4,8 @@ import static java.util.logging.Level.INFO; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; import org.briarproject.api.android.ReferenceManager; @@ -13,49 +15,67 @@ class ReferenceManagerImpl implements ReferenceManager { private static final Logger LOG = Logger.getLogger(ReferenceManagerImpl.class.getName()); - // Locking: this + private final Lock synchLock = new ReentrantLock(); + + // The following are locking: synchLock private final Map<Class<?>, Map<Long, Object>> outerMap = new HashMap<Class<?>, Map<Long, Object>>(); + private long nextHandle = 0; - private long nextHandle = 0; // Locking: this - - public synchronized <T> T getReference(long handle, Class<T> c) { - Map<Long, Object> innerMap = outerMap.get(c); - if(innerMap == null) { + public <T> T getReference(long handle, Class<T> c) { + synchLock.lock(); + try { + Map<Long, Object> innerMap = outerMap.get(c); + if(innerMap == null) { + if(LOG.isLoggable(INFO)) + LOG.info("0 handles for " + c.getName()); + return null; + } if(LOG.isLoggable(INFO)) - LOG.info("0 handles for " + c.getName()); - return null; + LOG.info(innerMap.size() + " handles for " + c.getName()); + Object o = innerMap.get(handle); + return c.cast(o); + } finally { + synchLock.unlock(); } - if(LOG.isLoggable(INFO)) - LOG.info(innerMap.size() + " handles for " + c.getName()); - Object o = innerMap.get(handle); - return c.cast(o); + } - public synchronized <T> long putReference(T reference, Class<T> c) { - Map<Long, Object> innerMap = outerMap.get(c); - if(innerMap == null) { - innerMap = new HashMap<Long, Object>(); - outerMap.put(c, innerMap); + public <T> long putReference(T reference, Class<T> c) { + synchLock.lock(); + try { + Map<Long, Object> innerMap = outerMap.get(c); + if(innerMap == null) { + innerMap = new HashMap<Long, Object>(); + outerMap.put(c, innerMap); + } + long handle = nextHandle++; + innerMap.put(handle, reference); + if(LOG.isLoggable(INFO)) { + LOG.info(innerMap.size() + " handles for " + c.getName() + + " after put"); + } + return handle; + } finally { + synchLock.unlock(); } - long handle = nextHandle++; - innerMap.put(handle, reference); - if(LOG.isLoggable(INFO)) { - LOG.info(innerMap.size() + " handles for " + c.getName() + - " after put"); - } - return handle; } - public synchronized <T> T removeReference(long handle, Class<T> c) { - Map<Long, Object> innerMap = outerMap.get(c); - if(innerMap == null) return null; - Object o = innerMap.remove(handle); - if(innerMap.isEmpty()) outerMap.remove(c); - if(LOG.isLoggable(INFO)) { - LOG.info(innerMap.size() + " handles for " + c.getName() + - " after remove"); + public <T> T removeReference(long handle, Class<T> c) { + synchLock.lock(); + try { + Map<Long, Object> innerMap = outerMap.get(c); + if(innerMap == null) return null; + Object o = innerMap.remove(handle); + if(innerMap.isEmpty()) outerMap.remove(c); + if(LOG.isLoggable(INFO)) { + LOG.info(innerMap.size() + " handles for " + c.getName() + + " after remove"); + } + return c.cast(o); + } finally { + synchLock.unlock(); } - return c.cast(o); + } } ===================================== briar-android/src/org/briarproject/android/SetupActivity.java ===================================== --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -34,6 +34,7 @@ import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoExecutor; import org.briarproject.api.crypto.KeyPair; import org.briarproject.api.crypto.PasswordStrengthEstimator; +import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.db.DatabaseConfig; import org.briarproject.util.StringUtils; @@ -225,7 +226,7 @@ OnEditorActionListener { // Store the DB key and create the identity in a background thread cryptoExecutor.execute(new Runnable() { public void run() { - byte[] key = crypto.generateSecretKey().getBytes(); + SecretKey key = crypto.generateSecretKey(); databaseConfig.setEncryptionKey(key); byte[] encrypted = encryptDatabaseKey(key, password); storeEncryptedDatabaseKey(encrypted); @@ -247,9 +248,9 @@ OnEditorActionListener { LOG.info("Key storage took " + duration + " ms"); } - private byte[] encryptDatabaseKey(byte[] key, String password) { + private byte[] encryptDatabaseKey(SecretKey key, String password) { long now = System.currentTimeMillis(); - byte[] encrypted = crypto.encryptWithPassword(key, password); + byte[] encrypted = crypto.encryptWithPassword(key.getBytes(), password); long duration = System.currentTimeMillis() - now; if(LOG.isLoggable(INFO)) LOG.info("Key derivation took " + duration + " ms"); ===================================== briar-android/src/org/briarproject/system/AndroidLocationUtils.java ===================================== --- a/briar-android/src/org/briarproject/system/AndroidLocationUtils.java +++ b/briar-android/src/org/briarproject/system/AndroidLocationUtils.java @@ -34,9 +34,6 @@ class AndroidLocationUtils implements LocationUtils { * <ul> * <li>Phone network. This works even when no SIM card is inserted, or a * foreign SIM card is inserted.</li> - * <li><del>Location service (GPS/WiFi/etc).</del> <em>This is disabled for - * now, until we figure out an offline method of converting a long/lat - * into a country code, that doesn't involve a network call.</em> * <li>SIM card. This is only an heuristic and assumes the user is not * roaming.</li> * <li>User locale. This is an even worse heuristic.</li> ===================================== briar-api/src/org/briarproject/api/crypto/SecretKey.java ===================================== --- a/briar-api/src/org/briarproject/api/crypto/SecretKey.java +++ b/briar-api/src/org/briarproject/api/crypto/SecretKey.java @@ -3,9 +3,12 @@ package org.briarproject.api.crypto; /** A secret key used for encryption and/or authentication. */ public class SecretKey { + public static final int LENGTH = 32; // Bytes + private final byte[] key; public SecretKey(byte[] key) { + if(key.length != LENGTH) throw new IllegalArgumentException(); this.key = key; } ===================================== briar-api/src/org/briarproject/api/db/DatabaseConfig.java ===================================== --- a/briar-api/src/org/briarproject/api/db/DatabaseConfig.java +++ b/briar-api/src/org/briarproject/api/db/DatabaseConfig.java @@ -2,15 +2,17 @@ package org.briarproject.api.db; import java.io.File; +import org.briarproject.api.crypto.SecretKey; + public interface DatabaseConfig { boolean databaseExists(); File getDatabaseDirectory(); - void setEncryptionKey(byte[] key); + void setEncryptionKey(SecretKey key); - byte[] getEncryptionKey(); + SecretKey getEncryptionKey(); long getMaxSize(); } ===================================== briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java ===================================== --- a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java +++ b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java @@ -9,7 +9,6 @@ import static org.briarproject.util.ByteUtils.MAX_32_BIT_UNSIGNED; import java.security.GeneralSecurityException; import java.security.SecureRandom; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.logging.Logger; @@ -49,7 +48,6 @@ class CryptoComponentImpl implements CryptoComponent { private static final Logger LOG = Logger.getLogger(CryptoComponentImpl.class.getName()); - private static final int CIPHER_KEY_BYTES = 32; // 256 bits private static final int AGREEMENT_KEY_PAIR_BITS = 256; private static final int SIGNATURE_KEY_PAIR_BITS = 256; private static final int STORAGE_IV_BYTES = 16; // 128 bits @@ -73,8 +71,6 @@ class CryptoComponentImpl implements CryptoComponent { { 'A', '_', 'F', 'R', 'A', 'M', 'E', '\0' }; private static final byte[] B_FRAME = { 'B', '_', 'F', 'R', 'A', 'M', 'E', '\0' }; - // Blank secret for argument validation - private static final byte[] BLANK_SECRET = new byte[CIPHER_KEY_BYTES]; private final SecureRandom secureRandom; private final ECKeyPairGenerator agreementKeyPairGenerator; @@ -105,7 +101,7 @@ class CryptoComponentImpl implements CryptoComponent { } public SecretKey generateSecretKey() { - byte[] b = new byte[CIPHER_KEY_BYTES]; + byte[] b = new byte[SecretKey.LENGTH]; secureRandom.nextBytes(b); return new SecretKey(b); } @@ -115,7 +111,7 @@ class CryptoComponentImpl implements CryptoComponent { } public PseudoRandom getPseudoRandom(int seed1, int seed2) { - return new PseudoRandomImpl(getMessageDigest(), seed1, seed2); + return new PseudoRandomImpl(seed1, seed2); } public SecureRandom getSecureRandom() { @@ -172,9 +168,7 @@ class CryptoComponentImpl implements CryptoComponent { } public int[] deriveConfirmationCodes(byte[] secret) { - if(secret.length != CIPHER_KEY_BYTES) - throw new IllegalArgumentException(); - if(Arrays.equals(secret, BLANK_SECRET)) + if(secret.length != SecretKey.LENGTH) throw new IllegalArgumentException(); byte[] alice = counterModeKdf(secret, CODE, 0); byte[] bob = counterModeKdf(secret, CODE, 1); @@ -185,9 +179,7 @@ class CryptoComponentImpl implements CryptoComponent { } public byte[][] deriveInvitationNonces(byte[] secret) { - if(secret.length != CIPHER_KEY_BYTES) - throw new IllegalArgumentException(); - if(Arrays.equals(secret, BLANK_SECRET)) + if(secret.length != SecretKey.LENGTH) throw new IllegalArgumentException(); byte[] alice = counterModeKdf(secret, NONCE, 0); byte[] bob = counterModeKdf(secret, NONCE, 1); @@ -237,26 +229,20 @@ class CryptoComponentImpl implements CryptoComponent { } public byte[] deriveGroupSalt(byte[] secret) { - if(secret.length != CIPHER_KEY_BYTES) - throw new IllegalArgumentException(); - if(Arrays.equals(secret, BLANK_SECRET)) + if(secret.length != SecretKey.LENGTH) throw new IllegalArgumentException(); return counterModeKdf(secret, SALT, 0); } public byte[] deriveInitialSecret(byte[] secret, int transportIndex) { - if(secret.length != CIPHER_KEY_BYTES) - throw new IllegalArgumentException(); - if(Arrays.equals(secret, BLANK_SECRET)) + if(secret.length != SecretKey.LENGTH) throw new IllegalArgumentException(); if(transportIndex < 0) throw new IllegalArgumentException(); return counterModeKdf(secret, FIRST, transportIndex); } public byte[] deriveNextSecret(byte[] secret, long period) { - if(secret.length != CIPHER_KEY_BYTES) - throw new IllegalArgumentException(); - if(Arrays.equals(secret, BLANK_SECRET)) + if(secret.length != SecretKey.LENGTH) throw new IllegalArgumentException(); if(period < 0 || period > MAX_32_BIT_UNSIGNED) throw new IllegalArgumentException(); @@ -264,9 +250,7 @@ class CryptoComponentImpl implements CryptoComponent { } public SecretKey deriveTagKey(byte[] secret, boolean alice) { - if(secret.length != CIPHER_KEY_BYTES) - throw new IllegalArgumentException(); - if(Arrays.equals(secret, BLANK_SECRET)) + if(secret.length != SecretKey.LENGTH) throw new IllegalArgumentException(); if(alice) return deriveKey(secret, A_TAG, 0); else return deriveKey(secret, B_TAG, 0); @@ -274,9 +258,7 @@ class CryptoComponentImpl implements CryptoComponent { public SecretKey deriveFrameKey(byte[] secret, long streamNumber, boolean alice) { - if(secret.length != CIPHER_KEY_BYTES) - throw new IllegalArgumentException(); - if(Arrays.equals(secret, BLANK_SECRET)) + if(secret.length != SecretKey.LENGTH) throw new IllegalArgumentException(); if(streamNumber < 0 || streamNumber > MAX_32_BIT_UNSIGNED) throw new IllegalArgumentException(); @@ -366,32 +348,30 @@ class CryptoComponentImpl implements CryptoComponent { // Key derivation function based on a hash function - see NIST SP 800-56A, // section 5.8 - private byte[] concatenationKdf(byte[]... args) { + private byte[] concatenationKdf(byte[]... inputs) { // The output of the hash function must be long enough to use as a key MessageDigest messageDigest = getMessageDigest(); - if(messageDigest.getDigestLength() < CIPHER_KEY_BYTES) + if(messageDigest.getDigestLength() < SecretKey.LENGTH) throw new RuntimeException(); - // Each argument is length-prefixed - the length must fit in an + // Each input is length-prefixed - the length must fit in an // unsigned 8-bit integer - for(byte[] arg : args) { - if(arg.length > 255) throw new IllegalArgumentException(); - messageDigest.update((byte) arg.length); - messageDigest.update(arg); + for(byte[] input : inputs) { + if(input.length > 255) throw new IllegalArgumentException(); + messageDigest.update((byte) input.length); + messageDigest.update(input); } byte[] hash = messageDigest.digest(); - // The output is the first CIPHER_KEY_BYTES bytes of the hash - if(hash.length == CIPHER_KEY_BYTES) return hash; - byte[] output = new byte[CIPHER_KEY_BYTES]; - System.arraycopy(hash, 0, output, 0, output.length); - return output; + // The output is the first SecretKey.LENGTH bytes of the hash + if(hash.length == SecretKey.LENGTH) return hash; + byte[] truncated = new byte[SecretKey.LENGTH]; + System.arraycopy(hash, 0, truncated, 0, truncated.length); + return truncated; } // Key derivation function based on a PRF in counter mode - see // NIST SP 800-108, section 5.1 private byte[] counterModeKdf(byte[] secret, byte[] label, long context) { - if(secret.length != CIPHER_KEY_BYTES) - throw new IllegalArgumentException(); - if(Arrays.equals(secret, BLANK_SECRET)) + if(secret.length != SecretKey.LENGTH) throw new IllegalArgumentException(); // The label must be null-terminated if(label[label.length - 1] != '\0') @@ -402,20 +382,20 @@ class CryptoComponentImpl implements CryptoComponent { prf.init(k); int macLength = prf.getMacSize(); // The output of the PRF must be long enough to use as a key - if(macLength < CIPHER_KEY_BYTES) throw new RuntimeException(); + if(macLength < SecretKey.LENGTH) throw new RuntimeException(); byte[] mac = new byte[macLength]; prf.update((byte) 0); // Counter prf.update(label, 0, label.length); // Null-terminated byte[] contextBytes = new byte[4]; ByteUtils.writeUint32(context, contextBytes, 0); prf.update(contextBytes, 0, contextBytes.length); - prf.update((byte) CIPHER_KEY_BYTES); // Output length + prf.update((byte) SecretKey.LENGTH); // Output length prf.doFinal(mac, 0); - // The output is the first CIPHER_KEY_BYTES bytes of the MAC - if(mac.length == CIPHER_KEY_BYTES) return mac; - byte[] output = new byte[CIPHER_KEY_BYTES]; - System.arraycopy(mac, 0, output, 0, output.length); - return output; + // The output is the first SecretKey.LENGTH bytes of the MAC + if(mac.length == SecretKey.LENGTH) return mac; + byte[] truncated = new byte[SecretKey.LENGTH]; + System.arraycopy(mac, 0, truncated, 0, truncated.length); + return truncated; } // Password-based key derivation function - see PKCS#5 v2.1, section 5.2 @@ -424,7 +404,7 @@ class CryptoComponentImpl implements CryptoComponent { Digest digest = new SHA256Digest(); PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(digest); gen.init(utf8, salt, iterations); - int keyLengthInBits = CIPHER_KEY_BYTES * 8; + int keyLengthInBits = SecretKey.LENGTH * 8; CipherParameters p = gen.generateDerivedParameters(keyLengthInBits); return ((KeyParameter) p).getKey(); } @@ -461,7 +441,7 @@ class CryptoComponentImpl implements CryptoComponent { private long sampleRunningTime(int iterations) { byte[] password = { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' }; byte[] salt = new byte[PBKDF_SALT_BYTES]; - int keyLengthInBits = CIPHER_KEY_BYTES * 8; + int keyLengthInBits = SecretKey.LENGTH * 8; long start = System.nanoTime(); Digest digest = new SHA256Digest(); PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(digest); ===================================== briar-core/src/org/briarproject/crypto/FortunaGenerator.java ===================================== --- a/briar-core/src/org/briarproject/crypto/FortunaGenerator.java +++ b/briar-core/src/org/briarproject/crypto/FortunaGenerator.java @@ -1,5 +1,8 @@ package org.briarproject.crypto; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + import org.briarproject.api.crypto.MessageDigest; import org.spongycastle.crypto.BlockCipher; import org.spongycastle.crypto.digests.SHA256Digest; @@ -16,7 +19,9 @@ class FortunaGenerator { private static final int KEY_BYTES = 32; private static final int BLOCK_BYTES = 16; - // All of the following are locking: this + private final Lock synchLock = new ReentrantLock(); + + // The following are locking: synchLock private final MessageDigest digest = new DoubleDigest(new SHA256Digest()); private final BlockCipher cipher = new AESLightEngine(); private final byte[] key = new byte[KEY_BYTES]; @@ -28,56 +33,78 @@ class FortunaGenerator { reseed(seed); } - synchronized void reseed(byte[] seed) { - digest.update(key); - digest.update(seed); - digest.digest(key, 0, KEY_BYTES); - incrementCounter(); + void reseed(byte[] seed) { + synchLock.lock(); + try { + digest.update(key); + digest.update(seed); + digest.digest(key, 0, KEY_BYTES); + incrementCounter(); + } finally { + synchLock.unlock(); + } + } // Package access for testing - synchronized void incrementCounter() { - counter[0]++; - for(int i = 0; counter[i] == 0; i++) { - if(i + 1 == BLOCK_BYTES) - throw new RuntimeException("Counter exhausted"); - counter[i + 1]++; + void incrementCounter() { + synchLock.lock(); + try { + counter[0]++; + for(int i = 0; counter[i] == 0; i++) { + if(i + 1 == BLOCK_BYTES) + throw new RuntimeException("Counter exhausted"); + counter[i + 1]++; + } + } finally { + synchLock.unlock(); } } // Package access for testing - synchronized byte[] getCounter() { - return counter; + byte[] getCounter() { + synchLock.lock(); + try { + return counter; + } finally { + synchLock.unlock(); + } + } - synchronized int nextBytes(byte[] dest, int off, int len) { - // Don't write more than the maximum number of bytes in one request - if(len > MAX_BYTES_PER_REQUEST) len = MAX_BYTES_PER_REQUEST; - cipher.init(true, new KeyParameter(key)); - // Generate full blocks directly into the output buffer - int fullBlocks = len / BLOCK_BYTES; - for(int i = 0; i < fullBlocks; i++) { - cipher.processBlock(counter, 0, dest, off + i * BLOCK_BYTES); - incrementCounter(); - } - // Generate a partial block if needed - int done = fullBlocks * BLOCK_BYTES, remaining = len - done; - assert remaining < BLOCK_BYTES; - if(remaining > 0) { - cipher.processBlock(counter, 0, buffer, 0); - incrementCounter(); - // Copy the partial block to the output buffer and erase our copy - System.arraycopy(buffer, 0, dest, off + done, remaining); - for(int i = 0; i < BLOCK_BYTES; i++) buffer[i] = 0; - } - // Generate a new key - for(int i = 0; i < KEY_BYTES / BLOCK_BYTES; i++) { - cipher.processBlock(counter, 0, newKey, i * BLOCK_BYTES); - incrementCounter(); + int nextBytes(byte[] dest, int off, int len) { + synchLock.lock(); + try { + // Don't write more than the maximum number of bytes in one request + if(len > MAX_BYTES_PER_REQUEST) len = MAX_BYTES_PER_REQUEST; + cipher.init(true, new KeyParameter(key)); + // Generate full blocks directly into the output buffer + int fullBlocks = len / BLOCK_BYTES; + for(int i = 0; i < fullBlocks; i++) { + cipher.processBlock(counter, 0, dest, off + i * BLOCK_BYTES); + incrementCounter(); + } + // Generate a partial block if needed + int done = fullBlocks * BLOCK_BYTES, remaining = len - done; + assert remaining < BLOCK_BYTES; + if(remaining > 0) { + cipher.processBlock(counter, 0, buffer, 0); + incrementCounter(); + // Copy the partial block to the output buffer and erase our copy + System.arraycopy(buffer, 0, dest, off + done, remaining); + for(int i = 0; i < BLOCK_BYTES; i++) buffer[i] = 0; + } + // Generate a new key + for(int i = 0; i < KEY_BYTES / BLOCK_BYTES; i++) { + cipher.processBlock(counter, 0, newKey, i * BLOCK_BYTES); + incrementCounter(); + } + System.arraycopy(newKey, 0, key, 0, KEY_BYTES); + for(int i = 0; i < KEY_BYTES; i++) newKey[i] = 0; + // Return the number of bytes written + return len; + } finally { + synchLock.unlock(); } - System.arraycopy(newKey, 0, key, 0, KEY_BYTES); - for(int i = 0; i < KEY_BYTES; i++) newKey[i] = 0; - // Return the number of bytes written - return len; } } ===================================== briar-core/src/org/briarproject/crypto/PseudoRandomImpl.java ===================================== --- a/briar-core/src/org/briarproject/crypto/PseudoRandomImpl.java +++ b/briar-core/src/org/briarproject/crypto/PseudoRandomImpl.java @@ -1,41 +1,23 @@ package org.briarproject.crypto; -import org.briarproject.api.crypto.MessageDigest; import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.util.ByteUtils; class PseudoRandomImpl implements PseudoRandom { - private final MessageDigest messageDigest; + private final FortunaGenerator generator; - private byte[] state; - private int offset; - - PseudoRandomImpl(MessageDigest messageDigest, int seed1, int seed2) { - this.messageDigest = messageDigest; - byte[] seedBytes = new byte[8]; - ByteUtils.writeUint32(seed1, seedBytes, 0); - ByteUtils.writeUint32(seed2, seedBytes, 4); - messageDigest.update(seedBytes); - state = messageDigest.digest(); - offset = 0; + PseudoRandomImpl(int seed1, int seed2) { + byte[] seed = new byte[8]; + ByteUtils.writeUint32(seed1, seed, 0); + ByteUtils.writeUint32(seed2, seed, 4); + generator = new FortunaGenerator(seed); } - public synchronized byte[] nextBytes(int bytes) { - byte[] b = new byte[bytes]; - int half = state.length / 2; - int off = 0, len = b.length, available = half - offset; - while(available < len) { - System.arraycopy(state, offset, b, off, available); - off += available; - len -= available; - messageDigest.update(state, half, half); - state = messageDigest.digest(); - offset = 0; - available = half; - } - System.arraycopy(state, offset, b, off, len); - offset += len; + public byte[] nextBytes(int length) { + byte[] b = new byte[length]; + int offset = 0; + while(offset < length) offset += generator.nextBytes(b, offset, length); return b; } } ===================================== briar-core/src/org/briarproject/db/H2Database.java ===================================== --- a/briar-core/src/org/briarproject/db/H2Database.java +++ b/briar-core/src/org/briarproject/db/H2Database.java @@ -83,7 +83,7 @@ class H2Database extends JdbcDatabase { @Override protected Connection createConnection() throws SQLException { - byte[] key = config.getEncryptionKey(); + byte[] key = config.getEncryptionKey().getBytes(); if(key == null) throw new IllegalStateException(); Properties props = new Properties(); props.setProperty("user", "user"); ===================================== briar-core/src/org/briarproject/db/JdbcDatabase.java ===================================== --- a/briar-core/src/org/briarproject/db/JdbcDatabase.java +++ b/briar-core/src/org/briarproject/db/JdbcDatabase.java @@ -27,6 +27,9 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; import org.briarproject.api.Author; @@ -313,16 +316,19 @@ abstract class JdbcDatabase implements Database<Connection> { private final Clock clock; private final LinkedList<Connection> connections = - new LinkedList<Connection>(); // Locking: self + new LinkedList<Connection>(); // Locking: connectionsLock private final AtomicInteger transactionCount = new AtomicInteger(0); - private int openConnections = 0; // Locking: connections - private boolean closed = false; // Locking: connections + private int openConnections = 0; // Locking: connectionsLock + private boolean closed = false; // Locking: connectionsLock protected abstract Connection createConnection() throws SQLException; protected abstract void flushBuffersToDisk(Statement s) throws SQLException; + private final Lock connectionsLock = new ReentrantLock(); + private final Condition connectionsChanged = connectionsLock.newCondition(); + JdbcDatabase(String hashType, String binaryType, String counterType, String secretType, Clock clock) { this.hashType = hashType; @@ -431,9 +437,12 @@ abstract class JdbcDatabase implements Database<Connection> { public Connection startTransaction() throws DbException { Connection txn = null; - synchronized(connections) { + connectionsLock.lock(); + try { if(closed) throw new DbClosedException(); txn = connections.poll(); + } finally { + connectionsLock.unlock(); } try { if(txn == null) { @@ -441,8 +450,11 @@ abstract class JdbcDatabase implements Database<Connection> { txn = createConnection(); if(txn == null) throw new DbException(); txn.setAutoCommit(false); - synchronized(connections) { + connectionsLock.lock(); + try { openConnections++; + } finally { + connectionsLock.unlock(); } } } catch(SQLException e) { @@ -455,9 +467,12 @@ abstract class JdbcDatabase implements Database<Connection> { public void abortTransaction(Connection txn) { try { txn.rollback(); - synchronized(connections) { + connectionsLock.lock(); + try { connections.add(txn); - connections.notifyAll(); + connectionsChanged.signalAll(); + } finally { + connectionsLock.unlock(); } } catch(SQLException e) { // Try to close the connection @@ -468,9 +483,12 @@ abstract class JdbcDatabase implements Database<Connection> { if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e1.toString(), e1); } // Whatever happens, allow the database to close - synchronized(connections) { + connectionsLock.lock(); + try { openConnections--; - connections.notifyAll(); + connectionsChanged.signalAll(); + } finally { + connectionsLock.unlock(); } } } @@ -486,9 +504,12 @@ abstract class JdbcDatabase implements Database<Connection> { tryToClose(s); throw new DbException(e); } - synchronized(connections) { + connectionsLock.lock(); + try { connections.add(txn); - connections.notifyAll(); + connectionsChanged.signalAll(); + } finally { + connectionsLock.unlock(); } } @@ -502,14 +523,15 @@ abstract class JdbcDatabase implements Database<Connection> { protected void closeAllConnections() throws SQLException { boolean interrupted = false; - synchronized(connections) { + connectionsLock.lock(); + try { closed = true; for(Connection c : connections) c.close(); openConnections -= connections.size(); connections.clear(); while(openConnections > 0) { try { - connections.wait(); + connectionsChanged.await(); } catch(InterruptedException e) { LOG.warning("Interrupted while closing connections"); interrupted = true; @@ -518,7 +540,10 @@ abstract class JdbcDatabase implements Database<Connection> { openConnections -= connections.size(); connections.clear(); } + } finally { + connectionsLock.unlock(); } + if(interrupted) Thread.currentThread().interrupt(); } ===================================== briar-core/src/org/briarproject/invitation/ConnectorGroup.java ===================================== --- a/briar-core/src/org/briarproject/invitation/ConnectorGroup.java +++ b/briar-core/src/org/briarproject/invitation/ConnectorGroup.java @@ -10,6 +10,8 @@ import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; import org.briarproject.api.Author; @@ -60,13 +62,9 @@ class ConnectorGroup extends Thread implements InvitationTask { private final Collection<InvitationListener> listeners; private final AtomicBoolean connected; private final CountDownLatch localConfirmationLatch; + private final Lock synchLock = new ReentrantLock(); - /* - * All of the following require locking: this. We don't want to call the - * listeners with a lock held, but we need to avoid a race condition in - * addListener(), so the state that's accessed in addListener() after - * calling listeners.add() must be guarded by a lock. - */ + // The following are locking: synchLock private int localConfirmationCode = -1, remoteConfirmationCode = -1; private boolean connectionFailed = false; private boolean localCompared = false, remoteCompared = false; @@ -104,12 +102,18 @@ class ConnectorGroup extends Thread implements InvitationTask { localConfirmationLatch = new CountDownLatch(1); } - public synchronized InvitationState addListener(InvitationListener l) { - listeners.add(l); - return new InvitationState(localInvitationCode, remoteInvitationCode, - localConfirmationCode, remoteConfirmationCode, connected.get(), - connectionFailed, localCompared, remoteCompared, localMatched, - remoteMatched, remoteName); + public InvitationState addListener(InvitationListener l) { + synchLock.lock(); + try { + listeners.add(l); + return new InvitationState(localInvitationCode, + remoteInvitationCode, localConfirmationCode, + remoteConfirmationCode, connected.get(), connectionFailed, + localCompared, remoteCompared, localMatched, remoteMatched, + remoteName); + } finally { + synchLock.unlock(); + } } public void removeListener(InvitationListener l) { @@ -130,8 +134,11 @@ class ConnectorGroup extends Thread implements InvitationTask { localProps = db.getLocalProperties(); } catch(DbException e) { if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - synchronized(this) { + synchLock.lock(); + try { connectionFailed = true; + } finally { + synchLock.unlock(); } for(InvitationListener l : listeners) l.connectionFailed(); return; @@ -163,8 +170,11 @@ class ConnectorGroup extends Thread implements InvitationTask { } // If none of the threads connected, inform the listeners if(!connected.get()) { - synchronized(this) { + synchLock.lock(); + try { connectionFailed = true; + } finally { + synchLock.unlock(); } for(InvitationListener l : listeners) l.connectionFailed(); } @@ -193,17 +203,23 @@ class ConnectorGroup extends Thread implements InvitationTask { } public void localConfirmationSucceeded() { - synchronized(this) { + synchLock.lock(); + try { localCompared = true; localMatched = true; + } finally { + synchLock.unlock(); } localConfirmationLatch.countDown(); } public void localConfirmationFailed() { - synchronized(this) { + synchLock.lock(); + try { localCompared = true; localMatched = false; + } finally { + synchLock.unlock(); } localConfirmationLatch.countDown(); } @@ -216,9 +232,12 @@ class ConnectorGroup extends Thread implements InvitationTask { } void keyAgreementSucceeded(int localCode, int remoteCode) { - synchronized(this) { + synchLock.lock(); + try { localConfirmationCode = localCode; remoteConfirmationCode = remoteCode; + } finally { + synchLock.unlock(); } for(InvitationListener l : listeners) l.keyAgreementSucceeded(localCode, remoteCode); @@ -230,31 +249,43 @@ class ConnectorGroup extends Thread implements InvitationTask { boolean waitForLocalConfirmationResult() throws InterruptedException { localConfirmationLatch.await(CONFIRMATION_TIMEOUT, MILLISECONDS); - synchronized(this) { + synchLock.lock(); + try { return localMatched; + } finally { + synchLock.unlock(); } } void remoteConfirmationSucceeded() { - synchronized(this) { + synchLock.lock(); + try { remoteCompared = true; remoteMatched = true; + } finally { + synchLock.unlock(); } for(InvitationListener l : listeners) l.remoteConfirmationSucceeded(); } void remoteConfirmationFailed() { - synchronized(this) { + synchLock.lock(); + try { remoteCompared = true; remoteMatched = false; + } finally { + synchLock.unlock(); } for(InvitationListener l : listeners) l.remoteConfirmationFailed(); } void pseudonymExchangeSucceeded(Author remoteAuthor) { String name = remoteAuthor.getName(); - synchronized(this) { + synchLock.lock(); + try { remoteName = name; + } finally { + synchLock.unlock(); } for(InvitationListener l : listeners) l.pseudonymExchangeSucceeded(name); ===================================== briar-core/src/org/briarproject/lifecycle/ShutdownManagerImpl.java ===================================== --- a/briar-core/src/org/briarproject/lifecycle/ShutdownManagerImpl.java +++ b/briar-core/src/org/briarproject/lifecycle/ShutdownManagerImpl.java @@ -2,34 +2,50 @@ package org.briarproject.lifecycle; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import org.briarproject.api.lifecycle.ShutdownManager; class ShutdownManagerImpl implements ShutdownManager { - protected final Map<Integer, Thread> hooks; // Locking: this + private final Lock synchLock = new ReentrantLock(); - private int nextHandle = 0; // Locking: this + // The following are locking: synchLock + protected final Map<Integer, Thread> hooks; + private int nextHandle = 0; ShutdownManagerImpl() { hooks = new HashMap<Integer, Thread>(); } - public synchronized int addShutdownHook(Runnable r) { - int handle = nextHandle++; - Thread hook = createThread(r); - hooks.put(handle, hook); - Runtime.getRuntime().addShutdownHook(hook); - return handle; + public int addShutdownHook(Runnable r) { + synchLock.lock(); + try { + int handle = nextHandle++; + Thread hook = createThread(r); + hooks.put(handle, hook); + Runtime.getRuntime().addShutdownHook(hook); + return handle; + } finally { + synchLock.unlock(); + } + } protected Thread createThread(Runnable r) { return new Thread(r, "ShutdownManager"); } - public synchronized boolean removeShutdownHook(int handle) { - Thread hook = hooks.remove(handle); - if(hook == null) return false; - else return Runtime.getRuntime().removeShutdownHook(hook); + public boolean removeShutdownHook(int handle) { + synchLock.lock(); + try { + Thread hook = hooks.remove(handle); + if(hook == null) return false; + else return Runtime.getRuntime().removeShutdownHook(hook); + } finally { + synchLock.unlock(); + } + } } ===================================== briar-core/src/org/briarproject/messaging/MessagingModule.java ===================================== --- a/briar-core/src/org/briarproject/messaging/MessagingModule.java +++ b/briar-core/src/org/briarproject/messaging/MessagingModule.java @@ -9,9 +9,9 @@ import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.GroupFactory; import org.briarproject.api.messaging.MessageFactory; import org.briarproject.api.messaging.MessageVerifier; +import org.briarproject.api.messaging.MessagingSessionFactory; import org.briarproject.api.messaging.PacketReaderFactory; import org.briarproject.api.messaging.PacketWriterFactory; -import org.briarproject.api.messaging.MessagingSessionFactory; import org.briarproject.api.messaging.SubscriptionUpdate; import org.briarproject.api.messaging.UnverifiedMessage; import org.briarproject.api.serial.StructReader; ===================================== briar-core/src/org/briarproject/plugins/ConnectionRegistryImpl.java ===================================== --- a/briar-core/src/org/briarproject/plugins/ConnectionRegistryImpl.java +++ b/briar-core/src/org/briarproject/plugins/ConnectionRegistryImpl.java @@ -8,6 +8,8 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; import org.briarproject.api.ContactId; @@ -25,9 +27,10 @@ class ConnectionRegistryImpl implements ConnectionRegistry { Logger.getLogger(ConnectionRegistryImpl.class.getName()); private final EventBus eventBus; - // Locking: this + private final Lock synchLock = new ReentrantLock(); + + // The following are locking: synchLock private final Map<TransportId, Map<ContactId, Integer>> connections; - // Locking: this private final Map<ContactId, Integer> contactCounts; @Inject @@ -40,7 +43,8 @@ class ConnectionRegistryImpl implements ConnectionRegistry { public void registerConnection(ContactId c, TransportId t) { LOG.info("Connection registered"); boolean firstConnection = false; - synchronized(this) { + synchLock.lock(); + try { Map<ContactId, Integer> m = connections.get(t); if(m == null) { m = new HashMap<ContactId, Integer>(); @@ -56,7 +60,10 @@ class ConnectionRegistryImpl implements ConnectionRegistry { } else { contactCounts.put(c, count + 1); } + } finally { + synchLock.unlock(); } + if(firstConnection) { LOG.info("Contact connected"); eventBus.broadcast(new ContactConnectedEvent(c)); @@ -66,7 +73,8 @@ class ConnectionRegistryImpl implements ConnectionRegistry { public void unregisterConnection(ContactId c, TransportId t) { LOG.info("Connection unregistered"); boolean lastConnection = false; - synchronized(this) { + synchLock.lock(); + try { Map<ContactId, Integer> m = connections.get(t); if(m == null) throw new IllegalArgumentException(); Integer count = m.remove(c); @@ -84,23 +92,38 @@ class ConnectionRegistryImpl implements ConnectionRegistry { } else { contactCounts.put(c, count - 1); } + } finally { + synchLock.unlock(); } + if(lastConnection) { LOG.info("Contact disconnected"); eventBus.broadcast(new ContactDisconnectedEvent(c)); } } - public synchronized Collection<ContactId> getConnectedContacts( + public Collection<ContactId> getConnectedContacts( TransportId t) { - Map<ContactId, Integer> m = connections.get(t); - if(m == null) return Collections.emptyList(); - List<ContactId> ids = new ArrayList<ContactId>(m.keySet()); - if(LOG.isLoggable(INFO)) LOG.info(ids.size() + " contacts connected"); - return Collections.unmodifiableList(ids); + synchLock.lock(); + try { + Map<ContactId, Integer> m = connections.get(t); + if(m == null) return Collections.emptyList(); + List<ContactId> ids = new ArrayList<ContactId>(m.keySet()); + if(LOG.isLoggable(INFO)) LOG.info(ids.size() + " contacts connected"); + return Collections.unmodifiableList(ids); + } finally { + synchLock.unlock(); + } + } - public synchronized boolean isConnected(ContactId c) { - return contactCounts.containsKey(c); + public boolean isConnected(ContactId c) { + synchLock.lock(); + try { + return contactCounts.containsKey(c); + } finally { + synchLock.unlock(); + } + } } ===================================== briar-core/src/org/briarproject/reliability/Receiver.java ===================================== --- a/briar-core/src/org/briarproject/reliability/Receiver.java +++ b/briar-core/src/org/briarproject/reliability/Receiver.java @@ -1,10 +1,15 @@ package org.briarproject.reliability; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.io.IOException; import java.util.Comparator; import java.util.Iterator; import java.util.SortedSet; import java.util.TreeSet; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import org.briarproject.api.reliability.ReadHandler; import org.briarproject.api.system.Clock; @@ -16,9 +21,13 @@ class Receiver implements ReadHandler { private final Clock clock; private final Sender sender; - private final SortedSet<Data> dataFrames; // Locking: this + private final Lock windowLock = new ReentrantLock(); + private final Condition dataFrameAvailable = windowLock.newCondition(); + + // The following are locking: windowLock + private final SortedSet<Data> dataFrames; + private int windowSize = MAX_WINDOW_SIZE; - private int windowSize = MAX_WINDOW_SIZE; // Locking: this private long finalSequenceNumber = Long.MAX_VALUE; private long nextSequenceNumber = 1; @@ -30,36 +39,44 @@ class Receiver implements ReadHandler { dataFrames = new TreeSet<Data>(new SequenceNumberComparator()); } - synchronized Data read() throws IOException, InterruptedException { - long now = clock.currentTimeMillis(), end = now + READ_TIMEOUT; - while(now < end && valid) { - if(dataFrames.isEmpty()) { - // Wait for a data frame - wait(end - now); - } else { - Data d = dataFrames.first(); - if(d.getSequenceNumber() == nextSequenceNumber) { - dataFrames.remove(d); - // Update the window - windowSize += d.getPayloadLength(); - sender.sendAck(0, windowSize); - nextSequenceNumber++; - return d; + Data read() throws IOException, InterruptedException { + windowLock.lock(); + try { + long now = clock.currentTimeMillis(), end = now + READ_TIMEOUT; + while(now < end && valid) { + if(dataFrames.isEmpty()) { + // Wait for a data frame + dataFrameAvailable.await(end - now, MILLISECONDS); } else { - // Wait for the next in-order data frame - wait(end - now); + Data d = dataFrames.first(); + if(d.getSequenceNumber() == nextSequenceNumber) { + dataFrames.remove(d); + // Update the window + windowSize += d.getPayloadLength(); + sender.sendAck(0, windowSize); + nextSequenceNumber++; + return d; + } else { + // Wait for the next in-order data frame + dataFrameAvailable.await(end - now, MILLISECONDS); + } } + now = clock.currentTimeMillis(); } - now = clock.currentTimeMillis(); + if(valid) throw new IOException("Read timed out"); + throw new IOException("Connection closed"); + } finally { + windowLock.unlock(); } - if(valid) throw new IOException("Read timed out"); - throw new IOException("Connection closed"); } void invalidate() { valid = false; - synchronized(this) { - notifyAll(); + windowLock.lock(); + try { + dataFrameAvailable.signalAll(); + } finally { + windowLock.unlock(); } } @@ -79,43 +96,48 @@ class Receiver implements ReadHandler { } } - private synchronized void handleData(byte[] b) throws IOException { - if(b.length < Data.MIN_LENGTH || b.length > Data.MAX_LENGTH) { - // Ignore data frame with invalid length - return; - } - Data d = new Data(b); - int payloadLength = d.getPayloadLength(); - if(payloadLength > windowSize) return; // No space in the window - if(d.getChecksum() != d.calculateChecksum()) { - // Ignore data frame with invalid checksum - return; - } - long sequenceNumber = d.getSequenceNumber(); - if(sequenceNumber == 0) { - // Window probe - } else if(sequenceNumber < nextSequenceNumber) { - // Duplicate data frame - } else if(d.isLastFrame()) { - finalSequenceNumber = sequenceNumber; - // Remove any data frames with higher sequence numbers - Iterator<Data> it = dataFrames.iterator(); - while(it.hasNext()) { - Data d1 = it.next(); - if(d1.getSequenceNumber() >= finalSequenceNumber) it.remove(); + private void handleData(byte[] b) throws IOException { + windowLock.lock(); + try { + if(b.length < Data.MIN_LENGTH || b.length > Data.MAX_LENGTH) { + // Ignore data frame with invalid length + return; } - if(dataFrames.add(d)) { - windowSize -= payloadLength; - notifyAll(); + Data d = new Data(b); + int payloadLength = d.getPayloadLength(); + if(payloadLength > windowSize) return; // No space in the window + if(d.getChecksum() != d.calculateChecksum()) { + // Ignore data frame with invalid checksum + return; } - } else if(sequenceNumber < finalSequenceNumber) { - if(dataFrames.add(d)) { - windowSize -= payloadLength; - notifyAll(); + long sequenceNumber = d.getSequenceNumber(); + if(sequenceNumber == 0) { + // Window probe + } else if(sequenceNumber < nextSequenceNumber) { + // Duplicate data frame + } else if(d.isLastFrame()) { + finalSequenceNumber = sequenceNumber; + // Remove any data frames with higher sequence numbers + Iterator<Data> it = dataFrames.iterator(); + ... [truncated message content] |
From: akwizgran <gi...@br...> - 2015-01-14 19:59:58
|
akwizgran pushed to refs/heads/master at <a href="akwizgran" rel="nofollow">https://code.briarproject.org/akwizgran/briar">akwizgran / Briar</a> Commits: <a href="1c7432ca" rel="nofollow">https://code.briarproject.org/akwizgran/briar/commit/1c7432cac463465ee0bb26a3204229af6d92486f">1c7432ca</a> by akwizgran Use a provider to instantiate AuthenticatedCipher. - - - - - Changes: ===================================== briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java ===================================== --- a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java +++ b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java @@ -336,7 +336,7 @@ class CryptoComponentImpl implements CryptoComponent { int macBytes = cipher.getMacBytes(); // The input contains the salt, iterations, IV, ciphertext and MAC if(input.length < PBKDF_SALT_BYTES + 4 + STORAGE_IV_BYTES + macBytes) - return null; // Invalid + return null; // Invalid input byte[] salt = new byte[PBKDF_SALT_BYTES]; System.arraycopy(input, 0, salt, 0, salt.length); long iterations = ByteUtils.readUint32(input, salt.length); @@ -366,28 +366,21 @@ class CryptoComponentImpl implements CryptoComponent { // Key derivation function based on a hash function - see NIST SP 800-56A, // section 5.8 - private byte[] concatenationKdf(byte[] rawSecret, byte[] label, - byte[] initiatorInfo, byte[] responderInfo) { + private byte[] concatenationKdf(byte[]... args) { // The output of the hash function must be long enough to use as a key MessageDigest messageDigest = getMessageDigest(); if(messageDigest.getDigestLength() < CIPHER_KEY_BYTES) throw new RuntimeException(); - // The length of every field must fit in an unsigned 8-bit integer - if(rawSecret.length > 255) throw new IllegalArgumentException(); - if(label.length > 255) throw new IllegalArgumentException(); - if(initiatorInfo.length > 255) throw new IllegalArgumentException(); - if(responderInfo.length > 255) throw new IllegalArgumentException(); - // All fields are length-prefixed - messageDigest.update((byte) rawSecret.length); - messageDigest.update(rawSecret); - messageDigest.update((byte) label.length); - messageDigest.update(label); - messageDigest.update((byte) initiatorInfo.length); - messageDigest.update(initiatorInfo); - messageDigest.update((byte) responderInfo.length); - messageDigest.update(responderInfo); + // Each argument is length-prefixed - the length must fit in an + // unsigned 8-bit integer + for(byte[] arg : args) { + if(arg.length > 255) throw new IllegalArgumentException(); + messageDigest.update((byte) arg.length); + messageDigest.update(arg); + } byte[] hash = messageDigest.digest(); - // The secret is the first CIPHER_KEY_BYTES bytes of the hash + // The output is the first CIPHER_KEY_BYTES bytes of the hash + if(hash.length == CIPHER_KEY_BYTES) return hash; byte[] output = new byte[CIPHER_KEY_BYTES]; System.arraycopy(hash, 0, output, 0, output.length); return output; @@ -410,7 +403,7 @@ class CryptoComponentImpl implements CryptoComponent { int macLength = prf.getMacSize(); // The output of the PRF must be long enough to use as a key if(macLength < CIPHER_KEY_BYTES) throw new RuntimeException(); - byte[] mac = new byte[macLength], output = new byte[CIPHER_KEY_BYTES]; + byte[] mac = new byte[macLength]; prf.update((byte) 0); // Counter prf.update(label, 0, label.length); // Null-terminated byte[] contextBytes = new byte[4]; @@ -418,6 +411,9 @@ class CryptoComponentImpl implements CryptoComponent { prf.update(contextBytes, 0, contextBytes.length); prf.update((byte) CIPHER_KEY_BYTES); // Output length prf.doFinal(mac, 0); + // The output is the first CIPHER_KEY_BYTES bytes of the MAC + if(mac.length == CIPHER_KEY_BYTES) return mac; + byte[] output = new byte[CIPHER_KEY_BYTES]; System.arraycopy(mac, 0, output, 0, output.length); return output; } ===================================== briar-core/src/org/briarproject/crypto/CryptoModule.java ===================================== --- a/briar-core/src/org/briarproject/crypto/CryptoModule.java +++ b/briar-core/src/org/briarproject/crypto/CryptoModule.java @@ -42,6 +42,7 @@ public class CryptoModule extends AbstractModule { @Override protected void configure() { + bind(AuthenticatedCipher.class).to(AuthenticatedCipherImpl.class); bind(CryptoComponent.class).to( CryptoComponentImpl.class).in(Singleton.class); bind(PasswordStrengthEstimator.class).to( ===================================== briar-core/src/org/briarproject/crypto/StreamDecrypterFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/crypto/StreamDecrypterFactoryImpl.java +++ b/briar-core/src/org/briarproject/crypto/StreamDecrypterFactoryImpl.java @@ -3,6 +3,7 @@ package org.briarproject.crypto; import java.io.InputStream; import javax.inject.Inject; +import javax.inject.Provider; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.SecretKey; @@ -13,10 +14,13 @@ import org.briarproject.api.transport.StreamContext; class StreamDecrypterFactoryImpl implements StreamDecrypterFactory { private final CryptoComponent crypto; + private final Provider<AuthenticatedCipher> cipherProvider; @Inject - StreamDecrypterFactoryImpl(CryptoComponent crypto) { + StreamDecrypterFactoryImpl(CryptoComponent crypto, + Provider<AuthenticatedCipher> cipherProvider) { this.crypto = crypto; + this.cipherProvider = cipherProvider; } public StreamDecrypter createStreamDecrypter(InputStream in, @@ -27,7 +31,7 @@ class StreamDecrypterFactoryImpl implements StreamDecrypterFactory { boolean alice = !ctx.getAlice(); SecretKey frameKey = crypto.deriveFrameKey(secret, streamNumber, alice); // Create the decrypter - AuthenticatedCipher cipher = new AuthenticatedCipherImpl(); + AuthenticatedCipher cipher = cipherProvider.get(); return new StreamDecrypterImpl(in, cipher, frameKey); } @@ -36,7 +40,7 @@ class StreamDecrypterFactoryImpl implements StreamDecrypterFactory { // Derive the frame key SecretKey frameKey = crypto.deriveFrameKey(secret, 0, alice); // Create the decrypter - AuthenticatedCipher cipher = new AuthenticatedCipherImpl(); + AuthenticatedCipher cipher = cipherProvider.get(); return new StreamDecrypterImpl(in, cipher, frameKey); } } ===================================== briar-core/src/org/briarproject/crypto/StreamEncrypterFactoryImpl.java ===================================== --- a/briar-core/src/org/briarproject/crypto/StreamEncrypterFactoryImpl.java +++ b/briar-core/src/org/briarproject/crypto/StreamEncrypterFactoryImpl.java @@ -5,6 +5,7 @@ import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH; import java.io.OutputStream; import javax.inject.Inject; +import javax.inject.Provider; import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.SecretKey; @@ -15,10 +16,13 @@ import org.briarproject.api.transport.StreamContext; class StreamEncrypterFactoryImpl implements StreamEncrypterFactory { private final CryptoComponent crypto; + private final Provider<AuthenticatedCipher> cipherProvider; @Inject - StreamEncrypterFactoryImpl(CryptoComponent crypto) { + StreamEncrypterFactoryImpl(CryptoComponent crypto, + Provider<AuthenticatedCipher> cipherProvider) { this.crypto = crypto; + this.cipherProvider = cipherProvider; } public StreamEncrypter createStreamEncrypter(OutputStream out, @@ -33,7 +37,7 @@ class StreamEncrypterFactoryImpl implements StreamEncrypterFactory { // Derive the frame key SecretKey frameKey = crypto.deriveFrameKey(secret, streamNumber, alice); // Create the encrypter - AuthenticatedCipher cipher = new AuthenticatedCipherImpl(); + AuthenticatedCipher cipher = cipherProvider.get(); return new StreamEncrypterImpl(out, cipher, frameKey, tag); } @@ -42,7 +46,7 @@ class StreamEncrypterFactoryImpl implements StreamEncrypterFactory { // Derive the frame key SecretKey frameKey = crypto.deriveFrameKey(secret, 0, alice); // Create the encrypter - AuthenticatedCipher cipher = new AuthenticatedCipherImpl(); + AuthenticatedCipher cipher = cipherProvider.get(); return new StreamEncrypterImpl(out, cipher, frameKey, null); } } |