Search in sources :

Example 6 with LeaseSet

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

the class ClientConnectionRunner method requestLeaseSet.

/**
 * Request that a particular client authorize the Leases contained in the
 * LeaseSet, after which the onCreateJob is queued up.  If that doesn't occur
 * within the timeout specified, queue up the onFailedJob.  This call does not
 * block.
 *
 * Job args are always null, may need some fixups if we start using them.
 *
 * @param h the Destination's hash
 * @param set LeaseSet with requested leases - this object must be updated to contain the
 *            signed version (as well as any changed/added/removed Leases)
 *            The LeaseSet contains Leases and destination only, it is unsigned.
 * @param expirationTime ms to wait before failing
 * @param onCreateJob Job to run after the LeaseSet is authorized, null OK
 * @param onFailedJob Job to run after the timeout passes without receiving authorization, null OK
 */
void requestLeaseSet(Hash h, LeaseSet set, long expirationTime, Job onCreateJob, Job onFailedJob) {
    if (_dead) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Requesting leaseSet from a dead client: " + set);
        if (onFailedJob != null)
            _context.jobQueue().addJob(onFailedJob);
        return;
    }
    SessionParams sp = _sessions.get(h);
    if (sp == null) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Requesting leaseSet for an unknown sesssion");
        return;
    }
    // We can't use LeaseSet.equals() here because the dest, keys, and sig on
    // the new LeaseSet are null. So we compare leases one by one.
    // In addition, the client rewrites the expiration time of all the leases to
    // the earliest one, so we can't use Lease.equals() or Lease.getEndDate().
    // So compare by tunnel ID, and then by gateway.
    // (on the remote possibility that two gateways are using the same ID).
    // TunnelPool.locked_buildNewLeaseSet() ensures that leases are sorted,
    // so the comparison will always work.
    int leases = set.getLeaseCount();
    // synch so _currentLeaseSet isn't changed out from under us
    LeaseSet current = null;
    Destination dest = sp.dest;
    LeaseRequestState state;
    synchronized (this) {
        current = sp.currentLeaseSet;
        if (current != null && current.getLeaseCount() == leases) {
            for (int i = 0; i < leases; i++) {
                if (!current.getLease(i).getTunnelId().equals(set.getLease(i).getTunnelId()))
                    break;
                if (!current.getLease(i).getGateway().equals(set.getLease(i).getGateway()))
                    break;
                if (i == leases - 1) {
                    if (_log.shouldLog(Log.INFO))
                        _log.info("Requested leaseSet hasn't changed");
                    if (onCreateJob != null)
                        _context.jobQueue().addJob(onCreateJob);
                    // no change
                    return;
                }
            }
        }
        if (_log.shouldLog(Log.INFO))
            _log.info("Current leaseSet " + current + "\nNew leaseSet " + set);
        state = sp.leaseRequest;
        if (state != null) {
            LeaseSet requested = state.getRequested();
            LeaseSet granted = state.getGranted();
            long ours = set.getEarliestLeaseDate();
            if (((requested != null) && (requested.getEarliestLeaseDate() > ours)) || ((granted != null) && (granted.getEarliestLeaseDate() > ours))) {
                // theirs is newer
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug("Already requesting, theirs newer, do nothing: " + state);
            } else {
                // ours is newer, so wait a few secs and retry
                set.setDestination(dest);
                Rerequest timer = new Rerequest(set, expirationTime, onCreateJob, onFailedJob);
                sp.rerequestTimer = timer;
                _context.simpleTimer2().addEvent(timer, 3 * 1000);
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug("Already requesting, ours newer, wait 3 sec: " + state);
            }
            // already requesting
            return;
        } else {
            set.setDestination(dest);
            if (current == null && _context.tunnelManager().getOutboundClientTunnelCount(h) <= 0) {
                // at startup of a client, where we don't have a leaseset, wait for
                // an outbound tunnel also, so the client doesn't start sending data
                // before we are ready
                Rerequest timer = new Rerequest(set, expirationTime, onCreateJob, onFailedJob);
                sp.rerequestTimer = timer;
                _context.simpleTimer2().addEvent(timer, 1000);
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug("No current LS but no OB tunnels, wait 1 sec for " + h);
                return;
            } else {
                // so the timer won't fire off with an older LS request
                sp.rerequestTimer = null;
                sp.leaseRequest = state = new LeaseRequestState(onCreateJob, onFailedJob, _context.clock().now() + expirationTime, set);
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug("New request: " + state);
            }
        }
    }
    _context.jobQueue().addJob(new RequestLeaseSetJob(_context, this, state));
}
Also used : LeaseSet(net.i2p.data.LeaseSet) Destination(net.i2p.data.Destination)

Example 7 with LeaseSet

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

the class TunnelPool method fail.

/**
 *  Remove the tunnel.
 */
private void fail(TunnelInfo cfg) {
    if (_log.shouldLog(Log.WARN))
        _log.warn(toString() + ": Tunnel failed: " + cfg);
    LeaseSet ls = null;
    synchronized (_tunnels) {
        boolean removed = _tunnels.remove(cfg);
        if (!removed)
            return;
        if (_settings.isInbound() && !_settings.isExploratory())
            ls = locked_buildNewLeaseSet();
        if (_lastSelected == cfg) {
            _lastSelected = null;
            _lastSelectionPeriod = 0;
        }
    }
    _manager.tunnelFailed();
    _lifetimeProcessed += cfg.getProcessedMessagesCount();
    updateRate();
    if (_settings.isInbound() && !_settings.isExploratory()) {
        if (ls != null) {
            _context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
        }
    }
}
Also used : LeaseSet(net.i2p.data.LeaseSet)

