Is there a way to passing a data between System Extension and App?

I try to use Darwin Notification Center to pass data. But
Code Block
userInfo
was ignored.

I already to try to use
Code Block
CFNotificationCenterGetDistributedCenter()

It can't communicate between System Extension and APP


Answered by DTS Engineer in 626887022

processes can communicate through Darwin Notification Center. But userInfo ignored.

Correct. This is documented behaviour for sandboxed processes.

It means the Container App has no way to create or access \[the socket’s path\]

Correct. The sysex is running as root and the container app is running as the logged in user, so shared app groups aren't particularly useful because they are scoped to the current user.

Is there a way more simple than XPC?

XPC is by far the best way to deal with this problem.

If you want to preserve your existing investment in UNIX domains sockets you can create a minimal XPC interface that allows the container app to request a socket from the server (the server can create the socket pair and send one side to the app via the XPC response).

But, honestly, I think you’d be better off going ‘all in’ an XPC. It’s the preferred IPC mechanism on our platforms.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
When you mentioned App here, I am assuming you are referring to the Container App of the System Extension? If so, what is the use-case here? The reason I ask is because a System Extension and Container App have very different life cycles and you could find yourself in a situation where these the System Extension is trying to communicate with the Container App, even though the Container App's process is not alive.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
The reason is that *the container app is a monitor app to watch the status of the System Extension. For example, grab RX, TX, connection status periodically. Thereby It isn't System Extension try to communicate to container app but container app has to know what's happing in System Extension.

The details as below:
  1. My App have to monitoring the status of Network Extension which is running in System Extension.

  2. For the purpose I was used IPC (Unix Domain Socket with App Group) to communicate with Network Extensions.

  3. After move over Network Extension from App Extension to System Extension IPC(Unix Domain Socket) doesn't work anymore.

Because
Code Block
[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:]
which was i called in my program that returns a path under
Code Block
/var/root
It means the Container App has no way to create or access
Code Block
sun_path
that indicate to the path under
Code Block
/var/root

So, I did my homework and found that processes can communicate through Darwin Notification Center.
But userInfo ignored. I'm back to square one.

I try to use XPC. I saw in simple firewall example. Or, Is there a way more simple than XPC?
Did you try the handleAppMessage() function? I'm using it for the app extension, but I'm not sure if it's relevant to a system extension

Summary
Handle messages sent by the tunnel provider extension’s containing app
Declaration
func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil)
Discussion
Use this method to communicate information between the Tunnel Provider and the Tunnel Provider’s containing app.
Accepted Answer

processes can communicate through Darwin Notification Center. But userInfo ignored.

Correct. This is documented behaviour for sandboxed processes.

It means the Container App has no way to create or access \[the socket’s path\]

Correct. The sysex is running as root and the container app is running as the logged in user, so shared app groups aren't particularly useful because they are scoped to the current user.

Is there a way more simple than XPC?

XPC is by far the best way to deal with this problem.

If you want to preserve your existing investment in UNIX domains sockets you can create a minimal XPC interface that allows the container app to request a socket from the server (the server can create the socket pair and send one side to the app via the XPC response).

But, honestly, I think you’d be better off going ‘all in’ an XPC. It’s the preferred IPC mechanism on our platforms.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
You're right, eskimo. I applied XPC to my program. it is more simple than any other IPC.
I'm updating my NKE to a SystemExtension following the SimpleFirewall example.
The example shows using XPC to call a method in the application (promptUser),
but does not show an example of calling from the Host App into the FilterDataProvider.
It does show how to register with the IPCConnection, but doesn't show the last step
of calling from the IPCConnection into the FilterDataProvider.

The IPCConnection doesn't seem to know of the FilterDataProvider (except
to return a value from the promptUser() call).

Is there a way to call directly into the FilterDataProvider?
Hi Peter! Long time no chat (-:

The example shows using XPC to call a method in the application
(promptUser), but does not show an example of calling from the Host
App into the FilterDataProvider.

Yeah it does. In the NE architecture the NE sysex registers the Mach service (using NEMachServiceName) and the app always connects to it. This is in line with the standard macOS practice that higher levels in the software stack should always ‘connect’ to lower levels, not the other way around.

Here’s how it goes down:
  1. The sysex registers its Mach service in main.swift.

  2. The app calls register(withExtension:delegate:completionHandler:).

  3. That opens an XPC connection to the sysex’s Mach service.

  4. It then uses XPC to call the register(_:) method in the ProviderCommunication.

  5. This bounces over to the sysex implementation at the bottom of IPCConnection.swift. That implementation doesn’t actually do anything because…

  6. As part of this the system sets up a new XPC connection and the sysex learns of this via listener(_:shouldAcceptNewConnection:). It stashes that connection in currentConnection.

  7. When the sysex calls promptUser(aboutFlow:responseHandler:), it finds the current connection and uses that to call the client.

This is a very simple strategy, and probably not one I’d use in a real app. Rather, I’d have the client create an anonymous listener and use the ‘register’ call to pass an endpoint for that listener to the sysex. That way the sysex can wrangle multiple clients and be notified when one dies.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
I’m looking for an example of how to have a method in the SimpleFirewall ViewController
call a method in the FilterDataProvider class to provide 2-way communication between a hosting application and its system extension.

The methods shown in the FilterDataProvider class override NEFilterDataProvider methods.
It appears they are meant to be called by the NEFilterManager.

I’ve had no trouble with 2-way communication between the App and IPCConnection class.
I’m just unsure how to establish 2-way communication with the FilterDataProvider?

It appears I can send it a vendorConfiguration dictionary as part of the filterManager.providerConfiguration, or pass an object to the completion handler when the FilterDataProvider calls up to the client application (promptUser in the SimpleFirewall example).

Presumably the established XPC connection can be used to provide this 2-way communication, but the details are unclear to me.
There are two processes in play here, your app and your sysex. Some classes are only loaded in your app (App and ViewController), some are only loaded in your sysex (FilterDataProvider), and some are loaded in both (IPCConnection).

Keeping that in mind, you wrote:

I’ve had no trouble with 2-way communication between the App and
IPCConnection class.

Are you talking about IPCConnection running in your app or IPCConnection running in your sysex? That’s important because the former is a question about inter-process communication and the latter is a question of how to connect your code all running in the same process.



Oh, and one other thing: Please define what you mean by “2-way communication”? There’s a few ways you can slice that:
  • Request-response messaging

  • Asynchronous notification

XPC can do both but the setup is slightly different in each case.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Is there a way to passing a data between System Extension and App?
 
 
Q