mirror of
https://github.com/Qortal/qortal.git
synced 2025-03-31 01:15:52 +00:00
Merge 00b1365bd13d45f437313b6b160218b50c519e0a into 8ffb0625a1edcf0b3d1ec2498b15a31ec38ade3c
This commit is contained in:
commit
2635596411
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user