The service part of the user space VPN support.

The dialogs will be in another change.

Change-Id: I0cdfd2ef21ffd40ee955b3cbde5ada65dbfdb0bc
This commit is contained in:
Chia-chi Yeh
2011-05-23 17:26:46 -07:00
parent 269d732e13
commit 9a4ad7d52c
3 changed files with 117 additions and 0 deletions

View File

@@ -19,6 +19,8 @@ package android.net;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.os.Binder;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import java.net.InetAddress;
@@ -756,4 +758,43 @@ public class ConnectivityManager {
} catch (RemoteException e) {
}
}
/**
* Protect a socket from routing changes. This method is limited to VPN
* applications, and it is always hidden to avoid direct use.
* @hide
*/
public void protectVpn(ParcelFileDescriptor socket) {
try {
mService.protectVpn(socket);
} catch (RemoteException e) {
}
}
/**
* Prepare for a VPN application. This method is limited to VpnDialogs,
* and it is always hidden to avoid direct use.
* @hide
*/
public String prepareVpn(String packageName) {
try {
return mService.prepareVpn(packageName);
} catch (RemoteException e) {
return null;
}
}
/**
* Configure a TUN interface and return its file descriptor. Parameters
* are encoded and opaque to this class. This method is limited to VPN
* applications, and it is always hidden to avoid direct use.
* @hide
*/
public ParcelFileDescriptor establishVpn(Bundle config) {
try {
return mService.establishVpn(config);
} catch (RemoteException e) {
return null;
}
}
}

View File

@@ -20,7 +20,9 @@ import android.net.LinkProperties;
import android.net.NetworkInfo;
import android.net.NetworkState;
import android.net.ProxyProperties;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
/**
* Interface that answers queries about, and allows changing, the
@@ -95,4 +97,10 @@ interface IConnectivityManager
ProxyProperties getProxy();
void setDataDependency(int networkType, boolean met);
void protectVpn(in ParcelFileDescriptor socket);
String prepareVpn(String packageName);
ParcelFileDescriptor establishVpn(in Bundle config);
}

View File

@@ -48,6 +48,7 @@ import android.net.RouteInfo;
import android.net.vpn.VpnManager;
import android.net.wifi.WifiStateTracker;
import android.os.Binder;
import android.os.Bundle;
import android.os.FileUtils;
import android.os.Handler;
import android.os.HandlerThread;
@@ -55,6 +56,7 @@ import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -67,6 +69,8 @@ import android.util.SparseIntArray;
import com.android.internal.telephony.Phone;
import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
import com.google.android.collect.Lists;
import java.io.FileDescriptor;
@@ -103,6 +107,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private Tethering mTethering;
private boolean mTetheringConfigValid = false;
private Vpn mVpn;
/** Currently active network rules by UID. */
private SparseIntArray mUidRules = new SparseIntArray();
@@ -461,8 +467,11 @@ public class ConnectivityService extends IConnectivityManager.Stub {
mTethering.getTetherableBluetoothRegexs().length != 0) &&
mTethering.getUpstreamIfaceRegexs().length != 0);
mVpn = new Vpn(mContext, new VpnCallback());
try {
nmService.registerObserver(mTethering);
nmService.registerObserver(mVpn);
} catch (RemoteException e) {
loge("Error registering observer :" + e);
}
@@ -2358,6 +2367,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private void loge(String s) {
Slog.e(TAG, s);
}
int convertFeatureToNetworkType(String feature){
int networkType = -1;
if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
@@ -2385,4 +2395,62 @@ public class ConnectivityService extends IConnectivityManager.Stub {
}
return value;
}
// @see ConnectivityManager#protectVpn(ParcelFileDescriptor)
// Permission checks are done in Vpn class.
@Override
public void protectVpn(ParcelFileDescriptor socket) {
mVpn.protect(socket, getDefaultInterface());
}
// @see ConnectivityManager#prepareVpn(String)
// Permission checks are done in Vpn class.
@Override
public String prepareVpn(String packageName) {
return mVpn.prepare(packageName);
}
// @see ConnectivityManager#establishVpn(Bundle)
// Permission checks are done in Vpn class.
@Override
public ParcelFileDescriptor establishVpn(Bundle config) {
return mVpn.establish(config);
}
private String getDefaultInterface() {
if (ConnectivityManager.isNetworkTypeValid(mActiveDefaultNetwork)) {
NetworkStateTracker tracker = mNetTrackers[mActiveDefaultNetwork];
if (tracker != null) {
LinkProperties properties = tracker.getLinkProperties();
if (properties != null) {
return properties.getInterfaceName();
}
}
}
throw new IllegalStateException("No default interface");
}
/**
* Callback for VPN subsystem. Currently VPN is not adapted to the service
* through NetworkStateTracker since it works differently. For example, it
* needs to override DNS servers but never takes the default routes. It
* relies on another data network, and it could keep existing connections
* alive after reconnecting, switching between networks, or even resuming
* from deep sleep. Calls from applications should be done synchronously
* to avoid race conditions. As these are all hidden APIs, refactoring can
* be done whenever a better abstraction is developed.
*/
public class VpnCallback {
private VpnCallback() {
}
public synchronized void override(String[] dnsServers) {
// TODO: override DNS servers and http proxy.
}
public synchronized void restore() {
// TODO: restore VPN changes.
}
}
}