diff --git a/briar-core/src/org/briarproject/plugins/tcp/LanTcpPlugin.java b/briar-core/src/org/briarproject/plugins/tcp/LanTcpPlugin.java index abed7f40ebdb9419fcb1f8d71da406f8aa1ef412..da0293603b89ecca7eb86c85f6a6aac04bd172a9 100644 --- a/briar-core/src/org/briarproject/plugins/tcp/LanTcpPlugin.java +++ b/briar-core/src/org/briarproject/plugins/tcp/LanTcpPlugin.java @@ -8,7 +8,6 @@ import java.net.InetSocketAddress; import java.net.NetworkInterface; import java.net.SocketAddress; import java.net.SocketException; -import java.net.UnknownHostException; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -18,7 +17,6 @@ import java.util.logging.Logger; import org.briarproject.api.TransportId; import org.briarproject.api.TransportProperties; import org.briarproject.api.plugins.duplex.DuplexPluginCallback; -import org.briarproject.util.StringUtils; /** A TCP plugin that supports exchanging invitations over a LAN. */ class LanTcpPlugin extends TcpPlugin { @@ -42,23 +40,9 @@ class LanTcpPlugin extends TcpPlugin { protected List<SocketAddress> getLocalSocketAddresses() { // Use the same address and port as last time if available TransportProperties p = callback.getLocalProperties(); - String addressString = p.get("address"); - String portString = p.get("port"); - InetAddress oldAddress = null; - int oldPort = 0; - if(!StringUtils.isNullOrEmpty(addressString) && - !StringUtils.isNullOrEmpty(portString)) { - try { - oldAddress = InetAddress.getByName(addressString); - oldPort = Integer.parseInt(portString); - } catch(NumberFormatException e) { - if(LOG.isLoggable(WARNING)) - LOG.warning("Invalid port: " + portString); - } catch(UnknownHostException e) { - if(LOG.isLoggable(WARNING)) - LOG.warning("Invalid address: " + addressString); - } - } + InetSocketAddress old = parseSocketAddress(p.get("address"), + p.get("port")); + // Get a list of the device's network interfaces List<NetworkInterface> ifaces; try { ifaces = Collections.list(NetworkInterface.getNetworkInterfaces()); @@ -66,8 +50,8 @@ class LanTcpPlugin extends TcpPlugin { if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); return Collections.emptyList(); } - List<SocketAddress> addresses = new LinkedList<SocketAddress>(); - // Accept interfaces with link-local or site-local addresses + List<SocketAddress> addrs = new LinkedList<SocketAddress>(); + // Accept interfaces with local IPv4 addresses for(NetworkInterface iface : ifaces) { for(InetAddress a : Collections.list(iface.getInetAddresses())) { boolean ipv4 = a instanceof Inet4Address; @@ -75,12 +59,13 @@ class LanTcpPlugin extends TcpPlugin { boolean link = a.isLinkLocalAddress(); boolean site = a.isSiteLocalAddress(); if(ipv4 && !loop && (link || site)) { - if(a.equals(oldAddress)) - addresses.add(0, new InetSocketAddress(a, oldPort)); - addresses.add(new InetSocketAddress(a, 0)); + // If this is the old address, try to use the same port + if(old != null && old.getAddress().equals(a)) + addrs.add(0, new InetSocketAddress(a, old.getPort())); + addrs.add(new InetSocketAddress(a, 0)); } } } - return addresses; + return addrs; } } \ No newline at end of file diff --git a/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java b/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java index 56b788dae77047d3540b549ba0ce6f77034bf0f2..9c062d378596fa6e862b4c1ce767a77a828086bb 100644 --- a/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java +++ b/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.Executor; import java.util.logging.Logger; +import java.util.regex.Pattern; import org.briarproject.api.ContactId; import org.briarproject.api.TransportProperties; @@ -26,6 +27,8 @@ import org.briarproject.util.StringUtils; abstract class TcpPlugin implements DuplexPlugin { + private static final Pattern DOTTED_QUAD = + Pattern.compile("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"); private static final Logger LOG = Logger.getLogger(TcpPlugin.class.getName()); @@ -81,7 +84,6 @@ abstract class TcpPlugin implements DuplexPlugin { break; } catch(IOException e) { if(LOG.isLoggable(INFO)) LOG.info("Failed to bind " + addr); - if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); tryToClose(ss); continue; } @@ -196,19 +198,23 @@ abstract class TcpPlugin implements DuplexPlugin { private SocketAddress getRemoteSocketAddress(ContactId c) { TransportProperties p = callback.getRemoteProperties().get(c); if(p == null) return null; - String addrString = p.get("address"); - if(StringUtils.isNullOrEmpty(addrString)) return null; - String portString = p.get("port"); - if(StringUtils.isNullOrEmpty(portString)) return null; + return parseSocketAddress(p.get("address"), p.get("port")); + } + + protected InetSocketAddress parseSocketAddress(String addr, String port) { + if(StringUtils.isNullOrEmpty(addr)) return null; + if(StringUtils.isNullOrEmpty(port)) return null; + // Ensure getByName() won't perform a DNS lookup + if(!DOTTED_QUAD.matcher(addr).matches()) return null; try { - InetAddress addr = InetAddress.getByName(addrString); - int port = Integer.parseInt(portString); - return new InetSocketAddress(addr, port); - } catch(NumberFormatException e) { - if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - return null; + InetAddress a = InetAddress.getByName(addr); + int p = Integer.parseInt(port); + return new InetSocketAddress(a, p); } catch(UnknownHostException e) { - if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); + if(LOG.isLoggable(WARNING)) LOG.warning("Invalid address: " + addr); + return null; + } catch(NumberFormatException e) { + if(LOG.isLoggable(WARNING)) LOG.warning("Invalid port: " + port); return null; } } diff --git a/briar-core/src/org/briarproject/plugins/tcp/WanTcpPlugin.java b/briar-core/src/org/briarproject/plugins/tcp/WanTcpPlugin.java index 100962902f47d373dd3f8d1216ff907e6a500ac6..56f61ec239b0d88a2e6db33a5a6686994d5149f7 100644 --- a/briar-core/src/org/briarproject/plugins/tcp/WanTcpPlugin.java +++ b/briar-core/src/org/briarproject/plugins/tcp/WanTcpPlugin.java @@ -8,7 +8,6 @@ import java.net.InetSocketAddress; import java.net.NetworkInterface; import java.net.SocketAddress; import java.net.SocketException; -import java.net.UnknownHostException; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -18,7 +17,6 @@ import java.util.logging.Logger; import org.briarproject.api.TransportId; import org.briarproject.api.TransportProperties; import org.briarproject.api.plugins.duplex.DuplexPluginCallback; -import org.briarproject.util.StringUtils; class WanTcpPlugin extends TcpPlugin { @@ -47,23 +45,8 @@ class WanTcpPlugin extends TcpPlugin { protected List<SocketAddress> getLocalSocketAddresses() { // Use the same address and port as last time if available TransportProperties p = callback.getLocalProperties(); - String addressString = p.get("address"); - String portString = p.get("port"); - InetAddress oldAddress = null; - int oldPort = 0; - if(!StringUtils.isNullOrEmpty(addressString) && - !StringUtils.isNullOrEmpty(portString)) { - try { - oldAddress = InetAddress.getByName(addressString); - oldPort = Integer.parseInt(portString); - } catch(NumberFormatException e) { - if(LOG.isLoggable(WARNING)) - LOG.warning("Invalid port: " + portString); - } catch(UnknownHostException e) { - if(LOG.isLoggable(WARNING)) - LOG.warning("Invalid address: " + addressString); - } - } + InetSocketAddress old = parseSocketAddress(p.get("address"), + p.get("port")); // Get a list of the device's network interfaces List<NetworkInterface> ifaces; try { @@ -72,8 +55,8 @@ class WanTcpPlugin extends TcpPlugin { if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); return Collections.emptyList(); } - List<SocketAddress> addresses = new LinkedList<SocketAddress>(); - // Accept interfaces without link-local or site-local addresses + List<SocketAddress> addrs = new LinkedList<SocketAddress>(); + // Accept interfaces without global IPv4 addresses for(NetworkInterface iface : ifaces) { for(InetAddress a : Collections.list(iface.getInetAddresses())) { boolean ipv4 = a instanceof Inet4Address; @@ -81,20 +64,21 @@ class WanTcpPlugin extends TcpPlugin { boolean link = a.isLinkLocalAddress(); boolean site = a.isSiteLocalAddress(); if(ipv4 && !loop && !link && !site) { - if(a.equals(oldAddress)) - addresses.add(0, new InetSocketAddress(a, oldPort)); - addresses.add(new InetSocketAddress(a, 0)); + // If this is the old address, try to use the same port + if(old != null && old.getAddress().equals(a)) + addrs.add(0, new InetSocketAddress(a, old.getPort())); + addrs.add(new InetSocketAddress(a, 0)); } } } // Accept interfaces with local addresses that can be port-mapped - if(oldPort == 0) oldPort = chooseEphemeralPort(); - mappingResult = portMapper.map(oldPort); + int port = old == null ? chooseEphemeralPort() : old.getPort(); + mappingResult = portMapper.map(port); if(mappingResult != null && mappingResult.isUsable()) { InetSocketAddress a = mappingResult.getInternal(); - if(a.getAddress() instanceof Inet4Address) addresses.add(a); + if(a.getAddress() instanceof Inet4Address) addrs.add(a); } - return addresses; + return addrs; } private int chooseEphemeralPort() {