Search in sources :

Example 1 with LeaseSet

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

the class NetDbRenderer method renderLeaseSetHTML.

/**
 *  @param debug @since 0.7.14 sort by distance from us, display
 *               median distance, and other stuff, useful when floodfill
 */
public void renderLeaseSetHTML(Writer out, boolean debug) throws IOException {
    StringBuilder buf = new StringBuilder(4 * 1024);
    if (debug)
        buf.append("<p id=\"debugmode\">Debug mode - Sorted by hash distance, closest first</p>\n");
    Hash ourRKey;
    Set<LeaseSet> leases;
    DecimalFormat fmt;
    if (debug) {
        ourRKey = _context.routerHash();
        leases = new TreeSet<LeaseSet>(new LeaseSetRoutingKeyComparator(ourRKey));
        fmt = new DecimalFormat("#0.00");
    } else {
        ourRKey = null;
        leases = new TreeSet<LeaseSet>(new LeaseSetComparator());
        fmt = null;
    }
    leases.addAll(_context.netDb().getLeases());
    int medianCount = 0;
    int rapCount = 0;
    BigInteger median = null;
    int c = 0;
    // Summary
    FloodfillNetworkDatabaseFacade netdb = (FloodfillNetworkDatabaseFacade) _context.netDb();
    if (debug) {
        buf.append("<table id=\"leasesetdebug\">\n");
    } else {
        buf.append("<table id=\"leasesetsummary\">\n");
    }
    buf.append("<tr><th colspan=\"3\">Leaseset Summary</th>").append("<th><a href=\"/configadvanced\" title=\"").append(_t("Manually Configure Floodfill Participation")).append("\">[").append(_t("Configure Floodfill Participation")).append("]</a></th></tr>\n").append("<tr><td><b>Total Leasesets:</b></td><td colspan=\"3\">").append(leases.size()).append("</td></tr>\n");
    if (debug) {
        buf.append("<tr><td><b>Published (RAP) Leasesets:</b></td><td colspan=\"3\">").append(netdb.getKnownLeaseSets()).append("</td></tr>\n").append("<tr><td><b>Mod Data:</b></td><td>").append(DataHelper.getUTF8(_context.routerKeyGenerator().getModData())).append("</td>").append("<td><b>Last Changed:</b></td><td>").append(new Date(_context.routerKeyGenerator().getLastChanged())).append("</td></tr>\n").append("<tr><td><b>Next Mod Data:</b></td><td>").append(DataHelper.getUTF8(_context.routerKeyGenerator().getNextModData())).append("</td>").append("<td><b>Change in:</b></td><td>").append(DataHelper.formatDuration(_context.routerKeyGenerator().getTimeTillMidnight())).append("</td></tr>\n");
    }
    int ff = _context.peerManager().getPeersByCapability(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL).size();
    buf.append("<tr><td><b>Known Floodfills:</b></td><td colspan=\"3\">").append(ff).append("</td></tr>\n").append("<tr><td><b>Currently Floodfill?</b></td><td colspan=\"3\">").append(netdb.floodfillEnabled() ? "yes" : "no").append("</td></tr>\n");
    buf.append("</table>\n");
    if (leases.isEmpty()) {
        if (!debug)
            buf.append("<div id=\"noleasesets\"><i>").append(_t("No Leasesets currently active.")).append("</i></div>");
    } else {
        if (debug) {
            // Find the center of the RAP leasesets
            for (LeaseSet ls : leases) {
                if (ls.getReceivedAsPublished())
                    rapCount++;
            }
            medianCount = rapCount / 2;
        }
        boolean linkSusi = WebAppStarter.isWebAppRunning("susidns");
        long now = _context.clock().now();
        buf.append("<div class=\"leasesets_container\">");
        for (LeaseSet ls : leases) {
            Destination dest = ls.getDestination();
            Hash key = dest.calculateHash();
            buf.append("<table class=\"leaseset\">\n").append("<tr><th><b>").append(_t("LeaseSet")).append(":</b>&nbsp;<code>").append(key.toBase64()).append("</code>");
            if (_context.keyRing().get(key) != null)
                buf.append(" (").append(_t("Encrypted")).append(')');
            buf.append("</th>");
            if (_context.clientManager().isLocal(dest)) {
                buf.append("<th><a href=\"tunnels#" + key.toBase64().substring(0, 4) + "\">" + _t("Local") + "</a> ");
                boolean unpublished = !_context.clientManager().shouldPublishLeaseSet(key);
                if (unpublished)
                    buf.append("<b>").append(_t("Unpublished")).append("</b> ");
                buf.append("<b>").append(_t("Destination")).append(":</b> ");
                TunnelPoolSettings in = _context.tunnelManager().getInboundSettings(key);
                if (in != null && in.getDestinationNickname() != null)
                    buf.append(in.getDestinationNickname());
                else
                    buf.append(dest.toBase64().substring(0, 6));
                buf.append("</th></tr>\n<tr><td");
                // If the dest is published but not in the addressbook, an extra
                // <td> is appended with an "Add to addressbook" link, so this
                // <td> should not span 2 columns.
                String host = null;
                if (!unpublished) {
                    host = _context.namingService().reverseLookup(dest);
                }
                if (unpublished || host != null || !linkSusi) {
                    buf.append(" colspan=\"2\"");
                }
                buf.append(">");
                String b32 = dest.toBase32();
                buf.append("<a href=\"http://").append(b32).append("\">").append(b32).append("</a></td>");
                if (linkSusi && !unpublished) {
                    if (host == null) {
                        buf.append("<td class=\"addtobook\" colspan=\"2\">").append("<a title=\"").append(_t("Add to addressbook")).append("\" href=\"/susidns/addressbook.jsp?book=private&amp;destination=").append(dest.toBase64()).append("#add\">").append(_t("Add to local addressbook")).append("</a></td>");
                    }
                }
            // else probably a client
            } else {
                buf.append("<th><b>").append(_t("Destination")).append(":</b> ");
                String host = _context.namingService().reverseLookup(dest);
                if (host != null) {
                    buf.append("<a href=\"http://").append(host).append("/\">").append(host).append("</a></th>");
                } else {
                    String b32 = dest.toBase32();
                    buf.append("<code>").append(dest.toBase64().substring(0, 6)).append("</code></th>").append("</tr>\n<tr><td");
                    if (!linkSusi)
                        buf.append(" colspan=\"2\"");
                    buf.append("><a href=\"http://").append(b32).append("\">").append(b32).append("</a></td>\n");
                    if (linkSusi) {
                        buf.append("<td class=\"addtobook\"><a title=\"").append(_t("Add to addressbook")).append("\" href=\"/susidns/addressbook.jsp?book=private&amp;destination=").append(dest.toBase64()).append("#add\">").append(_t("Add to local addressbook")).append("</a></td>");
                    }
                }
            }
            buf.append("</tr>\n<tr><td colspan=\"2\">\n");
            long exp = ls.getLatestLeaseDate() - now;
            if (exp > 0)
                buf.append("<b>").append(_t("Expires in {0}", DataHelper.formatDuration2(exp))).append("</b>");
            else
                buf.append("<b>").append(_t("Expired {0} ago", DataHelper.formatDuration2(0 - exp))).append("</b>");
            buf.append("</td></tr>\n");
            if (debug) {
                buf.append("<tr><td colspan=\"2\">");
                buf.append("<b>RAP?</b> ").append(ls.getReceivedAsPublished());
                buf.append("&nbsp;&nbsp;<b>RAR?</b> ").append(ls.getReceivedAsReply());
                BigInteger dist = HashDistance.getDistance(ourRKey, ls.getRoutingKey());
                if (ls.getReceivedAsPublished()) {
                    if (c++ == medianCount)
                        median = dist;
                }
                buf.append("&nbsp;&nbsp;<b>Distance: </b>").append(fmt.format(biLog2(dist)));
                buf.append("</td></tr>\n<tr><td colspan=\"2\">");
                // buf.append(dest.toBase32()).append("<br>");
                buf.append("<b>Signature type:</b> ").append(dest.getSigningPublicKey().getType());
                buf.append("&nbsp;&nbsp;<b>Encryption Key:</b> ").append(ls.getEncryptionKey().toBase64().substring(0, 20)).append("&hellip;");
                buf.append("</td></tr>\n<tr><td colspan=\"2\">");
                buf.append("<b>Routing Key:</b> ").append(ls.getRoutingKey().toBase64());
                buf.append("</td></tr>");
            }
            buf.append("<tr><td colspan=\"2\"><ul class=\"netdb_leases\">");
            for (int i = 0; i < ls.getLeaseCount(); i++) {
                Lease lease = ls.getLease(i);
                buf.append("<li><b>").append(_t("Lease")).append(' ').append(i + 1).append(":</b> <span class=\"netdb_gateway\" title=\"").append(_t("Gateway")).append("\"><img src=\"themes/console/images/info/gateway.png\" alt=\"").append(_t("Gateway")).append("\"></span> <span class=\"tunnel_peer\">");
                buf.append(_context.commSystem().renderPeerHTML(lease.getGateway()));
                buf.append("</span> <span class=\"netdb_tunnel\">").append(_t("Tunnel")).append(" <span class=\"tunnel_id\">").append(lease.getTunnelId().getTunnelId()).append("</span></span> ");
                if (debug) {
                    long exl = lease.getEndDate().getTime() - now;
                    if (exl > 0)
                        buf.append("<b class=\"netdb_expiry\">").append(_t("Expires in {0}", DataHelper.formatDuration2(exl))).append("</b>");
                    else
                        buf.append("<b class=\"netdb_expiry\">").append(_t("Expired {0} ago", DataHelper.formatDuration2(0 - exl))).append("</b>");
                }
                buf.append("</li>");
            }
            buf.append("</ul></td></tr>\n");
            buf.append("</table>\n");
            out.write(buf.toString());
            buf.setLength(0);
        }
        // for each
        if (debug) {
            buf.append("<table id=\"leasesetdebug\"><tr><td><b>Network data (only valid if floodfill):</b></td><td colspan=\"3\">");
            // buf.append("</b></p><p><b>Center of Key Space (router hash): " + ourRKey.toBase64());
            if (median != null) {
                double log2 = biLog2(median);
                buf.append("</td></tr>").append("<tr><td><b>Median distance (bits):</b></td><td colspan=\"3\">").append(fmt.format(log2)).append("</td></tr>\n");
                // 2 for 4 floodfills... -1 for median
                // this can be way off for unknown reasons
                int total = (int) Math.round(Math.pow(2, 2 + 256 - 1 - log2));
                buf.append("<tr><td><b>Estimated total floodfills:</b></td><td colspan=\"3\">").append(total).append("</td></tr>\n");
                buf.append("<tr><td><b>Estimated total leasesets:</b></td><td colspan=\"3\">").append(total * rapCount / 4);
            } else {
                buf.append("<i>Not floodfill or no data.</i>");
            }
            buf.append("</td></tr></table>\n");
        }
        // median table
        buf.append("</div>");
    }
    // !empty
    out.write(buf.toString());
    out.flush();
}
Also used : Destination(net.i2p.data.Destination) Lease(net.i2p.data.Lease) DecimalFormat(java.text.DecimalFormat) Hash(net.i2p.data.Hash) Date(java.util.Date) LeaseSet(net.i2p.data.LeaseSet) FloodfillNetworkDatabaseFacade(net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade) BigInteger(java.math.BigInteger) TunnelPoolSettings(net.i2p.router.TunnelPoolSettings)

