1

I have some logic that communicates with a backend server which has two versions, a NSURLConnection and NSURLSession. The latter was made because NSURLConnection is deprecated, and also we want to leverage the background download ability. These classes are written to support client-side certificates for authenticating the client.

The classes that do this communication is called from a few different types of routines throughout my application.

The issue I am seeing is that when using the NSURLSession version, I see that a SSL (TLSv1) session is never being reused, and there is a full chain of [Client Hello, Server Hello, Certificate, Certificate, Client Key Exchange, Certificate Verify, etc.] for each connection. Looking at the "Client Hello" message, I can see there is never a "session ID" in the message, so I think this is why the SSL session is never reused.

On the older, NSURLConnection version, I see that often the session is reused, and a previous session ID is given in the "Client Hello" message.

In both of these approaches, I am creating a new instance of NSURLConnection or NSURLSession. I think what is going on is that NSURLConnection works across the entire app, whereas NSURLSession does not.

However, I am not sure how I should be writing my NSURLSession logic so that the SSL session is shared between server and client and the client cert isn't sent every time. I think one way might be to use a single NSURLSession instance, but I am not sure if this is the right design pattern.

Locksleyu
  • 5,192
  • 8
  • 52
  • 77

1 Answers1

0

With NSURLSession, connections are not shared across multiple sessions, because different sessions can have different limits on the maximum number of concurrent connections, different keep-alive settings, different proxy settings, etc.

Thus, if you're only making one request per session, you'll end up creating a new connection every time, complete with the full TLS setup overhead.

There are two straightforward ways to fix this:

  • Create a single session when you launch the app and use it everywhere.
  • Use the shared session ([NSURLSession sharedSession]).

If you're doing background downloading, that session needs to be created once, when your app first starts, and then never recreated (unless the session was created in response to your app getting relaunched in the background to handle some task's results, in which case IIRC the session becomes invalid, so you'll recreate it again if your app subsequently gets launched in the usual way or whatever).

dgatwood
  • 10,129
  • 1
  • 28
  • 49