I created a TUN device using VpnService. Why does the TUN interface have the highest priority among other network interfaces of my device?
Update #1
This is how I configured the TUN device:
mInterface = new Builder().setSession(getString(R.string.app_name))
.addAddress("10.0.1.1", 24)
.addRoute("0.0.0.0", 1)
.addRoute("128.0.0.0", 1)
.establish();
Update #2
This is the output of route -n
without the TUN device:
shell@m0:/ $ busybox route -n
busybox route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.197.55.0 0.0.0.0 255.255.255.0 U 0 0 0 rmnet0
This is the output of route -n
with the TUN device:
shell@m0:/ $ busybox route -n
busybox route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.0.1.0 0.0.0.0 255.255.255.0 U 0 0 0 tun0
10.197.55.0 0.0.0.0 255.255.255.0 U 0 0 0 rmnet0
shell@m0:/ $
Always-on VPNAndroid can start a VPN service when the device boots, and keep it running while the device or work profile is on. This feature is called always-on VPN and is available in Android 7.0 or higher.
To add a VPN service to your app, create an Android service inheriting from VpnService . Declare the VPN service in your app manifest file with the following additions: Protect the service with the BIND_VPN_SERVICE permission so that only the system can bind to your service. Advertise the service with the "android.
If VpnService is enabled on Android, it does not mean that all traffic goes through VpnTunnel. This depends on IP route and allow/disable application proxy settings.
mInterface = new Builder().setSession(getString(R.string.app_name))
.addAddress("10.0.1.1", 24)
.addRoute("0.0.0.0", 1)
.addRoute("128.0.0.0", 1)
.establish();
The above code is obviously global routing, equivalent to 0.0.0.0/0, as you probably know from OpenVPN settings.
If the default gateway is tun, all IP traffic passes through the tun device.
In this case, if you don't want a socket traffic to pass through tun, you need to call VpnService::p rotect function for socket-fd to protect fd.
But that's not enough, you'll also need to find a valid network (not a VPN), call its Network::bindSocket function, and have a Socket go over that network and out.
If you don't want to protect the socket with the Network::bindSocket function! Then you can set the default network, but it is only valid for the android-process of opening the VPN service.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
try {
ConnectivityManager cm = PppVpnNetworkListener.getConnectivityManager(this._service);
if (cm != null) {
cm.bindProcessToNetwork(network);
}
} catch (Throwable ignored) {
}
}
try {
ConnectivityManager.setProcessDefaultNetwork(network);
} catch (Throwable ignored) {
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With