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)
|
//if (_context.router().getRouterInfo().getCapabilities().indexOf('O') >= 0)
|
||||||
// return _("WARN-Firewalled and Fast");
|
// return _("WARN-Firewalled and Fast");
|
||||||
return _("Firewalled");
|
return _("Firewalled");
|
||||||
|
case CommSystemFacade.STATUS_DISCONNECTED:
|
||||||
|
return _("Disconnected - check network cable");
|
||||||
case CommSystemFacade.STATUS_HOSED:
|
case CommSystemFacade.STATUS_HOSED:
|
||||||
return _("ERR-UDP Port In Use - Set i2np.udp.internalPort=xxxx in advanced config and restart");
|
return _("ERR-UDP Port In Use - Set i2np.udp.internalPort=xxxx in advanced config and restart");
|
||||||
case CommSystemFacade.STATUS_UNKNOWN: // fallthrough
|
case CommSystemFacade.STATUS_UNKNOWN: // fallthrough
|
||||||
|
@ -81,6 +81,7 @@ public abstract class CommSystemFacade implements Service {
|
|||||||
* Tell other transports our address changed
|
* Tell other transports our address changed
|
||||||
*/
|
*/
|
||||||
public void notifyReplaceAddress(RouterAddress UDPAddr) {}
|
public void notifyReplaceAddress(RouterAddress UDPAddr) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These must be increasing in "badness" (see TransportManager.java),
|
* These must be increasing in "badness" (see TransportManager.java),
|
||||||
* but UNKNOWN must be last.
|
* but UNKNOWN must be last.
|
||||||
@ -99,14 +100,19 @@ public abstract class CommSystemFacade implements Service {
|
|||||||
* cannot receive unsolicited connections
|
* cannot receive unsolicited connections
|
||||||
*/
|
*/
|
||||||
public static final short STATUS_REJECT_UNSOLICITED = 2;
|
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)
|
* 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
|
* 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:
|
case CommSystemFacade.STATUS_REJECT_UNSOLICITED:
|
||||||
ri.addCapability(CAPABILITY_UNREACHABLE);
|
ri.addCapability(CAPABILITY_UNREACHABLE);
|
||||||
break;
|
break;
|
||||||
|
case CommSystemFacade.STATUS_DISCONNECTED:
|
||||||
|
case CommSystemFacade.STATUS_HOSED:
|
||||||
case CommSystemFacade.STATUS_UNKNOWN:
|
case CommSystemFacade.STATUS_UNKNOWN:
|
||||||
// no explicit capability
|
// no explicit capability
|
||||||
break;
|
break;
|
||||||
|
@ -4,6 +4,7 @@ import java.io.File;
|
|||||||
|
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.router.Job;
|
import net.i2p.router.Job;
|
||||||
|
import net.i2p.router.CommSystemFacade;
|
||||||
import net.i2p.router.Router;
|
import net.i2p.router.Router;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.router.util.EventLog;
|
import net.i2p.router.util.EventLog;
|
||||||
@ -129,11 +130,15 @@ public class RouterWatchdog implements Runnable {
|
|||||||
boolean ok = verifyJobQueueLiveliness();
|
boolean ok = verifyJobQueueLiveliness();
|
||||||
// If we aren't connected to the network that's why there's nobody to talk to
|
// If we aren't connected to the network that's why there's nobody to talk to
|
||||||
long netErrors = 0;
|
long netErrors = 0;
|
||||||
RateStat rs = _context.statManager().getRate("udp.sendException");
|
if (_context.commSystem().getReachabilityStatus() == CommSystemFacade.STATUS_DISCONNECTED) {
|
||||||
if (rs != null) {
|
netErrors = 10;
|
||||||
Rate r = rs.getRate(60*1000);
|
} else {
|
||||||
if (r != null)
|
RateStat rs = _context.statManager().getRate("udp.sendException");
|
||||||
netErrors = r.getLastEventCount();
|
if (rs != null) {
|
||||||
|
Rate r = rs.getRate(60*1000);
|
||||||
|
if (r != null)
|
||||||
|
netErrors = r.getLastEventCount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = ok && (verifyClientLiveliness() || netErrors >= 5);
|
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.ntcp.NTCPTransport;
|
||||||
import net.i2p.router.transport.udp.UDPAddress;
|
import net.i2p.router.transport.udp.UDPAddress;
|
||||||
import net.i2p.router.transport.udp.UDPTransport;
|
import net.i2p.router.transport.udp.UDPTransport;
|
||||||
|
import net.i2p.util.Addresses;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.SimpleScheduler;
|
import net.i2p.util.SimpleScheduler;
|
||||||
import net.i2p.util.SimpleTimer;
|
import net.i2p.util.SimpleTimer;
|
||||||
|
import net.i2p.util.SimpleTimer2;
|
||||||
import net.i2p.util.Translate;
|
import net.i2p.util.Translate;
|
||||||
|
|
||||||
public class CommSystemFacadeImpl extends CommSystemFacade {
|
public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||||
private final Log _log;
|
private final Log _log;
|
||||||
private final RouterContext _context;
|
private final RouterContext _context;
|
||||||
private TransportManager _manager;
|
private TransportManager _manager;
|
||||||
private GeoIP _geoIP;
|
private final GeoIP _geoIP;
|
||||||
|
private volatile boolean _netMonitorStatus;
|
||||||
|
|
||||||
public CommSystemFacadeImpl(RouterContext context) {
|
public CommSystemFacadeImpl(RouterContext context) {
|
||||||
_context = context;
|
_context = context;
|
||||||
_log = _context.logManager().getLog(CommSystemFacadeImpl.class);
|
_log = _context.logManager().getLog(CommSystemFacadeImpl.class);
|
||||||
_context.statManager().createRateStat("transport.getBidsJobTime", "How long does it take?", "Transport", new long[] { 10*60*1000l });
|
_context.statManager().createRateStat("transport.getBidsJobTime", "How long does it take?", "Transport", new long[] { 10*60*1000l });
|
||||||
|
_netMonitorStatus = true;
|
||||||
|
_geoIP = new GeoIP(_context);
|
||||||
startGeoIP();
|
startGeoIP();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +59,7 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
|||||||
_manager = new TransportManager(_context);
|
_manager = new TransportManager(_context);
|
||||||
_manager.startListening();
|
_manager.startListening();
|
||||||
startTimestamper();
|
startTimestamper();
|
||||||
|
startNetMonitor();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -169,8 +175,12 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
|||||||
@Override
|
@Override
|
||||||
public short getReachabilityStatus() {
|
public short getReachabilityStatus() {
|
||||||
if (_manager == null) return STATUS_UNKNOWN;
|
if (_manager == null) return STATUS_UNKNOWN;
|
||||||
if (_context.router().isHidden()) return STATUS_OK;
|
if (!_netMonitorStatus)
|
||||||
return _manager.getReachabilityStatus();
|
return STATUS_DISCONNECTED;
|
||||||
|
short rv = _manager.getReachabilityStatus();
|
||||||
|
if (rv != STATUS_HOSED && _context.router().isHidden())
|
||||||
|
return STATUS_OK;
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void recheckReachability() { _manager.recheckReachability(); }
|
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 START_DELAY = 5*60*1000;
|
||||||
private static final int LOOKUP_TIME = 30*60*1000;
|
private static final int LOOKUP_TIME = 30*60*1000;
|
||||||
private void startGeoIP() {
|
private void startGeoIP() {
|
||||||
_geoIP = new GeoIP(_context);
|
|
||||||
_context.simpleScheduler().addEvent(new QueueAll(), START_DELAY);
|
_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_START_DELAY = 5*60*1000;
|
||||||
private static final int TIME_REPEAT_DELAY = 10*60*1000;
|
private static final int TIME_REPEAT_DELAY = 10*60*1000;
|
||||||
|
|
||||||
/** @since 0.7.12 */
|
/** @since 0.7.12 */
|
||||||
private void startTimestamper() {
|
private void startTimestamper() {
|
||||||
_context.simpleScheduler().addPeriodicEvent(new Timestamper(), TIME_START_DELAY, TIME_REPEAT_DELAY);
|
_context.simpleScheduler().addPeriodicEvent(new Timestamper(), TIME_START_DELAY, TIME_REPEAT_DELAY);
|
||||||
@ -579,4 +589,28 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
|||||||
_context.clock().setOffset(newOffset);
|
_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.Hash;
|
||||||
import net.i2p.data.i2np.I2NPMessage;
|
import net.i2p.data.i2np.I2NPMessage;
|
||||||
import net.i2p.data.RouterInfo;
|
import net.i2p.data.RouterInfo;
|
||||||
|
import net.i2p.router.CommSystemFacade;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.router.TunnelManagerFacade;
|
import net.i2p.router.TunnelManagerFacade;
|
||||||
import net.i2p.stat.Rate;
|
import net.i2p.stat.Rate;
|
||||||
@ -104,6 +105,8 @@ class BuildExecutor implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int allowed() {
|
private int allowed() {
|
||||||
|
if (_context.commSystem().getReachabilityStatus() == CommSystemFacade.STATUS_DISCONNECTED)
|
||||||
|
return 0;
|
||||||
int maxKBps = _context.bandwidthLimiter().getOutboundKBytesPerSecond();
|
int maxKBps = _context.bandwidthLimiter().getOutboundKBytesPerSecond();
|
||||||
int allowed = maxKBps / 6; // Max. 1 concurrent build per 6 KB/s outbound
|
int allowed = maxKBps / 6; // Max. 1 concurrent build per 6 KB/s outbound
|
||||||
RateStat rs = _context.statManager().getRate("tunnel.buildRequestTime");
|
RateStat rs = _context.statManager().getRate("tunnel.buildRequestTime");
|
||||||
|
Reference in New Issue
Block a user