Search in sources :

Example 1 with TunnelPoolSettings

use of net.i2p.router.TunnelPoolSettings 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 TunnelPoolSettings

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

the class SummaryHelper method getName.

/**
 * translate here so collation works above
 */
private String getName(Destination d) {
    TunnelPoolSettings in = _context.tunnelManager().getInboundSettings(d.calculateHash());
    String name = (in != null ? in.getDestinationNickname() : null);
    if (name == null) {
        TunnelPoolSettings out = _context.tunnelManager().getOutboundSettings(d.calculateHash());
        name = (out != null ? out.getDestinationNickname() : null);
        if (name == null)
            name = d.calculateHash().toBase64().substring(0, 6);
        else
            name = _t(name);
    } else {
        name = _t(name);
    }
    return name;
}
Also used : TunnelPoolSettings(net.i2p.router.TunnelPoolSettings)

Example 3 with TunnelPoolSettings

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

the class ExploratoryPeerSelector 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) {
        if (log.shouldLog(Log.DEBUG))
            log.debug("Length requested is zero: " + settings);
        return null;
    }
    // if (false && shouldSelectExplicit(settings)) {
    // List<Hash> rv = selectExplicit(settings, length);
    // if (l.shouldLog(Log.DEBUG))
    // l.debug("Explicit peers selected: " + rv);
    // return rv;
    // }
    boolean isInbound = settings.isInbound();
    Set<Hash> exclude = getExclude(isInbound, true);
    exclude.add(ctx.routerHash());
    // special cases
    boolean nonzero = length > 0;
    boolean exploreHighCap = nonzero && shouldPickHighCap();
    boolean v6Only = nonzero && isIPv6Only();
    boolean ntcpDisabled = nonzero && isNTCPDisabled();
    boolean ssuDisabled = nonzero && isSSUDisabled();
    boolean checkClosestHop = v6Only || ntcpDisabled || ssuDisabled;
    boolean hidden = nonzero && (ctx.router().isHidden() || ctx.router().getRouterInfo().getAddressCount() <= 0);
    boolean hiddenInbound = hidden && isInbound;
    boolean hiddenOutbound = hidden && !isInbound;
    boolean lowOutbound = nonzero && !isInbound && !ctx.commSystem().haveHighOutboundCapacity();
    // closest-hop restrictions
    // Since we're applying orderPeers() later, we don't know
    // which will be the closest hop, so select the closest one here if necessary.
    Hash closestHop = null;
    if (v6Only || hiddenInbound || lowOutbound) {
        Set<Hash> closestExclude;
        if (checkClosestHop) {
            closestExclude = getClosestHopExclude(isInbound);
            if (closestExclude != null)
                closestExclude.addAll(exclude);
            else
                closestExclude = exclude;
        } else {
            closestExclude = exclude;
        }
        Set<Hash> closest = new HashSet<Hash>(1);
        if (hiddenInbound || lowOutbound) {
            // use only connected peers so we don't make more connections
            if (log.shouldLog(Log.INFO))
                log.info("EPS SANFP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
            // SANFP adds all not-connected to exclude, so make a copy
            Set<Hash> SANFPExclude = new HashSet<Hash>(closestExclude);
            ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, closest);
            if (closest.isEmpty()) {
                // ANFP does not fall back to non-connected
                if (log.shouldLog(Log.INFO))
                    log.info("EPS SFP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
                ctx.profileOrganizer().selectFastPeers(1, closestExclude, closest);
            }
        } else if (exploreHighCap) {
            if (log.shouldLog(Log.INFO))
                log.info("EPS SHCP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
            ctx.profileOrganizer().selectHighCapacityPeers(1, closestExclude, closest);
        } else {
            if (log.shouldLog(Log.INFO))
                log.info("EPS SNFP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
            ctx.profileOrganizer().selectNotFailingPeers(1, closestExclude, closest, false);
        }
        if (!closest.isEmpty()) {
            closestHop = closest.iterator().next();
            exclude.add(closestHop);
            length--;
        }
    }
    // furthest-hop restrictions
    // Since we're applying orderPeers() later, we don't know
    // which will be the furthest hop, so select the furthest one here if necessary.
    Hash furthestHop = null;
    if (hiddenOutbound && length > 0) {
        // 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.getInboundExploratoryPool();
        TunnelPoolSettings tps = tp.getSettings();
        int len = tps.getLength();
        boolean pickFurthest = true;
        if (len <= 0 || tps.getLengthOverride() == 0 || len + tps.getLengthVariance() <= 0) {
        // leave it true
        } else {
            for (TunnelInfo ti : tp.listTunnels()) {
                if (ti.getLength() > 1) {
                    pickFurthest = false;
                    break;
                }
            }
        }
        if (pickFurthest) {
            Set<Hash> furthest = new HashSet<Hash>(1);
            if (log.shouldLog(Log.INFO))
                log.info("EPS SANFP furthest OB exclude " + exclude.size());
            // ANFP adds all not-connected to exclude, so make a copy
            Set<Hash> SANFPExclude = new HashSet<Hash>(exclude);
            ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, furthest);
            if (furthest.isEmpty()) {
                // ANFP does not fall back to non-connected
                if (log.shouldLog(Log.INFO))
                    log.info("EPS SFP furthest OB exclude " + exclude.size());
                ctx.profileOrganizer().selectFastPeers(1, exclude, furthest);
            }
            if (!furthest.isEmpty()) {
                furthestHop = furthest.iterator().next();
                exclude.add(furthestHop);
                length--;
            }
        }
    }
    // Don't use ff peers for exploratory tunnels to lessen exposure to netDb searches and stores
    // Hmm if they don't get explored they don't get a speed/capacity rating
    // so they don't get used for client tunnels either.
    // FloodfillNetworkDatabaseFacade fac = (FloodfillNetworkDatabaseFacade)ctx.netDb();
    // exclude.addAll(fac.getFloodfillPeers());
    HashSet<Hash> matches = new HashSet<Hash>(length);
    if (length > 0) {
        // 
        if (exploreHighCap) {
            if (log.shouldLog(Log.INFO))
                log.info("EPS SHCP " + length + (isInbound ? " IB" : " OB") + " exclude " + exclude.size());
            ctx.profileOrganizer().selectHighCapacityPeers(length, exclude, matches);
        } else {
            // Peer org credits existing items in matches
            if (length > 2)
                ctx.profileOrganizer().selectHighCapacityPeers(length - 2, exclude, matches);
            if (log.shouldLog(Log.INFO))
                log.info("EPS SNFP " + length + (isInbound ? " IB" : " OB") + " exclude " + exclude.size());
            ctx.profileOrganizer().selectNotFailingPeers(length, exclude, matches, false);
        }
        matches.remove(ctx.routerHash());
    }
    ArrayList<Hash> rv = new ArrayList<Hash>(matches);
    if (rv.size() > 1)
        orderPeers(rv, settings.getRandomKey());
    if (closestHop != null) {
        if (isInbound)
            rv.add(0, closestHop);
        else
            rv.add(closestHop);
        length++;
    }
    if (furthestHop != null) {
        // always OBEP for now, nothing special for IBGW
        if (isInbound)
            rv.add(furthestHop);
        else
            rv.add(0, furthestHop);
        length++;
    }
    // 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 : ArrayList(java.util.ArrayList) TunnelPoolSettings(net.i2p.router.TunnelPoolSettings) TunnelInfo(net.i2p.router.TunnelInfo) Hash(net.i2p.data.Hash) HashSet(java.util.HashSet) TunnelManagerFacade(net.i2p.router.TunnelManagerFacade)

Example 4 with TunnelPoolSettings

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

the class TunnelPool method configureNewTunnel.

/**
 *  @return null on failure
 */
private PooledTunnelCreatorConfig configureNewTunnel(boolean forceZeroHop) {
    TunnelPoolSettings settings = getSettings();
    // peers for new tunnel, including us, ENDPOINT FIRST
    List<Hash> peers = null;
    long now = _context.clock().now();
    long expiration = now + TunnelPoolSettings.DEFAULT_DURATION;
    if (!forceZeroHop) {
        int len = settings.getLengthOverride();
        if (len < 0)
            len = settings.getLength();
        if (len > 0 && (!settings.isExploratory()) && _context.random().nextBoolean()) {
            // look for a tunnel to reuse, if the right length and expiring soon
            // ignore variance for now.
            // us
            len++;
            synchronized (_tunnels) {
                for (TunnelInfo ti : _tunnels) {
                    if (ti.getLength() >= len && ti.getExpiration() < now + 3 * 60 * 1000 && !ti.wasReused()) {
                        ti.setReused();
                        len = ti.getLength();
                        peers = new ArrayList<Hash>(len);
                        // peers list is ordered endpoint first, but cfg.getPeer() is ordered gateway first
                        for (int i = len - 1; i >= 0; i--) {
                            peers.add(ti.getPeer(i));
                        }
                        break;
                    }
                }
            }
        }
        if (peers == null) {
            setLengthOverride();
            peers = _peerSelector.selectPeers(settings);
        }
        if ((peers == null) || (peers.isEmpty())) {
            // the pool is refusing 0 hop tunnels
            if (peers == null) {
                if (_log.shouldLog(Log.WARN))
                    _log.warn("No peers to put in the new tunnel! selectPeers returned null!  boo, hiss!");
            } else {
                if (_log.shouldLog(Log.WARN))
                    _log.warn("No peers to put in the new tunnel! selectPeers returned an empty list?!");
            }
            return null;
        }
    } else {
        peers = Collections.singletonList(_context.routerHash());
    }
    PooledTunnelCreatorConfig cfg = new PooledTunnelCreatorConfig(_context, peers.size(), settings.isInbound(), settings.getDestination());
    cfg.setTunnelPool(this);
    // peers list is ordered endpoint first, but cfg.getPeer() is ordered gateway first
    for (int i = 0; i < peers.size(); i++) {
        int j = peers.size() - 1 - i;
        cfg.setPeer(j, peers.get(i));
        HopConfig hop = cfg.getConfig(j);
        hop.setCreation(now);
        hop.setExpiration(expiration);
        hop.setIVKey(_context.keyGenerator().generateSessionKey());
        hop.setLayerKey(_context.keyGenerator().generateSessionKey());
    // tunnelIds will be updated during building, and as the creator, we
    // don't need to worry about prev/next hop
    }
    // note that this will be adjusted by expire job
    cfg.setExpiration(expiration);
    if (!settings.isInbound())
        cfg.setPriority(settings.getPriority());
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("Config contains " + peers + ": " + cfg);
    synchronized (_inProgress) {
        _inProgress.add(cfg);
    }
    return cfg;
}
Also used : TunnelPoolSettings(net.i2p.router.TunnelPoolSettings) TunnelInfo(net.i2p.router.TunnelInfo) HopConfig(net.i2p.router.tunnel.HopConfig) Hash(net.i2p.data.Hash)

Example 5 with TunnelPoolSettings

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

the class TunnelPoolManager method addAlias.

/**
 *  Add another destination to the same tunnels.
 *  Must have same encryption key and a different signing key.
 *  @throws IllegalArgumentException if not
 *  @return success
 *  @since 0.9.21
 */
public boolean addAlias(Destination dest, ClientTunnelSettings settings, Destination existingClient) {
    if (dest.getSigningPublicKey().equals(existingClient.getSigningPublicKey()))
        throw new IllegalArgumentException("signing key must differ");
    if (!dest.getPublicKey().equals(existingClient.getPublicKey()))
        throw new IllegalArgumentException("encryption key mismatch");
    Hash h = dest.calculateHash();
    Hash e = existingClient.calculateHash();
    synchronized (this) {
        TunnelPool inbound = _clientInboundPools.get(h);
        TunnelPool outbound = _clientOutboundPools.get(h);
        if (inbound != null || outbound != null) {
            if (_log.shouldLog(Log.WARN))
                _log.warn("already have alias " + dest.toBase32());
            return false;
        }
        TunnelPool eInbound = _clientInboundPools.get(e);
        TunnelPool eOutbound = _clientOutboundPools.get(e);
        if (eInbound == null || eOutbound == null) {
            if (_log.shouldLog(Log.WARN))
                _log.warn("primary not found " + existingClient);
            return false;
        }
        eInbound.getSettings().getAliases().add(h);
        eOutbound.getSettings().getAliases().add(h);
        TunnelPoolSettings newIn = settings.getInboundSettings();
        TunnelPoolSettings newOut = settings.getOutboundSettings();
        newIn.setAliasOf(e);
        newOut.setAliasOf(e);
        inbound = new AliasedTunnelPool(_context, this, newIn, eInbound);
        outbound = new AliasedTunnelPool(_context, this, newOut, eOutbound);
        _clientInboundPools.put(h, inbound);
        _clientOutboundPools.put(h, outbound);
        inbound.startup();
        outbound.startup();
    }
    if (_log.shouldLog(Log.WARN))
        _log.warn("Added " + dest.toBase32() + " as alias for " + existingClient.toBase32() + " with settings " + settings);
    return true;
}
Also used : TunnelPoolSettings(net.i2p.router.TunnelPoolSettings) Hash(net.i2p.data.Hash)

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