You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
My code uses getPinnedHttpsUrlConnection to create url connections to my server. After it's done reading a response, it closes the UrlConnection. The UrlConnection documentation says that it will not free the socket that it opens, and in fact that is what I see - if I do 'adb -e shell ls -l /proc/[processid]/fd | grep socket' shows a new socket opened (I'm assuming it's in CLOSED_WAIT state). This isn't a problem yet. However, each time that I call getPinnedHttpsUrlConnection, a new socket is opened and left in this state. Eventually, after calling getPinnedHttpsUrlConnection enough times, the android system reaps my process for having too many open file descriptors.
I suspect the issue here is that we are creating a new SSLSocketFactory for each call to getPinnedHttpsUrlConnection. In fact, I verify that caching the SSLSocketFactory keeps the number of sockets open to a constant.
I suggest modifying the PinningHelper class in the following way:
public PinningHelper {
private final static Map<List<String>,SSLSocketFactory> sSSLSocketFactories = new HashMap<List<String>, SSLSocketFactory>();
...stuff...
public static HttpsURLConnection getPinnedHttpsURLConnection(Context context, String[] pins, URL url)
throws IOException
{
if (!url.getProtocol().equals("https")) {
throw new IllegalArgumentException("Attempt to construct pinned non-https connection!");
}
SSLSocketFactory pinnedSslSocketFactory = getPinnedSslSocketFactory(context, pins, 0);
HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(pinnedSslSocketFactory);
return urlConnection;
}
public static SSLSocketFactory getPinnedSslSocketFactory(Context context, String[] pins, long enforceUntilTimestampMillis) {
List<String> pinsList = Arrays.asList(pins);
synchronized(sSSLSocketFactories) {
if (!sSSLSocketFactories.containsKey(pinsList)) {
sSSLSocketFactories.put(pinsList, createPinnedSslSocketFactory(context, pins, 0));
}
return sSSLSocketFactories.get(pinsList);
}
}
private static SSLSocketFactory createPinnedSslSocketFactory(Context context, String[] pins, long enforceUntilTimestampMillis) {
TrustManager[] trustManagers = new TrustManager[1];
trustManagers[0] = new PinningTrustManager(SystemKeyStore.getInstance(context), pins, enforceUntilTimestampMillis);
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagers, null);
return sslContext.getSocketFactory();
} catch (NoSuchAlgorithmException nsae) {
throw new AssertionError(nsae);
} catch (KeyManagementException e) {
throw new AssertionError(e);
}
}
}
The text was updated successfully, but these errors were encountered:
My code uses getPinnedHttpsUrlConnection to create url connections to my server. After it's done reading a response, it closes the UrlConnection. The UrlConnection documentation says that it will not free the socket that it opens, and in fact that is what I see - if I do 'adb -e shell ls -l /proc/[processid]/fd | grep socket' shows a new socket opened (I'm assuming it's in CLOSED_WAIT state). This isn't a problem yet. However, each time that I call getPinnedHttpsUrlConnection, a new socket is opened and left in this state. Eventually, after calling getPinnedHttpsUrlConnection enough times, the android system reaps my process for having too many open file descriptors.
I suspect the issue here is that we are creating a new SSLSocketFactory for each call to getPinnedHttpsUrlConnection. In fact, I verify that caching the SSLSocketFactory keeps the number of sockets open to a constant.
I suggest modifying the PinningHelper class in the following way:
The text was updated successfully, but these errors were encountered: