Search in sources :

Example 71 with Hash

use of net.i2p.data.Hash in project i2p.i2p by i2p.

the class TunnelPool method configureNewTunnel.

/**
 *  @return null on failure
 */
private PooledTunnelCreatorConfig configureNewTunnel(boolean forceZeroHop) {
    TunnelPoolSettings settings = getSettings();
    // peers for new tunnel, including us, ENDPOINT FIRST
    List<Hash> peers = null;
    long now = _context.clock().now();
    long expiration = now + TunnelPoolSettings.DEFAULT_DURATION;
    if (!forceZeroHop) {
        int len = settings.getLengthOverride();
        if (len < 0)
            len = settings.getLength();
        if (len > 0 && (!settings.isExploratory()) && _context.random().nextBoolean()) {
            // look for a tunnel to reuse, if the right length and expiring soon
            // ignore variance for now.
            // us
            len++;
            synchronized (_tunnels) {
                for (TunnelInfo ti : _tunnels) {
                    if (ti.getLength() >= len && ti.getExpiration() < now + 3 * 60 * 1000 && !ti.wasReused()) {
                        ti.setReused();
                        len = ti.getLength();
                        peers = new ArrayList<Hash>(len);
                        // peers list is ordered endpoint first, but cfg.getPeer() is ordered gateway first
                        for (int i = len - 1; i >= 0; i--) {
                            peers.add(ti.getPeer(i));
                        }
                        break;
                    }
                }
            }
        }
        if (peers == null) {
            setLengthOverride();
            peers = _peerSelector.selectPeers(settings);
        }
        if ((peers == null) || (peers.isEmpty())) {
            // the pool is refusing 0 hop tunnels
            if (peers == null) {
                if (_log.shouldLog(Log.WARN))
                    _log.warn("No peers to put in the new tunnel! selectPeers returned null!  boo, hiss!");
            } else {
                if (_log.shouldLog(Log.WARN))
                    _log.warn("No peers to put in the new tunnel! selectPeers returned an empty list?!");
            }
            return null;
        }
    } else {
        peers = Collections.singletonList(_context.routerHash());
    }
    PooledTunnelCreatorConfig cfg = new PooledTunnelCreatorConfig(_context, peers.size(), settings.isInbound(), settings.getDestination());
    cfg.setTunnelPool(this);
    // peers list is ordered endpoint first, but cfg.getPeer() is ordered gateway first
    for (int i = 0; i < peers.size(); i++) {
        int j = peers.size() - 1 - i;
        cfg.setPeer(j, peers.get(i));
        HopConfig hop = cfg.getConfig(j);
        hop.setCreation(now);
        hop.setExpiration(expiration);
        hop.setIVKey(_context.keyGenerator().generateSessionKey());
        hop.setLayerKey(_context.keyGenerator().generateSessionKey());
    // tunnelIds will be updated during building, and as the creator, we
    // don't need to worry about prev/next hop
    }
    // note that this will be adjusted by expire job
    cfg.setExpiration(expiration);
    if (!settings.isInbound())
        cfg.setPriority(settings.getPriority());
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("Config contains " + peers + ": " + cfg);
    synchronized (_inProgress) {
        _inProgress.add(cfg);
    }
    return cfg;
}
Also used : TunnelPoolSettings(net.i2p.router.TunnelPoolSettings) TunnelInfo(net.i2p.router.TunnelInfo) HopConfig(net.i2p.router.tunnel.HopConfig) Hash(net.i2p.data.Hash)

Example 72 with Hash

use of net.i2p.data.Hash in project i2p.i2p by i2p.

the class TunnelPoolManager method addAlias.

/**
 *  Add another destination to the same tunnels.
 *  Must have same encryption key and a different signing key.
 *  @throws IllegalArgumentException if not
 *  @return success
 *  @since 0.9.21
 */
