Search in sources :

Example 1 with Destination

use of net.i2p.data.Destination 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 Destination

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

the class Packet method readPacket.

/**
 * Read the packet from the buffer (starting at the offset) and return
 * the number of bytes read.
 *
 * @param buffer packet buffer containing the data
 * @param offset index into the buffer to start readign
 * @param length how many bytes within the buffer past the offset are
 *               part of the packet?
 *
 * @throws IllegalArgumentException if the data is b0rked
 */
public void readPacket(byte[] buffer, int offset, int length) throws IllegalArgumentException {
    if (buffer.length - offset < length)
        throw new IllegalArgumentException("len=" + buffer.length + " off=" + offset + " length=" + length);
    if (// min header size
    length < 22)
        throw new IllegalArgumentException("Too small: len=" + buffer.length);
    int cur = offset;
    setSendStreamId(DataHelper.fromLong(buffer, cur, 4));
    cur += 4;
    setReceiveStreamId(DataHelper.fromLong(buffer, cur, 4));
    cur += 4;
    setSequenceNum(DataHelper.fromLong(buffer, cur, 4));
    cur += 4;
    setAckThrough(DataHelper.fromLong(buffer, cur, 4));
    cur += 4;
    int numNacks = buffer[cur] & 0xff;
    cur++;
    if (length < 22 + numNacks * 4)
        throw new IllegalArgumentException("Too small with " + numNacks + " nacks: " + length);
    if (numNacks > 0) {
        long[] nacks = new long[numNacks];
        for (int i = 0; i < numNacks; i++) {
            nacks[i] = DataHelper.fromLong(buffer, cur, 4);
            cur += 4;
        }
        setNacks(nacks);
    } else {
        setNacks(null);
    }
    setResendDelay(buffer[cur] & 0xff);
    cur++;
    setFlags((int) DataHelper.fromLong(buffer, cur, 2));
    cur += 2;
    int optionSize = (int) DataHelper.fromLong(buffer, cur, 2);
    cur += 2;
    if (length < 22 + numNacks * 4 + optionSize)
        throw new IllegalArgumentException("Too small with " + numNacks + " nacks and " + optionSize + " options: " + length);
    int payloadBegin = cur + optionSize;
    int payloadSize = length - payloadBegin;
    if ((payloadSize < 0) || (payloadSize > MAX_PAYLOAD_SIZE))
        throw new IllegalArgumentException("length: " + length + " offset: " + offset + " begin: " + payloadBegin);
    // skip ahead to the payload
    // _payload = new ByteArray(new byte[payloadSize]);
    _payload = new ByteArray(buffer, payloadBegin, payloadSize);
    // ok now lets go back and deal with the options
    if (isFlagSet(FLAG_DELAY_REQUESTED)) {
        setOptionalDelay((int) DataHelper.fromLong(buffer, cur, 2));
        cur += 2;
    }
    if (isFlagSet(FLAG_FROM_INCLUDED)) {
        ByteArrayInputStream bais = new ByteArrayInputStream(buffer, cur, length - cur);
        try {
            Destination optionFrom = Destination.create(bais);
            cur += optionFrom.size();
            _optionFrom = optionFrom;
        } catch (IOException ioe) {
            throw new IllegalArgumentException("Bad from field", ioe);
        } catch (DataFormatException dfe) {
            throw new IllegalArgumentException("Bad from field", dfe);
        }
    }
    if (isFlagSet(FLAG_MAX_PACKET_SIZE_INCLUDED)) {
        setOptionalMaxSize((int) DataHelper.fromLong(buffer, cur, 2));
        cur += 2;
    }
    if (isFlagSet(FLAG_SIGNATURE_INCLUDED)) {
        Signature optionSignature;
        Destination from = getOptionalFrom();
        if (from != null) {
            optionSignature = new Signature(from.getSigningPublicKey().getType());
        } else {
            // super cheat for now, look for correct type,
            // assume no more options. If we add to the options
            // we will have to ask the manager.
            // We will get this wrong for Ed25519, same length as P256...
            // See verifySignature() below where we will recast the signature to
            // the correct type if necessary
            int siglen = payloadBegin - cur;
            SigType type = null;
            for (SigType t : SigType.values()) {
                if (t.getSigLen() == siglen) {
                    type = t;
                    break;
                }
            }
            if (type == null) {
                if (siglen < Signature.SIGNATURE_BYTES)
                    throw new IllegalArgumentException("unknown sig type len=" + siglen);
                // Hope it's the default type with some unknown options following;
                // if not the sig will fail later
                type = SigType.DSA_SHA1;
                siglen = Signature.SIGNATURE_BYTES;
            }
            optionSignature = new Signature(type);
        }
        byte[] buf = new byte[optionSignature.length()];
        System.arraycopy(buffer, cur, buf, 0, buf.length);
        optionSignature.setData(buf);
        setOptionalSignature(optionSignature);
        cur += buf.length;
    }
}
Also used : Destination(net.i2p.data.Destination) DataFormatException(net.i2p.data.DataFormatException) ByteArrayInputStream(java.io.ByteArrayInputStream) Signature(net.i2p.data.Signature) ByteArray(net.i2p.data.ByteArray) IOException(java.io.IOException) SigType(net.i2p.crypto.SigType)

