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