Re: Using dead notification with mach ports
Re: Using dead notification with mach ports
- Subject: Re: Using dead notification with mach ports
- From: Jim Magee <email@hidden>
- Date: Fri, 10 Sep 2004 12:22:21 -0400
On Sep 10, 2004, at 6:40 AM, Stiphane Letz wrote:
Hi
I'm developing a server/client system and would like to use the
MACH_NOTIFY_DEAD_NAME system so that the server can know when clients
disappear abnormally (crash...)
...[snip]...
Then I'm trying to add a dead notification to notify the server when
clients disappear :
On the client side :
mach_port_t server_port;
mach_port_t old_port;
if (task_for_pid(mach_task_self(),getpid(),&server_port) !=
KERN_SUCCESS) {
printf("NotifyDead: can't find mach task_for_pid");
return false;
}
kern_return_t result;
if ((result =
mach_port_request_notification(mach_task_self(),server_port,
MACH_NOTIFY_DEAD_NAME,
0,fServerPort,MACH_MSG_TYPE_MAKE_SEND_ONCE,
&old_port)) != KERN_SUCCESS) {
printf("NotifyDead %s\n",mach_error_string(result));
return false;
}
But I always get a "NotifyDead (ipc/send) invalid port right" error
message.
Any idea of what is wrong? Is is the right way to do? Any link to
code/examples that implements this correctly?
The correct answer almost never includes task_for_pid(). ;-)
Besides, the task_for_pid() call you make above is just getting your
own (client) task port. So, server_port should just be the same as
what mach_task_self() returns. You didn't need to call task_for-pid()
to get that. The second problem is that you are trying to use a send
right (the client's reference to fServerPort) to create a send-once
right (the one you try to make as part of the notification request).
You simply cannot create a send-once right from a send right. Only the
receive right can be used to make a send-once right. And that means
that only the server itself can make this request.
In trying to fix this, it is important to think about notifications in
general. All Mach port notification messages are "port namespace
relative" (only the name of the port is sent in the message). Within
each task's port namespace, the mach_task_self() port likely has the
same low-number name (because it is exposed during the pre-main()
initialization of the process). So, nearly every one of the
notification messages received by the server would look identical.
Nothing would actually identify the client in any way known to the
server.
What you need is a reference, held by the server, that identifies each
client. Then the server can request a notification about that
reference. It is tempting to just have each client send the server
their own task port to identify themselves. But that's a security
issue if you don't trust the server whole-heartedly. You could just
send a PID and have the server do the task_for_pid() itself. But then
the client may just be spoofing the PID. In Panther 10.3.4 and above
you could get a "trusted path" PID from the Mach message audit trailer
to get around the spoofing. But this is all too kludgy. I
f the server really does maintain state for each client independently,
it should probably maintain a private connection with each such
client. Just use the fServerPort (the one found in the bootstrap
namespace) to have each client make a private connection to the server
(the server creates a new, private, Mach port for the client and adds
it to the portset that it waits on). The server can then request a
"no-senders" notification on that private connection port to determine
when the client goes away.
--Jim
Thanks
Stephane Letz
_______________________________________________
darwin-development mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-development
Do not post admin requests to the list. They will be ignored.
_______________________________________________
darwin-development mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-development
Do not post admin requests to the list. They will be ignored.