Search in sources :

Example 1 with PeerListRequest

use of i2p.bote.packet.relay.PeerListRequest 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.");
}
Also used : Destination(net.i2p.data.Destination) PacketBatch(i2p.bote.network.PacketBatch) RelayPeer(i2p.bote.network.RelayPeer) DataPacket(i2p.bote.packet.DataPacket) PeerList(i2p.bote.packet.PeerList) PeerListRequest(i2p.bote.packet.relay.PeerListRequest) BanList(i2p.bote.network.BanList) HashSet(java.util.HashSet)

Example 2 with PeerListRequest

use of i2p.bote.packet.relay.PeerListRequest 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));
    }
}
Also used : Destination(net.i2p.data.Destination) PeerList(i2p.bote.packet.PeerList) ArrayList(java.util.ArrayList) RelayPeer(i2p.bote.network.RelayPeer) BanList(i2p.bote.network.BanList) PeerListRequest(i2p.bote.packet.relay.PeerListRequest)

Aggregations

BanList (i2p.bote.network.BanList)2 RelayPeer (i2p.bote.network.RelayPeer)2 PeerList (i2p.bote.packet.PeerList)2 PeerListRequest (i2p.bote.packet.relay.PeerListRequest)2 Destination (net.i2p.data.Destination)2 PacketBatch (i2p.bote.network.PacketBatch)1 DataPacket (i2p.bote.packet.DataPacket)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1