diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java
index 7d26b8e5e06999e1b7b48561e1f039dd9e4a3991..37c5935f949f4199b5e977728ca4cb8492171a2e 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java
@@ -23,7 +23,7 @@ import java.net.SocketAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.LinkedList;
+import java.util.Comparator;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executor;
@@ -44,6 +44,9 @@ class LanTcpPlugin extends TcpPlugin {
 	private static final Logger LOG =
 			Logger.getLogger(LanTcpPlugin.class.getName());
 
+	private static final LanAddressComparator ADDRESS_COMPARATOR =
+			new LanAddressComparator();
+
 	private static final int MAX_ADDRESSES = 4;
 	private static final String SEPARATOR = ",";
 
@@ -63,19 +66,18 @@ class LanTcpPlugin extends TcpPlugin {
 		TransportProperties p = callback.getLocalProperties();
 		String oldIpPorts = p.get(PROP_IP_PORTS);
 		List<InetSocketAddress> olds = parseSocketAddresses(oldIpPorts);
-		List<InetSocketAddress> locals = new LinkedList<>();
+		List<InetSocketAddress> locals = new ArrayList<>();
 		for (InetAddress local : getLocalIpAddresses()) {
 			if (isAcceptableAddress(local)) {
 				// If this is the old address, try to use the same port
 				for (InetSocketAddress old : olds) {
-					if (old.getAddress().equals(local)) {
-						int port = old.getPort();
-						locals.add(0, new InetSocketAddress(local, port));
-					}
+					if (old.getAddress().equals(local))
+						locals.add(new InetSocketAddress(local, old.getPort()));
 				}
 				locals.add(new InetSocketAddress(local, 0));
 			}
 		}
+		Collections.sort(locals, ADDRESS_COMPARATOR);
 		return locals;
 	}
 
@@ -153,17 +155,39 @@ class LanTcpPlugin extends TcpPlugin {
 	// Package access for testing
 	boolean addressesAreOnSameLan(byte[] localIp, byte[] remoteIp) {
 		// 10.0.0.0/8
-		if (localIp[0] == 10) return remoteIp[0] == 10;
+		if (isPrefix10(localIp)) return isPrefix10(remoteIp);
 		// 172.16.0.0/12
-		if (localIp[0] == (byte) 172 && (localIp[1] & 0xF0) == 16)
-			return remoteIp[0] == (byte) 172 && (remoteIp[1] & 0xF0) == 16;
+		if (isPrefix172(localIp)) return isPrefix172(remoteIp);
 		// 192.168.0.0/16
-		if (localIp[0] == (byte) 192 && localIp[1] == (byte) 168)
-			return remoteIp[0] == (byte) 192 && remoteIp[1] == (byte) 168;
+		if (isPrefix192(localIp)) return isPrefix192(remoteIp);
 		// Unrecognised prefix - may be compatible
 		return true;
 	}
 
+	private static boolean isPrefix10(byte[] ipv4) {
+		return ipv4[0] == 10;
+	}
+
+	private static boolean isPrefix172(byte[] ipv4) {
+		return ipv4[0] == (byte) 172 && (ipv4[1] & 0xF0) == 16;
+	}
+
+	private static boolean isPrefix192(byte[] ipv4) {
+		return ipv4[0] == (byte) 192 && ipv4[1] == (byte) 168;
+	}
+
+	// Returns the prefix length for an RFC 1918 address, or 0 for any other
+	// address
+	private static int getRfc1918PrefixLength(InetAddress addr) {
+		if (!(addr instanceof Inet4Address)) return 0;
+		if (!addr.isSiteLocalAddress()) return 0;
+		byte[] ipv4 = addr.getAddress();
+		if (isPrefix10(ipv4)) return 8;
+		if (isPrefix172(ipv4)) return 12;
+		if (isPrefix192(ipv4)) return 16;
+		return 0;
+	}
+
 	@Override
 	public boolean supportsKeyAgreement() {
 		return true;
@@ -278,4 +302,19 @@ class LanTcpPlugin extends TcpPlugin {
 			}
 		}
 	}
+
+	static class LanAddressComparator implements Comparator<InetSocketAddress> {
+
+		@Override
+		public int compare(InetSocketAddress a, InetSocketAddress b) {
+			// Prefer addresses with non-zero ports
+			int aPort = a.getPort(), bPort = b.getPort();
+			if (aPort > 0 && bPort == 0) return -1;
+			if (aPort == 0 && bPort > 0) return 1;
+			// Prefer addresses with longer RFC 1918 prefixes
+			int aPrefix = getRfc1918PrefixLength(a.getAddress());
+			int bPrefix = getRfc1918PrefixLength(b.getAddress());
+			return bPrefix - aPrefix;
+		}
+	}
 }
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java
index d6ea0b6390289463e1049bc3fff8acc3f3f7c934..ede3df810f2c646728e9f23715e5d53723d5e7b5 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java
@@ -11,6 +11,7 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
 import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
 import org.briarproject.bramble.api.properties.TransportProperties;
 import org.briarproject.bramble.api.settings.Settings;
