Qt IOS Application Extension - Packet Tunnel for Custom VPN Functionality

I am trying to create an application extension which provides vpn functionality over network extension with packet-tunnel. But when I enable vpn it doesn't call related callbacks.

Currently, i didn't find any example in qt documentation. So I read the documents of ios and qt and trying to find the right path.

Here is the CMakeLists.txt

add_executable(overlay-service MACOSX_BUNDLE main.cpp tunnel_provider.h tunnel_provider.mm)
   
   set_target_properties(overlay-service PROPERTIES
       MACOSX_BUNDLE_IDENTIFIER org.zenarmor.zenoverlay.network-extension
       BUNDLE YES
       XCODE_PRODUCT_TYPE com.apple.product-type.app-extension
       # XCODE_EMBED_FRAMEWORKS /System/Library/Frameworks/NetworkExtension.framework
   )

target_link_libraries(
   overlay-service

   PUBLIC
       Qt6::CorePrivate
       overlay-lib
)

tunnel_provider.h

#ifndef _TUNNEL_PROVIDER_H
#define _TUNNEL_PROVIDER_H

#import <Foundation/Foundation.h>
#import <NetworkExtension/NetworkExtension.h>

@interface ZenTunnelProvider : NEPacketTunnelProvider {
    int fd;
}

- (void) startTunnelWithOptions:(NSDictionary<NSString *,NSObject *> *) options
              completionHandler:(void (^)(NSError * error)) completionHandler;
- (void) stopTunnelWithReason:(NEProviderStopReason) reason
            completionHandler:(void (^)()) completionHandler;
@end

#endif

tunnel_provider.mm

#import <Foundation/Foundation.h>
#import <os/log.h>

@implementation ZenTunnelProvider
- (void) startTunnelWithOptions:(NSDictionary<NSString *,NSObject *> *) options
              completionHandler:(void (^)(NSError * error)) completionHandler {

    NSLog(@"===================== Tunnel Started, x=%i, %@", 5, self.protocolConfiguration);

    completionHandler(nil);
}
- (void) stopTunnelWithReason:(NEProviderStopReason) reason
            completionHandler:(void (^)()) completionHandler{
    NSLog(@"===================== Tunnel Stopped");;
    completionHandler();
}

@end

How I create configuration is:


        provider_protocol.providerBundleIdentifier = @"org.zenarmor.zenoverlay.packet-tunnel";
        provider_protocol.serverAddress = @"0.0.0.0";
        provider_protocol.providerConfiguration = @{
            @"helloString" : @"Hello, World!",
            @"magicNumber" : @42
        };

      NSLog(@"===================== Vpn configuration is written, x=%i", 5);

        vpn_manager.protocolConfiguration = provider_protocol;
        vpn_manager.localizedDescription  = @"ZenOverlayTunnel";
        vpn_manager.enabled               = true;

        [vpn_manager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
            if (error)
            {
                NSLog(@"err: %@", error);
            }
            else
            {
                NSLog(@"Successfully saved");
            }
        }];

main.cpp

#include <QCoreApplication>
#include <iostream>

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
    std::cout << "Hello world" << std::endl;
    return app.exec();
}

startTunnelWithOptions is not triggered when I enable vpn from settings on IOS. Could anyone. help to identify the issue?

Answered by DTS Engineer in 865137022

I recommend that you do this initial bring-up work in an Xcode test project. Then, once you get to the point where iOS is able to load your extension, you can look at what Xcode constructed and how it constructed it (based on Xcode’s build log). Then you can crib from that as you wrestle with you third-party tooling.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I recommend that you do this initial bring-up work in an Xcode test project. Then, once you get to the point where iOS is able to load your extension, you can look at what Xcode constructed and how it constructed it (based on Xcode’s build log). Then you can crib from that as you wrestle with you third-party tooling.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Qt IOS Application Extension - Packet Tunnel for Custom VPN Functionality
 
 
Q