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

\section{Message Library}\label{msg_lib}
\index{messages}

The message library provides a set of efficient, high-level operations
for manipulating messages.  The underlying data structure that
implements messages is optimized for fragmentation/reassembly, and for
adding/stripping headers.  Protocol programmers should manipulate
messages only with the operations documented here.

\subsection{Type Definitions}\label{msg_type_defs}

Messages, which are the {\xk}'s abstract data type for network
packets, are defined by the {\var Msg} structure. Loosely speaking,
this structure consists of a tree of buffers that collectively hold
the bytes contained in the message. The leftmost buffer in this tree
is called the {\it header stack} because it holds the headers that are
pushed onto the front of a packet.  This data structure is fairly
complex, however, and so we do not describe it in this document. The
interested reader is referred to a companion report
\cite{Message}. In addition, there is a {\var MsgWalk} structure
that is used by {\var msgWalkNext} to traverse the buffers that make
up a message (see Section~\ref{msgWalkNext}). This structure is also
defined in \cite{Message}. The fields of neither structure should not
be directly accessed by the protocol developer.

\subsection{Constructor/Destructor Operations}\label{cons_des_ops}

These operations are used to create and destroy messages.  Many of
them are, for example, used by device drivers and system call code
that has to incorporate a data buffer into an {\xk} message.

Messages that are newly created ``own'' the header stack, and can
write into that space efficiently using {\var msgPush}.  See
Section~\ref{msg_usage} for more information about message stacks.

\subsubsection{msgConstructEmpty}\label{msgConstructEmpty}
\index{msgConstructEmpty}

Initializes a message structure with a data length set to zero.  The
user must provide a pointer to valid memory.
\medskip

{\var void msgConstructEmpty(Msg *message)}

\subsubsection{msgConstructBuffer}\label{msgConstructBuffer}
\index{msgConstructBuffer}

Copies data from a user buffer ({\var buffer}) into an uninitialized
message structure.  The message data area, of size {\var length}, is
allocated and a copy is performed.  This constructor is used when the
data buffer already exists.  Use {\var msgConstructAllocate} when you
will not have the opportunity to fill the buffer until after it has
been created.
\medskip

{\var void msgConstructBuffer(Msg *message, void *buffer, int length)}

\subsubsection{msgConstructAllocate}\label{msgConstructAllocate}
\index{msgConstructAllocate}

Allocates a data area of size {\var length} and associates the area
with the uninitialized message structure {\var message}.  A pointer to
the data area is returned.  A device driver might use this
constructor, handing the pointer to the device as a place to put down
an incoming packet.
\medskip

{\var char *msgConstructAllocate(Msg *message, int length)}
\medskip

\subsubsection{msgConstructCopy}\label{msgConstructCopy}
\index{msgConstructCopy}

The uninitialized message {\var message} will refer to the same data
as {\var original\_msg}.  No data is copied.  See also {\var
msgAssign}.
\medskip

{\var void msgConstructCopy(Msg *message, Msg *original\_msg)}

\subsubsection{msgConstructInplace}\label{msgConstructInplace}
\index{msgConstructInplace}

An uninitialized message structure is constructed with a direct
reference to the buffer specified.  A function appropriate for freeing
the buffer when the message is destroyed must be provided.  The 
{\var msgConstructInplace} function is recommended only for limited use,
such as within device drivers.
\medskip

{\var void msgConstructInplace(\=Msg *message, char *buffer, int length, MsgCIPFreeFunc freefunc)}

{\var typedef void *MsgCIPFreeFunc)(void *, int)};

\subsubsection{msgDestroy}\label{msgDestroy}
\index{msgDestroy}

Logically frees {\var message}.  Data portions of the deallocated
message are freed if there are no other outstanding references to
them.
\medskip

{\var void msgDestroy(Msg *message)}

\subsubsection{msgRefresh}\label{msgRefresh}
\index{msgRefresh}

