Search in sources :

Example 31 with RouterAddress

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

the class Blocklist method getAddresses.

/**
 * Will not contain duplicates.
 * @since 0.9.29
 */
private static List<byte[]> getAddresses(RouterInfo pinfo) {
    List<byte[]> rv = new ArrayList<byte[]>(4);
    // for each peer address
    for (RouterAddress pa : pinfo.getAddresses()) {
        byte[] pib = pa.getIP();
        if (pib == null)
            continue;
        // O(n**2)
        boolean dup = false;
        for (int i = 0; i < rv.size(); i++) {
            if (DataHelper.eq(rv.get(i), pib)) {
                dup = true;
                break;
            }
        }
        if (!dup)
            rv.add(pib);
    }
    return rv;
}
Also used : ArrayList(java.util.ArrayList) RouterAddress(net.i2p.data.router.RouterAddress)

Example 32 with RouterAddress

use of net.i2p.data.router.RouterAddress 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 33 with RouterAddress

use of net.i2p.data.router.RouterAddress 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 34 with RouterAddress

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

the class NTCPTransport method getTargetAddress.

/**
 *  Get first available address we can use.
 *  @return address or null
 *  @since 0.9.6
 */
private RouterAddress getTargetAddress(RouterInfo target) {
    List<RouterAddress> addrs = getTargetAddresses(target);
    for (int i = 0; i < addrs.size(); i++) {
        RouterAddress addr = addrs.get(i);
        byte[] ip = addr.getIP();
        if (!TransportUtil.isValidPort(addr.getPort()) || ip == null) {
            // _log.debug("no bid when trying to send to " + peer + " as they don't have a valid ntcp address");
            continue;
        }
        if (!isValid(ip)) {
            if (!allowLocal()) {
                // _log.debug("no bid when trying to send to " + peer + " as they have a private ntcp address");
                continue;
            }
        }
        return addr;
    }
    return null;
}
Also used : RouterAddress(net.i2p.data.router.RouterAddress)

Example 35 with RouterAddress

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

the class NTCPTransport method externalAddressReceived.

/**
 *  UDP changed addresses, tell NTCP and restart.
 *  Port may be set to indicate requested port even if ip is null.
 *
 *  @param ip previously validated; may be null to indicate IPv4 failure or port info only
 *  @since IPv6 moved from CSFI.notifyReplaceAddress()
 */
