diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
index a93993edb..7ddf3847b 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
@@ -124,10 +124,10 @@ public class SummaryHelper {
case CommSystemFacade.STATUS_DIFFERENT:
return "ERR-SymmetricNAT";
case CommSystemFacade.STATUS_REJECT_UNSOLICITED:
- return "OK (NAT)";
+ return "Firewalled";
case CommSystemFacade.STATUS_UNKNOWN: // fallthrough
default:
- return "Unknown";
+ return "Testing";
}
}
@@ -494,6 +494,12 @@ public class SummaryHelper {
return _context.throttle().getTunnelLag() + "ms";
}
+ public String getTunnelStatus() {
+ if (_context == null)
+ return "";
+ return _context.throttle().getTunnelStatus();
+ }
+
public String getInboundBacklog() {
if (_context == null)
return "0";
diff --git a/apps/routerconsole/jsp/summary.jsp b/apps/routerconsole/jsp/summary.jsp
index dc92a174b..b7f3052e6 100644
--- a/apps/routerconsole/jsp/summary.jsp
+++ b/apps/routerconsole/jsp/summary.jsp
@@ -13,8 +13,8 @@
Ident:
Version:
Uptime:
- Now: <%
+ Now:
+ Reachability: <%
if (helper.updateAvailable()) {
// display all the time so we display the final failure message
out.print("
" + update.getStatus());
@@ -95,6 +95,7 @@
Message delay:
Tunnel lag:
Handle backlog:
+
diff --git a/router/java/src/net/i2p/router/RouterThrottle.java b/router/java/src/net/i2p/router/RouterThrottle.java
index ae621cfb8..982cb5fd8 100644
--- a/router/java/src/net/i2p/router/RouterThrottle.java
+++ b/router/java/src/net/i2p/router/RouterThrottle.java
@@ -43,4 +43,8 @@ public interface RouterThrottle {
*
*/
public double getInboundRateDelta();
+ /**
+ * Message on the state of participating tunnel acceptance
+ */
+ public String getTunnelStatus();
}
diff --git a/router/java/src/net/i2p/router/RouterThrottleImpl.java b/router/java/src/net/i2p/router/RouterThrottleImpl.java
index 78165bb21..5e5ce5eb8 100644
--- a/router/java/src/net/i2p/router/RouterThrottleImpl.java
+++ b/router/java/src/net/i2p/router/RouterThrottleImpl.java
@@ -15,6 +15,7 @@ import net.i2p.util.Log;
class RouterThrottleImpl implements RouterThrottle {
private RouterContext _context;
private Log _log;
+ private String _tunnelStatus;
/**
* arbitrary hard limit of 10 seconds - if its taking this long to get
@@ -39,6 +40,7 @@ class RouterThrottleImpl implements RouterThrottle {
public RouterThrottleImpl(RouterContext context) {
_context = context;
_log = context.logManager().getLog(RouterThrottleImpl.class);
+ setTunnelStatus();
_context.statManager().createRateStat("router.throttleNetworkCause", "How lagged the jobQueue was when an I2NP was throttled", "Throttle", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("router.throttleNetDbCause", "How lagged the jobQueue was when a networkDb request was throttled", "Throttle", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("router.throttleTunnelCause", "How lagged the jobQueue was when a tunnel request was throttled", "Throttle", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
@@ -84,9 +86,13 @@ class RouterThrottleImpl implements RouterThrottle {
if (_context.getProperty(Router.PROP_SHUTDOWN_IN_PROGRESS) != null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Refusing tunnel request since we are shutting down ASAP");
+ setTunnelStatus("Rejecting tunnels: Shutting down");
return TunnelHistory.TUNNEL_REJECT_CRIT;
}
+ if (_context.router().getUptime() < 10*60*1000)
+ return TunnelHistory.TUNNEL_REJECT_CRIT;
+
long lag = _context.jobQueue().getMaxLag();
RateStat rs = _context.statManager().getRate("transport.sendProcessingTime");
Rate r = null;
@@ -98,6 +104,7 @@ class RouterThrottleImpl implements RouterThrottle {
_log.debug("Refusing tunnel request with the job lag of " + lag
+ "since the 1 minute message processing time is too slow (" + processTime + ")");
_context.statManager().addRateData("router.throttleTunnelProcessingTime1m", (long)processTime, (long)processTime);
+ setTunnelStatus("Rejecting tunnels: High processing time");
return TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
}
@@ -130,6 +137,7 @@ class RouterThrottleImpl implements RouterThrottle {
_log.warn("Probabalistically refusing tunnel request (avg=" + avg
+ " current=" + numTunnels + ")");
_context.statManager().addRateData("router.throttleTunnelProbTooFast", (long)(numTunnels-avg), 0);
+ setTunnelStatus("Rejecting " + ((int) probAccept*100) + "% of tunnels: High number of requests");
return TunnelHistory.TUNNEL_REJECT_PROBABALISTIC_REJECT;
}
} else {
@@ -168,6 +176,7 @@ class RouterThrottleImpl implements RouterThrottle {
_log.warn("Probabalistically refusing tunnel request (test time avg 1m=" + avg1m
+ " 10m=" + avg10m + ")");
_context.statManager().addRateData("router.throttleTunnelProbTestSlow", (long)(avg1m-avg10m), 0);
+ setTunnelStatus("Rejecting " + ((int) probAccept*100) + "% of tunnels: High test time");
return TunnelHistory.TUNNEL_REJECT_PROBABALISTIC_REJECT;
}
} else {
@@ -186,6 +195,7 @@ class RouterThrottleImpl implements RouterThrottle {
_log.warn("Refusing tunnel request since we are already participating in "
+ numTunnels + " (our max is " + max + ")");
_context.statManager().addRateData("router.throttleTunnelMaxExceeded", numTunnels, 0);
+ setTunnelStatus("Rejecting tunnels: Limit reached");
return TunnelHistory.TUNNEL_REJECT_BANDWIDTH;
}
} catch (NumberFormatException nfe) {
@@ -217,6 +227,7 @@ class RouterThrottleImpl implements RouterThrottle {
return TunnelHistory.TUNNEL_REJECT_BANDWIDTH;
}
+/***
int queuedRequests = _context.tunnelManager().getInboundBuildQueueSize();
int timePerRequest = 1000;
rs = _context.statManager().getRate("tunnel.decryptRequestTime");
@@ -229,6 +240,7 @@ class RouterThrottleImpl implements RouterThrottle {
}
float pctFull = (queuedRequests * timePerRequest) / (4*1000f);
double pReject = Math.pow(pctFull, 16); //1 - ((1-pctFull) * (1-pctFull));
+***/
// let it in because we drop overload- rejecting may be overkill,
// especially since we've done the cpu-heavy lifting to figure out
// whats up
@@ -282,7 +294,7 @@ class RouterThrottleImpl implements RouterThrottle {
return false;
}
- if (true) {
+// if (true) {
// ok, ignore any predictions of 'bytesAllocated', since that makes poorly
// grounded conclusions about future use (or even the bursty use). Instead,
// simply say "do we have the bw to handle a new request"?
@@ -299,12 +311,16 @@ class RouterThrottleImpl implements RouterThrottle {
_log.debug("reject = " + reject + " avail/maxK/used " + availBps + "/" + maxKBps + "/"
+ used + " pReject = " + probReject + " pFull = " + pctFull + " numTunnels = " + numTunnels
+ "rand = " + rand + " est = " + bytesAllocated + " share = " + (float)share);
- if (reject) {
- return false;
- } else {
- return true;
- }
- }
+ if (probReject >= 0.9)
+ setTunnelStatus("Rejecting tunnels: Bandwidth limit");
+ else if (probReject >= 0.5)
+ setTunnelStatus("Rejecting " + ((int)(100.0*probReject)) + "% of tunnels: Bandwidth limit");
+ else if(probReject >= 0.1)
+ setTunnelStatus("Accepting " + (100-(int)(100.0*probReject)) + "% of tunnels");
+ else
+ setTunnelStatus("Accepting tunnels");
+ return !reject;
+// }
/*
@@ -317,6 +333,7 @@ class RouterThrottleImpl implements RouterThrottle {
}
*/
+/***
double growthFactor = ((double)(numTunnels+1))/(double)numTunnels;
double toAllocate = (numTunnels > 0 ? bytesAllocated * growthFactor : 0);
@@ -345,6 +362,7 @@ class RouterThrottleImpl implements RouterThrottle {
return false;
}
}
+***/
}
/** dont ever probabalistically throttle tunnels if we have less than this many */
@@ -401,5 +419,21 @@ class RouterThrottleImpl implements RouterThrottle {
return (bytes*1000.0d)/rate.getPeriod();
}
+ public String getTunnelStatus() {
+ return _tunnelStatus;
+ }
+
+ private void setTunnelStatus() {
+// NPE, too early
+// if (_context.router().getRouterInfo().getBandwidthTier().equals("K"))
+// setTunnelStatus("Not expecting tunnel requests: Advertised bandwidth too low");
+// else
+ setTunnelStatus("Rejecting tunnels");
+ }
+
+ private void setTunnelStatus(String msg) {
+ _tunnelStatus = msg;
+ }
+
protected RouterContext getContext() { return _context; }
}