Allocates a data area of size {\var length} and associates the area
with the initialized message structure {\var message}.  This is
equivalent to (but can be faster than) doing a {\var msgDestroy} to
{\var message}, followed by a {\var msgConstructAllocate}.  This
function should be used only when {\var message} is valid.
\medskip

{\var char *msgRefresh(Msg *message, int length)}
\medskip

\subsubsection{msgAssign}\label{msgAssign}
\index{msgAssign}

The assignment of {\var msg\_2} to {\var msg\_1} means that 
{\var msg\_1} will refer to the same data that {\var msg\_2} currently
points to.  No data copying is involved.  This is equivalent to doing
a {\var msgDestroy} to {\var msg\_1}, followed by a {\var
msgConstructCopy}.  This function should be used only when both
messages are valid; copying to an uninitialized structure should be
done with {\var msgConstructCopy}.
\medskip

{\var void msgAssign(Msg *msg\_1, Msg *msg\_2)}
\medskip

\subsection{Manipulation Operations}\label{manipulation_ops}

Protocols manipulate messages (e.g., add and strip headers, fragment
and reassemble packets) using the following set of operations.

\subsubsection{msgLength}\label{msgLength}
\index{msgLength}

Returns the number of bytes of data in {\var message}.
\medskip

{\var int msgLength(Msg *message)}
\medskip

\subsubsection{msgTruncate}\label{msgTruncate}
\index{msgTruncate}

Truncates the data in {\var message} to the given length.  An attempt
to to reduce the length to less than zero will result in no change to
the message.  No storage is freed as a result of truncation.  This
operation is used to strip trailers from a message.
\medskip

{\var void msgTruncate(Msg *message, int newLength)}
\medskip

\subsubsection{msgBreak}\label{msgBreak}
\index{msgBreak}

Removes {\var length} bytes from the front of {\var original\_msg} and
assigns them to {\var fragment\_msg}.  No copying is done.  This
operation is used to fragment a message into smaller pieces.  Both
messages must be valid at the time of the call.
\medskip

{\var void msgBreak(Msg *original\_msg, Msg *fragment\_msg, int length)}
\medskip

\subsubsection{msgJoin}\label{msgJoin}
\index{msgJoin}

Assigns (in the same sense as {\var msgAssign}) to {\var new\_msg} the
concatenation of message {\var fragment1} to the front of {\var fragment2}.
This operation is used to reassemble fragments into a larger message.
The first argument must be a valid message.  The arguments need not
refer to distinct messages. One common use of {\var msgJoin} is to attach
a fragment to the end of a larger message, in which case the first two
arguments are the same (the larger message) and the third argument is
the fragment.
\medskip

{\var void msgJoin(Msg *new\_msg, Msg *fragment1, Msg *fragment2)}
\medskip

\subsubsection{msgPush}\label{msgPush}
\index{msgPush}

Used to prepend space for a header to the front of a message. Returns
a pointer to contiguous buffer of {\var length} bytes that is
logically attached to the front of {\var message}.  Typically, a
header is then copied into this buffer.
\medskip

{\var char *msgPush(Msg *message, int length)}
\medskip

\subsubsection{msgPop}\label{msgPop}
\index{msgPop}

Used to remove a header from the front of a message.  Returns a
pointer to a contiguous buffer of {\var length} bytes that contains
the data that was at the front of {\var message} and removes 
{\var length} bytes from the front of the message.
\medskip

{\var char *msgPop(Msg *message, int length)}
\medskip

\subsubsection{msgPeek}\label{msgPeek}
\index{msgPeek}

Used to examine a header at the front of a message.  Returns a pointer
to a contiguous buffer of {\var length} bytes that contains the data
at the front of {\var message}.  The message remains unchanged.
\medskip

{\var char *msgPeek(Msg *message, int length)}
\medskip

\subsubsection{msgDiscard}\label{msgDiscard}
\index{msgDiscard}

Used to remove and discard a header of length {\var length} from the
front of a message.  {\var msgDiscard} is faster than {\var msgPop}
since it doesn't have to worry about making the returned buffer
contiguous.
\medskip

{\var void msgDiscard(Msg *message, int length)}
\medskip