public boolean addAlias(Destination dest, ClientTunnelSettings settings, Destination existingClient) {
    if (dest.getSigningPublicKey().equals(existingClient.getSigningPublicKey()))
        throw new IllegalArgumentException("signing key must differ");
    if (!dest.getPublicKey().equals(existingClient.getPublicKey()))
        throw new IllegalArgumentException("encryption key mismatch");
    Hash h = dest.calculateHash();
    Hash e = existingClient.calculateHash();
    synchronized (this) {
        TunnelPool inbound = _clientInboundPools.get(h);
        TunnelPool outbound = _clientOutboundPools.get(h);
        if (inbound != null || outbound != null) {
            if (_log.shouldLog(Log.WARN))
                _log.warn("already have alias " + dest.toBase32());
            return false;
        }
        TunnelPool eInbound = _clientInboundPools.get(e);
        TunnelPool eOutbound = _clientOutboundPools.get(e);
        if (eInbound == null || eOutbound == null) {
            if (_log.shouldLog(Log.WARN))
                _log.warn("primary not found " + existingClient);
            return false;
        }
        eInbound.getSettings().getAliases().add(h);
        eOutbound.getSettings().getAliases().add(h);
        TunnelPoolSettings newIn = settings.getInboundSettings();
        TunnelPoolSettings newOut = settings.getOutboundSettings();
        newIn.setAliasOf(e);
        newOut.setAliasOf(e);
        inbound = new AliasedTunnelPool(_context, this, newIn, eInbound);
        outbound = new AliasedTunnelPool(_context, this, newOut, eOutbound);
        _clientInboundPools.put(h, inbound);
        _clientOutboundPools.put(h, outbound);
        inbound.startup();
        outbound.startup();
    }
    if (_log.shouldLog(Log.WARN))
        _log.warn("Added " + dest.toBase32() + " as alias for " + existingClient.toBase32() + " with settings " + settings);
    return true;
}
Also used : TunnelPoolSettings(net.i2p.router.TunnelPoolSettings) Hash(net.i2p.data.Hash)

Example 73 with Hash

use of net.i2p.data.Hash in project i2p.i2p by i2p.

the class TunnelPoolManager method removeAlias.

/**
 *  Remove a destination for the same tunnels as another.
 *  @since 0.9.21
 */
public void removeAlias(Destination dest) {
    Hash h = dest.calculateHash();
    synchronized (this) {
        TunnelPool inbound = _clientInboundPools.remove(h);
        if (inbound != null) {
            Hash p = inbound.getSettings().getAliasOf();
            if (p != null) {
                TunnelPool pri = _clientInboundPools.get(p);
                if (pri != null) {
                    Set<Hash> aliases = pri.getSettings().getAliases();
                    if (aliases != null)
                        aliases.remove(h);
                }
            }
        }
        TunnelPool outbound = _clientOutboundPools.remove(h);
        if (outbound != null) {
            Hash p = outbound.getSettings().getAliasOf();
            if (p != null) {
                TunnelPool pri = _clientOutboundPools.get(p);
                if (pri != null) {
                    Set<Hash> aliases = pri.getSettings().getAliases();
                    if (aliases != null)
                        aliases.remove(h);
                }
            }
        }
    // TODO if primary already vanished...
    }
}
Also used : Hash(net.i2p.data.Hash)

Example 74 with Hash

use of net.i2p.data.Hash in project i2p.i2p by i2p.

the class TunnelPoolManager method selectPeersInTooManyTunnels.

/**
 *  For reliability reasons, don't allow a peer in more than x% of
 *  client and exploratory tunnels.
 *
 *  This also will prevent a single huge-capacity (or malicious) peer from
 *  taking all the tunnels in the network (although it would be nice to limit
 *  the % of total network tunnels to 10% or so, but that appears to be
 *  too low to set as a default here... much lower than 33% will push client
 *  tunnels out of the fast tier into high cap or beyond...)
 *
 *  Possible improvement - restrict based on count per IP, or IP block,
 *  to slightly increase costs of collusion
 *
 *  @return Set of peers that should not be allowed in another tunnel
 */
