Search in sources :

Example 26 with LeaseSet

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

the class HandleFloodfillDatabaseStoreMessageJob method runJob.

public void runJob() {
    // if (_log.shouldLog(Log.DEBUG))
    // _log.debug("Handling database store message");
    long recvBegin = System.currentTimeMillis();
    String invalidMessage = null;
    // set if invalid store but not his fault
    boolean dontBlamePeer = false;
    boolean wasNew = false;
    RouterInfo prevNetDb = null;
    Hash key = _message.getKey();
    DatabaseEntry entry = _message.getEntry();
    if (entry.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
        getContext().statManager().addRateData("netDb.storeLeaseSetHandled", 1);
        if (_log.shouldLog(Log.INFO))
            _log.info("Handling dbStore of leaseset " + _message);
        try {
            // storing the other guy's leaseset, it will confuse us badly.
            if (getContext().clientManager().isLocal(key)) {
                // getContext().statManager().addRateData("netDb.storeLocalLeaseSetAttempt", 1, 0);
                // throw rather than return, so that we send the ack below (prevent easy attack)
                dontBlamePeer = true;
                throw new IllegalArgumentException("Peer attempted to store local leaseSet: " + key.toBase64().substring(0, 4));
            }
            LeaseSet ls = (LeaseSet) entry;
            // See ../HDLMJ for more info
            if (!ls.getReceivedAsReply())
                ls.setReceivedAsPublished(true);
            // boolean rap = ls.getReceivedAsPublished();
            // if (_log.shouldLog(Log.INFO))
            // _log.info("oldrap? " + oldrap + " oldrar? " + oldrar + " newrap? " + rap);
            LeaseSet match = getContext().netDb().store(key, ls);
            if (match == null) {
                wasNew = true;
            } else if (match.getEarliestLeaseDate() < ls.getEarliestLeaseDate()) {
                wasNew = true;
                if (match.getReceivedAsPublished())
                    ls.setReceivedAsPublished(true);
            } else {
                wasNew = false;
            // The FloodOnlyLookupSelector goes away after the first good reply
            // So on the second reply, FloodOnlyMatchJob is not called to set ReceivedAsReply.
            // So then we think it's an unsolicited store.
            // So we should skip this.
            // If the 2nd reply is newer than the first, ReceivedAsPublished will be set incorrectly,
            // that will hopefully be rare.
            // A more elaborate solution would be a List of recent ReceivedAsReply LeaseSets, with receive time ?
            // A real unsolicited store is likely to be new - hopefully...
            // if (!ls.getReceivedAsReply())
            // match.setReceivedAsPublished(true);
            }
        } catch (UnsupportedCryptoException uce) {
            invalidMessage = uce.getMessage();
            dontBlamePeer = true;
        } catch (IllegalArgumentException iae) {
            invalidMessage = iae.getMessage();
        }
    } else if (entry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
        RouterInfo ri = (RouterInfo) entry;
        getContext().statManager().addRateData("netDb.storeRouterInfoHandled", 1);
        if (_log.shouldLog(Log.INFO))
            _log.info("Handling dbStore of router " + key + " with publishDate of " + new Date(ri.getPublished()));
        try {
            // somebody has our keys...
            if (getContext().routerHash().equals(key)) {
                // getContext().statManager().addRateData("netDb.storeLocalRouterInfoAttempt", 1, 0);
                // This is initiated by PeerTestJob from another peer
                // throw rather than return, so that we send the ack below (prevent easy attack)
                dontBlamePeer = true;
                throw new IllegalArgumentException("Peer attempted to store our RouterInfo");
            }
            getContext().profileManager().heardAbout(key);
            prevNetDb = getContext().netDb().store(key, ri);
            wasNew = ((null == prevNetDb) || (prevNetDb.getPublished() < ri.getPublished()));
            // Check new routerinfo address against blocklist
            if (wasNew) {
                if (prevNetDb == null) {
                    if ((!getContext().banlist().isBanlistedForever(key)) && getContext().blocklist().isBlocklisted(ri) && _log.shouldLog(Log.WARN))
                        _log.warn("Blocklisting new peer " + key + ' ' + ri);
                } else {
                    Collection<RouterAddress> oldAddr = prevNetDb.getAddresses();
                    Collection<RouterAddress> newAddr = ri.getAddresses();
                    if ((!newAddr.equals(oldAddr)) && (!getContext().banlist().isBanlistedForever(key)) && getContext().blocklist().isBlocklisted(ri) && _log.shouldLog(Log.WARN))
                        _log.warn("New address received, Blocklisting old peer " + key + ' ' + ri);
                }
            }
        } catch (UnsupportedCryptoException uce) {
            invalidMessage = uce.getMessage();
            dontBlamePeer = true;
        } catch (IllegalArgumentException iae) {
            invalidMessage = iae.getMessage();
        }
    } else {
        if (_log.shouldLog(Log.ERROR))
            _log.error("Invalid DatabaseStoreMessage data type - " + entry.getType() + ": " + _message);
        // don't ack or flood
        return;
    }
    long recvEnd = System.currentTimeMillis();
    getContext().statManager().addRateData("netDb.storeRecvTime", recvEnd - recvBegin);
    // TODO any cases where we shouldn't?
    if (_message.getReplyToken() > 0)
        sendAck(key);
    long ackEnd = System.currentTimeMillis();
    if (_from != null)
        _fromHash = _from.getHash();
    if (_fromHash != null) {
        if (invalidMessage == null || dontBlamePeer) {
            getContext().profileManager().dbStoreReceived(_fromHash, wasNew);
            getContext().statManager().addRateData("netDb.storeHandled", ackEnd - recvEnd);
        } else {
            // Should we record in the profile?
            if (_log.shouldLog(Log.WARN))
                _log.warn("Peer " + _fromHash.toBase64() + " sent bad data: " + invalidMessage);
        }
    } else if (invalidMessage != null && !dontBlamePeer) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Unknown peer sent bad data: " + invalidMessage);
    }
    // flood it
    if (invalidMessage == null && getContext().netDb().floodfillEnabled() && _message.getReplyToken() > 0) {
        if (wasNew) {
            // Note this does not throttle the ack above
            if (_facade.shouldThrottleFlood(key)) {
                if (_log.shouldLog(Log.WARN))
                    _log.warn("Too many recent stores, not flooding key: " + key);
                getContext().statManager().addRateData("netDb.floodThrottled", 1);
                return;
            }
            long floodBegin = System.currentTimeMillis();
            _facade.flood(_message.getEntry());
            // ERR: see comment in HandleDatabaseLookupMessageJob regarding hidden mode
            // else if (!_message.getRouterInfo().isHidden())
            long floodEnd = System.currentTimeMillis();
            getContext().statManager().addRateData("netDb.storeFloodNew", floodEnd - floodBegin, 60 * 1000);
        } else {
            // don't flood it *again*
            getContext().statManager().addRateData("netDb.storeFloodOld", 1);
        }
    }
}
Also used : LeaseSet(net.i2p.data.LeaseSet) RouterInfo(net.i2p.data.router.RouterInfo) Collection(java.util.Collection) DatabaseEntry(net.i2p.data.DatabaseEntry) Hash(net.i2p.data.Hash) Date(java.util.Date)

