Search in sources :

Example 61 with Destination

use of net.i2p.data.Destination in project i2p.i2p-bote by i2p.

the class KademliaDHT method getDhtResults.

/**
 * Returns all <code>DhtStorablePacket</code> packets that have been received as a response to a send batch,
 * plus <code>localResult</code> if it is non-<code>null</code>.
 * @param batch
 * @param localResult
 */
private DhtResults getDhtResults(PacketBatch batch, DhtStorablePacket localResult) {
    Map<Destination, DataPacket> responses = batch.getResponses();
    DhtResults results = new DhtResults();
    for (Entry<Destination, DataPacket> result : responses.entrySet()) {
        DataPacket packet = result.getValue();
        if (packet instanceof DhtStorablePacket)
            results.put(result.getKey(), (DhtStorablePacket) packet);
    }
    int totalResponses = responses.size();
    if (localResult != null) {
        results.put(localDestination, localResult);
        totalResponses++;
    }
    results.setTotalResponses(totalResponses);
    return results;
}
Also used : DhtStorablePacket(i2p.bote.packet.dht.DhtStorablePacket) Destination(net.i2p.data.Destination) DataPacket(i2p.bote.packet.DataPacket) DhtResults(i2p.bote.network.DhtResults)

Example 62 with Destination

use of net.i2p.data.Destination in project i2p.i2p-bote by i2p.

the class KademliaDHT method store.

@Override
public void store(DhtStorablePacket packet) throws DhtException, InterruptedException {
    Hash key = packet.getDhtKey();
    log.info("Looking up nodes to store a " + packet.getClass().getSimpleName() + " with key " + key);
    List<Destination> closeNodes = getClosestNodes(key);
    if (closeNodes.isEmpty())
        throw new DhtException("Cannot store packet because no storage nodes found.");
    // store on local node if appropriate
    if (!closeNodes.contains(localDestination))
        if (closeNodes.size() < KademliaConstants.K || isCloser(localDestination, closeNodes.get(0), key))
            closeNodes.add(localDestination);
    log.info("Storing a " + packet.getClass().getSimpleName() + " with key " + key + " on " + closeNodes.size() + " nodes");
    PacketBatch batch = new PacketBatch();
    for (Destination node : closeNodes) if (localDestination.equals(node))
        storeLocally(packet, null);
    else {
        // use a separate packet id for each request
        StoreRequest storeRequest = new StoreRequest(packet);
        batch.putPacket(storeRequest, node);
    }
    sendQueue.send(batch);
    batch.awaitSendCompletion();
    // TODO awaitAllResponses, repeat if necessary
    sendQueue.remove(batch);
}
Also used : Destination(net.i2p.data.Destination) PacketBatch(i2p.bote.network.PacketBatch) StoreRequest(i2p.bote.packet.dht.StoreRequest) Hash(net.i2p.data.Hash) DhtException(i2p.bote.network.DhtException)

Example 63 with Destination

use of net.i2p.data.Destination in project i2p.i2p-bote by i2p.

the class ReplicateThread method replicate.

private void replicate() throws InterruptedException {
    log.debug("Replicating DHT data...");
    replicationRunning = true;
    // refresh peers close to the local destination
    ClosestNodesLookupTask lookupTask = new ClosestNodesLookupTask(localDestination.calculateHash(), sendQueue, i2pReceiver, bucketManager);
    List<Destination> closestNodes = lookupTask.call();
    closestNodes.remove(localDestination);
    int numReplicated = 0;
    int numSkipped = 0;
    // If a peer responds with a delete request, replicate the delete request instead.
    for (DhtStorageHandler dhtStore : dhtStores) for (Iterator<? extends DhtStorablePacket> packetIterator = dhtStore.individualPackets(); packetIterator.hasNext(); ) {
        DhtStorablePacket packet = packetIterator.next();
        Hash dhtKey = packet.getDhtKey();
        if (!keysToSkip.contains(dhtKey)) {
            StoreRequest request = new StoreRequest(packet);
            List<Destination> closestPeers = bucketManager.getClosestPeers(dhtKey, KademliaConstants.K);
            for (Destination peer : closestPeers) {
                // Send the store request and give the peer time to respond with a delete request
                sendQueue.send(request, peer).await(SEND_TIMEOUT_MINUTES, TimeUnit.MINUTES);
                TimeUnit.SECONDS.sleep(WAIT_TIME_SECONDS);
                // If we received a delete request for the DHT item, notify the other close peers
                DeleteRequest delRequest = receivedDeleteRequests.get(dhtKey);
                if (delRequest != null) {
                    // KademliaDHT handles the delete request for local data, but we forward the
                    // request to the other nodes close to the DHT key.
                    // Note that the delete request contains only one entry, see packetReceived()
                    sendDeleteRequest(delRequest, closestPeers, peer);
                    break;
                }
            }
            numReplicated++;
        } else
            numSkipped++;
    }
    keysToSkip.clear();
    replicationRunning = false;
    receivedDeleteRequests.clear();
    log.debug("Replication finished. Replicated " + numReplicated + " packets, skipped: " + numSkipped);
}
Also used : DhtStorablePacket(i2p.bote.packet.dht.DhtStorablePacket) Destination(net.i2p.data.Destination) DhtStorageHandler(i2p.bote.network.DhtStorageHandler) StoreRequest(i2p.bote.packet.dht.StoreRequest) Iterator(java.util.Iterator) List(java.util.List) Hash(net.i2p.data.Hash) DeleteRequest(i2p.bote.packet.dht.DeleteRequest)

