diff options
| author | Alexandra Ellwood <lxs@mit.edu> | 2008-09-28 19:43:47 +0000 |
|---|---|---|
| committer | Alexandra Ellwood <lxs@mit.edu> | 2008-09-28 19:43:47 +0000 |
| commit | b5dce4285a9330d25542528030ce93da78e36375 (patch) | |
| tree | c8cbd6a729cddb99bda84991e1c7c231449434f2 /src/util/mac | |
| parent | 01a5986cbf7afdba2b805bdd16893b6b52c87f42 (diff) | |
| download | krb5-b5dce4285a9330d25542528030ce93da78e36375.tar.gz krb5-b5dce4285a9330d25542528030ce93da78e36375.tar.xz krb5-b5dce4285a9330d25542528030ce93da78e36375.zip | |
Create common stream and ipc layer for CCAPI and KIM.
Will switch CCAPI to this new code later though, so as
not to destabilize KfM and the Windows builds.
ticket: 6055
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20769 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/util/mac')
| -rw-r--r-- | src/util/mac/k5_mig.defs | 54 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_client.c | 292 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_client.h | 36 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_reply.defs | 58 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_request.defs | 62 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_server.c | 233 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_server.h | 53 | ||||
| -rw-r--r-- | src/util/mac/k5_mig_types.h | 55 |
8 files changed, 843 insertions, 0 deletions
diff --git a/src/util/mac/k5_mig.defs b/src/util/mac/k5_mig.defs new file mode 100644 index 000000000..6349eb877 --- /dev/null +++ b/src/util/mac/k5_mig.defs @@ -0,0 +1,54 @@ +/* $Copyright: + * + * Copyright 2004-2006 by the Massachusetts Institute of Technology. + * + * All rights reserved. + * + * Export of this software from the United States of America may require a + * specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute + * this software and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of M.I.T. not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Furthermore if you + * modify this software you must label your software as modified software + * and not distribute it in such a fashion that it might be confused with + * the original MIT software. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Individual source code files are copyright MIT, Cygnus Support, + * OpenVision, Oracle, Sun Soft, FundsXpress, and others. + * + * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + * and Zephyr are trademarks of the Massachusetts Institute of Technology + * (MIT). No commercial use of these trademarks may be made without prior + * written permission of MIT. + * + * "Commercial use" means use of a name in a product or other for-profit + * manner. It does NOT prevent a commercial firm from referring to the MIT + * trademarks in order to convey information (although in doing so, + * recognition of their trademark status should be given). + * $ + */ + +#include <mach/std_types.defs> +#include <mach/mach_types.defs> + +import "k5_mig_types.h"; + +/* Note the 1024 must be the same as K5_IPC_MAX_MSG_SIZE */ +type k5_ipc_inl_request_t = array [ * : 1024 ] of char; +type k5_ipc_ool_request_t = array [] of char; + +type k5_ipc_inl_reply_t = array [ * : 1024 ] of char; +type k5_ipc_ool_reply_t = array [] of char; diff --git a/src/util/mac/k5_mig_client.c b/src/util/mac/k5_mig_client.c new file mode 100644 index 000000000..5ffe7deb8 --- /dev/null +++ b/src/util/mac/k5_mig_client.c @@ -0,0 +1,292 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "k5_mig_client.h" + +#include <Kerberos/kipc_client.h> +#include "k5_mig_request.h" +#include "k5_mig_replyServer.h" +#include "k5-thread.h" + +MAKE_INIT_FUNCTION(k5_cli_ipc_thread_init); +MAKE_FINI_FUNCTION(k5_cli_ipc_thread_fini); + +/* ------------------------------------------------------------------------ */ + +static int k5_cli_ipc_thread_init (void) +{ + int err = 0; + + err = k5_key_register (K5_KEY_IPC_REQUEST_PORT, free); + + if (!err) { + err = k5_key_register (K5_KEY_IPC_REPLY_STREAM, NULL); + } + + if (!err) { + err = k5_key_register (K5_KEY_IPC_SERVER_DIED, NULL); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +static void k5_cli_ipc_thread_fini (void) +{ + k5_key_delete (K5_KEY_IPC_REQUEST_PORT); + k5_key_delete (K5_KEY_IPC_REPLY_STREAM); + k5_key_delete (K5_KEY_IPC_SERVER_DIED); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static boolean_t k5_ipc_reply_demux (mach_msg_header_t *request, + mach_msg_header_t *reply) +{ + boolean_t handled = 0; + + if (CALL_INIT_FUNCTION (k5_cli_ipc_thread_init) != 0) { + return 0; + } + + if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) { + int32_t *server_died = k5_getspecific (K5_KEY_IPC_SERVER_DIED); + if (!server_died) { + *server_died = 1; + } + + handled = 1; /* server died */ + } + + if (!handled) { + handled = k5_ipc_reply_server (request, reply); + } + + return handled; +} + +/* ------------------------------------------------------------------------ */ + +kern_return_t k5_ipc_client_reply (mach_port_t in_reply_port, + k5_ipc_inl_reply_t in_inl_reply, + mach_msg_type_number_t in_inl_replyCnt, + k5_ipc_ool_reply_t in_ool_reply, + mach_msg_type_number_t in_ool_replyCnt) +{ + kern_return_t err = KERN_SUCCESS; + k5_ipc_stream reply_stream = NULL; + + if (!err) { + err = CALL_INIT_FUNCTION (k5_cli_ipc_thread_init); + } + + if (!err) { + reply_stream = k5_getspecific (K5_KEY_IPC_REPLY_STREAM); + if (!reply_stream) { err = EINVAL; } + } + + if (!err) { + if (in_inl_replyCnt) { + err = k5_ipc_stream_write (reply_stream, in_inl_reply, in_inl_replyCnt); + + } else if (in_ool_replyCnt) { + err = k5_ipc_stream_write (reply_stream, in_ool_reply, in_ool_replyCnt); + + } else { + err = EINVAL; + } + } + + if (in_ool_replyCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_reply, in_ool_replyCnt); } + + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_send_request (int32_t in_launch_server, + k5_ipc_stream in_request_stream, + k5_ipc_stream *out_reply_stream) +{ + int err = 0; + int32_t done = 0; + int32_t try_count = 0; + int32_t server_died = 0; + mach_port_t server_port = MACH_PORT_NULL; + mach_port_t *request_port = NULL; + mach_port_t reply_port = MACH_PORT_NULL; + const char *inl_request = NULL; /* char * so we can pass the buffer in directly */ + mach_msg_type_number_t inl_request_length = 0; + k5_ipc_ool_request_t ool_request = NULL; + mach_msg_type_number_t ool_request_length = 0; + k5_ipc_stream reply_stream = NULL; + + if (!in_request_stream) { err = EINVAL; } + if (!out_reply_stream ) { err = EINVAL; } + + if (!err) { + err = CALL_INIT_FUNCTION (k5_cli_ipc_thread_init); + } + + if (!err) { + /* depending on how big the message is, use the fast inline buffer or + * the slow dynamically allocated buffer */ + mach_msg_type_number_t request_length = k5_ipc_stream_size (in_request_stream); + + if (request_length > K5_IPC_MAX_MSG_SIZE) { + //dprintf ("%s choosing out of line buffer (size is %d)", + // __FUNCTION__, request_length); + + err = vm_read (mach_task_self (), + (vm_address_t) k5_ipc_stream_data (in_request_stream), request_length, + (vm_address_t *) &ool_request, &ool_request_length); + } else { + //dprintf ("%s choosing in line buffer (size is %d)", + // __FUNCTION__, request_length); + + inl_request_length = request_length; + inl_request = k5_ipc_stream_data (in_request_stream); + } + } + + if (!err) { + request_port = k5_getspecific (K5_KEY_IPC_REQUEST_PORT); + + if (!request_port) { + request_port = malloc (sizeof (mach_port_t)); + if (!request_port) { err = ENOMEM; } + + if (!err) { + *request_port = MACH_PORT_NULL; + err = k5_setspecific (K5_KEY_IPC_REQUEST_PORT, request_port); + } + } + } + + if (!err) { + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &reply_port); + } + + if (!err) { + err = kipc_client_lookup_server (K5_IPC_SERVER_ID, + in_launch_server, TRUE, &server_port); + } + + while (!err && !done) { + if (!err && !MACH_PORT_VALID (*request_port)) { + err = k5_ipc_client_create_client_connection (server_port, request_port); + } + + if (!err) { + err = k5_ipc_client_request (*request_port, reply_port, + inl_request, inl_request_length, + ool_request, ool_request_length); + + } + + if (err == MACH_SEND_INVALID_DEST) { + if (try_count < 2) { + try_count++; + err = 0; + } + + if (request_port && MACH_PORT_VALID (*request_port)) { + mach_port_mod_refs (mach_task_self(), *request_port, MACH_PORT_RIGHT_SEND, -1 ); + *request_port = MACH_PORT_NULL; + } + + /* Look up server name again without using the cached copy */ + err = kipc_client_lookup_server (K5_IPC_SERVER_ID, + in_launch_server, FALSE, &server_port); + + } else { + /* Talked to server, though we may have gotten an error */ + done = 1; + + /* Because we use ",dealloc" ool_request will be freed by mach. + * Don't double free it. */ + ool_request = NULL; + ool_request_length = 0; + } + } + + if (!err) { + err = k5_ipc_stream_new (&reply_stream); + } + + if (!err) { + err = k5_setspecific (K5_KEY_IPC_REPLY_STREAM, reply_stream); + } + + if (!err) { + err = k5_setspecific (K5_KEY_IPC_SERVER_DIED, &server_died); + } + + if (!err) { + mach_port_t old_notification_target = MACH_PORT_NULL; + + /* request no-senders notification so we can get a message when server dies */ + err = mach_port_request_notification (mach_task_self (), reply_port, + MACH_NOTIFY_NO_SENDERS, 1, reply_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, + &old_notification_target); + + if (!err && old_notification_target != MACH_PORT_NULL) { + mach_port_deallocate (mach_task_self (), old_notification_target); + } + } + + if (!err) { + err = mach_msg_server_once (k5_ipc_reply_demux, kkipc_max_message_size, + reply_port, MACH_MSG_TIMEOUT_NONE); + } + + if (!err && server_died) { + err = ENOTCONN; + } + + if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) { + err = 0; /* If the server is not running just return an empty stream. */ + } + + if (!err) { + *out_reply_stream = reply_stream; + reply_stream = NULL; + } + + k5_setspecific (K5_KEY_IPC_REPLY_STREAM, NULL); + k5_setspecific (K5_KEY_IPC_SERVER_DIED, NULL); + if (reply_port != MACH_PORT_NULL) { mach_port_destroy (mach_task_self (), reply_port); } + if (ool_request_length ) { vm_deallocate (mach_task_self (), (vm_address_t) ool_request, ool_request_length); } + if (reply_stream ) { k5_ipc_stream_release (reply_stream); } + + return err; +} diff --git a/src/util/mac/k5_mig_client.h b/src/util/mac/k5_mig_client.h new file mode 100644 index 000000000..b5eefdc3a --- /dev/null +++ b/src/util/mac/k5_mig_client.h @@ -0,0 +1,36 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef K5_MIG_CLIENT_H +#define K5_MIG_CLIENT_H + +#include "k5-ipc_stream.h" + +int32_t k5_ipc_send_request (int32_t in_launch_server, + k5_ipc_stream in_request_stream, + k5_ipc_stream *out_reply_stream); + +#endif /* K5_MIG_CLIENT_H */ diff --git a/src/util/mac/k5_mig_reply.defs b/src/util/mac/k5_mig_reply.defs new file mode 100644 index 000000000..301778e15 --- /dev/null +++ b/src/util/mac/k5_mig_reply.defs @@ -0,0 +1,58 @@ +/* $Copyright: + * + * Copyright 2004-2006 by the Massachusetts Institute of Technology. + * + * All rights reserved. + * + * Export of this software from the United States of America may require a + * specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute + * this software and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of M.I.T. not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Furthermore if you + * modify this software you must label your software as modified software + * and not distribute it in such a fashion that it might be confused with + * the original MIT software. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Individual source code files are copyright MIT, Cygnus Support, + * OpenVision, Oracle, Sun Soft, FundsXpress, and others. + * + * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + * and Zephyr are trademarks of the Massachusetts Institute of Technology + * (MIT). No commercial use of these trademarks may be made without prior + * written permission of MIT. + * + * "Commercial use" means use of a name in a product or other for-profit + * manner. It does NOT prevent a commercial firm from referring to the MIT + * trademarks in order to convey information (although in doing so, + * recognition of their trademark status should be given). + * $ + */ + +#include "k5_mig.defs" + +subsystem k5_ipc_reply 200; + +serverprefix k5_ipc_client_; +userprefix k5_ipc_server_; + +/* ",dealloc" means that the vm_read() memory will be moved to + * the other process rather than copied. This is necessary on the + * client side because we can't know when server has copied our + * buffers so we can't vm_deallocate() them ourselves. */ + +simpleroutine reply (in_reply_port : mach_port_move_send_once_t; + in_inl_reply : k5_ipc_inl_reply_t; + in_ool_reply : k5_ipc_ool_reply_t, dealloc); diff --git a/src/util/mac/k5_mig_request.defs b/src/util/mac/k5_mig_request.defs new file mode 100644 index 000000000..bbb23f0e3 --- /dev/null +++ b/src/util/mac/k5_mig_request.defs @@ -0,0 +1,62 @@ +/* $Copyright: + * + * Copyright 2004-2006 by the Massachusetts Institute of Technology. + * + * All rights reserved. + * + * Export of this software from the United States of America may require a + * specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute + * this software and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of M.I.T. not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Furthermore if you + * modify this software you must label your software as modified software + * and not distribute it in such a fashion that it might be confused with + * the original MIT software. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Individual source code files are copyright MIT, Cygnus Support, + * OpenVision, Oracle, Sun Soft, FundsXpress, and others. + * + * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + * and Zephyr are trademarks of the Massachusetts Institute of Technology + * (MIT). No commercial use of these trademarks may be made without prior + * written permission of MIT. + * + * "Commercial use" means use of a name in a product or other for-profit + * manner. It does NOT prevent a commercial firm from referring to the MIT + * trademarks in order to convey information (although in doing so, + * recognition of their trademark status should be given). + * $ + */ + +#include "k5_mig.defs" + +subsystem k5_ipc_request 100; + +serverprefix k5_ipc_server_; +userprefix k5_ipc_client_; + +routine create_client_connection (in_server_port : mach_port_t; + out out_connection_port : mach_port_t = MACH_MSG_TYPE_MAKE_SEND); + +/* ",dealloc" means that the vm_read() memory will be moved to + * the other process rather than copied. This is necessary on the + * server side because we can't know when client has copied our + * buffers so we can't vm_deallocate() them ourselves. */ + +simpleroutine request (in_connection_port : mach_port_t; + in_reply_port : mach_port_make_send_once_t; + in_inl_request : k5_ipc_inl_request_t; + in_ool_request : k5_ipc_ool_request_t, dealloc); diff --git a/src/util/mac/k5_mig_server.c b/src/util/mac/k5_mig_server.c new file mode 100644 index 000000000..ddf81ce0b --- /dev/null +++ b/src/util/mac/k5_mig_server.c @@ -0,0 +1,233 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "k5_mig_server.h" + +#include <syslog.h> +#include <Kerberos/kipc_server.h> +#include "k5_mig_requestServer.h" +#include "k5_mig_reply.h" + + +/* ------------------------------------------------------------------------ */ + +static boolean_t k5_ipc_request_demux (mach_msg_header_t *request, + mach_msg_header_t *reply) +{ + boolean_t handled = false; + + if (!handled) { + handled = k5_ipc_request_server (request, reply); + } + + if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) { + kern_return_t err = KERN_SUCCESS; + + err = k5_ipc_server_remove_client (request->msgh_local_port); + + if (!err) { + /* Check here for a client in our table and free rights associated with it */ + err = mach_port_mod_refs (mach_task_self (), request->msgh_local_port, + MACH_PORT_RIGHT_RECEIVE, -1); + } + + if (!err) { + handled = 1; /* was a port we are tracking */ + } + } + + return handled; +} + +/* ------------------------------------------------------------------------ */ + +kern_return_t k5_ipc_server_create_client_connection (mach_port_t in_server_port, + mach_port_t *out_connection_port) +{ + kern_return_t err = KERN_SUCCESS; + mach_port_t connection_port = MACH_PORT_NULL; + mach_port_t old_notification_target = MACH_PORT_NULL; + + if (!err) { + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &connection_port); + } + + if (!err) { + err = mach_port_move_member (mach_task_self (), connection_port, kipc_server_get_listen_portset ()); + } + + if (!err) { + /* request no-senders notification so we can tell when client quits/crashes */ + err = mach_port_request_notification (mach_task_self (), connection_port, + MACH_NOTIFY_NO_SENDERS, 1, connection_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_notification_target ); + } + + if (!err) { + err = k5_ipc_server_add_client (connection_port); + } + + if (!err) { + *out_connection_port = connection_port; + connection_port = MACH_PORT_NULL; + } + + if (MACH_PORT_VALID (connection_port)) { mach_port_deallocate (mach_task_self (), connection_port); } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +kern_return_t k5_ipc_server_request (mach_port_t in_connection_port, + mach_port_t in_reply_port, + k5_ipc_inl_request_t in_inl_request, + mach_msg_type_number_t in_inl_requestCnt, + k5_ipc_ool_request_t in_ool_request, + mach_msg_type_number_t in_ool_requestCnt) +{ + kern_return_t err = KERN_SUCCESS; + k5_ipc_stream request_stream = NULL; + + if (!err) { + err = k5_ipc_stream_new (&request_stream); + } + + if (!err) { + if (in_inl_requestCnt) { + err = k5_ipc_stream_write (request_stream, in_inl_request, in_inl_requestCnt); + + } else if (in_ool_requestCnt) { + err = k5_ipc_stream_write (request_stream, in_ool_request, in_ool_requestCnt); + + } else { + err = EINVAL; + } + } + + if (!err) { + err = k5_ipc_server_handle_request (in_connection_port, in_reply_port, request_stream); + } + + k5_ipc_stream_release (request_stream); + if (in_ool_requestCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_request, in_ool_requestCnt); } + + return err; +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_server_initialize (int argc, const char *argv[]) +{ + int32_t err = 0; + + openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); + syslog (LOG_INFO, "Starting up."); + + syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); + + return err; +} + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_server_cleanup (int argc, const char *argv[]) +{ + int32_t err = 0; + + openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); + syslog (LOG_INFO, "Starting up."); + + syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); + + return err; +} + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_server_listen_loop (void) +{ + /* Run the Mach IPC listen loop. + * This will call k5_ipc_server_create_client_connection for new clients + * and k5_ipc_server_request for existing clients */ + + return kipc_server_run_server (k5_ipc_request_demux); +} + +/* ------------------------------------------------------------------------ */ + +int32_t k5_ipc_server_send_reply (mach_port_t in_reply_port, + k5_ipc_stream in_reply_stream) +{ + kern_return_t err = KERN_SUCCESS; + k5_ipc_inl_reply_t inl_reply; + mach_msg_type_number_t inl_reply_length = 0; + k5_ipc_ool_reply_t ool_reply = NULL; + mach_msg_type_number_t ool_reply_length = 0; + + if (!MACH_PORT_VALID (in_reply_port)) { err = EINVAL; } + if (!in_reply_stream ) { err = EINVAL; } + + if (!err) { + /* depending on how big the message is, use the fast inline buffer or + * the slow dynamically allocated buffer */ + mach_msg_type_number_t reply_length = k5_ipc_stream_size (in_reply_stream); + + if (reply_length > K5_IPC_MAX_MSG_SIZE) { + //dprintf ("%s choosing out of line buffer (size is %d)", + // __FUNCTION__, reply_length); + + err = vm_read (mach_task_self (), + (vm_address_t) k5_ipc_stream_data (in_reply_stream), reply_length, + (vm_address_t *) &ool_reply, &ool_reply_length); + + } else { + //cci_debug_printf ("%s choosing in line buffer (size is %d)", + // __FUNCTION__, reply_length); + + inl_reply_length = reply_length; + memcpy (inl_reply, k5_ipc_stream_data (in_reply_stream), reply_length); + } + } + + if (!err) { + err = k5_ipc_server_reply (in_reply_port, + inl_reply, inl_reply_length, + ool_reply, ool_reply_length); + } + + if (!err) { + /* Because we use ",dealloc" ool_reply will be freed by mach. Don't double free it. */ + ool_reply = NULL; + ool_reply_length = 0; + } + + if (ool_reply_length) { vm_deallocate (mach_task_self (), (vm_address_t) ool_reply, ool_reply_length); } + + return err; +} diff --git a/src/util/mac/k5_mig_server.h b/src/util/mac/k5_mig_server.h new file mode 100644 index 000000000..c98d1dc4b --- /dev/null +++ b/src/util/mac/k5_mig_server.h @@ -0,0 +1,53 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef K5_MIG_SERVER +#define K5_MIG_SERVER + +#include "k5-ipc_stream.h" + +/* Defined by caller */ + +int32_t k5_ipc_server_add_client (mach_port_t in_client_port); + +int32_t k5_ipc_server_remove_client (mach_port_t in_client_port); + +int32_t k5_ipc_server_handle_request (mach_port_t in_connection_port, + mach_port_t in_reply_port, + k5_ipc_stream in_request_stream); + +/* Server control functions */ + +int32_t k5_ipc_server_initialize (int argc, const char *argv[]); + +int32_t k5_ipc_server_cleanup (int argc, const char *argv[]); + +int32_t k5_ipc_server_listen_loop (void); + +int32_t k5_ipc_server_send_reply (mach_port_t in_reply_pipe, + k5_ipc_stream in_reply_stream); + +#endif /* K5_MIG_SERVER */ diff --git a/src/util/mac/k5_mig_types.h b/src/util/mac/k5_mig_types.h new file mode 100644 index 000000000..4c8ddb73b --- /dev/null +++ b/src/util/mac/k5_mig_types.h @@ -0,0 +1,55 @@ +/* $Copyright: +* +* Copyright 2004-2006 by the Massachusetts Institute of Technology. +* +* All rights reserved. +* +* Export of this software from the United States of America may require a +* specific license from the United States Government. It is the +* responsibility of any person or organization contemplating export to +* obtain such a license before exporting. +* +* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute +* this software and its documentation for any purpose and without fee is +* hereby granted, provided that the above copyright notice appear in all +* copies and that both that copyright notice and this permission notice +* appear in supporting documentation, and that the name of M.I.T. not be +* used in advertising or publicity pertaining to distribution of the +* software without specific, written prior permission. Furthermore if you +* modify this software you must label your software as modified software +* and not distribute it in such a fashion that it might be confused with +* the original MIT software. M.I.T. makes no representations about the +* suitability of this software for any purpose. It is provided "as is" +* without express or implied warranty. +* +* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +* +* Individual source code files are copyright MIT, Cygnus Support, +* OpenVision, Oracle, Sun Soft, FundsXpress, and others. +* +* Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, +* and Zephyr are trademarks of the Massachusetts Institute of Technology +* (MIT). No commercial use of these trademarks may be made without prior +* written permission of MIT. +* +* "Commercial use" means use of a name in a product or other for-profit +* manner. It does NOT prevent a commercial firm from referring to the MIT +* trademarks in order to convey information (although in doing so, +* recognition of their trademark status should be given). +* $ +*/ + +#ifndef K5_MIG_TYPES_H +#define K5_MIG_TYPES_H + + +#define K5_IPC_MAX_MSG_SIZE 1024 + +typedef const char k5_ipc_inl_request_t[K5_IPC_MAX_MSG_SIZE]; +typedef const char *k5_ipc_ool_request_t; +typedef char k5_ipc_inl_reply_t[K5_IPC_MAX_MSG_SIZE]; +typedef char *k5_ipc_ool_reply_t; + +#endif /* K5_MIG_TYPES_H */ |
