forked from I2P_Developers/i2p.i2p
* Transport:
- Add a simple network monitor - Add new reachability state for network disconnected - Prevent any tunnel building when disconnected (ticket #519) - Don't unleash watchdog when disconnected
This commit is contained in:
@ -171,6 +171,8 @@ public class SummaryHelper extends HelperBase {
|
||||
//if (_context.router().getRouterInfo().getCapabilities().indexOf('O') >= 0)
|
||||
// return _("WARN-Firewalled and Fast");
|
||||
return _("Firewalled");
|
||||
case CommSystemFacade.STATUS_DISCONNECTED:
|
||||
return _("Disconnected - check network cable");
|
||||
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
|
||||
|
@ -81,6 +81,7 @@ public abstract class CommSystemFacade implements Service {
|
||||
* Tell other transports our address changed
|
||||
*/
|
||||
public void notifyReplaceAddress(RouterAddress UDPAddr) {}
|
||||
|
||||
/**
|
||||
* These must be increasing in "badness" (see TransportManager.java),
|
||||
* but UNKNOWN must be last.
|
||||
@ -99,14 +100,19 @@ public abstract class CommSystemFacade implements Service {
|
||||
* cannot receive unsolicited connections
|
||||
*/
|
||||
public static final short STATUS_REJECT_UNSOLICITED = 2;
|
||||
/**
|
||||
* We have no network interface at all
|
||||
* @since 0.9.4
|
||||
*/
|
||||
public static final short STATUS_DISCONNECTED = 3;
|
||||
/**
|
||||
* Our detection system is broken (SSU bind port failed)
|
||||
*/
|
||||
public static final short STATUS_HOSED = 3;
|
||||
public static final short STATUS_HOSED = 4;
|
||||
/**
|
||||
* Our reachability is unknown
|
||||
*/
|
||||
public static final short STATUS_UNKNOWN = 4;
|
||||
public static final short STATUS_UNKNOWN = 5;
|
||||
|
||||
}
|
||||
|
||||
|
@ -619,6 +619,8 @@ public class Router implements RouterClock.ClockShiftListener {
|
||||
case CommSystemFacade.STATUS_REJECT_UNSOLICITED:
|
||||
ri.addCapability(CAPABILITY_UNREACHABLE);
|
||||
break;
|
||||
case CommSystemFacade.STATUS_DISCONNECTED:
|
||||
case CommSystemFacade.STATUS_HOSED:
|
||||
case CommSystemFacade.STATUS_UNKNOWN:
|
||||
// no explicit capability
|
||||
break;
|
||||
|
@ -4,6 +4,7 @@ import java.io.File;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.router.Job;
|
||||
import net.i2p.router.CommSystemFacade;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.util.EventLog;
|
||||
@ -129,11 +130,15 @@ public class RouterWatchdog implements Runnable {
|
||||
boolean ok = verifyJobQueueLiveliness();
|
||||
// If we aren't connected to the network that's why there's nobody to talk to
|
||||
long netErrors = 0;
|
||||
RateStat rs = _context.statManager().getRate("udp.sendException");
|
||||
if (rs != null) {
|
||||
Rate r = rs.getRate(60*1000);
|
||||
if (r != null)
|
||||
netErrors = r.getLastEventCount();
|
||||
if (_context.commSystem().getReachabilityStatus() == CommSystemFacade.STATUS_DISCONNECTED) {
|
||||
netErrors = 10;
|
||||
} else {
|
||||
RateStat rs = _context.statManager().getRate("udp.sendException");
|
||||
if (rs != null) {
|
||||
Rate r = rs.getRate(60*1000);
|
||||
if (r != null)
|
||||
netErrors = r.getLastEventCount();
|
||||
}
|
||||
}
|
||||
|
||||
ok = ok && (verifyClientLiveliness() || netErrors >= 5);
|
||||
|
@ -31,21 +31,26 @@ import net.i2p.router.transport.ntcp.NTCPAddress;
|
||||
import net.i2p.router.transport.ntcp.NTCPTransport;
|
||||
import net.i2p.router.transport.udp.UDPAddress;
|
||||
import net.i2p.router.transport.udp.UDPTransport;
|
||||
import net.i2p.util.Addresses;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SimpleScheduler;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
import net.i2p.util.SimpleTimer2;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
private final Log _log;
|
||||
private final RouterContext _context;
|
||||
private TransportManager _manager;
|
||||
private GeoIP _geoIP;
|
||||
private final GeoIP _geoIP;
|
||||
private volatile boolean _netMonitorStatus;
|
||||
|
||||
public CommSystemFacadeImpl(RouterContext context) {
|
||||
_context = context;
|
||||
_log = _context.logManager().getLog(CommSystemFacadeImpl.class);
|
||||
_context.statManager().createRateStat("transport.getBidsJobTime", "How long does it take?", "Transport", new long[] { 10*60*1000l });
|
||||
_netMonitorStatus = true;
|
||||
_geoIP = new GeoIP(_context);
|
||||
startGeoIP();
|
||||
}
|
||||
|
||||
@ -54,6 +59,7 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
_manager = new TransportManager(_context);
|
||||
_manager.startListening();
|
||||
startTimestamper();
|
||||
startNetMonitor();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,8 +175,12 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
@Override
|
||||
public short getReachabilityStatus() {
|
||||
if (_manager == null) return STATUS_UNKNOWN;
|
||||
if (_context.router().isHidden()) return STATUS_OK;
|
||||
return _manager.getReachabilityStatus();
|
||||
if (!_netMonitorStatus)
|
||||
return STATUS_DISCONNECTED;
|
||||
short rv = _manager.getReachabilityStatus();
|
||||
if (rv != STATUS_HOSED && _context.router().isHidden())
|
||||
return STATUS_OK;
|
||||
return rv;
|
||||
}
|
||||
@Override
|
||||
public void recheckReachability() { _manager.recheckReachability(); }
|
||||
@ -416,7 +426,6 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
private static final int START_DELAY = 5*60*1000;
|
||||
private static final int LOOKUP_TIME = 30*60*1000;
|
||||
private void startGeoIP() {
|
||||
_geoIP = new GeoIP(_context);
|
||||
_context.simpleScheduler().addEvent(new QueueAll(), START_DELAY);
|
||||
}
|
||||
|
||||
@ -555,6 +564,7 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
|
||||
private static final int TIME_START_DELAY = 5*60*1000;
|
||||
private static final int TIME_REPEAT_DELAY = 10*60*1000;
|
||||
|
||||
/** @since 0.7.12 */
|
||||
private void startTimestamper() {
|
||||
_context.simpleScheduler().addPeriodicEvent(new Timestamper(), TIME_START_DELAY, TIME_REPEAT_DELAY);
|
||||
@ -579,4 +589,28 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
_context.clock().setOffset(newOffset);
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.9.4 */
|
||||
private void startNetMonitor() {
|
||||
new NetMonitor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple check to see if we have a network connection
|
||||
* @since 0.9.4
|
||||
*/
|
||||
private class NetMonitor extends SimpleTimer2.TimedEvent {
|
||||
private static final long SHORT_DELAY = 15*1000;
|
||||
private static final long LONG_DELAY = 3*60*1000;
|
||||
|
||||
public NetMonitor() {
|
||||
super(_context.simpleTimer2(), 0);
|
||||
}
|
||||
|
||||
public void timeReached() {
|
||||
boolean good = Addresses.isConnected();
|
||||
_netMonitorStatus = good;
|
||||
reschedule(good ? LONG_DELAY : SHORT_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.i2np.I2NPMessage;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.router.CommSystemFacade;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.TunnelManagerFacade;
|
||||
import net.i2p.stat.Rate;
|
||||
@ -104,6 +105,8 @@ class BuildExecutor implements Runnable {
|
||||
}
|
||||
|
||||
private int allowed() {
|
||||
if (_context.commSystem().getReachabilityStatus() == CommSystemFacade.STATUS_DISCONNECTED)
|
||||
return 0;
|
||||
int maxKBps = _context.bandwidthLimiter().getOutboundKBytesPerSecond();
|
||||
int allowed = maxKBps / 6; // Max. 1 concurrent build per 6 KB/s outbound
|
||||
RateStat rs = _context.statManager().getRate("tunnel.buildRequestTime");
|
||||
|
Reference in New Issue
Block a user