%
% x-kernel v3.3
%
% Copyright (c) 1996,1993,1991,1990  Arizona Board of Regents
%

\section{Participant Library}\label{part_lib}
\index{participants}

Participant lists identify members of a session and are used for
opening connections.  An upper protocol interested in establishing a
connection constructs a participant list and passes it to the lower
protocol as a parameter of an open routine.  The lower protocol then
extracts information from the participant list, possibly passing the
participant list on to its own lower protocol.

Each participant in the list contains a participant address stack,
designed to facilitate a general method of communicating encapsulated
address information between protocol layers.  By using pointers to
address information, one layer can pass address information through a
lower layer without having the lower layer manipulate the address
information at all, not even by copying.  The address information for
each participant is kept as a stack of {\var void *} pointers to
address components and the lengths of each component.  The component
pointers are pushed or popped onto the stack by utility functions.

\subsection{Type Definitions}\label{part_type_defs}

The participant data structure is used to collect addressing
information for opening connections.  A participant list is defined to
be an array of type {\var Part}, and a {\var PartStack} is the main
field in a single {\var Part}.  The fields of these structures should
not be directly accessed by the protocol developer.

\var
\begin{tabbing}
xxxx \= xxxx \= xxx \= xxxxx \= \kill
\>\#define PART\_MAX\_STACK 20\\
\\
\>typedef struct \{\\
\>\>struct \{\\
\>\>\>void    \>*ptr;\\
\>\>\>int     \>len;\\
\>\>\} arr[PART\_MAX\_STACK];\\
\>\>int       \>\>top;\\
\>\} PartStack;\\
\\
\>typedef struct \{\\
\>\>int       \>\>len;\\
\>\>PartStack \>\>stack; \\
\>\} Part;
\end{tabbing}
\rm

\subsection{Participant List Operations}\label{part_list_ops}

The following operations provide a convenient interface that hides the
{\var PartStack} data structure.  However, the fact that a participant
list is really an array of type {\var Part} is visible to the
programmer.

\subsubsection{partInit}\label{partInit}
\index{partInit}
Initialize participant list {\var participants} of {\var number} entries.
\medskip

{\var void partInit(Part *participants, int number)}
\medskip

\subsubsection{partPush}\label{partPush}
\index{partPush}

Pushes address {\var addr}, pointing to {\var length} bytes, onto the
stack of {\var participant}.  A length of 0 indicates a
``special-value'' pointer (e.g., {\var ANY\_HOST}) whose value as a
pointer should be preserved across protection boundaries (and not
dereferenced).  See Section~\ref{part_usage}.
\medskip

{\var void partPush(Part participant, void *addr, int length)}
\medskip

\subsubsection{partPop}\label{partPop}
\index{partPop}

Pops an address off the stack of {\var participant}. Returns NULL if
there are no more elements on the stack.
\medskip

{\var void *partPop(Part participant)}
\medskip

\subsubsection{partStackTopByteLen}\label{partStackTopByteLen}
\index{partStackTopByteLen}

Returns the number of bytes pointed to by the top element of the stack
of {\var participants}.  Returns 0 if the stack element was pushed with
a length field of zero (i.e., a ``special-value'' pointer).  Returns
-1 if there are no elements on the stack.
\medskip

{\var int partStackTopByteLen(Part participants)}
\medskip

\subsubsection{partLength}\label{partLength}
\index{partLength}

Returns the number of entries in participant list {\var participants}.
\medskip

{\var int partLength(Part *participants)}
\medskip

\subsection{Relative Protocol Numbers}\label{relProtNum}
\index{protocol numbers}

Participant lists are used for passing addressing information between
protocols.  An additional problem is how a high-level protocol
identifies {\it itself} to a low-level protocol.  In most
conventional protocols, a low-level protocol uses a {\it relative
protocol number} to identify the protocols above it; e.g., IP
identifies UDP with protocol number 17 and TCP as protocol number 6.
However, protocols that have been especially designed to use the {\xk}
use an {\it absolute} addressing scheme.

The {\xk} reconciles these two approaches by maintaining a table of
relative protocol numbers.  (See Section~\ref{protocol_tables} for the
format of this table.)  Rather than embed protocol numbers in the
protocol source code, protocols learn the protocol numbers of
protocols above them by querying this table using the following
operation.\index{relProtNum}
\medskip

