* ExploratoryPeerSelector: Try NonFailing even more
* HostsTxtNamingService: Add reverse lookup support * Outbound message: Minor cleanup * i2psnark TrackerCLient: Minor cleanup * checklist.txt: Minor edit * hosts.txt: Add perv.i2p, false.i2p, mtn.i2p2.i2p * i2ptunnel.config: Change CVS client to mtn * netdb.jsp: Show leaseSet destinations using reverse lookup * profiles.jsp: First cut at showing floodfill data
This commit is contained in:
@ -275,8 +275,11 @@ public class TrackerClient extends I2PThread
|
||||
tr.stop = true;
|
||||
}
|
||||
}
|
||||
if (++tr.consecutiveFails == MAX_CONSEC_FAILS && tr.interval < LONG_SLEEP)
|
||||
tr.interval = LONG_SLEEP; // slow down
|
||||
if (++tr.consecutiveFails == MAX_CONSEC_FAILS) {
|
||||
tr.seenPeers = 0;
|
||||
if (tr.interval < LONG_SLEEP)
|
||||
tr.interval = LONG_SLEEP; // slow down
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((!tr.stop) && maxSeenPeers < tr.seenPeers)
|
||||
|
@ -14,6 +14,10 @@ Change revision in:
|
||||
router/java/src/net/i2p/router/RouterVersion.java
|
||||
core/java/src/net/i2p/CoreVersion.java
|
||||
|
||||
Review the complete diff from the last release:
|
||||
mtn diff -r t:i2p-0.6.1.(xx-1) > out.diff
|
||||
vi out.diff
|
||||
|
||||
Build and tag:
|
||||
ant pkg
|
||||
mtn ci
|
||||
|
@ -9,8 +9,10 @@ package net.i2p.client.naming;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
@ -87,6 +89,28 @@ public class HostsTxtNamingService extends NamingService {
|
||||
}
|
||||
|
||||
public String reverseLookup(Destination dest) {
|
||||
String destkey = dest.toBase64();
|
||||
List filenames = getFilenames();
|
||||
for (int i = 0; i < filenames.size(); i++) {
|
||||
String hostsfile = (String)filenames.get(i);
|
||||
Properties hosts = new Properties();
|
||||
try {
|
||||
File f = new File(hostsfile);
|
||||
if ( (f.exists()) && (f.canRead()) ) {
|
||||
DataHelper.loadProps(hosts, f, true);
|
||||
Set keyset = hosts.keySet();
|
||||
Iterator iter = keyset.iterator();
|
||||
while (iter.hasNext()) {
|
||||
String host = (String)iter.next();
|
||||
String key = hosts.getProperty(host);
|
||||
if (destkey.equals(key))
|
||||
return host;
|
||||
}
|
||||
}
|
||||
} catch (Exception ioe) {
|
||||
_log.error("Error loading hosts file " + hostsfile, ioe);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
12
history.txt
12
history.txt
@ -1,3 +1,14 @@
|
||||
2008-03-30 zzz
|
||||
* ExploratoryPeerSelector: Try NonFailing even more
|
||||
* HostsTxtNamingService: Add reverse lookup support
|
||||
* Outbound message: Minor cleanup
|
||||
* i2psnark TrackerCLient: Minor cleanup
|
||||
* checklist.txt: Minor edit
|
||||
* hosts.txt: Add perv.i2p, false.i2p, mtn.i2p2.i2p
|
||||
* i2ptunnel.config: Change CVS client to mtn
|
||||
* netdb.jsp: Show leaseSet destinations using reverse lookup
|
||||
* profiles.jsp: First cut at showing floodfill data
|
||||
|
||||
2008-03-27 zzz
|
||||
* Send messages for the same destination to the same inbound
|
||||
lease to reduce out-of-order delivery.
|
||||
@ -16,6 +27,7 @@
|
||||
- Don't have eepget retry announces
|
||||
- Slow down tracker contacts if they've failed for a while
|
||||
- Add some debug support showing connections (?p=2)
|
||||
* hosts.txt: Add nickyb.i2p, tracker.welterde.i2p
|
||||
|
||||
2008-03-22 zzz
|
||||
* NewsFetcher: Fix bug causing fetch every 10m
|
||||
|
@ -302,3 +302,6 @@ www.i2p2.i2p=-KR6qyfPWXoN~F3UzzYSMIsaRy4udcRkHu2Dx9syXSzUQXQdi2Af1TV2UMH3PpPuNu-
|
||||
i2p-projekt.i2p=8ZAW~KzGFMUEj0pdchy6GQOOZbuzbqpWtiApEj8LHy2~O~58XKxRrA43cA23a9oDpNZDqWhRWEtehSnX5NoCwJcXWWdO1ksKEUim6cQLP-VpQyuZTIIqwSADwgoe6ikxZG0NGvy5FijgxF4EW9zg39nhUNKRejYNHhOBZKIX38qYyXoB8XCVJybKg89aMMPsCT884F0CLBKbHeYhpYGmhE4YW~aV21c5pebivvxeJPWuTBAOmYxAIgJE3fFU-fucQn9YyGUFa8F3t-0Vco-9qVNSEWfgrdXOdKT6orr3sfssiKo3ybRWdTpxycZ6wB4qHWgTSU5A-gOA3ACTCMZBsASN3W5cz6GRZCspQ0HNu~R~nJ8V06Mmw~iVYOu5lDvipmG6-dJky6XRxCedczxMM1GWFoieQ8Ysfuxq-j8keEtaYmyUQme6TcviCEvQsxyVirr~dTC-F8aZ~y2AlG5IJz5KD02nO6TRkI2fgjHhv9OZ9nskh-I2jxAzFP6Is1kyAAAA
|
||||
nickyb.i2p=9On6d3cZ27JjwYCtyJJbowe054d5tFnfMjv4PHsYs-EQn4Y4mk2zRixatvuAyXz2MmRfXG-NAUfhKr0KCxRNZbvHmlckYfT-WBzwwpiMAl0wDFY~Pl8cqXuhfikSG5WrqdPfDNNIBuuznS0dqaczf~OyVaoEOpvuP3qV6wKqbSSLpjOwwAaQPHjlRtNIW8-EtUZp-I0LT45HSoowp~6b7zYmpIyoATvIP~sT0g0MTrczWhbVTUZnEkZeLhOR0Duw1-IRXI2KHPbA24wLO9LdpKKUXed05RTz0QklW5ROgR6TYv7aXFufX8kC0-DaKvQ5JKG~h8lcoHvm1RCzNqVE-2aiZnO2xH08H-iCWoLNJE-Td2kT-Tsc~3QdQcnEUcL5BF-VT~QYRld2--9r0gfGl-yDrJZrlrihHGr5J7ImahelNn9PpkVp6eIyABRmJHf2iicrk3CtjeG1j9OgTSwaNmEpUpn4aN7Kx0zNLdH7z6uTgCGD9Kmh1MFYrsoNlTp4AAAA
|
||||
tracker.welterde.i2p=BGKmlDOoH3RzFbPRfRpZV2FjpVj8~3moFftw5-dZfDf2070TOe8Tf2~DAVeaM6ZRLdmFEt~9wyFL8YMLMoLoiwGEH6IGW6rc45tstN68KsBDWZqkTohV1q9XFgK9JnCwE~Oi89xLBHsLMTHOabowWM6dkC8nI6QqJC2JODqLPIRfOVrDdkjLwtCrsckzLybNdFmgfoqF05UITDyczPsFVaHtpF1sRggOVmdvCM66otyonlzNcJbn59PA-R808vUrCPMGU~O9Wys0i-NoqtIbtWfOKnjCRFMNw5ex4n9m5Sxm9e20UkpKG6qzEuvKZWi8vTLe1NW~CBrj~vG7I3Ok4wybUFflBFOaBabxYJLlx4xTE1zJIVxlsekmAjckB4v-cQwulFeikR4LxPQ6mCQknW2HZ4JQIq6hL9AMabxjOlYnzh7kjOfRGkck8YgeozcyTvcDUcUsOuSTk06L4kdrv8h2Cozjbloi5zl6KTbj5ZTciKCxi73Pn9grICn-HQqEAAAA
|
||||
perv.i2p=HazSt3kSqVjpMO9Ol9HPjXCfzTLurOPjSeN47UxMLLs4lm5SJJHP-p3vA4sTfxrR3z7Cqq5Nd0t1gog~bV0PCbnKNsTiF~pSPBIFXOPVe5RuX7keDRJ-Mp5-quPIe2FFNEOz7HNkbuz6aHYN74T5Cs2VcMDEvL9Wz~oxV7FPSijD1qs1hi~f3byvSvswRkt4w7A10iJvunq43r1jOi6JwS~lAChP1q7t16sfhtWp4XEaEvfES0bIbnTsRv-aDVy0Kp4zYYPuZstit-S8GHkS7ceDRHSoid1O6V1WgogeDoTRzfxfHqQb5db5xWt4DXmnQbb7xysXub-2S3mbog-WnoawDRM5ZJDItCDuMsg0edIn5RJYkANh0Qox-JMVUZdU8tcx--DX9gONJ4cm4a-MLxY9dme~Zq4hqJJRNRvrRcA11ZuLH-ZN3aTXL70Yod-YyNPcechGrpugKEU38g5sDyj77pX~IrdaTVTFpJE6zlClRatTnl4Enhr4pQ7gWFpcAAAA
|
||||
false.i2p=V5EeX1UrVanCQhE9q-Nj5UFRyQiH6b~lSO7qe8hgxGZkymrpHFZ5j5D9rVOjsogokon1bZF5NPlPdzI~d4Ap7UyqBR~90vhFxsIKednRZLdf46JgjYTZq~ct-Bi3sdpBXdg04L8i4dStE4jkdvl6NF96MfQKdt6mtYFeaXb0XhPx~04NECG5~y~mTYcMjcvrftt5uulLbT6TcGmJ0KV5Xu2UVnkN3zOaQEObIIDZT4wkz9jOqaiJzMHNJqWc4GU4ocIfwxeMkSn9qvA0Q1AXuM~z11~wgHYLVEFoN5k0O4aB8b1r1WtpZTojZ9ADThW89q~AcD981nIYnRp59cmyqBdN7X-71cBrKC7QfnCRJpbwoVrn7kePw1dCu6Bobnd4~a74abxjFeCxVzQxSTbkey6f~wJXE2JPAqfsM1EKXsdqUZQJOP0ngQu16srSpqMSxkqHzlr3US~Vn9EgMcHuDCkdctwo7stwn0UQ34sSF9sLhtmlHIGqatDhfmYEGmSiAAAA
|
||||
mtn.i2p2.i2p=G6VmsrLYbdcxBq585OUcQn7wbwC7J5jfXDWWL6lPBw5iq68VxqxibraiPwwF6NM2aHV8BkqyCKYSL9fUuYWoeUc1zL~2l1DX2x~LfyItGJKDIUGImWQivXF1w7EGYMhjq4UCmPKTsnl4G86oKW8PGaaF8mzjjUKW1R7G7941my~mnbeTrhjlLgaMK-tauVodgTPIYkxfMJaq3zWuirztuUgDcXXIbkpzaA2Iben0VqbjbMJisj4fFh0EvqNkYAG54YBc26~W6SPWyBgZilXvFlcizF90Q5NkIGMMHXTq46qEYHkpQC3CoaH6PMNVDetDPmFc3QXmc68cNcj~VPh4XVsn3qiKhXuRdXggEC3RoTcxqaeassfIG5xhRdnJzGSVhYUE3At~8wI-AuRV~AglV1Q-AZTWT~9VxBzcxfI1PpfzeA-5z5T4542bh1e-RM9tzXEx5ErPCt6M~zJ2~4-tz-aBsZEhBkn0iDi8pazshg6lTl1~hCnueZBxYICqPrlBAAAA
|
||||
|
@ -29,14 +29,14 @@ tunnel.1.option.i2p.streaming.connectDelay=1000
|
||||
tunnel.1.option.i2p.streaming.maxWindowSize=1
|
||||
tunnel.1.startOnLoad=true
|
||||
|
||||
# I2P's cvs server
|
||||
tunnel.2.name=cvs.i2p
|
||||
tunnel.2.description=I2P CVS pserver
|
||||
# I2P's mtn server
|
||||
tunnel.2.name=mtn.i2p2.i2p
|
||||
tunnel.2.description=I2P Monotone Server
|
||||
tunnel.2.type=client
|
||||
tunnel.2.sharedClient=true
|
||||
tunnel.2.interface=127.0.0.1
|
||||
tunnel.2.listenPort=2401
|
||||
tunnel.2.targetDestination=cvs.i2p
|
||||
tunnel.2.listenPort=8998
|
||||
tunnel.2.targetDestination=mtn.i2p2.i2p
|
||||
tunnel.2.i2cpHost=127.0.0.1
|
||||
tunnel.2.i2cpPort=7654
|
||||
tunnel.2.option.inbound.nickname=shared clients
|
||||
|
@ -17,7 +17,7 @@ import net.i2p.CoreVersion;
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.548 $ $Date: 2008-02-10 15:00:00 $";
|
||||
public final static String VERSION = "0.6.1.32";
|
||||
public final static long BUILD = 13;
|
||||
public final static long BUILD = 14;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
||||
System.out.println("Router ID: " + RouterVersion.ID);
|
||||
|
@ -228,6 +228,9 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
* simultaneously talking to the same dest is probably rare enough
|
||||
* to not bother separating out.
|
||||
*
|
||||
* We're going to use the lease until it expires, not even looking for a newer lease.
|
||||
* So if the inbound tunnel fails and the dest publishes a new lease, we won't know about it.
|
||||
*
|
||||
* If not found,
|
||||
* fetch the next lease that we should try sending through, randomly chosen
|
||||
* from within the sorted leaseSet (NOT sorted by # of failures through each
|
||||
@ -244,8 +247,9 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
return false;
|
||||
}
|
||||
long now = getContext().clock().now();
|
||||
|
||||
|
||||
// Use the same lease if it's still good
|
||||
// Even if _leaseSet changed, _leaseSet.getEncryptionKey() didn't...
|
||||
synchronized (_leaseCache) {
|
||||
if (now - _cleanTime > 5*60*1000) { // clean out periodically
|
||||
cleanLeaseCache(_leaseCache);
|
||||
@ -254,12 +258,12 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
_lease = (Lease) _leaseCache.get(_to);
|
||||
if (_lease != null) {
|
||||
if (!_lease.isExpired()) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Found in cache - lease for dest " + _to.calculateHash().toBase64());
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Found in cache - lease for " + _toString);
|
||||
return true;
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Expired from cache - lease for dest " + _to.calculateHash().toBase64());
|
||||
_log.warn("Expired from cache - lease for " + _toString);
|
||||
_leaseCache.remove(_to);
|
||||
}
|
||||
}
|
||||
@ -288,6 +292,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
// sort are randomly ordered)
|
||||
Collections.shuffle(leases);
|
||||
|
||||
/****
|
||||
if (false) {
|
||||
// ordered by lease number of failures
|
||||
TreeMap orderedLeases = new TreeMap();
|
||||
@ -303,13 +308,14 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
|
||||
_lease = (Lease)orderedLeases.get(orderedLeases.firstKey());
|
||||
} else {
|
||||
****/
|
||||
_lease = (Lease)leases.get(0);
|
||||
}
|
||||
// }
|
||||
synchronized (_leaseCache) {
|
||||
_leaseCache.put(_to, _lease);
|
||||
}
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Added to cache - lease for dest " + _to.calculateHash().toBase64());
|
||||
_log.warn("Added to cache - lease for " + _toString);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -538,7 +544,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
if (getContext().tunnelManager().isValidTunnel(_from.calculateHash(), tunnel)) {
|
||||
if (!getContext().commSystem().isBacklogged(tunnel.getPeer(1))) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Switching back to tunnel " + tunnel + " for dest " + to.calculateHash().toBase64());
|
||||
_log.warn("Switching back to tunnel " + tunnel + " for " + _toString);
|
||||
_backloggedTunnelCache.remove(to);
|
||||
_tunnelCache.put(to, tunnel);
|
||||
return tunnel;
|
||||
@ -554,7 +560,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
return tunnel;
|
||||
// backlogged
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Switching from backlogged " + tunnel + " for dest " + to.calculateHash().toBase64());
|
||||
_log.warn("Switching from backlogged " + tunnel + " for " + _toString);
|
||||
_backloggedTunnelCache.put(to, tunnel);
|
||||
} // else no longer valid
|
||||
_tunnelCache.remove(to);
|
||||
|
@ -21,9 +21,11 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataStructure;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.Lease;
|
||||
import net.i2p.data.LeaseSet;
|
||||
@ -39,6 +41,7 @@ import net.i2p.router.networkdb.DatabaseLookupMessageHandler;
|
||||
import net.i2p.router.networkdb.DatabaseStoreMessageHandler;
|
||||
import net.i2p.router.networkdb.PublishLocalRouterInfoJob;
|
||||
import net.i2p.router.peermanager.PeerProfile;
|
||||
import net.i2p.router.TunnelPoolSettings;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -934,8 +937,28 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
long now = _context.clock().now();
|
||||
for (Iterator iter = leases.iterator(); iter.hasNext(); ) {
|
||||
LeaseSet ls = (LeaseSet)iter.next();
|
||||
Hash key = ls.getDestination().calculateHash();
|
||||
buf.append("<b>LeaseSet: ").append(key.toBase64()).append("</b><br />\n");
|
||||
Destination dest = ls.getDestination();
|
||||
Hash key = dest.calculateHash();
|
||||
buf.append("<b>LeaseSet: ").append(key.toBase64());
|
||||
if (_context.clientManager().isLocal(dest)) {
|
||||
buf.append(" (<a href=\"tunnels.jsp#" + key.toBase64().substring(0,4) + "\">Local</a> ");
|
||||
if (! _context.clientManager().shouldPublishLeaseSet(key))
|
||||
buf.append("Unpublished ");
|
||||
buf.append("Destination ");
|
||||
TunnelPoolSettings in = _context.tunnelManager().getInboundSettings(key);
|
||||
if (in != null && in.getDestinationNickname() != null)
|
||||
buf.append(in.getDestinationNickname());
|
||||
else
|
||||
buf.append(dest.toBase64().substring(0, 6));
|
||||
} else {
|
||||
buf.append(" (Destination ");
|
||||
String host = _context.namingService().reverseLookup(dest);
|
||||
if (host != null)
|
||||
buf.append(host);
|
||||
else
|
||||
buf.append(dest.toBase64().substring(0, 6));
|
||||
}
|
||||
buf.append(")</b><br />\n");
|
||||
long exp = ls.getEarliestLeaseDate()-now;
|
||||
if (exp > 0)
|
||||
buf.append("Earliest expiration date in: <i>").append(DataHelper.formatDuration(exp)).append("</i><br />\n");
|
||||
|
@ -3,6 +3,8 @@ package net.i2p.router.peermanager;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
import java.lang.Math;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
|
||||
@ -12,9 +14,13 @@ import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.peermanager.DBHistory;
|
||||
import net.i2p.stat.Rate;
|
||||
import net.i2p.stat.RateStat;
|
||||
|
||||
/**
|
||||
* Helper class to refactor the HTML rendering from out of the ProfileOrganizer
|
||||
@ -33,13 +39,22 @@ class ProfileOrganizerRenderer {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
Set peers = _organizer.selectAllPeers();
|
||||
|
||||
long hideBefore = _context.clock().now() - 3*60*60*1000;
|
||||
long now = _context.clock().now();
|
||||
long hideBefore = now - 3*60*60*1000;
|
||||
|
||||
TreeSet order = new TreeSet(_comparator);
|
||||
TreeSet integratedPeers = new TreeSet(_comparator);
|
||||
for (Iterator iter = peers.iterator(); iter.hasNext();) {
|
||||
Hash peer = (Hash)iter.next();
|
||||
if (_organizer.getUs().equals(peer)) continue;
|
||||
PeerProfile prof = _organizer.getProfile(peer);
|
||||
if (_organizer.isWellIntegrated(peer)) {
|
||||
integratedPeers.add(prof);
|
||||
} else {
|
||||
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
|
||||
if (info != null && info.getCapabilities().indexOf("f") >= 0)
|
||||
integratedPeers.add(prof);
|
||||
}
|
||||
if (prof.getLastSendSuccessful() <= hideBefore) continue;
|
||||
order.add(prof);
|
||||
}
|
||||
@ -127,6 +142,75 @@ class ProfileOrganizerRenderer {
|
||||
buf.append("</tr>");
|
||||
}
|
||||
buf.append("</table>");
|
||||
|
||||
buf.append("<h2>Floodfill and Integrated Peers</h2>\n");
|
||||
buf.append("<table border=\"1\">");
|
||||
buf.append("<tr>");
|
||||
buf.append("<td><b>Peer</b></td>");
|
||||
buf.append("<td><b>Caps</b></td>");
|
||||
buf.append("<td><b>Integ. Value</b></td>");
|
||||
buf.append("<td><b>Last Heard About</b></td>");
|
||||
buf.append("<td><b>Last Heard From</b></td>");
|
||||
buf.append("<td><b>Last Successful Send</b></td>");
|
||||
buf.append("<td><b>Last Failed Send</b></td>");
|
||||
buf.append("<td><b>10m Resp. Time</b></td>");
|
||||
buf.append("<td><b>1h Resp. Time</b></td>");
|
||||
buf.append("<td><b>1d Resp. Time</b></td>");
|
||||
buf.append("<td><b>Successful Lookups</b></td>");
|
||||
buf.append("<td><b>Failed Lookups</b></td>");
|
||||
buf.append("<td><b>New Stores</b></td>");
|
||||
buf.append("<td><b>Old Stores</b></td>");
|
||||
buf.append("<td><b>1m Fail Rate</b></td>");
|
||||
buf.append("<td><b>1h Fail Rate</b></td>");
|
||||
buf.append("<td><b>1d Fail Rate</b></td>");
|
||||
buf.append("</tr>");
|
||||
for (Iterator iter = integratedPeers.iterator(); iter.hasNext();) {
|
||||
PeerProfile prof = (PeerProfile)iter.next();
|
||||
Hash peer = prof.getPeer();
|
||||
|
||||
buf.append("<tr>");
|
||||
buf.append("<td><code>");
|
||||
if (prof.getIsFailing()) {
|
||||
buf.append("<font color=\"red\">-- ").append(peer.toBase64().substring(0,6)).append("</font>");
|
||||
} else {
|
||||
if (prof.getIsActive()) {
|
||||
buf.append("<font color=\"blue\">++ ").append(peer.toBase64().substring(0,6)).append("</font>");
|
||||
} else {
|
||||
buf.append(" ").append(peer.toBase64().substring(0,6));
|
||||
}
|
||||
}
|
||||
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
|
||||
if (info != null)
|
||||
buf.append("<td align=\"center\">" + info.getCapabilities() + "</td>");
|
||||
else
|
||||
buf.append("<td> </td>");
|
||||
buf.append("</code></td>");
|
||||
buf.append("<td align=\"right\">").append(num(prof.getIntegrationValue())).append("</td>");
|
||||
long time;
|
||||
time = now - prof.getLastHeardAbout();
|
||||
buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>");
|
||||
time = now - prof.getLastHeardFrom();
|
||||
buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>");
|
||||
time = now - prof.getLastSendSuccessful();
|
||||
buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>");
|
||||
time = now - prof.getLastSendFailed();
|
||||
buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>");
|
||||
buf.append("<td align=\"right\">").append(avg(prof, 10*60*1000l)).append("</td>");
|
||||
buf.append("<td align=\"right\">").append(avg(prof, 60*60*1000l)).append("</td>");
|
||||
buf.append("<td align=\"right\">").append(avg(prof, 24*60*60*1000l)).append("</td>");
|
||||
DBHistory dbh = prof.getDBHistory();
|
||||
if (dbh != null) {
|
||||
buf.append("<td align=\"right\">").append(dbh.getSuccessfulLookups()).append("</td>");
|
||||
buf.append("<td align=\"right\">").append(dbh.getFailedLookups()).append("</td>");
|
||||
buf.append("<td align=\"right\">").append(dbh.getUnpromptedDbStoreNew()).append("</td>");
|
||||
buf.append("<td align=\"right\">").append(dbh.getUnpromptedDbStoreOld()).append("</td>");
|
||||
buf.append("<td align=\"right\">").append(davg(dbh, 60*1000l)).append("</td>");
|
||||
buf.append("<td align=\"right\">").append(davg(dbh, 60*60*1000l)).append("</td>");
|
||||
buf.append("<td align=\"right\">").append(davg(dbh, 24*60*60*1000l)).append("</td>");
|
||||
}
|
||||
}
|
||||
buf.append("</table>");
|
||||
|
||||
buf.append("<p><i>Definitions:<ul>");
|
||||
buf.append("<li><b>groups</b>: as determined by the profile organizer</li>");
|
||||
buf.append("<li><b>caps</b>: capabilities in the netDb, not used to determine profiles</li>");
|
||||
@ -198,4 +282,29 @@ class ProfileOrganizerRenderer {
|
||||
|
||||
private final static DecimalFormat _fmt = new DecimalFormat("###,##0.00", new DecimalFormatSymbols(Locale.UK));
|
||||
private final static String num(double num) { synchronized (_fmt) { return _fmt.format(num); } }
|
||||
|
||||
String avg (PeerProfile prof, long rate) {
|
||||
RateStat rs = prof.getDbResponseTime();
|
||||
if (rs == null)
|
||||
return num(0d);
|
||||
Rate r = rs.getRate(rate);
|
||||
if (r == null)
|
||||
return num(0d);
|
||||
long c = r.getCurrentEventCount() + r.getLastEventCount();
|
||||
if (c == 0)
|
||||
return num(0d);
|
||||
double d = r.getCurrentTotalValue() + r.getLastTotalValue();
|
||||
return Math.round(d/c) + "ms";
|
||||
}
|
||||
|
||||
String davg (DBHistory dbh, long rate) {
|
||||
RateStat rs = dbh.getFailedLookupRate();
|
||||
if (rs == null)
|
||||
return num(0d);
|
||||
Rate r = rs.getRate(rate);
|
||||
if (r == null)
|
||||
return num(0d);
|
||||
long c = r.getCurrentEventCount() + r.getLastEventCount();
|
||||
return "" + c;
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
||||
failPct = getExploratoryFailPercentage(ctx);
|
||||
Log l = ctx.logManager().getLog(getClass());
|
||||
if (l.shouldLog(Log.DEBUG))
|
||||
l.debug("Fail pct: " + failPct);
|
||||
l.debug("Normalized Fail pct: " + failPct);
|
||||
// always try a little, this helps keep the failPct stat accurate too
|
||||
if (failPct > 100 - MIN_NONFAILING_PCT)
|
||||
failPct = 100 - MIN_NONFAILING_PCT;
|
||||
@ -86,14 +86,32 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
||||
}
|
||||
|
||||
// We should really use the difference between the exploratory fail rate
|
||||
// and the client fail rate.
|
||||
// (return 100 * ((Efail - Cfail) / (1 - Cfail)))
|
||||
// and the high capacity fail rate - but we don't have a stat for high cap,
|
||||
// so use the fast (== client) fail rate, it should be close
|
||||
// if the expl. and client tunnel lengths aren't too different.
|
||||
// So calculate the difference between the exploratory fail rate
|
||||
// and the client fail rate, normalized to 100:
|
||||
// 100 * ((Efail - Cfail) / (100 - Cfail))
|
||||
// Even this isn't the "true" rate for the NonFailingPeers pool, since we
|
||||
// are often building exploratory tunnels using the HighCapacity pool.
|
||||
private int getExploratoryFailPercentage(RouterContext ctx) {
|
||||
int timeout = getEvents(ctx, "tunnel.buildExploratoryExpire", 10*60*1000);
|
||||
int reject = getEvents(ctx, "tunnel.buildExploratoryReject", 10*60*1000);
|
||||
int accept = getEvents(ctx, "tunnel.buildExploratorySuccess", 10*60*1000);
|
||||
int c = getFailPercentage(ctx, "Client");
|
||||
int e = getFailPercentage(ctx, "Exploratory");
|
||||
Log l = ctx.logManager().getLog(getClass());
|
||||
if (l.shouldLog(Log.DEBUG))
|
||||
l.debug("Client, Expl. Fail pct: " + c + ", " + e);
|
||||
if (e <= c || e <= 25) // doing very well (unlikely)
|
||||
return 0;
|
||||
if (c >= 90) // doing very badly
|
||||
return 100 - MIN_NONFAILING_PCT;
|
||||
return (100 * (e-c)) / (100-c);
|
||||
}
|
||||
|
||||
private int getFailPercentage(RouterContext ctx, String t) {
|
||||
String pfx = "tunnel.build" + t;
|
||||
int timeout = getEvents(ctx, pfx + "Expire", 10*60*1000);
|
||||
int reject = getEvents(ctx, pfx + "Reject", 10*60*1000);
|
||||
int accept = getEvents(ctx, pfx + "Success", 10*60*1000);
|
||||
if (accept + reject + timeout <= 0)
|
||||
return 0;
|
||||
double pct = (double)(reject + timeout) / (accept + reject + timeout);
|
||||
|
Reference in New Issue
Block a user