2007-07-07 zzz

* Add auto-detect IP/Port to NTCP. When enabled on config.jsp,
      SSU will notify/restart NTCP when the external address changes.
      Now you can enable inbound TCP without a static IP or dyndns service.
This commit is contained in:
zzz
2007-07-07 20:03:50 +00:00
committed by zzz
parent 409b71def5
commit d4a1bcf28f
10 changed files with 209 additions and 23 deletions

View File

@ -41,6 +41,8 @@ public class ConfigNetHandler extends FormHandler {
private String _ntcpPort;
private String _tcpPort;
private String _udpPort;
private boolean _ntcpAutoIP;
private boolean _ntcpAutoPort;
private String _inboundRate;
private String _inboundBurstRate;
private String _inboundBurst;
@ -70,6 +72,8 @@ public class ConfigNetHandler extends FormHandler {
public void setDynamicKeys(String moo) { _dynamicKeys = true; }
public void setUpdateratesonly(String moo) { _ratesOnly = true; }
public void setEnableloadtesting(String moo) { _enableLoadTesting = true; }
public void setNtcpAutoIP(String moo) { _ntcpAutoIP = true; }
public void setNtcpAutoPort(String moo) { _ntcpAutoPort = true; }
public void setHostname(String hostname) {
_hostname = (hostname != null ? hostname.trim() : null);
@ -142,27 +146,49 @@ public class ConfigNetHandler extends FormHandler {
}
}
if ( (_ntcpHostname != null) && (_ntcpHostname.length() > 0) && (_ntcpPort != null) && (_ntcpPort.length() > 0) ) {
String oldHost = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME);
String oldPort = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_PORT);
if ( (oldHost == null) || (!oldHost.equalsIgnoreCase(_ntcpHostname)) ||
(oldPort == null) || (!oldPort.equalsIgnoreCase(_ntcpPort)) ) {
_context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME, _ntcpHostname);
_context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_PORT, _ntcpPort);
addFormNotice("Updating inbound TCP settings from " + oldHost + ":" + oldPort
+ " to " + _ntcpHostname + ":" + _ntcpPort);
restartRequired = true;
}
} else {
String oldHost = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME);
String oldPort = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_PORT);
if ( (oldHost != null) || (oldPort != null) ) {
// Normalize some things to make the following code a little easier...
String oldNHost = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME);
if (oldNHost == null) oldNHost = "";
String oldNPort = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_PORT);
if (oldNPort == null) oldNPort = "";
String sAutoHost = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_AUTO_IP);
String sAutoPort = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_AUTO_PORT);
boolean oldAutoHost = "true".equalsIgnoreCase(sAutoHost);
boolean oldAutoPort = "true".equalsIgnoreCase(sAutoPort);
if (_ntcpHostname == null) _ntcpHostname = "";
if (_ntcpPort == null) _ntcpPort = "";
if (oldAutoHost != _ntcpAutoIP || ! oldNHost.equalsIgnoreCase(_ntcpHostname)) {
if (_ntcpAutoIP) {
_context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_AUTO_IP, "true");
_context.router().removeConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME);
_context.router().removeConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_PORT);
addFormNotice("Updating inbound TCP settings from " + oldHost + ":" + oldPort
+ " so that we no longer receive inbound TCP connections");
restartRequired = true;
addFormNotice("Updating inbound TCP address to auto");
} else if (_ntcpHostname.length() > 0) {
_context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME, _ntcpHostname);
_context.router().removeConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_AUTO_IP);
addFormNotice("Updating inbound TCP address to " + _ntcpHostname);
} else {
_context.router().removeConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME);
_context.router().removeConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_AUTO_IP);
addFormNotice("Disabling inbound TCP");
}
restartRequired = true;
}
if (oldAutoPort != _ntcpAutoPort || ! oldNPort.equals(_ntcpPort)) {
if ( _ntcpAutoPort ) {
_context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_AUTO_PORT, "true");
_context.router().removeConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_PORT);
addFormNotice("Updating inbound TCP port to auto");
} else if (_ntcpPort.length() > 0) {
_context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_PORT, _ntcpPort);
_context.router().removeConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_AUTO_PORT);
addFormNotice("Updating inbound TCP port to " + _ntcpPort);
} else {
_context.router().removeConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_PORT);
_context.router().removeConfigSetting(ConfigNetHelper.PROP_I2NP_NTCP_AUTO_PORT);
addFormNotice("Disabling inbound TCP");
}
restartRequired = true;
}
if ( (_udpPort != null) && (_udpPort.length() > 0) ) {

View File

@ -50,6 +50,8 @@ public class ConfigNetHelper {
}
public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname";
public final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port";
public final static String PROP_I2NP_NTCP_AUTO_PORT = "i2np.ntcp.autoip";
public final static String PROP_I2NP_NTCP_AUTO_IP = "i2np.ntcp.autoport";
public String getNtcphostname() {
String hostname = _context.getProperty(PROP_I2NP_NTCP_HOSTNAME);
if (hostname == null) return "";
@ -69,6 +71,26 @@ public class ConfigNetHelper {
return ua.toString();
}
public String getUdpIP() {
RouterAddress addr = _context.router().getRouterInfo().getTargetAddress("SSU");
if (addr == null)
return "unknown";
UDPAddress ua = new UDPAddress(addr);
if (ua.getHost() == null)
return "unknown";
return ua.getHost();
}
public String getUdpPort() {
RouterAddress addr = _context.router().getRouterInfo().getTargetAddress("SSU");
if (addr == null)
return "unknown";
UDPAddress ua = new UDPAddress(addr);
if (ua.getPort() <= 0)
return "unknown";
return "" + ua.getPort();
}
public String getEnableTimeSyncChecked() {
String disabled = _context.getProperty(Timestamper.PROP_DISABLED, "false");
if ( (disabled != null) && ("true".equalsIgnoreCase(disabled)) )
@ -93,6 +115,22 @@ public class ConfigNetHelper {
return "";
}
public String getTcpAutoPortChecked() {
String enabled = _context.getProperty(PROP_I2NP_NTCP_AUTO_PORT, "false");
if ( (enabled != null) && ("true".equalsIgnoreCase(enabled)) )
return " checked ";
else
return "";
}
public String getTcpAutoIPChecked() {
String enabled = _context.getProperty(PROP_I2NP_NTCP_AUTO_IP, "false");
if ( (enabled != null) && ("true".equalsIgnoreCase(enabled)) )
return " checked ";
else
return "";
}
public String getRequireIntroductionsChecked() {
short status = _context.commSystem().getReachabilityStatus();
switch (status) {

View File

@ -82,14 +82,21 @@
Externally reachable hostname or IP address:
<input name ="ntcphost" type="text" size="16" value="<jsp:getProperty name="nethelper" property="ntcphostname" />" />
(dyndns and the like are fine)<br />
OR use IP address detected by SSU
(currently <jsp:getProperty name="nethelper" property="udpIP" />)?
<input type="checkbox" name="ntcpAutoIP" value="true" <jsp:getProperty name="nethelper" property="tcpAutoIPChecked" /> /><br />
<p>
Externally reachable TCP port:
<input name ="ntcpport" type="text" size="6" value="<jsp:getProperty name="nethelper" property="ntcpport" />" /><br />
OR use the same port configured for SSU
(currently <jsp:getProperty name="nethelper" property="udpPort" />)?
<input type="checkbox" name="ntcpAutoPort" value="true" <jsp:getProperty name="nethelper" property="tcpAutoPortChecked" /> /><br />
<p>You do <i>not</i> need to allow inbound TCP connections - outbound connections work with no
configuration. However, if you want to receive inbound TCP connections, you <b>must</b> poke a hole
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.</p>
<p><b>Note: changing this setting will terminate all of your connections and effectively
<p><b>Note: changing any of these settings will terminate all of your connections and effectively
restart your router.</b>
<hr />
<!--

View File

@ -1,4 +1,9 @@
$Id: history.txt,v 1.571 2007-07-01 17:07:53 zzz Exp $
$Id: history.txt,v 1.572 2007-07-04 17:58:50 zzz Exp $
2007-07-07 zzz
* Add auto-detect IP/Port to NTCP. When enabled on config.jsp,
SSU will notify/restart NTCP when the external address changes.
Now you can enable inbound TCP without a static IP or dyndns service.
2007-07-04 zzz
* Display calculated share bandwidth and remove load testing

View File

@ -14,6 +14,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.i2p.data.RouterAddress;
/**
* Manages the communication subsystem between peers, including connections,
@ -52,6 +53,10 @@ public abstract class CommSystemFacade implements Service {
public short getReachabilityStatus() { return STATUS_OK; }
public void recheckReachability() {}
/**
* Tell other transports our address changed
*/
public void notifyReplaceAddress(RouterAddress UDPAddr) {}
/**
* We are able to receive unsolicited connections
*/

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.506 $ $Date: 2007-07-01 17:07:52 $";
public final static String ID = "$Revision: 1.507 $ $Date: 2007-07-04 17:58:48 $";
public final static String VERSION = "0.6.1.28";
public final static long BUILD = 9;
public final static long BUILD = 10;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -26,6 +26,7 @@ import net.i2p.router.RouterContext;
import net.i2p.router.transport.ntcp.NTCPAddress;
import net.i2p.router.transport.ntcp.NTCPTransport;
import net.i2p.router.transport.tcp.TCPTransport;
import net.i2p.router.transport.udp.UDPAddress;
import net.i2p.util.Log;
public class CommSystemFacadeImpl extends CommSystemFacade {
@ -194,6 +195,8 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname";
public final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port";
public final static String PROP_I2NP_NTCP_AUTO_PORT = "i2np.ntcp.autoip";
public final static String PROP_I2NP_NTCP_AUTO_IP = "i2np.ntcp.autoport";
public static RouterAddress createNTCPAddress(RouterContext ctx) {
if (!TransportManager.enableNTCP(ctx)) return null;
@ -235,4 +238,80 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
//}
return addr;
}
/**
* UDP changed addresses, tell NTCP and restart
*/
public void notifyReplaceAddress(RouterAddress UDPAddr) {
if (UDPAddr == null)
return;
NTCPTransport t = (NTCPTransport) _manager.getNTCPTransport();
if (t == null)
return;
Properties UDPProps = UDPAddr.getOptions();
if (UDPProps == null)
return;
Properties newProps;
RouterAddress oldAddr = t.getCurrentAddress();
//_log.warn("Changing NTCP Address? was " + oldAddr);
RouterAddress newAddr = oldAddr;
if (newAddr == null) {
newAddr = new RouterAddress();
newAddr.setCost(10);
newAddr.setExpiration(null);
newAddr.setTransportStyle(NTCPTransport.STYLE);
newProps = new Properties();
} else {
newProps = newAddr.getOptions();
if (newProps == null)
newProps = new Properties();
}
boolean changed = false;
String oport = newProps.getProperty(NTCPAddress.PROP_PORT);
String enabled = _context.getProperty(PROP_I2NP_NTCP_AUTO_PORT, "false");
if ( (enabled != null) && ("true".equalsIgnoreCase(enabled)) ) {
String nport = UDPProps.getProperty(UDPAddress.PROP_PORT);
if (nport == null || nport.length() <= 0)
return;
if (oport == null || ! oport.equals(nport)) {
newProps.setProperty(NTCPAddress.PROP_PORT, nport);
changed = true;
}
} else if (oport == null || oport.length() <= 0) {
return;
}
String ohost = newProps.getProperty(NTCPAddress.PROP_HOST);
enabled = _context.getProperty(PROP_I2NP_NTCP_AUTO_IP, "false");
if ( (enabled != null) && ("true".equalsIgnoreCase(enabled)) ) {
String nhost = UDPProps.getProperty(UDPAddress.PROP_HOST);
if (nhost == null || nhost.length() <= 0)
return;
if (ohost == null || ! ohost.equalsIgnoreCase(nhost)) {
newProps.setProperty(NTCPAddress.PROP_HOST, nhost);
changed = true;
}
} else if (ohost == null || ohost.length() <= 0) {
return;
}
if (!changed) {
//_log.warn("No change to NTCP Address");
return;
}
// stopListening stops the pumper, readers, and writers, so required even if
// oldAddr == null since startListening starts them all again
_log.warn("Halting NTCP to change address");
t.stopListening();
newAddr.setOptions(newProps);
// Give NTCP Pumper time to stop so we don't end up with two...
// Need better way
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
t.restartListening(newAddr);
_log.warn("Changed NTCP Address and started up, address is now " + newAddr);
return;
}
}

View File

@ -367,7 +367,10 @@ public abstract class TransportImpl implements Transport {
* one.
*/
protected void replaceAddress(RouterAddress address) {
// _log.error("Replacing address for " + getStyle() + " was " + _currentAddress + " now " + address);
_currentAddress = address;
if ("SSU".equals(getStyle()))
_context.commSystem().notifyReplaceAddress(address);
}
/** Who to notify on message availability */

View File

@ -124,6 +124,15 @@ public class TransportManager implements TransportEventListener {
_transports.clear();
}
public Transport getNTCPTransport() {
for (int i = 0; i < _transports.size(); i++) {
Transport t = (Transport)_transports.get(i);
if("NTCP".equals(t.getStyle()))
return t;
}
return null;
}
int getTransportCount() { return _transports.size(); }
private boolean isSupported(Set addresses, Transport t) {

View File

@ -379,7 +379,21 @@ public class NTCPTransport extends TransportImpl {
_writer.startWriting(NUM_CONCURRENT_WRITERS);
configureLocalAddress();
return bindAddress();
}
public RouterAddress restartListening(RouterAddress addr) {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Restarting ntcp transport listening");
_pumper.startPumping();
_reader.startReading(NUM_CONCURRENT_READERS);
_writer.startWriting(NUM_CONCURRENT_WRITERS);
_myAddress = new NTCPAddress(addr);
return bindAddress();
}
private RouterAddress bindAddress() {
if (_myAddress != null) {
try {
ServerSocketChannel chan = ServerSocketChannel.open();