Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /*! |
2 | * \addtogroup rxrpc-spec RX RPC Specification | |
3 | * RX RPC Specification | |
4 | * @{ | |
5 | * | |
6 | * \mainpage AFS-3 Programmer's Reference: Specification for the Rx Remote | |
7 | * Procedure Call Facility | |
8 | * | |
9 | * AFS-3 Programmer's Reference: | |
10 | * | |
11 | * Specification for the Rx Remote Procedure Call Facility | |
12 | * \author Edward R. Zayas | |
13 | * Transarc Corporation | |
14 | * \version 1.2 | |
15 | * \date 28 August 1991 10:11 .cCopyright 1991 Transarc Corporation All Rights | |
16 | * Reserved FS-00-D164 | |
17 | * | |
18 | * \page chap1 Chapter 1 -- Overview of the Rx RPC system | |
19 | * | |
20 | * \section sec1-1 Section 1.1: Introduction to Rx | |
21 | * | |
22 | * \par | |
23 | * The Rx package provides a high-performance, multi-threaded, and secure | |
24 | * mechanism by which | |
25 | * remote procedure calls (RPCs) may be performed between programs executing | |
26 | * anywhere in a | |
27 | * network of computers. The Rx protocol is adaptive, conforming itself to | |
28 | * widely varying | |
29 | * network communication media. It allows user applications to define and | |
30 | * insert their own | |
31 | * security modules, allowing them to execute the precise end-to-end | |
32 | * authentication algorithms | |
33 | * required to suit their needs and goals. Although pervasive throughout the | |
34 | * AFS distributed | |
35 | * file system, all of its agents, and many of its standard application | |
36 | * programs, Rx is entirely | |
37 | * separable from AFS and does not depend on any of its features. In fact, Rx | |
38 | * can be used to build applications engaging in RPC-style communication under | |
39 | * a variety of unix-style file systems. There are in-kernel and user-space | |
40 | * implementations of the Rx facility, with both sharing the same interface. | |
41 | * \par | |
42 | * This document provides a comprehensive and detailed treatment of the Rx RPC | |
43 | * package. | |
44 | * | |
45 | * \section sec1-2 Section 1.2: Basic Concepts | |
46 | * | |
47 | * \par | |
48 | * The Rx design operates on the set of basic concepts described in this | |
49 | * section. | |
50 | * | |
51 | * \subsection sec1-2-1 Section 1.2.1: Security | |
52 | * | |
53 | * \par | |
54 | * The Rx architecture provides for tight integration between the RPC mechanism | |
55 | * and methods for making this communication medium secure. As elaborated in | |
56 | * Section 5.3.1.3 and illustrated by the built-in rxkad security system | |
57 | * described in Chapter 3, Rx defines the format for a generic security module, | |
58 | * and then allows application programmers to define and activate | |
59 | * instantiations of these modules. Rx itself knows nothing about the internal | |
60 | * details of any particular security model, or the module-specific state it | |
61 | * requires. It does, however, know when to call the generic security | |
62 | * operations, and so can easily execute the security algorithm defined. Rx | |
63 | * does maintain basic state per connection on behalf of any given security | |
64 | * class. | |
65 | * | |
66 | * \subsection sec1-2-2 Section 1.2.2: Services | |
67 | * | |
68 | * \par | |
69 | * An Rx-based server exports services, or specific RPC interfaces that | |
70 | * accomplish certain tasks. Services are identified by (host-address, | |
71 | * UDP-port, serviceID) triples. An Rx service is installed and initialized on | |
72 | * a given host through the use of the rx NewService() routine (See Section | |
73 | * 5.6.3). Incoming calls are stamped with the Rx service type, and must match | |
74 | * an installed service to be accepted. Internally, Rx services also carry | |
75 | * string names which identify them, which is useful for remote debugging and | |
76 | * statistics-gathering programs. The use of a service ID allows a single | |
77 | * server process to export multiple, independently-specified Rx RPC services. | |
78 | * \par | |
79 | * Each Rx service contains one or more security classes, as implemented by | |
80 | * individual security objects. These security objects implement end-to-end | |
81 | * security protocols. Individual peer-to-peer connections established on | |
82 | * behalf of an Rx service will select exactly one of the supported security | |
83 | * objects to define the authentication procedures followed by all calls | |
84 | * associated with the connection. Applications are not limited to using only | |
85 | * the core set of built-in security objects offered by Rx. They are free to | |
86 | * define their own security objects in order to execute the specific protocols | |
87 | * they require. | |
88 | * \par | |
89 | * It is possible to specify both the minimum and maximum number of lightweight | |
90 | * processes available to handle simultaneous calls directed to an Rx service. | |
91 | * In addition, certain procedures may be registered with the service and | |
92 | * called at specific times in the course of handling an RPC request. | |
93 | * | |
94 | * \subsection sec1-2-3 Section 1.2.3: Connections | |
95 | * | |
96 | * \par | |
97 | * An Rx connection represents an authenticated communication path, allowing a | |
98 | * sequence of multiple asynchronous conversations (calls). Each connection is | |
99 | * identified by a connection ID. The low-order bits of the connection ID are | |
100 | * reserved so that they may be stamped with the index of a particular call | |
101 | * channel. With up to RX MAXCALLS concurrent calls (set to 4 in this | |
102 | * implementation), the bottom two bits are set aside for this purpose. The | |
103 | * connection ID is not sufficient to uniquely identify an Rx connection by | |
104 | * itself. Should a client crash and restart, it may reuse a connection ID, | |
105 | * causing inconsistent results. Included with the connection ID is the epoch, | |
106 | * or start time for the client side of the connection. After a crash, the next | |
107 | * incarnation of the client will choose a different epoch value. This will | |
108 | * differentiate the new incarnation from the orphaned connection record on the | |
109 | * server side. | |
110 | * \par | |
111 | * Each connection is associated with a parent service, which defines a set of | |
112 | * supported security models. At creation time, an Rx connection selects the | |
113 | * particular security protocol it will implement, referencing the associated | |
114 | * service. The connection structure maintains state for each individual call | |
115 | * simultaneously handled. | |
116 | * | |
117 | * \subsection sec1-2-4 Section 1.2.4: Peers | |
118 | * | |
119 | * \par | |
120 | * For each connection, Rx maintains information describing the entity, or | |
121 | * peer, on the other side of the wire. A peer is identified by a (host, | |
122 | * UDP-port) pair, with an IP address used to identify the host. Included in | |
123 | * the information kept on this remote communication endpoint are such network | |
124 | * parameters as the maximum packet size supported by the host, current | |
125 | * readings on round trip time and retransmission delays, and packet skew (see | |
126 | * Section 1.2.7). There are also congestion control fields, including | |
127 | * retransmission statistics and descriptions of the maximum number of packets | |
128 | * that may be sent to the peer without pausing. Peer structures are shared | |
129 | * between connections whenever possible, and, hence, are reference-counted. A | |
130 | * peer object may be garbage-collected if it is not actively referenced by any | |
131 | * connection structure and a sufficient period of time has lapsed since the | |
132 | * reference count dropped to zero. | |
133 | * | |
134 | * \subsection sec1-2-5 Section 1.2.5: Calls | |
135 | * | |
136 | * \par | |
137 | * An Rx call represents an individual RPC being executed on a given | |
138 | * connection. As described above, each connection may have up to RX MAXCALLS | |
139 | * calls active at any one instant. The information contained in each call | |
140 | * structure is specific to the given call. | |
141 | * \par | |
142 | * "Permanent" call state, such as the call number, is maintained in the | |
143 | * connection structure itself. | |
144 | * | |
145 | * \subsection sec1-2-6 Section 1.2.6: Quotas | |
146 | * | |
147 | * \par | |
148 | * Each attached server thread must be able to make progress to avoid system | |
149 | * deadlock. The Rx facility ensures that it can always handle the arrival of | |
150 | * the next unacknowledged data packet for an attached call with its system of | |
151 | * packet quotas. A certain number of packets are reserved per server thread | |
152 | * for this purpose, allowing the server threads to queue up an entire window | |
153 | * full of data for an active call and still have packet buffers left over to | |
154 | * be able to read its input without blocking. | |
155 | * | |
156 | * \subsection sec1-2-7 Section 1.2.7: Packet Skew | |
157 | * | |
158 | * \par | |
159 | * If a packet is received n packets later than expected (based on packet | |
160 | * serial numbers), then we define it to have a skew of n. The maximum skew | |
161 | * values allow us to decide when a packet hasn't been received yet because it | |
162 | * is out of order, as opposed to when it is likely to have been dropped. | |
163 | * | |
164 | * \subsection sec1-2-8 Section 1.2.8: Multicasting | |
165 | * | |
166 | * \par | |
167 | * The rx multi.c module provides for multicast abilities, sending an RPC to | |
168 | * several targets simultaneously. While true multicasting is not achieved, it | |
169 | * is simulated by a rapid succession of packet transmissions and a collection | |
170 | * algorithm for the replies. A client program, though, may be programmed as if | |
171 | * multicasting were truly taking place. Thus, Rx is poised to take full | |
172 | * advantage of a system supporting true multicasting with minimal disruption | |
173 | * to the existing client code base. | |
174 | * | |
175 | * \section sec1-3 Section 1.3: Scope | |
176 | * | |
177 | * \par | |
178 | * This paper is a member of a documentation suite providing specifications as | |
179 | * to the operation and interfaces offered by the various AFS servers and | |
180 | * agents. Rx is an integral part of the AFS environment, as it provides the | |
181 | * high-performance, secure pathway by which these system components | |
182 | * communicate across the network. Although AFS is dependent on Rx's services, | |
183 | * the reverse is not true. Rx is a fully independent RPC package, standing on | |
184 | * its own and usable in other environments. | |
185 | * \par | |
186 | * The intent of this work is to provide readers with a sufficiently detailed | |
187 | * description of Rx that they may proceed to write their own applications on | |
188 | * top of it. In fact, code for a sample Rx server and client are provided. | |
189 | * \par | |
190 | * One topic related to Rx will not be covered by this document, namely the | |
191 | * Rxgen stub generator. Rather, rxgen is addressed in a separate document. | |
192 | * | |
193 | * \section sec1-4 Section 1.4: Document Layout | |
194 | * | |
195 | * \par | |
196 | * After this introduction, Chapter 2 will introduce and describe various | |
197 | * facilities and tools that support Rx. In particular, the threading and | |
198 | * locking packages used by Rx will be examined, along with a set of timer and | |
199 | * preemption tools. Chapter 3 proceeds to examine the details of one of the | |
200 | * built-in security modules offered by Rx. Based on the Kerberos system | |
201 | * developed by MIT's Project Athena, this rxkad module allows secure, ecrypted | |
202 | * communication between the server and client ends of the RPC. Chapter 5 then | |
203 | * provides the full Rx programming interface, and Chapter 6 illustrates the | |
204 | * use of this programming interface by providing a fully-operational | |
205 | * programming example employing Rx. This rxdemo suite is examined in detail, | |
206 | * ranging all the way from a step-by-step analysis of the human-authored | |
207 | * files, and the Rxgen-generated files upon which they are based, to the | |
208 | * workings of the associated Makefile. Output from the example rxdemo server | |
209 | * and client is also provided. | |
210 | * | |
211 | * \section sec1-5 Section 1.5: Related Documents | |
212 | * | |
213 | * \par | |
214 | * Titles for the full suite of AFS specification documents are listed below. | |
215 | * All of the servers and agents making up the AFS computing environment, | |
216 | * whether running in the unix kernel or in user space, utilize an Rx RPC | |
217 | * interface through which they export their services. | |
218 | * \par | |
219 | * \li AFS-3 Programmer's Reference: Architectural Overview: This paper | |
220 | * provides an architectual overview of the AFS distributed file system, | |
221 | * describing the full set of servers and agents in a coherent way, | |
222 | * illustrating their relationships to each other and examining their | |
223 | * interactions. | |
224 | * \li AFS-3 Programmer's Reference: file Server/Cache Manager Interface: This | |
225 | * document describes the workings and interfaces of the two primary AFS | |
226 | * agents, the file Server and Cache Manager. The file Server provides a | |
227 | * centralized disk repository for sets of files, regulating access to them. | |
228 | * End users sitting on client machines rely on the Cache Manager agent, | |
229 | * running in their kernel, to act as their agent in accessing the data stored | |
230 | * on file Server machines, making those files appear as if they were really | |
231 | * housed locally. | |
232 | * \li AFS-3 Programmer's Reference:Volume Server/Volume Location Server | |
233 | * Interface: This document describes the services through which "containers" | |
234 | * of related user data are located and managed. | |
235 | * \li AFS-3 Programmer's Reference: Protection Server Interface: This paper | |
236 | * describes the server responsible for mapping printable user names to and | |
237 | * from their internal AFS identifiers. The Protection Server also allows users | |
238 | * to create, destroy, and manipulate "groups" of users, which are suitable for | |
239 | * placement on access control lists (ACLs). | |
240 | * \li AFS-3 Programmer's Reference: BOS Server Interface: This paper | |
241 | * explicates the "nanny" service which assists in the administrability of the | |
242 | * AFS environment. | |
243 | * \par | |
244 | * In addition to these papers, the AFS 3.1 product is delivered with its own | |
245 | * user, system administrator, installation, and command reference documents. | |
246 | * | |
247 | * \page chap2 Chapter 2 -- The LWP Lightweight Process Package | |
248 | * | |
249 | * \section sec2-1 Section 2.1: Introduction | |
250 | * \par | |
251 | * This chapter describes a package allowing multiple threads of control to | |
252 | * coexist and cooperate within one unix process. Each such thread of control | |
253 | * is also referred to as a lightweight process, in contrast to the traditional | |
254 | * unix (heavyweight) process. Except for the limitations of a fixed stack size | |
255 | * and non-preemptive scheduling, these lightweight processes possess all the | |
256 | * properties usually associated with full-fledged processes in typical | |
257 | * operating systems. For the purposes of this document, the terms lightweight | |
258 | * process, LWP, and thread are completely interchangeable, and they appear | |
259 | * intermixed in this chapter. Included in this lightweight process facility | |
260 | * are various sub-packages, including services for locking, I/O control, | |
261 | * timers, fast time determination, and preemption. | |
262 | * \par | |
263 | * The Rx facility is not the only client of the LWP package. Other LWP clients | |
264 | * within AFS include the file Server, Protection Server, BOS Server, Volume | |
265 | * Server, Volume Location Server, and the Authentication Server, along with | |
266 | * many of the AFS application programs. | |
267 | * | |
268 | * \section sec2-2 Section 2.2: Description | |
269 | * | |
270 | * \subsection Section 2.2.1: sec2-2-1 LWP Overview | |
271 | * | |
272 | * \par | |
273 | * The LWP package implements primitive functions that provide the basic | |
274 | * facilities required to enable procedures written in C to execute | |
275 | * concurrently and asynchronously. The LWP package is meant to be | |
276 | * general-purpose (note the applications mentioned above), with a heavy | |
277 | * emphasis on simplicity. Interprocess communication facilities can be built | |
278 | * on top of this basic mechanism and in fact, many different IPC mechanisms | |
279 | * could be implemented. | |
280 | * \par | |
281 | * In order to set up the threading support environment, a one-time invocation | |
282 | * of the LWP InitializeProcessSupport() function must precede the use of the | |
283 | * facilities described here. This initialization function carves an initial | |
284 | * process out of the currently executing C procedure and returns its thread | |
285 | * ID. For symmetry, an LWP TerminateProcessSupport() function may be used | |
286 | * explicitly to release any storage allocated by its counterpart. If this | |
287 | * function is used, it must be issued from the thread created by the original | |
288 | * LWP InitializeProcessSupport() invocation. | |
289 | * \par | |
290 | * When any of the lightweight process functions completes, an integer value is | |
291 | * returned to indicate whether an error condition was encountered. By | |
292 | * convention, a return value of zero indicates that the operation succeeded. | |
293 | * \par | |
294 | * Macros, typedefs, and manifest constants for error codes needed by the | |
295 | * threading mechanism are exported by the lwp.h include file. A lightweight | |
296 | * process is identified by an object of type PROCESS, which is defined in the | |
297 | * include file. | |
298 | * \par | |
299 | * The process model supported by the LWP operations is based on a | |
300 | * non-preemptive priority dispatching scheme. A priority is an integer in the | |
301 | * range [0..LWP MAX PRIORITY], where 0 is the lowest priority. Once a given | |
302 | * thread is selected and dispatched, it remains in control until it | |
303 | * voluntarily relinquishes its claim on the CPU. Control may be relinquished | |
304 | * by either explicit means (LWP_DispatchProcess()) or implicit means (through | |
305 | * the use of certain other LWP operations with this side effect). In general, | |
306 | * all LWP operations that may cause a higher-priority process to become ready | |
307 | * for dispatching preempt the process requesting the service. When this | |
308 | * occurs, the dispatcher mechanism takes over and automatically schedules the | |
309 | * highest-priority runnable process. Routines in this category, where the | |
310 | * scheduler is guaranteed to be invoked in the absence of errors, are: | |
311 | * \li LWP_WaitProcess() | |
312 | * \li LWP_MwaitProcess() | |
313 | * \li LWP_SignalProcess() | |
314 | * \li LWP_DispatchProcess() | |
315 | * \li LWP_DestroyProcess() | |
316 | * \par | |
317 | * The following functions are guaranteed not to cause preemption, and so may | |
318 | * be issued with no fear of losing control to another thread: | |
319 | * \li LWP_InitializeProcessSupport() | |
320 | * \li LWP_NoYieldSignal() | |
321 | * \li LWP_CurrentProcess() | |
322 | * \li LWP_ActiveProcess() | |
323 | * \li LWP_StackUsed() | |
324 | * \li LWP_NewRock() | |
325 | * \li LWP_GetRock() | |
326 | * \par | |
327 | * The symbol LWP NORMAL PRIORITY, whose value is (LWP MAX PRIORITY-2), | |
328 | * provides a reasonable default value to use for process priorities. | |
329 | * \par | |
330 | * The lwp debug global variable can be set to activate or deactivate debugging | |
331 | * messages tracing the flow of control within the LWP routines. To activate | |
332 | * debugging messages, set lwp debug to a non-zero value. To deactivate, reset | |
333 | * it to zero. All debugging output from the LWP routines is sent to stdout. | |
334 | * \par | |
335 | * The LWP package checks for stack overflows at each context switch. The | |
336 | * variable that controls the action of the package when an overflow occurs is | |
337 | * lwp overflowAction. If it is set to LWP SOMESSAGE, then a message will be | |
338 | * printed on stderr announcing the overflow. If lwp overflowAction is set to | |
339 | * LWP SOABORT, the abort() LWP routine will be called. finally, if lwp | |
340 | * overflowAction is set to LWP SOQUIET, the LWP facility will ignore the | |
341 | * errors. By default, the LWP SOABORT setting is used. | |
342 | * \par | |
343 | * Here is a sketch of a simple program (using some psuedocode) demonstrating | |
344 | * the high-level use of the LWP facility. The opening #include line brings in | |
345 | * the exported LWP definitions. Following this, a routine is defined to wait | |
346 | * on a "queue" object until something is deposited in it, calling the | |
347 | * scheduler as soon as something arrives. Please note that various LWP | |
348 | * routines are introduced here. Their definitions will appear later, in | |
349 | * Section 2.3.1. | |
350 | * | |
351 | * \code | |
352 | * #include <afs/lwp.h> | |
353 | * static read_process(id) | |
354 | * int *id; | |
355 | * { /* Just relinquish control for now */ | |
356 | * LWP_DispatchProcess(); | |
357 | * for (;;) | |
358 | * { | |
359 | * /* Wait until there is something in the queue */ | |
360 | * while (empty(q)) LWP_WaitProcess(q); | |
361 | * /* Process the newly-arrived queue entry */ | |
362 | * LWP_DispatchProcess(); | |
363 | * } | |
364 | * } | |
365 | * \endcode | |
366 | * | |
367 | * \par | |
368 | * The next routine, write process(), sits in a loop, putting messages on the | |
369 | * shared queue and signalling the reader, which is waiting for activity on the | |
370 | * queue. Signalling a thread is accomplished via the LWP SignalProcess() | |
371 | * library routine. | |
372 | * | |
373 | * \code | |
374 | * static write_process() | |
375 | * { ... | |
376 | * /* Loop, writing data to the shared queue. */ | |
377 | * for (mesg = messages; *mesg != 0; mesg++) | |
378 | * { | |
379 | * insert(q, *mesg); | |
380 | * LWP_SignalProcess(q); | |
381 | * } | |
382 | * } | |
383 | * \endcode | |
384 | * | |
385 | * \par | |
386 | * finally, here is the main routine for this demo pseudocode. It starts by | |
387 | * calling the LWP initialization routine. Next, it creates some number of | |
388 | * reader threads with calls to LWP CreateProcess() in addition to the single | |
389 | * writer thread. When all threads terminate, they will signal the main routine | |
390 | * on the done variable. Once signalled, the main routine will reap all the | |
391 | * threads with the help of the LWP DestroyProcess() function. | |
392 | * | |
393 | * \code | |
394 | * main(argc, argv) | |
395 | * int argc; | |
396 | * char **argv; | |
397 | * { | |
398 | * PROCESS *id; /* Initial thread ID */ | |
399 | * /* Set up the LWP package, create the initial thread ID. */ | |
400 | * LWP_InitializeProcessSupport(0, &id); | |
401 | * /* Create a set of reader threads. */ | |
402 | * for (i = 0; i < nreaders; i++) | |
403 | * LWP_CreateProcess(read_process, STACK_SIZE, 0, i, "Reader", | |
404 | * &readers[i]); | |
405 | * | |
406 | * /* Create a single writer thread. */ | |
407 | * LWP_CreateProcess(write_process, STACK_SIZE, 1, 0, "Writer", &writer); | |
408 | * /* Wait for all the above threads to terminate. */ | |
409 | * for (i = 0; i <= nreaders; i++) | |
410 | * LWP_WaitProcess(&done); | |
411 | * | |
412 | * /* All threads are done. Destroy them all. */ | |
413 | * for (i = nreaders-1; i >= 0; i--) | |
414 | * LWP_DestroyProcess(readers[i]); | |
415 | * } | |
416 | * \endcode | |
417 | * | |
418 | * \subsection sec2-2-2 Section 2.2.2: Locking | |
419 | * \par | |
420 | * The LWP locking facility exports a number of routines and macros that allow | |
421 | * a C programmer using LWP threading to place read and write locks on shared | |
422 | * data structures. This locking facility was also written with simplicity in | |
423 | * mind. | |
424 | * \par | |
425 | * In order to invoke the locking mechanism, an object of type struct Lock must | |
426 | * be associated with the object. After being initialized with a call to | |
427 | * LockInit(), the lock object is used in invocations of various macros, | |
428 | * including ObtainReadLock(), ObtainWriteLock(), ReleaseReadLock(), | |
429 | * ReleaseWriteLock(), ObtainSharedLock(), ReleaseSharedLock(), and | |
430 | * BoostSharedLock(). | |
431 | * \par | |
432 | * Lock semantics specify that any number of readers may hold a lock in the | |
433 | * absence of a writer. Only a single writer may acquire a lock at any given | |
434 | * time. The lock package guarantees fairness, legislating that each reader and | |
435 | * writer will eventually obtain a given lock. However, this fairness is only | |
436 | * guaranteed if the priorities of the competing processes are identical. Note | |
437 | * that ordering is not guaranteed by this package. | |
438 | * \par | |
439 | * Shared locks are read locks that can be "boosted" into write locks. These | |
440 | * shared locks have an unusual locking matrix. Unboosted shared locks are | |
441 | * compatible with read locks, yet incompatible with write locks and other | |
442 | * shared locks. In essence, a thread holding a shared lock on an object has | |
443 | * effectively read-locked it, and has the option to promote it to a write lock | |
444 | * without allowing any other writer to enter the critical region during the | |
445 | * boost operation itself. | |
446 | * \par | |
447 | * It is illegal for a process to request a particular lock more than once | |
448 | * without first releasing it. Failure to obey this restriction will cause | |
449 | * deadlock. This restriction is not enforced by the LWP code. | |
450 | * \par | |
451 | * Here is a simple pseudocode fragment serving as an example of the available | |
452 | * locking operations. It defines a struct Vnode object, which contains a lock | |
453 | * object. The get vnode() routine will look up a struct Vnode object by name, | |
454 | * and then either read-lock or write-lock it. | |
455 | * \par | |
456 | * As with the high-level LWP example above, the locking routines introduced | |
457 | * here will be fully defined later, in Section 2.3.2. | |
458 | * | |
459 | * \code | |
460 | * #include <afs/lock.h> | |
461 | * | |
462 | * struct Vnode { | |
463 | * ... | |
464 | * struct Lock lock; Used to lock this vnode | |
465 | * ... }; | |
466 | * | |
467 | * #define READ 0 | |
468 | * #define WRITE 1 | |
469 | * | |
470 | * struct Vnode *get_vnode(name, how) char *name; | |
471 | * int how; | |
472 | * { | |
473 | * struct Vnode *v; | |
474 | * v = lookup(name); | |
475 | * if (how == READ) | |
476 | * ObtainReadLock(&v->lock); | |
477 | * else | |
478 | * ObtainWriteLock(&v->lock); | |
479 | * } | |
480 | * \endcode | |
481 | * | |
482 | * | |
483 | * \subsection sec2-2-3 Section 2.2.3: IOMGR | |
484 | * | |
485 | * \par | |
486 | * The IOMGR facility associated with the LWP service allows threads to wait on | |
487 | * various unix events. The exported IOMGR Select() routine allows a thread to | |
488 | * wait on the same set of events as the unix select() call. The parameters to | |
489 | * these two routines are identical. IOMGR Select() puts the calling LWP to | |
490 | * sleep until no threads are active. At this point, the built-in IOMGR thread, | |
491 | * which runs at the lowest priority, wakes up and coalesces all of the select | |
492 | * requests together. It then performs a single select() and wakes up all | |
493 | * threads affected by the result. | |
494 | * \par | |
495 | * The IOMGR Signal() routine allows an LWP to wait on the delivery of a unix | |
496 | * signal. The IOMGR thread installs a signal handler to catch all deliveries | |
497 | * of the unix signal. This signal handler posts information about the signal | |
498 | * delivery to a global data structure. The next time that the IOMGR thread | |
499 | * runs, it delivers the signal to any waiting LWP. | |
500 | * \par | |
501 | * Here is a pseudocode example of the use of the IOMGR facility, providing the | |
502 | * blueprint for an implemention a thread-level socket listener. | |
503 | * | |
504 | * \code | |
505 | * void rpc_SocketListener() | |
506 | * { | |
507 | * int ReadfdMask, WritefdMask, ExceptfdMask, rc; | |
508 | * struct timeval *tvp; | |
509 | * while(TRUE) | |
510 | * { ... | |
511 | * ExceptfdMask = ReadfdMask = (1 << rpc_RequestSocket); | |
512 | * WritefdMask = 0; | |
513 | * | |
514 | * rc = IOMGR_Select(8*sizeof(int), &ReadfdMask, &WritefdMask, | |
515 | * &ExceptfdMask, tvp); | |
516 | * | |
517 | * switch(rc) | |
518 | * { | |
519 | * case 0: /* Timeout */ continue; | |
520 | * /* Main while loop */ | |
521 | * | |
522 | * case -1: /* Error */ | |
523 | * SystemError("IOMGR_Select"); | |
524 | * exit(-1); | |
525 | * | |
526 | * case 1: /* RPC packet arrived! */ ... | |
527 | * process packet ... | |
528 | * break; | |
529 | * | |
530 | * default: Should never occur | |
531 | * } | |
532 | * } | |
533 | * } | |
534 | * \endcode | |
535 | * | |
536 | * \subsection sec2-2-4 Section 2.2.4: Timer | |
537 | * \par | |
538 | * The timer package exports a number of routines that assist in manipulating | |
539 | * lists of objects of type struct TM Elem. These struct TM Elem timers are | |
540 | * assigned a timeout value by the user and inserted in a package-maintained | |
541 | * list. The time remaining to each timer's timeout is kept up to date by the | |
542 | * package under user control. There are routines to remove a timer from its | |
543 | * list, to return an expired timer from a list, and to return the next timer | |
544 | * to expire. | |
545 | * \par | |
546 | * A timer is commonly used by inserting a field of type struct TM Elem into a | |
547 | * structure. After setting the desired timeout value, the structure is | |
548 | * inserted into a list by means of its timer field. | |
549 | * \par | |
550 | * Here is a simple pseudocode example of how the timer package may be used. | |
551 | * After calling the package initialization function, TM Init(), the pseudocode | |
552 | * spins in a loop. first, it updates all the timers via TM Rescan() calls. | |
553 | * Then, it pulls out the first expired timer object with TM GetExpired() (if | |
554 | * any), and processes it. | |
555 | * | |
556 | * \code | |
557 | * static struct TM_Elem *requests; | |
558 | * ... | |
559 | * TM_Init(&requests); /* Initialize timer list */ ... | |
560 | * for (;;) { | |
561 | * TM_Rescan(requests); /* Update the timers */ | |
562 | * expired = TM_GetExpired(requests); | |
563 | * if (expired == 0) | |
564 | * break; | |
565 | * . . . process expired element . . . | |
566 | * } | |
567 | * \endcode | |
568 | * | |
569 | * \subsection sec2-2-5 Section 2.2.5: Fast Time | |
570 | * | |
571 | * \par | |
572 | * The fast time routines allows a caller to determine the current time of day | |
573 | * without incurring the expense of a kernel call. It works by mapping the page | |
574 | * of the kernel that holds the time-of-day variable and examining it directly. | |
575 | * Currently, this package only works on Suns. The routines may be called on | |
576 | * other architectures, but they will run more slowly. | |
577 | * \par | |
578 | * The initialization routine for this package is fairly expensive, since it | |
579 | * does a lookup of a kernel symbol via nlist(). If the client application | |
580 | * program only runs for only a short time, it may wish to call FT Init() with | |
581 | * the notReally parameter set to TRUE in order to prevent the lookup from | |
582 | * taking place. This is useful if you are using another package that uses the | |
583 | * fast time facility. | |
584 | * | |
585 | * \section sec2-3 Section 2.3: Interface Specifications | |
586 | * | |
587 | * \subsection sec2-3-1 Section 2.3.1: LWP | |
588 | * | |
589 | * \par | |
590 | * This section covers the calling interfaces to the LWP package. Please note | |
591 | * that LWP macros (e.g., ActiveProcess) are also included here, rather than | |
592 | * being relegated to a different section. | |
593 | * | |
594 | * \subsubsection sec2-3-1-1 Section 2.3.1.1: LWP_InitializeProcessSupport | |
595 | * _ Initialize the LWP package | |
596 | * | |
597 | * \par | |
598 | * int LWP_InitializeProcessSupport(IN int priority; OUT PROCESS *pid) | |
599 | * \par Description | |
600 | * This function initializes the LWP package. In addition, it turns the current | |
601 | * thread of control into the initial process with the specified priority. The | |
602 | * process ID of this initial thread is returned in the pid parameter. This | |
603 | * routine must be called before any other routine in the LWP library. The | |
604 | * scheduler will NOT be invoked as a result of calling | |
605 | * LWP_InitializeProcessSupport(). | |
606 | * \par Error Codes | |
607 | * LWP EBADPRI The given priority is invalid, either negative or too large. | |
608 | * | |
609 | * \subsubsection sec2-3-1-2 Section 2.3.1.2: LWP_TerminateProcessSupport | |
610 | * _ End process support, perform cleanup | |
611 | * | |
612 | * \par | |
613 | * int LWP_TerminateProcessSupport() | |
614 | * \par Description | |
615 | * This routine terminates the LWP threading support and cleans up after it by | |
616 | * freeing any auxiliary storage used. This routine must be called from within | |
617 | * the process that invoked LWP InitializeProcessSupport(). After LWP | |
618 | * TerminateProcessSupport() has been called, it is acceptable to call LWP | |
619 | * InitializeProcessSupport() again in order to restart LWP process support. | |
620 | * \par Error Codes | |
621 | * ---Always succeeds, or performs an abort(). | |
622 | * | |
623 | * \subsubsection sec2-3-1-3 Section 2.3.1.3: LWP_CreateProcess _ Create a | |
624 | * new thread | |
625 | * | |
626 | * \par | |
627 | * int LWP_CreateProcess(IN int (*ep)(); IN int stacksize; IN int priority; IN | |
628 | * char *parm; IN char *name; OUT PROCESS *pid) | |
629 | * \par Description | |
630 | * This function is used to create a new lightweight process with a given | |
631 | * printable name. The ep argument identifies the function to be used as the | |
632 | * body of the thread. The argument to be passed to this function is contained | |
633 | * in parm. The new thread's stack size in bytes is specified in stacksize, and | |
634 | * its execution priority in priority. The pid parameter is used to return the | |
635 | * process ID of the new thread. | |
636 | * \par | |
637 | * If the thread is successfully created, it will be marked as runnable. The | |
638 | * scheduler is called before the LWP CreateProcess() call completes, so the | |
639 | * new thread may indeed begin its execution before the completion. Note that | |
640 | * the new thread is guaranteed NOT to run before the call completes if the | |
641 | * specified priority is lower than the caller's. On the other hand, if the new | |
642 | * thread's priority is higher than the caller's, then it is guaranteed to run | |
643 | * before the creation call completes. | |
644 | * \par Error Codes | |
645 | * LWP EBADPRI The given priority is invalid, either negative or too large. | |
646 | * \n LWP NOMEM Could not allocate memory to satisfy the creation request. | |
647 | * | |
648 | * \subsubsection sec2-3-1-4 Section: 2.3.1.4: LWP_DestroyProcess _ Create | |
649 | * a new thread | |
650 | * | |
651 | * \par | |
652 | * int LWP_DestroyProcess(IN PROCESS pid) | |
653 | * \par Description | |
654 | * This routine destroys the thread identified by pid. It will be terminated | |
655 | * immediately, and its internal storage will be reclaimed. A thread is allowed | |
656 | * to destroy itself. In this case, of course, it will only get to see the | |
657 | * return code if the operation fails. Note that a thread may also destroy | |
658 | * itself by returning from the parent C routine. | |
659 | * \par | |
660 | * The scheduler is called by this operation, which may cause an arbitrary | |
661 | * number of threads to execute before the caller regains the processor. | |
662 | * \par Error Codes | |
663 | * LWP EINIT The LWP package has not been initialized. | |
664 | * | |
665 | * \subsubsection sec2-3-1-5 Section 2.3.1.5: WaitProcess _ Wait on an | |
666 | * event | |
667 | * | |
668 | * \par | |
669 | * int LWP WaitProcess(IN char *event) | |
670 | * \par Description | |
671 | * This routine puts the thread making the call to sleep until another LWP | |
672 | * calls the LWP SignalProcess() or LWP NoYieldSignal() routine with the | |
673 | * specified event. Note that signalled events are not queued. If a signal | |
674 | * occurs and no thread is awakened, the signal is lost. The scheduler is | |
675 | * invoked by the LWP WaitProcess() routine. | |
676 | * \par Error Codes | |
677 | * LWP EINIT The LWP package has not been initialized. | |
678 | * \n LWP EBADEVENT The given event pointer is null. | |
679 | * | |
680 | * \subsubsection sec2-3-1-6 Section 2.3.1.6: MwaitProcess _ Wait on a set | |
681 | * of events | |
682 | * | |
683 | * \par | |
684 | * int LWP MwaitProcess(IN int wcount; IN char *evlist[]) | |
685 | * \par Description | |
686 | * This function allows a thread to wait for wcount signals on any of the items | |
687 | * in the given evlist. Any number of signals of a particular event are only | |
688 | * counted once. The evlist is a null-terminated list of events to wait for. | |
689 | * The scheduler will be invoked. | |
690 | * \par Error Codes | |
691 | * LWP EINIT The LWP package has not been initialized. | |
692 | * \n LWP EBADCOUNT An illegal number of events has been supplied. | |
693 | * | |
694 | * \subsubsection sec2-3-1-7 Section 2.3.1.7: SignalProcess _ Signal an | |
695 | * event | |
696 | * | |
697 | * \par | |
698 | * int LWP SignalProcess(IN char *event) | |
699 | * \par Description | |
700 | * This routine causes the given event to be signalled. All threads waiting for | |
701 | * this event (exclusively) will be marked as runnable, and the scheduler will | |
702 | * be invoked. Note that threads waiting on multiple events via LWP | |
703 | * MwaitProcess() may not be marked as runnable. Signals are not queued. | |
704 | * Therefore, if no thread is waiting for the signalled event, the signal will | |
705 | * be lost. | |
706 | * \par Error Codes | |
707 | * LWP EINIT The LWP package has not been initialized. LWP EBADEVENT A null | |
708 | * event pointer has been provided. LWP ENOWAIT No thread was waiting on the | |
709 | * given event. | |
710 | * | |
711 | * \subsubsection sec2-3-1-8 Section 2.3.1.8: NoYieldSignal _ Signal an | |
712 | * event without invoking scheduler | |
713 | * | |
714 | * \par | |
715 | * int LWP NoYieldSignal(IN char *event) | |
716 | * \par Description | |
717 | * This function is identical to LWP SignalProcess() except that the scheduler | |
718 | * will not be invoked. Thus, control will remain with the signalling process. | |
719 | * \par Error Codes | |
720 | * LWP EINIT The LWP package has not been initialized. LWP EBADEVENT A null | |
721 | * event pointer has been provided. LWP ENOWAIT No thread was waiting on the | |
722 | * given event. | |
723 | * | |
724 | * \subsubsection sec2-3-1-9 Section 2.3.1.9: DispatchProcess _ Yield | |
725 | * control to the scheduler | |
726 | * | |
727 | * \par | |
728 | * int LWP DispatchProcess() | |
729 | * \par Description | |
730 | * This routine causes the calling thread to yield voluntarily to the LWP | |
731 | * scheduler. If no other thread of appropriate priority is marked as runnable, | |
732 | * the caller will continue its execution. | |
733 | * \par Error Codes | |
734 | * LWP EINIT The LWP package has not been initialized. | |
735 | * | |
736 | * \subsubsection sec2-3-1-10 Section 2.3.1.10: CurrentProcess _ Get the | |
737 | * current thread's ID | |
738 | * | |
739 | * \par | |
740 | * int LWP CurrentProcess(IN PROCESS *pid) | |
741 | * \par Description | |
742 | * This call places the current lightweight process ID in the pid parameter. | |
743 | * \par Error Codes | |
744 | * LWP EINIT The LWP package has not been initialized. | |
745 | * | |
746 | * \subsubsection sec2-3-1-11 Section 2.3.1.11: ActiveProcess _ Get the | |
747 | * current thread's ID (macro) | |
748 | * | |
749 | * \par | |
750 | * int LWP ActiveProcess() | |
751 | * \par Description | |
752 | * This macro's value is the current lightweight process ID. It generates a | |
753 | * value identical to that acquired by calling the LWP CurrentProcess() | |
754 | * function described above if the LWP package has been initialized. If no such | |
755 | * initialization has been done, it will return a value of zero. | |
756 | * | |
757 | * \subsubsection sec2-3-1-12 Section: 2.3.1.12: StackUsed _ Calculate | |
758 | * stack usage | |
759 | * | |
760 | * \par | |
761 | * int LWP StackUsed(IN PROCESS pid; OUT int *max; OUT int *used) | |
762 | * \par Description | |
763 | * This function returns the amount of stack space allocated to the thread | |
764 | * whose identifier is pid, and the amount actually used so far. This is | |
765 | * possible if the global variable lwp stackUseEnabled was TRUE when the thread | |
766 | * was created (it is set this way by default). If so, the thread's stack area | |
767 | * was initialized with a special pattern. The memory still stamped with this | |
768 | * pattern can be determined, and thus the amount of stack used can be | |
769 | * calculated. The max parameter is always set to the thread's stack allocation | |
770 | * value, and used is set to the computed stack usage if lwp stackUseEnabled | |
771 | * was set when the process was created, or else zero. | |
772 | * \par Error Codes | |
773 | * LWP NO STACK Stack usage was not enabled at thread creation time. | |
774 | * | |
775 | * \subsubsection sec2-3-1-13 Section 2.3.1.13: NewRock _ Establish | |
776 | * thread-specific storage | |
777 | * | |
778 | * \par | |
779 | * int LWP NewRock (IN int tag; IN char **value) | |
780 | * \par Description | |
781 | * This function establishes a "rock", or thread-specific information, | |
782 | * associating it with the calling LWP. The tag is intended to be any unique | |
783 | * integer value, and the value is a pointer to a character array containing | |
784 | * the given data. | |
785 | * \par | |
786 | * Users of the LWP package must coordinate their choice of tag values. Note | |
787 | * that a tag's value cannot be changed. Thus, to obtain a mutable data | |
788 | * structure, another level of indirection is required. Up to MAXROCKS (4) | |
789 | * rocks may be associated with any given thread. | |
790 | * \par Error Codes | |
791 | * ENOROCKS A rock with the given tag field already exists. All of the MAXROCKS | |
792 | * are in use. | |
793 | * | |
794 | * | |
795 | * \subsubsection sec2-3-1-14 Section: 2.3.1.14: GetRock _ Retrieve | |
796 | * thread-specific storage | |
797 | * | |
798 | * \par | |
799 | * int LWP GetRock(IN int tag; OUT **value) | |
800 | * \par Description | |
801 | * This routine recovers the thread-specific information associated with the | |
802 | * calling process and the given tag, if any. Such a rock had to be established | |
803 | * through a LWP NewRock() call. The rock's value is deposited into value. | |
804 | * \par Error Codes | |
805 | * LWP EBADROCK A rock has not been associated with the given tag for this | |
806 | * thread. | |
807 | * | |
808 | * \subsection sec2-3-2 Section 2.3.2: Locking | |
809 | * | |
810 | * \par | |
811 | * This section covers the calling interfaces to the locking package. Many of | |
812 | * the user-callable routines are actually implemented as macros. | |
813 | * | |
814 | * \subsubsection sec2-3-2-1 Section 2.3.2.1: Lock Init _ Initialize lock | |
815 | * structure | |
816 | * | |
817 | * \par | |
818 | * void Lock Init(IN struct Lock *lock) | |
819 | * \par Description | |
820 | * This function must be called on the given lock object before any other | |
821 | * operations can be performed on it. | |
822 | * \par Error Codes | |
823 | * ---No value is returned. | |
824 | * | |
825 | * \subsubsection sec2-3-2-2 Section 2.3.2.2: ObtainReadLock _ Acquire a | |
826 | * read lock | |
827 | * | |
828 | * \par | |
829 | * void ObtainReadLock(IN struct Lock *lock) | |
830 | * \par Description | |
831 | * This macro obtains a read lock on the specified lock object. Since this is a | |
832 | * macro and not a function call, results are not predictable if the value of | |
833 | * the lock parameter is a side-effect producing expression, as it will be | |
834 | * evaluated multiple times in the course of the macro interpretation. | |
835 | * Read locks are incompatible with write, shared, and boosted shared locks. | |
836 | * \par Error Codes | |
837 | * ---No value is returned. | |
838 | * | |
839 | * \subsubsection sec2-3-2-3 Section 2.3.2.3: ObtainWriteLock _ Acquire a | |
840 | * write lock | |
841 | * | |
842 | * \par | |
843 | * void ObtainWriteLock(IN struct Lock *lock) | |
844 | * \par Description | |
845 | * This macro obtains a write lock on the specified lock object. Since this is | |
846 | * a macro and not a function call, results are not predictable if the value of | |
847 | * the lock parameter is a side-effect producing expression, as it will be | |
848 | * evaluated multiple times in the course of the macro interpretation. | |
849 | * \par | |
850 | * Write locks are incompatible with all other locks. | |
851 | * \par Error Codes | |
852 | * ---No value is returned. | |
853 | * | |
854 | * \subsubsection sec2-3-2-4 Section 2.3.2.4: ObtainSharedLock _ Acquire a | |
855 | * shared lock | |
856 | * | |
857 | * \par | |
858 | * void ObtainSharedLock(IN struct Lock *lock) | |
859 | * \par Description | |
860 | * This macro obtains a shared lock on the specified lock object. Since this is | |
861 | * a macro and not a function call, results are not predictable if the value of | |
862 | * the lock parameter is a side-effect producing expression, as it will be | |
863 | * evaluated multiple times in the course of the macro interpretation. | |
864 | * \par | |
865 | * Shared locks are incompatible with write and boosted shared locks, but are | |
866 | * compatible with read locks. | |
867 | * \par Error Codes | |
868 | * ---No value is returned. | |
869 | * | |
870 | * \subsubsection sec2-3-2-5 Section 2.3.2.5: ReleaseReadLock _ Release | |
871 | * read lock | |
872 | * | |
873 | * \par | |
874 | * void ReleaseReadLock(IN struct Lock *lock) | |
875 | * \par Description | |
876 | * This macro releases the specified lock. The lock must have been previously | |
877 | * read-locked. Since this is a macro and not a function call, results are not | |
878 | * predictable if the value of the lock parameter is a side-effect producing | |
879 | * expression, as it will be evaluated multiple times in the course of the | |
880 | * macro interpretation. The results are also unpredictable if the lock was not | |
881 | * previously read-locked by the thread calling ReleaseReadLock(). | |
882 | * \par Error Codes | |
883 | * ---No value is returned. | |
884 | * | |
885 | * \subsubsection sec2-3-2-6 Section 2.3.2.6: ReleaseWriteLock _ Release | |
886 | * write lock | |
887 | * | |
888 | * \par | |
889 | * void ReleaseWriteLock(IN struct Lock *lock) | |
890 | * \par Description | |
891 | * This macro releases the specified lock. The lock must have been previously | |
892 | * write-locked. Since this is a macro and not a function call, results are not | |
893 | * predictable if the value of the lock parameter is a side-effect producing | |
894 | * expression, as it will be evaluated multiple times in the course of the | |
895 | * macro interpretation. The results are also unpredictable if the lock was not | |
896 | * previously write-locked by the thread calling ReleaseWriteLock(). | |
897 | * \par Error Codes | |
898 | * ---No value is returned. | |
899 | * | |
900 | * \subsubsection sec2-3-2-7 Section 2.3.2.7: ReleaseSharedLock _ Release | |
901 | * shared lock | |
902 | * | |
903 | * \par | |
904 | * void ReleaseSharedLock(IN struct Lock *lock) | |
905 | * \par Description | |
906 | * This macro releases the specified lock. The lock must have been previously | |
907 | * share-locked. Since this is a macro and not a function call, results are not | |
908 | * predictalbe if the value of the lock parameter is a side-effect producing | |
909 | * expression, as it will be evaluated multiple times in the course of the | |
910 | * macro interpretation. The results are also unpredictable if the lock was not | |
911 | * previously share-locked by the thread calling ReleaseSharedLock(). | |
912 | * \par Error Codes | |
913 | * ---No value is returned. | |
914 | * | |
915 | * \subsubsection sec2-3-2-8 Section 2.3.2.8: CheckLock _ Determine state | |
916 | * of a lock | |
917 | * | |
918 | * \par | |
919 | * void CheckLock(IN struct Lock *lock) | |
920 | * \par Description | |
921 | * This macro produces an integer that specifies the status of the indicated | |
922 | * lock. The value will be -1 if the lock is write-locked, 0 if unlocked, or | |
923 | * otherwise a positive integer that indicates the number of readers (threads | |
924 | * holding read locks). Since this is a macro and not a function call, results | |
925 | * are not predictable if the value of the lock parameter is a side-effect | |
926 | * producing expression, as it will be evaluated multiple times in the course | |
927 | * of the macro interpretation. | |
928 | * \par Error Codes | |
929 | * ---No value is returned. | |
930 | * | |
931 | * \subsubsection sec2-3-2-9 Section 2.3.2.9: BoostLock _ Boost a shared | |
932 | * lock | |
933 | * | |
934 | * \par | |
935 | * void BoostLock(IN struct Lock *lock) | |
936 | * \par Description | |
937 | * This macro promotes ("boosts") a shared lock into a write lock. Such a boost | |
938 | * operation guarantees that no other writer can get into the critical section | |
939 | * in the process. Since this is a macro and not a function call, results are | |
940 | * not predictable if the value of the lock parameter is a side-effect | |
941 | * producing expression, as it will be evaluated multiple times in the course | |
942 | * of the macro interpretation. | |
943 | * \par Error Codes | |
944 | * ---No value is returned. | |
945 | * | |
946 | * \subsubsection sec2-3-2-10 Section 2.3.2.10: UnboostLock _ Unboost a | |
947 | * shared lock | |
948 | * | |
949 | * \par | |
950 | * void UnboostLock(IN struct Lock *lock) | |
951 | * \par Description | |
952 | * This macro demotes a boosted shared lock back down into a regular shared | |
953 | * lock. Such an unboost operation guarantees that no other writer can get into | |
954 | * the critical section in the process. Since this is a macro and not a | |
955 | * function call, results are not predictable if the value of the lock | |
956 | * parameter is a side-effect producing expression, as it will be evaluated | |
957 | * multiple times in the course of the macro interpretation. | |
958 | * \par Error Codes | |
959 | * ---No value is returned. | |
960 | * | |
961 | * \subsection sec2-3-3 Section 2.3.3: IOMGR | |
962 | * | |
963 | * \par | |
964 | * This section covers the calling interfaces to the I/O management package. | |
965 | * | |
966 | * \subsubsection sec2-3-3-1 Section: 2.3.3.1: IOMGR Initialize _ | |
967 | * Initialize the package | |
968 | * | |
969 | * \par | |
970 | * int IOMGR Initialize() | |
971 | * \par Description | |
972 | * This function initializes the IOMGR package. Its main task is to create the | |
973 | * IOMGR thread itself, which runs at the lowest possible priority (0). The | |
974 | * remainder of the lightweight processes must be running at priority 1 or | |
975 | * greater (up to a maximum of LWP MAX PRIORITY (4)) for the IOMGR package to | |
976 | * function correctly. | |
977 | * \par Error Codes | |
978 | * -1 The LWP and/or timer package haven't been initialized. | |
979 | * \n <misc> Any errors that may be returned by the LWP CreateProcess() | |
980 | * routine. | |
981 | * | |
982 | * \subsubsection sec2-3-3-2 Section 2.3.3.2: IOMGR finalize _ Clean up | |
983 | * the IOMGR facility | |
984 | * | |
985 | * \par | |
986 | * int IOMGR finalize() | |
987 | * \par Description | |
988 | * This routine cleans up after the IOMGR package when it is no longer needed. | |
989 | * It releases all storage and destroys the IOMGR thread itself. | |
990 | * \par Error Codes | |
991 | * <misc> Any errors that may be returned by the LWP DestroyProcess() routine. | |
992 | * | |
993 | * \subsubsection sec2-3-3-3 Section 2.3.3.3: IOMGR Select _ Perform a | |
994 | * thread-level select() | |
995 | * | |
996 | * \par | |
997 | * int IOMGR Select (IN int numfds; IN int *rfds; IN int *wfds; IN int *xfds; | |
998 | * IN truct timeval *timeout) | |
999 | * \par Description | |
1000 | * This routine performs an LWP version of unix select() operation. The | |
1001 | * parameters have the same meanings as with the unix call. However, the return | |
1002 | * values will be simplified (see below). If this is a polling select (i.e., | |
1003 | * the value of timeout is null), it is done and the IOMGR Select() function | |
1004 | * returns to the user with the results. Otherwise, the calling thread is put | |
1005 | * to sleep. If at some point the IOMGR thread is the only runnable process, it | |
1006 | * will awaken and collect all select requests. The IOMGR will then perform a | |
1007 | * single select and awaken the appropriate processes. This will force a return | |
1008 | * from the affected IOMGR Select() calls. | |
1009 | * \par Error Codes | |
1010 | * -1 An error occurred. | |
1011 | * \n 0 A timeout occurred. | |
1012 | * \n 1 Some number of file descriptors are ready. | |
1013 | * | |
1014 | * \subsubsection sec2-3-3-4 Section 2.3.3.4: IOMGR Signal _ Associate | |
1015 | * unix and LWP signals | |
1016 | * | |
1017 | * \par | |
1018 | * int IOMGR Signal(IN int signo; IN char *event) | |
1019 | * \par Description | |
1020 | * This function associates an LWP signal with a unix signal. After this call, | |
1021 | * when the given unix signal signo is delivered to the (heavyweight unix) | |
1022 | * process, the IOMGR thread will deliver an LWP signal to the event via LWP | |
1023 | * NoYieldSignal(). This wakes up any lightweight processes waiting on the | |
1024 | * event. Multiple deliveries of the signal may be coalesced into one LWP | |
1025 | * wakeup. The call to LWP NoYieldSignal() will happen synchronously. It is | |
1026 | * safe for an LWP to check for some condition and then go to sleep waiting for | |
1027 | * a unix signal without having to worry about delivery of the signal happening | |
1028 | * between the check and the call to LWP WaitProcess(). | |
1029 | * \par Error Codes | |
1030 | * LWP EBADSIG The signo value is out of range. | |
1031 | * \n LWP EBADEVENT The event pointer is null. | |
1032 | * | |
1033 | * \subsubsection sec2-3-3-5 Section 2.3.3.5: IOMGR CancelSignal _ Cancel | |
1034 | * unix and LWP signal association | |
1035 | * | |
1036 | * \par | |
1037 | * int IOMGR CancelSignal(IN int signo) | |
1038 | * \par Description | |
1039 | * This routine cancels the association between a unix signal and an LWP event. | |
1040 | * After calling this function, the unix signal signo will be handled however | |
1041 | * it was handled before the corresponding call to IOMGR Signal(). | |
1042 | * \par Error Codes | |
1043 | * LWP EBADSIG The signo value is out of range. | |
1044 | * | |
1045 | * \subsubsection sec2-3-3-6 Section 2.3.3.6: IOMGR Sleep _ Sleep for a | |
1046 | * given period | |
1047 | * | |
1048 | * \par | |
1049 | * void IOMGR Sleep(IN unsigned seconds) | |
1050 | * \par Description | |
1051 | * This function calls IOMGR Select() with zero file descriptors and a timeout | |
1052 | * structure set up to cause the thread to sleep for the given number of | |
1053 | * seconds. | |
1054 | * \par Error Codes | |
1055 | * ---No value is returned. | |
1056 | * | |
1057 | * \subsection sec2-3-4 Section 2.3.4: Timer | |
1058 | * | |
1059 | * \par | |
1060 | * This section covers the calling interface to the timer package associated | |
1061 | * with the LWP facility. | |
1062 | * | |
1063 | * \subsubsection sec2-3-4-1 Section 2.3.4.1: TM Init _ Initialize a timer | |
1064 | * list | |
1065 | * | |
1066 | * \par | |
1067 | * int TM Init(IN struct TM Elem **list) | |
1068 | * \par Description | |
1069 | * This function causes the specified timer list to be initialized. TM Init() | |
1070 | * must be called before any other timer operations are applied to the list. | |
1071 | * \par Error Codes | |
1072 | * -1 A null timer list could not be produced. | |
1073 | * | |
1074 | * \subsubsection sec2-3-4-2 Section 2.3.4.2: TM final _ Clean up a timer | |
1075 | * list | |
1076 | * | |
1077 | * \par | |
1078 | * int TM final(IN struct TM Elem **list) | |
1079 | * \par Description | |
1080 | * This routine is called when the given empty timer list is no longer needed. | |
1081 | * All storage associated with the list is released. | |
1082 | * \par Error Codes | |
1083 | * -1 The list parameter is invalid. | |
1084 | * | |
1085 | * \subsubsection sec2-3-4-3 Section 2.3.4.3: TM Insert _ Insert an object | |
1086 | * into a timer list | |
1087 | * | |
1088 | * \par | |
1089 | * void TM Insert(IN struct TM Elem **list; IN struct TM Elem *elem) | |
1090 | * \par Description | |
1091 | * This routine enters an new element, elem, into the list denoted by list. | |
1092 | * Before the new element is queued, its TimeLeft field (the amount of time | |
1093 | * before the object comes due) is set to the value stored in its TotalTime | |
1094 | * field. In order to keep TimeLeft fields current, the TM Rescan() function | |
1095 | * may be used. | |
1096 | * \par Error Codes | |
1097 | * ---No return value is generated. | |
1098 | * | |
1099 | * \subsubsection sec2-3-4-4 Section 2.3.4.4: TM Rescan _ Update all | |
1100 | * timers in the list | |
1101 | * | |
1102 | * \par | |
1103 | * int TM Rescan(IN struct TM Elem *list) | |
1104 | * \par Description | |
1105 | * This function updates the TimeLeft fields of all timers on the given list. | |
1106 | * This is done by checking the time-of-day clock. Note: this is the only | |
1107 | * routine other than TM Init() that updates the TimeLeft field in the elements | |
1108 | * on the list. | |
1109 | * \par | |
1110 | * Instead of returning a value indicating success or failure, TM Rescan() | |
1111 | * returns the number of entries that were discovered to have timed out. | |
1112 | * \par Error Codes | |
1113 | * ---Instead of error codes, the number of entries that were discovered to | |
1114 | * have timed out is returned. | |
1115 | * | |
1116 | * \subsubsection sec2-3-4-5 Section 2.3.4.5: TM GetExpired _ Returns an | |
1117 | * expired timer | |
1118 | * | |
1119 | * \par | |
1120 | * struct TM Elem *TM GetExpired(IN struct TM Elem *list) | |
1121 | * \par Description | |
1122 | * This routine searches the specified timer list and returns a pointer to an | |
1123 | * expired timer element from that list. An expired timer is one whose TimeLeft | |
1124 | * field is less than or equal to zero. If there are no expired timers, a null | |
1125 | * element pointer is returned. | |
1126 | * \par Error Codes | |
1127 | * ---Instead of error codes, an expired timer pointer is returned, or a null | |
1128 | * timer pointer if there are no expired timer objects. | |
1129 | * | |
1130 | * \subsubsection sec2-3-4-6 Section 2.3.4.6: TM GetEarliest _ Returns | |
1131 | * earliest unexpired timer | |
1132 | * | |
1133 | * \par | |
1134 | * struct TM Elem *TM GetEarliest(IN struct TM Elem *list) | |
1135 | * \par Description | |
1136 | * This function returns a pointer to the timer element that will be next to | |
1137 | * expire on the given list. This is defined to be the timer element with the | |
1138 | * smallest (positive) TimeLeft field. If there are no timers on the list, or | |
1139 | * if they are all expired, this function will return a null pointer. | |
1140 | * \par Error Codes | |
1141 | * ---Instead of error codes, a pointer to the next timer element to expireis | |
1142 | * returned, or a null timer object pointer if they are all expired. | |
1143 | * | |
1144 | * \subsubsection sec2-3-4-7 Section 2.3.4.7: TM eql _ Test for equality | |
1145 | * of two timestamps | |
1146 | * | |
1147 | * \par | |
1148 | * bool TM eql(IN struct timemval *t1; IN struct timemval *t2) | |
1149 | * \par Description | |
1150 | * This function compares the given timestamps, t1 and t2, for equality. Note | |
1151 | * that the function return value, bool, has been set via typedef to be | |
1152 | * equivalent to unsigned char. | |
1153 | * \par Error Codes | |
1154 | * 0 If the two timestamps differ. | |
1155 | * \n 1 If the two timestamps are identical. | |
1156 | * | |
1157 | * \subsection sec2-3-5 Section 2.3.5: Fast Time | |
1158 | * \par | |
1159 | * This section covers the calling interface to the fast time package | |
1160 | * associated with the LWP facility. | |
1161 | * | |
1162 | * \subsubsection sec2-3-5-1 Section 2.3.5.1: FT Init _ Initialize the | |
1163 | * fast time package | |
1164 | * | |
1165 | * \par | |
1166 | * int FT Init(IN int printErrors; IN int notReally) | |
1167 | * \par Description | |
1168 | * This routine initializes the fast time package, mapping in the kernel page | |
1169 | * containing the time-of-day variable. The printErrors argument, if non-zero, | |
1170 | * will cause any errors in initalization to be printed to stderr. The | |
1171 | * notReally parameter specifies whether initialization is really to be done. | |
1172 | * Other calls in this package will do auto-initialization, and hence the | |
1173 | * option is offered here. | |
1174 | * \par Error Codes | |
1175 | * -1 Indicates that future calls to FT GetTimeOfDay() will still work, but | |
1176 | * will not be able to access the information directly, having to make a | |
1177 | * kernel call every time. | |
1178 | * | |
1179 | * \subsubsection sec2-3-5-2 Section 2.3.5.2: FT GetTimeOfDay _ Initialize | |
1180 | * the fast time package | |
1181 | * | |
1182 | * \par | |
1183 | * int FT GetTimeOfDay(IN struct timeval *tv; IN struct timezone *tz) | |
1184 | * \par Description | |
1185 | * This routine is meant to mimic the parameters and behavior of the unix | |
1186 | * gettimeofday() function. However, as implemented, it simply calls | |
1187 | * gettimeofday() and then does some bound-checking to make sure the value is | |
1188 | * reasonable. | |
1189 | * \par Error Codes | |
1190 | * <misc> Whatever value was returned by gettimeofday() internally. | |
1191 | * | |
1192 | * \subsection sec2-3-6 Section 2.3.6: Preemption | |
1193 | * \par | |
1194 | * This section covers the calling interface to the preemption package | |
1195 | * associated with the LWP facility. | |
1196 | * | |
1197 | * \subsubsection sec2-3-6-1 Section 2.3.6.1: PRE InitPreempt _ Initialize | |
1198 | * the preemption package | |
1199 | * | |
1200 | * \par | |
1201 | * int PRE InitPreempt(IN struct timeval *slice) | |
1202 | * \par Description | |
1203 | * This function must be called to initialize the preemption package. It must | |
1204 | * appear sometime after the call to LWP InitializeProcessSupport() and | |
1205 | * sometime before the first call to any other preemption routine. The slice | |
1206 | * argument specifies the time slice size to use. If the slice pointer is set | |
1207 | * to null in the call, then the default time slice, DEFAULTSLICE (10 | |
1208 | * milliseconds), will be used. This routine uses the unix interval timer and | |
1209 | * handling of the unix alarm signal, SIGALRM, to implement this timeslicing. | |
1210 | * \par Error Codes | |
1211 | * LWP EINIT The LWP package hasn't been initialized. | |
1212 | * \n LWP ESYSTEM Operations on the signal vector or the interval timer have | |
1213 | * failed. | |
1214 | * | |
1215 | * \subsubsection sec2-3-6-2 Section 2.3.6.2: PRE EndPreempt _ finalize | |
1216 | * the preemption package | |
1217 | * | |
1218 | * \par | |
1219 | * int PRE EndPreempt() | |
1220 | * \par Description | |
1221 | * This routine finalizes use of the preemption package. No further preemptions | |
1222 | * will be made. Note that it is not necessary to make this call before exit. | |
1223 | * PRE EndPreempt() is provided only for those applications that wish to | |
1224 | * continue after turning off preemption. | |
1225 | * \par Error Codes | |
1226 | * LWP EINIT The LWP package hasn't been initialized. | |
1227 | * \n LWP ESYSTEM Operations on the signal vector or the interval timer have | |
1228 | * failed. | |
1229 | * | |
1230 | * \subsubsection sec2-3-6-3 Section 2.3.6.3: PRE PreemptMe _ Mark thread | |
1231 | * as preemptible | |
1232 | * | |
1233 | * \par | |
1234 | * int PRE PreemptMe() | |
1235 | * \par Description | |
1236 | * This macro is used to signify the current thread as a candidate for | |
1237 | * preemption. The LWP InitializeProcessSupport() routine must have been called | |
1238 | * before PRE PreemptMe(). | |
1239 | * \par Error Codes | |
1240 | * ---No return code is generated. | |
1241 | * | |
1242 | * \subsubsection sec2-3-6-4 Section 2.3.6.4: PRE BeginCritical _ Enter | |
1243 | * thread critical section | |
1244 | * | |
1245 | * \par | |
1246 | * int PRE BeginCritical() | |
1247 | * \par Description | |
1248 | * This macro places the current thread in a critical section. Upon return, and | |
1249 | * for as long as the thread is in the critical section, involuntary | |
1250 | * preemptions of this LWP will no longer occur. | |
1251 | * \par Error Codes | |
1252 | * ---No return code is generated. | |
1253 | * | |
1254 | * \subsubsection sec2-3-6-5 Section 2.3.6.5: PRE EndCritical _ Exit | |
1255 | * thread critical section | |
1256 | * | |
1257 | * \par | |
1258 | * int PRE EndCritical() | |
1259 | * \par Description | |
1260 | * This macro causes the executing thread to leave a critical section | |
1261 | * previously entered via PRE BeginCritical(). If involuntary preemptions were | |
1262 | * possible before the matching PRE BeginCritical(), they are once again | |
1263 | * possible. | |
1264 | * \par Error Codes | |
1265 | * ---No return code is generated. | |
1266 | * | |
1267 | * \page chap3 Chapter 3 -- Rxkad | |
1268 | * | |
1269 | * | |
1270 | * \section sec3-1 Section 3.1: Introduction | |
1271 | * | |
1272 | * \par | |
1273 | * The rxkad security module is offered as one of the built-in Rx | |
1274 | * authentication models. It is based on the Kerberos system developed by MIT's | |
1275 | * Project Athena. Readers wishing detailed information regarding Kerberos | |
1276 | * design and implementation are directed to [2]. This chapter is devoted to | |
1277 | * defining how Kerberos authentication services are made available as Rx | |
1278 | * components, and assumes the reader has some familiarity with Kerberos. | |
1279 | * Included are descriptions of how client-side and server-side Rx security | |
1280 | * objects (struct rx securityClass; see Section 5.3.1.1) implementing this | |
1281 | * protocol may be generated by an Rx application. Also, a description appears | |
1282 | * of the set of routines available in the associated struct rx securityOps | |
1283 | * structures, as covered in Section 5.3.1.2. It is strongly recommended that | |
1284 | * the reader become familiar with this section on struct rx securityOps before | |
1285 | * reading on. | |
1286 | * | |
1287 | * \section sec3-2 Section 3.2: Definitions | |
1288 | * | |
1289 | * \par | |
1290 | * An important set of definitions related to the rxkad security package is | |
1291 | * provided by the rxkad.h include file. Determined here are various values for | |
1292 | * ticket lifetimes, along with structures for encryption keys and Kerberos | |
1293 | * principals. Declarations for the two routines required to generate the | |
1294 | * different rxkad security objects also appear here. The two functions are | |
1295 | * named rxkad NewServerSecurityObject() and rxkad NewClientSecurityObject(). | |
1296 | * In addition, type field values, encryption levels, security index | |
1297 | * operations, and statistics structures may be found in this file. | |
1298 | * \section sec3-3 Section 3.3: Exported Objects | |
1299 | * \par | |
1300 | * To be usable as an Rx security module, the rxkad facility exports routines | |
1301 | * to create server-side and client-side security objects. The server | |
1302 | * authentication object is incorporated into the server code when calling rx | |
1303 | * NewService(). The client authentication object is incorporated into the | |
1304 | * client code every time a connection is established via rx NewConnection(). | |
1305 | * Also, in order to implement these security objects, the rxkad module must | |
1306 | * provide definitions for some subset of the generic security operations as | |
1307 | * defined in the appropriate struct rx securityOps variable. | |
1308 | * | |
1309 | * \subsection sec3-3-1 Section 3.3.1: Server-Side Mechanisms | |
1310 | * | |
1311 | * \subsubsection sec3-3-1-1 Section 3.3.1.1: Security Operations | |
1312 | * | |
1313 | * \par | |
1314 | * The server side of the rxkad module fills in all but two of the possible | |
1315 | * routines associated with an Rx security object, as described in Section | |
1316 | * 5.3.1.2. | |
1317 | * | |
1318 | * \code | |
1319 | * static struct rx_securityOps rxkad_server_ops = { | |
1320 | * rxkad_Close, | |
1321 | * rxkad_NewConnection, | |
1322 | * rxkad_PreparePacket, /* Once per packet creation */ | |
1323 | * 0, /* Send packet (once per retrans) */ | |
1324 | * rxkad_CheckAuthentication, | |
1325 | * rxkad_CreateChallenge, | |
1326 | * rxkad_GetChallenge, | |
1327 | * 0, | |
1328 | * rxkad_CheckResponse, /* Check data packet */ | |
1329 | * rxkad_DestroyConnection, | |
1330 | * rxkad_GetStats, | |
1331 | * }; | |
1332 | * \endcode | |
1333 | * | |
1334 | * \par | |
1335 | * The rxkad service does not need to take any special action each time a | |
1336 | * packet belonging to a call in an rxkad Rx connection is physically | |
1337 | * transmitted. Thus, a routine is not supplied for the op SendPacket() | |
1338 | * function slot. Similarly, no preparatory work needs to be done previous to | |
1339 | * the reception of a response packet from a security challenge, so the op | |
1340 | * GetResponse() function slot is also empty. | |
1341 | * | |
1342 | * \subsubsection sec3-3-1-2 Section 3.3.1.2: Security Object | |
1343 | * | |
1344 | * \par | |
1345 | * The exported routine used to generate an rxkad-specific server-side security | |
1346 | * class object is named rxdad NewServerSecurityObject(). It is declared with | |
1347 | * four parameters, as follows: | |
1348 | * | |
1349 | * \code | |
1350 | * struct rx_securityClass * | |
1351 | * rxkad_NewServerSecurityObject(a_level, a_getKeyRockP, a_getKeyP, a_userOKP) | |
1352 | * rxkad_level a_level; /* Minimum level */ | |
1353 | * char *a_getKeyRockP; /* Rock for get_key implementor */ | |
1354 | * int (*a_getKeyP)(); /* Passed kvno & addr(key) to fill */ | |
1355 | * int (*a_userOKP)(); /* Passed name, inst, cell => bool */ | |
1356 | * \endcode | |
1357 | * | |
1358 | * \par | |
1359 | * The first argument specifies the desired level of encryption, and may take | |
1360 | * on the following values (as defined in rxkad.h): | |
1361 | * \li rxkad clear: Specifies that packets are to be sent entirely in the | |
1362 | * clear, without any encryption whatsoever. | |
1363 | * \li rxkad auth: Specifies that packet sequence numbers are to be encrypted. | |
1364 | * \li rxkad crypt: Specifies that the entire data packet is to be encrypted. | |
1365 | * | |
1366 | * \par | |
1367 | * The second and third parameters represent, respectively, a pointer to a | |
1368 | * private data area, sometimes called a "rock", and a procedure reference that | |
1369 | * is called with the key version number accompanying the Kerberos ticket and | |
1370 | * returns a pointer to the server's decryption key. The fourth argument, if | |
1371 | * not null, is a pointer to a function that will be called for every new | |
1372 | * connection with the client's name, instance, and cell. This routine should | |
1373 | * return zero if the user is not acceptable to the server. | |
1374 | * | |
1375 | * \subsection sec3-3-2 Section 3.3.2: Client-Side Mechanisms | |
1376 | * | |
1377 | * \subsubsection sec3-3-2-1 Section 3.3.2.1: Security Operations | |
1378 | * | |
1379 | * \par | |
1380 | * The client side of the rxkad module fills in relatively few of the routines | |
1381 | * associated with an Rx security object, as demonstrated below. The general Rx | |
1382 | * security object, of which this is an instance, is described in detail in | |
1383 | * Section 5.3.1.2. | |
1384 | * | |
1385 | * \code | |
1386 | * static struct rx_securityOps rxkad_client_ops = { | |
1387 | * rxkad_Close, | |
1388 | * rxkad_NewConnection, /* Every new connection */ | |
1389 | * rxkad_PreparePacket, /* Once per packet creation */ | |
1390 | * 0, /* Send packet (once per retrans) */ | |
1391 | * 0, | |
1392 | * 0, | |
1393 | * 0, | |
1394 | * rxkad_GetResponse, /* Respond to challenge packet */ | |
1395 | * 0, | |
1396 | * rxkad_CheckPacket, /* Check data packet */ | |
1397 | * rxkad_DestroyConnection, | |
1398 | * rxkad_GetStats, | |
1399 | * 0, | |
1400 | * 0, | |
1401 | * 0, | |
1402 | * }; | |
1403 | * \endcode | |
1404 | * | |
1405 | * \par | |
1406 | * As expected, routines are defined for use when someone destroys a security | |
1407 | * object (rxkad Close()) and when an Rx connection using the rxkad model | |
1408 | * creates a new connection (rxkad NewConnection()) or deletes an existing one | |
1409 | * (rxkad DestroyConnection()). Security-specific operations must also be | |
1410 | * performed in behalf of rxkad when packets are created (rxkad | |
1411 | * PreparePacket()) and received (rxkad CheckPacket()). finally, the client | |
1412 | * side of an rxkad security object must also be capable of constructing | |
1413 | * responses to security challenges from the server (rxkad GetResponse()) and | |
1414 | * be willing to reveal statistics on its own operation (rxkad GetStats()). | |
1415 | * | |
1416 | * \subsubsection sec3-3-2-2 Section 3.3.2.2: Security Object | |
1417 | * | |
1418 | * \par | |
1419 | * The exported routine used to generate an rxkad-specific client-side security | |
1420 | * class object is named rxkad NewClientSecurityObject(). It is declared with | |
1421 | * five parameters, specified below: | |
1422 | * | |
1423 | * \code | |
1424 | * struct rx_securityClass * rxkad_NewClientSecurityObject( | |
1425 | * a_level, | |
1426 | * a_sessionKeyP, | |
1427 | * a_kvno, | |
1428 | * a_ticketLen, | |
1429 | * a_ticketP | |
1430 | * ) | |
1431 | * rxkad_level a_level; | |
1432 | * struct ktc_encryptionKey *a_sessionKeyP; | |
1433 | * long a_kvno; | |
1434 | * int a_ticketLen; | |
1435 | * char *a_ticketP; | |
1436 | * \endcode | |
1437 | * | |
1438 | * \par | |
1439 | * The first parameter, a level, specifies the level of encryption desired for | |
1440 | * this security object, with legal choices being identical to those defined | |
1441 | * for the server-side security object described in Section 3.3.1.2. The second | |
1442 | * parameter, a sessionKeyP, provides the session key to use. The ktc | |
1443 | * encryptionKey structure is defined in the rxkad.h include file, and consists | |
1444 | * of an array of 8 characters. The third parameter, a kvno, provides the key | |
1445 | * version number associated with a sessionKeyP. The fourth argument, a | |
1446 | * ticketLen, communicates the length in bytes of the data stored in the fifth | |
1447 | * parameter, a ticketP, which points to the Kerberos ticket to use for the | |
1448 | * principal for which the security object will operate. | |
1449 | * | |
1450 | * \page chap4 Chapter 4 -- Rx Support Packages | |
1451 | * | |
1452 | * \section sec4-1 Section 4.1: Introduction | |
1453 | * \par | |
1454 | * This chapter documents three packages defined directly in support of the Rx | |
1455 | * facility. | |
1456 | * \li rx queue: Doubly-linked queue package. | |
1457 | * \li rx clock: Clock package, using the 4.3BSD interval timer. | |
1458 | * \li rx event: Future events package. | |
1459 | * \par | |
1460 | * References to constants, structures, and functions defined by these support | |
1461 | * packages will appear in the following API chapter. | |
1462 | * | |
1463 | * \section sec4-2 Section 4.2: The rx queue Package | |
1464 | * | |
1465 | * \par | |
1466 | * This package provides a doubly-linked queue structure, along with a full | |
1467 | * suite of related operations. The main concern behind the coding of this | |
1468 | * facility was efficiency. All functions are implemented as macros, and it is | |
1469 | * suggested that only simple expressions be used for all parameters. | |
1470 | * \par | |
1471 | * The rx queue facility is defined by the rx queue.h include file. Some macros | |
1472 | * visible in this file are intended for rx queue internal use only. An | |
1473 | * understanding of these "hidden" macros is important, so they will also be | |
1474 | * described by this document. | |
1475 | * | |
1476 | * \subsection sec4-2-1 Section 4.2.1: struct queue | |
1477 | * | |
1478 | * \par | |
1479 | * The queue structure provides the linkage information required to maintain a | |
1480 | * queue of objects. The queue structure is prepended to any user-defined data | |
1481 | * type which is to be organized in this fashion. | |
1482 | * \n \b fields | |
1483 | * \li struct queue *prev - Pointer to the previous queue header. | |
1484 | * \li struct queue *next - Pointer to the next queue header. | |
1485 | * \par | |
1486 | * Note that a null Rx queue consists of a single struct queue object whose | |
1487 | * next and previous pointers refer to itself. | |
1488 | * | |
1489 | * \subsection sec4-2-2 Section 4.2.2: Internal Operations | |
1490 | * | |
1491 | * \par | |
1492 | * This section describes the internal operations defined for Rx queues. They | |
1493 | * will be referenced by the external operations documented in Section 4.2.3. | |
1494 | * | |
1495 | * \subsection sec4-2-2-1 Section 4.2.2.1: Q(): Coerce type to a queue | |
1496 | * element | |
1497 | * | |
1498 | * \par | |
1499 | * \#define _Q(x) ((struct queue *)(x)) | |
1500 | * \par | |
1501 | * This operation coerces the user structure named by x to a queue element. Any | |
1502 | * user structure using the rx queue package must have a struct queue as its | |
1503 | * first field. | |
1504 | * | |
1505 | * \subsubsection sec4-2-2-2 Section 4.2.2.2: QA(): Add a queue element | |
1506 | * before/after another element | |
1507 | * | |
1508 | * \par | |
1509 | * \#define _QA(q,i,a,b) (((i->a=q->a)->b=i)->b=q, q->a=i) | |
1510 | * \par | |
1511 | * This operation adds the queue element referenced by i either before or after | |
1512 | * a queue element represented by q. If the (a, b) argument pair corresponds to | |
1513 | * an element's (next, prev) fields, the new element at i will be linked after | |
1514 | * q. If the (a, b) argument pair corresponds to an element's (prev, next) | |
1515 | * fields, the new element at i will be linked before q. | |
1516 | * | |
1517 | * \subsubsection sec4-2-2-3 QR(): Remove a queue element | |
1518 | * | |
1519 | * \par | |
1520 | * \#define _QR(i) ((_Q(i)->prev->next=_Q(i)->next)->prev=_Q(i)->prev) | |
1521 | * \par | |
1522 | * This operation removes the queue element referenced by i from its queue. The | |
1523 | * prev and next fields within queue element i itself is not updated to reflect | |
1524 | * the fact that it is no longer part of the queue. | |
1525 | * | |
1526 | * \subsubsection sec4-2-2-4 QS(): Splice two queues together | |
1527 | * | |
1528 | * \par | |
1529 | * \#define _QS(q1,q2,a,b) if (queue_IsEmpty(q2)); else | |
1530 | * ((((q2->a->b=q1)->a->b=q2->b)->a=q1->a, q1->a=q2->a), queue_Init(q2)) | |
1531 | * \par | |
1532 | * This operation takes the queues identified by q1 and q2 and splices them | |
1533 | * together into a single queue. The order in which the two queues are appended | |
1534 | * is determined by the a and b arguments. If the (a, b) argument pair | |
1535 | * corresponds to q1's (next, prev) fields, then q2 is appended to q1. If the | |
1536 | * (a, b) argument pair corresponds to q1's (prev, next) fields, then q is | |
1537 | * prepended to q2. | |
1538 | * \par | |
1539 | * This internal QS() routine uses two exported queue operations, namely queue | |
1540 | * Init() and queue IsEmpty(), defined in Sections 4.2.3.1 and 4.2.3.16 | |
1541 | * respectively below. | |
1542 | * | |
1543 | * \subsection sec4-2-3 Section 4.2.3: External Operations | |
1544 | * | |
1545 | * \subsubsection sec4-2-3-1 Section 4.2.3.1: queue Init(): Initialize a | |
1546 | * queue header | |
1547 | * | |
1548 | * \par | |
1549 | * \#define queue_Init(q) (_Q(q))->prev = (_Q(q))->next = (_Q(q)) | |
1550 | * \par | |
1551 | * The queue header referred to by the q argument is initialized so that it | |
1552 | * describes a null (empty) queue. A queue head is simply a queue element. | |
1553 | * | |
1554 | * \subsubsection sec4-2-3-2 Section 4.2.3.2: queue Prepend(): Put element | |
1555 | * at the head of a queue | |
1556 | * | |
1557 | * \par | |
1558 | * \#define queue_Prepend(q,i) _QA(_Q(q),_Q(i),next,prev) | |
1559 | * \par | |
1560 | * Place queue element i at the head of the queue denoted by q. The new queue | |
1561 | * element, i, should not currently be on any queue. | |
1562 | * | |
1563 | * \subsubsection sec4-2-3-3 Section 4.2.3.3: queue Append(): Put an | |
1564 | * element a the tail of a queue | |
1565 | * | |
1566 | * \par | |
1567 | * \#define queue_Append(q,i) _QA(_Q(q),_Q(i),prev,next) | |
1568 | * \par | |
1569 | * Place queue element i at the tail of the queue denoted by q. The new queue | |
1570 | * element, i, should not currently be on any queue. | |
1571 | * | |
1572 | * \subsection sec4-2-3-4 Section 4.2.3.4: queue InsertBefore(): Insert a | |
1573 | * queue element before another element | |
1574 | * | |
1575 | * \par | |
1576 | * \#define queue_InsertBefore(i1,i2) _QA(_Q(i1),_Q(i2),prev,next) | |
1577 | * \par | |
1578 | * Insert queue element i2 before element i1 in i1's queue. The new queue | |
1579 | * element, i2, should not currently be on any queue. | |
1580 | * | |
1581 | * \subsubsection sec4-2-3-5 Section 4.2.3.5: queue InsertAfter(): Insert | |
1582 | * a queue element after another element | |
1583 | * | |
1584 | * \par | |
1585 | * \#define queue_InsertAfter(i1,i2) _QA(_Q(i1),_Q(i2),next,prev) | |
1586 | * \par | |
1587 | * Insert queue element i2 after element i1 in i1's queue. The new queue | |
1588 | * element, i2, should not currently be on any queue. | |
1589 | * | |
1590 | * \subsubsection sec4-2-3-6 Section: 4.2.3.6: queue SplicePrepend(): | |
1591 | * Splice one queue before another | |
1592 | * | |
1593 | * \par | |
1594 | * \#define queue_SplicePrepend(q1,q2) _QS(_Q(q1),_Q(q2),next,prev) | |
1595 | * \par | |
1596 | * Splice the members of the queue located at q2 to the beginning of the queue | |
1597 | * located at q1, reinitializing queue q2. | |
1598 | * | |
1599 | * \subsubsection sec4-2-3-7 Section 4.2.3.7: queue SpliceAppend(): Splice | |
1600 | * one queue after another | |
1601 | * | |
1602 | * \par | |
1603 | * \#define queue_SpliceAppend(q1,q2) _QS(_Q(q1),_Q(q2),prev,next) | |
1604 | * \par | |
1605 | * Splice the members of the queue located at q2 to the end of the queue | |
1606 | * located at q1, reinitializing queue q2. Note that the implementation of | |
1607 | * queue SpliceAppend() is identical to that of queue SplicePrepend() except | |
1608 | * for the order of the next and prev arguments to the internal queue splicer, | |
1609 | * QS(). | |
1610 | * | |
1611 | * \subsubsection sec4-2-3-8 Section 4.2.3.8: queue Replace(): Replace the | |
1612 | * contents of a queue with that of another | |
1613 | * | |
1614 | * \par | |
1615 | * \#define queue_Replace(q1,q2) (*_Q(q1) = *_Q(q2), | |
1616 | * \n _Q(q1)->next->prev = _Q(q1)->prev->next = _Q(q1), | |
1617 | * \n queue_Init(q2)) | |
1618 | * \par | |
1619 | * Replace the contents of the queue located at q1 with the contents of the | |
1620 | * queue located at q2. The prev and next fields from q2 are copied into the | |
1621 | * queue object referenced by q1, and the appropriate element pointers are | |
1622 | * reassigned. After the replacement has occurred, the queue header at q2 is | |
1623 | * reinitialized. | |
1624 | * | |
1625 | * \subsubsection sec4-2-3-9 Section 4.2.3.9: queue Remove(): Remove an | |
1626 | * element from its queue | |
1627 | * | |
1628 | * \par | |
1629 | * \#define queue_Remove(i) (_QR(i), _Q(i)->next = 0) | |
1630 | * \par | |
1631 | * This function removes the queue element located at i from its queue. The | |
1632 | * next field for the removed entry is zeroed. Note that multiple removals of | |
1633 | * the same queue item are not supported. | |
1634 | * | |
1635 | * \subsubsection sec4-2-3-10 Section 4.2.3.10: queue MoveAppend(): Move | |
1636 | * an element from its queue to the end of another queue | |
1637 | * | |
1638 | * \par | |
1639 | * \#define queue_MoveAppend(q,i) (_QR(i), queue_Append(q,i)) | |
1640 | * \par | |
1641 | * This macro removes the queue element located at i from its current queue. | |
1642 | * Once removed, the element at i is appended to the end of the queue located | |
1643 | * at q. | |
1644 | * | |
1645 | * \subsubsection sec4-2-3-11 Section 4.2.3.11: queue MovePrepend(): Move | |
1646 | * an element from its queue to the head of another queue | |
1647 | * | |
1648 | * \par | |
1649 | * \#define queue_MovePrepend(q,i) (_QR(i), queue_Prepend(q,i)) | |
1650 | * \par | |
1651 | * This macro removes the queue element located at i from its current queue. | |
1652 | * Once removed, the element at i is inserted at the head fo the queue located | |
1653 | * at q. | |
1654 | * | |
1655 | * \subsubsection sec4-2-3-12 Section 4.2.3.12: queue first(): Return the | |
1656 | * first element of a queue, coerced to a particular type | |
1657 | * | |
1658 | * \par | |
1659 | * \#define queue_first(q,s) ((struct s *)_Q(q)->next) | |
1660 | * \par | |
1661 | * Return a pointer to the first element of the queue located at q. The | |
1662 | * returned pointer value is coerced to conform to the given s structure. Note | |
1663 | * that a properly coerced pointer to the queue head is returned if q is empty. | |
1664 | * | |
1665 | * \subsubsection sec4-2-3-13 Section 4.2.3.13: queue Last(): Return the | |
1666 | * last element of a queue, coerced to a particular type | |
1667 | * | |
1668 | * \par | |
1669 | * \#define queue_Last(q,s) ((struct s *)_Q(q)->prev) | |
1670 | * \par | |
1671 | * Return a pointer to the last element of the queue located at q. The returned | |
1672 | * pointer value is coerced to conform to the given s structure. Note that a | |
1673 | * properly coerced pointer to the queue head is returned if q is empty. | |
1674 | * | |
1675 | * \subsubsection sec4-2-3-14 Section 4.2.3.14: queue Next(): Return the | |
1676 | * next element of a queue, coerced to a particular type | |
1677 | * | |
1678 | * \par | |
1679 | * \#define queue_Next(i,s) ((struct s *)_Q(i)->next) | |
1680 | * \par | |
1681 | * Return a pointer to the queue element occuring after the element located at | |
1682 | * i. The returned pointer value is coerced to conform to the given s | |
1683 | * structure. Note that a properly coerced pointer to the queue head is | |
1684 | * returned if item i is the last in its queue. | |
1685 | * | |
1686 | * \subsubsection sec4-2-3-15 Section 4.2.3.15: queue Prev(): Return the | |
1687 | * next element of a queue, coerced to a particular type | |
1688 | * | |
1689 | * \par | |
1690 | * \#define queue_Prev(i,s) ((struct s *)_Q(i)->prev) | |
1691 | * \par | |
1692 | * Return a pointer to the queue element occuring before the element located at | |
1693 | * i. The returned pointer value is coerced to conform to the given s | |
1694 | * structure. Note that a properly coerced pointer to the queue head is | |
1695 | * returned if item i is the first in its queue. | |
1696 | * | |
1697 | * \subsubsection sec4-2-3-16 Section 4.2.3.16: queue IsEmpty(): Is the | |
1698 | * given queue empty? | |
1699 | * | |
1700 | * \par | |
1701 | * \#define queue_IsEmpty(q) (_Q(q)->next == _Q(q)) | |
1702 | * \par | |
1703 | * Return a non-zero value if the queue located at q does not have any elements | |
1704 | * in it. In this case, the queue consists solely of the queue header at q | |
1705 | * whose next and prev fields reference itself. | |
1706 | * | |
1707 | * \subsubsection sec4-2-3-17 Section 4.2.3.17: queue IsNotEmpty(): Is the | |
1708 | * given queue not empty? | |
1709 | * | |
1710 | * \par | |
1711 | * \#define queue_IsNotEmpty(q) (_Q(q)->next != _Q(q)) | |
1712 | * \par | |
1713 | * Return a non-zero value if the queue located at q has at least one element | |
1714 | * in it other than the queue header itself. | |
1715 | * | |
1716 | * \subsubsection sec4-2-3-18 Section 4.2.3.18: queue IsOnQueue(): Is an | |
1717 | * element currently queued? | |
1718 | * | |
1719 | * \par | |
1720 | * \#define queue_IsOnQueue(i) (_Q(i)->next != 0) | |
1721 | * \par | |
1722 | * This macro returns a non-zero value if the queue item located at i is | |
1723 | * currently a member of a queue. This is determined by examining its next | |
1724 | * field. If it is non-null, the element is considered to be queued. Note that | |
1725 | * any element operated on by queue Remove() (Section 4.2.3.9) will have had | |
1726 | * its next field zeroed. Hence, it would cause a non-zero return from this | |
1727 | * call. | |
1728 | * | |
1729 | * \subsubsection sec4-2-3-19 Section 4.2.3.19: queue Isfirst(): Is an | |
1730 | * element the first on a queue? | |
1731 | * | |
1732 | * \par | |
1733 | * \#define queue_Isfirst(q,i) (_Q(q)->first == _Q(i)) | |
1734 | * \par | |
1735 | * This macro returns a non-zero value if the queue item located at i is the | |
1736 | * first element in the queue denoted by q. | |
1737 | * | |
1738 | * \subsubsection sec4-2-3-20 Section 4.2.3.20: queue IsLast(): Is an | |
1739 | * element the last on a queue? | |
1740 | * | |
1741 | * \par | |
1742 | * \#define queue_IsLast(q,i) (_Q(q)->prev == _Q(i)) | |
1743 | * \par | |
1744 | * This macro returns a non-zero value if the queue item located at i is the | |
1745 | * last element in the queue denoted by q. | |
1746 | * | |
1747 | * \subsubsection sec4-2-3-21 Section 4.2.3.21: queue IsEnd(): Is an | |
1748 | * element the end of a queue? | |
1749 | * | |
1750 | * \par | |
1751 | * \#define queue_IsEnd(q,i) (_Q(q) == _Q(i)) | |
1752 | * \par | |
1753 | * This macro returns a non-zero value if the queue item located at i is the | |
1754 | * end of the queue located at q. Basically, it determines whether a queue | |
1755 | * element in question is also the queue header structure itself, and thus does | |
1756 | * not represent an actual queue element. This function is useful for | |
1757 | * terminating an iterative sweep through a queue, identifying when the search | |
1758 | * has wrapped to the queue header. | |
1759 | * | |
1760 | * \subsubsection sec4-2-3-22 Section 4.2.3.22: queue Scan(): for loop | |
1761 | * test for scanning a queue in a forward direction | |
1762 | * | |
1763 | * \par | |
1764 | * \#define queue_Scan(q, qe, next, s) | |
1765 | * \n (qe) = queue_first(q, s), next = queue_Next(qe, s); | |
1766 | * \n !queue_IsEnd(q, qe); | |
1767 | * \n (qe) = (next), next = queue_Next(qe, s) | |
1768 | * \par | |
1769 | * This macro may be used as the body of a for loop test intended to scan | |
1770 | * through each element in the queue located at q. The qe argument is used as | |
1771 | * the for loop variable. The next argument is used to store the next value for | |
1772 | * qe in the upcoming loop iteration. The s argument provides the name of the | |
1773 | * structure to which each queue element is to be coerced. Thus, the values | |
1774 | * provided for the qe and next arguments must be of type (struct s *). | |
1775 | * \par | |
1776 | * An example of how queue Scan() may be used appears in the code fragment | |
1777 | * below. It declares a structure named mystruct, which is suitable for | |
1778 | * queueing. This queueable structure is composed of the queue pointers | |
1779 | * themselves followed by an integer value. The actual queue header is kept in | |
1780 | * demoQueue, and the currItemP and nextItemP variables are used to step | |
1781 | * through the demoQueue. The queue Scan() macro is used in the for loop to | |
1782 | * generate references in currItemP to each queue element in turn for each | |
1783 | * iteration. The loop is used to increment every queued structure's myval | |
1784 | * field by one. | |
1785 | * | |
1786 | * \code | |
1787 | * struct mystruct { | |
1788 | * struct queue q; | |
1789 | * int myval; | |
1790 | * }; | |
1791 | * struct queue demoQueue; | |
1792 | * struct mystruct *currItemP, *nextItemP; | |
1793 | * ... | |
1794 | * for (queue_Scan(&demoQueue, currItemP, nextItemP, mystruct)) { | |
1795 | * currItemP->myval++; | |
1796 | * } | |
1797 | * \endcode | |
1798 | * | |
1799 | * \par | |
1800 | * Note that extra initializers can be added before the body of the queue | |
1801 | * Scan() invocation above, and extra expressions can be added afterwards. | |
1802 | * | |
1803 | * \subsubsection sec4-2-3-23 Section 4.2.3.23: queue ScanBackwards(): for | |
1804 | * loop test for scanning a queue in a reverse direction | |
1805 | * | |
1806 | * \par | |
1807 | * #define queue_ScanBackwards(q, qe, prev, s) | |
1808 | * \n (qe) = queue_Last(q, s), prev = queue_Prev(qe, s); | |
1809 | * \n !queue_IsEnd(q, qe); | |
1810 | * \n (qe) = prev, prev = queue_Prev(qe, s) | |
1811 | * \par | |
1812 | * This macro is identical to the queue Scan() macro described above in Section | |
1813 | * 4.2.3.22 except for the fact that the given queue is scanned backwards, | |
1814 | * starting at the last item in the queue. | |
1815 | * | |
1816 | * \section sec4-3 Section 4.3: The rx clock Package | |
1817 | * | |
1818 | * \par | |
1819 | * This package maintains a clock which is independent of the time of day. It | |
1820 | * uses the unix 4.3BSD interval timer (e.g., getitimer(), setitimer()) in | |
1821 | * TIMER REAL mode. Its definition and interface may be found in the rx clock.h | |
1822 | * include file. | |
1823 | * | |
1824 | * \subsection sec4-3-1 Section 4.3.1: struct clock | |
1825 | * | |
1826 | * \par | |
1827 | * This structure is used to represent a clock value as understood by this | |
1828 | * package. It consists of two fields, storing the number of seconds and | |
1829 | * microseconds that have elapsed since the associated clock Init() routine has | |
1830 | * been called. | |
1831 | * \par | |
1832 | * \b fields | |
1833 | * \n long sec -Seconds since call to clock Init(). | |
1834 | * \n long usec -Microseconds since call to clock Init(). | |
1835 | * | |
1836 | * \subsection sec4-3-2 Section 4.3.12: clock nUpdates | |
1837 | * | |
1838 | * \par | |
1839 | * The integer-valued clock nUpdates is a variable exported by the rx clock | |
1840 | * facility. It records the number of times the clock value is actually | |
1841 | * updated. It is bumped each time the clock UpdateTime() routine is called, as | |
1842 | * described in Section 4.3.3.2. | |
1843 | * | |
1844 | * \subsection sec4-3-3 Section 4.3.3: Operations | |
1845 | * | |
1846 | * \subsubsection sec4-3-3-1 Section 4.3.3.1: clock Init(): Initialize the | |
1847 | * clock package | |
1848 | * | |
1849 | * \par | |
1850 | * This routine uses the unix setitimer() call to initialize the unix interval | |
1851 | * timer. If the setitimer() call fails, an error message will appear on | |
1852 | * stderr, and an exit(1) will be executed. | |
1853 | * | |
1854 | * \subsubsection sec4-3-3-2 Section 4.3.3.2: clock UpdateTime(): Compute | |
1855 | * the current time | |
1856 | * | |
1857 | * \par | |
1858 | * The clock UpdateTime() function calls the unix getitimer() routine in order | |
1859 | * to update the current time. The exported clock nUpdates variable is | |
1860 | * incremented each time the clock UpdateTime() routine is called. | |
1861 | * | |
1862 | * \subsubsection sec4-3-3-3 Section 4.3.3.3: clock GetTime(): Return the | |
1863 | * current clock time | |
1864 | * | |
1865 | * \par | |
1866 | * This macro updates the current time if necessary, and returns the current | |
1867 | * time into the cv argument, which is declared to be of type (struct clock *). | |
1868 | * 4.3.3.4 clock Sec(): Get the current clock time, truncated to seconds | |
1869 | * This macro returns the long value of the sec field of the current time. The | |
1870 | * recorded time is updated if necessary before the above value is returned. | |
1871 | * | |
1872 | * \subsubsection sec4-3-3-5 Section 4.3.3.5: clock ElapsedTime(): Measure | |
1873 | * milliseconds between two given clock values | |
1874 | * | |
1875 | * \par | |
1876 | * This macro returns the elapsed time in milliseconds between the two clock | |
1877 | * structure pointers provided as arguments, cv1 and cv2. | |
1878 | * | |
1879 | * \subsubsection sec4-3-3-6 Section 4.3.3.6: clock Advance(): Advance the | |
1880 | * recorded clock time by a specified clock value | |
1881 | * | |
1882 | * \par | |
1883 | * This macro takes a single (struct clock *) pointer argument, cv, and adds | |
1884 | * this clock value to the internal clock value maintined by the package. | |
1885 | * | |
1886 | * \subsubsection sec4-3-3-7 Section 4.3.3.7: clock Gt(): Is a clock value | |
1887 | * greater than another? | |
1888 | * | |
1889 | * \par | |
1890 | * This macro takes two parameters of type (struct clock *), a and b. It | |
1891 | * returns a nonzero value if the a parameter points to a clock value which is | |
1892 | * later than the one pointed to by b. | |
1893 | * | |
1894 | * \subsubsection sec4-3-3-8 Section 4.3.3.8: clock Ge(): Is a clock value | |
1895 | * greater than or equal to another? | |
1896 | * | |
1897 | * \par | |
1898 | * This macro takes two parameters of type (struct clock *), a and b. It | |
1899 | * returns a nonzero value if the a parameter points to a clock value which is | |
1900 | * greater than or equal to the one pointed to by b. | |
1901 | * | |
1902 | * \subsubsection sec4-3-3-9 Section 4.3.3.9: clock Gt(): Are two clock | |
1903 | * values equal? | |
1904 | * | |
1905 | * \par | |
1906 | * This macro takes two parameters of type (struct clock *), a and b. It | |
1907 | * returns a non-zero value if the clock values pointed to by a and b are | |
1908 | * equal. | |
1909 | * | |
1910 | * \subsubsection sec4.3.3.10 Section 4.3.3.10: clock Le(): Is a clock | |
1911 | * value less than or equal to another? | |
1912 | * | |
1913 | * \par | |
1914 | * This macro takes two parameters of type (struct clock *), a and b. It | |
1915 | * returns a nonzero value if the a parameter points to a clock value which is | |
1916 | * less than or equal to the one pointed to by b. | |
1917 | * | |
1918 | * \subsubsection sec4-3-3-11 Section 4.3.3.11: clock Lt(): Is a clock | |
1919 | * value less than another? | |
1920 | * | |
1921 | * \par | |
1922 | * This macro takes two parameters of type (struct clock *), a and b. It | |
1923 | * returns a nonzero value if the a parameter points to a clock value which is | |
1924 | * less than the one pointed to by b. | |
1925 | * | |
1926 | * \subsubsection sec4-3-3-12 Section 4.3.3.12: clock IsZero(): Is a clock | |
1927 | * value zero? | |
1928 | * | |
1929 | * \par | |
1930 | * This macro takes a single parameter of type (struct clock *), c. It returns | |
1931 | * a non-zero value if the c parameter points to a clock value which is equal | |
1932 | * to zero. | |
1933 | * | |
1934 | * \subsubsection sec4-3-3-13 Section 4.3.3.13: clock Zero(): Set a clock | |
1935 | * value to zero | |
1936 | * | |
1937 | * \par | |
1938 | * This macro takes a single parameter of type (struct clock *), c. It sets the | |
1939 | * given clock value to zero. | |
1940 | * \subsubsection sec4-3-3-14 Section 4.3.3.14: clock Add(): Add two clock | |
1941 | * values together | |
1942 | * \par | |
1943 | * This macro takes two parameters of type (struct clock *), c1 and c2. It adds | |
1944 | * the value of the time in c2 to c1. Both clock values must be positive. | |
1945 | * | |
1946 | * \subsubsection sec4-3-3-15 Section 4.3.3.15: clock Sub(): Subtract two | |
1947 | * clock values | |
1948 | * | |
1949 | * \par | |
1950 | * This macro takes two parameters of type (struct clock *), c1 and c2. It | |
1951 | * subtracts the value of the time in c2 from c1. The time pointed to by c2 | |
1952 | * should be less than the time pointed to by c1. | |
1953 | * | |
1954 | * \subsubsection sec4-3-3-16 Section 4.3.3.16: clock Float(): Convert a | |
1955 | * clock time into floating point | |
1956 | * | |
1957 | * \par | |
1958 | * This macro takes a single parameter of type (struct clock *), c. It | |
1959 | * expresses the given clock value as a floating point number. | |
1960 | * | |
1961 | * \section sec4-4 Section 4.4: The rx event Package | |
1962 | * | |
1963 | * \par | |
1964 | * This package maintains an event facility. An event is defined to be | |
1965 | * something that happens at or after a specified clock time, unless cancelled | |
1966 | * prematurely. The clock times used are those provided by the rx clock | |
1967 | * facility described in Section 4.3 above. A user routine associated with an | |
1968 | * event is called with the appropriate arguments when that event occurs. There | |
1969 | * are some restrictions on user routines associated with such events. first, | |
1970 | * this user-supplied routine should not cause process preemption. Also, the | |
1971 | * event passed to the user routine is still resident on the event queue at the | |
1972 | * time of invocation. The user must not remove this event explicitly (via an | |
1973 | * event Cancel(), see below). Rather, the user routine may remove or schedule | |
1974 | * any other event at this time. | |
1975 | * \par | |
1976 | * The events recorded by this package are kept queued in order of expiration | |
1977 | * time, so that the first entry in the queue corresponds to the event which is | |
1978 | * the first to expire. This interface is defined by the rx event.h include | |
1979 | * file. | |
1980 | * | |
1981 | * \subsection sec4-4-1 Section 4.4.1: struct rxevent | |
1982 | * | |
1983 | * \par | |
1984 | * This structure defines the format of an Rx event record. | |
1985 | * \par | |
1986 | * \b fields | |
1987 | * \n struct queue junk -The queue to which this event belongs. | |
1988 | * \n struct clock eventTime -The clock time recording when this event comes | |
1989 | * due. | |
1990 | * \n int (*func)() -The user-supplied function to call upon expiration. | |
1991 | * \n char *arg -The first argument to the (*func)() function above. | |
1992 | * \n char *arg1 -The second argument to the (*func)() function above. | |
1993 | * | |
1994 | * \subsection sec4-4-2 Section 4.4.2: Operations | |
1995 | * | |
1996 | * \par | |
1997 | * This section covers the interface routines provided for the Rx event | |
1998 | * package. | |
1999 | * | |
2000 | * \subsubsection sec4-4-2-1 Section 4.4.2.1: rxevent Init(): Initialize | |
2001 | * the event package | |
2002 | * | |
2003 | * \par | |
2004 | * The rxevent Init() routine takes two arguments. The first, nEvents, is an | |
2005 | * integer-valued parameter which specifies the number of event structures to | |
2006 | * allocate at one time. This specifies the appropriate granularity of memory | |
2007 | * allocation by the event package. The second parameter, scheduler, is a | |
2008 | * pointer to an integer-valued function. This function is to be called when an | |
2009 | * event is posted (added to the set of events managed by the package) that is | |
2010 | * scheduled to expire before any other existing event. | |
2011 | * \par | |
2012 | * This routine sets up future event allocation block sizes, initializes the | |
2013 | * queues used to manage active and free event structures, and recalls that an | |
2014 | * initialization has occurred. Thus, this function may be safely called | |
2015 | * multiple times. | |
2016 | * | |
2017 | * \subsubsection sec4-4-2-2 Section 4.4.2.2: rxevent Post(): Schedule an | |
2018 | * event | |
2019 | * | |
2020 | * \par | |
2021 | * This function constructs a new event based on the information included in | |
2022 | * its parameters and then schedules it. The rxevent Post() routine takes four | |
2023 | * parameters. The first is named when, and is of type (struct clock *). It | |
2024 | * specifies the clock time at which the event is to occur. The second | |
2025 | * parameter is named func and is a pointer to the integer-valued function to | |
2026 | * associate with the event that will be created. When the event comes due, | |
2027 | * this function will be executed by the event package. The next two arguments | |
2028 | * to rxevent Post() are named arg and arg1, and are both of type (char *). | |
2029 | * They serve as the two arguments thath will be supplied to the func routine | |
2030 | * when the event comes due. | |
2031 | * \par | |
2032 | * If the given event is set to take place before any other event currently | |
2033 | * posted, the scheduler routine established when the rxevent Init() routine | |
2034 | * was called will be executed. This gives the application a chance to react to | |
2035 | * this new event in a reasonable way. One might expect that this scheduler | |
2036 | * routine will alter sleep times used by the application to make sure that it | |
2037 | * executes in time to handle the new event. | |
2038 | * | |
2039 | * \subsubsection sec4-4-2-3 Section 4.4.2.3: rxevent Cancel 1(): Cancel | |
2040 | * an event (internal use) | |
2041 | * | |
2042 | * \par | |
2043 | * This routine removes an event from the set managed by this package. It takes | |
2044 | * a single parameter named ev of type (struct rxevent *). The ev argument | |
2045 | * identifies the pending event to be cancelled. | |
2046 | * \par | |
2047 | * The rxevent Cancel 1() routine should never be called directly. Rather, it | |
2048 | * should be accessed through the rxevent Cancel() macro, described in Section | |
2049 | * 4.4.2.4 below. | |
2050 | * | |
2051 | * \subsubsection sec4-4-2-4 Section 4.4.2.4: rxevent Cancel(): Cancel an | |
2052 | * event (external use) | |
2053 | * | |
2054 | * \par | |
2055 | * This macro is the proper way to call the rxevent Cancel 1() routine | |
2056 | * described in Section 4.4.2.3 above. Like rxevent Cancel 1(), it takes a | |
2057 | * single argument. This event ptr argument is of type (struct rxevent *), and | |
2058 | * identi#es the pending event to be cancelled. This macro #rst checks to see | |
2059 | * if event ptr is null. If not, it calls rxevent Cancel 1() to perform the | |
2060 | * real work. The event ptr argument is zeroed after the cancellation operation | |
2061 | * completes. | |
2062 | * | |
2063 | * \subsubsection sec4-4-2-5 Section 4.4.2.4: rxevent RaiseEvents(): | |
2064 | * Initialize the event package | |
2065 | * | |
2066 | * \par | |
2067 | * This function processes all events that have expired relative to the current | |
2068 | * clock time maintained by the event package. Each qualifying event is removed | |
2069 | * from the queue in order, and its user-supplied routine (func()) is executed | |
2070 | * with the associated arguments. | |
2071 | * \par | |
2072 | * The rxevent RaiseEvents() routine takes a single output parameter named | |
2073 | * next, defined to be of type (struct clock *). Upon completion of rxevent | |
2074 | * RaiseEvents(), the relative time to the next event due to expire is placed | |
2075 | * in next. This knowledge may be used to calculate the amount of sleep time | |
2076 | * before more event processing is needed. If there is no recorded event which | |
2077 | * is still pending at this point, rxevent RaiseEvents() returns a zeroed clock | |
2078 | * value into next. | |
2079 | * | |
2080 | * \subsubsection sec4-4-2-6 Section 4.4.2.6: rxevent TimeToNextEvent(): | |
2081 | * Get amount of time until the next event expires | |
2082 | * | |
2083 | * \par | |
2084 | * This function returns the time between the current clock value as maintained | |
2085 | * by the event package and the the next event's expiration time. This | |
2086 | * information is placed in the single output argument,interval, defined to be | |
2087 | * of type (struct clock *). The rxevent TimeToNextEvent() function returns | |
2088 | * integer-valued quantities. If there are no scheduled events, a zero is | |
2089 | * returned. If there are one or more scheduled events, a 1 is returned. If | |
2090 | * zero is returned, the interval argument is not updated. | |
2091 | * | |
2092 | * \page chap5 Chapter 5 -- Programming Interface | |
2093 | * | |
2094 | * \section sec5-1 Section 5.1: Introduction | |
2095 | * | |
2096 | * \par | |
2097 | * This chapter documents the API for the Rx facility. Included are | |
2098 | * descriptions of all the constants, structures, exported variables, macros, | |
2099 | * and interface functions available to the application programmer. This | |
2100 | * interface is identical regardless of whether the application lives within | |
2101 | * the unix kernel or above it. | |
2102 | * \par | |
2103 | * This chapter actually provides more information than what may be strictly | |
2104 | * considered the Rx API. Many objects that were intended to be opaque and for | |
2105 | * Rx internal use only are also described here. The reason driving the | |
2106 | * inclusion of this "extra" information is that such exported Rx interface | |
2107 | * files as rx.h make these objects visible to application programmers. It is | |
2108 | * prefereable to describe these objects here than to ignore them and leave | |
2109 | * application programmers wondering as to their meaning. | |
2110 | * \par | |
2111 | * An example application illustrating the use of this interface, showcasing | |
2112 | * code from both server and client sides, appears in the following chapter. | |
2113 | * | |
2114 | * \section sec5-2 Section 5.2: Constants | |
2115 | * | |
2116 | * \par | |
2117 | * This section covers the basic constant definitions of interest to the Rx | |
2118 | * application programmer. Each subsection is devoted to describing the | |
2119 | * constants falling into the following categories: | |
2120 | * \li Configuration quantities | |
2121 | * \li Waiting options | |
2122 | * \li Connection ID operations | |
2123 | * \li Connection flags | |
2124 | * \li Connection types | |
2125 | * \li Call states | |
2126 | * \li Call flags | |
2127 | * \li Call modes | |
2128 | * \li Packet header flags | |
2129 | * \li Packet sizes | |
2130 | * \li Packet types | |
2131 | * \li Packet classes | |
2132 | * \li Conditions prompting ack packets | |
2133 | * \li Ack types | |
2134 | * \li Error codes | |
2135 | * \li Debugging values | |
2136 | * \par | |
2137 | * An attempt has been made to relate these constant definitions to the objects | |
2138 | * or routines that utilize them. | |
2139 | * | |
2140 | * \subsection sec5-2-1 Section 5.2.1: Configuration Quantities | |
2141 | * | |
2142 | * \par | |
2143 | * These definitions provide some basic Rx configuration parameters, including | |
2144 | * the number of simultaneous calls that may be handled on a single connection, | |
2145 | * lightweight thread parameters, and timeouts for various operations. | |
2146 | * | |
2147 | * \par Name | |
2148 | * RX IDLE DEAD TIME | |
2149 | * \par Value | |
2150 | * 60 | |
2151 | * \par Description | |
2152 | * Default idle dead time for connections, in seconds. | |
2153 | * | |
2154 | * \par Name | |
2155 | * RX MAX SERVICES | |
2156 | * \par Value | |
2157 | * 20 | |
2158 | * \par Description | |
2159 | * The maximum number of Rx services that may be installed within one | |
2160 | * application. | |
2161 | * | |
2162 | * \par Name | |
2163 | * RX PROCESS MAXCALLS | |
2164 | * \par Value | |
2165 | * 4 | |
2166 | * \par Description | |
2167 | * The maximum number of asynchronous calls active simultaneously on any given | |
2168 | * Rx connection. This value must be set to a power of two. | |
2169 | * | |
2170 | * \par Name | |
2171 | * RX DEFAULT STACK SIZE | |
2172 | * \par Value | |
2173 | * 16,000 | |
2174 | * \par Description | |
2175 | * Default lightweight thread stack size, measured in bytes. This value may be | |
2176 | * overridden by calling the rx_SetStackSize() macro. | |
2177 | * | |
2178 | * \par Name | |
2179 | * RX PROCESS PRIORITY | |
2180 | * \par Value | |
2181 | * LWP NORMAL PRIORITY | |
2182 | * \par Description | |
2183 | * This is the priority under which an Rx thread should run. There should not | |
2184 | * generally be any reason to change this setting. | |
2185 | * | |
2186 | * \par Name | |
2187 | * RX CHALLENGE TIMEOUT | |
2188 | * \par Value | |
2189 | * 2 | |
2190 | * \par Description | |
2191 | * The number of seconds before another authentication request packet is | |
2192 | * generated. | |
2193 | * | |
2194 | * \par Name | |
2195 | * RX MAXACKS | |
2196 | * \par Value | |
2197 | * 255 | |
2198 | * \par Description | |
2199 | * Maximum number of individual acknowledgements that may be carried in an Rx | |
2200 | * acknowledgement packet. | |
2201 | * | |
2202 | * \subsection sec5-2-2 Section 5.2.2: Waiting Options | |
2203 | * | |
2204 | * \par | |
2205 | * These definitions provide readable values indicating whether an operation | |
2206 | * should block when packet buffer resources are not available. | |
2207 | * | |
2208 | * \par Name | |
2209 | * RX DONTWAIT | |
2210 | * \par Value | |
2211 | * 0 | |
2212 | * \par Description | |
2213 | * Wait until the associated operation completes. | |
2214 | * | |
2215 | * \par Name | |
2216 | * RX WAIT | |
2217 | * \par Value | |
2218 | * 1 | |
2219 | * \par Description | |
2220 | * Don't wait if the associated operation would block. | |
2221 | * | |
2222 | * \subsection sec5-2-3 Section 5.2.3: Connection ID Operations | |
2223 | * | |
2224 | * \par | |
2225 | * These values assist in extracting the call channel number from a connection | |
2226 | * identifier. A call channel is the index of a particular asynchronous call | |
2227 | * structure within a single Rx connection. | |
2228 | * | |
2229 | * \par Name | |
2230 | * RX CIDSHIFT | |
2231 | * \par Value | |
2232 | * 2 | |
2233 | * \par Description | |
2234 | * Number of bits to right-shift to isolate a connection ID. Must be set to | |
2235 | * the log (base two) of RX MAXCALLS. | |
2236 | * | |
2237 | * \par Name | |
2238 | * RX CHANNELMASK | |
2239 | * \par Value | |
2240 | * (RX MAXCALLS-1) | |
2241 | * \par Description | |
2242 | * Mask used to isolate a call channel from a connection ID field. | |
2243 | * | |
2244 | * \par Name | |
2245 | * RX CIDMASK | |
2246 | * \par Value | |
2247 | * (~RX CHANNELMASK) | |
2248 | * \par Description | |
2249 | * Mask used to isolate the connection ID from its field, masking out the call | |
2250 | * channel information. | |
2251 | * | |
2252 | * \subsection sec5-2-4 Section 5.2.4: Connection Flags | |
2253 | * | |
2254 | * \par | |
2255 | * The values defined here appear in the flags field of Rx connections, as | |
2256 | * defined by the rx connection structure described in Section 5.3.2.2. | |
2257 | * | |
2258 | * \par Name | |
2259 | * RX CONN MAKECALL WAITING | |
2260 | * \par Value | |
2261 | * 1 | |
2262 | * \par Description | |
2263 | * rx MakeCall() is waiting for a channel. | |
2264 | * | |
2265 | * \par Name | |
2266 | * RX CONN DESTROY ME | |
2267 | * \par Value | |
2268 | * 2 | |
2269 | * \par Description | |
2270 | * Destroy this (client) connection after its last call completes. | |
2271 | * | |
2272 | * \par Name | |
2273 | * RX CONN USING PACKET CKSUM | |
2274 | * \par Value | |
2275 | * 4 | |
2276 | * \par Description | |
2277 | * This packet is using security-related check-summing (a non-zero header, | |
2278 | * spare field has been seen.) | |
2279 | * | |
2280 | * \subsection sec5-2-5 Section 5.2.5: Connection Types | |
2281 | * | |
2282 | * \par | |
2283 | * Rx stores different information in its connection structures, depending on | |
2284 | * whether the given connection represents the server side (the one providing | |
2285 | * the service) or the client side (the one requesting the service) of the | |
2286 | * protocol. The type field within the connection structure (described in | |
2287 | * Section 5.3.2.2) takes on the following values to differentiate the two | |
2288 | * types of connections, and identifies the fields that are active within the | |
2289 | * connection structure. | |
2290 | * | |
2291 | * \par Name | |
2292 | * RX CLIENT CONNECTION | |
2293 | * \par Value | |
2294 | * 0 | |
2295 | * \par Description | |
2296 | * This is a client-side connection. | |
2297 | * | |
2298 | * \par Name | |
2299 | * CONNECTION | |
2300 | * \par Value | |
2301 | * 1 | |
2302 | * \par Description | |
2303 | * This is a server-side connection. | |
2304 | * | |
2305 | * \subsection sec5-2-6 Section 5.2.6: Call States | |
2306 | * | |
2307 | * \par | |
2308 | * An Rx call on a particular connection may be in one of several states at any | |
2309 | * instant in time. The following definitions identify the range of states that | |
2310 | * a call may assume. | |
2311 | * | |
2312 | * \par Name | |
2313 | * RX STATE NOTINIT | |
2314 | * \par Value | |
2315 | * 0 | |
2316 | * \par Description | |
2317 | * The call structure has never been used, and is thus still completely | |
2318 | * uninitialized. | |
2319 | * | |
2320 | * \par Name | |
2321 | * RX STATE PRECALL | |
2322 | * \par Value | |
2323 | * 1 | |
2324 | * \par Description | |
2325 | * A call is not yet in progress, but packets have arrived for it anyway. This | |
2326 | * only applies to calls within server-side connections. | |
2327 | * | |
2328 | * \par Name | |
2329 | * RX STATE ACTIVE | |
2330 | * \par Value | |
2331 | * 2 | |
2332 | * \par Description | |
2333 | * This call is fully active, having an attached lightweight thread operating | |
2334 | * on its behalf. | |
2335 | * | |
2336 | * \par Name | |
2337 | * RX STATE DAILY | |
2338 | * \par Value | |
2339 | * 3 | |
2340 | * \par Description | |
2341 | * The call structure is "dallying" after its lightweight thread has completed | |
2342 | * its most recent call. This is a "hot-standby" condition, where the call | |
2343 | * structure preserves state from the previous call and thus optimizes the | |
2344 | * arrival of further, related calls. | |
2345 | * | |
2346 | * \subsection sec5-2-7 Section 5.2.7: Call Flags: | |
2347 | * | |
2348 | * \par | |
2349 | * These values are used within the flags field of a variable declared to be of | |
2350 | * type struct rx call, as described in Section 5.3.2.4. They provide | |
2351 | * additional information as to the state of the given Rx call, such as the | |
2352 | * type of event for which it is waiting (if any) and whether or not all | |
2353 | * incoming packets have been received in support of the call. | |
2354 | * | |
2355 | * \par Name | |
2356 | * RX CALL READER WAIT | |
2357 | * \par Value | |
2358 | * 1 | |
2359 | * \par Description | |
2360 | * Reader is waiting for next packet. | |
2361 | * | |
2362 | * \par Name | |
2363 | * RX CALL WAIT WINDOW ALLOC | |
2364 | * \par Value | |
2365 | * 2 | |
2366 | * \par Description | |
2367 | * Sender is waiting for a window so that it can allocate buffers. | |
2368 | * | |
2369 | * \par Name | |
2370 | * RX CALL WAIT WINDOW SEND | |
2371 | * \par Value | |
2372 | * 4 | |
2373 | * \par Description | |
2374 | * Sender is waiting for a window so that it can send buffers. | |
2375 | * | |
2376 | * \par Name | |
2377 | * RX CALL WAIT PACKETS | |
2378 | * \par Value | |
2379 | * 8 | |
2380 | * \par Description | |
2381 | * Sender is waiting for packet buffers. | |
2382 | * | |
2383 | * \par Name | |
2384 | * RX CALL RECEIVE DONE | |
2385 | * \par Value | |
2386 | * 16 | |
2387 | * \par Description | |
2388 | * The call is waiting for a lightweight thread to be assigned to the operation | |
2389 | * it has just received. | |
2390 | * | |
2391 | * \par Name | |
2392 | * RX CALL RECEIVE DONE | |
2393 | * \par Value | |
2394 | * 32 | |
2395 | * \par Description | |
2396 | * All packets have been received on this call. | |
2397 | * | |
2398 | * \par Name | |
2399 | * RX CALL CLEARED | |
2400 | * \par Value | |
2401 | * 64 | |
2402 | * \par Description | |
2403 | * The receive queue has been cleared when in precall state. | |
2404 | * | |
2405 | * \subsection sec5-2-8 Section 5.2.8: Call Modes | |
2406 | * | |
2407 | * \par | |
2408 | * These values define the modes of an Rx call when it is in the RX STATE | |
2409 | * ACTIVE state, having a lightweight thread assigned to it. | |
2410 | * | |
2411 | * \par Name | |
2412 | * RX MODE SENDING | |
2413 | * \par Value | |
2414 | * 1 | |
2415 | * \par Description | |
2416 | * We are sending or ready to send. | |
2417 | * | |
2418 | * \par Name | |
2419 | * RX MODE RECEIVING | |
2420 | * \par Value | |
2421 | * 2 | |
2422 | * \par Description | |
2423 | * We are receiving or ready to receive. | |
2424 | * | |
2425 | * \par Name | |
2426 | * RX MODE ERROR | |
2427 | * \par Value | |
2428 | * 3 | |
2429 | * \par Description | |
2430 | * Something went wrong in the current conversation. | |
2431 | * | |
2432 | * \par Name | |
2433 | * RX MODE EOF | |
2434 | * \par Value | |
2435 | * 4 | |
2436 | * \par Description | |
2437 | * The server side has flushed (or the client side has read) the last reply | |
2438 | * packet. | |
2439 | * | |
2440 | * \subsection sec5-2-9 Section 5.2.9: Packet Header Flags | |
2441 | * | |
2442 | * \par | |
2443 | * Rx packets carry a flag field in their headers, providing additional | |
2444 | * information regarding the packet's contents. The Rx packet header's flag | |
2445 | * field's bits may take the following values: | |
2446 | * | |
2447 | * \par Name | |
2448 | * RX CLIENT INITIATED | |
2449 | * \par Value | |
2450 | * 1 | |
2451 | * \par Description | |
2452 | * Signifies that a packet has been sent/received from the client side of the | |
2453 | * call. | |
2454 | * | |
2455 | * \par Name | |
2456 | * RX REQUEST ACK | |
2457 | * \par Value | |
2458 | * 2 | |
2459 | * \par Description | |
2460 | * The Rx calls' peer entity requests an acknowledgement. | |
2461 | * | |
2462 | * \par Name | |
2463 | * RX LAST PACKET | |
2464 | * \par Value | |
2465 | * 4 | |
2466 | * \par Description | |
2467 | * This is the final packet from this side of the call. | |
2468 | * | |
2469 | * \par Name | |
2470 | * RX MORE PACKETS | |
2471 | * \par Value | |
2472 | * 8 | |
2473 | * \par Description | |
2474 | * There are more packets following this, i.e., the next sequence number seen | |
2475 | * by the receiver should be greater than this one, rather than a | |
2476 | * retransmission of an earlier sequence number. | |
2477 | * | |
2478 | * \par Name | |
2479 | * RX PRESET FLAGS | |
2480 | * \par Value | |
2481 | * (RX CLIENT INITIATED | RX LAST PACKET) | |
2482 | * \par Description | |
2483 | * This flag is preset once per Rx packet. It doesn't change on retransmission | |
2484 | * of the packet. | |
2485 | * | |
2486 | * \subsection sec5-3-10 Section 5.2.10: Packet Sizes | |
2487 | * | |
2488 | * \par | |
2489 | * These values provide sizing information on the various regions within Rx | |
2490 | * packets. These packet sections include the IP/UDP headers and bodies as well | |
2491 | * Rx header and bodies. Also covered are such values as different maximum | |
2492 | * packet sizes depending on whether they are targeted to peers on the same | |
2493 | * local network or a more far-flung network. Note that the MTU term appearing | |
2494 | * below is an abbreviation for Maximum Transmission Unit. | |
2495 | * | |
2496 | * \par Name | |
2497 | * RX IPUDP SIZE | |
2498 | * \par Value | |
2499 | * 28 | |
2500 | * \par Description | |
2501 | * The number of bytes taken up by IP/UDP headers. | |
2502 | * | |
2503 | * \par Name | |
2504 | * RX MAX PACKET SIZE | |
2505 | * \par Value | |
2506 | * (1500 - RX IPUDP SIZE) | |
2507 | * \par Description | |
2508 | * This is the Ethernet MTU minus IP and UDP header sizes. | |
2509 | * | |
2510 | * \par Name | |
2511 | * RX HEADER SIZE | |
2512 | * \par Value | |
2513 | * sizeof (struct rx header) | |
2514 | * \par Description | |
2515 | * The number of bytes in an Rx packet header. | |
2516 | * | |
2517 | * \par Name | |
2518 | * RX MAX PACKET DATA SIZE | |
2519 | * \par Value | |
2520 | * (RX MAX PACKET SIZE RX - HEADER SIZE) | |
2521 | * \par Description | |
2522 | * Maximum size in bytes of the user data in a packet. | |
2523 | * | |
2524 | * \par Name | |
2525 | * RX LOCAL PACKET SIZE | |
2526 | * \par Value | |
2527 | * RX MAX PACKET SIZE | |
2528 | * \par Description | |
2529 | * Packet size in bytes to use when being sent to a host on the same net. | |
2530 | * | |
2531 | * \par Name | |
2532 | * RX REMOTE PACKET SIZE | |
2533 | * \par Value | |
2534 | * (576 - RX IPUDP SIZE) | |
2535 | * \par Description | |
2536 | * Packet size in bytes to use when being sent to a host on a different net. | |
2537 | * | |
2538 | * \subsection sec5-2-11 Section 5.2.11: Packet Types | |
2539 | * | |
2540 | * \par | |
2541 | * The following values are used in the packetType field within a struct rx | |
2542 | * packet, and define the different roles assumed by Rx packets. These roles | |
2543 | * include user data packets, different flavors of acknowledgements, busies, | |
2544 | * aborts, authentication challenges and responses, and debugging vehicles. | |
2545 | * | |
2546 | * \par Name | |
2547 | * RX PACKET TYPE DATA | |
2548 | * \par Value | |
2549 | * 1 | |
2550 | * \par Description | |
2551 | * A user data packet. | |
2552 | * | |
2553 | * \par Name | |
2554 | * RX PACKET TYPE ACK | |
2555 | * \par Value | |
2556 | * 2 | |
2557 | * \par Description | |
2558 | * Acknowledgement packet. | |
2559 | * | |
2560 | * \par Name | |
2561 | * RX PACKET TYPE BUSY | |
2562 | * \par Value | |
2563 | * 3 | |
2564 | * \par Description | |
2565 | * Busy packet. The server-side entity cannot accept the call at the moment, | |
2566 | * but the requestor is encouraged to try again later. | |
2567 | * | |
2568 | * \par Name | |
2569 | * RX PACKET TYPE ABORT | |
2570 | * \par Value | |
2571 | * 4 | |
2572 | * \par Description | |
2573 | * Abort packet. No response is needed for this packet type. | |
2574 | * | |
2575 | * \par Name | |
2576 | * RX PACKET TYPE ACKALL | |
2577 | * \par Value | |
2578 | * 5 | |
2579 | * \par Description | |
2580 | * Acknowledges receipt of all packets on a call. | |
2581 | * | |
2582 | * \par Name | |
2583 | * RX PACKET TYPE CHALLENGE | |
2584 | * \par Value | |
2585 | * 6 | |
2586 | * \par Description | |
2587 | * Challenge the client's identity, requesting credentials. | |
2588 | * | |
2589 | * \par Name | |
2590 | * RX PACKET TYPE RESPONSE | |
2591 | * \par Value | |
2592 | * 7 | |
2593 | * \par Description | |
2594 | * Response to a RX PACKET TYPE CHALLENGE authentication challenge packet. | |
2595 | * | |
2596 | * \par Name | |
2597 | * RX PACKET TYPE DEBUG | |
2598 | * \par Value | |
2599 | * 8 | |
2600 | * \par Description | |
2601 | * Request for debugging information. | |
2602 | * | |
2603 | * \par Name | |
2604 | * RX N PACKET TYPES | |
2605 | * \par Value | |
2606 | * 9 | |
2607 | * \par Description | |
2608 | * The number of Rx packet types defined above. Note that it also includes | |
2609 | * packet type 0 (which is unused) in the count. | |
2610 | * | |
2611 | * \par | |
2612 | * The RX PACKET TYPES definition provides a mapping of the above values to | |
2613 | * human-readable string names, and is exported by the rx packetTypes variable | |
2614 | * catalogued in Section 5.4.9. | |
2615 | * | |
2616 | * \code | |
2617 | * { | |
2618 | * "data", | |
2619 | * "ack", | |
2620 | * "busy", | |
2621 | * "abort", | |
2622 | * "ackall", | |
2623 | * "challenge", | |
2624 | * "response", | |
2625 | * "debug" | |
2626 | * } | |
2627 | * \endcode | |
2628 | * | |
2629 | * \subsection sec5-2-12 Section 5.2.12: Packet Classes | |
2630 | * | |
2631 | * \par | |
2632 | * These definitions are used internally to manage alloction of Rx packet | |
2633 | * buffers according to quota classifications. Each packet belongs to one of | |
2634 | * the following classes, and its buffer is derived from the corresponding | |
2635 | * pool. | |
2636 | * | |
2637 | * \par Name | |
2638 | * RX PACKET CLASS RECEIVE | |
2639 | * \par Value | |
2640 | * 0 | |
2641 | * \par Description | |
2642 | * Receive packet for user data. | |
2643 | * | |
2644 | * \par Name | |
2645 | * RX PACKET CLASS SEND | |
2646 | * \par Value | |
2647 | * 1 | |
2648 | * \par Description | |
2649 | * Send packet for user data. | |
2650 | * | |
2651 | * \par Name | |
2652 | * RX PACKET CLASS SPECIAL | |
2653 | * \par Value | |
2654 | * 2 | |
2655 | * \par Description | |
2656 | * A special packet that does not hold user data, such as an acknowledgement or | |
2657 | * authentication challenge. | |
2658 | * | |
2659 | * \par Name | |
2660 | * RX N PACKET CLASSES | |
2661 | * \par Value | |
2662 | * 3 | |
2663 | * \par Description | |
2664 | * The number of Rx packet classes defined above. | |
2665 | * | |
2666 | * \subsection sec5-2-13 Section 5.2.13: Conditions Prompting Ack Packets | |
2667 | * | |
2668 | * \par | |
2669 | * Rx acknowledgement packets are constructed and sent by the protocol | |
2670 | * according to the following reasons. These values appear in the Rx packet | |
2671 | * header of the ack packet itself. | |
2672 | * | |
2673 | * \par Name | |
2674 | * RX ACK REQUESTED | |
2675 | * \par Value | |
2676 | * 1 | |
2677 | * \par Description | |
2678 | * The peer has explicitly requested an ack on this packet. | |
2679 | * | |
2680 | * \par Name | |
2681 | * RX ACK DUPLICATE | |
2682 | * \par Value | |
2683 | * 2 | |
2684 | * \par Description | |
2685 | * A duplicate packet has been received. | |
2686 | * | |
2687 | * \par Name | |
2688 | * RX ACK OUT OF SEQUENCE | |
2689 | * \par Value | |
2690 | * 3 | |
2691 | * \par Description | |
2692 | * A packet has arrived out of sequence. | |
2693 | * | |
2694 | * \par Name | |
2695 | * RX ACK EXCEEDS WINDOW | |
2696 | * \par Value | |
2697 | * 4 | |
2698 | * \par Description | |
2699 | * A packet sequence number higher than maximum value allowed by the call's | |
2700 | * window has been received. | |
2701 | * | |
2702 | * \par Name | |
2703 | * RX ACK NOSPACE | |
2704 | * \par Value | |
2705 | * 5 | |
2706 | * \par Description | |
2707 | * No packet buffer space is available. | |
2708 | * | |
2709 | * \par Name | |
2710 | * RX ACK PING | |
2711 | * \par Value | |
2712 | * 6 | |
2713 | * \par Description | |
2714 | * Acknowledgement for keep-alive purposes. | |
2715 | * | |
2716 | * \par Name | |
2717 | * RX ACK PING RESPONSE | |
2718 | * \par Value | |
2719 | * 7 | |
2720 | * \par Description | |
2721 | * Response to a RX ACK PING packet. | |
2722 | * | |
2723 | * \par Name | |
2724 | * RX ACK DELAY | |
2725 | * \par Value | |
2726 | * 8 | |
2727 | * \par Description | |
2728 | * An ack generated due to a period of inactivity after normal packet | |
2729 | * receptions. | |
2730 | * | |
2731 | * \subsection 5-2-14 Section 5.2.14: Acknowledgement Types | |
2732 | * | |
2733 | * \par | |
2734 | * These are the set of values placed into the acks array in an Rx | |
2735 | * acknowledgement packet, whose data format is defined by struct rx ackPacket. | |
2736 | * These definitions are used to convey positive or negative acknowledgements | |
2737 | * for a given range of packets. | |
2738 | * | |
2739 | * \par Name | |
2740 | * RX ACK TYPE NACK | |
2741 | * \par Value | |
2742 | * 0 | |
2743 | * \par Description | |
2744 | * Receiver doesn't currently have the associated packet; it may never hae been | |
2745 | * received, or received and then later dropped before processing. | |
2746 | * | |
2747 | * \par Name | |
2748 | * RX ACK TYPE ACK | |
2749 | * \par Value | |
2750 | * 1 | |
2751 | * \par Description | |
2752 | * Receiver has the associated packet queued, although it may later decide to | |
2753 | * discard it. | |
2754 | * | |
2755 | * \subsection sec5-2-15 Section 5.2.15: Error Codes | |
2756 | * | |
2757 | * \par | |
2758 | * Rx employs error codes ranging from -1 to -64. The Rxgen stub generator may | |
2759 | * use other error codes less than -64. User programs calling on Rx, on the | |
2760 | * other hand, are expected to return positive error codes. A return value of | |
2761 | * zero is interpreted as an indication that the given operation completed | |
2762 | * successfully. | |
2763 | * | |
2764 | * \par Name | |
2765 | * RX CALL DEAD | |
2766 | * \par Value | |
2767 | * -1 | |
2768 | * \par Description | |
2769 | * A connection has been inactive past Rx's tolerance levels and has been shut | |
2770 | * down. | |
2771 | * | |
2772 | * \par Name | |
2773 | * RX INVALID OPERATION | |
2774 | * \par Value | |
2775 | * -2 | |
2776 | * \par Description | |
2777 | * An invalid operation has been attempted, including such protocol errors as | |
2778 | * having a client-side call send data after having received the beginning of a | |
2779 | * reply from its server-side peer. | |
2780 | * | |
2781 | * \par Name | |
2782 | * RX CALL TIMEOUT | |
2783 | * \par Value | |
2784 | * -3 | |
2785 | * \par Description | |
2786 | * The (optional) timeout value placed on this call has been exceeded (see | |
2787 | * Sections 5.5.3.4 and 5.6.5). | |
2788 | * | |
2789 | * \par Name | |
2790 | * RX EOF | |
2791 | * \par Value | |
2792 | * -4 | |
2793 | * \par Description | |
2794 | * Unexpected end of data on a read operation. | |
2795 | * | |
2796 | * \par Name | |
2797 | * RX PROTOCOL ERROR | |
2798 | * \par Value | |
2799 | * -5 | |
2800 | * \par Description | |
2801 | * An unspecified low-level Rx protocol error has occurred. | |
2802 | * | |
2803 | * \par Name | |
2804 | * RX USER ABORT | |
2805 | * \par Value | |
2806 | * -6 | |
2807 | * \par Description | |
2808 | * A generic user abort code, used when no more specific error code needs to be | |
2809 | * communicated. For example, Rx clients employing the multicast feature (see | |
2810 | * Section 1.2.8) take advantage of this error code. | |
2811 | * | |
2812 | * \subsection sec5-2-16 Section 5.2.16: Debugging Values | |
2813 | * | |
2814 | * \par | |
2815 | * Rx provides a set of data collections that convey information about its | |
2816 | * internal status and performance. The following values have been defined in | |
2817 | * support of this debugging and statistics-collection feature. | |
2818 | * | |
2819 | * \subsubsection sec5-3-16-1 Section 5.2.16.1: Version Information | |
2820 | * | |
2821 | * \par | |
2822 | * Various versions of the Rx debugging/statistics interface are in existance, | |
2823 | * each defining different data collections and handling certain bugs. Each Rx | |
2824 | * facility is stamped with a version number of its debugging/statistics | |
2825 | * interface, allowing its clients to tailor their requests to the precise data | |
2826 | * collections that are supported by a particular Rx entity, and to properly | |
2827 | * interpret the data formats received through this interface. All existing Rx | |
2828 | * implementations should be at revision M. | |
2829 | * | |
2830 | * \par Name | |
2831 | * RX DEBUGI VERSION MINIMUM | |
2832 | * \par Value | |
2833 | * 'L' | |
2834 | * \par Description | |
2835 | * The earliest version of Rx statistics available. | |
2836 | * | |
2837 | * \par Name | |
2838 | * RX DEBUGI VERSION | |
2839 | * \par Value | |
2840 | * 'M' | |
2841 | * \par Description | |
2842 | * The latest version of Rx statistics available. | |
2843 | * | |
2844 | * \par Name | |
2845 | * RX DEBUGI VERSION W SECSTATS | |
2846 | * \par Value | |
2847 | * 'L' | |
2848 | * \par Description | |
2849 | * Identifies the earliest version in which statistics concerning Rx security | |
2850 | * objects is available. | |
2851 | * | |
2852 | * \par Name | |
2853 | * RX DEBUGI VERSION W GETALLCONN | |
2854 | * \par Value | |
2855 | * 'M' | |
2856 | * \par Description | |
2857 | * The first version that supports getting information about all current Rx | |
2858 | * connections, as specified y the RX DEBUGI GETALLCONN debugging request | |
2859 | * packet opcode described below. | |
2860 | * | |
2861 | * \par Name | |
2862 | * RX DEBUGI VERSION W RXSTATS | |
2863 | * \par Value | |
2864 | * 'M' | |
2865 | * \par Description | |
2866 | * The first version that supports getting all the Rx statistics in one | |
2867 | * operation, as specified by the RX DEBUGI RXSTATS debugging request packet | |
2868 | * opcode described below. | |
2869 | * | |
2870 | * \par Name | |
2871 | * RX DEBUGI VERSION W UNALIGNED CONN | |
2872 | * \par Value | |
2873 | * 'L' | |
2874 | * \par Description | |
2875 | * There was an alignment problem discovered when returning Rx connection | |
2876 | * information in older versions of this debugging/statistics interface. This | |
2877 | * identifies the last version that exhibited this alignment problem. | |
2878 | * | |
2879 | * \subsubsection sec5-2-16-2 Section 5.2.16.2: Opcodes | |
2880 | * | |
2881 | * \par | |
2882 | * When requesting debugging/statistics information, the caller specifies one | |
2883 | * of the following supported data collections: | |
2884 | * | |
2885 | * \par Name | |
2886 | * RX DEBUGI GETSTATS | |
2887 | * \par Value | |
2888 | * 1 | |
2889 | * \par Description | |
2890 | * Get basic Rx statistics. | |
2891 | * | |
2892 | * \par Name | |
2893 | * RX DEBUGI GETCONN | |
2894 | * \par Value | |
2895 | * 2 | |
2896 | * \par Description | |
2897 | * Get information on all Rx connections considered "interesting" (as defined | |
2898 | * below), and no others. | |
2899 | * | |
2900 | * \par Name | |
2901 | * RX DEBUGI GETALLCONN | |
2902 | * \par Value | |
2903 | * 3 | |
2904 | * \par Description | |
2905 | * Get information on all existing Rx connection structures, even | |
2906 | * "uninteresting" ones. | |
2907 | * | |
2908 | * \par Name | |
2909 | * RX DEBUGI RXSTATS | |
2910 | * \par Value | |
2911 | * 4 | |
2912 | * \par Description | |
2913 | * Get all available Rx stats. | |
2914 | * | |
2915 | * \par | |
2916 | * An Rx connection is considered "interesting" if it is waiting for a call | |
2917 | * channel to free up or if it has been marked for destruction. If neither is | |
2918 | * true, a connection is still considered interesting if any of its call | |
2919 | * channels is actively handling a call or in its preparatory pre-call state. | |
2920 | * Failing all the above conditions, a connection is still tagged as | |
2921 | * interesting if any of its call channels is in either of the RX MODE SENDING | |
2922 | * or RX MODE RECEIVING modes, which are not allowed when the call is not | |
2923 | * active. | |
2924 | * | |
2925 | * \subsubsection sec5-2-16-3 Section 5.2.16.3: Queuing | |
2926 | * | |
2927 | * \par | |
2928 | * These two queueing-related values indicate whether packets are present on | |
2929 | * the incoming and outgoing packet queues for a given Rx call. These values | |
2930 | * are only used in support of debugging and statistics-gathering operations. | |
2931 | * | |
2932 | * \par Name | |
2933 | * RX OTHER IN | |
2934 | * \par Value | |
2935 | * 1 | |
2936 | * \par Description | |
2937 | * Packets available in in queue. | |
2938 | * | |
2939 | * \par Name | |
2940 | * RX OTHER OUT | |
2941 | * \par Value | |
2942 | * 2 | |
2943 | * \par Description | |
2944 | * Packets available in out queue. | |
2945 | * | |
2946 | * \section sec5-3 Section 5.3: Structures | |
2947 | * | |
2948 | * \par | |
2949 | * This section describes the major exported Rx data structures of interest to | |
2950 | * application programmers. The following categories are utilized for the | |
2951 | * purpose of organizing the structure descriptions: | |
2952 | * \li Security objects | |
2953 | * \li Protocol objects | |
2954 | * \li Packet formats | |
2955 | * \li Debugging and statistics | |
2956 | * \li Miscellaneous | |
2957 | * \par | |
2958 | * Please note that many fields described in this section are declared to be | |
2959 | * VOID. This is defined to be char, and is used to get around some compiler | |
2960 | * limitations. | |
2961 | * \subsection sec5-3-1 Section 5.3.1: Security Objects | |
2962 | * | |
2963 | * \par | |
2964 | * As explained in Section 1.2.1, Rx provides a modular, extensible security | |
2965 | * model. This allows Rx applications to either use one of the built-in | |
2966 | * security/authentication protocol packages or write and plug in one of their | |
2967 | * own. This section examines the various structural components used by Rx to | |
2968 | * support generic security and authentication modules. | |
2969 | * | |
2970 | * \subsubsection sec5-3-1-1 Section 5.3.1.1: struct rx securityOps | |
2971 | * | |
2972 | * \par | |
2973 | * As previously described, each Rx security object must export a fixed set of | |
2974 | * interface functions, providing the full set of operations defined on the | |
2975 | * object. The rx securityOps structure defines the array of functions | |
2976 | * comprising this interface. The Rx facility calls these routines at the | |
2977 | * appropriate times, without knowing the specifics of how any particular | |
2978 | * security object implements the operation. | |
2979 | * \par | |
2980 | * A complete description of these interface functions, including information | |
2981 | * regarding their exact purpose, parameters, and calling conventions, may be | |
2982 | * found in Section 5.5.7. | |
2983 | * \par | |
2984 | * \b fields | |
2985 | * \li int (*op Close)() - React to the disposal of a security object. | |
2986 | * \li int (*op NewConnection)() - Invoked each time a new Rx connection | |
2987 | * utilizing the associated security object is created. | |
2988 | * \li int (*op PreparePacket)() - Invoked each time an outgoing Rx packet is | |
2989 | * created and sent on a connection using the given security object. | |
2990 | * \li int (*op SendPacket)() - Called each time a packet belonging to a call | |
2991 | * in a connection using the security object is physically transmitted. | |
2992 | * \li int (*op CheckAuthentication)() - This function is executed each time it | |
2993 | * is necessary to check whether authenticated calls are being perfomed on a | |
2994 | * connection using the associated security object. | |
2995 | * \li int (*op CreateChallenge)() - Invoked each time a server-side challenge | |
2996 | * event is created by Rx, namely when the identity of the principal associated | |
2997 | * with the peer process must be determined. | |
2998 | * \li int (*op GetChallenge)() - Called each time a client-side packet is | |
2999 | * constructed in response to an authentication challenge. | |
3000 | * \li int (*op GetResponse)() - Executed each time a response to a challenge | |
3001 | * event must be received on the server side of a connection. | |
3002 | * \li int (*op CheckResponse)() - Invoked each time a response to an | |
3003 | * authentication has been received, validating the response and pulling out | |
3004 | * the required authentication information. | |
3005 | * \li int (*op CheckPacket) () - Invoked each time an Rx packet has been | |
3006 | * received, making sure that the packet is properly formatted and that it | |
3007 | * hasn't been altered. | |
3008 | * \li int (*op DestroyConnection)() - Called each time an Rx connection | |
3009 | * employing the given security object is destroyed. | |
3010 | * \li int (*op GetStats)() - Executed each time a request for statistics on | |
3011 | * the given security object has been received. | |
3012 | * \li int (*op Spare1)()-int (*op Spare3)() - Three spare function slots, | |
3013 | * reserved for future use. | |
3014 | * | |
3015 | * \subsubsection sec5-3-1-2 Section 5.2.1.2: struct rx securityClass | |
3016 | * | |
3017 | * \par | |
3018 | * Variables of type struct rx securityClass are used to represent | |
3019 | * instantiations of a particular security model employed by Rx. It consists of | |
3020 | * a pointer to the set of interface operations implementing the given security | |
3021 | * object, along with a pointer to private storage as necessary to support its | |
3022 | * operations. These security objects are also reference-counted, tracking the | |
3023 | * number of Rx connections in existance that use the given security object. If | |
3024 | * the reference count drops to zero, the security module may garbage-collect | |
3025 | * the space taken by the unused security object. | |
3026 | * \par | |
3027 | * \b fields | |
3028 | * \li struct rx securityOps *ops - Pointer to the array of interface functions | |
3029 | * for the security object. | |
3030 | * \li VOID *privateData - Pointer to a region of storage used by the security | |
3031 | * object to support its operations. | |
3032 | * \li int refCount - A reference count on the security object, tracking the | |
3033 | * number of Rx connections employing this model. | |
3034 | * | |
3035 | * \subsubsection sec5-3-1-3 Section 5.3.1.3: struct rx | |
3036 | * securityObjectStats | |
3037 | * | |
3038 | * \par | |
3039 | * This structure is used to report characteristics for an instantiation of a | |
3040 | * security object on a particular Rx connection, as well as performance | |
3041 | * figures for that object. It is used by the debugging portions of the Rx | |
3042 | * package. Every security object defines and manages fields such as level and | |
3043 | * flags differently. | |
3044 | * \par | |
3045 | * \b fields | |
3046 | * \li char type - The type of security object being implemented. Existing | |
3047 | * values are: | |
3048 | * \li 0: The null security package. | |
3049 | * \li 1: An obsolete Kerberos-like security object. | |
3050 | * \li 2: The rxkad discipline (see Chapter 3). | |
3051 | * \li char level - The level at which encryption is utilized. | |
3052 | * \li char sparec[10] - Used solely for alignment purposes. | |
3053 | * \li long flags - Status flags regarding aspects of the connection relating | |
3054 | * to the security object. | |
3055 | * \li u long expires - Absolute time when the authentication information | |
3056 | * cached by the given connection expires. A value of zero indicates that the | |
3057 | * associated authentication information is valid for all time. | |
3058 | * \li u long packetsReceived - Number of packets received on this particular | |
3059 | * connection, and thus the number of incoming packets handled by the | |
3060 | * associated security object. | |
3061 | * \li u long packetsSent - Number of packets sent on this particular | |
3062 | * connection, and thus the number of outgoing packets handled by the | |
3063 | * associated security object. | |
3064 | * \li u long bytesReceived - Overall number of "payload" bytes received (i.e., | |
3065 | * packet bytes not associated with IP headers, UDP headers, and the security | |
3066 | * module's own header and trailer regions) on this connection. | |
3067 | * \li u long bytesSent - Overall number of "payload" bytes sent (i.e., packet | |
3068 | * bytes not associated with IP headers, UDP headers, and the security module's | |
3069 | * own header and trailer regions) on this connection. | |
3070 | * \li short spares[4] - Several shortword spares, reserved for future use. | |
3071 | * \li long sparel[8] - Several longword spares, reserved for future use. | |
3072 | * | |
3073 | * \subsection sec5-3-2 Section 5.3.2: Protocol Objects | |
3074 | * | |
3075 | * \par | |
3076 | * The structures describing the main abstractions and entities provided by Rx, | |
3077 | * namely services, peers, connections and calls are covered in this section. | |
3078 | * | |
3079 | * \subsubsection sec5-3-2-1 Section 5.3.2.1: struct rx service | |
3080 | * | |
3081 | * \par | |
3082 | * An Rx-based server exports services, or specific RPC interfaces that | |
3083 | * accomplish certain tasks. Services are identified by (host-address, | |
3084 | * UDP-port, serviceID) triples. An Rx service is installed and initialized on | |
3085 | * a given host through the use of the rx NewService() routine (See Section | |
3086 | * 5.6.3). Incoming calls are stamped with the Rx service type, and must match | |
3087 | * an installed service to be accepted. Internally, Rx services also carry | |
3088 | * string names for purposes of identification. These strings are useful to | |
3089 | * remote debugging and statistics-gathering programs. The use of a service ID | |
3090 | * allows a single server process to export multiple, independently-specified | |
3091 | * Rx RPC services. | |
3092 | * \par | |
3093 | * Each Rx service contains one or more security classes, as implemented by | |
3094 | * individual security objects. These security objects implement end-to-end | |
3095 | * security protocols. Individual peer-to-peer connections established on | |
3096 | * behalf of an Rx service will select exactly one of the supported security | |
3097 | * objects to define the authentication procedures followed by all calls | |
3098 | * associated with the connection. Applications are not limited to using only | |
3099 | * the core set of built-in security objects offered by Rx. They are free to | |
3100 | * define their own security objects in order to execute the specific protocols | |
3101 | * they require. | |
3102 | * \par | |
3103 | * It is possible to specify both the minimum and maximum number of lightweight | |
3104 | * processes available to handle simultaneous calls directed to an Rx service. | |
3105 | * In addition, certain procedures may be registered with the service and | |
3106 | * called at set times in the course of handling an RPC request. | |
3107 | * \par | |
3108 | * \b fields | |
3109 | * \li u short serviceId - The associated service number. | |
3110 | * \li u short servicePort - The chosen UDP port for this service. | |
3111 | * \li char *serviceName - The human-readable service name, expressed as a | |
3112 | * character | |
3113 | * \li string. osi socket socket - The socket structure or file descriptor used | |
3114 | * by this service. | |
3115 | * \li u short nSecurityObjects - The number of entries in the array of | |
3116 | * supported security objects. | |
3117 | * \li struct rx securityClass **securityObjects - The array of pointers to the | |
3118 | * ser | |
3119 | * vice's security class objects. | |
3120 | * \li long (*executeRequestProc)() - A pointer to the routine to call when an | |
3121 | * RPC request is received for this service. | |
3122 | * \li VOID (*destroyConnProc)() - A pointer to the routine to call when one of | |
3123 | * the server-side connections associated with this service is destroyed. | |
3124 | * \li VOID (*newConnProc)() - A pointer to the routine to call when a | |
3125 | * server-side connection associated with this service is created. | |
3126 | * \li VOID (*beforeProc)() - A pointer to the routine to call before an | |
3127 | * individual RPC call on one of this service's connections is executed. | |
3128 | * \li VOID (*afterProc)() - A pointer to the routine to call after an | |
3129 | * individual RPC call on one of this service's connections is executed. | |
3130 | * \li short nRequestsRunning - The number of simultaneous RPC calls currently | |
3131 | * in progress for this service. | |
3132 | * \li short maxProcs - This field has two meanings. first, maxProcs limits the | |
3133 | * total number of requests that may execute in parallel for any one service. | |
3134 | * It also guarantees that this many requests may be handled in parallel if | |
3135 | * there are no active calls for any other service. | |
3136 | * \li short minProcs - The minimum number of lightweight threads (hence | |
3137 | * requests) guaranteed to be simultaneously executable. | |
3138 | * \li short connDeadTime - The number of seconds until a client of this | |
3139 | * service will be declared to be dead, if it is not responding to the RPC | |
3140 | * protocol. | |
3141 | * \li short idleDeadTime - The number of seconds a server-side connection for | |
3142 | * this service will wait for packet I/O to resume after a quiescent period | |
3143 | * before the connection is marked as dead. | |
3144 | * | |
3145 | * \subsubsection sec5-3-2-2 Section 5.3.2.2: struct rx connection | |
3146 | * | |
3147 | * \par | |
3148 | * An Rx connection represents an authenticated communication path, allowing | |
3149 | * multiple asynchronous conversations (calls). Each connection is identified | |
3150 | * by a connection ID. The low-order bits of the connection ID are reserved so | |
3151 | * they may be stamped with the index of a particular call channel. With up to | |
3152 | * RX MAXCALLS concurrent calls (set to 4 in this implementation), the bottom | |
3153 | * two bits are set aside for this purpose. The connection ID is not sufficient | |
3154 | * by itself to uniquely identify an Rx connection. Should a client crash and | |
3155 | * restart, it may reuse a connection ID, causing inconsistent results. In | |
3156 | * addition to the connection ID, the epoch, or start time for the client side | |
3157 | * of the connection, is used to identify a connection. Should the above | |
3158 | * scenario occur, a different epoch value will be chosen by the client, | |
3159 | * differentiating this incarnation from the orphaned connection record on the | |
3160 | * server side. | |
3161 | * \par | |
3162 | * Each connection is associated with a parent service, which defines a set of | |
3163 | * supported security models. At creation time, an Rx connection selects the | |
3164 | * particular security protocol it will implement, referencing the associated | |
3165 | * service. The connection structure maintains state about the individual calls | |
3166 | * being simultaneously handled. | |
3167 | * \par | |
3168 | * \b fields | |
3169 | * \li struct rx connection *next - Used for internal queueing. | |
3170 | * \li struct rx peer *peer - Pointer to the connection's peer information (see | |
3171 | * below). | |
3172 | * \li u long epoch - Process start time of the client side of the connection. | |
3173 | * \li u long cid - Connection identifier. The call channel (i.e., the index | |
3174 | * into the connection's array of call structures) may appear in the bottom | |
3175 | * bits. | |
3176 | * \li VOID *rock - Pointer to an arbitrary region of memory in support of the | |
3177 | * connection's operation. The contents of this area are opaque to the Rx | |
3178 | * facility in general, but are understood by any special routines used by this | |
3179 | * connection. | |
3180 | * \li struct rx call *call[RX MAXCALLS] - Pointer to the call channel | |
3181 | * structures, describing up to RX MAXCALLS concurrent calls on this | |
3182 | * connection. | |
3183 | * \li u long callNumber[RX MAXCALLS] - The set of current call numbers on each | |
3184 | * of the call channels. | |
3185 | * \li int timeout - Obsolete; no longer used. | |
3186 | * \li u char flags - Various states of the connection; see Section 5.2.4 for | |
3187 | * individual bit definitions. | |
3188 | * \li u char type - Whether the connection is a server-side or client-side | |
3189 | * one. See Section 5.2.5 for individual bit definitions. | |
3190 | * \li u short serviceId - The service ID that should be stamped on requests. | |
3191 | * This field is only used by client-side instances of connection structures. | |
3192 | * \li struct rx service *service - A pointer to the service structure | |
3193 | * associated with this connection. This field is only used by server-side | |
3194 | * instances of connection structures. | |
3195 | * \li u long serial - Serial number of the next outgoing packet associated | |
3196 | * with this connection. | |
3197 | * \li u long lastSerial - Serial number of the last packet received in | |
3198 | * association with this connection. This field is used in computing packet | |
3199 | * skew. | |
3200 | * \li u short secondsUntilDead - Maximum numer of seconds of silence that | |
3201 | * should be tolerated from the connection's peer before calls will be | |
3202 | * terminated with an RX CALL DEAD error. | |
3203 | * \li u char secondsUntilPing - The number of seconds between "pings" | |
3204 | * (keep-alive probes) when at least one call is active on this connection. | |
3205 | * \li u char securityIndex - The index of the security object being used by | |
3206 | * this connection. This number selects a slot in the security class array | |
3207 | * maintained by the service associated with the connection. | |
3208 | * \li long error - Records the latest error code for calls occurring on this | |
3209 | * connection. | |
3210 | * \li struct rx securityClass *securityObject - A pointer to the security | |
3211 | * object used by this connection. This should coincide with the slot value | |
3212 | * chosen by the securityIndex field described above. | |
3213 | * \li VOID *securityData - A pointer to a region dedicated to hosting any | |
3214 | * storage required by the security object being used by this connection. | |
3215 | * \li u short securityHeaderSize - The length in bytes of the portion of the | |
3216 | * packet header before the user's data that contains the security module's | |
3217 | * information. | |
3218 | * \li u short securityMaxTrailerSize - The length in bytes of the packet | |
3219 | * trailer, appearing after the user's data, as mandated by the connection's | |
3220 | * security module. | |
3221 | * \li struct rxevent *challengeEvent -Pointer to an event that is scheduled | |
3222 | * when the server side of the connection is challenging the client to | |
3223 | * authenticate itself. | |
3224 | * \li int lastSendTime - The last time a packet was sent on this connection. | |
3225 | * \li long maxSerial - The largest serial number seen on incoming packets. | |
3226 | * \li u short hardDeadTime - The maximum number of seconds that any call on | |
3227 | * this connection may execute. This serves to throttle runaway calls. | |
3228 | * | |
3229 | * \subsubsection sec5-3-2-3 Section 5.3.2.3: struct rx peer | |
3230 | * | |
3231 | * \par | |
3232 | * For each connection, Rx maintains information describing the entity, or | |
3233 | * peer, on the other side of the wire. A peer is identified by a (host, | |
3234 | * UDP-port) pair. Included in the information kept on this remote | |
3235 | * communication endpoint are such network parameters as the maximum packet | |
3236 | * size supported by the host, current readings on round trip time to | |
3237 | * retransmission delays, and packet skew (see Section 1.2.7). There are also | |
3238 | * congestion control fields, ranging from descriptions of the maximum number | |
3239 | * of packets that may be sent to the peer without pausing and retransmission | |
3240 | * statistics. Peer structures are shared between connections whenever | |
3241 | * possible, and hence are reference-counted. A peer object may be | |
3242 | * garbage-collected if it is not actively referenced by any connection | |
3243 | * structure and a sufficient period of time has lapsed since the reference | |
3244 | * count dropped to zero. | |
3245 | * \par | |
3246 | * \b fields | |
3247 | * \li struct rx peer *next - Use to access internal lists. | |
3248 | * \li u long host - Remote IP address, in network byte order | |
3249 | * \li u short port - Remote UDP port, in network byte order | |
3250 | * \li short packetSize - Maximum packet size for this host, if known. | |
3251 | * \li u long idleWhen - When the refCount reference count field (see below) | |
3252 | * went to zero. | |
3253 | * \li short refCount - Reference count for this structure | |
3254 | * \li u char burstSize - Reinitialization size for the burst field (below). | |
3255 | * \li u char burst - Number of packets that can be transmitted immediately | |
3256 | * without pausing. | |
3257 | * \li struct clock burstWait - Time delay until new burst aimed at this peer | |
3258 | * is allowed. | |
3259 | * \li struct queue congestionQueue - Queue of RPC call descriptors that are | |
3260 | * waiting for a non-zero burst value. | |
3261 | * \li int rtt - Round trip time to the peer, measured in milliseconds. | |
3262 | * \li struct clock timeout - Current retransmission delay to the peer. | |
3263 | * \li int nSent - Total number of distinct data packets sent, not including | |
3264 | * retransmissions. | |
3265 | * \li int reSends - Total number of retransmissions for this peer since the | |
3266 | * peer structure instance was created. | |
3267 | * \li u long inPacketSkew - Maximum skew on incoming packets (see Section | |
3268 | * 1.2.7) | |
3269 | * \li u long outPacketSkew - Peer-reported maximum skew on outgoing packets | |
3270 | * (see Section 1.2.7). | |
3271 | * | |
3272 | * \subsubsection sec5-3-2-4 Section 5.3.2.4: struct rx call | |
3273 | * | |
3274 | * \par | |
3275 | * This structure records the state of an active call proceeding on a given Rx | |
3276 | * connection. As described above, each connection may have up to RX MAXCALLS | |
3277 | * calls active at any one instant, and thus each connection maintains an array | |
3278 | * of RX MAXCALLS rx call structures. The information contained here is | |
3279 | * specific to the given call; "permanent" call state, such as the call number, | |
3280 | * is maintained in the connection structure itself. | |
3281 | * \par | |
3282 | * \b fields | |
3283 | * \li struct queue queue item header - Queueing information for this | |
3284 | * structure. | |
3285 | * \li struct queue tq - Queue of outgoing ("transmit") packets. | |
3286 | * \li struct queue rq - Queue of incoming ("receive") packets. | |
3287 | * \li char *bufPtr - Pointer to the next byte to fill or read in the call's | |
3288 | * current packet, depending on whether it is being transmitted or received. | |
3289 | * \li u short nLeft - Number of bytes left to read in the first packet in the | |
3290 | * reception queue (see field rq). | |
3291 | * \li u short nFree - Number of bytes still free in the last packet in the | |
3292 | * transmission queue (see field tq). | |
3293 | * \li struct rx packet *currentPacket - Pointer to the current packet being | |
3294 | * assembled or read. | |
3295 | * \li struct rx connection *conn - Pointer to the parent connection for this | |
3296 | * call. | |
3297 | * \li u long *callNumber - Pointer to call number field within the call's | |
3298 | * current packet. | |
3299 | * \li u char channel - Index within the parent connection's call array that | |
3300 | * describes this call. | |
3301 | * \li u char dummy1, dummy2 - These are spare fields, reserved for future use. | |
3302 | * \li u char state - Current call state. The associated bit definitions appear | |
3303 | * in Section 5.2.7. | |
3304 | * \li u char mode - Current mode of a call that is in RX STATE ACTIVE state. | |
3305 | * The associated bit definitions appear in Section 5.2.8. | |
3306 | * \li u char flags - Flags pertaining to the state of the given call. The | |
3307 | * associated bit definitions appear in Section 5.2.7. | |
3308 | * \li u char localStatus - Local user status information, sent out of band. | |
3309 | * This field is currently not in use, set to zero. | |
3310 | * \li u char remoteStatus - Remote user status information, received out of | |
3311 | * band. This field is currently not in use, set to zero. | |
3312 | * \li long error - Error condition for this call. | |
3313 | * \li u long timeout - High level timeout for this call | |
3314 | * \li u long rnext - Next packet sequence number expected to be received. | |
3315 | * \li u long rprev - Sequence number of the previous packet received. This | |
3316 | * number is used to decide the proper sequence number for the next packet to | |
3317 | * arrive, and may be used to generate a negative acknowledgement. | |
3318 | * \li u long rwind - Width of the packet receive window for this call. The | |
3319 | * peer must not send packets with sequence numbers greater than or equal to | |
3320 | * rnext + rwind. | |
3321 | * \li u long tfirst - Sequence number of the first unacknowledged transmit | |
3322 | * packet for this call. | |
3323 | * \li u long tnext - Next sequence number to use for an outgoing packet. | |
3324 | * \li u long twind - Width of the packet transmit window for this call. Rx | |
3325 | * cannot assign a sequence number to an outgoing packet greater than or equal | |
3326 | * to tfirst + twind. | |
3327 | * \li struct rxevent *resendEvent - Pointer to a pending retransmission event, | |
3328 | * if any. | |
3329 | * \li struct rxevent *timeoutEvent - Pointer to a pending timeout event, if | |
3330 | * any. | |
3331 | * \li struct rxevent *keepAliveEvent - Pointer to a pending keep-alive event, | |
3332 | * if this is an active call. | |
3333 | * \li struct rxevent *delayedAckEvent - Pointer to a pending delayed | |
3334 | * acknowledgement packet event, if any. Transmission of a delayed | |
3335 | * acknowledgement packet is scheduled after all outgoing packets for a call | |
3336 | * have been sent. If neither a reply nor a new call are received by the time | |
3337 | * the delayedAckEvent activates, the ack packet will be sent. | |
3338 | * \li int lastSendTime - Last time a packet was sent for this call. | |
3339 | * \li int lastReceiveTime - Last time a packet was received for this call. | |
3340 | * \li VOID (*arrivalProc)() - Pointer to the procedure to call when reply is | |
3341 | * received. | |
3342 | * \li VOID *arrivalProcHandle - Pointer to the handle to pass to the | |
3343 | * arrivalProc as its first argument. | |
3344 | * \li VOID *arrivalProcArg - Pointer to an additional argument to pass to the | |
3345 | * given arrivalProc. | |
3346 | * \li u long lastAcked - Sequence number of the last packet "hard-acked" by | |
3347 | * the receiver. A packet is considered to be hard-acked if an acknowledgement | |
3348 | * is generated after the reader has processed it. The Rx facility may | |
3349 | * sometimes "soft-ack" a windowfull of packets before they have been picked up | |
3350 | * by the receiver. | |
3351 | * \li u long startTime - The time this call started running. | |
3352 | * \li u long startWait - The time that a server began waiting for input data | |
3353 | * or send quota. | |
3354 | * | |
3355 | * \subsection sec5-3-3 Section 5.3.3: Packet Formats | |
3356 | * | |
3357 | * \par | |
3358 | * The following sections cover the different data formats employed by the | |
3359 | * suite of Rx packet types, as enumerated in Section 5.2.11. A description of | |
3360 | * the most commonly-employed Rx packet header appears first, immediately | |
3361 | * followed by a description of the generic packet container and descriptor. | |
3362 | * The formats for Rx acknowledgement packets and debugging/statistics packets | |
3363 | * are also examined. | |
3364 | * | |
3365 | * \subsubsection sec5-3-3-1 Section 5.3.3.1: struct rx header | |
3366 | * | |
3367 | * \par | |
3368 | * Every Rx packet has its own header region, physically located after the | |
3369 | * leading IP/UDP headers. This header contains connection, call, security, and | |
3370 | * sequencing information. Along with a type identifier, these fields allow the | |
3371 | * receiver to properly interpret the packet. In addition, every client relates | |
3372 | * its "epoch", or Rx incarnation date, in each packet. This assists in | |
3373 | * identifying protocol problems arising from reuse of connection identifiers | |
3374 | * due to a client restart. Also included in the header is a byte of | |
3375 | * user-defined status information, allowing out-of-band channel of | |
3376 | * communication for the higher-level application using Rx as a transport | |
3377 | * mechanism. | |
3378 | * \par | |
3379 | * \b fields | |
3380 | * \li u long epoch - Birth time of the client Rx facility. | |
3381 | * \li u long cid - Connection identifier, as defined by the client. The last | |
3382 | * RX CIDSHIFT bits in the cid field identify which of the server-side RX | |
3383 | * MAXCALLS call channels is to receive the packet. | |
3384 | * \li u long callNumber - The current call number on the chosen call channel. | |
3385 | * \li u long seq - Sequence number of this packet. Sequence numbers start with | |
3386 | * 0 for each new Rx call. | |
3387 | * \li u long serial - This packet's serial number. A new serial number is | |
3388 | * stamped on each packet transmitted (or retransmitted). | |
3389 | * \li u char type - What type of Rx packet this is; see Section 5.2.11 for the | |
3390 | * list of legal definitions. | |
3391 | * \li u char flags - Flags describing this packet; see Section 5.2.9 for the | |
3392 | * list of legal settings. | |
3393 | * \li u char userStatus - User-defined status information, uninterpreted by | |
3394 | * the Rx facility itself. This field may be easily set or retrieved from Rx | |
3395 | * packets via calls to the rx GetLocalStatus(), rx SetLocalStatus(), rx | |
3396 | * GetRemoteStatus(), and rx SetRemoteStatus() macros. | |
3397 | * \li u char securityIndex - Index in the associated server-side service class | |
3398 | * of the security object used by this call. | |
3399 | * \li u short serviceId - The server-provided service ID to which this packet | |
3400 | * is directed. | |
3401 | * \li u short spare - This field was originally a true spare, but is now used | |
3402 | * by the built-in rxkad security module for packet header checksums. See the | |
3403 | * descriptions of the related rx IsUsingPktChecksum(), rx GetPacketCksum(), | |
3404 | * and rx SetPacketCksum() macros. | |
3405 | * | |
3406 | * \subsubsection sec5-3-3-2 Section 5.3.3.2: struct rx packet | |
3407 | * | |
3408 | * \par | |
3409 | * This structure is used to describe an Rx packet, and includes the wire | |
3410 | * version of the packet contents, where all fields exist in network byte | |
3411 | * order. It also includes acknowledgement, length, type, and queueing | |
3412 | * information. | |
3413 | * \par | |
3414 | * \b fields | |
3415 | * \li struct queue queueItemHeader - field used for internal queueing. | |
3416 | * \li u char acked - If non-zero, this field indicates that this packet has | |
3417 | * been tentatively (soft-) acknowledged. Thus, the packet has been accepted by | |
3418 | * the rx peer entity on the other side of the connection, but has not yet | |
3419 | * necessarily been passed to the true reader. The sender is not free to throw | |
3420 | * the packet away, as it might still get dropped by the peer before it is | |
3421 | * delivered to its destination process. | |
3422 | * \li short length - Length in bytes of the user data section. | |
3423 | * \li u char packetType - The type of Rx packet described by this record. The | |
3424 | * set of legal choices is available in Section 5.2.11. | |
3425 | * \li struct clock retryTime - The time when this packet should be | |
3426 | * retransmitted next. | |
3427 | * \li struct clock timeSent - The last time this packet was transmitted. | |
3428 | * \li struct rx header header - A copy of the internal Rx packet header. | |
3429 | * \li wire - The text of the packet as it appears on the wire. This structure | |
3430 | * has the following sub-fields: | |
3431 | * \li u long head[RX HEADER SIZE/sizeof(long)] The wire-level contents of | |
3432 | * IP, UDP, and Rx headers. | |
3433 | * \li u long data[RX MAX PACKET DATA SIZE/sizeof(long)] The wire form of | |
3434 | * the packet's "payload", namely the user data it carries. | |
3435 | * | |
3436 | * \subsubsection sec5-3-3-3 Section 5.3.3.3: struct rx ackPacket | |
3437 | * | |
3438 | * \par | |
3439 | * This is the format for the data portion of an Rx acknowledgement packet, | |
3440 | * used to inform a peer entity performing packet transmissions that a subset | |
3441 | * of its packets has been properly received. | |
3442 | * \par | |
3443 | * \b fields | |
3444 | * \li u short bufferSpace - Number of packet buffers available. Specifically, | |
3445 | * the number of packet buffers that the ack packet's sender is willing to | |
3446 | * provide for data on this or subsequent calls. This number does not have to | |
3447 | * fully accurate; it is acceptable for the sender to provide an estimate. | |
3448 | * \li u short maxSkew - The maximum difference seen between the serial number | |
3449 | * of the packet being acknowledged and highest packet yet received. This is an | |
3450 | * indication of the degree to which packets are arriving out of order at the | |
3451 | * receiver. | |
3452 | * \li u long firstPacket - The serial number of the first packet in the list | |
3453 | * of acknowledged packets, as represented by the acks field below. | |
3454 | * \li u long previousPacket - The previous packet serial number received. | |
3455 | * \li u long serial - The serial number of the packet prompted the | |
3456 | * acknowledgement. | |
3457 | * \li u char reason - The reason given for the acknowledgement; legal values | |
3458 | * for this field are described in Section 5.2.13. | |
3459 | * \li u char nAcks - Number of acknowledgements active in the acks array | |
3460 | * immediately following. | |
3461 | * \li u char acks[RX MAXACKS] - Up to RX MAXACKS packet acknowledgements. The | |
3462 | * legal values for each slot in the acks array are described in Section | |
3463 | * 5.2.14. Basically, these fields indicate either positive or negative | |
3464 | * acknowledgements. | |
3465 | * | |
3466 | * \par | |
3467 | * All packets with serial numbers prior to firstPacket are implicitly | |
3468 | * acknowledged by this packet, indicating that they have been fully processed | |
3469 | * by the receiver. Thus, the sender need no longer be concerned about them, | |
3470 | * and may release all of the resources that they occupy. Packets with serial | |
3471 | * numbers firstPacket + nAcks and higher are not acknowledged by this ack | |
3472 | * packet. Packets with serial numbers in the range [firstPacket, firstPacket + | |
3473 | * nAcks) are explicitly acknowledged, yet their sender-side resources must not | |
3474 | * yet be released, as there is yet no guarantee that the receiver will not | |
3475 | * throw them away before they can be processed there. | |
3476 | * \par | |
3477 | * There are some details of importance to be noted. For one, receiving a | |
3478 | * positive acknowlegement via the acks array does not imply that the | |
3479 | * associated packet is immune from being dropped before it is read and | |
3480 | * processed by the receiving entity. It does, however, imply that the sender | |
3481 | * should stop retransmitting the packet until further notice. Also, arrival of | |
3482 | * an ack packet should prompt the transmitter to immediately retransmit all | |
3483 | * packets it holds that have not been explicitly acknowledged and that were | |
3484 | * last transmitted with a serial number less than the highest serial number | |
3485 | * acknowledged by the acks array. | |
3486 | * Note: The fields in this structure are always kept in wire format, namely in | |
3487 | * network byte order. | |
3488 | * | |
3489 | * \subsection sec5-3-4 Section 5.3.4: Debugging and Statistics | |
3490 | * | |
3491 | * \par | |
3492 | * The following structures are defined in support of the debugging and | |
3493 | * statistics-gathering interfaces provided by Rx. | |
3494 | * | |
3495 | * \subsubsection sec5-3-4-1 Section 5.3.4.1: struct rx stats | |
3496 | * | |
3497 | * \par | |
3498 | * This structure maintains Rx statistics, and is gathered by such tools as the | |
3499 | * rxdebug program. It must be possible for all of the fields placed in this | |
3500 | * structure to be successfully converted from their on-wire network byte | |
3501 | * orderings to the host-specific ordering. | |
3502 | * \par | |
3503 | * \b fields | |
3504 | * \li int packetRequests - Number of packet allocation requests processed. | |
3505 | * \li int noPackets[RX N PACKET CLASSES] - Number of failed packet requests, | |
3506 | * organized per allocation class. | |
3507 | * \li int socketGreedy - Whether the SO GREEDY setting succeeded for the Rx | |
3508 | * socket. | |
3509 | * \li int bogusPacketOnRead - Number of inappropriately short packets | |
3510 | * received. | |
3511 | * \li int bogusHost - Contains the host address from the last bogus packet | |
3512 | * received. | |
3513 | * \li int noPacketOnRead - Number of attempts to read a packet off the wire | |
3514 | * when there was actually no packet there. | |
3515 | * \li int noPacketBuffersOnRead - Number of dropped data packets due to lack | |
3516 | * of packet buffers. | |
3517 | * \li int selects - Number of selects waiting for a packet arrival or a | |
3518 | * timeout. | |
3519 | * \li int sendSelects - Number of selects forced when sending packets. | |
3520 | * \li int packetsRead[RX N PACKET TYPES] - Total number of packets read, | |
3521 | * classified by type. | |
3522 | * \li int dataPacketsRead - Number of unique data packets read off the wire. | |
3523 | * \li int ackPacketsRead - Number of ack packets read. | |
3524 | * \li int dupPacketsRead - Number of duplicate data packets read. | |
3525 | * \li int spuriousPacketsRead - Number of inappropriate data packets. | |
3526 | * \li int packetsSent[RX N PACKET TYPES] - Number of packet transmissions, | |
3527 | * broken down by packet type. | |
3528 | * \li int ackPacketsSent - Number of ack packets sent. | |
3529 | * \li int pingPacketsSent - Number of ping packets sent. | |
3530 | * \li int abortPacketsSent - Number of abort packets sent. | |
3531 | * \li int busyPacketsSent - Number of busy packets sent. | |
3532 | * \li int dataPacketsSent - Number of unique data packets sent. | |
3533 | * \li int dataPacketsReSent - Number of retransmissions. | |
3534 | * \li int dataPacketsPushed - Number of retransmissions pushed early by a | |
3535 | * negative acknowledgement. | |
3536 | * \li int ignoreAckedPacket - Number of packets not retransmitted because they | |
3537 | * have already been acked. | |
3538 | * \li int struct clock totalRtt - Total round trip time measured for packets, | |
3539 | * used to compute average time figure. | |
3540 | * \li struct clock minRtt - Minimum round trip time measured for packets. | |
3541 | * struct clock maxRtt - Maximum round trip time measured for packets. | |
3542 | * \li int nRttSamples - Number of round trip samples. | |
3543 | * \li int nServerConns - Number of server connections. | |
3544 | * \li int nClientConns - Number of client connections. | |
3545 | * \li int nPeerStructs - Number of peer structures. | |
3546 | * \li int nCallStructs - Number of call structures physically allocated (using | |
3547 | * the internal storage allocator routine). | |
3548 | * \li int nFreeCallStructs - Number of call structures which were pulled from | |
3549 | * the free queue, thus avoiding a call to the internal storage allocator | |
3550 | * routine. | |
3551 | * \li int spares[10] - Ten integer spare fields, reserved for future use. | |
3552 | * | |
3553 | * \subsubsection sec5-3-4-2 Section 5.3.4.2: struct rx debugIn | |
3554 | * | |
3555 | * \par | |
3556 | * This structure defines the data format for a packet requesting one of the | |
3557 | * statistics collections maintained by Rx. | |
3558 | * \par | |
3559 | * \b fields | |
3560 | * \li long type - The specific data collection that the caller desires. Legal | |
3561 | * settings for this field are described in Section 5.2.16.2. | |
3562 | * \li long index - This field is only used when gathering information on Rx | |
3563 | * connections. Choose the index of the server-side connection record of which | |
3564 | * we are inquiring. This field may be used as an iterator, stepping through | |
3565 | * all the connection records, one per debugging request, until they have all | |
3566 | * been examined. | |
3567 | * | |
3568 | * \subsubsection sec5-3-4-3 Section 5.3.4.3: struct rx debugStats | |
3569 | * | |
3570 | * \par | |
3571 | * This structure describes the data format for a reply to an RX DEBUGI | |
3572 | * GETSTATS debugging request packet. These fields are given values indicating | |
3573 | * the current state of the Rx facility. | |
3574 | * \par | |
3575 | * \b fields | |
3576 | * \li long nFreePackets - Number of packet buffers currently assigned to the | |
3577 | * free pool. | |
3578 | * \li long packetReclaims - Currently unused. | |
3579 | * \li long callsExecuted - Number of calls executed since the Rx facility was | |
3580 | * initialized. | |
3581 | * \li char waitingForPackets - Is Rx currently blocked waiting for a packet | |
3582 | * buffer to come free? | |
3583 | * \li char usedFDs - If the Rx facility is executing in the kernel, return the | |
3584 | * number of unix file descriptors in use. This number is not directly related | |
3585 | * to the Rx package, but rather describes the state of the machine on which Rx | |
3586 | * is running. | |
3587 | * \li char version - Version number of the debugging package. | |
3588 | * \li char spare1[1] - Byte spare, reserved for future use. | |
3589 | * \li long spare2[10] - Set of 10 longword spares, reserved for future use. | |
3590 | * | |
3591 | * \subsubsection sec5-3-4-4 Section 5.3.4.4: struct rx debugConn | |
3592 | * | |
3593 | * \par | |
3594 | * This structure defines the data format returned when a caller requests | |
3595 | * information concerning an Rx connection. Thus, rx debugConn defines the | |
3596 | * external packaging of interest to external parties. Most of these fields are | |
3597 | * set from the rx connection structure, as defined in Section 5.3.2.2, and | |
3598 | * others are obtained by indirecting through such objects as the connection's | |
3599 | * peer and call structures. | |
3600 | * \par | |
3601 | * \b fields | |
3602 | * \li long host - Address of the host identified by the connection's peer | |
3603 | * structure. | |
3604 | * \li long cid - The connection ID. | |
3605 | * \li long serial - The serial number of the next outgoing packet associated | |
3606 | * with this connection. | |
3607 | * \li long callNumber[RX MAXCALLS] - The current call numbers for the | |
3608 | * individual call channels on this connection. | |
3609 | * \li long error - Records the latest error code for calls occurring on this | |
3610 | * connection. | |
3611 | * \li short port - UDP port associated with the connection's peer. | |
3612 | * \li char flags - State of the connection; see Section 5.2.4 for individual | |
3613 | * bit definitions. | |
3614 | * \li char type - Whether the connection is a server-side or client-side one. | |
3615 | * See Section 5.2.5 for individual bit definitions. | |
3616 | * \li char securityIndex - Index in the associated server-side service class | |
3617 | * of the security object being used by this call. | |
3618 | * \li char sparec[3] - Used to force alignment for later fields. | |
3619 | * \li char callState[RX MAXCALLS] - Current call state on each call channel. | |
3620 | * The associated bit definitions appear in Section 5.2.7. | |
3621 | * \li char callMode[RX MAXCALLS] - Current mode of all call channels that are | |
3622 | * in RX STATE ACTIVE state. The associated bit definitions appear in Section | |
3623 | * 5.2.8. | |
3624 | * \li char callFlags[RX MAXCALLS] - Flags pertaining to the state of each of | |
3625 | * the connection's call channels. The associated bit definitions appear in | |
3626 | * Section 5.2.7. | |
3627 | * \li char callOther[RX MAXCALLS] - Flag field for each call channel, where | |
3628 | * the presence of the RX OTHER IN flag indicates that there are packets | |
3629 | * present on the given call's reception queue, and the RX OTHER OUT flag | |
3630 | * indicates the presence of packets on the transmission queue. | |
3631 | * \li struct rx securityObjectStats secStats - The contents of the statistics | |
3632 | * related to the security object selected by the securityIndex field, if any. | |
3633 | * \li long epoch - The connection's client-side incarnation time. | |
3634 | * \li long sparel[10] - A set of 10 longword fields, reserved for future use. | |
3635 | * | |
3636 | * \subsubsection sec5-3-4-5 Section 5.3.4.5: struct rx debugConn vL | |
3637 | * | |
3638 | * \par | |
3639 | * This structure is identical to rx debugConn defined above, except for the | |
3640 | * fact that it is missing the sparec field. This sparec field is used in rx | |
3641 | * debugConn to fix an alignment problem that was discovered in version L of | |
3642 | * the debugging/statistics interface (hence the trailing "tt vL tag in the | |
3643 | * structure name). This alignment problem is fixed in version M, which | |
3644 | * utilizes and exports the rx debugConn structure exclusively. Information | |
3645 | * regarding the range of version-numbering values for the Rx | |
3646 | * debugging/statistics interface may be found in Section 5.2.16.1. | |
3647 | * \section sec5-4 Section 5.4: Exported Variables | |
3648 | * | |
3649 | * \par | |
3650 | * This section describes the set of variables that the Rx facility exports to | |
3651 | * its applications. Some of these variables have macros defined for the sole | |
3652 | * purpose of providing the caller with a convenient way to manipulate them. | |
3653 | * Note that some of these exported variables are never meant to be altered by | |
3654 | * application code (e.g., rx nPackets). | |
3655 | * | |
3656 | * \subsection sec5-4-1 Section 5.4.1: rx connDeadTime | |
3657 | * | |
3658 | * \par | |
3659 | * This integer-valued variable determines the maximum number of seconds that a | |
3660 | * connection may remain completely inactive, without receiving packets of any | |
3661 | * kind, before it is eligible for garbage collection. Its initial value is 12 | |
3662 | * seconds. The rx SetRxDeadTime macro sets the value of this variable. | |
3663 | * | |
3664 | * \subsection sec5-4-2 Section 5.4.2: rx idleConnectionTime | |
3665 | * | |
3666 | * \par | |
3667 | * This integer-valued variable determines the maximum number of seconds that a | |
3668 | * server connection may "idle" (i.e., not have any active calls and otherwise | |
3669 | * not have sent a packet) before becoming eligible for garbage collection. Its | |
3670 | * initial value is 60 seconds. | |
3671 | * | |
3672 | * \subsection sec5-4-3 Section 5.4.3: rx idlePeerTime | |
3673 | * | |
3674 | * \par | |
3675 | * This integer-valued variable determines the maximum number of seconds that | |
3676 | * an Rx peer structure is allowed to exist without any connection structures | |
3677 | * referencing it before becoming eligible for garbage collection. Its initial | |
3678 | * value is 60 seconds. | |
3679 | * | |
3680 | * \subsection sec5-4-4 Section 5.4.4: rx extraQuota | |
3681 | * | |
3682 | * \par | |
3683 | * This integer-valued variable is part of the Rx packet quota system (see | |
3684 | * Section 1.2.6), which is used to avoid system deadlock. This ensures that | |
3685 | * each server-side thread has a minimum number of packets at its disposal, | |
3686 | * allowing it to continue making progress on active calls. This particular | |
3687 | * variable records how many extra data packets a user has requested be | |
3688 | * allocated. Its initial value is 0. | |
3689 | * | |
3690 | * \subsection sec5-4-5 Section 5.4.5: rx extraPackets | |
3691 | * | |
3692 | * \par | |
3693 | * This integer-valued variable records how many additional packet buffers are | |
3694 | * to be created for each Rx server thread. The caller, upon setting this | |
3695 | * variable, is applying some application-specific knowledge of the level of | |
3696 | * network activity expected. The rx extraPackets variable is used to compute | |
3697 | * the overall number of packet buffers to reserve per server thread, namely rx | |
3698 | * nPackets, described below. The initial value is 32 packets. | |
3699 | * | |
3700 | * \subsection sec5-4-6 Section 5.4.6: rx nPackets | |
3701 | * | |
3702 | * \par | |
3703 | * This integer-valued variable records the total number of packet buffers to | |
3704 | * be allocated per Rx server thread. It takes into account the quota packet | |
3705 | * buffers and the extra buffers requested by the caller, if any. | |
3706 | * \note This variable should never be set directly; the Rx facility itself | |
3707 | * computes its value. Setting it incorrectly may result in the service | |
3708 | * becoming deadlocked due to insufficient resources. Callers wishing to | |
3709 | * allocate more packet buffers to their server threads should indicate that | |
3710 | * desire by setting the rx extraPackets variable described above. | |
3711 | * | |
3712 | * \subsection sec5-4-7 Section 5.4.7: rx nFreePackets | |
3713 | * | |
3714 | * \par | |
3715 | * This integer-valued variable records the number of Rx packet buffers not | |
3716 | * currently used by any call. These unused buffers are collected into a free | |
3717 | * pool. | |
3718 | * | |
3719 | * \subsection sec5-4-8 Section 5.4.8: rx stackSize | |
3720 | * | |
3721 | * \par | |
3722 | * This integer-valued variable records the size in bytes for the lightweight | |
3723 | * process stack. The variable is initially set to RX DEFAULT STACK SIZE, and | |
3724 | * is typically manipulated via the rx SetStackSize() macro. | |
3725 | * | |
3726 | * \subsection sec5-4-9 Section 5.4.9: rx packetTypes | |
3727 | * | |
3728 | * \par | |
3729 | * This variable holds an array of string names used to describe the different | |
3730 | * roles for Rx packets. Its value is derived from the RX PACKET TYPES | |
3731 | * definition found in Section 5.2.11. | |
3732 | * | |
3733 | * \subsection sec5-4-10 Section 5.4.10: rx stats | |
3734 | * | |
3735 | * \par | |
3736 | * This variable contains the statistics structure that keeps track of Rx | |
3737 | * statistics. The struct rx stats structure it provides is defined in Section | |
3738 | * 5.3.4.1. | |
3739 | * | |
3740 | * \section sec5-5 Section 5.5: Macros | |
3741 | * | |
3742 | * \par | |
3743 | * Rx uses many macro definitions in preference to calling C functions | |
3744 | * directly. There are two main reasons for doing this: | |
3745 | * \li field selection: Many Rx operations are easily realized by returning the | |
3746 | * value of a particular structure's field. It is wasteful to invoke a C | |
3747 | * routine to simply fetch a structure's field, incurring unnecessary function | |
3748 | * call overhead. Yet, a convenient, procedure-oriented operation is still | |
3749 | * provided to Rx clients for such operations by the use of macros. For | |
3750 | * example, the rx ConnectionOf() macro, described in Section 5.5.1.1, simply | |
3751 | * indirects through the Rx call structure pointer parameter to deliver the | |
3752 | * conn field. | |
3753 | * \li Performance optimization: In some cases, a simple test or operation can | |
3754 | * be performed to accomplish a particular task. When this simple, | |
3755 | * straightforward operation fails, then a true C routine may be called to | |
3756 | * handle to more complex (and rarer) situation. The Rx macro rx Write(), | |
3757 | * described in Section 5.5.6.2, is a perfect example of this type of | |
3758 | * optimization. Invoking rx Write() first checks to determine whether or not | |
3759 | * the outgoing call's internal buffer has enough room to accept the specified | |
3760 | * data bytes. If so, it copies them into the call's buffer, updating counts | |
3761 | * and pointers as appropriate. Otherwise, rx Write() calls the rx WriteProc() | |
3762 | * to do the work, which in this more complicated case involves packet | |
3763 | * manipulations, dispatches, and allocations. The result is that the common, | |
3764 | * simple cases are often handled in-line, with more complex (and rarer) cases | |
3765 | * handled through true function invocations. | |
3766 | * \par | |
3767 | * The set of Rx macros is described according to the following categories. | |
3768 | * \li field selections/assignments | |
3769 | * \li Boolean operations | |
3770 | * \li Service attributes | |
3771 | * \li Security-related operations | |
3772 | * \li Sizing operations | |
3773 | * \li Complex operation | |
3774 | * \li Security operation invocations | |
3775 | * | |
3776 | * \subsection sec5-5-1 Section 5.5.1: field Selections/Assignments | |
3777 | * | |
3778 | * \par | |
3779 | * These macros facilitate the fetching and setting of fields from the | |
3780 | * structures described Chapter 5.3. | |
3781 | * | |
3782 | * \subsubsection sec5-5-1-1 Section 5.5.1.1: rx ConnectionOf() | |
3783 | * | |
3784 | * \par | |
3785 | * \#define rx_ConnectionOf(call) ((call)->conn) | |
3786 | * \par | |
3787 | * Generate a reference to the connection field within the given Rx call | |
3788 | * structure. The value supplied as the call argument must resolve into an | |
3789 | * object of type (struct rx call *). An application of the rx ConnectionOf() | |
3790 | * macro itself yields an object of type rx peer. | |
3791 | * | |
3792 | * \subsubsection sec5-5-1-2 Section 5.5.1.2: rx PeerOf() | |
3793 | * | |
3794 | * \par | |
3795 | * \#define rx_PeerOf(conn) ((conn)->peer) | |
3796 | * \par | |
3797 | * Generate a reference to the peer field within the given Rx call structure. | |
3798 | * The value supplied as the conn argument must resolve into an object of type | |
3799 | * (struct rx connection *). An instance of the rx PeerOf() macro itself | |
3800 | * resolves into an object of type rx peer. | |
3801 | * | |
3802 | * \subsubsection sec5-5-1-3 Section 5.5.1.3: rx HostOf() | |
3803 | * | |
3804 | * \par | |
3805 | * \#define rx_HostOf(peer) ((peer)->host) | |
3806 | * \par | |
3807 | * Generate a reference to the host field within the given Rx peer structure. | |
3808 | * The value supplied as the peer argument must resolve into an object of type | |
3809 | * (struct rx peer *). An instance of the rx HostOf() macro itself resolves | |
3810 | * into an object of type u long. | |
3811 | * | |
3812 | * \subsubsection sec5-5-1-4 Section 5.5.1.4: rx PortOf() | |
3813 | * | |
3814 | * \par | |
3815 | * \#define rx_PortOf(peer) ((peer)->port) | |
3816 | * \par | |
3817 | * Generate a reference to the port field within the given Rx peer structure. | |
3818 | * The value supplied as the peer argument must resolve into an object of type | |
3819 | * (struct rx peer *). An instance of the rx PortOf() macro itself resolves | |
3820 | * into an object of type u short. | |
3821 | * | |
3822 | * \subsubsection sec5-5-1-5 Section 5.5.1.5: rx GetLocalStatus() | |
3823 | * | |
3824 | * \par | |
3825 | * \#define rx_GetLocalStatus(call, status) ((call)->localStatus) | |
3826 | * \par | |
3827 | * Generate a reference to the localStatus field, which specifies the local | |
3828 | * user status sent out of band, within the given Rx call structure. The value | |
3829 | * supplied as the call argument must resolve into an object of type (struct rx | |
3830 | * call *). The second argument, status, is not used. An instance of the rx | |
3831 | * GetLocalStatus() macro itself resolves into an object of type u char. | |
3832 | * | |
3833 | * \subsubsection sec5-5-1-6 Section 5.5.1.6: rx SetLocalStatus() | |
3834 | * | |
3835 | * \par | |
3836 | * \#define rx_SetLocalStatus(call, status) ((call)->localStatus = (status)) | |
3837 | * \par | |
3838 | * Assign the contents of the localStatus field, which specifies the local user | |
3839 | * status sent out of band, within the given Rx call structure. The value | |
3840 | * supplied as the call argument must resolve into an object of type (struct rx | |
3841 | * call *). The second argument, status, provides the new value of the | |
3842 | * localStatus field, and must resolve into an object of type u char. An | |
3843 | * instance of the rx GetLocalStatus() macro itself resolves into an object | |
3844 | * resulting from the assignment, namely the u char status parameter. | |
3845 | * | |
3846 | * \subsubsection sec5-5-1-7 Section 5.5.1.7: rx GetRemoteStatus() | |
3847 | * | |
3848 | * \par | |
3849 | * \#define rx_GetRemoteStatus(call) ((call)->remoteStatus) | |
3850 | * \par | |
3851 | * Generate a reference to the remoteStatus field, which specifies the remote | |
3852 | * user status received out of band, within the given Rx call structure. The | |
3853 | * value supplied as the call argument must resolve into an object of type | |
3854 | * (struct rx call *). An instance of the rx GetRemoteStatus() macro itself | |
3855 | * resolves into an object of type u char. | |
3856 | * | |
3857 | * \subsubsection sec5-5-1-8 Section 5.5.1.8: rx Error() | |
3858 | * | |
3859 | * \par | |
3860 | * \#define rx_Error(call) ((call)->error) | |
3861 | * \par | |
3862 | * Generate a reference to the error field, which specifies the current error | |
3863 | * condition, within the given Rx call structure. The value supplied as the | |
3864 | * call argument must resolve into an object of type (struct rx call *). An | |
3865 | * instance of the rx Error() macro itself resolves into an object of type | |
3866 | * long. | |
3867 | * | |
3868 | * \subsubsection sec5-5-1-9 Section 5.5.1.9: rx DataOf() | |
3869 | * | |
3870 | * \par | |
3871 | * \#define rx_DataOf(packet) ((char *) (packet)->wire.data) | |
3872 | * \par | |
3873 | * Generate a reference to the beginning of the data portion within the given | |
3874 | * Rx packet as it appears on the wire. Any encryption headers will be resident | |
3875 | * at this address. For Rx packets of type RX PACKET TYPE DATA, the actual user | |
3876 | * data will appear at the address returned by the rx DataOf macro plus the | |
3877 | * connection's security header size. The value supplied as the packet argument | |
3878 | * must resolve into an object of type (struct rx packet *). An instance of the | |
3879 | * rx DataOf() macro itself resolves into an object of type (u long *). | |
3880 | * | |
3881 | * \subsubsection sec5-5-1-10 Section 5.5.1.10: rx GetDataSize() | |
3882 | * | |
3883 | * \par | |
3884 | * \#define rx_GetDataSize(packet) ((packet)->length) | |
3885 | * \par | |
3886 | * Generate a reference to the length field, which specifies the number of | |
3887 | * bytes of user data contained within the wire form of the packet, within the | |
3888 | * given Rx packet description structure. The value supplied as the packet | |
3889 | * argument must resolve into an object of type (struct rx packet *). An | |
3890 | * instance of the rx GetDataSize() macro itself resolves into an object of | |
3891 | * type short. | |
3892 | * | |
3893 | * \subsubsection sec5-5-1-11 Section 5.5.1.11: rx SetDataSize() | |
3894 | * | |
3895 | * \par | |
3896 | * \#define rx_SetDataSize(packet, size) ((packet)->length = (size)) | |
3897 | * \par | |
3898 | * Assign the contents of the length field, which specifies the number of bytes | |
3899 | * of user data contained within the wire form of the packet, within the given | |
3900 | * Rx packet description structure. The value supplied as the packet argument | |
3901 | * must resolve into an object of type (struct rx packet *). The second | |
3902 | * argument, size, provides the new value of the length field, and must resolve | |
3903 | * into an object of type short. An instance of the rx SetDataSize() macro | |
3904 | * itself resolves into an object resulting from the assignment, namely the | |
3905 | * short length parameter. | |
3906 | * | |
3907 | * \subsubsection sec5-5-1-12 Section 5.5.1.12: rx GetPacketCksum() | |
3908 | * | |
3909 | * \par | |
3910 | * \#define rx_GetPacketCksum(packet) ((packet)->header.spare) | |
3911 | * \par | |
3912 | * Generate a reference to the header checksum field, as used by the built-in | |
3913 | * rxkad security module (See Chapter 3), within the given Rx packet | |
3914 | * description structure. The value supplied as the packet argument must | |
3915 | * resolve into an object of type (struct rx packet *). An instance of the rx | |
3916 | * GetPacketCksum() macro itself resolves into an object of type u short. | |
3917 | * | |
3918 | * \subsubsection sec5-5-1-13 Section 5.5.1.13: rx SetPacketCksum() | |
3919 | * | |
3920 | * \par | |
3921 | * \#define rx_SetPacketCksum(packet, cksum) ((packet)->header.spare = (cksum)) | |
3922 | * \par | |
3923 | * Assign the contents of the header checksum field, as used by the built-in | |
3924 | * rxkad security module (See Chapter 3), within the given Rx packet | |
3925 | * description structure. The value supplied as the packet argument must | |
3926 | * resolve into an object of type (struct rx packet *). The second argument, | |
3927 | * cksum, provides the new value of the checksum, and must resolve into an | |
3928 | * object of type u short. An instance of the rx SetPacketCksum() macro itself | |
3929 | * resolves into an object resulting from the assignment, namely the u short | |
3930 | * checksum parameter. | |
3931 | * | |
3932 | * \subsubsection sec5-5-1-14 Section 5.5.1.14: rx GetRock() | |
3933 | * | |
3934 | * \par | |
3935 | * \#define rx_GetRock(obj, type) ((type)(obj)->rock) | |
3936 | * \par | |
3937 | * Generate a reference to the field named rock within the object identified by | |
3938 | * the obj pointer. One common Rx structure to which this macro may be applied | |
3939 | * is struct rx connection. The specified rock field is casted to the value of | |
3940 | * the type parameter, which is the overall value of the rx GetRock() macro. | |
3941 | * | |
3942 | * \subsubsection sec5-5-1-15 Section 5.5.1.15: rx SetRock() | |
3943 | * | |
3944 | * \par | |
3945 | * \#define rx_SetRock(obj, newrock) ((obj)->rock = (VOID *)(newrock)) | |
3946 | * \par | |
3947 | * Assign the contents of the newrock parameter into the rock field of the | |
3948 | * object pointed to by obj. The given object's rock field must be of type | |
3949 | * (VOID *). An instance of the rx SetRock() macro itself resolves into an | |
3950 | * object resulting from the assignment and is of type (VOID *). | |
3951 | * | |
3952 | * \subsubsection sec5-5-1-16 Section 5.5.1.16: rx SecurityClassOf() | |
3953 | * | |
3954 | * \par | |
3955 | * \#define rx_SecurityClassOf(conn) ((conn)->securityIndex) | |
3956 | * \par | |
3957 | * Generate a reference to the security index field of the given Rx connection | |
3958 | * description structure. This identifies the security class used by the | |
3959 | * connection. The value supplied as the conn argument must resolve into an | |
3960 | * object of type (struct rx connection *). An instance of the rx | |
3961 | * SecurityClassOf() macro itself resolves into an object of type u char. | |
3962 | * | |
3963 | * \subsubsection sec5-5-1-17 Section 5.5.1.17: rx SecurityObjectOf() | |
3964 | * | |
3965 | * \par | |
3966 | * \#define rx_SecurityObjectOf(conn) ((conn)->securityObject) | |
3967 | * \par | |
3968 | * Generate a reference to the security object in use by the given Rx | |
3969 | * connection description structure. The choice of security object determines | |
3970 | * the authentication protocol enforced by the connection. The value supplied | |
3971 | * as the conn argument must resolve into an object of type (struct rx | |
3972 | * connection *). An instance of the rx SecurityObjectOf() macro itself | |
3973 | * resolves into an object of type (struct rx securityClass *). | |
3974 | * | |
3975 | * \subsection sec5-5-2 Section 5.5.2: Boolean Operations | |
3976 | * | |
3977 | * \par | |
3978 | * The macros described in this section all return Boolean values. They are | |
3979 | * used to query such things as the whether a connection is a server-side or | |
3980 | * client-side one and if extra levels of checksumming are being used in Rx | |
3981 | * packet headers. | |
3982 | * | |
3983 | * \subsubsection sec5-5-2-1 Section 5.5.2.1: rx IsServerConn() | |
3984 | * | |
3985 | * \par | |
3986 | * \#define rx_IsServerConn(conn) ((conn)->type == RX_SERVER_CONNECTION) | |
3987 | * \par | |
3988 | * Determine whether or not the Rx connection specified by the conn argument is | |
3989 | * a server-side connection. The value supplied for conn must resolve to an | |
3990 | * object of type struct rx connection. The result is determined by testing | |
3991 | * whether or not the connection's type field is set to RX SERVER CONNECTION. | |
3992 | * \note Another macro, rx ServerConn(), performs the identical operation. | |
3993 | * | |
3994 | * \subsubsection sec5-5-2-2 Section 5.5.2.2: rx IsClientConn() | |
3995 | * | |
3996 | * \par | |
3997 | * \#define rx_IsClientConn(conn) ((conn)->type == RX_CLIENT_CONNECTION) | |
3998 | * \par | |
3999 | * Determine whether or not the Rx connection specified by the conn argument is | |
4000 | * a client-side connection. The value supplied for conn must resolve to an | |
4001 | * object of type struct rx connection. The result is determined by testing | |
4002 | * whether or not the connection's type field is set to RX CLIENT CONNECTION. | |
4003 | * \note Another macro, rx ClientConn(), performs the identical operation. | |
4004 | * | |
4005 | * \subsubsection sec5-5-2-3 Section 5.5.2.2: rx IsUsingPktCksum() | |
4006 | * | |
4007 | * \par | |
4008 | * \#define rx_IsUsingPktCksum(conn) ((conn)->flags & | |
4009 | * RX_CONN_USING_PACKET_CKSUM) | |
4010 | * \par | |
4011 | * Determine whether or not the Rx connection specified by the conn argument is | |
4012 | * checksum-ming the headers of all packets on its calls. The value supplied | |
4013 | * for conn must resolve to an object of type struct rx connection. The result | |
4014 | * is determined by testing whether or not the connection's flags field has the | |
4015 | * RX CONN USING PACKET CKSUM bit enabled. | |
4016 | * | |
4017 | * \subsection sec5-5-3 Section 5.5.3: Service Attributes | |
4018 | * | |
4019 | * \par | |
4020 | * This section describes user-callable macros that manipulate the attributes | |
4021 | * of an Rx service. Note that these macros must be called (and hence their | |
4022 | * operations performed) before the given service is installed via the | |
4023 | * appropriate invocation of the associated rx StartServer() function. | |
4024 | * | |
4025 | * \subsubsection sec5-5-3-1 Section 5.5.3.1: rx SetStackSize() | |
4026 | * | |
4027 | * \par | |
4028 | * rx_stackSize = (((stackSize) stackSize) > rx_stackSize) ? stackSize : | |
4029 | * rx_stackSize) | |
4030 | * \par | |
4031 | * Inform the Rx facility of the stack size in bytes for a class of threads to | |
4032 | * be created in support of Rx services. The exported rx stackSize variable | |
4033 | * tracks the high-water mark for all stack size requests before the call to rx | |
4034 | * StartServer(). If no calls to rx SetStackSize() are made, then rx stackSize | |
4035 | * will retain its default setting of RX DEFAULT STACK SIZE. | |
4036 | * \par | |
4037 | * In this macro, the first argument is not used. It was originally intended | |
4038 | * that thread stack sizes would be settable on a per-service basis. However, | |
4039 | * calls to rx SetStackSize() will ignore the service parameter and set the | |
4040 | * high-water mark for all Rx threads created after the use of rx | |
4041 | * SetStackSize(). The second argument, stackSize, specifies determines the new | |
4042 | * stack size, and should resolve to an object of type int. The value placed in | |
4043 | * the stackSize parameter will not be recorded in the global rx stackSize | |
4044 | * variable unless it is greater than the variable's current setting. | |
4045 | * \par | |
4046 | * An instance of the rx SetStackSize() macro itself resolves into the result | |
4047 | * of the assignment, which is an object of type int. | |
4048 | * | |
4049 | * \subsubsection sec5-5-3-2 Section 5.5.3.2: rx SetMinProcs() | |
4050 | * | |
4051 | * \par | |
4052 | * \#define rx_SetMinProcs(service, min) ((service)->minProcs = (min)) | |
4053 | * \par | |
4054 | * Choose min as the minimum number of threads guaranteed to be available for | |
4055 | * parallel execution of the given Rx service. The service parameter should | |
4056 | * resolve to an object of type struct rx service. The min parameter should | |
4057 | * resolve to an object of type short. An instance of the rx SetMinProcs() | |
4058 | * macro itself resolves into the result of the assignment, which is an object | |
4059 | * of type short. | |
4060 | * | |
4061 | * \subsubsection sec5-5-3-3 Section 5.5.3.3: rx SetMaxProcs() | |
4062 | * | |
4063 | * \par | |
4064 | * \#define rx_SetMaxProcs(service, max) ((service)->maxProcs = (max)) | |
4065 | * \par | |
4066 | * Limit the maximum number of threads that may be made available to the given | |
4067 | * Rx service for parallel execution to be max. The service parameter should | |
4068 | * resolve to an object of type struct rx service. The max parameter should | |
4069 | * resolve to an object of type short. An instance of the rx SetMaxProcs() | |
4070 | * macro itself resolves into the result of the assignment, which is an object | |
4071 | * of type short. | |
4072 | * | |
4073 | * \subsubsection sec5-5-3-4 Section 5.5.3.4: rx SetIdleDeadTime() | |
4074 | * | |
4075 | * \par | |
4076 | * \#define rx_SetIdleDeadTime(service, time) ((service)->idleDeadTime = | |
4077 | * (time)) | |
4078 | * \par | |
4079 | * Every Rx service has a maximum amount of time it is willing to have its | |
4080 | * active calls sit idle (i.e., no new data is read or written for a call | |
4081 | * marked as RX STATE ACTIVE) before unilaterally shutting down the call. The | |
4082 | * expired call will have its error field set to RX CALL TIMEOUT. The operative | |
4083 | * assumption in this situation is that the client code is exhibiting a | |
4084 | * protocol error that prevents progress from being made on this call, and thus | |
4085 | * the call's resources on the server side should be freed. The default value, | |
4086 | * as recorded in the service's idleDeadTime field, is set at service creation | |
4087 | * time to be 60 seconds. The rx SetIdleTime() macro allows a caller to | |
4088 | * dynamically set this idle call timeout value. | |
4089 | * \par | |
4090 | * The service parameter should resolve to an object of type struct rx service. | |
4091 | * Also, the time parameter should resolve to an object of type short. finally, | |
4092 | * an instance of the rx SetIdleDeadTime() macro itself resolves into the | |
4093 | * result of the assignment, which is an object of type short. | |
4094 | * | |
4095 | * \subsubsection sec5-5-3-5 Section 5.5.3.5: rx SetServiceDeadTime() | |
4096 | * | |
4097 | * \par | |
4098 | * \#define rx_SetServiceDeadTime(service, seconds) | |
4099 | * ((service)->secondsUntilDead = (seconds)) | |
4100 | * \note This macro definition is obsolete and should NOT be used. Including it | |
4101 | * in application code will generate a compile-time error, since the service | |
4102 | * structure no longer has such a field defined. | |
4103 | * \par | |
4104 | * See the description of the rx SetConnDeadTime() macro below to see how hard | |
4105 | * timeouts may be set for situations of complete call inactivity. | |
4106 | * | |
4107 | * \subsubsection sec5-5-3-6 Section 5.5.3.6: rx SetRxDeadTime() | |
4108 | * | |
4109 | * \par | |
4110 | * \#define rx_SetRxDeadTime(seconds) (rx_connDeadTime = (seconds)) | |
4111 | * \par | |
4112 | * Inform the Rx facility of the maximum number of seconds of complete | |
4113 | * inactivity that will be tolerated on an active call. The exported rx | |
4114 | * connDeadTime variable tracks this value, and is initialized to a value of 12 | |
4115 | * seconds. The current value of rx connDeadTime will be copied into new Rx | |
4116 | * service and connection records upon their creation. | |
4117 | * \par | |
4118 | * The seconds argument determines the value of rx connDeadTime, and should | |
4119 | * resolve to an object of type int. An instance of the rx SetRxDeadTime() | |
4120 | * macro itself resolves into the result of the assignment, which is an object | |
4121 | * of type int. | |
4122 | * | |
4123 | * \subsubsection sec5-5-3-7 Section 5.5.3.7: rx SetConnDeadTime() | |
4124 | * | |
4125 | * \par | |
4126 | * \#define rx_SetConnDeadTime(conn, seconds) (rxi_SetConnDeadTime(conn, | |
4127 | * seconds)) | |
4128 | * \par | |
4129 | * Every Rx connection has a maximum amount of time it is willing to have its | |
4130 | * active calls on a server connection sit without receiving packets of any | |
4131 | * kind from its peer. After such a quiescent time, during which neither data | |
4132 | * packets (regardless of whether they are properly sequenced or duplicates) | |
4133 | * nor keep-alive packets are received, the call's error field is set to RX | |
4134 | * CALL DEAD and the call is terminated. The operative assumption in this | |
4135 | * situation is that the client making the call has perished, and thus the | |
4136 | * call's resources on the server side should be freed. The default value, as | |
4137 | * recorded in the connection's secondsUntilDead field, is set at connection | |
4138 | * creation time to be the same as its parent service. The rx SetConnDeadTime() | |
4139 | * macro allows a caller to dynamically set this timeout value. | |
4140 | * \par | |
4141 | * The conn parameter should resolve to an object of type struct rx connection. | |
4142 | * Also, the seconds parameter should resolve to an object of type int. | |
4143 | * finally, an instance of the rx SetConnDeadTime() macro itself resolves into | |
4144 | * the a call to rxi SetConnDeadTime(), whose return value is void. | |
4145 | * | |
4146 | * \subsubsection sec5-5-3-8 Section 5.5.3.8: rx SetConnHardDeadTime() | |
4147 | * | |
4148 | * \par | |
4149 | * \#define rx_SetConnHardDeadTime(conn, seconds) ((conn)->hardDeadTime = | |
4150 | * (seconds)) | |
4151 | * \par | |
4152 | * It is convenient to be able to specify that calls on certain Rx connections | |
4153 | * have a hard absolute timeout. This guards against protocol errors not caught | |
4154 | * by other checks in which one or both of the client and server are looping. | |
4155 | * The rx SetConnHardDeadTime() macro is available for this purpose. It will | |
4156 | * limit calls on the connection identified by the conn parameter to execution | |
4157 | * times of no more than the given number of seconds. By default, active calls | |
4158 | * on an Rx connection may proceed for an unbounded time, as long as they are | |
4159 | * not totally quiescent (see Section 5.5.3.7 for a description of the rx | |
4160 | * SetConnDeadTime()) or idle (see Section 5.5.3.4 for a description of the rx | |
4161 | * SetIdleDeadTime()). | |
4162 | * \par | |
4163 | * The conn parameter should resolve to an object of type (struct rx connection | |
4164 | * *). The seconds parameter should resolve to an object of type u short. An | |
4165 | * instance of the rx SetConnHardDeadTime() macro itself resolves into the | |
4166 | * result of the assignment, which is an object of type u short. | |
4167 | * | |
4168 | * \subsubsection sec5-5-3-9 Section 5.5.3.9: rx GetBeforeProc() | |
4169 | * | |
4170 | * \par | |
4171 | * \#define rx_GetBeforeProc(service) ((service)->beforeProc) | |
4172 | * \par | |
4173 | * Return a pointer of type (VOID *)() to the procedure associated with the | |
4174 | * given Rx service that will be called immediately upon activation of a server | |
4175 | * thread to handle an incoming call. The service parameter should resolve to | |
4176 | * an object of type struct rx service. | |
4177 | * \par | |
4178 | * When an Rx service is first created (via a call to the rx NewService() | |
4179 | * function), its beforeProc field is set to a null pointer. See the | |
4180 | * description of the rx SetBeforeProc() below. | |
4181 | * | |
4182 | * \subsubsection sec5-5-3-10 Section 5.5.3.10: rx SetBeforeProc() | |
4183 | * | |
4184 | * \par | |
4185 | * \#define rx_SetBeforeProc(service, proc) ((service)->beforeProc = (proc)) | |
4186 | * \par | |
4187 | * Instruct the Rx facility to call the procedure identified by the proc | |
4188 | * parameter immediately upon activation of a server thread to handle an | |
4189 | * incoming call. The specified procedure will be called with a single | |
4190 | * parameter, a pointer of type struct rx call, identifying the call this | |
4191 | * thread will now be responsible for handling. The value returned by the | |
4192 | * procedure, if any, is discarded. | |
4193 | * \par | |
4194 | * The service parameter should resolve to an object of type struct rx service. | |
4195 | * The proc parameter should resolve to an object of type (VOID *)(). An | |
4196 | * instance of the rx SetBeforeProc() macro itself resolves into the result of | |
4197 | * the assignment, which is an object of type (VOID *)(). | |
4198 | * | |
4199 | * \subsubsection sec5-5-3-11 Section 5.5.3.11: rx GetAfterProc() | |
4200 | * | |
4201 | * \par | |
4202 | * \#define rx_GetAfterProc(service) ((service)->afterProc) | |
4203 | * \par | |
4204 | * Return a pointer of type (VOID *)() to the procedure associated with the | |
4205 | * given Rx service that will be called immediately upon completion of the | |
4206 | * particular Rx call for which a server thread was activated. The service | |
4207 | * parameter should resolve to an object of type struct rx service. | |
4208 | * \par | |
4209 | * When an Rx service is first created (via a call to the rx NewService() | |
4210 | * function), its afterProc field is set to a null pointer. See the description | |
4211 | * of the rx SetAfterProc() below. | |
4212 | * | |
4213 | * \subsubsection sec5-5-3-12 Section 5.5.3.12: rx SetAfterProc() | |
4214 | * | |
4215 | * \par | |
4216 | * \#define rx_SetAfterProc(service, proc) ((service)->afterProc = (proc)) | |
4217 | * \par | |
4218 | * Instruct the Rx facility to call the procedure identified by the proc | |
4219 | * parameter immediately upon completion of the particular Rx call for which a | |
4220 | * server thread was activated. The specified procedure will be called with a | |
4221 | * single parameter, a pointer of type struct rx call, identifying the call | |
4222 | * this thread just handled. The value returned by the procedure, if any, is | |
4223 | * discarded. | |
4224 | * \par | |
4225 | * The service parameter should resolve to an object of type struct rx service. | |
4226 | * The proc parameter should resolve to an object of type (VOID *)(). An | |
4227 | * instance of the rx SetAfterProc() macro itself resolves into the result of | |
4228 | * the assignment, which is an object of type (VOID *)(). | |
4229 | * | |
4230 | * \subsubsection sec5-5-3-13 Section 5.5.3.13: rx SetNewConnProc() | |
4231 | * | |
4232 | * \par | |
4233 | * \#define rx_SetNewConnProc(service, proc) ((service)->newConnProc = (proc)) | |
4234 | * \par | |
4235 | * Instruct the Rx facility to call the procedure identified by the proc | |
4236 | * parameter as the last step in the creation of a new Rx server-side | |
4237 | * connection for the given service. The specified procedure will be called | |
4238 | * with a single parameter, a pointer of type (struct rx connection *), | |
4239 | * identifying the connection structure that was just built. The value returned | |
4240 | * by the procedure, if any, is discarded. | |
4241 | * \par | |
4242 | * The service parameter should resolve to an object of type struct rx service. | |
4243 | * The proc parameter should resolve to an object of type (VOID *)(). An | |
4244 | * instance of the rx SetNewConnProc() macro itself resolves into the result of | |
4245 | * the assignment, which is an object of type (VOID *)(). | |
4246 | * \note There is no access counterpart defined for this macro, namely one that | |
4247 | * returns the current setting of a service's newConnProc. | |
4248 | * | |
4249 | * \subsubsection sec5-5-3-14 Section 5.5.3.14: rx SetDestroyConnProc() | |
4250 | * | |
4251 | * \par | |
4252 | * \#define rx_SetDestroyConnProc(service, proc) ((service)->destroyConnProc = | |
4253 | * (proc)) | |
4254 | * \par | |
4255 | * Instruct the Rx facility to call the procedure identified by the proc | |
4256 | * parameter just before a server connection associated with the given Rx | |
4257 | * service is destroyed. The specified procedure will be called with a single | |
4258 | * parameter, a pointer of type (struct rx connection *), identifying the | |
4259 | * connection about to be destroyed. The value returned by the procedure, if | |
4260 | * any, is discarded. | |
4261 | * \par | |
4262 | * The service parameter should resolve to an object of type struct rx service. | |
4263 | * The proc parameter should resolve to an object of type (VOID *)(). An | |
4264 | * instance of the rx SetDestroyConnProc() macro itself resolves into the | |
4265 | * result of the assignment, which is an object of type (VOID *)(). | |
4266 | * \note There is no access counterpart defined for this macro, namely one that | |
4267 | * returns the current setting of a service's destroyConnProc. | |
4268 | * | |
4269 | * \subsection sec5-5-4 Section 5.5.4: Security-Related Operations | |
4270 | * | |
4271 | * \par | |
4272 | * The following macros are callable by Rx security modules, and assist in | |
4273 | * getting and setting header and trailer lengths, setting actual packet size, | |
4274 | * and finding the beginning of the security header (or data). | |
4275 | * | |
4276 | * \subsubsection sec5-5-4-1 Section 5.5.4.1: rx GetSecurityHeaderSize() | |
4277 | * | |
4278 | * \par | |
4279 | * \#define rx_GetSecurityHeaderSize(conn) ((conn)->securityHeaderSize) | |
4280 | * \par | |
4281 | * Generate a reference to the field in an Rx connection structure that records | |
4282 | * the length in bytes of the associated security module's packet header data. | |
4283 | * \par | |
4284 | * The conn parameter should resolve to an object of type struct rx connection. | |
4285 | * An instance of the rx GetSecurityHeaderSize() macro itself resolves into an | |
4286 | * object of type u short. | |
4287 | * | |
4288 | * \subsubsection sec5-5-4-2 Section 5.5.4.2: rx SetSecurityHeaderSize() | |
4289 | * | |
4290 | * \par | |
4291 | * \#define rx_SetSecurityHeaderSize(conn, length) ((conn)->securityHeaderSize | |
4292 | * = (length)) | |
4293 | * \par | |
4294 | * Set the field in a connection structure that records the length in bytes of | |
4295 | * the associated security module's packet header data. | |
4296 | * \par | |
4297 | * The conn parameter should resolve to an object of type struct rx connection. | |
4298 | * The length parameter should resolve to an object of type u short. An | |
4299 | * instance of the rx SetSecurityHeaderSize() macro itself resolves into the | |
4300 | * result of the assignment, which is an object of type u short. | |
4301 | * | |
4302 | * \subsubsection sec5-5-4-3 Section 5.5.4.3: rx | |
4303 | * GetSecurityMaxTrailerSize() | |
4304 | * | |
4305 | * \par | |
4306 | * \#define rx_GetSecurityMaxTrailerSize(conn) ((conn)->securityMaxTrailerSize) | |
4307 | * \par | |
4308 | * Generate a reference to the field in an Rx connection structure that records | |
4309 | * the maximum length in bytes of the associated security module's packet | |
4310 | * trailer data. | |
4311 | * \par | |
4312 | * The conn parameter should resolve to an object of type struct rx connection. | |
4313 | * An instance of the rx GetSecurityMaxTrailerSize() macro itself resolves into | |
4314 | * an object of type u short. | |
4315 | * | |
4316 | * \subsubsection sec5-5-4-4 Section 5.5.4.4: rx | |
4317 | * SetSecurityMaxTrailerSize() | |
4318 | * | |
4319 | * \par | |
4320 | * \#define rx_SetSecurityMaxTrailerSize(conn, length) | |
4321 | * ((conn)->securityMaxTrailerSize = (length)) | |
4322 | * \par | |
4323 | * Set the field in a connection structure that records the maximum length in | |
4324 | * bytes of the associated security module's packet trailer data. | |
4325 | * \par | |
4326 | * The conn parameter should resolve to an object of type struct rx connection. | |
4327 | * The length parameter should resolve to an object of type u short. An | |
4328 | * instance of the rx SetSecurityHeaderSize() macro itself resolves into the | |
4329 | * result of the assignment, which is an object of type u short. | |
4330 | * | |
4331 | * \subsection sec5-5-5 Section 5.5.5: Sizing Operations | |
4332 | * | |
4333 | * \par | |
4334 | * The macros described in this section assist the application programmer in | |
4335 | * determining the sizes of the various Rx packet regions, as well as their | |
4336 | * placement within a packet buffer. | |
4337 | * | |
4338 | * \subsubsection sec5-5-5-1 Section 5.5.5.1: rx UserDataOf() | |
4339 | * | |
4340 | * \par | |
4341 | * \#define rx_UserDataOf(conn, packet) (((char *) (packet)->wire.data) + | |
4342 | * (conn)->securityHeaderSize) | |
4343 | * \par | |
4344 | * Generate a pointer to the beginning of the actual user data in the given Rx | |
4345 | * packet, that is associated with the connection described by the conn | |
4346 | * pointer. User data appears immediately after the packet's security header | |
4347 | * region, whose length is determined by the security module used by the | |
4348 | * connection. The conn parameter should resolve to an object of type struct rx | |
4349 | * connection. The packet parameter should resolve to an object of type struct | |
4350 | * rx packet. An instance of the rx UserDataOf() macro itself resolves into an | |
4351 | * object of type (char *). | |
4352 | * | |
4353 | * \subsubsection sec5-5-5-2 Section 5.5.5.2: rx MaxUserDataSize() | |
4354 | * | |
4355 | * \par | |
4356 | * \#define rx_MaxUserDataSize(conn) | |
4357 | * \n ((conn)->peer->packetSize | |
4358 | * \n -RX_HEADER_SIZE | |
4359 | * \n -(conn)->securityHeaderSize | |
4360 | * \n -(conn)->securityMaxTrailerSize) | |
4361 | * \par | |
4362 | * Return the maximum number of user data bytes that may be carried by a packet | |
4363 | * on the Rx connection described by the conn pointer. The overall packet size | |
4364 | * is reduced by the IP, UDP, and Rx headers, as well as the header and trailer | |
4365 | * areas required by the connection's security module. | |
4366 | * \par | |
4367 | * The conn parameter should resolve to an object of type struct rx connection. | |
4368 | * An instance of the rx MaxUserDataSize() macro itself resolves into the an | |
4369 | * object of type (u short). | |
4370 | * | |
4371 | * \subsection sec5-5-6 Section 5.5.6: Complex Operations | |
4372 | * | |
4373 | * \par | |
4374 | * Two Rx macros are designed to handle potentially complex operations, namely | |
4375 | * reading data from an active incoming call and writing data to an active | |
4376 | * outgoing call. Each call structure has an internal buffer that is used to | |
4377 | * collect and cache data traveling through the call. This buffer is used in | |
4378 | * conjunction with reading or writing to the actual Rx packets traveling on | |
4379 | * the wire in support of the call. The rx Read() and rx Write() macros allow | |
4380 | * their caller to simply manipulate the internal data buffer associated with | |
4381 | * the Rx call structures whenever possible, thus avoiding the overhead | |
4382 | * associated with a function call. When buffers are either filled or drained | |
4383 | * (depending on the direction of the data flow), these macros will then call | |
4384 | * functions to handle the more complex cases of generating or receiving | |
4385 | * packets in support of the operation. | |
4386 | * | |
4387 | * \subsubsection sec5-5-6-1 Section 5.5.6.1: rx Read() | |
4388 | * | |
4389 | * \par | |
4390 | * \#define rx_Read(call, buf, nbytes) | |
4391 | * \n ((call)->nLeft > (nbytes) ? | |
4392 | * \n bcopy((call)->bufPtr, (buf), (nbytes)), | |
4393 | * \n (call)->nLeft -= (nbytes), (call)->bufPtr += (nbytes), (nbytes) | |
4394 | * \n : rx_ReadProc((call), (buf), (nbytes))) | |
4395 | * \par | |
4396 | * Read nbytes of data from the given Rx call into the buffer to which buf | |
4397 | * points. If the call's internal buffer has at least nbytes bytes already | |
4398 | * filled, then this is done in-line with a copy and some pointer and counter | |
4399 | * updates within the call structure. If the call's internal buffer doesn't | |
4400 | * have enough data to satisfy the request, then the rx ReadProc() function | |
4401 | * will handle this more complex situation. | |
4402 | * \par | |
4403 | * In either case, the rx Read() macro returns the number of bytes actually | |
4404 | * read from the call, resolving to an object of type int. If rx Read() returns | |
4405 | * fewer than nbytes bytes, the call status should be checked via the rx | |
4406 | * Error() macro. | |
4407 | * | |
4408 | * \subsubsection sec5-5-6-2 Section 5.5.6.2: rx Write() | |
4409 | * | |
4410 | * \par | |
4411 | * \#define rx_Write(call, buf, nbytes) | |
4412 | * \n ((call)->nFree > (nbytes) ? | |
4413 | * \n bcopy((buf), (call)->bufPtr, (nbytes)), | |
4414 | * \n (call)->nFree -= (nbytes), | |
4415 | * \n (call)->bufPtr += (nbytes), (nbytes) | |
4416 | * \n : rx_WriteProc((call), (buf), (nbytes))) | |
4417 | * \par | |
4418 | * Write nbytes of data from the buffer pointed to by buf into the given Rx | |
4419 | * call. If the call's internal buffer has at least nbytes bytes free, then | |
4420 | * this is done in-line with a copy and some pointer and counter updates within | |
4421 | * the call structure. If the call's internal buffer doesn't have room, then | |
4422 | * the rx WriteProc() function will handle this more complex situation. | |
4423 | * \par | |
4424 | * In either case, the rx Write() macro returns the number of bytes actually | |
4425 | * written to the call, resolving to an object of type int. If zero is | |
4426 | * returned, the call status should be checked via the rx Error() macro. | |
4427 | * | |
4428 | * \subsection sec5-5-7 Section 5.5.7: Security Operation Invocations | |
4429 | * | |
4430 | * \par | |
4431 | * Every Rx security module is required to implement an identically-named set | |
4432 | * of operations, through which the security mechanism it defines is invoked. | |
4433 | * This characteristic interface is reminiscent of the vnode interface defined | |
4434 | * and popularized for file systems by Sun Microsystems [4]. The structure | |
4435 | * defining this function array is described in Section 5.3.1.1. | |
4436 | * \par | |
4437 | * These security operations are part of the struct rx securityClass, which | |
4438 | * keeps not only the ops array itself but also any private data they require | |
4439 | * and a reference count. Every Rx service contains an array of these security | |
4440 | * class objects, specifying the range of security mechanisms it is capable of | |
4441 | * enforcing. Every Rx connection within a service is associated with exactly | |
4442 | * one of that service's security objects, and every call issued on the | |
4443 | * connection will execute the given security protocol. | |
4444 | * \par | |
4445 | * The macros described below facilitate the execution of the security module | |
4446 | * interface functions. They are covered in the same order they appear in the | |
4447 | * struct rx securityOps declaration. | |
4448 | * | |
4449 | * \subsubsection sec5-5-7-1 Section 5.5.7.1: RXS OP() | |
4450 | * | |
4451 | * \code | |
4452 | * #if defined(__STDC__) && !defined(__HIGHC__) | |
4453 | * #define RXS_OP(obj, op, args) | |
4454 | * ((obj->ops->op_ ## op) ? (*(obj)->ops->op_ ## op)args : 0) | |
4455 | * #else | |
4456 | * #define RXS_OP(obj, op, args) | |
4457 | * ((obj->ops->op_op) ? (*(obj)->ops->op_op)args : 0) | |
4458 | * #endif | |
4459 | * \endcode | |
4460 | * | |
4461 | * \par | |
4462 | * The RXS OP macro represents the workhorse macro in this group, used by all | |
4463 | * the others. It takes three arguments, the first of which is a pointer to the | |
4464 | * security object to be referenced. This obj parameter must resolve to an | |
4465 | * object of type (struct rx securityOps *). The second parameter identifies | |
4466 | * the specific op to be performed on this security object. The actual text of | |
4467 | * this op argument is used to name the desired opcode function. The third and | |
4468 | * final argument, args, specifies the text of the argument list to be fed to | |
4469 | * the chosen security function. Note that this argument must contain the | |
4470 | * bracketing parentheses for the function call's arguments. In fact, note that | |
4471 | * each of the security function access macros defined below provides the | |
4472 | * enclosing parentheses to this third RXS OP() macro. | |
4473 | * | |
4474 | * \subsubsection sec5-5-7-2 Section 5.5.7.1: RXS Close() | |
4475 | * | |
4476 | * \par | |
4477 | * \#define RXS_Close(obj) RXS_OP(obj, Close, (obj)) | |
4478 | * \par | |
4479 | * This macro causes the execution of the interface routine occupying the op | |
4480 | * Close() slot in the Rx security object identified by the obj pointer. This | |
4481 | * interface function is invoked by Rx immediately before a security object is | |
4482 | * discarded. Among the responsibilities of such a function might be | |
4483 | * decrementing the object's refCount field, and thus perhaps freeing up any | |
4484 | * space contained within the security object's private storage region, | |
4485 | * referenced by the object's privateData field. | |
4486 | * \par | |
4487 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4488 | * *). In generating a call to the security object's op Close() routine, the | |
4489 | * obj pointer is used as its single parameter. An invocation of the RXS | |
4490 | * Close() macro results in a return value identical to that of the op Close() | |
4491 | * routine, namely a value of type int. | |
4492 | * | |
4493 | * \subsubsection sec5-5-7-3 Section 5.5.7.3: RXS NewConnection() | |
4494 | * | |
4495 | * \par | |
4496 | * \#define RXS_NewConnection(obj, conn) RXS_OP(obj, NewConnection, (obj, | |
4497 | * conn)) | |
4498 | * \par | |
4499 | * This macro causes the execution of the interface routine in the op | |
4500 | * NewConnection() slot in the Rx security object identified by the obj | |
4501 | * pointer. This interface function is invoked by Rx immediately after a | |
4502 | * connection using the given security object is created. Among the | |
4503 | * responsibilities of such a function might be incrementing the object's | |
4504 | * refCount field, and setting any per-connection information based on the | |
4505 | * associated security object's private storage region, as referenced by the | |
4506 | * object's privateData field. | |
4507 | * \par | |
4508 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4509 | * *). The conn argument contains a pointer to the newly-created connection | |
4510 | * structure, and must resolve into an object of type (struct rx connection *). | |
4511 | * \par | |
4512 | * In generating a call to the routine located at the security object's op | |
4513 | * NewConnection() slot, the obj and conn pointers are used as its two | |
4514 | * parameters. An invocation of the RXS NewConnection() macro results in a | |
4515 | * return value identical to that of the op NewConnection() routine, namely a | |
4516 | * value of type int. | |
4517 | * | |
4518 | * \subsubsection sec5-5-7-4 Section 5.5.7.4: RXS PreparePacket() | |
4519 | * | |
4520 | * \par | |
4521 | * \#define RXS_PreparePacket(obj, call, packet) | |
4522 | * \n RXS_OP(obj, PreparePacket, (obj, call, packet)) | |
4523 | * \par | |
4524 | * This macro causes the execution of the interface routine in the op | |
4525 | * PreparePacket() slot in the Rx security object identified by the obj | |
4526 | * pointer. This interface function is invoked by Rx each time it prepares an | |
4527 | * outward-bound packet. Among the responsibilities of such a function might be | |
4528 | * computing information to put into the packet's security header and/or | |
4529 | * trailer. | |
4530 | * \par | |
4531 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4532 | * *). The call argument contains a pointer to the Rx call to which the given | |
4533 | * packet belongs, and must resolve to an object of type (struct rx call *). | |
4534 | * The final argument, packet, contains a pointer to the packet itself. It | |
4535 | * should resolve to an object of type (struct rx packet *). | |
4536 | * \par | |
4537 | * In generating a call to the routine located at the security object's op | |
4538 | * PreparePacket() slot, the obj, call, and packet pointers are used as its | |
4539 | * three parameters. An invocation of the RXS PreparePacket() macro results in | |
4540 | * a return value identical to that of the op PreparePacket() routine, namely a | |
4541 | * value of type int. | |
4542 | * | |
4543 | * \subsubsection sec5-5-7-5 Section 5.5.7.5: RXS SendPacket() | |
4544 | * | |
4545 | * \par | |
4546 | * \#define RXS_SendPacket(obj, call, packet) RXS_OP(obj, SendPacket, (obj, | |
4547 | * call, packet)) | |
4548 | * \par | |
4549 | * This macro causes the execution of the interface routine occupying the op | |
4550 | * SendPacket() slot in the Rx security object identified by the obj pointer. | |
4551 | * This interface function is invoked by Rx each time it physically transmits | |
4552 | * an outward-bound packet. Among the responsibilities of such a function might | |
4553 | * be recomputing information in the packet's security header and/or trailer. | |
4554 | * \par | |
4555 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4556 | * *). The call argument contains a pointer to the Rx call to which the given | |
4557 | * packet belongs, and must resolve to an object of type (struct rx call *). | |
4558 | * The final argument, packet, contains a pointer to the packet itself. It | |
4559 | * should resolve to an object of type (struct rx packet *). | |
4560 | * \par | |
4561 | * In generating a call to the routine located at the security object's op | |
4562 | * SendPacket() slot, the obj, call, and packet pointers are used as its three | |
4563 | * parameters. An invocation of the RXS SendPacket() macro results in a return | |
4564 | * value identical to that of the op SendPacket() routine, namely a value of | |
4565 | * type int. | |
4566 | * | |
4567 | * \subsubsection sec5-5-7-6 Section 5.5.7.6: RXS CheckAuthentication() | |
4568 | * | |
4569 | * \par | |
4570 | * \#define RXS_CheckAuthentication(obj, conn) RXS_OP(obj, CheckAuthentication, | |
4571 | * (obj, conn)) | |
4572 | * \par | |
4573 | * This macro causes the execution of the interface routine in the op | |
4574 | * CheckAuthentication() slot in the Rx security object identified by the obj | |
4575 | * pointer. This interface function is invoked by Rx each time it needs to | |
4576 | * check whether the given connection is one on which authenticated calls are | |
4577 | * being performed. Specifically, a value of 0 is returned if authenticated | |
4578 | * calls are not being executed on this connection, and a value of 1 is | |
4579 | * returned if they are. | |
4580 | * \par | |
4581 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4582 | * *). The conn argument contains a pointer to the Rx connection checked as to | |
4583 | * whether authentication is being performed, and must resolve to an object of | |
4584 | * type (struct rx connection *). | |
4585 | * \par | |
4586 | * In generating a call to the routine in the security object's op | |
4587 | * CheckAuthentication() slot, the obj and conn pointers are used as its two | |
4588 | * parameters. An invocation of the RXS CheckAuthentication() macro results in | |
4589 | * a return value identical to that of the op CheckAuthentication() routine, | |
4590 | * namely a value of type int. | |
4591 | * | |
4592 | * \subsubsection sec5-5-7-7 Section 5.5.7.7: RXS CreateChallenge() | |
4593 | * | |
4594 | * \par | |
4595 | * \#define RXS_CreateChallenge(obj, conn) RXS_OP(obj, CreateChallenge, (obj, | |
4596 | * conn)) | |
4597 | * \par | |
4598 | * This macro causes the execution of the interface routine in the op | |
4599 | * CreateChallenge() slot in the Rx security object identified by the obj | |
4600 | * pointer. This interface function is invoked by Rx each time a challenge | |
4601 | * event is constructed for a given connection. Among the responsibilities of | |
4602 | * such a function might be marking the connection as temporarily | |
4603 | * unauthenticated until the given challenge is successfully met. | |
4604 | * \par | |
4605 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4606 | * *). The conn argument contains a pointer to the Rx connection for which the | |
4607 | * authentication challenge is being constructed, and must resolve to an object | |
4608 | * of type (struct rx connection *). | |
4609 | * \par | |
4610 | * In generating a call to the routine located at the security object's op | |
4611 | * CreateChallenge() slot, the obj and conn pointers are used as its two | |
4612 | * parameters. An invocation of the RXS CreateChallenge() macro results in a | |
4613 | * return value identical to that of the op CreateChallenge() routine, namely a | |
4614 | * value of type int. | |
4615 | * | |
4616 | * \subsubsection sec5-5-7-8 Section 5.5.7.8: RXS GetChallenge() | |
4617 | * | |
4618 | * \par | |
4619 | * \#define RXS_GetChallenge(obj, conn, packet) RXS_OP(obj, GetChallenge, (obj, | |
4620 | * conn, packet)) | |
4621 | * \par | |
4622 | * This macro causes the execution of the interface routine occupying the op | |
4623 | * GetChallenge() slot in the Rx security object identified by the obj pointer. | |
4624 | * This interface function is invoked by Rx each time a challenge packet is | |
4625 | * constructed for a given connection. Among the responsibilities of such a | |
4626 | * function might be constructing the appropriate challenge structures in the | |
4627 | * area of packet dedicated to security matters. | |
4628 | * \par | |
4629 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4630 | * *). The conn argument contains a pointer to the Rx connection to which the | |
4631 | * given challenge packet belongs, and must resolve to an object of type | |
4632 | * (struct rx connection *). The final argument, packet, contains a pointer to | |
4633 | * the challenge packet itself. It should resolve to an object of type (struct | |
4634 | * rx packet *). | |
4635 | * \par | |
4636 | * In generating a call to the routine located at the security object's op | |
4637 | * GetChallenge() slot, the obj, conn, and packet pointers are used as its | |
4638 | * three parameters. An invocation of the RXS GetChallenge() macro results in a | |
4639 | * return value identical to that of the op GetChallenge() routine, namely a | |
4640 | * value of type int. | |
4641 | * | |
4642 | * \subsubsection sec5-5-7-9 Section 5.5.7.9: RXS GetResponse() | |
4643 | * | |
4644 | * \par | |
4645 | * \#define RXS_GetResponse(obj, conn, packet) RXS_OP(obj, GetResponse, (obj, | |
4646 | * conn, packet)) | |
4647 | * \par | |
4648 | * This macro causes the execution of the interface routine occupying the op | |
4649 | * GetResponse() slot in the Rx security object identified by the obj pointer. | |
4650 | * This interface function is invoked by Rx on the server side each time a | |
4651 | * response to a challenge packet must be received. | |
4652 | * \par | |
4653 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4654 | * *). The conn argument contains a pointer to the Rx client connection that | |
4655 | * must respond to the authentication challenge, and must resolve to a (struct | |
4656 | * rx connection *) object. The final argument, packet, contains a pointer to | |
4657 | * the packet to be built in response to the challenge. It should resolve to an | |
4658 | * object of type (struct rx packet *). | |
4659 | * \par | |
4660 | * In generating a call to the routine located at the security object's op | |
4661 | * GetResponse() slot, the obj, conn, and packet pointers are used as its three | |
4662 | * parameters. An invocation of the RXS GetResponse() macro results in a return | |
4663 | * value identical to that of the op GetResponse() routine, namely a value of | |
4664 | * type int. | |
4665 | * | |
4666 | * \subsubsection sec5-5-7-10 Section 5.5.7.10: RXS CheckResponse() | |
4667 | * | |
4668 | * \par | |
4669 | * \#define RXS_CheckResponse(obj, conn, packet) RXS_OP(obj, CheckResponse, | |
4670 | * (obj, conn, packet)) | |
4671 | * \par | |
4672 | * This macro causes the execution of the interface routine in the op | |
4673 | * CheckResponse() slot in the Rx security object identified by the obj | |
4674 | * pointer. This interface function is invoked by Rx on the server side each | |
4675 | * time a response to a challenge packet is received for a given connection. | |
4676 | * The responsibilities of such a function might include verifying the | |
4677 | * integrity of the response, pulling out the necessary security information | |
4678 | * and storing that information within the affected connection, and otherwise | |
4679 | * updating the state of the connection. | |
4680 | * \par | |
4681 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4682 | * *). The conn argument contains a pointer to the Rx server connection to | |
4683 | * which the given challenge response is directed. This argument must resolve | |
4684 | * to an object of type (struct rx connection *). The final argument, packet, | |
4685 | * contains a pointer to the packet received in response to the challenge | |
4686 | * itself. It should resolve to an object of type (struct rx packet *). | |
4687 | * \par | |
4688 | * In generating a call to the routine located at the security object's op | |
4689 | * CheckResponse() slot, the obj, conn, and packet pointers are ued as its | |
4690 | * three parameters. An invocation of the RXS CheckResponse() macro results in | |
4691 | * a return value identical to that of the op CheckResponse() routine, namely a | |
4692 | * value of type int. | |
4693 | * | |
4694 | * \subsubsection sec5-5-7-11 Section 5.5.7.11: RXS CheckPacket() | |
4695 | * | |
4696 | * \par | |
4697 | * \#define RXS_CheckPacket(obj, call, packet) RXS_OP(obj, CheckPacket, (obj, | |
4698 | * call, packet)) | |
4699 | * \par | |
4700 | * This macro causes the execution of the interface routine occupying the op | |
4701 | * CheckPacket() slot in the Rx security object identified by the obj pointer. | |
4702 | * This interface function is invoked by Rx each time a packet is received. The | |
4703 | * responsibilities of such a function might include verifying the integrity of | |
4704 | * given packet, detecting any unauthorized modifications or tampering. | |
4705 | * \par | |
4706 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4707 | * *). The conn argument contains a pointer to the Rx connection to which the | |
4708 | * given challenge response is directed, and must resolve to an object of type | |
4709 | * (struct rx connection *). The final argument, packet, contains a pointer to | |
4710 | * the packet received in response to the challenge itself. It should resolve | |
4711 | * to an object of type (struct rx packet *). | |
4712 | * \par | |
4713 | * In generating a call to the routine located at the security object's op | |
4714 | * CheckPacket() slot, the obj, conn, and packet pointers are used as its three | |
4715 | * parameters. An invocation of the RXS CheckPacket() macro results in a return | |
4716 | * value identical to that of the op CheckPacket() routine, namely a value of | |
4717 | * type int. | |
4718 | * \par | |
4719 | * Please note that any non-zero return will cause Rx to abort all calls on the | |
4720 | * connection. Furthermore, the connection itself will be marked as being in | |
4721 | * error in such a case, causing it to reject any further incoming packets. | |
4722 | * | |
4723 | * \subsubsection sec5-5-7-12 Section 5.5.7.12: RXS DestroyConnection() | |
4724 | * | |
4725 | * \par | |
4726 | * \#define RXS_DestroyConnection(obj, conn) RXS_OP(obj, DestroyConnection, | |
4727 | * (obj, conn)) | |
4728 | * \par | |
4729 | * This macro causes the execution of the interface routine in the op | |
4730 | * DestroyConnection() slot in the Rx security object identified by the obj | |
4731 | * pointer. This interface function is invoked by Rx each time a connection | |
4732 | * employing the given security object is being destroyed. The responsibilities | |
4733 | * of such a function might include deleting any private data maintained by the | |
4734 | * security module for this connection. | |
4735 | * \par | |
4736 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4737 | * *). The conn argument contains a pointer to the Rx connection being reaped, | |
4738 | * and must resolve to a (struct rx connection *) object. | |
4739 | * \par | |
4740 | * In generating a call to the routine located at the security object's op | |
4741 | * DestroyConnection() slot, the obj and conn pointers are used as its two | |
4742 | * parameters. An invocation of the RXS DestroyConnection() macro results in a | |
4743 | * return value identical to that of the op DestroyConnection() routine, namely | |
4744 | * a value of type int. | |
4745 | * | |
4746 | * \subsubsection sec5-5-7-13 Section 5.5.7.13: RXS GetStats() | |
4747 | * | |
4748 | * \par | |
4749 | * \#define RXS_GetStats(obj, conn, stats) RXS_OP(obj, GetStats, (obj, conn, | |
4750 | * stats)) | |
4751 | * \par | |
4752 | * This macro causes the execution of the interface routine in the op | |
4753 | * GetStats() slot in the Rx security object identified by the obj pointer. | |
4754 | * This interface function is invoked by Rx each time current statistics | |
4755 | * concerning the given security object are desired. | |
4756 | * \par | |
4757 | * The obj parameter must resolve into an object of type (struct rx securityOps | |
4758 | * *). The conn argument contains a pointer to the Rx connection using the | |
4759 | * security object to be examined, and must resolve to an object of type | |
4760 | * (struct rx connection *). The final argument, stats, contains a pointer to a | |
4761 | * region to be filled with the desired statistics. It should resolve to an | |
4762 | * object of type (struct rx securityObjectStats *). | |
4763 | * \par | |
4764 | * In generating a call to the routine located at the security object's op | |
4765 | * GetStats() slot, the obj, conn, and stats pointers are used as its three | |
4766 | * parameters. An invocation of the RXS GetStats() macro results in a return | |
4767 | * value identical to that of the op GetStats() routine, namely a value of type | |
4768 | * int. | |
4769 | * | |
4770 | * \section sec5-6 Section 5.6: Functions | |
4771 | * | |
4772 | * \par | |
4773 | * Rx exports a collection of functions that, in conjuction with the macros | |
4774 | * explored in Section 5.5, allows its clients to set up and export services, | |
4775 | * create and tear down connections to these services, and execute remote | |
4776 | * procedure calls along these connections. | |
4777 | * \par | |
4778 | * This paper employs two basic categorizations of these Rx routines. One set | |
4779 | * of functions is meant to be called directly by clients of the facility, and | |
4780 | * are referred to as the exported operations. The individual members of the | |
4781 | * second set of functions are not meant to be called directly by Rx clients, | |
4782 | * but rather are called by the collection of defined macros, so they must | |
4783 | * still be lexically visible. These indirectly-executed routines are referred | |
4784 | * to here as the semi-exported operations. | |
4785 | * \par | |
4786 | * All Rx routines return zero upon success. The range of error codes employed | |
4787 | * by Rx is defined in Section 5.2.15. | |
4788 | * | |
4789 | * \subsection sec5-6-1 Section 5.6.1: Exported Operations | |
4790 | * | |
4791 | * \subsection sec5-6-2 Section 5.6.2: rx Init _ Initialize Rx | |
4792 | * | |
4793 | * \par | |
4794 | * int rx Init(IN int port) | |
4795 | * \par Description | |
4796 | * Initialize the Rx facility. If a non-zero port number is provided, it | |
4797 | * becomes the default port number for any service installed later. If 0 is | |
4798 | * provided for the port, a random port will be chosen by the system. The rx | |
4799 | * Init() function sets up internal tables and timers, along with starting up | |
4800 | * the listener thread. | |
4801 | * \par Error Codes | |
4802 | * RX ADDRINUSE The port provided has already been taken. | |
4803 | * | |
4804 | * \subsection sec5-6-3 Section 5.6.3: rx NewService _ Create and install | |
4805 | * a new service | |
4806 | * | |
4807 | * \par | |
4808 | * struct rx service *rx NewService(IN u short port; IN u short serviceId; IN | |
4809 | * char *serviceName; IN struct rx securityClass **securityObjects; IN int | |
4810 | * nSecurityObjects; IN long (*serviceProc)()) | |
4811 | * \par Description | |
4812 | * Create and advertise a new Rx service. A service is uniquely named by a UDP | |
4813 | * port number plus a non-zero 16-bit serviceId on the given host. The port | |
4814 | * argument may be set to zero if rx Init() was called with a non-zero port | |
4815 | * number, in which case that original port will be used. A serviceName must | |
4816 | * also be provided, to be used for identification purposes (e.g., the service | |
4817 | * name might be used for probing for statistics). A pointer to an array of | |
4818 | * nSecurityObjects security objects to be associated with the new service is | |
4819 | * given in . securityObjects. The service's executeRequestProc() pointer is | |
4820 | * set to serviceProc. | |
4821 | * \par | |
4822 | * The function returns a pointer to a descriptor for the requested Rx service. | |
4823 | * A null return value indicates that the new service could not be created. | |
4824 | * Possible reasons include: | |
4825 | * \li The serviceId parameter was found to be zero. | |
4826 | * \li A port value of zero was specified at Rx initialization time (i.e., when | |
4827 | * rx init() was called), requiring a non-zero value for the port parameter | |
4828 | * here. | |
4829 | * \li Another Rx service is already using serviceId. | |
4830 | * \li Rx has already created the maximum RX MAX SERVICES Rx services (see | |
4831 | * Section 5.2.1). | |
4832 | * \par Error Codes | |
4833 | * (struct rx service *) NULL The new Rx service could not be created, due to | |
4834 | * one of the errors listed above. | |
4835 | * | |
4836 | * \subsection sec5-6-4 Section 5.6.4: rx NewConnection _ Create a new | |
4837 | * connection to a given service | |
4838 | * | |
4839 | * \par | |
4840 | * struct rx connection *rx NewConnection( IN u long shost, IN u short sport, | |
4841 | * IN u short sservice, IN struct rx securityClass *securityObject, IN int | |
4842 | * service SecurityIndex) | |
4843 | * \par Description | |
4844 | * Create a new Rx client connection to service sservice on the host whose IP | |
4845 | * address is contained in shost and to that host's sport UDP port. The | |
4846 | * corresponding Rx service identifier is expected in sservice. The caller also | |
4847 | * provides a pointer to the security object to use for the connection in | |
4848 | * securityObject, along with that object's serviceSecurityIndex among the | |
4849 | * security objects associated with service sservice via a previous rx | |
4850 | * NewService() call (see Section 5.6.3). | |
4851 | * \note It is permissible to provide a null value for the securityObject | |
4852 | * parameter if the chosen serviceSecurityIndex is zero. This corresponds to | |
4853 | * the pre-defined null security object, which does not engage in authorization | |
4854 | * checking of any kind. | |
4855 | * \par Error Codes | |
4856 | * --- A pointer to an initialized Rx connection is always returned, unless osi | |
4857 | * Panic() is called due to memory allocation failure. | |
4858 | * | |
4859 | * \subsection sec5-6-5 Section 5.6.5: rx NewCall _ Start a new call on | |
4860 | * the given connection | |
4861 | * | |
4862 | * \par | |
4863 | * struct rx call *rx NewCall( IN struct rx connection *conn) | |
4864 | * \par Description | |
4865 | * Start a new Rx remote procedure call on the connection specified by the conn | |
4866 | * parameter. The existing call structures (up to RX MAXCALLS of them) are | |
4867 | * examined in order. The first non-active call encountered (i.e., either | |
4868 | * unused or whose call->state is RX STATE DALLY) will be appropriated and | |
4869 | * reset if necessary. If all call structures are in active use, the RX CONN | |
4870 | * MAKECALL WAITING flag is set in the conn->flags field, and the thread | |
4871 | * handling this request will sleep until a call structure comes free. Once a | |
4872 | * call structure has been reserved, the keep-alive protocol is enabled for it. | |
4873 | * \par | |
4874 | * The state of the given connection determines the detailed behavior of the | |
4875 | * function. The conn->timeout field specifies the absolute upper limit of the | |
4876 | * number of seconds this particular call may be in operation. After this time | |
4877 | * interval, calls to such routines as rx SendData() or rx ReadData() will fail | |
4878 | * with an RX CALL TIMEOUT indication. | |
4879 | * \par Error Codes | |
4880 | * --- A pointer to an initialized Rx call is always returned, unless osi | |
4881 | * Panic() is called due to memory allocation failure. | |
4882 | * | |
4883 | * \subsection sec5-6-6 Section 5.6.6: rx EndCall _ Terminate the given | |
4884 | * call | |
4885 | * | |
4886 | * \par | |
4887 | * int rx EndCall( | |
4888 | * \param IN struct rx call *call, | |
4889 | * \param IN long rc | |
4890 | * \n ) | |
4891 | * \par Description | |
4892 | * Indicate that the Rx call described by the structure located at call is | |
4893 | * finished, possibly prematurely. The value passed in the rc parameter is | |
4894 | * returned to the peer, if appropriate. The final error code from processing | |
4895 | * the call will be returned as rx EndCall()'s value. The given call's state | |
4896 | * will be set to RX STATE DALLY, and threads waiting to establish a new call | |
4897 | * on this connection are signalled (see the description of the rx NewCall() in | |
4898 | * Section 5.6.5). | |
4899 | * \par Error Codes | |
4900 | * -1 Unspecified error has occurred. | |
4901 | * | |
4902 | * \subsection sec5-6-7 Section 5.6.7: rx StartServer _ Activate installed | |
4903 | * rx service(s) | |
4904 | * | |
4905 | * \par | |
4906 | * void rx StartServer( IN int donateMe) | |
4907 | * \par Description | |
4908 | * This function starts server threads in support of the Rx services installed | |
4909 | * via calls to rx NewService() (see Section 5.6.3). This routine first | |
4910 | * computes the number of server threads it must create, governed by the | |
4911 | * minProcs and maxProcs fields in the installed service descriptors. The | |
4912 | * minProcs field specifies the minimum number of threads that are guaranteed | |
4913 | * to be concurrently available to the given service. The maxProcs field | |
4914 | * specifies the maximum number of threads that may ever be concurrently | |
4915 | * assigned to the particular service, if idle threads are available. Using | |
4916 | * this information, rx StartServer() computes the correct overall number of | |
4917 | * threads as follows: For each installed service, minProcs threads will be | |
4918 | * created, enforcing the minimality guarantee. Calculate the maximum | |
4919 | * difference between the maxProcs and minProcs fields for each service, and | |
4920 | * create this many additional server threads, enforcing the maximality | |
4921 | * guarantee. | |
4922 | * \par | |
4923 | * If the value placed in the donateMe argument is zero, then rx StartServer() | |
4924 | * will simply return after performing as described above. Otherwise, the | |
4925 | * thread making the rx StartServer() call will itself begin executing the | |
4926 | * server thread loop. In this case, the rx StartServer() call will never | |
4927 | * return. | |
4928 | * \par Error Codes | |
4929 | * ---None. | |
4930 | * | |
4931 | * \subsection sec5-6-8 Section 5.6.8: rx PrintStats -- Print basic | |
4932 | * statistics to a file | |
4933 | * | |
4934 | * \par | |
4935 | * void rx PrintStats( IN FILE *file) | |
4936 | * \par Description | |
4937 | * Prints Rx statistics (basically the contents of the struct rx stats holding | |
4938 | * the statistics for the Rx facility) to the open file descriptor identified | |
4939 | * by file. The output is ASCII text, and is intended for human consumption. | |
4940 | * \note This function is available only if the Rx package has been compiled | |
4941 | * with the RXDEBUG flag. | |
4942 | * \par Error Codes | |
4943 | * ---None. | |
4944 | * | |
4945 | * \subsection sec5-6-9 Section 5.6.9: rx PrintPeerStats _ Print peer | |
4946 | * statistics to a file | |
4947 | * \par | |
4948 | * void rx PrintPeerStats( IN FILE *file, IN struct rx peer *peer) | |
4949 | * \par Description | |
4950 | * Prints the Rx peer statistics found in peer to the open file descriptor | |
4951 | * identified by file. The output is in normal ASCII text, and is intended for | |
4952 | * human consumption. | |
4953 | * \note This function is available only if the Rx package has been compiled | |
4954 | * with the RXDEBUG flag. | |
4955 | * \par Error Codes | |
4956 | * ---None. | |
4957 | * | |
4958 | * \subsection sec5-6-10 Section 5.6.10: rx finalize _ Shut down Rx | |
4959 | * gracefully | |
4960 | * | |
4961 | * \par | |
4962 | * void rx finalize() | |
4963 | * \par Description | |
4964 | * This routine may be used to shut down the Rx facility for either server or | |
4965 | * client applications. All of the client connections will be gracefully | |
4966 | * garbage-collected after their active calls are cleaned up. The result of | |
4967 | * calling rx finalize() from a client program is that the server-side entity | |
4968 | * will be explicitly advised that the client has terminated. This notification | |
4969 | * frees the server-side application from having to probe the client until its | |
4970 | * records eventually time out, and also allows it to free resources currently | |
4971 | * assigned to that client's support. | |
4972 | * \par Error Codes | |
4973 | * ---None. | |
4974 | * | |
4975 | * \subsection sec5-6-11 Section 5.6.11: Semi-Exported Operations | |
4976 | * | |
4977 | * \par | |
4978 | * As described in the introductory text in Section 5.6, entries in this | |
4979 | * lexically-visible set of Rx functions are not meant to be called directly by | |
4980 | * client applications, but rather are invoked by Rx macros called by users. | |
4981 | * | |
4982 | * \subsection sec5-6-12 Section 5.6.12: rx WriteProc _ Write data to an | |
4983 | * outgoing call | |
4984 | * | |
4985 | * \par | |
4986 | * int rx WriteProc( IN struct rx call *call, IN char *buf, IN int nbytes) | |
4987 | * \par Description | |
4988 | * Write nbytes of data from buffer buf into the Rx call identified by the call | |
4989 | * parameter. The value returned by rx WriteProc() reports the number of bytes | |
4990 | * actually written into the call. If zero is returned, then the rx Error() | |
4991 | * macro may be used to obtain the call status. | |
4992 | * \par | |
4993 | * This routine is called by the rx Write() macro, which is why it must be | |
4994 | * exported by the Rx facility. | |
4995 | * \par Error Codes | |
4996 | * Indicates error in the given Rx call; use the rx Error() macro to determine | |
4997 | * the call status. | |
4998 | * | |
4999 | * \subsection sec5-6-13 Section 5.6.13: rx ReadProc _ Read data from an | |
5000 | * incoming call | |
5001 | * | |
5002 | * \par | |
5003 | * int rx ReadProc( IN struct rx call *call, IN char *buf, IN int nbytes) | |
5004 | * \par Description | |
5005 | * Read up to nbytes of data from the Rx call identified by the call parameter | |
5006 | * into the buf buffer. The value returned by rx ReadProc() reports the number | |
5007 | * of bytes actually read from the call. If zero is returned, then the rx | |
5008 | * Error() macro may be used to obtain the call status. | |
5009 | * \par | |
5010 | * This routine is called by the rx Read() macro, which is why it must be | |
5011 | * exported by the Rx facility. | |
5012 | * \par Error Codes | |
5013 | * Indicates error in the given Rx call; use the rx Error() macro to determine | |
5014 | * the call status. | |
5015 | * | |
5016 | * \subsection sec5-6-1 Section 5.6.1: rx FlushWrite -- Flush buffered | |
5017 | * data on outgoing call | |
5018 | * | |
5019 | * \par | |
5020 | * void rx FlushWrite( IN struct rx call *call) | |
5021 | * \par Description | |
5022 | * Flush any buffered data on the given Rx call to the stream. If the call is | |
5023 | * taking place on a server connection, the call->mode is set to RX MODE EOF. | |
5024 | * If the call is taking place on a client connection, the call->mode is set to | |
5025 | * RX MODE RECEIVING. | |
5026 | * \par Error Codes | |
5027 | * ---None. | |
5028 | * | |
5029 | * \subsection sec5-6-15 Section 5.6.15: rx SetArrivalProc _ Set function | |
5030 | * to invoke upon call packet arrival | |
5031 | * | |
5032 | * \par | |
5033 | * void rx SetArrivalProc( IN struct rx call *call, IN VOID (*proc)(), IN VOID | |
5034 | * *handle, IN VOID *arg) | |
5035 | * \par Description | |
5036 | * Establish a procedure to be called when a packet arrives for a call. This | |
5037 | * routine will be called at most once after each call, and will also be called | |
5038 | * if there is an error condition on the call or the call is complete. The rx | |
5039 | * SetArrivalProc() function is used by multicast Rx routines to build a | |
5040 | * selection function that determines which of several calls is likely to be a | |
5041 | * good one to read from. The implementor's comments in the Rx code state that, | |
5042 | * due to the current implementation, it is probably only reasonable to use rx | |
5043 | * SetArrivalProc() immediately after an rx NewCall(), and to only use it once. | |
5044 | * \par Error Codes | |
5045 | * ---None. | |
5046 | * | |
5047 | * \page chap6 Chapter 6 -- Example Server and Client | |
5048 | * | |
5049 | * \section sec6-1 Section 6.1: Introduction | |
5050 | * | |
5051 | * \par | |
5052 | * This chapter provides a sample program showing the use of Rx. Specifically, | |
5053 | * the rxdemo application, with all its support files, is documented and | |
5054 | * examined. The goal is to provide the reader with a fully-developed and | |
5055 | * operational program illustrating the use of both regular Rx remote procedure | |
5056 | * calls and streamed RPCs. The full text of the rxdemo application is | |
5057 | * reproduced in the sections below, along with additional commentary. | |
5058 | * \par | |
5059 | * Readers wishing to directly experiment with this example Rx application are | |
5060 | * encouraged to examine the on-line version of rxdemo. Since it is a program | |
5061 | * of general interest, it has been installed in the usr/contrib tree in the | |
5062 | * grand.central.org cell. This area contains user-contributed software for the | |
5063 | * entire AFS community. At the top of this tree is the | |
5064 | * /afs/grand.central.org/darpa/usr/contrib directory. Both the server-side and | |
5065 | * client-side rxdemo binaries (rxdemo server and rxdemo client, respectively) | |
5066 | * may be found in the bin subdirectory. The actual sources reside in the | |
5067 | * .site/grand.central.org/rxdemo/src subdirectory. | |
5068 | * \par | |
5069 | * The rxdemo code is composed of two classes of files, namely those written by | |
5070 | * a human programmer and those generated from the human-written code by the | |
5071 | * Rxgen tool. Included in the first group of files are: | |
5072 | * \li rxdemo.xg This is the RPC interface definition file, providing | |
5073 | * high-level definitions of the supported calls. | |
5074 | * \li rxdemo client.c: This is the rxdemo client program, calling upon the | |
5075 | * associated server to perform operations defined by rxdemo.xg. | |
5076 | * \li rxdemo server.c: This is the rxdemo server program, implementing the | |
5077 | * operations promised in rxdemo.xg. | |
5078 | * \li Makefile: This is the file that directs the compilation and | |
5079 | * installation of the rxdemo code. | |
5080 | * \par | |
5081 | * The class of automatically-generated files includes the following items: | |
5082 | * \li rxdemo.h: This header file contains the set of constant definitions | |
5083 | * present in rxdemo.xg, along with information on the RPC opcodes defined for | |
5084 | * this Rx service. | |
5085 | * \li rxdemo.cs.c: This client-side stub file performs all the marshalling and | |
5086 | * unmarshalling of the arguments for the RPC routines defined in rxdemo.xg. | |
5087 | * \li rxdemo.ss.c: This stub file similarly defines all the marshalling and | |
5088 | * unmarshalling of arguments for the server side of the RPCs, invokes the | |
5089 | * routines defined within rxdemo server.c to implement the calls, and also | |
5090 | * provides the dispatcher function. | |
5091 | * \li rxdemo.xdr.c: This module defines the routines required to convert | |
5092 | * complex user-defined data structures appearing as arguments to the Rx RPC | |
5093 | * calls exported by rxdemo.xg into network byte order, so that correct | |
5094 | * communication is guaranteed between clients and server with different memory | |
5095 | * organizations. | |
5096 | * \par | |
5097 | * The chapter concludes with a section containing sample output from running | |
5098 | * the rxdemo server and client programs. | |
5099 | * | |
5100 | * \section sec6-2 Section 6.2: Human-Generated files | |
5101 | * | |
5102 | * \par | |
5103 | * The rxdemo application is based on the four human-authored files described | |
5104 | * in this section. They provide the basis for the construction of the full set | |
5105 | * of modules needed to implement the specified Rx service. | |
5106 | * | |
5107 | * \subsection sec6-2-1 Section 6.2.1: Interface file: rxdemo.xg | |
5108 | * | |
5109 | * \par | |
5110 | * This file serves as the RPC interface definition file for this application. | |
5111 | * It defines various constants, including the Rx service port to use and the | |
5112 | * index of the null security object (no encryption is used by rxdemo). It | |
5113 | * defines the RXDEMO MAX and RXDEMO MIN constants, which will be used by the | |
5114 | * server as the upper and lower bounds on the number of Rx listener threads to | |
5115 | * run. It also defines the set of error codes exported by this facility. | |
5116 | * finally, it provides the RPC function declarations, namely Add() and | |
5117 | * Getfile(). Note that when building the actual function definitions, Rxgen | |
5118 | * will prepend the value of the package line in this file, namely "RXDEMO ", | |
5119 | * to the function declarations. Thus, the generated functions become RXDEMO | |
5120 | * Add() and RXDEMO Getfile(), respectively. Note the use of the split keyword | |
5121 | * in the RXDEMO Getfile() declaration, which specifies that this is a streamed | |
5122 | * call, and actually generates two client-side stub routines (see Section | |
5123 | * 6.3.1). | |
5124 | * | |
5125 | * \code | |
5126 | * /*======================================================================= | |
5127 | * * Interface for an example Rx server/client application, using both * * | |
5128 | * standard and streamed calls. * ** * Edward R. Zayas * * Transarc | |
5129 | * Corporation * ** ** * The United States Government has rights in this | |
5130 | * work pursuant * * to contract no. MDA972-90-C-0036 between the United | |
5131 | * States Defense * * Advanced Research Projects Agency and Transarc | |
5132 | * Corporation. * ** * (C) Copyright 1991 Transarc Corporation * ** * | |
5133 | * Redistribution and use in source and binary forms are permitted * | |
5134 | * provided that: (1) source distributions retain this entire copy- * * | |
5135 | * right notice and comment, and (2) distributions including binaries * * | |
5136 | * display the following acknowledgement: * ** * ''This product includes | |
5137 | * software developed by Transarc * * Corporation and its contributors'' * | |
5138 | * ** * in the documentation or other materials mentioning features or * * | |
5139 | * use of this software. Neither the name of Transarc nor the names * * of | |
5140 | * its contributors may be used to endorse or promote products * * derived | |
5141 | * from this software without specific prior written * * permission. * ** | |
5142 | * * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED * | |
5143 | * * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | |
5144 | * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
5145 | * =======================================================================*/ | |
5146 | * | |
5147 | * package RXDEMO_ | |
5148 | * %#include <rx/rx.h> | |
5149 | * %#include <rx/rx_null.h> | |
5150 | * %#define RXDEMO_SERVER_PORT 8000 /* Service port to advertise */ | |
5151 | * %#define RXDEMO_SERVICE_PORT 0 /* User server's port */ | |
5152 | * %#define RXDEMO_SERVICE_ID 4 /* Service ID */ | |
5153 | * %#define RXDEMO_NULL_SECOBJ_IDX 0 /* Index of null security object */ | |
5154 | * | |
5155 | * /* Maximum number of requests that will be handled by this service | |
5156 | * * simultaneously. This number will be guaranteed to execute in | |
5157 | * * parallel if other service's results are being processed. */ | |
5158 | * | |
5159 | * %#define RXDEMO_MAX 3 | |
5160 | * | |
5161 | * /* Minimum number of requests that are guaranteed to be | |
5162 | * * handled simultaneously. */ | |
5163 | * | |
5164 | * %#define RXDEMO_MIN 2 | |
5165 | * | |
5166 | * /* Index of the "null" security class in the sample service. */ | |
5167 | * | |
5168 | * %#define RXDEMO_NULL 0 | |
5169 | * | |
5170 | * /* Maximum number of characters in a file name (for demo purposes). */ | |
5171 | * | |
5172 | * %#define RXDEMO_NAME_MAX_CHARS 64 | |
5173 | * | |
5174 | * /* Define the max number of bytes to transfer at one shot. */ | |
5175 | * | |
5176 | * %#define RXDEMO_BUFF_BYTES 512 | |
5177 | * | |
5178 | * /* Values returned by the RXDEMO_Getfile() call. | |
5179 | * * RXDEMO_CODE_SUCCESS : Everything went fine. | |
5180 | * * RXDEMO_CODE_CANT_OPEN : Can't open named file. | |
5181 | * * RXDEMO_CODE_CANT_STAT : Can't stat open file. | |
5182 | * * RXDEMO_CODE_CANT_READ : Error reading the open file. | |
5183 | * * RXDEMO_CODE_WRITE_ERROR : Error writing the open file. */ | |
5184 | * | |
5185 | * /* ------------Interface calls defined for this service ----------- */ | |
5186 | * %#define RXDEMO_CODE_SUCCESS 0 | |
5187 | * %#define RXDEMO_CODE_CANT_OPEN 1 | |
5188 | * %#define RXDEMO_CODE_CANT_STAT 2 | |
5189 | * %#define RXDEMO_CODE_CANT_READ 3 | |
5190 | * %#define RXDEMO_CODE_WRITE_ERROR 4 | |
5191 | * /* ------------------------------------------------------------------- | |
5192 | * * RXDEMO_Add * | |
5193 | * * | |
5194 | * * Summary: | |
5195 | * * Add the two numbers provided and return the result. * | |
5196 | * * Parameters: | |
5197 | * * int a_first : first operand. | |
5198 | * * int a_second : Second operand. | |
5199 | * * int *a_result : Sum of the above. * | |
5200 | * * Side effects: None. | |
5201 | * *-------------------------------------------------------------------- */ | |
5202 | * | |
5203 | * Add(IN int a, int b, OUT int *result) = 1; | |
5204 | * /*------------------------------------------------------------------- | |
5205 | * * RXDEMO_Getfile * | |
5206 | * * Summary: | |
5207 | * * Return the contents of the named file in the server's environment. | |
5208 | * * Parameters: | |
5209 | * * STRING a_nameToRead : Name of the file whose contents are to be | |
5210 | * * fetched. | |
5211 | * * int *a_result : Set to the result of opening and reading the file | |
5212 | * * on the server side. * | |
5213 | * * Side effects: None. | |
5214 | * *-------------------------------------------------------------------- */ | |
5215 | * | |
5216 | * Getfile(IN string a_nameToRead<RXDEMO_NAME_MAX_CHARS>, OUT int *a_result) | |
5217 | * split = 2; | |
5218 | * \endcode | |
5219 | * | |
5220 | * \subsection sec6-2-2 Section 6.2.2: Client Program: rxdemo client.c | |
5221 | * | |
5222 | * \par | |
5223 | * The rxdemo client program, rxdemo client, calls upon the associated server | |
5224 | * to perform operations defined by rxdemo.xg. After its header, it defines a | |
5225 | * private GetIPAddress() utility routine, which given a character string host | |
5226 | * name will return its IP address. | |
5227 | * | |
5228 | * \code | |
5229 | * /*======================================================================= | |
5230 | * % Client side of an example Rx application, using both standard and % % | |
5231 | * streamed calls. % %% % Edward R. Zayas % % Transarc Corporation % %% | |
5232 | * %% % The United States Government has rights in this work pursuant % % | |
5233 | * to contract no. MDA972-90-C-0036 between the United States Defense % % | |
5234 | * Advanced Research Projects Agency and Transarc Corporation. % %% % (C) | |
5235 | * Copyright 1991 Transarc Corporation % %% % Redistribution and use in source | |
5236 | * and binary forms are permitted % % provided that: (1) source distributions | |
5237 | * retain this entire copy- % % right notice and comment, and (2) distributions | |
5238 | * including binaries % % display the following acknowledgement: % %% % | |
5239 | * ''This product includes software developed by Transarc % % Corporation and | |
5240 | * its contributors'' % %% % in the documentation or other materials mentioning | |
5241 | * features or % % use of this software. Neither the name of Transarc nor the | |
5242 | * names % % of its contributors may be used to endorse or promote products % % | |
5243 | * derived from this software without specific prior written % % permission. | |
5244 | * % %% % THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED | |
5245 | * % % WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF % % | |
5246 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
5247 | * % %======================================================================= | |
5248 | * */ | |
5249 | * | |
5250 | * #include <sys/types.h> | |
5251 | * #include <netdb.h> | |
5252 | * #include <stdio.h> | |
5253 | * #include "rxdemo.h" | |
5254 | * static char pn[] = "rxdemo"; /* Program name */ | |
5255 | * static u_long GetIpAddress(a_hostName) char *a_hostName; | |
5256 | * { /* GetIPAddress */ | |
5257 | * static char rn[] = "GetIPAddress"; /* Routine name */ | |
5258 | * struct hostent *hostEntP; /* Ptr to host descriptor */ | |
5259 | * u_long hostIPAddr; /* Host IP address */ | |
5260 | * hostEntP = gethostbyname(a_hostName); | |
5261 | * if (hostEntP == (struct hostent *)0) { | |
5262 | * printf("[%s:%s] Host '%s' not found\n", | |
5263 | * pn, rn, a_hostName); | |
5264 | * exit(1); | |
5265 | * } | |
5266 | * if (hostEntP->h_length != sizeof(u_long)) { | |
5267 | * printf("[%s:%s] Wrong host address length (%d bytes instead of | |
5268 | * %d)", | |
5269 | * pn, rn, hostEntP->h_length, sizeof(u_long)); | |
5270 | * exit(1); | |
5271 | * } | |
5272 | * bcopy(hostEntP->h_addr, (char *)&hostIPAddr, sizeof(hostIPAddr)); | |
5273 | * return(hostIPAddr); | |
5274 | * } /* GetIpAddress */ | |
5275 | * \endcode | |
5276 | * | |
5277 | * \par | |
5278 | * The main program section of the client code, after handling its command line | |
5279 | * arguments, starts off by initializing the Rx facility. | |
5280 | * | |
5281 | * \code | |
5282 | * main(argc, argv) | |
5283 | * int argc; | |
5284 | * char **argv; | |
5285 | * { /* Main */ | |
5286 | * struct rx_connection *rxConnP; /* Ptr to server connection */ | |
5287 | * struct rx_call *rxCallP; /* Ptr to Rx call descriptor */ | |
5288 | * u_long hostIPAddr; /* IP address of chosen host */ | |
5289 | * int demoUDPPort; /* UDP port of Rx service */ | |
5290 | * struct rx_securityClass *nullSecObjP; /* Ptr to null security object */ | |
5291 | * int operand1, operand2; /* Numbers to add int sum; Their sum */ | |
5292 | * int code; /* Return code */ | |
5293 | * char fileName[64]; /* Buffer for desired file's name */ | |
5294 | * long fileDataBytes; /* Num bytes in file to get */ | |
5295 | * char buff[RXDEMO_BUFF_BYTES+1]; /* Read buffer */ | |
5296 | * int currBytesToRead; /* Num bytes to read in one iteration */ | |
5297 | * int maxBytesToRead; /* Max bytes to read in one iteration */ | |
5298 | * int bytesReallyRead; /* Num bytes read off Rx stream */ | |
5299 | * int getResults; /* Results of the file fetch */ | |
5300 | * printf("\n%s: Example Rx client process\n\n", pn); | |
5301 | * if ((argc < 2) || (argc > 3)) { | |
5302 | * printf("Usage: rxdemo <HostName> [PortToUse]"); | |
5303 | * exit(1); | |
5304 | * } | |
5305 | * hostIPAddr = GetIpAddress(argv[1]); | |
5306 | * if (argc > 2) | |
5307 | * demoUDPPort = atoi(argv[2]); | |
5308 | * else | |
5309 | * demoUDPPort = RXDEMO_SERVER_PORT; | |
5310 | * /* Initialize the Rx facility. */ | |
5311 | * code = rx_Init(htons(demoUDPPort)); | |
5312 | * if (code) { | |
5313 | * printf("** Error calling rx_Init(); code is %d\n", code); | |
5314 | * exit(1); | |
5315 | * } | |
5316 | * /* Create a client-side null security object. */ | |
5317 | * nullSecObjP = rxnull_NewClientSecurityObject(); | |
5318 | * if (nullSecObjP == (struct rx_securityClass *)0) { | |
5319 | * printf("%s: Can't create a null client-side security | |
5320 | * object!\n", pn); | |
5321 | * exit(1); | |
5322 | * } | |
5323 | * /* Set up a connection to the desired Rx service, telling it to use | |
5324 | * * the null security object we just created. */ | |
5325 | * printf("Connecting to Rx server on '%s', IP address 0x%x, UDP port | |
5326 | * %d\n", argv[1], hostIPAddr, demoUDPPort); | |
5327 | * rxConnP = rx_NewConnection(hostIPAddr, RXDEMO_SERVER_PORT, | |
5328 | * RXDEMO_SERVICE_ID, nullSecObjP, RXDEMO_NULL_SECOBJ_IDX); | |
5329 | * if (rxConnP == (struct rx_connection *)0) { | |
5330 | * printf("rxdemo: Can't create connection to server!\n"); | |
5331 | * exit(1); | |
5332 | * } else | |
5333 | * printf(" ---> Connected.\n"); | |
5334 | * \endcode | |
5335 | * | |
5336 | * \par | |
5337 | * The rx Init() invocation initializes the Rx library and defines the desired | |
5338 | * service UDP port (in network byte order). The rxnull | |
5339 | * NewClientSecurityObject() call creates a client-side Rx security object that | |
5340 | * does not perform any authentication on Rx calls. Once a client | |
5341 | * authentication object is in hand, the program calls rx NewConnection(), | |
5342 | * specifying the host, UDP port, Rx service ID, and security information | |
5343 | * needed to establish contact with the rxdemo server entity that will be | |
5344 | * providing the service. | |
5345 | * \par | |
5346 | * With the Rx connection in place, the program may perform RPCs. The first one | |
5347 | * to be invoked is RXDEMO Add(): | |
5348 | * | |
5349 | * \code | |
5350 | * /* Perform our first, simple remote procedure call. */ | |
5351 | * operand1 = 1; | |
5352 | * operand2 = 2; | |
5353 | * printf("Asking server to add %d and %d: ", operand1, operand2); | |
5354 | * code = RXDEMO_Add(rxConnP, operand1, operand2, &sum); | |
5355 | * if (code) { | |
5356 | * printf(" // ** Error in the RXDEMO_Add RPC: code is %d\n", code); | |
5357 | * exit(1); | |
5358 | * } | |
5359 | * printf("Reported sum is %d\n", sum); | |
5360 | * \endcode | |
5361 | * | |
5362 | * \par | |
5363 | * The first argument to RXDEMO Add() is a pointer to the Rx connection | |
5364 | * established above. The client-side body of the RXDEMO Add() function was | |
5365 | * generated from the rxdemo.xg interface file, and resides in the rxdemo.cs.c | |
5366 | * file (see Section 6.3.1). It gives the appearance of being a normal C | |
5367 | * procedure call. | |
5368 | * \par | |
5369 | * The second RPC invocation involves the more complex, streamed RXDEMO | |
5370 | * Getfile() function. More of the internal Rx workings are exposed in this | |
5371 | * type of call. The first additional detail to consider is that we must | |
5372 | * manually create a new Rx call on the connection. | |
5373 | * | |
5374 | * \code | |
5375 | * /* Set up for our second, streamed procedure call. */ | |
5376 | * printf("Name of file to read from server: "); | |
5377 | * scanf("%s", fileName); | |
5378 | * maxBytesToRead = RXDEMO_BUFF_BYTES; | |
5379 | * printf("Setting up an Rx call for RXDEMO_Getfile..."); | |
5380 | * rxCallP = rx_NewCall(rxConnP); | |
5381 | * if (rxCallP == (struct rx_call *)0) { | |
5382 | * printf("** Can't create call\n"); | |
5383 | * exit(1); | |
5384 | * } | |
5385 | * printf("done\n"); | |
5386 | * \endcode | |
5387 | * | |
5388 | * \par | |
5389 | * Once the Rx call structure has been created, we may begin executing the call | |
5390 | * itself. Having been declared to be split in the interface file, Rxgen | |
5391 | * creates two function bodies for rxdemo Getfile() and places them in | |
5392 | * rxdemo.cs.c. The first, StartRXDEMO Getfile(), is responsible for | |
5393 | * marshalling the outgoing arguments and issuing the RPC. The second, | |
5394 | * EndRXDEMO Getfile(), takes care of unmarshalling the non-streamed OUT | |
5395 | * function parameters. The following code fragment illustrates how the RPC is | |
5396 | * started, using the StartRXDEMO Getfile() routine to pass the call parameters | |
5397 | * to the server. | |
5398 | * | |
5399 | * \code | |
5400 | * /* Sending IN parameters for the streamed call. */ | |
5401 | * code = StartRXDEMO_Getfile(rxCallP, fileName); | |
5402 | * if (code) { | |
5403 | * printf("** Error calling StartRXDEMO_Getfile(); code is %d\n", | |
5404 | * code); | |
5405 | * exit(1); | |
5406 | * } | |
5407 | * \endcode | |
5408 | * | |
5409 | * \par | |
5410 | * Once the call parameters have been shipped, the server will commence | |
5411 | * delivering the "stream" data bytes back to the client on the given Rx call | |
5412 | * structure. The first longword to come back on the stream specifies the | |
5413 | * number of bytes to follow. | |
5414 | * | |
5415 | * \par | |
5416 | * Begin reading the data being shipped from the server in response to * our | |
5417 | * setup call. The first longword coming back on the Rx call is | |
5418 | * the number of bytes to follow. It appears in network byte order, | |
5419 | * so we have to fix it up before referring to it. | |
5420 | * | |
5421 | * \code | |
5422 | * bytesReallyRead = rx_Read(rxCallP, &fileDataBytes, sizeof(long)); | |
5423 | * if (bytesReallyRead != sizeof(long)) { | |
5424 | * printf("** Only %d bytes read for file length; should have been %d\n", | |
5425 | * bytesReallyRead, sizeof(long)); | |
5426 | * exit(1); | |
5427 | * } | |
5428 | * fileDataBytes = ntohl(fileDataBytes); | |
5429 | * \endcode | |
5430 | * | |
5431 | * \par | |
5432 | * Once the client knows how many bytes will be sent, it runs a loop in which | |
5433 | * it reads a buffer at a time from the Rx call stream, using rx Read() to | |
5434 | * accomplish this. In this application, all that is done with each | |
5435 | * newly-acquired buffer of information is printing it out. | |
5436 | * | |
5437 | * \code | |
5438 | * /* Read the file bytes via the Rx call, a buffer at a time. */ | |
5439 | * printf("[file contents (%d bytes) fetched over the Rx call appear | |
5440 | * below]\n\n", fileDataBytes); | |
5441 | * while (fileDataBytes > 0) | |
5442 | * { | |
5443 | * currBytesToRead = (fileDataBytes > maxBytesToRead ? maxBytesToRead : | |
5444 | * fileDataBytes); | |
5445 | * bytesReallyRead = rx_Read(rxCallP, buff, currBytesToRead); | |
5446 | * if (bytesReallyRead != currBytesToRead) | |
5447 | * { | |
5448 | * printf("\nExpecting %d bytes on this read, got %d instead\n", | |
5449 | * currBytesToRead, bytesReallyRead); | |
5450 | * exit(1); | |
5451 | * } | |
5452 | * /* Null-terminate the chunk before printing it. */ | |
5453 | * buff[currBytesToRead] = 0; | |
5454 | * printf("%s", buff); | |
5455 | * /* Adjust the number of bytes left to read. */ | |
5456 | * fileDataBytes -= currBytesToRead; | |
5457 | * } /* Read one bufferful of the file */ | |
5458 | * \endcode | |
5459 | * | |
5460 | * \par | |
5461 | * After this loop terminates, the Rx stream has been drained of all data. The | |
5462 | * Rx call is concluded by invoking the second of the two | |
5463 | * automatically-generated functions, EndRXDEMO Getfile(), which retrieves the | |
5464 | * call's OUT parameter from the server. | |
5465 | * | |
5466 | * \code | |
5467 | * /* finish off the Rx call, getting the OUT parameters. */ | |
5468 | * printf("\n\n[End of file data]\n"); | |
5469 | * code = EndRXDEMO_Getfile(rxCallP, &getResults); | |
5470 | * if (code) | |
5471 | * { | |
5472 | * printf("** Error getting file transfer results; code is %d\n", | |
5473 | * code); | |
5474 | * exit(1); | |
5475 | * } | |
5476 | * \endcode | |
5477 | * | |
5478 | * \par | |
5479 | * With both normal and streamed Rx calls accomplished, the client demo code | |
5480 | * concludes by terminating the Rx call it set up earlier. With that done, the | |
5481 | * client exits. | |
5482 | * | |
5483 | * \code | |
5484 | * /* finish off the Rx call. */ | |
5485 | * code = rx_EndCall(rxCallP, code); | |
5486 | * if (code) | |
5487 | * printf("Error in calling rx_EndCall(); code is %d\n", code); | |
5488 | * | |
5489 | * printf("\n\nrxdemo complete.\n"); | |
5490 | * \endcode | |
5491 | * | |
5492 | * \subsection sec6-2-3 Server Program: rxdemo server.c | |
5493 | * | |
5494 | * \par | |
5495 | * The rxdemo server program, rxdemo server, implements the operations promised | |
5496 | * in the rxdemo.xg interface file. | |
5497 | * \par | |
5498 | * After the initial header, the external function RXDEMO ExecuteRequest() is | |
5499 | * declared. The RXDEMO ExecuteRequest() function is generated automatically by | |
5500 | * rxgen from the interface file and deposited in rxdemo.ss.c. The main program | |
5501 | * listed below will associate this RXDEMO ExecuteRequest() routine with the Rx | |
5502 | * service to be instantiated. | |
5503 | * | |
5504 | * \code | |
5505 | * /*====================================================================== | |
5506 | * % % Advanced Research Projects Agency and Transarc Corporation. % %% % | |
5507 | * (C) Copyright 1991 Transarc Corporation % %% % Redistribution and use in | |
5508 | * source and binary forms are permitted % % provided that: (1) source | |
5509 | * distributions retain this entire copy- % % right notice and comment, and | |
5510 | * (2) distributions including binaries % % display the following | |
5511 | * acknowledgement: % %% % ''This product includes software developed by | |
5512 | * Transarc % % Corporation and its contributors'' % %% % in the documentation | |
5513 | * or other materials mentioning features or % % use of this software. Neither | |
5514 | * the name of Transarc nor the names % % of its contributors may be used to | |
5515 | * endorse or promote products % % derived from this software without specific | |
5516 | * prior written % % permission. % %% % THIS SOFTWARE IS PROVIDED "AS IS" AND | |
5517 | * WITHOUT ANY EXPRESS OR IMPLIED % % WARRANTIES, INCLUDING, WITHOUT | |
5518 | * LIMITATION, | |
5519 | * THE IMPLIED WARRANTIES OF % % MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
5520 | * PURPOSE. % % | |
5521 | * ====================================================================== */ | |
5522 | * | |
5523 | * /* Server portion of the example RXDEMO application, using both % | |
5524 | * standard and streamed calls. % % Edward R. Zayas % Transarc Corporation % | |
5525 | * % % The United States Government has rights in this work pursuant % | |
5526 | * to contract no. MDA972-90-C-0036 between the United States Defense % */ | |
5527 | * | |
5528 | * #include <sys/types.h> | |
5529 | * #include <sys/stat.h> | |
5530 | * #include <sys/file.h> | |
5531 | * #include <netdb.h> | |
5532 | * #include <stdio.h> | |
5533 | * #include "rxdemo.h" | |
5534 | * #define N_SECURITY_OBJECTS 1 | |
5535 | * extern RXDEMO_ExecuteRequest(); | |
5536 | * \endcode | |
5537 | * | |
5538 | * \par | |
5539 | * After choosing either the default or user-specified UDP port on which the Rx | |
5540 | * service will be established, rx Init() is called to set up the library. | |
5541 | * | |
5542 | * \code | |
5543 | * main(argc, argv) | |
5544 | * int argc; | |
5545 | * char **argv; | |
5546 | * { /* Main */ | |
5547 | * static char pn[] = "rxdemo_server"; /* Program name */ | |
5548 | * struct rx_securityClass | |
5549 | * (securityObjects[1]); /* Security objs */ | |
5550 | * struct rx_service *rxServiceP; /* Ptr to Rx service descriptor */ | |
5551 | * struct rx_call *rxCallP; /* Ptr to Rx call descriptor */ | |
5552 | * int demoUDPPort; /* UDP port of Rx service */ | |
5553 | * int fd; /* file descriptor */ | |
5554 | * int code; /* Return code */ | |
5555 | * printf("\n%s: Example Rx server process\n\n", pn); | |
5556 | * if (argc >2) { | |
5557 | * printf("Usage: rxdemo [PortToUse]"); | |
5558 | * exit(1); | |
5559 | * } | |
5560 | * if (argc > 1) | |
5561 | * demoUDPPort = atoi(argv[1]); | |
5562 | * else | |
5563 | * demoUDPPort = RXDEMO_SERVER_PORT; | |
5564 | * | |
5565 | * /* Initialize the Rx facility, telling it the UDP port number this | |
5566 | * * server will use for its single service. */ | |
5567 | * | |
5568 | * printf("Listening on UDP port %d\n", demoUDPPort); | |
5569 | * code = rx_Init(demoUDPPort); | |
5570 | * if (code) { | |
5571 | * printf("** Error calling rx_Init(); code is %d\n", code); | |
5572 | * exit(1); | |
5573 | * } | |
5574 | * \endcode | |
5575 | * | |
5576 | * \par | |
5577 | * A security object specific to the server side of an Rx conversation is | |
5578 | * created in the next code fragment. As with the client side of the code, a | |
5579 | * "null" server security object, namely one that does not perform any | |
5580 | * authentication at all, is constructed with the rxnull | |
5581 | * NewServerSecurityObject() function. | |
5582 | * | |
5583 | * \code | |
5584 | * /* Create a single server-side security object. In this case, the | |
5585 | * * null security object (for unauthenticated connections) will be used | |
5586 | * * to control security on connections made to this server. */ | |
5587 | * | |
5588 | * securityObjects[RXDEMO_NULL_SECOBJ_IDX] = | |
5589 | * rxnull_NewServerSecurityObject(); | |
5590 | * if (securityObjects[RXDEMO_NULL_SECOBJ_IDX] == (struct rx_securityClass | |
5591 | * *) 0) { | |
5592 | * printf("** Can't create server-side security object\n"); | |
5593 | * exit(1); | |
5594 | * } | |
5595 | * \endcode | |
5596 | * | |
5597 | * \par | |
5598 | * The rxdemo server program is now in a position to create the desired Rx | |
5599 | * service, primed to recognize exactly those interface calls defined in | |
5600 | * rxdemo.xg. This is accomplished by calling the rx NewService() library | |
5601 | * routine, passing it the security object created above and the generated Rx | |
5602 | * dispatcher routine. | |
5603 | * | |
5604 | * \code | |
5605 | * /* Instantiate a single sample service. The rxgen-generated procedure | |
5606 | * * called to dispatch requests is passed in (RXDEMO_ExecuteRequest). */ | |
5607 | * | |
5608 | * rxServiceP = rx_NewService( 0, | |
5609 | * RXDEMO_SERVICE_ID, | |
5610 | * "rxdemo", | |
5611 | * securityObjects, | |
5612 | * 1, | |
5613 | * RXDEMO_ExecuteRequest | |
5614 | * ); | |
5615 | * if (rxServiceP == (struct rx_service *) 0) { | |
5616 | * printf("** Can't create Rx service\n"); | |
5617 | * exit(1); | |
5618 | * } | |
5619 | * \endcode | |
5620 | * | |
5621 | * \par | |
5622 | * The final step in this main routine is to activate servicing of calls to the | |
5623 | * exported Rx interface. Specifically, the proper number of threads are | |
5624 | * created to handle incoming interface calls. Since we are passing a non-zero | |
5625 | * argument to the rx StartServer() call, the main program will itself begin | |
5626 | * executing the server thread loop, never returning from the rx StartServer() | |
5627 | * call. The print statement afterwards should never be executed, and its | |
5628 | * presence represents some level of paranoia, useful for debugging | |
5629 | * malfunctioning thread packages. | |
5630 | * | |
5631 | * \code | |
5632 | * /* Start up Rx services, donating this thread to the server pool. */ | |
5633 | * rx_StartServer(1); | |
5634 | * /* We should never return from the previous call. */ | |
5635 | * printf("** rx_StartServer() returned!!\n"); exit(1); | |
5636 | * } /* Main */ | |
5637 | * \endcode | |
5638 | * | |
5639 | * \par | |
5640 | * Following the main procedure are the functions called by the | |
5641 | * automatically-generated routines in the rxdemo.ss.c module to implement the | |
5642 | * specific routines defined in the Rx interface. | |
5643 | * \par | |
5644 | * The first to be defined is the RXDEMO Add() function. The arguments for this | |
5645 | * routine are exactly as they appear in the interface definition, with the | |
5646 | * exception of the very first. The a rxCallP parameter is a pointer to the Rx | |
5647 | * structure describing the call on which this function was activated. All | |
5648 | * user-supplied routines implementing an interface function are required to | |
5649 | * have a pointer to this structure as their first parameter. Other than | |
5650 | * printing out the fact that it has been called and which operands it | |
5651 | * received, all that RXDEMO Add() does is compute the sum and place it in the | |
5652 | * output parameter. | |
5653 | * \par | |
5654 | * Since RXDEMO Add() is a non-streamed function, with all data travelling | |
5655 | * through the set of parameters, this is all that needs to be done. To mark a | |
5656 | * successful completion, RXDEMO Add() returns zero, which is passed all the | |
5657 | * way through to the RPC's client. | |
5658 | * | |
5659 | * \code | |
5660 | * int RXDEMO_Add(a_rxCallP, a_operand1, a_operand2, a_resultP) | |
5661 | * struct rx_call *a_rxCallP; | |
5662 | * int a_operand1, a_operand2; | |
5663 | * int *a_resultP; | |
5664 | * { /* RXDEMO_Add */ | |
5665 | * printf("\t[Handling call to RXDEMO_Add(%d, %d)]\n", | |
5666 | * a_operand1, a_operand2); | |
5667 | * *a_resultP = a_operand1 + a_operand2; | |
5668 | * return(0); | |
5669 | * } /* RXDEMO_Add */ | |
5670 | * \endcode | |
5671 | * | |
5672 | * \par | |
5673 | * The next and final interface routine defined in this file is RXDEMO | |
5674 | * Getfile(). Declared as a split function in the interface file, RXDEMO | |
5675 | * Getfile() is an example of a streamed Rx call. As with RXDEMO Add(), the | |
5676 | * initial parameter is required to be a pointer to the Rx call structure with | |
5677 | * which this routine is associated, Similarly, the other parameters appear | |
5678 | * exactly as in the interface definition, and are handled identically. | |
5679 | * \par | |
5680 | * The difference between RXDEMO Add() and RXDEMO Getfile() is in the use of | |
5681 | * the rx Write() library routine by RXDEMO Getfile() to feed the desired | |
5682 | * file's data directly into the Rx call stream. This is an example of the use | |
5683 | * of the a rxCallP argument, providing all the information necessary to | |
5684 | * support the rx Write() activity. | |
5685 | * \par | |
5686 | * The RXDEMO Getfile() function begins by printing out the fact that it's been | |
5687 | * called and the name of the requested file. It will then attempt to open the | |
5688 | * requested file and stat it to determine its size. | |
5689 | * | |
5690 | * \code | |
5691 | * int RXDEMO_Getfile(a_rxCallP, a_nameToRead, a_resultP) | |
5692 | * struct rx_call *a_rxCallP; | |
5693 | * char *a_nameToRead; | |
5694 | * int *a_resultP; | |
5695 | * { /* RXDEMO_Getfile */ | |
5696 | * struct stat fileStat; /* Stat structure for file */ | |
5697 | * long fileBytes; /* Size of file in bytes */ | |
5698 | * long nbofileBytes; /* file bytes in network byte order */ | |
5699 | * int code; /* Return code */ | |
5700 | * int bytesReallyWritten; /* Bytes written on Rx channel */ | |
5701 | * int bytesToSend; /* Num bytes to read & send this time */ | |
5702 | * int maxBytesToSend; /* Max num bytes to read & send ever */ | |
5703 | * int bytesRead; /* Num bytes read from file */ | |
5704 | * char buff[RXDEMO_BUFF_BYTES+1]; /* Read buffer */ | |
5705 | * int fd; /* file descriptor */ | |
5706 | * maxBytesToSend = RXDEMO_BUFF_BYTES; | |
5707 | * printf("\t[Handling call to RXDEMO_Getfile(%s)]\n", a_nameToRead); | |
5708 | * fd = open(a_nameToRead, O_RDONLY, 0444); | |
5709 | * if (fd <0) { | |
5710 | * printf("\t\t[**Can't open file '%s']\n", a_nameToRead); | |
5711 | * *a_resultP = RXDEMO_CODE_CANT_OPEN; | |
5712 | * return(1); | |
5713 | * } else | |
5714 | * printf("\t\t[file opened]\n"); | |
5715 | * /* Stat the file to find out how big it is. */ | |
5716 | * code = fstat(fd, &fileStat); | |
5717 | * if (code) { | |
5718 | * a_resultP = RXDEMO_CODE_CANT_STAT; | |
5719 | * printf("\t\t[file closed]\n"); | |
5720 | * close(fd); | |
5721 | * return(1); | |
5722 | * } | |
5723 | * fileBytes = fileStat.st_size; | |
5724 | * printf("\t\t[file has %d bytes]\n", fileBytes); | |
5725 | * \endcode | |
5726 | * | |
5727 | * \par | |
5728 | * Only standard unix operations have been used so far. Now that the file is | |
5729 | * open, we must first feed the size of the file, in bytes, to the Rx call | |
5730 | * stream. With this information, the client code can then determine how many | |
5731 | * bytes will follow on the stream. As with all data that flows through an Rx | |
5732 | * stream, the longword containing the file size, in bytes, must be converted | |
5733 | * to network byte order before being sent. This insures that the recipient may | |
5734 | * properly interpret the streamed information, regardless of its memory | |
5735 | * architecture. | |
5736 | * | |
5737 | * \code | |
5738 | * nbofileBytes = htonl(fileBytes); | |
5739 | * /* Write out the size of the file to the Rx call. */ | |
5740 | * bytesReallyWritten = rx_Write(a_rxCallP, &nbofileBytes, sizeof(long)); | |
5741 | * if (bytesReallyWritten != sizeof(long)) { | |
5742 | * printf("** %d bytes written instead of %d for file length\n", | |
5743 | * bytesReallyWritten, sizeof(long)); | |
5744 | * *a_resultP = RXDEMO_CODE_WRITE_ERROR; | |
5745 | * printf("\t\t[file closed]\n"); | |
5746 | * close(fd); | |
5747 | * return(1); | |
5748 | * } | |
5749 | * \endcode | |
5750 | * | |
5751 | * \par | |
5752 | * Once the number of file bytes has been placed in the stream, the RXDEMO | |
5753 | * Getfile() routine runs a loop, reading a buffer's worth of the file and then | |
5754 | * inserting that buffer of file data into the Rx stream at each iteration. | |
5755 | * This loop executes until all of the file's bytes have been shipped. Notice | |
5756 | * there is no special end-of-file character or marker inserted into the | |
5757 | * stream. | |
5758 | * \par | |
5759 | * The body of the loop checks for both unix read() and rx Write errors. If | |
5760 | * there is a problem reading from the unix file into the transfer buffer, it | |
5761 | * is reflected back to the client by setting the error return parameter | |
5762 | * appropriately. Specifically, an individual unix read() operation could fail | |
5763 | * to return the desired number of bytes. Problems with rx Write() are handled | |
5764 | * similarly. All errors discovered in the loop result in the file being | |
5765 | * closed, and RXDEMO Getfile() exiting with a non-zero return value. | |
5766 | * | |
5767 | * \code | |
5768 | * /* Write out the contents of the file, one buffer at a time. */ | |
5769 | * while (fileBytes > 0) { | |
5770 | * /* figure out the number of bytes to | |
5771 | * * read (and send) this time. */ | |
5772 | * bytesToSend = (fileBytes > maxBytesToSend ? | |
5773 | * maxBytesToSend : fileBytes); | |
5774 | * bytesRead = read(fd, buff, bytesToSend); | |
5775 | * if (bytesRead != bytesToSend) { | |
5776 | * printf("Read %d instead of %d bytes from the file\n", | |
5777 | * bytesRead, bytesToSend); | |
5778 | * *a_resultP = RXDEMO_CODE_WRITE_ERROR; | |
5779 | * printf("\t\t[file closed]\n"); | |
5780 | * close(fd); | |
5781 | * return(1); | |
5782 | * } | |
5783 | * /* Go ahead and send them. */ | |
5784 | * bytesReallyWritten = rx_Write(a_rxCallP, buff, bytesToSend); | |
5785 | * if (bytesReallyWritten != bytesToSend) { | |
5786 | * printf("%d file bytes written instead of %d\n", | |
5787 | * bytesReallyWritten, bytesToSend); | |
5788 | * *a_resultP = RXDEMO_CODE_WRITE_ERROR; | |
5789 | * printf("\t\t[file closed]\n"); | |
5790 | * close(fd); | |
5791 | * return(1); | |
5792 | * } | |
5793 | * /* Update the number of bytes left to go. */ | |
5794 | * fileBytes -= bytesToSend; | |
5795 | * } /* Write out the file to our caller */ | |
5796 | * \endcode | |
5797 | * | |
5798 | * \par | |
5799 | * Once all of the file's bytes have been shipped to the remote client, all | |
5800 | * that remains to be done is to close the file and return successfully. | |
5801 | * | |
5802 | * \code | |
5803 | * /* Close the file, then return happily. */ | |
5804 | * *a_resultP = RXDEMO_CODE_SUCCESS; | |
5805 | * printf("\t\t[file closed]\n"); | |
5806 | * close(fd); | |
5807 | * return(0); | |
5808 | * } /* RXDEMO_Getfile */ | |
5809 | * \endcode | |
5810 | * | |
5811 | * \subsection sec6-2-4 Section 6.2.4: Makefile | |
5812 | * | |
5813 | * \par | |
5814 | * This file directs the compilation and installation of the rxdemo code. It | |
5815 | * specifies the locations of libraries, include files, sources, and such tools | |
5816 | * as Rxgen and install, which strips symbol tables from executables and places | |
5817 | * them in their target directories. This Makefile demostrates cross-cell | |
5818 | * software development, with the rxdemo sources residing in the | |
5819 | * grand.central.org cell and the AFS include files and libraries accessed from | |
5820 | * their locations in the transarc.com cell. | |
5821 | * \par | |
5822 | * In order to produce and install the rxdemo server and rxdemo client | |
5823 | * binaries, the system target should be specified on the command line when | |
5824 | * invoking make: | |
5825 | * \code | |
5826 | * make system | |
5827 | * \endcode | |
5828 | * \par | |
5829 | * A note of caution is in order concerning generation of the rxdemo binaries. | |
5830 | * While tools exist that deposit the results of all compilations to other | |
5831 | * (architecture-specific) directories, and thus facilitate multiple | |
5832 | * simultaneous builds across a variety of machine architectures (e.g., | |
5833 | * Transarc's washtool), the assumption is made here that compilations will | |
5834 | * take place directly in the directory containing all the rxdemo sources. | |
5835 | * Thus, a user will have to execute a make clean command to remove all | |
5836 | * machine-specific object, library, and executable files before compiling for | |
5837 | * a different architecture. Note, though, that the binaries are installed into | |
5838 | * a directory specifically reserved for the current machine type. | |
5839 | * Specifically, the final pathname component of the ${PROJ DIR}bin | |
5840 | * installation target is really a symbolic link to ${PROJ DIR}.bin/@sys. | |
5841 | * \par | |
5842 | * Two libraries are needed to support the rxdemo code. The first is obvious, | |
5843 | * namely the Rx librx.a library. The second is the lightweight thread package | |
5844 | * library, liblwp.a, which implements all the threading operations that must | |
5845 | * be performed. The include files are taken from the unix /usr/include | |
5846 | * directory, along with various AFS-specific directories. Note that for | |
5847 | * portability reasons, this Makefile only contains fully-qualified AFS | |
5848 | * pathnames and "standard" unix pathnames (such as /usr/include). | |
5849 | * | |
5850 | * \code | |
5851 | * /*#=======================================================================# | |
5852 | * # The United States Government has rights in this work pursuant # # to | |
5853 | * contract no. MDA972-90-C-0036 between the United States Defense # # Advanced | |
5854 | * Research Projects Agency and Transarc Corporation. # # # # (C) Copyright | |
5855 | * 1991 | |
5856 | * Transarc Corporation # # # # Redistribution and use in source and binary | |
5857 | * forms | |
5858 | * are permitted # # provided that: (1) source distributions retain this entire | |
5859 | * copy-# # right notice and comment, and (2) distributions including binaries | |
5860 | * # | |
5861 | * # display the following acknowledgement: # # # # ''This product includes | |
5862 | * software developed by Transarc # # Corporation and its contributors'' # # # | |
5863 | * # | |
5864 | * in the documentation or other materials mentioning features or # # use of | |
5865 | * this | |
5866 | * software. Neither the name of Transarc nor the names # # of its contributors | |
5867 | * may be used to endorse or promote products # # derived from this software | |
5868 | * without specific prior written # # permission. # # # # THIS SOFTWARE IS | |
5869 | * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED # # WARRANTIES, | |
5870 | * INCLUDING, | |
5871 | * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # # MERCHANTABILITY AND | |
5872 | * FITNESS | |
5873 | * FOR A PARTICULAR PURPOSE. # | |
5874 | * #=======================================================================# */ | |
5875 | * | |
5876 | * SHELL = /bin/sh | |
5877 | * TOOL_CELL = grand.central.org | |
5878 | * AFS_INCLIB_CELL = transarc.com | |
5879 | * USR_CONTRIB = /afs/${TOOL_CELL}/darpa/usr/contrib/ | |
5880 | * PROJ_DIR = ${USR_CONTRIB}.site/grand.central.org/rxdemo/ | |
5881 | * AFS_INCLIB_DIR = /afs/${AFS_INCLIB_CELL}/afs/dest/ | |
5882 | * RXGEN = ${AFS_INCLIB_DIR}bin/rxgen | |
5883 | * INSTALL = ${AFS_INCLIB_DIR}bin/install | |
5884 | * LIBS = ${AFS_INCLIB_DIR}lib/librx.a \ ${AFS_INCLIB_DIR}lib/liblwp.a | |
5885 | * CFLAGS = -g \ | |
5886 | * -I. \ | |
5887 | * -I${AFS_INCLIB_DIR}include \ | |
5888 | * -I${AFS_INCLIB_DIR}include/afs \ | |
5889 | * -I${AFS_INCLIB_DIR} \ | |
5890 | * -I/usr/include | |
5891 | * | |
5892 | * system: install | |
5893 | * | |
5894 | * install: all | |
5895 | * ${INSTALL} rxdemo_client | |
5896 | * ${PROJ_DIR}bin | |
5897 | * ${INSTALL} rxdemo_server | |
5898 | * ${PROJ_DIR}bin | |
5899 | * | |
5900 | * all: rxdemo_client rxdemo_server | |
5901 | * | |
5902 | * rxdemo_client: rxdemo_client.o ${LIBS} rxdemo.cs.o ${CC} ${CFLAGS} | |
5903 | * -o rxdemo_client rxdemo_client.o rxdemo.cs.o ${LIBS} | |
5904 | * | |
5905 | * rxdemo_server: rxdemo_server.o rxdemo.ss.o ${LIBS} ${CC} ${CFLAGS} | |
5906 | * -o rxdemo_server rxdemo_server.o rxdemo.ss.o ${LIBS} | |
5907 | * | |
5908 | * rxdemo_client.o: rxdemo.h | |
5909 | * | |
5910 | * rxdemo_server.o: rxdemo.h | |
5911 | * | |
5912 | * rxdemo.cs.c rxdemo.ss.c rxdemo.er.c rxdemo.h: rxdemo.xg rxgen rxdemo.xg | |
5913 | * | |
5914 | * clean: rm -f *.o rxdemo.cs.c rxdemo.ss.c rxdemo.xdr.c rxdemo.h \ | |
5915 | * rxdemo_client rxdemo_server core | |
5916 | * \endcode | |
5917 | * | |
5918 | * \section sec6-3 Section 6.3: Computer-Generated files | |
5919 | * | |
5920 | * \par | |
5921 | * The four human-generated files described above provide all the information | |
5922 | * necessary to construct the full set of modules to support the rxdemo example | |
5923 | * application. This section describes those routines that are generated from | |
5924 | * the base set by Rxgen, filling out the code required to implement an Rx | |
5925 | * service. | |
5926 | * | |
5927 | * \subsection sec6-3-1 Client-Side Routines: rxdemo.cs.c | |
5928 | * | |
5929 | * \par | |
5930 | * The rxdemo client.c program, described in Section 6.2.2, calls the | |
5931 | * client-side stub routines contained in this module in order to make rxdemo | |
5932 | * RPCs. Basically, these client-side stubs are responsible for creating new Rx | |
5933 | * calls on the given connection parameter and then marshalling and | |
5934 | * unmarshalling the rest of the interface call parameters. The IN and INOUT | |
5935 | * arguments, namely those that are to be delivered to the server-side code | |
5936 | * implementing the call, must be packaged in network byte order and shipped | |
5937 | * along the given Rx call. The return parameters, namely those objects | |
5938 | * declared as INOUT and OUT, must be fetched from the server side of the | |
5939 | * associated Rx call, put back in host byte order, and inserted into the | |
5940 | * appropriate parameter variables. | |
5941 | * \par | |
5942 | * The first part of rxdemo.cs.c echoes the definitions appearing in the | |
5943 | * rxdemo.xg interface file, and also #includes another Rxgen-generated file, | |
5944 | * rxdemo.h. | |
5945 | * | |
5946 | * \code | |
5947 | * /*======================================================================% | |
5948 | * * % THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED % | |
5949 | * * % WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF % | |
5950 | * * % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. % | |
5951 | * * %====================================================================== */ | |
5952 | * /* Machine generated file --Do NOT edit */ | |
5953 | * | |
5954 | * #include "rxdemo.h" | |
5955 | * #define RXDEMO_CODE_WRITE_ERROR 4 | |
5956 | * | |
5957 | * #include <rx/rx.h> | |
5958 | * #include <rx/rx_null.h> | |
5959 | * #define RXDEMO_SERVER_PORT 8000 /* Service port to advertise */ | |
5960 | * #define RXDEMO_SERVICE_PORT 0 /* User server's port */ | |
5961 | * #define RXDEMO_SERVICE_ID 4 /* Service ID */ | |
5962 | * #define RXDEMO_NULL_SECOBJ_IDX 0 /* Index of null security object */ | |
5963 | * #define RXDEMO_MAX 3 | |
5964 | * #define RXDEMO_MIN 2 | |
5965 | * #define RXDEMO_NULL 0 | |
5966 | * #define RXDEMO_NAME_MAX_CHARS 64 | |
5967 | * #define RXDEMO_BUFF_BYTES 512 | |
5968 | * #define RXDEMO_CODE_SUCCESS 0 | |
5969 | * #define RXDEMO_CODE_CANT_OPEN 1 | |
5970 | * #define RXDEMO_CODE_CANT_STAT 2 | |
5971 | * #define RXDEMO_CODE_CANT_READ 3 | |
5972 | * #define RXDEMO_CODE_WRITE_ERROR 4 | |
5973 | * \endcode | |
5974 | * | |
5975 | * \par | |
5976 | * The next code fragment defines the client-side stub for the RXDEMO Add() | |
5977 | * routine, called by the rxdemo client program to execute the associated RPC. | |
5978 | * | |
5979 | * \code | |
5980 | * int RXDEMO_Add(z_conn, a, b, result) register struct rx_connection *z_conn; | |
5981 | * int a, b; | |
5982 | * int * result; | |
5983 | * { | |
5984 | * struct rx_call *z_call = rx_NewCall(z_conn); | |
5985 | * static int z_op = 1; | |
5986 | * int z_result; | |
5987 | * XDR z_xdrs; | |
5988 | * xdrrx_create(&z_xdrs, z_call, XDR_ENCODE); | |
5989 | * /* Marshal the arguments */ | |
5990 | * if ((!xdr_int(&z_xdrs, &z_op)) | |
5991 | * || (!xdr_int(&z_xdrs, &a)) | |
5992 | * || (!xdr_int(&z_xdrs, &b))) { | |
5993 | * z_result = RXGEN_CC_MARSHAL; | |
5994 | * goto fail; | |
5995 | * } | |
5996 | * /* Un-marshal the reply arguments */ | |
5997 | * z_xdrs.x_op = XDR_DECODE; | |
5998 | * if ((!xdr_int(&z_xdrs, result))) { | |
5999 | * z_result = RXGEN_CC_UNMARSHAL; | |
6000 | * goto fail; | |
6001 | * } | |
6002 | * z_result = RXGEN_SUCCESS; | |
6003 | * fail: return rx_EndCall(z_call, z_result); | |
6004 | * } | |
6005 | * \endcode | |
6006 | * | |
6007 | * \par | |
6008 | * The very first operation performed by RXDEMO Add() occurs in the local | |
6009 | * variable declarations, where z call is set to point to the structure | |
6010 | * describing a newly-created Rx call on the given connection. An XDR | |
6011 | * structure, z xdrs, is then created for the given Rx call with xdrrx | |
6012 | * create(). This XDR object is used to deliver the proper arguments, in | |
6013 | * network byte order, to the matching server stub code. Three calls to xdr | |
6014 | * int() follow, which insert the appropriate Rx opcode and the two operands | |
6015 | * into the Rx call. With the IN arguments thus transmitted, RXDEMO Add() | |
6016 | * prepares to pull the value of the single OUT parameter. The z xdrs XDR | |
6017 | * structure, originally set to XDR ENCODE objects, is now reset to XDR DECODE | |
6018 | * to convert further items received into host byte order. Once the return | |
6019 | * parameter promised by the function is retrieved, RXDEMO Add() returns | |
6020 | * successfully. | |
6021 | * \par | |
6022 | * Should any failure occur in passing the parameters to and from the server | |
6023 | * side of the call, the branch to fail will invoke Rx EndCall(), which advises | |
6024 | * the server that the call has come to a premature end (see Section 5.6.6 for | |
6025 | * full details on rx EndCall() and the meaning of its return value). | |
6026 | * \par | |
6027 | * The next client-side stub appearing in this generated file handles the | |
6028 | * delivery of the IN parameters for StartRXDEMO Getfile(). It operates | |
6029 | * identically as the RXDEMO Add() stub routine in this respect, except that it | |
6030 | * does not attempt to retrieve the OUT parameter. Since this is a streamed | |
6031 | * call, the number of bytes that will be placed on the Rx stream cannot be | |
6032 | * determined at compile time, and must be handled explicitly by rxdemo | |
6033 | * client.c. | |
6034 | * | |
6035 | * \code | |
6036 | * int StartRXDEMO_Getfile(z_call, a_nameToRead) | |
6037 | * register struct rx_call *z_call; | |
6038 | * char * a_nameToRead; | |
6039 | * { | |
6040 | * static int z_op = 2; | |
6041 | * int z_result; | |
6042 | * XDR z_xdrs; | |
6043 | * xdrrx_create(&z_xdrs, z_call, XDR_ENCODE); | |
6044 | * /* Marshal the arguments */ | |
6045 | * if ((!xdr_int(&z_xdrs, &z_op)) || (!xdr_string(&z_xdrs, &a_nameToRead, | |
6046 | * RXDEMO_NAME_MAX_CHARS))) { | |
6047 | * z_result = RXGEN_CC_MARSHAL; | |
6048 | * goto fail; | |
6049 | * } | |
6050 | * z_result = RXGEN_SUCCESS; | |
6051 | * fail: return z_result; | |
6052 | * } | |
6053 | * \endcode | |
6054 | * | |
6055 | * \par | |
6056 | * The final stub routine appearing in this generated file, EndRXDEMO | |
6057 | * Getfile(), handles the case where rxdemo client.c has already successfully | |
6058 | * recovered the unbounded streamed data appearing on the call, and then simply | |
6059 | * has to fetch the OUT parameter. This routine behaves identially to the | |
6060 | * latter portion of RXDEMO Getfile(). | |
6061 | * | |
6062 | * \code | |
6063 | * int EndRXDEMO_Getfile(z_call, a_result) | |
6064 | * register struct rx_call *z_call; | |
6065 | * int * a_result; | |
6066 | * { | |
6067 | * int z_result; | |
6068 | * XDR z_xdrs; | |
6069 | * /* Un-marshal the reply arguments */ | |
6070 | * xdrrx_create(&z_xdrs, z_call, XDR_DECODE); | |
6071 | * if ((!xdr_int(&z_xdrs, a_result))) { | |
6072 | * z_result = RXGEN_CC_UNMARSHAL; | |
6073 | * goto fail; | |
6074 | * } | |
6075 | * z_result = RXGEN_SUCCESS; fail: | |
6076 | * return z_result; | |
6077 | * } | |
6078 | * \endcode | |
6079 | * | |
6080 | * \subsection sec6-3-2 Server-Side Routines: rxdemo.ss.c | |
6081 | * | |
6082 | * \par | |
6083 | * This generated file provides the core components required to implement the | |
6084 | * server side of the rxdemo RPC service. Included in this file is the | |
6085 | * generated dispatcher routine, RXDEMO ExecuteRequest(), which the rx | |
6086 | * NewService() invocation in rxdemo server.c uses to construct the body of | |
6087 | * each listener thread's loop. Also included are the server-side stubs to | |
6088 | * handle marshalling and unmarshalling of parameters for each defined RPC call | |
6089 | * (i.e., RXDEMO Add() and RXDEMO Getfile()). These stubs are called by RXDEMO | |
6090 | * ExecuteRequest(). The routine to be called by RXDEMO ExecuteRequest() | |
6091 | * depends on the opcode received, which appears as the very first longword in | |
6092 | * the call data. | |
6093 | * \par | |
6094 | * As usual, the first fragment is copyright information followed by the body | |
6095 | * of the definitions from the interface file. | |
6096 | * | |
6097 | * \code | |
6098 | * /*======================================================================% | |
6099 | * % Edward R. Zayas % % Transarc Corporation % % % % % % The United States | |
6100 | * Government has rights in this work pursuant % % to contract no. | |
6101 | * MDA972-90-C-0036 between the United States Defense % % Advanced Research | |
6102 | * Projects Agency and Transarc Corporation. % % % % (C) Copyright 1991 | |
6103 | * Transarc Corporation % % % % Redistribution and use in source and binary | |
6104 | * forms are permitted % % provided that: (1) source distributions retain | |
6105 |