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.
* This may be from a local interface, UPnP, a config change, etc.
* This should not be called if the ip didn't change
* (from that source's point of view), or is a local address,
* or if the ip is IPv6, but the transport should check anyway.
* (from that source's point of view), or is a local address.
* May be called multiple times for IPv4 or IPv6.
* The transport should also do its own checking on whether to accept
* notifications from this source.
*
* This can be called before startListening() to set an initial address,
* or after the transport is running.
*
* This implementation does nothing. Transports should override if they want notification.
*
* @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
*/
public void externalAddressReceived(String source, byte[] ip, int 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 externalPort the external port, which for now should always be the same as
* 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);
}
/**
* 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) {
String ips = Addresses.getAnyAddress();
if (ips == null)
return;
InetAddress ia;
Set<String> ipset = Addresses.getAddresses(false, true); // non-local, include IPv6
for (String ips : ipset) {
try {
ia = InetAddress.getByName(ips);
} catch (UnknownHostException e) {
_log.error("UDP failed to bind to local address", e);
return;
}
InetAddress ia = InetAddress.getByName(ips);
byte[] ip = ia.getAddress();
t.externalAddressReceived(Transport.SOURCE_INTERFACE, ip, 0);
} catch (UnknownHostException e) {
_log.error("UDP failed to bind to local address", e);
}
}
}
/**

View File

@ -511,11 +511,15 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_lastInboundReceivedOn = System.currentTimeMillis();
}
// temp prevent multiples
private boolean gotIPv4Addr = false;
private boolean gotIPv6Addr = false;
/**
* From config, UPnP, local i/f, ...
*
* @param source used for logging only
* @param ip publicly routable IPv4 only
* @param ip publicly routable IPv4 or IPv6
* @param port 0 if unknown
*/
@Override
@ -527,10 +531,22 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
String sources = _context.getProperty(PROP_SOURCES, DEFAULT_SOURCES);
if (!sources.contains(source))
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);
// 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.equals(Transport.SOURCE_INTERFACE))
if (changed && ip.length == 4 && source.equals(Transport.SOURCE_INTERFACE))
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
*/
private boolean changeAddress(byte ourIP[], int ourPort) {