From 79a963fcab6ab7a7f0466d6b95085c0c26c2e84e Mon Sep 17 00:00:00 2001
From: zzz
+ UPnP Configuration:
+ />
+ Enable UPnP to open firewall ports
+
+ IP Configuration:
Externally reachable hostname or IP address:
- />
- Use SSU detection only
- />
+ />
Use local public address if available, then UPnP detection, then SSU detection
- />
+ />
Use local public address if available, then SSU detection
- />
+ />
Use UPnP detection if available, then SSU detection
- />
+ />
+ Use SSU detection only
+ />
Specify hostname or IP:
- " />
+ " />
<% String[] ips = nethelper.getAddresses();
if (ips.length > 0) {
- out.print(" or
+ UDP Configuration:
Internal UDP port:
" />
/>
Require SSU introductions
(Enable if you cannot open your firewall)
-
+
Current External UDP address:
If you can, please poke a hole in your NAT or firewall to allow unsolicited UDP packets to reach you on your external UDP address. If you can't, I2P now includes supports UDP hole punching @@ -111,8 +118,8 @@ the Reachability: Firewalled line), or you can manually require them here. Users behind symmetric NATs, such as OpenBSD's pf, are not currently supported.
-
- Inbound TCP connection configuration:
+
+ Inbound TCP Configuration:
Externally reachable hostname or IP address:
/>
Disable (Firewalled)
@@ -125,7 +132,7 @@
Specify hostname or IP:
" />
(dyndns and the like are fine)
-
+
Externally reachable TCP port:
/>
Use the same port configured for SSU
@@ -133,8 +140,8 @@
/>
Specify Port:
" />
-
A hostname entered here will be published in the network database. - It is not private. +
Hostnames entered here will be published in the network database. + They are not private. Also, do not enter a private IP address like 127.0.0.1 or 192.168.1.1.
You do not need to allow inbound TCP connections - outbound connections work with no @@ -142,11 +149,6 @@ in your NAT or firewall for unsolicited TCP connections. If you specify the wrong IP address or hostname, or do not properly configure your NAT or firewall, your network performance will degrade substantially. When in doubt, leave the hostname and port number blank.
-
- UPnP Configuration:
- Open firewall port using UPnP:
- />
-
Note: changing any of these settings will terminate all of your connections and effectively restart your router.
diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 2c9a1319ea..a849e385ca 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -73,7 +73,10 @@ public class Router { /** used to differentiate routerInfo files on different networks */ public static final int NETWORK_ID = 2; + /** this puts an 'H' in your routerInfo **/ public final static String PROP_HIDDEN = "router.hiddenMode"; + /** this does not put an 'H' in your routerInfo **/ + public final static String PROP_HIDDEN_HIDDEN = "router.isHidden"; public final static String PROP_DYNAMIC_KEYS = "router.dynamicKeys"; public final static String PROP_INFO_FILENAME = "router.info.location"; public final static String PROP_INFO_FILENAME_DEFAULT = "router.info"; @@ -423,7 +426,7 @@ public class Router { RouterInfo ri = _routerInfo; if ( (ri != null) && (ri.isHidden()) ) return true; - return Boolean.valueOf(_context.getProperty("router.isHidden", "false")).booleanValue(); + return Boolean.valueOf(_context.getProperty(PROP_HIDDEN_HIDDEN)).booleanValue(); } public Certificate createCertificate() { Certificate cert = new Certificate(); diff --git a/router/java/src/net/i2p/router/transport/Transport.java b/router/java/src/net/i2p/router/transport/Transport.java index d7d73b77b5..fc5c32153a 100644 --- a/router/java/src/net/i2p/router/transport/Transport.java +++ b/router/java/src/net/i2p/router/transport/Transport.java @@ -35,9 +35,9 @@ public interface Transport { public RouterAddress startListening(); public void stopListening(); public RouterAddress getCurrentAddress(); - public static final String SOURCE_UPNP = "UPnP"; - public static final String SOURCE_INTERFACE = "Local interface"; - public static final String SOURCE_CONFIG = "Configuration change"; + public static final String SOURCE_UPNP = "upnp"; + public static final String SOURCE_INTERFACE = "local"; + public static final String SOURCE_CONFIG = "config"; // unused public void externalAddressReceived(String source, byte[] ip, int port); public void forwardPortStatus(int port, boolean success, String reason); public int getRequestedPort(); diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index 21bbcdda18..a6020ae341 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -542,6 +542,12 @@ public class NTCPTransport extends TransportImpl { /** * If we didn't used to be forwarded, and we have an address, * and we are configured to use UPnP, update our RouterAddress + * + * Don't do anything now. If it fails, we don't know if it's + * because there is no firewall, or if the firewall rejected the request. + * So we just use the SSU reachability status + * to decide whether to enable inbound NTCP. SSU will have CSFI build a new + * NTCP address when it transitions to OK. */ public void forwardPortStatus(int port, boolean success, String reason) { if (_log.shouldLog(Log.WARN)) { 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 a43213a9ca..e2bae885d4 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -100,6 +100,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority public static final String STYLE = "SSU"; public static final String PROP_INTERNAL_PORT = "i2np.udp.internalPort"; public static final int DEFAULT_INTERNAL_PORT = 8887; + private static final int MIN_EXTERNAL_PORT = 1024; /** define this to explicitly set an external IP address */ public static final String PROP_EXTERNAL_HOST = "i2np.udp.host"; @@ -118,9 +119,14 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority public static final String PROP_PREFER_UDP = "i2np.udp.preferred"; private static final String DEFAULT_PREFER_UDP = "false"; + /** if true (default), we don't change our advertised port no matter what our peers tell us */ public static final String PROP_FIXED_PORT = "i2np.udp.fixedPort"; private static final String DEFAULT_FIXED_PORT = "true"; + /** allowed sources of address updates */ + public static final String PROP_SOURCES = "i2np.udp.addressSources"; + public static final String DEFAULT_SOURCES = "local,upnp,ssu"; + /** do we require introducers, regardless of our status? */ public static final String PROP_FORCE_INTRODUCERS = "i2np.udp.forceIntroducers"; /** do we allow direct SSU connections, sans introducers? */ @@ -326,11 +332,21 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority /** * From config, UPnP, local i/f, ... + * + * @param source used for logging only + * @param ip publicly routable IPv4 only + * @param port 0 if unknown */ public void externalAddressReceived(String source, byte[] ip, int port) { String s = RemoteHostId.toString(ip); if (_log.shouldLog(Log.WARN)) _log.warn("Received address: " + s + " port: " + port + " from: " + source); + if (explicitAddressSpecified()) + return; + String sources = _context.getProperty(PROP_SOURCES, DEFAULT_SOURCES); + if (!sources.contains(source)) + return; + changeAddress(ip, port); } /** @@ -338,9 +354,15 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority * Right now, we just blindly trust them, changing our IP and port on a * whim. this is not good ;) * + * Todo: + * - Much better tracking of troublemakers + * - Disable if we have good local address or UPnP + * + * @param ip publicly routable IPv4 only + * @param ourPort >= 1024 */ void externalAddressReceived(Hash from, byte ourIP[], int ourPort) { - boolean isValid = isValid(ourIP); + boolean isValid = isValid(ourIP) && ourPort >= MIN_EXTERNAL_PORT; boolean explicitSpecified = explicitAddressSpecified(); boolean inboundRecent = _lastInboundReceivedOn + ALLOW_IP_CHANGE_INTERVAL > System.currentTimeMillis(); if (_log.shouldLog(Log.INFO)) @@ -350,15 +372,15 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority if (explicitSpecified) return; + String sources = _context.getProperty(PROP_SOURCES, DEFAULT_SOURCES); + if (!sources.contains("ssu")) + return; - boolean fixedPort = getIsPortFixed(); - boolean updated = false; - boolean fireTest = false; if (!isValid) { // ignore them if (_log.shouldLog(Log.ERROR)) _log.error("The router " + from.toBase64() + " told us we have an invalid IP - " - + RemoteHostId.toString(ourIP) + ". Lets throw tomatoes at them"); + + RemoteHostId.toString(ourIP) + " port " + ourPort + ". Lets throw tomatoes at them"); markUnreachable(from); //_context.shitlist().shitlistRouter(from, "They said we had an invalid IP", STYLE); return; @@ -367,6 +389,19 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority if (_log.shouldLog(Log.INFO)) _log.info("Ignoring IP address suggestion, since we have received an inbound con recently"); } else { + changeAddress(ourIP, ourPort); + } + + } + + /** + * @param ourPort >= 1024 or 0 for no change + */ + private void changeAddress(byte ourIP[], int ourPort) { + boolean fixedPort = getIsPortFixed(); + boolean updated = false; + boolean fireTest = false; + synchronized (this) { if ( (_externalListenHost == null) || (!eq(_externalListenHost.getAddress(), _externalListenPort, ourIP, ourPort)) ) { @@ -378,11 +413,13 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority _log.info("Trying to change our external address..."); try { _externalListenHost = InetAddress.getByAddress(ourIP); - if (!fixedPort) + if (ourPort >= MIN_EXTERNAL_PORT && !fixedPort) _externalListenPort = ourPort; - rebuildExternalAddress(); - replaceAddress(_externalAddress); - updated = true; + if (_externalListenPort >= MIN_EXTERNAL_PORT) { + rebuildExternalAddress(); + replaceAddress(_externalAddress); + updated = true; + } } catch (UnknownHostException uhe) { _externalListenHost = null; if (_log.shouldLog(Log.INFO)) @@ -401,8 +438,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority _log.info("Same address as the current one"); } } - } - + if (fireTest) { _context.statManager().addRateData("udp.addressTestInsteadOfUpdate", 1, 0); _testEvent.forceRun(); @@ -417,7 +453,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority SimpleTimer.getInstance().addEvent(_testEvent, 5*1000); } } - + private static final boolean eq(byte laddr[], int lport, byte raddr[], int rport) { return (rport == lport) && DataHelper.eq(laddr, raddr); }