Search in sources :

Example 6 with TunnelPoolSettings

use of net.i2p.router.TunnelPoolSettings in project i2p.i2p by i2p.

the class ClientPeerSelector method selectPeers.

/**
 * Returns ENDPOINT FIRST, GATEWAY LAST!!!!
 * In: us .. closest .. middle .. IBGW
 * Out: OBGW .. middle .. closest .. us
 *
 * @return ordered list of Hash objects (one per peer) specifying what order
 *         they should appear in a tunnel (ENDPOINT FIRST).  This includes
 *         the local router in the list.  If there are no tunnels or peers
 *         to build through, and the settings reject 0 hop tunnels, this will
 *         return null.
 */
public List<Hash> selectPeers(TunnelPoolSettings settings) {
    int length = getLength(settings);
    if (length < 0)
        return null;
    if ((length == 0) && (settings.getLength() + settings.getLengthVariance() > 0))
        return null;
    List<Hash> rv;
    boolean isInbound = settings.isInbound();
    if (length > 0) {
        // special cases
        boolean v6Only = isIPv6Only();
        boolean ntcpDisabled = isNTCPDisabled();
        boolean ssuDisabled = isSSUDisabled();
        boolean checkClosestHop = v6Only || ntcpDisabled || ssuDisabled;
        boolean hidden = ctx.router().isHidden() || ctx.router().getRouterInfo().getAddressCount() <= 0;
        boolean hiddenInbound = hidden && isInbound;
        boolean hiddenOutbound = hidden && !isInbound;
        if (shouldSelectExplicit(settings))
            return selectExplicit(settings, length);
        Set<Hash> exclude = getExclude(isInbound, false);
        Set<Hash> matches = new HashSet<Hash>(length);
        if (length == 1) {
            // closest-hop restrictions
            if (checkClosestHop) {
                Set<Hash> moreExclude = getClosestHopExclude(isInbound);
                if (moreExclude != null)
                    exclude.addAll(moreExclude);
            }
            if (hiddenInbound) {
                // SANFP adds all not-connected to exclude, so make a copy
                Set<Hash> SANFPExclude = new HashSet<Hash>(exclude);
                ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, matches);
            }
            if (matches.isEmpty()) {
                // ANFP does not fall back to non-connected
                ctx.profileOrganizer().selectFastPeers(length, exclude, matches, 0);
            }
            matches.remove(ctx.routerHash());
            rv = new ArrayList<Hash>(matches);
        } else {
            // build a tunnel using 4 subtiers.
            // For a 2-hop tunnel, the first hop comes from subtiers 0-1 and the last from subtiers 2-3.
            // For a longer tunnels, the first hop comes from subtier 0, the middle from subtiers 2-3, and the last from subtier 1.
            rv = new ArrayList<Hash>(length + 1);
            Hash randomKey = settings.getRandomKey();
            // OBEP or IB last hop
            // group 0 or 1 if two hops, otherwise group 0
            Set<Hash> lastHopExclude;
            if (isInbound) {
                // closest-hop restrictions
                if (checkClosestHop) {
                    Set<Hash> moreExclude = getClosestHopExclude(false);
                    if (moreExclude != null) {
                        moreExclude.addAll(exclude);
                        lastHopExclude = moreExclude;
                    } else {
                        lastHopExclude = exclude;
                    }
                } else {
                    lastHopExclude = exclude;
                }
            } else {
                lastHopExclude = exclude;
            }
            if (hiddenInbound) {
                // IB closest hop
                if (log.shouldInfo())
                    log.info("CPS SANFP closest IB exclude " + lastHopExclude.size());
                // SANFP adds all not-connected to exclude, so make a copy
                Set<Hash> SANFPExclude = new HashSet<Hash>(lastHopExclude);
                ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, matches);
                if (matches.isEmpty()) {
                    if (log.shouldInfo())
                        log.info("CPS SFP closest IB exclude " + lastHopExclude.size());
                    // ANFP does not fall back to non-connected
                    ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0);
                }
            } else if (hiddenOutbound) {
                // OBEP
                // check for hidden and outbound, and the paired (inbound) tunnel is zero-hop
                // if so, we need the OBEP to be connected to us, so we get the build reply back
                // This should be rare except at startup
                TunnelManagerFacade tmf = ctx.tunnelManager();
                TunnelPool tp = tmf.getInboundPool(settings.getDestination());
                boolean pickFurthest;
                if (tp != null) {
                    pickFurthest = true;
                    TunnelPoolSettings tps = tp.getSettings();
                    int len = tps.getLength();
                    if (len <= 0 || tps.getLengthOverride() == 0 || len + tps.getLengthVariance() <= 0) {
                    // leave it true
                    } else {
                        List<TunnelInfo> tunnels = tp.listTunnels();
                        if (!tunnels.isEmpty()) {
                            for (TunnelInfo ti : tp.listTunnels()) {
                                if (ti.getLength() > 1) {
                                    pickFurthest = false;
                                    break;
                                }
                            }
                        } else {
                            // no tunnels in the paired tunnel pool
                            // BuildRequester will be using exploratory
                            tp = tmf.getInboundExploratoryPool();
                            tps = tp.getSettings();
                            len = tps.getLength();
                            if (len <= 0 || tps.getLengthOverride() == 0 || len + tps.getLengthVariance() <= 0) {
                            // leave it true
                            } else {
                                tunnels = tp.listTunnels();
                                if (!tunnels.isEmpty()) {
                                    for (TunnelInfo ti : tp.listTunnels()) {
                                        if (ti.getLength() > 1) {
                                            pickFurthest = false;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                } else {
                    // shouldn't happen
                    pickFurthest = false;
                }
                if (pickFurthest) {
                    if (log.shouldInfo())
                        log.info("CPS SANFP OBEP exclude " + lastHopExclude.size());
                    // SANFP adds all not-connected to exclude, so make a copy
                    Set<Hash> SANFPExclude = new HashSet<Hash>(lastHopExclude);
                    ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, matches);
                    if (matches.isEmpty()) {
                        // ANFP does not fall back to non-connected
                        if (log.shouldInfo())
                            log.info("CPS SFP OBEP exclude " + lastHopExclude.size());
                        ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0);
                    }
                } else {
                    ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0);
                }
            } else {
                // TODO exclude IPv6-only at OBEP? Caught in checkTunnel() below
                ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0);
            }
            matches.remove(ctx.routerHash());
            exclude.addAll(matches);
            rv.addAll(matches);
            matches.clear();
            if (length > 2) {
                // middle hop(s)
                // group 2 or 3
                ctx.profileOrganizer().selectFastPeers(length - 2, exclude, matches, randomKey, SLICE_2_3);
                matches.remove(ctx.routerHash());
                if (matches.size() > 1) {
                    // order the middle peers for tunnels >= 4 hops
                    List<Hash> ordered = new ArrayList<Hash>(matches);
                    orderPeers(ordered, randomKey);
                    rv.addAll(ordered);
                } else {
                    rv.addAll(matches);
                }
                exclude.addAll(matches);
                matches.clear();
            }
            // group 2 or 3 if two hops, otherwise group 1
            if (!isInbound) {
                // closest-hop restrictions
                if (checkClosestHop) {
                    Set<Hash> moreExclude = getClosestHopExclude(true);
                    if (moreExclude != null)
                        exclude.addAll(moreExclude);
                }
            }
            // TODO exclude IPv6-only at IBGW? Caught in checkTunnel() below
            ctx.profileOrganizer().selectFastPeers(1, exclude, matches, randomKey, length == 2 ? SLICE_2_3 : SLICE_1);
            matches.remove(ctx.routerHash());
            rv.addAll(matches);
        }
    } else {
        rv = new ArrayList<Hash>(1);
    }
    // log.debug("EPS result: " + DataHelper.toString(rv));
    if (isInbound)
        rv.add(0, ctx.routerHash());
    else
        rv.add(ctx.routerHash());
    if (rv.size() > 1) {
        if (!checkTunnel(isInbound, rv))
            rv = null;
    }
    return rv;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) ArrayList(java.util.ArrayList) TunnelInfo(net.i2p.router.TunnelInfo) Hash(net.i2p.data.Hash) TunnelManagerFacade(net.i2p.router.TunnelManagerFacade) TunnelPoolSettings(net.i2p.router.TunnelPoolSettings) List(java.util.List) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Example 7 with TunnelPoolSettings