private synchronized void externalAddressReceived(byte[] ip, boolean isIPv6, int port) {
    // FIXME just take first address for now
    // FIXME if SSU set to hostname, NTCP will be set to IP
    RouterAddress oldAddr = getCurrentAddress(isIPv6);
    if (_log.shouldLog(Log.INFO))
        _log.info("Changing NTCP Address? was " + oldAddr);
    OrderedProperties newProps = new OrderedProperties();
    int cost;
    if (oldAddr == null) {
        cost = getDefaultCost(isIPv6);
    } else {
        cost = oldAddr.getCost();
        newProps.putAll(oldAddr.getOptionsMap());
    }
    RouterAddress newAddr = new RouterAddress(STYLE, newProps, cost);
    boolean changed = false;
    // Auto Port Setting
    // old behavior (<= 0.7.3): auto-port defaults to false, and true trumps explicit setting
    // new behavior (>= 0.7.4): auto-port defaults to true, but explicit setting trumps auto
    // TODO rewrite this to operate on ints instead of strings
    String oport = newProps.getProperty(RouterAddress.PROP_PORT);
    String nport = null;
    String cport = _context.getProperty(PROP_I2NP_NTCP_PORT);
    if (cport != null && cport.length() > 0) {
        nport = cport;
    } else if (_context.getBooleanPropertyDefaultTrue(PROP_I2NP_NTCP_AUTO_PORT)) {
        // it probably isn't mapping UDP and TCP the same.
        if (port > 0)
            // should always be true
            nport = Integer.toString(port);
    }
    if (_log.shouldLog(Log.INFO))
        _log.info("old port: " + oport + " config: " + cport + " new: " + nport);
    // if (oport == null || ! oport.equals(nport)) {
    if (oport == null && nport != null && nport.length() > 0) {
        newProps.setProperty(RouterAddress.PROP_PORT, nport);
        changed = true;
    }
    // Auto IP Setting
    // old behavior (<= 0.7.3): auto-ip defaults to false, and trumps configured hostname,
    // and ignores reachability status - leading to
    // "firewalled with inbound TCP enabled" warnings.
    // new behavior (>= 0.7.4): auto-ip defaults to true, and explicit setting trumps auto,
    // and only takes effect if reachability is OK.
    // And new "always" setting ignores reachability status, like
    // "true" was in 0.7.3
    String ohost = newProps.getProperty(RouterAddress.PROP_HOST);
    String enabled = _context.getProperty(PROP_I2NP_NTCP_AUTO_IP, "true").toLowerCase(Locale.US);
    String name = getConfiguredIP();
    // hostname config trumps auto config
    if (name != null && name.length() > 0)
        enabled = "false";
    // assume SSU is happy if the address is non-null
    // TODO is this sufficient?
    boolean ssuOK = ip != null;
    if (_log.shouldLog(Log.INFO))
        _log.info("old: " + ohost + " config: " + name + " auto: " + enabled + " ssuOK? " + ssuOK);
    if (enabled.equals("always") || (Boolean.parseBoolean(enabled) && ssuOK)) {
        if (!ssuOK) {
            if (_log.shouldLog(Log.WARN))
                _log.warn("null address with always config", new Exception());
            return;
        }
        // ip non-null
        String nhost = Addresses.toString(ip);
        if (_log.shouldLog(Log.INFO))
            _log.info("old: " + ohost + " config: " + name + " new: " + nhost);
        if (nhost == null || nhost.length() <= 0)
            return;
        if (ohost == null || !ohost.equalsIgnoreCase(nhost)) {
            newProps.setProperty(RouterAddress.PROP_HOST, nhost);
            changed = true;
        }
    } else if (enabled.equals("false") && name != null && name.length() > 0 && !name.equals(ohost)) {
        // otherwise createNTCPAddress() would have done it already
        if (_log.shouldLog(Log.INFO))
            _log.info("old host: " + ohost + " config: " + name + " new: " + name);
        newProps.setProperty(RouterAddress.PROP_HOST, name);
        changed = true;
    } else if (ohost == null || ohost.length() <= 0) {
        return;
    } else if (Boolean.parseBoolean(enabled) && !ssuOK) {
        // we are still firewalled (SW firewall, bad UPnP indication, etc.)
        if (_log.shouldLog(Log.INFO))
            _log.info("old host: " + ohost + " config: " + name + " new: null");
        newAddr = null;
        changed = true;
    }
    if (!changed) {
        if (oldAddr != null) {
            // change cost only?
            int oldCost = oldAddr.getCost();
            int newCost = getDefaultCost(ohost != null && ohost.contains(":"));
            if (ADJUST_COST && !haveCapacity())
                newCost += CONGESTION_COST_ADJUSTMENT;
            if (newCost != oldCost) {
                newAddr.setCost(newCost);
                if (_log.shouldLog(Log.WARN))
                    _log.warn("Changing NTCP cost from " + oldCost + " to " + newCost);
            // fall thru and republish
            } else {
                _log.info("No change to NTCP Address");
                return;
            }
        } else {
            _log.info("No change to NTCP Address");
            return;
        }
    }
    // stopListening stops the pumper, readers, and writers, so required even if
    // oldAddr == null since startListening starts them all again
    // 
    // really need to fix this so that we can change or create an inbound address
    // without tearing down everything
    // Especially on disabling the address, we shouldn't tear everything down.
    // 
    // if (_log.shouldLog(Log.WARN))
    // _log.warn("Halting NTCP to change address");
    // stopListening();
    // Wait for NTCP Pumper to stop so we don't end up with two...
    // while (isAlive()) {
    // try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
    // }
    restartListening(newAddr, isIPv6);
    if (_log.shouldLog(Log.WARN))
        _log.warn("Updating NTCP Address (ipv6? " + isIPv6 + ") with " + newAddr);
    return;
}
Also used : RouterAddress(net.i2p.data.router.RouterAddress) OrderedProperties(net.i2p.util.OrderedProperties) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException)

Aggregations

RouterAddress (net.i2p.data.router.RouterAddress)42 RouterInfo (net.i2p.data.router.RouterInfo)17 Hash (net.i2p.data.Hash)11 IOException (java.io.IOException)9 ArrayList (java.util.ArrayList)9 OrderedProperties (net.i2p.util.OrderedProperties)6 InetAddress (java.net.InetAddress)5 Map (java.util.Map)5 RouterIdentity (net.i2p.data.router.RouterIdentity)5 UnknownHostException (java.net.UnknownHostException)4 HashMap (java.util.HashMap)4 DataFormatException (net.i2p.data.DataFormatException)4 ServerSocketChannel (java.nio.channels.ServerSocketChannel)3 Date (java.util.Date)3 Status (net.i2p.router.CommSystemFacade.Status)3 OutNetMessage (net.i2p.router.OutNetMessage)3 File (java.io.File)2 InetSocketAddress (java.net.InetSocketAddress)2 Properties (java.util.Properties)2 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)2