forked from Qortal/qortal
Networking work-in-progress:
When node has reached max connections, Network will ignore pending incoming connections by: 1. not calling accept() 2. de-registering OP_ACCEPT 'interest op' on the listen socket's channel When a peer disconnects, Network might re-register OP_ACCEPT interest op on listen socket.
This commit is contained in:
parent
a5fb0be274
commit
6255b2a907
@ -43,7 +43,7 @@ public class Network {
|
||||
private static final Logger LOGGER = LogManager.getLogger(Network.class);
|
||||
private static Network instance;
|
||||
|
||||
private static final int LISTEN_BACKLOG = 10;
|
||||
private static final int LISTEN_BACKLOG = 5;
|
||||
/**
|
||||
* How long before retrying after a connection failure, in milliseconds.
|
||||
*/
|
||||
@ -122,6 +122,7 @@ public class Network {
|
||||
private final ExecuteProduceConsume networkEPC;
|
||||
private Selector channelSelector;
|
||||
private ServerSocketChannel serverChannel;
|
||||
private SelectionKey serverSelectionKey;
|
||||
private Iterator<SelectionKey> channelIterator = null;
|
||||
|
||||
// volatile because value is updated inside any one of the EPC threads
|
||||
@ -170,7 +171,7 @@ public class Network {
|
||||
serverChannel.configureBlocking(false);
|
||||
serverChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
|
||||
serverChannel.bind(endpoint, LISTEN_BACKLOG);
|
||||
serverChannel.register(channelSelector, SelectionKey.OP_ACCEPT);
|
||||
serverSelectionKey = serverChannel.register(channelSelector, SelectionKey.OP_ACCEPT);
|
||||
} catch (UnknownHostException e) {
|
||||
LOGGER.error("Can't bind listen socket to address {}", Settings.getInstance().getBindAddress());
|
||||
throw new IOException("Can't bind listen socket to address", e);
|
||||
@ -657,6 +658,15 @@ public class Network {
|
||||
SocketChannel socketChannel;
|
||||
|
||||
try {
|
||||
if (getImmutableConnectedPeers().size() >= maxPeers) {
|
||||
// We have enough peers
|
||||
if (serverSelectionKey.interestOps() != 0) {
|
||||
LOGGER.debug("Ignoring pending incoming connections because the server is full");
|
||||
serverSelectionKey.interestOps(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
socketChannel = serverSocketChannel.accept();
|
||||
} catch (IOException e) {
|
||||
return;
|
||||
@ -688,13 +698,6 @@ public class Network {
|
||||
return;
|
||||
}
|
||||
|
||||
if (getImmutableConnectedPeers().size() >= maxPeers) {
|
||||
// We have enough peers
|
||||
LOGGER.debug("Connection discarded from peer {} because the server is full", address);
|
||||
socketChannel.close();
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.debug("Connection accepted from peer {}", address);
|
||||
|
||||
newPeer = new Peer(socketChannel, channelSelector);
|
||||
@ -783,6 +786,10 @@ public class Network {
|
||||
}
|
||||
|
||||
private boolean connectPeer(Peer newPeer) throws InterruptedException {
|
||||
// NOT CORRECT:
|
||||
if (getImmutableConnectedPeers().size() >= minOutboundPeers)
|
||||
return false;
|
||||
|
||||
SocketChannel socketChannel = newPeer.connect(this.channelSelector);
|
||||
if (socketChannel == null) {
|
||||
return false;
|
||||
@ -866,6 +873,15 @@ public class Network {
|
||||
}
|
||||
|
||||
this.removeConnectedPeer(peer);
|
||||
|
||||
if (getImmutableConnectedPeers().size() < maxPeers - 1 && (serverSelectionKey.interestOps() & SelectionKey.OP_ACCEPT) == 0) {
|
||||
try {
|
||||
LOGGER.debug("Re-enabling accepting incoming connections because the server is not longer full");
|
||||
serverSelectionKey.interestOps(SelectionKey.OP_ACCEPT);
|
||||
} catch (CancelledKeyException e) {
|
||||
LOGGER.error("Failed to re-enable accepting of incoming connections: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void peerMisbehaved(Peer peer) {
|
||||
|
Loading…
Reference in New Issue
Block a user