OpenAFS
OpenAFS distributed network file system
/cygdrive/c/src/openafs/openafs.git/repo/doc/protocol/rx-spec.h
00001 
00356  *      LWP_DispatchProcess(); 
00357  *      for     (;;) 
00358  *      {  
00359  *              /* Wait until there is something in the queue */
00360  *              while   (empty(q)) LWP_WaitProcess(q); 
00361  *              /* Process the newly-arrived queue entry */
00362  *              LWP_DispatchProcess(); 
00363  *      } 
00364  * } 
00365  * \endcode
00366  * 
00367  * \par
00368  * The next routine, write process(), sits in a loop, putting messages on the
00369  * shared queue and signalling the reader, which is waiting for activity on the
00370  * queue. Signalling a thread is accomplished via the LWP SignalProcess()
00371  * library routine. 
00372  * 
00373  * \code
00374  * static write_process() 
00375  * { ... 
00376  *      /* Loop, writing data to the shared queue.  */
00377  *      for     (mesg = messages; *mesg != 0; mesg++) 
00378  *      { 
00379  *              insert(q, *mesg); 
00380  *              LWP_SignalProcess(q); 
00381  *      } 
00382  * } 
00383  * \endcode
00384  * 
00385  * \par
00386  * finally, here is the main routine for this demo pseudocode. It starts by
00387  * calling the LWP initialization routine. Next, it creates some number of
00388  * reader threads with calls to LWP CreateProcess() in addition to the single
00389  * writer thread. When all threads terminate, they will signal the main routine
00390  * on the done variable. Once signalled, the main routine will reap all the
00391  * threads with the help of the LWP DestroyProcess() function. 
00392  * 
00393  * \code
00394  * main(argc, argv) 
00395  * int argc; 
00396  * char **argv; 
00397  * { 
00398  *      PROCESS *id;  /* Initial thread ID */
00399  *      /* Set up the LWP package, create the initial thread ID. */
00400  *      LWP_InitializeProcessSupport(0, &id); 
00401  *      /* Create a set of reader threads.  */
00402  *      for (i = 0; i < nreaders; i++) 
00403  *              LWP_CreateProcess(read_process, STACK_SIZE, 0, i, "Reader",
00404  *              &readers[i]); 
00405  * 
00406  *      /* Create a single writer thread.  */
00407  *      LWP_CreateProcess(write_process, STACK_SIZE, 1, 0, "Writer", &writer); 
00408  *      /* Wait for all the above threads to terminate.  */
00409  *      for (i = 0; i <= nreaders; i++) 
00410  *              LWP_WaitProcess(&done); 
00411  * 
00412  *      /* All threads are done. Destroy them all.  */
00413  *      for (i = nreaders-1; i >= 0; i--) 
00414  *              LWP_DestroyProcess(readers[i]); 
00415  * } 
00416  * \endcode
00417  * 
00418  *      \subsection sec2-2-2 Section 2.2.2: Locking 
00419  * \par
00420  * The LWP locking facility exports a number of routines and macros that allow
00421  * a C programmer using LWP threading to place read and write locks on shared
00422  * data structures.  This locking facility was also written with simplicity in
00423  * mind. 
00424  * \par
00425  * In order to invoke the locking mechanism, an object of type struct Lock must
00426  * be associated with the object. After being initialized with a call to
00427  * LockInit(), the lock object is used in invocations of various macros,
00428  * including ObtainReadLock(), ObtainWriteLock(), ReleaseReadLock(),
00429  * ReleaseWriteLock(), ObtainSharedLock(), ReleaseSharedLock(), and
00430  * BoostSharedLock(). 
00431  * \par
00432  * Lock semantics specify that any number of readers may hold a lock in the
00433  * absence of a writer. Only a single writer may acquire a lock at any given
00434  * time. The lock package guarantees fairness, legislating that each reader and
00435  * writer will eventually obtain a given lock. However, this fairness is only
00436  * guaranteed if the priorities of the competing processes are identical. Note
00437  * that ordering is not guaranteed by this package. 
00438  * \par
00439  * Shared locks are read locks that can be "boosted" into write locks. These
00440  * shared locks have an unusual locking matrix. Unboosted shared locks are
00441  * compatible with read locks, yet incompatible with write locks and other
00442  * shared locks. In essence, a thread holding a shared lock on an object has
00443  * effectively read-locked it, and has the option to promote it to a write lock
00444  * without allowing any other writer to enter the critical region during the
00445  * boost operation itself. 
00446  * \par
00447  * It is illegal for a process to request a particular lock more than once
00448  * without first releasing it. Failure to obey this restriction will cause
00449  * deadlock. This restriction is not enforced by the LWP code. 
00450  * \par
00451  * Here is a simple pseudocode fragment serving as an example of the available
00452  * locking operations. It defines a struct Vnode object, which contains a lock
00453  * object. The get vnode() routine will look up a struct Vnode object by name,
00454  * and then either read-lock or write-lock it. 
00455  * \par
00456  * As with the high-level LWP example above, the locking routines introduced
00457  * here will be fully defined later, in Section 2.3.2. 
00458  * 
00459  * \code
00460  * #include <afs/lock.h> 
00461  * 
00462  * struct Vnode { 
00463  *      ... 
00464  *      struct Lock lock;  Used to lock this vnode  
00465  * ... }; 
00466  * 
00467  * #define READ 0 
00468  * #define WRITE 1 
00469  * 
00470  * struct Vnode *get_vnode(name, how) char *name; 
00471  * int how; 
00472  * { 
00473  *      struct Vnode *v; 
00474  *      v = lookup(name); 
00475  *      if (how == READ) 
00476  *              ObtainReadLock(&v->lock); 
00477  *      else 
00478  *              ObtainWriteLock(&v->lock); 
00479  * } 
00480  * \endcode
00481  * 
00482  * 
00483  *      \subsection sec2-2-3 Section 2.2.3: IOMGR 
00484  * 
00485  * \par
00486  * The IOMGR facility associated with the LWP service allows threads to wait on
00487  * various unix events. The exported IOMGR Select() routine allows a thread to
00488  * wait on the same set of events as the unix select() call. The parameters to
00489  * these two routines are identical. IOMGR Select() puts the calling LWP to
00490  * sleep until no threads are active. At this point, the built-in IOMGR thread,
00491  * which runs at the lowest priority, wakes up and coalesces all of the select
00492  * requests together. It then performs a single select() and wakes up all
00493  * threads affected by the result. 
00494  * \par
00495  * The IOMGR Signal() routine allows an LWP to wait on the delivery of a unix
00496  * signal. The IOMGR thread installs a signal handler to catch all deliveries
00497  * of the unix signal. This signal handler posts information about the signal
00498  * delivery to a global data structure. The next time that the IOMGR thread
00499  * runs, it delivers the signal to any waiting LWP. 
00500  * \par
00501  * Here is a pseudocode example of the use of the IOMGR facility, providing the
00502  * blueprint for an implemention a thread-level socket listener. 
00503  * 
00504  * \code
00505  * void rpc_SocketListener() 
00506  * { 
00507  *      int ReadfdMask, WritefdMask, ExceptfdMask, rc; 
00508  *      struct timeval *tvp; 
00509  *      while(TRUE) 
00510  *      { ... 
00511  *              ExceptfdMask = ReadfdMask = (1 << rpc_RequestSocket); 
00512  *              WritefdMask = 0; 
00513  * 
00514  *              rc = IOMGR_Select(8*sizeof(int), &ReadfdMask, &WritefdMask,
00515  *              &ExceptfdMask, tvp); 
00516  * 
00517  *              switch(rc) 
00518  *              { 
00519  *                      case 0: /* Timeout */ continue; 
00520  *                      /* Main while loop */
00521  * 
00522  *                      case -1: /* Error */ 
00523  *                      SystemError("IOMGR_Select"); 
00524  *                      exit(-1); 
00525  * 
00526  *                      case 1: /* RPC packet arrived! */ ... 
00527  *                      process packet ... 
00528  *                      break; 
00529  * 
00530  *                      default: Should never occur 
00531  *              } 
00532  *      } 
00533  * } 
00534  * \endcode
00535  * 
00536  *      \subsection sec2-2-4 Section 2.2.4: Timer 
00537  * \par
00538  * The timer package exports a number of routines that assist in manipulating
00539  * lists of objects of type struct TM Elem. These struct TM Elem timers are
00540  * assigned a timeout value by the user and inserted in a package-maintained
00541  * list. The time remaining to each timer's timeout is kept up to date by the
00542  * package under user control. There are routines to remove a timer from its
00543  * list, to return an expired timer from a list, and to return the next timer
00544  * to expire. 
00545  * \par
00546  * A timer is commonly used by inserting a field of type struct TM Elem into a
00547  * structure. After setting the desired timeout value, the structure is
00548  * inserted into a list by means of its timer field. 
00549  * \par
00550  * Here is a simple pseudocode example of how the timer package may be used.
00551  * After calling the package initialization function, TM Init(), the pseudocode
00552  * spins in a loop. first, it updates all the timers via TM Rescan() calls.
00553  * Then, it pulls out the first expired timer object with TM GetExpired() (if
00554  * any), and processes it. 
00555  * 
00556  * \code
00557  * static struct TM_Elem *requests; 
00558  * ... 
00559  * TM_Init(&requests); /* Initialize timer list */ ... 
00560  * for (;;) { 
00561  *      TM_Rescan(requests);  /* Update the timers */
00562  *      expired = TM_GetExpired(requests); 
00563  *      if (expired == 0) 
00564  *      break; 
00565  *      . . . process expired element . . . 
00566  *      } 
00567  * \endcode
00568  * 
00569  *      \subsection sec2-2-5 Section 2.2.5: Fast Time 
00570  * 
00571  * \par
00572  * The fast time routines allows a caller to determine the current time of day
00573  * without incurring the expense of a kernel call. It works by mapping the page
00574  * of the kernel that holds the time-of-day variable and examining it directly.
00575  * Currently, this package only works on Suns. The routines may be called on
00576  * other architectures, but they will run more slowly. 
00577  * \par
00578  * The initialization routine for this package is fairly expensive, since it
00579  * does a lookup of a kernel symbol via nlist(). If the client application
00580  * program only runs for only a short time, it may wish to call FT Init() with
00581  * the notReally parameter set to TRUE in order to prevent the lookup from
00582  * taking place. This is useful if you are using another package that uses the
00583  * fast time facility. 
00584  * 
00585  *      \subsection sec2-2-6 Section 2.2.6: Preemption 
00586  * 
00587  * \par
00588  * The preemption package provides a mechanism by which control can pass
00589  * between lightweight processes without the need for explicit calls to LWP
00590  * DispatchProcess(). This effect is achieved by periodically interrupting the
00591  * normal flow of control to check if other (higher priority) procesess are
00592  * ready to run. 
00593  * \par
00594  * The package makes use of the BSD interval timer facilities, and so will
00595  * cause programs that make their own use of these facilities to malfunction.
00596  * In particular, use of alarm(3) or explicit handling of SIGALRM is
00597  * disallowed. Also, calls to sleep(3) may return prematurely. 
00598  * \par
00599  * Care should be taken that routines are re-entrant where necessary. In
00600  * particular, note that stdio(3) is not re-entrant in general, and hence
00601  * multiple threads performing I/O on the same fiLE structure may function
00602  * incorrectly. 
00603  * \par
00604  * An example pseudocode routine illustrating the use of this preemption
00605  * facility appears below. 
00606  * 
00607  * \code
00608  * #include <sys/time.h> 
00609  * #include "preempt.h" 
00610  *      ...  struct timeval tv; 
00611  *      LWP_InitializeProcessSupport( ... ); 
00612  *      tv.tv_sec = 10; 
00613  *      tv.tv_usec = 0; 
00614  *      PRE_InitPreempt(&tv); 
00615  *      PRE_PreemptMe(); ... 
00616  *      PRE_BeginCritical(); ... 
00617  *      PRE_EndCritical(); ... 
00618  *      PRE_EndPreempt(); 
00619  * \endcode
00620  * 
00621  *      \section sec2-3 Section 2.3: Interface Specifications 
00622  * 
00623  *      \subsection sec2-3-1 Section 2.3.1: LWP 
00624  * 
00625  * \par
00626  * This section covers the calling interfaces to the LWP package. Please note
00627  * that LWP macros (e.g., ActiveProcess) are also included here, rather than
00628  * being relegated to a different section. 
00629  * 
00630  *      \subsubsection sec2-3-1-1 Section 2.3.1.1: LWP_InitializeProcessSupport
00631  *      _ Initialize the LWP package 
00632  * 
00633  * \par
00634  * int LWP_InitializeProcessSupport(IN int priority; OUT PROCESS *pid) 
00635  * \par Description 
00636  * This function initializes the LWP package. In addition, it turns the current
00637  * thread of control into the initial process with the specified priority. The
00638  * process ID of this initial thread is returned in the pid parameter. This
00639  * routine must be called before any other routine in the LWP library. The
00640  * scheduler will NOT be invoked as a result of calling
00641  * LWP_InitializeProcessSupport(). 
00642  * \par Error Codes 
00643  * LWP EBADPRI The given priority is invalid, either negative or too large. 
00644  * 
00645  *       \subsubsection sec2-3-1-2 Section 2.3.1.2: LWP_TerminateProcessSupport
00646  *       _ End process support, perform cleanup 
00647  * 
00648  * \par
00649  * int LWP_TerminateProcessSupport() 
00650  * \par Description 
00651  * This routine terminates the LWP threading support and cleans up after it by
00652  * freeing any auxiliary storage used. This routine must be called from within
00653  * the process that invoked LWP InitializeProcessSupport(). After LWP
00654  * TerminateProcessSupport() has been called, it is acceptable to call LWP
00655  * InitializeProcessSupport() again in order to restart LWP process support. 
00656  * \par Error Codes 
00657  * ---Always succeeds, or performs an abort(). 
00658  * 
00659  *      \subsubsection sec2-3-1-3 Section 2.3.1.3: LWP_CreateProcess _ Create a
00660  *      new thread 
00661  * 
00662  * \par
00663  * int LWP_CreateProcess(IN int (*ep)(); IN int stacksize; IN int priority; IN
00664  * char *parm; IN char *name; OUT PROCESS *pid) 
00665  * \par Description 
00666  * This function is used to create a new lightweight process with a given
00667  * printable name. The ep argument identifies the function to be used as the
00668  * body of the thread. The argument to be passed to this function is contained
00669  * in parm. The new thread's stack size in bytes is specified in stacksize, and
00670  * its execution priority in priority. The pid parameter is used to return the
00671  * process ID of the new thread. 
00672  * \par
00673  * If the thread is successfully created, it will be marked as runnable. The
00674  * scheduler is called before the LWP CreateProcess() call completes, so the
00675  * new thread may indeed begin its execution before the completion. Note that
00676  * the new thread is guaranteed NOT to run before the call completes if the
00677  * specified priority is lower than the caller's. On the other hand, if the new
00678  * thread's priority is higher than the caller's, then it is guaranteed to run
00679  * before the creation call completes. 
00680  * \par Error Codes 
00681  * LWP EBADPRI The given priority is invalid, either negative or too large. 
00682  * \n LWP NOMEM Could not allocate memory to satisfy the creation request. 
00683  * 
00684  *      \subsubsection sec2-3-1-4 Section: 2.3.1.4: LWP_DestroyProcess _ Create
00685  *      a new thread 
00686  * 
00687  * \par
00688  * int LWP_DestroyProcess(IN PROCESS pid) 
00689  * \par Description 
00690  * This routine destroys the thread identified by pid. It will be terminated
00691  * immediately, and its internal storage will be reclaimed. A thread is allowed
00692  * to destroy itself. In this case, of course, it will only get to see the
00693  * return code if the operation fails. Note that a thread may also destroy
00694  * itself by returning from the parent C routine. 
00695  * \par
00696  * The scheduler is called by this operation, which may cause an arbitrary
00697  * number of threads to execute before the caller regains the processor. 
00698  * \par Error Codes 
00699  * LWP EINIT The LWP package has not been initialized. 
00700  * 
00701  *      \subsubsection sec2-3-1-5 Section 2.3.1.5: WaitProcess _ Wait on an
00702  *      event 
00703  * 
00704  * \par
00705  * int LWP WaitProcess(IN char *event) 
00706  * \par Description 
00707  * This routine puts the thread making the call to sleep until another LWP
00708  * calls the LWP SignalProcess() or LWP NoYieldSignal() routine with the
00709  * specified event. Note that signalled events are not queued. If a signal
00710  * occurs and no thread is awakened, the signal is lost. The scheduler is
00711  * invoked by the LWP WaitProcess() routine. 
00712  * \par Error Codes 
00713  * LWP EINIT The LWP package has not been initialized. 
00714  * \n LWP EBADEVENT The given event pointer is null. 
00715  * 
00716  *      \subsubsection sec2-3-1-6 Section 2.3.1.6: MwaitProcess _ Wait on a set
00717  *      of events 
00718  * 
00719  * \par
00720  * int LWP MwaitProcess(IN int wcount; IN char *evlist[]) 
00721  * \par Description 
00722  * This function allows a thread to wait for wcount signals on any of the items
00723  * in the given evlist. Any number of signals of a particular event are only
00724  * counted once. The evlist is a null-terminated list of events to wait for.
00725  * The scheduler will be invoked. 
00726  * \par Error Codes 
00727  * LWP EINIT The LWP package has not been initialized. 
00728  * \n LWP EBADCOUNT An illegal number of events has been supplied. 
00729  * 
00730  *      \subsubsection sec2-3-1-7 Section 2.3.1.7: SignalProcess _ Signal an
00731  *      event 
00732  * 
00733  * \par
00734  * int LWP SignalProcess(IN char *event) 
00735  * \par Description 
00736  * This routine causes the given event to be signalled. All threads waiting for
00737  * this event (exclusively) will be marked as runnable, and the scheduler will
00738  * be invoked. Note that threads waiting on multiple events via LWP
00739  * MwaitProcess() may not be marked as runnable. Signals are not queued.
00740  * Therefore, if no thread is waiting for the signalled event, the signal will
00741  * be lost. 
00742  * \par Error Codes 
00743  * LWP EINIT The LWP package has not been initialized. LWP EBADEVENT A null
00744  * event pointer has been provided. LWP ENOWAIT No thread was waiting on the
00745  * given event. 
00746  * 
00747  *      \subsubsection sec2-3-1-8 Section 2.3.1.8: NoYieldSignal _ Signal an
00748  *      event without invoking scheduler 
00749  * 
00750  * \par
00751  * int LWP NoYieldSignal(IN char *event) 
00752  * \par Description 
00753  * This function is identical to LWP SignalProcess() except that the scheduler
00754  * will not be invoked. Thus, control will remain with the signalling process. 
00755  * \par Error Codes 
00756  * LWP EINIT The LWP package has not been initialized. LWP EBADEVENT A null
00757  * event pointer has been provided. LWP ENOWAIT No thread was waiting on the
00758  * given event. 
00759  * 
00760  *      \subsubsection sec2-3-1-9 Section 2.3.1.9: DispatchProcess _ Yield
00761  *      control to the scheduler 
00762  * 
00763  * \par
00764  * int LWP DispatchProcess() 
00765  * \par Description 
00766  * This routine causes the calling thread to yield voluntarily to the LWP
00767  * scheduler. If no other thread of appropriate priority is marked as runnable,
00768  * the caller will continue its execution. 
00769  * \par Error Codes 
00770  * LWP EINIT The LWP package has not been initialized. 
00771  * 
00772  *      \subsubsection sec2-3-1-10 Section 2.3.1.10: CurrentProcess _ Get the
00773  *      current thread's ID 
00774  * 
00775  * \par
00776  * int LWP CurrentProcess(IN PROCESS *pid) 
00777  * \par Description 
00778  * This call places the current lightweight process ID in the pid parameter. 
00779  * \par Error Codes 
00780  * LWP EINIT The LWP package has not been initialized. 
00781  * 
00782  *      \subsubsection sec2-3-1-11 Section 2.3.1.11: ActiveProcess _ Get the
00783  *      current thread's ID (macro) 
00784  * 
00785  * \par
00786  * int LWP ActiveProcess() 
00787  * \par Description 
00788  * This macro's value is the current lightweight process ID. It generates a
00789  * value identical to that acquired by calling the LWP CurrentProcess()
00790  * function described above if the LWP package has been initialized. If no such
00791  * initialization has been done, it will return a value of zero. 
00792  * 
00793  *      \subsubsection sec2-3-1-12 Section: 2.3.1.12: StackUsed _ Calculate
00794  *      stack usage 
00795  * 
00796  * \par
00797  * int LWP StackUsed(IN PROCESS pid; OUT int *max; OUT int *used) 
00798  * \par Description 
00799  * This function returns the amount of stack space allocated to the thread
00800  * whose identifier is pid, and the amount actually used so far. This is
00801  * possible if the global variable lwp stackUseEnabled was TRUE when the thread
00802  * was created (it is set this way by default). If so, the thread's stack area
00803  * was initialized with a special pattern. The memory still stamped with this
00804  * pattern can be determined, and thus the amount of stack used can be
00805  * calculated. The max parameter is always set to the thread's stack allocation
00806  * value, and used is set to the computed stack usage if lwp stackUseEnabled
00807  * was set when the process was created, or else zero. 
00808  * \par Error Codes 
00809  * LWP NO STACK Stack usage was not enabled at thread creation time. 
00810  * 
00811  *      \subsubsection sec2-3-1-13 Section 2.3.1.13: NewRock _ Establish
00812  *      thread-specific storage 
00813  * 
00814  * \par
00815  * int LWP NewRock (IN int tag; IN char **value)
00816  * \par Description
00817  * This function establishes a "rock", or thread-specific information,
00818  * associating it with the calling LWP. The tag is intended to be any unique
00819  * integer value, and the value is a pointer to a character array containing
00820  * the given data. 
00821  * \par
00822  * Users of the LWP package must coordinate their choice of tag values. Note
00823  * that a tag's value cannot be changed. Thus, to obtain a mutable data
00824  * structure, another level of indirection is required. Up to MAXROCKS (4)
00825  * rocks may be associated with any given thread. 
00826  * \par Error Codes
00827  * ENOROCKS A rock with the given tag field already exists. All of the MAXROCKS
00828  * are in use. 
00829  * 
00830  * 
00831  *      \subsubsection sec2-3-1-14 Section: 2.3.1.14: GetRock _ Retrieve
00832  *      thread-specific storage 
00833  * 
00834  * \par
00835  * int LWP GetRock(IN int tag; OUT **value) 
00836  * \par Description 
00837  * This routine recovers the thread-specific information associated with the
00838  * calling process and the given tag, if any. Such a rock had to be established
00839  * through a LWP NewRock() call. The rock's value is deposited into value. 
00840  * \par Error Codes 
00841  * LWP EBADROCK A rock has not been associated with the given tag for this
00842  * thread. 
00843  * 
00844  *      \subsection sec2-3-2 Section 2.3.2: Locking 
00845  * 
00846  * \par
00847  * This section covers the calling interfaces to the locking package. Many of
00848  * the user-callable routines are actually implemented as macros. 
00849  * 
00850  *      \subsubsection sec2-3-2-1 Section 2.3.2.1: Lock Init _ Initialize lock
00851  *      structure 
00852  * 
00853  * \par
00854  * void Lock Init(IN struct Lock *lock) 
00855  * \par Description 
00856  * This function must be called on the given lock object before any other
00857  * operations can be performed on it. 
00858  * \par Error Codes 
00859  * ---No value is returned. 
00860  * 
00861  *      \subsubsection sec2-3-2-2 Section 2.3.2.2: ObtainReadLock _ Acquire a
00862  *      read lock 
00863  * 
00864  * \par
00865  * void ObtainReadLock(IN struct Lock *lock) 
00866  * \par Description 
00867  * This macro obtains a read lock on the specified lock object. Since this is a
00868  * macro and not a function call, results are not predictable if the value of
00869  * the lock parameter is a side-effect producing expression, as it will be
00870  * evaluated multiple times in the course of the macro interpretation. 
00871  * Read locks are incompatible with write, shared, and boosted shared locks. 
00872  * \par Error Codes 
00873  * ---No value is returned. 
00874  * 
00875  *      \subsubsection sec2-3-2-3 Section 2.3.2.3: ObtainWriteLock _ Acquire a
00876  *      write lock 
00877  * 
00878  * \par
00879  * void ObtainWriteLock(IN struct Lock *lock) 
00880  * \par Description 
00881  * This macro obtains a write lock on the specified lock object. Since this is
00882  * a macro and not a function call, results are not predictable if the value of
00883  * the lock parameter is a side-effect producing expression, as it will be
00884  * evaluated multiple times in the course of the macro interpretation. 
00885  * \par
00886  * Write locks are incompatible with all other locks. 
00887  * \par Error Codes 
00888  * ---No value is returned. 
00889  * 
00890  *      \subsubsection sec2-3-2-4 Section 2.3.2.4: ObtainSharedLock _ Acquire a
00891  *      shared lock 
00892  * 
00893  * \par
00894  * void ObtainSharedLock(IN struct Lock *lock) 
00895  * \par Description 
00896  * This macro obtains a shared lock on the specified lock object. Since this is
00897  * a macro and not a function call, results are not predictable if the value of
00898  * the lock parameter is a side-effect producing expression, as it will be
00899  * evaluated multiple times in the course of the macro interpretation. 
00900  * \par
00901  * Shared locks are incompatible with write and boosted shared locks, but are
00902  * compatible with read locks. 
00903  * \par Error Codes 
00904  * ---No value is returned. 
00905  * 
00906  *      \subsubsection sec2-3-2-5 Section 2.3.2.5: ReleaseReadLock _ Release
00907  *      read lock 
00908  * 
00909  * \par
00910  * void ReleaseReadLock(IN struct Lock *lock) 
00911  * \par Description 
00912  * This macro releases the specified lock. The lock must have been previously
00913  * read-locked. Since this is a macro and not a function call, results are not
00914  * predictable if the value of the lock parameter is a side-effect producing
00915  * expression, as it will be evaluated multiple times in the course of the
00916  * macro interpretation. The results are also unpredictable if the lock was not
00917  * previously read-locked by the thread calling ReleaseReadLock(). 
00918  * \par Error Codes 
00919  * ---No value is returned. 
00920  * 
00921  *      \subsubsection sec2-3-2-6 Section 2.3.2.6: ReleaseWriteLock _ Release
00922  *      write lock 
00923  * 
00924  * \par
00925  * void ReleaseWriteLock(IN struct Lock *lock) 
00926  * \par Description 
00927  * This macro releases the specified lock. The lock must have been previously
00928  * write-locked. Since this is a macro and not a function call, results are not
00929  * predictable if the value of the lock parameter is a side-effect producing
00930  * expression, as it will be evaluated multiple times in the course of the
00931  * macro interpretation. The results are also unpredictable if the lock was not
00932  * previously write-locked by the thread calling ReleaseWriteLock(). 
00933  * \par Error Codes 
00934  * ---No value is returned. 
00935  * 
00936  *      \subsubsection sec2-3-2-7 Section 2.3.2.7: ReleaseSharedLock _ Release
00937  *      shared lock 
00938  * 
00939  * \par
00940  * void ReleaseSharedLock(IN struct Lock *lock) 
00941  * \par Description 
00942  * This macro releases the specified lock. The lock must have been previously
00943  * share-locked. Since this is a macro and not a function call, results are not
00944  * predictalbe if the value of the lock parameter is a side-effect producing
00945  * expression, as it will be evaluated multiple times in the course of the
00946  * macro interpretation. The results are also unpredictable if the lock was not
00947  * previously share-locked by the thread calling ReleaseSharedLock(). 
00948  * \par Error Codes 
00949  * ---No value is returned. 
00950  * 
00951  *      \subsubsection sec2-3-2-8 Section 2.3.2.8: CheckLock _ Determine state
00952  *      of a lock 
00953  * 
00954  * \par
00955  * void CheckLock(IN struct Lock *lock) 
00956  * \par Description 
00957  * This macro produces an integer that specifies the status of the indicated
00958  * lock. The value will be -1 if the lock is write-locked, 0 if unlocked, or
00959  * otherwise a positive integer that indicates the number of readers (threads
00960  * holding read locks). Since this is a macro and not a function call, results
00961  * are not predictable if the value of the lock parameter is a side-effect
00962  * producing expression, as it will be evaluated multiple times in the course
00963  * of the macro interpretation. 
00964  * \par Error Codes 
00965  * ---No value is returned. 
00966  * 
00967  *      \subsubsection sec2-3-2-9 Section 2.3.2.9: BoostLock _ Boost a shared
00968  *      lock 
00969  * 
00970  * \par
00971  * void BoostLock(IN struct Lock *lock) 
00972  * \par Description 
00973  * This macro promotes ("boosts") a shared lock into a write lock. Such a boost
00974  * operation guarantees that no other writer can get into the critical section
00975  * in the process. Since this is a macro and not a function call, results are
00976  * not predictable if the value of the lock parameter is a side-effect
00977  * producing expression, as it will be evaluated multiple times in the course
00978  * of the macro interpretation. 
00979  * \par Error Codes 
00980  * ---No value is returned. 
00981  * 
00982  *      \subsubsection sec2-3-2-10 Section 2.3.2.10: UnboostLock _ Unboost a
00983  *      shared lock 
00984  * 
00985  * \par
00986  * void UnboostLock(IN struct Lock *lock) 
00987  * \par Description 
00988  * This macro demotes a boosted shared lock back down into a regular shared
00989  * lock. Such an unboost operation guarantees that no other writer can get into
00990  * the critical section in the process. Since this is a macro and not a
00991  * function call, results are not predictable if the value of the lock
00992  * parameter is a side-effect producing expression, as it will be evaluated
00993  * multiple times in the course of the macro interpretation. 
00994  * \par Error Codes 
00995  * ---No value is returned. 
00996  * 
00997  *      \subsection sec2-3-3 Section 2.3.3: IOMGR 
00998  * 
00999  * \par
01000  * This section covers the calling interfaces to the I/O management package. 
01001  * 
01002  *      \subsubsection sec2-3-3-1 Section: 2.3.3.1: IOMGR Initialize _
01003  *      Initialize the package 
01004  * 
01005  * \par
01006  * int IOMGR Initialize() 
01007  * \par Description 
01008  * This function initializes the IOMGR package. Its main task is to create the
01009  * IOMGR thread itself, which runs at the lowest possible priority (0). The
01010  * remainder of the lightweight processes must be running at priority 1 or
01011  * greater (up to a maximum of LWP MAX PRIORITY (4)) for the IOMGR package to
01012  * function correctly. 
01013  * \par Error Codes 
01014  * -1 The LWP and/or timer package haven't been initialized. 
01015  * \n <misc> Any errors that may be returned by the LWP CreateProcess()
01016  * routine. 
01017  * 
01018  *      \subsubsection sec2-3-3-2 Section 2.3.3.2: IOMGR finalize _ Clean up
01019  *      the IOMGR facility 
01020  * 
01021  * \par
01022  * int IOMGR finalize() 
01023  * \par Description 
01024  * This routine cleans up after the IOMGR package when it is no longer needed.
01025  * It releases all storage and destroys the IOMGR thread itself. 
01026  * \par Error Codes 
01027  * <misc> Any errors that may be returned by the LWP DestroyProcess() routine. 
01028  * 
01029  *      \subsubsection sec2-3-3-3 Section 2.3.3.3: IOMGR Select _ Perform a
01030  *      thread-level select() 
01031  * 
01032  * \par
01033  * int IOMGR Select (IN int numfds; IN int *rfds; IN int *wfds; IN int *xfds;
01034  * IN truct timeval *timeout) 
01035  * \par Description 
01036  * This routine performs an LWP version of unix select() operation. The
01037  * parameters have the same meanings as with the unix call. However, the return
01038  * values will be simplified (see below). If this is a polling select (i.e.,
01039  * the value of timeout is null), it is done and the IOMGR Select() function
01040  * returns to the user with the results. Otherwise, the calling thread is put
01041  * to sleep. If at some point the IOMGR thread is the only runnable process, it
01042  * will awaken and collect all select requests. The IOMGR will then perform a
01043  * single select and awaken the appropriate processes. This will force a return
01044  * from the affected IOMGR Select() calls. 
01045  * \par Error Codes 
01046  * -1 An error occurred.
01047  * \n 0 A timeout occurred.
01048  * \n 1 Some number of file descriptors are ready. 
01049  * 
01050  *      \subsubsection sec2-3-3-4 Section 2.3.3.4: IOMGR Signal _ Associate
01051  *      unix and LWP signals 
01052  * 
01053  * \par
01054  * int IOMGR Signal(IN int signo; IN char *event) 
01055  * \par Description 
01056  * This function associates an LWP signal with a unix signal. After this call,
01057  * when the given unix signal signo is delivered to the (heavyweight unix)
01058  * process, the IOMGR thread will deliver an LWP signal to the event via LWP
01059  * NoYieldSignal(). This wakes up any lightweight processes waiting on the
01060  * event. Multiple deliveries of the signal may be coalesced into one LWP
01061  * wakeup. The call to LWP NoYieldSignal() will happen synchronously. It is
01062  * safe for an LWP to check for some condition and then go to sleep waiting for
01063  * a unix signal without having to worry about delivery of the signal happening
01064  * between the check and the call to LWP WaitProcess(). 
01065  * \par Error Codes 
01066  * LWP EBADSIG The signo value is out of range. 
01067  * \n LWP EBADEVENT The event pointer is null. 
01068  * 
01069  *      \subsubsection sec2-3-3-5 Section 2.3.3.5: IOMGR CancelSignal _ Cancel
01070  *      unix and LWP signal association 
01071  * 
01072  * \par
01073  * int IOMGR CancelSignal(IN int signo) 
01074  * \par Description 
01075  * This routine cancels the association between a unix signal and an LWP event.
01076  * After calling this function, the unix signal signo will be handled however
01077  * it was handled before the corresponding call to IOMGR Signal(). 
01078  * \par Error Codes 
01079  * LWP EBADSIG The signo value is out of range. 
01080  * 
01081  *      \subsubsection sec2-3-3-6 Section 2.3.3.6: IOMGR Sleep _ Sleep for a
01082  *      given period 
01083  * 
01084  * \par
01085  * void IOMGR Sleep(IN unsigned seconds) 
01086  * \par Description 
01087  * This function calls IOMGR Select() with zero file descriptors and a timeout
01088  * structure set up to cause the thread to sleep for the given number of
01089  * seconds. 
01090  * \par Error Codes 
01091  * ---No value is returned. 
01092  * 
01093  *      \subsection sec2-3-4 Section 2.3.4: Timer 
01094  * 
01095  * \par
01096  * This section covers the calling interface to the timer package associated
01097  * with the LWP facility. 
01098  * 
01099  *      \subsubsection sec2-3-4-1 Section 2.3.4.1: TM Init _ Initialize a timer
01100  *      list 
01101  * 
01102  * \par
01103  * int TM Init(IN struct TM Elem **list) 
01104  * \par Description 
01105  * This function causes the specified timer list to be initialized. TM Init()
01106  * must be called before any other timer operations are applied to the list. 
01107  * \par Error Codes 
01108  * -1 A null timer list could not be produced. 
01109  * 
01110  *      \subsubsection sec2-3-4-2 Section 2.3.4.2: TM final _ Clean up a timer
01111  *      list 
01112  * 
01113  * \par
01114  * int TM final(IN struct TM Elem **list) 
01115  * \par Description 
01116  * This routine is called when the given empty timer list is no longer needed.
01117  * All storage associated with the list is released. 
01118  * \par Error Codes 
01119  * -1 The list parameter is invalid. 
01120  * 
01121  *      \subsubsection sec2-3-4-3 Section 2.3.4.3: TM Insert _ Insert an object
01122  *      into a timer list
01123  * 
01124  * \par
01125  * void TM Insert(IN struct TM Elem **list; IN struct TM Elem *elem)
01126  * \par Description
01127  * This routine enters an new element, elem, into the list denoted by list.
01128  * Before the new element is queued, its TimeLeft field (the amount of time
01129  * before the object comes due) is set to the value stored in its TotalTime
01130  * field. In order to keep TimeLeft fields current, the TM Rescan() function
01131  * may be used. 
01132  * \par Error Codes 
01133  * ---No return value is generated. 
01134  * 
01135  *      \subsubsection sec2-3-4-4 Section 2.3.4.4: TM Rescan _ Update all
01136  *      timers in the list 
01137  * 
01138  * \par
01139  * int TM Rescan(IN struct TM Elem *list) 
01140  * \par Description 
01141  * This function updates the TimeLeft fields of all timers on the given list.
01142  * This is done by checking the time-of-day clock. Note: this is the only
01143  * routine other than TM Init() that updates the TimeLeft field in the elements
01144  * on the list. 
01145  * \par
01146  * Instead of returning a value indicating success or failure, TM Rescan()
01147  * returns the number of entries that were discovered to have timed out. 
01148  * \par Error Codes 
01149  * ---Instead of error codes, the number of entries that were discovered to
01150  *  have timed out is returned. 
01151  * 
01152  *      \subsubsection sec2-3-4-5 Section 2.3.4.5: TM GetExpired _ Returns an
01153  *      expired timer 
01154  * 
01155  * \par
01156  * struct TM Elem *TM GetExpired(IN struct TM Elem *list) 
01157  * \par Description 
01158  * This routine searches the specified timer list and returns a pointer to an
01159  * expired timer element from that list. An expired timer is one whose TimeLeft
01160  * field is less than or equal to zero. If there are no expired timers, a null
01161  * element pointer is returned. 
01162  * \par Error Codes 
01163  * ---Instead of error codes, an expired timer pointer is returned, or a null
01164  *  timer pointer if there are no expired timer objects. 
01165  * 
01166  *      \subsubsection sec2-3-4-6 Section 2.3.4.6: TM GetEarliest _ Returns
01167  *      earliest unexpired timer 
01168  * 
01169  * \par
01170  * struct TM Elem *TM GetEarliest(IN struct TM Elem *list) 
01171  * \par Description 
01172  * This function returns a pointer to the timer element that will be next to
01173  * expire on the given list. This is defined to be the timer element with the
01174  * smallest (positive) TimeLeft field. If there are no timers on the list, or
01175  * if they are all expired, this function will return a null pointer. 
01176  * \par Error Codes 
01177  * ---Instead of error codes, a pointer to the next timer element to expireis
01178  *  returned, or a null timer object pointer if they are all expired. 
01179  * 
01180  *      \subsubsection sec2-3-4-7 Section 2.3.4.7: TM eql _ Test for equality
01181  *      of two timestamps 
01182  * 
01183  * \par
01184  * bool TM eql(IN struct timemval *t1; IN struct timemval *t2) 
01185  * \par Description 
01186  * This function compares the given timestamps, t1 and t2, for equality. Note
01187  * that the function return value, bool, has been set via typedef to be
01188  * equivalent to unsigned char. 
01189  * \par Error Codes 
01190  * 0 If the two timestamps differ. 
01191  * \n 1 If the two timestamps are identical. 
01192  * 
01193  *      \subsection sec2-3-5 Section 2.3.5: Fast Time 
01194  * \par
01195  * This section covers the calling interface to the fast time package
01196  * associated with the LWP facility. 
01197  * 
01198  *      \subsubsection sec2-3-5-1 Section 2.3.5.1: FT Init _ Initialize the
01199  *      fast time package 
01200  * 
01201  * \par
01202  * int FT Init(IN int printErrors; IN int notReally) 
01203  * \par Description 
01204  * This routine initializes the fast time package, mapping in the kernel page
01205  * containing the time-of-day variable. The printErrors argument, if non-zero,
01206  * will cause any errors in initalization to be printed to stderr. The
01207  * notReally parameter specifies whether initialization is really to be done.
01208  * Other calls in this package will do auto-initialization, and hence the
01209  * option is offered here. 
01210  * \par Error Codes 
01211  * -1 Indicates that future calls to FT GetTimeOfDay() will still work, but
01212  *  will not be able to access the information directly, having to make a
01213  *  kernel call every time. 
01214  * 
01215  *      \subsubsection sec2-3-5-2 Section 2.3.5.2: FT GetTimeOfDay _ Initialize
01216  *      the fast time package 
01217  * 
01218  * \par
01219  * int FT GetTimeOfDay(IN struct timeval *tv; IN struct timezone *tz) 
01220  * \par Description 
01221  * This routine is meant to mimic the parameters and behavior of the unix
01222  * gettimeofday() function. However, as implemented, it simply calls
01223  * gettimeofday() and then does some bound-checking to make sure the value is
01224  * reasonable. 
01225  * \par Error Codes 
01226  * <misc> Whatever value was returned by gettimeofday() internally. 
01227  * 
01228  *      \subsection sec2-3-6 Section 2.3.6: Preemption 
01229  * \par
01230  * This section covers the calling interface to the preemption package
01231  * associated with the LWP facility. 
01232  * 
01233  *      \subsubsection sec2-3-6-1 Section 2.3.6.1: PRE InitPreempt _ Initialize
01234  *      the preemption package 
01235  * 
01236  * \par
01237  * int PRE InitPreempt(IN struct timeval *slice) 
01238  * \par Description 
01239  * This function must be called to initialize the preemption package. It must
01240  * appear sometime after the call to LWP InitializeProcessSupport() and
01241  * sometime before the first call to any other preemption routine. The slice
01242  * argument specifies the time slice size to use. If the slice pointer is set
01243  * to null in the call, then the default time slice, DEFAULTSLICE (10
01244  * milliseconds), will be used. This routine uses the unix interval timer and
01245  * handling of the unix alarm signal, SIGALRM, to implement this timeslicing. 
01246  * \par Error Codes 
01247  * LWP EINIT The LWP package hasn't been initialized. 
01248  * \n LWP ESYSTEM Operations on the signal vector or the interval timer have
01249  * failed. 
01250  * 
01251  *      \subsubsection sec2-3-6-2 Section 2.3.6.2: PRE EndPreempt _ finalize
01252  *      the preemption package 
01253  * 
01254  * \par
01255  * int PRE EndPreempt() 
01256  * \par Description 
01257  * This routine finalizes use of the preemption package. No further preemptions
01258  * will be made. Note that it is not necessary to make this call before exit.
01259  * PRE EndPreempt() is provided only for those applications that wish to
01260  * continue after turning off preemption. 
01261  * \par Error Codes 
01262  * LWP EINIT The LWP package hasn't been initialized. 
01263  * \n LWP ESYSTEM Operations on the signal vector or the interval timer have
01264  * failed. 
01265  * 
01266  *      \subsubsection sec2-3-6-3 Section 2.3.6.3: PRE PreemptMe _ Mark thread
01267  *      as preemptible 
01268  * 
01269  * \par
01270  * int PRE PreemptMe() 
01271  * \par Description 
01272  * This macro is used to signify the current thread as a candidate for
01273  * preemption. The LWP InitializeProcessSupport() routine must have been called
01274  * before PRE PreemptMe(). 
01275  * \par Error Codes 
01276  * ---No return code is generated. 
01277  * 
01278  *      \subsubsection sec2-3-6-4 Section 2.3.6.4: PRE BeginCritical _ Enter
01279  *      thread critical section 
01280  * 
01281  * \par
01282  * int PRE BeginCritical() 
01283  * \par Description 
01284  * This macro places the current thread in a critical section. Upon return, and
01285  * for as long as the thread is in the critical section, involuntary
01286  * preemptions of this LWP will no longer occur. 
01287  * \par Error Codes 
01288  * ---No return code is generated. 
01289  * 
01290  *      \subsubsection sec2-3-6-5 Section 2.3.6.5: PRE EndCritical _ Exit
01291  *      thread critical section 
01292  * 
01293  * \par
01294  * int PRE EndCritical() 
01295  * \par Description 
01296  * This macro causes the executing thread to leave a critical section
01297  * previously entered via PRE BeginCritical(). If involuntary preemptions were
01298  * possible before the matching PRE BeginCritical(), they are once again
01299  * possible. 
01300  * \par Error Codes 
01301  * ---No return code is generated. 
01302  * 
01303  *      \page chap3 Chapter 3 -- Rxkad 
01304  * 
01305  * 
01306  *      \section sec3-1 Section 3.1: Introduction 
01307  * 
01308  * \par
01309  * The rxkad security module is offered as one of the built-in Rx
01310  * authentication models. It is based on the Kerberos system developed by MIT's
01311  * Project Athena. Readers wishing detailed information regarding Kerberos
01312  * design and implementation are directed to [2]. This chapter is devoted to
01313  * defining how Kerberos authentication services are made available as Rx
01314  * components, and assumes the reader has some familiarity with Kerberos.
01315  * Included are descriptions of how client-side and server-side Rx security
01316  * objects (struct rx securityClass; see Section 5.3.1.1) implementing this
01317  * protocol may be generated by an Rx application. Also, a description appears
01318  * of the set of routines available in the associated struct rx securityOps
01319  * structures, as covered in Section 5.3.1.2. It is strongly recommended that
01320  * the reader become familiar with this section on struct rx securityOps before
01321  * reading on. 
01322  * 
01323  *      \section sec3-2 Section 3.2: Definitions 
01324  * 
01325  * \par
01326  * An important set of definitions related to the rxkad security package is
01327  * provided by the rxkad.h include file. Determined here are various values for
01328  * ticket lifetimes, along with structures for encryption keys and Kerberos
01329  * principals. Declarations for the two routines required to generate the
01330  * different rxkad security objects also appear here. The two functions are
01331  * named rxkad NewServerSecurityObject() and rxkad NewClientSecurityObject().
01332  * In addition, type field values, encryption levels, security index
01333  * operations, and statistics structures may be found in this file. 
01334  *      \section sec3-3 Section 3.3: Exported Objects 
01335  * \par
01336  * To be usable as an Rx security module, the rxkad facility exports routines
01337  * to create server-side and client-side security objects. The server
01338  * authentication object is incorporated into the server code when calling rx
01339  * NewService(). The client authentication object is incorporated into the
01340  * client code every time a connection is established via rx NewConnection().
01341  * Also, in order to implement these security objects, the rxkad module must
01342  * provide definitions for some subset of the generic security operations as
01343  * defined in the appropriate struct rx securityOps variable. 
01344  * 
01345  *      \subsection sec3-3-1 Section 3.3.1: Server-Side Mechanisms 
01346  * 
01347  *      \subsubsection sec3-3-1-1 Section 3.3.1.1: Security Operations 
01348  * 
01349  * \par
01350  * The server side of the rxkad module fills in all but two of the possible
01351  * routines associated with an Rx security object, as described in Section
01352  * 5.3.1.2. 
01353  * 
01354  * \code
01355  * static struct rx_securityOps rxkad_server_ops = { 
01356  *      rxkad_Close,
01357  *      rxkad_NewConnection,
01358  *      rxkad_PreparePacket, /* Once per packet creation */
01359  *      0, /* Send packet (once per retrans) */
01360  *      rxkad_CheckAuthentication,
01361  *      rxkad_CreateChallenge,
01362  *      rxkad_GetChallenge,
01363  *      0,
01364  *      rxkad_CheckResponse, /* Check data packet */
01365  *      rxkad_DestroyConnection,
01366  *      rxkad_GetStats,
01367  * };
01368  * \endcode
01369  * 
01370  * \par
01371  * The rxkad service does not need to take any special action each time a
01372  * packet belonging to a call in an rxkad Rx connection is physically
01373  * transmitted. Thus, a routine is not supplied for the op SendPacket()
01374  * function slot. Similarly, no preparatory work needs to be done previous to
01375  * the reception of a response packet from a security challenge, so the op
01376  * GetResponse() function slot is also empty. 
01377  * 
01378  *      \subsubsection sec3-3-1-2 Section 3.3.1.2: Security Object 
01379  * 
01380  * \par
01381  * The exported routine used to generate an rxkad-specific server-side security
01382  * class object is named rxdad NewServerSecurityObject(). It is declared with
01383  * four parameters, as follows: 
01384  * 
01385  * \code
01386  * struct rx_securityClass * 
01387  * rxkad_NewServerSecurityObject(a_level, a_getKeyRockP, a_getKeyP, a_userOKP) 
01388  * rxkad_level a_level; /* Minimum level */
01389  * char *a_getKeyRockP; /* Rock for get_key implementor */
01390  * int (*a_getKeyP)(); /* Passed kvno & addr(key) to fill */
01391  * int (*a_userOKP)(); /* Passed name, inst, cell => bool */
01392  * \endcode
01393  * 
01394  * \par
01395  * The first argument specifies the desired level of encryption, and may take
01396  * on the following values (as defined in rxkad.h): 
01397  * \li rxkad clear: Specifies that packets are to be sent entirely in the
01398  * clear, without any encryption whatsoever. 
01399  * \li rxkad auth: Specifies that packet sequence numbers are to be encrypted. 
01400  * \li rxkad crypt: Specifies that the entire data packet is to be encrypted. 
01401  * 
01402  * \par
01403  * The second and third parameters represent, respectively, a pointer to a
01404  * private data area, sometimes called a "rock", and a procedure reference that
01405  * is called with the key version number accompanying the Kerberos ticket and
01406  * returns a pointer to the server's decryption key. The fourth argument, if
01407  * not null, is a pointer to a function that will be called for every new
01408  * connection with the client's name, instance, and cell. This routine should
01409  * return zero if the user is not acceptable to the server. 
01410  * 
01411  *      \subsection sec3-3-2 Section 3.3.2: Client-Side Mechanisms 
01412  * 
01413  *      \subsubsection sec3-3-2-1 Section 3.3.2.1: Security Operations 
01414  * 
01415  * \par
01416  * The client side of the rxkad module fills in relatively few of the routines
01417  * associated with an Rx security object, as demonstrated below. The general Rx
01418  * security object, of which this is an instance, is described in detail in
01419  * Section 5.3.1.2. 
01420  * 
01421  * \code
01422  * static struct rx_securityOps rxkad_client_ops = { 
01423  *      rxkad_Close, 
01424  *      rxkad_NewConnection, /* Every new connection */
01425  *      rxkad_PreparePacket, /* Once per packet creation */
01426  *      0, /* Send packet (once per retrans) */
01427  *      0,
01428  *      0,
01429  *      0,
01430  *      rxkad_GetResponse, /* Respond to challenge packet */
01431  *      0,
01432  *      rxkad_CheckPacket, /* Check data packet */
01433  *      rxkad_DestroyConnection,
01434  *      rxkad_GetStats,
01435  *      0,
01436  *      0,
01437  *      0,
01438  * };
01439  * \endcode
01440  * 
01441  * \par
01442  * As expected, routines are defined for use when someone destroys a security
01443  * object (rxkad Close()) and when an Rx connection using the rxkad model
01444  * creates a new connection (rxkad NewConnection()) or deletes an existing one
01445  * (rxkad DestroyConnection()). Security-specific operations must also be
01446  * performed in behalf of rxkad when packets are created (rxkad
01447  * PreparePacket()) and received (rxkad CheckPacket()). finally, the client
01448  * side of an rxkad security object must also be capable of constructing
01449  * responses to security challenges from the server (rxkad GetResponse()) and
01450  * be willing to reveal statistics on its own operation (rxkad GetStats()). 
01451  * 
01452  *      \subsubsection sec3-3-2-2 Section 3.3.2.2: Security Object 
01453  * 
01454  * \par
01455  * The exported routine used to generate an rxkad-specific client-side security
01456  * class object is named rxkad NewClientSecurityObject(). It is declared with
01457  * five parameters, specified below: 
01458  * 
01459  * \code
01460  * struct rx_securityClass * rxkad_NewClientSecurityObject(
01461  *                              a_level, 
01462  *                              a_sessionKeyP, 
01463  *                              a_kvno, 
01464  *                              a_ticketLen, 
01465  *                              a_ticketP
01466  *                              ) 
01467  * rxkad_level a_level; 
01468  * struct ktc_encryptionKey *a_sessionKeyP; 
01469  * long a_kvno; 
01470  * int a_ticketLen; 
01471  * char *a_ticketP; 
01472  * \endcode
01473  * 
01474  * \par
01475  * The first parameter, a level, specifies the level of encryption desired for
01476  * this security object, with legal choices being identical to those defined
01477  * for the server-side security object described in Section 3.3.1.2. The second
01478  * parameter, a sessionKeyP, provides the session key to use. The ktc
01479  * encryptionKey structure is defined in the rxkad.h include file, and consists
01480  * of an array of 8 characters. The third parameter, a kvno, provides the key
01481  * version number associated with a sessionKeyP. The fourth argument, a
01482  * ticketLen, communicates the length in bytes of the data stored in the fifth
01483  * parameter, a ticketP, which points to the Kerberos ticket to use for the
01484  * principal for which the security object will operate. 
01485  * 
01486  *      \page chap4 Chapter 4 -- Rx Support Packages 
01487  * 
01488  *      \section sec4-1 Section 4.1: Introduction 
01489  * \par
01490  * This chapter documents three packages defined directly in support of the Rx
01491  * facility. 
01492  * \li rx queue: Doubly-linked queue package. 
01493  * \li rx clock: Clock package, using the 4.3BSD interval timer. 
01494  * \li rx event: Future events package. 
01495  * \par
01496  * References to constants, structures, and functions defined by these support
01497  * packages will appear in the following API chapter. 
01498  * 
01499  *      \section sec4-2 Section 4.2: The rx queue Package 
01500  * 
01501  * \par
01502  * This package provides a doubly-linked queue structure, along with a full
01503  * suite of related operations. The main concern behind the coding of this
01504  * facility was efficiency. All functions are implemented as macros, and it is
01505  * suggested that only simple expressions be used for all parameters. 
01506  * \par
01507  * The rx queue facility is defined by the rx queue.h include file. Some macros
01508  * visible in this file are intended for rx queue internal use only. An
01509  * understanding of these "hidden" macros is important, so they will also be
01510  * described by this document. 
01511  * 
01512  *      \subsection sec4-2-1 Section 4.2.1: struct queue 
01513  * 
01514  * \par
01515  * The queue structure provides the linkage information required to maintain a
01516  * queue of objects. The queue structure is prepended to any user-defined data
01517  * type which is to be organized in this fashion. 
01518  * \n \b fields 
01519  * \li struct queue *prev - Pointer to the previous queue header. 
01520  * \li struct queue *next - Pointer to the next queue header. 
01521  * \par
01522  * Note that a null Rx queue consists of a single struct queue object whose
01523  * next and previous pointers refer to itself. 
01524  * 
01525  *      \subsection sec4-2-2 Section 4.2.2: Internal Operations 
01526  * 
01527  * \par
01528  * This section describes the internal operations defined for Rx queues. They
01529  * will be referenced by the external operations documented in Section 4.2.3. 
01530  * 
01531  *      \subsection sec4-2-2-1 Section 4.2.2.1: Q(): Coerce type to a queue
01532  *      element 
01533  * 
01534  * \par
01535  * \#define _Q(x) ((struct queue *)(x)) 
01536  * \par
01537  * This operation coerces the user structure named by x to a queue element. Any
01538  * user structure using the rx queue package must have a struct queue as its
01539  * first field. 
01540  * 
01541  *      \subsubsection sec4-2-2-2 Section 4.2.2.2: QA(): Add a queue element
01542  *      before/after another element 
01543  * 
01544  * \par
01545  * \#define _QA(q,i,a,b) (((i->a=q->a)->b=i)->b=q, q->a=i) 
01546  * \par
01547  * This operation adds the queue element referenced by i either before or after
01548  * a queue element represented by q. If the (a, b) argument pair corresponds to
01549  * an element's (next, prev) fields, the new element at i will be linked after
01550  * q. If the (a, b) argument pair corresponds to an element's (prev, next)
01551  * fields, the new element at i will be linked before q. 
01552  * 
01553  *      \subsubsection sec4-2-2-3 QR(): Remove a queue element 
01554  * 
01555  * \par
01556  * \#define _QR(i) ((_Q(i)->prev->next=_Q(i)->next)->prev=_Q(i)->prev) 
01557  * \par
01558  * This operation removes the queue element referenced by i from its queue. The
01559  * prev and next fields within queue element i itself is not updated to reflect
01560  * the fact that it is no longer part of the queue. 
01561  * 
01562  *      \subsubsection sec4-2-2-4 QS(): Splice two queues together 
01563  * 
01564  * \par
01565  * \#define _QS(q1,q2,a,b) if (queue_IsEmpty(q2)); else
01566  * ((((q2->a->b=q1)->a->b=q2->b)->a=q1->a, q1->a=q2->a), queue_Init(q2)) 
01567  * \par
01568  * This operation takes the queues identified by q1 and q2 and splices them
01569  * together into a single queue. The order in which the two queues are appended
01570  * is determined by the a and b arguments. If the (a, b) argument pair
01571  * corresponds to q1's (next, prev) fields, then q2 is appended to q1. If the
01572  * (a, b) argument pair corresponds to q1's (prev, next) fields, then q is
01573  * prepended to q2. 
01574  * \par
01575  * This internal QS() routine uses two exported queue operations, namely queue
01576  * Init() and queue IsEmpty(), defined in Sections 4.2.3.1 and 4.2.3.16
01577  * respectively below. 
01578  * 
01579  *      \subsection sec4-2-3 Section 4.2.3: External Operations 
01580  * 
01581  *      \subsubsection sec4-2-3-1 Section 4.2.3.1: queue Init(): Initialize a
01582  *      queue header 
01583  * 
01584  * \par
01585  * \#define queue_Init(q) (_Q(q))->prev = (_Q(q))->next = (_Q(q)) 
01586  * \par
01587  * The queue header referred to by the q argument is initialized so that it
01588  * describes a null (empty) queue. A queue head is simply a queue element. 
01589  * 
01590  *      \subsubsection sec4-2-3-2 Section 4.2.3.2: queue Prepend(): Put element
01591  *      at the head of a queue 
01592  * 
01593  * \par
01594  * \#define queue_Prepend(q,i) _QA(_Q(q),_Q(i),next,prev) 
01595  * \par
01596  * Place queue element i at the head of the queue denoted by q. The new queue
01597  * element, i, should not currently be on any queue. 
01598  * 
01599  *      \subsubsection sec4-2-3-3 Section 4.2.3.3: queue Append(): Put an
01600  *      element a the tail of a queue 
01601  * 
01602  * \par
01603  * \#define queue_Append(q,i) _QA(_Q(q),_Q(i),prev,next) 
01604  * \par
01605  * Place queue element i at the tail of the queue denoted by q. The new queue
01606  * element, i, should not currently be on any queue. 
01607  * 
01608  *      \subsection sec4-2-3-4 Section 4.2.3.4: queue InsertBefore(): Insert a
01609  *      queue element before another element 
01610  * 
01611  * \par
01612  * \#define queue_InsertBefore(i1,i2) _QA(_Q(i1),_Q(i2),prev,next) 
01613  * \par
01614  * Insert queue element i2 before element i1 in i1's queue. The new queue
01615  * element, i2, should not currently be on any queue. 
01616  * 
01617  *      \subsubsection sec4-2-3-5 Section 4.2.3.5: queue InsertAfter(): Insert
01618  *      a queue element after another element 
01619  * 
01620  * \par
01621  * \#define queue_InsertAfter(i1,i2) _QA(_Q(i1),_Q(i2),next,prev) 
01622  * \par
01623  * Insert queue element i2 after element i1 in i1's queue. The new queue
01624  * element, i2, should not currently be on any queue. 
01625  * 
01626  *      \subsubsection sec4-2-3-6 Section: 4.2.3.6: queue SplicePrepend():
01627  *      Splice one queue before another 
01628  * 
01629  * \par
01630  * \#define queue_SplicePrepend(q1,q2) _QS(_Q(q1),_Q(q2),next,prev) 
01631  * \par
01632  * Splice the members of the queue located at q2 to the beginning of the queue
01633  * located at q1, reinitializing queue q2. 
01634  * 
01635  *      \subsubsection sec4-2-3-7 Section 4.2.3.7: queue SpliceAppend(): Splice
01636  *      one queue after another 
01637  * 
01638  * \par
01639  * \#define queue_SpliceAppend(q1,q2) _QS(_Q(q1),_Q(q2),prev,next) 
01640  * \par
01641  * Splice the members of the queue located at q2 to the end of the queue
01642  * located at q1, reinitializing queue q2. Note that the implementation of
01643  * queue SpliceAppend() is identical to that of queue SplicePrepend() except
01644  * for the order of the next and prev arguments to the internal queue splicer,
01645  * QS(). 
01646  * 
01647  *      \subsubsection sec4-2-3-8 Section 4.2.3.8: queue Replace(): Replace the
01648  *      contents of a queue with that of another 
01649  * 
01650  * \par
01651  * \#define queue_Replace(q1,q2) (*_Q(q1) = *_Q(q2), 
01652  * \n _Q(q1)->next->prev = _Q(q1)->prev->next = _Q(q1), 
01653  * \n queue_Init(q2)) 
01654  * \par
01655  * Replace the contents of the queue located at q1 with the contents of the
01656  * queue located at q2. The prev and next fields from q2 are copied into the
01657  * queue object referenced by q1, and the appropriate element pointers are
01658  * reassigned. After the replacement has occurred, the queue header at q2 is
01659  * reinitialized. 
01660  * 
01661  *      \subsubsection sec4-2-3-9 Section 4.2.3.9: queue Remove(): Remove an
01662  *      element from its queue 
01663  * 
01664  * \par
01665  * \#define queue_Remove(i) (_QR(i), _Q(i)->next = 0) 
01666  * \par
01667  * This function removes the queue element located at i from its queue. The
01668  * next field for the removed entry is zeroed. Note that multiple removals of
01669  * the same queue item are not supported. 
01670  * 
01671  *      \subsubsection sec4-2-3-10 Section 4.2.3.10: queue MoveAppend(): Move
01672  *      an element from its queue to the end of another queue 
01673  * 
01674  * \par
01675  * \#define queue_MoveAppend(q,i) (_QR(i), queue_Append(q,i)) 
01676  * \par
01677  * This macro removes the queue element located at i from its current queue.
01678  * Once removed, the element at i is appended to the end of the queue located
01679  * at q. 
01680  * 
01681  *      \subsubsection sec4-2-3-11 Section 4.2.3.11: queue MovePrepend(): Move
01682  *      an element from its queue to the head of another queue 
01683  * 
01684  * \par
01685  * \#define queue_MovePrepend(q,i) (_QR(i), queue_Prepend(q,i)) 
01686  * \par
01687  * This macro removes the queue element located at i from its current queue.
01688  * Once removed, the element at i is inserted at the head fo the queue located
01689  * at q. 
01690  * 
01691  *      \subsubsection sec4-2-3-12 Section 4.2.3.12: queue first(): Return the
01692  *      first element of a queue, coerced to a particular type 
01693  * 
01694  * \par
01695  * \#define queue_first(q,s) ((struct s *)_Q(q)->next) 
01696  * \par
01697  * Return a pointer to the first element of the queue located at q. The
01698  * returned pointer value is coerced to conform to the given s structure. Note
01699  * that a properly coerced pointer to the queue head is returned if q is empty. 
01700  * 
01701  *      \subsubsection sec4-2-3-13 Section 4.2.3.13: queue Last(): Return the
01702  *      last element of a queue, coerced to a particular type 
01703  * 
01704  * \par
01705  * \#define queue_Last(q,s) ((struct s *)_Q(q)->prev) 
01706  * \par
01707  * Return a pointer to the last element of the queue located at q. The returned
01708  * pointer value is coerced to conform to the given s structure. Note that a
01709  * properly coerced pointer to the queue head is returned if q is empty. 
01710  * 
01711  *      \subsubsection sec4-2-3-14 Section 4.2.3.14: queue Next(): Return the
01712  *      next element of a queue, coerced to a particular type 
01713  * 
01714  * \par
01715  * \#define queue_Next(i,s) ((struct s *)_Q(i)->next) 
01716  * \par
01717  * Return a pointer to the queue element occuring after the element located at
01718  * i. The returned pointer value is coerced to conform to the given s
01719  * structure. Note that a properly coerced pointer to the queue head is
01720  * returned if item i is the last in its queue. 
01721  * 
01722  *      \subsubsection sec4-2-3-15 Section 4.2.3.15: queue Prev(): Return the
01723  *      next element of a queue, coerced to a particular type 
01724  * 
01725  * \par
01726  * \#define queue_Prev(i,s) ((struct s *)_Q(i)->prev) 
01727  * \par
01728  * Return a pointer to the queue element occuring before the element located at
01729  * i. The returned pointer value is coerced to conform to the given s
01730  * structure. Note that a properly coerced pointer to the queue head is
01731  * returned if item i is the first in its queue. 
01732  * 
01733  *      \subsubsection sec4-2-3-16 Section 4.2.3.16: queue IsEmpty(): Is the
01734  *      given queue empty? 
01735  * 
01736  * \par
01737  * \#define queue_IsEmpty(q) (_Q(q)->next == _Q(q)) 
01738  * \par
01739  * Return a non-zero value if the queue located at q does not have any elements
01740  * in it. In this case, the queue consists solely of the queue header at q
01741  * whose next and prev fields reference itself. 
01742  * 
01743  *      \subsubsection sec4-2-3-17 Section 4.2.3.17: queue IsNotEmpty(): Is the
01744  *      given queue not empty? 
01745  * 
01746  * \par
01747  * \#define queue_IsNotEmpty(q) (_Q(q)->next != _Q(q)) 
01748  * \par
01749  * Return a non-zero value if the queue located at q has at least one element
01750  * in it other than the queue header itself. 
01751  * 
01752  *      \subsubsection sec4-2-3-18 Section 4.2.3.18: queue IsOnQueue(): Is an
01753  *      element currently queued? 
01754  * 
01755  * \par
01756  * \#define queue_IsOnQueue(i) (_Q(i)->next != 0) 
01757  * \par
01758  * This macro returns a non-zero value if the queue item located at i is
01759  * currently a member of a queue. This is determined by examining its next
01760  * field. If it is non-null, the element is considered to be queued. Note that
01761  * any element operated on by queue Remove() (Section 4.2.3.9) will have had
01762  * its next field zeroed. Hence, it would cause a non-zero return from this
01763  * call. 
01764  * 
01765  *      \subsubsection sec4-2-3-19 Section 4.2.3.19: queue Isfirst(): Is an
01766  *      element the first on a queue? 
01767  * 
01768  * \par
01769  * \#define queue_Isfirst(q,i) (_Q(q)->first == _Q(i)) 
01770  * \par
01771  * This macro returns a non-zero value if the queue item located at i is the
01772  * first element in the queue denoted by q. 
01773  * 
01774  *      \subsubsection sec4-2-3-20 Section 4.2.3.20: queue IsLast(): Is an
01775  *      element the last on a queue? 
01776  * 
01777  * \par
01778  * \#define queue_IsLast(q,i) (_Q(q)->prev == _Q(i)) 
01779  * \par
01780  * This macro returns a non-zero value if the queue item located at i is the
01781  * last element in the queue denoted by q. 
01782  * 
01783  *      \subsubsection sec4-2-3-21 Section 4.2.3.21: queue IsEnd(): Is an
01784  *      element the end of a queue? 
01785  * 
01786  * \par
01787  * \#define queue_IsEnd(q,i) (_Q(q) == _Q(i)) 
01788  * \par
01789  * This macro returns a non-zero value if the queue item located at i is the
01790  * end of the queue located at q. Basically, it determines whether a queue
01791  * element in question is also the queue header structure itself, and thus does
01792  * not represent an actual queue element. This function is useful for
01793  * terminating an iterative sweep through a queue, identifying when the search
01794  * has wrapped to the queue header. 
01795  * 
01796  *      \subsubsection sec4-2-3-22 Section 4.2.3.22: queue Scan(): for loop
01797  *      test for scanning a queue in a forward direction 
01798  * 
01799  * \par
01800  * \#define queue_Scan(q, qe, next, s) 
01801  * \n (qe) = queue_first(q, s), next = queue_Next(qe, s); 
01802  * \n !queue_IsEnd(q, qe); 
01803  * \n (qe) = (next), next = queue_Next(qe, s) 
01804  * \par
01805  * This macro may be used as the body of a for loop test intended to scan
01806  * through each element in the queue located at q. The qe argument is used as
01807  * the for loop variable. The next argument is used to store the next value for
01808  * qe in the upcoming loop iteration. The s argument provides the name of the
01809  * structure to which each queue element is to be coerced. Thus, the values
01810  * provided for the qe and next arguments must be of type (struct s *). 
01811  * \par
01812  * An example of how queue Scan() may be used appears in the code fragment
01813  * below. It declares a structure named mystruct, which is suitable for
01814  * queueing. This queueable structure is composed of the queue pointers
01815  * themselves followed by an integer value. The actual queue header is kept in
01816  * demoQueue, and the currItemP and nextItemP variables are used to step
01817  * through the demoQueue. The queue Scan() macro is used in the for loop to
01818  * generate references in currItemP to each queue element in turn for each
01819  * iteration. The loop is used to increment every queued structure's myval
01820  * field by one. 
01821  * 
01822  * \code
01823  * struct mystruct { 
01824  *      struct queue q; 
01825  *      int myval; 
01826  * }; 
01827  * struct queue demoQueue; 
01828  * struct mystruct *currItemP, *nextItemP; 
01829  * ... 
01830  * for (queue_Scan(&demoQueue, currItemP, nextItemP, mystruct)) { 
01831  *      currItemP->myval++; 
01832  * } 
01833  * \endcode
01834  * 
01835  * \par
01836  * Note that extra initializers can be added before the body of the queue
01837  * Scan() invocation above, and extra expressions can be added afterwards. 
01838  * 
01839  *      \subsubsection sec4-2-3-23 Section 4.2.3.23: queue ScanBackwards(): for
01840  *      loop test for scanning a queue in a reverse direction 
01841  * 
01842  * \par
01843  * #define queue_ScanBackwards(q, qe, prev, s) 
01844  * \n (qe) = queue_Last(q, s), prev = queue_Prev(qe, s); 
01845  * \n !queue_IsEnd(q, qe); 
01846  * \n (qe) = prev, prev = queue_Prev(qe, s) 
01847  * \par
01848  * This macro is identical to the queue Scan() macro described above in Section
01849  * 4.2.3.22 except for the fact that the given queue is scanned backwards,
01850  * starting at the last item in the queue. 
01851  * 
01852  *      \section sec4-3 Section 4.3: The rx clock Package 
01853  * 
01854  * \par
01855  * This package maintains a clock which is independent of the time of day. It
01856  * uses the unix 4.3BSD interval timer (e.g., getitimer(), setitimer()) in
01857  * TIMER REAL mode. Its definition and interface may be found in the rx clock.h
01858  * include file. 
01859  * 
01860  *      \subsection sec4-3-1 Section 4.3.1: struct clock 
01861  * 
01862  * \par
01863  * This structure is used to represent a clock value as understood by this
01864  * package. It consists of two fields, storing the number of seconds and
01865  * microseconds that have elapsed since the associated clock Init() routine has
01866  * been called. 
01867  * \par
01868  * \b fields 
01869  * \n long sec -Seconds since call to clock Init(). 
01870  * \n long usec -Microseconds since call to clock Init(). 
01871  * 
01872  *      \subsection sec4-3-2 Section 4.3.12: clock nUpdates 
01873  * 
01874  * \par
01875  * The integer-valued clock nUpdates is a variable exported by the rx clock
01876  * facility. It records the number of times the clock value is actually
01877  * updated. It is bumped each time the clock UpdateTime() routine is called, as
01878  * described in Section 4.3.3.2. 
01879  * 
01880  *      \subsection sec4-3-3 Section 4.3.3: Operations 
01881  * 
01882  *      \subsubsection sec4-3-3-1 Section 4.3.3.1: clock Init(): Initialize the
01883  *      clock package 
01884  * 
01885  * \par
01886  * This routine uses the unix setitimer() call to initialize the unix interval
01887  * timer. If the setitimer() call fails, an error message will appear on
01888  * stderr, and an exit(1) will be executed. 
01889  * 
01890  *      \subsubsection sec4-3-3-2 Section 4.3.3.2: clock UpdateTime(): Compute
01891  *      the current time 
01892  * 
01893  * \par
01894  * The clock UpdateTime() function calls the unix getitimer() routine in order
01895  * to update the current time. The exported clock nUpdates variable is
01896  * incremented each time the clock UpdateTime() routine is called. 
01897  * 
01898  *      \subsubsection sec4-3-3-3 Section 4.3.3.3: clock GetTime(): Return the
01899  *      current clock time 
01900  * 
01901  * \par
01902  * This macro updates the current time if necessary, and returns the current
01903  * time into the cv argument, which is declared to be of type (struct clock *). 
01904  * 4.3.3.4 clock Sec(): Get the current clock time, truncated to seconds 
01905  * This macro returns the long value of the sec field of the current time. The
01906  * recorded time is updated if necessary before the above value is returned. 
01907  * 
01908  *      \subsubsection sec4-3-3-5 Section 4.3.3.5: clock ElapsedTime(): Measure
01909  *      milliseconds between two given clock values 
01910  * 
01911  * \par
01912  * This macro returns the elapsed time in milliseconds between the two clock
01913  * structure pointers provided as arguments, cv1 and cv2. 
01914  * 
01915  *      \subsubsection sec4-3-3-6 Section 4.3.3.6: clock Advance(): Advance the
01916  *      recorded clock time by a specified clock value 
01917  * 
01918  * \par
01919  * This macro takes a single (struct clock *) pointer argument, cv, and adds
01920  * this clock value to the internal clock value maintined by the package. 
01921  * 
01922  *      \subsubsection sec4-3-3-7 Section 4.3.3.7: clock Gt(): Is a clock value
01923  *      greater than another? 
01924  * 
01925  * \par
01926  * This macro takes two parameters of type (struct clock *), a and b. It
01927  * returns a nonzero value if the a parameter points to a clock value which is
01928  * later than the one pointed to by b. 
01929  * 
01930  *      \subsubsection sec4-3-3-8 Section 4.3.3.8: clock Ge(): Is a clock value
01931  *      greater than or equal to another? 
01932  * 
01933  * \par
01934  * This macro takes two parameters of type (struct clock *), a and b. It
01935  * returns a nonzero value if the a parameter points to a clock value which is
01936  * greater than or equal to the one pointed to by b. 
01937  * 
01938  *      \subsubsection sec4-3-3-9 Section 4.3.3.9: clock Gt(): Are two clock
01939  *      values equal? 
01940  * 
01941  * \par
01942  * This macro takes two parameters of type (struct clock *), a and b. It
01943  * returns a non-zero value if the clock values pointed to by a and b are
01944  * equal. 
01945  * 
01946  *      \subsubsection sec4.3.3.10 Section 4.3.3.10: clock Le(): Is a clock
01947  *      value less than or equal to another? 
01948  * 
01949  * \par
01950  * This macro takes two parameters of type (struct clock *), a and b. It
01951  * returns a nonzero value if the a parameter points to a clock value which is
01952  * less than or equal to the one pointed to by b. 
01953  * 
01954  *      \subsubsection sec4-3-3-11 Section 4.3.3.11: clock Lt(): Is a clock
01955  *      value less than another? 
01956  * 
01957  * \par
01958  * This macro takes two parameters of type (struct clock *), a and b. It
01959  * returns a nonzero value if the a parameter points to a clock value which is
01960  * less than the one pointed to by b. 
01961  * 
01962  *      \subsubsection sec4-3-3-12 Section 4.3.3.12: clock IsZero(): Is a clock
01963  *      value zero? 
01964  * 
01965  * \par
01966  * This macro takes a single parameter of type (struct clock *), c. It returns
01967  * a non-zero value if the c parameter points to a clock value which is equal
01968  * to zero. 
01969  * 
01970  *      \subsubsection sec4-3-3-13 Section 4.3.3.13: clock Zero(): Set a clock
01971  *      value to zero 
01972  * 
01973  * \par
01974  * This macro takes a single parameter of type (struct clock *), c. It sets the
01975  * given clock value to zero. 
01976  *      \subsubsection sec4-3-3-14 Section 4.3.3.14: clock Add(): Add two clock
01977  *      values together 
01978  * \par
01979  * This macro takes two parameters of type (struct clock *), c1 and c2. It adds
01980  * the value of the time in c2 to c1. Both clock values must be positive. 
01981  * 
01982  *      \subsubsection sec4-3-3-15 Section 4.3.3.15: clock Sub(): Subtract two
01983  *      clock values 
01984  * 
01985  * \par
01986  * This macro takes two parameters of type (struct clock *), c1 and c2. It
01987  * subtracts the value of the time in c2 from c1. The time pointed to by c2
01988  * should be less than the time pointed to by c1. 
01989  * 
01990  *      \subsubsection sec4-3-3-16 Section 4.3.3.16: clock Float(): Convert a
01991  *      clock time into floating point 
01992  * 
01993  * \par
01994  * This macro takes a single parameter of type (struct clock *), c. It
01995  * expresses the given clock value as a floating point number. 
01996  * 
01997  *      \section sec4-4 Section 4.4: The rx event Package 
01998  * 
01999  * \par
02000  * This package maintains an event facility. An event is defined to be
02001  * something that happens at or after a specified clock time, unless cancelled
02002  * prematurely. The clock times used are those provided by the rx clock
02003  * facility described in Section 4.3 above. A user routine associated with an
02004  * event is called with the appropriate arguments when that event occurs. There
02005  * are some restrictions on user routines associated with such events. first,
02006  * this user-supplied routine should not cause process preemption. Also, the
02007  * event passed to the user routine is still resident on the event queue at the
02008  * time of invocation. The user must not remove this event explicitly (via an
02009  * event Cancel(), see below). Rather, the user routine may remove or schedule
02010  * any other event at this time. 
02011  * \par
02012  * The events recorded by this package are kept queued in order of expiration
02013  * time, so that the first entry in the queue corresponds to the event which is
02014  * the first to expire. This interface is defined by the rx event.h include
02015  * file. 
02016  * 
02017  *      \subsection sec4-4-1 Section 4.4.1: struct rxevent 
02018  * 
02019  * \par
02020  * This structure defines the format of an Rx event record. 
02021  * \par
02022  * \b fields 
02023  * \n struct queue junk -The queue to which this event belongs. 
02024  * \n struct clock eventTime -The clock time recording when this event comes
02025  * due. 
02026  * \n int (*func)() -The user-supplied function to call upon expiration. 
02027  * \n char *arg -The first argument to the (*func)() function above. 
02028  * \n char *arg1 -The second argument to the (*func)() function above. 
02029  * 
02030  *      \subsection sec4-4-2 Section 4.4.2: Operations 
02031  * 
02032  * \par
02033  * This section covers the interface routines provided for the Rx event
02034  * package. 
02035  * 
02036  *      \subsubsection sec4-4-2-1 Section 4.4.2.1: rxevent Init(): Initialize
02037  *      the event package 
02038  * 
02039  * \par
02040  * The rxevent Init() routine takes two arguments. The first, nEvents, is an
02041  * integer-valued parameter which specifies the number of event structures to
02042  * allocate at one time. This specifies the appropriate granularity of memory
02043  * allocation by the event package. The second parameter, scheduler, is a
02044  * pointer to an integer-valued function. This function is to be called when an
02045  * event is posted (added to the set of events managed by the package) that is
02046  * scheduled to expire before any other existing event. 
02047  * \par
02048  * This routine sets up future event allocation block sizes, initializes the
02049  * queues used to manage active and free event structures, and recalls that an
02050  * initialization has occurred. Thus, this function may be safely called
02051  * multiple times. 
02052  * 
02053  *      \subsubsection sec4-4-2-2 Section 4.4.2.2: rxevent Post(): Schedule an
02054  *      event 
02055  * 
02056  * \par
02057  * This function constructs a new event based on the information included in
02058  * its parameters and then schedules it. The rxevent Post() routine takes four
02059  * parameters. The first is named when, and is of type (struct clock *). It
02060  * specifies the clock time at which the event is to occur. The second
02061  * parameter is named func and is a pointer to the integer-valued function to
02062  * associate with the event that will be created. When the event comes due,
02063  * this function will be executed by the event package. The next two arguments
02064  * to rxevent Post() are named arg and arg1, and are both of type (char *).
02065  * They serve as the two arguments thath will be supplied to the func routine
02066  * when the event comes due. 
02067  * \par
02068  * If the given event is set to take place before any other event currently
02069  * posted, the scheduler routine established when the rxevent Init() routine
02070  * was called will be executed. This gives the application a chance to react to
02071  * this new event in a reasonable way. One might expect that this scheduler
02072  * routine will alter sleep times used by the application to make sure that it
02073  * executes in time to handle the new event. 
02074  * 
02075  *      \subsubsection sec4-4-2-3 Section 4.4.2.3: rxevent Cancel 1(): Cancel
02076  *      an event (internal use) 
02077  * 
02078  * \par
02079  * This routine removes an event from the set managed by this package. It takes
02080  * a single parameter named ev of type (struct rxevent *). The ev argument
02081  * identifies the pending event to be cancelled. 
02082  * \par
02083  * The rxevent Cancel 1() routine should never be called directly. Rather, it
02084  * should be accessed through the rxevent Cancel() macro, described in Section
02085  * 4.4.2.4 below. 
02086  * 
02087  *      \subsubsection sec4-4-2-4 Section 4.4.2.4: rxevent Cancel(): Cancel an
02088  *      event (external use) 
02089  * 
02090  * \par
02091  * This macro is the proper way to call the rxevent Cancel 1() routine
02092  * described in Section 4.4.2.3 above. Like rxevent Cancel 1(), it takes a
02093  * single argument. This event ptr argument is of type (struct rxevent *), and
02094  * identi#es the pending event to be cancelled. This macro #rst checks to see
02095  * if event ptr is null. If not, it calls rxevent Cancel 1() to perform the
02096  * real work. The event ptr argument is zeroed after the cancellation operation
02097  * completes. 
02098  * 
02099  *      \subsubsection sec4-4-2-5 Section 4.4.2.4: rxevent RaiseEvents():
02100  *      Initialize the event package 
02101  * 
02102  * \par
02103  * This function processes all events that have expired relative to the current
02104  * clock time maintained by the event package. Each qualifying event is removed
02105  * from the queue in order, and its user-supplied routine (func()) is executed
02106  * with the associated arguments. 
02107  * \par
02108  * The rxevent RaiseEvents() routine takes a single output parameter named
02109  * next, defined to be of type (struct clock *). Upon completion of rxevent
02110  * RaiseEvents(), the relative time to the next event due to expire is placed
02111  * in next. This knowledge may be used to calculate the amount of sleep time
02112  * before more event processing is needed. If there is no recorded event which
02113  * is still pending at this point, rxevent RaiseEvents() returns a zeroed clock
02114  * value into next. 
02115  * 
02116  *      \subsubsection sec4-4-2-6 Section 4.4.2.6: rxevent TimeToNextEvent():
02117  *      Get amount of time until the next event expires 
02118  * 
02119  * \par
02120  * This function returns the time between the current clock value as maintained
02121  * by the event package and the the next event's expiration time. This
02122  * information is placed in the single output argument,interval, defined to be
02123  * of type (struct clock *). The rxevent TimeToNextEvent() function returns
02124  * integer-valued quantities. If there are no scheduled events, a zero is
02125  * returned. If there are one or more scheduled events, a 1 is returned. If
02126  * zero is returned, the interval argument is not updated. 
02127  * 
02128  *      \page chap5 Chapter 5 -- Programming Interface 
02129  * 
02130  *      \section sec5-1 Section 5.1: Introduction 
02131  * 
02132  * \par
02133  * This chapter documents the API for the Rx facility. Included are
02134  * descriptions of all the constants, structures, exported variables, macros,
02135  * and interface functions available to the application programmer. This
02136  * interface is identical regardless of whether the application lives within
02137  * the unix kernel or above it. 
02138  * \par
02139  * This chapter actually provides more information than what may be strictly
02140  * considered the Rx API. Many objects that were intended to be opaque and for
02141  * Rx internal use only are also described here. The reason driving the
02142  * inclusion of this "extra" information is that such exported Rx interface
02143  * files as rx.h make these objects visible to application programmers. It is
02144  * prefereable to describe these objects here than to ignore them and leave
02145  * application programmers wondering as to their meaning. 
02146  * \par
02147  * An example application illustrating the use of this interface, showcasing
02148  * code from both server and client sides, appears in the following chapter. 
02149  * 
02150  *      \section sec5-2 Section 5.2: Constants 
02151  * 
02152  * \par
02153  * This section covers the basic constant definitions of interest to the Rx
02154  * application programmer. Each subsection is devoted to describing the
02155  * constants falling into the following categories: 
02156  * \li Configuration quantities 
02157  * \li Waiting options 
02158  * \li Connection ID operations 
02159  * \li Connection flags 
02160  * \li Connection types 
02161  * \li Call states 
02162  * \li Call flags 
02163  * \li Call modes 
02164  * \li Packet header flags 
02165  * \li Packet sizes 
02166  * \li Packet types 
02167  * \li Packet classes 
02168  * \li Conditions prompting ack packets 
02169  * \li Ack types 
02170  * \li Error codes 
02171  * \li Debugging values 
02172  * \par
02173  * An attempt has been made to relate these constant definitions to the objects
02174  * or routines that utilize them. 
02175  * 
02176  *      \subsection sec5-2-1 Section 5.2.1: Configuration Quantities 
02177  * 
02178  * \par
02179  * These definitions provide some basic Rx configuration parameters, including
02180  * the number of simultaneous calls that may be handled on a single connection,
02181  * lightweight thread parameters, and timeouts for various operations. 
02182  * 
02183  * \par Name 
02184  * RX IDLE DEAD TIME
02185  * \par Value 
02186  * 60
02187  * \par Description
02188  * Default idle dead time for connections, in seconds.
02189  * 
02190  * \par Name 
02191  * RX MAX SERVICES
02192  * \par Value 
02193  * 20
02194  * \par Description
02195  * The maximum number of Rx services that may be installed within one
02196  * application.
02197  * 
02198  * \par Name 
02199  * RX PROCESS MAXCALLS
02200  * \par Value 
02201  * 4
02202  * \par Description
02203  * The maximum number of asynchronous calls active simultaneously on any given
02204  * Rx connection.  This value must be set to a power of two.
02205  * 
02206  * \par Name 
02207  * RX DEFAULT STACK SIZE
02208  * \par Value 
02209  * 16,000
02210  * \par Description
02211  * Default lightweight thread stack size, measured in bytes.  This value may be
02212  * overridden by calling the rx_SetStackSize() macro.
02213  * 
02214  * \par Name 
02215  * RX PROCESS PRIORITY
02216  * \par Value 
02217  * LWP NORMAL PRIORITY
02218  * \par Description
02219  * This is the priority under which an Rx thread should run.  There should not
02220  * generally be any reason to change this setting.
02221  * 
02222  * \par Name 
02223  * RX CHALLENGE TIMEOUT
02224  * \par Value 
02225  * 2
02226  * \par Description
02227  * The number of seconds before another authentication request packet is
02228  * generated.
02229  * 
02230  * \par Name 
02231  * RX MAXACKS
02232  * \par Value 
02233  * 255
02234  * \par Description
02235  * Maximum number of individual acknowledgements that may be carried in an Rx
02236  * acknowledgement packet.
02237  * 
02238  *      \subsection sec5-2-2 Section 5.2.2: Waiting Options 
02239  * 
02240  * \par
02241  * These definitions provide readable values indicating whether an operation
02242  * should block when packet buffer resources are not available. 
02243  * 
02244  * \par Name 
02245  * RX DONTWAIT
02246  * \par Value 
02247  * 0
02248  * \par Description
02249  * Wait until the associated operation completes.
02250  * 
02251  * \par Name 
02252  * RX WAIT
02253  * \par Value 
02254  * 1
02255  * \par Description
02256  * Don't wait if the associated operation would block.
02257  * 
02258  *      \subsection sec5-2-3 Section 5.2.3: Connection ID Operations 
02259  * 
02260  * \par
02261  * These values assist in extracting the call channel number from a connection
02262  * identifier. A call channel is the index of a particular asynchronous call
02263  * structure within a single Rx connection. 
02264  * 
02265  * \par Name 
02266  * RX CIDSHIFT
02267  * \par Value 
02268  * 2
02269  * \par Description
02270  * Number of bits to right-shift to isolate a connection ID.  Must be set to
02271  * the log (base two) of RX MAXCALLS.
02272  * 
02273  * \par Name 
02274  * RX CHANNELMASK
02275  * \par Value 
02276  * (RX MAXCALLS-1)
02277  * \par Description
02278  * Mask used to isolate a call channel from a connection ID field.
02279  * 
02280  * \par Name 
02281  * RX CIDMASK
02282  * \par Value 
02283  * (~RX CHANNELMASK)
02284  * \par Description
02285  * Mask used to isolate the connection ID from its field, masking out the call
02286  * channel information.
02287  * 
02288  *      \subsection sec5-2-4 Section 5.2.4: Connection Flags 
02289  * 
02290  * \par
02291  * The values defined here appear in the flags field of Rx connections, as
02292  * defined by the rx connection structure described in Section 5.3.2.2. 
02293  * 
02294  * \par Name 
02295  * RX CONN MAKECALL WAITING
02296  * \par Value 
02297  * 1
02298  * \par Description
02299  * rx MakeCall() is waiting for a channel.
02300  * 
02301  * \par Name 
02302  * RX CONN DESTROY ME
02303  * \par Value 
02304  * 2
02305  * \par Description
02306  * Destroy this (client) connection after its last call completes.
02307  * 
02308  * \par Name 
02309  * RX CONN USING PACKET CKSUM
02310  * \par Value 
02311  * 4
02312  * \par Description
02313  * This packet is using security-related check-summing (a non-zero header,
02314  * spare field has been seen.)
02315  * 
02316  *      \subsection sec5-2-5 Section 5.2.5: Connection Types 
02317  * 
02318  * \par
02319  * Rx stores different information in its connection structures, depending on
02320  * whether the given connection represents the server side (the one providing
02321  * the service) or the client side (the one requesting the service) of the
02322  * protocol. The type field within the connection structure (described in
02323  * Section 5.3.2.2) takes on the following values to differentiate the two
02324  * types of connections, and identifies the fields that are active within the
02325  * connection structure. 
02326  * 
02327  * \par Name 
02328  * RX CLIENT CONNECTION
02329  * \par Value 
02330  * 0
02331  * \par Description
02332  * This is a client-side connection.
02333  * 
02334  * \par Name 
02335  * CONNECTION
02336  * \par Value 
02337  * 1
02338  * \par Description
02339  * This is a server-side connection.
02340  * 
02341  *      \subsection sec5-2-6 Section 5.2.6: Call States 
02342  * 
02343  * \par
02344  * An Rx call on a particular connection may be in one of several states at any
02345  * instant in time. The following definitions identify the range of states that
02346  * a call may assume. 
02347  * 
02348  * \par Name 
02349  * RX STATE NOTINIT
02350  * \par Value 
02351  * 0
02352  * \par Description
02353  * The call structure has never been used, and is thus still completely
02354  * uninitialized.
02355  * 
02356  * \par Name 
02357  * RX STATE PRECALL
02358  * \par Value 
02359  * 1
02360  * \par Description
02361  * A call is not yet in progress, but packets have arrived for it anyway.  This
02362  * only applies to calls within server-side connections.
02363  * 
02364  * \par Name 
02365  * RX STATE ACTIVE
02366  * \par Value 
02367  * 2
02368  * \par Description
02369  * This call is fully active, having an attached lightweight thread operating
02370  * on its behalf.
02371  * 
02372  * \par Name 
02373  * RX STATE DAILY
02374  * \par Value 
02375  * 3
02376  * \par Description
02377  * The call structure is "dallying" after its lightweight thread has completed
02378  * its most recent call.  This is a "hot-standby" condition, where the call
02379  * structure preserves state from the previous call and thus optimizes the
02380  * arrival of further, related calls.
02381  * 
02382  *      \subsection sec5-2-7 Section 5.2.7: Call Flags: 
02383  * 
02384  * \par
02385  * These values are used within the flags field of a variable declared to be of
02386  * type struct rx call, as described in Section 5.3.2.4. They provide
02387  * additional information as to the state of the given Rx call, such as the
02388  * type of event for which it is waiting (if any) and whether or not all
02389  * incoming packets have been received in support of the call. 
02390  * 
02391  * \par Name 
02392  * RX CALL READER WAIT
02393  * \par Value 
02394  * 1
02395  * \par Description
02396  * Reader is waiting for next packet.
02397  * 
02398  * \par Name 
02399  * RX CALL WAIT WINDOW ALLOC
02400  * \par Value 
02401  * 2
02402  * \par Description
02403  * Sender is waiting for a window so that it can allocate buffers.
02404  * 
02405  * \par Name 
02406  * RX CALL WAIT WINDOW SEND
02407  * \par Value 
02408  * 4
02409  * \par Description
02410  * Sender is waiting for a window so that it can send buffers.
02411  * 
02412  * \par Name 
02413  * RX CALL WAIT PACKETS
02414  * \par Value 
02415  * 8
02416  * \par Description
02417  * Sender is waiting for packet buffers.
02418  * 
02419  * \par Name 
02420  * RX CALL RECEIVE DONE
02421  * \par Value 
02422  * 16
02423  * \par Description
02424  * The call is waiting for a lightweight thread to be assigned to the operation
02425  * it has just received.
02426  * 
02427  * \par Name 
02428  * RX CALL RECEIVE DONE 
02429  * \par Value 
02430  * 32
02431  * \par Description
02432  * All packets have been received on this call.
02433  * 
02434  * \par Name 
02435  * RX CALL CLEARED
02436  * \par Value 
02437  * 64
02438  * \par Description
02439  * The receive queue has been cleared when in precall state.
02440  * 
02441  *      \subsection sec5-2-8 Section 5.2.8: Call Modes 
02442  * 
02443  * \par
02444  * These values define the modes of an Rx call when it is in the RX STATE
02445  * ACTIVE state, having a lightweight thread assigned to it. 
02446  * 
02447  * \par Name 
02448  * RX MODE SENDING
02449  * \par Value 
02450  * 1
02451  * \par Description
02452  * We are sending or ready to send.
02453  * 
02454  * \par Name 
02455  * RX MODE RECEIVING
02456  * \par Value 
02457  * 2
02458  * \par Description
02459  * We are receiving or ready to receive.
02460  * 
02461  * \par Name 
02462  * RX MODE ERROR
02463  * \par Value 
02464  * 3
02465  * \par Description
02466  * Something went wrong in the current conversation.
02467  * 
02468  * \par Name 
02469  * RX MODE EOF
02470  * \par Value 
02471  * 4
02472  * \par Description
02473  * The server side has flushed (or the client side has read) the last reply
02474  * packet.
02475  * 
02476  *      \subsection sec5-2-9 Section 5.2.9: Packet Header Flags 
02477  * 
02478  * \par
02479  * Rx packets carry a flag field in their headers, providing additional
02480  * information regarding the packet's contents. The Rx packet header's flag
02481  * field's bits may take the following values: 
02482  * 
02483  * \par Name 
02484  * RX CLIENT INITIATED
02485  * \par Value 
02486  * 1
02487  * \par Description
02488  * Signifies that a packet has been sent/received from the client side of the
02489  * call.
02490  * 
02491  * \par Name 
02492  * RX REQUEST ACK
02493  * \par Value 
02494  * 2
02495  * \par Description
02496  * The Rx calls' peer entity requests an acknowledgement.
02497  * 
02498  * \par Name 
02499  * RX LAST PACKET
02500  * \par Value 
02501  * 4
02502  * \par Description
02503  * This is the final packet from this side of the call.
02504  * 
02505  * \par Name 
02506  * RX MORE PACKETS
02507  * \par Value 
02508  * 8
02509  * \par Description
02510  * There are more packets following this, i.e., the next sequence number seen
02511  * by the receiver should be greater than this one, rather than a
02512  * retransmission of an earlier sequence number.
02513  * 
02514  * \par Name 
02515  * RX PRESET FLAGS
02516  * \par Value 
02517  * (RX CLIENT INITIATED | RX LAST PACKET)
02518  * \par Description
02519  * This flag is preset once per Rx packet.  It doesn't change on retransmission
02520  * of the packet.
02521  * 
02522  *      \subsection sec5-3-10 Section 5.2.10: Packet Sizes 
02523  * 
02524  * \par
02525  * These values provide sizing information on the various regions within Rx
02526  * packets. These packet sections include the IP/UDP headers and bodies as well
02527  * Rx header and bodies. Also covered are such values as different maximum
02528  * packet sizes depending on whether they are targeted to peers on the same
02529  * local network or a more far-flung network. Note that the MTU term appearing
02530  * below is an abbreviation for Maximum Transmission Unit. 
02531  * 
02532  * \par Name 
02533  * RX IPUDP SIZE
02534  * \par Value 
02535  * 28
02536  * \par Description
02537  * The number of bytes taken up by IP/UDP headers.
02538  * 
02539  * \par Name 
02540  * RX MAX PACKET SIZE
02541  * \par Value 
02542  * (1500 - RX IPUDP SIZE)
02543  * \par Description
02544  * This is the Ethernet MTU minus IP and UDP header sizes.
02545  * 
02546  * \par Name 
02547  * RX HEADER SIZE
02548  * \par Value 
02549  * sizeof (struct rx header)
02550  * \par Description
02551  * The number of bytes in an Rx packet header.
02552  * 
02553  * \par Name 
02554  * RX MAX PACKET DATA SIZE
02555  * \par Value 
02556  * (RX MAX PACKET SIZE RX - HEADER SIZE)
02557  * \par Description
02558  * Maximum size in bytes of the user data in a packet.
02559  * 
02560  * \par Name 
02561  * RX LOCAL PACKET SIZE
02562  * \par Value 
02563  * RX MAX PACKET SIZE
02564  * \par Description
02565  * Packet size in bytes to use when being sent to a host on the same net.
02566  * 
02567  * \par Name 
02568  * RX REMOTE PACKET SIZE
02569  * \par Value 
02570  * (576 - RX IPUDP SIZE)
02571  * \par Description
02572  * Packet size in bytes to use when being sent to a host on a different net.
02573  * 
02574  *      \subsection sec5-2-11 Section 5.2.11: Packet Types 
02575  * 
02576  * \par
02577  * The following values are used in the packetType field within a struct rx
02578  * packet, and define the different roles assumed by Rx packets. These roles
02579  * include user data packets, different flavors of acknowledgements, busies,
02580  * aborts, authentication challenges and responses, and debugging vehicles. 
02581  * 
02582  * \par Name 
02583  * RX PACKET TYPE DATA
02584  * \par Value 
02585  * 1
02586  * \par Description
02587  * A user data packet.
02588  * 
02589  * \par Name 
02590  * RX PACKET TYPE ACK
02591  * \par Value 
02592  * 2
02593  * \par Description
02594  * Acknowledgement packet.
02595  * 
02596  * \par Name 
02597  * RX PACKET TYPE BUSY
02598  * \par Value 
02599  * 3
02600  * \par Description
02601  * Busy packet.  The server-side entity cannot accept the call at the moment,
02602  * but the requestor is encouraged to try again later.
02603  * 
02604  * \par Name 
02605  * RX PACKET TYPE ABORT 
02606  * \par Value 
02607  * 4
02608  * \par Description
02609  * Abort packet. No response is needed for this packet type.
02610  * 
02611  * \par Name 
02612  * RX PACKET TYPE ACKALL
02613  * \par Value 
02614  * 5
02615  * \par Description
02616  * Acknowledges receipt of all packets on a call.
02617  * 
02618  * \par Name 
02619  * RX PACKET TYPE CHALLENGE
02620  * \par Value 
02621  * 6
02622  * \par Description
02623  * Challenge the client's identity, requesting credentials.
02624  * 
02625  * \par Name 
02626  * RX PACKET TYPE RESPONSE
02627  * \par Value 
02628  * 7
02629  * \par Description
02630  * Response to a RX PACKET TYPE CHALLENGE authentication challenge packet.
02631  * 
02632  * \par Name 
02633  * RX PACKET TYPE DEBUG
02634  * \par Value 
02635  * 8
02636  * \par Description
02637  * Request for debugging information.
02638  * 
02639  * \par Name 
02640  * RX N PACKET TYPES
02641  * \par Value 
02642  * 9
02643  * \par Description
02644  * The number of Rx packet types defined above.  Note that it also includes
02645  * packet type 0 (which is unused) in the count.
02646  * 
02647  * \par
02648  * The RX PACKET TYPES definition provides a mapping of the above values to
02649  * human-readable string names, and is exported by the rx packetTypes variable
02650  * catalogued in Section 5.4.9. 
02651  * 
02652  * \code 
02653  * {
02654  *      "data", 
02655  *      "ack", 
02656  *      "busy", 
02657  *      "abort", 
02658  *      "ackall", 
02659  *      "challenge", 
02660  *      "response", 
02661  *      "debug" 
02662  * } 
02663  * \endcode
02664  * 
02665  *      \subsection sec5-2-12 Section 5.2.12: Packet Classes 
02666  * 
02667  * \par
02668  * These definitions are used internally to manage alloction of Rx packet
02669  * buffers according to quota classifications. Each packet belongs to one of
02670  * the following classes, and its buffer is derived from the corresponding
02671  * pool. 
02672  * 
02673  * \par Name 
02674  * RX PACKET CLASS RECEIVE
02675  * \par Value 
02676  * 0
02677  * \par Description
02678  * Receive packet for user data.
02679  * 
02680  * \par Name 
02681  * RX PACKET CLASS SEND
02682  * \par Value 
02683  * 1
02684  * \par Description
02685  * Send packet for user data.
02686  * 
02687  * \par Name 
02688  * RX PACKET CLASS SPECIAL
02689  * \par Value 
02690  * 2
02691  * \par Description
02692  * A special packet that does not hold user data, such as an acknowledgement or
02693  * authentication challenge.
02694  * 
02695  * \par Name 
02696  * RX N PACKET CLASSES
02697  * \par Value 
02698  * 3
02699  * \par Description
02700  * The number of Rx packet classes defined above.
02701  * 
02702  *      \subsection sec5-2-13 Section 5.2.13: Conditions Prompting Ack Packets 
02703  * 
02704  * \par
02705  * Rx acknowledgement packets are constructed and sent by the protocol
02706  * according to the following reasons. These values appear in the Rx packet
02707  * header of the ack packet itself. 
02708  * 
02709  * \par Name 
02710  * RX ACK REQUESTED
02711  * \par Value 
02712  * 1
02713  * \par Description
02714  * The peer has explicitly requested an ack on this packet.
02715  * 
02716  * \par Name 
02717  * RX ACK DUPLICATE
02718  * \par Value 
02719  * 2
02720  * \par Description
02721  * A duplicate packet has been received.
02722  * 
02723  * \par Name 
02724  * RX ACK OUT OF SEQUENCE
02725  * \par Value 
02726  * 3
02727  * \par Description
02728  * A packet has arrived out of sequence.
02729  * 
02730  * \par Name 
02731  * RX ACK EXCEEDS WINDOW
02732  * \par Value 
02733  * 4
02734  * \par Description
02735  * A packet sequence number higher than maximum value allowed by the call's
02736  * window has been received.
02737  * 
02738  * \par Name 
02739  * RX ACK NOSPACE
02740  * \par Value 
02741  * 5
02742  * \par Description
02743  * No packet buffer space is available.
02744  * 
02745  * \par Name 
02746  * RX ACK PING
02747  * \par Value 
02748  * 6
02749  * \par Description
02750  * Acknowledgement for keep-alive purposes.
02751  * 
02752  * \par Name 
02753  * RX ACK PING RESPONSE
02754  * \par Value 
02755  * 7
02756  * \par Description
02757  * Response to a RX ACK PING packet.
02758  * 
02759  * \par Name 
02760  * RX ACK DELAY
02761  * \par Value 
02762  * 8
02763  * \par Description
02764  * An ack generated due to a period of inactivity after normal packet
02765  * receptions.
02766  * 
02767  *      \subsection 5-2-14 Section 5.2.14: Acknowledgement Types 
02768  * 
02769  * \par
02770  * These are the set of values placed into the acks array in an Rx
02771  * acknowledgement packet, whose data format is defined by struct rx ackPacket.
02772  * These definitions are used to convey positive or negative acknowledgements
02773  * for a given range of packets. 
02774  * 
02775  * \par Name 
02776  * RX ACK TYPE NACK
02777  * \par Value 
02778  * 0
02779  * \par Description
02780  * Receiver doesn't currently have the associated packet; it may never hae been
02781  * received, or received and then later dropped before processing.
02782  * 
02783  * \par Name 
02784  * RX ACK TYPE ACK
02785  * \par Value 
02786  * 1
02787  * \par Description
02788  * Receiver has the associated packet queued, although it may later decide to
02789  * discard it.
02790  * 
02791  *      \subsection sec5-2-15 Section 5.2.15: Error Codes 
02792  * 
02793  * \par
02794  * Rx employs error codes ranging from -1 to -64. The Rxgen stub generator may
02795  * use other error codes less than -64. User programs calling on Rx, on the
02796  * other hand, are expected to return positive error codes. A return value of
02797  * zero is interpreted as an indication that the given operation completed
02798  * successfully. 
02799  * 
02800  * \par Name 
02801  * RX CALL DEAD
02802  * \par Value 
02803  * -1
02804  * \par Description
02805  * A connection has been inactive past Rx's tolerance levels and has been shut
02806  * down.
02807  * 
02808  * \par Name 
02809  * RX INVALID OPERATION
02810  * \par Value 
02811  * -2
02812  * \par Description
02813  * An invalid operation has been attempted, including such protocol errors as
02814  * having a client-side call send data after having received the beginning of a
02815  * reply from its server-side peer.
02816  * 
02817  * \par Name 
02818  * RX CALL TIMEOUT
02819  * \par Value 
02820  * -3
02821  * \par Description
02822  * The (optional) timeout value placed on this call has been exceeded (see
02823  * Sections 5.5.3.4 and 5.6.5).
02824  * 
02825  * \par Name 
02826  * RX EOF
02827  * \par Value 
02828  * -4
02829  * \par Description
02830  * Unexpected end of data on a read operation.
02831  * 
02832  * \par Name 
02833  * RX PROTOCOL ERROR
02834  * \par Value 
02835  * -5
02836  * \par Description
02837  * An unspecified low-level Rx protocol error has occurred.
02838  * 
02839  * \par Name 
02840  * RX USER ABORT
02841  * \par Value 
02842  * -6
02843  * \par Description
02844  * A generic user abort code, used when no more specific error code needs to be
02845  * communicated.  For example, Rx clients employing the multicast feature (see
02846  * Section 1.2.8) take advantage of this error code.
02847  * 
02848  *      \subsection sec5-2-16 Section 5.2.16: Debugging Values 
02849  * 
02850  * \par
02851  * Rx provides a set of data collections that convey information about its
02852  * internal status and performance. The following values have been defined in
02853  * support of this debugging and statistics-collection feature. 
02854  * 
02855  *      \subsubsection sec5-3-16-1 Section 5.2.16.1: Version Information 
02856  * 
02857  * \par
02858  * Various versions of the Rx debugging/statistics interface are in existance,
02859  * each defining different data collections and handling certain bugs. Each Rx
02860  * facility is stamped with a version number of its debugging/statistics
02861  * interface, allowing its clients to tailor their requests to the precise data
02862  * collections that are supported by a particular Rx entity, and to properly
02863  * interpret the data formats received through this interface. All existing Rx
02864  * implementations should be at revision M. 
02865  * 
02866  * \par Name 
02867  * RX DEBUGI VERSION MINIMUM
02868  * \par Value 
02869  * 'L'
02870  * \par Description
02871  * The earliest version of Rx statistics available.
02872  * 
02873  * \par Name 
02874  * RX DEBUGI VERSION
02875  * \par Value 
02876  * 'M'
02877  * \par Description
02878  * The latest version of Rx statistics available.
02879  * 
02880  * \par Name 
02881  * RX DEBUGI VERSION W SECSTATS
02882  * \par Value 
02883  * 'L'
02884  * \par Description
02885  * Identifies the earliest version in which statistics concerning Rx security
02886  * objects is available.
02887  * 
02888  * \par Name 
02889  * RX DEBUGI VERSION W GETALLCONN
02890  * \par Value 
02891  * 'M'
02892  * \par Description
02893  * The first version that supports getting information about all current Rx
02894  * connections, as specified y the RX DEBUGI GETALLCONN debugging request
02895  * packet opcode described below.
02896  * 
02897  * \par Name 
02898  * RX DEBUGI VERSION W RXSTATS
02899  * \par Value 
02900  * 'M'
02901  * \par Description
02902  * The first version that supports getting all the Rx statistics in one
02903  * operation, as specified by the RX DEBUGI RXSTATS debugging request packet
02904  * opcode described below.
02905  * 
02906  * \par Name 
02907  * RX DEBUGI VERSION W UNALIGNED CONN
02908  * \par Value 
02909  * 'L'
02910  * \par Description
02911  * There was an alignment problem discovered when returning Rx connection
02912  * information in older versions of this debugging/statistics interface.  This
02913  * identifies the last version that exhibited this alignment problem.
02914  * 
02915  *      \subsubsection sec5-2-16-2 Section 5.2.16.2: Opcodes 
02916  * 
02917  * \par
02918  * When requesting debugging/statistics information, the caller specifies one
02919  * of the following supported data collections: 
02920  * 
02921  * \par Name 
02922  * RX DEBUGI GETSTATS
02923  * \par Value 
02924  * 1
02925  * \par Description
02926  * Get basic Rx statistics.
02927  * 
02928  * \par Name 
02929  * RX DEBUGI GETCONN
02930  * \par Value 
02931  * 2
02932  * \par Description
02933  * Get information on all Rx connections considered "interesting" (as defined
02934  * below), and no others.
02935  * 
02936  * \par Name 
02937  * RX DEBUGI GETALLCONN
02938  * \par Value 
02939  * 3
02940  * \par Description
02941  * Get information on all existing Rx connection structures, even
02942  * "uninteresting" ones.
02943  * 
02944  * \par Name 
02945  * RX DEBUGI RXSTATS
02946  * \par Value 
02947  * 4
02948  * \par Description
02949  * Get all available Rx stats.
02950  * 
02951  * \par
02952  * An Rx connection is considered "interesting" if it is waiting for a call
02953  * channel to free up or if it has been marked for destruction. If neither is
02954  * true, a connection is still considered interesting if any of its call
02955  * channels is actively handling a call or in its preparatory pre-call state.
02956  * Failing all the above conditions, a connection is still tagged as
02957  * interesting if any of its call channels is in either of the RX MODE SENDING
02958  * or RX MODE RECEIVING modes, which are not allowed when the call is not
02959  * active. 
02960  * 
02961  *      \subsubsection sec5-2-16-3 Section 5.2.16.3: Queuing 
02962  * 
02963  * \par
02964  * These two queueing-related values indicate whether packets are present on
02965  * the incoming and outgoing packet queues for a given Rx call. These values
02966  * are only used in support of debugging and statistics-gathering operations. 
02967  * 
02968  * \par Name 
02969  * RX OTHER IN
02970  * \par Value 
02971  * 1
02972  * \par Description
02973  * Packets available in in queue.
02974  * 
02975  * \par Name 
02976  * RX OTHER OUT 
02977  * \par Value 
02978  * 2
02979  * \par Description
02980  * Packets available in out queue.
02981  * 
02982  *      \section sec5-3 Section 5.3: Structures 
02983  * 
02984  * \par
02985  * This section describes the major exported Rx data structures of interest to
02986  * application programmers. The following categories are utilized for the
02987  * purpose of organizing the structure descriptions: 
02988  * \li Security objects 
02989  * \li Protocol objects 
02990  * \li Packet formats 
02991  * \li Debugging and statistics 
02992  * \li Miscellaneous 
02993  * \par
02994  * Please note that many fields described in this section are declared to be
02995  * VOID. This is defined to be char, and is used to get around some compiler
02996  * limitations. 
02997  *      \subsection sec5-3-1 Section 5.3.1: Security Objects 
02998  * 
02999  * \par
03000  * As explained in Section 1.2.1, Rx provides a modular, extensible security
03001  * model. This allows Rx applications to either use one of the built-in
03002  * security/authentication protocol packages or write and plug in one of their
03003  * own. This section examines the various structural components used by Rx to
03004  * support generic security and authentication modules. 
03005  * 
03006  *      \subsubsection sec5-3-1-1 Section 5.3.1.1: struct rx securityOps 
03007  * 
03008  * \par
03009  * As previously described, each Rx security object must export a fixed set of
03010  * interface functions, providing the full set of operations defined on the
03011  * object. The rx securityOps structure defines the array of functions
03012  * comprising this interface. The Rx facility calls these routines at the
03013  * appropriate times, without knowing the specifics of how any particular
03014  * security object implements the operation. 
03015  * \par
03016  * A complete description of these interface functions, including information
03017  * regarding their exact purpose, parameters, and calling conventions, may be
03018  * found in Section 5.5.7. 
03019  * \par
03020  * \b fields 
03021  * \li int (*op Close)() - React to the disposal of a security object. 
03022  * \li int (*op NewConnection)() - Invoked each time a new Rx connection
03023  * utilizing the associated security object is created. 
03024  * \li int (*op PreparePacket)() - Invoked each time an outgoing Rx packet is
03025  * created and sent on a connection using the given security object. 
03026  * \li int (*op SendPacket)() - Called each time a packet belonging to a call
03027  * in a connection using the security object is physically transmitted. 
03028  * \li int (*op CheckAuthentication)() - This function is executed each time it
03029  * is necessary to check whether authenticated calls are being perfomed on a
03030  * connection using the associated security object. 
03031  * \li int (*op CreateChallenge)() - Invoked each time a server-side challenge
03032  * event is created by Rx, namely when the identity of the principal associated
03033  * with the peer process must be determined. 
03034  * \li int (*op GetChallenge)() - Called each time a client-side packet is
03035  * constructed in response to an authentication challenge. 
03036  * \li int (*op GetResponse)() - Executed each time a response to a challenge
03037  * event must be received on the server side of a connection. 
03038  * \li int (*op CheckResponse)() - Invoked each time a response to an
03039  * authentication has been received, validating the response and pulling out
03040  * the required authentication information. 
03041  * \li int (*op CheckPacket) () - Invoked each time an Rx packet has been
03042  * received, making sure that the packet is properly formatted and that it
03043  * hasn't been altered. 
03044  * \li int (*op DestroyConnection)() - Called each time an Rx connection
03045  * employing the given security object is destroyed. 
03046  * \li int (*op GetStats)() - Executed each time a request for statistics on
03047  * the given security object has been received. 
03048  * \li int (*op Spare1)()-int (*op Spare3)() - Three spare function slots,
03049  * reserved for future use. 
03050  * 
03051  *      \subsubsection sec5-3-1-2 Section 5.2.1.2: struct rx securityClass 
03052  * 
03053  * \par
03054  * Variables of type struct rx securityClass are used to represent
03055  * instantiations of a particular security model employed by Rx. It consists of
03056  * a pointer to the set of interface operations implementing the given security
03057  * object, along with a pointer to private storage as necessary to support its
03058  * operations. These security objects are also reference-counted, tracking the
03059  * number of Rx connections in existance that use the given security object. If
03060  * the reference count drops to zero, the security module may garbage-collect
03061  * the space taken by the unused security object. 
03062  * \par
03063  * \b fields 
03064  * \li struct rx securityOps *ops - Pointer to the array of interface functions
03065  * for the security object. 
03066  * \li VOID *privateData - Pointer to a region of storage used by the security
03067  * object to support its operations. 
03068  * \li int refCount - A reference count on the security object, tracking the
03069  * number of Rx connections employing this model. 
03070  * 
03071  *      \subsubsection sec5-3-1-3 Section 5.3.1.3: struct rx
03072  *      securityObjectStats 
03073  * 
03074  * \par
03075  * This structure is used to report characteristics for an instantiation of a
03076  * security object on a particular Rx connection, as well as performance
03077  * figures for that object. It is used by the debugging portions of the Rx
03078  * package. Every security object defines and manages fields such as level and
03079  * flags differently. 
03080  * \par
03081  * \b fields 
03082  * \li char type - The type of security object being implemented. Existing
03083  * values are: 
03084  * \li 0: The null security package. 
03085  * \li 1: An obsolete Kerberos-like security object. 
03086  * \li 2: The rxkad discipline (see Chapter 3). 
03087  * \li char level - The level at which encryption is utilized. 
03088  * \li char sparec[10] - Used solely for alignment purposes. 
03089  * \li long flags - Status flags regarding aspects of the connection relating
03090  * to the security object. 
03091  * \li u long expires - Absolute time when the authentication information
03092  * cached by the given connection expires. A value of zero indicates that the
03093  * associated authentication information is valid for all time. 
03094  * \li u long packetsReceived - Number of packets received on this particular
03095  * connection, and thus the number of incoming packets handled by the
03096  * associated security object. 
03097  * \li u long packetsSent - Number of packets sent on this particular
03098  * connection, and thus the number of outgoing packets handled by the
03099  * associated security object. 
03100  * \li u long bytesReceived - Overall number of "payload" bytes received (i.e.,
03101  * packet bytes not associated with IP headers, UDP headers, and the security
03102  * module's own header and trailer regions) on this connection. 
03103  * \li u long bytesSent - Overall number of "payload" bytes sent (i.e., packet
03104  * bytes not associated with IP headers, UDP headers, and the security module's
03105  * own header and trailer regions) on this connection. 
03106  * \li short spares[4] - Several shortword spares, reserved for future use. 
03107  * \li long sparel[8] - Several longword spares, reserved for future use. 
03108  * 
03109  *      \subsection sec5-3-2 Section 5.3.2: Protocol Objects 
03110  * 
03111  * \par
03112  * The structures describing the main abstractions and entities provided by Rx,
03113  * namely services, peers, connections and calls are covered in this section. 
03114  * 
03115  *      \subsubsection sec5-3-2-1 Section 5.3.2.1: struct rx service 
03116  * 
03117  * \par
03118  * An Rx-based server exports services, or specific RPC interfaces that
03119  * accomplish certain tasks. Services are identified by (host-address,
03120  * UDP-port, serviceID) triples. An Rx service is installed and initialized on
03121  * a given host through the use of the rx NewService() routine (See Section
03122  * 5.6.3). Incoming calls are stamped with the Rx service type, and must match
03123  * an installed service to be accepted. Internally, Rx services also carry
03124  * string names for purposes of identification. These strings are useful to
03125  * remote debugging and statistics-gathering programs. The use of a service ID
03126  * allows a single server process to export multiple, independently-specified
03127  * Rx RPC services. 
03128  * \par
03129  * Each Rx service contains one or more security classes, as implemented by
03130  * individual security objects. These security objects implement end-to-end
03131  * security protocols. Individual peer-to-peer connections established on
03132  * behalf of an Rx service will select exactly one of the supported security
03133  * objects to define the authentication procedures followed by all calls
03134  * associated with the connection. Applications are not limited to using only
03135  * the core set of built-in security objects offered by Rx. They are free to
03136  * define their own security objects in order to execute the specific protocols
03137  * they require. 
03138  * \par
03139  * It is possible to specify both the minimum and maximum number of lightweight
03140  * processes available to handle simultaneous calls directed to an Rx service.
03141  * In addition, certain procedures may be registered with the service and
03142  * called at set times in the course of handling an RPC request. 
03143  * \par
03144  * \b fields 
03145  * \li u short serviceId - The associated service number. 
03146  * \li u short servicePort - The chosen UDP port for this service. 
03147  * \li char *serviceName - The human-readable service name, expressed as a
03148  * character 
03149  * \li string. osi socket socket - The socket structure or file descriptor used
03150  * by this service. 
03151  * \li u short nSecurityObjects - The number of entries in the array of
03152  * supported security objects. 
03153  * \li struct rx securityClass **securityObjects - The array of pointers to the
03154  * ser
03155  * vice's security class objects. 
03156  * \li long (*executeRequestProc)() - A pointer to the routine to call when an
03157  * RPC request is received for this service. 
03158  * \li VOID (*destroyConnProc)() - A pointer to the routine to call when one of
03159  * the server-side connections associated with this service is destroyed. 
03160  * \li VOID (*newConnProc)() - A pointer to the routine to call when a
03161  * server-side connection associated with this service is created. 
03162  * \li VOID (*beforeProc)() - A pointer to the routine to call before an
03163  * individual RPC call on one of this service's connections is executed. 
03164  * \li VOID (*afterProc)() - A pointer to the routine to call after an
03165  * individual RPC call on one of this service's connections is executed. 
03166  * \li short nRequestsRunning - The number of simultaneous RPC calls currently
03167  * in progress for this service. 
03168  * \li short maxProcs - This field has two meanings. first, maxProcs limits the
03169  * total number of requests that may execute in parallel for any one service.
03170  * It also guarantees that this many requests may be handled in parallel if
03171  * there are no active calls for any other service. 
03172  * \li short minProcs - The minimum number of lightweight threads (hence
03173  * requests) guaranteed to be simultaneously executable. 
03174  * \li short connDeadTime - The number of seconds until a client of this
03175  * service will be declared to be dead, if it is not responding to the RPC
03176  * protocol. 
03177  * \li short idleDeadTime - The number of seconds a server-side connection for
03178  * this service will wait for packet I/O to resume after a quiescent period
03179  * before the connection is marked as dead. 
03180  * 
03181  *      \subsubsection sec5-3-2-2 Section 5.3.2.2: struct rx connection 
03182  * 
03183  * \par
03184  * An Rx connection represents an authenticated communication path, allowing
03185  * multiple asynchronous conversations (calls). Each connection is identified
03186  * by a connection ID. The low-order bits of the connection ID are reserved so
03187  * they may be stamped with the index of a particular call channel. With up to
03188  * RX MAXCALLS concurrent calls (set to 4 in this implementation), the bottom
03189  * two bits are set aside for this purpose. The connection ID is not sufficient
03190  * by itself to uniquely identify an Rx connection. Should a client crash and
03191  * restart, it may reuse a connection ID, causing inconsistent results. In
03192  * addition to the connection ID, the epoch, or start time for the client side
03193  * of the connection, is used to identify a connection. Should the above
03194  * scenario occur, a different epoch value will be chosen by the client,
03195  * differentiating this incarnation from the orphaned connection record on the
03196  * server side. 
03197  * \par
03198  * Each connection is associated with a parent service, which defines a set of
03199  * supported security models. At creation time, an Rx connection selects the
03200  * particular security protocol it will implement, referencing the associated
03201  * service. The connection structure maintains state about the individual calls
03202  * being simultaneously handled. 
03203  * \par
03204  * \b fields 
03205  * \li struct rx connection *next - Used for internal queueing. 
03206  * \li struct rx peer *peer - Pointer to the connection's peer information (see
03207  * below). 
03208  * \li u long epoch - Process start time of the client side of the connection. 
03209  * \li u long cid - Connection identifier. The call channel (i.e., the index
03210  * into the connection's array of call structures) may appear in the bottom
03211  * bits. 
03212  * \li VOID *rock - Pointer to an arbitrary region of memory in support of the
03213  * connection's operation. The contents of this area are opaque to the Rx
03214  * facility in general, but are understood by any special routines used by this
03215  * connection. 
03216  * \li struct rx call *call[RX MAXCALLS] - Pointer to the call channel
03217  * structures, describing up to RX MAXCALLS concurrent calls on this
03218  * connection. 
03219  * \li u long callNumber[RX MAXCALLS] - The set of current call numbers on each
03220  * of the call channels. 
03221  * \li int timeout - Obsolete; no longer used. 
03222  * \li u char flags - Various states of the connection; see Section 5.2.4 for
03223  * individual bit definitions. 
03224  * \li u char type - Whether the connection is a server-side or client-side
03225  * one. See Section 5.2.5 for individual bit definitions. 
03226  * \li u short serviceId - The service ID that should be stamped on requests.
03227  * This field is only used by client-side instances of connection structures. 
03228  * \li struct rx service *service - A pointer to the service structure
03229  * associated with this connection. This field is only used by server-side
03230  * instances of connection structures. 
03231  * \li u long serial - Serial number of the next outgoing packet associated
03232  * with this connection. 
03233  * \li u long lastSerial - Serial number of the last packet received in
03234  * association with this connection. This field is used in computing packet
03235  * skew. 
03236  * \li u short secondsUntilDead - Maximum numer of seconds of silence that
03237  * should be tolerated from the connection's peer before calls will be
03238  * terminated with an RX CALL DEAD error. 
03239  * \li u char secondsUntilPing - The number of seconds between "pings"
03240  * (keep-alive probes) when at least one call is active on this connection. 
03241  * \li u char securityIndex - The index of the security object being used by
03242  * this connection. This number selects a slot in the security class array
03243  * maintained by the service associated with the connection. 
03244  * \li long error - Records the latest error code for calls occurring on this
03245  * connection. 
03246  * \li struct rx securityClass *securityObject - A pointer to the security
03247  * object used by this connection. This should coincide with the slot value
03248  * chosen by the securityIndex field described above. 
03249  * \li VOID *securityData - A pointer to a region dedicated to hosting any
03250  * storage required by the security object being used by this connection. 
03251  * \li u short securityHeaderSize - The length in bytes of the portion of the
03252  * packet header before the user's data that contains the security module's
03253  * information. 
03254  * \li u short securityMaxTrailerSize - The length in bytes of the packet
03255  * trailer, appearing after the user's data, as mandated by the connection's
03256  * security module. 
03257  * \li struct rxevent *challengeEvent -Pointer to an event that is scheduled
03258  * when the server side of the connection is challenging the client to
03259  * authenticate itself. 
03260  * \li int lastSendTime - The last time a packet was sent on this connection. 
03261  * \li long maxSerial - The largest serial number seen on incoming packets. 
03262  * \li u short hardDeadTime - The maximum number of seconds that any call on
03263  * this connection may execute. This serves to throttle runaway calls. 
03264  * 
03265  *      \subsubsection sec5-3-2-3 Section 5.3.2.3: struct rx peer 
03266  * 
03267  * \par
03268  * For each connection, Rx maintains information describing the entity, or
03269  * peer, on the other side of the wire. A peer is identified by a (host,
03270  * UDP-port) pair. Included in the information kept on this remote
03271  * communication endpoint are such network parameters as the maximum packet
03272  * size supported by the host, current readings on round trip time to
03273  * retransmission delays, and packet skew (see Section 1.2.7). There are also
03274  * congestion control fields, ranging from descriptions of the maximum number
03275  * of packets that may be sent to the peer without pausing and retransmission
03276  * statistics. Peer structures are shared between connections whenever
03277  * possible, and hence are reference-counted. A peer object may be
03278  * garbage-collected if it is not actively referenced by any connection
03279  * structure and a sufficient period of time has lapsed since the reference
03280  * count dropped to zero. 
03281  * \par
03282  * \b fields 
03283  * \li struct rx peer *next - Use to access internal lists. 
03284  * \li u long host - Remote IP address, in network byte order 
03285  * \li u short port - Remote UDP port, in network byte order 
03286  * \li short packetSize - Maximum packet size for this host, if known. 
03287  * \li u long idleWhen - When the refCount reference count field (see below)
03288  * went to zero. 
03289  * \li short refCount - Reference count for this structure 
03290  * \li u char burstSize - Reinitialization size for the burst field (below). 
03291  * \li u char burst - Number of packets that can be transmitted immediately
03292  * without pausing. 
03293  * \li struct clock burstWait - Time delay until new burst aimed at this peer
03294  * is allowed. 
03295  * \li struct queue congestionQueue - Queue of RPC call descriptors that are
03296  * waiting for a non-zero burst value. 
03297  * \li int rtt - Round trip time to the peer, measured in milliseconds. 
03298  * \li struct clock timeout - Current retransmission delay to the peer. 
03299  * \li int nSent - Total number of distinct data packets sent, not including
03300  * retransmissions. 
03301  * \li int reSends - Total number of retransmissions for this peer since the
03302  * peer structure instance was created. 
03303  * \li u long inPacketSkew - Maximum skew on incoming packets (see Section
03304  * 1.2.7) 
03305  * \li u long outPacketSkew - Peer-reported maximum skew on outgoing packets
03306  * (see Section 1.2.7). 
03307  * 
03308  *      \subsubsection sec5-3-2-4 Section 5.3.2.4: struct rx call 
03309  * 
03310  * \par
03311  * This structure records the state of an active call proceeding on a given Rx
03312  * connection. As described above, each connection may have up to RX MAXCALLS
03313  * calls active at any one instant, and thus each connection maintains an array
03314  * of RX MAXCALLS rx call structures. The information contained here is
03315  * specific to the given call; "permanent" call state, such as the call number,
03316  * is maintained in the connection structure itself. 
03317  * \par
03318  * \b fields 
03319  * \li struct queue queue item header - Queueing information for this
03320  * structure. 
03321  * \li struct queue tq - Queue of outgoing ("transmit") packets. 
03322  * \li struct queue rq - Queue of incoming ("receive") packets. 
03323  * \li char *bufPtr - Pointer to the next byte to fill or read in the call's
03324  * current packet, depending on whether it is being transmitted or received. 
03325  * \li u short nLeft - Number of bytes left to read in the first packet in the
03326  * reception queue (see field rq). 
03327  * \li u short nFree - Number of bytes still free in the last packet in the
03328  * transmission queue (see field tq). 
03329  * \li struct rx packet *currentPacket - Pointer to the current packet being
03330  * assembled or read. 
03331  * \li struct rx connection *conn - Pointer to the parent connection for this
03332  * call. 
03333  * \li u long *callNumber - Pointer to call number field within the call's
03334  * current packet. 
03335  * \li u char channel - Index within the parent connection's call array that
03336  * describes this call. 
03337  * \li u char dummy1, dummy2 - These are spare fields, reserved for future use. 
03338  * \li u char state - Current call state. The associated bit definitions appear
03339  * in Section 5.2.7. 
03340  * \li u char mode - Current mode of a call that is in RX STATE ACTIVE state.
03341  * The associated bit definitions appear in Section 5.2.8. 
03342  * \li u char flags - Flags pertaining to the state of the given call. The
03343  * associated bit definitions appear in Section 5.2.7. 
03344  * \li u char localStatus - Local user status information, sent out of band.
03345  * This field is currently not in use, set to zero. 
03346  * \li u char remoteStatus - Remote user status information, received out of
03347  * band.  This field is currently not in use, set to zero. 
03348  * \li long error - Error condition for this call. 
03349  * \li u long timeout - High level timeout for this call 
03350  * \li u long rnext - Next packet sequence number expected to be received. 
03351  * \li u long rprev - Sequence number of the previous packet received. This
03352  * number is used to decide the proper sequence number for the next packet to
03353  * arrive, and may be used to generate a negative acknowledgement. 
03354  * \li u long rwind - Width of the packet receive window for this call. The
03355  * peer must not send packets with sequence numbers greater than or equal to
03356  * rnext + rwind. 
03357  * \li u long tfirst - Sequence number of the first unacknowledged transmit
03358  * packet for this call. 
03359  * \li u long tnext - Next sequence number to use for an outgoing packet. 
03360  * \li u long twind - Width of the packet transmit window for this call. Rx
03361  * cannot assign a sequence number to an outgoing packet greater than or equal
03362  * to tfirst + twind. 
03363  * \li struct rxevent *resendEvent - Pointer to a pending retransmission event,
03364  * if any. 
03365  * \li struct rxevent *timeoutEvent - Pointer to a pending timeout event, if
03366  * any. 
03367  * \li struct rxevent *keepAliveEvent - Pointer to a pending keep-alive event,
03368  * if this is an active call. 
03369  * \li struct rxevent *delayedAckEvent - Pointer to a pending delayed
03370  * acknowledgement packet event, if any. Transmission of a delayed
03371  * acknowledgement packet is scheduled after all outgoing packets for a call
03372  * have been sent. If neither a reply nor a new call are received by the time
03373  * the delayedAckEvent activates, the ack packet will be sent. 
03374  * \li int lastSendTime - Last time a packet was sent for this call. 
03375  * \li int lastReceiveTime - Last time a packet was received for this call. 
03376  * \li VOID (*arrivalProc)() - Pointer to the procedure to call when reply is
03377  * received. 
03378  * \li VOID *arrivalProcHandle - Pointer to the handle to pass to the
03379  * arrivalProc as its first argument. 
03380  * \li VOID *arrivalProcArg - Pointer to an additional argument to pass to the
03381  * given arrivalProc. 
03382  * \li u long lastAcked - Sequence number of the last packet "hard-acked" by
03383  * the receiver. A packet is considered to be hard-acked if an acknowledgement
03384  * is generated after the reader has processed it. The Rx facility may
03385  * sometimes "soft-ack" a windowfull of packets before they have been picked up
03386  * by the receiver. 
03387  * \li u long startTime - The time this call started running. 
03388  * \li u long startWait - The time that a server began waiting for input data
03389  * or send quota. 
03390  * 
03391  *      \subsection sec5-3-3 Section 5.3.3: Packet Formats 
03392  * 
03393  * \par
03394  * The following sections cover the different data formats employed by the
03395  * suite of Rx packet types, as enumerated in Section 5.2.11. A description of
03396  * the most commonly-employed Rx packet header appears first, immediately
03397  * followed by a description of the generic packet container and descriptor.
03398  * The formats for Rx acknowledgement packets and debugging/statistics packets
03399  * are also examined. 
03400  * 
03401  *      \subsubsection sec5-3-3-1 Section 5.3.3.1: struct rx header 
03402  * 
03403  * \par
03404  * Every Rx packet has its own header region, physically located after the
03405  * leading IP/UDP headers. This header contains connection, call, security, and
03406  * sequencing information. Along with a type identifier, these fields allow the
03407  * receiver to properly interpret the packet. In addition, every client relates
03408  * its "epoch", or Rx incarnation date, in each packet. This assists in
03409  * identifying protocol problems arising from reuse of connection identifiers
03410  * due to a client restart. Also included in the header is a byte of
03411  * user-defined status information, allowing out-of-band channel of
03412  * communication for the higher-level application using Rx as a transport
03413  * mechanism. 
03414  * \par
03415  * \b fields 
03416  * \li u long epoch - Birth time of the client Rx facility. 
03417  * \li u long cid - Connection identifier, as defined by the client. The last
03418  * RX CIDSHIFT bits in the cid field identify which of the server-side RX
03419  * MAXCALLS call channels is to receive the packet. 
03420  * \li u long callNumber - The current call number on the chosen call channel. 
03421  * \li u long seq - Sequence number of this packet. Sequence numbers start with
03422  * 0 for each new Rx call. 
03423  * \li u long serial - This packet's serial number. A new serial number is
03424  * stamped on each packet transmitted (or retransmitted). 
03425  * \li u char type - What type of Rx packet this is; see Section 5.2.11 for the
03426  * list of legal definitions. 
03427  * \li u char flags - Flags describing this packet; see Section 5.2.9 for the
03428  * list of legal settings. 
03429  * \li u char userStatus - User-defined status information, uninterpreted by
03430  * the Rx facility itself. This field may be easily set or retrieved from Rx
03431  * packets via calls to the rx GetLocalStatus(), rx SetLocalStatus(), rx
03432  * GetRemoteStatus(), and rx SetRemoteStatus() macros. 
03433  * \li u char securityIndex - Index in the associated server-side service class
03434  * of the security object used by this call. 
03435  * \li u short serviceId - The server-provided service ID to which this packet
03436  * is directed. 
03437  * \li u short spare - This field was originally a true spare, but is now used
03438  * by the built-in rxkad security module for packet header checksums. See the
03439  * descriptions of the related rx IsUsingPktChecksum(), rx GetPacketCksum(),
03440  * and rx SetPacketCksum() macros. 
03441  * 
03442  *      \subsubsection sec5-3-3-2 Section 5.3.3.2: struct rx packet 
03443  * 
03444  * \par
03445  * This structure is used to describe an Rx packet, and includes the wire
03446  * version of the packet contents, where all fields exist in network byte
03447  * order. It also includes acknowledgement, length, type, and queueing
03448  * information. 
03449  * \par
03450  * \b fields 
03451  * \li struct queue queueItemHeader - field used for internal queueing. 
03452  * \li u char acked - If non-zero, this field indicates that this packet has
03453  * been tentatively (soft-) acknowledged. Thus, the packet has been accepted by
03454  * the rx peer entity on the other side of the connection, but has not yet
03455  * necessarily been passed to the true reader. The sender is not free to throw
03456  * the packet away, as it might still get dropped by the peer before it is
03457  * delivered to its destination process. 
03458  * \li short length - Length in bytes of the user data section. 
03459  * \li u char packetType - The type of Rx packet described by this record. The
03460  * set of legal choices is available in Section 5.2.11. 
03461  * \li struct clock retryTime - The time when this packet should be
03462  * retransmitted next. 
03463  * \li struct clock timeSent - The last time this packet was transmitted. 
03464  * \li struct rx header header - A copy of the internal Rx packet header. 
03465  * \li wire - The text of the packet as it appears on the wire. This structure
03466  * has the following sub-fields: 
03467  *      \li u long head[RX HEADER SIZE/sizeof(long)] The wire-level contents of
03468  *      IP, UDP, and Rx headers. 
03469  *      \li u long data[RX MAX PACKET DATA SIZE/sizeof(long)] The wire form of
03470  *      the packet's "payload", namely the user data it carries. 
03471  * 
03472  *      \subsubsection sec5-3-3-3 Section 5.3.3.3: struct rx ackPacket 
03473  * 
03474  * \par
03475  * This is the format for the data portion of an Rx acknowledgement packet,
03476  * used to inform a peer entity performing packet transmissions that a subset
03477  * of its packets has been properly received. 
03478  * \par
03479  * \b fields 
03480  * \li u short bufferSpace - Number of packet buffers available. Specifically,
03481  * the number of packet buffers that the ack packet's sender is willing to
03482  * provide for data on this or subsequent calls. This number does not have to
03483  * fully accurate; it is acceptable for the sender to provide an estimate. 
03484  * \li u short maxSkew - The maximum difference seen between the serial number
03485  * of the packet being acknowledged and highest packet yet received. This is an
03486  * indication of the degree to which packets are arriving out of order at the
03487  * receiver. 
03488  * \li u long firstPacket - The serial number of the first packet in the list
03489  * of acknowledged packets, as represented by the acks field below. 
03490  * \li u long previousPacket - The previous packet serial number received. 
03491  * \li u long serial - The serial number of the packet prompted the
03492  * acknowledgement. 
03493  * \li u char reason - The reason given for the acknowledgement; legal values
03494  * for this field are described in Section 5.2.13. 
03495  * \li u char nAcks - Number of acknowledgements active in the acks array
03496  * immediately following. 
03497  * \li u char acks[RX MAXACKS] - Up to RX MAXACKS packet acknowledgements. The
03498  * legal values for each slot in the acks array are described in Section
03499  * 5.2.14. Basically, these fields indicate either positive or negative
03500  * acknowledgements. 
03501  * 
03502  * \par
03503  * All packets with serial numbers prior to firstPacket are implicitly
03504  * acknowledged by this packet, indicating that they have been fully processed
03505  * by the receiver. Thus, the sender need no longer be concerned about them,
03506  * and may release all of the resources that they occupy. Packets with serial
03507  * numbers firstPacket + nAcks and higher are not acknowledged by this ack
03508  * packet. Packets with serial numbers in the range [firstPacket, firstPacket +
03509  * nAcks) are explicitly acknowledged, yet their sender-side resources must not
03510  * yet be released, as there is yet no guarantee that the receiver will not
03511  * throw them away before they can be processed there. 
03512  * \par
03513  * There are some details of importance to be noted. For one, receiving a
03514  * positive acknowlegement via the acks array does not imply that the
03515  * associated packet is immune from being dropped before it is read and
03516  * processed by the receiving entity. It does, however, imply that the sender
03517  * should stop retransmitting the packet until further notice. Also, arrival of
03518  * an ack packet should prompt the transmitter to immediately retransmit all
03519  * packets it holds that have not been explicitly acknowledged and that were
03520  * last transmitted with a serial number less than the highest serial number
03521  * acknowledged by the acks array. 
03522  * Note: The fields in this structure are always kept in wire format, namely in
03523  * network byte order. 
03524  * 
03525  *      \subsection sec5-3-4 Section 5.3.4: Debugging and Statistics 
03526  * 
03527  * \par
03528  * The following structures are defined in support of the debugging and
03529  * statistics-gathering interfaces provided by Rx. 
03530  * 
03531  *      \subsubsection sec5-3-4-1 Section 5.3.4.1: struct rx stats 
03532  * 
03533  * \par
03534  * This structure maintains Rx statistics, and is gathered by such tools as the
03535  * rxdebug program. It must be possible for all of the fields placed in this
03536  * structure to be successfully converted from their on-wire network byte
03537  * orderings to the host-specific ordering. 
03538  * \par
03539  * \b fields 
03540  * \li int packetRequests - Number of packet allocation requests processed. 
03541  * \li int noPackets[RX N PACKET CLASSES] - Number of failed packet requests,
03542  * organized per allocation class. 
03543  * \li int socketGreedy - Whether the SO GREEDY setting succeeded for the Rx
03544  * socket. 
03545  * \li int bogusPacketOnRead - Number of inappropriately short packets
03546  * received. 
03547  * \li int bogusHost - Contains the host address from the last bogus packet
03548  * received. 
03549  * \li int noPacketOnRead - Number of attempts to read a packet off the wire
03550  * when there was actually no packet there. 
03551  * \li int noPacketBuffersOnRead - Number of dropped data packets due to lack
03552  * of packet buffers. 
03553  * \li int selects - Number of selects waiting for a packet arrival or a
03554  * timeout. 
03555  * \li int sendSelects - Number of selects forced when sending packets. 
03556  * \li int packetsRead[RX N PACKET TYPES] - Total number of packets read,
03557  * classified by type. 
03558  * \li int dataPacketsRead - Number of unique data packets read off the wire. 
03559  * \li int ackPacketsRead - Number of ack packets read. 
03560  * \li int dupPacketsRead - Number of duplicate data packets read. 
03561  * \li int spuriousPacketsRead - Number of inappropriate data packets. 
03562  * \li int packetsSent[RX N PACKET TYPES] - Number of packet transmissions,
03563  * broken down by packet type. 
03564  * \li int ackPacketsSent - Number of ack packets sent. 
03565  * \li int pingPacketsSent - Number of ping packets sent. 
03566  * \li int abortPacketsSent - Number of abort packets sent. 
03567  * \li int busyPacketsSent - Number of busy packets sent. 
03568  * \li int dataPacketsSent - Number of unique data packets sent. 
03569  * \li int dataPacketsReSent - Number of retransmissions. 
03570  * \li int dataPacketsPushed - Number of retransmissions pushed early by a
03571  * negative acknowledgement. 
03572  * \li int ignoreAckedPacket - Number of packets not retransmitted because they
03573  * have already been acked. 
03574  * \li int struct clock totalRtt - Total round trip time measured for packets,
03575  * used to compute average time figure. 
03576  * \li struct clock minRtt - Minimum round trip time measured for packets. 
03577  * struct clock maxRtt - Maximum round trip time measured for packets. 
03578  * \li int nRttSamples - Number of round trip samples. 
03579  * \li int nServerConns - Number of server connections. 
03580  * \li int nClientConns - Number of client connections. 
03581  * \li int nPeerStructs - Number of peer structures. 
03582  * \li int nCallStructs - Number of call structures physically allocated (using
03583  * the internal storage allocator routine). 
03584  * \li int nFreeCallStructs - Number of call structures which were pulled from
03585  * the free queue, thus avoiding a call to the internal storage allocator
03586  * routine. 
03587  * \li int spares[10] - Ten integer spare fields, reserved for future use. 
03588  * 
03589  *      \subsubsection sec5-3-4-2 Section 5.3.4.2: struct rx debugIn 
03590  * 
03591  * \par
03592  * This structure defines the data format for a packet requesting one of the
03593  * statistics collections maintained by Rx. 
03594  * \par
03595  * \b fields 
03596  * \li long type - The specific data collection that the caller desires. Legal
03597  * settings for this field are described in Section 5.2.16.2. 
03598  * \li long index - This field is only used when gathering information on Rx
03599  * connections. Choose the index of the server-side connection record of which
03600  * we are inquiring. This field may be used as an iterator, stepping through
03601  * all the connection records, one per debugging request, until they have all
03602  * been examined. 
03603  * 
03604  *      \subsubsection sec5-3-4-3 Section 5.3.4.3: struct rx debugStats 
03605  * 
03606  * \par
03607  * This structure describes the data format for a reply to an RX DEBUGI
03608  * GETSTATS debugging request packet. These fields are given values indicating
03609  * the current state of the Rx facility. 
03610  * \par
03611  * \b fields 
03612  * \li long nFreePackets - Number of packet buffers currently assigned to the
03613  * free pool. 
03614  * \li long packetReclaims - Currently unused. 
03615  * \li long callsExecuted - Number of calls executed since the Rx facility was
03616  * initialized. 
03617  * \li char waitingForPackets - Is Rx currently blocked waiting for a packet
03618  * buffer to come free? 
03619  * \li char usedFDs - If the Rx facility is executing in the kernel, return the
03620  * number of unix file descriptors in use. This number is not directly related
03621  * to the Rx package, but rather describes the state of the machine on which Rx
03622  * is running. 
03623  * \li char version - Version number of the debugging package. 
03624  * \li char spare1[1] - Byte spare, reserved for future use. 
03625  * \li long spare2[10] - Set of 10 longword spares, reserved for future use. 
03626  * 
03627  *      \subsubsection sec5-3-4-4 Section 5.3.4.4: struct rx debugConn 
03628  * 
03629  * \par
03630  * This structure defines the data format returned when a caller requests
03631  * information concerning an Rx connection. Thus, rx debugConn defines the
03632  * external packaging of interest to external parties. Most of these fields are
03633  * set from the rx connection structure, as defined in Section 5.3.2.2, and
03634  * others are obtained by indirecting through such objects as the connection's
03635  * peer and call structures. 
03636  * \par
03637  * \b fields 
03638  * \li long host - Address of the host identified by the connection's peer
03639  * structure. 
03640  * \li long cid - The connection ID. 
03641  * \li long serial - The serial number of the next outgoing packet associated
03642  * with this connection. 
03643  * \li long callNumber[RX MAXCALLS] - The current call numbers for the
03644  * individual call channels on this connection. 
03645  * \li long error - Records the latest error code for calls occurring on this
03646  * connection. 
03647  * \li short port - UDP port associated with the connection's peer. 
03648  * \li char flags - State of the connection; see Section 5.2.4 for individual
03649  * bit definitions. 
03650  * \li char type - Whether the connection is a server-side or client-side one.
03651  * See Section 5.2.5 for individual bit definitions. 
03652  * \li char securityIndex - Index in the associated server-side service class
03653  * of the security object being used by this call. 
03654  * \li char sparec[3] - Used to force alignment for later fields. 
03655  * \li char callState[RX MAXCALLS] - Current call state on each call channel.
03656  * The associated bit definitions appear in Section 5.2.7. 
03657  * \li char callMode[RX MAXCALLS] - Current mode of all call channels that are
03658  * in RX STATE ACTIVE state. The associated bit definitions appear in Section
03659  * 5.2.8. 
03660  * \li char callFlags[RX MAXCALLS] - Flags pertaining to the state of each of
03661  * the connection's call channels. The associated bit definitions appear in
03662  * Section 5.2.7. 
03663  * \li char callOther[RX MAXCALLS] - Flag field for each call channel, where
03664  * the presence of the RX OTHER IN flag indicates that there are packets
03665  * present on the given call's reception queue, and the RX OTHER OUT flag
03666  * indicates the presence of packets on the transmission queue. 
03667  * \li struct rx securityObjectStats secStats - The contents of the statistics
03668  * related to the security object selected by the securityIndex field, if any. 
03669  * \li long epoch - The connection's client-side incarnation time. 
03670  * \li long sparel[10] - A set of 10 longword fields, reserved for future use. 
03671  * 
03672  *      \subsubsection sec5-3-4-5 Section 5.3.4.5: struct rx debugConn vL 
03673  * 
03674  * \par
03675  * This structure is identical to rx debugConn defined above, except for the
03676  * fact that it is missing the sparec field. This sparec field is used in rx
03677  * debugConn to fix an alignment problem that was discovered in version L of
03678  * the debugging/statistics interface (hence the trailing "tt vL tag in the
03679  * structure name). This alignment problem is fixed in version M, which
03680  * utilizes and exports the rx debugConn structure exclusively. Information
03681  * regarding the range of version-numbering values for the Rx
03682  * debugging/statistics interface may be found in Section 5.2.16.1. 
03683  *      \section sec5-4 Section 5.4: Exported Variables 
03684  * 
03685  * \par
03686  * This section describes the set of variables that the Rx facility exports to
03687  * its applications. Some of these variables have macros defined for the sole
03688  * purpose of providing the caller with a convenient way to manipulate them.
03689  * Note that some of these exported variables are never meant to be altered by
03690  * application code (e.g., rx nPackets). 
03691  * 
03692  *      \subsection sec5-4-1 Section 5.4.1: rx connDeadTime 
03693  * 
03694  * \par
03695  * This integer-valued variable determines the maximum number of seconds that a
03696  * connection may remain completely inactive, without receiving packets of any
03697  * kind, before it is eligible for garbage collection. Its initial value is 12
03698  * seconds. The rx SetRxDeadTime macro sets the value of this variable. 
03699  * 
03700  *      \subsection sec5-4-2 Section 5.4.2: rx idleConnectionTime 
03701  * 
03702  * \par
03703  * This integer-valued variable determines the maximum number of seconds that a
03704  * server connection may "idle" (i.e., not have any active calls and otherwise
03705  * not have sent a packet) before becoming eligible for garbage collection. Its
03706  * initial value is 60 seconds. 
03707  * 
03708  *      \subsection sec5-4-3 Section 5.4.3: rx idlePeerTime 
03709  * 
03710  * \par
03711  * This integer-valued variable determines the maximum number of seconds that
03712  * an Rx peer structure is allowed to exist without any connection structures
03713  * referencing it before becoming eligible for garbage collection. Its initial
03714  * value is 60 seconds. 
03715  * 
03716  *      \subsection sec5-4-4 Section 5.4.4: rx extraQuota 
03717  * 
03718  * \par
03719  * This integer-valued variable is part of the Rx packet quota system (see
03720  * Section 1.2.6), which is used to avoid system deadlock. This ensures that
03721  * each server-side thread has a minimum number of packets at its disposal,
03722  * allowing it to continue making progress on active calls. This particular
03723  * variable records how many extra data packets a user has requested be
03724  * allocated. Its initial value is 0. 
03725  * 
03726  *      \subsection sec5-4-5 Section 5.4.5: rx extraPackets 
03727  * 
03728  * \par
03729  * This integer-valued variable records how many additional packet buffers are
03730  * to be created for each Rx server thread. The caller, upon setting this
03731  * variable, is applying some application-specific knowledge of the level of
03732  * network activity expected. The rx extraPackets variable is used to compute
03733  * the overall number of packet buffers to reserve per server thread, namely rx
03734  * nPackets, described below. The initial value is 32 packets. 
03735  * 
03736  *      \subsection sec5-4-6 Section 5.4.6: rx nPackets 
03737  * 
03738  * \par
03739  * This integer-valued variable records the total number of packet buffers to
03740  * be allocated per Rx server thread. It takes into account the quota packet
03741  * buffers and the extra buffers requested by the caller, if any. 
03742  * \note This variable should never be set directly; the Rx facility itself
03743  * computes its value. Setting it incorrectly may result in the service
03744  * becoming deadlocked due to insufficient resources. Callers wishing to
03745  * allocate more packet buffers to their server threads should indicate that
03746  * desire by setting the rx extraPackets variable described above. 
03747  * 
03748  *      \subsection sec5-4-7 Section 5.4.7: rx nFreePackets 
03749  * 
03750  * \par
03751  * This integer-valued variable records the number of Rx packet buffers not
03752  * currently used by any call. These unused buffers are collected into a free
03753  * pool. 
03754  * 
03755  *      \subsection sec5-4-8 Section 5.4.8: rx stackSize 
03756  * 
03757  * \par
03758  * This integer-valued variable records the size in bytes for the lightweight
03759  * process stack. The variable is initially set to RX DEFAULT STACK SIZE, and
03760  * is typically manipulated via the rx SetStackSize() macro. 
03761  * 
03762  *      \subsection sec5-4-9 Section 5.4.9: rx packetTypes 
03763  * 
03764  * \par
03765  * This variable holds an array of string names used to describe the different
03766  * roles for Rx packets. Its value is derived from the RX PACKET TYPES
03767  * definition found in Section 5.2.11. 
03768  * 
03769  *      \subsection sec5-4-10 Section 5.4.10: rx stats 
03770  * 
03771  * \par
03772  * This variable contains the statistics structure that keeps track of Rx
03773  * statistics. The struct rx stats structure it provides is defined in Section
03774  * 5.3.4.1. 
03775  * 
03776  *      \section sec5-5 Section 5.5: Macros 
03777  * 
03778  * \par
03779  * Rx uses many macro definitions in preference to calling C functions
03780  * directly. There are two main reasons for doing this: 
03781  * \li field selection: Many Rx operations are easily realized by returning the
03782  * value of a particular structure's field. It is wasteful to invoke a C
03783  * routine to simply fetch a structure's field, incurring unnecessary function
03784  * call overhead. Yet, a convenient, procedure-oriented operation is still
03785  * provided to Rx clients for such operations by the use of macros. For
03786  * example, the rx ConnectionOf() macro, described in Section 5.5.1.1, simply
03787  * indirects through the Rx call structure pointer parameter to deliver the
03788  * conn field. 
03789  * \li Performance optimization: In some cases, a simple test or operation can
03790  * be performed to accomplish a particular task. When this simple,
03791  * straightforward operation fails, then a true C routine may be called to
03792  * handle to more complex (and rarer) situation. The Rx macro rx Write(),
03793  * described in Section 5.5.6.2, is a perfect example of this type of
03794  * optimization. Invoking rx Write() first checks to determine whether or not
03795  * the outgoing call's internal buffer has enough room to accept the specified
03796  * data bytes. If so, it copies them into the call's buffer, updating counts
03797  * and pointers as appropriate. Otherwise, rx Write() calls the rx WriteProc()
03798  * to do the work, which in this more complicated case involves packet
03799  * manipulations, dispatches, and allocations. The result is that the common,
03800  * simple cases are often handled in-line, with more complex (and rarer) cases
03801  * handled through true function invocations. 
03802  * \par
03803  * The set of Rx macros is described according to the following categories. 
03804  * \li field selections/assignments 
03805  * \li Boolean operations 
03806  * \li Service attributes 
03807  * \li Security-related operations 
03808  * \li Sizing operations 
03809  * \li Complex operation 
03810  * \li Security operation invocations 
03811  * 
03812  *      \subsection sec5-5-1 Section 5.5.1: field Selections/Assignments 
03813  * 
03814  * \par
03815  * These macros facilitate the fetching and setting of fields from the
03816  * structures described Chapter 5.3. 
03817  * 
03818  *      \subsubsection sec5-5-1-1 Section 5.5.1.1: rx ConnectionOf() 
03819  * 
03820  * \par
03821  * \#define rx_ConnectionOf(call) ((call)->conn) 
03822  * \par
03823  * Generate a reference to the connection field within the given Rx call
03824  * structure. The value supplied as the call argument must resolve into an
03825  * object of type (struct rx call *). An application of the rx ConnectionOf()
03826  * macro itself yields an object of type rx peer. 
03827  * 
03828  *      \subsubsection sec5-5-1-2 Section 5.5.1.2: rx PeerOf() 
03829  * 
03830  * \par
03831  * \#define rx_PeerOf(conn) ((conn)->peer) 
03832  * \par
03833  * Generate a reference to the peer field within the given Rx call structure.
03834  * The value supplied as the conn argument must resolve into an object of type
03835  * (struct rx connection *). An instance of the rx PeerOf() macro itself
03836  * resolves into an object of type rx peer. 
03837  * 
03838  *      \subsubsection sec5-5-1-3 Section 5.5.1.3: rx HostOf() 
03839  * 
03840  * \par
03841  * \#define rx_HostOf(peer) ((peer)->host) 
03842  * \par
03843  * Generate a reference to the host field within the given Rx peer structure.
03844  * The value supplied as the peer argument must resolve into an object of type
03845  * (struct rx peer *). An instance of the rx HostOf() macro itself resolves
03846  * into an object of type u long. 
03847  * 
03848  *      \subsubsection sec5-5-1-4 Section 5.5.1.4: rx PortOf() 
03849  * 
03850  * \par
03851  * \#define rx_PortOf(peer) ((peer)->port) 
03852  * \par
03853  * Generate a reference to the port field within the given Rx peer structure.
03854  * The value supplied as the peer argument must resolve into an object of type
03855  * (struct rx peer *). An instance of the rx PortOf() macro itself resolves
03856  * into an object of type u short. 
03857  * 
03858  *      \subsubsection sec5-5-1-5 Section 5.5.1.5: rx GetLocalStatus() 
03859  * 
03860  * \par
03861  * \#define rx_GetLocalStatus(call, status) ((call)->localStatus) 
03862  * \par
03863  * Generate a reference to the localStatus field, which specifies the local
03864  * user status sent out of band, within the given Rx call structure. The value
03865  * supplied as the call argument must resolve into an object of type (struct rx
03866  * call *). The second argument, status, is not used. An instance of the rx
03867  * GetLocalStatus() macro itself resolves into an object of type u char. 
03868  * 
03869  *      \subsubsection sec5-5-1-6 Section 5.5.1.6: rx SetLocalStatus() 
03870  * 
03871  * \par
03872  * \#define rx_SetLocalStatus(call, status) ((call)->localStatus = (status)) 
03873  * \par
03874  * Assign the contents of the localStatus field, which specifies the local user
03875  * status sent out of band, within the given Rx call structure. The value
03876  * supplied as the call argument must resolve into an object of type (struct rx
03877  * call *). The second argument, status, provides the new value of the
03878  * localStatus field, and must resolve into an object of type u char. An
03879  * instance of the rx GetLocalStatus() macro itself resolves into an object
03880  * resulting from the assignment, namely the u char status parameter. 
03881  * 
03882  *      \subsubsection sec5-5-1-7 Section 5.5.1.7: rx GetRemoteStatus() 
03883  * 
03884  * \par
03885  * \#define rx_GetRemoteStatus(call) ((call)->remoteStatus) 
03886  * \par
03887  * Generate a reference to the remoteStatus field, which specifies the remote
03888  * user status received out of band, within the given Rx call structure. The
03889  * value supplied as the call argument must resolve into an object of type
03890  * (struct rx call *). An instance of the rx GetRemoteStatus() macro itself
03891  * resolves into an object of type u char. 
03892  * 
03893  *      \subsubsection sec5-5-1-8 Section 5.5.1.8: rx Error() 
03894  * 
03895  * \par
03896  * \#define rx_Error(call) ((call)->error) 
03897  * \par
03898  * Generate a reference to the error field, which specifies the current error
03899  * condition, within the given Rx call structure. The value supplied as the
03900  * call argument must resolve into an object of type (struct rx call *). An
03901  * instance of the rx Error() macro itself resolves into an object of type
03902  * long. 
03903  * 
03904  *      \subsubsection sec5-5-1-9 Section 5.5.1.9: rx DataOf() 
03905  * 
03906  * \par
03907  * \#define rx_DataOf(packet) ((char *) (packet)->wire.data) 
03908  * \par
03909  * Generate a reference to the beginning of the data portion within the given
03910  * Rx packet as it appears on the wire. Any encryption headers will be resident
03911  * at this address. For Rx packets of type RX PACKET TYPE DATA, the actual user
03912  * data will appear at the address returned by the rx DataOf macro plus the
03913  * connection's security header size. The value supplied as the packet argument
03914  * must resolve into an object of type (struct rx packet *). An instance of the
03915  * rx DataOf() macro itself resolves into an object of type (u long *). 
03916  * 
03917  *      \subsubsection sec5-5-1-10 Section 5.5.1.10: rx GetDataSize() 
03918  * 
03919  * \par
03920  * \#define rx_GetDataSize(packet) ((packet)->length) 
03921  * \par
03922  * Generate a reference to the length field, which specifies the number of
03923  * bytes of user data contained within the wire form of the packet, within the
03924  * given Rx packet description structure. The value supplied as the packet
03925  * argument must resolve into an object of type (struct rx packet *). An
03926  * instance of the rx GetDataSize() macro itself resolves into an object of
03927  * type short. 
03928  * 
03929  *      \subsubsection sec5-5-1-11 Section 5.5.1.11: rx SetDataSize() 
03930  * 
03931  * \par
03932  * \#define rx_SetDataSize(packet, size) ((packet)->length = (size)) 
03933  * \par
03934  * Assign the contents of the length field, which specifies the number of bytes
03935  * of user data contained within the wire form of the packet, within the given
03936  * Rx packet description structure. The value supplied as the packet argument
03937  * must resolve into an object of type (struct rx packet *). The second
03938  * argument, size, provides the new value of the length field, and must resolve
03939  * into an object of type short. An instance of the rx SetDataSize() macro
03940  * itself resolves into an object resulting from the assignment, namely the
03941  * short length parameter. 
03942  * 
03943  *      \subsubsection sec5-5-1-12 Section 5.5.1.12: rx GetPacketCksum() 
03944  * 
03945  * \par
03946  * \#define rx_GetPacketCksum(packet) ((packet)->header.spare) 
03947  * \par
03948  * Generate a reference to the header checksum field, as used by the built-in
03949  * rxkad security module (See Chapter 3), within the given Rx packet
03950  * description structure. The value supplied as the packet argument must
03951  * resolve into an object of type (struct rx packet *). An instance of the rx
03952  * GetPacketCksum() macro itself resolves into an object of type u short. 
03953  * 
03954  *      \subsubsection sec5-5-1-13 Section 5.5.1.13: rx SetPacketCksum() 
03955  * 
03956  * \par
03957  * \#define rx_SetPacketCksum(packet, cksum) ((packet)->header.spare = (cksum)) 
03958  * \par
03959  * Assign the contents of the header checksum field, as used by the built-in
03960  * rxkad security module (See Chapter 3), within the given Rx packet
03961  * description structure. The value supplied as the packet argument must
03962  * resolve into an object of type (struct rx packet *). The second argument,
03963  * cksum, provides the new value of the checksum, and must resolve into an
03964  * object of type u short. An instance of the rx SetPacketCksum() macro itself
03965  * resolves into an object resulting from the assignment, namely the u short
03966  * checksum parameter. 
03967  * 
03968  *      \subsubsection sec5-5-1-14 Section 5.5.1.14: rx GetRock() 
03969  * 
03970  * \par
03971  * \#define rx_GetRock(obj, type) ((type)(obj)->rock) 
03972  * \par
03973  * Generate a reference to the field named rock within the object identified by
03974  * the obj pointer. One common Rx structure to which this macro may be applied
03975  * is struct rx connection. The specified rock field is casted to the value of
03976  * the type parameter, which is the overall value of the rx GetRock() macro. 
03977  * 
03978  *      \subsubsection sec5-5-1-15 Section 5.5.1.15: rx SetRock() 
03979  * 
03980  * \par
03981  * \#define rx_SetRock(obj, newrock) ((obj)->rock = (VOID *)(newrock)) 
03982  * \par
03983  * Assign the contents of the newrock parameter into the rock field of the
03984  * object pointed to by obj. The given object's rock field must be of type
03985  * (VOID *). An instance of the rx SetRock() macro itself resolves into an
03986  * object resulting from the assignment and is of type (VOID *). 
03987  * 
03988  *      \subsubsection sec5-5-1-16 Section 5.5.1.16: rx SecurityClassOf() 
03989  * 
03990  * \par
03991  * \#define rx_SecurityClassOf(conn) ((conn)->securityIndex) 
03992  * \par
03993  * Generate a reference to the security index field of the given Rx connection
03994  * description structure. This identifies the security class used by the
03995  * connection. The value supplied as the conn argument must resolve into an
03996  * object of type (struct rx connection *). An instance of the rx
03997  * SecurityClassOf() macro itself resolves into an object of type u char. 
03998  * 
03999  *      \subsubsection sec5-5-1-17 Section 5.5.1.17: rx SecurityObjectOf() 
04000  * 
04001  * \par
04002  * \#define rx_SecurityObjectOf(conn) ((conn)->securityObject) 
04003  * \par
04004  * Generate a reference to the security object in use by the given Rx
04005  * connection description structure. The choice of security object determines
04006  * the authentication protocol enforced by the connection. The value supplied
04007  * as the conn argument must resolve into an object of type (struct rx
04008  * connection *). An instance of the rx SecurityObjectOf() macro itself
04009  * resolves into an object of type (struct rx securityClass *). 
04010  * 
04011  *      \subsection sec5-5-2 Section 5.5.2: Boolean Operations 
04012  * 
04013  * \par
04014  * The macros described in this section all return Boolean values. They are
04015  * used to query such things as the whether a connection is a server-side or
04016  * client-side one and if extra levels of checksumming are being used in Rx
04017  * packet headers. 
04018  * 
04019  *      \subsubsection sec5-5-2-1 Section 5.5.2.1: rx IsServerConn() 
04020  * 
04021  * \par
04022  * \#define rx_IsServerConn(conn) ((conn)->type == RX_SERVER_CONNECTION) 
04023  * \par
04024  * Determine whether or not the Rx connection specified by the conn argument is
04025  * a server-side connection. The value supplied for conn must resolve to an
04026  * object of type struct rx connection. The result is determined by testing
04027  * whether or not the connection's type field is set to RX SERVER CONNECTION. 
04028  * \note Another macro, rx ServerConn(), performs the identical operation. 
04029  * 
04030  *      \subsubsection sec5-5-2-2 Section 5.5.2.2: rx IsClientConn() 
04031  * 
04032  * \par
04033  * \#define rx_IsClientConn(conn) ((conn)->type == RX_CLIENT_CONNECTION) 
04034  * \par
04035  * Determine whether or not the Rx connection specified by the conn argument is
04036  * a client-side connection. The value supplied for conn must resolve to an
04037  * object of type struct rx connection. The result is determined by testing
04038  * whether or not the connection's type field is set to RX CLIENT CONNECTION. 
04039  * \note Another macro, rx ClientConn(), performs the identical operation. 
04040  * 
04041  *      \subsubsection sec5-5-2-3 Section 5.5.2.2: rx IsUsingPktCksum() 
04042  * 
04043  * \par
04044  * \#define rx_IsUsingPktCksum(conn) ((conn)->flags &
04045  * RX_CONN_USING_PACKET_CKSUM) 
04046  * \par
04047  * Determine whether or not the Rx connection specified by the conn argument is
04048  * checksum-ming the headers of all packets on its calls. The value supplied
04049  * for conn must resolve to an object of type struct rx connection. The result
04050  * is determined by testing whether or not the connection's flags field has the
04051  * RX CONN USING PACKET CKSUM bit enabled. 
04052  * 
04053  *      \subsection sec5-5-3 Section 5.5.3: Service Attributes 
04054  * 
04055  * \par
04056  * This section describes user-callable macros that manipulate the attributes
04057  * of an Rx service. Note that these macros must be called (and hence their
04058  * operations performed) before the given service is installed via the
04059  * appropriate invocation of the associated rx StartServer() function.
04060  * 
04061  *      \subsubsection sec5-5-3-1 Section 5.5.3.1: rx SetStackSize()
04062  * 
04063  * \par
04064  * rx_stackSize = (((stackSize) stackSize) > rx_stackSize) ? stackSize :
04065  * rx_stackSize) 
04066  * \par
04067  * Inform the Rx facility of the stack size in bytes for a class of threads to
04068  * be created in support of Rx services. The exported rx stackSize variable
04069  * tracks the high-water mark for all stack size requests before the call to rx
04070  * StartServer(). If no calls to rx SetStackSize() are made, then rx stackSize
04071  * will retain its default setting of RX DEFAULT STACK SIZE. 
04072  * \par
04073  * In this macro, the first argument is not used. It was originally intended
04074  * that thread stack sizes would be settable on a per-service basis. However,
04075  * calls to rx SetStackSize() will ignore the service parameter and set the
04076  * high-water mark for all Rx threads created after the use of rx
04077  * SetStackSize(). The second argument, stackSize, specifies determines the new
04078  * stack size, and should resolve to an object of type int. The value placed in
04079  * the stackSize parameter will not be recorded in the global rx stackSize
04080  * variable unless it is greater than the variable's current setting. 
04081  * \par
04082  * An instance of the rx SetStackSize() macro itself resolves into the result
04083  * of the assignment, which is an object of type int. 
04084  * 
04085  *      \subsubsection sec5-5-3-2 Section 5.5.3.2: rx SetMinProcs() 
04086  * 
04087  * \par
04088  * \#define rx_SetMinProcs(service, min) ((service)->minProcs = (min)) 
04089  * \par
04090  * Choose min as the minimum number of threads guaranteed to be available for
04091  * parallel execution of the given Rx service. The service parameter should
04092  * resolve to an object of type struct rx service. The min parameter should
04093  * resolve to an object of type short. An instance of the rx SetMinProcs()
04094  * macro itself resolves into the result of the assignment, which is an object
04095  * of type short. 
04096  * 
04097  *      \subsubsection sec5-5-3-3 Section 5.5.3.3: rx SetMaxProcs() 
04098  * 
04099  * \par
04100  * \#define rx_SetMaxProcs(service, max) ((service)->maxProcs = (max)) 
04101  * \par
04102  * Limit the maximum number of threads that may be made available to the given
04103  * Rx service for parallel execution to be max. The service parameter should
04104  * resolve to an object of type struct rx service. The max parameter should
04105  * resolve to an object of type short. An instance of the rx SetMaxProcs()
04106  * macro itself resolves into the result of the assignment, which is an object
04107  * of type short. 
04108  * 
04109  *      \subsubsection sec5-5-3-4 Section 5.5.3.4: rx SetIdleDeadTime() 
04110  * 
04111  * \par
04112  * \#define rx_SetIdleDeadTime(service, time) ((service)->idleDeadTime =
04113  * (time)) 
04114  * \par
04115  * Every Rx service has a maximum amount of time it is willing to have its
04116  * active calls sit idle (i.e., no new data is read or written for a call
04117  * marked as RX STATE ACTIVE) before unilaterally shutting down the call. The
04118  * expired call will have its error field set to RX CALL TIMEOUT. The operative
04119  * assumption in this situation is that the client code is exhibiting a
04120  * protocol error that prevents progress from being made on this call, and thus
04121  * the call's resources on the server side should be freed. The default value,
04122  * as recorded in the service's idleDeadTime field, is set at service creation
04123  * time to be 60 seconds. The rx SetIdleTime() macro allows a caller to
04124  * dynamically set this idle call timeout value. 
04125  * \par
04126  * The service parameter should resolve to an object of type struct rx service.
04127  * Also, the time parameter should resolve to an object of type short. finally,
04128  * an instance of the rx SetIdleDeadTime() macro itself resolves into the
04129  * result of the assignment, which is an object of type short. 
04130  * 
04131  *      \subsubsection sec5-5-3-5 Section 5.5.3.5: rx SetServiceDeadTime() 
04132  * 
04133  * \par
04134  * \#define rx_SetServiceDeadTime(service, seconds)
04135  * ((service)->secondsUntilDead = (seconds)) 
04136  * \note This macro definition is obsolete and should NOT be used. Including it
04137  * in application code will generate a compile-time error, since the service
04138  * structure no longer has such a field defined. 
04139  * \par
04140  * See the description of the rx SetConnDeadTime() macro below to see how hard
04141  * timeouts may be set for situations of complete call inactivity. 
04142  * 
04143  *      \subsubsection sec5-5-3-6 Section 5.5.3.6: rx SetRxDeadTime() 
04144  * 
04145  * \par
04146  * \#define rx_SetRxDeadTime(seconds) (rx_connDeadTime = (seconds)) 
04147  * \par
04148  * Inform the Rx facility of the maximum number of seconds of complete
04149  * inactivity that will be tolerated on an active call. The exported rx
04150  * connDeadTime variable tracks this value, and is initialized to a value of 12
04151  * seconds. The current value of rx connDeadTime will be copied into new Rx
04152  * service and connection records upon their creation. 
04153  * \par
04154  * The seconds argument determines the value of rx connDeadTime, and should
04155  * resolve to an object of type int. An instance of the rx SetRxDeadTime()
04156  * macro itself resolves into the result of the assignment, which is an object
04157  * of type int. 
04158  * 
04159  *      \subsubsection sec5-5-3-7 Section 5.5.3.7: rx SetConnDeadTime() 
04160  * 
04161  * \par
04162  * \#define rx_SetConnDeadTime(conn, seconds) (rxi_SetConnDeadTime(conn,
04163  * seconds)) 
04164  * \par
04165  * Every Rx connection has a maximum amount of time it is willing to have its
04166  * active calls on a server connection sit without receiving packets of any
04167  * kind from its peer. After such a quiescent time, during which neither data
04168  * packets (regardless of whether they are properly sequenced or duplicates)
04169  * nor keep-alive packets are received, the call's error field is set to RX
04170  * CALL DEAD and the call is terminated. The operative assumption in this
04171  * situation is that the client making the call has perished, and thus the
04172  * call's resources on the server side should be freed. The default value, as
04173  * recorded in the connection's secondsUntilDead field, is set at connection
04174  * creation time to be the same as its parent service. The rx SetConnDeadTime()
04175  * macro allows a caller to dynamically set this timeout value. 
04176  * \par
04177  * The conn parameter should resolve to an object of type struct rx connection.
04178  * Also, the seconds parameter should resolve to an object of type int.
04179  * finally, an instance of the rx SetConnDeadTime() macro itself resolves into
04180  * the a call to rxi SetConnDeadTime(), whose return value is void. 
04181  * 
04182  *      \subsubsection sec5-5-3-8 Section 5.5.3.8: rx SetConnHardDeadTime() 
04183  * 
04184  * \par
04185  * \#define rx_SetConnHardDeadTime(conn, seconds) ((conn)->hardDeadTime =
04186  * (seconds)) 
04187  * \par
04188  * It is convenient to be able to specify that calls on certain Rx connections
04189  * have a hard absolute timeout. This guards against protocol errors not caught
04190  * by other checks in which one or both of the client and server are looping.
04191  * The rx SetConnHardDeadTime() macro is available for this purpose. It will
04192  * limit calls on the connection identified by the conn parameter to execution
04193  * times of no more than the given number of seconds. By default, active calls
04194  * on an Rx connection may proceed for an unbounded time, as long as they are
04195  * not totally quiescent (see Section 5.5.3.7 for a description of the rx
04196  * SetConnDeadTime()) or idle (see Section 5.5.3.4 for a description of the rx
04197  * SetIdleDeadTime()). 
04198  * \par
04199  * The conn parameter should resolve to an object of type (struct rx connection
04200  * *). The seconds parameter should resolve to an object of type u short. An
04201  * instance of the rx SetConnHardDeadTime() macro itself resolves into the
04202  * result of the assignment, which is an object of type u short. 
04203  * 
04204  *      \subsubsection sec5-5-3-9 Section 5.5.3.9: rx GetBeforeProc() 
04205  * 
04206  * \par
04207  * \#define rx_GetBeforeProc(service) ((service)->beforeProc) 
04208  * \par
04209  * Return a pointer of type (VOID *)() to the procedure associated with the
04210  * given Rx service that will be called immediately upon activation of a server
04211  * thread to handle an incoming call. The service parameter should resolve to
04212  * an object of type struct rx service. 
04213  * \par
04214  * When an Rx service is first created (via a call to the rx NewService()
04215  * function), its beforeProc field is set to a null pointer. See the
04216  * description of the rx SetBeforeProc() below. 
04217  * 
04218  *      \subsubsection sec5-5-3-10 Section 5.5.3.10: rx SetBeforeProc() 
04219  * 
04220  * \par
04221  * \#define rx_SetBeforeProc(service, proc) ((service)->beforeProc = (proc)) 
04222  * \par
04223  * Instruct the Rx facility to call the procedure identified by the proc
04224  * parameter immediately upon activation of a server thread to handle an
04225  * incoming call. The specified procedure will be called with a single
04226  * parameter, a pointer of type struct rx call, identifying the call this
04227  * thread will now be responsible for handling. The value returned by the
04228  * procedure, if any, is discarded. 
04229  * \par
04230  * The service parameter should resolve to an object of type struct rx service.
04231  * The proc parameter should resolve to an object of type (VOID *)(). An
04232  * instance of the rx SetBeforeProc() macro itself resolves into the result of
04233  * the assignment, which is an object of type (VOID *)(). 
04234  * 
04235  *      \subsubsection sec5-5-3-11 Section 5.5.3.11: rx GetAfterProc() 
04236  * 
04237  * \par
04238  * \#define rx_GetAfterProc(service) ((service)->afterProc) 
04239  * \par
04240  * Return a pointer of type (VOID *)() to the procedure associated with the
04241  * given Rx service that will be called immediately upon completion of the
04242  * particular Rx call for which a server thread was activated. The service
04243  * parameter should resolve to an object of type struct rx service. 
04244  * \par
04245  * When an Rx service is first created (via a call to the rx NewService()
04246  * function), its afterProc field is set to a null pointer. See the description
04247  * of the rx SetAfterProc() below. 
04248  * 
04249  *      \subsubsection sec5-5-3-12 Section 5.5.3.12: rx SetAfterProc() 
04250  * 
04251  * \par
04252  * \#define rx_SetAfterProc(service, proc) ((service)->afterProc = (proc)) 
04253  * \par
04254  * Instruct the Rx facility to call the procedure identified by the proc
04255  * parameter immediately upon completion of the particular Rx call for which a
04256  * server thread was activated. The specified procedure will be called with a
04257  * single parameter, a pointer of type struct rx call, identifying the call
04258  * this thread just handled. The value returned by the procedure, if any, is
04259  * discarded. 
04260  * \par
04261  * The service parameter should resolve to an object of type struct rx service.
04262  * The proc parameter should resolve to an object of type (VOID *)(). An
04263  * instance of the rx SetAfterProc() macro itself resolves into the result of
04264  * the assignment, which is an object of type (VOID *)(). 
04265  * 
04266  *      \subsubsection sec5-5-3-13 Section 5.5.3.13: rx SetNewConnProc() 
04267  * 
04268  * \par
04269  * \#define rx_SetNewConnProc(service, proc) ((service)->newConnProc = (proc)) 
04270  * \par
04271  * Instruct the Rx facility to call the procedure identified by the proc
04272  * parameter as the last step in the creation of a new Rx server-side
04273  * connection for the given service. The specified procedure will be called
04274  * with a single parameter, a pointer of type (struct rx connection *),
04275  * identifying the connection structure that was just built. The value returned
04276  * by the procedure, if any, is discarded. 
04277  * \par
04278  * The service parameter should resolve to an object of type struct rx service.
04279  * The proc parameter should resolve to an object of type (VOID *)(). An
04280  * instance of the rx SetNewConnProc() macro itself resolves into the result of
04281  * the assignment, which is an object of type (VOID *)(). 
04282  * \note There is no access counterpart defined for this macro, namely one that
04283  * returns the current setting of a service's newConnProc. 
04284  * 
04285  *      \subsubsection sec5-5-3-14 Section 5.5.3.14: rx SetDestroyConnProc() 
04286  * 
04287  * \par
04288  * \#define rx_SetDestroyConnProc(service, proc) ((service)->destroyConnProc =
04289  * (proc)) 
04290  * \par
04291  * Instruct the Rx facility to call the procedure identified by the proc
04292  * parameter just before a server connection associated with the given Rx
04293  * service is destroyed. The specified procedure will be called with a single
04294  * parameter, a pointer of type (struct rx connection *), identifying the
04295  * connection about to be destroyed. The value returned by the procedure, if
04296  * any, is discarded. 
04297  * \par
04298  * The service parameter should resolve to an object of type struct rx service.
04299  * The proc parameter should resolve to an object of type (VOID *)(). An
04300  * instance of the rx SetDestroyConnProc() macro itself resolves into the
04301  * result of the assignment, which is an object of type (VOID *)(). 
04302  * \note There is no access counterpart defined for this macro, namely one that
04303  * returns the current setting of a service's destroyConnProc. 
04304  * 
04305  *      \subsection sec5-5-4 Section 5.5.4: Security-Related Operations 
04306  * 
04307  * \par
04308  * The following macros are callable by Rx security modules, and assist in
04309  * getting and setting header and trailer lengths, setting actual packet size,
04310  * and finding the beginning of the security header (or data). 
04311  * 
04312  *      \subsubsection sec5-5-4-1 Section 5.5.4.1: rx GetSecurityHeaderSize() 
04313  * 
04314  * \par
04315  * \#define rx_GetSecurityHeaderSize(conn) ((conn)->securityHeaderSize) 
04316  * \par
04317  * Generate a reference to the field in an Rx connection structure that records
04318  * the length in bytes of the associated security module's packet header data. 
04319  * \par
04320  * The conn parameter should resolve to an object of type struct rx connection.
04321  * An instance of the rx GetSecurityHeaderSize() macro itself resolves into an
04322  * object of type u short. 
04323  * 
04324  *      \subsubsection sec5-5-4-2 Section 5.5.4.2: rx SetSecurityHeaderSize() 
04325  * 
04326  * \par
04327  * \#define rx_SetSecurityHeaderSize(conn, length) ((conn)->securityHeaderSize
04328  * = (length)) 
04329  * \par
04330  * Set the field in a connection structure that records the length in bytes of
04331  * the associated security module's packet header data. 
04332  * \par
04333  * The conn parameter should resolve to an object of type struct rx connection.
04334  * The length parameter should resolve to an object of type u short. An
04335  * instance of the rx SetSecurityHeaderSize() macro itself resolves into the
04336  * result of the assignment, which is an object of type u short. 
04337  * 
04338  *      \subsubsection sec5-5-4-3 Section 5.5.4.3: rx
04339  *      GetSecurityMaxTrailerSize() 
04340  * 
04341  * \par
04342  * \#define rx_GetSecurityMaxTrailerSize(conn) ((conn)->securityMaxTrailerSize) 
04343  * \par
04344  * Generate a reference to the field in an Rx connection structure that records
04345  * the maximum length in bytes of the associated security module's packet
04346  * trailer data. 
04347  * \par
04348  * The conn parameter should resolve to an object of type struct rx connection.
04349  * An instance of the rx GetSecurityMaxTrailerSize() macro itself resolves into
04350  * an object of type u short. 
04351  * 
04352  *      \subsubsection sec5-5-4-4 Section 5.5.4.4: rx
04353  *      SetSecurityMaxTrailerSize() 
04354  * 
04355  * \par
04356  * \#define rx_SetSecurityMaxTrailerSize(conn, length)
04357  * ((conn)->securityMaxTrailerSize = (length)) 
04358  * \par
04359  * Set the field in a connection structure that records the maximum length in
04360  * bytes of the associated security module's packet trailer data. 
04361  * \par
04362  * The conn parameter should resolve to an object of type struct rx connection.
04363  * The length parameter should resolve to an object of type u short. An
04364  * instance of the rx SetSecurityHeaderSize() macro itself resolves into the
04365  * result of the assignment, which is an object of type u short. 
04366  * 
04367  *      \subsection sec5-5-5 Section 5.5.5: Sizing Operations 
04368  * 
04369  * \par
04370  * The macros described in this section assist the application programmer in
04371  * determining the sizes of the various Rx packet regions, as well as their
04372  * placement within a packet buffer. 
04373  * 
04374  *      \subsubsection sec5-5-5-1 Section 5.5.5.1: rx UserDataOf() 
04375  * 
04376  * \par
04377  * \#define rx_UserDataOf(conn, packet) (((char *) (packet)->wire.data) +
04378  * (conn)->securityHeaderSize) 
04379  * \par
04380  * Generate a pointer to the beginning of the actual user data in the given Rx
04381  * packet, that is associated with the connection described by the conn
04382  * pointer. User data appears immediately after the packet's security header
04383  * region, whose length is determined by the security module used by the
04384  * connection. The conn parameter should resolve to an object of type struct rx
04385  * connection. The packet parameter should resolve to an object of type struct
04386  * rx packet. An instance of the rx UserDataOf() macro itself resolves into an
04387  * object of type (char *). 
04388  * 
04389  *      \subsubsection sec5-5-5-2 Section 5.5.5.2: rx MaxUserDataSize() 
04390  * 
04391  * \par
04392  * \#define rx_MaxUserDataSize(conn) 
04393  * \n ((conn)->peer->packetSize 
04394  * \n -RX_HEADER_SIZE 
04395  * \n -(conn)->securityHeaderSize 
04396  * \n -(conn)->securityMaxTrailerSize) 
04397  * \par
04398  * Return the maximum number of user data bytes that may be carried by a packet
04399  * on the Rx connection described by the conn pointer. The overall packet size
04400  * is reduced by the IP, UDP, and Rx headers, as well as the header and trailer
04401  * areas required by the connection's security module. 
04402  * \par
04403  * The conn parameter should resolve to an object of type struct rx connection.
04404  * An instance of the rx MaxUserDataSize() macro itself resolves into the an
04405  * object of type (u short). 
04406  * 
04407  *      \subsection sec5-5-6 Section 5.5.6: Complex Operations 
04408  * 
04409  * \par
04410  * Two Rx macros are designed to handle potentially complex operations, namely
04411  * reading data from an active incoming call and writing data to an active
04412  * outgoing call. Each call structure has an internal buffer that is used to
04413  * collect and cache data traveling through the call. This buffer is used in
04414  * conjunction with reading or writing to the actual Rx packets traveling on
04415  * the wire in support of the call. The rx Read() and rx Write() macros allow
04416  * their caller to simply manipulate the internal data buffer associated with
04417  * the Rx call structures whenever possible, thus avoiding the overhead
04418  * associated with a function call. When buffers are either filled or drained
04419  * (depending on the direction of the data flow), these macros will then call
04420  * functions to handle the more complex cases of generating or receiving
04421  * packets in support of the operation. 
04422  * 
04423  *      \subsubsection sec5-5-6-1 Section 5.5.6.1: rx Read() 
04424  * 
04425  * \par
04426  * \#define rx_Read(call, buf, nbytes) 
04427  * \n ((call)->nLeft > (nbytes) ? 
04428  * \n bcopy((call)->bufPtr, (buf), (nbytes)), 
04429  * \n (call)->nLeft -= (nbytes), (call)->bufPtr += (nbytes), (nbytes) 
04430  * \n : rx_ReadProc((call), (buf), (nbytes))) 
04431  * \par
04432  * Read nbytes of data from the given Rx call into the buffer to which buf
04433  * points. If the call's internal buffer has at least nbytes bytes already
04434  * filled, then this is done in-line with a copy and some pointer and counter
04435  * updates within the call structure. If the call's internal buffer doesn't
04436  * have enough data to satisfy the request, then the rx ReadProc() function
04437  * will handle this more complex situation. 
04438  * \par
04439  * In either case, the rx Read() macro returns the number of bytes actually
04440  * read from the call, resolving to an object of type int. If rx Read() returns
04441  * fewer than nbytes bytes, the call status should be checked via the rx
04442  * Error() macro. 
04443  * 
04444  *      \subsubsection sec5-5-6-2 Section 5.5.6.2: rx Write() 
04445  * 
04446  * \par
04447  * \#define rx_Write(call, buf, nbytes) 
04448  * \n ((call)->nFree > (nbytes) ? 
04449  * \n bcopy((buf), (call)->bufPtr, (nbytes)), 
04450  * \n (call)->nFree -= (nbytes), 
04451  * \n (call)->bufPtr += (nbytes), (nbytes) 
04452  * \n : rx_WriteProc((call), (buf), (nbytes))) 
04453  * \par
04454  * Write nbytes of data from the buffer pointed to by buf into the given Rx
04455  * call. If the call's internal buffer has at least nbytes bytes free, then
04456  * this is done in-line with a copy and some pointer and counter updates within
04457  * the call structure. If the call's internal buffer doesn't have room, then
04458  * the rx WriteProc() function will handle this more complex situation. 
04459  * \par
04460  * In either case, the rx Write() macro returns the number of bytes actually
04461  * written to the call, resolving to an object of type int. If zero is
04462  * returned, the call status should be checked via the rx Error() macro. 
04463  * 
04464  *      \subsection sec5-5-7 Section 5.5.7: Security Operation Invocations 
04465  * 
04466  * \par
04467  * Every Rx security module is required to implement an identically-named set
04468  * of operations, through which the security mechanism it defines is invoked.
04469  * This characteristic interface is reminiscent of the vnode interface defined
04470  * and popularized for file systems by Sun Microsystems [4]. The structure
04471  * defining this function array is described in Section 5.3.1.1. 
04472  * \par
04473  * These security operations are part of the struct rx securityClass, which
04474  * keeps not only the ops array itself but also any private data they require
04475  * and a reference count. Every Rx service contains an array of these security
04476  * class objects, specifying the range of security mechanisms it is capable of
04477  * enforcing. Every Rx connection within a service is associated with exactly
04478  * one of that service's security objects, and every call issued on the
04479  * connection will execute the given security protocol. 
04480  * \par
04481  * The macros described below facilitate the execution of the security module
04482  * interface functions. They are covered in the same order they appear in the
04483  * struct rx securityOps declaration. 
04484  * 
04485  *      \subsubsection sec5-5-7-1 Section 5.5.7.1: RXS OP() 
04486  * 
04487  * \code
04488  * #if defined(__STDC__) && !defined(__HIGHC__) 
04489  *      #define RXS_OP(obj, op, args) 
04490  *              ((obj->ops->op_ ## op) ? (*(obj)->ops->op_ ## op)args : 0) 
04491  * #else 
04492  *      #define RXS_OP(obj, op, args) 
04493  *              ((obj->ops->op_op) ? (*(obj)->ops->op_op)args : 0) 
04494  * #endif 
04495  * \endcode
04496  * 
04497  * \par
04498  * The RXS OP macro represents the workhorse macro in this group, used by all
04499  * the others. It takes three arguments, the first of which is a pointer to the
04500  * security object to be referenced. This obj parameter must resolve to an
04501  * object of type (struct rx securityOps *). The second parameter identifies
04502  * the specific op to be performed on this security object. The actual text of
04503  * this op argument is used to name the desired opcode function. The third and
04504  * final argument, args, specifies the text of the argument list to be fed to
04505  * the chosen security function. Note that this argument must contain the
04506  * bracketing parentheses for the function call's arguments. In fact, note that
04507  * each of the security function access macros defined below provides the
04508  * enclosing parentheses to this third RXS OP() macro. 
04509  * 
04510  *      \subsubsection sec5-5-7-2 Section 5.5.7.1: RXS Close() 
04511  * 
04512  * \par
04513  * \#define RXS_Close(obj) RXS_OP(obj, Close, (obj)) 
04514  * \par
04515  * This macro causes the execution of the interface routine occupying the op
04516  * Close() slot in the Rx security object identified by the obj pointer. This
04517  * interface function is invoked by Rx immediately before a security object is
04518  * discarded. Among the responsibilities of such a function might be
04519  * decrementing the object's refCount field, and thus perhaps freeing up any
04520  * space contained within the security object's private storage region,
04521  * referenced by the object's privateData field. 
04522  * \par
04523  * The obj parameter must resolve into an object of type (struct rx securityOps
04524  * *). In generating a call to the security object's op Close() routine, the
04525  * obj pointer is used as its single parameter. An invocation of the RXS
04526  * Close() macro results in a return value identical to that of the op Close()
04527  * routine, namely a value of type int. 
04528  * 
04529  *      \subsubsection sec5-5-7-3 Section 5.5.7.3: RXS NewConnection() 
04530  * 
04531  * \par
04532  * \#define RXS_NewConnection(obj, conn) RXS_OP(obj, NewConnection, (obj,
04533  * conn)) 
04534  * \par
04535  * This macro causes the execution of the interface routine in the op
04536  * NewConnection() slot in the Rx security object identified by the obj
04537  * pointer. This interface function is invoked by Rx immediately after a
04538  * connection using the given security object is created. Among the
04539  * responsibilities of such a function might be incrementing the object's
04540  * refCount field, and setting any per-connection information based on the
04541  * associated security object's private storage region, as referenced by the
04542  * object's privateData field. 
04543  * \par
04544  * The obj parameter must resolve into an object of type (struct rx securityOps
04545  * *). The conn argument contains a pointer to the newly-created connection
04546  * structure, and must resolve into an object of type (struct rx connection *). 
04547  * \par
04548  * In generating a call to the routine located at the security object's op
04549  * NewConnection() slot, the obj and conn pointers are used as its two
04550  * parameters. An invocation of the RXS NewConnection() macro results in a
04551  * return value identical to that of the op NewConnection() routine, namely a
04552  * value of type int. 
04553  * 
04554  *      \subsubsection sec5-5-7-4 Section 5.5.7.4: RXS PreparePacket() 
04555  * 
04556  * \par
04557  * \#define RXS_PreparePacket(obj, call, packet) 
04558  * \n RXS_OP(obj, PreparePacket, (obj, call, packet)) 
04559  * \par
04560  * This macro causes the execution of the interface routine in the op
04561  * PreparePacket() slot in the Rx security object identified by the obj
04562  * pointer. This interface function is invoked by Rx each time it prepares an
04563  * outward-bound packet. Among the responsibilities of such a function might be
04564  * computing information to put into the packet's security header and/or
04565  * trailer. 
04566  * \par
04567  * The obj parameter must resolve into an object of type (struct rx securityOps
04568  * *). The call argument contains a pointer to the Rx call to which the given
04569  * packet belongs, and must resolve to an object of type (struct rx call *).
04570  * The final argument, packet, contains a pointer to the packet itself. It
04571  * should resolve to an object of type (struct rx packet *). 
04572  * \par
04573  * In generating a call to the routine located at the security object's op
04574  * PreparePacket() slot, the obj, call, and packet pointers are used as its
04575  * three parameters. An invocation of the RXS PreparePacket() macro results in
04576  * a return value identical to that of the op PreparePacket() routine, namely a
04577  * value of type int. 
04578  * 
04579  *      \subsubsection sec5-5-7-5 Section 5.5.7.5: RXS SendPacket() 
04580  * 
04581  * \par
04582  * \#define RXS_SendPacket(obj, call, packet) RXS_OP(obj, SendPacket, (obj,
04583  * call, packet)) 
04584  * \par
04585  * This macro causes the execution of the interface routine occupying the op
04586  * SendPacket() slot in the Rx security object identified by the obj pointer.
04587  * This interface function is invoked by Rx each time it physically transmits
04588  * an outward-bound packet. Among the responsibilities of such a function might
04589  * be recomputing information in the packet's security header and/or trailer. 
04590  * \par
04591  * The obj parameter must resolve into an object of type (struct rx securityOps
04592  * *). The call argument contains a pointer to the Rx call to which the given
04593  * packet belongs, and must resolve to an object of type (struct rx call *).
04594  * The final argument, packet, contains a pointer to the packet itself. It
04595  * should resolve to an object of type (struct rx packet *). 
04596  * \par
04597  * In generating a call to the routine located at the security object's op
04598  * SendPacket() slot, the obj, call, and packet pointers are used as its three
04599  * parameters. An invocation of the RXS SendPacket() macro results in a return
04600  * value identical to that of the op SendPacket() routine, namely a value of
04601  * type int. 
04602  * 
04603  *      \subsubsection sec5-5-7-6 Section 5.5.7.6: RXS CheckAuthentication() 
04604  * 
04605  * \par
04606  * \#define RXS_CheckAuthentication(obj, conn) RXS_OP(obj, CheckAuthentication,
04607  * (obj, conn)) 
04608  * \par
04609  * This macro causes the execution of the interface routine in the op
04610  * CheckAuthentication() slot in the Rx security object identified by the obj
04611  * pointer. This interface function is invoked by Rx each time it needs to
04612  * check whether the given connection is one on which authenticated calls are
04613  * being performed. Specifically, a value of 0 is returned if authenticated
04614  * calls are not being executed on this connection, and a value of 1 is
04615  * returned if they are. 
04616  * \par
04617  * The obj parameter must resolve into an object of type (struct rx securityOps
04618  * *). The conn argument contains a pointer to the Rx connection checked as to
04619  * whether authentication is being performed, and must resolve to an object of
04620  * type (struct rx connection *). 
04621  * \par
04622  * In generating a call to the routine in the security object's op
04623  * CheckAuthentication() slot, the obj and conn pointers are used as its two
04624  * parameters. An invocation of the RXS CheckAuthentication() macro results in
04625  * a return value identical to that of the op CheckAuthentication() routine,
04626  * namely a value of type int. 
04627  * 
04628  *      \subsubsection sec5-5-7-7 Section 5.5.7.7: RXS CreateChallenge() 
04629  * 
04630  * \par
04631  * \#define RXS_CreateChallenge(obj, conn) RXS_OP(obj, CreateChallenge, (obj,
04632  * conn)) 
04633  * \par
04634  * This macro causes the execution of the interface routine in the op
04635  * CreateChallenge() slot in the Rx security object identified by the obj
04636  * pointer. This interface function is invoked by Rx each time a challenge
04637  * event is constructed for a given connection. Among the responsibilities of
04638  * such a function might be marking the connection as temporarily
04639  * unauthenticated until the given challenge is successfully met. 
04640  * \par
04641  * The obj parameter must resolve into an object of type (struct rx securityOps
04642  * *). The conn argument contains a pointer to the Rx connection for which the
04643  * authentication challenge is being constructed, and must resolve to an object
04644  * of type (struct rx connection *). 
04645  * \par
04646  * In generating a call to the routine located at the security object's op
04647  * CreateChallenge() slot, the obj and conn pointers are used as its two
04648  * parameters. An invocation of the RXS CreateChallenge() macro results in a
04649  * return value identical to that of the op CreateChallenge() routine, namely a
04650  * value of type int. 
04651  * 
04652  *      \subsubsection sec5-5-7-8 Section 5.5.7.8: RXS GetChallenge() 
04653  * 
04654  * \par
04655  * \#define RXS_GetChallenge(obj, conn, packet) RXS_OP(obj, GetChallenge, (obj,
04656  * conn, packet)) 
04657  * \par
04658  * This macro causes the execution of the interface routine occupying the op
04659  * GetChallenge() slot in the Rx security object identified by the obj pointer.
04660  * This interface function is invoked by Rx each time a challenge packet is
04661  * constructed for a given connection. Among the responsibilities of such a
04662  * function might be constructing the appropriate challenge structures in the
04663  * area of packet dedicated to security matters. 
04664  * \par
04665  * The obj parameter must resolve into an object of type (struct rx securityOps
04666  * *). The conn argument contains a pointer to the Rx connection to which the
04667  * given challenge packet belongs, and must resolve to an object of type
04668  * (struct rx connection *). The final argument, packet, contains a pointer to
04669  * the challenge packet itself. It should resolve to an object of type (struct
04670  * rx packet *). 
04671  * \par
04672  * In generating a call to the routine located at the security object's op
04673  * GetChallenge() slot, the obj, conn, and packet pointers are used as its
04674  * three parameters. An invocation of the RXS GetChallenge() macro results in a
04675  * return value identical to that of the op GetChallenge() routine, namely a
04676  * value of type int. 
04677  * 
04678  *      \subsubsection sec5-5-7-9 Section 5.5.7.9: RXS GetResponse() 
04679  * 
04680  * \par
04681  * \#define RXS_GetResponse(obj, conn, packet) RXS_OP(obj, GetResponse, (obj,
04682  * conn, packet)) 
04683  * \par
04684  * This macro causes the execution of the interface routine occupying the op
04685  * GetResponse() slot in the Rx security object identified by the obj pointer.
04686  * This interface function is invoked by Rx on the server side each time a
04687  * response to a challenge packet must be received. 
04688  * \par
04689  * The obj parameter must resolve into an object of type (struct rx securityOps
04690  * *). The conn argument contains a pointer to the Rx client connection that
04691  * must respond to the authentication challenge, and must resolve to a (struct
04692  * rx connection *) object. The final argument, packet, contains a pointer to
04693  * the packet to be built in response to the challenge. It should resolve to an
04694  * object of type (struct rx packet *). 
04695  * \par
04696  * In generating a call to the routine located at the security object's op
04697  * GetResponse() slot, the obj, conn, and packet pointers are used as its three
04698  * parameters. An invocation of the RXS GetResponse() macro results in a return
04699  * value identical to that of the op GetResponse() routine, namely a value of
04700  * type int. 
04701  * 
04702  *      \subsubsection sec5-5-7-10 Section 5.5.7.10: RXS CheckResponse() 
04703  * 
04704  * \par
04705  * \#define RXS_CheckResponse(obj, conn, packet) RXS_OP(obj, CheckResponse,
04706  * (obj, conn, packet)) 
04707  * \par
04708  * This macro causes the execution of the interface routine in the op
04709  * CheckResponse() slot in the Rx security object identified by the obj
04710  * pointer. This interface function is invoked by Rx on the server side each
04711  * time a response to a challenge packet is received for a given connection.
04712  * The responsibilities of such a function might include verifying the
04713  * integrity of the response, pulling out the necessary security information
04714  * and storing that information within the affected connection, and otherwise
04715  * updating the state of the connection. 
04716  * \par
04717  * The obj parameter must resolve into an object of type (struct rx securityOps
04718  * *). The conn argument contains a pointer to the Rx server connection to
04719  * which the given challenge response is directed. This argument must resolve
04720  * to an object of type (struct rx connection *). The final argument, packet,
04721  * contains a pointer to the packet received in response to the challenge
04722  * itself. It should resolve to an object of type (struct rx packet *). 
04723  * \par
04724  * In generating a call to the routine located at the security object's op
04725  * CheckResponse() slot, the obj, conn, and packet pointers are ued as its
04726  * three parameters. An invocation of the RXS CheckResponse() macro results in
04727  * a return value identical to that of the op CheckResponse() routine, namely a
04728  * value of type int. 
04729  * 
04730  *      \subsubsection sec5-5-7-11 Section 5.5.7.11: RXS CheckPacket() 
04731  * 
04732  * \par
04733  * \#define RXS_CheckPacket(obj, call, packet) RXS_OP(obj, CheckPacket, (obj,
04734  * call, packet)) 
04735  * \par
04736  * This macro causes the execution of the interface routine occupying the op
04737  * CheckPacket() slot in the Rx security object identified by the obj pointer.
04738  * This interface function is invoked by Rx each time a packet is received. The
04739  * responsibilities of such a function might include verifying the integrity of
04740  * given packet, detecting any unauthorized modifications or tampering. 
04741  * \par
04742  * The obj parameter must resolve into an object of type (struct rx securityOps
04743  * *). The conn argument contains a pointer to the Rx connection to which the
04744  * given challenge response is directed, and must resolve to an object of type
04745  * (struct rx connection *). The final argument, packet, contains a pointer to
04746  * the packet received in response to the challenge itself. It should resolve
04747  * to an object of type (struct rx packet *). 
04748  * \par
04749  * In generating a call to the routine located at the security object's op
04750  * CheckPacket() slot, the obj, conn, and packet pointers are used as its three
04751  * parameters. An invocation of the RXS CheckPacket() macro results in a return
04752  * value identical to that of the op CheckPacket() routine, namely a value of
04753  * type int. 
04754  * \par
04755  * Please note that any non-zero return will cause Rx to abort all calls on the
04756  * connection. Furthermore, the connection itself will be marked as being in
04757  * error in such a case, causing it to reject any further incoming packets. 
04758  * 
04759  *      \subsubsection sec5-5-7-12 Section 5.5.7.12: RXS DestroyConnection() 
04760  * 
04761  * \par
04762  * \#define RXS_DestroyConnection(obj, conn) RXS_OP(obj, DestroyConnection,
04763  * (obj, conn)) 
04764  * \par
04765  * This macro causes the execution of the interface routine in the op
04766  * DestroyConnection() slot in the Rx security object identified by the obj
04767  * pointer. This interface function is invoked by Rx each time a connection
04768  * employing the given security object is being destroyed. The responsibilities
04769  * of such a function might include deleting any private data maintained by the
04770  * security module for this connection. 
04771  * \par
04772  * The obj parameter must resolve into an object of type (struct rx securityOps
04773  * *). The conn argument contains a pointer to the Rx connection being reaped,
04774  * and must resolve to a (struct rx connection *) object. 
04775  * \par
04776  * In generating a call to the routine located at the security object's op
04777  * DestroyConnection() slot, the obj and conn pointers are used as its two
04778  * parameters. An invocation of the RXS DestroyConnection() macro results in a
04779  * return value identical to that of the op DestroyConnection() routine, namely
04780  * a value of type int. 
04781  * 
04782  *      \subsubsection sec5-5-7-13 Section 5.5.7.13: RXS GetStats() 
04783  * 
04784  * \par
04785  * \#define RXS_GetStats(obj, conn, stats) RXS_OP(obj, GetStats, (obj, conn,
04786  * stats)) 
04787  * \par
04788  * This macro causes the execution of the interface routine in the op
04789  * GetStats() slot in the Rx security object identified by the obj pointer.
04790  * This interface function is invoked by Rx each time current statistics
04791  * concerning the given security object are desired. 
04792  * \par
04793  * The obj parameter must resolve into an object of type (struct rx securityOps
04794  * *). The conn argument contains a pointer to the Rx connection using the
04795  * security object to be examined, and must resolve to an object of type
04796  * (struct rx connection *). The final argument, stats, contains a pointer to a
04797  * region to be filled with the desired statistics. It should resolve to an
04798  * object of type (struct rx securityObjectStats *). 
04799  * \par
04800  * In generating a call to the routine located at the security object's op
04801  * GetStats() slot, the obj, conn, and stats pointers are used as its three
04802  * parameters. An invocation of the RXS GetStats() macro results in a return
04803  * value identical to that of the op GetStats() routine, namely a value of type
04804  * int. 
04805  * 
04806  *      \section sec5-6 Section 5.6: Functions 
04807  * 
04808  * \par
04809  * Rx exports a collection of functions that, in conjuction with the macros
04810  * explored in Section 5.5, allows its clients to set up and export services,
04811  * create and tear down connections to these services, and execute remote
04812  * procedure calls along these connections. 
04813  * \par
04814  * This paper employs two basic categorizations of these Rx routines. One set
04815  * of functions is meant to be called directly by clients of the facility, and
04816  * are referred to as the exported operations. The individual members of the
04817  * second set of functions are not meant to be called directly by Rx clients,
04818  * but rather are called by the collection of defined macros, so they must
04819  * still be lexically visible. These indirectly-executed routines are referred
04820  * to here as the semi-exported operations. 
04821  * \par
04822  * All Rx routines return zero upon success. The range of error codes employed
04823  * by Rx is defined in Section 5.2.15. 
04824  * 
04825  *      \subsection sec5-6-1 Section 5.6.1: Exported Operations 
04826  * 
04827  *      \subsection sec5-6-2 Section 5.6.2: rx Init _ Initialize Rx 
04828  * 
04829  * \par
04830  * int rx Init(IN int port) 
04831  * \par Description 
04832  * Initialize the Rx facility. If a non-zero port number is provided, it
04833  * becomes the default port number for any service installed later. If 0 is
04834  * provided for the port, a random port will be chosen by the system. The rx
04835  * Init() function sets up internal tables and timers, along with starting up
04836  * the listener thread. 
04837  * \par Error Codes 
04838  * RX ADDRINUSE The port provided has already been taken. 
04839  * 
04840  *      \subsection sec5-6-3 Section 5.6.3: rx NewService _ Create and install
04841  *      a new service 
04842  * 
04843  * \par
04844  * struct rx service *rx NewService(IN u short port; IN u short serviceId; IN
04845  * char *serviceName; IN struct rx securityClass **securityObjects; IN int
04846  * nSecurityObjects; IN long (*serviceProc)()) 
04847  * \par Description 
04848  * Create and advertise a new Rx service. A service is uniquely named by a UDP
04849  * port number plus a non-zero 16-bit serviceId on the given host. The port
04850  * argument may be set to zero if rx Init() was called with a non-zero port
04851  * number, in which case that original port will be used. A serviceName must
04852  * also be provided, to be used for identification purposes (e.g., the service
04853  * name might be used for probing for statistics). A pointer to an array of
04854  * nSecurityObjects security objects to be associated with the new service is
04855  * given in . securityObjects. The service's executeRequestProc() pointer is
04856  * set to serviceProc. 
04857  * \par
04858  * The function returns a pointer to a descriptor for the requested Rx service.
04859  * A null return value indicates that the new service could not be created.
04860  * Possible reasons include: 
04861  * \li The serviceId parameter was found to be zero. 
04862  * \li A port value of zero was specified at Rx initialization time (i.e., when
04863  * rx init() was called), requiring a non-zero value for the port parameter
04864  * here. 
04865  * \li Another Rx service is already using serviceId. 
04866  * \li Rx has already created the maximum RX MAX SERVICES Rx services (see
04867  * Section 5.2.1). 
04868  * \par Error Codes 
04869  * (struct rx service *) NULL The new Rx service could not be created, due to
04870  * one of the errors listed above. 
04871  * 
04872  *      \subsection sec5-6-4 Section 5.6.4: rx NewConnection _ Create a new
04873  *      connection to a given service 
04874  * 
04875  * \par
04876  * struct rx connection *rx NewConnection( IN u long shost, IN u short sport,
04877  * IN u short sservice, IN struct rx securityClass *securityObject, IN int
04878  * service SecurityIndex) 
04879  * \par Description 
04880  * Create a new Rx client connection to service sservice on the host whose IP
04881  * address is contained in shost and to that host's sport UDP port. The
04882  * corresponding Rx service identifier is expected in sservice. The caller also
04883  * provides a pointer to the security object to use for the connection in
04884  * securityObject, along with that object's serviceSecurityIndex among the
04885  * security objects associated with service sservice via a previous rx
04886  * NewService() call (see Section 5.6.3). 
04887  * \note It is permissible to provide a null value for the securityObject
04888  * parameter if the chosen serviceSecurityIndex is zero. This corresponds to
04889  * the pre-defined null security object, which does not engage in authorization
04890  * checking of any kind. 
04891  * \par Error Codes 
04892  * --- A pointer to an initialized Rx connection is always returned, unless osi
04893  *  Panic() is called due to memory allocation failure. 
04894  * 
04895  *      \subsection sec5-6-5 Section 5.6.5: rx NewCall _ Start a new call on
04896  *      the given connection 
04897  * 
04898  * \par
04899  * struct rx call *rx NewCall( IN struct rx connection *conn) 
04900  * \par Description 
04901  * Start a new Rx remote procedure call on the connection specified by the conn
04902  * parameter. The existing call structures (up to RX MAXCALLS of them) are
04903  * examined in order. The first non-active call encountered (i.e., either
04904  * unused or whose call->state is RX STATE DALLY) will be appropriated and
04905  * reset if necessary. If all call structures are in active use, the RX CONN
04906  * MAKECALL WAITING flag is set in the conn->flags field, and the thread
04907  * handling this request will sleep until a call structure comes free. Once a
04908  * call structure has been reserved, the keep-alive protocol is enabled for it. 
04909  * \par
04910  * The state of the given connection determines the detailed behavior of the
04911  * function. The conn->timeout field specifies the absolute upper limit of the
04912  * number of seconds this particular call may be in operation. After this time
04913  * interval, calls to such routines as rx SendData() or rx ReadData() will fail
04914  * with an RX CALL TIMEOUT indication. 
04915  * \par Error Codes 
04916  * --- A pointer to an initialized Rx call is always returned, unless osi
04917  *  Panic() is called due to memory allocation failure. 
04918  * 
04919  *      \subsection sec5-6-6 Section 5.6.6: rx EndCall _ Terminate the given
04920  *      call 
04921  * 
04922  * \par
04923  * int rx EndCall(
04924  * \param IN struct rx call *call,
04925  * \param IN long rc
04926  * \n ) 
04927  * \par Description
04928  * Indicate that the Rx call described by the structure located at call is
04929  * finished, possibly prematurely. The value passed in the rc parameter is
04930  * returned to the peer, if appropriate. The final error code from processing
04931  * the call will be returned as rx EndCall()'s value. The given call's state
04932  * will be set to RX STATE DALLY, and threads waiting to establish a new call
04933  * on this connection are signalled (see the description of the rx NewCall() in
04934  * Section 5.6.5). 
04935  * \par Error Codes 
04936  * -1 Unspecified error has occurred. 
04937  * 
04938  *      \subsection sec5-6-7 Section 5.6.7: rx StartServer _ Activate installed
04939  *      rx service(s) 
04940  * 
04941  * \par
04942  * void rx StartServer( IN int donateMe) 
04943  * \par Description 
04944  * This function starts server threads in support of the Rx services installed
04945  * via calls to rx NewService() (see Section 5.6.3). This routine first
04946  * computes the number of server threads it must create, governed by the
04947  * minProcs and maxProcs fields in the installed service descriptors. The
04948  * minProcs field specifies the minimum number of threads that are guaranteed
04949  * to be concurrently available to the given service. The maxProcs field
04950  * specifies the maximum number of threads that may ever be concurrently
04951  * assigned to the particular service, if idle threads are available. Using
04952  * this information, rx StartServer() computes the correct overall number of
04953  * threads as follows: For each installed service, minProcs threads will be
04954  * created, enforcing the minimality guarantee. Calculate the maximum
04955  * difference between the maxProcs and minProcs fields for each service, and
04956  * create this many additional server threads, enforcing the maximality
04957  * guarantee. 
04958  * \par
04959  * If the value placed in the donateMe argument is zero, then rx StartServer()
04960  * will simply return after performing as described above. Otherwise, the
04961  * thread making the rx StartServer() call will itself begin executing the
04962  * server thread loop. In this case, the rx StartServer() call will never
04963  * return. 
04964  * \par Error Codes 
04965  * ---None. 
04966  * 
04967  *      \subsection sec5-6-8 Section 5.6.8: rx PrintStats -- Print basic
04968  *      statistics to a file
04969  * 
04970  * \par
04971  * void rx PrintStats( IN FILE *file)
04972  * \par Description
04973  * Prints Rx statistics (basically the contents of the struct rx stats holding
04974  * the statistics for the Rx facility) to the open file descriptor identified
04975  * by file. The output is ASCII text, and is intended for human consumption. 
04976  * \note This function is available only if the Rx package has been compiled
04977  * with the RXDEBUG flag. 
04978  * \par Error Codes 
04979  * ---None. 
04980  * 
04981  *      \subsection sec5-6-9 Section 5.6.9: rx PrintPeerStats _ Print peer
04982  *      statistics to a file 
04983  * \par
04984  * void rx PrintPeerStats( IN FILE *file, IN struct rx peer *peer)
04985  * \par Description
04986  * Prints the Rx peer statistics found in peer to the open file descriptor
04987  * identified by file. The output is in normal ASCII text, and is intended for
04988  * human consumption. 
04989  * \note This function is available only if the Rx package has been compiled
04990  * with the RXDEBUG flag. 
04991  * \par Error Codes 
04992  * ---None. 
04993  * 
04994  *      \subsection sec5-6-10 Section 5.6.10: rx finalize _ Shut down Rx
04995  *      gracefully 
04996  * 
04997  * \par
04998  * void rx finalize() 
04999  * \par Description 
05000  * This routine may be used to shut down the Rx facility for either server or
05001  * client applications. All of the client connections will be gracefully
05002  * garbage-collected after their active calls are cleaned up. The result of
05003  * calling rx finalize() from a client program is that the server-side entity
05004  * will be explicitly advised that the client has terminated. This notification
05005  * frees the server-side application from having to probe the client until its
05006  * records eventually time out, and also allows it to free resources currently
05007  * assigned to that client's support. 
05008  * \par Error Codes 
05009  * ---None. 
05010  * 
05011  *      \subsection sec5-6-11 Section 5.6.11: Semi-Exported Operations 
05012  * 
05013  * \par
05014  * As described in the introductory text in Section 5.6, entries in this
05015  * lexically-visible set of Rx functions are not meant to be called directly by
05016  * client applications, but rather are invoked by Rx macros called by users. 
05017  * 
05018  *      \subsection sec5-6-12 Section 5.6.12: rx WriteProc _ Write data to an
05019  *      outgoing call 
05020  * 
05021  * \par
05022  * int rx WriteProc( IN struct rx call *call, IN char *buf, IN int nbytes)
05023  * \par Description 
05024  * Write nbytes of data from buffer buf into the Rx call identified by the call
05025  * parameter. The value returned by rx WriteProc() reports the number of bytes
05026  * actually written into the call. If zero is returned, then the rx Error()
05027  * macro may be used to obtain the call status. 
05028  * \par
05029  * This routine is called by the rx Write() macro, which is why it must be
05030  * exported by the Rx facility. 
05031  * \par Error Codes 
05032  * Indicates error in the given Rx call; use the rx Error() macro to determine
05033  * the call status. 
05034  * 
05035  *      \subsection sec5-6-13 Section 5.6.13: rx ReadProc _ Read data from an
05036  *      incoming call 
05037  * 
05038  * \par
05039  * int rx ReadProc( IN struct rx call *call, IN char *buf, IN int nbytes)
05040  * \par Description 
05041  * Read up to nbytes of data from the Rx call identified by the call parameter
05042  * into the buf buffer. The value returned by rx ReadProc() reports the number
05043  * of bytes actually read from the call. If zero is returned, then the rx
05044  * Error() macro may be used to obtain the call status. 
05045  * \par
05046  * This routine is called by the rx Read() macro, which is why it must be
05047  * exported by the Rx facility. 
05048  * \par Error Codes 
05049  * Indicates error in the given Rx call; use the rx Error() macro to determine
05050  * the call status. 
05051  * 
05052  *      \subsection sec5-6-1 Section 5.6.1: rx FlushWrite -- Flush buffered
05053  *      data on outgoing call
05054  * 
05055  * \par
05056  * void rx FlushWrite( IN struct rx call *call)
05057  * \par Description
05058  * Flush any buffered data on the given Rx call to the stream. If the call is
05059  * taking place on a server connection, the call->mode is set to RX MODE EOF.
05060  * If the call is taking place on a client connection, the call->mode is set to
05061  * RX MODE RECEIVING. 
05062  * \par Error Codes 
05063  * ---None. 
05064  * 
05065  *      \subsection sec5-6-15 Section 5.6.15: rx SetArrivalProc _ Set function
05066  *      to invoke upon call packet arrival 
05067  * 
05068  * \par
05069  * void rx SetArrivalProc( IN struct rx call *call, IN VOID (*proc)(), IN VOID
05070  * *handle, IN VOID *arg) 
05071  * \par Description 
05072  * Establish a procedure to be called when a packet arrives for a call. This
05073  * routine will be called at most once after each call, and will also be called
05074  * if there is an error condition on the call or the call is complete. The rx
05075  * SetArrivalProc() function is used by multicast Rx routines to build a
05076  * selection function that determines which of several calls is likely to be a
05077  * good one to read from. The implementor's comments in the Rx code state that,
05078  * due to the current implementation, it is probably only reasonable to use rx
05079  * SetArrivalProc() immediately after an rx NewCall(), and to only use it once. 
05080  * \par Error Codes 
05081  * ---None. 
05082  * 
05083  *      \page chap6 Chapter 6 -- Example Server and Client 
05084  * 
05085  *      \section sec6-1 Section 6.1: Introduction 
05086  * 
05087  * \par
05088  * This chapter provides a sample program showing the use of Rx. Specifically,
05089  * the rxdemo application, with all its support files, is documented and
05090  * examined. The goal is to provide the reader with a fully-developed and
05091  * operational program illustrating the use of both regular Rx remote procedure
05092  * calls and streamed RPCs. The full text of the rxdemo application is
05093  * reproduced in the sections below, along with additional commentary. 
05094  * \par
05095  * Readers wishing to directly experiment with this example Rx application are
05096  * encouraged to examine the on-line version of rxdemo. Since it is a program
05097  * of general interest, it has been installed in the usr/contrib tree in the
05098  * grand.central.org cell. This area contains user-contributed software for the
05099  * entire AFS community. At the top of this tree is the
05100  * /afs/grand.central.org/darpa/usr/contrib directory. Both the server-side and
05101  * client-side rxdemo binaries (rxdemo server and rxdemo client, respectively)
05102  * may be found in the bin subdirectory. The actual sources reside in the
05103  * .site/grand.central.org/rxdemo/src subdirectory. 
05104  * \par
05105  * The rxdemo code is composed of two classes of files, namely those written by
05106  * a human programmer and those generated from the human-written code by the
05107  * Rxgen tool. Included in the first group of files are: 
05108  * \li  rxdemo.xg This is the RPC interface definition file, providing
05109  * high-level definitions of the supported calls. 
05110  * \li  rxdemo client.c: This is the rxdemo client program, calling upon the
05111  * associated server to perform operations defined by rxdemo.xg. 
05112  * \li  rxdemo server.c: This is the rxdemo server program, implementing the
05113  * operations promised in rxdemo.xg. 
05114  * \li  Makefile: This is the file that directs the compilation and
05115  * installation of the rxdemo code. 
05116  * \par
05117  * The class of automatically-generated files includes the following items: 
05118  * \li rxdemo.h: This header file contains the set of constant definitions
05119  * present in rxdemo.xg, along with information on the RPC opcodes defined for
05120  * this Rx service. 
05121  * \li rxdemo.cs.c: This client-side stub file performs all the marshalling and
05122  * unmarshalling of the arguments for the RPC routines defined in rxdemo.xg. 
05123  * \li rxdemo.ss.c: This stub file similarly defines all the marshalling and
05124  * unmarshalling of arguments for the server side of the RPCs, invokes the
05125  * routines defined within rxdemo server.c to implement the calls, and also
05126  * provides the dispatcher function. 
05127  * \li rxdemo.xdr.c: This module defines the routines required to convert
05128  * complex user-defined data structures appearing as arguments to the Rx RPC
05129  * calls exported by rxdemo.xg into network byte order, so that correct
05130  * communication is guaranteed between clients and server with different memory
05131  * organizations. 
05132  * \par
05133  * The chapter concludes with a section containing sample output from running
05134  * the rxdemo server and client programs. 
05135  * 
05136  *      \section sec6-2 Section 6.2: Human-Generated files 
05137  * 
05138  * \par
05139  * The rxdemo application is based on the four human-authored files described
05140  * in this section. They provide the basis for the construction of the full set
05141  * of modules needed to implement the specified Rx service. 
05142  * 
05143  *      \subsection sec6-2-1 Section 6.2.1: Interface file: rxdemo.xg 
05144  * 
05145  * \par
05146  * This file serves as the RPC interface definition file for this application.
05147  * It defines various constants, including the Rx service port to use and the
05148  * index of the null security object (no encryption is used by rxdemo). It
05149  * defines the RXDEMO MAX and RXDEMO MIN constants, which will be used by the
05150  * server as the upper and lower bounds on the number of Rx listener threads to
05151  * run. It also defines the set of error codes exported by this facility.
05152  * finally, it provides the RPC function declarations, namely Add() and
05153  * Getfile(). Note that when building the actual function definitions, Rxgen
05154  * will prepend the value of the package line in this file, namely "RXDEMO ",
05155  * to the function declarations. Thus, the generated functions become RXDEMO
05156  * Add() and RXDEMO Getfile(), respectively. Note the use of the split keyword
05157  * in the RXDEMO Getfile() declaration, which specifies that this is a streamed
05158  * call, and actually generates two client-side stub routines (see Section
05159  * 6.3.1). 
05160  * 
05161  * \code
05162  * /*======================================================================= 
05163  * * Interface for an example Rx server/client application, using both * * 
05164  * standard and streamed calls.  * ** * Edward R. Zayas * * Transarc 
05165  * Corporation * ** ** * The United States Government has rights in this 
05166  * work pursuant * * to contract no. MDA972-90-C-0036 between the United 
05167  * States Defense * * Advanced Research Projects Agency and Transarc 
05168  * Corporation.  * ** * (C) Copyright 1991 Transarc Corporation * ** * 
05169  * Redistribution and use in source and binary forms are permitted * 
05170  * provided that: (1) source distributions retain this entire copy- * * 
05171  * right notice and comment, and (2) distributions including binaries * * 
05172  * display the following acknowledgement: * ** * ''This product includes 
05173  * software developed by Transarc * * Corporation and its contributors'' * 
05174  * ** * in the documentation or other materials mentioning features or * * 
05175  * use of this software. Neither the name of Transarc nor the names * * of 
05176  * its contributors may be used to endorse or promote products * * derived 
05177  * from this software without specific prior written * * permission.  * ** 
05178  * * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED * 
05179  * * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * 
05180  * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 
05181  * =======================================================================*/
05182  * 
05183  * package RXDEMO_ 
05184  * %#include <rx/rx.h> 
05185  * %#include <rx/rx_null.h> 
05186  * %#define RXDEMO_SERVER_PORT 8000 /* Service port to advertise */
05187  * %#define RXDEMO_SERVICE_PORT 0 /* User server's port */
05188  * %#define RXDEMO_SERVICE_ID 4 /* Service ID */
05189  * %#define RXDEMO_NULL_SECOBJ_IDX 0 /* Index of null security object */
05190  * 
05191  * /* Maximum number of requests that will be handled by this service 
05192  *  * simultaneously. This number will be guaranteed to execute in 
05193  *  * parallel if other service's results are being processed. */
05194  * 
05195  * %#define RXDEMO_MAX 3 
05196  * 
05197  * /* Minimum number of requests that are guaranteed to be 
05198  *  * handled simultaneously. */
05199  * 
05200  * %#define RXDEMO_MIN 2 
05201  * 
05202  * /* Index of the "null" security class in the sample service. */
05203  * 
05204  * %#define RXDEMO_NULL 0 
05205  * 
05206  * /* Maximum number of characters in a file name (for demo purposes). */
05207  * 
05208  * %#define RXDEMO_NAME_MAX_CHARS 64 
05209  * 
05210  * /* Define the max number of bytes to transfer at one shot. */
05211  * 
05212  * %#define RXDEMO_BUFF_BYTES 512 
05213  * 
05214  * /* Values returned by the RXDEMO_Getfile() call. 
05215  *  * RXDEMO_CODE_SUCCESS : Everything went fine. 
05216  *  * RXDEMO_CODE_CANT_OPEN : Can't open named file. 
05217  *  * RXDEMO_CODE_CANT_STAT : Can't stat open file. 
05218  *  * RXDEMO_CODE_CANT_READ : Error reading the open file. 
05219  *  * RXDEMO_CODE_WRITE_ERROR : Error writing the open file. */
05220  * 
05221  * /* ------------Interface calls defined for this service ----------- */
05222  * %#define RXDEMO_CODE_SUCCESS 0 
05223  * %#define RXDEMO_CODE_CANT_OPEN 1 
05224  * %#define RXDEMO_CODE_CANT_STAT 2 
05225  * %#define RXDEMO_CODE_CANT_READ 3 
05226  * %#define RXDEMO_CODE_WRITE_ERROR 4 
05227  * /* -------------------------------------------------------------------
05228  * * RXDEMO_Add * 
05229  * *    
05230  * * Summary: 
05231  * *    Add the two numbers provided and return the result. * 
05232  * * Parameters: 
05233  * *    int a_first : first operand. 
05234  * *    int a_second : Second operand. 
05235  * *    int *a_result : Sum of the above. * 
05236  * *    Side effects: None.  
05237  * *-------------------------------------------------------------------- */
05238  * 
05239  * Add(IN int a, int b, OUT int *result) = 1; 
05240  * /*-------------------------------------------------------------------
05241  * * RXDEMO_Getfile * 
05242  * * Summary: 
05243  * *    Return the contents of the named file in the server's environment. 
05244  * * Parameters: 
05245  * *    STRING a_nameToRead : Name of the file whose contents are to be 
05246  * *    fetched. 
05247  * *    int *a_result : Set to the result of opening and reading the file 
05248  * *    on the server side. * 
05249  * *    Side effects: None. 
05250  * *-------------------------------------------------------------------- */
05251  * 
05252  * Getfile(IN string a_nameToRead<RXDEMO_NAME_MAX_CHARS>, OUT int *a_result) 
05253  *      split = 2; 
05254  * \endcode
05255  * 
05256  *      \subsection sec6-2-2 Section 6.2.2: Client Program: rxdemo client.c 
05257  * 
05258  * \par
05259  * The rxdemo client program, rxdemo client, calls upon the associated server
05260  * to perform operations defined by rxdemo.xg. After its header, it defines a
05261  * private GetIPAddress() utility routine, which given a character string host
05262  * name will return its IP address. 
05263  * 
05264  * \code
05265  * /*======================================================================= 
05266  * % Client side of an example Rx application, using both standard and % % 
05267  * streamed calls.  % %% % Edward R. Zayas % % Transarc Corporation % %% 
05268  * %% % The United States Government has rights in this work pursuant % % 
05269  * to contract no. MDA972-90-C-0036 between the United States Defense % % 
05270  * Advanced Research Projects Agency and Transarc Corporation.  % %% % (C) 
05271  * Copyright 1991 Transarc Corporation % %% % Redistribution and use in source 
05272  * and binary forms are permitted % % provided that: (1) source distributions 
05273  * retain this entire copy- % % right notice and comment, and (2) distributions 
05274  * including binaries % % display the following acknowledgement: % %% % 
05275  * ''This product includes software developed by Transarc % % Corporation and 
05276  * its contributors'' % %% % in the documentation or other materials mentioning 
05277  * features or % % use of this software. Neither the name of Transarc nor the 
05278  * names % % of its contributors may be used to endorse or promote products % % 
05279  * derived from this software without specific prior written % % permission. 
05280  * % %% % THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED 
05281  * % % WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF % % 
05282  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 
05283  * % %=======================================================================
05284  * */
05285  * 
05286  * #include <sys/types.h> 
05287  * #include <netdb.h> 
05288  * #include <stdio.h> 
05289  * #include "rxdemo.h" 
05290  * static char pn[] = "rxdemo"; /* Program name */
05291  * static u_long GetIpAddress(a_hostName) char *a_hostName; 
05292  * { /* GetIPAddress */
05293  *      static char rn[] = "GetIPAddress"; /* Routine name */
05294  *      struct hostent *hostEntP; /* Ptr to host descriptor */
05295  *      u_long hostIPAddr; /* Host IP address */
05296  *      hostEntP = gethostbyname(a_hostName); 
05297  *      if (hostEntP == (struct hostent *)0) { 
05298  *              printf("[%s:%s] Host '%s' not found\n", 
05299  *              pn, rn, a_hostName); 
05300  *              exit(1); 
05301  *      } 
05302  *      if (hostEntP->h_length != sizeof(u_long)) { 
05303  *              printf("[%s:%s] Wrong host address length (%d bytes instead of
05304  *              %d)", 
05305  *              pn, rn, hostEntP->h_length, sizeof(u_long)); 
05306  *              exit(1); 
05307  *      } 
05308  *      bcopy(hostEntP->h_addr, (char *)&hostIPAddr, sizeof(hostIPAddr)); 
05309  *      return(hostIPAddr); 
05310  * } /* GetIpAddress */
05311  * \endcode
05312  * 
05313  * \par
05314  * The main program section of the client code, after handling its command line
05315  * arguments, starts off by initializing the Rx facility. 
05316  * 
05317  * \code
05318  * main(argc, argv) 
05319  * int argc; 
05320  * char **argv; 
05321  * { /* Main */
05322  *      struct rx_connection *rxConnP; /* Ptr to server connection */
05323  *      struct rx_call *rxCallP; /* Ptr to Rx call descriptor */
05324  *      u_long hostIPAddr; /* IP address of chosen host */
05325  *      int demoUDPPort; /* UDP port of Rx service */
05326  *      struct rx_securityClass *nullSecObjP; /* Ptr to null security object */
05327  *      int operand1, operand2; /* Numbers to add int sum; Their sum */
05328  *      int code; /* Return code */
05329  *      char fileName[64]; /* Buffer for desired file's name */
05330  *      long fileDataBytes; /* Num bytes in file to get */
05331  *      char buff[RXDEMO_BUFF_BYTES+1]; /* Read buffer */
05332  *      int currBytesToRead; /* Num bytes to read in one iteration */
05333  *      int maxBytesToRead; /* Max bytes to read in one iteration */
05334  *      int bytesReallyRead; /* Num bytes read off Rx stream */
05335  *      int getResults; /* Results of the file fetch */
05336  *      printf("\n%s: Example Rx client process\n\n", pn); 
05337  *      if ((argc < 2) || (argc > 3)) { 
05338  *              printf("Usage: rxdemo <HostName> [PortToUse]"); 
05339  *              exit(1); 
05340  *      } 
05341  *      hostIPAddr = GetIpAddress(argv[1]); 
05342  *      if (argc > 2) 
05343  *              demoUDPPort = atoi(argv[2]); 
05344  *      else 
05345  *              demoUDPPort = RXDEMO_SERVER_PORT; 
05346  *      /* Initialize the Rx facility. */
05347  *      code = rx_Init(htons(demoUDPPort)); 
05348  *      if (code) { 
05349  *              printf("**      Error calling rx_Init(); code is %d\n", code); 
05350  *              exit(1); 
05351  *      } 
05352  *      /* Create a client-side null security object. */
05353  *      nullSecObjP = rxnull_NewClientSecurityObject(); 
05354  *      if (nullSecObjP == (struct rx_securityClass *)0) { 
05355  *              printf("%s: Can't create a null client-side security
05356  *              object!\n", pn); 
05357  *              exit(1); 
05358  *      } 
05359  *      /* Set up a connection to the desired Rx service, telling it to use
05360  *      * the null security object we just created.  */
05361  *      printf("Connecting to Rx server on '%s', IP address 0x%x, UDP port
05362  *      %d\n", argv[1], hostIPAddr, demoUDPPort); 
05363  *      rxConnP = rx_NewConnection(hostIPAddr, RXDEMO_SERVER_PORT,
05364  *      RXDEMO_SERVICE_ID, nullSecObjP, RXDEMO_NULL_SECOBJ_IDX); 
05365  *      if (rxConnP == (struct rx_connection *)0) { 
05366  *              printf("rxdemo: Can't create connection to server!\n"); 
05367  *              exit(1); 
05368  *      } else 
05369  *              printf(" ---> Connected.\n"); 
05370  * \endcode
05371  * 
05372  * \par
05373  * The rx Init() invocation initializes the Rx library and defines the desired
05374  * service UDP port (in network byte order). The rxnull
05375  * NewClientSecurityObject() call creates a client-side Rx security object that
05376  * does not perform any authentication on Rx calls. Once a client
05377  * authentication object is in hand, the program calls rx NewConnection(),
05378  * specifying the host, UDP port, Rx service ID, and security information
05379  * needed to establish contact with the rxdemo server entity that will be
05380  * providing the service. 
05381  * \par
05382  * With the Rx connection in place, the program may perform RPCs. The first one
05383  * to be invoked is RXDEMO Add(): 
05384  *  
05385  * \code
05386  * /* Perform our first, simple remote procedure call. */
05387  * operand1 = 1; 
05388  * operand2 = 2; 
05389  * printf("Asking server to add %d and %d: ", operand1, operand2); 
05390  * code = RXDEMO_Add(rxConnP, operand1, operand2, &sum); 
05391  * if (code) { 
05392  *      printf("  // ** Error in the RXDEMO_Add RPC: code is %d\n", code); 
05393  *      exit(1); 
05394  * } 
05395  * printf("Reported sum is %d\n", sum); 
05396  * \endcode
05397  * 
05398  * \par
05399  * The first argument to RXDEMO Add() is a pointer to the Rx connection
05400  * established above. The client-side body of the RXDEMO Add() function was
05401  * generated from the rxdemo.xg interface file, and resides in the rxdemo.cs.c
05402  * file (see Section 6.3.1). It gives the appearance of being a normal C
05403  * procedure call. 
05404  * \par
05405  * The second RPC invocation involves the more complex, streamed RXDEMO
05406  * Getfile() function. More of the internal Rx workings are exposed in this
05407  * type of call. The first additional detail to consider is that we must
05408  * manually create a new Rx call on the connection. 
05409  *  
05410  * \code
05411  * /* Set up for our second, streamed procedure call. */
05412  * printf("Name of file to read from server: "); 
05413  * scanf("%s", fileName); 
05414  * maxBytesToRead = RXDEMO_BUFF_BYTES; 
05415  * printf("Setting up an Rx call for RXDEMO_Getfile..."); 
05416  * rxCallP = rx_NewCall(rxConnP); 
05417  * if (rxCallP == (struct rx_call *)0) { 
05418  *      printf("** Can't create call\n"); 
05419  *      exit(1); 
05420  * } 
05421  * printf("done\n"); 
05422  * \endcode
05423  * 
05424  * \par
05425  * Once the Rx call structure has been created, we may begin executing the call
05426  * itself. Having been declared to be split in the interface file, Rxgen
05427  * creates two function bodies for rxdemo Getfile() and places them in
05428  * rxdemo.cs.c. The first, StartRXDEMO Getfile(), is responsible for
05429  * marshalling the outgoing arguments and issuing the RPC. The second,
05430  * EndRXDEMO Getfile(), takes care of unmarshalling the non-streamed OUT
05431  * function parameters. The following code fragment illustrates how the RPC is
05432  * started, using the StartRXDEMO Getfile() routine to pass the call parameters
05433  * to the server. 
05434  *  
05435  * \code
05436  * /* Sending IN parameters for the streamed call. */
05437  * code = StartRXDEMO_Getfile(rxCallP, fileName); 
05438  * if (code) { 
05439  *      printf("**      Error calling StartRXDEMO_Getfile(); code is %d\n",
05440  *      code); 
05441  *      exit(1); 
05442  * } 
05443  * \endcode
05444  * 
05445  * \par
05446  * Once the call parameters have been shipped, the server will commence
05447  * delivering the "stream" data bytes back to the client on the given Rx call
05448  * structure. The first longword to come back on the stream specifies the
05449  * number of bytes to follow. 
05450  *  
05451  * \par
05452  * Begin reading the data being shipped from the server in response to * our
05453  * setup call. The first longword coming back on the Rx call is 
05454  * the number of bytes to follow. It appears in network byte order, 
05455  * so we have to fix it up before referring to it. 
05456  * 
05457  * \code
05458  * bytesReallyRead = rx_Read(rxCallP, &fileDataBytes, sizeof(long)); 
05459  * if (bytesReallyRead != sizeof(long)) { 
05460  *      printf("** Only %d bytes read for file length; should have been %d\n",
05461  *      bytesReallyRead, sizeof(long)); 
05462  *      exit(1); 
05463  * } 
05464  * fileDataBytes = ntohl(fileDataBytes); 
05465  * \endcode
05466  * 
05467  * \par
05468  * Once the client knows how many bytes will be sent, it runs a loop in which
05469  * it reads a buffer at a time from the Rx call stream, using rx Read() to
05470  * accomplish this. In this application, all that is done with each
05471  * newly-acquired buffer of information is printing it out. 
05472  * 
05473  * \code 
05474  * /* Read the file bytes via the Rx call, a buffer at a time. */
05475  * printf("[file contents (%d bytes) fetched over the Rx call appear
05476  * below]\n\n", fileDataBytes); 
05477  * while (fileDataBytes > 0) 
05478  * { 
05479  *      currBytesToRead = (fileDataBytes > maxBytesToRead ?  maxBytesToRead :
05480  *      fileDataBytes); 
05481  *      bytesReallyRead = rx_Read(rxCallP, buff, currBytesToRead); 
05482  *      if (bytesReallyRead != currBytesToRead)
05483  *      { 
05484  *              printf("\nExpecting %d bytes on this read, got %d instead\n",
05485  *              currBytesToRead, bytesReallyRead); 
05486  *              exit(1); 
05487  *      }  
05488  *      /* Null-terminate the chunk before printing it. */
05489  *      buff[currBytesToRead] = 0; 
05490  *      printf("%s", buff); 
05491  *      /* Adjust the number of bytes left to read. */
05492  *      fileDataBytes -= currBytesToRead; 
05493  * } /* Read one bufferful of the file */
05494  * \endcode
05495  * 
05496  * \par
05497  * After this loop terminates, the Rx stream has been drained of all data. The
05498  * Rx call is concluded by invoking the second of the two
05499  * automatically-generated functions, EndRXDEMO Getfile(), which retrieves the
05500  * call's OUT parameter from the server. 
05501  * 
05502  * \code
05503  * /* finish off the Rx call, getting the OUT parameters. */
05504  * printf("\n\n[End of file data]\n"); 
05505  * code = EndRXDEMO_Getfile(rxCallP, &getResults); 
05506  * if (code) 
05507  * { 
05508  *      printf("**      Error getting file transfer results; code is %d\n",
05509  *      code); 
05510  *      exit(1); 
05511  * } 
05512  * \endcode
05513  * 
05514  * \par
05515  * With both normal and streamed Rx calls accomplished, the client demo code
05516  * concludes by terminating the Rx call it set up earlier. With that done, the
05517  * client exits. 
05518  * 
05519  * \code 
05520  * /* finish off the Rx call. */
05521  * code = rx_EndCall(rxCallP, code); 
05522  * if (code) 
05523  *      printf("Error   in calling rx_EndCall(); code is %d\n", code); 
05524  * 
05525  * printf("\n\nrxdemo complete.\n"); 
05526  * \endcode
05527  * 
05528  *      \subsection sec6-2-3 Server Program: rxdemo server.c 
05529  * 
05530  * \par
05531  * The rxdemo server program, rxdemo server, implements the operations promised
05532  * in the rxdemo.xg interface file. 
05533  * \par
05534  * After the initial header, the external function RXDEMO ExecuteRequest() is
05535  * declared. The RXDEMO ExecuteRequest() function is generated automatically by
05536  * rxgen from the interface file and deposited in rxdemo.ss.c. The main program
05537  * listed below will associate this RXDEMO ExecuteRequest() routine with the Rx
05538  * service to be instantiated. 
05539  * 
05540  * \code
05541  * /*======================================================================
05542  * % % Advanced Research Projects Agency and Transarc Corporation.  % %% % 
05543  * (C) Copyright 1991 Transarc Corporation % %% % Redistribution and use in 
05544  * source and binary forms are permitted % % provided that: (1) source 
05545  * distributions retain this entire copy- % % right notice and comment, and 
05546  * (2) distributions including binaries % % display the following 
05547  * acknowledgement: % %% % ''This product includes software developed by 
05548  * Transarc % % Corporation and its contributors'' % %% % in the documentation 
05549  * or other materials mentioning features or % % use of this software. Neither 
05550  * the name of Transarc nor the names % % of its contributors may be used to 
05551  * endorse or promote products % % derived from this software without specific 
05552  * prior written % % permission.  % %% % THIS SOFTWARE IS PROVIDED "AS IS" AND 
05553  * WITHOUT ANY EXPRESS OR IMPLIED % % WARRANTIES, INCLUDING, WITHOUT
05554  * LIMITATION, 
05555  * THE IMPLIED WARRANTIES OF % % MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
05556  * PURPOSE.  % %
05557  * ====================================================================== */
05558  * 
05559  * /* Server portion of the example RXDEMO application, using both % 
05560  * standard and streamed calls. % % Edward R. Zayas % Transarc Corporation % 
05561  * % % The United States Government has rights in this work pursuant % 
05562  * to contract no. MDA972-90-C-0036 between the United States Defense % */
05563  * 
05564  * #include <sys/types.h> 
05565  * #include <sys/stat.h> 
05566  * #include <sys/file.h> 
05567  * #include <netdb.h> 
05568  * #include <stdio.h> 
05569  * #include "rxdemo.h" 
05570  * #define N_SECURITY_OBJECTS 1 
05571  * extern RXDEMO_ExecuteRequest(); 
05572  * \endcode
05573  * 
05574  * \par
05575  * After choosing either the default or user-specified UDP port on which the Rx
05576  * service will be established, rx Init() is called to set up the library. 
05577  * 
05578  * \code
05579  * main(argc, argv) 
05580  *      int argc; 
05581  *      char **argv; 
05582  * { /* Main */
05583  *      static char pn[] = "rxdemo_server"; /* Program name */
05584  *      struct rx_securityClass 
05585  *      (securityObjects[1]); /* Security objs */
05586  *      struct rx_service *rxServiceP; /* Ptr to Rx service descriptor */
05587  *      struct rx_call *rxCallP; /* Ptr to Rx call descriptor */
05588  *      int demoUDPPort; /* UDP port of Rx service */
05589  *      int fd; /* file descriptor */
05590  *      int code; /* Return code */
05591  *      printf("\n%s: Example Rx server process\n\n", pn); 
05592  *      if (argc >2) { 
05593  *              printf("Usage: rxdemo [PortToUse]"); 
05594  *              exit(1); 
05595  *      } 
05596  *      if (argc > 1) 
05597  *              demoUDPPort = atoi(argv[1]); 
05598  *      else 
05599  *              demoUDPPort = RXDEMO_SERVER_PORT; 
05600  * 
05601  *      /* Initialize the Rx facility, telling it the UDP port number this 
05602  *      * server will use for its single service.  */
05603  * 
05604  *      printf("Listening on UDP port %d\n", demoUDPPort); 
05605  *      code = rx_Init(demoUDPPort); 
05606  *      if (code) { 
05607  *              printf("**      Error calling rx_Init(); code is %d\n", code); 
05608  *              exit(1); 
05609  *      } 
05610  * \endcode
05611  *  
05612  * \par
05613  * A security object specific to the server side of an Rx conversation is
05614  * created in the next code fragment. As with the client side of the code, a
05615  * "null" server security object, namely one that does not perform any
05616  * authentication at all, is constructed with the rxnull
05617  * NewServerSecurityObject() function. 
05618  *  
05619  * \code
05620  *      /* Create a single server-side security object. In this case, the 
05621  *      * null security object (for unauthenticated connections) will be used 
05622  *      * to control security on connections made to this server. */
05623  * 
05624  *      securityObjects[RXDEMO_NULL_SECOBJ_IDX] =
05625  *      rxnull_NewServerSecurityObject(); 
05626  *      if (securityObjects[RXDEMO_NULL_SECOBJ_IDX] == (struct rx_securityClass
05627  *      *) 0) { 
05628  *              printf("** Can't create server-side security object\n"); 
05629  *              exit(1); 
05630  *      } 
05631  * \endcode
05632  * 
05633  * \par
05634  * The rxdemo server program is now in a position to create the desired Rx
05635  * service, primed to recognize exactly those interface calls defined in
05636  * rxdemo.xg. This is accomplished by calling the rx NewService() library
05637  * routine, passing it the security object created above and the generated Rx
05638  * dispatcher routine. 
05639  * 
05640  * \code 
05641  * /* Instantiate a single sample service. The rxgen-generated procedure 
05642  * * called to dispatch requests is passed in (RXDEMO_ExecuteRequest).  */
05643  * 
05644  *      rxServiceP = rx_NewService(     0, 
05645  *                                      RXDEMO_SERVICE_ID, 
05646  *                                      "rxdemo", 
05647  *                                      securityObjects, 
05648  *                                      1, 
05649  *                                      RXDEMO_ExecuteRequest
05650  *                              ); 
05651  *      if (rxServiceP == (struct rx_service *) 0) { 
05652  *              printf("** Can't create Rx service\n"); 
05653  *              exit(1); 
05654  *      } 
05655  * \endcode
05656  * 
05657  * \par
05658  * The final step in this main routine is to activate servicing of calls to the
05659  * exported Rx interface. Specifically, the proper number of threads are
05660  * created to handle incoming interface calls. Since we are passing a non-zero
05661  * argument to the rx StartServer() call, the main program will itself begin
05662  * executing the server thread loop, never returning from the rx StartServer()
05663  * call. The print statement afterwards should never be executed, and its
05664  * presence represents some level of paranoia, useful for debugging
05665  * malfunctioning thread packages. 
05666  * 
05667  * \code 
05668  *      /* Start up Rx services, donating this thread to the server pool. */
05669  *      rx_StartServer(1); 
05670  *      /* We should never return from the previous call. */
05671  *      printf("** rx_StartServer() returned!!\n"); exit(1); 
05672  * } /* Main */
05673  * \endcode
05674  * 
05675  * \par
05676  * Following the main procedure are the functions called by the
05677  * automatically-generated routines in the rxdemo.ss.c module to implement the
05678  * specific routines defined in the Rx interface. 
05679  * \par
05680  * The first to be defined is the RXDEMO Add() function. The arguments for this
05681  * routine are exactly as they appear in the interface definition, with the
05682  * exception of the very first. The a rxCallP parameter is a pointer to the Rx
05683  * structure describing the call on which this function was activated. All
05684  * user-supplied routines implementing an interface function are required to
05685  * have a pointer to this structure as their first parameter. Other than
05686  * printing out the fact that it has been called and which operands it
05687  * received, all that RXDEMO Add() does is compute the sum and place it in the
05688  * output parameter. 
05689  * \par
05690  * Since RXDEMO Add() is a non-streamed function, with all data travelling
05691  * through the set of parameters, this is all that needs to be done. To mark a
05692  * successful completion, RXDEMO Add() returns zero, which is passed all the
05693  * way through to the RPC's client. 
05694  * 
05695  * \code
05696  * int RXDEMO_Add(a_rxCallP, a_operand1, a_operand2, a_resultP) 
05697  *      struct rx_call *a_rxCallP; 
05698  * int a_operand1, a_operand2; 
05699  * int *a_resultP; 
05700  * { /* RXDEMO_Add */
05701  *      printf("\t[Handling call to RXDEMO_Add(%d, %d)]\n", 
05702  *              a_operand1, a_operand2); 
05703  *      *a_resultP = a_operand1 + a_operand2; 
05704  *      return(0); 
05705  * } /* RXDEMO_Add */
05706  * \endcode
05707  * 
05708  * \par
05709  * The next and final interface routine defined in this file is RXDEMO
05710  * Getfile(). Declared as a split function in the interface file, RXDEMO
05711  * Getfile() is an example of a streamed Rx call. As with RXDEMO Add(), the
05712  * initial parameter is required to be a pointer to the Rx call structure with
05713  * which this routine is associated, Similarly, the other parameters appear
05714  * exactly as in the interface definition, and are handled identically. 
05715  * \par
05716  * The difference between RXDEMO Add() and RXDEMO Getfile() is in the use of
05717  * the rx Write() library routine by RXDEMO Getfile() to feed the desired
05718  * file's data directly into the Rx call stream. This is an example of the use
05719  * of the a rxCallP argument, providing all the information necessary to
05720  * support the rx Write() activity. 
05721  * \par
05722  * The RXDEMO Getfile() function begins by printing out the fact that it's been
05723  * called and the name of the requested file. It will then attempt to open the
05724  * requested file and stat it to determine its size. 
05725  * 
05726  * \code
05727  * int RXDEMO_Getfile(a_rxCallP, a_nameToRead, a_resultP) 
05728  *      struct rx_call *a_rxCallP; 
05729  * char *a_nameToRead; 
05730  * int *a_resultP; 
05731  * { /* RXDEMO_Getfile */
05732  *      struct stat fileStat; /* Stat structure for file */
05733  *      long fileBytes; /* Size of file in bytes */
05734  *      long nbofileBytes; /* file bytes in network byte order */
05735  *      int code; /* Return code */
05736  *      int bytesReallyWritten; /* Bytes written on Rx channel */
05737  *      int bytesToSend; /* Num bytes to read & send this time */
05738  *      int maxBytesToSend; /* Max num bytes to read & send ever */
05739  *      int bytesRead; /* Num bytes read from file */
05740  *      char buff[RXDEMO_BUFF_BYTES+1]; /* Read buffer */
05741  *      int fd; /* file descriptor */
05742  *      maxBytesToSend = RXDEMO_BUFF_BYTES; 
05743  *      printf("\t[Handling call to RXDEMO_Getfile(%s)]\n", a_nameToRead); 
05744  *      fd = open(a_nameToRead, O_RDONLY, 0444); 
05745  *      if (fd <0) { 
05746  *              printf("\t\t[**Can't open file '%s']\n", a_nameToRead); 
05747  *              *a_resultP = RXDEMO_CODE_CANT_OPEN; 
05748  *              return(1); 
05749  *      } else 
05750  *              printf("\t\t[file opened]\n"); 
05751  *      /* Stat the file to find out how big it is. */
05752  *      code = fstat(fd, &fileStat); 
05753  *      if (code) { 
05754  *              a_resultP = RXDEMO_CODE_CANT_STAT; 
05755  *              printf("\t\t[file closed]\n"); 
05756  *              close(fd); 
05757  *              return(1); 
05758  *      } 
05759  *      fileBytes = fileStat.st_size; 
05760  *      printf("\t\t[file has %d bytes]\n", fileBytes); 
05761  * \endcode
05762  * 
05763  * \par
05764  * Only standard unix operations have been used so far. Now that the file is
05765  * open, we must first feed the size of the file, in bytes, to the Rx call
05766  * stream. With this information, the client code can then determine how many
05767  * bytes will follow on the stream. As with all data that flows through an Rx
05768  * stream, the longword containing the file size, in bytes, must be converted
05769  * to network byte order before being sent. This insures that the recipient may
05770  * properly interpret the streamed information, regardless of its memory
05771  * architecture. 
05772  * 
05773  * \code
05774  *      nbofileBytes = htonl(fileBytes); 
05775  *      /* Write out the size of the file to the Rx call. */
05776  *      bytesReallyWritten = rx_Write(a_rxCallP, &nbofileBytes, sizeof(long)); 
05777  *      if (bytesReallyWritten != sizeof(long)) { 
05778  *              printf("** %d bytes written instead of %d for file length\n", 
05779  *              bytesReallyWritten, sizeof(long)); 
05780  *              *a_resultP = RXDEMO_CODE_WRITE_ERROR; 
05781  *              printf("\t\t[file closed]\n"); 
05782  *              close(fd); 
05783  *              return(1); 
05784  *      } 
05785  * \endcode
05786  * 
05787  * \par
05788  * Once the number of file bytes has been placed in the stream, the RXDEMO
05789  * Getfile() routine runs a loop, reading a buffer's worth of the file and then
05790  * inserting that buffer of file data into the Rx stream at each iteration.
05791  * This loop executes until all of the file's bytes have been shipped. Notice
05792  * there is no special end-of-file character or marker inserted into the
05793  * stream. 
05794  * \par
05795  * The body of the loop checks for both unix read() and rx Write errors. If
05796  * there is a problem reading from the unix file into the transfer buffer, it
05797  * is reflected back to the client by setting the error return parameter
05798  * appropriately. Specifically, an individual unix read() operation could fail
05799  * to return the desired number of bytes. Problems with rx Write() are handled
05800  * similarly. All errors discovered in the loop result in the file being
05801  * closed, and RXDEMO Getfile() exiting with a non-zero return value. 
05802  *  
05803  * \code
05804  *      /* Write out the contents of the file, one buffer at a time.  */
05805  *      while (fileBytes > 0) {  
05806  *              /* figure out the number of bytes to 
05807  *              * read (and send) this time.  */
05808  *              bytesToSend = (fileBytes > maxBytesToSend ? 
05809  *                              maxBytesToSend : fileBytes); 
05810  *              bytesRead = read(fd, buff, bytesToSend); 
05811  *              if (bytesRead != bytesToSend) { 
05812  *                      printf("Read %d instead of %d bytes from the file\n", 
05813  *                              bytesRead, bytesToSend); 
05814  *                      *a_resultP = RXDEMO_CODE_WRITE_ERROR; 
05815  *                      printf("\t\t[file closed]\n"); 
05816  *                      close(fd); 
05817  *                      return(1); 
05818  *              } 
05819  *              /* Go ahead and send them. */
05820  *              bytesReallyWritten = rx_Write(a_rxCallP, buff, bytesToSend); 
05821  *              if (bytesReallyWritten != bytesToSend) { 
05822  *                      printf("%d file bytes written instead of %d\n", 
05823  *                              bytesReallyWritten, bytesToSend); 
05824  *                      *a_resultP = RXDEMO_CODE_WRITE_ERROR; 
05825  *                      printf("\t\t[file closed]\n"); 
05826  *                      close(fd); 
05827  *                      return(1); 
05828  *              } 
05829  *              /* Update the number of bytes left to go. */
05830  *              fileBytes -= bytesToSend; 
05831  *      } /* Write out the file to our caller */
05832  * \endcode
05833  * 
05834  * \par
05835  * Once all of the file's bytes have been shipped to the remote client, all
05836  * that remains to be done is to close the file and return successfully. 
05837  * 
05838  * \code
05839  *      /* Close the file, then return happily. */
05840  *      *a_resultP = RXDEMO_CODE_SUCCESS; 
05841  *      printf("\t\t[file closed]\n"); 
05842  *      close(fd); 
05843  *      return(0); 
05844  * } /* RXDEMO_Getfile */
05845  * \endcode
05846  * 
05847  *      \subsection sec6-2-4 Section 6.2.4: Makefile 
05848  * 
05849  * \par
05850  * This file directs the compilation and installation of the rxdemo code. It
05851  * specifies the locations of libraries, include files, sources, and such tools
05852  * as Rxgen and install, which strips symbol tables from executables and places
05853  * them in their target directories. This Makefile demostrates cross-cell
05854  * software development, with the rxdemo sources residing in the
05855  * grand.central.org cell and the AFS include files and libraries accessed from
05856  * their locations in the transarc.com cell. 
05857  * \par
05858  * In order to produce and install the rxdemo server and rxdemo client
05859  * binaries, the system target should be specified on the command line when
05860  * invoking make: 
05861  * \code
05862  *              make system 
05863  * \endcode
05864  * \par
05865  * A note of caution is in order concerning generation of the rxdemo binaries.
05866  * While tools exist that deposit the results of all compilations to other
05867  * (architecture-specific) directories, and thus facilitate multiple
05868  * simultaneous builds across a variety of machine architectures (e.g.,
05869  * Transarc's washtool), the assumption is made here that compilations will
05870  * take place directly in the directory containing all the rxdemo sources.
05871  * Thus, a user will have to execute a make clean command to remove all
05872  * machine-specific object, library, and executable files before compiling for
05873  * a different architecture. Note, though, that the binaries are installed into
05874  * a directory specifically reserved for the current machine type.
05875  * Specifically, the final pathname component of the ${PROJ DIR}bin
05876  * installation target is really a symbolic link to ${PROJ DIR}.bin/@sys. 
05877  * \par
05878  * Two libraries are needed to support the rxdemo code. The first is obvious,
05879  * namely the Rx librx.a library. The second is the lightweight thread package
05880  * library, liblwp.a, which implements all the threading operations that must
05881  * be performed. The include files are taken from the unix /usr/include
05882  * directory, along with various AFS-specific directories. Note that for
05883  * portability reasons, this Makefile only contains fully-qualified AFS
05884  * pathnames and "standard" unix pathnames (such as /usr/include). 
05885  * 
05886  * \code
05887  * /*#=======================================================================# 
05888  * # The United States Government has rights in this work pursuant # # to 
05889  * contract no. MDA972-90-C-0036 between the United States Defense # # Advanced 
05890  * Research Projects Agency and Transarc Corporation. # # # # (C) Copyright
05891  * 1991 
05892  * Transarc Corporation # # # # Redistribution and use in source and binary
05893  * forms 
05894  * are permitted # # provided that: (1) source distributions retain this entire 
05895  * copy-# # right notice and comment, and (2) distributions including binaries
05896  * # 
05897  * # display the following acknowledgement: # # # # ''This product includes 
05898  * software developed by Transarc # # Corporation and its contributors'' # # #
05899  * # 
05900  * in the documentation or other materials mentioning features or # # use of
05901  * this 
05902  * software. Neither the name of Transarc nor the names # # of its contributors 
05903  * may be used to endorse or promote products # # derived from this software 
05904  * without specific prior written # # permission. # # # # THIS SOFTWARE IS 
05905  * PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED # # WARRANTIES,
05906  * INCLUDING, 
05907  * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # # MERCHANTABILITY AND
05908  * FITNESS 
05909  * FOR A PARTICULAR PURPOSE. # 
05910  * #=======================================================================# */
05911  * 
05912  * SHELL = /bin/sh 
05913  * TOOL_CELL = grand.central.org 
05914  * AFS_INCLIB_CELL = transarc.com 
05915  * USR_CONTRIB = /afs/${TOOL_CELL}/darpa/usr/contrib/ 
05916  * PROJ_DIR = ${USR_CONTRIB}.site/grand.central.org/rxdemo/ 
05917  * AFS_INCLIB_DIR = /afs/${AFS_INCLIB_CELL}/afs/dest/ 
05918  * RXGEN = ${AFS_INCLIB_DIR}bin/rxgen 
05919  * INSTALL = ${AFS_INCLIB_DIR}bin/install 
05920  * LIBS =       ${AFS_INCLIB_DIR}lib/librx.a \ ${AFS_INCLIB_DIR}lib/liblwp.a 
05921  * CFLAGS = -g \ 
05922  *      -I. \ 
05923  *      -I${AFS_INCLIB_DIR}include \ 
05924  *      -I${AFS_INCLIB_DIR}include/afs \ 
05925  *      -I${AFS_INCLIB_DIR} \ 
05926  *      -I/usr/include 
05927  * 
05928  * system: install 
05929  * 
05930  * install: all 
05931  *      ${INSTALL} rxdemo_client 
05932  *      ${PROJ_DIR}bin 
05933  *      ${INSTALL} rxdemo_server 
05934  *      ${PROJ_DIR}bin 
05935  * 
05936  * all: rxdemo_client rxdemo_server 
05937  * 
05938  * rxdemo_client: rxdemo_client.o ${LIBS} rxdemo.cs.o ${CC} ${CFLAGS} 
05939  *              -o rxdemo_client rxdemo_client.o rxdemo.cs.o ${LIBS} 
05940  * 
05941  * rxdemo_server: rxdemo_server.o rxdemo.ss.o ${LIBS} ${CC} ${CFLAGS} 
05942  *              -o rxdemo_server rxdemo_server.o rxdemo.ss.o ${LIBS} 
05943  * 
05944  * rxdemo_client.o: rxdemo.h 
05945  * 
05946  * rxdemo_server.o: rxdemo.h 
05947  * 
05948  * rxdemo.cs.c rxdemo.ss.c rxdemo.er.c rxdemo.h: rxdemo.xg rxgen rxdemo.xg 
05949  * 
05950  * clean: rm -f *.o rxdemo.cs.c rxdemo.ss.c rxdemo.xdr.c rxdemo.h \ 
05951  *              rxdemo_client rxdemo_server core 
05952  * \endcode
05953  * 
05954  *      \section sec6-3 Section 6.3: Computer-Generated files 
05955  * 
05956  * \par
05957  * The four human-generated files described above provide all the information
05958  * necessary to construct the full set of modules to support the rxdemo example
05959  * application. This section describes those routines that are generated from
05960  * the base set by Rxgen, filling out the code required to implement an Rx
05961  * service. 
05962  * 
05963  *      \subsection sec6-3-1 Client-Side Routines: rxdemo.cs.c 
05964  * 
05965  * \par
05966  * The rxdemo client.c program, described in Section 6.2.2, calls the
05967  * client-side stub routines contained in this module in order to make rxdemo
05968  * RPCs. Basically, these client-side stubs are responsible for creating new Rx
05969  * calls on the given connection parameter and then marshalling and
05970  * unmarshalling the rest of the interface call parameters. The IN and INOUT
05971  * arguments, namely those that are to be delivered to the server-side code
05972  * implementing the call, must be packaged in network byte order and shipped
05973  * along the given Rx call. The return parameters, namely those objects
05974  * declared as INOUT and OUT, must be fetched from the server side of the
05975  * associated Rx call, put back in host byte order, and inserted into the
05976  * appropriate parameter variables. 
05977  * \par
05978  * The first part of rxdemo.cs.c echoes the definitions appearing in the
05979  * rxdemo.xg interface file, and also #includes another Rxgen-generated file,
05980  * rxdemo.h. 
05981  * 
05982  * \code
05983  * /*======================================================================% 
05984  * * % THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED % 
05985  * * % WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF % 
05986  * * % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. % 
05987  * * %====================================================================== */
05988  * /* Machine generated file --Do NOT edit */
05989  * 
05990  * #include "rxdemo.h" 
05991  * #define RXDEMO_CODE_WRITE_ERROR 4 
05992  * 
05993  * #include <rx/rx.h>
05994  * #include <rx/rx_null.h>
05995  * #define RXDEMO_SERVER_PORT 8000 /* Service port to advertise */
05996  * #define RXDEMO_SERVICE_PORT 0 /* User server's port */
05997  * #define RXDEMO_SERVICE_ID 4 /* Service ID */
05998  * #define RXDEMO_NULL_SECOBJ_IDX 0 /* Index of null security object */
05999  * #define RXDEMO_MAX 3
06000  * #define RXDEMO_MIN 2
06001  * #define RXDEMO_NULL 0 
06002  * #define RXDEMO_NAME_MAX_CHARS 64
06003  * #define RXDEMO_BUFF_BYTES 512
06004  * #define RXDEMO_CODE_SUCCESS 0
06005  * #define RXDEMO_CODE_CANT_OPEN 1
06006  * #define RXDEMO_CODE_CANT_STAT 2
06007  * #define RXDEMO_CODE_CANT_READ 3
06008  * #define RXDEMO_CODE_WRITE_ERROR 4
06009  * \endcode
06010  * 
06011  * \par
06012  * The next code fragment defines the client-side stub for the RXDEMO Add()
06013  * routine, called by the rxdemo client program to execute the associated RPC. 
06014  * 
06015  * \code
06016  * int RXDEMO_Add(z_conn, a, b, result) register struct rx_connection *z_conn; 
06017  * int a, b; 
06018  * int * result; 
06019  * { 
06020  *      struct rx_call *z_call = rx_NewCall(z_conn); 
06021  *      static int z_op = 1; 
06022  *      int z_result; 
06023  *      XDR z_xdrs; 
06024  *      xdrrx_create(&z_xdrs, z_call, XDR_ENCODE); 
06025  *      /* Marshal the arguments */
06026  *      if ((!xdr_int(&z_xdrs, &z_op)) 
06027  *                      || (!xdr_int(&z_xdrs, &a)) 
06028  *                      || (!xdr_int(&z_xdrs, &b))) { 
06029  *              z_result = RXGEN_CC_MARSHAL; 
06030  *              goto fail; 
06031  *      } 
06032  *      /* Un-marshal the reply arguments */
06033  *      z_xdrs.x_op = XDR_DECODE; 
06034  *      if ((!xdr_int(&z_xdrs, result))) { 
06035  *              z_result = RXGEN_CC_UNMARSHAL; 
06036  *              goto fail; 
06037  *      } 
06038  *      z_result = RXGEN_SUCCESS; 
06039  *      fail: return rx_EndCall(z_call, z_result); 
06040  * } 
06041  * \endcode
06042  * 
06043  * \par
06044  * The very first operation performed by RXDEMO Add() occurs in the local
06045  * variable declarations, where z call is set to point to the structure
06046  * describing a newly-created Rx call on the given connection. An XDR
06047  * structure, z xdrs, is then created for the given Rx call with xdrrx
06048  * create(). This XDR object is used to deliver the proper arguments, in
06049  * network byte order, to the matching server stub code. Three calls to xdr
06050  * int() follow, which insert the appropriate Rx opcode and the two operands
06051  * into the Rx call. With the IN arguments thus transmitted, RXDEMO Add()
06052  * prepares to pull the value of the single OUT parameter. The z xdrs XDR
06053  * structure, originally set to XDR ENCODE objects, is now reset to XDR DECODE
06054  * to convert further items received into host byte order. Once the return
06055  * parameter promised by the function is retrieved, RXDEMO Add() returns
06056  * successfully. 
06057  * \par
06058  * Should any failure occur in passing the parameters to and from the server
06059  * side of the call, the branch to fail will invoke Rx EndCall(), which advises
06060  * the server that the call has come to a premature end (see Section 5.6.6 for
06061  * full details on rx EndCall() and the meaning of its return value). 
06062  * \par
06063  * The next client-side stub appearing in this generated file handles the
06064  * delivery of the IN parameters for StartRXDEMO Getfile(). It operates
06065  * identically as the RXDEMO Add() stub routine in this respect, except that it
06066  * does not attempt to retrieve the OUT parameter. Since this is a streamed
06067  * call, the number of bytes that will be placed on the Rx stream cannot be
06068  * determined at compile time, and must be handled explicitly by rxdemo
06069  * client.c. 
06070  * 
06071  * \code
06072  * int StartRXDEMO_Getfile(z_call, a_nameToRead) 
06073  *      register struct rx_call *z_call; 
06074  * char * a_nameToRead; 
06075  * { 
06076  *      static int z_op = 2; 
06077  *      int z_result; 
06078  *      XDR z_xdrs; 
06079  *      xdrrx_create(&z_xdrs, z_call, XDR_ENCODE); 
06080  *      /* Marshal the arguments */
06081  *      if ((!xdr_int(&z_xdrs, &z_op)) || (!xdr_string(&z_xdrs, &a_nameToRead,
06082  *      RXDEMO_NAME_MAX_CHARS))) { 
06083  *              z_result = RXGEN_CC_MARSHAL; 
06084  *              goto fail; 
06085  *      } 
06086  *      z_result = RXGEN_SUCCESS; 
06087  *      fail: return z_result; 
06088  * } 
06089  * \endcode
06090  * 
06091  * \par
06092  * The final stub routine appearing in this generated file, EndRXDEMO
06093  * Getfile(), handles the case where rxdemo client.c has already successfully
06094  * recovered the unbounded streamed data appearing on the call, and then simply
06095  * has to fetch the OUT parameter. This routine behaves identially to the
06096  * latter portion of RXDEMO Getfile(). 
06097  * 
06098  * \code
06099  * int EndRXDEMO_Getfile(z_call, a_result) 
06100  *      register struct rx_call *z_call; 
06101  * int * a_result; 
06102  * { 
06103  *      int z_result; 
06104  *      XDR z_xdrs; 
06105  *      /* Un-marshal the reply arguments */
06106  *      xdrrx_create(&z_xdrs, z_call, XDR_DECODE); 
06107  *      if ((!xdr_int(&z_xdrs, a_result))) { 
06108  *              z_result = RXGEN_CC_UNMARSHAL; 
06109  *              goto fail; 
06110  *      } 
06111  *      z_result = RXGEN_SUCCESS; fail: 
06112  *      return z_result; 
06113  * } 
06114  * \endcode
06115  * 
06116  *      \subsection sec6-3-2 Server-Side Routines: rxdemo.ss.c 
06117  * 
06118  * \par
06119  * This generated file provides the core components required to implement the
06120  * server side of the rxdemo RPC service. Included in this file is the
06121  * generated dispatcher routine, RXDEMO ExecuteRequest(), which the rx
06122  * NewService() invocation in rxdemo server.c uses to construct the body of
06123  * each listener thread's loop. Also included are the server-side stubs to
06124  * handle marshalling and unmarshalling of parameters for each defined RPC call
06125  * (i.e., RXDEMO Add() and RXDEMO Getfile()). These stubs are called by RXDEMO
06126  * ExecuteRequest(). The routine to be called by RXDEMO ExecuteRequest()
06127  * depends on the opcode received, which appears as the very first longword in
06128  * the call data. 
06129  * \par
06130  * As usual, the first fragment is copyright information followed by the body
06131  * of the definitions from the interface file. 
06132  * 
06133  * \code
06134  * /*======================================================================% 
06135  * % Edward R. Zayas % % Transarc Corporation % % % % % % The United States 
06136  * Government has rights in this work pursuant % % to contract no. 
06137  * MDA972-90-C-0036 between the United States Defense % % Advanced Research 
06138  * Projects Agency and Transarc Corporation. % % % % (C) Copyright 1991 
06139  * Transarc Corporation % % % % Redistribution and use in source and binary 
06140  * forms are permitted % % provided that: (1) source distributions retain 
06141  * this entire copy¬% % right notice and comment, and (2) distributions 
06142  * including binaries % 
06143  * %====================================================================== */
06144  * /* Machine generated file --Do NOT edit */
06145  * 
06146  * #include "rxdemo.h" 
06147  * #include <rx/rx.h> 
06148  * #include <rx/rx_null.h> 
06149  * #define RXDEMO_SERVER_PORT 8000 /* Service port to advertise */
06150  * #define RXDEMO_SERVICE_PORT 0 /* User server's port */
06151  * #define RXDEMO_SERVICE_ID 4 /* Service ID */
06152  * #define RXDEMO_NULL_SECOBJ_IDX 0 /* Index of null security object */
06153  * #define RXDEMO_MAX 3 
06154  * #define RXDEMO_MIN 2 
06155  * #define RXDEMO_NULL 0 
06156  * #define RXDEMO_NAME_MAX_CHARS 64 
06157  * #define RXDEMO_BUFF_BYTES 512 
06158  * #define RXDEMO_CODE_SUCCESS 0 
06159  * #define RXDEMO_CODE_CANT_OPEN 1 
06160  * #define RXDEMO_CODE_CANT_STAT 2 
06161  * #define RXDEMO_CODE_CANT_READ 3 
06162  * #define RXDEMO_CODE_WRITE_ERROR 4 
06163  * \endcode
06164  * 
06165  * \par
06166  * After this preamble, the first server-side stub appears. This RXDEMO Add()
06167  * routine is basically the inverse of the RXDEMO Add() client-side stub
06168  * defined in rxdemo.cs.c. Its job is to unmarshall the IN parameters for the
06169  * call, invoke the "true" server-side RXDEMO Add() routine (defined in rxdemo
06170  * server.c), and then package and ship the OUT parameter. Being so similar to
06171  * the client-side RXDEMO Add(), no further discussion is offered here. 
06172  * 
06173  * \code
06174  * long _RXDEMO_Add(z_call, z_xdrs) 
06175  *      struct rx_call *z_call; 
06176  * XDR *z_xdrs; 
06177  * { 
06178  *      long z_result; 
06179  *      int a, b; 
06180  *      int result; 
06181  *      if ((!xdr_int(z_xdrs, &a)) || (!xdr_int(z_xdrs, &b))) 
06182  *      { 
06183  *              z_result = RXGEN_SS_UNMARSHAL; 
06184  *              goto fail; 
06185  *      } 
06186  *      z_result = RXDEMO_Add(z_call, a, b, &result); 
06187  *      z_xdrs->x_op = XDR_ENCODE; 
06188  *      if ((!xdr_int(z_xdrs, &result))) 
06189  *              z_result = RXGEN_SS_MARSHAL; 
06190  *      fail: return z_result; 
06191  * } 
06192  * \endcode
06193  * 
06194  * \par
06195  * The second server-side stub, RXDEMO Getfile(), appears next. It operates
06196  * identically to RXDEMO Add(), first unmarshalling the IN arguments, then
06197  * invoking the routine that actually performs the server-side work for the
06198  * call, then finishing up by returning the OUT parameters. 
06199  * 
06200  * \code
06201  * long _RXDEMO_Getfile(z_call, z_xdrs) 
06202  *      struct rx_call *z_call; 
06203  * XDR *z_xdrs; 
06204  * { 
06205  *      long z_result; 
06206  *      char * a_nameToRead=(char *)0; 
06207  *      int a_result; 
06208  *      if ((!xdr_string(z_xdrs, &a_nameToRead, RXDEMO_NAME_MAX_CHARS))) { 
06209  *              z_result = RXGEN_SS_UNMARSHAL; 
06210  *              goto fail; 
06211  *      } 
06212  *      z_result = RXDEMO_Getfile(z_call, a_nameToRead, &a_result); 
06213  *      z_xdrs->x_op = XDR_ENCODE; 
06214  *      if ((!xdr_int(z_xdrs, &a_result))) 
06215  *              z_result = RXGEN_SS_MARSHAL; 
06216  *      fail: z_xdrs->x_op = XDR_FREE; 
06217  *      if (!xdr_string(z_xdrs, &a_nameToRead, RXDEMO_NAME_MAX_CHARS)) 
06218  *              goto fail1; 
06219  *      return z_result; 
06220  *      fail1: return RXGEN_SS_XDRFREE; 
06221  * } 
06222  * \endcode
06223  * 
06224  * \par
06225  * The next portion of the automatically generated server-side module sets up
06226  * the dispatcher routine for incoming Rx calls. The above stub routines are
06227  * placed into an array in opcode order. 
06228  * 
06229  * \code
06230  * long _RXDEMO_Add(); 
06231  * long _RXDEMO_Getfile(); 
06232  * static long (*StubProcsArray0[])() = {_RXDEMO_Add, _RXDEMO_Getfile}; 
06233  * \endcode
06234  * 
06235  * \par
06236  * The dispatcher routine itself, RXDEMO ExecuteRequest, appears next. This is
06237  * the function provided to the rx NewService() call in rxdemo server.c, and it
06238  * is used as the body of each listener thread's service loop. When activated,
06239  * it decodes the first longword in the given Rx call, which contains the
06240  * opcode. It then dispatches the call based on this opcode, invoking the
06241  * appropriate server-side stub as organized in the StubProcsArray. 
06242  * 
06243  * \code
06244  * RXDEMO_ExecuteRequest(z_call) 
06245  *      register struct rx_call *z_call; 
06246  * { 
06247  *      int op; 
06248  *      XDR z_xdrs; 
06249  *      long z_result; 
06250  *      xdrrx_create(&z_xdrs, z_call, XDR_DECODE); 
06251  *      if (!xdr_int(&z_xdrs, &op)) 
06252  *              z_result = RXGEN_DECODE; 
06253  *      else if (op < RXDEMO_LOWEST_OPCODE || op > RXDEMO_HIGHEST_OPCODE) 
06254  *              z_result = RXGEN_OPCODE; 
06255  *      else 
06256  *              z_result = (*StubProcsArray0[op -RXDEMO_LOWEST_OPCODE])(z_call,
06257  *              &z_xdrs); 
06258  *      return z_result; 
06259  * } 
06260  * \endcode
06261  * 
06262  *      \subsection sec6-3-3 External Data Rep file: rxdemo.xdr.c 
06263  * 
06264  * \par
06265  * This file is created to provide the special routines needed to map any
06266  * user-defined structures appearing as Rx arguments into and out of network
06267  * byte order. Again, all on-thewire data appears in network byte order,
06268  * insuring proper communication between servers and clients with different
06269  * memory organizations. 
06270  * \par
06271  * Since the rxdemo example application does not define any special structures
06272  * to pass as arguments in its calls, this generated file contains only the set
06273  * of definitions appearing in the interface file. In general, though, should
06274  * the user define a struct xyz and use it as a parameter to an RPC function,
06275  * this file would contain a routine named xdr xyz(), which converted the
06276  * structure field-by-field to and from network byte order. 
06277  * 
06278  * \code
06279  * /*======================================================================% 
06280  * %% % in the documentation or other materials mentioning features or % % 
06281  * use of this software. Neither the name of Transarc nor the names % % of 
06282  * its contributors may be used to endorse or promote products % % derived 
06283  * from this software without specific prior written % % permission. % % % 
06284  * % THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED % 
06285  * % WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF % 
06286  * % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. % 
06287  * % Edward R. Zayas % Transarc Corporation % % % The United States 
06288  * Government has rights in this work pursuant to contract no. 
06289  * MDA972-90-C-0036 between the United States Defense % Advanced Research 
06290  * Projects Agency and Transarc Corporation. % % (C) Copyright 1991 Transarc 
06291  * Corporation % % Redistribution and use in source and binary forms are 
06292  * permitted % % provided that: (1) source distributions retain this entire 
06293  * copy¬ % right notice and comment, and (2) distributions including binaries 
06294  * % % display the following acknowledgement: % % % % ``This product includes 
06295  * software developed by Transarc % % Corporation and its contributors'' % 
06296  * %====================================================================== */
06297  * /* Machine generated file --Do NOT edit */
06298  * 
06299  * #include "rxdemo.h" 
06300  * #include <rx/rx.h> 
06301  * #include <rx/rx_null.h> 
06302  * #define RXDEMO_SERVER_PORT 8000 /* Service port to advertise */
06303  * #define RXDEMO_SERVICE_PORT 0 /* User server's port */
06304  * #define RXDEMO_SERVICE_ID 4 /* Service ID */
06305  * #define RXDEMO_NULL_SECOBJ_IDX 0 /* Index of null security object */
06306  * #define RXDEMO_MAX 3 
06307  * #define RXDEMO_MIN 2 
06308  * #define RXDEMO_NULL 0 
06309  * #define RXDEMO_NAME_MAX_CHARS 64 
06310  * #define RXDEMO_BUFF_BYTES 512 
06311  * #define RXDEMO_CODE_SUCCESS 0 
06312  * #define RXDEMO_CODE_CANT_OPEN 1 
06313  * #define RXDEMO_CODE_CANT_STAT 2 
06314  * #define RXDEMO_CODE_CANT_READ 3 
06315  * #define RXDEMO_CODE_WRITE_ERROR 4 
06316  * \endcode
06317  * 
06318  *      \section sec6-4 Section 6.4: Sample Output 
06319  * 
06320  * \par
06321  * This section contains the output generated by running the example rxdemo
06322  * server and rxdemo client programs described above. The server end was run on
06323  * a machine named Apollo, and the client program was run on a machine named
06324  * Bigtime. 
06325  * \par
06326  * The server program on Apollo was started as follows: 
06327  * \li apollo: rxdemo_server 
06328  * \li rxdemo_server: Example Rx server process 
06329  * \li Listening on UDP port 8000 
06330  * \par
06331  * At this point, rxdemo server has initialized its Rx module and started up
06332  * its listener LWPs, which are sleeping on the arrival of an RPC from any
06333  * rxdemo client. 
06334  * \par
06335  * The client portion was then started on Bigtime: 
06336  * \n bigtime: rxdemo_client apollo 
06337  * \n rxdemo: Example Rx client process 
06338  * \n Connecting to Rx server on 'apollo', IP address 0x1acf37c0, UDP port 8000 
06339  * \n ---> Connected. Asking server to add 1 and 2: Reported sum is 3 
06340  * \par
06341  * The command line instructs rxdemo client to connect to the rxdemo server on
06342  * host apollo and to use the standard port defined for this service. It
06343  * reports on the successful Rx connection establishment, and immediately
06344  * executes an rxdemo Add(1, 2) RPC. It reports that the sum was successfully
06345  * received. When the RPC request arrived at the server and was dispatched by
06346  * the rxdemo server code, it printed out the following line: 
06347  * \n [Handling call to RXDEMO_Add(1, 2)] 
06348  * \par
06349  * Next, rxdemo client prompts for the name of the file to read from the rxdemo
06350  * server. It is told to fetch the Makefile for the Rx demo directory. The
06351  * server is executing in the same directory in which it was compiled, so an
06352  * absolute name for the Makefile is not required. The client echoes the
06353  * following: 
06354  * \n Name of file to read from server: Makefile Setting up an Rx call for
06355  * RXDEMO_Getfile...done 
06356  * \par
06357  * As with the rxdemo Add() call, rxdemo server receives this RPC, and prints
06358  * out the following information: 
06359  * \li [Handling call to RXDEMO_Getfile(Makefile)] 
06360  * \li [file opened] 
06361  * \li [file has 2450 bytes] 
06362  * \li [file closed] 
06363  * \par
06364  * It successfully opens the named file, and reports on its size in bytes. The
06365  * rxdemo server program then executes the streamed portion of the rxdemo
06366  * Getfile call, and when complete, indicates that the file has been closed.
06367  * Meanwhile, rxdemo client prints out the reported size of the file, follows
06368  * it with the file's contents, then advises that the test run has completed: 
06369  * 
06370  * \code
06371  * [file contents (2450 bytes) fetched over the Rx call appear below] 
06372  * 
06373  * /*#=======================================================================# 
06374  * # The United States Government has rights in this work pursuant # # to 
06375  * contract no. MDA972-90-C-0036 between the United States Defense # # Advanced 
06376  * Research Projects Agency and Transarc Corporation. # # # # (C) Copyright 
06377  * 1991 Transarc Corporation # # # # Redistribution and use in source and 
06378  * binary forms are permitted # # provided that: (1) source distributions 
06379  * retain this entire copy-# # right notice and comment, and (2) distributions 
06380  * including binaries # # display the following acknowledgement: # # # # ''This 
06381  * product includes software developed by Transarc # # Corporation and its 
06382  * contributors'' # # # # in the documentation or other materials mentioning 
06383  * features or # # use of this software. Neither the name of Transarc nor the 
06384  * names # # of its contributors may be used to endorse or promote products # 
06385  * # derived from this software without specific prior written # # permission. 
06386  * # # # # THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED 
06387  * # # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # # 
06388  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # 
06389  * #=======================================================================# */
06390  * 
06391  * SHELL = /bin/sh 
06392  * TOOL_CELL = grand.central.org 
06393  * AFS_INCLIB_CELL = transarc.com 
06394  * USR_CONTRIB = /afs/${TOOL_CELL}/darpa/usr/contrib/ 
06395  * PROJ_DIR = ${USR_CONTRIB}.site/grand.central.org/rxdemo/ 
06396  * AFS_INCLIB_DIR = /afs/${AFS_INCLIB_CELL}/afs/dest/ 
06397  * RXGEN = ${AFS_INCLIB_DIR}bin/rxgen 
06398  * INSTALL = ${AFS_INCLIB_DIR}bin/install 
06399  * LIBS =       ${AFS_INCLIB_DIR}lib/librx.a \ ${AFS_INCLIB_DIR}lib/liblwp.a 
06400  *      CFLAGS = -g \ 
06401  *      -I. \ 
06402  *      -I${AFS_INCLIB_DIR}include \ 
06403  *      -I${AFS_INCLIB_DIR}include/afs \ 
06404  *      -I${AFS_INCLIB_DIR} \ 
06405  *      -I/usr/include 
06406  * 
06407  * system: install 
06408  * 
06409  * install: all 
06410  *      ${INSTALL} rxdemo_client ${PROJ_DIR}bin 
06411  *      ${INSTALL} rxdemo_server ${PROJ_DIR}bin 
06412  * 
06413  * all: rxdemo_client rxdemo_server 
06414  * 
06415  * rxdemo_client: rxdemo_client.o ${LIBS} rxdemo.cs.o ${CC} ${CFLAGS} 
06416  *      -o rxdemo_client rxdemo_client.o rxdemo.cs.o ${LIBS} 
06417  * 
06418  * rxdemo_server: rxdemo_server.o rxdemo.ss.o ${LIBS} ${CC} ${CFLAGS} 
06419  *      -o rxdemo_server rxdemo_server.o rxdemo.ss.o ${LIBS} 
06420  * 
06421  * rxdemo_client.o: rxdemo.h 
06422  * 
06423  * rxdemo_server.o: rxdemo.h 
06424  * 
06425  * rxdemo.cs.c rxdemo.ss.c rxdemo.er.c rxdemo.h: rxdemo.xg rxgen rxdemo.xg 
06426  * 
06427  * clean: rm -f *.o rxdemo.cs.c rxdemo.ss.c rxdemo.xdr.c rxdemo.h \ 
06428  *      rxdemo_client rxdemo_server core 
06429  * 
06430  * [End of file data] 
06431  * rxdemo complete. 
06432  * \endcode
06433  * 
06434  * \par
06435  * The rxdemo server program continues to run after handling these calls,
06436  * offering its services to any other callers. It can be killed by sending it
06437  * an interrupt signal using Control-C (or whatever mapping has been set up for
06438  * the shell's interrupt character). 
06439  * 
06440  *      \section Bibliography Bibliography 
06441  * 
06442  * \li [1] Transarc Corporation. AFS 3.0 System Administrator's Guide,
06443  * F-30-0-D102, Pittsburgh, PA, April 1990. 
06444  * \li [2] S.P. Miller, B.C. Neuman, J.I. Schiller, J.H. Saltzer. Kerberos
06445  * Authentication and Authorization System, Project Athena Technical Plan,
06446  * Section E.2.1, M.I.T., December 1987. 
06447  * \li [3] Bill         Bryant. Designing an Authentication System: a Dialogue
06448  * in Four Scenes, Project Athena internal document, M.I.T, draft of 8 February
06449  * 1988. 
06450  * \li [4] S. R. Kleinman.      Vnodes: An Architecture for Multiple file
06451  * System Types in Sun UNIX, Conference Proceedings, 1986 Summer Usenix
06452  * Technical Conference, pp. 238-247, El Toro, CA, 1986. 
06453  *
06454  * @}
06455  */
 All Data Structures Files Functions Variables