Search in sources :

Example 56 with RouterInfo

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

the class BundleRouterInfos method main.

/**
 *  Usage: PersistentDataStore -i configDir -o toDir -c count
 *
 *  Copy a random selection of 'count' router infos from configDir/netDb
 *  to 'toDir'. Skip your own router info, and old, hidden, unreachable, and
 *  introduced routers, and those from bad countries.
 *
 *  @since 0.9.15
 */
public static void main(String[] args) {
    Getopt g = new Getopt("PersistentDataStore", args, "i:o:c:");
    String in = System.getProperty("user.home") + "/.i2p";
    String out = "netDb";
    int count = 200;
    boolean error = false;
    int c;
    while ((c = g.getopt()) != -1) {
        switch(c) {
            case 'i':
                in = g.getOptarg();
                break;
            case 'o':
                out = g.getOptarg();
                break;
            case 'c':
                String scount = g.getOptarg();
                try {
                    count = Integer.parseInt(scount);
                } catch (NumberFormatException nfe) {
                    error = true;
                }
                break;
            case '?':
            case ':':
            default:
                error = true;
        }
    }
    if (error) {
        usage();
        System.exit(1);
    }
    Properties props = new Properties();
    props.setProperty(GeoIP.PROP_GEOIP_DIR, System.getProperty("user.dir") + "/installer/resources");
    GeoIP geoIP = new GeoIP(new I2PAppContext(props));
    File confDir = new File(in);
    File dbDir = new File(confDir, "netDb");
    if (!dbDir.exists()) {
        System.out.println("NetDB directory " + dbDir + " does not exist");
        System.exit(1);
    }
    File myFile = new File(confDir, "router.info");
    File toDir = new File(out);
    toDir.mkdirs();
    InputStream fis = null;
    Hash me = null;
    try {
        fis = new BufferedInputStream(new FileInputStream(myFile));
        RouterInfo ri = new RouterInfo();
        // true = verify sig on read
        ri.readBytes(fis, true);
        me = ri.getIdentity().getHash();
    } catch (IOException e) {
    // System.out.println("Can't determine our identity");
    } catch (DataFormatException e) {
    // System.out.println("Can't determine our identity");
    } finally {
        if (fis != null)
            try {
                fis.close();
            } catch (IOException ioe) {
            }
    }
    int routerCount = 0;
    List<File> toRead = new ArrayList<File>(2048);
    for (int j = 0; j < Base64.ALPHABET_I2P.length(); j++) {
        File subdir = new File(dbDir, PersistentDataStore.DIR_PREFIX + Base64.ALPHABET_I2P.charAt(j));
        File[] files = subdir.listFiles(PersistentDataStore.RI_FILTER);
        if (files == null)
            continue;
        routerCount += files.length;
        for (int i = 0; i < files.length; i++) {
            toRead.add(files[i]);
        }
    }
    if (toRead.isEmpty()) {
        System.out.println("No files to copy in " + dbDir);
        System.exit(1);
    }
    Collections.shuffle(toRead);
    int copied = 0;
    long tooOld = System.currentTimeMillis() - 7 * 24 * 60 * 60 * 1000L;
    Map<String, String> ipMap = new HashMap<String, String>(count);
    for (File file : toRead) {
        if (copied >= count)
            break;
        Hash key = PersistentDataStore.getRouterInfoHash(file.getName());
        if (key == null) {
            System.out.println("Skipping bad " + file);
            continue;
        }
        if (key.equals(me)) {
            System.out.println("Skipping my RI");
            continue;
        }
        fis = null;
        try {
            fis = new BufferedInputStream(new FileInputStream(file));
            RouterInfo ri = new RouterInfo();
            // true = verify sig on read
            ri.readBytes(fis, true);
            try {
                fis.close();
            } catch (IOException ioe) {
            }
            fis = null;
            if (ri.getPublished() < tooOld) {
                System.out.println("Skipping too old " + key);
                continue;
            }
            if (ri.getCapabilities().contains("U")) {
                System.out.println("Skipping unreachable " + key);
                continue;
            }
            if (ri.getCapabilities().contains("K")) {
                System.out.println("Skipping slow " + key);
                continue;
            }
            Collection<RouterAddress> addrs = ri.getAddresses();
            if (addrs.isEmpty()) {
                System.out.println("Skipping hidden " + key);
                continue;
            }
            boolean hasIntro = false;
            boolean hasIPv4 = false;
            boolean dupIP = false;
            for (RouterAddress addr : addrs) {
                if ("SSU".equals(addr.getTransportStyle()) && addr.getOption("ihost0") != null) {
                    hasIntro = true;
                    break;
                }
                String host = addr.getHost();
                if (host != null && host.contains(".")) {
                    hasIPv4 = true;
                    geoIP.add(host);
                    String old = ipMap.put(host, file.getName());
                    if (old != null && !old.equals(file.getName())) {
                        dupIP = true;
                        break;
                    }
                }
            }
            if (dupIP) {
                System.out.println("Skipping dup IP " + key);
                continue;
            }
            if (hasIntro) {
                System.out.println("Skipping introduced " + key);
                continue;
            }
            if (!hasIPv4) {
                System.out.println("Skipping IPv6-only " + key);
                continue;
            }
            File toFile = new File(toDir, file.getName());
            // We could call ri.write() to avoid simultaneous change by the router
            boolean ok = FileUtil.copy(file, toFile, true, true);
            if (ok)
                copied++;
            else
                System.out.println("Failed copy of " + file + " to " + toDir);
        } catch (IOException e) {
            System.out.println("Skipping bad " + file);
        } catch (DataFormatException e) {
            System.out.println("Skipping bad " + file);
        } finally {
            if (fis != null)
                try {
                    fis.close();
                } catch (IOException ioe) {
                }
        }
    }
    if (copied > 0) {
        // now do all the geoip lookups, and delete any bad countries
        geoIP.blockingLookup();
        for (Map.Entry<String, String> e : ipMap.entrySet()) {
            String co = geoIP.get(e.getKey());
            if (co != null) {
                if (BadCountries.contains(co)) {
                    String name = e.getValue();
                    File toFile = new File(toDir, name);
                    if (toFile.delete()) {
                        String full = geoIP.fullName(co);
                        if (full == null)
                            full = co;
                        System.out.println("Skipping " + full + ": " + name);
                        copied--;
                    }
                }
            }
        }
    }
    if (copied > 0) {
        System.out.println("Copied " + copied + " router info files to " + toDir);
    } else {
        System.out.println("Failed to copy any files to " + toDir);
        System.exit(1);
    }
}
Also used : GeoIP(net.i2p.router.transport.GeoIP) I2PAppContext(net.i2p.I2PAppContext) HashMap(java.util.HashMap) RouterInfo(net.i2p.data.router.RouterInfo) ArrayList(java.util.ArrayList) Properties(java.util.Properties) Hash(net.i2p.data.Hash) Getopt(gnu.getopt.Getopt) BufferedInputStream(java.io.BufferedInputStream) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) RouterAddress(net.i2p.data.router.RouterAddress) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) DataFormatException(net.i2p.data.DataFormatException) File(java.io.File) HashMap(java.util.HashMap) Map(java.util.Map)

