use of i2p.bote.packet.PeerList in project i2p.i2p-bote by i2p.
the class RelayPeerManager method run.
@Override
public void run() {
while (!Thread.interrupted()) {
try {
// ask all peers for their peer lists
Set<RelayPeer> peersToQuery = new HashSet<RelayPeer>(peers);
PacketBatch batch = new PacketBatch();
for (RelayPeer peer : peersToQuery) // don't reuse request packets because PacketBatch will not add the same one more than once
batch.putPacket(new PeerListRequest(), peer);
sendQueue.send(batch);
batch.awaitSendCompletion();
batch.awaitAllResponses(2, TimeUnit.MINUTES);
// build a Set of destinations
Set<Destination> responders = batch.getResponses().keySet();
// update reachability data
log.debug("Relay peer stats:");
for (RelayPeer peer : peersToQuery) {
// use peersToQuery (not peers) so new peers that have been added in the meantime are not wrongly considered unresponsive
boolean didRespond = responders.contains(peer);
peer.addReachabilitySample(didRespond);
if (log.shouldLog(Log.DEBUG)) {
StringBuilder logMessage = new StringBuilder(" ");
logMessage.append(Util.toBase32(peer));
logMessage.append(" ");
for (boolean responded : peer.getAllSamples()) logMessage.append(responded ? '*' : '.');
log.debug(logMessage.toString());
}
}
// make a Set with the new peers
Set<Destination> receivedPeers = new HashSet<Destination>();
BanList banList = BanList.getInstance();
for (DataPacket response : batch.getResponses().values()) {
if (!(response instanceof PeerList))
continue;
PeerList peerList = (PeerList) response;
for (Destination peer : peerList.getPeers()) if (!banList.isBanned(peer))
receivedPeers.add(peer);
}
log.debug("Received a total of " + receivedPeers.size() + " relay peers in " + batch.getResponses().size() + " packets.");
// replace low-reachability peers with new peers (a PeerList is supposed to contain only high-reachability peers)
synchronized (peers) {
// add all received peers, then remove low-reachability ones (all of which are existing peers)
for (Destination newPeer : receivedPeers) if (!localDestination.equals(newPeer))
peers.add(new RelayPeer(newPeer));
for (Iterator<RelayPeer> iterator = peers.iterator(); iterator.hasNext(); ) {
if (peers.size() <= MAX_PEERS)
break;
RelayPeer peer = iterator.next();
if (// don't remove the peer before it has had a chance to respond to a request
!peer.getAllSamples().isEmpty() && peer.getReachability() < MIN_REACHABILITY)
iterator.remove();
}
}
log.debug("Number of relay peers is now " + peers.size());
// if no good peers available, ask more often
if (getGoodPeers().isEmpty())
TimeUnit.MINUTES.sleep(UPDATE_INTERVAL_SHORT);
else
TimeUnit.MINUTES.sleep(UPDATE_INTERVAL_LONG);
} catch (InterruptedException e) {
break;
} catch (RuntimeException e) {
// catch unexpected exceptions to keep the thread running
log.error("Exception caught in RelayPeerManager loop", e);
}
}
writePeers(peerFile);
log.debug("RelayPeerManager thread exiting.");
}
use of i2p.bote.packet.PeerList in project i2p.i2p-bote by i2p.
the class KademliaDHT method sendPeerList.
private void sendPeerList(FindClosePeersPacket packet, Destination destination) {
Collection<Destination> closestPeers = bucketManager.getClosestPeers(packet.getKey(), KademliaConstants.K);
PeerList peerList = new PeerList(closestPeers);
sendQueue.sendResponse(peerList, destination, packet.getPacketId());
}
use of i2p.bote.packet.PeerList in project i2p.i2p-bote by i2p.
the class RelayPeerManager method packetReceived.
@Override
public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) {
BanList banList = BanList.getInstance();
banList.update(sender, packet);
synchronized (peers) {
if (banList.isBanned(sender)) {
peers.remove(sender);
return;
}
// respond to PeerListRequests
if (packet instanceof PeerListRequest) {
// send up to MAX_PEERS_TO_SEND high-reachability peers minus the sender itself
List<Destination> peersToSend = new ArrayList<Destination>();
peersToSend.addAll(getGoodPeers(MAX_PEERS_TO_SEND));
peersToSend.remove(sender);
PeerList response = new PeerList(peersToSend);
log.debug("Sending a PeerList containing " + peersToSend.size() + " peers in response to a PeerListRequest from " + Util.toShortenedBase32(sender));
sendQueue.sendResponse(response, sender, packet.getPacketId());
}
// as a relay peer. The other MAX_PEERS/2 are reserved for peers from PeerListRequests since they are preferrable.
if (peers.size() < MAX_PEERS / 2)
peers.add(new RelayPeer(sender));
}
}
Aggregations