* Transport: Implement NTCP auto-transition from an

address to no address, so that inbound NTCP is disabled
      after SSU detects a firewall. When UPnP was apparently successful
      but the router is still firewalled (due to an additional
      software firewall or a bad UPnP indication, for example)
      the router will now remove the NTCP address.
This commit is contained in:
zzz
2009-07-05 18:48:10 +00:00
parent ca14002bd1
commit a8a21ddb73
3 changed files with 39 additions and 16 deletions

View File

@ -206,14 +206,15 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
public final static String PROP_I2NP_NTCP_AUTO_IP = "i2np.ntcp.autoip"; public final static String PROP_I2NP_NTCP_AUTO_IP = "i2np.ntcp.autoip";
/** /**
* This only creates an address if the hostname AND port are set in router.config,
* which should be rare.
* Otherwise, notifyReplaceAddress() below takes care of it.
* Note this is called both from above and from NTCPTransport.startListening()
*
* This should really be moved to ntcp/NTCPTransport.java, why is it here? * This should really be moved to ntcp/NTCPTransport.java, why is it here?
*/ */
public static RouterAddress createNTCPAddress(RouterContext ctx) { public static RouterAddress createNTCPAddress(RouterContext ctx) {
if (!TransportManager.enableNTCP(ctx)) return null; if (!TransportManager.enableNTCP(ctx)) return null;
RouterAddress addr = new RouterAddress();
addr.setCost(10);
addr.setExpiration(null);
Properties props = new Properties();
String name = ctx.router().getConfigSetting(PROP_I2NP_NTCP_HOSTNAME); String name = ctx.router().getConfigSetting(PROP_I2NP_NTCP_HOSTNAME);
String port = ctx.router().getConfigSetting(PROP_I2NP_NTCP_PORT); String port = ctx.router().getConfigSetting(PROP_I2NP_NTCP_PORT);
/* /*
@ -236,12 +237,16 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
return null; return null;
} }
Properties props = new Properties();
props.setProperty(NTCPAddress.PROP_HOST, name); props.setProperty(NTCPAddress.PROP_HOST, name);
props.setProperty(NTCPAddress.PROP_PORT, port); props.setProperty(NTCPAddress.PROP_PORT, port);
RouterAddress addr = new RouterAddress();
addr.setCost(10);
addr.setExpiration(null);
addr.setOptions(props); addr.setOptions(props);
addr.setTransportStyle(NTCPTransport.STYLE); addr.setTransportStyle(NTCPTransport.STYLE);
//if (isNew) { //if (isNew) {
if (false) return null; // why save the same thing?
ctx.router().setConfigSetting(PROP_I2NP_NTCP_HOSTNAME, name); ctx.router().setConfigSetting(PROP_I2NP_NTCP_HOSTNAME, name);
ctx.router().setConfigSetting(PROP_I2NP_NTCP_PORT, port); ctx.router().setConfigSetting(PROP_I2NP_NTCP_PORT, port);
ctx.router().saveConfig(); ctx.router().saveConfig();
@ -334,6 +339,15 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
} }
} else if (ohost == null || ohost.length() <= 0) { } else if (ohost == null || ohost.length() <= 0) {
return; return;
} else if (enabled.equalsIgnoreCase("true") && status != STATUS_OK) {
// UDP transitioned to not-OK, turn off NTCP address
// This will commonly happen at startup if we were initially OK
// because UPnP was successful, but a subsequent SSU Peer Test determines
// we are still firewalled (SW firewall, bad UPnP indication, etc.)
if (_log.shouldLog(Log.INFO))
_log.info("old: " + ohost + " config: " + name + " new: null");
newAddr = null;
changed = true;
} }
if (!changed) { if (!changed) {
@ -346,9 +360,11 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
// //
// really need to fix this so that we can change or create an inbound address // really need to fix this so that we can change or create an inbound address
// without tearing down everything // without tearing down everything
// Especially on disabling the address, we shouldn't tear everything down.
// //
_log.warn("Halting NTCP to change address"); _log.warn("Halting NTCP to change address");
t.stopListening(); t.stopListening();
if (newAddr != null)
newAddr.setOptions(newProps); newAddr.setOptions(newProps);
// Wait for NTCP Pumper to stop so we don't end up with two... // Wait for NTCP Pumper to stop so we don't end up with two...
while (t.isAlive()) { while (t.isAlive()) {

View File

@ -417,7 +417,7 @@ public class NTCPTransport extends TransportImpl {
private static final int NUM_CONCURRENT_WRITERS = 3; private static final int NUM_CONCURRENT_WRITERS = 3;
public synchronized RouterAddress startListening() { public synchronized RouterAddress startListening() {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Starting ntcp transport listening"); if (_log.shouldLog(Log.WARN)) _log.warn("Starting ntcp transport listening");
_finisher.start(); _finisher.start();
_pumper.startPumping(); _pumper.startPumping();
@ -429,13 +429,16 @@ public class NTCPTransport extends TransportImpl {
} }
public synchronized RouterAddress restartListening(RouterAddress addr) { public synchronized RouterAddress restartListening(RouterAddress addr) {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Restarting ntcp transport listening"); if (_log.shouldLog(Log.WARN)) _log.warn("Restarting ntcp transport listening");
_finisher.start(); _finisher.start();
_pumper.startPumping(); _pumper.startPumping();
_reader.startReading(NUM_CONCURRENT_READERS); _reader.startReading(NUM_CONCURRENT_READERS);
_writer.startWriting(NUM_CONCURRENT_WRITERS); _writer.startWriting(NUM_CONCURRENT_WRITERS);
if (addr == null)
_myAddress = null;
else
_myAddress = new NTCPAddress(addr); _myAddress = new NTCPAddress(addr);
return bindAddress(); return bindAddress();
} }
@ -603,7 +606,7 @@ public class NTCPTransport extends TransportImpl {
* before calling startListening() or restartListening() * before calling startListening() or restartListening()
*/ */
public synchronized void stopListening() { public synchronized void stopListening() {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Stopping ntcp transport"); if (_log.shouldLog(Log.WARN)) _log.warn("Stopping ntcp transport");
_pumper.stopPumping(); _pumper.stopPumping();
_writer.stopWriting(); _writer.stopWriting();
_reader.stopReading(); _reader.stopReading();

View File

@ -437,12 +437,16 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
synchronized (this) { synchronized (this) {
if ( (_externalListenHost == null) || if ( (_externalListenHost == null) ||
(!eq(_externalListenHost.getAddress(), _externalListenPort, ourIP, ourPort)) ) { (!eq(_externalListenHost.getAddress(), _externalListenPort, ourIP, ourPort)) ) {
if (_log.shouldLog(Log.WARN))
_log.warn("Change address? status = " + _reachabilityStatus +
" diff = " + (_context.clock().now() - _reachabilityStatusLastUpdated) +
" old = " + _externalListenHost + ':' + _externalListenPort);
if ( (_reachabilityStatus != CommSystemFacade.STATUS_OK) || if ( (_reachabilityStatus != CommSystemFacade.STATUS_OK) ||
(_externalListenHost == null) || (_externalListenPort <= 0) || (_externalListenHost == null) || (_externalListenPort <= 0) ||
(_context.clock().now() - _reachabilityStatusLastUpdated > 2*TEST_FREQUENCY) ) { (_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.INFO)) if (_log.shouldLog(Log.WARN))
_log.info("Trying to change our external address..."); _log.warn("Trying to change our external address...");
try { try {
_externalListenHost = InetAddress.getByAddress(ourIP); _externalListenHost = InetAddress.getByAddress(ourIP);
// fixed port defaults to true so we never do this // fixed port defaults to true so we never do this
@ -455,15 +459,15 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
} }
} catch (UnknownHostException uhe) { } catch (UnknownHostException uhe) {
_externalListenHost = null; _externalListenHost = null;
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.WARN))
_log.info("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.INFO)) if (_log.shouldLog(Log.WARN))
_log.info("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