Example 27 with LeaseSet

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

the class ClientConnectionRunner method stopRunning.

/**
 *  Die a horrible death. Cannot be restarted.
 */
public synchronized void stopRunning() {
    if (_dead)
        return;
    // router may be null in unit tests
    if ((_context.router() == null || _context.router().isAlive()) && _log.shouldWarn())
        _log.warn("Stop the I2CP connection!", new Exception("Stop client connection"));
    _dead = true;
    // we need these keys to unpublish the leaseSet
    if (_reader != null)
        _reader.stopReading();
    if (_writer != null)
        _writer.stopWriting();
    if (_socket != null)
        try {
            _socket.close();
        } catch (IOException ioe) {
        }
    _messages.clear();
    _acceptedPending.clear();
    if (_sessionKeyManager != null)
        _sessionKeyManager.shutdown();
    _manager.unregisterConnection(this);
    // netdb may be null in unit tests
    if (_context.netDb() != null) {
        for (SessionParams sp : _sessions.values()) {
            LeaseSet ls = sp.currentLeaseSet;
            if (ls != null)
                _context.netDb().unpublish(ls);
            if (!sp.isPrimary)
                _context.tunnelManager().removeAlias(sp.dest);
        }
    }
    synchronized (_alreadyProcessed) {
        _alreadyProcessed.clear();
    }
    _sessions.clear();
}
Also used : LeaseSet(net.i2p.data.LeaseSet) IOException(java.io.IOException) I2CPMessageException(net.i2p.data.i2cp.I2CPMessageException) IOException(java.io.IOException) EOFException(java.io.EOFException)

Example 28 with LeaseSet

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

the class ClientConnectionRunner method removeSession.

/**
 *  Kill the session. Caller must kill runner if none left.
 *
 *  @since 0.9.21
 */
void removeSession(SessionId id) {
    if (id == null)
        return;
    boolean isPrimary = false;
    for (Iterator<SessionParams> iter = _sessions.values().iterator(); iter.hasNext(); ) {
        SessionParams sp = iter.next();
        if (id.equals(sp.sessionId)) {
            if (_log.shouldLog(Log.INFO))
                _log.info("Destroying client session " + id);
            iter.remove();
            // Tell client manger
            _manager.unregisterSession(id, sp.dest);
            LeaseSet ls = sp.currentLeaseSet;
            if (ls != null)
                _context.netDb().unpublish(ls);
            isPrimary = sp.isPrimary;
            if (!isPrimary)
                _context.tunnelManager().removeAlias(sp.dest);
            break;
        }
    }
    if (isPrimary && !_sessions.isEmpty()) {
        // kill all the others also
        for (SessionParams sp : _sessions.values()) {
            if (_log.shouldLog(Log.INFO))
                _log.info("Destroying remaining client subsession " + sp.sessionId);
            _manager.unregisterSession(sp.sessionId, sp.dest);
            LeaseSet ls = sp.currentLeaseSet;
            if (ls != null)
                _context.netDb().unpublish(ls);
            _context.tunnelManager().removeAlias(sp.dest);
        }
    }
}
Also used : LeaseSet(net.i2p.data.LeaseSet)

Example 29 with LeaseSet

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

the class ClientManagerFacadeImpl method verifyClientLiveliness.

@Override
public boolean verifyClientLiveliness() {
    if (_manager == null)
        return true;
    boolean lively = true;
    for (Destination dest : _manager.getRunnerDestinations()) {
        ClientConnectionRunner runner = _manager.getRunner(dest);
        if ((runner == null) || (runner.getIsDead()))
            continue;
        LeaseSet ls = runner.getLeaseSet(dest.calculateHash());
        if (ls == null)
            // still building
            continue;
        long howLongAgo = _context.clock().now() - ls.getEarliestLeaseDate();
        if (howLongAgo > MAX_TIME_TO_REBUILD) {
            if (_log.shouldLog(Log.ERROR))
                _log.error("Client " + dest.toBase32() + " has a leaseSet that expired " + DataHelper.formatDuration(howLongAgo) + " ago");
            lively = false;
        }
    }
    return lively;
}
Also used : LeaseSet(net.i2p.data.LeaseSet) Destination(net.i2p.data.Destination)

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