Example 2 with LeaseSet

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

the class SummaryHelper method getDestinations.

/**
 * Client destinations connected locally.
 *
 * @return html section summary
 */
public String getDestinations() {
    // convert the set to a list so we can sort by name and not lose duplicates
    List<Destination> clients = new ArrayList<Destination>(_context.clientManager().listClients());
    StringBuilder buf = new StringBuilder(512);
    boolean link = WebAppStarter.isWebAppRunning("i2ptunnel");
    buf.append("<h3>");
    if (link) {
        buf.append("<a href=\"/i2ptunnelmgr\" target=\"_top\" title=\"").append(_t("Add/remove/edit &amp; control your client and server tunnels")).append("\">");
    }
    buf.append(_t("Local Tunnels"));
    if (link) {
        buf.append("</a>");
    }
    buf.append("</h3><hr class=\"b\">");
    if (!clients.isEmpty()) {
        Collections.sort(clients, new AlphaComparator());
        buf.append("<table id=\"sb_localtunnels\">");
        for (Destination client : clients) {
            String name = getName(client);
            Hash h = client.calculateHash();
            buf.append("<tr><td align=\"right\"><img src=\"/themes/console/images/");
            if (_context.clientManager().shouldPublishLeaseSet(h))
                buf.append("server.png\" alt=\"Server\" title=\"").append(_t("Hidden Service")).append("\">");
            else
                buf.append("client.png\" alt=\"Client\" title=\"").append(_t("Client")).append("\">");
            buf.append("</td><td align=\"left\"><b><a href=\"tunnels#").append(h.toBase64().substring(0, 4));
            buf.append("\" target=\"_top\" title=\"").append(_t("Show tunnels")).append("\">");
            // Increase permitted max length of tunnel name & handle overflow with css
            if (name.length() <= 32)
                buf.append(DataHelper.escapeHTML(name));
            else
                buf.append(DataHelper.escapeHTML(ServletUtil.truncate(name, 29))).append("&hellip;");
            buf.append("</a></b></td>\n");
            LeaseSet ls = _context.netDb().lookupLeaseSetLocally(h);
            if (ls != null && _context.tunnelManager().getOutboundClientTunnelCount(h) > 0) {
                long timeToExpire = ls.getEarliestLeaseDate() - _context.clock().now();
                if (timeToExpire < 0) {
                    // red or yellow light
                    buf.append("<td><img src=\"/themes/console/images/local_inprogress.png\" alt=\"").append(_t("Rebuilding")).append("&hellip;\" title=\"").append(_t("Leases expired")).append(" ").append(DataHelper.formatDuration2(0 - timeToExpire));
                    buf.append(" ").append(_t("ago")).append(". ").append(_t("Rebuilding")).append("&hellip;\"></td></tr>\n");
                } else {
                    // green light
                    buf.append("<td><img src=\"/themes/console/images/local_up.png\" alt=\"Ready\" title=\"").append(_t("Ready")).append("\"></td></tr>\n");
                }
            } else {
                // yellow light
                buf.append("<td><img src=\"/themes/console/images/local_inprogress.png\" alt=\"").append(_t("Building")).append("&hellip;\" title=\"").append(_t("Building tunnels")).append("&hellip;\"></td></tr>\n");
            }
        }
        buf.append("</table>");
    } else {
        buf.append("<center><i>").append(_t("none")).append("</i></center>");
    }
    return buf.toString();
}
Also used : LeaseSet(net.i2p.data.LeaseSet) Destination(net.i2p.data.Destination) ArrayList(java.util.ArrayList) Hash(net.i2p.data.Hash)