Example 8 with LeaseSet

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

the class TunnelPool method refreshLeaseSet.

/**
 * noop for outbound and exploratory
 */
void refreshLeaseSet() {
    if (_settings.isInbound() && !_settings.isExploratory()) {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug(toString() + ": refreshing leaseSet on tunnel expiration (but prior to grace timeout)");
        LeaseSet ls;
        synchronized (_tunnels) {
            ls = locked_buildNewLeaseSet();
        }
        if (ls != null) {
            _context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
            Set<Hash> aliases = _settings.getAliases();
            if (aliases != null && !aliases.isEmpty()) {
                for (Hash h : aliases) {
                    _context.clientManager().requestLeaseSet(h, ls);
                }
            }
        }
    }
}
Also used : LeaseSet(net.i2p.data.LeaseSet) Hash(net.i2p.data.Hash)

Example 9 with LeaseSet

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

the class TunnelPool method startup.

/**
 *  Warning, this may be called more than once
 *  (without an intervening shutdown()) if the
 *  tunnel is stopped and then restarted by the client manager with the same
 *  Destination (i.e. for servers or clients w/ persistent key,
 *  or restarting close-on-idle clients)
 */
synchronized void startup() {
    synchronized (_inProgress) {
        _inProgress.clear();
    }
    if (_log.shouldLog(Log.INFO))
        _log.info(toString() + ": Startup() called, was already alive? " + _alive, new Exception());
    _alive = true;
    _started = System.currentTimeMillis();
    _lastRateUpdate = _started;
    _lastLifetimeProcessed = 0;
    _manager.getExecutor().repoll();
    if (_settings.isInbound() && !_settings.isExploratory()) {
        // we just reconnected and didn't require any new tunnel builders.
        // however, we /do/ want a leaseSet, so build one
        LeaseSet ls = null;
        synchronized (_tunnels) {
            ls = locked_buildNewLeaseSet();
        }
        if (ls != null)
            _context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
    }
    _context.statManager().createRequiredRateStat(_rateName, "Tunnel Bandwidth (Bytes/sec)", "Tunnels", new long[] { 5 * 60 * 1000l });
}
Also used : LeaseSet(net.i2p.data.LeaseSet)

Example 10 with LeaseSet

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

the class TunnelPool method removeTunnel.

/**
 *  Remove from the pool.
 */
void removeTunnel(TunnelInfo info) {
    if (_log.shouldLog(Log.DEBUG))
        _log.debug(toString() + ": Removing tunnel " + info);
    int remaining = 0;
    LeaseSet ls = null;
    synchronized (_tunnels) {
        boolean removed = _tunnels.remove(info);
        if (!removed)
            return;
        if (_settings.isInbound() && !_settings.isExploratory())
            ls = locked_buildNewLeaseSet();
        remaining = _tunnels.size();
        if (_lastSelected == info) {
            _lastSelected = null;
            _lastSelectionPeriod = 0;
        }
    }
    _manager.getExecutor().repoll();
    _lifetimeProcessed += info.getProcessedMessagesCount();
    updateRate();
    long lifetimeConfirmed = info.getVerifiedBytesTransferred();
    long lifetime = 10 * 60 * 1000;
    for (int i = 0; i < info.getLength(); i++) _context.profileManager().tunnelLifetimePushed(info.getPeer(i), lifetime, lifetimeConfirmed);
    if (_alive && _settings.isInbound() && !_settings.isExploratory()) {
        if (ls != null) {
            _context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
        } else {
            if (_log.shouldLog(Log.WARN))
                _log.warn(toString() + ": unable to build a new leaseSet on removal (" + remaining + " remaining), request a new tunnel");
            if (_settings.getAllowZeroHop())
                buildFallback();
        }
    }
    if (getTunnelCount() <= 0 && !isAlive()) {
        // this calls both our shutdown() and the other one (inbound/outbound)
        // This is racy - see TunnelPoolManager
        _manager.removeTunnels(_settings.getDestination());
    }
}
Also used : LeaseSet(net.i2p.data.LeaseSet)

Aggregations

LeaseSet (net.i2p.data.LeaseSet)29 Date (java.util.Date)7 Hash (net.i2p.data.Hash)7 Lease (net.i2p.data.Lease)6 RouterInfo (net.i2p.data.router.RouterInfo)6 Destination (net.i2p.data.Destination)5 DatabaseEntry (net.i2p.data.DatabaseEntry)4 DataFormatException (net.i2p.data.DataFormatException)3 TunnelId (net.i2p.data.TunnelId)3 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 I2CPMessageException (net.i2p.data.i2cp.I2CPMessageException)2 RequestLeaseSetMessage (net.i2p.data.i2cp.RequestLeaseSetMessage)2 RequestVariableLeaseSetMessage (net.i2p.data.i2cp.RequestVariableLeaseSetMessage)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 EOFException (java.io.EOFException)1 BigInteger (java.math.BigInteger)1 DecimalFormat (java.text.DecimalFormat)1 Collection (java.util.Collection)1