public Set<Hash> selectPeersInTooManyTunnels() {
    ObjectCounter<Hash> lc = new ObjectCounter<Hash>();
    int tunnelCount = countTunnelsPerPeer(lc);
    Set<Hash> rv = new HashSet<Hash>();
    if (tunnelCount >= 4 && _context.router().getUptime() > 10 * 60 * 1000) {
        int max = _context.getProperty("router.maxTunnelPercentage", DEFAULT_MAX_PCT_TUNNELS);
        for (Hash h : lc.objects()) {
            if (lc.count(h) > 0 && (lc.count(h) + 1) * 100 / (tunnelCount + 1) > max)
                rv.add(h);
        }
    }
    return rv;
}
Also used : ObjectCounter(net.i2p.util.ObjectCounter) Hash(net.i2p.data.Hash) HashSet(java.util.HashSet)

Example 75 with Hash

use of net.i2p.data.Hash in project i2p.i2p by i2p.

the class InboundEndpointProcessor method retrievePreprocessedData.

/**
 * Undo all of the encryption done by the peers in the tunnel, recovering the
 * preprocessed data sent by the gateway.
 *
 * @return true if the data was recovered (and written in place to orig), false
 *         if it was a duplicate or from the wrong peer.
 */
public boolean retrievePreprocessedData(byte[] orig, int offset, int length, Hash prev) {
    Hash last = _config.getPeer(_config.getLength() - 2);
    if (!last.equals(prev)) {
        // shouldn't happen now that we have good dup ID detection in BuildHandler
        if (_log.shouldLog(Log.WARN))
            _log.warn("Attempted IBEP injection from " + prev + ", expected " + last);
        return false;
    }
    byte[] iv = SimpleByteCache.acquire(HopProcessor.IV_LENGTH);
    System.arraycopy(orig, offset, iv, 0, iv.length);
    // if (_config.getLength() > 1)
    // _log.debug("IV at inbound endpoint before decrypt: " + Base64.encode(iv));
    boolean ok = _validator.receiveIV(iv, 0, orig, offset + HopProcessor.IV_LENGTH);
    if (!ok) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Invalid IV, dropping at IBEP " + _config);
        SimpleByteCache.release(iv);
        return false;
    }
    // inbound endpoints and outbound gateways have to undo the crypto in the same way
    // if (USE_ENCRYPTION)
    decrypt(_context, _config, iv, orig, offset, length);
    SimpleByteCache.release(iv);
    if (_config.getLength() > 0) {
        // dunno... may not be related to an rtt
        int rtt = 0;
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Received a " + length + "byte message through tunnel " + _config);
        for (int i = 0; i < _config.getLength(); i++) _context.profileManager().tunnelDataPushed(_config.getPeer(i), rtt, length);
        _config.incrementVerifiedBytesTransferred(length);
    }
    return true;
}
Also used : Hash(net.i2p.data.Hash)

Aggregations

Hash (net.i2p.data.Hash)235 RouterInfo (net.i2p.data.router.RouterInfo)45 ArrayList (java.util.ArrayList)29 TunnelId (net.i2p.data.TunnelId)20 Destination (net.i2p.data.Destination)18 HashSet (java.util.HashSet)17 ConvertToHash (net.i2p.util.ConvertToHash)17 IOException (java.io.IOException)16 TunnelInfo (net.i2p.router.TunnelInfo)15 DataFormatException (net.i2p.data.DataFormatException)14 Properties (java.util.Properties)13 Date (java.util.Date)12 DatabaseEntry (net.i2p.data.DatabaseEntry)11 SessionKey (net.i2p.data.SessionKey)11 RouterAddress (net.i2p.data.router.RouterAddress)11 DatabaseStoreMessage (net.i2p.data.i2np.DatabaseStoreMessage)9 I2NPMessage (net.i2p.data.i2np.I2NPMessage)9 Job (net.i2p.router.Job)9 OutNetMessage (net.i2p.router.OutNetMessage)9 TunnelPoolSettings (net.i2p.router.TunnelPoolSettings)8