\n");
}
}
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 0085d7b40..dec2d7891 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
@@ -10,6 +10,7 @@ import java.util.Set;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.LeaseSet;
+import net.i2p.data.RouterAddress;
import net.i2p.stat.Rate;
import net.i2p.stat.RateStat;
import net.i2p.router.CommSystemFacade;
@@ -17,6 +18,7 @@ import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.router.RouterVersion;
import net.i2p.router.TunnelPoolSettings;
+import net.i2p.router.transport.ntcp.NTCPAddress;
/**
* Simple helper to query the appropriate router for data necessary to render
@@ -120,7 +122,10 @@ public class SummaryHelper {
int status = _context.commSystem().getReachabilityStatus();
switch (status) {
case CommSystemFacade.STATUS_OK:
- return "OK";
+ RouterAddress ra = _context.router().getRouterInfo().getTargetAddress("NTCP");
+ if (ra == null || (new NTCPAddress(ra)).isPubliclyRoutable())
+ return "OK";
+ return "ERR-Private TCP Address";
case CommSystemFacade.STATUS_DIFFERENT:
return "ERR-SymmetricNAT";
case CommSystemFacade.STATUS_REJECT_UNSOLICITED:
@@ -130,6 +135,8 @@ public class SummaryHelper {
return "WARN-Firewalled and Fast";
else
return "Firewalled";
+ case CommSystemFacade.STATUS_HOSED:
+ return "ERR-UDP Port In Use - Set i2np.udp.internalPort=xxxx in advanced config and restart";
case CommSystemFacade.STATUS_UNKNOWN: // fallthrough
default:
return "Testing";
@@ -512,6 +519,28 @@ public class SummaryHelper {
return String.valueOf(_context.tunnelManager().getInboundBuildQueueSize());
}
+ public String getPRNGStatus() {
+ Rate r = _context.statManager().getRate("prng.bufferWaitTime").getRate(60*1000);
+ int use = (int) r.getLastEventCount();
+ int i = (int) (r.getAverageValue() + 0.5);
+ if (i <= 0) {
+ r = _context.statManager().getRate("prng.bufferWaitTime").getRate(10*60*1000);
+ i = (int) (r.getAverageValue() + 0.5);
+ }
+ String rv = i + "/";
+ r = _context.statManager().getRate("prng.bufferFillTime").getRate(60*1000);
+ i = (int) (r.getAverageValue() + 0.5);
+ if (i <= 0) {
+ r = _context.statManager().getRate("prng.bufferFillTime").getRate(10*60*1000);
+ i = (int) (r.getAverageValue() + 0.5);
+ }
+ rv = rv + i + "ms";
+ // margin == fill time / use time
+ if (use > 0 && i > 0)
+ rv = rv + ' ' + (60*1000 / (use * i)) + 'x';
+ return rv;
+ }
+
public boolean updateAvailable() {
return NewsFetcher.getInstance(_context).updateAvailable();
}
diff --git a/apps/routerconsole/jsp/configclients.jsp b/apps/routerconsole/jsp/configclients.jsp
index 8f4f6c8e2..724028198 100644
--- a/apps/routerconsole/jsp/configclients.jsp
+++ b/apps/routerconsole/jsp/configclients.jsp
@@ -18,7 +18,6 @@
" />
- " />
" />
" />
@@ -30,7 +29,6 @@
if (prev != null) System.setProperty("net.i2p.router.web.ConfigClientsHandler.noncePrev", prev);
System.setProperty("net.i2p.router.web.ConfigClientsHandler.nonce", new java.util.Random().nextLong()+""); %>
" />
-
Client Configuration
The Java clients listed below are started by the router and run in the same JVM.
@@ -39,7 +37,7 @@
- All changes require restart to take effect. For other changes edit the clients.config file.
+ All changes require restart to take effect. To change other client options, edit the clients.config file.
WebApp Configuration
@@ -50,11 +48,15 @@
front-ends to another client or application which must be separately enabled (e.g. susidns, i2ptunnel),
or have no web interface at all (e.g. addressbook).
+ A web app may also be disabled by removing the .war file from the webapps directory;
+ however the .war file and web app will reappear when you update your router to a newer version,
+ so disabling the web app here is the preferred method.
+
- All changes require restart to take effect. For other changes edit the webapps.config file.
+ All changes require restart to take effect. To change other webapp options, edit the webapps.config file.
diff --git a/apps/routerconsole/jsp/confignav.jsp b/apps/routerconsole/jsp/confignav.jsp
index 8625ca687..7ab47f76b 100644
--- a/apps/routerconsole/jsp/confignav.jsp
+++ b/apps/routerconsole/jsp/confignav.jsp
@@ -4,10 +4,10 @@
%>Service | <% } else { %>Service | <% }
if (request.getRequestURI().indexOf("configupdate.jsp") != -1) {
%>Update | <% } else { %>Update | <% }
- if (request.getRequestURI().indexOf("configclients.jsp") != -1) {
- %>Clients | <% } else { %>Clients | <% }
if (request.getRequestURI().indexOf("configtunnels.jsp") != -1) {
%>Tunnels | <% } else { %>Tunnels | <% }
+ if (request.getRequestURI().indexOf("configclients.jsp") != -1) {
+ %>Clients | <% } else { %>Clients | <% }
if (request.getRequestURI().indexOf("configlogging.jsp") != -1) {
%>Logging | <% } else { %>Logging | <% }
if (request.getRequestURI().indexOf("configstats.jsp") != -1) {
diff --git a/apps/routerconsole/jsp/summary.jsp b/apps/routerconsole/jsp/summary.jsp
index 1f284c64b..7bd85aaf9 100644
--- a/apps/routerconsole/jsp/summary.jsp
+++ b/apps/routerconsole/jsp/summary.jsp
@@ -95,6 +95,7 @@
Message delay: Tunnel lag: Handle backlog:
+ PRNG wait/fill:
diff --git a/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java b/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java
index 90d8d97d7..c7b5c36e5 100644
--- a/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java
+++ b/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java
@@ -2,6 +2,8 @@ package gnu.crypto.prng;
import java.util.*;
+import net.i2p.I2PAppContext;
+
/**
* fortuna instance that tries to avoid blocking if at all possible by using separate
* filled buffer segments rather than one buffer (and blocking when that buffer's data
@@ -13,16 +15,20 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
private final byte asyncBuffers[][] = new byte[BUFFERS][BUFSIZE];
private final int status[] = new int[BUFFERS];
private int nextBuf = 0;
+ private I2PAppContext _context;
private static final int STATUS_NEED_FILL = 0;
private static final int STATUS_FILLING = 1;
private static final int STATUS_FILLED = 2;
private static final int STATUS_LIVE = 3;
- public AsyncFortunaStandalone() {
+ public AsyncFortunaStandalone(I2PAppContext context) {
super();
for (int i = 0; i < BUFFERS; i++)
status[i] = STATUS_NEED_FILL;
+ _context = context;
+ context.statManager().createRateStat("prng.bufferWaitTime", "", "Encryption", new long[] { 60*1000, 10*60*1000, 60*60*1000 } );
+ context.statManager().createRateStat("prng.bufferFillTime", "", "Encryption", new long[] { 60*1000, 10*60*1000, 60*60*1000 } );
}
public void startup() {
@@ -61,6 +67,7 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
} catch (InterruptedException ie) {}
waited = System.currentTimeMillis()-before;
}
+ _context.statManager().addRateData("prng.bufferWaitTime", waited, 0);
if (waited > 10*1000)
System.out.println(Thread.currentThread().getName() + ": Took " + waited
+ "ms for a full PRNG buffer to be found");
@@ -108,6 +115,7 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
//System.out.println(Thread.currentThread().getName() + ": Prng buffer " + toFill + " filled after " + (after-before));
asyncBuffers.notifyAll();
}
+ _context.statManager().addRateData("prng.bufferFillTime", after - before, 0);
Thread.yield();
long waitTime = (after-before)*5;
if (waitTime <= 0) // somehow postman saw waitTime show up as negative
@@ -147,7 +155,7 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
public static void main(String args[]) {
try {
- AsyncFortunaStandalone rand = new AsyncFortunaStandalone();
+ AsyncFortunaStandalone rand = new AsyncFortunaStandalone(null); // Will cause NPEs above; fix this if you want to test! Sorry...
byte seed[] = new byte[1024];
rand.seed(seed);
diff --git a/core/java/src/net/i2p/stat/StatManager.java b/core/java/src/net/i2p/stat/StatManager.java
index 07cce24ef..3f3ab4a72 100644
--- a/core/java/src/net/i2p/stat/StatManager.java
+++ b/core/java/src/net/i2p/stat/StatManager.java
@@ -37,13 +37,15 @@ public class StatManager {
public static final String PROP_STAT_REQUIRED = "stat.required";
/**
* These are all the stats published in netDb, plus those required for the operation of
- * the router (many in RouterThrottleImpl), plus those that are on graphs.jsp by default.
+ * the router (many in RouterThrottleImpl), plus those that are on graphs.jsp by default,
+ * plus those used on the summary bar (SummaryHelper.java).
* Wildcard ('*') allowed at end of stat only.
* Ignore all the rest of the stats unless stat.full=true.
*/
public static final String DEFAULT_STAT_REQUIRED =
"bw.recvRate,bw.sendBps,bw.sendRate,client.sendAckTime,clock.skew,crypto.elGamal.encrypt," +
"jobQueue.jobLag,netDb.successTime,router.fastPeers," +
+ "prng.bufferFillTime,prng.bufferWaitTime," +
"transport.receiveMessageSize,transport.sendMessageSize,transport.sendProcessingTime," +
"tunnel.acceptLoad,tunnel.buildRequestTime,tunnel.rejectOverloaded,tunnel.rejectTimeout" +
"tunnel.buildClientExpire,tunnel.buildClientReject,tunnel.buildClientSuccess," +
diff --git a/core/java/src/net/i2p/util/FortunaRandomSource.java b/core/java/src/net/i2p/util/FortunaRandomSource.java
index 2d1a69196..865cc0bb4 100644
--- a/core/java/src/net/i2p/util/FortunaRandomSource.java
+++ b/core/java/src/net/i2p/util/FortunaRandomSource.java
@@ -32,7 +32,7 @@ public class FortunaRandomSource extends RandomSource implements EntropyHarveste
public FortunaRandomSource(I2PAppContext context) {
super(context);
- _fortuna = new AsyncFortunaStandalone();
+ _fortuna = new AsyncFortunaStandalone(context);
byte seed[] = new byte[1024];
if (initSeed(seed)) {
_fortuna.seed(seed);
diff --git a/history.txt b/history.txt
index e202dd206..a3e13b7e9 100644
--- a/history.txt
+++ b/history.txt
@@ -1,3 +1,17 @@
+2008-06-23 zzz
+ * configclients.jsp: Add start button for clients and webapps.
+ * PRNG: Add two stats
+ * Summary bar:
+ - Display Warning for TCP private IP address
+ - Display PRNG stats
+ * OutNetMessage: Change cache logging from WARN to INFO
+
+2008-06-17 zzz
+ * Comm System: Add new STATUS_HOSED for use when UDP bind fails
+ * Summary bar: Display helpful errror message when UDP bind fails
+ * UDP: Don't bid when UDP bind fails
+ * configclients.jsp: Implement saves for clients and webapps.
+
2008-06-16 zzz
* UDP: Prevent 100% CPU when UDP bind fails;
change bind fail message from ERROR to CRIT
@@ -12,7 +26,6 @@
* configclients.jsp: New. For both clients and webapps.
Saves are not yet implemented.
-
2008-06-10 zzz
* Floodfill: Add new FloodfillMonitorJob, which tracks active
floodfills, and automatically enables/disables floodfill on
diff --git a/router/java/src/net/i2p/router/CommSystemFacade.java b/router/java/src/net/i2p/router/CommSystemFacade.java
index 2978ce928..3fb141865 100644
--- a/router/java/src/net/i2p/router/CommSystemFacade.java
+++ b/router/java/src/net/i2p/router/CommSystemFacade.java
@@ -61,6 +61,9 @@ public abstract class CommSystemFacade implements Service {
*/
public void notifyReplaceAddress(RouterAddress UDPAddr) {}
/**
+ * These must be increasing in "badness" (see TransportManager.java),
+ * but UNKNOWN must be last.
+ *
* We are able to receive unsolicited connections
*/
public static final short STATUS_OK = 0;
@@ -75,10 +78,14 @@ public abstract class CommSystemFacade implements Service {
* cannot receive unsolicited connections
*/
public static final short STATUS_REJECT_UNSOLICITED = 2;
+ /**
+ * Our detection system is broken (SSU bind port failed)
+ */
+ public static final short STATUS_HOSED = 3;
/**
* Our reachability is unknown
*/
- public static final short STATUS_UNKNOWN = 3;
+ public static final short STATUS_UNKNOWN = 4;
}
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index da77a17e2..9cea22605 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-06-07 23:00:00 $";
public final static String VERSION = "0.6.2";
- public final static long BUILD = 3;
+ public final static long BUILD = 5;
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/message/OutboundClientMessageOneShotJob.java b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java
index 8dba7275d..02e2efd40 100644
--- a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java
+++ b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java
@@ -247,8 +247,8 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
return null;
//}
} else {
- if (_log.shouldLog(Log.WARN))
- _log.warn("Expired from cache - reply leaseset for " + _toString);
+ if (_log.shouldLog(Log.INFO))
+ _log.info("Expired from cache - reply leaseset for " + _toString);
// will get overwritten below
// _leaseSetCache.remove(hashPair());
}
@@ -256,8 +256,8 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
}
_leaseSetCache.put(hashPair(), newLS);
}
- if (_log.shouldLog(Log.WARN))
- _log.warn("Added to cache - reply leaseset for " + _toString);
+ if (_log.shouldLog(Log.INFO))
+ _log.info("Added to cache - reply leaseset for " + _toString);
return newLS;
}
@@ -329,8 +329,8 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
}
}
}
- if (_log.shouldLog(Log.WARN))
- _log.warn("Expired from cache - lease for " + _toString);
+ if (_log.shouldLog(Log.INFO))
+ _log.info("Expired from cache - lease for " + _toString);
_leaseCache.remove(_to);
}
}
@@ -340,8 +340,8 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
for (int i = 0; i < _leaseSet.getLeaseCount(); i++) {
Lease lease = _leaseSet.getLease(i);
if (lease.isExpired(Router.CLOCK_FUDGE_FACTOR)) {
- if (_log.shouldLog(Log.WARN))
- _log.warn(getJobId() + ": getNextLease() - expired lease! - " + lease + " for " + _toString);
+ if (_log.shouldLog(Log.INFO))
+ _log.info(getJobId() + ": getNextLease() - expired lease! - " + lease + " for " + _toString);
continue;
} else {
leases.add(lease);
@@ -403,8 +403,8 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
synchronized (_leaseCache) {
_leaseCache.put(hashPair(), _lease);
}
- if (_log.shouldLog(Log.WARN))
- _log.warn("Added to cache - lease for " + _toString);
+ if (_log.shouldLog(Log.INFO))
+ _log.info("Added to cache - lease for " + _toString);
return true;
}
diff --git a/router/java/src/net/i2p/router/startup/ClientAppConfig.java b/router/java/src/net/i2p/router/startup/ClientAppConfig.java
index 8c54ea1fa..0a994069f 100644
--- a/router/java/src/net/i2p/router/startup/ClientAppConfig.java
+++ b/router/java/src/net/i2p/router/startup/ClientAppConfig.java
@@ -2,6 +2,7 @@ package net.i2p.router.startup;
import java.io.IOException;
import java.io.File;
+import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
@@ -22,6 +23,7 @@ public class ClientAppConfig {
private static final String PROP_CLIENT_CONFIG_FILENAME = "router.clientConfigFile";
private static final String DEFAULT_CLIENT_CONFIG_FILENAME = "clients.config";
+ private static final String PREFIX = "clientApp.";
// let's keep this really simple
public String className;
@@ -63,14 +65,14 @@ public class ClientAppConfig {
List rv = new ArrayList(5);
int i = 0;
while (true) {
- String className = clientApps.getProperty("clientApp."+i+".main");
+ String className = clientApps.getProperty(PREFIX + i + ".main");
if (className == null)
break;
- String clientName = clientApps.getProperty("clientApp."+i+".name");
- String args = clientApps.getProperty("clientApp."+i+".args");
- String delayStr = clientApps.getProperty("clientApp." + i + ".delay");
- String onBoot = clientApps.getProperty("clientApp." + i + ".onBoot");
- String disabled = clientApps.getProperty("clientApp." + i + ".startOnLoad");
+ String clientName = clientApps.getProperty(PREFIX + i + ".name");
+ String args = clientApps.getProperty(PREFIX + i + ".args");
+ String delayStr = clientApps.getProperty(PREFIX + i + ".delay");
+ String onBoot = clientApps.getProperty(PREFIX + i + ".onBoot");
+ String disabled = clientApps.getProperty(PREFIX + i + ".startOnLoad");
i++;
boolean dis = disabled != null && "false".equals(disabled);
@@ -87,5 +89,25 @@ public class ClientAppConfig {
return rv;
}
+ public static void writeClientAppConfig(RouterContext ctx, List apps) {
+ String clientConfigFile = ctx.getProperty(PROP_CLIENT_CONFIG_FILENAME, DEFAULT_CLIENT_CONFIG_FILENAME);
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(clientConfigFile);
+ StringBuffer buf = new StringBuffer(2048);
+ for(int i = 0; i < apps.size(); i++) {
+ ClientAppConfig app = (ClientAppConfig) apps.get(i);
+ buf.append(PREFIX).append(i).append(".main=").append(app.className).append("\n");
+ buf.append(PREFIX).append(i).append(".name=").append(app.clientName).append("\n");
+ buf.append(PREFIX).append(i).append(".args=").append(app.args).append("\n");
+ buf.append(PREFIX).append(i).append(".delay=").append(app.delay / 1000).append("\n");
+ buf.append(PREFIX).append(i).append(".startOnLoad=").append(!app.disabled).append("\n");
+ }
+ fos.write(buf.toString().getBytes());
+ } catch (IOException ioe) {
+ } finally {
+ if (fos != null) try { fos.close(); } catch (IOException ioe) {}
+ }
+ }
}
diff --git a/router/java/src/net/i2p/router/startup/LoadClientAppsJob.java b/router/java/src/net/i2p/router/startup/LoadClientAppsJob.java
index 62e713238..0770241d6 100644
--- a/router/java/src/net/i2p/router/startup/LoadClientAppsJob.java
+++ b/router/java/src/net/i2p/router/startup/LoadClientAppsJob.java
@@ -15,7 +15,7 @@ import net.i2p.util.Log;
* it'll get queued up for starting 2 minutes later.
*
*/
-class LoadClientAppsJob extends JobImpl {
+public class LoadClientAppsJob extends JobImpl {
private Log _log;
private static boolean _loaded = false;
@@ -36,7 +36,7 @@ class LoadClientAppsJob extends JobImpl {
String argVal[] = parseArgs(app.args);
if (app.delay == 0) {
// run this guy now
- runClient(app.className, app.clientName, argVal);
+ runClient(app.className, app.clientName, argVal, _log);
} else {
// wait before firing it up
getContext().jobQueue().addJob(new DelayedRunClient(getContext(), app.className, app.clientName, argVal, app.delay));
@@ -56,11 +56,11 @@ class LoadClientAppsJob extends JobImpl {
}
public String getName() { return "Delayed client job"; }
public void runJob() {
- runClient(_className, _clientName, _args);
+ runClient(_className, _clientName, _args, _log);
}
}
- static String[] parseArgs(String args) {
+ public static String[] parseArgs(String args) {
List argList = new ArrayList(4);
if (args != null) {
char data[] = args.toCharArray();
@@ -109,9 +109,9 @@ class LoadClientAppsJob extends JobImpl {
return rv;
}
- private void runClient(String className, String clientName, String args[]) {
- _log.info("Loading up the client application " + clientName + ": " + className + " " + args);
- I2PThread t = new I2PThread(new RunApp(className, clientName, args));
+ public static void runClient(String className, String clientName, String args[], Log log) {
+ log.info("Loading up the client application " + clientName + ": " + className + " " + args);
+ I2PThread t = new I2PThread(new RunApp(className, clientName, args, log));
if (clientName == null)
clientName = className + " client";
t.setName(clientName);
@@ -119,17 +119,19 @@ class LoadClientAppsJob extends JobImpl {
t.start();
}
- private final class RunApp implements Runnable {
+ private final static class RunApp implements Runnable {
private String _className;
private String _appName;
private String _args[];
- public RunApp(String className, String appName, String args[]) {
+ private Log _log;
+ public RunApp(String className, String appName, String args[], Log log) {
_className = className;
_appName = appName;
if (args == null)
_args = new String[0];
else
_args = args;
+ _log = log;
}
public void run() {
try {
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java b/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java
index cb57dcf0f..aefe18b8b 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java
@@ -5,6 +5,7 @@ import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
+import net.i2p.router.CommSystemFacade;
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
@@ -44,6 +45,7 @@ public class UDPEndpoint {
_sender.startup();
_receiver.startup();
} catch (SocketException se) {
+ _transport.setReachabilityStatus(CommSystemFacade.STATUS_HOSED);
_log.log(Log.CRIT, "Unable to bind on port " + _listenPort, se);
}
}
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
index 4e5e77030..040fac761 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
@@ -858,6 +858,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
else
return _fastBid;
} else {
+ // If we don't have a port, all is lost
+ if ( _reachabilityStatus == CommSystemFacade.STATUS_HOSED) {
+ markUnreachable(to);
+ return null;
+ }
+
// Validate his SSU address
RouterAddress addr = toAddress.getTargetAddress(STYLE);
if (addr == null) {
@@ -1870,6 +1876,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
buf.append(" \n");
buf.append("
");
long bytesTransmitted = _context.bandwidthLimiter().getTotalAllocatedOutboundBytes();
+ // NPE here early
double averagePacketSize = _context.statManager().getRate("udp.sendPacketSize").getLifetimeAverageValue();
// lifetime value, not just the retransmitted packets of current connections
resentTotal = (long)_context.statManager().getRate("udp.packetsRetransmitted").getLifetimeEventCount();
@@ -2005,6 +2012,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
break;
case CommSystemFacade.STATUS_REJECT_UNSOLICITED:
_context.statManager().addRateData("udp.statusReject", 1, 0);
+ // fall through...
+ case CommSystemFacade.STATUS_HOSED:
_reachabilityStatus = status;
_reachabilityStatusLastUpdated = now;
break;
@@ -2021,6 +2030,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
break;
}
if ( (status != old) && (status != CommSystemFacade.STATUS_UNKNOWN) ) {
+ if (_log.shouldLog(Log.INFO))
+ _log.info("Old status: " + old + " New status: " + status + " from: ", new Exception("traceback"));
if (needsRebuild())
rebuildExternalAddress();
}