Search in sources :

Example 6 with Hash

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

the class SybilRenderer method addVersionPoints.

private void addVersionPoints(List<RouterInfo> ris, Map<Hash, Points> points) {
    RouterInfo us = _context.router().getRouterInfo();
    if (us == null)
        return;
    String ourVer = us.getVersion();
    if (!ourVer.startsWith("0.9."))
        return;
    ourVer = ourVer.substring(4);
    int dot = ourVer.indexOf('.');
    if (dot > 0)
        ourVer = ourVer.substring(0, dot);
    int minor;
    try {
        minor = Integer.parseInt(ourVer);
    } catch (NumberFormatException nfe) {
        return;
    }
    for (RouterInfo info : ris) {
        Hash h = info.getHash();
        String caps = info.getCapabilities();
        if (!caps.contains("R"))
            addPoints(points, h, POINTS_UNREACHABLE, "Unreachable: " + DataHelper.escapeHTML(caps));
        String hisFullVer = info.getVersion();
        if (!hisFullVer.startsWith("0.9.")) {
            addPoints(points, h, POINTS_BAD_VERSION, "Strange version " + DataHelper.escapeHTML(hisFullVer));
            continue;
        }
        String hisVer = hisFullVer.substring(4);
        dot = hisVer.indexOf('.');
        if (dot > 0)
            hisVer = hisVer.substring(0, dot);
        int hisMinor;
        try {
            hisMinor = Integer.parseInt(hisVer);
        } catch (NumberFormatException nfe) {
            continue;
        }
        int howOld = minor - hisMinor;
        if (howOld < 3)
            continue;
        addPoints(points, h, howOld * VERSION_FACTOR, howOld + " versions behind: " + DataHelper.escapeHTML(hisFullVer));
    }
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) Hash(net.i2p.data.Hash) ConvertToHash(net.i2p.util.ConvertToHash)

Example 7 with Hash

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

the class SybilRenderer method renderRouterInfoHTML.

/**
 *  The whole thing
 *
 *  @param routerPrefix ignored
 */
