Bundles are gone - the batch-mode and stream-mode protocols now

consist of independently encrypted and authenticated packets (Ack,
Batch, Subscriptions and Transports so far).
This commit is contained in:
akwizgran
2011-07-22 22:19:24 +01:00
parent 5d000b62f8
commit de648daca5
42 changed files with 1309 additions and 1716 deletions

View File

@@ -1,17 +1,22 @@
package net.sf.briar.api.db;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.Rating;
import net.sf.briar.api.protocol.Ack;
import net.sf.briar.api.protocol.AckWriter;
import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.BundleReader;
import net.sf.briar.api.protocol.BundleWriter;
import net.sf.briar.api.protocol.Batch;
import net.sf.briar.api.protocol.BatchWriter;
import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.SubscriptionWriter;
import net.sf.briar.api.protocol.Subscriptions;
import net.sf.briar.api.protocol.TransportWriter;
import net.sf.briar.api.protocol.Transports;
/**
* Encapsulates the database implementation and exposes high-level operations
@@ -48,20 +53,35 @@ public interface DatabaseComponent {
void addLocallyGeneratedMessage(Message m) throws DbException;
/**
* Generates a bundle of acknowledgements, subscriptions, and batches of
* messages for the given contact.
* Finds any lost batches that were sent to the given contact, and marks any
* messages in the batches that are still outstanding for retransmission.
*/
void generateBundle(ContactId c, BundleWriter bundleBuilder)
throws DbException, IOException, GeneralSecurityException;
void findLostBatches(ContactId c) throws DbException;
/** Generates an acknowledgement for the given contact. */
void generateAck(ContactId c, AckWriter a) throws DbException,
IOException;
/** Generates a batch of messages for the given contact. */
void generateBatch(ContactId c, BatchWriter b) throws DbException,
IOException;
/** Generates a subscription update for the given contact. */
void generateSubscriptions(ContactId c, SubscriptionWriter s) throws
DbException, IOException;
/** Generates a transport update for the given contact. */
void generateTransports(ContactId c, TransportWriter t) throws
DbException, IOException;
/** Returns the IDs of all contacts. */
Set<ContactId> getContacts() throws DbException;
Collection<ContactId> getContacts() throws DbException;
/** Returns the user's rating for the given author. */
Rating getRating(AuthorId a) throws DbException;
/** Returns the set of groups to which the user subscribes. */
Set<GroupId> getSubscriptions() throws DbException;
Collection<GroupId> getSubscriptions() throws DbException;
/** Returns the local transport details. */
Map<String, String> getTransports() throws DbException;
@@ -69,13 +89,17 @@ public interface DatabaseComponent {
/** Returns the transport details for the given contact. */
Map<String, String> getTransports(ContactId c) throws DbException;
/**
* Processes a bundle of acknowledgements, subscriptions, and batches of
* messages received from the given contact. Some or all of the messages
* in the bundle may be stored.
*/
void receiveBundle(ContactId c, BundleReader b) throws DbException,
IOException, GeneralSecurityException;
/** Processes an acknowledgement from the given contact. */
void receiveAck(ContactId c, Ack a) throws DbException;
/** Processes a batches of messages from the given contact. */
void receiveBatch(ContactId c, Batch b) throws DbException;
/** Processes a subscription update from the given contact. */
void receiveSubscriptions(ContactId c, Subscriptions s) throws DbException;
/** Processes a transport update from the given contact. */
void receiveTransports(ContactId c, Transports t) throws DbException;
/** Removes a contact (and all associated state) from the database. */
void removeContact(ContactId c) throws DbException;

View File

@@ -0,0 +1,16 @@
package net.sf.briar.api.protocol;
import java.util.Collection;
/** A packet acknowledging receipt of one or more batches. */
public interface Ack {
/**
* The maximum size of a serialised ack, excluding encryption and
* authentication.
*/
static final int MAX_SIZE = (1024 * 1024) - 100;
/** Returns the IDs of the acknowledged batches. */
Collection<BatchId> getBatches();
}

View File

@@ -0,0 +1,16 @@
package net.sf.briar.api.protocol;
import java.io.IOException;
/** An interface for creating an ack. */
public interface AckWriter {
/**
* Attempts to add the given BatchId to the ack and returns true if it
* was added.
*/
boolean addBatchId(BatchId b) throws IOException;
/** Finishes writing the ack. */
void finish() throws IOException;
}

View File

@@ -1,13 +1,19 @@
package net.sf.briar.api.protocol;
/** A batch of messages up to MAX_SIZE bytes in total size. */
import java.util.Collection;
/** A packet containing messages. */
public interface Batch {
public static final int MAX_SIZE = 1024 * 1024;
/**
* The maximum size of a serialised batch, excluding encryption and
* authentication.
*/
static final int MAX_SIZE = (1024 * 1024) - 100;
/** Returns the batch's unique identifier. */
BatchId getId();
/** Returns the messages contained in the batch. */
Iterable<Message> getMessages();
Collection<Message> getMessages();
}

View File

@@ -0,0 +1,19 @@
package net.sf.briar.api.protocol;
import java.io.IOException;
/** An interface for creating a batch of messages. */
public interface BatchWriter {
/** Returns the capacity of the batch in bytes. */
int getCapacity();
/**
* Attempts to add the given raw message to the batch and returns true if
* it was added.
*/
boolean addMessage(byte[] raw) throws IOException;
/** Finishes writing the batch and returns its unique identifier. */
BatchId finish() throws IOException;
}

View File

@@ -1,22 +0,0 @@
package net.sf.briar.api.protocol;
import java.io.IOException;
import java.security.GeneralSecurityException;
/**
* An interface for reading a bundle of acknowledgements, subscriptions,
* transport details and batches.
*/
public interface BundleReader {
/** Returns the bundle's header. */
Header getHeader() throws IOException, GeneralSecurityException;
/**
* Returns the next batch of messages, or null if there are no more batches.
*/
Batch getNextBatch() throws IOException, GeneralSecurityException;
/** Finishes reading the bundle. */
void finish() throws IOException;
}

View File

@@ -1,30 +0,0 @@
package net.sf.briar.api.protocol;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collection;
import java.util.Map;
import net.sf.briar.api.serial.Raw;
/**
* An interface for writing a bundle of acknowledgements, subscriptions,
* transport details and batches.
*/
public interface BundleWriter {
/** Returns the bundle's remaining capacity in bytes. */
long getRemainingCapacity() throws IOException;
/** Adds a header to the bundle. */
void addHeader(Collection<BatchId> acks, Collection<GroupId> subs,
Map<String, String> transports) throws IOException,
GeneralSecurityException;
/** Adds a batch of messages to the bundle and returns its identifier. */
BatchId addBatch(Collection<Raw> messages) throws IOException,
GeneralSecurityException;
/** Finishes writing the bundle. */
void finish() throws IOException;
}

View File

@@ -0,0 +1,29 @@
package net.sf.briar.api.protocol;
import java.security.PublicKey;
/** A group to which users may subscribe. */
public interface Group {
/** Returns the name of the group. */
String getName();
/**
* Returns true if messages sent to the group must be signed with a
* particular private key.
*/
boolean isRestricted();
/**
* If the group is restricted, returns null. Otherwise returns a salt
* value that is combined with the group's name to generate its unique
* identifier.
*/
byte[] getSalt();
/**
* If the group is restricted, returns the public key that is used to
* authorise all messages sent to the group. Otherwise returns null.
*/
PublicKey getPublicKey();
}

View File

@@ -1,22 +0,0 @@
package net.sf.briar.api.protocol;
import java.util.Map;
import java.util.Set;
/** A bundle header up to MAX_SIZE bytes in total size. */
public interface Header {
static final int MAX_SIZE = 1024 * 1024;
/** Returns the acknowledgements contained in the header. */
Set<BatchId> getAcks();
/** Returns the subscriptions contained in the header. */
Set<GroupId> getSubscriptions();
/** Returns the transport details contained in the header. */
Map<String, String> getTransports();
/** Returns the header's timestamp. */
long getTimestamp();
}

View File

@@ -0,0 +1,11 @@
package net.sf.briar.api.protocol;
import java.io.IOException;
/** An interface for creating a subscription update. */
public interface SubscriptionWriter {
// FIXME: This should work with groups, not IDs
/** Sets the contents of the update. */
void setSubscriptions(Iterable<GroupId> subs) throws IOException;
}

View File

@@ -0,0 +1,17 @@
package net.sf.briar.api.protocol;
import java.util.Collection;
/** A packet updating the sender's subscriptions. */
public interface Subscriptions {
// FIXME: This should work with groups, not IDs
/** Returns the subscriptions contained in the update. */
Collection<GroupId> getSubscriptions();
/**
* Returns the update's timestamp. Updates that are older than the newest
* update received from the same contact must be ignored.
*/
long getTimestamp();
}

View File

@@ -7,11 +7,13 @@ package net.sf.briar.api.protocol;
*/
public interface Tags {
static final int AUTHOR_ID = 0;
static final int BATCH = 1;
static final int BATCH_ID = 2;
static final int GROUP_ID = 3;
static final int HEADER = 4;
static final int ACK = 0;
static final int AUTHOR_ID = 1;
static final int BATCH = 2;
static final int BATCH_ID = 3;
static final int GROUP_ID = 4;
static final int MESSAGE = 5;
static final int MESSAGE_ID = 6;
static final int SUBSCRIPTIONS = 7;
static final int TRANSPORTS = 8;
}

View File

@@ -0,0 +1,11 @@
package net.sf.briar.api.protocol;
import java.io.IOException;
import java.util.Map;
/** An interface for creating a transports update. */
public interface TransportWriter {
/** Sets the contents of the update. */
void setTransports(Map<String, String> transports) throws IOException;
}

View File

@@ -0,0 +1,16 @@
package net.sf.briar.api.protocol;
import java.util.Map;
/** A packet updating the sender's transports. */
public interface Transports {
/** Returns the transports contained in the update. */
Map<String, String> getTransports();
/**
* Returns the update's timestamp. Updates that are older than the newest
* update received from the same contact must be ignored.
*/
long getTimestamp();
}

View File

@@ -8,6 +8,7 @@ import net.sf.briar.api.serial.Writable;
public abstract class UniqueId implements Raw, Writable {
public static final int LENGTH = 32;
public static final int SERIALISED_LENGTH = LENGTH + 3;
protected final byte[] id;