diff options
author | Chia-chi Yeh <chiachi@android.com> | 2011-07-02 16:16:03 -0700 |
---|---|---|
committer | Chia-chi Yeh <chiachi@android.com> | 2011-07-02 16:16:03 -0700 |
commit | 3281034c1c458b4eecd867d20b64dc5edd68ec14 (patch) | |
tree | 95b745fc557eda8d5ad94b0895a882706e28658b /services | |
parent | e9107901ae264de4ff5603d3cfc63a03ca4117d4 (diff) | |
download | frameworks_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.java | 27 | ||||
-rw-r--r-- | services/jni/com_android_server_connectivity_Vpn.cpp | 162 |
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}, |