use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.
the class ProfileOrganizerRenderer method renderStatusHTML.
/**
* @param mode 0 = high cap; 1 = all; 2 = floodfill
*/
public void renderStatusHTML(Writer out, int mode) throws IOException {
boolean full = mode == 1;
Set<Hash> peers = _organizer.selectAllPeers();
long now = _context.clock().now();
long hideBefore = now - 90 * 60 * 1000;
Set<PeerProfile> order = new TreeSet<PeerProfile>(mode == 2 ? new HashComparator() : new ProfileComparator());
int older = 0;
int standard = 0;
for (Hash peer : peers) {
if (_organizer.getUs().equals(peer))
continue;
PeerProfile prof = _organizer.getProfileNonblocking(peer);
if (prof == null)
continue;
if (mode == 2) {
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
if (info != null && info.getCapabilities().indexOf('f') >= 0)
order.add(prof);
continue;
}
if (prof.getLastSendSuccessful() <= hideBefore) {
older++;
continue;
}
if ((!full) && !_organizer.isHighCapacity(peer)) {
standard++;
continue;
}
order.add(prof);
}
int fast = 0;
int reliable = 0;
int integrated = 0;
StringBuilder buf = new StringBuilder(16 * 1024);
// //
if (mode < 2) {
// buf.append("<h2>").append(_t("Peer Profiles")).append("</h2>\n<p>");
buf.append("<p id=\"profiles_overview\" class=\"infohelp\">");
buf.append(ngettext("Showing 1 recent profile.", "Showing {0} recent profiles.", order.size())).append('\n');
if (older > 0)
buf.append(ngettext("Hiding 1 older profile.", "Hiding {0} older profiles.", older)).append('\n');
if (standard > 0)
buf.append("<a href=\"/profiles?f=1\">").append(ngettext("Hiding 1 standard profile.", "Hiding {0} standard profiles.", standard)).append("</a>\n");
buf.append("</p>");
buf.append("<div class=\"widescroll\"><table id=\"profilelist\">");
buf.append("<tr>");
buf.append("<th>").append(_t("Peer")).append("</th>");
buf.append("<th>").append(_t("Groups")).append("</th>");
buf.append("<th>").append(_t("Caps")).append("</th>");
buf.append("<th>").append(_t("Version")).append("</th>");
buf.append("<th>").append(_t("Speed")).append("</th>");
buf.append("<th>").append(_t("Capacity")).append("</th>");
buf.append("<th>").append(_t("Integration")).append("</th>");
buf.append("<th>").append(_t("Status")).append("</th>");
buf.append("<th>").append(_t("View/Edit")).append("</th>");
buf.append("</tr>");
int prevTier = 1;
for (PeerProfile prof : order) {
Hash peer = prof.getPeer();
int tier = 0;
boolean isIntegrated = false;
if (_organizer.isFast(peer)) {
tier = 1;
fast++;
reliable++;
} else if (_organizer.isHighCapacity(peer)) {
tier = 2;
reliable++;
} else if (_organizer.isFailing(peer)) {
} else {
tier = 3;
}
if (_organizer.isWellIntegrated(peer)) {
isIntegrated = true;
integrated++;
}
if (tier != prevTier)
buf.append("<tr><td colspan=\"9\"><hr></td></tr>\n");
prevTier = tier;
buf.append("<tr><td align=\"center\" nowrap>");
buf.append(_context.commSystem().renderPeerHTML(peer));
// debug
// if(prof.getIsExpandedDB())
// buf.append(" ** ");
buf.append("</td><td align=\"center\">");
switch(tier) {
case 1:
buf.append(_t("Fast, High Capacity"));
break;
case 2:
buf.append(_t("High Capacity"));
break;
case 3:
buf.append(_t("Standard"));
break;
default:
buf.append(_t("Failing"));
break;
}
if (isIntegrated)
buf.append(", ").append(_t("Integrated"));
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
if (info != null) {
// prevent HTML injection in the caps and version
buf.append("<td align=\"right\">").append(DataHelper.stripHTML(info.getCapabilities()));
} else {
buf.append("<td align=\"right\"><i>").append(_t("unknown")).append("</i></td>");
}
buf.append("<td align=\"right\">");
String v = info != null ? info.getOption("router.version") : null;
if (v != null)
buf.append(DataHelper.stripHTML(v));
buf.append("</td><td align=\"right\">").append(num(prof.getSpeedValue()));
long bonus = prof.getSpeedBonus();
if (bonus != 0) {
if (bonus > 0)
buf.append(" (+");
else
buf.append(" (");
buf.append(bonus).append(')');
}
buf.append("</td><td align=\"right\">").append(num(prof.getCapacityValue()));
bonus = prof.getCapacityBonus();
if (bonus != 0) {
if (bonus > 0)
buf.append(" (+");
else
buf.append(" (");
buf.append(bonus).append(')');
}
buf.append("</td><td align=\"right\">").append(num(prof.getIntegrationValue()));
buf.append("</td><td align=\"center\">");
boolean ok = true;
if (_context.banlist().isBanlisted(peer)) {
buf.append(_t("Banned"));
ok = false;
}
if (prof.getIsFailing()) {
buf.append(' ').append(_t("Failing"));
ok = false;
}
if (_context.commSystem().wasUnreachable(peer)) {
buf.append(' ').append(_t("Unreachable"));
ok = false;
}
RateAverages ra = RateAverages.getTemp();
Rate failed = prof.getTunnelHistory().getFailedRate().getRate(30 * 60 * 1000);
long fails = failed.computeAverages(ra, false).getTotalEventCount();
if (ok && fails == 0) {
buf.append(_t("OK"));
} else if (fails > 0) {
Rate accepted = prof.getTunnelCreateResponseTime().getRate(30 * 60 * 1000);
long total = fails + accepted.computeAverages(ra, false).getTotalEventCount();
if (// hide if < 10%
total / fails <= 10)
buf.append(' ').append(fails).append('/').append(total).append(' ').append(_t("Test Fails"));
}
buf.append(" </td>");
// buf.append("<td nowrap align=\"center\"><a target=\"_blank\" href=\"dumpprofile.jsp?peer=")
// .append(peer.toBase64().substring(0,6)).append("\">").append(_t("profile")).append("</a>");
buf.append("<td nowrap align=\"center\"><a href=\"viewprofile?peer=").append(peer.toBase64()).append("\">").append(_t("profile")).append("</a>");
buf.append(" <a title=\"").append(_t("Configure peer")).append("\" href=\"configpeer?peer=").append(peer.toBase64()).append("\">+-</a></td>\n");
buf.append("</tr>");
// let's not build the whole page in memory (~500 bytes per peer)
out.write(buf.toString());
buf.setLength(0);
}
buf.append("</table></div>");
// //
// // don't bother reindenting
// //
} else {
// buf.append("<h2><a name=\"flood\"></a>").append(_t("Floodfill and Integrated Peers"))
// .append(" (").append(integratedPeers.size()).append(")</h2>\n");
buf.append("<div class=\"widescroll\"><table id=\"floodfills\">");
buf.append("<tr class=\"smallhead\">");
buf.append("<th>").append(_t("Peer")).append("</th>");
buf.append("<th>").append(_t("Caps")).append("</th>");
buf.append("<th>").append(_t("Integ. Value")).append("</th>");
buf.append("<th>").append(_t("Last Heard About")).append("</th>");
buf.append("<th>").append(_t("Last Heard From")).append("</th>");
buf.append("<th>").append(_t("Last Good Send")).append("</th>");
buf.append("<th>").append(_t("Last Bad Send")).append("</th>");
buf.append("<th>").append(_t("10m Resp. Time")).append("</th>");
buf.append("<th>").append(_t("1h Resp. Time")).append("</th>");
buf.append("<th>").append(_t("1d Resp. Time")).append("</th>");
buf.append("<th>").append(_t("Last Good Lookup")).append("</th>");
buf.append("<th>").append(_t("Last Bad Lookup")).append("</th>");
buf.append("<th>").append(_t("Last Good Store")).append("</th>");
buf.append("<th>").append(_t("Last Bad Store")).append("</th>");
buf.append("<th>").append(_t("1h Fail Rate")).append("</th>");
buf.append("<th>").append(_t("1d Fail Rate")).append("</th>");
buf.append("</tr>");
RateAverages ra = RateAverages.getTemp();
for (PeerProfile prof : order) {
Hash peer = prof.getPeer();
buf.append("<tr><td align=\"center\" nowrap>");
buf.append(_context.commSystem().renderPeerHTML(peer));
buf.append("</td>");
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
if (info != null)
buf.append("<td align=\"center\">").append(DataHelper.stripHTML(info.getCapabilities())).append("</td>");
else
buf.append("<td> </td>");
buf.append("<td align=\"right\">").append(num(prof.getIntegrationValue())).append("</td>");
buf.append("<td align=\"right\">").append(formatInterval(now, prof.getLastHeardAbout())).append("</td>");
buf.append("<td align=\"right\">").append(formatInterval(now, prof.getLastHeardFrom())).append("</td>");
buf.append("<td align=\"right\">").append(formatInterval(now, prof.getLastSendSuccessful())).append("</td>");
buf.append("<td align=\"right\">").append(formatInterval(now, prof.getLastSendFailed())).append("</td>");
buf.append("<td align=\"right\">").append(avg(prof, 10 * 60 * 1000l, ra)).append("</td>");
buf.append("<td align=\"right\">").append(avg(prof, 60 * 60 * 1000l, ra)).append("</td>");
buf.append("<td align=\"right\">").append(avg(prof, 24 * 60 * 60 * 1000l, ra)).append("</td>");
DBHistory dbh = prof.getDBHistory();
if (dbh != null) {
buf.append("<td align=\"right\">").append(formatInterval(now, dbh.getLastLookupSuccessful())).append("</td>");
buf.append("<td align=\"right\">").append(formatInterval(now, dbh.getLastLookupFailed())).append("</td>");
buf.append("<td align=\"right\">").append(formatInterval(now, dbh.getLastStoreSuccessful())).append("</td>");
buf.append("<td align=\"right\">").append(formatInterval(now, dbh.getLastStoreFailed())).append("</td>");
buf.append("<td align=\"right\">").append(davg(dbh, 60 * 60 * 1000l, ra)).append("</td>");
buf.append("<td align=\"right\">").append(davg(dbh, 24 * 60 * 60 * 1000l, ra)).append("</td>");
} else {
for (int i = 0; i < 6; i++) buf.append("<td align=\"right\">").append(_t(NA));
}
buf.append("</tr>\n");
}
buf.append("</table></div>");
// //
// // don't bother reindenting
// //
}
if (mode < 2) {
buf.append("<h3 class=\"tabletitle\">").append(_t("Thresholds")).append("</h3>\n").append("<table id=\"thresholds\"><tbody>").append("<tr><th><b>").append(_t("Speed")).append(": </b>").append(num(_organizer.getSpeedThreshold())).append("</th><th><b>").append(_t("Capacity")).append(": </b>").append(num(_organizer.getCapacityThreshold())).append("</th><th><b>").append(_t("Integration")).append(": </b>").append(num(_organizer.getIntegrationThreshold())).append("</th></tr><tr><td>").append(fast).append(' ').append(_t("fast peers")).append("</td><td>").append(reliable).append(' ').append(_t("high capacity peers")).append("</td><td>").append(integrated).append(' ').append(_t(" well integrated peers")).append("</td></tr></tbody></table>\n");
buf.append("<h3 class=\"tabletitle\">").append(_t("Definitions")).append("</h3>\n").append("<table id=\"profile_defs\"><tbody>");
buf.append("<tr><td><b>").append(_t("groups")).append(":</b></td><td>").append(_t("as determined by the profile organizer")).append("</td></tr>");
buf.append("<tr><td><b>").append(_t("caps")).append(":</b></td><td>").append(_t("capabilities in the netDb, not used to determine profiles")).append("</td></tr>");
buf.append("<tr id=\"capabilities_key\"><td colspan=\"2\"><table><tbody>");
buf.append("<tr><td> </td>").append("<td><b>B</b></td><td>").append(_t("SSU Testing")).append("</td>").append("<td><b>C</b></td><td>").append(_t("SSU Introducer")).append("</td>").append("<td> </td></tr>");
buf.append("<tr><td> </td>").append("<td><b>f</b></td><td>").append(_t("Floodfill")).append("</td>").append("<td><b>H</b></td><td>").append(_t("Hidden")).append("</td>").append("<td> </td></tr>");
buf.append("<tr><td> </td>").append("<td><b>K</b></td><td>").append(_t("Under {0} shared bandwidth", Router.MIN_BW_L + " KBps")).append("</td>").append("<td><b>L</b></td><td>").append(_t("{0} shared bandwidth", range(Router.MIN_BW_L, Router.MIN_BW_M))).append("</td>").append("<td> </td></tr>");
buf.append("<tr><td> </td>").append("<td><b>M</b></td><td>").append(_t("{0} shared bandwidth", range(Router.MIN_BW_M, Router.MIN_BW_N))).append("</td>").append("<td><b>N</b></td><td>").append(_t("{0} shared bandwidth", range(Router.MIN_BW_N, Router.MIN_BW_O))).append("</td>").append("<td> </td></tr>");
buf.append("<tr><td> </td>").append("<td><b>O</b></td><td>").append(_t("{0} shared bandwidth", range(Router.MIN_BW_O, Router.MIN_BW_P))).append("</td>").append("<td><b>P</b></td><td>").append(_t("{0} shared bandwidth", range(Router.MIN_BW_P, Router.MIN_BW_X))).append("</td>").append("<td> </td></tr>");
buf.append("<tr><td> </td>").append("<td><b>R</b></td><td>").append(_t("Reachable")).append("</td>").append("<td><b>U</b></td><td>").append(_t("Unreachable")).append("</td>").append("<td> </td></tr>");
buf.append("<tr><td> </td>").append("<td><b>X</b></td><td>").append(_t("Over {0} shared bandwidth", Math.round(Router.MIN_BW_X * 1.024f) + " KBps")).append("</td>").append("<td> </td><td> </td><td> </td></tr>");
buf.append("<tr><td> </td><td colspan=\"5\">").append(_t("Note: For P and X bandwidth tiers, O is included for the purpose of backward compatibility in the NetDB.")).append("</tr>");
// profile_defs
buf.append("</tbody></table></td></tr>");
buf.append("<tr><td><b>").append(_t("speed")).append(":</b></td><td>").append(_t("peak throughput (bytes per second) over a 1 minute period that the peer has sustained in a single tunnel")).append("</td></tr>");
buf.append("<tr><td><b>").append(_t("capacity")).append(":</b></td><td>").append(_t("how many tunnels can we ask them to join in an hour?")).append("</td></tr>");
buf.append("<tr><td><b>").append(_t("integration")).append(":</b></td><td>").append(_t("how many new peers have they told us about lately?")).append("</td></tr>");
buf.append("<tr><td><b>").append(_t("status")).append(":</b></td><td>").append(_t("is the peer banned, or unreachable, or failing tunnel tests?")).append("</td></tr>");
// thresholds
buf.append("</tbody></table>\n");
// //
// // don't bother reindenting
// //
}
// mode < 2
out.write(buf.toString());
out.flush();
}
use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.
the class ProofHelper method getProof.
public String getProof() {
StringBuilder buf = new StringBuilder(512);
RouterInfo us = _context.router().getRouterInfo();
buf.append("Hash: ").append(us.getIdentity().calculateHash().toBase64()).append('\n');
// buf.append("Ident: ").append(us.getIdentity().toBase64()).append('\n');
for (RouterAddress addr : us.getAddresses()) {
buf.append(addr.getTransportStyle()).append(": ").append(addr.getHost()).append('\n');
}
buf.append("Caps: ").append(us.getCapabilities()).append('\n');
// no trailing newline
buf.append("Date: ").append(new Date());
String msg = buf.toString();
byte[] data = DataHelper.getUTF8(msg);
Signature sig = _context.dsa().sign(data, _context.keyManager().getSigningPrivateKey());
buf.setLength(0);
buf.append("---BEGIN I2P SIGNED MESSAGE---\n");
buf.append(msg);
buf.append("\n---BEGIN I2P SIGNATURE---\n");
buf.append(sig.toBase64());
buf.append("\n---END I2P SIGNATURE---");
return buf.toString();
}
use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.
the class SybilRenderer method renderIPGroupsFamily.
private void renderIPGroupsFamily(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException {
buf.append("<h3 id=\"samefamily\" class=\"sybils\">Floodfills in the Same Declared Family</h3><div class=\"sybil_container\">");
ObjectCounter<String> oc = new ObjectCounter<String>();
for (RouterInfo info : ris) {
String fam = info.getOption("family");
if (fam == null)
continue;
oc.increment(fam);
}
List<String> foo = new ArrayList<String>(oc.objects());
Collections.sort(foo, new FoofComparator(oc));
FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto();
String ourFamily = fkc != null ? fkc.getOurFamilyName() : null;
boolean found = false;
for (String s : foo) {
int count = oc.count(s);
String ss = DataHelper.escapeHTML(s);
if (count > 1) {
buf.append("<p class=\"family\"><b>").append(count).append(" floodfills in family: <a href=\"/netdb?fam=").append(ss).append("&sybil\">").append(ss).append("</a></b></p>");
}
for (RouterInfo info : ris) {
String fam = info.getOption("family");
if (fam == null)
continue;
if (!fam.equals(s))
continue;
found = true;
// limit display
// renderRouterInfo(buf, info, null, false, false);
double point = POINTS_FAMILY;
if (fkc != null && s.equals(ourFamily)) {
if (fkc.verifyOurFamily(info))
addPoints(points, info.getHash(), POINTS_OUR_FAMILY, "Our family \"" + DataHelper.escapeHTML(s) + "\" with " + (count - 1) + " other" + ((count > 2) ? "s" : ""));
else
addPoints(points, info.getHash(), POINTS_BAD_OUR_FAMILY, "Spoofed our family \"" + DataHelper.escapeHTML(s) + "\" with " + (count - 1) + " other" + ((count > 2) ? "s" : ""));
} else if (count > 1) {
addPoints(points, info.getHash(), point, "Same declared family \"" + DataHelper.escapeHTML(s) + "\" with " + (count - 1) + " other" + ((count > 2) ? "s" : ""));
} else {
addPoints(points, info.getHash(), point, "Declared family \"" + DataHelper.escapeHTML(s) + '"');
}
}
}
if (!found)
buf.append("<p class=\"notfound\">None</p>");
buf.append("</div>");
out.write(buf.toString());
out.flush();
buf.setLength(0);
}
use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.
the class SybilRenderer method addVersionPoints.
private void addVersionPoints(List<RouterInfo> ris, Map<Hash, Points> points) {
RouterInfo us = _context.router().getRouterInfo();
if (us == null)
return;
String ourVer = us.getVersion();
if (!ourVer.startsWith("0.9."))
return;
ourVer = ourVer.substring(4);
int dot = ourVer.indexOf('.');
if (dot > 0)
ourVer = ourVer.substring(0, dot);
int minor;
try {
minor = Integer.parseInt(ourVer);
} catch (NumberFormatException nfe) {
return;
}
for (RouterInfo info : ris) {
Hash h = info.getHash();
String caps = info.getCapabilities();
if (!caps.contains("R"))
addPoints(points, h, POINTS_UNREACHABLE, "Unreachable: " + DataHelper.escapeHTML(caps));
String hisFullVer = info.getVersion();
if (!hisFullVer.startsWith("0.9.")) {
addPoints(points, h, POINTS_BAD_VERSION, "Strange version " + DataHelper.escapeHTML(hisFullVer));
continue;
}
String hisVer = hisFullVer.substring(4);
dot = hisVer.indexOf('.');
if (dot > 0)
hisVer = hisVer.substring(0, dot);
int hisMinor;
try {
hisMinor = Integer.parseInt(hisVer);
} catch (NumberFormatException nfe) {
continue;
}
int howOld = minor - hisMinor;
if (howOld < 3)
continue;
addPoints(points, h, howOld * VERSION_FACTOR, howOld + " versions behind: " + DataHelper.escapeHTML(hisFullVer));
}
}
use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.
the class SybilRenderer method renderIPGroups24.
private void renderIPGroups24(Writer out, StringBuilder buf, List<RouterInfo> ris, Map<Hash, Points> points) throws IOException {
buf.append("<h3 id=\"same24\" class=\"sybils\">Floodfills in the Same /24 (2 minimum)</h3>");
ObjectCounter<Integer> oc = new ObjectCounter<Integer>();
for (RouterInfo info : ris) {
byte[] ip = getIP(info);
if (ip == null)
continue;
Integer x = Integer.valueOf((int) DataHelper.fromLong(ip, 0, 3));
oc.increment(x);
}
List<Integer> foo = new ArrayList<Integer>();
for (Integer ii : oc.objects()) {
int count = oc.count(ii);
if (count >= 2)
foo.add(ii);
}
Collections.sort(foo, new FooComparator(oc));
boolean found = false;
for (Integer ii : foo) {
int count = oc.count(ii);
int i = ii.intValue();
int i0 = i >> 16;
int i1 = (i >> 8) & 0xff;
int i2 = i & 0xff;
String sip = i0 + "." + i1 + '.' + i2 + ".0/24";
buf.append("<p class=\"sybil_info\"><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=").append(sip).append("&sybil\">").append(sip).append("</a>:</b></p>");
for (RouterInfo info : ris) {
byte[] ip = getIP(info);
if (ip == null)
continue;
if ((ip[0] & 0xff) != i0)
continue;
if ((ip[1] & 0xff) != i1)
continue;
if ((ip[2] & 0xff) != i2)
continue;
found = true;
renderRouterInfo(buf, info, null, false, false);
double point = POINTS24 * (count - 1);
addPoints(points, info.getHash(), point, "Same /24 IP with " + (count - 1) + " other" + ((count > 2) ? "s" : ""));
}
}
if (!found)
buf.append("<p class=\"notfound\">None</p>");
out.write(buf.toString());
out.flush();
buf.setLength(0);
}
Aggregations