diff --git a/router/java/src/net/i2p/router/transport/udp/PeerTestEvent.java b/router/java/src/net/i2p/router/transport/udp/PeerTestEvent.java index 6e4243e2b43c951efafb018b34ea5567127203af..10de3c87d9f7b385d0d02cd31a7e127c15e1a69e 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerTestEvent.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerTestEvent.java @@ -8,7 +8,7 @@ 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) * @@ -26,6 +26,7 @@ class PeerTestEvent extends SimpleTimer2.TimedEvent { private final AtomicLong _lastTestedV6 = new AtomicLong(); private static final int NO_FORCE = 0, FORCE_IPV4 = 1, FORCE_IPV6 = 2; private int _forceRun; + private boolean _lastTestIPv6 = true; private static final int TEST_FREQUENCY = 13*60*1000; private static final int MIN_TEST_FREQUENCY = 45*1000; @@ -37,7 +38,7 @@ class PeerTestEvent extends SimpleTimer2.TimedEvent { _transport = udp; _testManager = ptmgr; } - + public synchronized void timeReached() { if (shouldTest()) { long now = _context.clock().now(); @@ -45,14 +46,17 @@ class PeerTestEvent extends SimpleTimer2.TimedEvent { long sinceRunV6 = now - _lastTestedV6.get(); boolean configV4fw = _transport.isIPv4Firewalled(); boolean configV6fw = _transport.isIPv6Firewalled(); + boolean preferV4 = _lastTestIPv6; if (!configV4fw && _forceRun == FORCE_IPV4 && sinceRunV4 >= MIN_TEST_FREQUENCY) { locked_runTest(false); } else if (!configV6fw && _forceRun == FORCE_IPV6 && _transport.hasIPv6Address() && sinceRunV6 >= MIN_TEST_FREQUENCY) { locked_runTest(true); - } else if (!configV4fw && sinceRunV4 >= TEST_FREQUENCY && _transport.getIPv6Config() != IPV6_ONLY) { + } else if (preferV4 && !configV4fw && sinceRunV4 >= TEST_FREQUENCY && _transport.getIPv6Config() != IPV6_ONLY) { locked_runTest(false); } else if (!configV6fw && _transport.hasIPv6Address() && sinceRunV6 >= TEST_FREQUENCY) { locked_runTest(true); + } else if (!preferV4 && !configV4fw && sinceRunV4 >= TEST_FREQUENCY && _transport.getIPv6Config() != IPV6_ONLY) { + locked_runTest(false); } else { if (_log.shouldLog(Log.INFO)) _log.info("PTE timeReached(), no test run, last v4 test: " + new java.util.Date(_lastTested.get()) + @@ -72,8 +76,9 @@ class PeerTestEvent extends SimpleTimer2.TimedEvent { schedule(delay); } } - + private void locked_runTest(boolean isIPv6) { + _lastTestIPv6 = isIPv6; PeerState bob = _transport.pickTestPeer(BOB, isIPv6, null); if (bob != null) { if (_log.shouldLog(Log.INFO)) @@ -88,7 +93,7 @@ class PeerTestEvent extends SimpleTimer2.TimedEvent { // so we don't get stuck running the same test over and over _forceRun = NO_FORCE; } - + /** * Run within the next 45 seconds at the latest * @since 0.9.13 @@ -96,7 +101,7 @@ class PeerTestEvent extends SimpleTimer2.TimedEvent { public synchronized void forceRunSoon(boolean isIPv6) { forceRunSoon(isIPv6, MIN_TEST_FREQUENCY); } - + /** * Run within the specified time at the latest * @since 0.9.39 @@ -113,7 +118,7 @@ class PeerTestEvent extends SimpleTimer2.TimedEvent { _log.debug("reschedule for " + net.i2p.data.DataHelper.formatDuration(delay)); reschedule(delay); } - + /** * * Run within the next 5 seconds at the latest @@ -122,7 +127,7 @@ class PeerTestEvent extends SimpleTimer2.TimedEvent { public synchronized void forceRunImmediately(boolean isIPv6) { forceRunSoon(isIPv6, 5*1000); } - + public synchronized void setIsAlive(boolean isAlive) { if (_log.shouldLog(Log.DEBUG)) _log.debug("PTE.setIsAlive(), isAlive? " + isAlive, new Exception()); @@ -151,7 +156,7 @@ class PeerTestEvent extends SimpleTimer2.TimedEvent { if (_log.shouldLog(Log.DEBUG)) _log.debug("PTE.setLastTested() - v6? " + isIPv6, new Exception()); } - + private boolean shouldTest() { return ! (_context.router().isHidden() || (_transport.isIPv4Firewalled() && _transport.isIPv6Firewalled())); diff --git a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java index 3f5a619d9223677c506eceb7003c8f2242531964..e4b5d94b47a19ccd18e82f55059f90317f73da82 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java @@ -195,7 +195,6 @@ class PeerTestManager { test.setBobPort(bobPort); test.setBobCipherKey(bobCipherKey); test.setBobMACKey(bobMACKey); - test.setLastSendTime(test.getBeginTime()); _currentTest = test; _currentTestComplete = false; @@ -268,6 +267,7 @@ class PeerTestManager { if (!expired()) { if (_log.shouldLog(Log.DEBUG)) _log.debug("Sending test to Bob: " + test); + test.setLastSendTime(_context.clock().now()); _transport.send(_packetBuilder.buildPeerTestFromAlice(test.getBobIP(), test.getBobPort(), test.getBobCipherKey(), test.getBobMACKey(), //_bobIntroKey, test.getNonce(), _transport.getIntroKey())); @@ -282,6 +282,7 @@ class PeerTestManager { if (!expired()) { if (_log.shouldLog(Log.DEBUG)) _log.debug("Sending test to Charlie: " + test); + test.setLastSendTime(_context.clock().now()); _transport.send(_packetBuilder.buildPeerTestFromAlice(test.getCharlieIP(), test.getCharliePort(), test.getCharlieIntroKey(), test.getNonce(), _transport.getIntroKey())); @@ -688,7 +689,6 @@ class PeerTestManager { state.setAliceIntroKey(aliceIntroKey); state.setBobIP(bobIP); state.setBobPort(from.getPort()); - state.setLastSendTime(now); state.setReceiveBobTime(now); PeerState bob = _transport.getPeerState(from); @@ -716,6 +716,7 @@ class PeerTestManager { _context.simpleTimer2().addEvent(new RemoveTest(nonce), MAX_CHARLIE_LIFETIME); } + state.setLastSendTime(now); UDPPacket packet = _packetBuilder.buildPeerTestToBob(bobIP, from.getPort(), aliceIP, alicePort, aliceIntroKey, nonce, state.getBobCipherKey(), state.getBobMACKey()); @@ -810,7 +811,6 @@ class PeerTestManager { state.setCharlieIP(charlie.getRemoteIPAddress()); state.setCharliePort(charlie.getRemotePort()); state.setCharlieIntroKey(charlieIntroKey); - state.setLastSendTime(now); state.setReceiveAliceTime(now); if (state.incrementPacketsRelayed() > MAX_RELAYED_PER_TEST_BOB) { @@ -824,6 +824,7 @@ class PeerTestManager { _context.simpleTimer2().addEvent(new RemoveTest(nonce), MAX_CHARLIE_LIFETIME); } + state.setLastSendTime(now); UDPPacket packet = _packetBuilder.buildPeerTestToCharlie(aliceIP, from.getPort(), aliceIntroKey, nonce, charlie.getRemoteIPAddress(), charlie.getRemotePort(), @@ -862,6 +863,7 @@ class PeerTestManager { return; } state.setReceiveCharlieTime(now); + state.setLastSendTime(now); UDPPacket packet = _packetBuilder.buildPeerTestToAlice(state.getAliceIP(), state.getAlicePort(), state.getAliceIntroKey(), state.getCharlieIntroKey(), @@ -894,6 +896,7 @@ class PeerTestManager { return; } state.setReceiveAliceTime(now); + state.setLastSendTime(now); try { InetAddress aliceIP = InetAddress.getByAddress(from.getIP()); 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 3e2cfbdf33781dd4844145121e3975b32c99285d..5a533ca9e52c57509481f43e8eb94990b9acd976 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -3353,9 +3353,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority // as rebuildExternalAddress() calls replaceAddress() which calls CSFI.notifyReplaceAddress() // which will start up NTCP inbound when we transition to OK. if (isIPv6) { - if (STATUS_IPV6_FW.contains(status)) { + if (STATUS_IPV6_FW_2.contains(status)) { removeExternalAddress(true, true); - } else if (STATUS_IPV6_FW.contains(old) && + } else if (STATUS_IPV6_FW_2.contains(old) && STATUS_IPV6_OK.contains(status) && _lastOurIPv6 != null && !explicitAddressSpecified()){ @@ -3367,6 +3367,13 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority rebuildExternalAddress(); } } else { + if (newStatus == Status.UNKNOWN && status != _reachabilityStatusPending) { + // still have something pending, try again + if (_log.shouldLog(Log.WARN)) + _log.warn("Old status: " + status + " status pending confirmation: " + _reachabilityStatusPending + + " Caused by update: " + newStatus); + _testEvent.forceRunSoon(isIPv6); + } if (_log.shouldLog(Log.INFO)) _log.info("Status unchanged: " + _reachabilityStatus + " after update: " + newStatus +