/* * Copyright (c) 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Inc. ("Apple") nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Portions of this software have been released under the following terms: * * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION * * To anyone who acknowledges that this file is provided "AS IS" * without any express or implied warranty: * permission to use, copy, modify, and distribute this file for any * purpose is hereby granted without fee, provided that the above * copyright notices and this notice appears in all source code copies, * and that none of the names of Open Software Foundation, Inc., Hewlett- * Packard Company or Digital Equipment Corporation be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Neither Open Software * Foundation, Inc., Hewlett-Packard Company nor Digital * Equipment Corporation makes any representations about the suitability * of this software for any purpose. * * Copyright (c) 2007, Novell, Inc. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Novell Inc. nor the names of its contributors * may be used to endorse or promote products derived from this * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @APPLE_LICENSE_HEADER_END@ */ /* ** ** NAME: ** ** dghnd.c ** ** FACILITY: ** ** Remote Procedure Call (RPC) ** ** ABSTRACT: ** ** Routines for manipulating Datagram Specific RPC bindings. ** ** */ #include <dg.h> #include <dghnd.h> #include <dgcall.h> #include <dgccall.h> /* ======================================================================== */ /* * R E L E A S E _ C A C H E D _ C C A L L * * Release any client call binding we might have in the binding binding. */ INTERNAL void release_cached_ccall ( rpc_dg_binding_client_p_t /*h*/ ); INTERNAL void release_cached_ccall ( rpc_dg_binding_client_p_t h ) { if (h->ccall == NULL) return; RPC_DG_CALL_LOCK(&h->ccall->c); rpc__dg_ccall_free_prep(h->ccall); RPC_DG_CCALL_RELEASE(&h->ccall); /* unlocks as a side effect */ } /* * R P C _ _ D G _ B I N D I N G _ A L L O C * * Allocate a DG-specific binding rep. */ PRIVATE rpc_binding_rep_p_t rpc__dg_binding_alloc ( boolean32 is_server, unsigned32 *st ) { rpc_binding_rep_p_t h; *st = rpc_s_ok; if (is_server) { RPC_MEM_ALLOC(h, rpc_binding_rep_p_t, sizeof(rpc_dg_binding_server_t), RPC_C_MEM_DG_SHAND, RPC_C_MEM_NOWAIT); } else { RPC_MEM_ALLOC(h, rpc_binding_rep_p_t, sizeof(rpc_dg_binding_client_t), RPC_C_MEM_DG_CHAND, RPC_C_MEM_NOWAIT); } return(h); } /* * R P C _ _ D G _ B I N D I N G _ I N I T * * Initialize the DG-specific part of a client binding binding. */ PRIVATE void rpc__dg_binding_init ( rpc_binding_rep_p_t h_, unsigned32 *st ) { *st = rpc_s_ok; if (RPC_BINDING_IS_SERVER(h_)) { rpc_dg_binding_server_p_t h = (rpc_dg_binding_server_p_t) h_; h->chand = NULL; h->scall = NULL; } else { rpc_dg_binding_client_p_t h = (rpc_dg_binding_client_p_t) h_; h->ccall = NULL; h->server_boot = 0; h->shand = NULL; h->maint_binding = NULL; h->is_WAY_binding = 0; } } /* * R P C _ _ D G _ B I N D I N G _ F R E E * * Free a DG-specific, client-side binding binding. */ PRIVATE void rpc__dg_binding_free ( rpc_binding_rep_p_t *h_, unsigned32 *st ) { /* * The binding and the call binding are public at this point (remember * the call monitor) hence we need to ensure that things remain * orderly. */ RPC_LOCK_ASSERT(0); if ((*h_)->is_server == 0) { release_cached_ccall((rpc_dg_binding_client_p_t) *h_); RPC_MEM_FREE(*h_, RPC_C_MEM_DG_CHAND); } else { RPC_MEM_FREE(*h_, RPC_C_MEM_DG_SHAND); } *h_ = NULL; *st = rpc_s_ok; } /* * R P C _ _ D G _ B I N D I N G _ C H A N G E D * * */ PRIVATE void rpc__dg_binding_changed ( rpc_binding_rep_p_t h, unsigned32 *st ) { RPC_LOCK(0); /* !!! this should really be done in common code */ release_cached_ccall((rpc_dg_binding_client_p_t) h); /* !!! Crude but effective. Sufficient? */ *st = rpc_s_ok; RPC_UNLOCK(0); } /* * R P C _ _ D G _ B I N D I N G _ I N Q _ A D D R * * */ PRIVATE void rpc__dg_binding_inq_addr ( rpc_binding_rep_p_t h ATTRIBUTE_UNUSED, rpc_addr_p_t *addr ATTRIBUTE_UNUSED, unsigned32 *st ATTRIBUTE_UNUSED ) { /* * rpc_m_unimp_call * "(%s) Call not implemented" */ rpc_dce_svc_printf ( __FILE__, __LINE__, "%s", rpc_svc_general, svc_c_sev_fatal | svc_c_action_abort, rpc_m_unimp_call, "rpc__dg_binding_inq_addr" ); } /* * R P C _ _ D G _ B I N D I N G _ R E S E T * * Dissociate the binding from a bound server instance. */ PRIVATE void rpc__dg_binding_reset ( rpc_binding_rep_p_t h_, unsigned32 *st ) { rpc_dg_binding_client_p_t h = (rpc_dg_binding_client_p_t) h_; RPC_LOCK(0); /* !!! this should really be done in common code */ h->server_boot = 0; release_cached_ccall(h); /* Crude but effective */ *st = rpc_s_ok; RPC_UNLOCK(0); } /* * R P C _ _ D G _ B I N D I N G _ C O P Y * * Copy DG private part of a binding. */ PRIVATE void rpc__dg_binding_copy ( rpc_binding_rep_p_t src_h_, rpc_binding_rep_p_t dst_h_, unsigned32 *st ) { rpc_dg_binding_client_p_t src_h = (rpc_dg_binding_client_p_t) src_h_; rpc_dg_binding_client_p_t dst_h = (rpc_dg_binding_client_p_t) dst_h_; RPC_LOCK(0); /* !!! this should really be done in common code */ dst_h->server_boot = src_h->server_boot; dst_h->host_bound = src_h->host_bound; *st = rpc_s_ok; RPC_UNLOCK(0); } /* * R P C _ _ D G _ B I N D I N G _ S E R V E R _ T O _ C L I E N T * * Create a client binding binding suitable for doing callbacks from a * server to a client. The server binding binding of the current call * is used as a template for the new client binding. */ PRIVATE rpc_dg_binding_client_p_t rpc__dg_binding_srvr_to_client ( rpc_dg_binding_server_p_t shand, unsigned32 *st ) { rpc_dg_binding_client_p_t chand; rpc_addr_p_t client_addr; *st = rpc_s_ok; /* * If we've already made a callback on this binding binding, * then use the client binding binding that was previously * created. */ if (shand->chand != NULL) return(shand->chand); /* * Otherwise, allocate a client binding binding and bind it to the * address associated with the server binding binding. */ rpc__naf_addr_copy(shand->c.c.rpc_addr, &client_addr, st); chand = (rpc_dg_binding_client_p_t) rpc__binding_alloc(false, &UUID_NIL, RPC_C_PROTOCOL_ID_NCADG, client_addr, st); if (*st != rpc_s_ok) return(NULL); /* * Link the binding bindings. */ chand->shand = shand; shand->chand = chand; return(chand); } /* * R P C _ _ D G _ B I N D I N G _ C R O S S _ F O R K * * This routine makes it possible for children of forks to use * binding handles inherited from their parents. It does this * by vaporizing any state associated with the handle, so that * the child is forced to rebuild its own state from scratch. */ PRIVATE void rpc__dg_binding_cross_fork ( rpc_binding_rep_p_t h_, unsigned32 *st ) { rpc_dg_binding_client_p_t h = (rpc_dg_binding_client_p_t) h_; *st = rpc_s_ok; /* * Drop any state associated with this handle. This state * survives in the parent of the fork, and will be processed * correctly there. */ h->ccall = NULL; h->shand = NULL; h->maint_binding = NULL; } #if 0 /* **++ ** ** ROUTINE NAME: rpc__cn_binding_cross_fork ** ** SCOPE: PRIVATE - declared in cnbind.h ** ** DESCRIPTION: ** ** This routine makes it possible for children of forks to use ** binding handles inherited from their parents. ** ** INPUTS: ** ** binding_r The binding rep to be inherited ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** st The return status of this routine. ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: ** ** rpc_s_coding_error ** rpc_s_ok ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE void rpc__cn_binding_cross_fork ( rpc_binding_rep_p_t binding_r ATTRIBUTE_UNUSED, unsigned32 *st ) { CODING_ERROR (st); /* * This is a dummy function to avoid the null reference * causing a core dump. */ *st = rpc_s_ok; } #endif