* Transport:

- Fix recognition of IP change when not firewalled
      - Require consecutive identical results from two peers before changing IP
This commit is contained in:
zzz
2010-02-18 16:31:57 +00:00
parent d4f1230b37
commit e2dc9715d2

View File

@ -80,6 +80,11 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
private int _expireTimeout; private int _expireTimeout;
/** last report from a peer of our IP */
private Hash _lastFrom;
private byte[] _lastOurIP;
private int _lastOurPort;
private static final int DROPLIST_PERIOD = 10*60*1000; private static final int DROPLIST_PERIOD = 10*60*1000;
private static final int MAX_DROPLIST_SIZE = 256; private static final int MAX_DROPLIST_SIZE = 256;
@ -407,9 +412,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
* Right now, we just blindly trust them, changing our IP and port on a * Right now, we just blindly trust them, changing our IP and port on a
* whim. this is not good ;) * whim. this is not good ;)
* *
* Slight enhancement - require two different peers in a row to agree
*
* Todo: * Todo:
* - Much better tracking of troublemakers * - Much better tracking of troublemakers
* - Disable if we have good local address or UPnP * - Disable if we have good local address or UPnP
* - This gets harder if and when we publish multiple addresses, or IPv6
* *
* @param from Hash of inbound destination * @param from Hash of inbound destination
* @param ourIP publicly routable IPv4 only * @param ourIP publicly routable IPv4 only
@ -441,9 +449,25 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
return; return;
} else if (inboundRecent && _externalListenPort > 0 && _externalListenHost != null) { } else if (inboundRecent && _externalListenPort > 0 && _externalListenHost != null) {
// use OS clock since its an ordering thing, not a time thing // use OS clock since its an ordering thing, not a time thing
// Note that this fails us if we switch from one IP to a second, then back to the first,
// as some routers still have the first IP and will successfully connect,
// leaving us thinking the second IP is still good.
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Ignoring IP address suggestion, since we have received an inbound con recently"); _log.info("Ignoring IP address suggestion, since we have received an inbound con recently");
} else if (from.equals(_lastFrom) || !eq(_lastOurIP, _lastOurPort, ourIP, ourPort)) {
_lastFrom = from;
_lastOurIP = ourIP;
_lastOurPort = ourPort;
if (_log.shouldLog(Log.WARN))
_log.warn("The router " + from.toBase64() + " told us we have a new IP - "
+ RemoteHostId.toString(ourIP) + " port " + ourPort + ". Wait until somebody else tells us the same thing.");
} else { } else {
if (_log.shouldLog(Log.WARN))
_log.warn(from.toBase64() + " and " + _lastFrom.toBase64() + " agree we have a new IP - "
+ RemoteHostId.toString(ourIP) + " port " + ourPort + ". Changing address.");
_lastFrom = from;
_lastOurIP = ourIP;
_lastOurPort = ourPort;
changeAddress(ourIP, ourPort); changeAddress(ourIP, ourPort);
} }
@ -462,14 +486,15 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_log.warn("Change address? status = " + _reachabilityStatus + _log.warn("Change address? status = " + _reachabilityStatus +
" diff = " + (_context.clock().now() - _reachabilityStatusLastUpdated) + " diff = " + (_context.clock().now() - _reachabilityStatusLastUpdated) +
" old = " + _externalListenHost + ':' + _externalListenPort + " old = " + _externalListenHost + ':' + _externalListenPort +
" new = " + DataHelper.toString(ourIP) + ':' + ourPort); " new = " + RemoteHostId.toString(ourIP) + ':' + ourPort);
synchronized (this) { synchronized (this) {
if ( (_externalListenHost == null) || if ( (_externalListenHost == null) ||
(!eq(_externalListenHost.getAddress(), _externalListenPort, ourIP, ourPort)) ) { (!eq(_externalListenHost.getAddress(), _externalListenPort, ourIP, ourPort)) ) {
if ( (_reachabilityStatus != CommSystemFacade.STATUS_OK) || // This prevents us from changing our IP when we are not firewalled
(_externalListenHost == null) || (_externalListenPort <= 0) || //if ( (_reachabilityStatus != CommSystemFacade.STATUS_OK) ||
(_context.clock().now() - _reachabilityStatusLastUpdated > 2*TEST_FREQUENCY) ) { // (_externalListenHost == null) || (_externalListenPort <= 0) ||
// (_context.clock().now() - _reachabilityStatusLastUpdated > 2*TEST_FREQUENCY) ) {
// they told us something different and our tests are either old or failing // they told us something different and our tests are either old or failing
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Trying to change our external address..."); _log.warn("Trying to change our external address...");
@ -488,13 +513,13 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Error trying to change our external address", uhe); _log.warn("Error trying to change our external address", uhe);
} }
} else { //} else {
// they told us something different, but our tests are recent and positive, // // they told us something different, but our tests are recent and positive,
// so lets test again // // so lets test again
fireTest = true; // fireTest = true;
if (_log.shouldLog(Log.WARN)) // if (_log.shouldLog(Log.WARN))
_log.warn("Different address, but we're fine.. (" + _reachabilityStatus + ")"); // _log.warn("Different address, but we're fine.. (" + _reachabilityStatus + ")");
} //}
} else { } else {
// matched what we expect // matched what we expect
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))