Allow VPNs to add/remove link addresses dynamically.
Bug: 15409819
Change-Id: If91fc6891d7ce04060362c6cde8c57462394c4e8
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 0a8ca6a..b9dd609 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -83,8 +83,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.net.InetAddress;
import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
@@ -754,11 +755,53 @@
}
}
+ public synchronized boolean addAddress(String address, int prefixLength) {
+ if (Binder.getCallingUid() != mOwnerUID || mInterface == null || mNetworkAgent == null) {
+ return false;
+ }
+ boolean success = jniAddAddress(mInterface, address, prefixLength);
+ if (success && (!mAllowIPv4 || !mAllowIPv6)) {
+ try {
+ InetAddress inetAddress = InetAddress.parseNumericAddress(address);
+ if ((inetAddress instanceof Inet4Address) && !mAllowIPv4) {
+ mAllowIPv4 = true;
+ mNetworkAgent.unblockAddressFamily(AF_INET);
+ } else if ((inetAddress instanceof Inet6Address) && !mAllowIPv6) {
+ mAllowIPv6 = true;
+ mNetworkAgent.unblockAddressFamily(AF_INET6);
+ }
+ } catch (IllegalArgumentException e) {
+ // ignore
+ }
+ }
+ // Ideally, we'd call mNetworkAgent.sendLinkProperties() here to notify ConnectivityService
+ // that the LinkAddress has changed. But we don't do so for two reasons: (1) We don't set
+ // LinkAddresses on the LinkProperties we establish in the first place (see agentConnect())
+ // and (2) CS doesn't do anything with LinkAddresses anyway (see updateLinkProperties()).
+ // TODO: Maybe fix this.
+ return success;
+ }
+
+ public synchronized boolean removeAddress(String address, int prefixLength) {
+ if (Binder.getCallingUid() != mOwnerUID || mInterface == null || mNetworkAgent == null) {
+ return false;
+ }
+ boolean success = jniDelAddress(mInterface, address, prefixLength);
+ // Ideally, we'd call mNetworkAgent.sendLinkProperties() here to notify ConnectivityService
+ // that the LinkAddress has changed. But we don't do so for two reasons: (1) We don't set
+ // LinkAddresses on the LinkProperties we establish in the first place (see agentConnect())
+ // and (2) CS doesn't do anything with LinkAddresses anyway (see updateLinkProperties()).
+ // TODO: Maybe fix this.
+ return success;
+ }
+
private native int jniCreate(int mtu);
private native String jniGetName(int tun);
private native int jniSetAddresses(String interfaze, String addresses);
private native void jniReset(String interfaze);
private native int jniCheck(String interfaze);
+ private native boolean jniAddAddress(String interfaze, String address, int prefixLen);
+ private native boolean jniDelAddress(String interfaze, String address, int prefixLen);
private static RouteInfo findIPv4DefaultRoute(LinkProperties prop) {
for (RouteInfo route : prop.getAllRoutes()) {