diff options
author | Tobias Brunner <tobias@strongswan.org> | 2014-07-16 13:54:57 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2014-07-22 11:10:36 +0200 |
commit | 36aab70ab068a8552cf3bc4f80187fc178a2aaf7 (patch) | |
tree | 317ed74400b5cca112a6deca9be39df4fab8524d /src | |
parent | cc1712a8f4656f0e2417da44f3b27385e71ffa17 (diff) | |
download | strongswan-36aab70ab068a8552cf3bc4f80187fc178a2aaf7.tar.bz2 strongswan-36aab70ab068a8552cf3bc4f80187fc178a2aaf7.tar.xz |
android: Add method to BuilderAdapter to re-establish without DNS-related data
Non-DNS data is cached in the BuilderAdapter so the TUN device can be
recreated easily (since the CHILD_SA is gone we couldn't actually gather
that information).
Diffstat (limited to 'src')
3 files changed, 113 insertions, 5 deletions
diff --git a/src/frontends/android/jni/libandroidbridge/vpnservice_builder.c b/src/frontends/android/jni/libandroidbridge/vpnservice_builder.c index 6b10228d0..c7a6eb6da 100644 --- a/src/frontends/android/jni/libandroidbridge/vpnservice_builder.c +++ b/src/frontends/android/jni/libandroidbridge/vpnservice_builder.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Tobias Brunner + * Copyright (C) 2012-2014 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * Hochschule fuer Technik Rapperswil @@ -197,8 +197,10 @@ failed: return FALSE; } -METHOD(vpnservice_builder_t, establish, int, - private_vpnservice_builder_t *this) +/** + * Establish or reestablish the TUN device + */ +static int establish_internal(private_vpnservice_builder_t *this, char *method) { JNIEnv *env; jmethodID method_id; @@ -209,7 +211,7 @@ METHOD(vpnservice_builder_t, establish, int, DBG2(DBG_LIB, "builder: building TUN device"); method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class, - "establish", "()I"); + method, "()I"); if (!method_id) { goto failed; @@ -229,6 +231,18 @@ failed: return -1; } +METHOD(vpnservice_builder_t, establish, int, + private_vpnservice_builder_t *this) +{ + return establish_internal(this, "establish"); +} + +METHOD(vpnservice_builder_t, establish_no_dns, int, + private_vpnservice_builder_t *this) +{ + return establish_internal(this, "establishNoDns"); +} + METHOD(vpnservice_builder_t, destroy, void, private_vpnservice_builder_t *this) { @@ -252,6 +266,7 @@ vpnservice_builder_t *vpnservice_builder_create(jobject builder) .add_dns = _add_dns, .set_mtu = _set_mtu, .establish = _establish, + .establish_no_dns = _establish_no_dns, .destroy = _destroy, }, ); diff --git a/src/frontends/android/jni/libandroidbridge/vpnservice_builder.h b/src/frontends/android/jni/libandroidbridge/vpnservice_builder.h index 209090896..08c436da6 100644 --- a/src/frontends/android/jni/libandroidbridge/vpnservice_builder.h +++ b/src/frontends/android/jni/libandroidbridge/vpnservice_builder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2014 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * Hochschule fuer Technik Rapperswil @@ -78,6 +78,13 @@ struct vpnservice_builder_t { int (*establish)(vpnservice_builder_t *this); /** + * Build the TUN device without DNS related data + * + * @return the TUN file descriptor, -1 if failed + */ + int (*establish_no_dns)(vpnservice_builder_t *this); + + /** * Destroy a vpnservice_builder */ void (*destroy)(vpnservice_builder_t *this); diff --git a/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java index d53d478b2..5707f4fb6 100644 --- a/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java @@ -22,6 +22,7 @@ import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.List; import org.strongswan.android.data.VpnProfile; import org.strongswan.android.data.VpnProfileDataSource; @@ -526,11 +527,14 @@ public class CharonVpnService extends VpnService implements Runnable { private final String mName; private VpnService.Builder mBuilder; + private BuilderCache mCache; + private BuilderCache mEstablishedCache; public BuilderAdapter(String name) { mName = name; mBuilder = createBuilder(name); + mCache = new BuilderCache(); } private VpnService.Builder createBuilder(String name) @@ -553,6 +557,7 @@ public class CharonVpnService extends VpnService implements Runnable try { mBuilder.addAddress(address, prefixLength); + mCache.addAddress(address, prefixLength); } catch (IllegalArgumentException ex) { @@ -579,6 +584,7 @@ public class CharonVpnService extends VpnService implements Runnable try { mBuilder.addRoute(address, prefixLength); + mCache.addRoute(address, prefixLength); } catch (IllegalArgumentException ex) { @@ -605,6 +611,7 @@ public class CharonVpnService extends VpnService implements Runnable try { mBuilder.setMtu(mtu); + mCache.setMtu(mtu); } catch (IllegalArgumentException ex) { @@ -632,8 +639,87 @@ public class CharonVpnService extends VpnService implements Runnable /* now that the TUN device is created we don't need the current * builder anymore, but we might need another when reestablishing */ mBuilder = createBuilder(mName); + mEstablishedCache = mCache; + mCache = new BuilderCache(); return fd.detachFd(); } + + public synchronized int establishNoDns() + { + ParcelFileDescriptor fd; + + if (mEstablishedCache == null) + { + return -1; + } + try + { + Builder builder = createBuilder(mName); + mEstablishedCache.applyData(builder); + fd = builder.establish(); + } + catch (Exception ex) + { + ex.printStackTrace(); + return -1; + } + if (fd == null) + { + return -1; + } + return fd.detachFd(); + } + } + + /** + * Cache non DNS related information so we can recreate the builder without + * that information when reestablishing IKE_SAs + */ + public class BuilderCache + { + private final List<PrefixedAddress> mAddresses = new ArrayList<PrefixedAddress>(); + private final List<PrefixedAddress> mRoutes = new ArrayList<PrefixedAddress>(); + private int mMtu; + + public void addAddress(String address, int prefixLength) + { + mAddresses.add(new PrefixedAddress(address, prefixLength)); + } + + public void addRoute(String address, int prefixLength) + { + mRoutes.add(new PrefixedAddress(address, prefixLength)); + } + + public void setMtu(int mtu) + { + mMtu = mtu; + } + + public void applyData(VpnService.Builder builder) + { + for (PrefixedAddress address : mAddresses) + { + builder.addAddress(address.mAddress, address.mPrefix); + } + for (PrefixedAddress route : mRoutes) + { + builder.addRoute(route.mAddress, route.mPrefix); + } + builder.setMtu(mMtu); + } + + private class PrefixedAddress + { + public String mAddress; + public int mPrefix; + + public PrefixedAddress(String address, int prefix) + { + this.mAddress = address; + this.mPrefix = prefix; + } + } } /* |