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**      dg.h
82**
83**  FACILITY:
84**
85**      Remote Procedure Call (RPC)
86**
87**  ABSTRACT:
88**
89**  Declarations of types/constants related to the NCA RPC datagram protocol.
90**
91**
92*/
93
94#ifndef _DG_H
95#define _DG_H
96
97/* ========================================================================= */
98
99#include <commonp.h>
100#include <com.h>
101#include <ndrp.h>
102#include <ndrglob.h>
103
104/* ========================================================================= */
105
106/*
107 * Some terminology conventions in procedure naming.
108 *
109 * Below, by "collection" ("C") we mean a table of some sort; collections
110 * are composed of "elements".  The Client Connection Table (CCT) is
111 * an example of a collection; a client connection table entry (CCTE)
112 * is an example of an element.  By "object" ("O") we mean some data
113 * structure.  A call handle is an example of an object.
114 *
115 * C_lookup
116 *      means look something up in the "C" collection.  If a matching
117 *      element is found, return the element.  Otherwise return NULL.
118 *
119 * C_insert
120 *      means insert an element into the "C" collection.
121 *
122 * C_remove
123 *      means remove an element from the "C" collection.
124 *
125 * C_get
126 *      means look something up in the "C" collection.  If a matching
127 *      element is found, return the element.  Otherwise, create an
128 *      appropriate element, insert it in the collection and return the
129 *      element.
130 *
131 * O_release
132 *      means release a reference to an "O" object.  (If "O" refers to
133 *      a collection, the object is an element in the collection previously
134 *      obtained via either "C_lookup" or "C_get".)  See "Reference Counts"
135 *      comment below.
136 *
137 * O_reference
138 *      means establish another reference to an "O" object.  (If "O"
139 *      refers to a collection, the object is an element in the collection
140 *      previously obtained via either "C_lookup" or "C_get".)  See
141 *      "Reference Counts" comment below.
142 *
143 * O_alloc
144 *      means allocate and return (a reference to) an "O" object.
145 *
146 * O_free
147 *      means deallocate an "O" object.
148 *
149 * O_init
150 *      means initialize an "O" object.
151 *
152 * O_reinit
153 *      means re-initialize an "O" object.
154 *
155 * In general "O_foo" operates on an "O".  This is the "object-oriented"
156 * approach.  However, we don't belabor it -- some procedures are just
157 * not best considered as operations on objects; i.e., they're procedures,
158 * not operations (messages, in the Smalltalk sense).  For just procedures,
159 * we use English-oriented names (whatever that means).
160 */
161
162/* ========================================================================= */
163
164/*
165 * Reference Counts
166 * ----------------
167 *
168 * Various data structures have a reference count field named ".refcnt".
169 * Reference counting augments (does not replace) mutex locking in situations
170 * where (a) a lock would have to be held for "too long", (b) the data
171 * structure is heap allocated, and (c) the data structure should not be
172 * freed until all the logical users of the structure are done with it.
173 * The paradigmatic code sequence that requires reference counts is:
174 *
175 *      (1) Lock data structure
176 *      (2) Look at interesting parts of structure
177 *      (3) Do something for a long time
178 *      (4) Look at interesting parts of structure
179 *      (5) Unlock structure
180 *
181 * We avoid the "holding a lock for too long" problem in the above code
182 * by doing:
183 *
184 *      (1) Lock data structure
185 *      (2) Look at interesting parts of structure
186 *      (3) "reference"
187 *      (4) Unlock structure
188 *      (5) Do something for a long time
189 *      (6) Lock data structure
190 *      (7) Look at interesting parts of structure
191 *      (8) "release"
192 *
193 * "Reference" means increment the structure's reference count; "release"
194 * means decrement the structure's reference count and if the count becomes
195 * zero then free the structure, otherwise just unlock the structure.  In
196 * this model no one directly calls a "free" function; they call a "release"
197 * function instead (which in turn does a "free" if the reference count
198 * drops to zero).
199 *
200 * Note that the code above is really an execution flow and does not
201 * necessarily reflect code structure.  I.e., steps (1)-(4) might be in
202 * one place, step (5) in another, and steps (6)-(8) in yet another.  The
203 * basic idea is this:  If you establish a reference to a structure (e.g.,
204 * by embedding a pointer to the structure in some other structure, or if
205 * you "pass" a pointer to another thread somehow) and you unlock the
206 * structure and you want the structure to be there later, you must increment
207 * the reference count.
208 *
209 * Routines that look things up and return references to entries should
210 * return with the entry locked and the reference count already incremented.
211 *
212 * To establish or release a reference or to free a structure, you must
213 * have the structure locked.
214 *
215 * Since releasing a reference will unlock or free a structure, you must
216 * not use the reference after a release.
217 */
218
219/* ========================================================================= */
220
221/* !!! */
222
223#define UUID_NIL uuid_g_nil_uuid
224
225/* ========================================================================= */
226
227/*
228 * In some cases it is inconvenient/wasteful to be dynamically allocating
229 * storage to hold network addresses.  For example, each rqe in the packet
230 * buffer cache contains a network address field;  adhering to the
231 * prescribed use of rpc_addr_p_t's could result in having to reallocate
232 * this buffer each time a packet is received on a different NAF.  To
233 * avoid this situation, we define an RPC address structure that should
234 * be large enough to hold the largest network address we expect to see.
235 * The size of the actual address part of this type is determined by the
236 * value of the constant MAX_NETADDR_LENGTH, which can be defined in
237 * the system specific include file for any system which does not want
238 * to use the default value (defined below).
239 */
240
241#ifndef MAX_NETADDR_LENGTH
242# define MAX_NETADDR_LENGTH 14
243#endif
244
245typedef struct
246{
247    rpc_protseq_id_t        rpc_protseq_id;
248    unsigned32          len;
249    struct
250    {
251        unsigned16          family;
252        unsigned8           data[MAX_NETADDR_LENGTH];
253    } sa;
254} rpc_addr_il_t, *rpc_addr_il_p_t;
255
256/* ========================================================================= */
257
258/*
259 * RPC protocol ID for DG protocol.  For tower rep.
260 */
261
262#define RPC_C_DG_PROTO_ID 0x0a
263
264/* ========================================================================= */
265
266/*
267 * Packet format definitions
268 */
269
270/*
271 * The current version of the NCA/RPC protocol.  See RPC_DG_HDR_{INQ,SET}_VERS
272 * macros below.
273 */
274
275#define RPC_C_DG_PROTO_VERS 4
276
277/*
278 * Max packet size
279 *
280 * This is the size of the largest RPC packet (including RPC packet header
281 * and body) we can cope with.  This value must be 0 MOD 8 (see discussion
282 * in packet header comments below).  This is an IMPLEMENTATION artifact
283 * and does not represent the largest packet the protocol supports.
284 *
285 * We assume that the packet buffer memory is cheap in the user
286 * space and use the packet buffer size which can hold a single IP
287 * fragment on the FDDI network.
288 */
289
290#define RPC_C_DG_MAX_PKT_SIZE  (540 * 8) /* = 4320 */
291
292/*
293 * The different kinds of RPC packets, annotated as to which direction
294 * they're sent.  See RPC_DG_HDR_{INQ,SET}_PTYPE macros below.
295 */
296
297typedef unsigned32 rpc_dg_ptype_t;
298
299#define RPC_C_DG_PT_REQUEST           0 /* client -> server */
300#define RPC_C_DG_PT_PING              1 /* client -> server */
301#define RPC_C_DG_PT_RESPONSE          2 /* server -> client */
302#define RPC_C_DG_PT_FAULT             3 /* server -> client */
303#define RPC_C_DG_PT_WORKING           4 /* server -> client */
304#define RPC_C_DG_PT_NOCALL            5 /* server -> client */
305#define RPC_C_DG_PT_REJECT            6 /* server -> client */
306#define RPC_C_DG_PT_ACK               7 /* client -> server */
307#define RPC_C_DG_PT_QUIT              8 /* client -> server */
308#define RPC_C_DG_PT_FACK              9 /* both directions  */
309#define RPC_C_DG_PT_QUACK            10 /* server -> client */
310
311#define RPC_C_DG_PT_MAX_TYPE RPC_C_DG_PT_QUACK
312
313/*
314 * Macros to (hopefully efficiently) test packet types.
315 */
316
317#define RPC_DG_PT_IS(ptype, mask) (((1 << (ptype)) & (mask)) != 0)
318
319#define RPC_DG_PT_IS_DATA(ptype) \
320    RPC_DG_PT_IS(ptype, \
321        (1 << RPC_C_DG_PT_REQUEST)  | \
322        (1 << RPC_C_DG_PT_RESPONSE) | \
323        (1 << RPC_C_DG_PT_FAULT)      \
324    )
325
326#define RPC_DG_PT_IS_CTOS(ptype) \
327    RPC_DG_PT_IS(ptype, \
328        (1 << RPC_C_DG_PT_REQUEST)  | \
329        (1 << RPC_C_DG_PT_PING)     | \
330        (1 << RPC_C_DG_PT_ACK)      | \
331        (1 << RPC_C_DG_PT_QUIT)       \
332    )
333
334#define RPC_DG_PT_IS_STOC(ptype) \
335    RPC_DG_PT_IS(ptype, \
336        (1 << RPC_C_DG_PT_RESPONSE) | \
337        (1 << RPC_C_DG_PT_FAULT)    | \
338        (1 << RPC_C_DG_PT_WORKING)  | \
339        (1 << RPC_C_DG_PT_NOCALL)   | \
340        (1 << RPC_C_DG_PT_REJECT)   | \
341        (1 << RPC_C_DG_PT_QUACK)      \
342    )
343
344/*
345 * Packet header structure.
346 *
347 * Alignment
348 * ---------
349 * All the scalar fields are "naturally aligned" -- i.e. aligned 0 MOD
350 * min(8, sizeof(field)).  This is done for maximum portability and
351 * efficiency of field reference.  Note also that the header is a integral
352 * multiple of 8 bytes in length.  This ensures that (assuming the pkt
353 * is 8-byte aligned in memory), the start of the data area is 8-byte
354 * aligned.  (8 bytes is the size of the largest scalar we support.)
355 *
356 * Wrapping
357 * --------
358 * Sequence and fragment numbers can wrap.  Non-equality comparisons
359 * between such objects must use the comparison macros below.
360 *
361 * Fragment numbers
362 * ----------------
363 * In requests, "fragnum" is the number of the frag sent.  In facks,
364 * "fragnum" is the number of the highest in-order frag received; if
365 * frag 0 hasn't been received, the fack contains a "fragnum" of 0xffff.
366 *
367 *
368 * Packet lengths
369 * --------------
370 * Packet bodies must have lengths that are 0 MOD 8, except for the last
371 * fragment in a request or response.  (Since the packet header is also
372 * of a length that is 0 MOD 8, this means that the entire packet will
373 * be of a length that is 0 MOD 8.)  Rationale: The stub/runtime interface
374 * demands that we return data buffers whose length is 0 MOD 8.  (This
375 * means that no NDR scalar will ever be split across buffers, a convenient
376 * property for the stubs.)  We make it easy to meet this demand by making
377 * packets of length 0 MOD 8, meaning we can simply return (pointer to)
378 * packets as received data buffers to the stubs.
379 *
380 * Storage layout
381 * --------------
382 * Not all C compilers (esp. those for machines whose smallest addressible
383 * unit is not 8 bits) pack the "rpc_dg_pkt_hdr_t" structure "correctly"
384 * (i.e. into a storage layout that can be overlayed on a vector of bytes
385 * that make up a packet that's just come off the wire).  Thus, on some
386 * machines "rpc_dg_pkt_hdr_t" can not simply be used on incoming packets
387 * (or used to set up outgoing packets).  We call machines that have
388 * this problem "mispacked header machines".
389 *
390 * To fix this problem, on mispacked header machine, when a packet arrives
391 * we expand the header bits so they correspond to the actual storage
392 * layout of "rpc_dg_pkt_hdr_t".  Analogously, before sending a packet,
393 * we contract the header bits.
394 */
395
396typedef struct {
397    u_char _rpc_vers;       /* 00:01 RPC version (see RPC_DG_HDR_*_VERS below) */
398    u_char _ptype;          /* 01:01 packet type (see RPC_HDR_HDR_*_PTYPE below) */
399    u_char flags;           /* 02:01 flags (see rpc_c_dg_pf_... below) */
400    u_char flags2;          /* 03:01 more flag (see rpc_c_dg_pf2__... below) */
401    u_char drep[3];         /* 04:03 data type format of sender (see below) */
402    u_char serial_hi;       /* 07:01 high byte of fragment serial number */
403    idl_uuid_t object;          /* 08:16 object UID */
404    idl_uuid_t if_id;           /* 24:16 interface UID */
405    idl_uuid_t actuid;          /* 40:16 activity UID of caller */
406    unsigned32 server_boot; /* 56:04 time server booted */
407    unsigned32 if_vers;     /* 60:04 version of interface */
408    unsigned32 seq;         /* 64:04 sequence # -- monotonically increasing */
409    unsigned16 opnum;       /* 68:02 operation # within the trait */
410    unsigned16 ihint;       /* 70:02 interface hint (which interface w/in server) */
411    unsigned16 ahint;       /* 72:02 activity hint */
412    unsigned16 len;         /* 74:02 length of body */
413    unsigned16 fragnum;     /* 76:02 fragment # */
414    u_char auth_proto;      /* 78:01 authentication protocol */
415    u_char serial_lo;       /* 79:01 low byte of fragment serial number */
416} rpc_dg_pkt_hdr_t, *rpc_dg_pkt_hdr_p_t;
417
418/*
419 * Macros for accessing the "rpc_vers" field.  These macros operate on
420 * only the low 4 bits of the field, yielding possible versions in the
421 * range (0..15).  While pre-NCS 2.0 implementations look at all 8 bits,
422 * using these macros may allow us some flexibility in the use of these
423 * bits in environments where all systems are NCS 2.0 or later.  NOTE
424 * WELL, that the "set" macro sets ALL 8 bits (i.e., the high 4 bits to
425 * zero), so when/if we want to use those bits, we have to visit all
426 * the callers of that macro (which we'd presumably have to do in any
427 * case).
428 */
429
430#define RPC_C_DG_VERS_MASK  0x0f    /* 4 bits wide */
431
432#define RPC_DG_HDR_INQ_VERS(hdrp) \
433    ((hdrp)->_rpc_vers & RPC_C_DG_VERS_MASK)
434#define RPC_DG_HDR_SET_VERS(hdrp) \
435    ((hdrp)->_rpc_vers = RPC_C_DG_PROTO_VERS)
436
437/*
438 * Macros for accessing the "ptype" field.  These macros operate on only
439 * the low 5 bits of the field, yielding possible packet types in the
440 * range (0..31).  While pre-NCS 2.0 implementations look at all 8 bits,
441 * using these macros may allow us some flexibility in the use of these
442 * bits in environments where all systems are NCS 2.0 or later.  NOTE
443 * WELL, that the "set" macro sets ALL 8 bits (i.e., the high 3 bits to
444 * zero), so when/if we want to use those bits, we have to visit all
445 * the callers of that macro (which we'd presumably have to do in any
446 * case).
447 */
448
449#define RPC_C_DG_PTYPE_MASK 0x1f    /* 5 bits wide */
450
451#define RPC_DG_HDR_INQ_PTYPE(hdrp) \
452    ((hdrp)->_ptype & RPC_C_DG_PTYPE_MASK)
453
454#define RPC_DG_HDR_SET_PTYPE(hdrp, ptype) \
455    ((hdrp)->_ptype = (ptype))
456
457/*
458 * Initial value for ihint and ahint fields.
459 */
460
461#define RPC_C_DG_NO_HINT ((unsigned16) 0xffff)
462
463/*
464 * Packet flags (used in "flags" field in packet header), indicating
465 * in packets and in which direction(s)--i.e., client->server,
466 * server->client, or both--they're used.  Currently, no flag is defined
467 * to have one meaning in one direction and another meaning in the other
468 * direction; i.e., if a flag is used in both directions, it means the
469 * same thing in both directions.  However, to allow for the possibility
470 * in the future of flags meaning one thing in one direction and another
471 * thing in the other, all flags that are currently used in only one
472 * direction must be set to zero when sent in the other direction.
473 *
474 * Note on rpc_c_dg_pf_blast_outs:  Early versions of NCK did not blast
475 * large ins/outs but were designed to work with senders that did blast
476 * large ins/outs.  (I.e. early versions supported the rpc_c_dg_pf_no_fack
477 * bit which is now used by new senders that want to blast multiple frags.)
478 * Unfortunately, while the design was correct, the implementation wasn't.
479 * Old clients have a bug in handling blasted outs.  So by default, new
480 * servers won't blast large outs.  The rpc_c_dg_pf_blast_outs flag is
481 * set by new clients to tell the server that the client can handle blasts.
482 *
483 * Note on forwarding:  Forwarding is a purely intra-machine function;
484 * i.e. The rpc_c_dg_pf_forwarded and rpc_c_dg_pf2_forwarded2 bits should
485 * never be set on packets sent on the wire.  It's pretty sleazy to be
486 * stealing these bits (i.e. make them unavailable for the on-the-wire
487 * protocol), but that's life.  If in the future we're willing to go
488 * through more work (i.e. do intra-machine forwarding through some other
489 * means), we could free up those bits.  See comments below for details
490 * on use of the bits.
491 */
492
493#define RPC_C_DG_PF_FORWARDED    0x01        /* (client -> server) Packet was forwarded */
494#define RPC_C_DG_PF_LAST_FRAG    0x02        /* (both directions)  Packet is the last fragment */
495#define RPC_C_DG_PF_FRAG         0x04        /* (both directions)  Packet is a fragment */
496#define RPC_C_DG_PF_NO_FACK      0x08        /* (both directions)  Don't send an FACK for this FRAG */
497#define RPC_C_DG_PF_MAYBE        0x10        /* (client -> server) "maybe" request */
498#define RPC_C_DG_PF_IDEMPOTENT   0x20        /* (client -> server) "idempotent" request */
499#define RPC_C_DG_PF_BROADCAST    0x40        /* (client -> server) "broadcast" request */
500#define RPC_C_DG_PF_BLAST_OUTS   0x80        /* (client -> server) out's can be blasted */
501
502/*
503 * Packet flags (used in "flags2" field in packet header).
504 */
505
506#define RPC_C_DG_PF2_FORWARDED_2 0x01        /* (client -> server) Packet is being forwarded in two pieces */
507#define RPC_C_DG_PF2_CANCEL_PENDING 0x02     /* (server -> client) Cancel was pending at call end */
508#define RPC_C_DG_PF2_RESERVED04  0x04
509#define RPC_C_DG_PF2_RESERVED08  0x08
510#define RPC_C_DG_PF2_RESERVED10  0x10
511#define RPC_C_DG_PF2_RESERVED20  0x20
512#define RPC_C_DG_PF2_RESERVED40  0x40
513#define RPC_C_DG_PF2_RESERVED80  0x80
514
515/*
516 * Macros for munging with packet flags
517 */
518
519#define RPC_DG_HDR_FLAG_IS_SET(hdrp, flag)  (((hdrp)->flags  & (flag)) != 0)
520#define RPC_DG_HDR_FLAG2_IS_SET(hdrp, flag) (((hdrp)->flags2 & (flag)) != 0)
521
522#define RPC_DG_FLAG_IS_SET(flags, flag)   ((flags  & (flag)) != 0)
523#define RPC_DG_FLAG2_IS_SET(flags2, flag) ((flags2 & (flag)) != 0)
524
525/*
526 * Macros to help do A < B and A <= B compares on unsigned numbers in
527 * general and specifically packet fragment and sequence numbers.  These
528 * macros are useful when the numbers being compared are allowed to wrap
529 * (e.g. we really want 0xfffffffe to be less than 0x00000002).
530 *
531 * To perform such a comparison, we count the fact that the number space
532 * for a given data type / object is large enough that we can assert:
533 * if the unsigned difference A - B is "negative", A is < B.  We define
534 * "negative" as being a unsigned difference that when converted to
535 * a signed type of the same precision yields a negative value.
536 */
537
538#define RPC_DG_UNSIGNED_IS_LT(a, b, signed_cast)    (((signed_cast) ((a) - (b))) < 0)
539#define RPC_DG_UNSIGNED_IS_LTE(a, b, signed_cast)   (((signed_cast) ((a) - (b))) <= 0)
540
541#define RPC_DG_FRAGNUM_IS_LT(a, b)  RPC_DG_UNSIGNED_IS_LT(a, b, signed16)
542#define RPC_DG_FRAGNUM_IS_LTE(a, b) RPC_DG_UNSIGNED_IS_LTE(a, b, signed16)
543
544#define RPC_DG_SERIAL_IS_LT(a, b)  RPC_DG_UNSIGNED_IS_LT(a, b, signed16)
545#define RPC_DG_SERIAL_IS_LTE(a, b) RPC_DG_UNSIGNED_IS_LTE(a, b, signed16)
546
547#define RPC_DG_SEQ_IS_LT(a, b)      RPC_DG_UNSIGNED_IS_LT(a, b, signed32)
548#define RPC_DG_SEQ_IS_LTE(a, b)     RPC_DG_UNSIGNED_IS_LTE(a, b, signed32)
549
550/*
551 * Macros to manipulate the packet header NDR drep.
552 *
553 * We "stole" the last byte of the 4 byte drep (which is currently
554 * "reserved" and not likely to ever actually be used) to hold the
555 * authentication type.  (See "ndrp.h" for details on NDR dreps.)  As
556 * a result, we can't use all the macros in "ndrp.h".  We define our
557 * own here.  (We #undef NDR_COPY_DREP to make sure we don't use it by
558 * mistake.)
559 */
560
561#ifdef NDR_COPY_DREP
562#  undef NDR_COPY_DREP
563#endif
564
565#define RPC_DG_HDR_SET_DREP(hdrp) { \
566    (hdrp)->drep[0] = ndr_g_local_drep_packed[0]; \
567    (hdrp)->drep[1] = ndr_g_local_drep_packed[1]; \
568    (hdrp)->drep[2] = ndr_g_local_drep_packed[2]; \
569}
570
571#define RPC_DG_HDR_INQ_DREP(dst_drep, src_hdrp) { \
572    (dst_drep)->int_rep   = NDR_DREP_INT_REP((src_hdrp)->drep); \
573    (dst_drep)->char_rep  = NDR_DREP_CHAR_REP((src_hdrp)->drep); \
574    (dst_drep)->float_rep = NDR_DREP_FLOAT_REP((src_hdrp)->drep); \
575    (dst_drep)->reserved  = 0; \
576}
577
578/*
579 * Raw packet header
580 *
581 * "rpc_c_dg_raw_pkt_hdr_size" is the actual size of a packet header
582 * (in bytes) as it appears on the wire.  The size of "rpc_dg_pkt_hdr_t"
583 * can only be the same or larger.  "rpc_dg_raw_pkt_hdr" is the struct
584 * used for declaring a real wire-format packet header.
585 *
586 *  #ifndef RPC_MISPACKED_HDR
587 *      assert(RPC_C_DG_RAW_PKT_HDR_SIZE == sizeof(rpc_dg_pkt_hdr_t))
588 *  #endif
589 *
590 * The "rpc_c_dg_rpho_..." constants ("rpho" = "raw packet header offset")
591 * can be used to locate the logical header fields in a raw packet header.
592 */
593
594#define RPC_C_DG_RAW_PKT_HDR_SIZE 80UL
595
596typedef struct {
597    char hdr[RPC_C_DG_RAW_PKT_HDR_SIZE];
598} rpc_dg_raw_pkt_hdr_t, *rpc_dg_raw_pkt_hdr_p_t;
599
600#define RPC_C_DG_RPHO_RPC_VERS         0
601#define RPC_C_DG_RPHO_PTYPE            1
602#define RPC_C_DG_RPHO_FLAGS            2
603#define RPC_C_DG_RPHO_FLAGS2           3
604#define RPC_C_DG_RPHO_DREP             4
605#define RPC_C_DG_RPHO_SERIAL_HI        7
606#define RPC_C_DG_RPHO_OBJECT           8
607#define RPC_C_DG_RPHO_IF_ID           24
608#define RPC_C_DG_RPHO_ACTUID          40
609#define RPC_C_DG_RPHO_SERVER_BOOT     56
610#define RPC_C_DG_RPHO_IF_VERS         60
611#define RPC_C_DG_RPHO_SEQ             64
612#define RPC_C_DG_RPHO_OPNUM           68
613#define RPC_C_DG_RPHO_IHINT           70
614#define RPC_C_DG_RPHO_AHINT           72
615#define RPC_C_DG_RPHO_LEN             74
616#define RPC_C_DG_RPHO_FRAGNUM         76
617#define RPC_C_DG_RPHO_AUTH_PROTO      78
618#define RPC_C_DG_RPHO_SERIAL_LO       79
619
620/*
621 * Packet body structure
622 *
623 * The "body" part of a pkt is used only for certain pkt types (e.g.
624 * request, response).
625 */
626
627typedef struct {
628    char args[RPC_C_DG_MAX_PKT_SIZE - RPC_C_DG_RAW_PKT_HDR_SIZE];
629} rpc_dg_pkt_body_t, *rpc_dg_pkt_body_p_t;
630
631#define RPC_C_DG_MAX_PKT_BODY_SIZE \
632    (RPC_C_DG_MAX_PKT_SIZE - RPC_C_DG_RAW_PKT_HDR_SIZE)
633
634#if (RPC_C_DG_MAX_PKT_BODY_SIZE & 0x7) != 0
635#error RPC_C_DG_MAX_PKT_BODY_SIZE must be 0 MOD 8!
636#endif
637
638/*
639 * Packet structure
640 */
641
642typedef struct
643{
644    rpc_dg_pkt_hdr_t hdr;
645    rpc_dg_pkt_body_t body;
646} rpc_dg_pkt_t, *rpc_dg_pkt_p_t;
647
648/*
649 * Error packet body structure
650 *
651 * Used for packets with a body that only consist of an error status
652 * (i.e. reject and fault packets).
653 */
654
655typedef struct
656{
657    unsigned32 st;
658} rpc_dg_epkt_body_t, *rpc_dg_epkt_body_p_t;
659
660#define RPC_C_DG_RAW_EPKT_BODY_SIZE 4   /* sizeof unsigned32     on the wire */
661
662typedef struct
663{
664    u_char body[RPC_C_DG_RAW_EPKT_BODY_SIZE];
665} rpc_dg_raw_epkt_body_t, *rpc_dg_raw_epkt_body_p_t;
666
667/*
668 * Quit packet body structure.  This is currently used for
669 * NCS 2.0 "cancel-requests".
670 */
671
672typedef struct
673{
674    unsigned32  vers;       /* quit body format version */
675    unsigned32  cancel_id;  /* id of a cancel-request event */
676    /* end of version 0 format */
677} rpc_dg_quitpkt_body_t, *rpc_dg_quitpkt_body_p_t;
678
679#define RPC_C_DG_QUITPKT_BODY_VERS   0
680
681#define RPC_C_DG_RAW_QUITPKT_BODY_SIZE    (4+4)   /* on-the-wire size */
682
683typedef struct
684{
685    u_char body[RPC_C_DG_RAW_QUITPKT_BODY_SIZE];
686} rpc_dg_raw_quitpkt_body_t, *rpc_dg_raw_quitpkt_body_p_t;
687
688/*
689 * Quack packet body structure.  This is currently used for
690 * NCS 2.0 "cancel-request" acknowlegements.
691 */
692
693typedef struct
694{
695    unsigned32  vers;       /* cancel-request body format version */
696    unsigned32  cancel_id;  /* id of a cancel-request event being ack'd */
697    boolean     server_is_accepting;    /* NIDL boolean */
698    /* end of version 0 format */
699} rpc_dg_quackpkt_body_t, *rpc_dg_quackpkt_body_p_t;
700
701#define RPC_C_DG_QUACKPKT_BODY_VERS   0
702
703#define RPC_C_DG_RAW_QUACKPKT_BODY_SIZE    (4+4+1)  /* on-the-wire size */
704
705typedef struct
706{
707    u_char body[RPC_C_DG_RAW_QUACKPKT_BODY_SIZE];
708} rpc_dg_raw_quackpkt_body_t, *rpc_dg_raw_quackpkt_body_p_t;
709
710/*
711 * Fack packet body structure.
712 *
713 * Pre-v2 NCK facks always had zero length bodies.  V2 fack bodies
714 * contain useful information.
715 *
716 * The following two values related to packet size can appear in a fack
717 * body:
718 *
719 * max_tsdu:      The size of the largest transport protocol data unit
720 *                (TPDU) that can be passed through the local transport
721 *                service interface (i.e., transport API).  The fack
722 *                sender can never process datagrams larger than this.
723 *
724 * max_frag_size: The size of the largest fragment that can be
725 *                sent/received by the fack sender.
726 *                (AES spells it as max_path_tpdu.)
727 *
728 * The sender of a fack puts its local idea of these two values into
729 * the fack body, to help the other side determine what fragment
730 * size to use. The fack sender is saying "Don't ever send me
731 * fragments larger than 'max_tsdu'" and "I think you probably don't
732 * want to send me fragments larger than 'max_frag_size' because I
733 * can't process it".
734 *
735 * The receiver of a fack compares the two values with the locally
736 * determined values (in the receiver's call xmitq) and, if
737 * appropriate, the xmitq's fragment size, 'snd_frag_size', is
738 * increased. (Currently, we play it safe by taking the minimum the
739 * two values in the fack and the two locally computed values.)
740 *
741 * The serial_num field is taken from the packet header of the packet
742 * that induced the ack.  Since each packet is given a unique serial
743 * number prior to transmission, the sender can always determine exactly
744 * which packet induced the ack.  Serial numbers play the role of logical
745 * clocks, which allow the sender to determine which packets should have
746 * been received given an ack for a packet sent at time n.  This is
747 * especially useful in the face of multiple retransmissions, when
748 * fragment numbers don't provide any ordering information.
749 *
750 * The selective ack fields provide information about what additional
751 * packets were received in addition to the fragment explicitly mentioned
752 * in this fack (N).  If included, each bit in the mask (B) corresponds
753 * to whether of not fragment N+B was received.  Note that the low order
754 * bit in the first mask will always be 0, since atleast one fragment
755 * is missing, and N will always be the number of the fragment before
756 * the first known missing fragment.
757 *
758 * Note that nocall packets can also have fack bodies.  (Pre-DCE 1.0.2
759 * nocall packets always had zero length bodies.)  This is to remedy
760 * a couple of flaws in the original protocol which precluded (a) sending
761 * facks in response to single-packet requests, and (b) sending facks
762 * in response to pings (in requests of any size).  Older clients will
763 * ignore the fack body that appears in nocall packets.
764 */
765
766typedef struct
767{
768    unsigned8 vers;             /* Fack packet body version */
769    u_char pad1;
770    unsigned16 window_size;     /* Sender's receive window size (in kilobytes) */
771    unsigned32 max_tsdu;        /* See above */
772    unsigned32 max_frag_size;   /* See above */
773    unsigned16 serial_num;      /* serial # of packet that induced this fack */
774    unsigned16 selack_len;      /* number of elements in the selack array    */
775    unsigned32 selack[1];       /* variable number of 32 bit selective ack   */
776                                /* bit masks.                                */
777} rpc_dg_fackpkt_body_t, *rpc_dg_fackpkt_body_p_t;
778
779#define RPC_C_DG_FACKPKT_BODY_VERS      1
780#define RPC_C_DG_RAW_FACKPKT_BODY_SIZE  20
781
782typedef struct
783{
784    u_char body[RPC_C_DG_RAW_FACKPKT_BODY_SIZE];
785} rpc_dg_raw_fackpkt_body_t, *rpc_dg_raw_fackpkt_body_p_t;
786
787/*
788 * Forwarding
789 *
790 * So that clients don't need to know the actual port a server is using,
791 * we provide for a "forwarder" process on the server's machine.  A
792 * client that doesn't know the server's port sends to the forwarder's
793 * well-known port instead.
794 *
795 * When a packet is received by the forwarder process, it is forwarded
796 * to the correct server process on the machine.  The server must know
797 * the original sender.  However, what the server "sees" as a result
798 * of the "receive" is the address of the forwarder, not the original
799 * client.  The solution to this problem has two cases: the case where
800 * the body of the packet to be forwarded is not full and the case where
801 * it IS full.  In the non-full case, the forwarder inserts the original
802 * client address at the front of the body of the packet to be forwarded.
803 * (The original body is slid down.)  The rpc_c_dg_pf_forwarded bit is
804 * set in the header.  When the server receives such a packet, it just
805 * picks up the address from the body and slides the real body back up.
806 *
807 * In the case of a full packet body, the packet must be forwarded in
808 * two packets.  The forwarder makes body of the first packet contains
809 * only the original client address and sets the rpc_c_dg_pf2_forwarded2
810 * flag.  The body of the second packet is the original packet body;
811 * no forwarding flags are set.
812 */
813
814/*
815 * Forwarded packet structure
816 *
817 * This format for local use between a forwarding agent (LLBD) and a
818 * real server.  This format does not appear on the wire.
819 */
820
821typedef struct
822{
823    unsigned32 len;             /* Length of addr */
824    struct sockaddr addr;       /* Original sender of packet */
825    u_char drep[4];             /* Original data rep (describes body) */
826} rpc_dg_fpkt_hdr_t, *rpc_dg_fpkt_hdr_p_t;
827
828typedef struct
829{
830    rpc_dg_pkt_hdr_t hdr;
831    rpc_dg_fpkt_hdr_t fhdr;
832    rpc_dg_pkt_body_t body;
833} rpc_dg_fpkt_t, *rpc_dg_fpkt_p_t;
834
835/*
836 * Common raw packet structure (as sent / received over the wire)
837 */
838
839typedef struct {
840    rpc_dg_raw_pkt_hdr_t hdr;
841    rpc_dg_pkt_body_t body;
842} rpc_dg_raw_pkt_t, *rpc_dg_raw_pkt_p_t;
843
844/* =============================================================================== */
845
846typedef enum {
847    rpc_e_dg_recv_no_data,
848    rpc_e_dg_recv_unspec_error,
849    rpc_e_dg_recv_cksum_error,
850    rpc_e_dg_recv_bad_ptype,
851    rpc_e_dg_recv_bad_len,
852    rpc_e_dg_recv_bad_version,
853#ifdef NON_REENTRANT_SOCKETS
854    rpc_e_dg_recv_reentered,
855#endif
856    rpc_e_dg_recv_ok
857} rpc_dg_recv_status_t;
858
859/* =============================================================================== */
860
861/*
862 * Monitor liveness client rep structure
863 *
864 * This structure is used by the server runtime to monitor the liveness
865 * of a client.  The fields of interest are a UUID, which identifies
866 * a particular instance of a client address space, and a pointer to
867 * a function to call should contact be lost with the client.
868 *
869 * This structure is primarily associated, and cached, with an SCTE.
870 * In the normal case, in which liveness is not being monitored, no such
871 * entry is created.  If the server stub desires the runtime to monitor
872 * the client,  a callback is made to the client (if the SCTE does not
873 * yet contain such an entry) to retrieve a UUID by which the server
874 * can identify that client's address space (i.e., any thread within
875 * that process).  The client rep is then added to a hash table, a
876 * reference is placed in the SCTE, and a pointer is returned back to
877 * the server stub.  The server stub can then begin monitoring the client
878 * by registering a rundown function pointer through a call to the
879 * monitor_liveness() routine.  A NULL rundown function pointer
880 * indicates that the client is not currently being monitored.
881 *
882 * Note that several SCTEs may point to a single client_rep.  Since the
883 * runtime has no way of mapping activity IDs to address spaces, a seperate
884 * call back is required for each activity ID.  However the address space
885 * UUID returned for actids in the same process will be the same, and
886 * only one client rep will be created.  It is also presumed that the
887 * stubs will not try to register more than one rundown funtion for a
888 * given client address space.
889 */
890typedef struct rpc_dg_client_rep_t
891{
892    struct rpc_dg_client_rep_t *next;
893    idl_uuid_t                     cas_uuid;         /* UUID uniquely identifying client    */
894    rpc_network_rundown_fn_t   rundown;          /* routine to call if client dies      */
895    rpc_clock_t                last_update;      /* last time we heard from this client */
896    unsigned32                 refcnt;           /* # of references to this element     */
897} rpc_dg_client_rep_t, *rpc_dg_client_rep_p_t;
898
899/* ========================================================================= */
900
901/*
902 * Transmit packet queue element (XQE)
903 *
904 * We choose to decouple the packet body from the element itself to lessen
905 * our dependency on the ideosyncracies of various memory allocation
906 * mechanisms.
907 *
908 * A private xqelt (i.e. not on a xmitq) has no locking requirements.
909 * A xqelt that is a member of a xmitq essentially becomes part of that
910 * data structure and inherits the xmitq's locking requirements.
911 */
912
913typedef struct rpc_dg_xmitq_elt_t {
914    struct rpc_dg_xmitq_elt_t *next;
915    struct rpc_dg_xmitq_elt_t *next_rexmit; /* when on rexmit queue   */
916    struct rpc_dg_xmitq_elt_t *more_data;   /* for multi-buffer fragments */
917    unsigned32 frag_len;        /* fragment length, iff more_data != NULL */
918    unsigned16 flags;                   /* pkt header flags */
919    unsigned32 fragnum;                 /* our fragment number */
920    unsigned16 serial_num;              /* our serial number */
921    unsigned16 body_len;                /* # of bytes used in .body */
922    rpc_dg_pkt_body_p_t body;           /* pkt body */
923    unsigned in_cwindow: 1;             /* T => pkt is in cwindow size count */
924} rpc_dg_xmitq_elt_t, *rpc_dg_xmitq_elt_p_t;
925
926#define RPC_C_DG_INITIAL_REXMIT_TIMEOUT RPC_CLOCK_SEC(2)
927#define RPC_C_DG_MAX_REXMIT_TIMEOUT     RPC_CLOCK_SEC(8)
928
929/*
930 * Transmit packet queue (XMITQ or XQ)
931 *
932 * This is a queue of structs describing packets (fragments) that can
933 * (and may already have been) transmitted and are awaiting receipt
934 * acknowledgement.  Receipt acknowledgements can come in several flavors
935 * depending on whether you are a client or a server and whether there
936 * are fragments.  Adaquate acknowledgements are one of the following
937 * packets: fack, working, response, ack.  The key here is that if there
938 * is data on the xq then it must be there because it can't yet be tossed;
939 * it's awaiting an ack.
940 *
941 * All necessary encryption operations (on either just the header [for
942 * integrity] or on the header and the body [for privacy]) have been
943 * performed on the packets in this queue.  This queue is constructed
944 * using the information present in a XMIT IO Vector Queue.  Creation
945 * of Packet Queue Elements is controlled by resource consumption /
946 * transmit window availability.  Since encryption is based on a packet
947 * worth of data (including a complete pkt header), encryption must be
948 * delayed until the complete packet is "assembled".
949 *
950 * Periodically, some of the "packets" on the queue may need to be
951 * retransmitted because they've timed out.  They may also need to be
952 * retransmitted in response to a nocall or fack receipt.  After some
953 * period of no apparent acknowledgement arrivals you have to just give
954 * up.
955 *
956 * As fragment acknowledgements are received, the packet queue elements
957 * may be freed.  The transmit window will be adjusted, thereby allowing
958 * more data to be transmitted.
959 *
960 * Some background on packet sizes:  ".max_tsdu" is our local computation
961 * of how large a packet we can fit through our local tranport API.
962 * ".max_path_tpdu" is our local computation of the largest packet that
963 * we can send to our peer without incurring fragmentation.
964 * ".max_pkt_size" is the size of the packets we're actually currently
965 * sending to our peer.  This value is maintained to be the min of
966 * ".max_tsdu", ".max_path_tpdu", and the TPDU info of fack bodies we
967 * receive from our peer.
968 *
969 * ".awaiting_ack" is true in case we're expecting some sort of
970 * acknowledgement (e.g., response, fack, ack, working) from the receiver.
971 * This field (in conjunction with ".awaiting_ack_timestamp") is used
972 * to decide when to declare the receiver dead.
973 *
974 * The queue is empty when 'head' == NULL.
975 *
976 * Several fields within the queue are used for adjusting the blast size.
977 * This mechanism is not present for "fine tuning" the blast size; it
978 * is for the case where we have a very reliable connection to a fast
979 * reciever and facks are returning so quickly that we are not able to
980 * grow the congestion grow (i.e. we're not able to start a pipeline
981 * of outstanding packets).  ".max_blast_size" is the limit to the number
982 * of packets that will be sent back-to-back.  Periodically, if we aren't
983 * seeing lost packets and we notice that the congestion window is not
984 * reaching the advertised window size, we will increase the blast size
985 * by 2.  We may do this twice, reaching a maximum blast of 8.  The field
986 * ".high_cwindow" is used to keep track of congestion window growth
987 * between these periodic adjustments.  The time between adjustments
988 * is controlled by ".xq_timer", a counter which gets decremented each
989 * time we receive a fack which does not report a loss.  Initially we
990 * check after 8 such facks have arrived.  However, each time the blast
991 * size is adjusted, we increment ".xq_timer_throttle" which is used
992 * as a multiplier for ".xq_timer".  That is, the periods between
993 * considering a change to the blast size become longer and longer, to
994 * prevent oscillating around the blast size limit.
995 *
996 * The entire xmitq inherits the containing structure's locking
997 * requirements and is protected by that structure's lock.
998 */
999
1000typedef struct {
1001    rpc_dg_xmitq_elt_p_t head;          /* -> head pktq element */
1002    rpc_dg_xmitq_elt_p_t first_unsent;  /* -> 1st unsent pkt in the queue */
1003    rpc_dg_xmitq_elt_p_t tail;          /* -> tail pktq element */
1004    rpc_dg_xmitq_elt_p_t rexmitq;       /* -> pkts to be resent */
1005    rpc_dg_xmitq_elt_p_t part_xqe;      /* partially filled xmit queue element */
1006    rpc_dg_pkt_hdr_t hdr;               /* prototype pkt hdr */
1007    rpc_clock_t awaiting_ack_timestamp; /* when awaiting_ack was set */
1008    rpc_clock_t timestamp;              /* last (re)transmission time */
1009    rpc_clock_t rexmit_timeout;         /* time until next retransmission time */
1010    unsigned16 base_flags;              /* header flags constants for all pkts */
1011    unsigned16 base_flags2;             /* header flags constants for all pkts */
1012    unsigned16 next_fragnum;            /* next fragnum to use */
1013    unsigned16 next_serial_num;         /* unique serial # sent in each pkt   */
1014    unsigned16 last_fack_serial;        /* serial # that induced last recv'd fack */
1015    unsigned16 window_size;             /* receiver's window size (in fragments) */
1016    unsigned16 cwindow_size;            /* congestion window size (in fragments) */
1017    unsigned32 max_rcv_tsdu;            /* max receive data size supported by the LOCAL transport API (recvmsg) */
1018    unsigned32 max_snd_tsdu;            /* max send data size supported by the LOCAL transport API (sendmsg) */
1019    unsigned32 max_frag_size;           /* max frag size can be received/sent */
1020    size_t snd_frag_size;               /* send frag size, currently used */
1021    unsigned8 blast_size;               /* # of pkts to send as a blast */
1022    unsigned8 max_blast_size;           /* limit to the above value */
1023    unsigned16 xq_timer;                /* used by blast size code to delay adjustments */
1024    unsigned16 xq_timer_throttle;       /* multiplier to timer, to increase delays */
1025    unsigned8 high_cwindow;             /* highest value of .cwindow_size so far */
1026    unsigned8 freqs_out;                /* # of outstanding fack requests */
1027    unsigned push: 1;                   /* T => don't keep at least one pkt on queue */
1028    unsigned awaiting_ack: 1;           /* T => we are waiting for a xq ack event */
1029    unsigned first_fack_seen: 1;        /* T => we saw the first fack */
1030} rpc_dg_xmitq_t, *rpc_dg_xmitq_p_t;
1031
1032/*
1033 * The initial value of ".window_size".  The window size we will believe
1034 * the receiver is offering until we hear otherwise.
1035 */
1036#define RPC_C_DG_INITIAL_WINDOW_SIZE        8
1037
1038/*
1039 * The initial blast size, used when (re)starting a cwindow.
1040 */
1041#define RPC_C_DG_INITIAL_BLAST_SIZE         2
1042
1043/*
1044 * The default maximum blast size.  For some conversations, the actual
1045 * blast size used may be greater.
1046 */
1047#define RPC_C_DG_INITIAL_MAX_BLAST_SIZE     4
1048
1049/*
1050 * The absolute maximum blast size allowable under any circumstances.
1051 * Any increase in this value will require revisiting the code which determines
1052 * when fack requests are sent out (rpc__dg_call_xmit).
1053 */
1054#define RPC_C_DG_MAX_BLAST_SIZE             8
1055
1056/*
1057 * The initial value of the xq_timer field.  This is the number of "good" facks
1058 * we must see before considering an adjustment to the blast size.
1059 */
1060#define RPC_C_DG_INITIAL_XQ_TIMER           8
1061
1062/*
1063 * The initial value of ".max_pkt_size".  The size of the largest datagrams
1064 * we will send unless the receiver tells us we can send larger ones.  We
1065 * start small to deal with pre-v2 receivers, which deal exclusively in
1066 * 1024 byte packets.
1067 */
1068#define RPC_C_DG_INITIAL_MAX_PKT_SIZE       1024
1069
1070/*
1071 * Since the sockets used by the DG protocol are non-blocking, it is always
1072 * possible to receive an EWOULDBLOCK error status when trying to transmit
1073 * data.  Since this condition should be short-lived, what we'd like to do
1074 * is put the thread to sleep until the transmission can be done successfully.
1075 * This is fine when the send is being done from a client/call thread, since
1076 * the thread has nothing better to do at the time.  It *is* a problem if the
1077 * send is being done from the listener or timer threads;  in these cases,
1078 * there is other work that the thread could be doing for other threads.
1079 *
1080 * Unfortunately, we have not been totally successful in eliminating
1081 * all need for data transmissions from the listener/timer threads.  The
1082 * one exception in the case where the last packet(s) of a call's OUTS
1083 * are dropped.  Because of delayed acknowledgements, it is not desirable
1084 * to detain the server call thread while waiting for an ack from the
1085 * client.  In the worst case, the client could exit without returning
1086 * an ACK, and the server call thread would be hung up for 30 seconds
1087 * before it timed out.
1088 *
1089 * To avoid tieing up the thread, we will allow transmissions to be made
1090 * from the listener/timer thread in cases where the call has transitioned
1091 * to the final state.  However, if an EWOULDBLOCK error occurs, it will be
1092 * ignored, and the packet will have to wait for the next timeout to be resent.
1093 * This solution was deemed acceptable based on the following observations:
1094 *
1095 *      1) All packets have been successfully sent atleast once (w/o EWOULDBLOCK)
1096 *      2) On a timeout, there could be at most 4 packets left to send.  The
1097 *         transport algorithm would restart the congestion window by sending
1098 *         out two packets, both requesting facks.  Hopefully, at least one will
1099 *         get through.
1100 */
1101#define RPC_DG_START_XMIT(call) \
1102        if ((call)->state == rpc_e_dg_cs_final) \
1103            rpc__dg_call_xmit(call, false); \
1104        else \
1105            rpc__dg_call_signal(call);
1106
1107/*
1108 * And here's a macro to help decide if you should call the macro above.
1109 */
1110#define RPC_DG_CALL_READY_TO_SEND(call) ((call)->xq.blast_size > 0)
1111
1112/* ========================================================================= */
1113
1114/*
1115 * Receive packet queue element (RQE).
1116 *
1117 * An adorned packet.  The adornment consists of (1) a linked list pointer,
1118 * (2) the packet's source network address, and (3) a pointer to a "usable
1119 * header".  By "usable" we mean that the data rep is correct and that
1120 * the layout matches what the local compiler produces for the
1121 * "rpc_dg_pkt_hdr_t" struct.
1122 *
1123 * We choose to decouple the packet body from the element itself to lessen
1124 * our dependency on the idiosyncracies of various memory allocation
1125 * mechanisms.  ".pkt_real" points to the buffer that's been allocated
1126 * to hold the packet that arrives on the wire.  ".pkt" is an copy of
1127 * ".pkt_real" that's been aligned to a 0 mod 8 boundary.  (The stubs
1128 * expect data returned via "rpc_call_receive" and "rpc_call_transceive"
1129 * to be so aligned.)  All processing of the packet other than allocation
1130 * and freeing uses ".pkt", not ".pkt_real".
1131 *
1132 * ".hdrp" can point to either ".hdr" or ".pkt->hdr", depending on whether
1133 * the original header is usable.  This allows us to save data copies
1134 * in case the original header is usable.
1135 *
1136 * A private rqelt (i.e. not on a recvq) has no locking requirements.
1137 * A rqelt that is a member of a recvq essentially becomes part of that
1138 * data structure and inherits the recvq's locking requirements.
1139 */
1140
1141typedef struct rpc_dg_recvq_elt_t {
1142    struct rpc_dg_recvq_elt_t *next;
1143    struct rpc_dg_recvq_elt_t *more_data;  /* for multi-buffer fragments */
1144    rpc_dg_pkt_hdr_p_t hdrp;            /* -> usable header info */
1145    rpc_dg_pkt_hdr_t hdr;               /* pkt hdr in usable form */
1146    rpc_socket_t sock;                  /* socket for response */
1147    size_t frag_len;                    /* length of fragment, as recv'ed
1148                                         * iff a head of fragment */
1149    unsigned16 from_len;                /* length of ".from" */
1150    unsigned16 pkt_len;                 /* length of .pkt, as recv'ed */
1151    rpc_addr_il_t from;                 /* address of sender */
1152    rpc_dg_raw_pkt_p_t pkt;             /* the raw received packet (offset to
1153                                         * 0 mod 8 boundary) */
1154    rpc_dg_raw_pkt_p_t pkt_real;        /* the real start of the raw packet */
1155} rpc_dg_recvq_elt_t, *rpc_dg_recvq_elt_p_t;
1156
1157/*
1158 * Receive packet queue (RECVQ or RQ).
1159 *
1160 * Packets are removed off the head of the list (only in-sequence fragments
1161 * are given to stubs).  The packets are kept in fragment number order.
1162 *
1163 * As an optimization, a pointer tracks the "last inorder" packet on
1164 * the list to avoid scanning the entire list from the head to the tail
1165 * for the appropriate insertion point.  A queue length count is maintained
1166 * for resource utilization control (if the queue becomes too full,
1167 * received packets will just be ignored).
1168 *
1169 * If ".last_inorder" is NULL, then there is a "gap" at the beginning
1170 * of the queue or there are no pkts in the queue.
1171 *
1172 * The entire recvq inherits the containing structure's locking
1173 * requirements and is protected by that structure's lock.
1174 */
1175
1176typedef struct {
1177    rpc_dg_recvq_elt_p_t head;          /* -> head pktq element */
1178    rpc_dg_recvq_elt_p_t last_inorder;  /* -> last in-order frag in the queue */
1179    size_t high_rcv_frag_size;          /* largest frag size seen so far */
1180    unsigned16 next_fragnum;            /* next in-order frag we want to see */
1181    unsigned16 high_fragnum;            /* highest numbered fragnum so far */
1182    unsigned16 high_serial_num;         /* highest serial number seen so far */
1183    unsigned16 head_fragnum;            /* fragnum for the head of queue */
1184    unsigned16 head_serial_num;         /* serial # for the head of queue,
1185                                           iff head->hdrp == NULL */
1186    unsigned16 window_size;             /* our receive window size (in pkts) */
1187    unsigned16 wake_thread_qsize;       /* # of bytes to q before waking thread */
1188    unsigned16 max_queue_len;           /* max. # of frags allowed on queue */
1189    unsigned8 queue_len;                /* total frags on queue */
1190    unsigned8 inorder_len;              /* total inorder frags on queue */
1191    unsigned recving_frags: 1;          /* T => we are receiving frags */
1192    unsigned all_pkts_recvd: 1;         /* T => we've recv'd all data pkts */
1193    unsigned is_way_validated: 1;       /* T => we've passed the WAY check */
1194} rpc_dg_recvq_t, *rpc_dg_recvq_p_t;
1195
1196/*
1197 * Maximum number of packets we'll queue for any receiver.  This limit
1198 * is imposed in the interest of providing all threads with fair access
1199 * to RQE's.  Functionally, exceeding this limit will be handled the
1200 * same as if the receive packet quota had been exceeded.
1201 */
1202
1203#define RPC_C_DG_MAX_RECVQ_LEN       96
1204
1205/* ========================================================================= */
1206
1207/*
1208 * Client connection table (CCT) and connection table elements (CCTE).
1209 *
1210 * Keeps track of all "connections" from the local client address space
1211 * to remote servers.  The CCT is keyed by authentication info.  The
1212 * CCT is a hash table with separate chaining.
1213 *
1214 * A client wanting to make a call picks a connection to use by looking
1215 * up a non-inuse CCTE that has a matching authentication information
1216 * handle.  If it finds an entry, it uses that entry's activity ID (actid)
1217 * and sequence number in its call.  The client increments the sequence
1218 * number in the table and sets the "in use" flag for the duration of
1219 * the client's call.  If the client finds no matching entry, it creates
1220 * a new entry by generating a new UUID as the activity ID.  Maintain
1221 * the chains in "oldest first" order.  This will cause older available
1222 * entries to be reused before newer entries thereby naturally limiting
1223 * the ccte (actid) selection to a smaller set.
1224 *
1225 * The CCT is garbage collectable -- slots containing entries that are
1226 * not "in use" can be re-assigned to new auth's.  Any deletions in the
1227 * CCT *must* increment the CCT's GC counter.
1228 *
1229 * See "dgglob.h" for definition of the table itself.
1230 *
1231 * A CCTE that is not inuse is "owned" by the CCT and inherits its locking
1232 * requirements.  When a CCTE is inuse (".refcnt" > 1 -- note that the
1233 * CCT's reference itself counts as a reference), all fields except the
1234 * next field are "owned" by the call that is using this connection.
1235 * The next field is always "owned" by the CCT.
1236 *
1237 * The relationship between the CCTEs, activity ids, auth-infos, call
1238 * handles, and binding handles is important (to make things work at
1239 * all, as well as work efficiently).  So, here's more info on the topic:
1240 *
1241 *      Actids are the cornerstone of all client / server conversations.
1242 *      Servers identify clients by an actid.
1243 *
1244 *      Actids have an associated non-decreasing RPC Call Sequence Number.
1245 *
1246 *      A single actid may be used by a single RPC at a time.
1247 *
1248 *      Actids have an associated authentication identity which is fixed
1249 *      for the lifetime of the actid.  If for no other reason, this
1250 *      mapping of an actid to an auth-info is an artifact of the NCA
1251 *      DG protocol.  (There is no free space in the DG packet header,
1252 *      so the actid is "overloaded" to allow the server to determine
1253 *      the client's auth-info.)
1254 *
1255 *      A single auth-info may be bound to any number of NCS binding
1256 *      handles (handle_t) subject to the auth package and application
1257 *      restrictions.  (I.e., the authentication package decides whether
1258 *      the same auth-info can be used for multiple servers that happen
1259 *      to have the same principal ID.)
1260 *
1261 *      Servers cache state across RPCs based on actid to lessen the
1262 *      need for the server to callback a client to validate the RPC
1263 *      sequence number or learn the auth session key.
1264 *
1265 *      For clients to take advantage of server caching, they are
1266 *      encouraged to reuse actids on subsequent RPCs to a server that
1267 *      already knows that actid.
1268 *
1269 * Subtlety relating to server boot time
1270 * -------------------------------------
1271 *
1272 * Clients who don't (yet) know a server's boot time (i.e., whose binding
1273 * handle ".server_boot" time is zero) MUST generate a new CCTE/actid
1274 * before making a call.  Doing so ensures that the server does a WAY
1275 * callback to the client and that the client acquires the boot time.
1276 * The problem case we're trying to avoid is as follows:
1277 *
1278 * - Client creates a binding to a server and calls it.
1279 * - The server calls back to client (WAY) causing the binding to acquire
1280 *   the server's boot time.
1281 * - The client creates a NEW binding to the same server and calls it
1282 *   using the same actid as in previous call.
1283 *
1284 * Since the server already knows about this actid (and sequence number)
1285 * it does NOT call back and the new binding doesn't acquire the server's
1286 * boot time.  This can cause protocol problems (inability to detect
1287 * a duplicate WAY from a rebooted instance of a server that's already
1288 * executed our call once).  (See "conv_who_are_you" in "conv.c" for
1289 * background.)
1290 *
1291 * What's going on here is that on the one hand we're trying to minimize
1292 * the number of actids we create (in an attempt to minimize the number
1293 * of WAY callbacks that happen) and we can't (easily) keep track of
1294 * the boot times of all the servers which we've called with each actid,
1295 * while on the other hand, we MUST know the server boot time to maintain
1296 * "at most once" semantics.  You might imagine that a CCTE could hold
1297 * a list of boot times (keyed by server location) and that when you
1298 * picked up a CCTE, you'd stick the right boot time from its list into
1299 * the binding handle, but this would be complicated (if it works at all!).
1300 * We take the simpler approach of forcing new CCTE/actids to be created
1301 * for each binding.  This results in an excess of CCTEs, but they can
1302 * be put to good effect later (e.g., in parallel calls being made using
1303 * a single binding).
1304 *
1305 * Another fallout from this approach is that when a first call on a
1306 * binding gets a comm failure (i.e., times out), there are cases where
1307 * we can KNOW that the server didn't execute the call (i.e., in case
1308 * the call was to a non-idem procedure and the boot time in the binding
1309 * is zero--i.e., the server didn't call us back).  This turns out to
1310 * be useful since when a client has multiple bindings to some sort of
1311 * replicated service, there are (more) cases where it knows that it's
1312 * safe to move onto another binding (i.e., without accidentally executing
1313 * the call more than once).  We expect this to be a common occurrence
1314 * (e.g., in network partitions where some of the bindings you have are
1315 * to unreachable servers).
1316 */
1317
1318typedef struct rpc_dg_cct_elt_t {
1319    struct rpc_dg_cct_elt_t *next;      /* -> next in hash chain */
1320    rpc_auth_info_p_t auth_info;        /* auth info to be used with server */
1321    rpc_key_info_p_t key_info;       /* key to use */
1322    struct rpc_dg_auth_epv_t *auth_epv; /* auth epv */
1323    idl_uuid_t actid;                       /* activity ID to use in msgs to server */
1324    unsigned32 actid_hash;              /* uuid_hash(.actid) */
1325    unsigned32 seq;                     /* seq # to use in next call to server */
1326    rpc_clock_t timestamp;              /* last time connection used in a call */
1327    unsigned8 refcnt;                   /* # of references to the CCTE */
1328} rpc_dg_cct_elt_t, *rpc_dg_cct_elt_p_t;
1329
1330#define RPC_DG_CCT_SIZE 29              /* Must be prime */
1331
1332typedef struct rpc_dg_cct_t {
1333    unsigned32 gc_count;
1334    struct {
1335        rpc_dg_cct_elt_p_t first;
1336        rpc_dg_cct_elt_p_t last;
1337    } t[RPC_DG_CCT_SIZE];
1338} rpc_dg_cct_t;
1339
1340/*
1341 * Client Connection Table Element Soft Reference.
1342 *
1343 * A "soft reference" is a reference that can cope with the fact that
1344 * the thing pointed to might be garbage collected (i.e., freed).  The
1345 * actual pointer in a soft reference is accompanied by a the "GC count"
1346 * for the table the pointee belongs to.  When any entry in the table
1347 * is GC'd, the GC count of the table is incremented.  The actual pointer
1348 * is considered valid iff the soft ref's GC count (which was the table
1349 * GC count at the time the soft ref was created) matches the table's
1350 * current GC count.
1351 *
1352 * CCT soft refs are used by call handles to refer to CCTEs that are
1353 * not in use (and hence are GC-able).
1354 */
1355
1356typedef struct rpc_dg_cct_elt_ref_t {
1357    struct rpc_dg_cct_elt_t *ccte;  /* soft -> CCTE */
1358    unsigned32 gc_count;            /* CCT GC ref count for above pointer */
1359} rpc_dg_ccte_ref_t, *rpc_dg_ccte_ref_p_t;
1360
1361/* ========================================================================= */
1362
1363/*
1364 * Call handle types.
1365 */
1366
1367/* ========================================================================= */
1368
1369/*
1370 * Call states.
1371 *
1372 * For both client and server call handles, the only time that a handle
1373 * isn't actively performing or associated with a specific call is when
1374 * the handle is in the "idle" state.
1375 *
1376 * Client Call Handle State Transitions:
1377 *
1378 *                                                   end_call()
1379 *  start_call()                   transceive()      non-idempotent or
1380 *  handle        transceive()     non-maybe         idempotent w/large outs
1381 *  created       transmit()       call              call
1382 *    |   +------+         +------+         +------+         +------+
1383 *    +-->| init |-------->| xmit |-------->| recv |-------->|final |---+
1384 *        +------+         +------+         +------+         +------+   |
1385 *         ^  ^           / |end_call() end_call()| \           |       |
1386 *         |  |          /  |quit             quit|  \          |       |
1387 *         |  |         /   |       +------+      |   \         |       |
1388 *         |  |        /    +------>|orphan|<-----+    \        |       |
1389 *         |  |       /             +------+            \       |       |
1390 *         |  |       \                | end_call()     /       |       |
1391 *         |  |        \               V quack signal  /        |       |
1392 *         |  |         \           +------+          /         |       |
1393 *         |  |          ---------->| idle |<---------          |       |
1394 *         |  |          end call() +------+  end call()        |       |
1395 *         |  |          maybe call   |  ^    idempotent call   |       |
1396 *         |  |                       |  |                      |       |
1397 *         |  +-----------------------+  +----------------------+       |
1398 *         |        start call()                     ack sent           |
1399 *         +------------------------------------------------------------+
1400 *                             start_call() - new call
1401 *
1402 *
1403 * Server Call Handle State Transitions:
1404 *
1405 *                                                   stub returns
1406 *  do_request()   execute_call()                    non-idempotent or
1407 *  handle         stub is                           idempotent w/large outs
1408 *  created        being called    transmit()        call
1409 *    |   +------+(*)      +------+         +------+         +------+
1410 *    +-->| init |-------->| recv |-------->| xmit |-------->|final |---+
1411 *        +------+         +------+         +------+         +------+   |
1412 *         ^  ^ | WAY     / |quit rcvd   quit rcvd| \           |       |
1413 *         |  | | rejects/  |                     |  \          |       |
1414 *         |  | | call  /   |       +------+(*)   |   \         |       |
1415 *         |  | |      /    +------>|orphan|<-----+    \        |       |
1416 *         |  | |     /             +------+            \       |       |
1417 *         |  | |     \                                 /       |       |
1418 *         |  | |      \                               /        |       |
1419 *         |  | |       \           +------+          /         |       |
1420 *         |  | |        ---------->| idle |<---------          |       |
1421 *         |  | |    stub returns   +------+   stub returns     |       |
1422 *         |  | |      maybe call    ^ |  ^    idempotent call  |       |
1423 *         |  | +--------------------+ |  +---------------------+       |
1424 *         |  +-------------------------             ack rcvd           |
1425 *         |        new call rcvd                                       |
1426 *         +------------------------------------------------------------+
1427 *                              new call rcvd
1428 *
1429 * (*) Server calls leave the "orphan" state by exiting.
1430 */
1431typedef enum {
1432    rpc_e_dg_cs_init,       /* call initialized and in use */
1433    rpc_e_dg_cs_xmit,       /* call in use; currently sending data */
1434    rpc_e_dg_cs_recv,       /* call in use; awaiting data */
1435    rpc_e_dg_cs_final,      /* call in use; delayed ack pending */
1436    rpc_e_dg_cs_idle,       /* call NOT in use */
1437    rpc_e_dg_cs_orphan      /* call orphaned; waiting to exit */
1438} rpc_dg_call_state_t;
1439
1440/* ========================================================================= */
1441
1442/*
1443 * Call handle common header (CALL).
1444 *
1445 * Defines data that is common to client and server call handles
1446 * (see below).  Note that we're using the transmit queue's prototype
1447 * packet header as the repository for various per-call state (e.g. seq
1448 * #, interface ID).
1449 *
1450 * The mutex (".mutex") protects fields in the composite call handles
1451 * (i.e., CCALLs and SCALLs).  The call handle mutex is a level 2 lock.
1452 *
1453 * The condition variable (".cv") is used to wait for changes in the
1454 * call handle (typically, changes to the transmit and receive queues)
1455 * and is partnered with the handle's mutex.
1456 *
1457 * The high_seq field is used to keep track of the sequence number space
1458 * in the event of callbacks.  This can get updated in two ways.  First,
1459 * by receiving a response with a bumped-up sequence number, as in the
1460 * 1.5 code.  Second, by receiving a request packet on the current activity
1461 * ID.  The second form will help avoid problems with having a callback
1462 * die (timeout, etc) and not receiving the results from the original
1463 * call;  in this case, we will still begin a new call with the appropriate
1464 * sequence number.
1465 *
1466 * The reference count (".refcnt") keeps track of all references to the
1467 * call handle.  For client call handles, references can be from:
1468 *
1469 *      - Client binding handles (cached client call handles).
1470 *      - The CCALLT.
1471 *      - The application thread (via the return from "start call").
1472 *      - The call handle's timer.
1473 *
1474 * Almost all fields are protected by the call handle's lock.  Two
1475 * exceptions: (1) the ".next" field, which is essentially owned and
1476 * protected by the data structure upon which the call handle is chained
1477 * (i.e. the binding handle); (2) the ".is_in_pkt_chain" flag, which
1478 * is owned and protected by the packet pool logic (and is therefore
1479 * wrapped with "unsigned : 0"s to (hopefully) force alignment).
1480 *
1481 * All call handle lock, condition wait and signalling operations should
1482 * be done via the macros below.
1483 */
1484
1485typedef struct rpc_dg_call_t {
1486    rpc_call_rep_t c;                   /* call handle common header */
1487    struct rpc_dg_call_t *next;         /* -> next in chain */
1488    rpc_dg_call_state_t state;          /* call state */
1489    unsigned32 status;                  /* call's error status indicator / value */
1490    rpc_clock_t state_timestamp;        /* time we entered the current state */
1491    rpc_cond_t cv;                      /* conditional variable (->c.m is mutex) */
1492    rpc_dg_xmitq_t xq;                  /* transmit queue */
1493    rpc_dg_recvq_t rq;                  /* receive queue */
1494    struct rpc_dg_sock_pool_elt_t *sock_ref;   /* reference to socket pool element */
1495    unsigned32 actid_hash;              /* uuid_hash(.call_actid) */
1496    rpc_key_info_p_t key_info;       /* key info */
1497    struct rpc_dg_auth_epv_t *auth_epv; /* auth epv */
1498    rpc_addr_p_t addr;                  /* location (network address) of peer */
1499    rpc_timer_t timer;                  /* timer */
1500    rpc_clock_t last_rcv_timestamp;     /* last time we rcv'd some packets for this call */
1501    rpc_clock_t start_time;             /* time call started */
1502    unsigned32 high_seq;                /* seq # from response packets or callback-generated call handles */
1503    struct rpc_dg_call_t *pkt_chain;    /* linked list used when waiting for an XQE. */
1504    unsigned32 com_timeout_knob;        /* com timeout control knob */
1505    dcethread* thread_id;               /* iff client is using a private socket*/
1506    unsigned8 refcnt;                   /* # of references to the call */
1507    unsigned8 n_resvs;                  /* # of packets reserved */
1508    unsigned8 n_resvs_wait;             /* # of packets waiting */
1509    unsigned8 max_resvs;                /* max # of pkts possibly reserved */
1510    unsigned blocked_in_receive: 1;     /* private socket users only */
1511    unsigned priv_cond_signal: 1;       /* T => call is being woken from recvfrom */
1512    unsigned stop_timer: 1;             /* T => timer should self-destruct at next execution */
1513    unsigned is_cbk: 1;                 /* T => this call handle was created specifically for a callback */
1514    unsigned : 0;                       /* force alignment */
1515    unsigned is_in_pkt_chain: 1;        /* T => waiting for an XQE to become available (see comments above!) */
1516    unsigned : 0;                       /* force alignment */
1517} rpc_dg_call_t, *rpc_dg_call_p_t;
1518
1519/*
1520 * Logically these fields are part of the CALL, but they live in the
1521 * transmit queue's prototype packet header as an optimization.
1522 */
1523
1524#define call_actid          xq.hdr.actuid
1525#define call_object         xq.hdr.object
1526#define call_if_id          xq.hdr.if_id
1527#define call_if_vers        xq.hdr.if_vers
1528#define call_ihint          xq.hdr.ihint
1529#define call_ahint          xq.hdr.ahint
1530#define call_opnum          xq.hdr.opnum
1531#define call_seq            xq.hdr.seq
1532#define call_server_boot    xq.hdr.server_boot
1533
1534/*
1535 * The various operations on the call handle mutex and condition variables.
1536 */
1537
1538#define RPC_DG_CALL_LOCK_INIT(call)     RPC_CALL_LOCK_INIT(&(call)->c)
1539#define RPC_DG_CALL_LOCK(call)          RPC_CALL_LOCK(&(call)->c)
1540#define RPC_DG_CALL_UNLOCK(call)        RPC_CALL_UNLOCK(&(call)->c)
1541#define RPC_DG_CALL_TRY_LOCK(call,bp)   RPC_CALL_TRY_LOCK(&(call)->c,(bp))
1542#define RPC_DG_CALL_LOCK_DELETE(call)   RPC_CALL_LOCK_DELETE(&(call)->c)
1543#define RPC_DG_CALL_LOCK_ASSERT(call)   RPC_CALL_LOCK_ASSERT(&(call)->c)
1544#define RPC_DG_CALL_UNLOCK_ASSERT(call) RPC_CALL_UNLOCKED_ASSERT(&(call)->c)
1545
1546#define RPC_DG_CALL_COND_INIT(call)     RPC_COND_INIT((call)->cv, (call)->c.m)
1547#define RPC_DG_CALL_COND_DELETE(call)   RPC_COND_DELETE((call)->cv, (call)->c.m)
1548#define RPC_DG_CALL_COND_WAIT(call)     RPC_COND_WAIT((call)->cv, (call)->c.m)
1549#define RPC_DG_CALL_COND_SIGNAL(call)   RPC_COND_SIGNAL((call)->cv, (call)->c.m)
1550
1551#define RPC_DG_CALL_IS_SERVER(call)     RPC_CALL_IS_SERVER(&(call)->c)
1552#define RPC_DG_CALL_IS_CLIENT(call)     RPC_CALL_IS_CLIENT(&(call)->c)
1553
1554/*
1555 * A common function for changing the call handle state.
1556 */
1557
1558#define RPC_DG_CALL_SET_STATE(call, s) { \
1559    if ((call)->state != (s)) { \
1560        RPC_DBG_PRINTF(rpc_e_dbg_dg_state, 2, ("(RPC_DG_CALL_SET_STATE) " #call "=%p, old state=%u, new state=%u\n", \
1561                        (call), (int) (call)->state, (int) (s))); \
1562        (call)->state = (s); \
1563        (call)->state_timestamp = rpc__clock_stamp(); \
1564    } \
1565}
1566
1567/* ========================================================================= */
1568
1569/*
1570 * Server call handle (SCALL).
1571 *
1572 * Defines the dg-specific, server-specific structure referred to
1573 * from an rpc_call_rep_t.
1574 *
1575 * To support normal callbacks, an SCALL is linked with its paired CCALL
1576 * (a CCALL with the same actid as the SCALL) via the cbk_ccall field.
1577 *
1578 * .has_call_executor_ref means that one of the scall's referece counts
1579 * is for the rpc__dg_execute_call() processing.  This flag was introduced
1580 * for orphan processing since orphaned scalls can't have their final cleanup
1581 * performed until the call executor processing has completed.
1582 *
1583 * Callbacks
1584 * --------
1585 *
1586 * Callback CCALLs linger around (cached on the paired scall) until the
1587 * paired scall processing frees them.
1588 *
1589 * The following shows the relationships among the SCT, CCALLs, and SCALLs
1590 * in the case of callback processing in the original server process
1591 * (i.e. the process where the server manager is calling back to the
1592 * original client; where the callback is originating).  Note the values
1593 * of the {s,c}call fields in this picture and how the differ from the
1594 * subsequent picture; this is critical to understanding callback
1595 * relationships.
1596 *
1597 * This is only the original server process half of a callback.  Refer
1598 * to the following description of CCALLs for the special relationships
1599 * that exist for a SCALL that is created to perform a callback.
1600 *
1601 *        SCT
1602 *  +------+------+
1603 *  |      |      |
1604 *  |-------------|             SCALL
1605 *  |  U1  |  ----|------> +--------------+ <---------------------+
1606 *  |-------------| <---+  | .c.is_cbk = F|                       |
1607 *  |      |      |     |  |--------------|                       |
1608 *  |-------------|     +--|-- .scte      |          is_cbk       |
1609 *  |      |      |        |--------------|          CCALL        |
1610 *  |-------------|        | .cbk_ccall --|---> +--------------+  |
1611 *  |      |      |        +--------------+     | .c.is_cbk = T|  |
1612 *  |-------------|                             |--------------|  |
1613 *  |      |      |                             | .ccte_ref = 0|  |
1614 *  +-------------+                             |--------------|  |
1615 *                                              | .cbk_scall --|--+
1616 *                                              +--------------+
1617 *
1618 * See the subsequent CCALL description for more info on callbacks
1619 * (ESPECIALLY THE LOCKING HIERARCHY).
1620 *
1621 * All fields are protected by the common call handle lock.
1622 */
1623
1624typedef struct rpc_dg_scall_t {
1625    rpc_dg_call_t c;                    /* call handle common header */
1626    rpc_dg_recvq_elt_p_t fwd2_rqe;  /* if non-NULL, -> 1st half of 2-part forwarded pkt */
1627    struct rpc_dg_sct_elt_t *scte;
1628    struct rpc_dg_ccall_t *cbk_ccall;   /* -> callback paired ccall */
1629    struct rpc_dg_binding_server_t *h;  /* binding handle associated with this call */
1630    unsigned client_needs_sboot: 1;     /* T => client needs to be WAY'd to get it the server boot time */
1631    unsigned call_is_setup: 1;          /* T => "call executor" has been established */
1632    unsigned has_call_executor_ref: 1;  /* T => "call executor" has ref */
1633    unsigned call_is_queued: 1;         /* T => call has been queued */
1634} rpc_dg_scall_t, *rpc_dg_scall_p_t;
1635
1636/* ========================================================================= */
1637
1638/*
1639 * Client call handle (CCALL).
1640 *
1641 * Defines the dg-specific, client-specific structure referred to
1642 * from an rpc_call_rep_t.
1643 *
1644 * CCALLs are entered into the CCALL table (CCALLT); see below.
1645 *
1646 * A call handle is associated with both a single binding handle and
1647 * a single CCTE.  In addition to providing the data structures for a
1648 * in-progress call, a call handle provides a inter-RPC cache of useful
1649 * information to allow us to quickly start up subsequent RPCs.  Changes
1650 * to the state of the binding handle (e.g. object id, server location)
1651 * require that the call handle be appropriatly updated.  On every call,
1652 * the call handle's per call state (e.g. interface id, ihint, opn) must
1653 * be properly initialized.
1654 *
1655 * An in-progress call increments its associated CCTE's reference count
1656 * for the duration of the call (thereby reserving the CCTE's actid).
1657 * The reference count should not be decremented until the call no longer
1658 * requires the exclusive use of that actid.
1659 *
1660 * A call handle may be re-associated with a new CCTE (if the last one
1661 * it used happens to be "inuse" or has been freed and a call is starting
1662 * up).  If such a re-association occurs, cached activity related info in
1663 * the call handle (e.g., the actid and the ahint) need to be reinitialized.
1664 *
1665 * Callbacks
1666 * ---------
1667 *
1668 * The server call handle (".cbk_scall") refers to the handle of a callback
1669 * from the remote server to the local client.  Callbacks are indicated
1670 * by the receipt of request packet on a socket being used by a client;
1671 * the activity ID in the request must match the activity ID being used
1672 * by the client making the call.  (Requests packets with non-matching
1673 * activity IDs received on client sockets are discarded.)
1674 *
1675 * When a callback request is received, the request packet handling code
1676 * sets ".cbk_start" and awakens the application client thread to let
1677 * it know to start executing the callback.
1678 *
1679 * Callback SCALLs linger around for a while (cached on the paired ccall)
1680 * in the case of a non-idempotent callback that is awaiting a response
1681 * ack.  The callback SCALL is freed when the original call completes.
1682 *
1683 * The following shows the relationships among the CCALLT, CCALLs, and
1684 * SCALLs in the case of callback processing in the original client
1685 * processing (i.e. where the callback manager is executing).  Note the
1686 * values of the {s,c}call fields in this picture and how the differ
1687 * from the previous picture; this is critical to understanding callback
1688 * relationships.
1689 *
1690 * This is only the original client process half of a callback.  Refer
1691 * to the above description of SCALLs for the special relationships that
1692 * exist for a CCALL that is created to perform a callback.
1693 *
1694 *      CCALLT
1695 *  +------+------+
1696 *  |      |      |
1697 *  |-------------|             CCALL
1698 *  |  U1  |  ----|------> +--------------+ <---------------------+
1699 *  |-------------| <---+  | .c.is_cbk = F|                       |
1700 *  |      |      |     |  |--------------|                       |
1701 *  |-------------|     +--|-- .ccte_ref  |          is_cbk       |
1702 *  |      |      |        |--------------|          SCALL        |
1703 *  |-------------|        | .cbk_scall --|---> +--------------+  |
1704 *  |      |      |        +--------------+     | .c.is_cbk = T|  |
1705 *  |-------------|                             |--------------|  |
1706 *  |      |      |                             | .scte = NULL |  |
1707 *  +-------------+                             |--------------|  |
1708 *                                              | .cbk_ccall --|--+
1709 *                                              +--------------+
1710 *
1711 * Note the special case of the "conv_who_are_you" (WAY) callback used
1712 * to do "connection management".  For protocol correctness reasons,
1713 * the request packet in this callback does not have the same activity
1714 * ID as the client.  We handle this case specially (no cbk scall is used);
1715 * see comments above "rpc__dg_handle_conv" for details.
1716 *
1717 *
1718 * Proxy Calls
1719 * -----------
1720 *
1721 * Proxy calls are calls from a server manager during the execution of
1722 * an "originating" call that are performed using the client's activity
1723 * id (hence sequence number space).  Callbacks as described above are
1724 * one form of proxy calls.  The sequence number from the server's response
1725 * packet header tells us the highest sequence number it consumed doing
1726 * proxy calls is saved (".high_seq").  This enables us to properly
1727 * manage this activities sequence number space in the face of such calls.
1728 * When the original call completes, the value of the response sequence
1729 * number is stored back into the CCTE.
1730 *
1731 * All fields are protected by the common call handle lock.
1732 *
1733 * LOCKING HIERARCHY:
1734 *  The only occasion where more than one call handle may require locking
1735 *  at any instant is due to callbacks.  The locking hierarchy for callback
1736 *  ccall / scall pairs depends on which side of the wire you're on (which
1737 *  really means which call of the pair has been tagged ".is_cbk == true").
1738 *  The reason for the difference is for convienience to the listener
1739 *  processing.  In the original client process, the listener will have
1740 *  a ccall and need to get the associated is_cbk scall.  In the original
1741 *  server process the listener will have a scall and will need to get
1742 *  the associated is_cbk ccall.  See the above for a visual description.
1743 *
1744 *  So, the locking hierarchy order is (first, second):
1745 *      ccall, is_cbk scall
1746 *      scall, is_cbk ccall
1747 */
1748
1749/*
1750 * Ping information (part of CCALL).
1751 */
1752
1753typedef struct rpc_dg_ping_info_t {
1754    rpc_clock_t next_time;          /* time to send next ping */
1755    rpc_clock_t start_time;         /* time we started pinging */
1756    unsigned16 count;               /* # of unack'd pings sent in a row */
1757    unsigned pinging: 1;            /* T => ping has been sent but not ack'd */
1758} rpc_dg_ping_info_t;
1759
1760#define RPC_C_DG_FIRST_PING_INTERVAL    RPC_CLOCK_SEC(2)
1761#define RPC_C_DG_MAX_INTER_PING_TIME    RPC_CLOCK_SEC(8)
1762
1763#define RPC_DG_PING_INFO_INIT(ping) \
1764{ \
1765    (ping)->pinging   = false; \
1766    (ping)->next_time = rpc__clock_stamp() + RPC_C_DG_FIRST_PING_INTERVAL; \
1767}
1768
1769#define RPC_PING_INFO_NEXT(ping, now) \
1770{ \
1771    (ping)->next_time = (now) + MIN(RPC_C_DG_MAX_INTER_PING_TIME, RPC_C_DG_FIRST_PING_INTERVAL << (ping)->count); \
1772    (ping)->count++; \
1773}
1774
1775/*
1776 * Quit information (part of CCALL).
1777 */
1778
1779typedef struct rpc_dg_quit_info_t {
1780    rpc_clock_t next_time;          /* time to send next quit */
1781    unsigned quack_rcvd: 1;         /* quack received notification flag */
1782} rpc_dg_quit_info_t;
1783
1784/*
1785 * Cancel information (part of CCALL).
1786 */
1787
1788typedef struct rpc_dg_cancel_info_t {
1789    rpc_clock_t next_time;          /* time to (re)send cancel request */
1790    unsigned16 local_count;         /* # of detected local cancel events */
1791    unsigned16 server_count;        /* # of server-accepted cancel events */
1792    rpc_clock_t timeout_time;       /* when to give up */
1793    unsigned server_is_accepting: 1;
1794    unsigned server_had_pending: 1;
1795} rpc_dg_cancel_info_t;
1796
1797/*
1798 * The CCALL itself.
1799 */
1800
1801typedef struct rpc_dg_ccall_t {
1802    rpc_dg_call_t c;                /* call handle common header */
1803    rpc_dg_recvq_elt_p_t fault_rqe; /* received call fault rqe */
1804    unsigned32 reject_status;       /* if non-0, then value rcv'd in a reject pkt */
1805    unsigned cbk_start: 1;          /* T => awakened to start a callback */
1806    unsigned response_info_updated: 1; /* T => ahint, etc.. has been updated */
1807    unsigned server_bound: 1;       /* T => "real" server address is known */
1808    rpc_dg_scall_p_t cbk_scall;     /* -> callback paired scall */
1809    rpc_dg_ccte_ref_t ccte_ref;     /* a soft ref to the associated CCTE */
1810    struct rpc_dg_binding_client_t *h;  /* binding handle that started this call */
1811    rpc_dg_ping_info_t ping;        /* ping information */
1812    rpc_dg_quit_info_t quit;        /* quit information */
1813    rpc_dg_cancel_info_t cancel;    /* cancel information */
1814    rpc_clock_t timeout_stamp;      /* max call execution time */
1815    unsigned_char_p_t auth_way_info;/* ptr to oversized auth PAC buffer */
1816    unsigned32 auth_way_info_len;   /* length of preceding buffer */
1817} rpc_dg_ccall_t, *rpc_dg_ccall_p_t;
1818
1819/* ========================================================================= */
1820
1821/*
1822 * Client call handle table (CCALLT).
1823 *
1824 * A mapping from activity IDs (the keys) to client calls.  The CCALLT
1825 * is a hash table with separate chaining.  The CCALLT is used by the
1826 * packet listen loop to dispatch incoming packets received on client
1827 * connection sockets to the appropriate call.  The CCALLT is a hash
1828 * table with separate chaining.
1829 *
1830 * In the case of callback related packets (i.e. client -> server pkts),
1831 * the ahint in the packet header may be used as an index into this table.
1832 *
1833 * See "dgglob.h" for definition of the table itself.
1834 *
1835 * The CCALLT (scanning, inserting, deleting) is protected by the global lock.
1836 */
1837
1838#define RPC_DG_CCALLT_SIZE 29           /* Must be prime */
1839
1840/* ======================================================================== */
1841
1842/*
1843 * Server connection table (SCT)
1844 *
1845 * A mapping from remote client activity IDs (the keys) to server calls.
1846 * The SCT is a hash table with separate chaining.  The SCT is used by
1847 * the packet listen loop to dispatch incoming packets received on server
1848 * connection sockets to the appropriate server call handle.  Additionally
1849 * the SCT holds "inter-call history" about remote clients (seq and
1850 * auth_info).
1851 *
1852 * The SCT is roughly the server-side analog to the CCALLT and CCT.  It's
1853 * like the CCALLT in that it's the database for demultiplexing packets
1854 * to call handles based on the packet's activity ID.  It's like the
1855 * CCT in that it maintains inter-call history.  We maintain this
1856 * information as a single table on the server side so that we can deal
1857 * with the case of request from previously unknown clients without having
1858 * to do lookups/inserts into two tables.  (The client being the initiator
1859 * of calls doesn't have the problem of dealing with packets arriving
1860 * from unknown servers.)
1861 *
1862 * The ".ahint" field in the packet header of packets sent from client
1863 * to server (i.e. NOT callback) is an index into the SCT.
1864 *
1865 * Logically, a "server" maintains some RPC sequence number information
1866 * for a connection to model the client's sequence number state; this
1867 * is done to allow the server to detect/prevent reruns of non-idempotent
1868 * RPCs.  The server is only truely synchronized with the client when
1869 * it performs a WAY to definitively learn the client's current sequence
1870 * number.  In all other instances the model is only approximate due
1871 * to the fact that the server doesn't necessarily see all RPCs the client
1872 * makes (nor is the client obgligated to only increase the seq by 1
1873 * on each succesive call).
1874 *
1875 * At any instant, the SCTE ".high_seq" represents the *highest* RPC
1876 * seq of the following: "tentatively accepted" RPCs for execution by
1877 * the server, RPCs actually executed by the server or the result of
1878 * a WAY.  The creation of a SCTE occurs because a request pkt for a
1879 * connection is received and the server knows nothing about the
1880 * connection.  A created SCTE's ".high_seq" is initialized to the
1881 * (inducing_request_seq - 1); logically the highest previous call that
1882 * the server could have known about.
1883 *
1884 * A call may be tentatively accepted as long as it's sequence number
1885 * is greater than the SCTE ".high_seq"; this new sequence becomes
1886 * the SCTE ".high_seq".  The state of the SCTE ".high_seq" is represented
1887 * by ".high_seq_is_way_validated".  Initially ".high_seq_is_way_validated"
1888 * is false; it is set to true once a WAY is performed to the client.
1889 * A WAY validated SCTE ".high_seq" must be used for comparison prior
1890 * the actual execution (stub dispatch) of a tentatively accepted
1891 * Non-idempotent RPC.
1892 *
1893 * Note that in the case of maybe-calls, it is not necessary for the
1894 * call's sequence number to be greater that the SCTE ".high_seq", since
1895 * the call's request packet could have been (legally) reordered wrt a
1896 * packet from a subsequent call; in this case the maybe call will not
1897 * update the ".high_seq" field.
1898 *
1899 * The SCTE ".scall" field points to a SCALL for the connection.  This
1900 * field is used both to locate the SCALL for an in-progress call and
1901 * as a place to cache a previously created / used SCALL.  If the SCALL
1902 * ".call_seq" field matches the SCTE ".high_seq" field then the SCALL
1903 * is for the connection's current (or just completed) call; otherwise
1904 * the SCALL is just being cached and logically does not contain useful
1905 * information.
1906 *
1907 * The SCTE ".maybe_chain" field points to a list of scalls which represent
1908 * currently/recently executing calls made using the "maybe" attribute.
1909 * Since the client does not wait for such calls to complete before
1910 * continuing, it's perfectly legal to have several of maybe calls executing
1911 * in paralel.
1912 *
1913 * See the dgsct.[ch] for the operations available for the SCT.
1914 *
1915 * Each SCTE is reference counted.  The SCALLs reference to the SCTE
1916 * counts as a reference.  Lookup and get functions increment the ref
1917 * count since they are returning a reference.  The SCT reference to the
1918 * SCTE DOES count as a reference.
1919 *
1920 * The SCT is garbage collectable -- SCTEs that are not "inuse" (i.e.
1921 * refcnt == 1; only referenced by the SCT) can be freed.
1922 *
1923 * See "dgglob.h" for definition of the table itself.
1924 *
1925 * The SCT and all it's elements are protected by the global lock.
1926 */
1927
1928typedef struct rpc_dg_sct_elt_t {
1929    struct rpc_dg_sct_elt_t *next;      /* -> next in hash chain */
1930    idl_uuid_t actid;                       /* activity of of remote client */
1931    unsigned16 ahint;                   /* uuid_hash(.actid) % RPC_DG_SCT_SIZE */
1932    unsigned32 high_seq;                /* highest known seq */
1933    unsigned high_seq_is_way_validated: 1; /* T => .high_seq is WAY validated */
1934    unsigned8 refcnt;                   /* scte reference count */
1935    rpc_key_info_p_t key_info;       /* key info to be used */
1936    struct rpc_dg_auth_epv_t *auth_epv; /* auth epv */
1937    rpc_dg_scall_p_t scall;             /* -> server call handle being used in call */
1938    rpc_dg_scall_p_t maybe_chain;       /* list of maybe calls associated with */
1939                                        /* this connection.                    */
1940    rpc_clock_t timestamp;              /* last time connection used in a call */
1941    rpc_dg_client_rep_p_t client;       /* -> to client handle   */
1942} rpc_dg_sct_elt_t, *rpc_dg_sct_elt_p_t;
1943
1944#define RPC_DG_SCT_SIZE 101             /* Must be prime */
1945
1946/* ========================================================================= */
1947
1948/*
1949 * Data types that describe the DG protocol service binding rep.
1950 */
1951
1952typedef struct rpc_dg_binding_rep_t {    rpc_binding_rep_t c;
1953} rpc_dg_binding_rep_t, *rpc_dg_binding_rep_p_t;
1954
1955typedef struct rpc_dg_binding_client_t {
1956    rpc_dg_binding_rep_t c;
1957    rpc_dg_ccall_p_t ccall;
1958    unsigned32 server_boot;
1959    struct rpc_dg_binding_server_t *shand;     /* => to server handle if doing callback */
1960    rpc_binding_rep_p_t maint_binding;
1961    unsigned8 is_WAY_binding;   /* number of packets reserved
1962                                 * non-zero if handle is for doing a WAY or WAY2 */
1963    unsigned host_bound: 1;            /* compat only; T => if contains a valid netaddr */
1964} rpc_dg_binding_client_t, *rpc_dg_binding_client_p_t;
1965
1966typedef struct rpc_dg_binding_server_t {
1967    rpc_dg_binding_rep_t c;
1968    rpc_dg_binding_client_p_t chand;   /* => to client binding handle for callbacks */
1969    rpc_dg_scall_p_t scall;
1970} rpc_dg_binding_server_t, *rpc_dg_binding_server_p_t;
1971
1972/* ========================================================================= */
1973
1974/*
1975 * Local fragment size and packet buffer.
1976 *
1977 */
1978
1979#define RPC_DG_FRAG_SIZE_TO_NUM_PKTS(frag_size,n_pkts) \
1980{ \
1981    (n_pkts) = ((frag_size) - RPC_C_DG_RAW_PKT_HDR_SIZE) \
1982             / RPC_C_DG_MAX_PKT_BODY_SIZE; \
1983    if (((frag_size) - RPC_C_DG_RAW_PKT_HDR_SIZE) > \
1984        ((n_pkts) * RPC_C_DG_MAX_PKT_BODY_SIZE)) \
1985        (n_pkts)++; \
1986}
1987
1988#define RPC_DG_NUM_PKTS_TO_FRAG_SIZE(n_pkts,frag_size) \
1989{ \
1990    (frag_size) = ((n_pkts) * RPC_C_DG_MAX_PKT_BODY_SIZE \
1991                   + RPC_C_DG_RAW_PKT_HDR_SIZE) & ~0x7; \
1992}
1993
1994/*
1995 * Max receive fragment size
1996 *
1997 * This is the lower bound on the size of a single fragment
1998 * (including RPC packet header and body, i.e., PDU) that all
1999 * implementations must be able to receive. It's defined by the
2000 * protocol.
2001 * (Derived from RPC_C_IP_UDP_MAX_LOC_UNFRG_TPDU.)
2002 */
2003
2004#define RPC_C_DG_MUST_RECV_FRAG_SIZE 1464
2005
2006/*
2007 * RPC_C_DG_MAX_PKT_SIZE must be larger than (or equal to)
2008 * RPC_C_DG_MUST_RECV_FRAG_SIZE so that the minimum packet
2009 * reservation becomes 1.
2010 */
2011#if RPC_C_DG_MUST_RECV_FRAG_SIZE > RPC_C_DG_MAX_PKT_SIZE
2012#error RPC_C_DG_MAX_PKT_SIZE is less than RPC_C_DG_MUST_RECV_FRAG_SIZE.
2013#endif
2014
2015/*
2016 * Max fragment size
2017 *
2018 * This is the size of the largest RPC fragment (including RPC
2019 * packet header and body, i.e., PDU) we can cope with. This is an
2020 * IMPLEMENTATION artifact and does not represent the largest
2021 * fragment the protocol supports. We need this to determine the
2022 * size of some resources at compile-time.
2023 */
2024
2025#ifndef RPC_C_DG_MAX_FRAG_SIZE
2026
2027#define RPC_C_DG_MAX_FRAG_SIZE \
2028    (2 * RPC_C_DG_MAX_PKT_BODY_SIZE + RPC_C_DG_RAW_PKT_HDR_SIZE)
2029#define RPC_C_DG_MAX_NUM_PKTS_IN_FRAG   2
2030
2031#else   /* RPC_C_DG_MAX_FRAG_SIZE */
2032
2033#if ((RPC_C_DG_MAX_FRAG_SIZE - RPC_C_DG_RAW_PKT_HDR_SIZE) \
2034     / RPC_C_DG_MAX_PKT_BODY_SIZE) * RPC_C_DG_MAX_PKT_BODY_SIZE == \
2035    RPC_C_DG_MAX_FRAG_SIZE - RPC_C_DG_RAW_PKT_HDR_SIZE
2036
2037#define RPC_C_DG_MAX_NUM_PKTS_IN_FRAG \
2038    ((RPC_C_DG_MAX_FRAG_SIZE - RPC_C_DG_RAW_PKT_HDR_SIZE) \
2039        / RPC_C_DG_MAX_PKT_BODY_SIZE)
2040
2041#else
2042
2043#define RPC_C_DG_MAX_NUM_PKTS_IN_FRAG \
2044    (((RPC_C_DG_MAX_FRAG_SIZE - RPC_C_DG_RAW_PKT_HDR_SIZE) \
2045        / RPC_C_DG_MAX_PKT_BODY_SIZE) + 1)
2046
2047#endif
2048
2049#endif  /* RPC_C_DG_MAX_FRAG_SIZE */
2050
2051#if RPC_C_DG_MAX_NUM_PKTS_IN_FRAG > (RPC_C_MAX_IOVEC_LEN - 1)
2052#error RPC_C_DG_MAX_NUM_PKTS_IN_FRAG greater than RPC_C_MAX_IOVEC_LEN!
2053#endif
2054
2055/* =============================================================================== */
2056
2057/*
2058 * Local window size and socket buffering.
2059 *
2060 * "RPC_C_DG_MAX_WINDOW_SIZE" is the size of the window we want to offer
2061 * (in kilobytes). The window size indicates the receiver's idea of
2062 * how much buffering is available in the network (including
2063 * IP/UDP). The window size is the receiver's advice on how much
2064 * *unacknowledged* data the sender should have outstanding. This is
2065 * changed dynamically by the receiver.
2066 * The amount of socket receive buffering required is the product of
2067 * the max window size, 1024,
2068 * and the socket's expected "load" (i.e., how many simultaneous calls
2069 * with what amounts of in/out data we expect a single socket to support).
2070 * We know the first two values; we don't know the last one.  We assert
2071 * it to be "RPC_C_DG_SOCK_LOAD" below.
2072 * Since the private socket's "load" is 1, it will be adjusted in
2073 * use_protseq().
2074 */
2075
2076#ifndef RPC_C_DG_MAX_WINDOW_SIZE
2077#define RPC_C_DG_MAX_WINDOW_SIZE    24
2078#endif
2079
2080#ifndef RPC_C_DG_SOCK_LOAD
2081#define RPC_C_DG_SOCK_LOAD          2
2082#endif
2083
2084#define RPC_C_DG_MAX_WINDOW_SIZE_BYTES \
2085    (RPC_C_DG_MAX_WINDOW_SIZE * 1024)
2086
2087#define RPC_C_DG_SOCK_DESIRED_RCVBUF \
2088    (RPC_C_DG_MAX_WINDOW_SIZE_BYTES * RPC_C_DG_SOCK_LOAD)
2089
2090/*
2091 * A macro to convert a given socket receive buffering size into a window
2092 * size value we might offer.  This macro is used after we ask for a
2093 * particular socket receive buffering, inquire what the system actually
2094 * gave us, and need to figure out what window size to offer as a result.
2095 *
2096 * The most conservative thing to do would be:
2097 *
2098 *  WS = rcvbuf / "socket load" / 1024 ;
2099 *  WS = (WS > RPC_C_DG_MAX_WINDOW_SIZE)? RPC_C_DG_MAX_WINDOW_SIZE : WS;
2100 *
2101 * We don't really trust our "load" measure well enough, but have no
2102 * better alternative.
2103 * Unless there are large IN/OUTs, most fragments actually sent will
2104 * be less than max_frag_size and we may offer windows that are as
2105 * low as this might result in. On the other hand, our "load"
2106 * measure may be too small and we may offer too large windows.
2107 * They may be well-balanced...
2108 */
2109
2110#define RPC_DG_RBUF_SIZE_TO_WINDOW_SIZE(rcvbuf, is_private, frag_size, window_size) \
2111{ \
2112    if ((is_private)) \
2113        (window_size) = (rcvbuf) >> 10; \
2114    else \
2115        (window_size) = ((rcvbuf) / RPC_C_DG_SOCK_LOAD) >> 10; \
2116    if ((window_size) > RPC_C_DG_MAX_WINDOW_SIZE) \
2117        (window_size) = RPC_C_DG_MAX_WINDOW_SIZE; \
2118}
2119
2120/*
2121 * The amount of socket send buffering we establish is based on how much
2122 * window we expect to be offered from remote peers and the socket's
2123 * expected load (as described above).  Essentially, we guess that this
2124 * value is the same as the amount of receive buffering.
2125 */
2126
2127#define RPC_C_DG_SOCK_DESIRED_SNDBUF \
2128    RPC_C_DG_SOCK_DESIRED_RCVBUF
2129
2130/* ========================================================================= */
2131
2132/*
2133 * Macros to decide if a given socket pool entry was created in service
2134 * of a server or a client.
2135 */
2136
2137#define RPC_DG_SOCKET_IS_SERVER(sock_pool_elt)   ((sock_pool_elt)->is_server)
2138#define RPC_DG_SOCKET_IS_CLIENT(sock_pool_elt)   (! (sock_pool_elt)->is_server)
2139
2140/* ========================================================================= */
2141
2142/*
2143 * !!! DON'T USE THE rpc__socket API DIRECTLY !!!
2144 *
2145 * To centralize the chores of pkt logging and lossy mode behavior, the
2146 * following macros must be used by ALL DG code:
2147 *      RPC_DG_SOCKET_RECVFROM(sock, buf, buflen, from, ccp, serrp)
2148 *      RPC_DG_SOCKET_RECVFROM_OOL(sock, buf, buflen, from, ccp, serrp)
2149 *      RPC_DG_SOCKET_SENDMSG(sock, iov, iovlen, addr, ccp, serrp)
2150 *      RPC_DG_SOCKET_SENDMSG_OOL(sock, iov, iovlen, addr, ccp, serrp)
2151 *
2152 * Note: this DG API exactly corresponds to the semantics of the rpc__socket
2153 * interface.  As such, it deals in terms of "raw pkts" structures (i.e.
2154 * MISPACKED_HDR systems must do conversions before and after transmitting
2155 * and receiving respectively).  The single difference in the interfaces is that
2156 * these recvfrom macros expect a buf of type rpc_dg_raw_pkt_p_t (the socket
2157 * versions expect a byte_p_t).
2158 *
2159 * Pkt receive processing is the same regardless of whether or not lossy
2160 * capability is present (lossy currently only affects pkt transmission).
2161 *
2162 * If RPC_DG_PLOG is defined, pkt logging capability exists (if not compiled
2163 * for pkt logging capability the plog operations are a no-op; i.e. doesn't
2164 * even involve a subroutine call).  Note that even if RPC_DG_PLOG is
2165 * defined, nothing bad will happen unless the rpc_e_dbg_dg_plog debug
2166 * switch is set appropriately.  See "dgutl.c" for more info.
2167 *
2168 * If RPC_DG_LOSSY is defined, lossy mode capability exists and all xmits
2169 * are mapped to the dg lossy xmit routine.  The lossy xmit routine
2170 * performs the necessary pkt logging.  It will also do bad stuff every
2171 * once in a while.  Used for testing.  Note that even if RPC_DG_LOSSY
2172 * is defined, nothing bad will happen unless the rpc_e_dbg_dg_lossy
2173 * debug switch is set appropriately.  See "dglossy.c" for more info.
2174 *
2175 * Note that we don't (currently) use rpc__socket_sendto() (or
2176 * RPC_SOCKET_SENDTO) but just in case, we alias them here.
2177 */
2178
2179#define RPC_DG_SOCKET_RECVFROM(sock, buf, buflen, from, ccp, serrp) \
2180    { \
2181        *(serrp) = rpc__socket_recvfrom(sock, (byte_p_t)(buf), buflen, from, ccp); \
2182        if (! RPC_SOCKET_IS_ERR(*serrp)) \
2183        { \
2184            RPC_DG_PLOG_RECVFROM_PKT(&(buf->hdr), &(buf->body)); \
2185        } \
2186    }
2187
2188#define RPC_DG_SOCKET_RECVFROM_OOL(sock, buf, buflen, from, ccp, serrp) \
2189    { \
2190        *(serr) = rpc__socket_recvfrom(sock, (byte_p_t)(buf), buflen, from, ccp); \
2191        if (! RPC_SOCKET_IS_ERR(*serrp)) \
2192        { \
2193            RPC_DG_PLOG_RECVFROM_PKT(&(buf->hdr), &(buf->body)); \
2194        } \
2195    }
2196
2197#ifndef RPC_DG_LOSSY
2198#  define RPC_DG_SOCKET_SENDMSG_OOL(sock, iov, iovlen, addr, ccp, serrp) \
2199        { \
2200            *(serrp) = rpc__socket_sendmsg(sock, iov, iovlen, addr, ccp); \
2201            if (! RPC_SOCKET_IS_ERR(*serrp)) \
2202            { \
2203                RPC_DG_PLOG_SENDMSG_PKT(iov, iovlen); \
2204            } \
2205        }
2206
2207#  define RPC_DG_SOCKET_SENDMSG(sock, iov, iovlen, addr, ccp, serrp) \
2208        { \
2209            *(serrp) = rpc__socket_sendmsg(sock, iov, iovlen, addr, ccp); \
2210            if (! RPC_SOCKET_IS_ERR(*serrp)) \
2211            { \
2212                RPC_DG_PLOG_SENDMSG_PKT(iov, iovlen); \
2213            } \
2214        }
2215
2216#  define RPC_DG_SOCKET_SENDTO_OOL  rpc__dg_socket_sendto_not_impl
2217#  define RPC_DG_SOCKET_SENDTO      rpc__dg_socket_sendto_not_impl
2218
2219#else
2220
2221#  define RPC_DG_SOCKET_SENDMSG_OOL(sock, iov, iovlen, addr, ccp, serrp) \
2222        { \
2223            *(serrp) = rpc__dg_lossy_socket_sendmsg(sock, iov, iovlen, addr, ccp); \
2224        }
2225
2226#  define RPC_DG_SOCKET_SENDMSG(sock, iov, iovlen, addr, ccp, serrp) \
2227        { \
2228            *(serrp) = rpc__dg_lossy_socket_sendmsg(sock, iov, iovlen, addr, ccp); \
2229        }
2230
2231#  define RPC_DG_SOCKET_SENDTO_OOL  rpc__dg_socket_sendto_not_impl
2232#  define RPC_DG_SOCKET_SENDTO      rpc__dg_socket_sendto_not_impl
2233
2234#ifdef __cplusplus
2235extern "C" {
2236#endif
2237
2238PRIVATE rpc_socket_error_t rpc__dg_lossy_socket_sendmsg ((
2239        rpc_socket_t /*sock*/,
2240        rpc_socket_iovec_p_t /*iov*/,
2241        int /*iov_len*/,
2242        rpc_addr_p_t /*addr*/,
2243        int * /*cc*/
2244    ));
2245
2246#endif
2247
2248#ifdef __cplusplus
2249}
2250#endif
2251
2252/* ======================================================================== */
2253
2254/*
2255 * A macro to align a pointer to a 0 mod 8 boundary.  The #ifndef is here
2256 * to allow a per-system override in case the way we do it here doesn't
2257 * work for some systems.
2258 */
2259
2260#ifndef RPC_DG_ALIGN_8
2261#  define RPC_DG_ALIGN_8(p) (((uintptr_t)((unsigned8 *) (p)) + 7) & ~7)
2262#endif
2263
2264/* ========================================================================= */
2265
2266/*
2267 * Authentication operations EPV.
2268 *
2269 * A pointer to one of these may be found through the auth_info
2270 * pointer in the SCTE and CCTE structures.
2271 *
2272 * The operations are invoked at the "right time" during call processing.
2273 *
2274 * EPVs are assumed to be read-only and shared; each authentication
2275 * module declares exactly one.
2276 *
2277 * The auth_data structures, on the other hand, are managed using
2278 * the reference and release operations.
2279 */
2280
2281#define RPC_DG_AUTH_REFERENCE(info) \
2282    rpc__auth_info_reference(info)
2283
2284#define RPC_DG_AUTH_RELEASE(info) \
2285    rpc__auth_info_release(&(info))
2286
2287#define RPC_DG_KEY_REFERENCE(key) \
2288    rpc__key_info_reference(key)
2289
2290#define RPC_DG_KEY_RELEASE(key) \
2291    rpc__key_info_release(&(key))
2292
2293#ifdef __cplusplus
2294extern "C" {
2295#endif
2296
2297/*
2298 * invoked on server to create new auth_t for a new client
2299 */
2300typedef rpc_key_info_p_t (*rpc_dg_auth_create_fn_t) (
2301        unsigned32 * /*st*/
2302    );
2303
2304/*
2305 * invoked before each call
2306 */
2307typedef void (*rpc_dg_auth_pre_call_fn_t) (
2308        rpc_key_info_p_t                /*info*/,
2309        handle_t                         /*h*/,
2310        unsigned32                      * /*st*/
2311    );
2312
2313typedef void (*rpc_dg_auth_encrypt_fn_t) (
2314        rpc_key_info_p_t                /*info*/,
2315        rpc_dg_xmitq_elt_p_t            ,
2316        unsigned32                      * /*st*/
2317    );
2318
2319/*
2320 * invoked after header is packed
2321 */
2322typedef void (*rpc_dg_auth_pre_send_fn_t) (
2323        rpc_key_info_p_t                /*info*/,
2324        rpc_dg_xmitq_elt_p_t            ,
2325        rpc_dg_pkt_hdr_p_t              ,
2326        rpc_socket_iovec_p_t             /*iov*/,
2327        int                              /*iovlen*/,
2328        dce_pointer_t                        /*cksum*/,
2329        unsigned32                      * /*st*/
2330    );
2331
2332/*
2333 * invoked after header in unpacked
2334 */
2335typedef void (*rpc_dg_auth_recv_ck_fn_t) (
2336        rpc_key_info_p_t                /*info*/,
2337        rpc_dg_recvq_elt_p_t             /*pkt*/,
2338        dce_pointer_t                        /*cksum*/,
2339        unsigned32                      * /*st*/
2340    );
2341
2342/*
2343 * called on server side
2344 */
2345typedef void (*rpc_dg_auth_way_fn_t) (
2346        rpc_key_info_p_t               /* in */   /*info*/,
2347        handle_t                        /* in */   /*h*/,
2348        idl_uuid_t                          /* in */  * /*actuid*/,
2349        unsigned32                      /* in */   /*boot_time*/,
2350        unsigned32                      /* out */ * /*seqno*/,
2351        idl_uuid_t                          /* out */ * /*cas_uuid*/,
2352        unsigned32                      /* out */ * /*st*/
2353    );
2354
2355/*
2356 * called on client side
2357 */
2358typedef void (*rpc_dg_auth_way_handler_fn_t) (
2359        rpc_key_info_p_t                /*info*/,
2360        ndr_byte                        * /*in_data*/,
2361        signed32                         /*in_len*/,
2362        signed32                         /*out_max_len*/,
2363        ndr_byte                        ** /*out_data*/,
2364        signed32                        * /*out_len*/,
2365        unsigned32                      * /*st*/
2366     );
2367
2368/*
2369 * Generate new keyblock backed by info.
2370 * Note that this theoretically "can't fail".
2371 */
2372
2373typedef rpc_key_info_p_t (*rpc_dg_auth_new_key_fn_t) (
2374        rpc_auth_info_p_t               /*info*/
2375    );
2376
2377typedef struct rpc_dg_auth_epv_t
2378{
2379    unsigned32 auth_proto;
2380    unsigned32 overhead;
2381    unsigned32 blocksize;
2382    rpc_dg_auth_create_fn_t create;
2383    rpc_dg_auth_pre_call_fn_t pre_call;
2384    rpc_dg_auth_encrypt_fn_t encrypt;
2385    rpc_dg_auth_pre_send_fn_t pre_send;
2386    rpc_dg_auth_recv_ck_fn_t recv_ck;
2387    rpc_dg_auth_way_fn_t way;
2388    rpc_dg_auth_way_handler_fn_t way_handler;
2389    rpc_dg_auth_new_key_fn_t new_key;
2390} rpc_dg_auth_epv_t, *rpc_dg_auth_epv_p_t;
2391
2392/* =============================================================================== */
2393
2394/*
2395 * Statistics of all forms
2396 */
2397
2398typedef struct
2399{
2400    unsigned32 calls_sent;          /* # of remote calls made */
2401    unsigned32 calls_rcvd;          /* # of remote calls processed */
2402    unsigned32 pkts_sent;           /* Total # of pkts sent */
2403    unsigned32 pkts_rcvd;           /* Total # of pkts rcvd */
2404    unsigned32 brds_sent;           /* Total # of broadcast pkts sent */
2405    unsigned32 dups_sent;           /* # of duplicate frags sent */
2406    unsigned32 dups_rcvd;           /* # of duplicate frags rcvd */
2407    unsigned32 oo_rcvd;             /* # of out or order pkts rcvd */
2408    struct dg_pkt_stats_t              /* Breakdown of pkts sent/rcvd by pkt type */
2409    {
2410        unsigned32 sent;
2411        unsigned32 rcvd;
2412    } pstats[RPC_C_DG_PT_MAX_TYPE + 1];
2413} rpc_dg_stats_t;
2414#define RPC_DG_STATS_INITIALIZER {0, 0, 0, 0, 0, 0, 0, 0, {{0, 0}}}
2415
2416#define RPC_DG_STATS_INCR(s) (rpc_g_dg_stats.s++)
2417
2418PRIVATE void rpc__dg_stats_print ( void );
2419
2420/* ========================================================================= */
2421
2422/*
2423 * Receive dispatch flags.
2424 *
2425 * Dispatch flags are returned by the per-packet-type handler routines
2426 * called in the listener thread (from "recv_dispatch" in "dglsn.c").
2427 * These routines return certain information up to the common code that
2428 * handles all types of packets through a "rpc_dg_dflags_t" return value,
2429 * which is a bit set.  The various "rpc_c_dg_rdf_..." constants are
2430 * the possible members of the set.
2431 */
2432
2433typedef unsigned32 rpc_dg_rd_flags_t;
2434
2435#define RPC_C_DG_RDF_FREE_RQE  0x00000001   /* Free rqe--not enqueued by callee */
2436#define RPC_C_DG_RDF_YIELD     0x00000002   /* Yield before processing socket again */
2437
2438/* =============================================================================== */
2439
2440/*
2441 * Prototype of the DG fork handling routine.
2442 */
2443void rpc__ncadg_fork_handler ( rpc_fork_stage_id_t /*stage*/);
2444
2445/*
2446 * Prototypes of routines used in the DG RPC Protocol Service (call)
2447 */
2448
2449PRIVATE rpc_call_rep_p_t rpc__dg_call_start (
2450        rpc_binding_rep_p_t  /*h*/,
2451        unsigned32  /*options*/,
2452        rpc_if_rep_p_t  /*ifspec*/,
2453        unsigned32  /*opn*/,
2454        rpc_transfer_syntax_t * /*transfer_syntax*/,
2455        unsigned32 * /*st*/
2456    );
2457PRIVATE void rpc__dg_call_transmit (
2458        rpc_call_rep_p_t  /*call*/,
2459        rpc_iovector_p_t  /*data*/,
2460        unsigned32 * /*st*/
2461    );
2462PRIVATE void rpc__dg_call_transceive (
2463        rpc_call_rep_p_t  /*call*/,
2464        rpc_iovector_p_t  /*send_data*/,
2465        rpc_iovector_elt_t * /*recv_data*/,
2466        ndr_format_t * /*ndr_format*/,
2467        unsigned32 * /*st*/
2468    );
2469PRIVATE void rpc__dg_call_receive (
2470        rpc_call_rep_p_t  /*call*/,
2471        rpc_iovector_elt_t * /*data*/,
2472        unsigned32 * /*st*/
2473    );
2474PRIVATE void rpc__dg_call_end (
2475        rpc_call_rep_p_t * /*call*/,
2476        unsigned32 * /*st*/
2477    );
2478PRIVATE void rpc__dg_call_block_until_free (
2479        rpc_call_rep_p_t  /*call*/,
2480        unsigned32 * /*st*/
2481    );
2482PRIVATE void rpc__dg_call_alert (
2483        rpc_call_rep_p_t  /*call*/,
2484        unsigned32 * /*st*/
2485    );
2486PRIVATE void rpc__dg_call_fault (
2487        rpc_call_rep_p_t  /*call*/,
2488        rpc_iovector_p_t  /*fault_info*/,
2489        unsigned32 * /*st*/
2490    );
2491PRIVATE void rpc__dg_call_receive_fault (
2492        rpc_call_rep_p_t  /*call*/,
2493        rpc_iovector_elt_t * /*data*/,
2494        ndr_format_t * /*remote_ndr_format*/,
2495        unsigned32 * /*st*/
2496    );
2497PRIVATE boolean32 rpc__dg_call_did_mgr_execute (
2498        rpc_call_rep_p_t  /*call*/,
2499        unsigned32 * /*st*/
2500    );
2501
2502/* =============================================================================== */
2503
2504/*
2505 * Prototypes of routines used in the DG RPC Protocol Service (network).
2506 */
2507
2508PRIVATE dce_pointer_t rpc__dg_network_init_desc (
2509        rpc_socket_t * /*sock*/,
2510        rpc_protseq_id_t  /*pseq_id*/,
2511        unsigned32 * /*st*/
2512    );
2513PRIVATE void rpc__dg_network_use_protseq (
2514        rpc_protseq_id_t  /*pseq_id*/,
2515        unsigned32  /*max_calls*/,
2516        rpc_addr_p_t  /*rpc_addr*/,
2517        unsigned_char_p_t  /*endpoint*/,
2518        unsigned32 * /*st*/
2519    );
2520PRIVATE void rpc__dg_network_mon (
2521        rpc_binding_rep_p_t  /*binding_r*/,
2522        rpc_client_handle_t  /*client_h*/,
2523        rpc_network_rundown_fn_t  /*rundown*/,
2524        unsigned32 * /*st*/
2525    );
2526PRIVATE void rpc__dg_network_stop_mon (
2527        rpc_binding_rep_p_t  /*binding_r*/,
2528        rpc_client_handle_t  /*client_h*/,
2529        unsigned32 * /*st*/
2530    );
2531PRIVATE void rpc__dg_network_maint (
2532        rpc_binding_rep_p_t  /*binding_r*/,
2533        unsigned32 * /*st*/
2534    );
2535PRIVATE void rpc__dg_network_stop_maint (
2536        rpc_binding_rep_p_t  /*binding_r*/,
2537        unsigned32 * /*st*/
2538    );
2539PRIVATE void rpc__dg_network_close (
2540        rpc_binding_rep_p_t  /*binding_r*/,
2541        unsigned32 * /*st*/
2542    );
2543PRIVATE void rpc__dg_network_select_dispatch (
2544        rpc_socket_t  /*desc*/,
2545        dce_pointer_t  /*si*/,
2546        boolean32  /*is_active*/,
2547        unsigned32 * /*st*/
2548    );
2549PRIVATE void rpc__dg_network_inq_prot_vers (
2550        unsigned8 * /*prot_id*/,
2551        unsigned32 * /*vers_major*/,
2552        unsigned32 * /*vers_minor*/,
2553        unsigned32 * /*st*/
2554    );
2555
2556/* =============================================================================== */
2557
2558/*
2559 * Prototypes of routines used in the DG RPC Protocol Service (mgmt)
2560 */
2561
2562PRIVATE unsigned32 rpc__dg_mgmt_inq_calls_sent ( void );
2563PRIVATE unsigned32 rpc__dg_mgmt_inq_calls_rcvd ( void );
2564PRIVATE unsigned32 rpc__dg_mgmt_inq_pkts_sent ( void );
2565PRIVATE unsigned32 rpc__dg_mgmt_inq_pkts_rcvd ( void );
2566
2567/* ========================================================================= */
2568
2569PRIVATE void rpc__dg_monitor_init (void);
2570
2571PRIVATE void rpc__dg_monitor_fork_handler (
2572        rpc_fork_stage_id_t /*stage*/
2573    );
2574
2575PRIVATE void rpc__dg_maintain_init (void);
2576
2577PRIVATE void rpc__dg_maintain_fork_handler (
2578        rpc_fork_stage_id_t /*stage*/
2579    );
2580
2581PRIVATE void rpc__dg_call_transmit_int (
2582        rpc_dg_call_p_t  /*call*/,
2583        rpc_iovector_p_t  /*data*/,
2584        unsigned32 * /*st*/
2585    );
2586
2587PRIVATE void rpc__dg_call_receive_int (
2588        rpc_dg_call_p_t  /*call*/,
2589        rpc_iovector_elt_t * /*data*/,
2590        unsigned32 * /*st*/
2591    );
2592
2593PRIVATE boolean32 rpc__dg_handle_conv (
2594        rpc_socket_t  /*sock*/,
2595        rpc_dg_recvq_elt_p_t /*rqe*/
2596    );
2597
2598PRIVATE void rpc__dg_convc_indy ( uuid_p_t /*cas_uuid*/);
2599
2600PRIVATE void rpc__dg_handle_convc (
2601        rpc_dg_recvq_elt_p_t /*rqe*/
2602    );
2603
2604#ifdef PASSWD_ETC
2605PRIVATE void rpc__dg_handle_rgy (
2606        rpc_socket_t  /*sock*/,
2607        rpc_dg_recvq_elt_p_t /*rqe*/
2608    );
2609#endif
2610
2611PRIVATE void rpc__dg_get_epkt_body_st (
2612        rpc_dg_recvq_elt_p_t  /*rqe*/,
2613        unsigned32 * /*st*/
2614    );
2615
2616/* ========================================================================= */
2617
2618#include <dgsoc.h>
2619#include <dgglob.h>
2620#include <dgutl.h>
2621
2622/* ========================================================================= */
2623
2624PRIVATE void rpc__dg_conv_init ( void );
2625
2626PRIVATE void rpc__dg_conv_fork_handler (
2627    rpc_fork_stage_id_t /*stage*/
2628    );
2629
2630PRIVATE void rpc__dg_fack_common    (
2631        rpc_dg_sock_pool_elt_p_t  /*sp*/,
2632        rpc_dg_recvq_elt_p_t  /*rqe*/,
2633        rpc_dg_call_p_t  /*call*/,
2634        boolean * /*sent_data*/
2635    );
2636
2637/* ======================================================================== */
2638
2639void rpc__dg_init_func(void);
2640
2641#ifdef __cplusplus
2642}
2643#endif
2644
2645#endif /* _DG_H */
2646