use of net.i2p.data.Lease 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> <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&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&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(" <b>RAR?</b> ").append(ls.getReceivedAsReply());
BigInteger dist = HashDistance.getDistance(ourRKey, ls.getRoutingKey());
if (ls.getReceivedAsPublished()) {
if (c++ == medianCount)
median = dist;
}
buf.append(" <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(" <b>Encryption Key:</b> ").append(ls.getEncryptionKey().toBase64().substring(0, 20)).append("…");
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();
}
use of net.i2p.data.Lease 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);
}
use of net.i2p.data.Lease in project i2p.i2p by i2p.
the class TunnelPool method locked_buildNewLeaseSet.
/**
* Build a leaseSet with the required tunnels that aren't about to expire.
* Caller must synchronize on _tunnels.
*
* @return null on failure
*/
protected LeaseSet locked_buildNewLeaseSet() {
if (!_alive)
return null;
int wanted = Math.min(_settings.getQuantity(), LeaseSet.MAX_LEASES);
if (_tunnels.size() < wanted) {
if (_log.shouldLog(Log.WARN))
_log.warn(toString() + ": Not enough tunnels (" + _tunnels.size() + ", wanted " + wanted + ")");
// see comment below
if (_tunnels.isEmpty())
return null;
}
// + _settings.getRebuildPeriod();
long expireAfter = _context.clock().now();
TunnelInfo zeroHopTunnel = null;
Lease zeroHopLease = null;
TreeSet<Lease> leases = new TreeSet<Lease>(new LeaseComparator());
for (int i = 0; i < _tunnels.size(); i++) {
TunnelInfo tunnel = _tunnels.get(i);
if (tunnel.getExpiration() <= expireAfter)
// expires too soon, skip it
continue;
if (tunnel.getLength() <= 1) {
// Keep only the one that expires the latest.
if (zeroHopTunnel != null) {
if (zeroHopTunnel.getExpiration() > tunnel.getExpiration())
continue;
if (zeroHopLease != null)
leases.remove(zeroHopLease);
}
zeroHopTunnel = tunnel;
}
TunnelId inId = tunnel.getReceiveTunnelId(0);
Hash gw = tunnel.getPeer(0);
if ((inId == null) || (gw == null)) {
_log.error(toString() + ": broken? tunnel has no inbound gateway/tunnelId? " + tunnel);
continue;
}
Lease lease = new Lease();
// bugfix
// ExpireJob reduces the expiration, which causes a 2nd leaseset with the same lease
// to have an earlier expiration, so it isn't stored.
// Get the "real" expiration from the gateway hop config,
// HopConfig expirations are the same as the "real" expiration and don't change
// see configureNewTunnel()
lease.setEndDate(new Date(((TunnelCreatorConfig) tunnel).getConfig(0).getExpiration()));
lease.setTunnelId(inId);
lease.setGateway(gw);
leases.add(lease);
// remember in case we want to remove it for a later-expiring zero-hopper
if (tunnel.getLength() <= 1)
zeroHopLease = lease;
}
// Do we want a config option for this, or are there times when we shouldn't do this?
if (leases.size() < wanted) {
if (_log.shouldLog(Log.WARN))
_log.warn(toString() + ": Not enough leases (" + leases.size() + ", wanted " + wanted + ")");
if (leases.isEmpty())
return null;
}
LeaseSet ls = new LeaseSet();
Iterator<Lease> iter = leases.iterator();
int count = Math.min(leases.size(), wanted);
for (int i = 0; i < count; i++) ls.addLease(iter.next());
if (_log.shouldLog(Log.INFO))
_log.info(toString() + ": built new leaseSet: " + ls);
return ls;
}
use of net.i2p.data.Lease in project i2p.i2p by i2p.
the class AliasedTunnelPool method locked_buildNewLeaseSet.
@Override
protected LeaseSet locked_buildNewLeaseSet() {
LeaseSet ls = _context.netDb().lookupLeaseSetLocally(_aliasOf.getSettings().getDestination());
if (ls == null)
return null;
// copy everything so it isn't corrupted
LeaseSet rv = new LeaseSet();
for (int i = 0; i < ls.getLeaseCount(); i++) {
Lease old = ls.getLease(i);
Lease lease = new Lease();
lease.setEndDate(old.getEndDate());
lease.setTunnelId(old.getTunnelId());
lease.setGateway(old.getGateway());
rv.addLease(lease);
}
return rv;
}
use of net.i2p.data.Lease in project i2p.i2p by i2p.
the class RequestVariableLeaseSetMessage method doReadMessage.
@Override
protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException {
try {
if (_sessionId != null)
throw new IllegalStateException();
_sessionId = new SessionId();
_sessionId.readBytes(in);
int numTunnels = (int) DataHelper.readLong(in, 1);
for (int i = 0; i < numTunnels; i++) {
Lease lease = new Lease();
lease.readBytes(in);
_endpoints.add(lease);
}
} catch (DataFormatException dfe) {
throw new I2CPMessageException("Unable to load the message data", dfe);
}
}
Aggregations