diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
index 594e37096b..bee288e531 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
@@ -649,7 +649,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
"http://i2host.i2p/cgi-bin/i2hostjump?",
// "http://orion.i2p/jump/",
"http://stats.i2p/cgi-bin/jump.cgi?a=",
- "http://trevorreznik.i2p/cgi-bin/jump.php?hostname=",
+ // "http://trevorreznik.i2p/cgi-bin/jump.php?hostname=",
"http://i2jump.i2p/"
};
private static void writeErrorMessage(byte[] errMessage, OutputStream out, String targetRequest,
diff --git a/history.txt b/history.txt
index 4359d9b3b8..d2fa66902f 100644
--- a/history.txt
+++ b/history.txt
@@ -1,3 +1,16 @@
+2008-05-20 zzz
+ * Reachability:
+ - Call the previously unused profile.tunnelTestFailed()
+ (redefined to include a probability argument)
+ and severely downgrade a peer's capacity upon failures,
+ depending on tunnel length and direction.
+ This will help push unreachable and malicious peers
+ out of the High Capacity tier.
+ - Put recent fail rate on profiles.jsp
+ * ProfileOrganizer: Logging cleanup
+ * eepsite_index.html: Update add-host and jump links
+ * HTTP Proxy: Remove trevorreznik jump server from list
+
2008-05-20 welterde
* implemented PrivateKeyFile
diff --git a/installer/resources/eepsite_index.html b/installer/resources/eepsite_index.html
index 57241a4065..2fe80c8c12 100644
--- a/installer/resources/eepsite_index.html
+++ b/installer/resources/eepsite_index.html
@@ -55,9 +55,7 @@
such as stats.i2p.
That is, you must enter
your eepsite name and key into a web interface on one or more of these sites.
- Here is the key entry form at stats.i2p,
- and
- here is the key entry form at trevorreznik.i2p.
+ Here is the key entry form at stats.i2p.
Again, your key is the entire "Local destination" key on the
eepsite i2ptunnel configuration page.
Be sure you get the whole thing, ending with "AAAA".
@@ -70,14 +68,15 @@
and add a couple of these -
http://tino.i2p/hosts.txt,
http://stats.i2p/cgi-bin/newhosts.txt,
- http://i2jump.i2p/hosts.txt,
- http://trevorreznik.i2p/hosts.txt and hit "Save".
+ http://i2host.i2p/cgi-bin/i2hostetag,
+ and hit "Save".
Now you will get updates too!
If you are in a hurry and can't wait a few hours, you can tell people to use a "jump" address helper redirection service.
- This will work within a few minutes of your entering the key to an address book.
+ This will work within a few minutes of your entering the key to an address book on the same site.
Test it yourself first by entering
http://stats.i2p/cgi-bin/jump.cgi?a=something.i2p or
- or http://trevorreznik.i2p/cgi-bin/jump.php?hostname=something.i2p into your browser.
+ or http://i2host.i2p/cgi-bin/i2hostjump?something.i2p
+ into your browser.
Once it's working, then you can tell others to use it.
Some people check eepsite lists such as
inproxy.tino.i2p/status.php for new eepsites, so you may start getting
diff --git a/router/java/src/net/i2p/router/ProfileManager.java b/router/java/src/net/i2p/router/ProfileManager.java
index f491421840..20e3d95cbd 100644
--- a/router/java/src/net/i2p/router/ProfileManager.java
+++ b/router/java/src/net/i2p/router/ProfileManager.java
@@ -85,7 +85,7 @@ public interface ProfileManager {
* been the peer's fault however.
*
*/
- void tunnelFailed(Hash peer);
+ void tunnelFailed(Hash peer, int pct);
/**
* Note that the peer was able to return the valid data for a db lookup
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index 7099c1f5d3..4c90a8a1b0 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -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.33";
- public final static long BUILD = 6;
+ public final static long BUILD = 7;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);
diff --git a/router/java/src/net/i2p/router/peermanager/CapacityCalculator.java b/router/java/src/net/i2p/router/peermanager/CapacityCalculator.java
index 6c576600ea..be96a875d9 100644
--- a/router/java/src/net/i2p/router/peermanager/CapacityCalculator.java
+++ b/router/java/src/net/i2p/router/peermanager/CapacityCalculator.java
@@ -103,8 +103,12 @@ public class CapacityCalculator extends Calculator {
double stretch = ((double)ESTIMATE_PERIOD) / period;
double val = eventCount * stretch;
long failed = 0;
+ // Let's say a failure is 4 times worse than a rejection.
+ // It's actually much worse than that, but with 2-hop tunnels and a 8-peer
+ // fast pool, for example, you have a 1/7 chance of being falsely blamed.
+ // We also don't want to drive everybody's capacity to zero, that isn't helpful.
if (curFailed != null)
- failed = curFailed.getCurrentEventCount() + curFailed.getLastEventCount();
+ failed = (long) (0.5 + (4.0 * (curFailed.getCurrentTotalValue() + curFailed.getLastTotalValue()) / 100.0));
if (failed > 0) {
//if ( (period <= 10*60*1000) && (curFailed.getCurrentEventCount() > 0) )
// return 0.0d; // their tunnels have failed in the last 0-10 minutes
diff --git a/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java b/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java
index e82c965905..6cf63418dc 100644
--- a/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java
+++ b/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java
@@ -150,13 +150,14 @@ public class ProfileManagerImpl implements ProfileManager {
/**
* Note that the peer participated in a tunnel that failed. Its failure may not have
* been the peer's fault however.
+ * Blame the peer with a probability of pct/100.
*
*/
- public void tunnelFailed(Hash peer) {
+ public void tunnelFailed(Hash peer, int pct) {
PeerProfile data = getProfile(peer);
if (data == null) return;
data.setLastHeardFrom(_context.clock().now());
- data.getTunnelHistory().incrementFailed();
+ data.getTunnelHistory().incrementFailed(pct);
}
/**
diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java
index 4e0266da5a..85e22bdd92 100644
--- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java
+++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java
@@ -563,6 +563,7 @@ public class ProfileOrganizer {
if (_log.shouldLog(Log.INFO))
_log.info("Profiles reorganized. averages: [integration: " + _thresholdIntegrationValue
+ ", capacity: " + _thresholdCapacityValue + ", speed: " + _thresholdSpeedValue + "]");
+ /*****
if (_log.shouldLog(Log.DEBUG)) {
StringBuffer buf = new StringBuffer(512);
for (Iterator iter = _strictCapacityOrder.iterator(); iter.hasNext(); ) {
@@ -572,6 +573,7 @@ public class ProfileOrganizer {
_log.debug("Strictly organized (highest capacity first): " + buf.toString());
_log.debug("fast: " + _fastPeers.values());
}
+ *****/
}
long total = System.currentTimeMillis()-start;
@@ -601,16 +603,18 @@ public class ProfileOrganizer {
if ( (!_fastPeers.containsKey(cur.getPeer())) && (!cur.getIsFailing()) ) {
if (!isSelectable(cur.getPeer())) {
// skip peers we dont have in the netDb
- if (_log.shouldLog(Log.INFO))
- _log.info("skip unknown peer from fast promotion: " + cur.getPeer().toBase64());
+ // if (_log.shouldLog(Log.INFO))
+ // _log.info("skip unknown peer from fast promotion: " + cur.getPeer().toBase64());
continue;
}
if (!cur.getIsActive()) {
// skip inactive
- if (_log.shouldLog(Log.INFO))
- _log.info("skip inactive peer from fast promotion: " + cur.getPeer().toBase64());
+ // if (_log.shouldLog(Log.INFO))
+ // _log.info("skip inactive peer from fast promotion: " + cur.getPeer().toBase64());
continue;
}
+ if (_log.shouldLog(Log.INFO))
+ _log.info("Fast promoting: " + cur.getPeer().toBase64());
_fastPeers.put(cur.getPeer(), cur);
// no need to remove it from any of the other groups, since if it is
// fast, it has a high capacity, and it is not failing
@@ -969,8 +973,8 @@ public class ProfileOrganizer {
if (netDb == null) return true;
if (_context.router() == null) return true;
if ( (_context.shitlist() != null) && (_context.shitlist().isShitlisted(peer)) ) {
- if (_log.shouldLog(Log.DEBUG))
- _log.debug("Peer " + peer.toBase64() + " is shitlisted, dont select it");
+ // if (_log.shouldLog(Log.DEBUG))
+ // _log.debug("Peer " + peer.toBase64() + " is shitlisted, dont select it");
return false; // never select a shitlisted peer
}
@@ -983,18 +987,18 @@ public class ProfileOrganizer {
} else {
boolean exclude = TunnelPeerSelector.shouldExclude(_context, info);
if (exclude) {
- if (_log.shouldLog(Log.WARN))
- _log.warn("Peer " + peer.toBase64() + " has capabilities or other stats suggesting we avoid it");
+ // if (_log.shouldLog(Log.WARN))
+ // _log.warn("Peer " + peer.toBase64() + " has capabilities or other stats suggesting we avoid it");
return false;
} else {
- if (_log.shouldLog(Log.INFO))
- _log.info("Peer " + peer.toBase64() + " is locally known, allowing its use");
+ // if (_log.shouldLog(Log.INFO))
+ // _log.info("Peer " + peer.toBase64() + " is locally known, allowing its use");
return true;
}
}
} else {
- if (_log.shouldLog(Log.WARN))
- _log.warn("Peer " + peer.toBase64() + " is NOT locally known, disallowing its use");
+ // if (_log.shouldLog(Log.WARN))
+ // _log.warn("Peer " + peer.toBase64() + " is NOT locally known, disallowing its use");
return false;
}
}
diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizerRenderer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizerRenderer.java
index cf61aa6721..1a5541f917 100644
--- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizerRenderer.java
+++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizerRenderer.java
@@ -143,6 +143,14 @@ class ProfileOrganizerRenderer {
if (_context.shitlist().isShitlisted(peer)) buf.append("Shitlist");
if (prof.getIsFailing()) buf.append(" Failing");
if (_context.commSystem().wasUnreachable(peer)) buf.append(" Unreachable");
+ Rate failed = prof.getTunnelHistory().getFailedRate().getRate(30*60*1000);
+ long fails = failed.getCurrentEventCount() + failed.getLastEventCount();
+ if (fails > 0) {
+ Rate accepted = prof.getTunnelCreateResponseTime().getRate(30*60*1000);
+ long total = fails + accepted.getCurrentEventCount() + accepted.getLastEventCount();
+ if (total / fails <= 10) // hide if < 10%
+ buf.append(' ').append(fails).append('/').append(total).append(" Test Fails");
+ }
buf.append(" ");
//buf.append("profile.txt ");
//buf.append(" netDb | ");
diff --git a/router/java/src/net/i2p/router/peermanager/TunnelHistory.java b/router/java/src/net/i2p/router/peermanager/TunnelHistory.java
index c50d19f8c3..2ea23099dd 100644
--- a/router/java/src/net/i2p/router/peermanager/TunnelHistory.java
+++ b/router/java/src/net/i2p/router/peermanager/TunnelHistory.java
@@ -108,9 +108,12 @@ public class TunnelHistory {
// dont increment the reject rate in this case
}
}
- public void incrementFailed() {
+
+ // Define this rate as the probability it really failed
+ // @param pct = probability * 100
+ public void incrementFailed(int pct) {
_lifetimeFailed++;
- _failRate.addData(1, 1);
+ _failRate.addData(pct, 1);
_lastFailed = _context.clock().now();
}
diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java
index e9894b20cd..24a3686b9e 100644
--- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java
+++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java
@@ -332,6 +332,7 @@ public class TunnelPool {
}
_manager.tunnelFailed();
+ tellProfileFailed(cfg);
_lifetimeProcessed += cfg.getProcessedMessagesCount();
updateRate();
@@ -343,6 +344,33 @@ public class TunnelPool {
}
}
+ // Blame all the other peers in the tunnel, with a probability
+ // inversely related to the tunnel length
+ private void tellProfileFailed(PooledTunnelCreatorConfig cfg) {
+ int len = cfg.getLength();
+ if (len < 2)
+ return;
+ int start = 0;
+ int end = len;
+ if (cfg.isInbound())
+ end--;
+ else
+ start++;
+ for (int i = start; i < end; i++) {
+ int pct = 100/(len-1);
+ // if inbound, it's probably the gateway's fault
+ if (cfg.isInbound() && len > 2) {
+ if (i == start)
+ pct *= 2;
+ else
+ pct /= 2;
+ }
+ if (_log.shouldLog(Log.WARN))
+ _log.warn(toString() + ": Blaming " + cfg.getPeer(i) + ' ' + pct + '%');
+ _context.profileManager().tunnelFailed(cfg.getPeer(i), pct);
+ }
+ }
+
void updateRate() {
long now = _context.clock().now();
long et = now - _lastRateUpdate;