This section has some protocol design rules that protocol writers should follow in order to develop ``well-behaved'' protocols that interact properly with other protocols with which they might be composed.
At system boot time, the x-kernel calls xCreateProtocol for each protocol configured into the kernel (see section 12). xCreateProtocol, in turn, calls the protocol's init routine, where for a protocol named `yap', this initialization routine must be named `yap_init'. Generally, this routine does the following work.
void yap_init(self) XObj self; { /* fill in protocol-specific operations */ self->open = yap_open; self->demux = yap_demux; . . . /* create and initialize protocol-specific state, including maps */ self->state = xMalloc( sizeof(struct yap_state) ); . . . /* get handle for, and register with, lower-level protocol */ llp = xGetDown(self, 0)); partInit(&part, 1); partPush(part, ANY_HOST, 0); xOpenEnable(self, self, llp, &part); }
The operations xOpen, xOpenEnable, and xOpenDisable
take two high-level protocols, hlpRcv and hlpType. hlpRcv is the protocol to which the new lower session should route
incoming messages. The lower protocol uses hlpRcv as the hlp
argument to xCreateSessn. The lower protocol uses hlpType
to determine which messages the new session should handle. For
example, when ethOpen is called with IP as the hlpType,
ETH knows that the new session will deal with packets that have the IP
ethernet type. The lower protocol typically determines the number
that corresponds to hlpType by using it in a call to relProtNum (see section 13.1.)
Most protocols use their self pointer as both hlpRcv and
hlpType when making these calls, though virtual protocols (see
below) are the exception.
Although the x-kernel defines a single interface for all protocols, not
all protocols are created equal. Our experience is that protocols can
be classified into different categories, which we call realms. Chances
are, any protocol you write falls into one of the following realms. In
some cases, the realm into which a protocol falls defines both a restricted
subset of the interface that the protocol implements, and the set of
protocols with which it may be composed.
Most protocols-e.g., protocols like IP, TCP, and UDP-fall
in this category. The x-kernel supports asynchronous protocols through
the use of xPush, xPop and xDemux operations.
Asynchronous protocols are typically symmetric in the sense that the
protocols' sessions process both incoming and outgoing messages.
While it seems possible for asynchronous protocols to have asymmetric
sessions (a given session can handle only incoming or outgoing
messages, but not both), we have thus far been able to make all our
asynchronous protocols symmetric, and we strongly encourage such
designs. Knowing that any low-level protocols one may use are
symmetric enhances one's ability to compose protocols and makes
implementing a given protocol much easier.
These are RPC protocols. They are typically asymmetric in the
sense that client-side sessions and the server-side sessions are quite
different. The x-kernel explicitly supports synchronous/asymmetric
sessions through the use of xCall, xCallPop and xCallDemux. Since synchronous protocols are asymmetric, xCall
is used on the client side and xCallPop and xCallDeumx are
used on the server side.
Note that some protocols lie on the boundary between the synchronous
and asynchronous realms. For example, a protocol that implements RPC
(as opposed to one that uses it) probably looks asynchronous from the
bottom (i.e., lower level protocols call its xPop routine),
but synchronous from above (i.e., higher level protocols call its
xCall routine).
These protocols support neither a xPush/xPop nor a
xCall/xCallPop interface. Typically, only control operations
may be performed on these protocols. ARP and ICMP fall into this
category.
Anchor protocols sit either at the top or the bottom of a protocol
stack and provide an interface between the x-kernel and the system in
which the x-kernel is embedded. Top-level anchor protocols look like an
x-kernel protocol from the bottom, but provide an Application Programmer
Interface to the x-kernel (see appendix C.) Bottom-level anchor
protocols (e.g., device drivers) look like a protocol from the top,
but typically interface with the lower levels of the surrounding
system or with network hardware.
Writing anchor protocols involves careful synchronization of
external threads with x-kernel threads and objects. See section
7.5.3.
Virtual protocols occupy places in the protocol (and sometimes the
session) graphs, but they neither produce nor interpret network headers.
They typically make decisions about how messages should be routed
through the session graph based on participants in xOpen or on
properties of messages, such as size.
The xOpen, xOpenEnable, and xOpenDisable routines of
virtual protocols differ from those of conventional protocols. A
virtual protocol's implementation of xOpen, for example, will
usually make an xOpen call to its lower protocols using the hlpType that was passed into the virtual protocol, but using its self pointer as hlpRcv. This allows arbitrary chains of
virtual protocols to insert their sessions between the upper and lower
conventional sessions while still passing ``type information'' from
the upper protocol to the lower protocol.
Note that virtual protocols can be either synchronous (support the
xCall/xCallPop/xCallDemux interface) or asynchronous
(support the xPush/xPop/xDemux interface).
Protocol Realms
Asynchronous Protocols
Synchronous Protocols
Control Protocols
Anchor Protocols
Virtual Protocols
Next: Default Operations
Up: Uniform Protocol Interface
Previous: Utility Operations