Example 57 with RouterInfo

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

the class MultiRouter method internalReseed.

private static void internalReseed() {
    HashSet<RouterInfo> riSet = new HashSet<RouterInfo>();
    for (Router r : _routers) {
        riSet.addAll(r.getContext().netDb().getRouters());
    }
    for (Router r : _routers) {
        for (RouterInfo ri : riSet) {
            r.getContext().netDb().publish(ri);
        }
    }
    _out.println(riSet.size() + " RouterInfos were reseeded");
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) Router(net.i2p.router.Router) HashSet(java.util.HashSet)

Example 58 with RouterInfo

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

the class NTCPTransport method outboundMessageReady.

protected void outboundMessageReady() {
    OutNetMessage msg = getNextMessage();
    if (msg != null) {
        RouterInfo target = msg.getTarget();
        RouterIdentity ident = target.getIdentity();
        Hash ih = ident.calculateHash();
        NTCPConnection con = null;
        boolean isNew = false;
        boolean fail = false;
        synchronized (_conLock) {
            con = _conByIdent.get(ih);
            if (con == null) {
                isNew = true;
                RouterAddress addr = getTargetAddress(target);
                if (addr != null) {
                    con = new NTCPConnection(_context, this, ident, addr);
                    // if (_log.shouldLog(Log.DEBUG))
                    // _log.debug("Send on a new con: " + con + " at " + addr + " for " + ih);
                    // Note that outbound conns go in the map BEFORE establishment
                    _conByIdent.put(ih, con);
                } else {
                    // race, RI changed out from under us
                    // call afterSend below outside of conLock
                    fail = true;
                }
            }
        }
        if (fail) {
            // race, RI changed out from under us, maybe SSU can handle it
            if (_log.shouldLog(Log.WARN))
                _log.warn("we bid on a peer who doesn't have an ntcp address? " + target);
            afterSend(msg, false);
            return;
        }
        if (isNew) {
            // doesn't do anything yet, just enqueues it
            con.send(msg);
            // As of 0.9.12, don't send our info if the first message is
            // doing the same (common when connecting to a floodfill).
            // Also, put the info message after whatever we are trying to send
            // (it's a priority queue anyway and the info is low priority)
            // Prior to 0.9.12, Bob would not send his RI unless he had ours,
            // but that's fixed in 0.9.12.
            boolean shouldSkipInfo = false;
            I2NPMessage m = msg.getMessage();
            if (m.getType() == DatabaseStoreMessage.MESSAGE_TYPE) {
                DatabaseStoreMessage dsm = (DatabaseStoreMessage) m;
                if (dsm.getKey().equals(_context.routerHash())) {
                    shouldSkipInfo = true;
                }
            }
            if (!shouldSkipInfo) {
                con.enqueueInfoMessage();
            } else if (_log.shouldLog(Log.INFO)) {
                _log.info("SKIPPING INFO message: " + con);
            }
            try {
                SocketChannel channel = SocketChannel.open();
                con.setChannel(channel);
                channel.configureBlocking(false);
                _pumper.registerConnect(con);
                con.getEstablishState().prepareOutbound();
            } catch (IOException ioe) {
                if (_log.shouldLog(Log.ERROR))
                    _log.error("Error opening a channel", ioe);
                _context.statManager().addRateData("ntcp.outboundFailedIOEImmediate", 1);
                con.close();
            }
        } else {
            con.send(msg);
        }
    /*
            NTCPConnection con = getCon(ident);
            remove the race here
            if (con != null) {
                //if (_log.shouldLog(Log.DEBUG))
                //    _log.debug("Send on an existing con: " + con);
                con.send(msg);
            } else {
                RouterAddress addr = msg.getTarget().getTargetAddress(STYLE);
                if (addr != null) {
                    NTCPAddress naddr = new NTCPAddress(addr);
                    con = new NTCPConnection(_context, this, ident, naddr);
                    Hash ih = ident.calculateHash();
                    if (_log.shouldLog(Log.DEBUG))
                        _log.debug("Send on a new con: " + con + " at " + addr + " for " + ih.toBase64());
                    NTCPConnection old = null;
                    synchronized (_conLock) {
                        old = (NTCPConnection)_conByIdent.put(ih, con);
                    }
                    if (old != null) {
                        if (_log.shouldLog(Log.WARN))
                            _log.warn("Multiple connections on out ready, closing " + old + " and keeping " + con);
                        old.close();
                    }
                    con.enqueueInfoMessage(); // enqueues a netDb store of our own info
                    con.send(msg); // doesn't do anything yet, just enqueues it

                    try {
                        SocketChannel channel = SocketChannel.open();
                        con.setChannel(channel);
                        channel.configureBlocking(false);
                        _pumper.registerConnect(con);
                    } catch (IOException ioe) {
                        if (_log.shouldLog(Log.ERROR))
                            _log.error("Error opening a channel", ioe);
                        con.close();
                    }
                } else {
                    con.close();
                }
            }
             */
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) ServerSocketChannel(java.nio.channels.ServerSocketChannel) OutNetMessage(net.i2p.router.OutNetMessage) RouterInfo(net.i2p.data.router.RouterInfo) RouterIdentity(net.i2p.data.router.RouterIdentity) I2NPMessage(net.i2p.data.i2np.I2NPMessage) DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage) RouterAddress(net.i2p.data.router.RouterAddress) IOException(java.io.IOException) Hash(net.i2p.data.Hash)

