1/*
2 * Copyright (c) 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1.  Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 * 2.  Redistributions in binary form must reproduce the above copyright
13 *     notice, this list of conditions and the following disclaimer in the
14 *     documentation and/or other materials provided with the distribution.
15 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
16 *     contributors may be used to endorse or promote products derived from
17 *     this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Portions of this software have been released under the following terms:
31 *
32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
35 *
36 * To anyone who acknowledges that this file is provided "AS IS"
37 * without any express or implied warranty:
38 * permission to use, copy, modify, and distribute this file for any
39 * purpose is hereby granted without fee, provided that the above
40 * copyright notices and this notice appears in all source code copies,
41 * and that none of the names of Open Software Foundation, Inc., Hewlett-
42 * Packard Company or Digital Equipment Corporation be used
43 * in advertising or publicity pertaining to distribution of the software
44 * without specific, written prior permission.  Neither Open Software
45 * Foundation, Inc., Hewlett-Packard Company nor Digital
46 * Equipment Corporation makes any representations about the suitability
47 * of this software for any purpose.
48 *
49 * Copyright (c) 2007, Novell, Inc. All rights reserved.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 *
54 * 1.  Redistributions of source code must retain the above copyright
55 *     notice, this list of conditions and the following disclaimer.
56 * 2.  Redistributions in binary form must reproduce the above copyright
57 *     notice, this list of conditions and the following disclaimer in the
58 *     documentation and/or other materials provided with the distribution.
59 * 3.  Neither the name of Novell Inc. nor the names of its contributors
60 *     may be used to endorse or promote products derived from this
61 *     this software without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 *
74 * @APPLE_LICENSE_HEADER_END@
75 */
76
77/*
78**
79**  NAME
80**
81**      cninit.c
82**
83**  FACILITY:
84**
85**      Remote Procedure Call (RPC)
86**
87**  ABSTRACT:
88**
89**  The NCA Connection Protocol Initialization Service.
90**
91**
92*/
93
94#include <commonp.h>    /* Common declarations for all RPC runtime */
95#include <com.h>        /* Common communications services */
96#include <comprot.h>    /* Common protocol services */
97#include <cnp.h>        /* NCA connection private declarations */
98#include <cncall.h>     /* NCA connection call service */
99#include <cnid.h>       /* NCA Connection local ID service */
100#include <cnbind.h>     /* NCA connection binding service */
101#include <cnmgmt.h>     /* NCA connection management service */
102#include <cnnet.h>      /* NCA connection network service */
103#include <cnfbuf.h>     /* NCA connection fragment buffer service */
104#include <cnpkt.h>	/* NCA connection packet layout */
105#include <cnassoc.h>    /* NCA connection association service */
106
107void rpc__cn_minute_system_time (void);
108void rpc__cn_init_func(void);
109
110/*
111 * INTERNAL variables.
112 */
113
114INTERNAL rpc_prot_call_epv_t cn_call_epv =
115{
116    .call_start =               rpc__cn_call_start,
117    .call_transmit =            rpc__cn_call_transmit,
118    .call_transceive =          rpc__cn_call_transceive,
119    .call_receive =             rpc__cn_call_receive,
120    .call_end =                 rpc__cn_call_end,
121    .call_block_until_free =    rpc__cn_call_block_until_free,
122    .call_transmit_fault =      rpc__cn_call_transmit_fault,
123    .call_cancel =              rpc__cn_call_alert,
124    .call_receive_fault =       rpc__cn_call_receive_fault,
125    .call_did_mgr_execute =     rpc__cn_call_did_mgr_execute
126};
127
128INTERNAL rpc_prot_mgmt_epv_t cn_mgmt_epv =
129{
130    .mgmt_inq_calls_sent =  rpc__cn_mgmt_inq_calls_sent,
131    .mgmt_inq_calls_rcvd =  rpc__cn_mgmt_inq_calls_rcvd,
132    .mgmt_inq_pkts_sent =   rpc__cn_mgmt_inq_pkts_sent,
133    .mgmt_inq_pkts_rcvd =   rpc__cn_mgmt_inq_pkts_rcvd,
134};
135
136INTERNAL rpc_prot_binding_epv_t cn_binding_epv =
137{
138    .binding_alloc =        rpc__cn_binding_alloc,
139    .binding_init =         rpc__cn_binding_init,
140    .binding_reset =        rpc__cn_binding_reset,
141    .binding_changed =      rpc__cn_binding_changed,
142    .binding_free =         rpc__cn_binding_free,
143    .binding_inq_addr =     rpc__cn_binding_inq_addr,
144    .binding_inq_client =   rpc__cn_binding_inq_client,
145    .binding_copy =         rpc__cn_binding_copy,
146    .binding_cross_fork =   rpc__cn_binding_cross_fork
147};
148
149INTERNAL rpc_prot_network_epv_t cn_network_epv =
150{
151    .network_use_socket =       rpc__cn_network_use_socket,
152    .network_use_protseq =      rpc__cn_network_use_protseq,
153    .network_mon =              rpc__cn_network_mon,
154    .network_stop_mon =         rpc__cn_network_stop_mon,
155    .network_maint =            rpc__cn_network_maint,
156    .network_stop_maint =       rpc__cn_network_stop_maint,
157    .network_select_disp =      rpc__cn_network_select_dispatch,
158    .network_inq_prot_vers =    rpc__cn_network_inq_prot_vers,
159    .network_close =            rpc__cn_network_close,
160    .network_getpeereid =       rpc__cn_network_getpeereid
161};
162
163/***********************************************************************/
164
165
166#include <comp.h>
167void rpc__cn_init_func(void)
168{
169	static rpc_protocol_id_elt_t prot[1] = {
170		{
171			rpc__ncacn_init,                /* Connection-RPC */
172			NULL,
173			RPC_C_PROTOCOL_ID_NCACN,
174			NULL, NULL, NULL, NULL
175		}
176	};
177	rpc__register_protocol_id(prot, 1);
178}
179
180/*
181**++
182**
183**  ROUTINE NAME:       rpc__ncacn_init
184**
185**  SCOPE:              PRIVATE - declared in comprot.h
186**
187**  DESCRIPTION:
188**
189**  This routine will handle one-time initialization for the NCA
190**  Connection Protocol Service. It will also return the Entry Point
191**  Vectors which comprise the external interface to the NCA
192**  Connection Protocol Service.
193**
194**  INPUTS:             none
195**
196**  INPUTS/OUTPUTS:
197**
198**      call_epv        The Call Service interface.
199**      mgmt_epv        The Manangement Service interface.
200**      binding_epv     The Binding Service interface.
201**      network_epv     The Network Service interface.
202**      fork_handler    The fork handler routine.
203**
204**  OUTPUTS:
205**
206**      st              The return status of this routine.
207**
208**  IMPLICIT INPUTS:    none
209**
210**  IMPLICIT OUTPUTS:   none
211**
212**  FUNCTION VALUE:
213**
214**      rpc_s_coding_error
215**      rpc_s_ok
216**
217**  SIDE EFFECTS:       none
218**
219**--
220**/
221
222void rpc__ncacn_init
223(
224    rpc_prot_call_epv_p_t           *call_epv,
225    rpc_prot_mgmt_epv_p_t           *mgmt_epv,
226    rpc_prot_binding_epv_p_t        *binding_epv,
227    rpc_prot_network_epv_p_t        *network_epv,
228    rpc_prot_fork_handler_fn_t      *fork_handler,
229    unsigned32                      *st
230)
231{
232
233    CODING_ERROR (st);
234
235    /*
236     * Initialize the management counters.
237     */
238    rpc__cn_mgmt_init ();
239
240    /*
241     * Initialize the CN lookaside list condition variable.
242     */
243    RPC_COND_INIT (rpc_g_cn_lookaside_cond,
244                   rpc_g_global_mutex);
245
246    /*
247     * Initialize the global sequence number cell.
248     */
249    rpc__cn_init_seqnum ();
250
251    /*
252     * Initialize the global call_id cell.
253     */
254    rpc_g_cn_call_id = 0;
255
256    /*
257     * Initialize the call rep lookaside list.
258     */
259    rpc__list_desc_init (&rpc_g_cn_call_lookaside_list,
260                         RPC_C_CN_CALL_LOOKASIDE_MAX,
261                         sizeof (rpc_cn_call_rep_t),
262                         RPC_C_MEM_CN_CALL_REP,
263                         (rpc_list_element_alloc_fn_t) rpc__cn_call_ccb_create,
264                         (rpc_list_element_alloc_fn_t) rpc__cn_call_ccb_free,
265                         &rpc_g_global_mutex,
266                         &rpc_g_cn_lookaside_cond);
267    /*
268     * Initialize binding_rep lookaside list.
269     */
270    rpc__list_desc_init (&rpc_g_cn_binding_lookaside_list,
271                         RPC_C_CN_BINDING_LOOKASIDE_MAX,
272                         sizeof (rpc_cn_binding_rep_t),
273                         RPC_C_MEM_CN_BINDING_REP,
274                         NULL,
275                         NULL,
276                         &rpc_g_global_mutex,
277                         &rpc_g_cn_lookaside_cond);
278    /*
279     * Initialize fragment buffer lookaside lists. Note that 7 extra
280     * bytes will be allocated per structure. This is so that we can
281     * adjust the data pointer to be on an 8 byte boundary and still
282     * have the same size data area. Note that the CN global mutex
283     * cannot be used to protect the large fragbuf lookaside list,
284     * hence the NULL input args for mutex and cond to
285     * rpc__list_desc_init. This is because large fragbufs are given
286     * to stubs which indirectly call the fragbuf free routine which
287     * calls the list free routine. Since this fragbuf free routine is
288     * also called internally, where the CN global mutex is held,
289     * it would be difficult to determine whether the CN global mutex
290     * needed to be acquired in the fragbuf free routine.
291     */
292    rpc__list_desc_init (&rpc_g_cn_lg_fbuf_lookaside_list,
293                         RPC_C_CN_FRAGBUF_LOOKASIDE_MAX,
294                         RPC_C_CN_LG_FRAGBUF_ALLOC_SIZE + 7,
295                         RPC_C_MEM_CN_LG_FRAGBUF,
296                         NULL,
297                         NULL,
298                         NULL,
299                         NULL);
300    rpc__list_desc_init (&rpc_g_cn_sm_fbuf_lookaside_list,
301                         RPC_C_CN_FRAGBUF_LOOKASIDE_MAX,
302                         RPC_C_CN_SM_FRAGBUF_ALLOC_SIZE + 7,
303                         RPC_C_MEM_CN_SM_FRAGBUF,
304                         NULL,
305                         NULL,
306                         &rpc_g_global_mutex,
307                         &rpc_g_cn_lookaside_cond);
308    /*
309     * Initialize the association control block lookaside list.
310     */
311    rpc__list_desc_init (&rpc_g_cn_assoc_lookaside_list,
312                         RPC_C_CN_ASSOC_LOOKASIDE_MAX,
313                         sizeof(rpc_cn_assoc_t),
314                         RPC_C_MEM_CN_ASSOC,
315                         (rpc_list_element_alloc_fn_t) rpc__cn_assoc_acb_create,
316                         (rpc_list_element_alloc_fn_t) rpc__cn_assoc_acb_free,
317                         &rpc_g_global_mutex,
318                         &rpc_g_cn_lookaside_cond);
319    /*
320     * Initialize the association syntax element lookaside list.
321     */
322    rpc__list_desc_init (&rpc_g_cn_syntax_lookaside_list,
323                         RPC_C_CN_SYNTAX_LOOKASIDE_MAX,
324                         sizeof(rpc_cn_syntax_t),
325                         RPC_C_MEM_CN_SYNTAX,
326                         NULL,
327                         NULL,
328                         &rpc_g_global_mutex,
329                         &rpc_g_cn_lookaside_cond);
330    /*
331     * Initialize the association security context element lookaside list.
332     */
333    rpc__list_desc_init (&rpc_g_cn_sec_lookaside_list,
334                         RPC_C_CN_SEC_LOOKASIDE_MAX,
335                         sizeof(rpc_cn_sec_context_t),
336                         RPC_C_MEM_CN_SEC_CONTEXT,
337                         NULL,
338                         NULL,
339                         &rpc_g_global_mutex,
340                         &rpc_g_cn_lookaside_cond);
341
342    /*
343     * Initialize the association group table.
344     */
345    rpc__cn_assoc_grp_tbl_init ();
346
347    /*
348     * Return the interface to the NCA Connection Protocol Service in the four
349     * EPVs.
350     */
351    *call_epv = &cn_call_epv;
352    *mgmt_epv = &cn_mgmt_epv;
353    *binding_epv = &cn_binding_epv;
354    *network_epv = &cn_network_epv;
355
356    if (RPC_DBG(rpc_es_dbg_stats, 5))
357    {
358        atexit (rpc__cn_stats_print);
359    }
360
361    *fork_handler = NULL;
362    *st = rpc_s_ok;
363}
364