Best practice for developing app leveraging per app vpn solution

Hello,


I am developing an iOS application using Swift for iOS 10 which is going to leverage MDM provided per app vpn solution and would like to know if there is any best practice or such guide which highligts what netwok programming practice (sync/async, forground/background) I need to adhere and which networking APIs (urlseession, cfsocket , cfstream,uiwebview,wkwebview,bsd networking etc.) I can or can NOT use while writing this app.


The intent of asking this question is I couldn't find any explicit doucmentation that states above points and have seen people run into issues where the traffic originating from the applicaiton is not being tunneled by the MDM per app vpn. Some say that sync vs async network call effect this other say to do socket programming instead of url programming in the app to achieve a better comptability with per app vpn solution for my app.


To summaries my specific questions to apple are:

1. Do I need to worry about the way my app is doing netwoking on iOS if the app is going to leverage per app vpn on iOS?

2. If answer to 1 is yes, what are the best practices?

3. If answer to 1 is yes, does it also depend on the type of per app vpn solution I am using, for example approxy vs packettunnel?


Thanks

Replies

1. Do I need to worry about the way my app is doing netwoking on iOS if the app is going to leverage per app vpn on iOS?

Not really. There are a couple of gotchas, but these affect all sorts of VPN, not just per-app VPN. I’ll cover those below.

2. If answer to 1 is yes, what are the best practices?

See below.

3. If answer to 1 is yes, does it also depend on the type of per app vpn solution I am using, for example approxy vs packettunnel?

No.

To support VPN On Demand you must use some sort of connect by name API. These includes CFSocketStream and anything layered on top of that (including NSURLSession). Doing separate resolve then connect is more work and is incompatible with VPN On Demand.

IMPORTANT BSD Sockets does not have a connect by name API. If you need to use BSD Sockets for other reasons — for example, you’re porting some cross-platform code — you can do some sneaky stuff to connect by name and then continue using BSD Sockets for the bulk of your I/O. See this post for an example of that.

To work with VPN in general you must not do your own DNS resolution. The system DNS resolver has lots of smarts to cope with all sorts of odd situations, and those situations often crop up in a VPN scenario. For example, a company

example.com
might have two DNS servers:
  • An external DNS server, that contains a limited set of DNS records for their public ’net presence (like

    www.example.com
    )
  • An internal DNS server, that contains a larger set of DNS records for all their internal systems (like

    human-resources.example.com
    )

Their VPN is configured such that the system DNS resolver uses the internal server for

example.com
when the VPN is up. If you, as an app developer, do your own DNS resolution this won’t work.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"