Transport: Add config to force IPv4 (only) to firewalled (ticket #1541)

since we cannot reliably detect DS-lite (ticket #1458)
Hide transport status on /peers unless routerconsole.advanced
This commit is contained in:
zzz
2015-05-06 01:45:33 +00:00
parent 31435685bf
commit abd8ca34dc
8 changed files with 83 additions and 15 deletions

View File

@ -50,6 +50,7 @@ public class ConfigNetHandler extends FormHandler {
private boolean _ratesOnly;
private boolean _udpDisabled;
private String _ipv6Mode;
private boolean _ipv4Firewalled;
private final Map<String, String> changes = new HashMap<String, String>();
private static final String PROP_HIDDEN = Router.PROP_HIDDEN_HIDDEN; // see Router for other choice
@ -79,9 +80,13 @@ public class ConfigNetHandler extends FormHandler {
public void setNtcpAutoPort(String mode) {
_ntcpAutoPort = mode.equals("2");
}
public void setUpnp(String moo) { _upnp = true; }
public void setLaptop(String moo) { _laptop = true; }
/** @since 0.9.20 */
public void setIPv4Firewalled(String moo) { _ipv4Firewalled = true; }
public void setHostname(String hostname) {
_hostname = (hostname != null ? hostname.trim() : null);
}
@ -348,6 +353,16 @@ public class ConfigNetHandler extends FormHandler {
}
changes.put(UDPTransport.PROP_LAPTOP_MODE, "" + _laptop);
if (Boolean.parseBoolean(_context.getProperty(TransportUtil.PROP_IPV4_FIREWALLED)) !=
_ipv4Firewalled) {
if (_ipv4Firewalled)
addFormNotice(_("Disabling inbound IPv4"));
else
addFormNotice(_("Enabling inbound IPv4"));
restartRequired = true;
}
changes.put(TransportUtil.PROP_IPV4_FIREWALLED, "" + _ipv4Firewalled);
if (_context.getBooleanPropertyDefaultTrue(TransportManager.PROP_ENABLE_UDP) !=
!_udpDisabled) {
if (_udpDisabled)

View File

@ -93,6 +93,11 @@ public class ConfigNetHelper extends HelperBase {
return getChecked(UDPTransport.PROP_LAPTOP_MODE);
}
/** @since 0.9.20 */
public String getIPv4FirewalledChecked() {
return getChecked(TransportUtil.PROP_IPV4_FIREWALLED);
}
public String getTcpAutoPortChecked(int mode) {
String port = _context.getProperty(PROP_I2NP_NTCP_PORT);
boolean specified = port != null && port.length() > 0;

View File

@ -51,6 +51,10 @@
<%=intl._("Laptop mode - Change router identity and UDP port when IP changes for enhanced anonymity")%>
(<i><%=intl._("Experimental")%></i>)
</p><p>
<%=intl._("IPv4 Configuration")%>:<br>
<input type="checkbox" class="optbox" name="IPv4Firewalled" value="true" <jsp:getProperty name="nethelper" property="IPv4FirewalledChecked" /> >
<%=intl._("Disable inbound (Firewalled by Carrier-grade NAT or DS-Lite)")%>
</p><p>
<%=intl._("IPv6 Configuration")%>:<br>
<input type="radio" class="optbox" name="ipv6" value="false" <%=nethelper.getIPv6Checked("false") %> >
<%=intl._("Disable IPv6")%><br>

View File

@ -813,6 +813,14 @@ public abstract class TransportImpl implements Transport {
*/
public void recheckReachability() {}
/**
* @param transportStyle ignored
* @since 0.9.20
*/
protected boolean isIPv4Firewalled() {
return TransportUtil.isIPv4Firewalled(_context, getStyle());
}
public boolean isBacklogged(Hash dest) { return false; }
public boolean isEstablished(Hash dest) { return false; }

View File

@ -61,6 +61,8 @@ public class TransportManager implements TransportEventListener {
/** default true */
public final static String PROP_ENABLE_UPNP = "i2np.upnp.enable";
private static final String PROP_ADVANCED = "routerconsole.advanced";
/** not forever, since they may update */
private static final long SIGTYPE_BANLIST_DURATION = 36*60*60*1000L;
@ -667,11 +669,13 @@ public class TransportManager implements TransportEventListener {
* will take many seconds if it has vanished.
*/
public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException {
out.write("<p>");
if (_context.getBooleanProperty(PROP_ADVANCED)) {
out.write("<p><b>");
out.write(_("Status"));
out.write(": ");
out.write(_(getReachabilityStatus().toStatusString()));
out.write("</p>");
out.write("</b></p>");
}
TreeMap<String, Transport> transports = new TreeMap<String, Transport>();
for (Transport t : _transports.values()) {
transports.put(t.getStyle(), t);

View File

@ -23,6 +23,7 @@ public abstract class TransportUtil {
public static final String NTCP_IPV6_CONFIG = "i2np.ntcp.ipv6";
public static final String SSU_IPV6_CONFIG = "i2np.udp.ipv6";
public static final String PROP_IPV4_FIREWALLED = "i2np.ipv4.firewalled";
public enum IPv6Config {
/** IPv6 disabled */
@ -83,6 +84,14 @@ public abstract class TransportUtil {
return DEFAULT_IPV6_CONFIG;
}
/**
* @param transportStyle ignored
* @since 0.9.20
*/
public static boolean isIPv4Firewalled(RouterContext ctx, String transportStyle) {
return ctx.getBooleanProperty(PROP_IPV4_FIREWALLED);
}
/**
* Addresses without a host (i.e. w/introducers)
* are assumed to be IPv4

View File

@ -1344,7 +1344,9 @@ public class NTCPTransport extends TransportImpl {
buf.append("<h3 id=\"ntcpcon\">").append(_("NTCP connections")).append(": ").append(peers.size());
buf.append(". ").append(_("Limit")).append(": ").append(getMaxConnections());
buf.append(". ").append(_("Timeout")).append(": ").append(DataHelper.formatDuration2(_pumper.getIdleTimeout()));
if (_context.getBooleanProperty(PROP_ADVANCED)) {
buf.append(". ").append(_("Status")).append(": ").append(_(getReachabilityStatus().toStatusString()));
}
buf.append(".</h3>\n" +
"<table>\n" +
"<tr><th><a href=\"#def.peer\">").append(_("Peer")).append("</a></th>" +

View File

@ -167,6 +167,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
public static final String PROP_BIND_INTERFACE = "i2np.udp.bindInterface";
/** override the "large" (max) MTU, default is PeerState.LARGE_MTU */
private static final String PROP_DEFAULT_MTU = "i2np.udp.mtu";
private static final String PROP_ADVANCED = "routerconsole.advanced";
private static final String CAP_TESTING = "" + UDPAddress.CAPACITY_TESTING;
private static final String CAP_TESTING_INTRO = "" + UDPAddress.CAPACITY_TESTING + UDPAddress.CAPACITY_INTRODUCER;
@ -457,6 +458,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
//if (SHOULD_FLOOD_PEERS)
// _flooder.startup();
_expireEvent.setIsAlive(true);
_reachabilityStatus = Status.UNKNOWN;
_testEvent.setIsAlive(true); // this queues it for 3-6 minutes in the future...
_testEvent.reschedule(10*1000); // lets requeue it for Real Soon
@ -477,6 +479,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_lastInboundIPv6 = _context.clock().now();
setReachabilityStatus(Status.IPV4_UNKNOWN_IPV6_OK);
} else {
if (!isIPv4Firewalled())
setReachabilityStatus(Status.IPV4_OK_IPV6_UNKNOWN);
}
rebuildExternalAddress(ia.getHostAddress(), newPort, false);
@ -487,11 +490,18 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_lastInboundIPv6 = _context.clock().now();
setReachabilityStatus(Status.IPV4_UNKNOWN_IPV6_OK);
} else {
if (!isIPv4Firewalled())
setReachabilityStatus(Status.IPV4_OK_IPV6_UNKNOWN);
}
rebuildExternalAddress(ia.getHostAddress(), newPort, false);
}
}
if (isIPv4Firewalled()) {
if (_lastInboundIPv6 > 0)
setReachabilityStatus(Status.IPV4_FIREWALLED_IPV6_UNKNOWN);
else
setReachabilityStatus(Status.REJECT_UNSOLICITED);
}
rebuildExternalAddress(false);
}
@ -763,14 +773,16 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
// Assume if we have an interface with a public IP that we aren't firewalled.
// If this is wrong, the peer test will figure it out and change the status.
if (changed && source == SOURCE_INTERFACE) {
if (ip.length == 4)
if (ip.length == 4) {
if (!isIPv4Firewalled())
setReachabilityStatus(Status.IPV4_OK_IPV6_UNKNOWN);
else if (ip.length == 16)
} else if (ip.length == 16) {
// TODO should we set both to unknown and wait for an inbound v6 conn,
// since there's no v6 testing?
setReachabilityStatus(Status.IPV4_UNKNOWN_IPV6_OK);
}
}
}
/**
* Callback from UPnP.
@ -786,9 +798,11 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
else
_log.warn("UPnP has failed to open the SSU port: " + port + " reason: " + reason);
}
if (success && ip != null && getExternalIP() != null)
if (success && ip != null && getExternalIP() != null) {
if (!isIPv4Firewalled())
setReachabilityStatus(Status.IPV4_OK_IPV6_UNKNOWN);
}
}
/**
* Someone we tried to contact gave us what they think our IP address is.
@ -2434,7 +2448,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
buf.append("<h3 id=\"udpcon\">").append(_("UDP connections")).append(": ").append(peers.size());
buf.append(". ").append(_("Limit")).append(": ").append(getMaxConnections());
buf.append(". ").append(_("Timeout")).append(": ").append(DataHelper.formatDuration2(_expireTimeout));
if (_context.getBooleanProperty(PROP_ADVANCED)) {
buf.append(". ").append(_("Status")).append(": ").append(_(_reachabilityStatus.toStatusString()));
}
buf.append(".</h3>\n");
buf.append("<table>\n");
buf.append("<tr><th class=\"smallhead\" nowrap><a href=\"#def.peer\">").append(_("Peer")).append("</a><br>");
@ -3003,7 +3019,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
}
private boolean shouldTest() {
return ! _context.router().isHidden();
return ! (_context.router().isHidden() ||
isIPv4Firewalled());
//String val = _context.getProperty(PROP_SHOULD_TEST);
//return ( (val != null) && ("true".equals(val)) );
}
@ -3053,6 +3070,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
* @since 0.9.13
*/
public synchronized void forceRunSoon() {
if (isIPv4Firewalled())
return;
_forceRun = true;
reschedule(MIN_TEST_FREQUENCY);
}
@ -3063,6 +3082,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
* @since 0.9.13
*/
public synchronized void forceRunImmediately() {
if (isIPv4Firewalled())
return;
_lastTested.set(0);
_forceRun = true;
reschedule(5*1000);