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**      cnp.h
82**
83**  FACILITY:
84**
85**      Remote Procedure Call (RPC)
86**
87**  ABSTRACT:
88**
89**  Definitions of types/constants internal to NCA Connection RPC
90**  Protocol Service and common to all its components.
91**
92**
93*/
94
95#ifndef _CNP_H
96#define _CNP_H	1
97
98#include <cn.h>
99
100/*
101 * CN internal status codes. These will not be passed out of CN.
102 *	RPC_C_CN_STATEBASE:  determines base value for the state
103 *			     and this value is used to quickly determine
104 *			     by the state evaluation routine, whether a
105 *			     value is a state or action.
106 */
107#define RPC_S_HEADER_FULL               0x0001beef
108#define RPC_C_CN_STATEBASE 		100
109/*
110 * Macros for serializing access to the connection protocol code.
111 */
112#define RPC_CN_LOCK()                   RPC_LOCK(0)
113#define RPC_CN_UNLOCK()                 RPC_UNLOCK(0)
114#define RPC_CN_LOCK_ASSERT()            RPC_LOCK_ASSERT(0)
115
116/*
117 * rpc_e_dbg_general debug switch levels
118 */
119#define RPC_C_CN_DBG_ROUTINE_TRACE      20
120#define RPC_C_CN_DBG_THREADS            2       /* exact */
121#define RPC_C_CN_DBG_ERRORS             1
122#define RPC_C_CN_DBG_BUFFS              1
123#define RPC_C_CN_DBG_GENERAL            1
124#define RPC_C_CN_DBG_SECURITY_ERRORS    1
125
126/*
127 * rpc_e_dbg_cn_state debug switch levels
128 */
129#define RPC_C_CN_DBG_ASSOC_SM_TRACE     3
130#define RPC_C_CN_DBG_ASSOC_GRP_SM_TRACE 2
131#define RPC_C_CN_DBG_CALL_SM_TRACE      1
132
133/*
134 * rpc_e_dbg_orphan debug switch levels
135 */
136#define RPC_C_CN_DBG_ORPHAN             1
137
138/*
139 * rpc_e_dbg_cancel debug switch levels
140 */
141#define RPC_C_CN_DBG_CANCEL             1
142
143/*
144 * rpc_e_dbg_cn_pkt debug switch levels
145 */
146#define RPC_C_CN_DBG_PKT_DUMP           20
147#define RPC_C_CN_DBG_PKT                1
148
149/*
150 * rpc_e_dbg_cn_errors debug switch levels
151 *
152 * Switches to set on server to generate bind NAKs and a status code used only
153 * when one of the error debug levels are set.
154 */
155#define RPC_S_CN_DBG_FAILURE            0xdeadbeefU
156#define RPC_C_CN_DBG_PROT_VERS_MISMATCH 1 /* server: force a mismatch */
157#define RPC_C_CN_DBG_GRP_LKUP_BY_ID     2 /* server: make lkup fail  */
158                                          /* (>1 assoc on group) */
159                                          /* Must be more than 1 */
160                                          /* client thread making */
161                                          /* call on group. */
162#define RPC_C_CN_DBG_GRP_ALLOC          3 /* server: make alloc fail */
163#define RPC_C_CN_DBG_HEADER_FULL        4 /* server: make bind ACK too big */
164                                          /* for large fragbuf */
165#define RPC_C_CN_DBG_GRP_MAX_EXCEEDED   5 /* server: set grp_cur_assoc = */
166                                          /* grp_max_assoc */
167                                          /* (>1 assoc on group) */
168                                          /* Must be more than 1 */
169                                          /* client thread making */
170                                          /* call on group. */
171/*
172 * Switches to set on server to generate bind ACKs with various
173 * pprov reason codes.
174 */
175#define RPC_C_CN_DBG_IF_LOOKUP          6 /* server: cause the abstract */
176                                          /* syntax to not be found */
177#define RPC_C_CN_DBG_NO_XFER_SYNTAX     7 /* server: cause no matching xfer */
178                                          /* syntax to be found */
179
180/*
181 * Various other switches to force errors.
182 */
183#define RPC_C_CN_DBG_SEC_ALLOC_FAIL     8 /* cause the sec_alloc to */
184                                          /* fail */
185#define RPC_C_CN_DBG_ASSOC_REQ_FAIL     9 /* cause the association */
186                                          /* request eval event to */
187                                          /* fail */
188
189/*
190 * Error switches to force packet fragmentation.
191 */
192#define RPC_C_CN_DBG_FRAG_BIND		10 /* bind (and alter_ctx) fragment */
193#define RPC_C_CN_DBG_FRAG_BIND_ACK	11 /* bind_ack (and alter_ctx_resp)
194                                              fragment */
195
196#define RPC_CN_DBG_RTN_PRINTF(s) RPC_DBG_PRINTF(rpc_e_dbg_general, \
197                                                RPC_C_CN_DBG_ROUTINE_TRACE,\
198                                                ("(" #s ")\n"))
199
200
201/***********************************************************************/
202/*
203 * R P C _ C N _ M G M T _ T
204 */
205#include <cnpkt.h>
206typedef struct
207{
208    unsigned32          calls_sent;
209    unsigned32          calls_rcvd;
210    unsigned32          pkts_sent;
211    unsigned32          pkts_rcvd;
212    unsigned32          connections;
213    unsigned32          closed_connections;
214    unsigned32          alloced_assocs;
215    unsigned32          dealloced_assocs;
216    unsigned32          aborted_assocs;
217    unsigned32          assoc_grps;
218    struct cn_pkt_stats_t              /* Breakdown of pkts sent/rcvd by pkt type */
219    {
220        unsigned32 sent;
221        unsigned32 rcvd;
222    } pstats[RPC_C_CN_PKT_MAX_TYPE + 1];
223} rpc_cn_mgmt_t, *rpc_cn_mgmt_p_t;
224#define RPC_CN_STATS_INCR(s) (rpc_g_cn_mgmt.s++)
225
226/***********************************************************************/
227/*
228 * R P C _ C N _ S M _ P R E D _ R E S U L T _ T
229 */
230
231#define RPC_C_SM_NO_PREDICATE           255
232#define RPC_C_SM_NO_ACTION              255
233#define RPC_C_SM_NO_NSTATE              255
234
235/*
236 * Returning the current error status can be accomplished by
237 * taking no action.  The generic state machine evaluator will
238 * automatically return the status of the last action routine
239 * invoked.
240 */
241#define RPC_C_SM_RETURN_ERROR_STATUS RPC_C_SM_NO_ACTION
242
243typedef struct
244{
245    unsigned8                           nstate;
246    unsigned8                           action;
247} rpc_cn_sm_pred_result_t, *rpc_cn_sm_pred_result_p_t;
248
249/***********************************************************************/
250/*
251 * R P C _ C N _ S M _ S T A T E _ E N T R Y _ T
252 */
253
254#define RPC_C_NUM_PREDICATES 	3
255
256/*
257 * The rpc_cn_sm_state_entry_t can contain either the action
258 * or the next state.  If both are required, then we include the
259 * action, which updates the next state internally.  Distinguish
260 * between actions and states by numeric value.  States will
261 * be some value (usually 0 -> 14) + rpc_c_cn_statebase.
262 */
263typedef struct
264{
265    unsigned8                           action;
266} rpc_cn_sm_state_entry_t, *rpc_cn_sm_state_entry_p_t;
267
268#define ILLEGAL_TRANSITION \
269    { PROTOCOL_ERROR }
270
271#define ILLEGAL_PREDICATE_RESULT \
272    { RPC_C_SM_NO_NSTATE, \
273      PROTOCOL_ERROR }
274
275/*
276 * R P C _ C N _ S M _ S T A T E _ T B L _ E N T R Y _ T
277 */
278
279typedef rpc_cn_sm_state_entry_t         rpc_cn_sm_state_tbl_entry_t[];
280
281/*
282 * R P C _ C N _ S M _ A C T I O N _ F N _ T
283 */
284
285typedef unsigned32     (*rpc_cn_sm_action_fn_t) (
286    dce_pointer_t   /*spc_struct*/,
287    dce_pointer_t   /*event_parameter*/,
288    dce_pointer_t   /*sm*/);
289
290typedef rpc_cn_sm_action_fn_t      *rpc_cn_sm_action_fn_p_t;
291
292/*
293 * R P C _ C N _ S M _ P R E D I C A T E _ F N _ T
294 */
295
296typedef unsigned8 (*rpc_cn_sm_predicate_fn_t) (
297    dce_pointer_t   /*spc_struct*/,
298    dce_pointer_t   /*event_parameter*/);
299
300typedef rpc_cn_sm_predicate_fn_t   *rpc_cn_sm_predicate_fn_p_t;
301
302/*
303 * R P C _ C N _ S M _ E V E N T _ E N T R Y _ T
304 */
305
306typedef struct
307{
308    unsigned8                           event_id;
309    dce_pointer_t                           event_param;
310} rpc_cn_sm_event_entry_t, *rpc_cn_sm_event_entry_p_t;
311
312/*
313 * R P C _ C N _ S M _ E V E N T _ L I S T _ T
314 */
315
316#define RPC_C_CN_SM_EVENT_LIST_MAX_ENTRIES 2
317typedef rpc_cn_sm_event_entry_t
318        rpc_cn_sm_event_list_t [ RPC_C_CN_SM_EVENT_LIST_MAX_ENTRIES ];
319
320/*
321 * R P C _ C N _ S M _ C T L B L K _ T
322 */
323/*
324 * State values are incremented by 100 to distinguish them from
325 * action routine indexes which are all < 100.  This was done as
326 * an efficiency measure to the engine, rpc__cn_sm_eval_event().
327 */
328
329/*
330 * Performance Table ID defines
331 */
332#define       rpc_c_cn_svr_assoc   1  /* server association tbl */
333#define       rpc_c_cn_cl_assoc    2  /* client association tbl */
334#define       rpc_c_cn_svr_call    3  /* server call rep tbl */
335#define       rpc_c_cn_cl_call     4  /* client call rep tbl */
336#define       rpc_c_cn_svr_a_g     5  /* server assoc group tbl */
337#define       rpc_c_cn_cl_a_g	   6  /* client assoc group tbl */
338
339typedef struct
340{
341    rpc_cn_sm_state_entry_p_t           *state_tbl;
342    rpc_cn_sm_action_fn_t               *action_tbl;
343#define RPC_C_SM_CLOSED_STATE           100
344    unsigned8                           cur_state;
345    unsigned8                           cur_event;
346    unsigned32                          action_status;
347    unsigned8                           event_list_hindex;
348    unsigned8                           event_list_tindex;
349#define RPC_C_CN_SM_EVENT_LIST_EMPTY       0
350    unsigned8                           event_list_state;
351    rpc_cn_sm_event_list_t              event_list;
352    unsigned32				tbl_id;
353} rpc_cn_sm_ctlblk_t, *rpc_cn_sm_ctlblk_p_t;
354
355/***********************************************************************/
356
357/*
358 * R P C _ C N _ F R A G B U F _ T
359 */
360
361#define RPC_C_CN_OVERHEAD_SIZE          4
362
363typedef struct rpc_cn_fragbuf_s_t rpc_cn_fragbuf_t, *rpc_cn_fragbuf_p_t;
364typedef void (*rpc_cn_fragbuf_dealloc_fn_t) (rpc_cn_fragbuf_t *);
365
366struct rpc_cn_fragbuf_s_t
367{
368    rpc_list_t                  link;   /* MUST BE 1ST */
369    unsigned32                  max_data_size;
370    rpc_cn_fragbuf_dealloc_fn_t fragbuf_dealloc;
371    dce_pointer_t                   data_p;
372    unsigned32                  data_size;
373    unsigned8                   overhead_area[RPC_C_CN_OVERHEAD_SIZE];
374    unsigned8                   data_area[1];
375};
376
377/***********************************************************************/
378
379/*
380 * R P C _ CN _ L O C A L _ I D _ T
381 */
382
383typedef struct
384{
385    unsigned16                          id_seqnum;
386    unsigned16                          id_index;
387} rpc_cn_local_id_parts_t, *rpc_cn_local_id_parts_p_t;
388
389typedef union
390{
391    unsigned32                          all;
392    rpc_cn_local_id_parts_t             parts;
393} rpc_cn_local_id_t, *rpc_cn_local_id_p_t;
394
395/*
396 * R P C _ C N _ B I N D I N G _ R E P _ T
397 */
398
399typedef struct
400{
401    rpc_binding_rep_t                   common;
402    rpc_cn_local_id_t                   grp_id;
403    boolean                             being_resolved;
404    dcethread*                          resolving_thread_id;
405} rpc_cn_binding_rep_t, *rpc_cn_binding_rep_p_t;
406
407/*
408 * R P C _ C N _ C A L L _ R E P _ T
409 */
410
411typedef struct
412{
413    rpc_iovector_t                      iov;
414    rpc_iovector_elt_t                  iov_elmts[ RPC_C_MAX_IOVEC_LEN - 1];
415    unsigned32                          total_acc_byte_count;
416    unsigned32                          cur_iov_index;
417    unsigned32                          num_free_bytes;
418    byte_p_t                            free_byte_ptr;
419    unsigned32                          size_of_header;
420    unsigned32                          trailer_pad;
421} rpc_cn_buffered_output_t, *rpc_cn_buffered_output_p_t;
422
423/*
424 * Client cancel state information
425 *
426 * server_is_accepting : used to indicate when the first fragment
427 *                       has been sent.
428 * local_count         : # of cancels detected locally but not
429 *                       forwarded yet. These may be forwarded
430 *                       by setting the PFC_PENDING_ALERT bit in
431 *                       the first fragment of a request.
432 * server_count        : # of cancels detected and forwarded
433 *                       locally *not* including the PFC_PENDING_ALERT
434 *                       bit in the first fragment of a request.
435 * server_had_pending  : indicates whether the server completed
436 *                       with a pending alert. If so the alert
437 *                       should be re-generated before returning
438 *                       to the client stub
439 */
440typedef struct rpc_cn_cancel_info_s_t
441{
442    unsigned16                          local_count;
443    unsigned16                          server_count;
444    rpc_clock_t                         timeout_time;
445    rpc_timer_t                         timer;
446    unsigned                            timer_running: 1;
447    unsigned                            server_is_accepting: 1;
448    unsigned                            server_had_pending: 1;
449    dcethread*                          thread_h;
450} rpc_cn_cancel_info_t, *rpc_cn_cancel_info_p_t;
451
452typedef struct rpc_cn_call_rep_s_t
453{
454    rpc_call_rep_t                      common;
455    rpc_cn_sm_ctlblk_t                  call_state;
456    unsigned32                          cn_call_status;
457    rpc_binding_rep_t                   *binding_rep;
458    struct rpc_cn_assoc_s_t             *assoc;
459    rpc_cn_fragbuf_t                    *prot_header;
460    rpc_cn_fragbuf_t                    *prot_tlr;
461    unsigned32                          max_seg_size;
462    unsigned32                          alloc_hint;
463    rpc_cn_buffered_output_t            buffered_output;
464    unsigned16                          context_id;
465    unsigned16                          num_pkts;
466    rpc_transfer_syntax_t               transfer_syntax;
467    unsigned16                          opnum;
468    unsigned                            last_frag_received: 1;
469    unsigned                            call_executed: 1;
470    rpc_cn_sec_context_t                *sec;
471    union
472    {
473        struct
474        {
475            rpc_cn_fragbuf_t            *fault_data;
476            rpc_cn_cancel_info_t        cancel;
477        } client;
478        struct
479        {
480            idl_uuid_t                      *if_id;
481            unsigned32                  if_vers;
482            unsigned16                  ihint;
483            struct
484            {
485                unsigned16              local_count; /* common cancel count */
486                                                     /* less pending */
487                                                     /* alert bit cancel */
488            } cancel;
489        } server;
490    } u;
491} rpc_cn_call_rep_t, *rpc_cn_call_rep_p_t;
492
493#define RPC_CN_CREP_SEND_HDR(cp) \
494    (((rpc_cn_fragbuf_p_t)((cp)->prot_header))->data_p)
495#define RPC_CN_CREP_ACC_BYTCNT(cp) \
496    (((cp)->buffered_output).total_acc_byte_count)
497#define RPC_CN_CREP_IOV(cp)                (((cp)->buffered_output).iov.elt)
498#define RPC_CN_CREP_IOVLEN(cp)             (((cp)->buffered_output).iov.num_elt)
499#define RPC_CN_CREP_CUR_IOV_INDX(cp)       (((cp)->buffered_output).cur_iov_index)
500#define RPC_CN_CREP_FREE_BYTES(cp)         (((cp)->buffered_output).num_free_bytes)
501#define RPC_CN_CREP_FREE_BYTE_PTR(cp)      (((cp)->buffered_output).free_byte_ptr)
502#define RPC_CN_CREP_SIZEOF_HDR(cp)         (((cp)->buffered_output).size_of_header)
503#define RPC_CN_CREP_SIZEOF_TLR_PAD(cp)     (((cp)->buffered_output).trailer_pad)
504
505/*
506 * R P C _ C N _ C R E P _ A D J _ F O R _ T L R
507 *
508 * This macro will adjust all the appriate field in the call rep
509 * "buffered_output" structure so that an authentication trailer can
510 * be added to the packet. Note that the size of the trailer will be
511 * rounded up to the nearest 8-byte boundary. This is so that any user
512 * data placed in the PDU will also be a multiple of 8-bytes. This
513 * rounding will be removed before the packet is sent.
514 */
515#define RPC_CN_CREP_ADJ_IOV_FOR_TLR(cp, header_p, auth_value_len)\
516{\
517    (cp)->prot_tlr->data_size = \
518    ((auth_value_len + RPC_CN_PKT_SIZEOF_COM_AUTH_TLR + 7) & ~0x07);\
519    RPC_CN_CREP_SIZEOF_TLR_PAD (cp) =\
520       (cp)->prot_tlr->data_size - \
521       auth_value_len - \
522       RPC_CN_PKT_SIZEOF_COM_AUTH_TLR; \
523    RPC_CN_CREP_SIZEOF_HDR (cp) += (cp)->prot_tlr->data_size;\
524    RPC_CN_CREP_FREE_BYTES (cp) -= (cp)->prot_tlr->data_size;\
525    RPC_CN_CREP_ACC_BYTCNT (cp) += (cp)->prot_tlr->data_size;\
526    RPC_CN_CREP_IOVLEN (cp)++;\
527    RPC_CN_PKT_AUTH_LEN (header_p) = auth_value_len;\
528    /*\
529     * Add the size of the auth trailer (plus padding to\
530     * make it an 8-byte multiple to the data length of the\
531     * protocol header iovector element. This is so that the\
532     * trailer length will be taken into account when adding\
533     * user data to the packet. It will be subtracted when the\
534     * actual trailer is added to the packet in\
535     * rpc__cn_transmit_buffers.\
536     */\
537    (RPC_CN_CREP_IOV (cp)[0]).data_len = RPC_CN_CREP_SIZEOF_HDR (cp);\
538}
539
540
541/***********************************************************************/
542/*
543 * R P C _ C N _ A S S O C _ G R P _ T B L _ T
544 */
545
546typedef struct
547{
548    unsigned16                          grp_count;
549    unsigned16                          grp_active_count;
550    rpc_timer_t                         grp_client_timer;
551    rpc_timer_t                         grp_server_timer;
552    struct rpc_cn_assoc_grp_s_t         *assoc_grp_vector;
553} rpc_cn_assoc_grp_tbl_t, *rpc_cn_assoc_grp_tbl_p_t;
554
555/*
556 * R P C _ C N _ S Y N T A X _ T
557 */
558
559typedef void    (*rpc_cn_marshal_fn_t) (void);
560
561typedef struct rpc_cn_syntax_s_t
562{
563    rpc_list_t                          link;   /* MUST BE 1ST */
564    rpc_syntax_id_t                     syntax_abstract_id;
565    rpc_syntax_id_t                     syntax_transfer_id;
566    unsigned16                          syntax_pres_id;
567    unsigned16                          syntax_vector_index;
568    rpc_syntax_vector_t                 *syntax_vector;
569    rpc_cn_marshal_fn_t                 *syntax_epv;
570    unsigned16                          syntax_ihint;
571    unsigned                            syntax_valid: 1;
572    unsigned32                          syntax_status;
573    unsigned32                          syntax_call_id;
574} rpc_cn_syntax_t, *rpc_cn_syntax_p_t;
575
576
577/***********************************************************************/
578/*
579 * R P C _ A S S O C _ S M _ W O R K _ T
580 *
581 * This structure is used to hold various pieces of information
582 * which are needed by action routines in the association state
583 * machine.
584 */
585typedef struct
586{
587    unsigned32                  grp_id;
588    rpc_cn_syntax_t             *pres_context;
589    boolean                     reuse_context;
590    rpc_cn_sec_context_t        *sec_context;
591} rpc_cn_assoc_sm_work_t, *rpc_cn_assoc_sm_work_p_t;
592
593/*
594 * R P C _ C N _ A S S O C _ G R P _ T
595 */
596
597#define RPC_C_CN_ASSOC_GRP_CLIENT       1
598#define RPC_C_CN_ASSOC_GRP_SERVER       2
599
600typedef struct rpc_cn_assoc_grp_s_t
601{
602    rpc_cn_sm_ctlblk_t                  grp_state;
603    unsigned32                          grp_status;
604    unsigned16                          grp_flags;
605    unsigned16                          grp_refcnt;
606    rpc_addr_p_t                        grp_address;
607    rpc_addr_p_t                        grp_secaddr;
608    rpc_transport_info_p_t              grp_transport_info;
609    rpc_cn_local_id_t                   grp_id;
610    unsigned16                          grp_max_assoc;
611    unsigned16                          grp_cur_assoc;
612    unsigned16                          grp_assoc_waiters;
613    rpc_cond_t                          grp_assoc_wt;
614    rpc_list_t                          grp_assoc_list;
615    unsigned16                          grp_callcnt;
616    rpc_network_rundown_fn_t            grp_liveness_mntr;
617    rpc_cn_local_id_t                   grp_remid;
618    unsigned32                          grp_next_key_id;
619} rpc_cn_assoc_grp_t, *rpc_cn_assoc_grp_p_t;
620
621/*
622 * R P C _ C N _ C T L B L K _ T
623 */
624
625typedef struct
626{
627    unsigned16 volatile                 cn_state;
628    unsigned16 volatile                 cn_rcvr_waiters;
629    rpc_mutex_t                         cn_rcvr_mutex; /* unused so far */
630    rpc_cond_t                          cn_rcvr_cond;
631    dcethread*                          cn_rcvr_thread_id;
632    unsigned_char_t                     *cn_listening_endpoint;
633    rpc_socket_t volatile               cn_sock;
634    rpc_addr_p_t                        rpc_addr;
635    unsigned volatile                   exit_rcvr : 1;
636    unsigned volatile                   in_sendmsg : 1;
637    unsigned volatile                   waiting_for_sendmsg_complete : 1;
638} rpc_cn_ctlblk_t, *rpc_cn_ctlblk_p_t;
639
640#define RPC_CN_ASSOC_LOCK(__assoc)	RPC_MUTEX_LOCK((__assoc)->cn_ctlblk.cn_rcvr_mutex)
641#define RPC_CN_ASSOC_UNLOCK(__assoc)	RPC_MUTEX_UNLOCK((__assoc)->cn_ctlblk.cn_rcvr_mutex)
642
643/*
644 * R P C _ C N _ A S S O C _ T
645 */
646
647#define RPC_C_CN_ASSOC_CLIENT                   0x00000001
648#define RPC_C_CN_ASSOC_SERVER                   0x00000002
649#define RPC_C_CN_ASSOC_SHUTDOWN_REQUESTED       0x00000004
650#define RPC_C_CN_ASSOC_SCANNED                  0x00000008
651#define RPC_C_CN_ASSOC_AUTH_EXPECTED            0x00000010
652
653struct rpc_cn_assoc_s_t
654{
655    rpc_list_t                          link;   /* MUST BE 1ST */
656    rpc_cn_sm_ctlblk_t                  assoc_state;
657    unsigned32                          assoc_status;
658    unsigned32                          assoc_local_status;
659    unsigned16                          assoc_flags;
660    unsigned16                          assoc_ref_count;
661    unsigned16                          assoc_acb_ref_count;
662#define RPC_C_CN_ASSOC_SERVER_MAX_SHUTDOWN_REQ_COUNT 2
663    unsigned16                          assoc_shutdown_req_count;
664
665    rpc_cn_local_id_t                   assoc_grp_id;
666    unsigned16                          assoc_msg_waiters;
667    rpc_cond_t                          assoc_msg_cond;
668    unsigned16                          assoc_max_xmit_frag;
669    unsigned16                          assoc_max_recv_frag;
670    unsigned8                           assoc_vers_minor;
671    unsigned32                          assoc_pres_context_id;
672    ndr_format_t                        assoc_remote_ndr_format;
673    rpc_cn_fragbuf_t                    assoc_dummy_fragbuf;
674    rpc_cn_call_rep_t                   *call_rep;
675    rpc_cn_ctlblk_t                     cn_ctlblk;
676    rpc_list_t                          syntax_list;    /* rpc_cn_syntax_t */
677    rpc_list_t                          msg_list;       /* rpc_cn_fragbuf_t */
678    rpc_cn_assoc_sec_context_t          security;
679    rpc_transport_info_p_t              transport_info;
680    rpc_cn_fragbuf_p_t                  raw_packet_p;
681    rpc_cn_assoc_sm_work_p_t            assoc_sm_work;
682    unsigned32                          bind_packets_sent;
683    signed long long                    alter_call_id;
684};
685// rpc_cn_assoc_t and rpc_cn_assoc_p_t are declared in comsoc.h
686
687/*
688 * If KRB_CN is on, or it isn't explicitly off, turn on CN_AUTH.
689 */
690#if	defined(AUTH_KRB_CN) || !defined(AUTH_KRB_DG)
691#define CN_AUTH
692#endif
693
694/*
695 * Authentication interface macros. These will dispatch through the
696 * authentication protocol ID table using an auth prot ID and the CN
697 * RPC prot ID.
698 */
699#ifdef CN_AUTH
700#define RPC_CN_AUTH_PROT_EPV(prot)              (rpc_cn_auth_epv_t *)(rpc__auth_rpc_prot_epv(prot, RPC_C_PROTOCOL_ID_NCACN))
701#else
702#define RPC_CN_AUTH_PROT_EPV(prot)              (rpc_cn_auth_epv_t *)(0xbabababa)
703#endif /* CN_AUTH */
704
705#define RPC_CN_AUTH_SEC_THREE_WAY(sec, ind)\
706{\
707    ind = (*(sec)->sec_cn_info->cn_epv->three_way)();\
708}
709
710#define RPC_CN_AUTH_THREE_WAY(prot, ind)\
711{\
712    rpc_cn_auth_epv_t   *_cn_epv;\
713    _cn_epv = RPC_CN_AUTH_PROT_EPV(prot);\
714    ind = (*_cn_epv->three_way)();\
715}
716
717#define RPC_CN_AUTH_CONTEXT_VALID(sec, st)\
718    (*(sec)->sec_cn_info->cn_epv->context_valid)(sec, st)
719
720#define RPC_CN_AUTH_CREATE_INFO(prot, level, info, st)\
721{\
722    rpc_cn_auth_epv_t   *_cn_epv;\
723    _cn_epv = RPC_CN_AUTH_PROT_EPV(prot);\
724    (*_cn_epv->create_info)(level, info, st);\
725}
726
727#define RPC_CN_AUTH_CRED_CHANGED(sec, st)\
728    (*(sec)->sec_cn_info->cn_epv->cred_changed)(sec, st)
729
730#define RPC_CN_AUTH_CRED_REFRESH(auth_info, st)\
731{\
732    rpc_cn_auth_epv_t   *_cn_epv;\
733    _cn_epv = RPC_CN_AUTH_PROT_EPV((auth_info)->authn_protocol);\
734    (*_cn_epv->cred_refresh)(auth_info, st);\
735}
736
737#define RPC_CN_AUTH_FMT_CLIENT_REQ(assoc_sec, sec, auth_value, auth_value_len, last_auth_pos, auth_len_remain, retry, st)\
738    (*(sec)->sec_cn_info->cn_epv->fmt_client_req)(assoc_sec, sec, auth_value, auth_value_len, last_auth_pos, auth_len_remain, retry, st)
739
740#define RPC_CN_AUTH_FMT_SRVR_RESP(verify_st, assoc_sec, sec, req_auth_value, req_auth_value_len, auth_value, auth_value_len)\
741    (*(sec)->sec_cn_info->cn_epv->fmt_srvr_resp)(verify_st,assoc_sec,sec,\
742                                                 req_auth_value, req_auth_value_len, auth_value, auth_value_len)
743
744#define RPC_CN_AUTH_FREE_PROT_INFO(info, cn_info)\
745    (*(*(cn_info))->cn_epv->free_prot_info)(info, cn_info)
746
747#define RPC_CN_AUTH_GET_PROT_INFO(info, cn_info, st)\
748{\
749    rpc_cn_auth_epv_t   *_cn_epv;\
750    _cn_epv = RPC_CN_AUTH_PROT_EPV((info)->authn_protocol);\
751    (*_cn_epv->get_prot_info)(info, cn_info, st);\
752}
753
754#define RPC_CN_AUTH_PRE_CALL(assoc_sec, sec, auth_value, auth_value_len, st)\
755    (*(sec)->sec_cn_info->cn_epv->pre_call)(assoc_sec, sec, auth_value, auth_value_len, st);
756
757#define RPC_CN_AUTH_PRE_SEND(assoc_sec, sec, iovp, iovlen, out_iov, st)\
758    (*(sec)->sec_cn_info->cn_epv->pre_send)(assoc_sec, sec, iovp, iovlen, out_iov, st);
759
760#define RPC_CN_AUTH_RECV_CHECK(authn_prot, assoc_sec, sec, pdu, pdu_len, cred_len, auth_tlr, unpack_ints, st)\
761{\
762    if (sec == NULL)\
763    {\
764        rpc_cn_auth_epv_t   *_cn_epv;\
765        _cn_epv = RPC_CN_AUTH_PROT_EPV(authn_prot);\
766        (*_cn_epv->recv_check)(assoc_sec, sec, pdu, pdu_len, cred_len,\
767                               auth_tlr, unpack_ints, st);\
768    }\
769    else\
770    {\
771        (*(sec)->sec_cn_info->cn_epv->recv_check)(assoc_sec, sec, pdu,\
772             pdu_len, cred_len, auth_tlr, unpack_ints, st);\
773    }\
774}
775
776#define RPC_CN_AUTH_TLR_UUID_CRC(prot, auth_value, auth_value_len, assoc_uuid_crc)\
777{\
778    rpc_cn_auth_epv_t   *_cn_epv;\
779    _cn_epv = RPC_CN_AUTH_PROT_EPV(prot);\
780    (*_cn_epv->tlr_uuid_crc)(auth_value, auth_value_len, assoc_uuid_crc);\
781}
782
783#define RPC_CN_AUTH_TLR_UNPACK(prot, pkt_p, auth_value_len, packed_drep)\
784{\
785    rpc_cn_auth_epv_t   *_cn_epv;\
786    _cn_epv = RPC_CN_AUTH_PROT_EPV(prot);\
787    (*_cn_epv->tlr_unpack)(pkt_p, auth_value_len, packed_drep);\
788}
789
790#define RPC_CN_AUTH_VFY_CLIENT_REQ(assoc_sec, sec, auth_value, auth_value_len, old_client, st)\
791    (*(sec)->sec_cn_info->cn_epv->vfy_client_req)(assoc_sec, sec, auth_value, auth_value_len, old_client, st)
792
793#define RPC_CN_AUTH_VFY_SRVR_RESP(assoc_sec, sec, auth_value, auth_value_len, st)\
794    (*(sec)->sec_cn_info->cn_epv->vfy_srvr_resp)(assoc_sec, sec, auth_value, auth_value_len, st)
795
796/*
797 * These macros are RPC protocol independent.
798 */
799#define RPC_CN_AUTH_ADD_REFERENCE(info)         rpc__auth_info_reference(info)
800#define RPC_CN_AUTH_RELEASE_REFERENCE(info)     rpc__auth_info_release(info)
801#ifdef CN_AUTH
802#define RPC_CN_AUTH_CVT_ID_API_TO_WIRE(id,st)   rpc__auth_cvt_id_api_to_wire(\
803id,st)
804#define RPC_CN_AUTH_CVT_ID_WIRE_TO_API(id,st)   rpc__auth_cvt_id_wire_to_api(\
805id,st)
806#define RPC_CN_AUTH_INQ_SUPPORTED(id)           rpc__auth_inq_supported(id)
807#else
808#define RPC_CN_AUTH_CVT_ID_API_TO_WIRE(id,st)   0
809#define RPC_CN_AUTH_CVT_ID_WIRE_TO_API(id,st)   0
810#define RPC_CN_AUTH_INQ_SUPPORTED(id)           false
811#endif
812
813/*
814 * R P C _ C N _ A L I G N _ P T R
815 *
816 * RPC Pointer Alignment macro
817 *
818 * Casting to (unsigned long) is needed because bitwise operations are not
819 * allowed with pointers as an operand.
820 *
821 * NOTE: Assumption sizeof(unsigned long) = sizeof(unsigned8 *).  This
822 *       assumption may not be correct for all machines.
823 */
824
825/* ??? */
826
827#define RPC_CN_ALIGN_PTR(ptr, boundary) \
828    ((uintptr_t) ((unsigned8 *)(ptr) + ((boundary)-1)) & ~((boundary)-1))
829
830/*
831 * R P C _ C N _ A U T H _ R E Q U I R E D
832 */
833
834#define RPC_CN_AUTH_REQUIRED(info) ((info != NULL) && \
835                                    ((info)->authn_protocol != rpc_c_authn_none))
836
837#define RPC_CN_PKT_AUTH_REQUIRED(info) ((info != NULL) && \
838                                    ((info)->authn_level != rpc_c_protect_level_none) && \
839                                    ((info)->authn_level != rpc_c_protect_level_connect))
840
841/*
842 * R P C _ G _ C N _ A S S O C _ G R P _ T B L
843 */
844
845EXTERNAL rpc_cn_assoc_grp_tbl_t rpc_g_cn_assoc_grp_tbl;
846
847/*
848 * R P C _ G _ C N _ S Y N T A X _ L O O K A S I D E _ L I S T
849 */
850
851#define RPC_C_CN_SYNTAX_LOOKASIDE_MAX           16
852EXTERNAL rpc_list_desc_t        rpc_g_cn_syntax_lookaside_list;
853
854/*
855 * R P C _ G _ C N _ S E C _ L O O K A S I D E _ L I S T
856 */
857
858#define RPC_C_CN_SEC_LOOKASIDE_MAX              16
859EXTERNAL rpc_list_desc_t        rpc_g_cn_sec_lookaside_list;
860
861/*
862 * R P C _ G _ C N _ A S S O C _ L O O K A S I D E _ L I S T
863 */
864
865#define RPC_C_CN_ASSOC_LOOKASIDE_MAX            16
866EXTERNAL rpc_list_desc_t        rpc_g_cn_assoc_lookaside_list;
867
868/*
869 * R P C _ G _ C N _ C A L L _ R E P _ L O O K A S I D E _ L I S T
870 */
871
872#define RPC_C_CN_CALL_LOOKASIDE_MAX             0
873EXTERNAL rpc_list_desc_t        rpc_g_cn_call_lookaside_list;
874
875/*
876 * R P C _ G _ C N _ B I N D I N G _ L O O K A S I D E _ L I S T
877 */
878
879#define RPC_C_CN_BINDING_LOOKASIDE_MAX          8
880EXTERNAL rpc_list_desc_t          rpc_g_cn_binding_lookaside_list;
881
882/*
883 * R P C _ G _ C N _ [ L G , S M ] _ F R A G B U F _ L I S T
884 */
885
886#define RPC_C_CN_FRAGBUF_LOOKASIDE_MAX          0
887EXTERNAL rpc_list_desc_t          rpc_g_cn_lg_fbuf_lookaside_list;
888EXTERNAL rpc_list_desc_t          rpc_g_cn_sm_fbuf_lookaside_list;
889
890/*
891 * R P C _ G _ C N _ L O O K A S I D E _ C O N D
892 */
893
894EXTERNAL rpc_cond_t             rpc_g_cn_lookaside_cond;
895
896/*
897 * R P C _ G _ C N _ C A L L _ I D
898 */
899
900EXTERNAL unsigned32             rpc_g_cn_call_id;
901
902/*
903 * R P C _ G _ C N _ M G M T
904 */
905EXTERNAL rpc_cn_mgmt_t          rpc_g_cn_mgmt;
906
907#endif /* _CNP_H */
908