use of net.i2p.router.TunnelPoolSettings in project i2p.i2p by i2p.

the class InboundMessageDistributor method handleClove.

/**
 * Handle a clove removed from the garlic message
 */
public void handleClove(DeliveryInstructions instructions, I2NPMessage data) {
    int type = data.getType();
    switch(instructions.getDeliveryMode()) {
        case DeliveryInstructions.DELIVERY_MODE_LOCAL:
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("local delivery instructions for clove: " + data.getClass().getSimpleName());
            if (type == GarlicMessage.MESSAGE_TYPE) {
                _receiver.receive((GarlicMessage) data);
            } else if (type == DatabaseStoreMessage.MESSAGE_TYPE) {
                // Treat db store explicitly here (not in HandleFloodfillDatabaseStoreMessageJob),
                // since we don't want to republish (or flood)
                // unnecessarily. Reply tokens ignored.
                DatabaseStoreMessage dsm = (DatabaseStoreMessage) data;
                // Ensure the reply info is cleared, just in case
                dsm.setReplyToken(0);
                dsm.setReplyTunnel(null);
                dsm.setReplyGateway(null);
                if (dsm.getEntry().getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
                    // Case 1:
                    // store of our own LS.
                    // This is almost certainly a response to a FloodfillVerifyStoreJob search.
                    // We must send to the InNetMessagePool so the message can be matched
                    // and the verify marked as successful.
                    // Case 2:
                    // Store of somebody else's LS.
                    // This could be an encrypted response to an IterativeSearchJob search.
                    // We must send to the InNetMessagePool so the message can be matched
                    // and the search marked as successful.
                    // Or, it's a normal LS bundled with data and a MessageStatusMessage.
                    // ... and inject it.
                    ((LeaseSet) dsm.getEntry()).setReceivedAsReply();
                    if (_log.shouldLog(Log.INFO))
                        _log.info("Storing garlic LS down tunnel for: " + dsm.getKey() + " sent to: " + _client);
                    _context.inNetMessagePool().add(dsm, null, null);
                } else {
                    if (_client != null) {
                        // drop it, since the data we receive shouldn't include router
                        // references, as that might get us to talk to them (and therefore
                        // open an attack vector)
                        _context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1, DatabaseStoreMessage.MESSAGE_TYPE);
                        _log.error("Dropped dangerous message down a tunnel for " + _client + ": " + dsm, new Exception("cause"));
                        return;
                    }
                    // ... and inject it.
                    if (_log.shouldLog(Log.INFO))
                        _log.info("Storing garlic RI down tunnel for: " + dsm.getKey() + " sent to: " + _client);
                    _context.inNetMessagePool().add(dsm, null, null);
                }
            } else if (_client != null && type == DatabaseSearchReplyMessage.MESSAGE_TYPE) {
                // DSRMs show up here now that replies are encrypted
                // TODO: Strip in IterativeLookupJob etc. instead, depending on
                // LS or RI and client or expl., so that we can safely follow references
                // in a reply to a LS lookup over client tunnels.
                // ILJ would also have to follow references via client tunnels
                DatabaseSearchReplyMessage orig = (DatabaseSearchReplyMessage) data;
                /**
                 **
                 *                    if (orig.getNumReplies() > 0) {
                 *                        if (_log.shouldLog(Log.INFO))
                 *                            _log.info("Removing replies from a garlic DSRM down a tunnel for " + _client + ": " + data);
                 *                        DatabaseSearchReplyMessage newMsg = new DatabaseSearchReplyMessage(_context);
                 *                        newMsg.setFromHash(orig.getFromHash());
                 *                        newMsg.setSearchKey(orig.getSearchKey());
                 *                        orig = newMsg;
                 *                     }
                 ***
                 */
                _context.inNetMessagePool().add(orig, null, null);
            } else if (type == DataMessage.MESSAGE_TYPE) {
                // a data message targetting the local router is how we send load tests (real
                // data messages target destinations)
                _context.statManager().addRateData("tunnel.handleLoadClove", 1);
                data = null;
            // _context.inNetMessagePool().add(data, null, null);
            } else if (_client != null && type != DeliveryStatusMessage.MESSAGE_TYPE) {
                // drop it, since the data we receive shouldn't include other stuff,
                // as that might open an attack vector
                _context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1, data.getType());
                _log.error("Dropped dangerous message down a tunnel for " + _client + ": " + data, new Exception("cause"));
            } else {
                _context.inNetMessagePool().add(data, null, null);
            }
            return;
        case DeliveryInstructions.DELIVERY_MODE_DESTINATION:
            Hash to = instructions.getDestination();
            // Can we route UnknownI2NPMessages to a destination too?
            if (type != DataMessage.MESSAGE_TYPE) {
                if (_log.shouldLog(Log.ERROR))
                    _log.error("cant send a " + data.getClass().getSimpleName() + " to a destination");
            } else if (_client != null && _client.equals(to)) {
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug("data message came down a tunnel for " + _client);
                DataMessage dm = (DataMessage) data;
                Payload payload = new Payload();
                payload.setEncryptedData(dm.getData());
                ClientMessage m = new ClientMessage(_client, payload);
                _context.clientManager().messageReceived(m);
            } else if (_client != null) {
                // Shared tunnel?
                TunnelPoolSettings tgt = _context.tunnelManager().getInboundSettings(to);
                if (tgt != null && _client.equals(tgt.getAliasOf())) {
                    // same as above, just different log
                    if (_log.shouldLog(Log.DEBUG))
                        _log.debug("data message came down a tunnel for " + _client + " targeting shared " + to);
                    DataMessage dm = (DataMessage) data;
                    Payload payload = new Payload();
                    payload.setEncryptedData(dm.getData());
                    ClientMessage m = new ClientMessage(to, payload);
                    _context.clientManager().messageReceived(m);
                } else {
                    if (_log.shouldLog(Log.ERROR))
                        _log.error("Data message came down a tunnel for " + _client + " but targetted " + to);
                }
            } else {
                if (_log.shouldLog(Log.ERROR))
                    _log.error("Data message came down an exploratory tunnel targeting " + to);
            }
            return;
        // fall through
        case DeliveryInstructions.DELIVERY_MODE_ROUTER:
        case DeliveryInstructions.DELIVERY_MODE_TUNNEL:
            if (_log.shouldLog(Log.INFO))
                _log.info("clove targetted " + instructions.getRouter() + ":" + instructions.getTunnelId() + ", treat recursively to prevent leakage");
            distribute(data, instructions.getRouter(), instructions.getTunnelId());
            return;
        default:
            if (_log.shouldLog(Log.ERROR))
                _log.error("Unknown instruction " + instructions.getDeliveryMode() + ": " + instructions);
            return;
    }
}
Also used : DataMessage(net.i2p.data.i2np.DataMessage) DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage) DatabaseSearchReplyMessage(net.i2p.data.i2np.DatabaseSearchReplyMessage) TunnelPoolSettings(net.i2p.router.TunnelPoolSettings) Payload(net.i2p.data.Payload) ClientMessage(net.i2p.router.ClientMessage) Hash(net.i2p.data.Hash)

