iosvpntunnelnetworkextensionandroid-vpn-service

How to achieve VpnService's protect in an iOS VPN?


I'm porting an Android device's VPN App to iOS (using NEPacketTunnelProvider).

Android provides a mechanism to bypass VPN for some tcp/udp connections, using the following API:

class VpnService {

  // ...
  
  public boolean protect(int socket) { /* ... */ }

I don't see equivalent API in iOS. How do I implement something equivalent for iOS?


Solution

  • Coming from Android and knowing nothing of Apple API (except Swift and ObjC++ languages), I will try to point out what a normal developer would like to know.


    An iOS App's life ends the moment the views are closed, hence a permanent VPN-Service is ONLY possible in an extension, which is a completely different target than that of your views (because iOS has no Service concept).

    In addition to knowing above, learn the fact that any connection (aka Socket) created from within your extension is magically excluded (aka protected) from going through packetFlow (aka Tunnel), no matter if it's a Raw-socket made by C/C++ or OOP-Wrapped class in Swift5.

    Surprisingly enough, actually making your extension's socket go through tunnel is much harder,
    and you would need to use NEPacketTunnelProvider class's methods:

    - createTCPConnectionThroughTunnelToEndpoint:enableTLS:TLSParameters:delegate:
    
    - createUDPSessionThroughTunnelToEndpoint:fromEndpoint:
    

    Note that above are instance methods, which is what minus sign in ObjC means,
    so only available in extension context (but there is no escaping from the tunnel for App-targets anyway).

    See also: https://developer.apple.com/forums/thread/94430