forked from I2P_Developers/i2p.i2p
SSU: Refactor PeerTestEvent out of UDPTransport
This commit is contained in:
@@ -815,18 +815,18 @@ public abstract class TransportImpl implements Transport {
|
||||
/**
|
||||
* This returns true if the force-firewalled setting is configured, false otherwise.
|
||||
*
|
||||
* @since 0.9.20
|
||||
* @since 0.9.20, public since 0.9.30
|
||||
*/
|
||||
protected boolean isIPv4Firewalled() {
|
||||
public boolean isIPv4Firewalled() {
|
||||
return TransportUtil.isIPv4Firewalled(_context, getStyle());
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns true if the force-firewalled setting is configured, false otherwise.
|
||||
*
|
||||
* @since 0.9.27
|
||||
* @since 0.9.27, public since 0.9.30
|
||||
*/
|
||||
protected boolean isIPv6Firewalled() {
|
||||
public boolean isIPv6Firewalled() {
|
||||
return TransportUtil.isIPv6Firewalled(_context, getStyle());
|
||||
}
|
||||
|
||||
@@ -987,9 +987,9 @@ public abstract class TransportImpl implements Transport {
|
||||
}
|
||||
|
||||
/**
|
||||
* @since IPv6
|
||||
* @since IPv6, public since 0.9.30
|
||||
*/
|
||||
protected TransportUtil.IPv6Config getIPv6Config() {
|
||||
public TransportUtil.IPv6Config getIPv6Config() {
|
||||
return TransportUtil.getIPv6Config(_context, getStyle());
|
||||
}
|
||||
|
||||
|
||||
146
router/java/src/net/i2p/router/transport/udp/PeerTestEvent.java
Normal file
146
router/java/src/net/i2p/router/transport/udp/PeerTestEvent.java
Normal file
@@ -0,0 +1,146 @@
|
||||
package net.i2p.router.transport.udp;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SimpleTimer2;
|
||||
|
||||
import static net.i2p.router.transport.TransportUtil.IPv6Config.*;
|
||||
import static net.i2p.router.transport.udp.PeerTestState.Role.*;
|
||||
|
||||
/**
|
||||
* Initiate a test (we are Alice)
|
||||
*
|
||||
* @since 0.9.30 moved out of UDPTransport
|
||||
*/
|
||||
class PeerTestEvent extends SimpleTimer2.TimedEvent {
|
||||
private final RouterContext _context;
|
||||
private final Log _log;
|
||||
private final UDPTransport _transport;
|
||||
private final PeerTestManager _testManager;
|
||||
|
||||
private boolean _alive;
|
||||
/** when did we last test our reachability */
|
||||
private final AtomicLong _lastTested = new AtomicLong();
|
||||
private final AtomicLong _lastTestedV6 = new AtomicLong();
|
||||
private static final int NO_FORCE = 0, FORCE_IPV4 = 1, FORCE_IPV6 = 2;
|
||||
private int _forceRun;
|
||||
|
||||
private static final int TEST_FREQUENCY = 13*60*1000;
|
||||
private static final int MIN_TEST_FREQUENCY = 45*1000;
|
||||
|
||||
PeerTestEvent(RouterContext ctx, UDPTransport udp, PeerTestManager ptmgr) {
|
||||
super(ctx.simpleTimer2());
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(PeerTestEvent.class);
|
||||
_transport = udp;
|
||||
_testManager = ptmgr;
|
||||
}
|
||||
|
||||
public synchronized void timeReached() {
|
||||
// just for IPv6 for now
|
||||
if (shouldTest()) {
|
||||
long now = _context.clock().now();
|
||||
long sinceRunV4 = now - _lastTested.get();
|
||||
long sinceRunV6 = now - _lastTestedV6.get();
|
||||
if (_forceRun == FORCE_IPV4 && sinceRunV4 >= MIN_TEST_FREQUENCY) {
|
||||
locked_runTest(false);
|
||||
} else if (_transport.hasIPv6Address() &&_forceRun == FORCE_IPV6 && sinceRunV6 >= MIN_TEST_FREQUENCY) {
|
||||
locked_runTest(true);
|
||||
} else if (sinceRunV4 >= TEST_FREQUENCY && _transport.getIPv6Config() != IPV6_ONLY) {
|
||||
locked_runTest(false);
|
||||
} else if (_transport.hasIPv6Address() && sinceRunV6 >= TEST_FREQUENCY) {
|
||||
locked_runTest(true);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("PTE timeReached(), no test run, last v4 test: " + new java.util.Date(_lastTested.get()) +
|
||||
" last v6 test: " + new java.util.Date(_lastTestedV6.get()));
|
||||
}
|
||||
}
|
||||
if (_alive) {
|
||||
long delay = (TEST_FREQUENCY / 2) + _context.random().nextInt(TEST_FREQUENCY);
|
||||
// if we have 2 addresses, give IPv6 a chance also
|
||||
if (_transport.hasIPv6Address() && _transport.getIPv6Config() != IPV6_ONLY)
|
||||
delay /= 2;
|
||||
schedule(delay);
|
||||
}
|
||||
}
|
||||
|
||||
private void locked_runTest(boolean isIPv6) {
|
||||
PeerState bob = _transport.pickTestPeer(BOB, isIPv6, null);
|
||||
if (bob != null) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Running periodic test with bob = " + bob);
|
||||
_testManager.runTest(bob.getRemoteIPAddress(), bob.getRemotePort(), bob.getCurrentCipherKey(), bob.getCurrentMACKey());
|
||||
setLastTested(isIPv6);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Unable to run peer test, no peers available - v6? " + isIPv6);
|
||||
}
|
||||
_forceRun = NO_FORCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run within the next 45 seconds at the latest
|
||||
* @since 0.9.13
|
||||
*/
|
||||
public synchronized void forceRunSoon(boolean isIPv6) {
|
||||
if (!isIPv6 && _transport.isIPv4Firewalled())
|
||||
return;
|
||||
if (isIPv6 && _transport.isIPv6Firewalled())
|
||||
return;
|
||||
_forceRun = isIPv6 ? FORCE_IPV6 : FORCE_IPV4;
|
||||
reschedule(MIN_TEST_FREQUENCY);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Run within the next 5 seconds at the latest
|
||||
* @since 0.9.13
|
||||
*/
|
||||
public synchronized void forceRunImmediately(boolean isIPv6) {
|
||||
if (!isIPv6 && _transport.isIPv4Firewalled())
|
||||
return;
|
||||
if (isIPv6 && _transport.isIPv6Firewalled())
|
||||
return;
|
||||
if (isIPv6)
|
||||
_lastTestedV6.set(0);
|
||||
else
|
||||
_lastTested.set(0);
|
||||
_forceRun = isIPv6 ? FORCE_IPV6 : FORCE_IPV4;
|
||||
reschedule(5*1000);
|
||||
}
|
||||
|
||||
public synchronized void setIsAlive(boolean isAlive) {
|
||||
_alive = isAlive;
|
||||
if (isAlive) {
|
||||
long delay = _context.random().nextInt(2*TEST_FREQUENCY);
|
||||
reschedule(delay);
|
||||
} else {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the last-tested timer to now
|
||||
* @since 0.9.13
|
||||
*/
|
||||
public void setLastTested(boolean isIPv6) {
|
||||
// do not synchronize - deadlock with PeerTestManager
|
||||
long now = _context.clock().now();
|
||||
if (isIPv6)
|
||||
_lastTestedV6.set(now);
|
||||
else
|
||||
_lastTested.set(now);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("PTE.setLastTested() - v6? " + isIPv6, new Exception());
|
||||
}
|
||||
|
||||
private boolean shouldTest() {
|
||||
return ! (_context.router().isHidden() ||
|
||||
(_transport.isIPv4Firewalled() && _transport.isIPv6Firewalled()));
|
||||
//String val = _context.getProperty(PROP_SHOULD_TEST);
|
||||
//return ( (val != null) && ("true".equals(val)) );
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
private volatile PacketPusher _pusher;
|
||||
private final InboundMessageFragments _inboundFragments;
|
||||
//private UDPFlooder _flooder;
|
||||
private PeerTestManager _testManager;
|
||||
private final PeerTestManager _testManager;
|
||||
private final IntroductionManager _introManager;
|
||||
private final ExpirePeerEvent _expireEvent;
|
||||
private final PeerTestEvent _testEvent;
|
||||
@@ -195,8 +195,6 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
private static final int MAX_CONSECUTIVE_FAILED = 5;
|
||||
|
||||
public static final int DEFAULT_COST = 5;
|
||||
private static final int TEST_FREQUENCY = 13*60*1000;
|
||||
private static final int MIN_TEST_FREQUENCY = 45*1000;
|
||||
static final long[] RATES = { 10*60*1000 };
|
||||
/** minimum active peers to maintain IP detection, etc. */
|
||||
private static final int MIN_PEERS = 5;
|
||||
@@ -266,7 +264,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
// _flooder = new UDPFlooder(_context, this);
|
||||
_expireTimeout = EXPIRE_TIMEOUT;
|
||||
_expireEvent = new ExpirePeerEvent();
|
||||
_testEvent = new PeerTestEvent();
|
||||
_testManager = new PeerTestManager(_context, this);
|
||||
_testEvent = new PeerTestEvent(_context, this, _testManager);
|
||||
_reachabilityStatus = Status.UNKNOWN;
|
||||
_introManager = new IntroductionManager(_context, this);
|
||||
_introducersSelectedOn = -1;
|
||||
@@ -476,9 +475,6 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
if (_establisher == null)
|
||||
_establisher = new EstablishmentManager(_context, this);
|
||||
|
||||
if (_testManager == null)
|
||||
_testManager = new PeerTestManager(_context, this);
|
||||
|
||||
if (_handler == null)
|
||||
_handler = new PacketHandler(_context, this, _establisher, _inboundFragments, _testManager, _introManager);
|
||||
|
||||
@@ -667,6 +663,14 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* For PeerTestManager
|
||||
* @since 0.9.30
|
||||
*/
|
||||
boolean hasIPv6Address() {
|
||||
return _haveIPv6Address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this IP too close to ours to trust it for
|
||||
* things like relaying?
|
||||
@@ -3283,129 +3287,6 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean shouldTest() {
|
||||
return ! (_context.router().isHidden() ||
|
||||
(isIPv4Firewalled() && isIPv6Firewalled()));
|
||||
//String val = _context.getProperty(PROP_SHOULD_TEST);
|
||||
//return ( (val != null) && ("true".equals(val)) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate a test (we are Alice)
|
||||
*/
|
||||
private class PeerTestEvent extends SimpleTimer2.TimedEvent {
|
||||
private boolean _alive;
|
||||
/** when did we last test our reachability */
|
||||
private final AtomicLong _lastTested = new AtomicLong();
|
||||
private final AtomicLong _lastTestedV6 = new AtomicLong();
|
||||
private static final int NO_FORCE = 0, FORCE_IPV4 = 1, FORCE_IPV6 = 2;
|
||||
private int _forceRun;
|
||||
|
||||
PeerTestEvent() {
|
||||
super(_context.simpleTimer2());
|
||||
}
|
||||
|
||||
public synchronized void timeReached() {
|
||||
// just for IPv6 for now
|
||||
if (shouldTest()) {
|
||||
long now = _context.clock().now();
|
||||
long sinceRunV4 = now - _lastTested.get();
|
||||
long sinceRunV6 = now - _lastTestedV6.get();
|
||||
if (_forceRun == FORCE_IPV4 && sinceRunV4 >= MIN_TEST_FREQUENCY) {
|
||||
locked_runTest(false);
|
||||
} else if (_haveIPv6Address &&_forceRun == FORCE_IPV6 && sinceRunV6 >= MIN_TEST_FREQUENCY) {
|
||||
locked_runTest(true);
|
||||
} else if (sinceRunV4 >= TEST_FREQUENCY && getIPv6Config() != IPV6_ONLY) {
|
||||
locked_runTest(false);
|
||||
} else if (_haveIPv6Address && sinceRunV6 >= TEST_FREQUENCY) {
|
||||
locked_runTest(true);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("PTE timeReached(), no test run, last v4 test: " + new java.util.Date(_lastTested.get()) +
|
||||
" last v6 test: " + new java.util.Date(_lastTestedV6.get()));
|
||||
}
|
||||
}
|
||||
if (_alive) {
|
||||
long delay = (TEST_FREQUENCY / 2) + _context.random().nextInt(TEST_FREQUENCY);
|
||||
// if we have 2 addresses, give IPv6 a chance also
|
||||
if (_haveIPv6Address && getIPv6Config() != IPV6_ONLY)
|
||||
delay /= 2;
|
||||
schedule(delay);
|
||||
}
|
||||
}
|
||||
|
||||
private void locked_runTest(boolean isIPv6) {
|
||||
PeerState bob = pickTestPeer(BOB, isIPv6, null);
|
||||
if (bob != null) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Running periodic test with bob = " + bob);
|
||||
_testManager.runTest(bob.getRemoteIPAddress(), bob.getRemotePort(), bob.getCurrentCipherKey(), bob.getCurrentMACKey());
|
||||
setLastTested(isIPv6);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Unable to run peer test, no peers available - v6? " + isIPv6);
|
||||
}
|
||||
_forceRun = NO_FORCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run within the next 45 seconds at the latest
|
||||
* @since 0.9.13
|
||||
*/
|
||||
public synchronized void forceRunSoon(boolean isIPv6) {
|
||||
if (!isIPv6 && isIPv4Firewalled())
|
||||
return;
|
||||
if (isIPv6 && isIPv6Firewalled())
|
||||
return;
|
||||
_forceRun = isIPv6 ? FORCE_IPV6 : FORCE_IPV4;
|
||||
reschedule(MIN_TEST_FREQUENCY);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Run within the next 5 seconds at the latest
|
||||
* @since 0.9.13
|
||||
*/
|
||||
public synchronized void forceRunImmediately(boolean isIPv6) {
|
||||
if (!isIPv6 && isIPv4Firewalled())
|
||||
return;
|
||||
if (isIPv6 && isIPv6Firewalled())
|
||||
return;
|
||||
if (isIPv6)
|
||||
_lastTestedV6.set(0);
|
||||
else
|
||||
_lastTested.set(0);
|
||||
_forceRun = isIPv6 ? FORCE_IPV6 : FORCE_IPV4;
|
||||
reschedule(5*1000);
|
||||
}
|
||||
|
||||
public synchronized void setIsAlive(boolean isAlive) {
|
||||
_alive = isAlive;
|
||||
if (isAlive) {
|
||||
long delay = _context.random().nextInt(2*TEST_FREQUENCY);
|
||||
reschedule(delay);
|
||||
} else {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the last-tested timer to now
|
||||
* @since 0.9.13
|
||||
*/
|
||||
public void setLastTested(boolean isIPv6) {
|
||||
// do not synchronize - deadlock with PeerTestManager
|
||||
long now = _context.clock().now();
|
||||
if (isIPv6)
|
||||
_lastTestedV6.set(now);
|
||||
else
|
||||
_lastTested.set(now);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("PTE.setLastTested() - v6? " + isIPv6, new Exception());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Periodically ping the introducers, split out since we need to
|
||||
* do it faster than we rebuild our address.
|
||||
|
||||
Reference in New Issue
Block a user