private void renderRouterInfoHTML(Writer out, String routerPrefix) throws IOException {
    Set<Hash> ffs = _context.peerManager().getPeersByCapability('f');
    List<RouterInfo> ris = new ArrayList<RouterInfo>(ffs.size());
    Hash us = _context.routerHash();
    Hash ourRKey = _context.router().getRouterInfo().getRoutingKey();
    for (Hash ff : ffs) {
        if (ff.equals(us))
            continue;
        RouterInfo ri = _context.netDb().lookupRouterInfoLocally(ff);
        if (ri != null)
            ris.add(ri);
    }
    if (ris.isEmpty()) {
        out.write("<h3 class=\"sybils\">No known floodfills</h3>");
        return;
    }
    StringBuilder buf = new StringBuilder(4 * 1024);
    buf.append("<p id=\"sybilinfo\"><b>This is an experimental network database tool for debugging and analysis. Do not panic even if you see warnings below. " + "Possible \"threats\" are summarized at the bottom, however these are unlikely to be real threats. " + "If you see anything you would like to discuss with the devs, contact us on IRC #i2p-dev.</b></p>" + "<div id=\"sybilnav\"><ul><li><a href=\"#known\">FF Summary</a>" + "</li><li><a href=\"#family\">Same Family</a>" + "</li><li><a href=\"#ourIP\">IP close to us</a>" + "</li><li><a href=\"#sameIP\">Same IP</a>" + "</li><li><a href=\"#same24\">Same /24</a>" + "</li><li><a href=\"#same16\">Same /16</a>" + "</li><li><a href=\"#pairs\">Pair distance</a>" + "</li><li><a href=\"#ritoday\">Close to us</a>" + "</li><li><a href=\"#ritmrw\">Close to us tomorrow</a>" + "</li><li><a href=\"#dht\">DHT neighbors</a>" + "</li><li><a href=\"#dest\">Close to our destinations</a>" + "</li><li><a href=\"#threats\">Highest threats</a>" + "</li></ul></div>");
    renderRouterInfo(buf, _context.router().getRouterInfo(), null, true, false);
    buf.append("<h3 id=\"known\" class=\"sybils\">Known Floodfills: ").append(ris.size()).append("</h3>");
    double tot = 0;
    int count = 200;
    byte[] b = new byte[32];
    for (int i = 0; i < count; i++) {
        _context.random().nextBytes(b);
        Hash h = new Hash(b);
        double d = closestDistance(h, ris);
        tot += d;
    }
    double avgMinDist = tot / count;
    buf.append("<div id=\"sybils_summary\">\n");
    buf.append("<b>Average closest floodfill distance:</b> ").append(fmt.format(avgMinDist)).append("<br>\n");
    buf.append("<b>Routing Data:</b> \"").append(DataHelper.getUTF8(_context.routerKeyGenerator().getModData())).append("\" <b>Last Changed:</b> ").append(new Date(_context.routerKeyGenerator().getLastChanged())).append("<br>\n");
    buf.append("<b>Next Routing Data:</b> \"").append(DataHelper.getUTF8(_context.routerKeyGenerator().getNextModData())).append("\" <b>Rotates in:</b> ").append(DataHelper.formatDuration(_context.routerKeyGenerator().getTimeTillMidnight())).append("\n");
    buf.append("</div>\n");
    Map<Hash, Points> points = new HashMap<Hash, Points>(64);
    // IP analysis
    renderIPGroupsFamily(out, buf, ris, points);
    renderIPGroupsUs(out, buf, ris, points);
    renderIPGroups32(out, buf, ris, points);
    renderIPGroups24(out, buf, ris, points);
    renderIPGroups16(out, buf, ris, points);
    // Pairwise distance analysis
    renderPairDistance(out, buf, ris, points);
    // Distance to our router analysis
    buf.append("<h3 id=\"ritoday\" class=\"sybils\">Closest Floodfills to Our Routing Key (Where we Store our RI)</h3>");
    buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&amp;sybil\">See all</a></p>");
    renderRouterInfoHTML(out, buf, ourRKey, avgMinDist, ris, points);
    RouterKeyGenerator rkgen = _context.routerKeyGenerator();
    Hash nkey = rkgen.getNextRoutingKey(us);
    buf.append("<h3 id=\"ritmrw\" class=\"sybils\">Closest Floodfills to Tomorrow's Routing Key (Where we will Store our RI)</h3>");
    buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&amp;sybil\">See all</a></p>");
    renderRouterInfoHTML(out, buf, nkey, avgMinDist, ris, points);
    buf.append("<h3 id=\"dht\" class=\"sybils\">Closest Floodfills to Our Router Hash (DHT Neighbors if we are Floodfill)</h3>");
    renderRouterInfoHTML(out, buf, us, avgMinDist, ris, points);
    // Distance to our published destinations analysis
    buf.append("<h3 id=\"dest\" class=\"sybils\">Floodfills Close to Our Destinations</h3>");
    Map<Hash, TunnelPool> clientInboundPools = _context.tunnelManager().getInboundClientPools();
    List<Hash> destinations = new ArrayList<Hash>(clientInboundPools.keySet());
    // boolean debug = _context.getBooleanProperty(HelperBase.PROP_ADVANCED);
    for (Hash client : destinations) {
        boolean isLocal = _context.clientManager().isLocal(client);
        if (!isLocal)
            continue;
        if (!_context.clientManager().shouldPublishLeaseSet(client))
            continue;
        LeaseSet ls = _context.netDb().lookupLeaseSetLocally(client);
        if (ls == null)
            continue;
        Hash rkey = ls.getRoutingKey();
        TunnelPool in = clientInboundPools.get(client);
        String name = (in != null) ? in.getSettings().getDestinationNickname() : client.toBase64().substring(0, 4);
        buf.append("<h3 class=\"sybils\">Closest floodfills to the Routing Key for " + DataHelper.escapeHTML(name) + " (where we store our LS)</h3>");
        buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&amp;sybil=" + ls.getHash().toBase64() + "\">See all</a></p>");
        renderRouterInfoHTML(out, buf, rkey, avgMinDist, ris, points);
        nkey = rkgen.getNextRoutingKey(ls.getHash());
        buf.append("<h3 class=\"sybils\">Closest floodfills to Tomorrow's Routing Key for " + DataHelper.escapeHTML(name) + " (where we will store our LS)</h3>");
        buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&amp;sybil=" + ls.getHash().toBase64() + "\">See all</a></p>");
        renderRouterInfoHTML(out, buf, nkey, avgMinDist, ris, points);
    }
    // Profile analysis
    addProfilePoints(ris, points);
    addVersionPoints(ris, points);
    if (!points.isEmpty()) {
        List<Hash> warns = new ArrayList<Hash>(points.keySet());
        Collections.sort(warns, new PointsComparator(points));
        buf.append("<h3 id=\"threats\" class=\"sybils\">Routers with Most Threat Points</h3>");
        for (Hash h : warns) {
            RouterInfo ri = _context.netDb().lookupRouterInfoLocally(h);
            if (ri == null)
                continue;
            Points pp = points.get(h);
            double p = pp.points;
            if (p < MIN_DISPLAY_POINTS)
                // sorted
                break;
            buf.append("<p class=\"threatpoints\"><b>Threat Points: " + fmt.format(p) + "</b></p><ul>");
            for (String s : pp.reasons) {
                buf.append("<li>").append(s).append("</li>");
            }
            buf.append("</ul>");
            renderRouterInfo(buf, ri, null, false, false);
        }
    }
    out.write(buf.toString());
    out.flush();
    buf.setLength(0);
}
Also used : TunnelPool(net.i2p.router.tunnel.pool.TunnelPool) HashMap(java.util.HashMap) RouterInfo(net.i2p.data.router.RouterInfo) RouterKeyGenerator(net.i2p.data.router.RouterKeyGenerator) ArrayList(java.util.ArrayList) Hash(net.i2p.data.Hash) ConvertToHash(net.i2p.util.ConvertToHash) Date(java.util.Date) LeaseSet(net.i2p.data.LeaseSet)