Example 8 with TunnelPoolSettings

use of net.i2p.router.TunnelPoolSettings in project i2p.i2p by i2p.

the class ConfigTunnelsHandler method saveChanges.

/**
 * The user made changes to the network config and wants to save them, so
 * lets go ahead and do so.
 */
private void saveChanges() {
    boolean saveRequired = false;
    Map<String, String> changes = new HashMap<String, String>();
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("Saving changes, with props = " + _settings + ".");
    int updated = 0;
    int index = 0;
    while (true) {
        Object val = _settings.get("pool." + index);
        if (val == null)
            break;
        Hash client = new Hash();
        String poolName = (val instanceof String ? (String) val : ((String[]) val)[0]);
        TunnelPoolSettings in = null;
        TunnelPoolSettings out = null;
        if ("exploratory".equals(poolName)) {
            in = _context.tunnelManager().getInboundSettings();
            out = _context.tunnelManager().getOutboundSettings();
        } else {
            try {
                client.fromBase64(poolName);
            } catch (DataFormatException dfe) {
                addFormError("Internal error (pool name could not resolve - " + poolName + ").");
                index++;
                continue;
            }
            in = _context.tunnelManager().getInboundSettings(client);
            out = _context.tunnelManager().getOutboundSettings(client);
        }
        if ((in == null) || (out == null)) {
            addFormError("Internal error (pool settings cound not be found for " + poolName + ").");
            index++;
            continue;
        }
        in.setLength(getInt(_settings.get(index + ".depthInbound")));
        out.setLength(getInt(_settings.get(index + ".depthOutbound")));
        in.setLengthVariance(getInt(_settings.get(index + ".varianceInbound")));
        out.setLengthVariance(getInt(_settings.get(index + ".varianceOutbound")));
        in.setQuantity(getInt(_settings.get(index + ".quantityInbound")));
        out.setQuantity(getInt(_settings.get(index + ".quantityOutbound")));
        in.setBackupQuantity(getInt(_settings.get(index + ".backupInbound")));
        out.setBackupQuantity(getInt(_settings.get(index + ".backupOutbound")));
        if ("exploratory".equals(poolName)) {
            changes.put(TunnelPoolSettings.PREFIX_INBOUND_EXPLORATORY + TunnelPoolSettings.PROP_LENGTH, in.getLength() + "");
            changes.put(TunnelPoolSettings.PREFIX_OUTBOUND_EXPLORATORY + TunnelPoolSettings.PROP_LENGTH, out.getLength() + "");
            changes.put(TunnelPoolSettings.PREFIX_INBOUND_EXPLORATORY + TunnelPoolSettings.PROP_LENGTH_VARIANCE, in.getLengthVariance() + "");
            changes.put(TunnelPoolSettings.PREFIX_OUTBOUND_EXPLORATORY + TunnelPoolSettings.PROP_LENGTH_VARIANCE, out.getLengthVariance() + "");
            changes.put(TunnelPoolSettings.PREFIX_INBOUND_EXPLORATORY + TunnelPoolSettings.PROP_QUANTITY, in.getQuantity() + "");
            changes.put(TunnelPoolSettings.PREFIX_OUTBOUND_EXPLORATORY + TunnelPoolSettings.PROP_QUANTITY, out.getQuantity() + "");
            changes.put(TunnelPoolSettings.PREFIX_INBOUND_EXPLORATORY + TunnelPoolSettings.PROP_BACKUP_QUANTITY, in.getBackupQuantity() + "");
            changes.put(TunnelPoolSettings.PREFIX_OUTBOUND_EXPLORATORY + TunnelPoolSettings.PROP_BACKUP_QUANTITY, out.getBackupQuantity() + "");
        }
        if ("exploratory".equals(poolName)) {
            if (_log.shouldLog(Log.DEBUG)) {
                _log.debug("Inbound exploratory settings: " + in);
                _log.debug("Outbound exploratory settings: " + out);
            }
            _context.tunnelManager().setInboundSettings(in);
            _context.tunnelManager().setOutboundSettings(out);
        } else {
            if (_log.shouldLog(Log.DEBUG)) {
                _log.debug("Inbound settings for " + client.toBase64() + ": " + in);
                _log.debug("Outbound settings for " + client.toBase64() + ": " + out);
            }
            _context.tunnelManager().setInboundSettings(client, in);
            _context.tunnelManager().setOutboundSettings(client, out);
        }
        updated++;
        saveRequired = true;
        index++;
    }
    if (updated > 0)
        // the count isn't really correct anyway, since we don't check for actual changes
        // addFormNotice("Updated settings for " + updated + " pools.");
        addFormNotice(_t("Updated settings for all pools."));
    if (saveRequired) {
        boolean saved = _context.router().saveConfig(changes, null);
        if (saved)
            addFormNotice(_t("Exploratory tunnel configuration saved successfully."));
        else
            addFormError(_t("Error saving the configuration (applied but not saved) - please see the error logs."));
    }
}
Also used : DataFormatException(net.i2p.data.DataFormatException) HashMap(java.util.HashMap) TunnelPoolSettings(net.i2p.router.TunnelPoolSettings) Hash(net.i2p.data.Hash)