Example 3 with LeaseSet

use of net.i2p.data.LeaseSet 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 4 with LeaseSet

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

the class RequestLeaseSetMessageHandler method handleMessage.

public void handleMessage(I2CPMessage message, I2PSessionImpl session) {
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("Handle message " + message);
    RequestLeaseSetMessage msg = (RequestLeaseSetMessage) message;
    LeaseSet leaseSet = new LeaseSet();
    for (int i = 0; i < msg.getEndpoints(); i++) {
        Lease lease = new Lease();
        lease.setGateway(msg.getRouter(i));
        lease.setTunnelId(msg.getTunnelId(i));
        lease.setEndDate(msg.getEndDate());
        // lease.setStartDate(msg.getStartDate());
        leaseSet.addLease(lease);
    }
    signLeaseSet(leaseSet, session);
}
Also used : LeaseSet(net.i2p.data.LeaseSet) Lease(net.i2p.data.Lease) RequestLeaseSetMessage(net.i2p.data.i2cp.RequestLeaseSetMessage)

Example 5 with LeaseSet

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

the class DatabaseStoreMessage method readMessage.

public void readMessage(byte[] data, int offset, int dataSize, int type) throws I2NPMessageException {
    if (type != MESSAGE_TYPE)
        throw new I2NPMessageException("Message type is incorrect for this message");
    int curIndex = offset;
    _key = Hash.create(data, curIndex);
    // Fast-fail here to save resources.
    if (_key.equals(Hash.FAKE_HASH)) {
        // createRateStat in KNDF
        _context.statManager().addRateData("netDb.DSMAllZeros", 1);
        throw new I2NPMessageException("DSM all zeros");
    }
    curIndex += Hash.HASH_LENGTH;
    // as of 0.9.18, ignore other 7 bits of the type byte, in preparation for future options
    int dbType = data[curIndex] & 0x01;
    curIndex++;
    _replyToken = DataHelper.fromLong(data, curIndex, 4);
    curIndex += 4;
    if (_replyToken > 0) {
        long tunnel = DataHelper.fromLong(data, curIndex, 4);
        if (tunnel > 0)
            _replyTunnel = new TunnelId(tunnel);
        curIndex += 4;
        _replyGateway = Hash.create(data, curIndex);
        curIndex += Hash.HASH_LENGTH;
    } else {
        _replyTunnel = null;
        _replyGateway = null;
    }
    if (dbType == DatabaseEntry.KEY_TYPE_LEASESET) {
        _dbEntry = new LeaseSet();
        try {
            _dbEntry.readBytes(new ByteArrayInputStream(data, curIndex, data.length - curIndex));
        } catch (DataFormatException dfe) {
            throw new I2NPMessageException("Error reading the leaseSet", dfe);
        } catch (IOException ioe) {
            throw new I2NPMessageException("Error reading the leaseSet", ioe);
        }
    } else {
        // dbType == DatabaseEntry.KEY_TYPE_ROUTERINFO
        _dbEntry = new RouterInfo();
        int compressedSize = (int) DataHelper.fromLong(data, curIndex, 2);
        curIndex += 2;
        if (compressedSize <= 0 || curIndex + compressedSize > data.length || curIndex + compressedSize > dataSize + offset)
            throw new I2NPMessageException("Compressed RI length: " + compressedSize + " but remaining bytes: " + Math.min(data.length - curIndex, dataSize + offset - curIndex));
        try {
            // TODO we could delay decompression, just copy to a new byte array and store in _byteCache
            // May not be necessary since the IBGW now uses UnknownI2NPMessage.
            // DSMs at the OBEP are generally garlic wrapped, so the OBEP won't see it.
            // If we do delay it, getEntry() will have to check if _dbEntry is null and _byteCache
            // is non-null, and then decompress.
            byte[] decompressed = DataHelper.decompress(data, curIndex, compressedSize);
            _dbEntry.readBytes(new ByteArrayInputStream(decompressed));
        } catch (DataFormatException dfe) {
            throw new I2NPMessageException("Error reading the routerInfo", dfe);
        } catch (IOException ioe) {
            throw new I2NPMessageException("Corrupt compressed routerInfo size = " + compressedSize, ioe);
        }
    }
// if (!key.equals(_dbEntry.getHash()))
// throw new I2NPMessageException("Hash mismatch in DSM");
}
Also used : LeaseSet(net.i2p.data.LeaseSet) DataFormatException(net.i2p.data.DataFormatException) ByteArrayInputStream(java.io.ByteArrayInputStream) RouterInfo(net.i2p.data.router.RouterInfo) IOException(java.io.IOException) TunnelId(net.i2p.data.TunnelId)

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