diff --git a/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java b/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java index 80df25c16b6724a5c8bad31f6a352e2e1dcd7ccd..993dea7785070cf677fd44f8c80d249d8552a30f 100644 --- a/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java +++ b/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java @@ -80,23 +80,25 @@ public interface DatabaseComponent { /** * Generates a batch of raw messages for the given contact, with a total - * length less than or equal to the given length. Returns null if - * there are no sendable messages that fit in the given length. + * length less than or equal to the given length, for transmission over a + * transport with the given maximum latency. Returns null if there are no + * sendable messages that fit in the given length. */ - Collection<byte[]> generateBatch(ContactId c, int maxLength) - throws DbException; + Collection<byte[]> generateBatch(ContactId c, int maxLength, + long maxLatency) throws DbException; /** * Generates a batch of raw messages for the given contact from the given * collection of requested messages, with a total length less than or equal - * to the given length. Any messages that were either added to the batch, - * or were considered but are no longer sendable to the contact, are - * removed from the collection of requested messages before returning. - * Returns null if there are no sendable messages that fit in the given - * length. + * to the given length, for transmission over a transport with the given + * maximum latency. Any messages that were either added to the batch, or + * were considered but are no longer sendable to the contact, are removed + * from the collection of requested messages before returning. Returns null + * if there are no sendable messages that fit in the given length. */ Collection<byte[]> generateBatch(ContactId c, int maxLength, - Collection<MessageId> requested) throws DbException; + long maxLatency, Collection<MessageId> requested) + throws DbException; /** * Generates an offer for the given contact. Returns null if there are no diff --git a/briar-api/src/net/sf/briar/api/plugins/duplex/DuplexTransportConnection.java b/briar-api/src/net/sf/briar/api/plugins/duplex/DuplexTransportConnection.java index 6fc1d3cd570b7602f0a1375cde124ed50bdc2fce..06e0f148bfcf4bccf3502e2a7904eab41d2a4545 100644 --- a/briar-api/src/net/sf/briar/api/plugins/duplex/DuplexTransportConnection.java +++ b/briar-api/src/net/sf/briar/api/plugins/duplex/DuplexTransportConnection.java @@ -11,6 +11,9 @@ import java.io.OutputStream; */ public interface DuplexTransportConnection { + /** Returns the maximum latency of the transport in milliseconds. */ + long getMaxLatency(); + /** Returns an input stream for reading from the connection. */ InputStream getInputStream() throws IOException; diff --git a/briar-api/src/net/sf/briar/api/plugins/simplex/SimplexTransportWriter.java b/briar-api/src/net/sf/briar/api/plugins/simplex/SimplexTransportWriter.java index 152b7fd673e9d0402c5875007b49d2df90590dd9..facb4769c32d75bf80538d32ac14716a6e71a7d7 100644 --- a/briar-api/src/net/sf/briar/api/plugins/simplex/SimplexTransportWriter.java +++ b/briar-api/src/net/sf/briar/api/plugins/simplex/SimplexTransportWriter.java @@ -12,6 +12,9 @@ public interface SimplexTransportWriter { /** Returns the capacity of the transport in bytes. */ long getCapacity(); + /** Returns the maximum latency of the transport in milliseconds. */ + long getMaxLatency(); + /** Returns an output stream for writing to the transport. */ OutputStream getOutputStream() throws IOException; diff --git a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java index 4b8ff546e84ecd37ff4c24477457ef64272858f0..eeddfb96b4c594af83ab71b735f34c4a4c1f95c8 100644 --- a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java +++ b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java @@ -488,8 +488,8 @@ DatabaseCleaner.Callback { return new Ack(acked); } - public Collection<byte[]> generateBatch(ContactId c, int maxLength) - throws DbException { + public Collection<byte[]> generateBatch(ContactId c, int maxLength, + long maxLatency) throws DbException { Collection<MessageId> ids; List<byte[]> messages = new ArrayList<byte[]>(); // Get some sendable messages from the database @@ -504,9 +504,8 @@ DatabaseCleaner.Callback { if(!db.containsContact(txn, c)) throw new NoSuchContactException(); ids = db.getSendableMessages(txn, c, maxLength); - for(MessageId m : ids) { + for(MessageId m : ids) messages.add(db.getRawMessage(txn, m)); - } db.commitTransaction(txn); } catch(DbException e) { db.abortTransaction(txn); @@ -519,13 +518,14 @@ DatabaseCleaner.Callback { messageLock.readLock().unlock(); } if(messages.isEmpty()) return null; + // Calculate the expiry time of the messages + long expiry = calculateExpiryTime(maxLatency); // Record the messages as sent messageLock.writeLock().lock(); try { T txn = db.startTransaction(); try { - // FIXME: Calculate the expiry time - db.addOutstandingMessages(txn, c, ids, Long.MAX_VALUE); + db.addOutstandingMessages(txn, c, ids, expiry); db.commitTransaction(txn); } catch(DbException e) { db.abortTransaction(txn); @@ -541,7 +541,8 @@ DatabaseCleaner.Callback { } public Collection<byte[]> generateBatch(ContactId c, int maxLength, - Collection<MessageId> requested) throws DbException { + long maxLatency, Collection<MessageId> requested) + throws DbException { Collection<MessageId> ids = new ArrayList<MessageId>(); List<byte[]> messages = new ArrayList<byte[]>(); // Get some sendable messages from the database @@ -579,13 +580,14 @@ DatabaseCleaner.Callback { messageLock.readLock().unlock(); } if(messages.isEmpty()) return null; + // Calculate the expiry times of the messages + long expiry = calculateExpiryTime(maxLatency); // Record the messages as sent messageLock.writeLock().lock(); try { T txn = db.startTransaction(); try { - // FIXME: Calculate the expiry time - db.addOutstandingMessages(txn, c, ids, Long.MAX_VALUE); + db.addOutstandingMessages(txn, c, ids, expiry); db.commitTransaction(txn); } catch(DbException e) { db.abortTransaction(txn); @@ -600,6 +602,14 @@ DatabaseCleaner.Callback { return Collections.unmodifiableList(messages); } + private long calculateExpiryTime(long maxLatency) { + long roundTrip = maxLatency * 2; + if(roundTrip < 0) roundTrip = Long.MAX_VALUE; // Overflow + long expiry = clock.currentTimeMillis() + roundTrip; + if(expiry < 0) expiry = Long.MAX_VALUE; // Overflow + return expiry; + } + public Offer generateOffer(ContactId c, int maxMessages) throws DbException { Collection<MessageId> offered; diff --git a/briar-core/src/net/sf/briar/db/JdbcDatabase.java b/briar-core/src/net/sf/briar/db/JdbcDatabase.java index 596b7a8632100047227a1fdba213be7fc2f7dbc7..99970f9ab9d5f763de93a008537c79286987929b 100644 --- a/briar-core/src/net/sf/briar/db/JdbcDatabase.java +++ b/briar-core/src/net/sf/briar/db/JdbcDatabase.java @@ -156,7 +156,6 @@ abstract class JdbcDatabase implements Database<Connection> { + " (messageId HASH NOT NULL," + " contactId INT NOT NULL," + " seen BOOLEAN NOT NULL," - + " transmissionCount INT NOT NULL," + " expiry BIGINT NOT NULL," + " PRIMARY KEY (messageId, contactId)," + " FOREIGN KEY (messageId)" @@ -651,16 +650,14 @@ abstract class JdbcDatabase implements Database<Connection> { Collection<MessageId> sent, long expiry) throws DbException { PreparedStatement ps = null; try { - // Update the transmission count and expiry time of each message - String sql = "UPDATE statuses SET expiry = ?," - + " transmissionCount = transmissionCount + ?" + // Update the expiry time of each message + String sql = "UPDATE statuses SET expiry = ?" + " WHERE messageId = ? AND contactId = ?"; ps = txn.prepareStatement(sql); ps.setLong(1, expiry); - ps.setInt(2, 1); - ps.setInt(4, c.getInt()); + ps.setInt(3, c.getInt()); for(MessageId m : sent) { - ps.setBytes(3, m.getBytes()); + ps.setBytes(2, m.getBytes()); ps.addBatch(); } int[] batchAffected = ps.executeBatch(); @@ -713,8 +710,8 @@ abstract class JdbcDatabase implements Database<Connection> { PreparedStatement ps = null; try { String sql = "INSERT INTO statuses" - + " (messageId, contactId, seen, transmissionCount, expiry)" - + " VALUES (?, ?, ?, ZERO(), ZERO())"; + + " (messageId, contactId, seen, expiry)" + + " VALUES (?, ?, ?, ZERO())"; ps = txn.prepareStatement(sql); ps.setBytes(1, m.getBytes()); ps.setInt(2, c.getInt()); diff --git a/briar-core/src/net/sf/briar/messaging/duplex/DuplexConnection.java b/briar-core/src/net/sf/briar/messaging/duplex/DuplexConnection.java index 6d4984cef79825081d124351f8ad41076c654548..1f56449e743a7e1713d7cdaa40cfda0e1da7e93a 100644 --- a/briar-core/src/net/sf/briar/messaging/duplex/DuplexConnection.java +++ b/briar-core/src/net/sf/briar/messaging/duplex/DuplexConnection.java @@ -467,7 +467,8 @@ abstract class DuplexConnection implements DatabaseListener { assert writer != null; try { Collection<byte[]> batch = db.generateBatch(contactId, - Integer.MAX_VALUE, requested); + Integer.MAX_VALUE, transport.getMaxLatency(), + requested); if(batch == null) new GenerateOffer().run(); else writerTasks.add(new WriteBatch(batch, requested)); } catch(DbException e) { diff --git a/briar-core/src/net/sf/briar/messaging/simplex/OutgoingSimplexConnection.java b/briar-core/src/net/sf/briar/messaging/simplex/OutgoingSimplexConnection.java index 4a643a123727bcb3d91dc156eed87e6772c0653f..e2990f547a2c46f1b49642a08fd12f8651a19f8b 100644 --- a/briar-core/src/net/sf/briar/messaging/simplex/OutgoingSimplexConnection.java +++ b/briar-core/src/net/sf/briar/messaging/simplex/OutgoingSimplexConnection.java @@ -69,6 +69,7 @@ class OutgoingSimplexConnection { throw new EOFException(); PacketWriter writer = packetWriterFactory.createPacketWriter(out, transport.shouldFlush()); + long maxLatency = transport.getMaxLatency(); // Send the initial packets: updates and acks boolean hasSpace = writeTransportAcks(conn, writer); if(hasSpace) hasSpace = writeTransportUpdates(conn, writer); @@ -89,12 +90,13 @@ class OutgoingSimplexConnection { // Write messages until you can't write messages no more capacity = conn.getRemainingCapacity(); int maxLength = (int) Math.min(capacity, MAX_PACKET_LENGTH); - Collection<byte[]> batch = db.generateBatch(contactId, maxLength); + Collection<byte[]> batch = db.generateBatch(contactId, maxLength, + maxLatency); while(batch != null) { for(byte[] raw : batch) writer.writeMessage(raw); capacity = conn.getRemainingCapacity(); maxLength = (int) Math.min(capacity, MAX_PACKET_LENGTH); - batch = db.generateBatch(contactId, maxLength); + batch = db.generateBatch(contactId, maxLength, maxLatency); } writer.flush(); writer.close(); diff --git a/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java b/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java index 78734a0e3bda1e2075d0a4f0a57a12632f416956..639afb122b23b1ea96a5ca3756389c8341039f9e 100644 --- a/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java @@ -155,7 +155,7 @@ class BluetoothPlugin implements DuplexPlugin { return; } BluetoothTransportConnection conn = - new BluetoothTransportConnection(s); + new BluetoothTransportConnection(s, maxLatency); callback.incomingConnectionCreated(conn); if(!running) return; } @@ -202,7 +202,7 @@ class BluetoothPlugin implements DuplexPlugin { private DuplexTransportConnection connect(String url) { try { StreamConnection s = (StreamConnection) Connector.open(url); - return new BluetoothTransportConnection(s); + return new BluetoothTransportConnection(s, maxLatency); } catch(IOException e) { if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); return null; @@ -294,7 +294,7 @@ class BluetoothPlugin implements DuplexPlugin { // Try to accept a connection and close the socket try { StreamConnection s = scn.acceptAndOpen(); - return new BluetoothTransportConnection(s); + return new BluetoothTransportConnection(s, maxLatency); } catch(IOException e) { // This is expected when the socket is closed if(LOG.isLoggable(INFO)) LOG.log(INFO, e.toString(), e); diff --git a/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothTransportConnection.java b/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothTransportConnection.java index bc2c1fbd44858ac027a0d29b1fddda567cf9ea35..5d5fda3b95da2d5faa31014ce869bc571b135635 100644 --- a/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothTransportConnection.java +++ b/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothTransportConnection.java @@ -11,9 +11,15 @@ import net.sf.briar.api.plugins.duplex.DuplexTransportConnection; class BluetoothTransportConnection implements DuplexTransportConnection { private final StreamConnection stream; + private final long maxLatency; - BluetoothTransportConnection(StreamConnection stream) { + BluetoothTransportConnection(StreamConnection stream, long maxLatency) { this.stream = stream; + this.maxLatency = maxLatency; + } + + public long getMaxLatency() { + return maxLatency; } public InputStream getInputStream() throws IOException { diff --git a/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java b/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java index a20da57a9fe41cac5a7137c14299c86d24eae286..275f968c153a19d681094169087a2f82e919c3a3 100644 --- a/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java @@ -188,7 +188,7 @@ class DroidtoothPlugin implements DuplexPlugin { return; } DroidtoothTransportConnection conn = - new DroidtoothTransportConnection(s); + new DroidtoothTransportConnection(s, maxLatency); callback.incomingConnectionCreated(conn); if(!running) return; } @@ -250,7 +250,7 @@ class DroidtoothPlugin implements DuplexPlugin { try { BluetoothSocket s = InsecureBluetooth.createSocket(d, u); s.connect(); - return new DroidtoothTransportConnection(s); + return new DroidtoothTransportConnection(s, maxLatency); } catch(IOException e) { if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); return null; @@ -310,7 +310,8 @@ class DroidtoothPlugin implements DuplexPlugin { } // Return the first connection received by the socket, if any try { - return new DroidtoothTransportConnection(ss.accept((int) timeout)); + BluetoothSocket s = ss.accept((int) timeout); + return new DroidtoothTransportConnection(s, maxLatency); } catch(SocketTimeoutException e) { if(LOG.isLoggable(INFO)) LOG.info("Invitation timed out"); return null; diff --git a/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothTransportConnection.java b/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothTransportConnection.java index c493a5b6711d20cc8a500a6da1f3b74b5cde3e09..2a3238033b6394548570f74d0519035e7651ec5d 100644 --- a/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothTransportConnection.java +++ b/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothTransportConnection.java @@ -10,9 +10,15 @@ import android.bluetooth.BluetoothSocket; class DroidtoothTransportConnection implements DuplexTransportConnection { private final BluetoothSocket socket; + private final long maxLatency; - DroidtoothTransportConnection(BluetoothSocket socket) { + DroidtoothTransportConnection(BluetoothSocket socket, long maxLatency) { this.socket = socket; + this.maxLatency = maxLatency; + } + + public long getMaxLatency() { + return maxLatency; } public InputStream getInputStream() throws IOException { diff --git a/briar-core/src/net/sf/briar/plugins/file/FilePlugin.java b/briar-core/src/net/sf/briar/plugins/file/FilePlugin.java index 11e55d127996024660b7d35e216ae66731ceeec2..d72d4ee8ba796e5759b8e2b61905f7f1db35ff66 100644 --- a/briar-core/src/net/sf/briar/plugins/file/FilePlugin.java +++ b/briar-core/src/net/sf/briar/plugins/file/FilePlugin.java @@ -28,6 +28,7 @@ public abstract class FilePlugin implements SimplexPlugin { protected final Executor pluginExecutor; protected final SimplexPluginCallback callback; + protected final long maxLatency; protected volatile boolean running = false; @@ -37,9 +38,10 @@ public abstract class FilePlugin implements SimplexPlugin { protected abstract void readerFinished(File f); protected FilePlugin(@PluginExecutor Executor pluginExecutor, - SimplexPluginCallback callback) { + SimplexPluginCallback callback, long maxLatency) { this.pluginExecutor = pluginExecutor; this.callback = callback; + this.maxLatency = maxLatency; } public SimplexTransportReader createReader(ContactId c) { @@ -72,7 +74,7 @@ public abstract class FilePlugin implements SimplexPlugin { long capacity = getCapacity(dir.getPath()); if(capacity < MIN_CONNECTION_LENGTH) return null; OutputStream out = new FileOutputStream(f); - return new FileTransportWriter(f, out, capacity, this); + return new FileTransportWriter(f, out, capacity, maxLatency, this); } catch(IOException e) { if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); f.delete(); diff --git a/briar-core/src/net/sf/briar/plugins/file/FileTransportWriter.java b/briar-core/src/net/sf/briar/plugins/file/FileTransportWriter.java index c40e0ca33fe5566e61239754d3e8a4a7afd5609d..e86b2f81457900db3eadf2be7793cc5467ac7dee 100644 --- a/briar-core/src/net/sf/briar/plugins/file/FileTransportWriter.java +++ b/briar-core/src/net/sf/briar/plugins/file/FileTransportWriter.java @@ -16,14 +16,15 @@ class FileTransportWriter implements SimplexTransportWriter { private final File file; private final OutputStream out; - private final long capacity; + private final long capacity, maxLatency; private final FilePlugin plugin; FileTransportWriter(File file, OutputStream out, long capacity, - FilePlugin plugin) { + long maxLatency, FilePlugin plugin) { this.file = file; this.out = out; this.capacity = capacity; + this.maxLatency = maxLatency; this.plugin = plugin; } @@ -31,6 +32,10 @@ class FileTransportWriter implements SimplexTransportWriter { return capacity; } + public long getMaxLatency() { + return maxLatency; + } + public OutputStream getOutputStream() { return out; } diff --git a/briar-core/src/net/sf/briar/plugins/file/RemovableDrivePlugin.java b/briar-core/src/net/sf/briar/plugins/file/RemovableDrivePlugin.java index c0d31920154b03be37dcad3246486af23850988d..fecb1dfe7157ccbe73529470931d32513cec92c6 100644 --- a/briar-core/src/net/sf/briar/plugins/file/RemovableDrivePlugin.java +++ b/briar-core/src/net/sf/briar/plugins/file/RemovableDrivePlugin.java @@ -31,15 +31,13 @@ implements RemovableDriveMonitor.Callback { private final RemovableDriveFinder finder; private final RemovableDriveMonitor monitor; - private final long maxLatency; RemovableDrivePlugin(@PluginExecutor Executor pluginExecutor, SimplexPluginCallback callback, RemovableDriveFinder finder, RemovableDriveMonitor monitor, long maxLatency) { - super(pluginExecutor, callback); + super(pluginExecutor, callback, maxLatency); this.finder = finder; this.monitor = monitor; - this.maxLatency = maxLatency; } public TransportId getId() { diff --git a/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java b/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java index 5e459b6ddec09f34b42a5f4642cf0a31c26af82a..cb838c5988a4cce7438570bbf30f01af25a6008f 100644 --- a/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java @@ -234,6 +234,10 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { private final CountDownLatch finished = new CountDownLatch(1); + public long getMaxLatency() { + return maxLatency; + } + public InputStream getInputStream() throws IOException { return modem.getInputStream(); } diff --git a/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java b/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java index 2b00190a9c7c9346b8c31442c8b02de4b0f35d7d..8b82d7e75038c5371ceec577e46d67bc02d83027 100644 --- a/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java @@ -152,7 +152,7 @@ class LanTcpPlugin extends TcpPlugin { // Connect back on the advertised TCP port Socket s = new Socket(packet.getAddress(), port); s.setSoTimeout(0); - return new TcpTransportConnection(s); + return new TcpTransportConnection(s, maxLatency); } catch(IOException e) { if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); @@ -290,7 +290,7 @@ class LanTcpPlugin extends TcpPlugin { ss.setSoTimeout(wait < 1 ? 1 : wait); Socket s = ss.accept(); s.setSoTimeout(0); - return new TcpTransportConnection(s); + return new TcpTransportConnection(s, maxLatency); } catch(SocketTimeoutException e) { now = clock.currentTimeMillis(); if(now < end) { diff --git a/briar-core/src/net/sf/briar/plugins/tcp/TcpPlugin.java b/briar-core/src/net/sf/briar/plugins/tcp/TcpPlugin.java index 5af3fd8b06ef35d078f52f28fe850967ba2e4057..bd129a6cc01c23480a16c8f5fdd8ad2479e545df 100644 --- a/briar-core/src/net/sf/briar/plugins/tcp/TcpPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/tcp/TcpPlugin.java @@ -131,8 +131,8 @@ abstract class TcpPlugin implements DuplexPlugin { tryToClose(ss); return; } - TcpTransportConnection conn = new TcpTransportConnection(s); - callback.incomingConnectionCreated(conn); + callback.incomingConnectionCreated(new TcpTransportConnection(s, + maxLatency)); if(!running) return; } } @@ -177,7 +177,7 @@ abstract class TcpPlugin implements DuplexPlugin { try { s.setSoTimeout(0); s.connect(addr); - return new TcpTransportConnection(s); + return new TcpTransportConnection(s, maxLatency); } catch(IOException e) { if(LOG.isLoggable(INFO)) LOG.log(INFO, e.toString(), e); return null; diff --git a/briar-core/src/net/sf/briar/plugins/tcp/TcpTransportConnection.java b/briar-core/src/net/sf/briar/plugins/tcp/TcpTransportConnection.java index 379b706da63964cf809c213ccb22fb6cb01b0227..ee27cf22a6750de813057dcea3b954d1e853301d 100644 --- a/briar-core/src/net/sf/briar/plugins/tcp/TcpTransportConnection.java +++ b/briar-core/src/net/sf/briar/plugins/tcp/TcpTransportConnection.java @@ -10,9 +10,15 @@ import net.sf.briar.api.plugins.duplex.DuplexTransportConnection; class TcpTransportConnection implements DuplexTransportConnection { private final Socket socket; + private final long maxLatency; - TcpTransportConnection(Socket socket) { + TcpTransportConnection(Socket socket, long maxLatency) { this.socket = socket; + this.maxLatency = maxLatency; + } + + public long getMaxLatency() { + return maxLatency; } public InputStream getInputStream() throws IOException { diff --git a/briar-core/src/net/sf/briar/plugins/tor/TorPlugin.java b/briar-core/src/net/sf/briar/plugins/tor/TorPlugin.java index 2b1fea717dec3023e48fe0999dcdccab6c7d0d65..860963cf99cf84268d66253093f39290e0b323ac 100644 --- a/briar-core/src/net/sf/briar/plugins/tor/TorPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/tor/TorPlugin.java @@ -195,8 +195,8 @@ class TorPlugin implements DuplexPlugin { tryToClose(ss); return; } - TorTransportConnection conn = new TorTransportConnection(s); - callback.incomingConnectionCreated(conn); + callback.incomingConnectionCreated(new TorTransportConnection(s, + maxLatency)); synchronized(this) { if(!running) return; } @@ -277,7 +277,7 @@ class TorPlugin implements DuplexPlugin { if(LOG.isLoggable(INFO)) LOG.info("Connecting to hidden service"); NetSocket s = nl.createNetSocket(null, null, addr); if(LOG.isLoggable(INFO)) LOG.info("Connected to hidden service"); - return new TorTransportConnection(s); + return new TorTransportConnection(s, maxLatency); } catch(IOException e) { if(LOG.isLoggable(INFO)) LOG.log(INFO, e.toString(), e); return null; diff --git a/briar-core/src/net/sf/briar/plugins/tor/TorTransportConnection.java b/briar-core/src/net/sf/briar/plugins/tor/TorTransportConnection.java index c258e0dbe7f5e8c76519ee5b10a3c01e6a085691..de785e687a1bac234d0ff7646be709e598908eca 100644 --- a/briar-core/src/net/sf/briar/plugins/tor/TorTransportConnection.java +++ b/briar-core/src/net/sf/briar/plugins/tor/TorTransportConnection.java @@ -11,9 +11,15 @@ import org.silvertunnel.netlib.api.NetSocket; class TorTransportConnection implements DuplexTransportConnection { private final NetSocket socket; + private final long maxLatency; - TorTransportConnection(NetSocket socket) { + TorTransportConnection(NetSocket socket, long maxLatency) { this.socket = socket; + this.maxLatency = maxLatency; + } + + public long getMaxLatency() { + return maxLatency; } public InputStream getInputStream() throws IOException { diff --git a/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java b/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java index 6099975be85d806a061b9ab5d5725f11b0cfa5ad..a952cb341a04e06ee88a7867ef3301968126b684 100644 --- a/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java +++ b/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java @@ -503,12 +503,12 @@ public abstract class DatabaseComponentTest extends BriarTestCase { } catch(NoSuchContactException expected) {} try { - db.generateBatch(contactId, 123); + db.generateBatch(contactId, 123, 456); fail(); } catch(NoSuchContactException expected) {} try { - db.generateBatch(contactId, 123, Arrays.asList(messageId)); + db.generateBatch(contactId, 123, 456, Arrays.asList(messageId)); fail(); } catch(NoSuchContactException expected) {} @@ -696,14 +696,14 @@ public abstract class DatabaseComponentTest extends BriarTestCase { oneOf(database).getRawMessage(txn, messageId1); will(returnValue(raw1)); // Record the outstanding messages - // FIXME: Calculate the expiry time oneOf(database).addOutstandingMessages(txn, contactId, sendable, Long.MAX_VALUE); }}); DatabaseComponent db = createDatabaseComponent(database, cleaner, shutdown); - assertEquals(messages, db.generateBatch(contactId, size * 2)); + assertEquals(messages, db.generateBatch(contactId, size * 2, + Long.MAX_VALUE)); context.assertIsSatisfied(); } @@ -733,16 +733,15 @@ public abstract class DatabaseComponentTest extends BriarTestCase { will(returnValue(raw1)); // Message is sendable oneOf(database).getRawMessageIfSendable(txn, contactId, messageId2); will(returnValue(null)); // Message is not sendable - // Record the outstanding messages - // FIXME: Calculate the expiry time + // Record the outstanding message oneOf(database).addOutstandingMessages(txn, contactId, - Collections.singletonList(messageId1), Long.MAX_VALUE); + Arrays.asList(messageId1), Long.MAX_VALUE); }}); DatabaseComponent db = createDatabaseComponent(database, cleaner, shutdown); assertEquals(messages, db.generateBatch(contactId, size * 3, - requested)); + Long.MAX_VALUE, requested)); context.assertIsSatisfied(); } diff --git a/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java b/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java index 17546db32a11b47a94684ccbf7a4320b6fccae50..cbe723448c18f530668b0802277724d3c334b817 100644 --- a/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java +++ b/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java @@ -524,9 +524,8 @@ public class H2DatabaseTest extends BriarTestCase { assertTrue(it.hasNext()); assertEquals(messageId, it.next()); assertFalse(it.hasNext()); - // FIXME: Calculate the expiry time - db.addOutstandingMessages(txn, contactId, - Collections.singletonList(messageId), Long.MAX_VALUE); + db.addOutstandingMessages(txn, contactId, Arrays.asList(messageId), + Long.MAX_VALUE); // The message should no longer be sendable it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); diff --git a/briar-tests/src/net/sf/briar/messaging/simplex/OutgoingSimplexConnectionTest.java b/briar-tests/src/net/sf/briar/messaging/simplex/OutgoingSimplexConnectionTest.java index 6e6d261c7a64726dcb2f6ab8b2a1f6fac34ece99..8843642c004b2664dadee81779233a15fa353ea5 100644 --- a/briar-tests/src/net/sf/briar/messaging/simplex/OutgoingSimplexConnectionTest.java +++ b/briar-tests/src/net/sf/briar/messaging/simplex/OutgoingSimplexConnectionTest.java @@ -87,7 +87,7 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase { public void testConnectionTooShort() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); TestSimplexTransportWriter transport = new TestSimplexTransportWriter( - out, MAX_PACKET_LENGTH, true); + out, MAX_PACKET_LENGTH, Long.MAX_VALUE, true); ConnectionContext ctx = new ConnectionContext(contactId, transportId, secret, 0, true); OutgoingSimplexConnection connection = new OutgoingSimplexConnection(db, @@ -105,7 +105,7 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase { public void testNothingToSend() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); TestSimplexTransportWriter transport = new TestSimplexTransportWriter( - out, MIN_CONNECTION_LENGTH, true); + out, MIN_CONNECTION_LENGTH, Long.MAX_VALUE, true); ConnectionContext ctx = new ConnectionContext(contactId, transportId, secret, 0, true); OutgoingSimplexConnection connection = new OutgoingSimplexConnection(db, @@ -134,7 +134,8 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase { oneOf(db).generateAck(with(contactId), with(any(int.class))); will(returnValue(null)); // No messages to send - oneOf(db).generateBatch(with(contactId), with(any(int.class))); + oneOf(db).generateBatch(with(contactId), with(any(int.class)), + with(any(long.class))); will(returnValue(null)); }}); connection.write(); @@ -150,7 +151,7 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase { public void testSomethingToSend() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); TestSimplexTransportWriter transport = new TestSimplexTransportWriter( - out, MIN_CONNECTION_LENGTH, true); + out, MIN_CONNECTION_LENGTH, Long.MAX_VALUE, true); ConnectionContext ctx = new ConnectionContext(contactId, transportId, secret, 0, true); OutgoingSimplexConnection connection = new OutgoingSimplexConnection(db, @@ -183,10 +184,12 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase { oneOf(db).generateAck(with(contactId), with(any(int.class))); will(returnValue(null)); // One message to send - oneOf(db).generateBatch(with(contactId), with(any(int.class))); + oneOf(db).generateBatch(with(contactId), with(any(int.class)), + with(any(long.class))); will(returnValue(Collections.singletonList(raw))); // No more messages - oneOf(db).generateBatch(with(contactId), with(any(int.class))); + oneOf(db).generateBatch(with(contactId), with(any(int.class)), + with(any(long.class))); will(returnValue(null)); }}); connection.write(); diff --git a/briar-tests/src/net/sf/briar/messaging/simplex/SimplexMessagingIntegrationTest.java b/briar-tests/src/net/sf/briar/messaging/simplex/SimplexMessagingIntegrationTest.java index 15affd913bf1464b28e2e9c60359aad9f636381c..c5f9a402c4c48e685a06f562ca9064aad104b17a 100644 --- a/briar-tests/src/net/sf/briar/messaging/simplex/SimplexMessagingIntegrationTest.java +++ b/briar-tests/src/net/sf/briar/messaging/simplex/SimplexMessagingIntegrationTest.java @@ -126,7 +126,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase { PacketWriterFactory packetWriterFactory = alice.getInstance(PacketWriterFactory.class); TestSimplexTransportWriter transport = new TestSimplexTransportWriter( - out, Long.MAX_VALUE, false); + out, Long.MAX_VALUE, Long.MAX_VALUE, false); ConnectionContext ctx = km.getConnectionContext(contactId, transportId); assertNotNull(ctx); OutgoingSimplexConnection simplex = new OutgoingSimplexConnection(db, diff --git a/briar-tests/src/net/sf/briar/messaging/simplex/TestSimplexTransportWriter.java b/briar-tests/src/net/sf/briar/messaging/simplex/TestSimplexTransportWriter.java index 539da8456e61ab6727e9c59f84ab769a92ffe01d..e2fc34ed269d01e185206bd23698112c63ba0448 100644 --- a/briar-tests/src/net/sf/briar/messaging/simplex/TestSimplexTransportWriter.java +++ b/briar-tests/src/net/sf/briar/messaging/simplex/TestSimplexTransportWriter.java @@ -8,15 +8,16 @@ import net.sf.briar.api.plugins.simplex.SimplexTransportWriter; class TestSimplexTransportWriter implements SimplexTransportWriter { private final ByteArrayOutputStream out; - private final long capacity; + private final long capacity, maxLatency; private final boolean flush; private boolean disposed = false, exception = false; TestSimplexTransportWriter(ByteArrayOutputStream out, long capacity, - boolean flush) { + long maxLatency, boolean flush) { this.out = out; this.capacity = capacity; + this.maxLatency = maxLatency; this.flush = flush; } @@ -24,6 +25,10 @@ class TestSimplexTransportWriter implements SimplexTransportWriter { return capacity; } + public long getMaxLatency() { + return maxLatency; + } + public OutputStream getOutputStream() { return out; }