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