mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 21:59:54 +01:00
Only bind to the SLAAC address of the wifi interface.
This is just a precaution - on all devices I've tested, the wifi interface is the only one with a SLAAC address.
This commit is contained in:
@@ -8,6 +8,7 @@ import android.net.wifi.WifiInfo;
|
|||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
|
|
||||||
import org.briarproject.bramble.PoliteExecutor;
|
import org.briarproject.bramble.PoliteExecutor;
|
||||||
|
import org.briarproject.bramble.api.Pair;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
|
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
@@ -17,7 +18,9 @@ import org.briarproject.bramble.api.settings.Settings;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.net.SocketException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@@ -31,12 +34,14 @@ import static android.content.Context.WIFI_SERVICE;
|
|||||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Collections.list;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
||||||
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
|
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
|
||||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||||
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class AndroidLanTcpPlugin extends LanTcpPlugin {
|
class AndroidLanTcpPlugin extends LanTcpPlugin {
|
||||||
@@ -84,36 +89,58 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<InetAddress> getUsableLocalInetAddresses(boolean ipv4) {
|
protected List<InetAddress> getUsableLocalInetAddresses(boolean ipv4) {
|
||||||
if (ipv4) return getUsableLocalIpv4Addresses();
|
Pair<InetAddress, Boolean> wifi = getWifiIpv4Address();
|
||||||
else return getUsableLocalIpv6Addresses();
|
if (wifi == null) return emptyList();
|
||||||
|
if (ipv4) return singletonList(wifi.getFirst());
|
||||||
|
InetAddress slaac = getSlaacAddressForInterface(wifi.getFirst());
|
||||||
|
return slaac == null ? emptyList() : singletonList(slaac);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<InetAddress> getUsableLocalIpv4Addresses() {
|
/**
|
||||||
// If the device doesn't have wifi, don't open any sockets
|
* Returns a {@link Pair} where the first element is the IPv4 address of
|
||||||
if (wifiManager == null) return emptyList();
|
* the wifi interface and the second element is true if this device is
|
||||||
|
* providing an access point, or false if this device is a client. Returns
|
||||||
|
* null if this device isn't connected to wifi as an access point or client.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private Pair<InetAddress, Boolean> getWifiIpv4Address() {
|
||||||
|
if (wifiManager == null) return null;
|
||||||
// If we're connected to a wifi network, return its address
|
// If we're connected to a wifi network, return its address
|
||||||
WifiInfo info = wifiManager.getConnectionInfo();
|
WifiInfo info = wifiManager.getConnectionInfo();
|
||||||
if (info != null && info.getIpAddress() != 0) {
|
if (info != null && info.getIpAddress() != 0) {
|
||||||
return singletonList(intToInetAddress(info.getIpAddress()));
|
return new Pair<>(intToInetAddress(info.getIpAddress()), false);
|
||||||
}
|
}
|
||||||
// If we're running an access point, return its address
|
List<InetAddress> addrs = getLocalInetAddresses();
|
||||||
for (InetAddress addr : getLocalInetAddresses()) {
|
// If we're providing a normal access point, return its address
|
||||||
if (addr.equals(WIFI_AP_ADDRESS)) return singletonList(addr);
|
for (InetAddress addr : addrs) {
|
||||||
if (addr.equals(WIFI_DIRECT_AP_ADDRESS)) return singletonList(addr);
|
if (WIFI_AP_ADDRESS.equals(addr)) {
|
||||||
|
return new Pair<>(addr, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// No suitable addresses
|
// If we're providing a wifi direct access point, return its address
|
||||||
return emptyList();
|
for (InetAddress addr : addrs) {
|
||||||
|
if (WIFI_DIRECT_AP_ADDRESS.equals(addr)) {
|
||||||
|
return new Pair<>(addr, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Not connected to wifi
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<InetAddress> getUsableLocalIpv6Addresses() {
|
@Nullable
|
||||||
// If the device doesn't have wifi, don't open any sockets
|
private InetAddress getSlaacAddressForInterface(InetAddress wifi) {
|
||||||
if (wifiManager == null) return emptyList();
|
try {
|
||||||
// If we have a SLAAC address, return it
|
NetworkInterface iface = NetworkInterface.getByInetAddress(wifi);
|
||||||
for (InetAddress addr : getLocalInetAddresses()) {
|
if (iface == null) return null;
|
||||||
if (isSlaacAddress(addr)) return singletonList(addr);
|
for (InetAddress addr : list(iface.getInetAddresses())) {
|
||||||
|
if (isSlaacAddress(addr)) return addr;
|
||||||
|
}
|
||||||
|
// No suitable address
|
||||||
|
return null;
|
||||||
|
} catch (SocketException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
// No suitable addresses
|
|
||||||
return emptyList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private InetAddress intToInetAddress(int ip) {
|
private InetAddress intToInetAddress(int ip) {
|
||||||
@@ -153,9 +180,20 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
|||||||
connectionStatusExecutor.execute(() -> {
|
connectionStatusExecutor.execute(() -> {
|
||||||
State s = getState();
|
State s = getState();
|
||||||
if (s != ACTIVE && s != INACTIVE) return;
|
if (s != ACTIVE && s != INACTIVE) return;
|
||||||
List<InetAddress> addrs = getLocalInetAddresses();
|
Pair<InetAddress, Boolean> wifi = getWifiIpv4Address();
|
||||||
if (addrs.contains(WIFI_AP_ADDRESS)
|
if (wifi == null) {
|
||||||
|| addrs.contains(WIFI_DIRECT_AP_ADDRESS)) {
|
LOG.info("Not connected to wifi");
|
||||||
|
socketFactory = SocketFactory.getDefault();
|
||||||
|
// Server sockets may not have been closed automatically when
|
||||||
|
// interface was taken down. If any sockets are open, closing
|
||||||
|
// them here will cause the sockets to be cleared and the state
|
||||||
|
// to be updated in acceptContactConnections()
|
||||||
|
if (s == ACTIVE) {
|
||||||
|
LOG.info("Closing server sockets");
|
||||||
|
tryToClose(state.getServerSocket(true), LOG, WARNING);
|
||||||
|
tryToClose(state.getServerSocket(false), LOG, WARNING);
|
||||||
|
}
|
||||||
|
} else if (wifi.getSecond()) {
|
||||||
LOG.info("Providing wifi hotspot");
|
LOG.info("Providing wifi hotspot");
|
||||||
// There's no corresponding Network object and thus no way
|
// There's no corresponding Network object and thus no way
|
||||||
// to get a suitable socket factory, so we won't be able to
|
// to get a suitable socket factory, so we won't be able to
|
||||||
@@ -163,17 +201,6 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
|||||||
// has internet access
|
// has internet access
|
||||||
socketFactory = SocketFactory.getDefault();
|
socketFactory = SocketFactory.getDefault();
|
||||||
if (s == INACTIVE) bind();
|
if (s == INACTIVE) bind();
|
||||||
} else if (addrs.isEmpty()) {
|
|
||||||
LOG.info("Not connected to wifi");
|
|
||||||
socketFactory = SocketFactory.getDefault();
|
|
||||||
// Server sockets may not have been closed automatically when
|
|
||||||
// interface was taken down. Sockets will be cleared and state
|
|
||||||
// updated in acceptContactConnections()
|
|
||||||
if (s == ACTIVE) {
|
|
||||||
LOG.info("Closing server sockets");
|
|
||||||
tryToClose(state.getServerSocket(true), LOG, WARNING);
|
|
||||||
tryToClose(state.getServerSocket(false), LOG, WARNING);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
LOG.info("Connected to wifi");
|
LOG.info("Connected to wifi");
|
||||||
socketFactory = getSocketFactory();
|
socketFactory = getSocketFactory();
|
||||||
|
|||||||
Reference in New Issue
Block a user