Network Reachability In Network extension

Hi

I am developing App proxy network system extension on 10.15.5. Reachability callaback is registered using below method but reachability_callback is never called.

Code Block void registerNetworkChangeCallback() {
sockaddr_in ipv4{};
ipv4.sin_family = AF_INET;
ipv4.sin_len = sizeof(sockaddr_in);
ipv4.sin_addr.s_addr = 0x08080808; /*dummy ip*/
SCNetworkReachabilityRef reachableTarget = SCNetworkReachabilityCreateWithAddress(NULL, (sockaddr *)&ipv4);
Boolean ok = SCNetworkReachabilitySetCallback(reachableTarget, reachability_callback, NULL);
ok = SCNetworkReachabilityScheduleWithRunLoop(reachableTarget,
CFRunLoopGetMain(),
kCFRunLoopDefaultMode
);
}


I know "defaultPath" can be used to detect the network change.

I am trying to understand underlying root cause of this issue. Does reachability callback not work with CFRunLoopGetMain?

Regards,
Anand Choubey

Replies

Hey Anand, checkout and see if you are parking the main thread with dispatch_main(); in your App Proxy Extension's main.m file. Try could be why you are running into issues.

You could try and setting Reachability to a dispatch queue instead.

Code Block objC
SCNetworkReachabilityRef reachableTarget = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [@"apple.com" UTF8String]);
if (SCNetworkReachabilitySetCallback(reachableTarget, reachability_callback, NULL)) {
if (SCNetworkReachabilitySetDispatchQueue(reachableTarget, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))) {
/* Success to set reachability callback on queue */
} else {
/* Failed to set reachability callback on queue */
}
}

However, if you need to evaluate Reachability inside a Network Extension, my recommendation would be to look into using nw_path_monitor_t as a more modern API for Reachability.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Thanks Matt!
Code Block
int main(int argc, char *argv[])
{
  @autoreleasepool {
    [NEProvider startSystemExtensionMode];
  }
   
  dispatch_main();
}

Does RunLoop work with dispatch_main()?

Anyway, SCNetworkReachabilitySetDispatchQueue works for me.

Thanks


NetworkExtension providers do not have guaranteed access to a run loop. If you want to use a run loop based API, you must:
  1. Start your own thread

  2. Schedule your run loop sources on that thread’s run loop

  3. Have that thread run the run loop

This is a colossal pain, so it’s best to use a queue-based API where it’s available.



Finally, I want to reiterate Matt’s comments about moving away from SCNetworkReachability. NWPathMonitor is easier to use, doesn’t have this problem, and is generally aligned with Apple’s plans moving forward.

Share and Enjoy

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

Your suggestion helped me a lot.

NetworkExtension providers do not have guaranteed access to a run loop. If you want to use a run loop based API, you must:
Start your own thread
Schedule your run loop sources on that thread’s run loop
Have that thread run the run loop
This is a colossal pain, so it’s best to use a queue-based API where it’s available.

How would one handle callbacks for SCDynamicStoreCreateRunLoopSource?

Could you provide a snippet for setting up the run loop.

Oh I see SCDynamicStoreSetDispatchQueue