Example 64 with Destination

use of net.i2p.data.Destination 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 65 with Destination

use of net.i2p.data.Destination in project i2p.i2p-bote by i2p.

the class RelayRequest method create.

/**
 * Creates a <code>RelayRequest</code> containing <code>numHops</code> nested
 * <code>RelayRequest</code>s<br/>
 * Returns <code>null</code> if <code>numHops</code> is <code>0</code>.
 * @param payload
 * @param peerManager For obtaining relay peers
 * @param numHops
 * @param minDelay The minimum delay in milliseconds
 * @param maxDelay The maximum delay in milliseconds
 */
public static RelayRequest create(CommunicationPacket payload, RelayPeerManager peerManager, int numHops, long minDelay, long maxDelay) {
    List<Destination> relayPeers = peerManager.getRandomPeers(numHops);
    Log log = new Log(RelayRequest.class);
    if (log.shouldLog(Log.DEBUG)) {
        StringBuilder debugMsg = new StringBuilder("Creating relay chain: [");
        for (int i = relayPeers.size() - 1; i >= 0; i--) {
            debugMsg.append(Util.toShortenedBase32(relayPeers.get(i)));
            if (i > 0)
                debugMsg.append(" --> ");
        }
        debugMsg.append("]");
        log.debug(debugMsg.toString());
    }
    // calculate the number of pad bytes necessary to pad the payload to the maximum size possible
    int maxSize = I2PBotePacket.MAX_DATAGRAM_SIZE - getMaxOverhead(numHops);
    int padBytes = maxSize - payload.getSize();
    if (padBytes < 0)
        padBytes = 0;
    CommunicationPacket request = payload;
    for (Destination relayPeer : relayPeers) {
        // generate a random time between minDelay and maxDelay in the future
        long delay;
        if (minDelay == maxDelay)
            delay = minDelay;
        else
            delay = minDelay + Math.abs(random.nextLong()) % Math.abs(maxDelay - minDelay);
        request = new RelayRequest(request, relayPeer, delay, padBytes);
        // only pad the innermost packet (the payload)
        padBytes = 0;
    }
    return (RelayRequest) request;
}
Also used : Destination(net.i2p.data.Destination) Log(net.i2p.util.Log) CommunicationPacket(i2p.bote.packet.CommunicationPacket)

Aggregations

Destination (net.i2p.data.Destination)149 IOException (java.io.IOException)46 DataFormatException (net.i2p.data.DataFormatException)33 Properties (java.util.Properties)29 I2PException (net.i2p.I2PException)26 Hash (net.i2p.data.Hash)18 ArrayList (java.util.ArrayList)13 File (java.io.File)12 I2PSessionException (net.i2p.client.I2PSessionException)12 SigType (net.i2p.crypto.SigType)12 ByteArrayInputStream (java.io.ByteArrayInputStream)11 ByteArrayOutputStream (java.io.ByteArrayOutputStream)10 I2PSession (net.i2p.client.I2PSession)10 I2PSocket (net.i2p.client.streaming.I2PSocket)10 FileInputStream (java.io.FileInputStream)7 InputStream (java.io.InputStream)7 OutputStream (java.io.OutputStream)7 I2PClient (net.i2p.client.I2PClient)7 I2PSocketOptions (net.i2p.client.streaming.I2PSocketOptions)7 Test (org.junit.Test)6