mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-20 14:49:53 +01:00
Close old connections to stay within limit.
This commit is contained in:
@@ -40,7 +40,7 @@ class AndroidBluetoothTransportConnection
|
|||||||
try {
|
try {
|
||||||
socket.close();
|
socket.close();
|
||||||
} finally {
|
} finally {
|
||||||
connectionManager.connectionClosed();
|
connectionManager.connectionClosed(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,36 @@
|
|||||||
package org.briarproject.bramble.plugin.bluetooth;
|
package org.briarproject.bramble.plugin.bluetooth;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
interface BluetoothConnectionManager {
|
interface BluetoothConnectionManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if a contact connection can be opened without exceeding
|
* Returns true if a contact connection can be opened without exceeding
|
||||||
* the connection limit.
|
* the connection limit. This method does not need to be called for key
|
||||||
|
* exchange connections.
|
||||||
*/
|
*/
|
||||||
boolean canOpenConnection();
|
boolean canOpenConnection();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments the number of open connections and returns true if the new
|
* Passes a newly opened connection to the manager. The manager may close
|
||||||
* connection can be kept open without exceeding the connection limit.
|
* the new connection or another connection to stay within the connection
|
||||||
|
* limit.
|
||||||
|
* <p/>
|
||||||
|
* Returns false if the manager has closed the new connection (this will
|
||||||
|
* never be the case for key exchange connections).
|
||||||
*/
|
*/
|
||||||
boolean connectionOpened();
|
boolean connectionOpened(DuplexTransportConnection conn,
|
||||||
|
boolean isForKeyExchange);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrements the number of open connections.
|
* Informs the manager that the given connection has been closed.
|
||||||
*/
|
*/
|
||||||
void connectionClosed();
|
void connectionClosed(DuplexTransportConnection conn);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the number of open connections.
|
* Informs the manager that all connections have been closed.
|
||||||
*/
|
*/
|
||||||
void allConnectionsClosed();
|
void allConnectionsClosed();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
package org.briarproject.bramble.plugin.bluetooth;
|
package org.briarproject.bramble.plugin.bluetooth;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.INFO;
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
@ThreadSafe
|
||||||
class BluetoothConnectionManagerImpl implements BluetoothConnectionManager {
|
class BluetoothConnectionManagerImpl implements BluetoothConnectionManager {
|
||||||
|
|
||||||
private static final int MAX_OPEN_CONNECTIONS = 5;
|
private static final int MAX_OPEN_CONNECTIONS = 5;
|
||||||
@@ -12,34 +21,69 @@ class BluetoothConnectionManagerImpl implements BluetoothConnectionManager {
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(BluetoothConnectionManagerImpl.class.getName());
|
Logger.getLogger(BluetoothConnectionManagerImpl.class.getName());
|
||||||
|
|
||||||
private final AtomicInteger openConnections = new AtomicInteger(0);
|
private final Object lock = new Object();
|
||||||
|
private final LinkedList<DuplexTransportConnection> connections =
|
||||||
|
new LinkedList<>(); // Locking: lock
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canOpenConnection() {
|
public boolean canOpenConnection() {
|
||||||
int open = openConnections.get();
|
synchronized (lock) {
|
||||||
if (LOG.isLoggable(INFO))
|
int open = connections.size();
|
||||||
LOG.info(open + " open connections");
|
if (LOG.isLoggable(INFO)) LOG.info(open + " open connections");
|
||||||
return open < MAX_OPEN_CONNECTIONS;
|
return open < MAX_OPEN_CONNECTIONS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean connectionOpened() {
|
public boolean connectionOpened(DuplexTransportConnection conn,
|
||||||
int open = openConnections.incrementAndGet();
|
boolean isForKeyExchange) {
|
||||||
if (LOG.isLoggable(INFO))
|
DuplexTransportConnection close = null;
|
||||||
LOG.info("Connection opened, " + open + " open");
|
synchronized (lock) {
|
||||||
return open <= MAX_OPEN_CONNECTIONS;
|
int open = connections.size();
|
||||||
|
boolean accept = isForKeyExchange || open < MAX_OPEN_CONNECTIONS;
|
||||||
|
if (accept) {
|
||||||
|
if (LOG.isLoggable(INFO))
|
||||||
|
LOG.info("Accepting connection, " + (open + 1) + " open");
|
||||||
|
connections.add(conn);
|
||||||
|
if (open == MAX_OPEN_CONNECTIONS) {
|
||||||
|
LOG.info("Closing old connection to stay within limit");
|
||||||
|
close = connections.poll();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (LOG.isLoggable(INFO))
|
||||||
|
LOG.info("Refusing connection, " + open + " open");
|
||||||
|
close = conn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (close != null) tryToClose(close);
|
||||||
|
return close != conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryToClose(DuplexTransportConnection conn) {
|
||||||
|
try {
|
||||||
|
conn.getWriter().dispose(false);
|
||||||
|
conn.getReader().dispose(false, false);
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void connectionClosed() {
|
public void connectionClosed(DuplexTransportConnection conn) {
|
||||||
int open = openConnections.decrementAndGet();
|
synchronized (lock) {
|
||||||
if (LOG.isLoggable(INFO))
|
connections.remove(conn);
|
||||||
LOG.info("Connection closed, " + open + " open");
|
if (LOG.isLoggable(INFO)) {
|
||||||
|
int open = connections.size();
|
||||||
|
LOG.info("Connection closed, " + open + " open");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void allConnectionsClosed() {
|
public void allConnectionsClosed() {
|
||||||
LOG.info("All connections closed");
|
synchronized (lock) {
|
||||||
openConnections.set(0);
|
connections.clear();
|
||||||
|
LOG.info("All connections closed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,25 +219,12 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
backoff.reset();
|
backoff.reset();
|
||||||
if (connectionManager.connectionOpened()) {
|
if (connectionManager.connectionOpened(conn, false))
|
||||||
callback.incomingConnectionCreated(conn);
|
callback.incomingConnectionCreated(conn);
|
||||||
} else {
|
|
||||||
LOG.info("Closing incoming connection");
|
|
||||||
tryToCloseUnusedConnection(conn);
|
|
||||||
}
|
|
||||||
if (!running) return;
|
if (!running) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToCloseUnusedConnection(DuplexTransportConnection conn) {
|
|
||||||
try {
|
|
||||||
conn.getWriter().dispose(false);
|
|
||||||
conn.getReader().dispose(false, false);
|
|
||||||
} catch (IOException e) {
|
|
||||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
running = false;
|
running = false;
|
||||||
@@ -284,12 +271,8 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
DuplexTransportConnection conn = connect(address, uuid);
|
DuplexTransportConnection conn = connect(address, uuid);
|
||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
backoff.reset();
|
backoff.reset();
|
||||||
if (connectionManager.connectionOpened()) {
|
if (connectionManager.connectionOpened(conn, false))
|
||||||
callback.outgoingConnectionCreated(c, conn);
|
callback.outgoingConnectionCreated(c, conn);
|
||||||
} else {
|
|
||||||
LOG.info("Closing outgoing connection");
|
|
||||||
tryToCloseUnusedConnection(conn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -341,13 +324,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
DuplexTransportConnection conn = connect(address, uuid);
|
DuplexTransportConnection conn = connect(address, uuid);
|
||||||
if (conn == null) return null;
|
if (conn == null) return null;
|
||||||
// TODO: Why don't we reset the backoff here?
|
// TODO: Why don't we reset the backoff here?
|
||||||
if (connectionManager.connectionOpened()) {
|
return connectionManager.connectionOpened(conn, false) ? conn : null;
|
||||||
return conn;
|
|
||||||
} else {
|
|
||||||
LOG.info("Closing outgoing connection");
|
|
||||||
tryToCloseUnusedConnection(conn);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -399,7 +376,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
LOG.info("Connecting to key agreement UUID " + uuid);
|
LOG.info("Connecting to key agreement UUID " + uuid);
|
||||||
DuplexTransportConnection conn = connect(address, uuid);
|
DuplexTransportConnection conn = connect(address, uuid);
|
||||||
// The connection limit doesn't apply to key agreement
|
// The connection limit doesn't apply to key agreement
|
||||||
if (conn != null) connectionManager.connectionOpened();
|
if (conn != null) connectionManager.connectionOpened(conn, true);
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,7 +433,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info(ID.getString() + ": Incoming connection");
|
LOG.info(ID.getString() + ": Incoming connection");
|
||||||
// The connection limit doesn't apply to key agreement
|
// The connection limit doesn't apply to key agreement
|
||||||
connectionManager.connectionOpened();
|
connectionManager.connectionOpened(conn, true);
|
||||||
return new KeyAgreementConnection(conn, ID);
|
return new KeyAgreementConnection(conn, ID);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class JavaBluetoothTransportConnection
|
|||||||
try {
|
try {
|
||||||
stream.close();
|
stream.close();
|
||||||
} finally {
|
} finally {
|
||||||
connectionManager.connectionClosed();
|
connectionManager.connectionClosed(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user