mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-05 00:00:45 -04:00
android: Make fetching OCSP/CRL interruptible
This allows cancelling connecting if e.g. the OCSP server is not reachable. Previously this caused some delay in disconnecting state but even worse it cause an ANR if the user tried reconnecting during that time as the main thread would get struck in setNextProfile() (we could probably find a better solution there too in the future).
This commit is contained in:
parent
8a09350f9f
commit
ad2d20e5f0
@ -283,6 +283,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
|
||||
startConnection(mCurrentProfile);
|
||||
mIsDisconnecting = false;
|
||||
|
||||
SimpleFetcher.enable();
|
||||
addNotification();
|
||||
mBuilderAdapter.setProfile(mCurrentProfile);
|
||||
if (initializeCharon(mBuilderAdapter, mLogFile, mAppDir, mCurrentProfile.getVpnType().has(VpnTypeFeature.BYOD)))
|
||||
@ -350,6 +351,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
|
||||
{
|
||||
setState(State.DISCONNECTING);
|
||||
mIsDisconnecting = true;
|
||||
SimpleFetcher.disable();
|
||||
deinitializeCharon();
|
||||
Log.i(TAG, "charon stopped");
|
||||
mCurrentProfile = null;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Tobias Brunner
|
||||
* Copyright (C) 2017-2018 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@ -23,36 +23,118 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
@Keep
|
||||
public class SimpleFetcher
|
||||
{
|
||||
public static byte[] fetch(String uri, byte[] data, String contentType) throws IOException
|
||||
private static ExecutorService mExecutor = Executors.newCachedThreadPool();
|
||||
private static Object mLock = new Object();
|
||||
private static ArrayList<Future> mFutures = new ArrayList<>();
|
||||
private static boolean mDisabled;
|
||||
|
||||
public static byte[] fetch(String uri, byte[] data, String contentType)
|
||||
{
|
||||
URL url = new URL(uri);
|
||||
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
|
||||
conn.setConnectTimeout(10000);
|
||||
conn.setReadTimeout(10000);
|
||||
Future<byte[]> future;
|
||||
|
||||
synchronized (mLock)
|
||||
{
|
||||
if (mDisabled)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
future = mExecutor.submit(() -> {
|
||||
URL url = new URL(uri);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setConnectTimeout(10000);
|
||||
conn.setReadTimeout(10000);
|
||||
try
|
||||
{
|
||||
if (contentType != null)
|
||||
{
|
||||
conn.setRequestProperty("Content-Type", contentType);
|
||||
}
|
||||
if (data != null)
|
||||
{
|
||||
conn.setDoOutput(true);
|
||||
conn.setFixedLengthStreamingMode(data.length);
|
||||
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
|
||||
out.write(data);
|
||||
out.close();
|
||||
}
|
||||
return streamToArray(conn.getInputStream());
|
||||
}
|
||||
catch (SocketTimeoutException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
mFutures.add(future);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (contentType != null)
|
||||
{
|
||||
conn.setRequestProperty("Content-Type", contentType);
|
||||
}
|
||||
if (data != null)
|
||||
{
|
||||
conn.setDoOutput(true);
|
||||
conn.setFixedLengthStreamingMode(data.length);
|
||||
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
|
||||
out.write(data);
|
||||
out.close();
|
||||
}
|
||||
return streamToArray(conn.getInputStream());
|
||||
/* this enforces a timeout as the ones set on HttpURLConnection might not work reliably */
|
||||
return future.get(10000, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (InterruptedException|ExecutionException|TimeoutException|CancellationException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.disconnect();
|
||||
synchronized (mLock)
|
||||
{
|
||||
mFutures.remove(future);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable fetching after it has been disabled.
|
||||
*/
|
||||
public static void enable()
|
||||
{
|
||||
synchronized (mLock)
|
||||
{
|
||||
mDisabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the fetcher and abort any future requests.
|
||||
*
|
||||
* The native thread is not cancelable as it is working on an IKE_SA (cancelling the methods of
|
||||
* HttpURLConnection is not reliably possible anyway), so to abort while fetching we cancel the
|
||||
* Future (causing a return from fetch() immediately) and let the executor thread continue its
|
||||
* thing in the background.
|
||||
*
|
||||
* Also prevents future fetches until enabled again (e.g. if we aborted OCSP but would then
|
||||
* block in the subsequent fetch for a CRL).
|
||||
*/
|
||||
public static void disable()
|
||||
{
|
||||
synchronized (mLock)
|
||||
{
|
||||
mDisabled = true;
|
||||
for (Future future : mFutures)
|
||||
{
|
||||
future.cancel(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user