forked from I2P_Developers/i2p.i2p
Transports: Track IPv4/v6 reachability separately (ticket #1458)
Don't include NTCP conns established too long ago in clock skew vector Hide unestablished outbound NTCP conns from /peers view Add per-transport status to /peers Put status description instead of code into event log reachability changes
This commit is contained in:
@@ -18,7 +18,7 @@ public class RouterVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Monotone";
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
public final static long BUILD = 10;
|
||||
public final static long BUILD = 11;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
@@ -84,11 +84,14 @@ public class NTCPTransport extends TransportImpl {
|
||||
* TODO periodically update via CSFI.NetMonitor?
|
||||
*/
|
||||
private boolean _haveIPv6Address;
|
||||
private long _lastInboundIPv4;
|
||||
private long _lastInboundIPv6;
|
||||
|
||||
public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname";
|
||||
public final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port";
|
||||
public final static String PROP_I2NP_NTCP_AUTO_PORT = "i2np.ntcp.autoport";
|
||||
public final static String PROP_I2NP_NTCP_AUTO_IP = "i2np.ntcp.autoip";
|
||||
private static final String PROP_ADVANCED = "routerconsole.advanced";
|
||||
public static final int DEFAULT_COST = 10;
|
||||
|
||||
/** this is rarely if ever used, default is to bind to wildcard address */
|
||||
@@ -210,6 +213,10 @@ public class NTCPTransport extends TransportImpl {
|
||||
synchronized (_conLock) {
|
||||
old = _conByIdent.put(peer, con);
|
||||
}
|
||||
if (con.isIPv6())
|
||||
_lastInboundIPv6 = con.getCreated();
|
||||
else
|
||||
_lastInboundIPv4 = con.getCreated();
|
||||
return old;
|
||||
}
|
||||
|
||||
@@ -231,6 +238,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
con = new NTCPConnection(_context, this, ident, addr);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Send on a new con: " + con + " at " + addr + " for " + ih);
|
||||
// Note that outbound conns go in the map BEFORE establishment
|
||||
_conByIdent.put(ih, con);
|
||||
} else {
|
||||
// race, RI changed out from under us
|
||||
@@ -528,7 +536,11 @@ public class NTCPTransport extends TransportImpl {
|
||||
return active;
|
||||
}
|
||||
|
||||
/** @param skew in seconds */
|
||||
/**
|
||||
* A positive number means our clock is ahead of theirs.
|
||||
*
|
||||
* @param skew in seconds
|
||||
*/
|
||||
void setLastBadSkew(long skew) {
|
||||
_lastBadSkew = skew;
|
||||
}
|
||||
@@ -536,13 +548,18 @@ public class NTCPTransport extends TransportImpl {
|
||||
/**
|
||||
* Return our peer clock skews on this transport.
|
||||
* Vector composed of Long, each element representing a peer skew in seconds.
|
||||
* A positive number means our clock is ahead of theirs.
|
||||
*/
|
||||
@Override
|
||||
public Vector<Long> getClockSkews() {
|
||||
Vector<Long> skews = new Vector<Long>();
|
||||
// Omit ones established too long ago,
|
||||
// since the skew is only set at startup (or after a meta message)
|
||||
// and won't include effects of later offset adjustments
|
||||
long tooOld = _context.clock().now() - 10*60*1000;
|
||||
|
||||
for (NTCPConnection con : _conByIdent.values()) {
|
||||
if (con.isEstablished())
|
||||
if (con.isEstablished() && con.getCreated() > tooOld)
|
||||
skews.addElement(Long.valueOf(con.getClockSkew()));
|
||||
}
|
||||
|
||||
@@ -622,11 +639,11 @@ public class NTCPTransport extends TransportImpl {
|
||||
*
|
||||
* Doesn't actually restart unless addr is non-null and
|
||||
* the port is different from the current listen port.
|
||||
* If addr is null, removes all addresses.
|
||||
* If addr is null, removes IPv4 addresses only.
|
||||
*
|
||||
* If we had interface addresses before, we lost them.
|
||||
*
|
||||
* @param addr may be null
|
||||
* @param addr may be null to indicate remove the IPv4 address only
|
||||
*/
|
||||
private synchronized void restartListening(RouterAddress addr) {
|
||||
if (addr != null) {
|
||||
@@ -637,7 +654,16 @@ public class NTCPTransport extends TransportImpl {
|
||||
replaceAddress(addr);
|
||||
// UDPTransport.rebuildExternalAddress() calls router.rebuildRouterInfo()
|
||||
} else {
|
||||
replaceAddress(null);
|
||||
// can't do this, want to remove IPv4 only
|
||||
//replaceAddress(null);
|
||||
for (RouterAddress ra : _currentAddresses) {
|
||||
byte[] ip = ra.getIP();
|
||||
if (ip != null && ip.length == 4) {
|
||||
// COWAL
|
||||
_currentAddresses.remove(ra);
|
||||
}
|
||||
}
|
||||
_lastInboundIPv4 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -920,6 +946,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
/**
|
||||
* UDP changed addresses, tell NTCP and (possibly) restart
|
||||
*
|
||||
* @param ip typ. IPv4 or IPv6 non-local; may be null to indicate IPv4 failure or port info only
|
||||
* @since IPv6 moved from CSFI.notifyReplaceAddress()
|
||||
*/
|
||||
@Override
|
||||
@@ -958,20 +985,21 @@ public class NTCPTransport extends TransportImpl {
|
||||
* UDP changed addresses, tell NTCP and restart.
|
||||
* Port may be set to indicate requested port even if ip is null.
|
||||
*
|
||||
* @param ip previously validated
|
||||
* @param ip previously validated; may be null to indicate IPv4 failure or port info only
|
||||
* @since IPv6 moved from CSFI.notifyReplaceAddress()
|
||||
*/
|
||||
private synchronized void externalAddressReceived(byte[] ip, int port) {
|
||||
// FIXME just take first IPv4 address for now
|
||||
// FIXME just take first address for now
|
||||
// FIXME if SSU set to hostname, NTCP will be set to IP
|
||||
RouterAddress oldAddr = getCurrentAddress(false);
|
||||
boolean isIPv6 = ip != null && ip.length == 16;
|
||||
RouterAddress oldAddr = getCurrentAddress(isIPv6);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Changing NTCP Address? was " + oldAddr);
|
||||
|
||||
OrderedProperties newProps = new OrderedProperties();
|
||||
int cost;
|
||||
if (oldAddr == null) {
|
||||
cost = getDefaultCost(ip != null && ip.length == 16);
|
||||
cost = getDefaultCost(isIPv6);
|
||||
} else {
|
||||
cost = oldAddr.getCost();
|
||||
newProps.putAll(oldAddr.getOptionsMap());
|
||||
@@ -1163,16 +1191,81 @@ public class NTCPTransport extends TransportImpl {
|
||||
* We have to be careful here because much of the router console code assumes
|
||||
* that the reachability status is really just the UDP status.
|
||||
*
|
||||
* This only returns OK, DISABLED, or UNKNOWN for IPv4 and IPv6.
|
||||
* We leave the FIREWALLED status for UDP.
|
||||
*
|
||||
* Previously returned short, now enum as of 0.9.20
|
||||
*/
|
||||
public Status getReachabilityStatus() {
|
||||
// If we have an IPv4 address
|
||||
if (isAlive() && getCurrentAddress(false) != null) {
|
||||
for (NTCPConnection con : _conByIdent.values()) {
|
||||
if (con.isInbound())
|
||||
return Status.OK;
|
||||
}
|
||||
if (!isAlive())
|
||||
return Status.UNKNOWN;
|
||||
TransportUtil.IPv6Config config = getIPv6Config();
|
||||
boolean v4Disabled, v6Disabled;
|
||||
if (config == IPV6_DISABLED) {
|
||||
v4Disabled = false;
|
||||
v6Disabled = true;
|
||||
} else if (config == IPV6_ONLY) {
|
||||
v4Disabled = true;
|
||||
v6Disabled = false;
|
||||
} else {
|
||||
v4Disabled = false;
|
||||
v6Disabled = false;
|
||||
}
|
||||
boolean hasV4 = getCurrentAddress(false) != null;
|
||||
// or use _haveIPv6Addrnss ??
|
||||
boolean hasV6 = getCurrentAddress(true) != null;
|
||||
if (!hasV4 && !hasV6)
|
||||
return Status.UNKNOWN;
|
||||
long now = _context.clock().now();
|
||||
boolean v4OK = hasV4 && !v4Disabled && now - _lastInboundIPv4 < 10*60*1000;
|
||||
boolean v6OK = hasV6 && !v6Disabled && now - _lastInboundIPv6 < 30*60*1000;
|
||||
if (v4OK) {
|
||||
if (v6OK)
|
||||
return Status.OK;
|
||||
if (v6Disabled)
|
||||
return Status.OK;
|
||||
if (!hasV6)
|
||||
return Status.IPV4_OK_IPV6_UNKNOWN;
|
||||
}
|
||||
if (v6OK) {
|
||||
if (v4Disabled)
|
||||
return Status.IPV4_DISABLED_IPV6_OK;
|
||||
if (!hasV4)
|
||||
return Status.IPV4_UNKNOWN_IPV6_OK;
|
||||
}
|
||||
for (NTCPConnection con : _conByIdent.values()) {
|
||||
if (con.isInbound()) {
|
||||
if (con.isIPv6()) {
|
||||
if (hasV6)
|
||||
v6OK = true;
|
||||
} else {
|
||||
if (hasV4)
|
||||
v4OK = true;
|
||||
}
|
||||
if (v4OK) {
|
||||
if (v6OK)
|
||||
return Status.OK;
|
||||
if (v6Disabled)
|
||||
return Status.OK;
|
||||
if (!hasV6)
|
||||
return Status.IPV4_OK_IPV6_UNKNOWN;
|
||||
}
|
||||
if (v6OK) {
|
||||
if (v4Disabled)
|
||||
return Status.IPV4_DISABLED_IPV6_OK;
|
||||
if (!hasV4)
|
||||
return Status.IPV4_UNKNOWN_IPV6_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (v4OK)
|
||||
return Status.IPV4_OK_IPV6_UNKNOWN;
|
||||
if (v6OK)
|
||||
return Status.IPV4_UNKNOWN_IPV6_OK;
|
||||
if (v4Disabled)
|
||||
return Status.IPV4_DISABLED_IPV6_UNKNOWN;
|
||||
if (v6Disabled)
|
||||
return Status.UNKNOWN;
|
||||
return Status.UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -1197,6 +1290,8 @@ public class NTCPTransport extends TransportImpl {
|
||||
NTCPConnection.releaseResources();
|
||||
replaceAddress(null);
|
||||
_endpoints.clear();
|
||||
_lastInboundIPv4 = 0;
|
||||
_lastInboundIPv6 = 0;
|
||||
}
|
||||
|
||||
public static final String STYLE = "NTCP";
|
||||
@@ -1215,10 +1310,19 @@ public class NTCPTransport extends TransportImpl {
|
||||
long totalSend = 0;
|
||||
long totalRecv = 0;
|
||||
|
||||
if (!_context.getBooleanProperty(PROP_ADVANCED)) {
|
||||
for (Iterator<NTCPConnection> iter = peers.iterator(); iter.hasNext(); ) {
|
||||
// outbound conns get put in the map before they are established
|
||||
if (!iter.next().isEstablished())
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
buf.append("<h3 id=\"ntcpcon\">").append(_("NTCP connections")).append(": ").append(peers.size());
|
||||
buf.append(". ").append(_("Limit")).append(": ").append(getMaxConnections());
|
||||
buf.append(". ").append(_("Timeout")).append(": ").append(DataHelper.formatDuration2(_pumper.getIdleTimeout()));
|
||||
buf.append(". ").append(_("Status")).append(": ").append(_(getReachabilityStatus().toStatusString()));
|
||||
buf.append(".</h3>\n" +
|
||||
"<table>\n" +
|
||||
"<tr><th><a href=\"#def.peer\">").append(_("Peer")).append("</a></th>" +
|
||||
|
@@ -705,7 +705,8 @@ class EstablishmentManager {
|
||||
|
||||
_transport.addRemotePeerState(peer);
|
||||
|
||||
_transport.inboundConnectionReceived();
|
||||
boolean isIPv6 = state.getSentIP().length == 16;
|
||||
_transport.inboundConnectionReceived(isIPv6);
|
||||
_transport.setIP(remote.calculateHash(), state.getSentIP());
|
||||
|
||||
_context.statManager().addRateData("udp.inboundEstablishTime", state.getLifetime(), 0);
|
||||
|
@@ -448,16 +448,16 @@ class PeerTestManager {
|
||||
if ( (test.getAlicePort() == test.getAlicePortFromCharlie()) &&
|
||||
(test.getAliceIP() != null) && (test.getAliceIPFromCharlie() != null) &&
|
||||
(test.getAliceIP().equals(test.getAliceIPFromCharlie())) ) {
|
||||
status = Status.OK;
|
||||
status = Status.IPV4_OK_IPV6_UNKNOWN;
|
||||
} else {
|
||||
status = Status.DIFFERENT;
|
||||
status = Status.IPV4_SNAT_IPV6_UNKNOWN;
|
||||
}
|
||||
} else if (test.getReceiveCharlieTime() > 0) {
|
||||
// we received only one message from charlie
|
||||
status = Status.UNKNOWN;
|
||||
} else if (test.getReceiveBobTime() > 0) {
|
||||
// we received a message from bob but no messages from charlie
|
||||
status = Status.REJECT_UNSOLICITED;
|
||||
status = Status.IPV4_FIREWALLED_IPV6_UNKNOWN;
|
||||
} else {
|
||||
// we never received anything from bob - he is either down,
|
||||
// ignoring us, or unable to get a Charlie to respond
|
||||
|
@@ -258,10 +258,10 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
_context.statManager().createRateStat("udp.alreadyConnected", "What is the lifetime of a reestablished session", "udp", RATES);
|
||||
_context.statManager().createRateStat("udp.droppedPeer", "How long ago did we receive from a dropped peer (duration == session lifetime", "udp", RATES);
|
||||
_context.statManager().createRateStat("udp.droppedPeerInactive", "How long ago did we receive from a dropped peer (duration == session lifetime)", "udp", RATES);
|
||||
_context.statManager().createRateStat("udp.statusOK", "How many times the peer test returned OK", "udp", RATES);
|
||||
_context.statManager().createRateStat("udp.statusDifferent", "How many times the peer test returned different IP/ports", "udp", RATES);
|
||||
_context.statManager().createRateStat("udp.statusReject", "How many times the peer test returned reject unsolicited", "udp", RATES);
|
||||
_context.statManager().createRateStat("udp.statusUnknown", "How many times the peer test returned an unknown result", "udp", RATES);
|
||||
//_context.statManager().createRateStat("udp.statusOK", "How many times the peer test returned OK", "udp", RATES);
|
||||
//_context.statManager().createRateStat("udp.statusDifferent", "How many times the peer test returned different IP/ports", "udp", RATES);
|
||||
//_context.statManager().createRateStat("udp.statusReject", "How many times the peer test returned reject unsolicited", "udp", RATES);
|
||||
//_context.statManager().createRateStat("udp.statusUnknown", "How many times the peer test returned an unknown result", "udp", RATES);
|
||||
_context.statManager().createRateStat("udp.addressTestInsteadOfUpdate", "How many times we fire off a peer test of ourselves instead of adjusting our own reachable address?", "udp", RATES);
|
||||
_context.statManager().createRateStat("udp.addressUpdated", "How many times we adjust our own reachable IP address", "udp", RATES);
|
||||
_context.statManager().createRateStat("udp.proactiveReestablish", "How long a session was idle for when we proactively reestablished it", "udp", RATES);
|
||||
@@ -662,9 +662,14 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
*/
|
||||
private static final int ALLOW_IP_CHANGE_INTERVAL = 2*60*1000;
|
||||
|
||||
void inboundConnectionReceived() {
|
||||
// use OS clock since its an ordering thing, not a time thing
|
||||
_lastInboundReceivedOn = System.currentTimeMillis();
|
||||
void inboundConnectionReceived(boolean isIPv6) {
|
||||
if (isIPv6) {
|
||||
if (_currentOurV6Address != null)
|
||||
setReachabilityStatus(Status.IPV4_UNKNOWN_IPV6_OK);
|
||||
} else {
|
||||
// use OS clock since its an ordering thing, not a time thing
|
||||
_lastInboundReceivedOn = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
// temp prevent multiples
|
||||
@@ -725,8 +730,14 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
boolean changed = changeAddress(ip, port);
|
||||
// Assume if we have an interface with a public IP that we aren't firewalled.
|
||||
// If this is wrong, the peer test will figure it out and change the status.
|
||||
if (changed && ip.length == 4 && source == SOURCE_INTERFACE)
|
||||
setReachabilityStatus(Status.OK);
|
||||
if (changed && source == SOURCE_INTERFACE) {
|
||||
if (ip.length == 4)
|
||||
setReachabilityStatus(Status.IPV4_OK_IPV6_UNKNOWN);
|
||||
else if (ip.length == 16)
|
||||
// TODO should we set both to unknown and wait for an inbound v6 conn,
|
||||
// since there's no v6 testing?
|
||||
setReachabilityStatus(Status.IPV4_UNKNOWN_IPV6_OK);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -744,7 +755,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
_log.warn("UPnP has failed to open the SSU port: " + port + " reason: " + reason);
|
||||
}
|
||||
if (success && ip != null && getExternalIP() != null)
|
||||
setReachabilityStatus(Status.OK);
|
||||
setReachabilityStatus(Status.IPV4_OK_IPV6_UNKNOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2092,6 +2103,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
switch (status) {
|
||||
case REJECT_UNSOLICITED:
|
||||
case DIFFERENT:
|
||||
case IPV4_FIREWALLED_IPV6_OK:
|
||||
case IPV4_FIREWALLED_IPV6_UNKNOWN:
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Require introducers, because our status is " + status);
|
||||
return true;
|
||||
@@ -2289,6 +2302,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
/**
|
||||
* Return our peer clock skews on this transport.
|
||||
* Vector composed of Long, each element representing a peer skew in seconds.
|
||||
* A positive number means our clock is ahead of theirs.
|
||||
*/
|
||||
@Override
|
||||
public Vector<Long> getClockSkews() {
|
||||
@@ -2348,6 +2362,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
buf.append("<h3 id=\"udpcon\">").append(_("UDP connections")).append(": ").append(peers.size());
|
||||
buf.append(". ").append(_("Limit")).append(": ").append(getMaxConnections());
|
||||
buf.append(". ").append(_("Timeout")).append(": ").append(DataHelper.formatDuration2(_expireTimeout));
|
||||
buf.append(". ").append(_("Status")).append(": ").append(_(_reachabilityStatus.toStatusString()));
|
||||
buf.append(".</h3>\n");
|
||||
buf.append("<table>\n");
|
||||
buf.append("<tr><th class=\"smallhead\" nowrap><a href=\"#def.peer\">").append(_("Peer")).append("</a><br>");
|
||||
@@ -2779,58 +2794,49 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
}
|
||||
}
|
||||
|
||||
private void locked_setReachabilityStatus(Status status) {
|
||||
private void locked_setReachabilityStatus(Status newStatus) {
|
||||
Status old = _reachabilityStatus;
|
||||
long now = _context.clock().now();
|
||||
switch (status) {
|
||||
case OK:
|
||||
// TODO if OK but internal port != external port, should we have
|
||||
// a different status state? ...as we don't know if the TCP
|
||||
// port will be mapped the same way or not...
|
||||
// Right now, we assume it is and hope for the best for TCP.
|
||||
_context.statManager().addRateData("udp.statusOK", 1);
|
||||
_reachabilityStatus = status;
|
||||
_reachabilityStatusLastUpdated = now;
|
||||
break;
|
||||
case DIFFERENT:
|
||||
_context.statManager().addRateData("udp.statusDifferent", 1);
|
||||
_reachabilityStatus = status;
|
||||
_reachabilityStatusLastUpdated = now;
|
||||
break;
|
||||
case REJECT_UNSOLICITED:
|
||||
_context.statManager().addRateData("udp.statusReject", 1);
|
||||
// if old != unsolicited && now - lastUpdated > STATUS_GRACE_PERIOD)
|
||||
//
|
||||
// fall through...
|
||||
case DISCONNECTED:
|
||||
case HOSED:
|
||||
_reachabilityStatus = status;
|
||||
_reachabilityStatusLastUpdated = now;
|
||||
break;
|
||||
case UNKNOWN:
|
||||
default:
|
||||
_context.statManager().addRateData("udp.statusUnknown", 1);
|
||||
//if (now - _reachabilityStatusLastUpdated < STATUS_GRACE_PERIOD) {
|
||||
// _testEvent.forceRun();
|
||||
// SimpleTimer.getInstance().addEvent(_testEvent, 5*1000);
|
||||
//} else {
|
||||
// _reachabilityStatus = status;
|
||||
// _reachabilityStatusLastUpdated = now;
|
||||
//}
|
||||
break;
|
||||
}
|
||||
// merge new status into old
|
||||
Status status = Status.merge(old, newStatus);
|
||||
_testEvent.setLastTested();
|
||||
if (status != Status.UNKNOWN) {
|
||||
if (status != old)
|
||||
_reachabilityStatusUnchanged = 0;
|
||||
else
|
||||
_reachabilityStatusUnchanged++;
|
||||
// now modify if we are IPv6 only
|
||||
TransportUtil.IPv6Config config = getIPv6Config();
|
||||
if (config == IPV6_ONLY) {
|
||||
if (status == Status.IPV4_UNKNOWN_IPV6_OK)
|
||||
status = Status.IPV4_DISABLED_IPV6_OK;
|
||||
else if (status == Status.IPV4_UNKNOWN_IPV6_FIREWALLED)
|
||||
status = Status.IPV4_DISABLED_IPV6_FIREWALLED;
|
||||
else if (status == Status.UNKNOWN)
|
||||
status = Status.IPV4_DISABLED_IPV6_UNKNOWN;
|
||||
}
|
||||
if ( (status != old) && (status != Status.UNKNOWN) ) {
|
||||
if (status != Status.UNKNOWN) {
|
||||
// now modify if we have no IPv6 address
|
||||
if (_currentOurV6Address == null) {
|
||||
if (status == Status.IPV4_OK_IPV6_UNKNOWN)
|
||||
status = Status.OK;
|
||||
else if (status == Status.IPV4_FIREWALLED_IPV6_UNKNOWN)
|
||||
status = Status.REJECT_UNSOLICITED;
|
||||
else if (status == Status.IPV4_SNAT_IPV6_UNKNOWN)
|
||||
status = Status.DIFFERENT;
|
||||
}
|
||||
|
||||
if (status != old) {
|
||||
_reachabilityStatusUnchanged = 0;
|
||||
long now = _context.clock().now();
|
||||
_reachabilityStatusLastUpdated = now;
|
||||
_reachabilityStatus = status;
|
||||
} else {
|
||||
_reachabilityStatusUnchanged++;
|
||||
}
|
||||
}
|
||||
if (status != old) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Old status: " + old + " New status: " + status + " from: ", new Exception("traceback"));
|
||||
_log.warn("Old status: " + old + " New status: " + status +
|
||||
" Caused by update: " + newStatus +
|
||||
" from: ", new Exception("traceback"));
|
||||
if (old != Status.UNKNOWN)
|
||||
_context.router().eventLog().addEvent(EventLog.REACHABILITY, status.toStatusString());
|
||||
_context.router().eventLog().addEvent(EventLog.REACHABILITY,
|
||||
"from " + _(old.toStatusString()) + " to " + _(status.toStatusString()));
|
||||
// Always rebuild when the status changes, even if our address hasn't changed,
|
||||
// as rebuildExternalAddress() calls replaceAddress() which calls CSFI.notifyReplaceAddress()
|
||||
// which will start up NTCP inbound when we transition to OK.
|
||||
@@ -2838,7 +2844,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
rebuildExternalAddress();
|
||||
} else {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Status unchanged: " + _reachabilityStatus + " (" + _reachabilityStatusUnchanged + " consecutive times), last updated " +
|
||||
_log.info("Status unchanged: " + _reachabilityStatus +
|
||||
" after update: " + newStatus +
|
||||
" (unchanged " + _reachabilityStatusUnchanged + " consecutive times), last updated " +
|
||||
DataHelper.formatDuration(_context.clock().now() - _reachabilityStatusLastUpdated) + " ago");
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user