Example 8 with Hash

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

the class ConnectionManager method receiveConnection.

/**
 * Create a new connection based on the SYN packet we received.
 *
 * @param synPacket SYN packet to process
 * @return created Connection with the packet's data already delivered to
 *         it, or null if the syn's streamId was already taken
 */
public Connection receiveConnection(Packet synPacket) {
    ConnectionOptions opts = new ConnectionOptions(_defaultOptions);
    opts.setPort(synPacket.getRemotePort());
    opts.setLocalPort(synPacket.getLocalPort());
    boolean reject = false;
    int active = 0;
    int total = 0;
    // }
    if (locked_tooManyStreams()) {
        if ((!_defaultOptions.getDisableRejectLogging()) || _log.shouldLog(Log.WARN))
            _log.logAlways(Log.WARN, "Refusing connection since we have exceeded our max of " + _defaultOptions.getMaxConns() + " connections");
        reject = true;
    } else {
        // this may not be right if more than one is enabled
        String why = shouldRejectConnection(synPacket);
        if (why != null) {
            if ((!_defaultOptions.getDisableRejectLogging()) || _log.shouldLog(Log.WARN))
                _log.logAlways(Log.WARN, "Refusing connection since peer is " + why + (synPacket.getOptionalFrom() == null ? "" : ": " + synPacket.getOptionalFrom().toBase32()));
            reject = true;
        }
    }
    _context.statManager().addRateData("stream.receiveActive", active, total);
    if (reject) {
        Destination from = synPacket.getOptionalFrom();
        if (from == null)
            return null;
        String resp = _defaultOptions.getLimitAction();
        if ("drop".equals(resp)) {
            // always drop
            return null;
        }
        Hash h = from.calculateHash();
        if (_globalBlacklist.contains(h) || (_defaultOptions.isAccessListEnabled() && !_defaultOptions.getAccessList().contains(h)) || (_defaultOptions.isBlacklistEnabled() && _defaultOptions.getBlacklist().contains(h))) {
            // always drop these regardless of setting
            return null;
        }
        if ((_minuteThrottler != null && _minuteThrottler.isOverBy(h, DROP_OVER_LIMIT)) || (_hourThrottler != null && _hourThrottler.isOverBy(h, DROP_OVER_LIMIT)) || (_dayThrottler != null && _dayThrottler.isOverBy(h, DROP_OVER_LIMIT))) {
            // thus more inbound, but let's not spend several KB on the outbound.
            if (_log.shouldLog(Log.INFO))
                _log.info("Dropping limit response to " + from.toBase32());
            return null;
        }
        boolean reset = resp == null || resp.equals("reset") || resp.length() <= 0;
        boolean http = !reset && "http".equals(resp);
        boolean custom = !(reset || http);
        String sendResponse;
        if (http) {
            sendResponse = LIMIT_HTTP_RESPONSE;
        } else if (custom) {
            sendResponse = resp.replace("\\r", "\r").replace("\\n", "\n");
        } else {
            sendResponse = null;
        }
        PacketLocal reply = new PacketLocal(_context, from, synPacket.getSession());
        if (sendResponse != null) {
            reply.setFlag(Packet.FLAG_SYNCHRONIZE | Packet.FLAG_CLOSE | Packet.FLAG_SIGNATURE_INCLUDED);
            reply.setSequenceNum(0);
            ByteArray payload = new ByteArray(DataHelper.getUTF8(sendResponse));
            reply.setPayload(payload);
        } else {
            reply.setFlag(Packet.FLAG_RESET | Packet.FLAG_SIGNATURE_INCLUDED);
        }
        reply.setAckThrough(synPacket.getSequenceNum());
        reply.setSendStreamId(synPacket.getReceiveStreamId());
        long rcvStreamId = assignRejectId();
        reply.setReceiveStreamId(rcvStreamId);
        reply.setOptionalFrom();
        reply.setLocalPort(synPacket.getLocalPort());
        reply.setRemotePort(synPacket.getRemotePort());
        if (_log.shouldInfo())
            // _log.info("Over limit, sending " + (sendResponse != null ? "configured response" : "reset") + " to " + from.toBase32());
            _log.info("Over limit, sending " + reply + " to " + from.toBase32());
        // this just sends the packet - no retries or whatnot
        _outboundQueue.enqueue(reply);
        return null;
    }
    Connection con = new Connection(_context, this, synPacket.getSession(), _schedulerChooser, _timer, _outboundQueue, _conPacketHandler, opts, true);
    _tcbShare.updateOptsFromShare(con);
    assignReceiveStreamId(con);
    // finally, we know enough that we can log the packet with the conn filled in
    if (I2PSocketManagerFull.pcapWriter != null && _context.getBooleanProperty(I2PSocketManagerFull.PROP_PCAP))
        synPacket.logTCPDump(con);
    try {
        // This validates the packet, and sets the con's SendStreamID and RemotePeer
        con.getPacketHandler().receivePacket(synPacket, con);
    } catch (I2PException ie) {
        _connectionByInboundId.remove(Long.valueOf(con.getReceiveStreamId()));
        return null;
    }
    _context.statManager().addRateData("stream.connectionReceived", 1);
    return con;
}
Also used : I2PException(net.i2p.I2PException) Destination(net.i2p.data.Destination) ByteArray(net.i2p.data.ByteArray) Hash(net.i2p.data.Hash) ConvertToHash(net.i2p.util.ConvertToHash)

