Type-safe transport IDs.

This commit is contained in:
akwizgran
2011-09-30 12:52:29 +01:00
parent 7190509ede
commit 72b594d270
32 changed files with 292 additions and 188 deletions

View File

@@ -5,6 +5,7 @@ import java.util.Map;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.Rating;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.Status;
import net.sf.briar.api.protocol.AuthorId;
@@ -83,8 +84,9 @@ interface Database<T> {
* <p>
* Locking: contacts write, transports write.
*/
ContactId addContact(T txn, Map<Integer, Map<String, String>> transports,
byte[] secret) throws DbException;
ContactId addContact(T txn,
Map<TransportId, Map<String, String>> transports, byte[] secret)
throws DbException;
/**
* Returns false if the given message is already in the database. Otherwise
@@ -171,7 +173,7 @@ interface Database<T> {
* <p>
* Locking: contacts read, windows write.
*/
long getConnectionNumber(T txn, ContactId c, int transportId)
long getConnectionNumber(T txn, ContactId c, TransportId t)
throws DbException;
/**
@@ -180,7 +182,7 @@ interface Database<T> {
* <p>
* Locking: contacts read, windows read.
*/
ConnectionWindow getConnectionWindow(T txn, ContactId c, int transportId)
ConnectionWindow getConnectionWindow(T txn, ContactId c, TransportId t)
throws DbException;
/**
@@ -319,7 +321,7 @@ interface Database<T> {
* <p>
* Locking: transports read.
*/
Map<String, String> getTransportConfig(T txn, int transportId)
Map<String, String> getTransportConfig(T txn, TransportId t)
throws DbException;
/**
@@ -327,14 +329,15 @@ interface Database<T> {
* <p>
* Locking: transports read.
*/
Map<Integer, Map<String, String>> getTransports(T txn) throws DbException;
Map<TransportId, Map<String, String>> getTransports(T txn)
throws DbException;
/**
* Returns all transport properties for the given contact.
* <p>
* Locking: contacts read, transports read.
*/
Map<Integer, Map<String, String>> getTransports(T txn, ContactId c)
Map<TransportId, Map<String, String>> getTransports(T txn, ContactId c)
throws DbException;
/**
@@ -415,7 +418,7 @@ interface Database<T> {
* <p>
* Locking: contacts read, windows write.
*/
void setConnectionWindow(T txn, ContactId c, int transportId,
void setConnectionWindow(T txn, ContactId c, TransportId t,
ConnectionWindow w) throws DbException;
/**
@@ -476,7 +479,7 @@ interface Database<T> {
* <p>
* Locking: transports write.
*/
void setTransportConfig(T txn, int transportId, Map<String, String> config)
void setTransportConfig(T txn, TransportId t, Map<String, String> config)
throws DbException;
/**
@@ -485,7 +488,7 @@ interface Database<T> {
* <p>
* Locking: transports write.
*/
void setTransportProperties(T txn, int transportId,
void setTransportProperties(T txn, TransportId t,
Map<String, String> properties) throws DbException;
/**
@@ -496,7 +499,7 @@ interface Database<T> {
* Locking: contacts read, transports write.
*/
void setTransports(T txn, ContactId c,
Map<Integer, Map<String, String>> transports, long timestamp)
Map<TransportId, Map<String, String>> transports, long timestamp)
throws DbException;
/**

View File

@@ -21,6 +21,7 @@ import java.util.logging.Logger;
import net.sf.briar.api.Bytes;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.Rating;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DatabaseListener;
import net.sf.briar.api.db.DatabaseListener.Event;
@@ -117,8 +118,9 @@ DatabaseCleaner.Callback {
}
}
public ContactId addContact(Map<Integer, Map<String, String>> transports,
byte[] secret) throws DbException {
public ContactId addContact(
Map<TransportId, Map<String, String>> transports, byte[] secret)
throws DbException {
if(LOG.isLoggable(Level.FINE)) LOG.fine("Adding contact");
ContactId c;
contactLock.writeLock().lock();
@@ -604,7 +606,7 @@ DatabaseCleaner.Callback {
public void generateTransportUpdate(ContactId c, TransportWriter t)
throws DbException, IOException {
Map<Integer, Map<String, String>> transports;
Map<TransportId, Map<String, String>> transports;
long timestamp;
contactLock.readLock().lock();
try {
@@ -632,7 +634,7 @@ DatabaseCleaner.Callback {
LOG.fine("Added " + transports.size() + " transports to update");
}
public long getConnectionNumber(ContactId c, int transportId)
public long getConnectionNumber(ContactId c, TransportId t)
throws DbException {
contactLock.readLock().lock();
try {
@@ -641,7 +643,7 @@ DatabaseCleaner.Callback {
try {
T txn = db.startTransaction();
try {
long outgoing = db.getConnectionNumber(txn, c, transportId);
long outgoing = db.getConnectionNumber(txn, c, t);
db.commitTransaction(txn);
return outgoing;
} catch(DbException e) {
@@ -656,7 +658,7 @@ DatabaseCleaner.Callback {
}
}
public ConnectionWindow getConnectionWindow(ContactId c, int transportId)
public ConnectionWindow getConnectionWindow(ContactId c, TransportId t)
throws DbException {
contactLock.readLock().lock();
try {
@@ -665,8 +667,7 @@ DatabaseCleaner.Callback {
try {
T txn = db.startTransaction();
try {
ConnectionWindow w =
db.getConnectionWindow(txn, c, transportId);
ConnectionWindow w = db.getConnectionWindow(txn, c, t);
db.commitTransaction(txn);
return w;
} catch(DbException e) {
@@ -750,14 +751,13 @@ DatabaseCleaner.Callback {
}
}
public Map<String, String> getTransportConfig(int transportId)
public Map<String, String> getTransportConfig(TransportId t)
throws DbException {
transportLock.readLock().lock();
try {
T txn = db.startTransaction();
try {
Map<String, String> config =
db.getTransportConfig(txn, transportId);
Map<String, String> config = db.getTransportConfig(txn, t);
db.commitTransaction(txn);
return config;
} catch(DbException e) {
@@ -769,13 +769,13 @@ DatabaseCleaner.Callback {
}
}
public Map<Integer, Map<String, String>> getTransports()
public Map<TransportId, Map<String, String>> getTransports()
throws DbException {
transportLock.readLock().lock();
try {
T txn = db.startTransaction();
try {
Map<Integer, Map<String, String>> transports =
Map<TransportId, Map<String, String>> transports =
db.getTransports(txn);
db.commitTransaction(txn);
return transports;
@@ -788,7 +788,7 @@ DatabaseCleaner.Callback {
}
}
public Map<Integer, Map<String, String>> getTransports(ContactId c)
public Map<TransportId, Map<String, String>> getTransports(ContactId c)
throws DbException {
contactLock.readLock().lock();
try {
@@ -797,7 +797,7 @@ DatabaseCleaner.Callback {
try {
T txn = db.startTransaction();
try {
Map<Integer, Map<String, String>> transports =
Map<TransportId, Map<String, String>> transports =
db.getTransports(txn, c);
db.commitTransaction(txn);
return transports;
@@ -1046,7 +1046,7 @@ DatabaseCleaner.Callback {
try {
T txn = db.startTransaction();
try {
Map<Integer, Map<String, String>> transports =
Map<TransportId, Map<String, String>> transports =
t.getTransports();
db.setTransports(txn, c, transports, t.getTimestamp());
if(LOG.isLoggable(Level.FINE))
@@ -1104,7 +1104,7 @@ DatabaseCleaner.Callback {
callListeners(Event.CONTACTS_UPDATED);
}
public void setConnectionWindow(ContactId c, int transportId,
public void setConnectionWindow(ContactId c, TransportId t,
ConnectionWindow w) throws DbException {
contactLock.readLock().lock();
try {
@@ -1113,7 +1113,7 @@ DatabaseCleaner.Callback {
try {
T txn = db.startTransaction();
try {
db.setConnectionWindow(txn, c, transportId, w);
db.setConnectionWindow(txn, c, t, w);
db.commitTransaction(txn);
} catch(DbException e) {
db.abortTransaction(txn);
@@ -1220,17 +1220,16 @@ DatabaseCleaner.Callback {
+ indirect + " indirectly");
}
public void setTransportConfig(int transportId,
public void setTransportConfig(TransportId t,
Map<String, String> config) throws DbException {
boolean changed = false;
transportLock.writeLock().lock();
try {
T txn = db.startTransaction();
try {
Map<String, String> old =
db.getTransportConfig(txn, transportId);
Map<String, String> old = db.getTransportConfig(txn, t);
if(!config.equals(old)) {
db.setTransportConfig(txn, transportId, config);
db.setTransportConfig(txn, t, config);
changed = true;
}
db.commitTransaction(txn);
@@ -1245,18 +1244,18 @@ DatabaseCleaner.Callback {
if(changed) callListeners(Event.TRANSPORTS_UPDATED);
}
public void setTransportProperties(int transportId,
public void setTransportProperties(TransportId t,
Map<String, String> properties) throws DbException {
boolean changed = false;
transportLock.writeLock().lock();
try {
T txn = db.startTransaction();
try {
Map<Integer, Map<String, String>> transports =
Map<TransportId, Map<String, String>> transports =
db.getTransports(txn);
Map<String, String> old = transports.get(transportId);
Map<String, String> old = transports.get(t);
if(!properties.equals(old)) {
db.setTransportProperties(txn, transportId, properties);
db.setTransportProperties(txn, t, properties);
changed = true;
}
db.commitTransaction(txn);

View File

@@ -21,6 +21,7 @@ import java.util.logging.Logger;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.Rating;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.Status;
import net.sf.briar.api.protocol.AuthorId;
@@ -455,7 +456,7 @@ abstract class JdbcDatabase implements Database<Connection> {
}
public ContactId addContact(Connection txn,
Map<Integer, Map<String, String>> transports, byte[] secret)
Map<TransportId, Map<String, String>> transports, byte[] secret)
throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
@@ -486,8 +487,9 @@ abstract class JdbcDatabase implements Database<Connection> {
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
int batchSize = 0;
for(Entry<Integer, Map<String, String>> e : transports.entrySet()) {
ps.setInt(2, e.getKey());
for(Entry<TransportId, Map<String, String>> e
: transports.entrySet()) {
ps.setInt(2, e.getKey().getInt());
for(Entry<String, String> e1 : e.getValue().entrySet()) {
ps.setString(3, e1.getKey());
ps.setString(4, e1.getValue());
@@ -807,7 +809,7 @@ abstract class JdbcDatabase implements Database<Connection> {
}
public long getConnectionNumber(Connection txn, ContactId c,
int transportId) throws DbException {
TransportId t) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
@@ -815,7 +817,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " WHERE contactId = ? AND transportId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setInt(2, transportId);
ps.setInt(2, t.getInt());
rs = ps.executeQuery();
if(rs.next()) {
long outgoing = rs.getLong(1);
@@ -827,7 +829,7 @@ abstract class JdbcDatabase implements Database<Connection> {
ps = txn.prepareStatement(sql);
ps.setLong(1, outgoing + 1);
ps.setInt(2, c.getInt());
ps.setInt(3, transportId);
ps.setInt(3, t.getInt());
int affected = ps.executeUpdate();
if(affected != 1) throw new DbStateException();
ps.close();
@@ -840,7 +842,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " VALUES(?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setInt(2, transportId);
ps.setInt(2, t.getInt());
ps.setLong(3, 0L);
ps.setInt(4, 0);
ps.setLong(5, 0L);
@@ -857,7 +859,7 @@ abstract class JdbcDatabase implements Database<Connection> {
}
public ConnectionWindow getConnectionWindow(Connection txn, ContactId c,
int transportId) throws DbException {
TransportId t) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
@@ -865,7 +867,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " WHERE contactId = ? AND transportId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setInt(2, transportId);
ps.setInt(2, t.getInt());
rs = ps.executeQuery();
long centre = 0L;
int bitmap = 0;
@@ -1394,14 +1396,14 @@ abstract class JdbcDatabase implements Database<Connection> {
}
public Map<String, String> getTransportConfig(Connection txn,
int transportId) throws DbException {
TransportId t) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT key, value FROM transportConfig"
+ " WHERE transportId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, transportId);
ps.setInt(1, t.getInt());
rs = ps.executeQuery();
Map<String, String> config = new TreeMap<String, String>();
while(rs.next()) config.put(rs.getString(1), rs.getString(2));
@@ -1415,7 +1417,7 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public Map<Integer, Map<String, String>> getTransports(Connection txn)
public Map<TransportId, Map<String, String>> getTransports(Connection txn)
throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
@@ -1424,15 +1426,15 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " ORDER BY transportId";
ps = txn.prepareStatement(sql);
rs = ps.executeQuery();
Map<Integer, Map<String, String>> transports =
new TreeMap<Integer, Map<String, String>>();
Map<TransportId, Map<String, String>> transports =
new TreeMap<TransportId, Map<String, String>>();
Map<String, String> properties = null;
Integer lastId = null;
TransportId lastId = null;
while(rs.next()) {
Integer transportId = rs.getInt(1);
if(!transportId.equals(lastId)) {
TransportId id = new TransportId(rs.getInt(1));
if(!id.equals(lastId)) {
properties = new TreeMap<String, String>();
transports.put(transportId, properties);
transports.put(id, properties);
}
properties.put(rs.getString(2), rs.getString(3));
}
@@ -1446,7 +1448,7 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public Map<Integer, Map<String, String>> getTransports(Connection txn,
public Map<TransportId, Map<String, String>> getTransports(Connection txn,
ContactId c) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
@@ -1457,15 +1459,15 @@ abstract class JdbcDatabase implements Database<Connection> {
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
rs = ps.executeQuery();
Map<Integer, Map<String, String>> transports =
new TreeMap<Integer, Map<String, String>>();
Map<TransportId, Map<String, String>> transports =
new TreeMap<TransportId, Map<String, String>>();
Map<String, String> properties = null;
Integer lastId = null;
TransportId lastId = null;
while(rs.next()) {
Integer transportId = rs.getInt(1);
if(!transportId.equals(lastId)) {
TransportId id = new TransportId(rs.getInt(1));
if(!id.equals(lastId)) {
properties = new TreeMap<String, String>();
transports.put(transportId, properties);
transports.put(id, properties);
}
properties.put(rs.getString(2), rs.getString(3));
}
@@ -1767,7 +1769,7 @@ abstract class JdbcDatabase implements Database<Connection> {
}
public void setConnectionWindow(Connection txn, ContactId c,
int transportId, ConnectionWindow w) throws DbException {
TransportId t, ConnectionWindow w) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
@@ -1775,7 +1777,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " WHERE contactId = ? AND transportId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setInt(2, transportId);
ps.setInt(2, t.getInt());
rs = ps.executeQuery();
if(rs.next()) {
if(rs.next()) throw new DbStateException();
@@ -1787,7 +1789,7 @@ abstract class JdbcDatabase implements Database<Connection> {
ps.setLong(1, w.getCentre());
ps.setInt(2, w.getBitmap());
ps.setInt(3, c.getInt());
ps.setInt(4, transportId);
ps.setInt(4, t.getInt());
int affected = ps.executeUpdate();
if(affected != 1) throw new DbStateException();
ps.close();
@@ -1799,7 +1801,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " VALUES(?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setInt(2, transportId);
ps.setInt(2, t.getInt());
ps.setLong(3, w.getCentre());
ps.setInt(4, w.getBitmap());
ps.setLong(5, 0L);
@@ -2039,26 +2041,26 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public void setTransportConfig(Connection txn, int transportId,
public void setTransportConfig(Connection txn, TransportId t,
Map<String, String> config) throws DbException {
setTransportDetails(txn, transportId, config, "transportConfig");
setTransportDetails(txn, t, config, "transportConfig");
}
private void setTransportDetails(Connection txn, int transportId,
private void setTransportDetails(Connection txn, TransportId t,
Map<String, String> details, String table) throws DbException {
PreparedStatement ps = null;
try {
// Delete any existing details for the given transport
String sql = "DELETE FROM " + table + " WHERE transportId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, transportId);
ps.setInt(1, t.getInt());
ps.executeUpdate();
ps.close();
// Store the new details
sql = "INSERT INTO " + table + " (transportId, key, value)"
+ " VALUES (?, ?, ?)";
ps = txn.prepareStatement(sql);
ps.setInt(1, transportId);
ps.setInt(1, t.getInt());
for(Entry<String, String> e : details.entrySet()) {
ps.setString(2, e.getKey());
ps.setString(3, e.getValue());
@@ -2077,13 +2079,13 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public void setTransportProperties(Connection txn, int transportId,
public void setTransportProperties(Connection txn, TransportId t,
Map<String, String> properties) throws DbException {
setTransportDetails(txn, transportId, properties, "transports");
setTransportDetails(txn, t, properties, "transports");
}
public void setTransports(Connection txn, ContactId c,
Map<Integer, Map<String, String>> transports, long timestamp)
Map<TransportId, Map<String, String>> transports, long timestamp)
throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
@@ -2113,8 +2115,9 @@ abstract class JdbcDatabase implements Database<Connection> {
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
int batchSize = 0;
for(Entry<Integer, Map<String, String>> e : transports.entrySet()) {
ps.setInt(2, e.getKey());
for(Entry<TransportId, Map<String, String>> e
: transports.entrySet()) {
ps.setInt(2, e.getKey().getInt());
for(Entry<String, String> e1 : e.getValue().entrySet()) {
ps.setString(3, e1.getKey());
ps.setString(4, e1.getValue());

View File

@@ -8,6 +8,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.invitation.InvitationCallback;
@@ -70,7 +71,7 @@ class InvitationWorker implements Runnable {
File invitationDat = new File(dir, "invitation.dat");
callback.encryptingFile(invitationDat);
// FIXME: Create a real invitation
Map<Integer, Map<String, String>> transports;
Map<TransportId, Map<String, String>> transports;
try {
transports = db.getTransports();
} catch(DbException e) {

View File

@@ -2,10 +2,11 @@ package net.sf.briar.protocol;
import java.util.Map;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.protocol.TransportUpdate;
interface TransportFactory {
TransportUpdate createTransportUpdate(
Map<Integer, Map<String, String>> transports, long timestamp);
Map<TransportId, Map<String, String>> transports, long timestamp);
}

View File

@@ -2,12 +2,13 @@ package net.sf.briar.protocol;
import java.util.Map;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.protocol.TransportUpdate;
class TransportFactoryImpl implements TransportFactory {
public TransportUpdate createTransportUpdate(
Map<Integer, Map<String, String>> transports, long timestamp) {
Map<TransportId, Map<String, String>> transports, long timestamp) {
return new TransportUpdateImpl(transports, timestamp);
}
}

View File

@@ -6,9 +6,10 @@ import java.util.Map;
import java.util.TreeMap;
import net.sf.briar.api.FormatException;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.protocol.ProtocolConstants;
import net.sf.briar.api.protocol.Types;
import net.sf.briar.api.protocol.TransportUpdate;
import net.sf.briar.api.protocol.Types;
import net.sf.briar.api.serial.Consumer;
import net.sf.briar.api.serial.ObjectReader;
import net.sf.briar.api.serial.Reader;
@@ -37,11 +38,11 @@ class TransportReader implements ObjectReader<TransportUpdate> {
r.removeObjectReader(Types.TRANSPORT_PROPERTIES);
if(l.size() > TransportUpdate.MAX_PLUGINS_PER_UPDATE)
throw new FormatException();
Map<Integer, Map<String, String>> transports =
new TreeMap<Integer, Map<String, String>>();
Map<TransportId, Map<String, String>> transports =
new TreeMap<TransportId, Map<String, String>>();
for(TransportProperties t : l) {
if(transports.put(t.transportId, t.properties) != null)
throw new FormatException(); // Duplicate plugin name
if(transports.put(t.id, t.properties) != null)
throw new FormatException(); // Duplicate transport ID
}
long timestamp = r.readInt64();
r.removeConsumer(counting);
@@ -51,11 +52,11 @@ class TransportReader implements ObjectReader<TransportUpdate> {
private static class TransportProperties {
private final int transportId;
private final TransportId id;
private final Map<String, String> properties;
TransportProperties(int transportId, Map<String, String> properties) {
this.transportId = transportId;
TransportProperties(TransportId id, Map<String, String> properties) {
this.id = id;
this.properties = properties;
}
}
@@ -65,14 +66,17 @@ class TransportReader implements ObjectReader<TransportUpdate> {
public TransportProperties readObject(Reader r) throws IOException {
r.readUserDefinedId(Types.TRANSPORT_PROPERTIES);
int transportId = r.readInt32();
int i = r.readInt32();
if(i < TransportId.MIN_ID || i > TransportId.MAX_ID)
throw new FormatException();
TransportId id = new TransportId(i);
r.setMaxStringLength(TransportUpdate.MAX_KEY_OR_VALUE_LENGTH);
Map<String, String> properties =
r.readMap(String.class, String.class);
r.resetMaxStringLength();
if(properties.size() > TransportUpdate.MAX_PROPERTIES_PER_PLUGIN)
throw new FormatException();
return new TransportProperties(transportId, properties);
return new TransportProperties(id, properties);
}
}
}

View File

@@ -2,20 +2,21 @@ package net.sf.briar.protocol;
import java.util.Map;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.protocol.TransportUpdate;
class TransportUpdateImpl implements TransportUpdate {
private final Map<Integer, Map<String, String>> transports;
private final Map<TransportId, Map<String, String>> transports;
private final long timestamp;
TransportUpdateImpl(Map<Integer, Map<String, String>> transports,
TransportUpdateImpl(Map<TransportId, Map<String, String>> transports,
long timestamp) {
this.transports = transports;
this.timestamp = timestamp;
}
public Map<Integer, Map<String, String>> getTransports() {
public Map<TransportId, Map<String, String>> getTransports() {
return transports;
}

View File

@@ -5,6 +5,7 @@ import java.io.OutputStream;
import java.util.Map;
import java.util.Map.Entry;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.protocol.Types;
import net.sf.briar.api.protocol.writers.TransportWriter;
import net.sf.briar.api.serial.Writer;
@@ -20,13 +21,14 @@ class TransportWriterImpl implements TransportWriter {
w = writerFactory.createWriter(out);
}
public void writeTransports(Map<Integer, Map<String, String>> transports,
long timestamp) throws IOException {
public void writeTransports(
Map<TransportId, Map<String, String>> transports, long timestamp)
throws IOException {
w.writeUserDefinedId(Types.TRANSPORT_UPDATE);
w.writeListStart();
for(Entry<Integer, Map<String, String>> e : transports.entrySet()) {
for(Entry<TransportId, Map<String, String>> e : transports.entrySet()) {
w.writeUserDefinedId(Types.TRANSPORT_PROPERTIES);
w.writeInt32(e.getKey());
w.writeInt32(e.getKey().getInt());
w.writeMap(e.getValue());
}
w.writeListEnd();

View File

@@ -1,5 +1,6 @@
package net.sf.briar.transport;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.transport.ConnectionRecogniser;
@@ -19,7 +20,7 @@ class ConnectionRecogniserFactoryImpl implements ConnectionRecogniserFactory {
this.db = db;
}
public ConnectionRecogniser createConnectionRecogniser(int transportId) {
return new ConnectionRecogniserImpl(transportId, crypto, db);
public ConnectionRecogniser createConnectionRecogniser(TransportId t) {
return new ConnectionRecogniserImpl(t, crypto, db);
}
}

View File

@@ -13,6 +13,7 @@ import javax.crypto.SecretKey;
import net.sf.briar.api.Bytes;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DatabaseListener;
@@ -24,7 +25,7 @@ import net.sf.briar.api.transport.ConnectionWindow;
class ConnectionRecogniserImpl implements ConnectionRecogniser,
DatabaseListener {
private final int transportId;
private final TransportId id;
private final CryptoComponent crypto;
private final DatabaseComponent db;
private final Map<Bytes, ContactId> ivToContact;
@@ -34,9 +35,9 @@ DatabaseListener {
private final Map<ContactId, ConnectionWindow> contactToWindow;
private boolean initialised = false;
ConnectionRecogniserImpl(int transportId, CryptoComponent crypto,
ConnectionRecogniserImpl(TransportId id, CryptoComponent crypto,
DatabaseComponent db) {
this.transportId = transportId;
this.id = id;
this.crypto = crypto;
this.db = db;
// FIXME: There's probably a tidier way of maintaining all this state
@@ -62,7 +63,7 @@ DatabaseListener {
}
contactToCipher.put(c, cipher);
// Calculate the IVs for the contact's connection window
ConnectionWindow w = db.getConnectionWindow(c, transportId);
ConnectionWindow w = db.getConnectionWindow(c, id);
Map<Long, Bytes> ivs = new HashMap<Long, Bytes>();
for(Long unseen : w.getUnseenConnectionNumbers()) {
Bytes expectedIv = new Bytes(encryptIv(c, unseen));
@@ -81,7 +82,7 @@ DatabaseListener {
}
private synchronized byte[] encryptIv(ContactId c, long connection) {
byte[] iv = IvEncoder.encodeIv(true, transportId, connection);
byte[] iv = IvEncoder.encodeIv(true, id, connection);
Cipher cipher = contactToCipher.get(c);
assert cipher != null;
try {
@@ -107,7 +108,7 @@ DatabaseListener {
ConnectionWindow w = contactToWindow.get(contactId);
assert w != null;
w.setSeen(connection);
db.setConnectionWindow(contactId, transportId, w);
db.setConnectionWindow(contactId, id, w);
// Update the set of expected IVs
Map<Long, Bytes> oldIvs = contactToIvs.remove(contactId);
assert oldIvs != null;

View File

@@ -6,6 +6,7 @@ import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.crypto.CryptoComponent;
import net.sf.briar.api.transport.ConnectionWriter;
import net.sf.briar.api.transport.ConnectionWriterFactory;
@@ -22,14 +23,14 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
}
public ConnectionWriter createConnectionWriter(OutputStream out,
long capacity, boolean initiator, int transportId, long connection,
long capacity, boolean initiator, TransportId t, long connection,
byte[] secret) {
// Create the encrypter
Cipher ivCipher = crypto.getIvCipher();
Cipher frameCipher = crypto.getFrameCipher();
SecretKey ivKey = crypto.deriveOutgoingIvKey(secret);
SecretKey frameKey = crypto.deriveOutgoingFrameKey(secret);
byte[] iv = IvEncoder.encodeIv(initiator, transportId, connection);
byte[] iv = IvEncoder.encodeIv(initiator, t, connection);
ConnectionEncrypter encrypter = new ConnectionEncrypterImpl(out,
capacity, iv, ivCipher, frameCipher, ivKey, frameKey);
// Create the writer

View File

@@ -1,17 +1,18 @@
package net.sf.briar.transport;
import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH;
import net.sf.briar.api.TransportId;
import net.sf.briar.util.ByteUtils;
class IvEncoder {
static byte[] encodeIv(boolean initiator, int transportId,
static byte[] encodeIv(boolean initiator, TransportId transport,
long connection) {
byte[] iv = new byte[IV_LENGTH];
// Bit 31 is the initiator flag
if(initiator) iv[3] = 1;
// Encode the transport identifier as an unsigned 16-bit integer
ByteUtils.writeUint16(transportId, iv, 4);
ByteUtils.writeUint16(transport.getInt(), iv, 4);
// Encode the connection number as an unsigned 32-bit integer
ByteUtils.writeUint32(connection, iv, 6);
return iv;