Example 3 with Destination

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

the class PacketHandler method sendReset.

/**
 *  This sends a reset back to the place this packet came from.
 *  If the packet has no 'optional from' or valid signature, this does nothing.
 *  This is not associated with a connection, so no con stats are updated.
 *
 *  @param packet incoming packet to be replied to
 */
private void sendReset(Packet packet) {
    Destination from = packet.getOptionalFrom();
    if (from == null)
        return;
    boolean ok = packet.verifySignature(_context, from, null);
    if (!ok) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Can't send reset after recv spoofed packet: " + packet);
        return;
    }
    PacketLocal reply = new PacketLocal(_context, from, packet.getSession());
    reply.setFlag(Packet.FLAG_RESET);
    reply.setFlag(Packet.FLAG_SIGNATURE_INCLUDED);
    reply.setSendStreamId(packet.getReceiveStreamId());
    reply.setReceiveStreamId(packet.getSendStreamId());
    // TODO remove this someday, as of 0.9.20 we do not require it
    reply.setOptionalFrom();
    reply.setLocalPort(packet.getLocalPort());
    reply.setRemotePort(packet.getRemotePort());
    // this just sends the packet - no retries or whatnot
    _manager.getPacketQueue().enqueue(reply);
}
Also used : Destination(net.i2p.data.Destination)

Example 4 with Destination

use of net.i2p.data.Destination 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 5 with Destination

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

the class SAMv1Handler method execNamingMessage.

/* Parse and execute a NAMING message */
protected boolean execNamingMessage(String opcode, Properties props) {
    if (opcode.equals("LOOKUP")) {
        String name = props.getProperty("NAME");
        if (name == null) {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Name to resolve not specified in NAMING message");
            return writeString("NAMING REPLY RESULT=KEY_NOT_FOUND NAME=\"\" MESSAGE=\"Must specify NAME\"\n");
        }
        Destination dest = null;
        if (name.equals("ME")) {
            if (rawSession != null) {
                dest = rawSession.getDestination();
            } else if (streamSession != null) {
                dest = streamSession.getDestination();
            } else if (datagramSession != null) {
                dest = datagramSession.getDestination();
            } else {
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug("Lookup for SESSION destination, but session is null");
                return false;
            }
        } else {
            try {
                dest = SAMUtils.getDest(name);
            } catch (DataFormatException e) {
            }
        }
        if (dest == null) {
            return writeString("NAMING REPLY RESULT=KEY_NOT_FOUND NAME=" + name + "\n");
        }
        return writeString("NAMING REPLY RESULT=OK NAME=" + name + " VALUE=" + dest.toBase64() + "\n");
    } else {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Unrecognized NAMING message opcode: \"" + opcode + "\"");
        return false;
    }
}
Also used : Destination(net.i2p.data.Destination) DataFormatException(net.i2p.data.DataFormatException)

Aggregations

Destination (net.i2p.data.Destination)149 IOException (java.io.IOException)46 DataFormatException (net.i2p.data.DataFormatException)33 Properties (java.util.Properties)29 I2PException (net.i2p.I2PException)26 Hash (net.i2p.data.Hash)18 ArrayList (java.util.ArrayList)13 File (java.io.File)12 I2PSessionException (net.i2p.client.I2PSessionException)12 SigType (net.i2p.crypto.SigType)12 ByteArrayInputStream (java.io.ByteArrayInputStream)11 ByteArrayOutputStream (java.io.ByteArrayOutputStream)10 I2PSession (net.i2p.client.I2PSession)10 I2PSocket (net.i2p.client.streaming.I2PSocket)10 FileInputStream (java.io.FileInputStream)7 InputStream (java.io.InputStream)7 OutputStream (java.io.OutputStream)7 I2PClient (net.i2p.client.I2PClient)7 I2PSocketOptions (net.i2p.client.streaming.I2PSocketOptions)7 Test (org.junit.Test)6