Skip to content

Commit c161621

Browse files
committed
Refactor getNetworkForIp for Android<=10, use RouteInfo instead of LinkAddress
* In Android 10, with previous versions of Android SDK this fallback was working but something changed. The previous logic was incorrect and was matching the host ip (current device) with the targetHostIp (the device we want to connect to). * Code is now more robust and uses DHCP (A11+) or Route info (A10 or older, and A11+ if DHCP fails)
1 parent cf44157 commit c161621

File tree

1 file changed

+33
-16
lines changed

1 file changed

+33
-16
lines changed

android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
import android.net.NetworkInfo;
1313
import android.net.Uri;
1414
import android.net.LinkProperties;
15-
import android.net.LinkAddress;
16-
import java.net.Inet4Address;
15+
import android.net.RouteInfo;
16+
import java.net.Inet4Address;
17+
import java.net.InetAddress;
1718
import android.os.Build;
1819
import android.os.Bundle;
1920
import android.os.Environment;
@@ -44,6 +45,7 @@
4445
import java.io.IOException;
4546
import java.io.InputStream;
4647
import java.net.MalformedURLException;
48+
import java.net.UnknownHostException;
4749
import java.net.Proxy;
4850
import java.net.SocketException;
4951
import java.net.SocketTimeoutException;
@@ -391,10 +393,22 @@ else if (this.options.fileCache)
391393

392394
// wifi only, need ACCESS_NETWORK_STATE permission
393395
// and API level >= 21
394-
boolean targetHostIpAvailable = (this.options.targetHostIp != null && !this.options.targetHostIp.isEmpty());
396+
final String targetHostIp = this.options.targetHostIp;
397+
boolean targetHostIpAvailable = (targetHostIp != null && !targetHostIp.isEmpty());
398+
395399
if (this.options.wifiOnly) {
396400
boolean found = false;
397401

402+
// convert targetHostIp from String into InetAddress
403+
InetAddress targetHostAddr = null;
404+
if (targetHostIpAvailable) {
405+
try {
406+
targetHostAddr = InetAddress.getByName(targetHostIp);
407+
} catch (UnknownHostException e) {
408+
targetHostAddr = null; // skip
409+
}
410+
}
411+
398412
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
399413
ConnectivityManager connectivityManager = (ConnectivityManager) ReactNativeBlobUtilImpl.RCTContext.getSystemService(ReactNativeBlobUtilImpl.RCTContext.CONNECTIVITY_SERVICE);
400414
Network[] networks = connectivityManager.getAllNetworks();
@@ -408,9 +422,7 @@ else if (this.options.fileCache)
408422

409423
// if targetHostIpAvailable does not match, fallback to any wifi
410424
if (targetHostIpAvailable) {
411-
String targetHostIp = this.options.targetHostIp;
412-
413-
if (networkMatchesTargetIp(connectivityManager, network, targetHostIp)) {
425+
if (networkMatchesTargetIp(connectivityManager, network, targetHostIp, targetHostAddr)) {
414426
clientBuilder.proxy(Proxy.NO_PROXY);
415427
clientBuilder.socketFactory(network.getSocketFactory());
416428
found = true;
@@ -1048,28 +1060,33 @@ private boolean isValidWifiNetwork(ConnectivityManager cm, Network network) {
10481060
/**
10491061
* Check if a network matches the target host IP address
10501062
*/
1051-
private boolean networkMatchesTargetIp(ConnectivityManager cm, Network network, String targetHostIp) {
1063+
private boolean networkMatchesTargetIp(ConnectivityManager cm, Network network, String targetHostIp, InetAddress targetHostAddr) {
10521064
LinkProperties lp = cm.getLinkProperties(network);
10531065
if (lp == null) return false;
10541066

10551067
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
1056-
// For Android R and above, use DHCP server address
1068+
// For Android 11 and above, use DHCP server address
10571069
Inet4Address dhcpServer = lp.getDhcpServerAddress();
10581070
if (dhcpServer != null && dhcpServer.getHostAddress().equals(targetHostIp)) {
10591071
return true;
10601072
}
10611073
}
1062-
1063-
// Always fall back to linkAddresses check
1064-
List<LinkAddress> linkAddresses = lp.getLinkAddresses();
1065-
if (linkAddresses != null && !linkAddresses.isEmpty()) {
1066-
for (LinkAddress la : linkAddresses) {
1067-
if (la.getAddress().getHostAddress().equals(targetHostIp)) {
1068-
return true;
1074+
1075+
// For older versions or Android 11+ if DHCP does not match, check routing table
1076+
if (targetHostAddr != null) {
1077+
List<RouteInfo> routes = lp.getRoutes();
1078+
if (routes != null) {
1079+
for (RouteInfo route : routes) {
1080+
if (route.isDefaultRoute()) {
1081+
continue;
1082+
}
1083+
if (route.matches(targetHostAddr)) {
1084+
return true;
1085+
}
10691086
}
10701087
}
10711088
}
1072-
1089+
10731090
return false;
10741091
}
10751092
}

0 commit comments

Comments
 (0)