{\var ProtId relProtNum(Protl hlp, Protl llp)}
\medskip

\noindent
This operation returns the protocol number of the high-level protocol
relative to the low-level protocol, or -1 if no such binding has been
configured in the protocol tables.  This number will have to be cast
into the appropriate type; e.g., an unsigned short by the ETH protocol
and an unsigned char by IP.

Two other operations provide an alternate query interface. The operation
\index{protTblGetId}
\medskip

{\var ProtId protTblGetId(char *protocolName)}
\medskip

\noindent
returns the protocol ID number for the named protocol. This ID number
can be used with
\index{relProtNumById}
\medskip

{\var ProtId relProtNumById(ProtId hlpId, Protl llp)}
\medskip

\noindent
which has the same semantics as {\var relProtNum}, except that the
high-level protocol is identified by its ID number rather than by the
{\var Protl} object itself.  This interface can be useful when you
need to determine relative protocol numbers, but do not have the
appropriate {\var Protl} objects in scope.

\subsection{Usage Rules}\label{part_usage}
\index{protocol number usage}

By convention, active participant lists (those used in {\var xOpen})
have the remote participant(s) first, followed by an optional local
participant.  The local participant can often be omitted, in which
case the protocol tries to use a reasonable default.  For example, a
UDP participant contains a UDP port and an IP host.  If the local
participant is missing from an active participant list, UDP selects an
available port for the local participant.

In some cases, it is necessary to specify part of the information in a
participant, but it is convenient to allow the lower protocol to
``fill in'' the rest.  To allow this flexibility, the constant
pointers {\var ANY\_HOST} and {\var ANY\_PORT} can be used to specify
``wildcard'' values.  For example, if you want to open UDP with a
specific local port, but don't care which local host number is used,
you could construct a local participant with the specific local port
but with the pointer {\var ANY\_HOST} pushed on the stack.  The
protocol that interprets the host part of the participant stack could
then choose a reasonable default.  Similarly, the pointer {\var
ANY\_PORT} could be used for protocols that use ports on their stacks.
Protocols that support wildcards indicate this in their manual page.

Figure~\ref{fig:part} illustrates how a protocol that is about to
invoke {\var xOpen} on a low-level protocol initializes the
participant list, and then how the low-level protocol extracts that
information from the participant list.

\begin{figure}
\caption{Using the participant list \label{fig:part}}
\begin{verbatim}
/* protocol invoking xOpen on low-level protocol llp */
{
    Part p[2];

    ...
    /* set participant addresses before calling low-level protocol's open */
    partInit(p, 2);
    partPush(p[0], &ServerHostAddr, sizeof(IPhost));  /* remote */
    partPush(p[0], &ServerPort, sizeof(long));        /* remote */
    partPush(p[1], ANY_HOST, 0);                      /* local  */
    partPush(p[1], &ClientPort, sizeof(long));        /* local  */
    xOpen(self, self, llp, p);
    ...
}

llp_open(Protl self, Protl hlp, Protl hlpType, Part *p)
{
    /* get participant addresses within low-level protocol's open */
    remoteport = (long *)partPop(p[0]);
    localport  = (long *)partPop(p[1]);
    ...
}
\end{verbatim}
\end{figure}

Notice in this example how the high-level protocol pushes two items (a
host address and a port number) onto each participant's address stack,
but the low-level protocol pops off only one item.  This is because
the low-level protocol does not interpret the first item (the host
address); it just passes it on to {\var its} low-level protocol.  Also
note that when using participants that have been passed from other
protocols, you must keep in mind that the address pointers may be
valid only for the duration of the current subroutine.  Data that is
needed beyond this time should be explicitly copied into static
storage.  In addition, because the participant structure is passed by
reference in the {\var xOpen} call, the caller should consider the
contents invalid after the return.

In general, passive participant lists (those used in {\var
xOpenEnable}) contain only the local participant, with no remote
participant specified.  This indicates that an upper protocol is
willing to accept connections from any remote participant, as long as
the connection is addressed to the correct local participant.
Protocols which provide different semantics for their openEnable
participants will indicate this explicitly in their manual page in
the Appendix.
