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

\section{Control Operations}\label{control_ops}
\index{GETMYHOST}
\index{GETMYHOSTCOUNT}
\index{GETMAXPACKET}
\index{GETOPTPACKET}
\index{GETOPTPACKET}
\index{RESOLVE}
\index{RRESOLVE}
\index{GETPEERHOST}
\index{GETPEERHOSTCOUNT}
\index{FREERESOURCES}
\index{SETNONBLOCKINGIO}

Control operations are used to perform arbitrary operations on
protocols and sessions, via the {\var xControlProtl} and 
{\var xControlSessn} operations described in Sections \ref{xControlProtl}
and \ref{xControlSessn}.  {\var xControlProtl} and 
{\var xControlSessn} return an integer that indicates the length in bytes of
the information which was written into the buffer, or -1 to indicate
an error.

All implementations of control operations should check the length
field before reading or writing the buffer, returning -1 if the buffer
is too small.  The {\var checkLen}({\var actualLength}, 
{\var expectedLength}) macro can be used for this.

The {\var opcode} field in the control operations specifies the
operation to be performed on the protocol or session.  There are two
``classes'' of operations: standard ones that may be implemented by
more than one protocol, and protocol-specific ones.

\subsection{Standard Control Operations}\label{stand_ops}

\subsubsection{Operations Common to Both Protocols and Sessions}\label{protl_sessn_ops}

These operations can be performed on both protocols and sessions.

\begin{quote}
{\var GETMYHOST, GETMYHOSTCOUNT}

\begin{quote}
When used on a protocol, {\var GETMYHOST} asks for all possible host
addresses for the local host.  When used on a session, 
{\var GETMYHOST} asks for the local host addresses actually being used on
the connection.  If the buffer is too small for all of the hosts,
{\var GETMYHOST} will write as many hosts as the buffer allows 
({\var GETMYHOST} with a buffer large enough to hold one host will return 
the most common or default host). {\var GETMYHOSTCOUNT} asks for the
number of hosts which could be returned by {\var GETMYHOST}.
\end{quote}
\medskip

{\var GETMAXPACKET, GETOPTPACKET}

\begin{quote}
Treats the buffer as a pointer to an integer and sets it to the length
of the longest message that the protocol can deliver 
({\var GETMAXPACKET}) or the length of the longest message that can be
delivered without fragmentation ({\var GETOPTPACKET}).  A protocol
typically implements this operation by querying its lower protocol and
then subtracting its header length.

\smallskip
Although {\var GETMAXPACKET} and {\var GETOPTPACKET} can be performed
on protocols, it is preferable to use them on sessions, since
different sessions of the same protocol may return different values.
\end{quote}
\medskip

{\var RESOLVE, RRESOLVE}

\begin{quote}
These operations map high-level addresses into low-level addresses
({\var RESOLVE}) and vice versa ({\var RRESOLVE}).
\end{quote}
\end{quote}

\subsubsection{Session-Only Operations}\label{sessn_ops}

These operations can be performed on sessions only.

\begin{quote}
{\var GETPEERHOST, GETPEERHOSTCOUNT}

\begin{quote}
{\var GETPEERHOST} returns the host addresses of all peers of a
session.  It is an error to submit a buffer that is too small for all
of the peer hosts, and -1 will be returned.  {\var GETPEERHOSTCOUNT}
asks for the number of hosts which will be returned by 
{\var GETPEERHOST}.
\end{quote}

{\var GETMYPROTO, GETPEERPROTO}

\begin{quote}
Treats the buffer as a pointer to a long and sets it to the local or
remote ``protocol number'' of the session.  For example, UDP returns
the local UDP port from a {\var GETMYPROTO} operation.
\end{quote}

{\var FREERESOURCES}

\begin{quote}
Treats the buffer as a pointer to an {\var XkHandle}.  This value is
interpreted as the result of a previous {\var xPush} and frees the
resources associated with that message.
\end{quote}

{\var SETNONBLOCKINGIO}

\begin{quote}
Treats the buffer as a pointer to an {\var int} (non-zero == TRUE).
This operation is interpreted by sessions which do output buffering.
Such sessions may block threads executing an {\var xPush} until
sufficient buffer space is available to hold the outgoing message.  If
{\var SETNONBLOCKINGIO} with value TRUE is performed on such a
session, a thread which would normally block in such a situation
returns with an {\var XMSG\_ERR\_WOULDBLOCK} message handle instead.
\end{quote}
\end{quote}

\subsection{Protocol-Specific Control Operations}\label{protl_ops}

While all protocols support the control operations enumerated above,
it is not uncommon for any given protocol to also support a collection
of protocol-specific opcodes. These opcodes can be associated with
either both the protocol's session and protocol objects, or with just
its session objects. These opcodes are defined relative to an
identifier that has been assigned to each protocol (in the file 
{\var include/upi.h}).  For example, the protocol ARP has been assigned the
id {\var ARP\_CTL}.  Individual opcodes are then defined (in 
{\var arp.h}) as:

\var
\begin{tabbing}
xxxx \= xxxxxxxxxxxxxxxxxxxxxxxxxxxx \= \kill
\>\#define ARP\_INSTALL      \>(ARP\_CTL*MAXOPS + 0)\\
\>\#define ARP\_IPINTERFACES \>(ARP\_CTL*MAXOPS + 1)\\
\>\#define ARP\_IPADDRS      \>(ARP\_CTL*MAXOPS + 2)
\end{tabbing}
\rm

\noindent
This scheme is used to ensure that all control opcodes are unique.  By
convention, protocol-specific opcodes defined by protocol XYZ are
prefixed with {\var XYZ\_}.  Also, until an identifier has been
assigned to a protocol being written (i.e., until it's been defined in
{\var upi.h}), a set of temporary ids, {\var TMP0\_CTL}, 
{\var TMP1\_CTL}, ... {\var TMP4\_CTL}, can be used.

Protocol-specific control operations are described in the manual page
for each protocol in Appendix~\ref{prot_specs}.

\subsection{Forwarding Control Operations}\label{forward_ops}

There are several situations where a protocol or session may not be
prepared to handle a control operation.  For example, a
protocol-specific control operation may be sent through several
intermediate protocols in a graph before it reaches a protocol that
understands the operation.  Because of this, protocols and sessions
should be prepared to forward control operations which they don't
understand or can't satisfy to their lower protocols/sessions.