Example 9 with Hash

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

the class ConnectionOptions method initLists.

private void initLists(Properties opts) {
    boolean accessListEnabled = getBool(opts, PROP_ENABLE_ACCESS_LIST, false);
    boolean blackListEnabled = getBool(opts, PROP_ENABLE_BLACKLIST, false);
    // Don't think these would ever be accessed simultaneously,
    // but avoid concurrent modification just in case
    Set<Hash> accessList, blackList;
    if (accessListEnabled)
        accessList = new HashSet<Hash>();
    else
        accessList = Collections.emptySet();
    if (blackListEnabled)
        blackList = new HashSet<Hash>();
    else
        blackList = Collections.emptySet();
    if (accessListEnabled || blackListEnabled) {
        String hashes = opts.getProperty(PROP_ACCESS_LIST);
        if (hashes == null)
            return;
        StringTokenizer tok = new StringTokenizer(hashes, ",; ");
        while (tok.hasMoreTokens()) {
            String hashstr = tok.nextToken();
            Hash h = ConvertToHash.getHash(hashstr);
            if (h == null)
                error("bad list hash: " + hashstr);
            else if (blackListEnabled)
                blackList.add(h);
            else
                accessList.add(h);
        }
    }
    _accessList = accessList;
    _blackList = blackList;
    _accessListEnabled = accessListEnabled;
    _blackListEnabled = blackListEnabled;
    if (_accessListEnabled && _accessList.isEmpty())
        error("Connection access list enabled but no valid entries; no peers can connect");
    else if (_blackListEnabled && _blackList.isEmpty())
        error("Connection blacklist enabled but no valid entries; all peers can connect");
}
Also used : StringTokenizer(java.util.StringTokenizer) Hash(net.i2p.data.Hash) ConvertToHash(net.i2p.util.ConvertToHash) HashSet(java.util.HashSet)