+import org.briarproject.bramble.plugin.tcp.LanTcpPlugin.LanAddressComparator;
 import org.briarproject.bramble.test.BrambleTestCase;
 import org.junit.Test;
 
@@ -22,6 +23,7 @@ import java.net.NetworkInterface;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.Hashtable;
 import java.util.Map;
 import java.util.concurrent.Callable;
@@ -56,6 +58,9 @@ public class LanTcpPluginTest extends BrambleTestCase {
 		// Local and remote in 192.168.0.0/16 should return true
 		assertTrue(plugin.addressesAreOnSameLan(makeAddress(192, 168, 0, 0),
 				makeAddress(192, 168, 255, 255)));
+		// Local and remote in 169.254.0.0/16 (link-local) should return true
+		assertTrue(plugin.addressesAreOnSameLan(makeAddress(169, 254, 0, 0),
+				makeAddress(169, 254, 255, 255)));
 		// Local and remote in different recognised prefixes should return false
 		assertFalse(plugin.addressesAreOnSameLan(makeAddress(10, 0, 0, 0),
 				makeAddress(172, 31, 255, 255)));
@@ -269,6 +274,57 @@ public class LanTcpPluginTest extends BrambleTestCase {
 		plugin.stop();
 	}
 
+	@Test
+	public void testComparatorPrefersNonZeroPorts() throws Exception {
+		Comparator<InetSocketAddress> comparator = new LanAddressComparator();
+		InetSocketAddress nonZero = new InetSocketAddress("1.2.3.4", 1234);
+		InetSocketAddress zero = new InetSocketAddress("1.2.3.4", 0);
+
+		assertEquals(0, comparator.compare(nonZero, nonZero));
+		assertTrue(comparator.compare(nonZero, zero) < 0);
+
+		assertTrue(comparator.compare(zero, nonZero) > 0);
+		assertEquals(0, comparator.compare(zero, zero));
+	}
+
+	@Test
+	public void testComparatorPrefersLongerPrefixes() throws Exception {
+		Comparator<InetSocketAddress> comparator = new LanAddressComparator();
+		InetSocketAddress prefix192 = new InetSocketAddress("192.168.0.1", 0);
+		InetSocketAddress prefix172 = new InetSocketAddress("172.16.0.1", 0);
+		InetSocketAddress prefix10 = new InetSocketAddress("10.0.0.1", 0);
+
+		assertEquals(0, comparator.compare(prefix192, prefix192));
+		assertTrue(comparator.compare(prefix192, prefix172) < 0);
+		assertTrue(comparator.compare(prefix192, prefix10) < 0);
+
+		assertTrue(comparator.compare(prefix172, prefix192) > 0);
+		assertEquals(0, comparator.compare(prefix172, prefix172));
+		assertTrue(comparator.compare(prefix172, prefix10) < 0);
+
+		assertTrue(comparator.compare(prefix10, prefix192) > 0);
+		assertTrue(comparator.compare(prefix10, prefix172) > 0);
+		assertEquals(0, comparator.compare(prefix10, prefix10));
+	}
+
+	@Test
+	public void testComparatorPrefersSiteLocalToLinkLocal() throws Exception {
+		Comparator<InetSocketAddress> comparator = new LanAddressComparator();
+		InetSocketAddress prefix192 = new InetSocketAddress("192.168.0.1", 0);
+		InetSocketAddress prefix172 = new InetSocketAddress("172.16.0.1", 0);
+		InetSocketAddress prefix10 = new InetSocketAddress("10.0.0.1", 0);
+		InetSocketAddress linkLocal = new InetSocketAddress("169.254.0.1", 0);
+
+		assertTrue(comparator.compare(prefix192, linkLocal) < 0);
+		assertTrue(comparator.compare(prefix172, linkLocal) < 0);
+		assertTrue(comparator.compare(prefix10, linkLocal) < 0);
+
+		assertTrue(comparator.compare(linkLocal, prefix192) > 0);
+		assertTrue(comparator.compare(linkLocal, prefix172) > 0);
+		assertTrue(comparator.compare(linkLocal, prefix10) > 0);
+		assertEquals(0, comparator.compare(linkLocal, linkLocal));
+	}
+
 	private boolean systemHasLocalIpv4Address() throws Exception {
 		for (NetworkInterface i : Collections.list(
 				NetworkInterface.getNetworkInterfaces())) {