Example 59 with RouterInfo

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

the class TransportManager method getNextBid.

TransportBid getNextBid(OutNetMessage msg) {
    int unreachableTransports = 0;
    Hash peer = msg.getTarget().getIdentity().calculateHash();
    Set<String> failedTransports = msg.getFailedTransports();
    TransportBid rv = null;
    for (Transport t : _transports.values()) {
        if (t.isUnreachable(peer)) {
            unreachableTransports++;
            // this keeps GetBids() from banlisting for "no common transports"
            // right after we banlisted for "unreachable on any transport" below...
            msg.transportFailed(t.getStyle());
            continue;
        }
        if (failedTransports.contains(t.getStyle())) {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Skipping transport " + t.getStyle() + " as it already failed");
            continue;
        }
        // we always want to try all transports, in case there is a faster bidirectional one
        // already connected (e.g. peer only has a public PHTTP address, but they've connected
        // to us via TCP, send via TCP)
        TransportBid bid = t.bid(msg.getTarget(), msg.getMessageSize());
        if (bid != null) {
            if (bid.getLatencyMs() == TransportBid.TRANSIENT_FAIL)
                // this keeps GetBids() from banlisting for "no common transports"
                msg.transportFailed(t.getStyle());
            else if ((rv == null) || (rv.getLatencyMs() > bid.getLatencyMs()))
                rv = bid;
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Transport " + t.getStyle() + " bid: " + bid + " currently winning? " + (rv == bid) + " (winning latency: " + rv.getLatencyMs() + " / " + rv + ")");
        } else {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Transport " + t.getStyle() + " did not produce a bid");
            if (t.isUnreachable(peer))
                unreachableTransports++;
        }
    }
    if (unreachableTransports >= _transports.size()) {
        if (msg.getTarget().getIdentity().getSigningPublicKey().getType() == null) {
            // we don't support his crypto
            _context.statManager().addRateData("transport.banlistOnUnsupportedSigType", 1);
            _context.banlist().banlistRouterForever(peer, _x("Unsupported signature type"));
        } else if (unreachableTransports >= _transports.size() && countActivePeers() > 0) {
            // Don't banlist if we aren't talking to anybody, as we may have a network connection issue
            boolean incompat = false;
            RouterInfo us = _context.router().getRouterInfo();
            if (us != null) {
                RouterIdentity id = us.getIdentity();
                if (id.getSigType() != SigType.DSA_SHA1) {
                    String v = msg.getTarget().getVersion();
                    // NTCP is earlier than SSU, use that one
                    if (VersionComparator.comp(v, NTCPTransport.MIN_SIGTYPE_VERSION) < 0)
                        incompat = true;
                }
            }
            if (incompat) {
                // they don't support our crypto
                _context.statManager().addRateData("transport.banlistOnUnsupportedSigType", 1);
                _context.banlist().banlistRouter(peer, _x("No support for our signature type"), null, null, _context.clock().now() + SIGTYPE_BANLIST_DURATION);
            } else {
                _context.statManager().addRateData("transport.banlistOnUnreachable", msg.getLifetime(), msg.getLifetime());
                _context.banlist().banlistRouter(peer, _x("Unreachable on any transport"));
            }
        }
    } else if (rv == null) {
        _context.statManager().addRateData("transport.noBidsYetNotAllUnreachable", unreachableTransports, msg.getLifetime());
    }
    return rv;
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) RouterIdentity(net.i2p.data.router.RouterIdentity) Hash(net.i2p.data.Hash) NTCPTransport(net.i2p.router.transport.ntcp.NTCPTransport) UDPTransport(net.i2p.router.transport.udp.UDPTransport)

