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..390a37e4d 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java @@ -130,6 +130,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"; 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/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(); }