Merge 00b1365bd13d45f437313b6b160218b50c519e0a into 8ffb0625a1edcf0b3d1ec2498b15a31ec38ade3c

This commit is contained in:
cwd.systems | 0KN 2024-11-27 17:12:02 +06:00 committed by GitHub
commit 2635596411
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -32,112 +32,105 @@ public class ChannelAcceptTask implements Task {
@Override
public void perform() throws InterruptedException {
Network network = Network.getInstance();
SocketChannel socketChannel;
final Network network = Network.getInstance();
try {
if (network.getImmutableConnectedPeers().size() >= network.getMaxPeers()) {
// We have enough peers
LOGGER.debug("Ignoring pending incoming connections because the server is full");
// Check if max peer limit is reached
int currentPeerCount = network.getImmutableConnectedPeers().size();
if (currentPeerCount >= network.getMaxPeers()) {
LOGGER.debug("Incoming connection ignored: server is full ({} peers connected)", currentPeerCount);
return;
}
socketChannel = serverSocketChannel.accept();
// Accept new socket connection
SocketChannel socketChannel = serverSocketChannel.accept();
network.setInterestOps(serverSocketChannel, SelectionKey.OP_ACCEPT);
// Handle null case for socketChannel
if (socketChannel == null) {
return;
}
// Process the accepted connection
handleNewConnection(network, socketChannel);
} catch (IOException e) {
return;
}
// No connection actually accepted?
if (socketChannel == null) {
return;
LOGGER.error("Error during connection accept: {}", e.getMessage(), e);
}
}
private void handleNewConnection(Network network, SocketChannel socketChannel) throws IOException {
PeerAddress address = PeerAddress.fromSocket(socketChannel.socket());
List<String> fixedNetwork = Settings.getInstance().getFixedNetwork();
// Check if peer is allowed in fixed network
if (fixedNetwork != null && !fixedNetwork.isEmpty() && network.ipNotInFixedList(address, fixedNetwork)) {
try {
LOGGER.debug("Connection discarded from peer {} as not in the fixed network list", address);
socketChannel.close();
} catch (IOException e) {
// IGNORE
}
LOGGER.debug("Connection rejected: peer {} not in fixed network list", address);
closeSocket(socketChannel);
return;
}
// We allow up to a maximum of maxPeers connected peers, of which...
// - maxDataPeers must be prearranged data connections (these are intentionally short-lived)
// - the remainder can be any regular peers
// Firstly, determine the maximum limits
// Determine connection limits
int maxPeers = Settings.getInstance().getMaxPeers();
int maxDataPeers = Settings.getInstance().getMaxDataPeers();
int maxRegularPeers = maxPeers - maxDataPeers;
// Next, obtain the current state
int connectedDataPeerCount = Network.getInstance().getImmutableConnectedDataPeers().size();
int connectedRegularPeerCount = Network.getInstance().getImmutableConnectedNonDataPeers().size();
int connectedDataPeers = network.getImmutableConnectedDataPeers().size();
int connectedRegularPeers = network.getImmutableConnectedNonDataPeers().size();
// Check if the incoming connection should be considered a data or regular peer
boolean isDataPeer = ArbitraryDataFileManager.getInstance().isPeerRequestingData(address.getHost());
boolean connectionLimitReached = (isDataPeer && connectedDataPeers >= maxDataPeers)
|| (!isDataPeer && connectedRegularPeers >= maxRegularPeers);
// Finally, decide if we have any capacity for this incoming peer
boolean connectionLimitReached;
if (isDataPeer) {
connectionLimitReached = (connectedDataPeerCount >= maxDataPeers);
}
else {
connectionLimitReached = (connectedRegularPeerCount >= maxRegularPeers);
}
// Extra maxPeers check just to be safe
if (Network.getInstance().getImmutableConnectedPeers().size() >= maxPeers) {
// Double-check maxPeers limit
if (network.getImmutableConnectedPeers().size() >= maxPeers) {
connectionLimitReached = true;
}
if (connectionLimitReached) {
try {
// We have enough peers
LOGGER.debug("Connection discarded from peer {} because the server is full", address);
socketChannel.close();
} catch (IOException e) {
// IGNORE
}
LOGGER.debug("Connection rejected: server is full for {} peer type", isDataPeer ? "data" : "regular");
closeSocket(socketChannel);
return;
}
// Check NTP synchronization
final Long now = NTP.getTime();
Peer newPeer;
if (now == null) {
LOGGER.debug("Connection rejected: NTP time unavailable for peer {}", address);
closeSocket(socketChannel);
return;
}
// Accept the new peer
acceptPeer(network, socketChannel, address, isDataPeer);
}
private void acceptPeer(Network network, SocketChannel socketChannel, PeerAddress address, boolean isDataPeer) {
try {
if (now == null) {
LOGGER.debug("Connection discarded from peer {} due to lack of NTP sync", address);
socketChannel.close();
return;
}
LOGGER.debug("Connection accepted from peer {}", address);
newPeer = new Peer(socketChannel);
Peer newPeer = new Peer(socketChannel);
if (isDataPeer) {
newPeer.setMaxConnectionAge(Settings.getInstance().getMaxDataPeerConnectionTime() * 1000L);
long maxConnectionAge = Settings.getInstance().getMaxDataPeerConnectionTime() * 1000L;
newPeer.setMaxConnectionAge(maxConnectionAge);
}
newPeer.setIsDataPeer(isDataPeer);
network.addConnectedPeer(newPeer);
// Notify the network that the peer is ready
network.onPeerReady(newPeer);
} catch (IOException e) {
if (socketChannel.isOpen()) {
try {
LOGGER.debug("Connection failed from peer {} while connecting/closing", address);
socketChannel.close();
} catch (IOException ce) {
// Couldn't close?
}
}
return;
LOGGER.error("Failed to accept peer {}: {}", address, e.getMessage(), e);
closeSocket(socketChannel);
}
}
network.onPeerReady(newPeer);
private void closeSocket(SocketChannel socketChannel) {
if (socketChannel != null && socketChannel.isOpen()) {
try {
socketChannel.close();
} catch (IOException e) {
LOGGER.error("Failed to close socket: {}", e.getMessage(), e);
}
}
}
}