summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorChia-chi Yeh <chiachi@android.com>2011-07-02 16:16:03 -0700
committerChia-chi Yeh <chiachi@android.com>2011-07-02 16:16:03 -0700
commit3281034c1c458b4eecd867d20b64dc5edd68ec14 (patch)
tree95b745fc557eda8d5ad94b0895a882706e28658b /services
parente9107901ae264de4ff5603d3cfc63a03ca4117d4 (diff)
downloadframeworks_base-3281034c1c458b4eecd867d20b64dc5edd68ec14.zip
frameworks_base-3281034c1c458b4eecd867d20b64dc5edd68ec14.tar.gz
frameworks_base-3281034c1c458b4eecd867d20b64dc5edd68ec14.tar.bz2
VPN: merge JNI methods.
Legacy VPN needs to change routes by itself. Change-Id: I4cf6639f2b00225810f49704ae05797fc70921d9
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/connectivity/Vpn.java27
-rw-r--r--services/jni/com_android_server_connectivity_Vpn.cpp162
2 files changed, 67 insertions, 122 deletions
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 760a5b6..ede3ffd 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -177,16 +177,10 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
}
// Configure the interface. Abort if any of these steps fails.
- ParcelFileDescriptor descriptor =
- ParcelFileDescriptor.adoptFd(jniCreateInterface(config.mtu));
+ ParcelFileDescriptor descriptor = ParcelFileDescriptor.adoptFd(
+ jniConfigure(config.mtu, config.addresses, config.routes));
try {
String name = jniGetInterfaceName(descriptor.getFd());
- if (jniSetAddresses(name, config.addresses) < 1) {
- throw new IllegalArgumentException("At least one address must be specified");
- }
- if (config.routes != null) {
- jniSetRoutes(name, config.routes);
- }
if (mInterfaceName != null && !mInterfaceName.equals(name)) {
jniResetInterface(mInterfaceName);
}
@@ -269,10 +263,8 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
}
}
- private native int jniCreateInterface(int mtu);
+ private native int jniConfigure(int mtu, String addresses, String routes);
private native String jniGetInterfaceName(int fd);
- private native int jniSetAddresses(String name, String addresses);
- private native int jniSetRoutes(String name, String routes);
private native void jniResetInterface(String name);
private native int jniCheckInterface(String name);
private native void jniProtectSocket(int fd, String name);
@@ -354,7 +346,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
} else if (now - mTimer <= 30000) {
Thread.sleep(yield ? 200 : 1);
} else {
- throw new InterruptedException("timeout");
+ throw new InterruptedException("time is up");
}
}
@@ -433,7 +425,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
for (String argument : arguments) {
byte[] bytes = argument.getBytes(Charsets.UTF_8);
if (bytes.length >= 0xFFFF) {
- throw new IllegalArgumentException("argument too large");
+ throw new IllegalArgumentException("argument is too large");
}
out.write(bytes.length >> 8);
out.write(bytes.length);
@@ -477,12 +469,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
}
}
- // TODO: support routes and search domains from IPSec Mode-CFG.
-
- // Set the routes as requested.
- if (mConfig.routes != null) {
- jniSetRoutes(mConfig.interfaceName, mConfig.routes);
- }
+ // TODO: support search domains from ISAKMP mode config.
// The final step must be synchronized.
synchronized (Vpn.this) {
@@ -501,7 +488,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
}
Log.i(TAG, "Connected!");
} catch (Exception e) {
- Log.i(TAG, "Abort due to " + e.getMessage());
+ Log.i(TAG, "Abort because " + e.getMessage());
exit();
}
}
diff --git a/services/jni/com_android_server_connectivity_Vpn.cpp b/services/jni/com_android_server_connectivity_Vpn.cpp
index 62d7636..6d4f68f 100644
--- a/services/jni/com_android_server_connectivity_Vpn.cpp
+++ b/services/jni/com_android_server_connectivity_Vpn.cpp
@@ -54,7 +54,7 @@ static inline in_addr_t *as_in_addr(sockaddr *sa) {
#define SYSTEM_ERROR -1
#define BAD_ARGUMENT -2
-static int create_interface(int mtu)
+static int create_interface(char *name, int *index, int mtu)
{
int tun = open("/dev/tun", O_RDWR | O_NONBLOCK);
@@ -82,6 +82,14 @@ static int create_interface(int mtu)
goto error;
}
+ // Get interface index.
+ if (ioctl(inet4, SIOGIFINDEX, &ifr4)) {
+ LOGE("Cannot get index of %s: %s", ifr4.ifr_name, strerror(errno));
+ goto error;
+ }
+
+ strncpy(name, ifr4.ifr_name, IFNAMSIZ);
+ *index = ifr4.ifr_ifindex;
return tun;
error:
@@ -89,36 +97,9 @@ error:
return SYSTEM_ERROR;
}
-static int get_interface_name(char *name, int tun)
-{
- ifreq ifr4;
- if (ioctl(tun, TUNGETIFF, &ifr4)) {
- LOGE("Cannot get interface name: %s", strerror(errno));
- return SYSTEM_ERROR;
- }
- strncpy(name, ifr4.ifr_name, IFNAMSIZ);
- return 0;
-}
-
-static int get_interface_index(const char *name)
+static int set_addresses(const char *name, int index, const char *addresses)
{
ifreq ifr4;
- strncpy(ifr4.ifr_name, name, IFNAMSIZ);
- if (ioctl(inet4, SIOGIFINDEX, &ifr4)) {
- LOGE("Cannot get index of %s: %s", name, strerror(errno));
- return SYSTEM_ERROR;
- }
- return ifr4.ifr_ifindex;
-}
-
-static int set_addresses(const char *name, const char *addresses)
-{
- int index = get_interface_index(name);
- if (index < 0) {
- return index;
- }
-
- ifreq ifr4;
memset(&ifr4, 0, sizeof(ifr4));
strncpy(ifr4.ifr_name, name, IFNAMSIZ);
ifr4.ifr_addr.sa_family = AF_INET;
@@ -187,13 +168,8 @@ static int set_addresses(const char *name, const char *addresses)
return count;
}
-static int set_routes(const char *name, const char *routes)
+static int set_routes(const char *name, int index, const char *routes)
{
- int index = get_interface_index(name);
- if (index < 0) {
- return index;
- }
-
rtentry rt4;
memset(&rt4, 0, sizeof(rt4));
rt4.rt_dev = (char *)name;
@@ -277,6 +253,17 @@ static int set_routes(const char *name, const char *routes)
return count;
}
+static int get_interface_name(char *name, int tun)
+{
+ ifreq ifr4;
+ if (ioctl(tun, TUNGETIFF, &ifr4)) {
+ LOGE("Cannot get interface name: %s", strerror(errno));
+ return SYSTEM_ERROR;
+ }
+ strncpy(name, ifr4.ifr_name, IFNAMSIZ);
+ return 0;
+}
+
static int reset_interface(const char *name)
{
ifreq ifr4;
@@ -322,90 +309,63 @@ static void throwException(JNIEnv *env, int error, const char *message)
}
}
-static jint createInterface(JNIEnv *env, jobject thiz, jint mtu)
+static jint configure(JNIEnv *env, jobject thiz,
+ jint mtu, jstring jAddresses, jstring jRoutes)
{
- int tun = create_interface(mtu);
+ char name[IFNAMSIZ];
+ int index;
+ int tun = create_interface(name, &index, mtu);
if (tun < 0) {
throwException(env, tun, "Cannot create interface");
return -1;
}
- return tun;
-}
-static jstring getInterfaceName(JNIEnv *env, jobject thiz, jint tun)
-{
- char name[IFNAMSIZ];
- if (get_interface_name(name, tun) < 0) {
- throwException(env, SYSTEM_ERROR, "Cannot get interface name");
- return NULL;
- }
- return env->NewStringUTF(name);
-}
-
-static jint setAddresses(JNIEnv *env, jobject thiz, jstring jName,
- jstring jAddresses)
-{
- const char *name = NULL;
const char *addresses = NULL;
- int count = -1;
+ const char *routes = NULL;
+ int count;
- name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
- if (!name) {
- jniThrowNullPointerException(env, "name");
- goto error;
- }
+ // At least one address must be set.
addresses = jAddresses ? env->GetStringUTFChars(jAddresses, NULL) : NULL;
if (!addresses) {
- jniThrowNullPointerException(env, "addresses");
+ jniThrowNullPointerException(env, "address");
goto error;
}
- count = set_addresses(name, addresses);
- if (count < 0) {
+ count = set_addresses(name, index, addresses);
+ env->ReleaseStringUTFChars(jAddresses, addresses);
+ if (count <= 0) {
throwException(env, count, "Cannot set address");
- count = -1;
- }
-
-error:
- if (name) {
- env->ReleaseStringUTFChars(jName, name);
- }
- if (addresses) {
- env->ReleaseStringUTFChars(jAddresses, addresses);
- }
- return count;
-}
-
-static jint setRoutes(JNIEnv *env, jobject thiz, jstring jName,
- jstring jRoutes)
-{
- const char *name = NULL;
- const char *routes = NULL;
- int count = -1;
-
- name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
- if (!name) {
- jniThrowNullPointerException(env, "name");
goto error;
}
+ LOGD("Configured %d address(es) on %s", count, name);
+
+ // On the contrary, routes are optional.
routes = jRoutes ? env->GetStringUTFChars(jRoutes, NULL) : NULL;
- if (!routes) {
- jniThrowNullPointerException(env, "routes");
- goto error;
- }
- count = set_routes(name, routes);
- if (count < 0) {
- throwException(env, count, "Cannot set route");
- count = -1;
+ if (routes) {
+ count = set_routes(name, index, routes);
+ env->ReleaseStringUTFChars(jRoutes, routes);
+ if (count < 0) {
+ throwException(env, count, "Cannot set route");
+ goto error;
+ }
+ LOGD("Configured %d route(s) on %s", count, name);
}
+ return tun;
+
error:
- if (name) {
- env->ReleaseStringUTFChars(jName, name);
- }
- if (routes) {
- env->ReleaseStringUTFChars(jRoutes, routes);
+ close(tun);
+ LOGD("%s is destroyed", name);
+ return -1;
+}
+
+static jstring getInterfaceName(JNIEnv *env, jobject thiz, jint tun)
+{
+ char name[IFNAMSIZ];
+ if (get_interface_name(name, tun) < 0) {
+ throwException(env, SYSTEM_ERROR, "Cannot get interface name");
+ return NULL;
}
- return count;
+ return env->NewStringUTF(name);
}
static void resetInterface(JNIEnv *env, jobject thiz, jstring jName)
@@ -449,10 +409,8 @@ static void protectSocket(JNIEnv *env, jobject thiz, jint fd, jstring jName)
//------------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
- {"jniCreateInterface", "(I)I", (void *)createInterface},
+ {"jniConfigure", "(ILjava/lang/String;Ljava/lang/String;)I", (void *)configure},
{"jniGetInterfaceName", "(I)Ljava/lang/String;", (void *)getInterfaceName},
- {"jniSetAddresses", "(Ljava/lang/String;Ljava/lang/String;)I", (void *)setAddresses},
- {"jniSetRoutes", "(Ljava/lang/String;Ljava/lang/String;)I", (void *)setRoutes},
{"jniResetInterface", "(Ljava/lang/String;)V", (void *)resetInterface},
{"jniCheckInterface", "(Ljava/lang/String;)I", (void *)checkInterface},
{"jniProtectSocket", "(ILjava/lang/String;)V", (void *)protectSocket},