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

@ -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();