Example 9 with TunnelPoolSettings

use of net.i2p.router.TunnelPoolSettings in project i2p.i2p by i2p.

the class ConfigTunnelsHelper method getForm.

public String getForm() {
    StringBuilder buf = new StringBuilder(1024);
    // HTML: <input> cannot be inside a <table>
    buf.append("<input type=\"hidden\" name=\"pool.0\" value=\"exploratory\" >\n");
    int cur = 1;
    Set<Destination> clients = _context.clientManager().listClients();
    for (Destination dest : clients) {
        buf.append("<input type=\"hidden\" name=\"pool.").append(cur).append("\" value=\"");
        buf.append(dest.calculateHash().toBase64()).append("\" >\n");
        cur++;
    }
    buf.append("<table id=\"tunnelconfig\">\n");
    TunnelPoolSettings exploratoryIn = _context.tunnelManager().getInboundSettings();
    TunnelPoolSettings exploratoryOut = _context.tunnelManager().getOutboundSettings();
    renderForm(buf, 0, "exploratory", _t("Exploratory tunnels"), exploratoryIn, exploratoryOut);
    cur = 1;
    for (Destination dest : clients) {
        TunnelPoolSettings in = _context.tunnelManager().getInboundSettings(dest.calculateHash());
        TunnelPoolSettings out = _context.tunnelManager().getOutboundSettings(dest.calculateHash());
        if (in == null || in.getAliasOf() != null || out == null || out.getAliasOf() != null)
            continue;
        String name = in.getDestinationNickname();
        if (name == null)
            name = out.getDestinationNickname();
        if (name == null)
            name = dest.calculateHash().toBase64().substring(0, 6);
        String prefix = dest.calculateHash().toBase64().substring(0, 4);
        renderForm(buf, cur, prefix, _t("Client tunnels for {0}", DataHelper.escapeHTML(_t(name))), in, out);
        cur++;
    }
    buf.append("</table>\n");
    return buf.toString();
}
Also used : Destination(net.i2p.data.Destination) TunnelPoolSettings(net.i2p.router.TunnelPoolSettings)

