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 +