\subsubsection{msgSetAttr}\label{msgSetAttr}
\index{message attributes}
\index{msgSetAttr}

Associates an {\var attribute} of {\var length} bytes with {\var name}
and attaches it to message {\var message}.  Setting an attribute
overrides any previous attribute with the same name.  Message
attributes are used to communicate ancillary properties of messages
from a protocol to a session, or between protocols.

The only name supported at this time is {\var 0}.  Attempting to set
an attribute with another name will result in an {\var XK\_FAILURE}
return value.
\medskip

{\var XkReturn msgSetAttr(Msg *message, int name, void *attribute, int length)}
\medskip

\subsubsection{msgGetAttr}\label{msgGetAttr}
\index{msgGetAttr}

Retrieves an attribute previously attached to message {\var message}
with {\var name}.  If no attribute has been associated with {\var
name}, {\var 0} will be returned.
\medskip

{\var void *msgGetAttr(Msg *message, int name)}

\subsubsection{msgWalkInit}\label{msgWalkInit}
\index{msgWalkInit}

Intializes the context {\var cxt} for {\var message}, as required by
{\var msgWalk}.
\medskip

{\var void msgWalkInit(MsgWalk *cxt, Msg *message)}

\subsubsection{msgWalkNext}\label{msgWalkNext}
\index{msgWalk}

Walks the tree structure of buffers that hold the message data, and
returns a pointer to the next chunk of data in the message.  Also sets
{\var length} to the number of bytes in that chunk.  Argument 
{\var cxt} maintains the context for the message traversal, so that 
{\var msgWalk} knows how far through the tree it got on the last invocation.
\medskip

{\var char *msgWalkNext(MsgWalk *cxt, int *length)}
\medskip

\subsubsection{msgWalkDone}\label{msgWalkDone}
\index{msgWalkDone}

Destroys the context {\var cxt} used by {\var msgWalkNext}.
\medskip

{\var void msgCleanUp(Msg *message)}

\subsubsection{msgCleanUp}\label{msgCleanUp}
\index{msgCleanUp}

Frees unnecessary resources allocated to {\var message}.
\medskip

{\var void msgCleanUp(Msg *message)}

\subsubsection{msgShow}\label{msgShow}
\index{msgShow}

Shows information about {\var message}.  Only valid when compiling
in DEBUG mode.
\medskip

{\var void msgShow(Msg *message)}

\subsubsection{msgStats}\label{msgStats}
\index{msgStats}

Prints statistics about {\var message}.  Only valid when compiling
with OPTION\_MSG\_STATISTICS defined.
\medskip

{\var void msgStats(MsgWalk *message)}

\subsection{Usage Rules}\label{msg_usage}

The {\xk} coding conventions dictate that messages should be destroyed
by the same entity that originally constructed them.  Thus, the
ethernet driver is responsible for destroying messages after
successfully delivering them upward, and the top-level protocols that
interface to user functions should destroy messages that have been
successfully delivered to their destination.

\index{message validity}
When a protocol passes a message to an adjacent protocol (via 
{\var xPush}, {\var xDemux}, etc.) its view of the message becomes invalid.
The contents of the message after such an operation depend on which
lower headers were pushed onto it.  Should a protocol want to keep a
reference to the message (e.g., so it can later retransmit it) it must
explicitly save a copy using either the {\var msgAssign} or the 
{\var msgConstructCopy} operation before passing the message on to another
protocol.

Note that although a protocol which constructs a message invalidates
its view of the message by performing a UPI operation involving that
message, it is still responsible for destroying the message.

The stack ownership is a hidden variable in the message library
implementation that affects whether or not storage is automatically
allocated on {\var msgPush} operations.  The stack ownership is
affected by several message library operations, particularly 
{\var msgAssign, msgJoin, msgPeek}, and {\var msgConstructCopy}. The user
is referred to the source code for the details of the ownership rules.

Message attributes passed between protocols should consist of
exportable data, i.e., not pointers.  Adherence to this convention
will ensure that the protocol can be in used in a multi-address space
environment.