Example 10 with Hash

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

the class TunnelRenderer method renderPool.

private void renderPool(Writer out, TunnelPool in, TunnelPool outPool) throws IOException {
    List<TunnelInfo> tunnels = null;
    if (in == null)
        tunnels = new ArrayList<TunnelInfo>();
    else
        tunnels = in.listTunnels();
    if (outPool != null)
        tunnels.addAll(outPool.listTunnels());
    long processedIn = (in != null ? in.getLifetimeProcessed() : 0);
    long processedOut = (outPool != null ? outPool.getLifetimeProcessed() : 0);
    int live = 0;
    int maxLength = 1;
    for (int i = 0; i < tunnels.size(); i++) {
        TunnelInfo info = tunnels.get(i);
        int length = info.getLength();
        if (length > maxLength)
            maxLength = length;
    }
    out.write("<table class=\"tunneldisplay tunnels_client\"><tr><th title=\"" + _t("Inbound or outbound?") + ("\">") + _t("In/Out") + "</th><th>" + _t("Expiry") + "</th><th>" + _t("Usage") + "</th><th>" + _t("Gateway") + "</th>");
    if (maxLength > 3) {
        out.write("<th align=\"center\" colspan=\"" + (maxLength - 2));
        out.write("\">" + _t("Participants") + "</th>");
    } else if (maxLength == 3) {
        out.write("<th>" + _t("Participant") + "</th>");
    }
    if (maxLength > 1) {
        out.write("<th>" + _t("Endpoint") + "</th>");
    }
    out.write("</tr>\n");
    for (int i = 0; i < tunnels.size(); i++) {
        TunnelInfo info = tunnels.get(i);
        long timeLeft = info.getExpiration() - _context.clock().now();
        if (timeLeft <= 0)
            // don't display tunnels in their grace period
            continue;
        live++;
        boolean isInbound = info.isInbound();
        if (isInbound)
            out.write("<tr><td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/inbound.png\" alt=\"Inbound\" title=\"" + _t("Inbound") + "\"></td>");
        else
            out.write("<tr><td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/outbound.png\" alt=\"Outbound\" title=\"" + _t("Outbound") + "\"></td>");
        out.write("<td class=\"cells\" align=\"center\">" + DataHelper.formatDuration2(timeLeft) + "</td>\n");
        int count = info.getProcessedMessagesCount() * 1024 / 1000;
        out.write("<td class=\"cells\" align=\"center\">" + count + " KB</td>\n");
        int length = info.getLength();
        for (int j = 0; j < length; j++) {
            Hash peer = info.getPeer(j);
            TunnelId id = (isInbound ? info.getReceiveTunnelId(j) : info.getSendTunnelId(j));
            if (_context.routerHash().equals(peer)) {
                if (length < maxLength && length == 1 && isInbound) {
                    // pad before inbound zero hop
                    for (int k = 1; k < maxLength; k++) {
                        out.write("<td class=\"cells\" align=\"center\">&nbsp;</td>");
                    }
                }
                // Add empty content placeholders to force alignment.
                out.write(" <td class=\"cells\" align=\"center\"><span class=\"tunnel_peer tunnel_local\" title=\"" + _t("Locally hosted tunnel") + "\">" + _t("Local") + "</span>&nbsp;<span class=\"tunnel_id\" title=\"" + _t("Tunnel identity") + "\">" + (id == null ? "" : "" + id) + "</span><b class=\"tunnel_cap\" title=\"" + _t("Bandwidth tier") + "\"></b></td>");
            } else {
                String cap = getCapacity(peer);
                out.write(" <td class=\"cells\" align=\"center\"><span class=\"tunnel_peer\">" + netDbLink(peer) + "</span>&nbsp;<span class=\"nowrap\"><span class=\"tunnel_id\" title=\"" + _t("Tunnel identity") + "\">" + (id == null ? "" : " " + id) + "</span><b class=\"tunnel_cap\" title=\"" + _t("Bandwidth tier") + "\">" + cap + "</b></span></td>");
            }
            if (length < maxLength && ((length == 1 && !isInbound) || j == length - 2)) {
                // pad out outbound zero hop; non-zero-hop pads in middle
                for (int k = length; k < maxLength; k++) {
                    out.write("<td class=\"cells\" align=\"center\">&nbsp;</td>");
                }
            }
        }
        out.write("</tr>\n");
        if (info.isInbound())
            processedIn += count;
        else
            processedOut += count;
    }
    out.write("</table>\n");
    if (in != null) {
        // PooledTunnelCreatorConfig
        List<?> pending = in.listPending();
        if (!pending.isEmpty()) {
            out.write("<div class=\"statusnotes\"><center><b>" + _t("Build in progress") + ":&nbsp;&nbsp;" + pending.size() + " " + _t("inbound") + "</b></center></div>\n");
            live += pending.size();
        }
    }
    if (outPool != null) {
        // PooledTunnelCreatorConfig
        List<?> pending = outPool.listPending();
        if (!pending.isEmpty()) {
            out.write("<div class=\"statusnotes\"><center><b>" + _t("Build in progress") + ":&nbsp;&nbsp;" + pending.size() + " " + _t("outbound") + "</b></center></div>\n");
            live += pending.size();
        }
    }
    if (live <= 0)
        out.write("<div class=\"statusnotes\"><center><b>" + _t("No tunnels; waiting for the grace period to end.") + "</b></center></div>\n");
    out.write("<div class=\"statusnotes\"><center><b>" + _t("Lifetime bandwidth usage") + ":&nbsp;&nbsp;" + DataHelper.formatSize2Decimal(processedIn * 1024) + "B " + _t("in") + ", " + DataHelper.formatSize2Decimal(processedOut * 1024) + "B " + _t("out") + "</b></center></div>");
}
Also used : ArrayList(java.util.ArrayList) TunnelInfo(net.i2p.router.TunnelInfo) Hash(net.i2p.data.Hash) TunnelId(net.i2p.data.TunnelId)

Aggregations

Hash (net.i2p.data.Hash)235 RouterInfo (net.i2p.data.router.RouterInfo)45 ArrayList (java.util.ArrayList)29 TunnelId (net.i2p.data.TunnelId)20 Destination (net.i2p.data.Destination)18 HashSet (java.util.HashSet)17 ConvertToHash (net.i2p.util.ConvertToHash)17 IOException (java.io.IOException)16 TunnelInfo (net.i2p.router.TunnelInfo)15 DataFormatException (net.i2p.data.DataFormatException)14 Properties (java.util.Properties)13 Date (java.util.Date)12 DatabaseEntry (net.i2p.data.DatabaseEntry)11 SessionKey (net.i2p.data.SessionKey)11 RouterAddress (net.i2p.data.router.RouterAddress)11 DatabaseStoreMessage (net.i2p.data.i2np.DatabaseStoreMessage)9 I2NPMessage (net.i2p.data.i2np.I2NPMessage)9 Job (net.i2p.router.Job)9 OutNetMessage (net.i2p.router.OutNetMessage)9 TunnelPoolSettings (net.i2p.router.TunnelPoolSettings)8