Example 60 with RouterInfo

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

the class SearchJob method continueSearch.

/**
 * Send a series of searches to the next available peers as selected by
 * the routing table, but making sure no more than SEARCH_BREDTH are outstanding
 * at any time
 */
protected void continueSearch() {
    if (_state.completed()) {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug(getJobId() + ": Search already completed", new Exception("already completed"));
        return;
    }
    int toCheck = getBredth() - _state.getPending().size();
    if (toCheck <= 0) {
        // too many already pending
        if (_log.shouldLog(Log.INFO))
            _log.info(getJobId() + ": Too many searches already pending (pending: " + _state.getPending().size() + " max: " + getBredth() + ")");
        requeuePending();
        return;
    }
    int sent = 0;
    Set<Hash> attempted = _state.getAttempted();
    while (sent <= 0) {
        // boolean onlyFloodfill = onlyQueryFloodfillPeers(getContext());
        boolean onlyFloodfill = true;
        if (_floodfillPeersExhausted && onlyFloodfill && _state.getPending().isEmpty()) {
            if (_log.shouldLog(Log.WARN))
                _log.warn(getJobId() + ": no non-floodfill peers left, and no more pending.  Searched: " + _state.getAttempted().size() + " failed: " + _state.getFailed().size());
            fail();
            return;
        }
        List<Hash> closestHashes = getClosestRouters(_state.getTarget(), toCheck, attempted);
        if ((closestHashes == null) || (closestHashes.isEmpty())) {
            if (_state.getPending().isEmpty()) {
                // we tried to find some peers, but there weren't any and no one else is going to answer
                if (_log.shouldLog(Log.INFO))
                    _log.info(getJobId() + ": No peers left, and none pending!  Already searched: " + _state.getAttempted().size() + " failed: " + _state.getFailed().size());
                fail();
            } else {
                // no more to try, but we might get data or close peers from some outstanding requests
                if (_log.shouldLog(Log.INFO))
                    _log.info(getJobId() + ": No peers left, but some are pending!  Pending: " + _state.getPending().size() + " attempted: " + _state.getAttempted().size() + " failed: " + _state.getFailed().size());
                requeuePending();
            }
            return;
        } else {
            attempted.addAll(closestHashes);
            for (Hash peer : closestHashes) {
                DatabaseEntry ds = _facade.getDataStore().get(peer);
                if (ds == null) {
                    if (_log.shouldLog(Log.INFO))
                        _log.info("Next closest peer " + peer + " was only recently referred to us, sending a search for them");
                    getContext().netDb().lookupRouterInfo(peer, null, null, _timeoutMs);
                } else if (!(ds.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO)) {
                    if (_log.shouldLog(Log.WARN))
                        _log.warn(getJobId() + ": Error selecting closest hash that wasnt a router! " + peer + " : " + ds.getClass().getName());
                    _state.replyTimeout(peer);
                } else {
                    RouterInfo ri = (RouterInfo) ds;
                    if (!FloodfillNetworkDatabaseFacade.isFloodfill(ri)) {
                        _floodfillPeersExhausted = true;
                        if (onlyFloodfill)
                            continue;
                    }
                    if (ri.isHidden()) {
                    // || // allow querying banlisted, since its indirect
                    // getContext().banlist().isBanlisted(peer)) {
                    // dont bother
                    } else {
                        _state.addPending(peer);
                        sendSearch((RouterInfo) ds);
                        sent++;
                    }
                }
            }
        /*
                if (sent <= 0) {
                    // the (potentially) last peers being searched for could not be,
                    // er, searched for, so lets retry ASAP (causing either another 
                    // peer to be selected, or the whole search to fail)
                    if (_log.shouldLog(Log.INFO))
                        _log.info(getJobId() + ": No new peer queued up, so we are going to requeue " +
                                  "ourselves in our search for " + _state.getTarget().toBase64());
                    requeuePending(0);
                }
                 */
        }
    }
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) DatabaseEntry(net.i2p.data.DatabaseEntry) Hash(net.i2p.data.Hash)

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