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).
This commit is contained in:
Tobias Brunner
2014-07-22 11:10:36 +02:00
parent cc1712a8f4
commit 36aab70ab0
3 changed files with 113 additions and 5 deletions
@@ -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,
},
);
@@ -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
@@ -77,6 +77,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
*/
@@ -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;
}
}
}
/*