prep for multiple address discovery

This commit is contained in:
zzz
2013-05-03 16:34:02 +00:00
parent c6121cb31e
commit 757df8c726
3 changed files with 40 additions and 16 deletions

View File

@ -529,22 +529,27 @@ public abstract class TransportImpl implements Transport {
* Notify a transport of an external address change. * Notify a transport of an external address change.
* This may be from a local interface, UPnP, a config change, etc. * This may be from a local interface, UPnP, a config change, etc.
* This should not be called if the ip didn't change * This should not be called if the ip didn't change
* (from that source's point of view), or is a local address, * (from that source's point of view), or is a local address.
* or if the ip is IPv6, but the transport should check anyway. * May be called multiple times for IPv4 or IPv6.
* The transport should also do its own checking on whether to accept * The transport should also do its own checking on whether to accept
* notifications from this source. * notifications from this source.
* *
* This can be called before startListening() to set an initial address, * This can be called before startListening() to set an initial address,
* or after the transport is running. * or after the transport is running.
* *
* This implementation does nothing. Transports should override if they want notification.
*
* @param source defined in Transport.java * @param source defined in Transport.java
* @param ip typ. IPv4 non-local * @param ip typ. IPv4 or IPv6 non-local
* @param port 0 for unknown or unchanged * @param port 0 for unknown or unchanged
*/ */
public void externalAddressReceived(String source, byte[] ip, int port) {} public void externalAddressReceived(String source, byte[] ip, int port) {}
/** /**
* Notify a transport of the results of trying to forward a port. * Notify a transport of the results of trying to forward a port.
*
* This implementation does nothing. Transports should override if they want notification.
*
* @param port the internal port * @param port the internal port
* @param externalPort the external port, which for now should always be the same as * @param externalPort the external port, which for now should always be the same as
* the internal port if the forwarding was successful. * the internal port if the forwarding was successful.

View File

@ -101,19 +101,21 @@ public class TransportManager implements TransportEventListener {
return ctx.getBooleanPropertyDefaultTrue(PROP_ENABLE_NTCP); return ctx.getBooleanPropertyDefaultTrue(PROP_ENABLE_NTCP);
} }
/**
* Notify transport of ALL routable local addresses, including IPv6.
* It's the transport's job to ignore what it can't handle.
*/
private void initializeAddress(Transport t) { private void initializeAddress(Transport t) {
String ips = Addresses.getAnyAddress(); Set<String> ipset = Addresses.getAddresses(false, true); // non-local, include IPv6
if (ips == null) for (String ips : ipset) {
return; try {
InetAddress ia; InetAddress ia = InetAddress.getByName(ips);
try { byte[] ip = ia.getAddress();
ia = InetAddress.getByName(ips); t.externalAddressReceived(Transport.SOURCE_INTERFACE, ip, 0);
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
_log.error("UDP failed to bind to local address", e); _log.error("UDP failed to bind to local address", e);
return; }
} }
byte[] ip = ia.getAddress();
t.externalAddressReceived(Transport.SOURCE_INTERFACE, ip, 0);
} }
/** /**

View File

@ -511,11 +511,15 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_lastInboundReceivedOn = System.currentTimeMillis(); _lastInboundReceivedOn = System.currentTimeMillis();
} }
// temp prevent multiples
private boolean gotIPv4Addr = false;
private boolean gotIPv6Addr = false;
/** /**
* From config, UPnP, local i/f, ... * From config, UPnP, local i/f, ...
* *
* @param source used for logging only * @param source used for logging only
* @param ip publicly routable IPv4 only * @param ip publicly routable IPv4 or IPv6
* @param port 0 if unknown * @param port 0 if unknown
*/ */
@Override @Override
@ -527,10 +531,22 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
String sources = _context.getProperty(PROP_SOURCES, DEFAULT_SOURCES); String sources = _context.getProperty(PROP_SOURCES, DEFAULT_SOURCES);
if (!sources.contains(source)) if (!sources.contains(source))
return; return;
if (!isValid(ip))
return;
if (source.equals(Transport.SOURCE_INTERFACE)) {
// temp prevent multiples
if (ip.length == 4 && !gotIPv4Addr) {
gotIPv4Addr = true;
return;
} else if (ip.length == 16 && !gotIPv6Addr) {
gotIPv6Addr = true;
return;
}
}
boolean changed = changeAddress(ip, port); boolean changed = changeAddress(ip, port);
// Assume if we have an interface with a public IP that we aren't firewalled. // 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 this is wrong, the peer test will figure it out and change the status.
if (changed && source.equals(Transport.SOURCE_INTERFACE)) if (changed && ip.length == 4 && source.equals(Transport.SOURCE_INTERFACE))
setReachabilityStatus(CommSystemFacade.STATUS_OK); setReachabilityStatus(CommSystemFacade.STATUS_OK);
} }
@ -620,6 +636,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
} }
/** /**
* @param ourIP MUST have been previously validated with isValid()
* @param ourPort >= 1024 or 0 for no change * @param ourPort >= 1024 or 0 for no change
*/ */
private boolean changeAddress(byte ourIP[], int ourPort) { private boolean changeAddress(byte ourIP[], int ourPort) {