Example 10 with TunnelPoolSettings

use of net.i2p.router.TunnelPoolSettings in project i2p.i2p by i2p.

the class ConfigKeyringHelper method render.

/**
 *  @since 0.9.33 moved from PersistentKeyRing
 */
private void render(StringBuilder buf, boolean local) {
    buf.append("\n<table class=\"configtable\"><tr><th align=\"left\">").append(_t("Destination")).append("<th align=\"left\">").append(_t("Name")).append("<th align=\"left\">").append(_t("Encryption Key")).append("</tr>");
    for (Map.Entry<Hash, SessionKey> e : _context.keyRing().entrySet()) {
        Hash h = e.getKey();
        if (local != _context.clientManager().isLocal(h))
            continue;
        buf.append("\n<tr><td>");
        buf.append(h.toBase32());
        buf.append("</td><td>");
        Destination dest = _context.netDb().lookupDestinationLocally(h);
        if (dest != null && local) {
            TunnelPoolSettings in = _context.tunnelManager().getInboundSettings(h);
            if (in != null && in.getDestinationNickname() != null)
                buf.append(in.getDestinationNickname());
        } else {
            String host = _context.namingService().reverseLookup(h);
            if (host != null)
                buf.append(host);
        }
        buf.append("</td><td>");
        SessionKey sk = e.getValue();
        buf.append(sk.toBase64());
        buf.append("</td>\n");
    }
    buf.append("</table>\n");
}
Also used : Destination(net.i2p.data.Destination) SessionKey(net.i2p.data.SessionKey) TunnelPoolSettings(net.i2p.router.TunnelPoolSettings) Hash(net.i2p.data.Hash) Map(java.util.Map)

Aggregations

TunnelPoolSettings (net.i2p.router.TunnelPoolSettings)10 Hash (net.i2p.data.Hash)8 Destination (net.i2p.data.Destination)3 TunnelInfo (net.i2p.router.TunnelInfo)3 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 TunnelManagerFacade (net.i2p.router.TunnelManagerFacade)2 BigInteger (java.math.BigInteger)1 DecimalFormat (java.text.DecimalFormat)1 Date (java.util.Date)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 DataFormatException (net.i2p.data.DataFormatException)1 Lease (net.i2p.data.Lease)1 LeaseSet (net.i2p.data.LeaseSet)1 Payload (net.i2p.data.Payload)1 SessionKey (net.i2p.data.SessionKey)1 DataMessage (net.i2p.data.i2np.DataMessage)1