Start new IPv6 branch

- Add new TransportUtil for getting/setting IPv6 config
- Prep for supporting multiple RouterAddresses per-transport
- RouterAddress hashCode/equals tweaks
This commit is contained in:
zzz
2013-05-02 12:55:35 +00:00
parent 6265bdf026
commit 3ec78e27b4
11 changed files with 255 additions and 77 deletions

View File

@@ -238,14 +238,18 @@ public class RouterAddress extends DataStructureImpl {
DataHelper.writeProperties(out, _options); DataHelper.writeProperties(out, _options);
} }
/**
* Transport, IP, and port only.
* Never look at cost or other properties.
*/
@Override @Override
public boolean equals(Object object) { public boolean equals(Object object) {
if (object == this) return true; if (object == this) return true;
if ((object == null) || !(object instanceof RouterAddress)) return false; if ((object == null) || !(object instanceof RouterAddress)) return false;
RouterAddress addr = (RouterAddress) object; RouterAddress addr = (RouterAddress) object;
// let's keep this fast as we are putting an address into the RouterInfo set frequently
return return
_cost == addr._cost && getPort() == addr.getPort() &&
DataHelper.eq(getIP(), addr.getIP()) &&
DataHelper.eq(_transportStyle, addr._transportStyle); DataHelper.eq(_transportStyle, addr._transportStyle);
//DataHelper.eq(_options, addr._options) && //DataHelper.eq(_options, addr._options) &&
//DataHelper.eq(_expiration, addr._expiration); //DataHelper.eq(_expiration, addr._expiration);
@@ -253,13 +257,13 @@ public class RouterAddress extends DataStructureImpl {
/** /**
* Just use a few items for speed (expiration is always null). * Just use a few items for speed (expiration is always null).
* Never look at cost or other properties.
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return DataHelper.hashCode(_transportStyle) ^ return DataHelper.hashCode(_transportStyle) ^
DataHelper.hashCode(getIP()) ^ DataHelper.hashCode(getIP()) ^
getPort() ^ getPort();
_cost;
} }
/** /**

View File

@@ -28,8 +28,8 @@ public abstract class CommSystemFacade implements Service {
public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException { } public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException { }
public void renderStatusHTML(Writer out) throws IOException { renderStatusHTML(out, null, 0); } public void renderStatusHTML(Writer out) throws IOException { renderStatusHTML(out, null, 0); }
/** Create the set of RouterAddress structures based on the router's config */ /** Create the list of RouterAddress structures based on the router's config */
public Set<RouterAddress> createAddresses() { return Collections.EMPTY_SET; } public List<RouterAddress> createAddresses() { return Collections.EMPTY_LIST; }
public int countActivePeers() { return 0; } public int countActivePeers() { return 0; }
public int countActiveSendPeers() { return 0; } public int countActiveSendPeers() { return 0; }

View File

@@ -10,15 +10,14 @@ package net.i2p.router.transport;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set;
import java.util.Vector; import java.util.Vector;
import net.i2p.data.Hash; import net.i2p.data.Hash;
@@ -167,7 +166,7 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
} }
@Override @Override
public List getMostRecentErrorMessages() { public List<String> getMostRecentErrorMessages() {
return _manager.getMostRecentErrorMessages(); return _manager.getMostRecentErrorMessages();
} }
@@ -190,26 +189,29 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
/** @return non-null, possibly empty */ /** @return non-null, possibly empty */
@Override @Override
public Set<RouterAddress> createAddresses() { public List<RouterAddress> createAddresses() {
// No, don't do this, it makes it almost impossible to build inbound tunnels // No, don't do this, it makes it almost impossible to build inbound tunnels
//if (_context.router().isHidden()) //if (_context.router().isHidden())
// return Collections.EMPTY_SET; // return Collections.EMPTY_SET;
Map<String, RouterAddress> addresses = _manager.getAddresses(); List<RouterAddress> addresses = new ArrayList(_manager.getAddresses());
Transport ntcp = _manager.getTransport(NTCPTransport.STYLE);
boolean hasNTCP = ntcp != null && ntcp.hasCurrentAddress();
boolean newCreated = false; boolean newCreated = false;
if (!hasNTCP) {
if (!addresses.containsKey(NTCPTransport.STYLE)) {
RouterAddress addr = createNTCPAddress(_context); RouterAddress addr = createNTCPAddress(_context);
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("NTCP address: " + addr); _log.info("NTCP address: " + addr);
if (addr != null) { if (addr != null) {
addresses.put(NTCPTransport.STYLE, addr); addresses.add(addr);
newCreated = true; newCreated = true;
} }
} }
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Creating addresses: " + addresses + " isNew? " + newCreated, new Exception("creator")); _log.info("Creating addresses: " + addresses + " isNew? " + newCreated, new Exception("creator"));
return new HashSet(addresses.values()); return addresses;
} }
public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname"; public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname";
@@ -278,9 +280,20 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
NTCPTransport t = (NTCPTransport) _manager.getTransport(NTCPTransport.STYLE); NTCPTransport t = (NTCPTransport) _manager.getTransport(NTCPTransport.STYLE);
if (t == null) if (t == null)
return; return;
RouterAddress oldAddr = t.getCurrentAddress();
//////// FIXME just take first IPv4 address for now
List<RouterAddress> oldAddrs = t.getCurrentAddresses();
RouterAddress oldAddr = null;
for (RouterAddress ra : oldAddrs) {
byte[] ipx = ra.getIP();
if (ipx != null && ipx.length == 4) {
oldAddr = ra;
break;
}
}
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Changing NTCP Address? was " + oldAddr); _log.info("Changing NTCP Address? was " + oldAddr);
RouterAddress newAddr = new RouterAddress(); RouterAddress newAddr = new RouterAddress();
newAddr.setTransportStyle(NTCPTransport.STYLE); newAddr.setTransportStyle(NTCPTransport.STYLE);
Properties newProps = new Properties(); Properties newProps = new Properties();

View File

@@ -32,10 +32,29 @@ public interface Transport {
* *
*/ */
public void send(OutNetMessage msg); public void send(OutNetMessage msg);
public RouterAddress startListening(); public void startListening();
public void stopListening(); public void stopListening();
public RouterAddress getCurrentAddress();
public RouterAddress updateAddress(); /**
* What addresses are we currently listening to?
* Replaces getCurrentAddress()
* @return all addresses, non-null
* @since IPv6
*/
public List<RouterAddress> getCurrentAddresses();
/**
* Do we have any current address?
* @since IPv6
*/
public boolean hasCurrentAddress();
/**
* Ask the transport to update its addresses based on current information and return them
* @return all addresses, non-null
*/
public List<RouterAddress> updateAddress();
public static final String SOURCE_UPNP = "upnp"; public static final String SOURCE_UPNP = "upnp";
public static final String SOURCE_INTERFACE = "local"; public static final String SOURCE_INTERFACE = "local";
public static final String SOURCE_CONFIG = "config"; // unused public static final String SOURCE_CONFIG = "config"; // unused
@@ -51,7 +70,7 @@ public interface Transport {
public boolean haveCapacity(); public boolean haveCapacity();
public boolean haveCapacity(int pct); public boolean haveCapacity(int pct);
public Vector getClockSkews(); public Vector getClockSkews();
public List getMostRecentErrorMessages(); public List<String> getMostRecentErrorMessages();
public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException; public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException;
public short getReachabilityStatus(); public short getReachabilityStatus();

View File

@@ -10,7 +10,6 @@ package net.i2p.router.transport;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@@ -23,6 +22,7 @@ import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
import net.i2p.data.Hash; import net.i2p.data.Hash;
@@ -50,7 +50,7 @@ import net.i2p.util.SimpleTimer;
public abstract class TransportImpl implements Transport { public abstract class TransportImpl implements Transport {
private final Log _log; private final Log _log;
private TransportEventListener _listener; private TransportEventListener _listener;
private RouterAddress _currentAddress; protected final List<RouterAddress> _currentAddresses;
// Only used by NTCP. SSU does not use. See send() below. // Only used by NTCP. SSU does not use. See send() below.
private final BlockingQueue<OutNetMessage> _sendPool; private final BlockingQueue<OutNetMessage> _sendPool;
protected final RouterContext _context; protected final RouterContext _context;
@@ -87,6 +87,8 @@ public abstract class TransportImpl implements Transport {
_context.statManager().createRequiredRateStat("transport.sendProcessingTime", "Time to process and send a message (ms)", "Transport", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l }); _context.statManager().createRequiredRateStat("transport.sendProcessingTime", "Time to process and send a message (ms)", "Transport", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
//_context.statManager().createRateStat("transport.sendProcessingTime." + getStyle(), "Time to process and send a message (ms)", "Transport", new long[] { 60*1000l }); //_context.statManager().createRateStat("transport.sendProcessingTime." + getStyle(), "Time to process and send a message (ms)", "Transport", new long[] { 60*1000l });
_context.statManager().createRateStat("transport.expiredOnQueueLifetime", "How long a message that expires on our outbound queue is processed", "Transport", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l } ); _context.statManager().createRateStat("transport.expiredOnQueueLifetime", "How long a message that expires on our outbound queue is processed", "Transport", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l } );
_currentAddresses = new CopyOnWriteArrayList();
if (getStyle().equals("NTCP")) if (getStyle().equals("NTCP"))
_sendPool = new ArrayBlockingQueue(8); _sendPool = new ArrayBlockingQueue(8);
else else
@@ -166,7 +168,7 @@ public abstract class TransportImpl implements Transport {
*/ */
public Vector getClockSkews() { return new Vector(); } public Vector getClockSkews() { return new Vector(); }
public List getMostRecentErrorMessages() { return Collections.EMPTY_LIST; } public List<String> getMostRecentErrorMessages() { return Collections.EMPTY_LIST; }
/** /**
* Nonblocking call to pull the next outbound message * Nonblocking call to pull the next outbound message
@@ -464,27 +466,61 @@ public abstract class TransportImpl implements Transport {
/** Do we increase the advertised cost when approaching conn limits? */ /** Do we increase the advertised cost when approaching conn limits? */
public static final boolean ADJUST_COST = true; public static final boolean ADJUST_COST = true;
/** What addresses are we currently listening to? */ /**
public RouterAddress getCurrentAddress() { * What addresses are we currently listening to?
return _currentAddress; * Replaces getCurrentAddress()
* @return all addresses, non-null
* @since IPv6
*/
public List<RouterAddress> getCurrentAddresses() {
return _currentAddresses;
}
/**
* Do we have any current address?
* @since IPv6
*/
public boolean hasCurrentAddress() {
return !_currentAddresses.isEmpty();
} }
/** /**
* Ask the transport to update its address based on current information and return it * Ask the transport to update its address based on current information and return it
* Transports should override. * Transports should override.
* @return all addresses, non-null
* @since 0.7.12 * @since 0.7.12
*/ */
public RouterAddress updateAddress() { public List<RouterAddress> updateAddress() {
return _currentAddress; return _currentAddresses;
} }
/** /**
* Replace any existing addresses for the current transport with the given * Replace any existing addresses for the current transport
* one. * with the same IP length (4 or 16) with the given one.
* TODO: Allow multiple addresses of the same length.
* Calls listener.transportAddressChanged()
*
* @param address null to remove all
*/ */
protected void replaceAddress(RouterAddress address) { protected void replaceAddress(RouterAddress address) {
// _log.error("Replacing address for " + getStyle() + " was " + _currentAddress + " now " + address); if (_log.shouldLog(Log.WARN))
_currentAddress = address; _log.warn("Replacing address with " + address);
if (address == null) {
_currentAddresses.clear();
} else {
byte[] ip = address.getIP();
if (ip == null) {
_log.error("WTF null ip for " + address);
return;
}
int len = ip.length;
for (RouterAddress ra : _currentAddresses) {
byte[] ipx = ra.getIP();
if (ipx != null && ipx.length == len)
_currentAddresses.remove(ra);
}
_currentAddresses.add(address);
}
if (_listener != null) if (_listener != null)
_listener.transportAddressChanged(); _listener.transportAddressChanged();
} }

View File

@@ -14,6 +14,7 @@ import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -248,7 +249,7 @@ public class TransportManager implements TransportEventListener {
*/ */
public boolean haveInboundCapacity(int pct) { public boolean haveInboundCapacity(int pct) {
for (Transport t : _transports.values()) { for (Transport t : _transports.values()) {
if (t.getCurrentAddress() != null && t.haveCapacity(pct)) if (t.hasCurrentAddress() && t.haveCapacity(pct))
return true; return true;
} }
return false; return false;
@@ -332,43 +333,67 @@ public class TransportManager implements TransportEventListener {
/** /**
* This forces a rebuild * This forces a rebuild
*/ */
public Map<String, RouterAddress> getAddresses() { public List<RouterAddress> getAddresses() {
Map<String, RouterAddress> rv = new HashMap(_transports.size()); List<RouterAddress> rv = new ArrayList(4);
// do this first since SSU may force a NTCP change // do this first since SSU may force a NTCP change
for (Transport t : _transports.values()) for (Transport t : _transports.values())
t.updateAddress(); t.updateAddress();
for (Transport t : _transports.values()) { for (Transport t : _transports.values()) {
if (t.getCurrentAddress() != null) rv.addAll(t.getCurrentAddresses());
rv.put(t.getStyle(), t.getCurrentAddress());
} }
return rv; return rv;
} }
/**
* @since IPv6
*/
static class Port {
public final String style;
public final int port;
public Port(String style, int port) {
this.style = style;
this.port = port;
}
@Override
public int hashCode() {
return style.hashCode() ^ port;
}
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (! (o instanceof Port))
return false;
Port p = (Port) o;
return port == p.port && style.equals(p.style);
}
}
/** /**
* Include the published port, or the requested port, for each transport * Include the published port, or the requested port, for each transport
* which we will pass along to UPnP * which we will pass along to UPnP
*/ */
private Map<String, Integer> getPorts() { private Set<Port> getPorts() {
Map<String, Integer> rv = new HashMap(_transports.size()); Set<Port> rv = new HashSet(4);
for (Transport t : _transports.values()) { for (Transport t : _transports.values()) {
int port = t.getRequestedPort(); int port = t.getRequestedPort();
if (t.getCurrentAddress() != null) { for (RouterAddress ra : t.getCurrentAddresses()) {
String s = t.getCurrentAddress().getOption("port"); int p = ra.getPort();
if (s != null) { if (p > 0)
try { port = p;
port = Integer.parseInt(s); // Use UDP port for NTCP too - see comment in NTCPTransport.getRequestedPort() for why this is here
} catch (NumberFormatException nfe) {} if (t.getStyle().equals(NTCPTransport.STYLE) && port <= 0 &&
} _context.getBooleanProperty(CommSystemFacadeImpl.PROP_I2NP_NTCP_AUTO_PORT)) {
Transport udp = getTransport(UDPTransport.STYLE);
if (udp != null)
port = t.getRequestedPort();
}
if (port > 0)
rv.add(new Port(t.getStyle(), port));
} }
// Use UDP port for NTCP too - see comment in NTCPTransport.getRequestedPort() for why this is here
if (t.getStyle().equals(NTCPTransport.STYLE) && port <= 0 &&
_context.getBooleanProperty(CommSystemFacadeImpl.PROP_I2NP_NTCP_AUTO_PORT)) {
Transport udp = getTransport(UDPTransport.STYLE);
if (udp != null)
port = t.getRequestedPort();
}
if (port > 0)
rv.put(t.getStyle(), Integer.valueOf(port));
} }
return rv; return rv;
} }
@@ -485,8 +510,8 @@ public class TransportManager implements TransportEventListener {
_upnpManager.update(getPorts()); _upnpManager.update(getPorts());
} }
public List getMostRecentErrorMessages() { public List<String> getMostRecentErrorMessages() {
List rv = new ArrayList(16); List<String> rv = new ArrayList(16);
for (Transport t : _transports.values()) { for (Transport t : _transports.values()) {
rv.addAll(t.getMostRecentErrorMessages()); rv.addAll(t.getMostRecentErrorMessages());
} }
@@ -510,11 +535,15 @@ public class TransportManager implements TransportEventListener {
StringBuilder buf = new StringBuilder(4*1024); StringBuilder buf = new StringBuilder(4*1024);
buf.append("<h3>").append(_("Router Transport Addresses")).append("</h3><pre>\n"); buf.append("<h3>").append(_("Router Transport Addresses")).append("</h3><pre>\n");
for (Transport t : _transports.values()) { for (Transport t : _transports.values()) {
if (t.getCurrentAddress() != null) if (t.hasCurrentAddress()) {
buf.append(t.getCurrentAddress()); for (RouterAddress ra : t.getCurrentAddresses()) {
else buf.append(ra.toString());
buf.append("\n\n");
}
} else {
buf.append(_("{0} is used for outbound connections only", t.getStyle())); buf.append(_("{0} is used for outbound connections only", t.getStyle()));
buf.append("\n\n"); buf.append("\n\n");
}
} }
buf.append("</pre>\n"); buf.append("</pre>\n");
out.write(buf.toString()); out.write(buf.toString());

View File

@@ -0,0 +1,78 @@
package net.i2p.router.transport;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind { either expressed or implied.
* It probably won't make your computer catch on fire { or eat
* your children { but it might. Use at your own risk.
*
*/
import java.util.HashMap;
import java.util.Map;
import net.i2p.router.RouterContext;
/**
* @since IPv6
*/
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 enum IPv6Config {
/** IPv6 disabled */
IPV6_DISABLED("false"),
/** lower priority than IPv4 */
IPV6_NOT_PREFERRED("preferIPv4"),
/** equal priority to IPv4 */
IPV6_ENABLED("enable"),
/** higher priority than IPv4 */
IPV6_PREFERRED("preferIPv6"),
/** IPv4 disabled */
IPV6_ONLY("only");
private final String cfgstr;
IPv6Config(String cfgstr) {
this.cfgstr = cfgstr;
}
public String toConfigString() {
return cfgstr;
}
}
private static final Map<String, IPv6Config> BY_NAME = new HashMap<String, IPv6Config>();
static {
for (IPv6Config cfg : IPv6Config.values()) {
BY_NAME.put(cfg.toConfigString(), cfg);
}
}
public static IPv6Config getIPv6Config(RouterContext ctx, String transportStyle) {
String cfg;
if (transportStyle.equals("NTCP"))
cfg = ctx.getProperty(NTCP_IPV6_CONFIG);
else if (transportStyle.equals("SSU"))
cfg = ctx.getProperty(SSU_IPV6_CONFIG);
else
return IPv6Config.IPV6_DISABLED;
return getIPv6Config(cfg);
}
public static IPv6Config getIPv6Config(String cfg) {
if (cfg == null)
return IPv6Config.IPV6_DISABLED;
IPv6Config c = BY_NAME.get(cfg);
if (c != null)
return c;
return IPv6Config.IPV6_DISABLED;
}
}

View File

@@ -52,6 +52,7 @@ import org.freenetproject.ForwardPortStatus;
* *
* @see "http://www.upnp.org/" * @see "http://www.upnp.org/"
* @see "http://en.wikipedia.org/wiki/Universal_Plug_and_Play" * @see "http://en.wikipedia.org/wiki/Universal_Plug_and_Play"
* @since 0.7.4
*/ */
/* /*

View File

@@ -25,6 +25,7 @@ import org.freenetproject.ForwardPortStatus;
* Bridge from the I2P RouterAddress data structure to * Bridge from the I2P RouterAddress data structure to
* the freenet data structures * the freenet data structures
* *
* @since 0.7.4
* @author zzz * @author zzz
*/ */
class UPnPManager { class UPnPManager {
@@ -106,7 +107,7 @@ class UPnPManager {
* which can have multiple UPnP threads running at once, but * which can have multiple UPnP threads running at once, but
* that should be ok. * that should be ok.
*/ */
public void update(Map<String, Integer> ports) { public void update(Set<TransportManager.Port> ports) {
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("UPnP Update with " + ports.size() + " ports"); _log.debug("UPnP Update with " + ports.size() + " ports");
@@ -121,9 +122,9 @@ class UPnPManager {
//} //}
Set<ForwardPort> forwards = new HashSet(ports.size()); Set<ForwardPort> forwards = new HashSet(ports.size());
for (Map.Entry<String, Integer> entry : ports.entrySet()) { for (TransportManager.Port entry : ports) {
String style = entry.getKey(); String style = entry.style;
int port = entry.getValue().intValue(); int port = entry.port;
int protocol = -1; int protocol = -1;
if ("SSU".equals(style)) if ("SSU".equals(style))
protocol = ForwardPort.PROTOCOL_UDP_IPV4; protocol = ForwardPort.PROTOCOL_UDP_IPV4;

View File

@@ -458,30 +458,28 @@ public class NTCPTransport extends TransportImpl {
* verify stopped with isAlive() * verify stopped with isAlive()
* Unfortunately TransportManager doesn't do that, so we * Unfortunately TransportManager doesn't do that, so we
* check here to prevent two pumpers. * check here to prevent two pumpers.
* @return appears to be ignored by caller
*/ */
public synchronized RouterAddress startListening() { public synchronized void startListening() {
// try once again to prevent two pumpers which is fatal // try once again to prevent two pumpers which is fatal
if (_pumper.isAlive()) if (_pumper.isAlive())
return _myAddress != null ? _myAddress.toRouterAddress() : null; return;
if (_log.shouldLog(Log.WARN)) _log.warn("Starting ntcp transport listening"); if (_log.shouldLog(Log.WARN)) _log.warn("Starting ntcp transport listening");
startIt(); startIt();
configureLocalAddress(); configureLocalAddress();
return bindAddress(); bindAddress();
} }
/** /**
* Only called by CSFI. * Only called by CSFI.
* Caller should stop the transport first, then * Caller should stop the transport first, then
* verify stopped with isAlive() * verify stopped with isAlive()
* @return appears to be ignored by caller
*/ */
public synchronized RouterAddress restartListening(RouterAddress addr) { public synchronized void restartListening(RouterAddress addr) {
// try once again to prevent two pumpers which is fatal // try once again to prevent two pumpers which is fatal
// we could just return null since the return value is ignored // we could just return null since the return value is ignored
if (_pumper.isAlive()) if (_pumper.isAlive())
return _myAddress != null ? _myAddress.toRouterAddress() : null; return;
if (_log.shouldLog(Log.WARN)) _log.warn("Restarting ntcp transport listening"); if (_log.shouldLog(Log.WARN)) _log.warn("Restarting ntcp transport listening");
startIt(); startIt();
@@ -489,7 +487,7 @@ public class NTCPTransport extends TransportImpl {
_myAddress = null; _myAddress = null;
else else
_myAddress = new NTCPAddress(addr); _myAddress = new NTCPAddress(addr);
return bindAddress(); bindAddress();
} }
/** /**

View File

@@ -1446,9 +1446,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
// we don't need the following, since we have our own queueing // we don't need the following, since we have our own queueing
protected void outboundMessageReady() { throw new UnsupportedOperationException("Not used for UDP"); } protected void outboundMessageReady() { throw new UnsupportedOperationException("Not used for UDP"); }
public RouterAddress startListening() { public void startListening() {
startup(); startup();
return _externalAddress;
} }
public void stopListening() { public void stopListening() {
@@ -1470,9 +1469,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
* @since 0.7.12 * @since 0.7.12
*/ */
@Override @Override
public RouterAddress updateAddress() { public List<RouterAddress> updateAddress() {
rebuildExternalAddress(false); rebuildExternalAddress(false);
return getCurrentAddress(); return getCurrentAddresses();
} }
private void rebuildExternalAddress() { rebuildExternalAddress(true); } private void rebuildExternalAddress() { rebuildExternalAddress(true); }