Connections are now severed after a configurable time (12h by default) or when a limit is exceeded (150 by default)
This commit is contained in:
parent
a398b072b5
commit
bdc8e025c1
@ -40,6 +40,7 @@ import static ch.dissem.bitmessage.entity.Plaintext.Status.*;
|
|||||||
import static ch.dissem.bitmessage.entity.Plaintext.Type.BROADCAST;
|
import static ch.dissem.bitmessage.entity.Plaintext.Type.BROADCAST;
|
||||||
import static ch.dissem.bitmessage.entity.Plaintext.Type.MSG;
|
import static ch.dissem.bitmessage.entity.Plaintext.Type.MSG;
|
||||||
import static ch.dissem.bitmessage.utils.UnixTime.DAY;
|
import static ch.dissem.bitmessage.utils.UnixTime.DAY;
|
||||||
|
import static ch.dissem.bitmessage.utils.UnixTime.HOUR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Use this class if you want to create a Bitmessage client.</p>
|
* <p>Use this class if you want to create a Bitmessage client.</p>
|
||||||
@ -295,6 +296,8 @@ public class BitmessageContext {
|
|||||||
Security security;
|
Security security;
|
||||||
MessageCallback messageCallback;
|
MessageCallback messageCallback;
|
||||||
Listener listener;
|
Listener listener;
|
||||||
|
int connectionLimit = 150;
|
||||||
|
long connectionTTL = 12 * HOUR;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
}
|
}
|
||||||
@ -349,6 +352,16 @@ public class BitmessageContext {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder connectionLimit(int connectionLimit) {
|
||||||
|
this.connectionLimit = connectionLimit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder connectionTTL(int hours) {
|
||||||
|
this.connectionTTL = hours * HOUR;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public BitmessageContext build() {
|
public BitmessageContext build() {
|
||||||
nonNull("inventory", inventory);
|
nonNull("inventory", inventory);
|
||||||
nonNull("nodeRegistry", nodeRegistry);
|
nonNull("nodeRegistry", nodeRegistry);
|
||||||
|
@ -56,6 +56,8 @@ public class InternalContext {
|
|||||||
private final long clientNonce;
|
private final long clientNonce;
|
||||||
private final long networkNonceTrialsPerByte = 1000;
|
private final long networkNonceTrialsPerByte = 1000;
|
||||||
private final long networkExtraBytes = 1000;
|
private final long networkExtraBytes = 1000;
|
||||||
|
private long connectionTTL;
|
||||||
|
private int connectionLimit;
|
||||||
|
|
||||||
public InternalContext(BitmessageContext.Builder builder) {
|
public InternalContext(BitmessageContext.Builder builder) {
|
||||||
this.security = builder.security;
|
this.security = builder.security;
|
||||||
@ -68,6 +70,8 @@ public class InternalContext {
|
|||||||
this.clientNonce = security.randomNonce();
|
this.clientNonce = security.randomNonce();
|
||||||
this.messageCallback = builder.messageCallback;
|
this.messageCallback = builder.messageCallback;
|
||||||
this.port = builder.port;
|
this.port = builder.port;
|
||||||
|
this.connectionLimit = builder.connectionLimit;
|
||||||
|
this.connectionTTL = builder.connectionTTL;
|
||||||
|
|
||||||
Singleton.initialize(security);
|
Singleton.initialize(security);
|
||||||
|
|
||||||
@ -232,6 +236,14 @@ public class InternalContext {
|
|||||||
return clientNonce;
|
return clientNonce;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getConnectionTTL() {
|
||||||
|
return connectionTTL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getConnectionLimit() {
|
||||||
|
return connectionLimit;
|
||||||
|
}
|
||||||
|
|
||||||
public interface ContextHolder {
|
public interface ContextHolder {
|
||||||
void setContext(InternalContext context);
|
void setContext(InternalContext context);
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,12 @@ public class Singleton {
|
|||||||
private static Security security;
|
private static Security security;
|
||||||
|
|
||||||
public static void initialize(Security security) {
|
public static void initialize(Security security) {
|
||||||
|
synchronized (Singleton.class) {
|
||||||
|
if (Singleton.security == null) {
|
||||||
Singleton.security = security;
|
Singleton.security = security;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Security security() {
|
public static Security security() {
|
||||||
return security;
|
return security;
|
||||||
|
@ -51,8 +51,10 @@ import static ch.dissem.bitmessage.utils.UnixTime.MINUTE;
|
|||||||
*/
|
*/
|
||||||
public class Connection {
|
public class Connection {
|
||||||
public static final int READ_TIMEOUT = 2000;
|
public static final int READ_TIMEOUT = 2000;
|
||||||
private final static Logger LOG = LoggerFactory.getLogger(Connection.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Connection.class);
|
||||||
private static final int CONNECT_TIMEOUT = 5000;
|
private static final int CONNECT_TIMEOUT = 5000;
|
||||||
|
|
||||||
|
private final long startTime;
|
||||||
private final ConcurrentMap<InventoryVector, Long> ivCache;
|
private final ConcurrentMap<InventoryVector, Long> ivCache;
|
||||||
private final InternalContext ctx;
|
private final InternalContext ctx;
|
||||||
private final Mode mode;
|
private final Mode mode;
|
||||||
@ -89,6 +91,7 @@ public class Connection {
|
|||||||
|
|
||||||
private Connection(InternalContext context, Mode mode, MessageListener listener, Socket socket,
|
private Connection(InternalContext context, Mode mode, MessageListener listener, Socket socket,
|
||||||
Map<InventoryVector, Long> requestedObjectsMap, NetworkAddress node, long syncTimeout) {
|
Map<InventoryVector, Long> requestedObjectsMap, NetworkAddress node, long syncTimeout) {
|
||||||
|
this.startTime = UnixTime.now();
|
||||||
this.ctx = context;
|
this.ctx = context;
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
this.state = CONNECTING;
|
this.state = CONNECTING;
|
||||||
@ -109,6 +112,10 @@ public class Connection {
|
|||||||
timeoutInSeconds);
|
timeoutInSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getStartTime() {
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
public Mode getMode() {
|
public Mode getMode() {
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import ch.dissem.bitmessage.entity.valueobject.NetworkAddress;
|
|||||||
import ch.dissem.bitmessage.ports.NetworkHandler;
|
import ch.dissem.bitmessage.ports.NetworkHandler;
|
||||||
import ch.dissem.bitmessage.utils.Collections;
|
import ch.dissem.bitmessage.utils.Collections;
|
||||||
import ch.dissem.bitmessage.utils.Property;
|
import ch.dissem.bitmessage.utils.Property;
|
||||||
|
import ch.dissem.bitmessage.utils.UnixTime;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -112,9 +113,21 @@ public class DefaultNetworkHandler implements NetworkHandler, ContextHolder {
|
|||||||
while (running) {
|
while (running) {
|
||||||
try {
|
try {
|
||||||
int active = 0;
|
int active = 0;
|
||||||
|
long now = UnixTime.now();
|
||||||
synchronized (connections) {
|
synchronized (connections) {
|
||||||
|
int diff = connections.size() - ctx.getConnectionLimit();
|
||||||
|
if (diff > 0) {
|
||||||
|
for (Connection c : connections) {
|
||||||
|
c.disconnect();
|
||||||
|
diff--;
|
||||||
|
if (diff == 0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (Iterator<Connection> iterator = connections.iterator(); iterator.hasNext(); ) {
|
for (Iterator<Connection> iterator = connections.iterator(); iterator.hasNext(); ) {
|
||||||
Connection c = iterator.next();
|
Connection c = iterator.next();
|
||||||
|
if (now - c.getStartTime() > ctx.getConnectionTTL()) {
|
||||||
|
c.disconnect();
|
||||||
|
}
|
||||||
if (c.getState() == DISCONNECTED) {
|
if (c.getState() == DISCONNECTED) {
|
||||||
// Remove the current element from the iterator and the list.
|
// Remove the current element from the iterator and the list.
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
|
Loading…
Reference in New Issue
Block a user