Search in sources :

Example 81 with RouterInfo

use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.

the class ExpireRoutersJob method expireKeys.

/**
 * Run through all of the known peers and pick ones that have really old
 * routerInfo publish dates, excluding ones that we are connected to,
 * so that they can be failed
 *
 * @return number removed
 */
private int expireKeys() {
    Set<Hash> keys = _facade.getAllRouters();
    keys.remove(getContext().routerHash());
    if (keys.size() < 150)
        return 0;
    int removed = 0;
    for (Hash key : keys) {
        // Don't expire anybody we are connected to
        if (!getContext().commSystem().isEstablished(key)) {
            DatabaseEntry e = _facade.lookupLocallyWithoutValidation(key);
            if (e != null && e.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
                try {
                    if (_facade.validate((RouterInfo) e) != null) {
                        _facade.dropAfterLookupFailed(key);
                        removed++;
                    }
                } catch (IllegalArgumentException iae) {
                    _facade.dropAfterLookupFailed(key);
                    removed++;
                }
            }
        }
    }
    return removed;
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) DatabaseEntry(net.i2p.data.DatabaseEntry) Hash(net.i2p.data.Hash)

Example 82 with RouterInfo

use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.

the class FloodfillRouterInfoFloodJob method runJob.

public void runJob() {
    FloodfillPeerSelector sel = (FloodfillPeerSelector) _facade.getPeerSelector();
    DatabaseStoreMessage dsm;
    OutNetMessage outMsg;
    RouterInfo nextPeerInfo;
    List<Hash> peers = sel.selectFloodfillParticipants(getContext().routerHash(), FLOOD_PEERS, null);
    for (Hash ri : peers) {
        // Iterate through list of nearby (ff) peers
        dsm = new DatabaseStoreMessage(getContext());
        dsm.setMessageExpiration(getContext().clock().now() + 10 * 1000);
        dsm.setEntry(getContext().router().getRouterInfo());
        nextPeerInfo = getContext().netDb().lookupRouterInfoLocally(ri);
        if (nextPeerInfo == null) {
            continue;
        }
        outMsg = new OutNetMessage(getContext(), dsm, getContext().clock().now() + 10 * 1000, OutNetMessage.PRIORITY_MY_NETDB_STORE, nextPeerInfo);
        // Whoosh!
        getContext().outNetMessagePool().add(outMsg);
        if (_log.shouldLog(Log.DEBUG)) {
            _log.logAlways(Log.DEBUG, "Sending our RI to: " + nextPeerInfo.getHash());
        }
    }
}
Also used : OutNetMessage(net.i2p.router.OutNetMessage) RouterInfo(net.i2p.data.router.RouterInfo) DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage) Hash(net.i2p.data.Hash)

Example 83 with RouterInfo

use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.

the class FloodfillVerifyStoreJob method pickTarget.

/**
 *  Pick a responsive floodfill close to the key, but not the one we sent to
 */
private Hash pickTarget() {
    Hash rkey = getContext().routingKeyGenerator().getRoutingKey(_key);
    FloodfillPeerSelector sel = (FloodfillPeerSelector) _facade.getPeerSelector();
    Certificate keyCert = null;
    if (!_isRouterInfo) {
        Destination dest = _facade.lookupDestinationLocally(_key);
        if (dest != null) {
            Certificate cert = dest.getCertificate();
            if (cert.getCertificateType() == Certificate.CERTIFICATE_TYPE_KEY)
                keyCert = cert;
        }
    }
    if (keyCert != null) {
        while (true) {
            List<Hash> peers = sel.selectFloodfillParticipants(rkey, 1, _ignore, _facade.getKBuckets());
            if (peers.isEmpty())
                break;
            Hash peer = peers.get(0);
            RouterInfo ri = _facade.lookupRouterInfoLocally(peer);
            // if (ri != null && StoreJob.supportsCert(ri, keyCert)) {
            if (ri != null && StoreJob.shouldStoreTo(ri)) {
                Set<String> peerIPs = new MaskedIPSet(getContext(), ri, IP_CLOSE_BYTES);
                if (!_ipSet.containsAny(peerIPs)) {
                    _ipSet.addAll(peerIPs);
                    return peer;
                } else {
                    if (_log.shouldLog(Log.INFO))
                        _log.info(getJobId() + ": Skipping verify w/ router too close to the store " + peer);
                }
            } else {
                if (_log.shouldLog(Log.INFO))
                    _log.info(getJobId() + ": Skipping verify w/ router that is too old " + peer);
            }
            _ignore.add(peer);
        }
    } else {
        List<Hash> peers = sel.selectFloodfillParticipants(rkey, 1, _ignore, _facade.getKBuckets());
        if (!peers.isEmpty())
            return peers.get(0);
    }
    if (_log.shouldLog(Log.WARN))
        _log.warn("No other peers to verify floodfill with, using the one we sent to");
    return _sentTo;
}
Also used : Destination(net.i2p.data.Destination) RouterInfo(net.i2p.data.router.RouterInfo) Hash(net.i2p.data.Hash) MaskedIPSet(net.i2p.router.util.MaskedIPSet) Certificate(net.i2p.data.Certificate)

Example 84 with RouterInfo

use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.

the class HandleFloodfillDatabaseLookupMessageJob method sendClosest.

/**
 * We extend this here to send our routerInfo back as well, if we are not floodfill.
 * This gets the word out to routers that we are no longer floodfill, so they
 * will stop bugging us.
 */
@Override
protected void sendClosest(Hash key, Set<Hash> routerInfoSet, Hash toPeer, TunnelId replyTunnel) {
    super.sendClosest(key, routerInfoSet, toPeer, replyTunnel);
    // go away, you got the wrong guy, send our RI back unsolicited
    if (!getContext().netDb().floodfillEnabled()) {
        // We could just call sendData(myhash, myri, toPeer, replyTunnel) but
        // that would increment the netDb.lookupsHandled and netDb.lookupsMatched stats
        DatabaseStoreMessage msg = new DatabaseStoreMessage(getContext());
        RouterInfo me = getContext().router().getRouterInfo();
        msg.setEntry(me);
        sendMessage(msg, toPeer, replyTunnel);
    }
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage)

Example 85 with RouterInfo

use of net.i2p.data.router.RouterInfo 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)

Aggregations

RouterInfo (net.i2p.data.router.RouterInfo)95 Hash (net.i2p.data.Hash)45 ArrayList (java.util.ArrayList)18 RouterAddress (net.i2p.data.router.RouterAddress)17 DataFormatException (net.i2p.data.DataFormatException)11 IOException (java.io.IOException)10 RouterIdentity (net.i2p.data.router.RouterIdentity)10 DatabaseEntry (net.i2p.data.DatabaseEntry)9 OutNetMessage (net.i2p.router.OutNetMessage)9 File (java.io.File)8 DatabaseStoreMessage (net.i2p.data.i2np.DatabaseStoreMessage)8 Properties (java.util.Properties)7 LeaseSet (net.i2p.data.LeaseSet)6 BigInteger (java.math.BigInteger)5 Date (java.util.Date)5 SigType (net.i2p.crypto.SigType)5 TunnelId (net.i2p.data.TunnelId)5 TunnelInfo (net.i2p.router.TunnelInfo)5 FileOutputStream (java.io.FileOutputStream)4 HashMap (java.util.HashMap)4