summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2010-06-08 20:12:53 -0700
committerAlan Coopersmith <alan.coopersmith@oracle.com>2010-06-08 20:12:53 -0700
commit9b54f509832c50c1fac0edc0cb78e1a3454a56dc (patch)
treeac194e791e05a3fd2c7feedc4d4373b014001f84 /doc
parent1967c04c021a4cfd7b3cdd4efdc13610b4385a65 (diff)
downloadxorg-lib-libICE-9b54f509832c50c1fac0edc0cb78e1a3454a56dc.tar.gz
Move ICE protocol & API specs from xorg-docs module
For now, just checked in and included in dist tarballs, not processed into a usable format - same as it was in xorg-docs Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/ICElib.ms3400
-rw-r--r--doc/Makefile.am1
-rw-r--r--doc/ice.ms1878
3 files changed, 5279 insertions, 0 deletions
diff --git a/doc/ICElib.ms b/doc/ICElib.ms
new file mode 100644
index 0000000..0c35d60
--- /dev/null
+++ b/doc/ICElib.ms
@@ -0,0 +1,3400 @@
+.\" $Xorg: ICElib.ms,v 1.3 2000/08/17 19:42:09 cpqbld Exp $
+.\" $XdotOrg: xc/doc/specs/ICE/ICElib.ms,v 1.2 2004/04/23 18:42:16 eich Exp $
+.\"
+.\" Use tbl, -ms, and macros.t
+.\"
+.\" macro: start marker
+.de sM
+.ne 4
+.sp 1
+\\h'-0.3i'\\L'-1v'\\v'3p'\\l'1v'\\v'1v-3p'
+.sp -1
+..
+.\" macro: end marker
+.de eM
+.sp -1
+\\h'-0.3i'\\L'-1v'\\v'1v+4p'\\l'1v'\\v'-4p'
+.sp 1
+..
+.EH ''''
+.OH ''''
+.EF ''''
+.OF ''''
+.ad b
+.sp 10
+.TL
+\s+2\fBInter-Client Exchange Library\fP\s-2
+.sp
+Version 1.0
+.sp
+X Consortium Standard
+.sp
+X Version 11, Release 6.8
+.AU
+Ralph Mor
+.AI
+X Consortium
+.LP
+.DS C
+Copyright \(co 1993, 1994, 1996 X Consortium
+.DE
+.LP
+.sp 5
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the ``Software''), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+.LP
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+.LP
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+.LP
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+.sp 5
+X Window System is a trademark of The Open Group.
+.bp
+.EH '\fBInter-Client Exchange Library\fP''\fBX11, Release 6.8\fP'
+.OH '\fBInter-Client Exchange Library\fP''\fBX11, Release 6.8\fP'
+.bp 1
+.EF ''\- \\\\n(PN \-''
+.OF ''\- \\\\n(PN \-''
+.NH 1
+Overview of ICE
+.XS
+\*(SN Overview of ICE
+.XE
+.LP
+There are numerous possible inter-client protocols, with many similarities
+and common needs - authentication, version negotiation, byte
+order negotiation, and so on.
+The Inter-Client Exchange (ICE) protocol is intended to provide a framework
+for building such protocols, allowing them to make use of common negotiation
+mechanisms and to be multiplexed over a single transport connection.
+.NH 1
+The ICE Library - C Language Interface to ICE
+.XS
+\*(SN The ICE Library - C Language Interface to ICE
+.XE
+.LP
+A client that wishes to utilize ICE must first register the protocols it
+understands with the ICE library. Each protocol is dynamically assigned
+a major opcode ranging from 1-255 (two clients can use different
+major opcodes for the same protocol). The next step for the client is either
+to open a connection with another client or to wait for connections made
+by other clients. Authentication may be required. A client can both
+initiate connections with other clients and be
+waiting for clients to connect to itself (a nested session manager is an
+example). Once an ICE connection is established between the two clients, one
+of the clients needs to initiate a
+.PN ProtocolSetup
+in order to
+"activate" a given protocol. Once the other client accepts the
+.PN ProtocolSetup
+(once again, authentication may be required), the
+two clients are ready to start passing messages specific to that protocol to
+each other. Multiple protocols may be active on a single ICE connection.
+Clients are responsible for notifying the ICE library when a protocol is no
+longer active on an ICE connection, although ICE does not define how each
+subprotocol triggers a protocol shutdown.
+.LP
+The ICE library utilizes callbacks to process incoming messages. Using
+callbacks allows
+.PN ProtocolSetup
+messages and authentication to happen
+behind the scenes. An additional benefit is that messages never need
+to be buffered up by the library when the client blocks waiting for a
+particular message.
+.NH 1
+Intended Audience
+.XS
+\*(SN Intended Audience
+.XE
+.LP
+This document is intended primarily for implementors of protocol libraries
+layered on top of ICE. Typically, applications that wish to utilize ICE
+will make calls into individual protocol libraries rather than directly
+make calls into the ICE library. However, some applications will have to
+make some initial calls into the ICE library in order to accept ICE
+connections (for example, a session manager accepting connections from
+clients). But in general, protocol libraries should be designed to hide
+the inner details of ICE from applications.
+.NH 1
+Header Files and Library Name
+.XS
+\*(SN Header Files and Library Name
+.XE
+.LP
+The header file
+.Pn < X11/ICE/ICElib.h >
+defines all of the ICElib data structures and function prototypes.
+.PN ICElib.h
+includes the header file
+.Pn < X11/ICE/ICE.h >,
+which defines all of the ICElib constants.
+Protocol libraries that need to read and write messages should include
+the header file
+.Pn < X11/ICE/ICEmsg.h >.
+.LP
+Applications should link against ICElib using -lICE.
+.NH 1
+Note on Prefixes
+.XS
+\*(SN Note on Prefixes
+.XE
+.LP
+The following name prefixes are used in the library to distinguish between
+a client that initiates a
+.PN ProtocolSetup
+and a client that
+responds with a
+.PN ProtocolReply :
+.IP \(bu 5
+.PN IcePo
+\- Ice Protocol Originator
+.IP \(bu 5
+.PN IcePa
+\- Ice Protocol Acceptor
+.NH 1
+Protocol Registration
+.XS
+\*(SN Protocol Registration
+.XE
+.LP
+In order for two clients to exchange messages for a given protocol, each
+side must register the protocol with the ICE library. The purpose of
+registration is for each side to obtain a major opcode for the protocol
+and to provide callbacks for processing messages and handling authentication.
+There are two separate registration functions:
+.IP \(bu 5
+One to handle the side that does a
+.PN ProtocolSetup
+.IP \(bu 5
+One to handle the side that responds with a
+.PN ProtocolReply
+.LP
+It is recommended that protocol registration occur before the two clients
+establish an ICE connection. If protocol registration occurs after an
+ICE connection is created, there can be a brief interval of time in which
+a
+.PN ProtocolSetup
+is received, but the protocol is not registered.
+If it is not possible to register a protocol before the creation of an
+ICE connection, proper precautions should be taken to avoid the above race
+condition.
+.sp
+.LP
+The
+.PN IceRegisterForProtocolSetup
+function should be called for the client that initiates a
+.PN ProtocolSetup .
+.sM
+.FD 0
+int IceRegisterForProtocolSetup\^(\^\fIprotocol_name\fP, \fIvendor\fP\^, \
+\fIrelease\fP\^, \fIversion_count\fP\^, \fIversion_recs\fP\^,
+.br
+ \fIauth_count\fP\^, \fIauth_names\fP\^, \fIauth_procs\fP\^, \
+\fIio_error_proc\fP\^)
+.br
+ char *\fIprotocol_name\fP\^;
+.br
+ char *\fIvendor\fP\^;
+.br
+ char *\fIrelease\fP\^;
+.br
+ int \fIversion_count\fP\^;
+.br
+ IcePoVersionRec *\fIversion_recs\fP\^;
+.br
+ int \fIauth_count\fP\^;
+.br
+ char **\fIauth_names\fP\^;
+.br
+ IcePoAuthProc *\fIauth_procs\fP\^;
+.br
+ IceIOErrorProc \fIio_error_proc\fP\^;
+.FN
+.IP \fIprotocol_name\fP 1i
+A string specifying the name of the protocol to register.
+.IP \fIvendor\fP 1i
+A vendor string with semantics specified by the protocol.
+.IP \fIrelease\fP 1i
+A release string with semantics specified by the protocol.
+.IP \fIversion_count\fP 1i
+The number of different versions of the protocol supported.
+.IP \fIversion_recs\fP 1i
+List of versions and associated callbacks.
+.IP \fIauth_count\fP 1i
+The number of authentication methods supported.
+.IP \fIauth_names\fP 1i
+The list of authentication methods supported.
+.IP \fIauth_procs\fP 1i
+The list of authentication callbacks, one for each authentication method.
+.IP \fIio_error_proc\fP 1i
+IO error handler, or NULL.
+.LP
+.eM
+.PN IceRegisterForProtocolSetup
+returns the major opcode reserved or -1 if an error occurred. In order
+to actually activate the protocol, the
+.PN IceProtocolSetup
+function needs to be called with this major opcode. Once the protocol is
+activated, all messages for the protocol should be sent using this major
+opcode.
+.LP
+A protocol library may support multiple versions of the same protocol.
+The version_recs argument specifies a list of supported versions of the protocol,
+which are prioritized in decreasing order of preference.
+Each version record consists of a major and minor version of the protocol
+as well as a callback to be used for processing incoming messages.
+.LP
+.sM
+.Ds 0
+.TA .5i
+.ta .5i
+typedef struct {
+ int major_version;
+ int minor_version;
+ IcePoProcessMsgProc process_msg_proc;
+} IcePoVersionRec;
+.De
+.LP
+.eM
+The
+.PN IcePoProcessMsgProc
+callback is responsible for processing the set of messages that can be
+received by the client that initiated the
+.PN ProtocolSetup .
+For further information,
+see section 6.1, ``Callbacks for Processing Messages.''
+.LP
+Authentication may be required before the protocol can become active.
+The protocol library must register the authentication methods that it
+supports with the ICE library.
+The auth_names and auth_procs arguments are a list of authentication names
+and callbacks that are prioritized in decreasing order of preference.
+For information on the
+.PN IcePoAuthProc
+callback, see section 6.2, ``Authentication Methods.''
+.LP
+The
+.PN IceIOErrorProc
+callback is invoked if the ICE connection unexpectedly breaks.
+You should pass NULL for io_error_proc if not interested in being notified.
+For further information,
+see section 13, ``Error Handling.''
+.sp
+.LP
+The
+.PN IceRegisterForProtocolReply
+function should be called for the client that responds to a
+.PN ProtocolSetup
+with a
+.PN ProtocolReply .
+.sM
+.FD 0
+int IceRegisterForProtocolReply\^(\^\fIprotocol_name\fP, \fIvendor\fP\^, \fIrelease\fP\^, \fIversion_count\fP\^, \fIversion_recs\fP\^,
+.br
+ \fIauth_count\fP\^, \fIauth_names\fP\^, \fIauth_procs\fP\^, \fIhost_based_auth_proc\fP\^, \fIprotocol_setup_proc\fP\^,
+.br
+ \fIprotocol_activate_proc\fP\^, \fIio_error_proc\fP\^)
+.br
+ char *\fIprotocol_name\fP\^;
+.br
+ char *\fIvendor\fP\^;
+.br
+ char *\fIrelease\fP\^;
+.br
+ int \fIversion_count\fP\^;
+.br
+ IcePaVersionRec *\fIversion_recs\fP\^;
+.br
+ int \fIauth_count\fP\^;
+.br
+ char **\fIauth_names\fP\^;
+.br
+ IcePaAuthProc *\fIauth_procs\fP\^;
+.br
+ IceHostBasedAuthProc \fIhost_based_auth_proc\fP\^;
+.br
+ IceProtocolSetupProc \fIprotocol_setup_proc\fP\^;
+.br
+ IceProtocolActivateProc \fIprotocol_activate_proc\fP\^;
+.br
+ IceIOErrorProc \fIio_error_proc\fP\^;
+.FN
+.IP \fIprotocol_name\fP 1i
+A string specifying the name of the protocol to register.
+.IP \fIvendor\fP 1i
+A vendor string with semantics specified by the protocol.
+.IP \fIrelease\fP 1i
+A release string with semantics specified by the protocol.
+.IP \fIversion_count\fP 1i
+The number of different versions of the protocol supported.
+.IP \fIversion_recs\fP 1i
+List of versions and associated callbacks.
+.IP \fIauth_count\fP 1i
+The number of authentication methods supported.
+.IP \fIauth_names\fP 1i
+The list of authentication methods supported.
+.IP \fIauth_procs\fP 1i
+The list of authentication callbacks, one for each authentication method.
+.IP \fIhost_based_auth_proc\fP 1i
+Host based authentication callback.
+.IP \fIprotocol_setup_proc\fP 1i
+A callback to be invoked when authentication has succeeded for a
+.PN ProtocolSetup
+but before the
+.PN ProtocolReply
+is sent.
+.IP \fIprotocol_activate_proc\fP 1i
+A callback to be invoked after the
+.PN ProtocolReply
+is sent.
+.IP \fIio_error_proc\fP 1i
+IO error handler, or NULL.
+.LP
+.eM
+.PN IceRegisterForProtocolReply
+returns the major opcode reserved or -1 if an error occurred. The major
+opcode should be used in all subsequent messages sent for this protocol.
+.LP
+A protocol library may support multiple versions of the same protocol.
+The version_recs argument specifies a list of supported versions of the protocol,
+which are prioritized in decreasing order of preference.
+Each version record consists of a major and minor version of the protocol
+as well as a callback to be used for processing incoming messages.
+.LP
+.sM
+.Ds 0
+.TA .5i
+.ta .5i
+typedef struct {
+ int major_version;
+ int minor_version;
+ IcePaProcessMsgProc process_msg_proc;
+} IcePaVersionRec;
+.De
+.LP
+.eM
+The
+.PN IcePaProcessMsgProc
+callback is responsible for processing the set of messages that can be
+received by the client that accepted the
+.PN ProtocolSetup .
+For further information,
+see section 6.1, ``Callbacks for Processing Messages.''
+.LP
+Authentication may be required before the protocol can become active.
+The protocol library must register the authentication methods that it
+supports with the ICE library.
+The auth_names and auth_procs arguments are a list of authentication names
+and callbacks that are prioritized in decreasing order of preference.
+For information on the
+.PN IcePaAuthProc
+callback, see section 6.2, ``Authentication Methods.''
+.LP
+If authentication fails and the client attempting to initiate
+the
+.PN ProtocolSetup
+has not required authentication, the
+.PN IceHostBasedAuthProc
+callback is invoked with the host name of the originating client.
+If the callback returns
+.PN True ,
+the
+.PN ProtocolSetup
+will succeed, even though the original
+authentication failed.
+Note that authentication can effectively be disabled by registering an
+.PN IceHostBasedAuthProc ,
+which always returns
+.PN True .
+If no host based
+authentication is allowed, you should pass NULL for host_based_auth_proc.
+.LP
+.sM
+.FD 0
+typedef Bool (*IceHostBasedAuthProc) ();
+
+Bool HostBasedAuthProc\^(\^\fIhost_name\fP\^)
+.br
+ char *\fIhost_name\fP\^;
+.FN
+.IP \fIhost_name\fP 1i
+The host name of the client that sent the
+.PN ProtocolSetup .
+.LP
+.eM
+The host_name argument is a string of the form \fIprotocol\fP\^/\^\fIhostname\fP,
+where \fIprotocol\fP\^ is one of {tcp, decnet, local}.
+.LP
+Because
+.PN ProtocolSetup
+messages and authentication happen behind the scenes
+via callbacks, the protocol library needs some way of being notified when the
+.PN ProtocolSetup
+has completed.
+This occurs in two phases.
+In the first phase, the
+.PN IceProtocolSetupProc
+callback is invoked after authentication has
+successfully completed but before the ICE library sends a
+.PN ProtocolReply .
+Any resources required for this protocol should be allocated at this time.
+If the
+.PN IceProtocolSetupProc
+returns a successful status, the ICE library will
+send the
+.PN ProtocolReply
+and then invoke the
+.PN IceProtocolActivateProc
+callback. Otherwise, an error will be sent to the
+other client in response to the
+.PN ProtocolSetup .
+.LP
+The
+.PN IceProtocolActivateProc
+is an optional callback and should be registered only if the protocol
+library intends to generate a message immediately following the
+.PN ProtocolReply .
+You should pass NULL for protocol_activate_proc if not interested
+in this callback.
+.if t .bp
+.sM
+.FD 0
+typedef Status (*IceProtocolSetupProc) ();
+
+Status ProtocolSetupProc\^(\^\fIice_conn\fP, \fImajor_version\fP\^, \
+\fIminor_version\fP\^, \fIvendor\fP\^, \fIrelease\fP\^,
+.br
+ \fIclient_data_ret\fP\^, \fIfailure_reason_ret\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fImajor_version\fP\^;
+.br
+ int \fIminor_version\fP\^;
+.br
+ char *\fIvendor\fP\^;
+.br
+ char *\fIrelease\fP\^;
+.br
+ IcePointer *\fIclient_data_ret\fP\^;
+.br
+ char **\fIfailure_reason_ret\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection object.
+.IP \fImajor_version\fP 1i
+The major version of the protocol.
+.IP \fIminor_version\fP 1i
+The minor version of the protocol.
+.IP \fIvendor\fP 1i
+The vendor string registered by the protocol originator.
+.IP \fIrelease\fP 1i
+The release string registered by the protocol originator.
+.IP \fIclient_data_ret\fP 1i
+Client data to be set by callback.
+.IP \fIfailure_reason_ret\fP 1i
+Failure reason returned.
+.LP
+.eM
+The pointer stored in the client_data_ret argument will be passed
+to the
+.PN IcePaProcessMsgProc
+callback whenever a message has arrived for this protocol on the
+ICE connection.
+.LP
+The vendor and release strings should be freed with
+.PN free
+when they are no longer needed.
+.LP
+If a failure occurs, the
+.PN IceProtocolSetupProc
+should return a zero status as well as allocate and return a failure
+reason string in failure_reason_ret.
+The ICE library will be responsible for freeing this memory.
+.LP
+The
+.PN IceProtocolActivateProc
+callback is defined as follows:
+.sM
+.FD 0
+typedef void (*IceProtocolActivateProc)();
+
+void ProtocolActivateProc\^(\^\fIice_conn\fP, \fIclient_data\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ IcePointer \fIclient_data\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection object.
+.IP \fIclient_data\fP 1i
+The client data set in the
+.PN IceProtocolSetupProc
+callback.
+.LP
+.eM
+The
+.PN IceIOErrorProc
+callback is invoked if the ICE connection unexpectedly breaks.
+You should pass NULL for io_error_proc if not interested in being notified.
+For further information,
+see section 13, ``Error Handling.''
+.NH 2
+Callbacks for Processing Messages
+.XS
+\*(SN Callbacks for Processing Messages
+.XE
+.LP
+When an application detects that there is new data to read on an ICE
+connection (via
+.PN select ),
+it calls the
+.PN IceProcessMessages
+function (see section 9, ``Processing Messages'').
+When
+.PN IceProcessMessages
+reads an ICE message header with a major opcode other than
+zero (reserved for the ICE protocol), it needs to call a function that will
+read the rest of the message, unpack it, and process it accordingly.
+.LP
+If the message arrives at the client that initiated the
+.PN ProtocolSetup ,
+the
+.PN IcePoProcessMsgProc
+callback is invoked.
+.sM
+.FD 0
+typedef void (*IcePoProcessMsgProc)();
+
+void PoProcessMsgProc\^(\^\fIice_conn\fP, \fIclient_data\fP\^, \fIopcode\fP\^, \fIlength\fP\^, \fIswap\fP\^, \fIreply_wait\fP\^, \fIreply_ready_ret\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ IcePointer \fIclient_data\fP\^;
+.br
+ int \fIopcode\fP\^;
+.br
+ unsigned long \fIlength\fP\^;
+.br
+ Bool \fIswap\fP\^;
+.br
+ IceReplyWaitInfo *\fIreply_wait\fP\^;
+.br
+ Bool *\fIreply_ready_ret\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection object.
+.IP \fIclient_data\fP 1i
+Client data associated with this protocol on the ICE connection.
+.IP \fIopcode\fP 1i
+The minor opcode of the message.
+.IP \fIlength\fP 1i
+The length (in 8-byte units) of the message beyond the ICE header.
+.IP \fIswap\fP 1i
+A flag that indicates if byte swapping is necessary.
+.IP \fIreply_wait\fP 1i
+Indicates if the invoking client is waiting for a reply.
+.IP \fIreply_ready_ret\fP 1i
+If set to
+.PN True ,
+a reply is ready.
+.LP
+.eM
+If the message arrives at the client that accepted the
+.PN ProtocolSetup ,
+the
+.PN IcePaProcessMsgProc
+callback is invoked.
+.sM
+.FD 0
+typedef void (*IcePaProcessMsgProc)();
+
+void PaProcessMsgProc\^(\^\fIice_conn\fP, \fIclient_data\fP\^, \fIopcode\fP\^, \fIlength\fP\^, \fIswap\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ IcePointer \fIclient_data\fP\^;
+.br
+ int \fIopcode\fP\^;
+.br
+ unsigned long \fIlength\fP\^;
+.br
+ Bool \fIswap\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection object.
+.IP \fIclient_data\fP 1i
+Client data associated with this protocol on the ICE connection.
+.IP \fIopcode\fP 1i
+The minor opcode of the message.
+.IP \fIlength\fP 1i
+The length (in 8-byte units) of the message beyond the ICE header.
+.IP \fIswap\fP 1i
+A flag that indicates if byte swapping is necessary.
+.LP
+.eM
+In order to read the message, both of these callbacks should use the
+macros defined for this purpose (see section 12.2, ``Reading ICE Messages'').
+Note that byte swapping may be necessary.
+As a convenience, the length field in the ICE header will be swapped by ICElib
+if necessary.
+.LP
+In both of these callbacks, the client_data argument is a pointer to client
+data that was registered at
+.PN ProtocolSetup
+time.
+In the case of
+.PN IcePoProcessMsgProc ,
+the client data was set in the call to
+.PN IceProtocolSetup .
+In the case of
+.PN IcePaProcessMsgProc ,
+the client data was set in the
+.PN IceProtocolSetupProc
+callback.
+.LP
+The
+.PN IcePoProcessMsgProc
+callback needs to check the reply_wait argument.
+If reply_wait is NULL ,
+the ICE library expects the function to
+pass the message to the client via a callback.
+For example, if this is a Session Management ``Save Yourself'' message,
+this function should notify the client of the ``Save Yourself'' via a callback.
+The details of how such a callback would be defined
+are implementation-dependent.
+.LP
+However, if reply_wait is not NULL ,
+then the client is waiting for
+a reply or an error for a message it previously sent.
+The reply_wait is of type
+.PN IceReplyWaitInfo .
+.sM
+.Ds 0
+.TA .5i 2.5i
+.ta .5i 2.5i
+typedef struct {
+ unsigned long sequence_of_request;
+ int major_opcode_of_request;
+ int minor_opcode_of_request;
+ IcePointer reply;
+} IceReplyWaitInfo;
+.De
+.LP
+.eM
+.PN IceReplyWaitInfo
+contains the major/minor opcodes and sequence number of
+the message for which a reply is being awaited.
+It also contains a pointer to the reply message to be filled in
+(the protocol library should cast this
+.PN IcePointer
+to the appropriate reply type).
+In most cases, the reply will have some fixed-size part, and the client waiting
+for the reply will have provided a pointer to a structure to hold
+this fixed-size data. If there is variable-length data, it would be
+expected that the
+.PN IcePoProcessMsgProc
+callback will have to allocate additional
+memory and store pointer(s) to that memory in the fixed-size
+structure. If the entire data is variable length (for example., a single
+variable-length string), then the client waiting for the reply would probably
+just pass a pointer to fixed-size space to hold a pointer, and the
+.PN IcePoProcessMsgProc
+callback would allocate the storage and store the pointer.
+It is the responsibility of the client receiving the reply to
+free any memory allocated on its behalf.
+.LP
+If reply_wait is not NULL and
+.PN IcePoProcessMsgProc
+has a reply or error to return in response to this reply_wait
+(that is, no callback was generated), then the reply_ready_ret argument
+should be set to
+.PN True .
+Note that an error should only be returned
+if it corresponds to the reply being waited for. Otherwise, the
+.PN IcePoProcessMsgProc
+should either handle the error internally or invoke an error handler
+for its library.
+.LP
+If reply_wait is NULL,
+then care must be taken not to store any value in reply_ready_ret,
+because this pointer may also be NULL.
+.LP
+The
+.PN IcePaProcessMsgProc
+callback, on the other hand, should always pass
+the message to the client via a callback. For example, if this is a Session
+Management ``Interact Request'' message, this function should notify the
+client of the ``Interact Request'' via a callback.
+.LP
+The reason the
+.PN IcePaProcessMsgProc
+callback does not have a reply_wait, like
+.PN IcePoProcessMsgProc
+does, is because a process that is acting as
+a server should never block for a reply (infinite blocking can
+occur if the connecting client does not act properly, denying access
+to other clients).
+.NH 2
+Authentication Methods
+.XS
+\*(SN Authentication Methods
+.XE
+.LP
+As already stated, a protocol library must register the authentication
+methods that it supports with the ICE library. For each authentication
+method, there are two callbacks that may be registered:
+.IP \(bu 5
+One to handle the side that initiates a
+.PN ProtocolSetup
+.IP \(bu 5
+One to handle the side that accepts or rejects this request
+.LP
+.PN IcePoAuthProc
+is the callback invoked for the client that initiated the
+.PN ProtocolSetup .
+This callback must be able to respond
+to the initial ``Authentication Required'' message or subsequent
+``Authentication Next Phase'' messages sent by the other client.
+.if t .bp
+.sM
+.FD 0
+typedef IcePoAuthStatus (*IcePoAuthProc)();
+
+IcePoAuthStatus PoAuthProc\^(\^\fIice_conn\fP, \fIauth_state_ptr\fP\^, \fIclean_up\fP\^, \fIswap\fP\^, \fIauth_datalen\fP\^, \fIauth_data\fP\^,
+.br
+ \fIreply_datalen_ret\fP\^, \fIreply_data_ret\fP\^, \fIerror_string_ret\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ IcePointer *\fIauth_state_ptr\fP\^;
+.br
+ Bool \fIclean_up\fP\^;
+.br
+ Bool \fIswap\fP\^;
+.br
+ int \fIauth_datalen\fP\^;
+.br
+ IcePointer \fIauth_data\fP\^;
+.br
+ int *\fIreply_datalen_ret\fP\^;
+.br
+ IcePointer *\fIreply_data_ret\fP\^;
+.br
+ char **\fIerror_string_ret\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection object.
+.IP \fIauth_state_ptr\fP 1i
+A pointer to state for use by the authentication callback procedure.
+.IP \fIclean_up\fP 1i
+If
+.PN True ,
+authentication is over, and the function
+should clean up any state it was maintaining. The
+last 6 arguments should be ignored.
+.IP \fIswap\fP 1i
+If
+.PN True ,
+the auth_data may have to be byte swapped
+(depending on its contents).
+.IP \fIauth_datalen\fP 1i
+The length (in bytes) of the authenticator data.
+.IP \fIauth_data\fP 1i
+The data from the authenticator.
+.IP \fIreply_datalen_ret\fP 1i
+The length (in bytes) of the reply data returned.
+.IP \fIreply_data_ret\fP 1i
+The reply data returned.
+.IP \fIerror_string_ret\fP 1i
+If the authentication procedure encounters an error during
+authentication, it should allocate and return
+an error string.
+.LP
+.eM
+Authentication may require several phases, depending on the authentication
+method. As a result, the
+.PN IcePoAuthProc
+may be called more than once when authenticating a client, and
+some state will have to be maintained between each invocation.
+At the start of each
+.PN ProtocolSetup ,
+*auth_state_ptr is NULL,
+and the function should initialize its state and set
+this pointer. In subsequent invocations of the callback, the pointer
+should be used to get at any state previously stored by the callback.
+.LP
+If needed, the network ID of the client accepting the
+.PN ProtocolSetup
+can be obtained by calling the
+.PN IceConnectionString
+function.
+.LP
+ICElib will be responsible for freeing the reply_data_ret and
+error_string_ret pointers with
+.PN free .
+.LP
+The auth_data pointer may point to a volatile block of memory.
+If the data must be kept beyond this invocation of the callback, be sure
+to make a copy of it.
+.LP
+The
+.PN IcePoAuthProc
+should return one of four values:
+.IP \(bu 5
+.PN IcePoAuthHaveReply
+\- a reply is available.
+.IP \(bu 5
+.PN IcePoAuthRejected
+\- authentication rejected.
+.IP \(bu 5
+.PN IcePoAuthFailed
+\- authentication failed.
+.IP \(bu 5
+.PN IcePoAuthDoneCleanup
+\- done cleaning up.
+.LP
+.PN IcePaAuthProc
+is the callback invoked for the client that received the
+.PN ProtocolSetup .
+.if t .bp
+.sM
+.FD 0
+typedef IcePaAuthStatus (*IcePaAuthProc) ();
+
+IcePaAuthStatus PaAuthProc\^(\^\fIice_conn\fP, \fIauth_state_ptr\fP\^, \fIswap\fP\^, \fIauth_datalen\fP\^, \fIauth_data\fP\^,
+.br
+ \fIreply_datalen_ret\fP\^, \fIreply_data_ret\fP\^, \fIerror_string_ret\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ IcePointer *\fIauth_state_ptr\fP\^;
+.br
+ Bool \fIswap\fP\^;
+.br
+ int \fIauth_datalen\fP\^;
+.br
+ IcePointer \fIauth_data\fP\^;
+.br
+ int *\fIreply_datalen_ret\fP\^;
+.br
+ IcePointer *\fIreply_data_ret\fP\^;
+.br
+ char **\fIerror_string_ret\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection object.
+.IP \fIauth_state_ptr\fP 1i
+A pointer to state for use by the authentication callback procedure.
+.IP \fIswap\fP 1i
+If
+.PN True ,
+auth_data may have to be byte swapped
+(depending on its contents).
+.IP \fIauth_datalen\fP 1i
+The length (in bytes) of the protocol originator authentication data.
+.IP \fIauth_data\fP 1i
+The authentication data from the protocol originator.
+.IP \fIreply_datalen_ret\fP 1i
+The length of the authentication data returned.
+.IP \fIreply_data_ret\fP 1i
+The authentication data returned.
+.IP \fIerror_string_ret\fP 1i
+If authentication is rejected or fails, an error
+string is returned.
+.LP
+.eM
+.LP
+Authentication may require several phases, depending on the authentication
+method. As a result, the
+.PN IcePaAuthProc
+may be called more than once when authenticating a client, and
+some state will have to be maintained between each invocation.
+At the start of each
+.PN ProtocolSetup ,
+auth_datalen is zero,
+*auth_state_ptr is NULL,
+and the function should initialize its state and set
+this pointer. In subsequent invocations of the callback, the pointer
+should be used to get at any state previously stored by the callback.
+.LP
+If needed, the network ID of the client accepting the
+.PN ProtocolSetup
+can be obtained by calling the
+.PN IceConnectionString
+function.
+.LP
+The auth_data pointer may point to a volatile block of memory.
+If the data must be kept beyond this invocation of the callback, be sure
+to make a copy of it.
+.LP
+ICElib will be responsible for transmitting and freeing the reply_data_ret and
+error_string_ret pointers with
+.PN free .
+.LP
+The
+.PN IcePaAuthProc
+should return one of four values:
+.IP \(bu 5
+.PN IcePaAuthContinue
+\- continue (or start) authentication.
+.IP \(bu 5
+.PN IcePaAuthAccepted
+\- authentication accepted.
+.IP \(bu 5
+.PN IcePaAuthRejected
+\- authentication rejected.
+.IP \(bu 5
+.PN IcePaAuthFailed
+\- authentication failed.
+.NH 1
+ICE Connections
+.XS
+\*(SN ICE Connections
+.XE
+.LP
+In order for two clients to establish an ICE connection, one client has
+to be waiting for connections, and the other client has to initiate the
+connection.
+Most clients will initiate connections, so we discuss that first.
+.NH 2
+Opening an ICE Connection
+.XS
+\*(SN Opening an ICE Connection
+.XE
+.LP
+To open an ICE connection with another client (that is, waiting
+for connections), use
+.PN IceOpenConnection .
+.sM
+.FD 0
+IceConn IceOpenConnection\^(\^\fInetwork_ids_list\fP, \fIcontext\fP\^, \fImust_authenticate\fP\^, \fImajor_opcode_check\fP\^,
+.br
+ \fIerror_length\fP\^, \fIerror_string_ret\fP\^)
+.br
+ char *\fInetwork_ids_list\fP\^;
+.br
+ IcePointer \fIcontext\fP\^;
+.br
+ Bool \fImust_authenticate\fP\^;
+.br
+ int \fImajor_opcode_check\fP\^;
+.br
+ int \fIerror_length\fP\^;
+.br
+ char *\fIerror_string_ret\fP\^;
+.FN
+.IP \fInetwork_ids_list\fP 1i
+Specifies the network ID(s) of the other client.
+.IP \fIcontext\fP 1i
+A pointer to an opaque object or NULL. Used to determine if an
+ICE connection can be shared (see below).
+.IP \fImust_authenticate\fP 1i
+If
+.PN True ,
+the other client may not bypass authentication.
+.IP \fImajor_opcode_check\fP 1i
+Used to force a new ICE connection to be created (see below).
+.IP \fIerror_length\fP 1i
+Length of the error_string_ret argument passed in.
+.IP \fIerror_string_ret\fP 1i
+Returns a null-terminated error message, if any.
+The error_string_ret argument points to user supplied memory.
+No more than error_length bytes
+are used.
+.LP
+.eM
+.PN IceOpenConnection
+returns an opaque ICE connection object if it succeeds;
+otherwise, it returns NULL.
+.LP
+The network_ids_list argument contains a list of network IDs separated by commas.
+An attempt will be made to use the first network ID. If that fails,
+an attempt will be made using the second network ID, and so on.
+Each network ID has the following format:
+.TS
+lw(0.25i) lw(2.5i) lw(1i).
+ tcp/<hostname>:<portnumber> or
+ decnet/<hostname>::<objname> or
+ local/<hostname>:<path>
+.TE
+.LP
+Most protocol libraries will have some sort of open function that should
+internally make a call into
+.PN IceOpenConnection .
+When
+.PN IceOpenConnection
+is called, it may be possible to use a previously opened ICE connection (if
+the target client is the same). However, there are cases in which shared
+ICE connections are not desired.
+.LP
+The context argument is used to determine if an ICE connection can
+be shared.
+If context is NULL,
+then the caller is always willing to share the connection.
+If context is not NULL,
+then the caller is not willing to use a previously opened ICE connection
+that has a different non-NULL context associated with it.
+.LP
+In addition, if major_opcode_check contains a nonzero major opcode value,
+a previously created ICE connection will be used only if the major opcode
+is not active on the connection. This can be used to force multiple ICE
+connections between two clients for the same protocol.
+.LP
+Any authentication requirements are handled internally by the ICE library.
+The method by which the authentication data is obtained
+is implementation-dependent.\(dg
+.FS \(dg
+The X Consortium's ICElib implementation uses an \&.ICEauthority file (see
+Appendix A).
+.FE
+.LP
+After
+.PN IceOpenConnection
+is called, the client is ready to send a
+.PN ProtocolSetup
+(provided that
+.PN IceRegisterForProtocolSetup
+was called) or receive a
+.PN ProtocolSetup
+(provided that
+.PN IceRegisterForProtocolReply
+was called).
+.NH 2
+Listening for ICE Connections
+.XS
+\*(SN Listening for ICE Connections
+.XE
+.LP
+Clients wishing to accept ICE connections must first call
+.PN IceListenForConnections
+or
+.PN IceListenForWellKnownConnections
+so that they can listen for connections. A list of opaque "listen" objects are
+returned, one for each type of transport method that is available
+(for example, Unix Domain, TCP, DECnet, and so on).
+.LP
+Normally clients will let ICElib allocate an available name in each
+transport and return listen objects. Such a client will then use
+.PN IceComposeNetworkIdList
+to extract the chosen names and make them
+available to other clients for opening the connection. In certain
+cases it may be necessary for a client to listen for connections
+on pre-arranged transport object names. Such a client may use
+.PN IceListenForWellKnownConnections
+to specify the names for the listen objects.
+.sM
+.FD 0
+Status IceListenForConnections\^(\^\fIcount_ret\fP, \fIlisten_objs_ret\fP\^, \fIerror_length\fP\^, \fIerror_string_ret\fP\^)
+.br
+ int *\fIcount_ret\fP\^;
+.br
+ IceListenObj **\fIlisten_objs_ret\fP\^;
+.br
+ int \fIerror_length\fP\^;
+.br
+ char *\fIerror_string_ret\fP\^;
+.FN
+.IP \fIcount_ret\fP 1i
+Returns the number of listen objects created.
+.IP \fIlisten_objs_ret\fP 1i
+Returns a list of pointers to opaque listen objects.
+.IP \fIerror_length\fP 1i
+The length of the error_string_ret argument passed in.
+.IP \fIerror_string_ret\fP 1i
+Returns a null-terminated error message, if any.
+The error_string_ret points to user supplied memory.
+No more than error_length bytes are used.
+.LP
+.eM
+The return value of
+.PN IceListenForConnections
+is zero for failure and a positive value for success.
+.sp
+.sM
+.FD 0
+Status IceListenForWellKnownConnections\^(\^\fIport_id\fP, \fIcount_ret\fP, \fIlisten_objs_ret\fP\^, \fIerror_length\fP\^, \fIerror_string_ret\fP\^)
+.br
+ char *\fIport_id\fP\^;
+.br
+ int *\fIcount_ret\fP\^;
+.br
+ IceListenObj **\fIlisten_objs_ret\fP\^;
+.br
+ int \fIerror_length\fP\^;
+.br
+ char *\fIerror_string_ret\fP\^;
+.FN
+.IP \fIport_id\fP 1i
+Specifies the port identification for the address(es)
+to be opened. The value must not contain the slash
+(\^``/''\^) or comma (\^``,''\^) character;
+these are reserved for future use.
+.IP \fIcount_ret\fP 1i
+Returns the number of listen objects created.
+.IP \fIlisten_objs_ret\fP 1i
+Returns a list of pointers to opaque listen objects.
+.IP \fIerror_length\fP 1i
+The length of the error_string_ret argument passed in.
+.IP \fIerror_string_ret\fP 1i
+Returns a null-terminated error message, if any.
+The error_string_ret points to user supplied memory.
+No more than error_length bytes are used.
+.LP
+.eM
+.PN IceListenForWellKnownConnections
+constructs a list of network IDs
+by prepending each known transport to port_id and then attempts to
+create listen objects for the result. Port_id is the portnumber,
+objname, or path portion of the ICE network ID. If a listen object for
+a particular network ID cannot be created the network ID is ignored.
+If no listen objects are created
+.PN IceListenForWellKnownConnections
+returns failure.
+.LP
+The return value of
+.PN IceListenForWellKnownConnections
+is zero for failure and a positive value for success.
+.sp
+.LP
+To close and free the listen objects, use
+.PN IceFreeListenObjs .
+.LP
+.sM
+.FD 0
+void IceFreeListenObjs\^(\^\fIcount\fP, \fIlisten_objs\fP\^)
+.br
+ int \fIcount\fP\^;
+.br
+ IceListenObj *\fIlisten_objs\fP\^;
+.FN
+.IP \fIcount\fP 1i
+The number of listen objects.
+.IP \fIlisten_objs\fP 1i
+The listen objects.
+.LP
+.eM
+.LP
+To detect a new connection on a listen object, use
+.PN select
+on the descriptor associated with the listen object.
+.sp
+.LP
+To obtain the descriptor, use
+.PN IceGetListenConnectionNumber .
+.LP
+.sM
+.FD 0
+int IceGetListenConnectionNumber\^(\^\fIlisten_obj\fP\^)
+.br
+ IceListenObj \fIlisten_obj\fP\^;
+.FN
+.IP \fIlisten_obj\fP 1i
+The listen object.
+.LP
+.eM
+.LP
+To obtain the network ID string associated with a listen object, use
+.PN IceGetListenConnectionString .
+.sM
+.FD 0
+char *IceGetListenConnectionString\^(\^\fIlisten_obj\fP\^)
+.br
+ IceListenObj \fIlisten_obj\fP\^;
+.FN
+.IP \fIlisten_obj\fP 1i
+The listen object.
+.LP
+.eM
+.LP
+A network ID has the following format:
+.TS
+lw(0.25i) lw(2.5i) lw(1i).
+ tcp/<hostname>:<portnumber> or
+ decnet/<hostname>::<objname> or
+ local/<hostname>:<path>
+.TE
+.LP
+To compose a string containing a list of network IDs separated by commas
+(the format recognized by
+.PN IceOpenConnection ),
+use
+.PN IceComposeNetworkIdList .
+.LP
+.sM
+.FD 0
+char *IceComposeNetworkIdList\^(\^\fIcount\fP, \fIlisten_objs\fP\^)
+.br
+ int \fIcount\fP\^;
+.br
+ IceListenObj *\fIlisten_objs\fP\^;
+.FN
+.IP \fIcount\fP 1i
+The number of listen objects.
+.IP \fIlisten_objs\fP 1i
+The listen objects.
+.LP
+.eM
+.NH 2
+Host Based Authentication for ICE Connections
+.XS
+\*(SN Host Based Authentication for ICE Connections
+.XE
+.LP
+If authentication fails when a client attempts to open an
+ICE connection and the initiating client has not required authentication,
+a host based authentication procedure may be invoked to provide
+a last chance for the client to connect. Each listen object has such a
+callback associated with it, and this callback is set using the
+.PN IceSetHostBasedAuthProc
+function.
+.sM
+.FD 0
+void IceSetHostBasedAuthProc\^(\^\fIlisten_obj\fP, \fIhost_based_auth_proc\fP\^)
+.br
+ IceListenObj \fIlisten_obj\fP\^;
+.br
+ IceHostBasedAuthProc \fIhost_based_auth_proc\fP\^;
+.FN
+.IP \fIlisten_obj\fP 1i
+The listen object.
+.IP \fIhost_based_auth_proc\fP 1i
+The host based authentication procedure.
+.LP
+.eM
+By default, each listen object has no host based authentication procedure
+associated with it.
+Passing NULL for host_based_auth_proc turns off host based authentication
+if it was previously set.
+.LP
+.sM
+.FD 0
+typedef Bool (*IceHostBasedAuthProc) ();
+
+Bool HostBasedAuthProc\^(\^\fIhost_name\fP\^)
+.br
+ char *\fIhost_name\fP\^;
+.FN
+.IP \fIhost_name\fP 1i
+The host name of the client that tried to open an ICE connection.
+.LP
+.eM
+The host_name argument is a string in the form \fIprotocol\fP\^/\^\fIhostname\fP,
+where \fIprotocol\fP\^ is one of {tcp, decnet, local}.
+.LP
+If
+.PN IceHostBasedAuthProc
+returns
+.PN True ,
+access will be granted, even though the original
+authentication failed. Note that authentication can effectively be
+disabled by registering an
+.PN IceHostBasedAuthProc ,
+which always returns
+.PN True .
+.LP
+Host based authentication is also allowed at
+.PN ProtocolSetup
+time.
+The callback is specified in the
+.PN IceRegisterForProtocolReply
+function (see section 6, ``Protocol Registration'').
+.NH 2
+Accepting ICE Connections
+.XS
+\*(SN Accepting ICE Connections
+.XE
+.LP
+After a connection attempt is detected on a listen object returned by
+.PN IceListenForConnections ,
+you should call
+.PN IceAcceptConnection .
+This returns a new opaque ICE connection object.
+.sM
+.FD 0
+IceConn IceAcceptConnection\^(\^\fIlisten_obj\fP, \fI\^status_ret\fP\^)
+.br
+ IceListenObj \fIlisten_obj\fP\^;
+.br
+ IceAcceptStatus *\fIstatus_ret\fP\^;
+.FN
+.IP \fIlisten_obj\fP 1i
+The listen object on which a new connection was detected.
+.IP \fIstatus_ret\fP 1i
+Return status information.
+.LP
+.eM
+The status_ret argument is set to one of the following values:
+.IP \(bu 5
+.PN IceAcceptSuccess
+\- the accept operation succeeded,
+and the function returns a new connection object.
+.IP \(bu 5
+.PN IceAcceptFailure
+\- the accept operation failed, and the function returns NULL.
+.IP \(bu 5
+.PN IceAcceptBadMalloc
+\- a memory allocation failed, and the function returns NULL.
+.LP
+In general, to detect new connections, you should call
+.PN select
+on the file descriptors associated with the listen objects.
+When a new connection is detected, the
+.PN IceAcceptConnection
+function should be called.
+.PN IceAcceptConnection
+may return a new ICE connection that is in a pending state. This is because
+before the connection can become valid, authentication may be necessary.
+Because the ICE library cannot block and wait for the connection to
+become valid (infinite blocking can occur if the connecting client
+does not act properly), the application must wait for the connection status
+to become valid.
+.LP
+The following pseudo-code demonstrates how connections are accepted:
+.if t .bp
+.LP
+.Ds 0
+.TA .5i 1i 1.5i 2i
+.ta .5i 1i 1.5i 2i
+new_ice_conn = IceAcceptConnection (listen_obj, &accept_status);
+if (accept_status != IceAcceptSuccess)
+{
+ close the file descriptor and return
+}
+
+status = IceConnectionStatus (new_ice_conn);
+time_start = time_now;
+
+while (status == IceConnectPending)
+{
+ select() on {new_ice_conn, all open connections}
+
+ for (each ice_conn in the list of open connections)
+ if (data ready on ice_conn)
+ {
+ status = IceProcessMessages (ice_conn, NULL, NULL);
+ if (status == IceProcessMessagesIOError)
+ IceCloseConnection (ice_conn);
+ }
+
+ if (data ready on new_ice_conn)
+ {
+ /*
+ * IceProcessMessages is called until the connection
+ * is non-pending. Doing so handles the connection
+ * setup request and any authentication requirements.
+ */
+
+ IceProcessMessages (new_ice_conn, NULL, NULL);
+ status = IceConnectionStatus (new_ice_conn);
+ }
+ else
+ {
+ if (time_now - time_start > MAX_WAIT_TIME)
+ status = IceConnectRejected;
+ }
+}
+
+if (status == IceConnectAccepted)
+{
+ Add new_ice_conn to the list of open connections
+}
+else
+{
+ IceCloseConnection (new_ice_conn);
+}
+.De
+.LP
+After
+.PN IceAcceptConnection
+is called and the connection has been
+validated, the client is ready to receive a
+.PN ProtocolSetup
+(provided
+that
+.PN IceRegisterForProtocolReply
+was called) or send a
+.PN ProtocolSetup
+(provided that
+.PN IceRegisterForProtocolSetup
+was called).
+.NH 2
+Closing ICE Connections
+.XS
+\*(SN Closing ICE Connections
+.XE
+.LP
+To close an ICE connection created with
+.PN IceOpenConnection
+or
+.PN IceAcceptConnection ,
+use
+.PN IceCloseConnection .
+.sM
+.FD 0
+IceCloseStatus IceCloseConnection\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection to close.
+.LP
+.eM
+To actually close an ICE connection, the following conditions
+must be met:
+.IP \(bu 5
+The \fIopen reference count\fP must have reached zero on this ICE connection.
+When
+.PN IceOpenConnection
+is called, it tries to use a previously opened
+ICE connection. If it is able to use an existing connection, it increments
+the open reference count on the connection by one.
+So, to close an ICE connection, each call to
+.PN IceOpenConnection
+must be matched with a call to
+.PN IceCloseConnection .
+The connection can be closed only
+on the last call to
+.PN IceCloseConnection .
+.IP \(bu 5
+The \fIactive protocol count\fP\^ must have reached zero. Each time a
+.PN ProtocolSetup
+succeeds on the connection, the active protocol count
+is incremented by one. When the client no longer expects to use the
+protocol on the connection, the
+.PN IceProtocolShutdown
+function should be called, which decrements the active protocol count
+by one (see section 8, ``Protocol Setup and Shutdown'').
+.IP \(bu 5
+If shutdown negotiation is enabled on the connection, the client on the other
+side of the ICE connection must agree to have the connection closed.
+.LP
+.PN IceCloseConnection
+returns one of the following values:
+.IP \(bu 5
+.PN IceClosedNow
+\- the ICE connection was closed at this time. The watch procedures were
+invoked and the connection was freed.
+.IP \(bu 5
+.PN IceClosedASAP
+\- an IO error had occurred on the connection, but
+.PN IceCloseConnection
+is being called within a nested
+.PN IceProcessMessages .
+The watch procedures have been invoked at this time, but the connection
+will be freed as soon as possible (when the nesting level reaches zero and
+.PN IceProcessMessages
+returns a status of
+.PN IceProcessMessagesConnectionClosed ).
+.IP \(bu 5
+.PN IceConnectionInUse
+\- the connection was not closed at this time, because it is being used by
+other active protocols.
+.IP \(bu 5
+.PN IceStartedShutdownNegotiation
+\- the connection was not closed at this time and shutdown negotiation started
+with the client on the other side of the ICE connection. When the connection
+is actually closed,
+.PN IceProcessMessages
+will return a status of
+.PN IceProcessMessagesConnectionClosed .
+.sp
+.LP
+When it is known that the client on the other side of the ICE connection
+has terminated the connection without initiating shutdown negotiation, the
+.PN IceSetShutdownNegotiation
+function should be called to turn off shutdown negotiation. This will prevent
+.PN IceCloseConnection
+from writing to a broken connection.
+.sM
+.FD 0
+void IceSetShutdownNegotiation\^(\^\fIice_conn\fP, \fInegotiate\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ Bool \fInegotiate\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fInegotiate\fP 1i
+If
+.PN False ,
+shutdown negotiating will be turned off.
+.LP
+.eM
+.LP
+To check the shutdown negotiation status of an ICE connection, use
+.PN IceCheckShutdownNegotiation .
+.sM
+.FD 0
+Bool IceCheckShutdownNegotiation\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.LP
+.eM
+.PN IceCheckShutdownNegotiation
+returns
+.PN True
+if shutdown negotiation will take place on the connection;
+otherwise, it returns
+.PN False .
+Negotiation is on by default for a connection. It
+can only be changed with the
+.PN IceSetShutdownNegotiation
+function.
+.NH 2
+Connection Watch Procedures
+.XS
+\*(SN Connection Watch Procedures
+.XE
+.LP
+To add a watch procedure that will be called
+each time ICElib opens a new connection via
+.PN IceOpenConnection
+or
+.PN IceAcceptConnection
+or closes a connection via
+.PN IceCloseConnection ,
+use
+.PN IceAddConnectionWatch .
+.sM
+.FD 0
+Status IceAddConnectionWatch\^(\^\fIwatch_proc\fP, \fIclient_data\fP\^)
+.br
+ IceWatchProc \fIwatch_proc\fP\^;
+.br
+ IcePointer \fIclient_data\fP\^;
+.FN
+.IP \fIwatch_proc\fP 1i
+The watch procedure to invoke when ICElib opens or
+closes a connection.
+.IP \fIclient_data\fP 1i
+This pointer will be passed to the watch procedure.
+.LP
+.eM
+The return value of
+.PN IceAddConnectionWatch
+is zero for failure, and a positive value for success.
+.LP
+Note that several calls to
+.PN IceOpenConnection
+might share the same ICE connection. In such a case, the watch procedure
+is only invoked when the connection is first created (after authentication
+succeeds). Similarly, because
+connections might be shared, the watch procedure is called only if
+.PN IceCloseConnection
+actually closes the connection (right before the IceConn is freed).
+.LP
+The watch procedures are very useful for applications that
+need to add a file descriptor to a select mask when a new connection
+is created and remove the file descriptor when the connection is destroyed.
+Because connections are shared, knowing when to add and remove the file
+descriptor from the select mask would be difficult without the watch
+procedures.
+.LP
+Multiple watch procedures may be registered with the ICE library.
+No assumptions should be made about their order of invocation.
+.LP
+If one or more ICE connections were already created by the ICE library at the
+time the watch procedure is registered, the watch procedure will instantly
+be invoked for each of these ICE connections (with the opening argument
+set to
+.PN True ).
+.LP
+The watch procedure is of type
+.PN IceWatchProc .
+.sM
+.FD 0
+typedef void (*IceWatchProc)();
+
+void WatchProc\^(\^\fIice_conn\fP, \fIclient_data\fP\^, \fIopening\fP\^, \fIwatch_data\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ IcePointer \fIclient_data\fP\^;
+.br
+ Bool \fIopening\fP\^;
+.br
+ IcePointer *\fIwatch_data\fP\^;
+.FN
+.IP \fIice_conn\fP\^ 1i
+The opened or closed ICE connection. Call
+.PN IceConnectionNumber
+to get the file descriptor associated with this connection.
+.IP \fIclient_data\fP\^ 1i
+Client data specified in the call to
+.PN IceAddConnectionWatch .
+.IP \fIopening\fP\^ 1i
+If
+.PN True ,
+the connection is being opened. If
+.PN False ,
+the connection is being closed.
+.IP \fIwatch_data\fP\^ 1i
+Can be used to save a pointer to client data.
+.LP
+.eM
+If opening is
+.PN True ,
+the client should set the *watch_data
+pointer to any data it may need to save until the connection is closed
+and the watch procedure is
+invoked again with opening set to
+.PN False .
+.sp
+.LP
+To remove a watch procedure, use
+.PN IceRemoveConnectionWatch .
+.sM
+.FD 0
+void IceRemoveConnectionWatch\^(\^\fIwatch_proc\fP, \fIclient_data\fP\^)
+.br
+ IceWatchProc \fIwatch_proc\fP\^;
+.br
+ IcePointer \fIclient_data\fP\^;
+.LP
+.FN
+.IP \fIwatch_proc\fP 1i
+The watch procedure that was passed to
+.PN IceAddConnectionWatch .
+.IP \fIclient_data\fP 1i
+The client_data pointer that was passed to
+.PN IceAddConnectionWatch .
+.LP
+.eM
+.NH 1
+Protocol Setup and Shutdown
+.XS
+\*(SN Protocol Setup and Shutdown
+.XE
+.LP
+To activate a protocol on a given ICE connection, use
+.PN IceProtocolSetup .
+.LP
+.sM
+.FD 0
+IceProtocolSetupStatus IceProtocolSetup\^(\^\fIice_conn\fP, \fImy_opcode\fP\^, \fIclient_data\fP\^, \fImust_authenticate\fP\^,
+.br
+ \fImajor_version_ret\fP\^, \fIminor_version_ret\fP\^, \fIvendor_ret\fP\^, \fIrelease_ret\fP\^, \fIerror_length\fP\^, \fIerror_string_ret\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fImy_opcode\fP\^;
+.br
+ IcePointer \fIclient_data\fP\^;
+.br
+ Bool \fImust_authenticate\fP\^;
+.br
+ int *\fImajor_version_ret\fP\^;
+.br
+ int *\fIminor_version_ret\fP\^;
+.br
+ char **\fIvendor_ret\fP\^;
+.br
+ char **\fIrelease_ret\fP\^;
+.br
+ int \fIerror_length\fP\^;
+.br
+ char *\fIerror_string_ret\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fImy_opcode\fP 1i
+The major opcode of the protocol to be set up, as returned by
+.PN IceRegisterForProtocolSetup .
+.IP \fIclient_data\fP 1i
+The client data stored in this pointer will be passed to the
+.PN IcePoProcessMsgProc
+callback.
+.IP \fImust_authenticate\fP 1i
+If
+.PN True ,
+the other client may not bypass authentication.
+.IP \fImajor_version_ret\fP 1i
+The major version of the protocol to be used is returned.
+.IP \fIminor_version_ret\fP 1i
+The minor version of the protocol to be used is returned.
+.IP \fIvendor_ret\fP 1i
+The vendor string specified by the protocol acceptor.
+.IP \fIrelease_ret\fP 1i
+The release string specified by the protocol acceptor.
+.IP \fIerror_length\fP 1i
+Specifies the length of the error_string_ret argument passed in.
+.IP \fIerror_string_ret\fP 1i
+Returns a null-terminated error message, if any.
+The error_string_ret argument points to user supplied memory.
+No more than error_length bytes are used.
+.LP
+.eM
+The vendor_ret and release_ret strings should be freed with
+.PN free
+when no longer needed.
+.LP
+.PN IceProtocolSetup
+returns one of the following values:
+.IP \(bu 5
+.PN IceProtocolSetupSuccess
+\- the major_version_ret, minor_version_ret, vendor_ret, release_ret are set.
+.IP \(bu 5
+.PN IceProtocolSetupFailure
+or
+.PN IceProtocolSetupIOError
+\- check error_string_ret for failure reason.
+The major_version_ret, minor_version_ret, vendor_ret, release_ret are not set.
+.IP \(bu 5
+.PN IceProtocolAlreadyActive
+\- this protocol is already active on this connection.
+The major_version_ret, minor_version_ret, vendor_ret, release_ret are not set.
+.sp
+.LP
+To notify the ICE library when a given protocol
+will no longer be used on an ICE connection, use
+.PN IceProtocolShutdown .
+.LP
+.sM
+.FD 0
+Status IceProtocolShutdown\^(\^\fIice_conn\fP, \fImajor_opcode\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fImajor_opcode\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fImajor_opcode\fP 1i
+The major opcode of the protocol to shut down.
+.LP
+.eM
+The return value of
+.PN IceProtocolShutdown
+is zero for failure and a positive value for success.
+.LP
+Failure will occur if the major opcode was never registered OR the protocol
+of the major opcode was never activated on the connection. By activated,
+we mean that a
+.PN ProtocolSetup
+succeeded on the connection.
+Note that ICE does not define how each sub-protocol triggers a
+protocol shutdown.
+.NH 1
+Processing Messages
+.XS
+\*(SN Processing Messages
+.XE
+.LP
+To process incoming messages on an ICE connection, use
+.PN IceProcessMessages .
+.sM
+.FD 0
+IceProcessMessagesStatus IceProcessMessages\^(\^\fIice_conn\fP, \fIreply_wait\fP\^, \fIreply_ready_ret\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ IceReplyWaitInfo *\fIreply_wait\fP\^;
+.br
+ Bool *\fIreply_ready_ret\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIreply_wait\fP 1i
+Indicates if a reply is being waited for.
+.IP \fIreply_ready_ret\fP 1i
+If set to
+.PN True
+on return, a reply is ready.
+.LP
+.eM
+.PN IceProcessMessages
+is used in two ways:
+.IP \(bu 5
+In the first, a client may
+generate a message and block by calling
+.PN IceProcessMessages
+repeatedly until it gets its reply.
+.IP \(bu 5
+In the second, a
+client calls
+.PN IceProcessMessages
+with reply_wait set to NULL in response to
+.PN select
+showing that there is data to read on the ICE connection.
+The ICE library may process zero or more complete messages.
+Note that messages that are not blocked for are always processed by
+invoking callbacks.
+.LP
+.PN IceReplyWaitInfo
+contains the major/minor opcodes and sequence number
+of the message for which a reply is being awaited. It also contains
+a pointer to the reply message to be filled in (the protocol library
+should cast this
+.PN IcePointer
+to the appropriate reply type). In most
+cases, the reply will have some fixed-size part, and the client waiting
+for the reply will have provided a pointer to a structure to hold
+this fixed-size data. If there is variable-length data, it would be
+expected that the
+.PN IcePoProcessMsgProc
+callback will have to allocate additional
+memory and store pointer(s) to that memory in the fixed-size
+structure. If the entire data is variable length (for example, a single
+variable-length string), then the client waiting for the reply would probably
+just pass a pointer to fixed-size space to hold a pointer, and the
+.PN IcePoProcessMsgProc
+callback would allocate the storage and store the pointer.
+It is the responsibility of the client receiving the reply to
+free up any memory allocated on its behalf.
+.LP
+.sM
+.Ds 0
+.TA .5i
+.ta .5i
+typedef struct {
+ unsigned long sequence_of_request;
+ int major_opcode_of_request;
+ int minor_opcode_of_request;
+ IcePointer reply;
+} IceReplyWaitInfo;
+.De
+.LP
+.eM
+If reply_wait is not NULL and
+.PN IceProcessMessages
+has a reply or error to return in response to this reply_wait
+(that is, no callback was generated), then the reply_ready_ret argument
+will be set to
+.PN True .
+.LP
+If reply_wait is NULL,
+then the caller may also pass NULL
+for reply_ready_ret and be guaranteed that no value will be stored
+in this pointer.
+.LP
+.PN IceProcessMessages
+returns one of the following values:
+.IP \(bu 5
+.PN IceProcessMessagesSuccess
+\- no error occurred.
+.IP \(bu 5
+.PN IceProcessMessagesIOError
+\- an IO error occurred,
+and the caller must explicitly close the connection by calling
+.PN IceCloseConnection .
+.IP \(bu 5
+.PN IceProcessMessagesConnectionClosed
+\- the ICE connection has been closed (closing of the connection was deferred
+because of shutdown negotiation, or because the
+.PN IceProcessMessages
+nesting level was not zero). Do not attempt
+to access the ICE connection at this point, since it has been freed.
+.NH 1
+Ping
+.XS
+\*(SN Ping
+.XE
+.LP
+To send a ``Ping'' message to the client on the other side of the
+ICE connection, use
+.PN IcePing .
+.sM
+.FD 0
+Status IcePing\^(\^\fIice_conn\fP, \fIping_reply_proc\fP\^, \fIclient_data\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ IcePingReplyProc \fIping_reply_proc\fP\^;
+.br
+ IcePointer \fIclient_data\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIping_reply_proc\fP 1i
+The callback to invoke when the Ping reply arrives.
+.IP \fIclient_data\fP 1i
+This pointer will be passed to the
+.PN IcePingReplyProc
+callback.
+.LP
+.eM
+.PN IcePing
+returns zero for failure and a positive value for success.
+.LP
+When
+.PN IceProcessMessages
+processes the Ping reply, it will invoke the
+.PN IcePingReplyProc
+callback.
+.sM
+.FD 0
+typedef void (*IcePingReplyProc)();
+
+void PingReplyProc\^(\^\fIice_conn\fP, \fIclient_data\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ IcePointer \fIclient_data\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection object.
+.IP \fIclient_data\fP 1i
+The client data specified in the call to
+.PN IcePing .
+.LP
+.eM
+.NH 1
+Using ICElib Informational Functions
+.XS
+\*(SN Using ICElib Informational Functions
+.XE
+.LP
+.sM
+.FD 0
+IceConnectStatus IceConnectionStatus\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.eM
+.PN IceConnectionStatus
+returns the status of an ICE connection. The possible return values are:
+.IP \(bu 5
+.PN IceConnectPending
+\- the connection is not valid yet (that is, authentication is taking place).
+This is only relevant to connections created by
+.PN IceAcceptConnection .
+.IP \(bu 5
+.PN IceConnectAccepted
+\- the connection has been accepted.
+This is only relevant to connections created by
+.PN IceAcceptConnection .
+.IP \(bu 5
+.PN IceConnectRejected
+\- the connection had been rejected (that is, authentication failed).
+This is only relevant to connections created by
+.PN IceAcceptConnection .
+.IP \(bu 5
+.PN IceConnectIOError
+\- an IO error has occurred on the connection.
+.LP
+.sM
+.FD 0
+char *IceVendor\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.eM
+.PN IceVendor
+returns the ICE library vendor identification
+for the other side of the connection.
+The string should be freed with a call to
+.PN free
+when no longer needed.
+.LP
+.sM
+.FD 0
+char *IceRelease\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.eM
+.PN IceRelease
+returns the release identification of the ICE library
+on the other side of the connection.
+The string should be freed with a call to
+.PN free
+when no longer needed.
+.LP
+.sM
+.FD 0
+int IceProtocolVersion\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.eM
+.PN IceProtocolVersion
+returns the major version of the ICE protocol on this connection.
+.LP
+.sM
+.FD 0
+int IceProtocolRevision\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.eM
+.PN IceProtocolRevision
+returns the minor version of the ICE protocol on this connection.
+.LP
+.sM
+.FD 0
+int IceConnectionNumber\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.eM
+.PN IceConnectionNumber
+returns the file descriptor of this ICE connection.
+.LP
+.sM
+.FD 0
+char *IceConnectionString\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.eM
+.PN IceConnectionString
+returns the network ID of the client that
+accepted this connection. The string should be freed with a call to
+.PN free
+when no longer needed.
+.LP
+.sM
+.FD 0
+unsigned long IceLastSentSequenceNumber\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.eM
+.PN IceLastSentSequenceNumber
+returns the sequence number of the last message sent on this ICE connection.
+.LP
+.sM
+.FD 0
+unsigned long IceLastReceivedSequenceNumber\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.eM
+.PN IceLastReceivedSequenceNumber
+returns the sequence number of the last message received on this
+ICE connection.
+.LP
+.sM
+.FD 0
+Bool IceSwapping\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.eM
+.PN IceSwapping
+returns
+.PN True
+if byte swapping is necessary when reading messages on the ICE connection.
+.LP
+.sM
+.FD 0
+IcePointer IceGetContext\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.eM
+.PN IceGetContext
+returns the context associated with a connection created by
+.PN IceOpenConnection .
+.NH 1
+ICE Messages
+.XS
+\*(SN ICE Messages
+.XE
+.LP
+All ICE messages have a standard 8-byte header. The ICElib macros that
+read and write messages rely on the following naming convention for message
+headers:
+.LP
+.Ds 0
+.TA .5i 1i
+.ta .5i 1i
+ CARD8 major_opcode;
+ CARD8 minor_opcode;
+ CARD8 data[2];
+ CARD32 length B32;
+.De
+.LP
+The 3rd and 4th bytes of the message header can be used as needed.
+The length field is specified in units of 8 bytes.
+.NH 2
+Sending ICE Messages
+.XS
+\*(SN Sending ICE Messages
+.XE
+.LP
+The ICE library maintains an output buffer used for generating messages.
+Protocol libraries layered on top of ICE may choose to batch messages
+together and flush the output buffer at appropriate times.
+.LP
+If an IO error has occurred on an ICE connection, all write operations
+will be ignored.
+For further information, see section 13, ``Error Handling.''
+.sp
+.LP
+To get the size of the ICE output buffer, use
+.PN IceGetOutBufSize .
+.sM
+.FD 0
+int IceGetOutBufSize\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.LP
+.eM
+.LP
+To flush the ICE output buffer, use
+.PN IceFlush .
+.sM
+.FD 0
+IceFlush\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.LP
+.eM
+Note that the output buffer may be implicitly flushed if there is insufficient
+space to generate a message.
+.LP
+The following macros can be used to generate ICE messages:
+.LP
+.sM
+.FD 0
+IceGetHeader\^(\^\fIice_conn\fP, \fImajor_opcode\fP\^, \fIminor_opcode\fP\^, \fIheader_size\fP\^, \fI<C_data_type>\fP\^, \fIpmsg\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fImajor_opcode\fP\^;
+.br
+ int \fIminor_opcode\fP\^;
+.br
+ int \fIheader_size\fP\^;
+.br
+ <C_data_type> *\fIpmsg\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fImajor_opcode\fP 1i
+The major opcode of the message.
+.IP \fIminor_opcode\fP 1i
+The minor opcode of the message.
+.IP \fIheader_size\fP 1i
+The size of the message header (in bytes).
+.IP \fI<C_data_type>\fP 1i
+The actual C data type of the message header.
+.IP \fIpmsg\fP 1i
+The message header pointer. After this macro is called, the
+library can store data in the message header.
+.LP
+.eM
+.PN IceGetHeader
+is used to set up a message header on an ICE connection.
+It sets the major and minor opcodes of the message, and initializes
+the message's length to the length of the header. If additional
+variable length data follows, the message's length field should be
+updated.
+.sp
+.LP
+.sM
+.FD 0
+IceGetHeaderExtra\^(\^\fIice_conn\fP, \fImajor_opcode\fP\^, \fIminor_opcode\fP\^, \fIheader_size\fP\^, \fIextra\fP\^, \fI<C_data_type>\fP\^, \fIpmsg\fP\^, \fIpdata\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fImajor_opcode\fP\^;
+.br
+ int \fIminor_opcode\fP\^;
+.br
+ int \fIheader_size\fP\^;
+.br
+ int \fIextra\fP\^;
+.br
+ <C_data_type> *\fIpmsg\fP\^;
+.br
+ char *\fIpdata\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fImajor_opcode\fP 1i
+The major opcode of the message.
+.IP \fIminor_opcode\fP 1i
+The minor opcode of the message.
+.IP \fIheader_size\fP 1i
+The size of the message header (in bytes).
+.IP \fIextra\fP 1i
+The size of the extra data beyond the header (in 8-byte units).
+.IP \fI<C_data_type>\fP 1i
+The actual C data type of the message header.
+.IP \fIpmsg\fP 1i
+The message header pointer. After this macro is called, the
+library can store data in the message header.
+.IP \fIpdata\fP 1i
+Returns a pointer to the ICE output buffer that points
+immediately after the message header. The variable length
+data should be stored here. If there was not enough room
+in the ICE output buffer, pdata is set to NULL.
+.LP
+.eM
+.PN IceGetHeaderExtra
+is used to generate a message with a fixed (and relatively small) amount
+of variable length data. The complete message must fit in the ICE output
+buffer.
+.sp
+.LP
+.sM
+.FD 0
+IceSimpleMessage\^(\^\fIice_conn\fP, \fImajor_opcode\fP\^, \fIminor_opcode\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fImajor_opcode\fP\^;
+.br
+ int \fIminor_opcode\fP\^;
+.FN
+.br
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fImajor_opcode\fP 1i
+The major opcode of the message.
+.IP \fIminor_opcode\fP 1i
+The minor opcode of the message.
+.LP
+.eM
+.PN IceSimpleMessage
+is used to generate a message that is identical
+in size to the ICE header message, and has no additional data.
+.sp
+.LP
+.sM
+.FD 0
+IceErrorHeader\^(\^\fIice_conn\fP, \fIoffending_major_opcode\fP\^, \fIoffending_minor_opcode\fP\^, \fIoffending_sequence_num\fP\^,
+.br
+ \fIseverity\fP\^, \fIerror_class\fP\^, \fIdata_length\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fIoffending_major_opcode\fP\^;
+.br
+ int \fIoffending_minor_opcode\fP\^;
+.br
+ int \fIoffending_sequence_num\fP\^;
+.br
+ int \fIseverity\fP\^;
+.br
+ int \fIerror_class\fP\^;
+.br
+ int \fIdata_length\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIoffending_major_opcode\fP 1i
+The major opcode of the protocol in which an error was detected.
+.IP \fIoffending_minor_opcode\fP 1i
+The minor opcode of the protocol in which an error was detected.
+.IP \fIoffending_sequence_num\fP 1i
+The sequence number of the message that caused the error.
+.IP \fIseverity\fP 1i
+.PN IceCanContinue ,
+.PN IceFatalToProtocol ,
+or
+.PN IceFatalToConnection .
+.IP \fIerror_class\fP 1i
+The error class.
+.IP \fIdata_length\fP 1i
+Length of data (in 8-byte units) to be written after the header.
+.LP
+.eM
+.PN IceErrorHeader
+sets up an error message header.
+.LP
+Note that the two clients connected by ICE may be using different
+major opcodes for a given protocol. The offending_major_opcode passed
+to this macro is the major opcode of the protocol for the client
+sending the error message.
+.LP
+Generic errors, which are common to all protocols, have classes
+in the range 0x8000..0xFFFF.
+See the \fIInter-Client Exchange Protocol\fP\^ standard for more details.
+.TS
+lw(1i) lw(1i).
+T{
+.PN IceBadMinor
+T} T{
+0x8000
+T}
+.sp 4p
+T{
+.PN IceBadState
+T} T{
+0x8001
+T}
+.sp 4p
+T{
+.PN IceBadLength
+T} T{
+0x8002
+T}
+.sp 4p
+T{
+.PN IceBadValue
+T} T{
+0x8003
+T}
+.TE
+.LP
+Per-protocol errors have classes in the range 0x0000-0x7fff.
+.sp
+.LP
+To write data to an ICE connection, use the
+.PN IceWriteData
+macro. If the data fits into the ICE output buffer, it is copied there.
+Otherwise, the ICE output buffer is flushed and the data is directly sent.
+.LP
+This macro is used in conjunction with
+.PN IceGetHeader
+and
+.PN IceErrorHeader .
+.sp
+.LP
+.sM
+.FD 0
+IceWriteData\^(\^\fIice_conn\fP, \fIbytes\fP\^, \fIdata\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fIbytes\fP\^;
+.br
+ char *\fIdata\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIbytes\fP 1i
+The number of bytes to write.
+.IP \fIdata\fP 1i
+The data to write.
+.LP
+.eM
+.sp
+To write data as 16-bit quantities, use
+.PN IceWriteData16 .
+.sM
+.FD 0
+IceWriteData16\^(\^\fIice_conn\fP, \fIbytes\fP\^, \fIdata\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fIbytes\fP\^;
+.br
+ short *\fIdata\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIbytes\fP 1i
+The number of bytes to write.
+.IP \fIdata\fP 1i
+The data to write.
+.LP
+.eM
+.sp
+To write data as 32-bit quantities, use
+.PN IceWriteData32 .
+.sM
+.FD 0
+IceWriteData32\^(\^\fIice_conn\fP, \fIbytes\fP\^, \fIdata\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fIbytes\fP\^;
+.br
+ long *\fIdata\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIbytes\fP 1i
+The number of bytes to write.
+.IP \fIdata\fP 1i
+The data to write.
+.LP
+.eM
+.sp
+To bypass copying data to the ICE output buffer, use
+.PN IceSendData
+to directly send data over the network connection. If necessary, the
+ICE output buffer is first flushed.
+.sM
+.FD 0
+IceSendData\^(\^\fIice_conn\fP, \fIbytes\fP\^, \fI(char *) data\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fIbytes\fP\^;
+.br
+ char *\fIdata\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIbytes\fP 1i
+The number of bytes to send.
+.IP \fIdata\fP 1i
+The data to send.
+.LP
+.eM
+.sp
+To force 32-bit or 64-bit alignment, use
+.PN IceWritePad .
+A maximum of 7 pad bytes can be specified.
+.sM
+.FD 0
+IceWritePad\^(\^\fIice_conn\fP, \fIbytes\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fIbytes\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIbytes\fP 1i
+The number of pad bytes.
+.LP
+.eM
+.NH 2
+Reading ICE Messages
+.XS
+\*(SN Reading ICE Messages
+.XE
+.LP
+The ICE library maintains an input buffer used for reading messages.
+If the ICE library chooses to perform nonblocking reads (this is
+implementation-dependent), then for every read operation that it makes,
+zero or more complete messages may be read into the input buffer. As
+a result, for all of the macros described in this section that read
+messages, an actual read operation will occur on the connection only if
+the data is not already present in the input buffer.
+.sp
+.LP
+To get the size of the ICE input buffer, use
+.PN IceGetInBufSize .
+.sM
+.FD 0
+int IceGetInBufSize\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.LP
+.eM
+.LP
+When reading messages, care must be taken to check for IO errors. If
+any IO error occurs in reading any part of a message, the message should
+be thrown out. After using any of the macros described below for reading
+messages, the
+.PN IceValidIO
+macro can be used to check if an IO error occurred on the
+connection. After an IO error has occurred on an ICE connection, all
+read operations will be ignored.
+For further information, see section 13, ``Error Handling.''
+.sp
+.LP
+.sM
+.FD 0
+Bool IceValidIO\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.LP
+.eM
+.LP
+The following macros can be used to read ICE messages.
+.sM
+.FD 0
+IceReadSimpleMessage\^(\^\fIice_conn\fP, \fI<C_data_type>\fP\^, \fIpmsg\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ <C_data_type> *\fIpmsg\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fI<C_data_type>\fP 1i
+The actual C data type of the message header.
+.IP \fIpmsg\fP 1i
+This pointer is set to the message header.
+.LP
+.eM
+.PN IceReadSimpleMessage
+is used for messages that are identical in size to the 8-byte ICE header, but
+use the spare 2 bytes in the header to encode additional data. Note that the
+ICE library always reads in these first 8 bytes, so it can obtain the major
+opcode of the message.
+.PN IceReadSimpleMessage
+simply returns a pointer to these 8 bytes; it does not actually read any data
+into the input buffer.
+.LP
+For a message with variable length data, there are two ways of reading
+the message. One method involves reading the complete message in one
+pass using
+.PN IceReadCompleteMessage .
+The second method involves reading the message header (note that this may
+be larger than the 8-byte ICE header), then reading
+the variable length data in chunks (see
+.PN IceReadMessageHeader
+and
+.PN IceReadData ).
+.sp
+.LP
+.sM
+.FD 0
+IceReadCompleteMessage\^(\^\fIice_conn\fP, \fIheader_size\fP\^, \fI<C_data_type>\fP\^, \fIpmsg\fP\^, \fIpdata\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fIheader_size\fP\^;
+.br
+ <C_data_type> *\fIpmsg\fP\^;
+.br
+ char *\fIpdata\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIheader_size\fP 1i
+The size of the message header (in bytes).
+.IP \fI<C_data_type>\fP 1i
+The actual C data type of the message header.
+.IP \fIpmsg\fP 1i
+This pointer is set to the message header.
+.IP \fIpdata\fP 1i
+This pointer is set to the variable length data of the message.
+.LP
+.eM
+If the ICE input buffer has sufficient space,
+.PN IceReadCompleteMessage
+will read the complete message into the
+ICE input buffer. Otherwise, a buffer will be allocated to hold the
+variable length data. After the call, the pdata argument should
+be checked against NULL to make sure that there was sufficient memory
+to allocate the buffer.
+.sp
+.LP
+After calling
+.PN IceReadCompleteMessage
+and processing the message,
+.PN IceDisposeCompleteMessage
+should be called.
+.LP
+.sM
+.FD 0
+IceDisposeCompleteMessage\^(\^\fIice_conn\fP, \fIpdata\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ char *\fIpdata\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIpdata\fP 1i
+The pointer to the variable length data returned in
+.PN IceReadCompleteMessage .
+.LP
+.eM
+If a buffer had to be allocated to hold the variable length data (because
+it did not fit in the ICE input buffer), it is freed here by ICElib.
+.sp
+.LP
+.sM
+.FD 0
+IceReadMessageHeader\^(\^\fIice_conn\fP, \fIheader_size\fP\^, \fI<C_data_type>\fP\^, \fIpmsg\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fIheader_size\fP\^;
+.br
+ <C_data_type> *\fIpmsg\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIheader_size\fP 1i
+The size of the message header (in bytes).
+.IP \fI<C_data_type>\fP 1i
+The actual C data type of the message header.
+.IP \fIpmsg\fP 1i
+This pointer is set to the message header.
+.LP
+.eM
+.PN IceReadMessageHeader
+reads just the message header. The rest
+of the data should be read with the
+.PN IceReadData
+family of macros. This method of reading a message should be used when the
+variable length data must be read in chunks.
+.sp
+.LP
+To read data directly into a user supplied buffer, use
+.PN IceReadData .
+.sM
+.FD 0
+IceReadData\^(\^\fIice_conn\fP, \fIbytes\fP\^, \fIpdata\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fIbytes\fP\^;
+.br
+ char *\fIpdata\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIbytes\fP 1i
+The number of bytes to read.
+.IP \fIpdata\fP 1i
+The data is read into this user supplied buffer.
+.LP
+.eM
+.sp
+To read data as 16-bit quantities, use
+.PN IceReadData16 .
+.sM
+.FD 0
+IceReadData16\^(\^\fIice_conn\fP, \fIswap\fP\^, \fIbytes\fP\^, \fIpdata\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ Bool \fIswap\fP\^;
+.br
+ int \fIbytes\fP\^;
+.br
+ short *\fIpdata\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIswap\fP 1i
+If
+.PN True,
+the values will be byte swapped.
+.IP \fIbytes\fP 1i
+The number of bytes to read.
+.IP \fIpdata\fP 1i
+The data is read into this user supplied buffer.
+.LP
+.eM
+.sp
+To read data as 32-bit quantities, use
+.PN IceReadData32 .
+.sM
+.FD 0
+IceReadData32\^(\^\fIice_conn\fP, \fIswap\fP\^, \fIbytes\fP\^, \fIpdata\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ Bool \fIswap\fP\^;
+.br
+ int \fIbytes\fP\^;
+.br
+ long *\fIpdata\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIswap\fP 1i
+If
+.PN True,
+the values will be byte swapped.
+.IP \fIbytes\fP 1i
+The number of bytes to read.
+.IP \fIpdata\fP 1i
+The data is read into this user supplied buffer.
+.LP
+.eM
+.sp
+To force 32-bit or 64-bit alignment, use
+.PN IceReadPad .
+A maximum of 7 pad bytes can be specified.
+.sM
+.FD 0
+IceReadPad\^(\^\fIice_conn\fP, \fIbytes\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ int \fIbytes\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIbytes\fP 1i
+The number of pad bytes.
+.LP
+.eM
+.NH 1
+Error Handling
+.XS
+\*(SN Error Handling
+.XE
+.LP
+There are two default error handlers in ICElib:
+.IP \(bu 5
+One to handle typically fatal conditions (for example,
+a connection dying because a machine crashed)
+.IP \(bu 5
+One to handle ICE-specific protocol errors
+.LP
+These error handlers can be changed to user-supplied routines if you
+prefer your own error handling and can be changed as often as you like.
+.sp
+.LP
+To set the ICE error handler, use
+.PN IceSetErrorHandler .
+.sM
+.FD 0
+IceErrorHandler IceSetErrorHandler\^(\^\fIhandler\fP\^)
+.br
+ IceErrorHandler \fIhandler\fP\^;
+.FN
+.IP \fIhandler\fP 1i
+The ICE error handler.
+You should pass NULL to restore the default handler.
+.LP
+.eM
+.PN IceSetErrorHandler
+returns the previous error handler.
+.LP
+The ICE error handler is invoked when an unexpected ICE protocol
+error (major opcode 0) is encountered. The action of the default
+handler is to print an explanatory message to
+.PN stderr
+and if the severity is fatal, call
+.PN exit
+with a nonzero value. If exiting
+is undesirable, the application should register its own error handler.
+.LP
+Note that errors in other protocol
+domains should be handled by their respective libraries (these libraries
+should have their own error handlers).
+.LP
+An ICE error handler has the type of
+.PN IceErrorHandler .
+.sM
+.FD 0
+typedef void (*IceErrorHandler)();
+
+void ErrorHandler\^(\^\fIice_conn\fP, \fIswap\fP\^, \fIoffending_minor_opcode\fP\^, \fIoffending_sequence_num\fP\^, \fIerror_class\fP\^,
+.br
+ \fIseverity\fP\^, \fIvalues\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ Bool \fIswap\fP\^;
+.br
+ int \fIoffending_minor_opcode\fP\^;
+.br
+ unsigned long \fIoffending_sequence_num\fP\^;
+.br
+ int \fIerror_class\fP\^;
+.br
+ int \fIseverity\fP\^;
+.br
+ IcePointer \fIvalues\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection object.
+.IP \fIswap\fP 1i
+A flag that indicates if the values need byte swapping.
+.IP \fIoffending_minor_opcode\fP 1i
+The ICE minor opcode of the offending message.
+.IP \fIoffending_sequence_num\fP 1i
+The sequence number of the offending message.
+.IP \fIerror_class\fP 1i
+The error class of the offending message.
+.IP \fIseverity\fP 1i
+.PN IceCanContinue ,
+.PN IceFatalToProtocol ,
+or
+.PN IceFatalToConnection .
+.IP \fIvalues\fP 1i
+Any additional error values specific to the minor opcode and class.
+.LP
+.eM
+The following error classes are defined at the ICE level:
+.LP
+.Ds 0
+.PN IceBadMinor
+.PN IceBadState
+.PN IceBadLength
+.PN IceBadValue
+.PN IceBadMajor
+.PN IceNoAuth
+.PN IceNoVersion
+.PN IceSetupFailed
+.PN IceAuthRejected
+.PN IceAuthFailed
+.PN IceProtocolDuplicate
+.PN IceMajorOpcodeDuplicate
+.PN IceUnknownProtocol
+.De
+.LP
+For further information, see
+the \fIInter-Client Exchange Protocol\fP\^ standard.
+.sp
+.LP
+To handle fatal I/O errors, use
+.PN IceSetIOErrorHandler .
+.LP
+.sM
+.FD 0
+IceIOErrorHandler IceSetIOErrorHandler\^(\^\fIhandler\fP\^)
+.br
+ IceIOErrorHandler \fIhandler\fP\^;
+.FN
+.IP \fIhandler\fP 1i
+The I/O error handler.
+You should pass NULL to restore the default handler.
+.LP
+.eM
+.PN IceSetIOErrorHandler
+returns the previous IO error handler.
+.LP
+An ICE I/O error handler has the type of
+.PN IceIOErrorHandler .
+.LP
+.sM
+.FD 0
+typedef void (*IceIOErrorHandler)();
+
+void IOErrorHandler\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection object.
+.LP
+.eM
+There are two ways of handling IO errors in ICElib:
+.IP \(bu 5
+In the first, the IO error handler does whatever is necessary
+to respond to the IO error and then returns, but it does not call
+.PN IceCloseConnection .
+The ICE connection is given a ``bad IO'' status, and all future reads
+and writes to the connection are ignored. The next time
+.PN IceProcessMessages
+is called it will return a status of
+.PN IceProcessMessagesIOError .
+At that time, the application should call
+.PN IceCloseConnection .
+.IP \(bu 5
+In the second, the IO error handler does call
+.PN IceCloseConnection ,
+and then uses the
+.PN longjmp
+call to get back to the application's main event loop.
+The
+.PN setjmp
+and
+.PN longjmp
+calls may not work properly on all platforms,
+and special care must be taken to avoid memory leaks.
+Therefore, this second model is less desirable.
+.LP
+Before the application I/O error handler is invoked, protocol libraries
+that were interested in being notified of I/O errors will have their
+.PN IceIOErrorProc
+handlers invoked. This handler is set up in the protocol registration
+functions (see
+.PN IceRegisterForProtocolSetup
+and
+.PN IceRegisterForProtocolReply )
+and could be used to clean up
+state specific to the protocol.
+.sp
+.LP
+.sM
+typedef void (*IceIOErrorProc)();
+.LP
+.FD 0
+void IOErrorProc\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection object.
+.LP
+.eM
+Note that every
+.PN IceIOErrorProc
+callback must return. This is required
+because each active protocol must be notified of the broken connection,
+and the application IO error handler must be invoked afterwards.
+.NH 1
+Multi-Threading Support
+.XS
+\*(SN Multi-Threading Support
+.XE
+.LP
+To declare that multiple threads in an application will be using the ICE
+library, use
+.PN IceInitThreads .
+.LP
+.sM
+.FD 0
+Status IceInitThreads\^()
+.FN
+.LP
+.eM
+The
+.PN IceInitThreads
+function must be the first ICElib function a
+multi-threaded program calls. It must complete before any other ICElib
+call is made.
+.PN IceInitThreads
+returns a nonzero status if and only if it was able
+to initialize the threads package successfully.
+It is safe to call
+.PN IceInitThreads
+more than once, although the threads package will only be initialized once.
+.LP
+Protocol libraries layered on top of ICElib will have to lock critical
+sections of code that access an ICE connection (for example, when
+generating messages). Two calls, which are generally implemented as
+macros, are provided:
+.sM
+.FD 0
+IceLockConn\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+.sp
+IceUnlockConn\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection.
+.LP
+.eM
+.sp
+To keep an ICE connection locked across several ICElib calls, applications use
+.PN IceAppLockConn
+and
+.PN IceAppUnlockConn .
+.sM
+.FD 0
+void IceAppLockConn\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection to lock.
+.LP
+.eM
+The
+.PN IceAppLockConn
+function completely locks out other threads using the connection
+until
+.PN IceAppUnlockConn
+is called. Other threads attempting to use ICElib
+calls on the connection will block.
+If the program has not previously called
+.PN IceInitThreads ,
+.PN IceAppLockConn
+has no effect.
+.LP
+.sM
+.FD 0
+void IceAppUnlockConn\^(\^\fIice_conn\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+The ICE connection to unlock.
+.LP
+.eM
+The
+.PN IceAppUnlockConn
+function allows other threads to complete ICElib
+calls on the connection that were blocked by a previous call to
+.PN IceAppLockConn
+from this thread. If the program has not previously called
+.PN IceInitThreads ,
+.PN IceAppUnlockConn
+has no effect.
+.NH 1
+Miscellaneous Functions
+.XS
+\*(SN Miscellaneous Functions
+.XE
+.LP
+To allocate scratch space (for example, when generating
+messages with variable data), use
+.PN IceAllocScratch .
+Each ICE connection has one scratch space associated with it.
+The scratch space starts off as empty and grows as needed.
+The contents of the scratch space is not guaranteed to be preserved
+after any ICElib function is called.
+.LP
+.sM
+.FD 0
+char *IceAllocScratch\^(\^\fIice_conn\fP, \fIsize\fP\^)
+.br
+ IceConn \fIice_conn\fP\^;
+.br
+ unsigned long \fIsize\fP\^;
+.FN
+.IP \fIice_conn\fP 1i
+A valid ICE connection object.
+.IP \fIsize\fP 1i
+The number of bytes required.
+.LP
+.eM
+Note that the memory returned by
+.PN IceAllocScratch
+should not be freed by the caller.
+The ICE library will free the memory when the ICE connection is closed.
+.NH 1
+Acknowledgements
+.XS
+\*(SN Acknowledgements
+.XE
+.LP
+Thanks to Bob Scheifler for his thoughtful input on the design
+of the ICE library. Thanks also to Jordan Brown, Larry Cable, Donna Converse,
+Clive Feather, Stephen Gildea, Vania Joloboff, Kaleb Keithley,
+Stuart Marks, Hiro Miyamoto, Ralph Swick, Jim VanGilder, and Mike Wexler.
+.bp
+.XS
+Appendix A \- Authentication Utility Functions
+.XE
+.ce 10
+.sp 5
+\s+2\fBAppendix A\fP\s-2
+.sp
+\s+1\fBAuthentication Utility Functions\fP\s-1
+.ce 0
+.sp
+.LP
+As discussed in this document, the means by which authentication data
+is obtained by the ICE library (for
+.PN ConnectionSetup
+messages or
+.PN ProtocolSetup
+messages) is implementation-dependent.\(dg
+.FS \(dg
+The X Consortium's ICElib implementation assumes the presence of an
+ICE authority file.
+.FE
+.LP
+This appendix describes some utility functions that manipulate an
+ICE authority file. The authority file can be used to pass authentication
+data between clients.
+.LP
+The basic operations on the \&.ICEauthority file are:
+.IP \(bu 5
+Get file name
+.IP \(bu 5
+Lock
+.IP \(bu 5
+Unlock
+.IP \(bu 5
+Read entry
+.IP \(bu 5
+Write entry
+.IP \(bu 5
+Search for entry
+.LP
+These are fairly low-level operations, and it is expected that a program,
+like "iceauth", would
+exist to add, remove, and display entries in the file.
+.LP
+In order to use these utility functions, the
+.Pn < X11/ICE/ICEutil.h >
+header file must be included.
+.LP
+An entry in the \&.ICEauthority file is defined by the following data structure:
+.LP
+.sM
+.Ds 0
+.TA .5i
+.ta .5i
+typedef struct {
+ char *protocol_name;
+ unsigned short protocol_data_length;
+ char *protocol_data;
+ char *network_id;
+ char *auth_name;
+ unsigned short auth_data_length;
+ char *auth_data;
+} IceAuthFileEntry;
+.De
+.LP
+.eM
+The protocol_name member is either ``ICE'' for connection setup authentication
+or the subprotocol name, such as ``XSMP''. For each entry, protocol specific
+data can be specified in the protocol_data member. This can be used
+to search for old entries that need to be removed from the file.
+.LP
+The network_id member is the network ID of the client accepting authentication
+(for example, the network ID of a session manager).
+A network ID has the following form:
+.TS
+lw(0.25i) lw(2.5i) lw(1i).
+ tcp/<hostname>:<portnumber> or
+ decnet/<hostname>::<objname> or
+ local/<hostname>:<path>
+.TE
+.LP
+The auth_name member is the name of the authentication method.
+The auth_data member is the actual authentication data,
+and the auth_data_length member is the number of bytes in the data.
+.sp
+.LP
+To obtain the default authorization file name, use
+.PN IceAuthFileName .
+.sM
+.FD 0
+char *IceAuthFileName\^()
+.FN
+.LP
+.eM
+If the ICEAUTHORITY environment variable if set, this value is returned.
+Otherwise, the default authorization file name is $HOME/\&.ICEauthority.
+This name is statically allocated and should not be freed.
+.LP
+To synchronously update the authorization file, the file must
+be locked with a call to
+.PN IceLockAuthFile .
+This function takes advantage of the fact that the
+.PN link
+system call will fail if the name of the new link already exists.
+.sM
+.FD 0
+int IceLockAuthFile\^(\^\fIfile_name\fP, \fIretries\fP\^, \fItimeout\fP\^, \fIdead\fP\^)
+.br
+ char *\fIfile_name\fP\^;
+.br
+ int \fIretries\fP\^;
+.br
+ int \fItimeout\fP\^;
+.br
+ long \fIdead\fP\^;
+.FN
+.IP \fIfile_name\fP 1i
+The authorization file to lock.
+.IP \fIretries\fP 1i
+The number of retries.
+.IP \fItimeout\fP 1i
+The number of seconds before each retry.
+.IP \fIdead\fP 1i
+If a lock already exists that is the specified dead seconds old,
+it is broken.
+A value of zero is used to unconditionally break an old lock.
+.LP
+.eM
+One of three values is returned:
+.IP \(bu 5
+.PN IceAuthLockSuccess
+\- the lock succeeded.
+.IP \(bu 5
+.PN IceAuthLockError
+\- a system error occurred, and
+.PN errno
+may prove useful.
+.IP \(bu 5
+.PN IceAuthLockTimeout
+\- the specified number of retries failed.
+.LP
+.sp
+To unlock an authorization file, use
+.PN IceUnlockAuthFile .
+.sM
+.FD 0
+void IceUnlockAuthFile\^(\^\fIfile_name\fP\^)
+.br
+ char *\fIfile_name\fP\^;
+.FN
+.IP \fIfile_name\fP 1i
+The authorization file to unlock.
+.LP
+.eM
+.LP
+To read the next entry in an authorization file, use
+.PN IceReadAuthFileEntry .
+.sM
+.FD 0
+IceAuthFileEntry *IceReadAuthFileEntry\^(\^\fIauth_file\fP\^)
+.br
+ FILE *\fIauth_file\fP\^;
+.FN
+.IP \fIauth_file\fP 1i
+The authorization file.
+.LP
+.eM
+Note that it is the responsibility of the application to open the file
+for reading before calling this function. If an error is encountered,
+or there are no more entries to read, NULL is returned.
+.LP
+Entries should be free with a call to
+.PN IceFreeAuthFileEntry .
+.LP
+.sp
+To write an entry in an authorization file, use
+.PN IceWriteAuthFileEntry .
+.sM
+.FD 0
+Status IceWriteAuthFileEntry\^(\^\fIauth_file\fP, \fIentry\fP\^)
+.br
+ FILE *\fIauth_file\fP\^;
+.br
+ IceAuthFileEntry *\fIentry\fP\^;
+.FN
+.IP \fIauth_file\fP 1i
+The authorization file.
+.IP \fIentry\fP 1i
+The entry to write.
+.LP
+.eM
+Note that it is the responsibility of the application to open the file
+for writing before calling this function. The function returns a nonzero
+status if the operation was successful.
+.LP
+.sp
+To search the default authorization file for an entry that matches a given
+protocol_name/network_id/auth_name tuple, use
+.PN IceGetAuthFileEntry .
+.sM
+.FD 0
+IceAuthFileEntry *IceGetAuthFileEntry\^(\^\fIprotocol_name\fP, \fInetwork_id\fP\^, \fIauth_name\fP\^)
+.br
+ char *\fIprotocol_name\fP\^;
+.br
+ char *\fInetwork_id\fP\^;
+.br
+ char *\fIauth_name\fP\^;
+.FN
+.IP \fIprotocol_name\fP 1i
+The name of the protocol to search on.
+.IP \fInetwork_id\fP 1i
+The network ID to search on.
+.IP \fIauth_name\fP 1i
+The authentication method to search on.
+.LP
+.eM
+If
+.PN IceGetAuthFileEntry
+fails to find such an entry, NULL is returned.
+.LP
+.sp
+To free an entry returned by
+.PN IceReadAuthFileEntry
+or
+.PN IceGetAuthFileEntry ,
+use
+.PN IceFreeAuthFileEntry .
+.sM
+.FD 0
+void IceFreeAuthFileEntry\^(\^\fIentry\fP\^)
+.br
+ IceAuthFileEntry *\fIentry\fP\^;
+.FN
+.IP \fIentry\fP 1i
+The entry to free.
+.LP
+.eM
+.bp
+.XS
+Appendix B \- MIT-MAGIC-COOKIE-1 Authentication
+.XE
+.ce 10
+.sp 5
+\s+2\fBAppendix B\fP\s-2
+.sp
+\s+1\fBMIT-MAGIC-COOKIE-1 Authentication\fP\s-1
+.ce 0
+.sp
+.LP
+The X Consortium's ICElib implementation supports a simple
+MIT-MAGIC-COOKIE-1 authentication scheme using the authority file utilities
+described in Appendix A.
+.LP
+In this model, an application, such as a session manager, obtains a
+magic cookie by calling
+.PN IceGenerateMagicCookie ,
+and then stores it in the user's local \&.ICEauthority file
+so that local clients can connect. In order to allow remote clients to
+connect, some remote execution mechanism should be used to store the
+magic cookie in the user's \&.ICEauthority file on a remote machine.
+.LP
+In addition to storing the magic cookie in the \&.ICEauthority file, the
+application needs to call the
+.PN IceSetPaAuthData
+function in order to store the magic cookie in memory. When it comes time
+for the MIT-MAGIC-COOKIE-1 authentication procedure to accept or reject the
+connection, it will compare the magic cookie presented by the requestor to
+the magic cookie in memory.
+.LP
+.sM
+.FD 0
+char *IceGenerateMagicCookie\^(\^\fIlength\fP\^)
+.br
+ int \fIlength\fP\^;
+.FN
+.IP \fIlength\fP 1i
+The desired length of the magic cookie.
+.LP
+.eM
+.LP
+The magic cookie returned will be null-terminated. If memory can not be
+allocated for the magic cookie, the function will return NULL.
+Otherwise, the magic cookie should be freed with a call to
+.PN free .
+.LP
+.sp
+To store the authentication data in memory, use
+.PN IceSetPaAuthData .
+Currently, this function is only used for MIT-MAGIC-COOKIE-1
+authentication, but it may be used for additional authentication
+methods in the future.
+.sM
+.FD 0
+void IceSetPaAuthData\^(\^\fInum_entries\fP, \fIentries\fP\^)
+.br
+ int \fInum_entries\fP\^;
+.br
+ IceAuthDataEntry *\fIentries\fP\^;
+.FN
+.IP \fInum_entries\fP 1i
+The number of authentication data entries.
+.IP \fIentries\fP 1i
+The list of authentication data entries.
+.LP
+.eM
+Each entry has associated with it a protocol name
+(for example, ``ICE'' for ICE connection setup authentication,
+``XSMP'' for session management authentication), a network ID for the
+``accepting'' client, an authentication name (for example, MIT-MAGIC-COOKIE-1),
+and authentication data. The ICE library
+will merge these entries with previously set entries, based on the
+(protocol_name, network_id, auth_name) tuple.
+.LP
+.sM
+.Ds 0
+.TA .5i
+.ta .5i
+typedef struct {
+ char *protocol_name;
+ char *network_id;
+ char *auth_name;
+ unsigned short auth_data_length;
+ char *auth_data;
+} IceAuthDataEntry;
+.De
+.LP
+.eM
+.EH ''''
+.OH ''''
+.YZ 3
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..e3cbc9d
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = ice.ms ICElib.ms
diff --git a/doc/ice.ms b/doc/ice.ms
new file mode 100644
index 0000000..7d31ea6
--- /dev/null
+++ b/doc/ice.ms
@@ -0,0 +1,1878 @@
+.\" Use tbl macros.t ice.ms | troff -ms
+.\" $XdotOrg: xc/doc/specs/ICE/ice.ms,v 1.2 2004/04/23 18:42:16 eich Exp $
+.\"
+.\" TODO:
+.\" Think about connector/listener originator/answerer terminology.
+.EH ''''
+.OH ''''
+.EF ''''
+.OF ''''
+.\"
+.\" Disable hyphenation. I hate it.
+.hy 0
+.de hy
+..
+.\" A couple of macros to standardize things and make them
+.\" easy to type.
+.de Ss \" Begin state - .Ss <state name>
+.KS
+.LP
+\fC\\$1\fP\^:
+.br
+..
+.de St \" Transition - .St "condition" message <new state>
+.RS
+\\$1
+.PN \\$2
+\(-> \fC\\$3\fP
+.RE
+..
+.de Se \" End state - .Se
+.LP
+.KE
+..
+.de Ms \" Start message header - .Ms messagename
+.sM
+.PN \\$1
+.RS
+..
+.de Mf \" Field in message - .Mf name; types follow on separate line(s)
+.\".br
+.IP "\fI\\$1\fP\^:" "\w'\fI\\$1\fP\^:'u+1"
+..
+.de Mc \" Field Continuation - .Mc; description follows on separate line(s)
+.br
+.\" \h'1i'
+..
+.de Ma \" Message addendum - .Ma title; contents follow
+.IP "\\$1:" "\w'\\$1:'u+1"
+..
+.de Me \" End of message header - .Me
+.RE
+.LP
+.eM
+..
+.de Es \" Start Encoding - .Es messagename
+.KS
+.LP
+.nf
+.PN \\$1
+.ta .2i .5i 2.0i
+..
+.de Ee \" End Encoding - .Ee
+.fi
+.LP
+.KE
+..
+.\"
+.\" --- cT --- centered title; centers $1, adds TOC entry unless $2 is "no"
+.\"
+.de cT
+\\& \" filler so that the following .sp really leaves a space
+.sp 1
+.ce 1
+\\s+1\\fB\\$1\\fP\\s-1
+.sp 1
+.if !'\\$2'no' \{\
+.XS \\n(PN
+\\$1
+.XE
+\}
+..
+.ps 10
+.nr PS 10
+\&
+.TL
+\s+2\fBInter-Client Exchange (ICE) Protocol\fP\s-2
+.sp
+Version 1.1
+.sp
+X Consortium Standard
+.sp
+X Version 11, Release 6.8
+
+
+
+.AU
+Robert Scheifler
+.AI
+X Consortium, Inc.
+.AU
+Jordan Brown
+.AI
+Quarterdeck Office Systems
+
+
+
+.AB
+.LP
+There are numerous possible protocols that can be used for communication
+among clients. They have many similarities and common needs, including
+authentication,
+version negotiation,
+data typing, and
+connection management. The
+.I
+Inter-Client Exchange
+.R
+(ICE) protocol is intended to provide a framework for building such
+protocols. Using ICE reduces the complexity of designing new protocols and
+allows the sharing of many aspects of the implementation.
+.AE
+.LP
+.bp
+\&
+.sp 8
+.LP
+.DS C
+.if n Copyright (c) 1993, 1994 X Consortium
+.if t Copyright \(co 1993, 1994 X Consortium
+.DE
+.sp 3
+.LP
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the ``Software''), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+.LP
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+.LP
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+.LP
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+.sp 5
+X Window System is a trademark of The Open Group.
+.EH '\fBInter-Client Exchange Protocol\fP''\fBX11, Release 6.8\fP'
+.OH '\fBInter-Client Exchange Protocol\fP''\fBX11, Release 6.8\fP'
+.bp 1
+.EF ''\fB % \fP''
+.OF ''\fB % \fP''
+.nH 1 "Purpose and Goals"
+.LP
+In discussing a variety of protocols \(em existing, under development, and
+hypothetical \(em it was noted that they have many elements in common. Most
+protocols need mechanisms for authentication, for
+version negotiation,
+and for setting up and taking down connections. There are also
+cases where the same two parties need to talk to each other using multiple
+protocols. For example, an embedding relationship between two parties is
+likely to require the simultaneous use of session management, data transfer,
+focus negotiation, and command notification protocols. While these are
+logically separate protocols, it is desirable for them to share as many
+pieces of implementation as possible.
+.LP
+The
+.I
+Inter-Client Exchange
+.R
+(ICE) protocol provides a generic framework for building protocols on top of
+reliable, byte-stream transport connections. It provides basic mechanisms
+for setting up and shutting down connections, for performing authentication,
+for negotiating
+versions,
+and for reporting errors. The
+protocols running within an ICE connection are referred to here as
+.I subprotocols.
+ICE provides facilities for each subprotocol to do its own version
+negotiation, authentication, and error reporting. In addition, if two
+parties are communicating using several different subprotocols, ICE will
+allow them to share the same transport layer connection.
+.nH 1 "Overview of the protocol"
+.LP
+Through some mechanism outside ICE, two parties make themselves known to
+each other and agree that they would like to communicate using an ICE
+subprotocol. ICE assumes that this negotation includes some notion by which
+the parties will decide which is the \*Qoriginating\*U party and which is
+the \*Qanswering\*U party. The negotiation will also need to provide the
+originating party with a name or address of the answering party. Examples
+of mechanisms by which parties can make themselves known to each other are
+the X selection mechanism, environment
+variables, and shared files.
+.LP
+The originating party first determines whether there is an existing ICE
+connection between the two parties. If there is, it can re-use the existing
+connection and move directly to the setup of the subprotocol. If no ICE
+connection exists, the originating party will open a transport connection to
+the answering party and will start ICE connection setup.
+.LP
+The ICE connection setup dialog consists of three major parts: byte order
+exchange, authentication, and connection information exchange. The first
+message in each direction is a
+.PN ByteOrder
+message telling which byte order will be used by the sending party in
+messages that it sends. After that, the originating party sends a
+.PN ConnectionSetup
+message giving information about itself (vendor name and release number) and
+giving a list of ICE version numbers it is capable of supporting and a list
+of authentication schemes it is willing to accept. Authentication is
+optional. If no authentication is required, the answering party responds
+with a
+.PN ConnectionReply
+message giving information about itself, and the connection setup is complete.
+.LP
+If the connection setup is to be authenticated, the answering party will
+respond with an
+.PN AuthenticationRequired
+message instead of a
+.PN ConnectionReply
+message. The parties then exchange
+.PN AuthenticationReply
+and
+.PN AuthenticationNextPhase
+messages until authentication is complete, at which time the answering party
+finally sends its
+.PN ConnectionReply
+message.
+.LP
+Once an ICE connection is established (or an existing connection reused),
+the originating party starts subprotocol negotiation by sending a
+.PN ProtocolSetup
+message. This message gives the name of the subprotocol that the parties
+have agreed to use, along with the ICE major opcode that the originating
+party has assigned to that subprotocol. Authentication can also occur for
+the subprotocol, independently of authentication for the connection.
+Subprotocol authentication is optional. If there is no subprotocol
+authentication, the answering party responds with a
+.PN ProtocolReply
+message, giving the ICE major opcode that it has assigned
+for the subprotocol.
+.LP
+Subprotocols are authenticated independently of each other, because they may
+have differing security requirements. If there is authentication for this
+particular subprotocol, it takes place before the answering party emits the
+.PN ProtocolReply
+message, and it uses the
+.PN AuthenticationRequired ,
+.PN AuthenticationReply ,
+and
+.PN AuthenticationNextPhase
+messages, just as for the connection authentication. Only when subprotocol
+authentication is complete does the answering party send its
+.PN ProtocolReply
+message.
+.LP
+When a subprotocol has been set up and authenticated, the two parties can
+communicate using messages defined by the subprotocol. Each message has two
+opcodes: a major opcode and a minor opcode. Each party will send messages
+using the major opcode it has assigned in its
+.PN ProtocolSetup
+or
+.PN ProtocolReply
+message. These opcodes will, in general, not be the same. For a particular
+subprotocol, each party will need to keep track of two major opcodes: the
+major opcode it uses when it sends messages, and the major opcode it expects
+to see in messages it receives. The minor opcode values and semantics are
+defined by each individual subprotocol.
+.LP
+Each subprotocol will have one or more messages whose semantics are that the
+subprotocol is to be shut down. Whether this is done unilaterally or is
+performed through negotiation is defined by each subprotocol. Once a
+subprotocol is shut down, its major opcodes are removed from
+use; no further messages on this subprotocol should be sent until the
+opcode is reestablished with
+.PN ProtocolSetup .
+.LP
+ICE has a facility to negotiate the closing of the connection when there are
+no longer any active subprotocols. When either party decides that no
+subprotocols are active, it can send a
+.PN WantToClose
+message. If the other party agrees to close the connection, it can simply
+do so. If the other party wants to keep the connection open, it can
+indicate its desire by replying with a
+.PN NoClose
+message.
+.\" XXX - Note that it's likely that both parties will WantToClose at once.
+.LP
+It should be noted that the party that initiates the connection isn't
+necessarily the same as the one that initiates setting up a subprotocol.
+For example, suppose party A connects to party B. Party A will issue the
+.PN ConnectionSetup
+message and party B will respond with a
+.PN ConnectionReply
+message. (The authentication steps are omitted here for brevity.)
+Typically, party A will also issue the
+.PN ProtocolSetup
+message and expect a
+.PN ProtocolReply
+from party B. Once the connection is established, however, either party may
+initiate the negotiation of a subprotocol. Continuing this example, party B
+may decide that it needs to set up a subprotocol for communication with
+party A. Party B would issue the
+.PN ProtocolSetup
+message and expect a
+.PN ProtocolReply
+from party A.
+.nH 1 "Data Types"
+.LP
+ICE messages contain several types of data. Byte order is negotiated in
+the initial connection messages; in general data is sent in the sender's
+byte order and the receiver is required to swap it appropriately.
+In order to support 64-bit machines, ICE messages
+are padded to multiples of 8 bytes. All messages are designed so that
+fields are \*Qnaturally\*U aligned on 16-, 32-, and 64-bit boundaries.
+The following formula gives the number of bytes necessary
+to pad \fIE\fP bytes to the next multiple of \fIb\fP\^:
+.DS
+pad(\fIE\fP, \fIb\fP\^) = (\fIb\fP \- (\fIE\fP mod \fIb\fP\^)) mod \fIb\fP
+.DE
+.nH 2 "Primitive Types"
+.LP
+.TS H
+expand;
+lB lB
+l lw(3.5i).
+_
+.sp 6p
+Type Name Description
+.sp 6p
+_
+.sp 6p
+.TH
+.R
+CARD8 8-bit unsigned integer
+CARD16 16-bit unsigned integer
+CARD32 32-bit unsigned integer
+BOOL T{
+.PN False
+or
+.PN True
+T}
+LPCE T{
+A character from the X Portable Character Set in Latin Portable Character
+Encoding
+T}
+.sp 6p
+_
+.TE
+.KS
+.nH 2 "Complex Types"
+.LP
+.TS H
+expand;
+lB lB
+l lw(3.5i).
+_
+.sp 6p
+Type Name Type
+.sp 6p
+_
+.sp 6p
+.TH
+.R
+VERSION [Major, minor: CARD16]
+STRING LISTofLPCE
+.sp 6p
+_
+.TE
+.KE
+LISTof<type> denotes a counted collection of <type>. The exact encoding
+varies depending on the context; see the encoding section.
+.nH 1 "Message Format"
+.LP
+All ICE messages include the following information:
+.TS H
+expand;
+cB lB
+
+l lw(3.5i).
+_
+.sp 6p
+Field Type Description
+.sp 6p
+_
+.sp 6p
+.TH
+CARD8 protocol major opcode
+CARD8 protocol minor opcode
+CARD32 length of remaining data in 8-byte units
+.sp 6p
+_
+.TE
+.LP
+The fields are as follows:
+.LP
+Protocol major opcode
+.RS
+This specifies what subprotocol the message is intended for. Major opcode
+0 is reserved for ICE control messages. The major opcodes of other
+subprotocols are dynamically assigned and exchanged at protocol
+negotiation time.
+.RE
+.LP
+Protocol minor opcode
+.RS
+This specifies what protocol-specific operation is to be performed.
+Minor opcode 0 is reserved for Errors; other values are protocol-specific.
+.RE
+.LP
+Length of data in 8-byte units
+.RS
+This specifies the length of the information following the first 8 bytes.
+Each message-type has a different format, and will need to be separately
+length-checked against this value. As every data item has either an
+explicit length, or an implicit length, this can be easily accomplished.
+Messages that have too little or too much data indicate a serious
+protocol failure, and should result in a
+.PN BadLength
+error.
+.RE
+.nH 1 "Overall Protocol Description"
+.LP
+Every message sent in a given direction has an implicit sequence number,
+starting with 1. Sequence numbers are global to the connection; independent
+sequence numbers are \fInot\fP maintained for each protocol.
+.LP
+Messages of a given major-opcode (i.e., of a given protocol) must be
+responded to (if a response is called for) in order by the receiving party.
+Messages from different protocols can be responded to in arbitrary order.
+.LP
+Minor opcode 0 in every protocol is for reporting errors. At most one error
+is generated per request. If more than one error condition is encountered
+in processing a request, the choice of which error is returned is
+implementation-dependent.
+.Ms Error
+.Mf offending-minor-opcode
+CARD8
+.Mf severity
+.Pn { CanContinue ,
+.PN FatalToProtocol ,
+.PN FatalToConnection }
+.Mf sequence-number
+CARD32
+.Mf class
+CARD16
+.Mf value(s)
+<dependent on major/minor opcode and class>
+.Me
+This message is sent to report an error in response to a message
+from any protocol.
+The
+.PN Error
+message
+exists in all protocol major-opcode spaces; it
+is minor-opcode zero in every protocol. The minor opcode of the
+message that caused the error is reported, as well as the sequence
+number of that message.
+The severity indicates the sender's behavior following
+the identification of the error.
+.PN CanContinue
+indicates the sender is willing to accept additional messages for this
+protocol.
+.PN FatalToProcotol
+indicates the sender is unwilling to accept further messages for this
+protocol but that messages for other protocols may be accepted.
+.PN FatalToConnection
+indicates the sender is unwilling to accept any further
+messages for any protocols on the connection. The sender
+is required to conform to specified severity conditions
+for generic and ICE (major opcode 0) errors; see Sections 6.1
+and 6.2.
+The class defines the generic class of
+error. Classes are specified separately for each protocol (numeric
+values can mean different things in different protocols). The error
+values, if any, and their types vary with the specific error class
+for the protocol.
+.LP
+.\" XXX
+.\" (Asynchronous errors \(em errors not associated with a previous
+.\" message??? If so, offending-minor and sequence = 0.)
+.nH 1 "ICE Control Subprotocol \(em Major Opcode 0"
+.LP
+Each of the ICE control opcodes is described below.
+Most of the messages have additional information included beyond the
+description above. The additional information is appended to the message
+header and
+the length field is computed accordingly.
+.LP
+In the following message descriptions, \*QExpected errors\*U indicates
+errors that may occur in the normal course of events. Other errors
+(in particular
+.PN BadMajor ,
+.PN BadMinor ,
+.PN BadState ,
+.PN BadLength ,
+.PN BadValue ,
+.PN ProtocolDuplicate ,
+and
+.PN MajorOpcodeDuplicate )
+might occur, but generally indicate a serious implementation failure on
+the part of the
+errant
+peer.
+.Ms ByteOrder
+.Mf byte-order
+.Pn { MSBfirst ,
+.PN LSBfirst }
+.Me
+Both parties must send this message before sending any other,
+including errors. This message specifies the byte order that
+will be used on subsequent messages sent by this party.
+.LP
+Note: If the receiver detects an error in this message,
+it must be sure to send its own
+.PN ByteOrder
+message before sending the
+.PN Error .
+.Ms ConnectionSetup
+.Mf versions
+LISTofVERSION
+.Mf must-authenticate
+BOOL
+.Mf authentication-protocol-names
+LISTofSTRING
+.Mf vendor
+STRING
+.Mf release
+STRING
+.LP
+.Ma "Responses"
+.PN ConnectionReply ,
+.PN AuthenticationRequired .
+(See note)
+.Ma "Expected errors"
+.PN NoVersion ,
+.PN SetupFailed ,
+.PN NoAuthentication ,
+.PN AuthenticationRejected ,
+.Mc
+.PN AuthenticationFailed .
+.Me
+The party that initiates the connection
+(the
+one that does the \*Qconnect()\*U)
+must send this
+message
+as the second message (after
+.PN ByteOrder )
+on startup.
+.LP
+Versions gives a list, in decreasing order of preference, of the
+protocol versions this party is capable of speaking. This document
+specifies major version 1, minor version 0.
+.LP
+If must-authenticate is
+.PN True ,
+the initiating party demands authentication; the accepting party \fImust\fP
+pick an authentication scheme and use it. In this case, the only valid
+response is
+.PN AuthenticationRequired .
+.LP
+If must-authenticate is
+.PN False ,
+the accepting party may choose an authentication mechanism, use a
+host-address-based authentication scheme, or skip authentication.
+When must-authenticate is
+.PN False ,
+.PN ConnectionReply
+and
+.PN AuthenticationRequired
+are both valid responses. If a host-address-based authentication scheme is
+used,
+.PN AuthenticationRejected
+and
+.PN AuthenticationFailed
+errors are possible.
+.LP
+Authentication-protocol-names specifies a (possibly null, if
+must-authenticate is
+.PN False )
+list of authentication protocols the party is willing to perform. If
+must-authenticate is
+.PN True ,
+presumably the party will offer only authentication mechanisms
+allowing mutual authentication.
+.LP
+Vendor gives the name of the vendor of this ICE implementation.
+.LP
+Release gives the release identifier of this ICE implementation.
+.LP
+.Ms AuthenticationRequired
+.Mf authentication-protocol-index
+CARD8
+.Mf data
+<specific to authentication protocol>
+.LP
+.Ma "Response"
+.PN AuthenticationReply .
+.Ma "Expected errors"
+.PN AuthenticationRejected ,
+.PN AuthenticationFailed .
+.Me
+This message is sent in response to a
+.PN ConnectionSetup
+or
+.PN ProtocolSetup
+message to specify that authentication is to be done and what authentication
+mechanism is to be used.
+.LP
+The authentication protocol is specified by a 0-based index into the list
+of names given in the
+.PN ConnectionSetup
+or
+.PN ProtocolSetup .
+Any protocol-specific data that might be required is also sent.
+.Ms AuthenticationReply
+.Mf data
+<specific to authentication protocol>
+.LP
+.Ma "Responses"
+.PN AuthenticationNextPhase ,
+.PN ConnectionReply ,
+.PN ProtocolReply .
+.Ma "Expected errors"
+.PN AuthenticationRejected ,
+.PN AuthenticationFailed ,
+.PN SetupFailed .
+.Me
+This message is sent in response to an
+.PN AuthenticationRequired
+or
+.PN AuthenticationNextPhase
+message, to
+supply authentication data as defined by the authentication protocol
+being used.
+.LP
+Note that this message is sent by the party that initiated the current
+negotiation \(em the party that sent the
+.PN ConnectionSetup
+or
+.PN ProtocolSetup
+message.
+.LP
+.PN AuthenticationNextPhase
+indicates that more is to be done to complete the authentication.
+If the authentication is complete,
+.PN ConnectionReply
+is appropriate if the current authentication handshake is the result of a
+.PN ConnectionSetup ,
+and a
+.PN ProtocolReply
+is appropriate if it is the result of a
+.PN ProtocolSetup .
+.Ms AuthenticationNextPhase
+.Mf data
+<specific to authentication protocol>
+.LP
+.Ma "Response"
+.PN AuthenticationReply .
+.Ma "Expected errors"
+.PN AuthenticationRejected ,
+.PN AuthenticationFailed .
+.Me
+This message is sent in response to an
+.PN AuthenticationReply
+message, to supply authentication data as defined by the authentication
+protocol being used.
+.Ms ConnectionReply
+.Mf version-index
+CARD8
+.Mf vendor
+STRING
+.Mf release
+STRING
+.Me
+This message is sent in response to a
+.PN ConnectionSetup
+or
+.PN AuthenticationReply
+message to indicate that the authentication handshake is complete.
+.LP
+Version-index gives a 0-based index into the list of versions offered in
+the
+.PN ConnectionSetup
+message; it specifies the version of the ICE protocol that both parties
+should speak for the duration of the connection.
+.LP
+Vendor gives the name of the vendor of this ICE implementation.
+.LP
+Release gives the release identifier of this ICE implementation.
+.Ms ProtocolSetup
+.Mf protocol-name
+STRING
+.Mf major-opcode
+CARD8
+.Mf versions
+LISTofVERSION
+.Mf vendor
+STRING
+.Mf release
+STRING
+.Mf must-authenticate
+BOOL
+.Mf authentication-protocol-names
+LISTofSTRING
+.LP
+.Ma "Responses"
+.PN AuthenticationRequired ,
+.PN ProtocolReply .
+.Ma "Expected errors"
+.PN UnknownProtocol ,
+.PN NoVersion ,
+.PN SetupFailed ,
+.PN NoAuthentication ,
+.Mc
+.PN AuthenticationRejected ,
+.PN AuthenticationFailed .
+.Me
+This message is used to initiate negotiation of
+a protocol and establish any authentication
+specific to it.
+.LP
+Protocol-name gives the name of the protocol the party wishes
+to speak.
+.LP
+Major-opcode gives the opcode that the party will use in messages
+it sends.
+.LP
+Versions gives a list of version numbers, in decreasing order of
+preference, that the party is willing to speak.
+.LP
+Vendor and release are identification strings with semantics defined
+by the specific protocol being negotiated.
+.LP
+If must-authenticate is
+.PN True ,
+the initiating party demands authentication; the accepting party \fImust\fP
+pick an authentication scheme and use it. In this case, the only valid
+response is
+.PN AuthenticationRequired .
+.LP
+If must-authenticate is
+.PN False ,
+the accepting party may choose an authentication mechanism, use a
+host-address-based authentication scheme, or skip authentication.
+When must-authenticate is
+.PN False ,
+.PN ProtocolReply
+and
+.PN AuthenticationRequired
+are both valid responses. If a host-address-based authentication scheme is
+used,
+.PN AuthenticationRejected
+and
+.PN AuthenticationFailed
+errors are possible.
+.LP
+Authentication-protocol-names specifies a (possibly null, if
+must-authenticate is
+.PN False )
+list of authentication protocols the party is willing to perform. If
+must-authenticate is
+.PN True ,
+presumably the party will offer only authentication mechanisms
+allowing mutual authentication.
+.Ms ProtocolReply
+.Mf major-opcode
+CARD8
+.Mf version-index
+CARD8
+.Mf vendor
+STRING
+.Mf release
+STRING
+.Me
+This message is sent in response to a
+.PN ProtocolSetup
+or
+.PN AuthenticationReply
+message to indicate that the authentication handshake is complete.
+.LP
+Major-opcode gives the opcode that this party will use in
+messages that it sends.
+.LP
+Version-index gives a 0-based index into the list of versions offered in the
+.PN ProtocolSetup
+message; it specifies the version of the protocol that both
+parties should speak for the duration of the connection.
+.LP
+Vendor and release are identification strings with semantics defined
+by the specific protocol being negotiated.
+.LP
+.Ms Ping
+.Ma "Response"
+.PN PingReply .
+.Me
+This message is used to test if the connection is still functioning.
+.Ms PingReply
+.Me
+This message is sent in response to a
+.PN Ping
+message, indicating that the connection is still functioning.
+.Ms WantToClose
+.Ma "Responses"
+.PN WantToClose ,
+.PN NoClose ,
+.PN ProtocolSetup .
+.Me
+This message is used to initiate a possible close of the connection.
+The sending party has noticed that, as a result of mechanisms specific
+to each protocol, there are no active
+protocols
+left.
+There are
+four possible scenarios arising from this request:
+.IP (1) 5
+The receiving side noticed too, and has already sent a
+.PN WantToClose .
+On receiving a
+.PN WantToClose
+while already attempting to shut down, each party should simply close the
+connection.
+.IP (2)
+The receiving side hasn't noticed, but agrees. It closes
+the connection.
+.IP (3)
+The receiving side has a
+.PN ProtocolSetup
+\*Qin flight,\*U in which case it is to ignore
+.PN WantToClose
+and the party sending
+.PN WantToClose
+is to abandon the shutdown attempt when it receives the
+.PN ProtocolSetup .
+.IP (4)
+The receiving side wants the connection kept open for some
+reason not specified by the ICE protocol, in which case it
+sends
+.PN NoClose .
+.LP
+See the state transition diagram for additional information.
+.Ms NoClose
+.Me
+This message is sent in response to a
+.PN WantToClose
+message to indicate that the responding
+party does not want the connection closed at
+this time. The receiving party should not close the
+connection. Either party may again initiate
+.PN WantToClose
+at some future time.
+.nH 2 "Generic Error Classes"
+.LP
+These errors should be used by all protocols, as applicable.
+For ICE (major opcode 0),
+.PN FatalToProtocol
+should
+be interpreted as
+.PN FatalToConnection.
+.Ms BadMinor
+.Mf offending-minor-opcode
+<any>
+.Mf severity
+.PN FatalToProtocol
+or
+.PN CanContinue
+(protocol's discretion)
+.Mf values
+(none)
+.Me
+Received a message with an unknown minor opcode.
+.br
+.ne 9
+.Ms BadState
+.Mf offending-minor-opcode
+<any>
+.Mf severity
+.PN FatalToProtocol
+or
+.PN CanContinue
+(protocol's discretion)
+.Mf values
+(none)
+.Me
+Received a message with a valid minor opcode which is not appropriate
+for the current state of the protocol.
+.Ms BadLength
+.Mf offending-minor-opcode
+<any>
+.Mf severity
+.PN FatalToProtocol
+or
+.PN CanContinue
+(protocol's discretion)
+.Mf values
+(none)
+.Me
+Received a message with a bad length. The length of the message is
+longer or shorter than required to contain the data.
+.Ms BadValue
+.Mf offending-minor-opcode
+<any>
+.Mf severity
+.PN CanContinue
+.Mf values
+CARD32 Byte offset to offending value in offending message
+.Mc
+CARD32 Length of offending value
+.Mc
+<varies> Offending value
+.Me
+Received a message with a bad value specified.
+.nH 2 "ICE Error Classes"
+.LP
+These errors are all major opcode 0 errors.
+.Ms BadMajor
+.Mf offending-minor-opcode
+<any>
+.Mf severity
+.PN CanContinue
+.Mf values
+CARD8 Opcode
+.Me
+The opcode given is not one that has been registered.
+.Ms NoAuthentication
+.Mf offending-minor-opcode
+.PN ConnectionSetup ,
+.PN ProtocolSetup
+.Mf severity
+.PN ConnectionSetup
+\(->
+.PN FatalToConnection
+.Mc
+.PN ProtocolSetup
+\(->
+.PN FatalToProtocol
+.Mf values
+(none)
+.Me
+None of the authentication protocols offered are available.
+.Ms NoVersion
+.Mf offending-minor-opcode
+.PN ConnectionSetup ,
+.PN ProtocolSetup
+.Mf severity
+.PN ConnectionSetup
+\(->
+.PN FatalToConnection
+.Mc
+.PN ProtocolSetup
+\(->
+.PN FatalToProtocol
+.Mf values
+(none)
+.Me
+None of the protocol versions offered are available.
+.\" .Ms SetupFailed
+.sM
+.PN SetupFailed
+.RS
+.Mf offending-minor-opcode
+.PN ConnectionSetup ,
+.PN ProtocolSetup ,
+.PN AuthenticationReply
+.Mf severity
+.PN ConnectionSetup
+\(->
+.PN FatalToConnection
+.Mc
+.PN ProtocolSetup
+\(->
+.PN FatalToProtocol
+.Mc
+.PN AuthenticationReply
+\(->
+.PN FatalToConnection
+if authenticating a connection, otherwise
+.PN FatalToProtocol
+.Mf values
+STRING reason
+.Me
+The sending side is unable to accept the
+new connection or new protocol for a reason other than authentication
+failure. Typically this error will be a result of inability to allocate
+additional resources on the sending side. The reason field will give a
+human-interpretable message providing further detail on the type of failure.
+.br
+.Ms AuthenticationRejected
+.Mf offending-minor-opcode
+.PN AuthenticationReply ,
+.PN AuthenticationRequired ,
+.br
+.PN AuthenticationNextPhase
+.Mf severity
+.PN FatalToProtocol
+.Mf values
+STRING reason
+.Me
+Authentication rejected. The peer has failed to properly
+authenticate itself.
+The reason field will give a human-interpretable message
+providing further detail.
+.Ms AuthenticationFailed
+.Mf offending-minor-opcode
+.PN AuthenticationReply ,
+.PN AuthenticationRequired ,
+.br
+.PN AuthenticationNextPhase
+.Mf severity
+.PN FatalToProtocol
+.Mf values
+STRING reason
+.Me
+Authentication failed.
+.PN AuthenticationFailed
+does not imply that the authentication was rejected, as
+.PN AuthenticationRejected
+does. Instead it means that the sender was unable to complete
+the authentication for some other reason. (For instance, it
+may have been unable to contact an authentication server.)
+The reason field will give a human-interpretable message
+providing further detail.
+.br
+.ne 10
+.Ms ProtocolDuplicate
+.Mf offending-minor-opcode
+.PN ProtocolSetup
+.Mf severity
+.PN FatalToProtocol
+(but see note)
+.Mf values
+STRING protocol name
+.Me
+The protocol name was already registered. This is fatal to
+the \*Qnew\*U protocol being set up by
+.PN ProtocolSetup ,
+but it does not affect the existing registration.
+.Ms MajorOpcodeDuplicate
+.Mf offending-minor-opcode
+.PN ProtocolSetup
+.Mf severity
+.PN FatalToProtocol
+(but see note)
+.Mf values
+CARD8 opcode
+.Me
+The major opcode specified was already registered. This is
+fatal to the \*Qnew\*U protocol being set up by
+.PN ProtocolSetup ,
+but it does not affect the existing registration.
+.Ms UnknownProtocol
+.Mf offending-minor-opcode
+.PN ProtocolSetup
+.Mf severity
+.PN FatalToProtocol
+.Mf values
+STRING protocol name
+.Me
+The protocol specified is not supported.
+.nH 1 "State Diagrams"
+.LP
+Here are the state diagrams for the party that initiates the connection:
+.Ss start
+.\" .St "connect to other end, send" ConnectionSetup conn_wait
+.RS
+connect to other end, send
+.PN ByteOrder ,
+.PN ConnectionSetup
+\(-> \fCconn_wait\fP
+.RE
+.Se
+.Ss conn_wait
+.St "receive" ConnectionReply stasis
+.St "receive" AuthenticationRequired conn_auth1
+.St "receive" Error quit
+.St "receive <other>, send" Error quit
+.Se
+.Ss conn_auth1
+.St "if good auth data, send" AuthenticationReply conn_auth2
+.St "if bad auth data, send" Error quit
+.Se
+.Ss conn_auth2
+.St "receive" ConnectionReply stasis
+.St "receive" AuthenticationNextPhase conn_auth1
+.St "receive" Error quit
+.St "receive <other>, send" Error quit
+.Se
+.br
+.ne 22
+Here are top-level state transitions for the party that accepts connections.
+.Ss listener
+.\" .St "accept connection" "" init_wait
+.RS
+accept connection \(-> \fCinit_wait\fP
+.RE
+.Se
+.Ss init_wait
+.\" .St "receive ByteOrder, ConnectionSetup" auth_ask
+.RS
+receive
+.PN ByteOrder ,
+.PN ConnectionSetup
+\(-> \fCauth_ask\fP
+.RE
+.St "receive <other>, send" Error quit
+.Se
+.Ss auth_ask
+.\" .St "send ByteOrder, ConnectionReply" stasis
+.RS
+send
+.PN ByteOrder ,
+.PN ConnectionReply
+\(-> \fCstasis\fP
+.RE
+.St "send" AuthenticationRequired auth_wait
+.St "send" Error quit
+.Se
+.Ss auth_wait
+.St "receive" AuthenticationReply auth_check
+.St "receive <other>, send" Error quit
+.Se
+.Ss auth_check
+.St "if no more auth needed, send" ConnectionReply stasis
+.St "if good auth data, send" AuthenticationNextPhase auth_wait
+.St "if bad auth data, send" Error quit
+.Se
+.sp 1
+Here are the top-level state transitions for all parties after the initial
+connection establishment subprotocol.
+.LP
+Note: this is not quite the truth for branches out from stasis, in
+that multiple conversations can be interleaved on the connection.
+.Ss stasis
+.St "send" ProtocolSetup proto_wait
+.St "receive" ProtocolSetup proto_reply
+.St "send" Ping ping_wait
+.\" .St "receive Ping, send PingReply" stasis
+.RS
+receive
+.PN Ping ,
+send
+.PN PingReply
+\(-> \fCstasis\fP
+.RE
+.St "receive" WantToClose shutdown_attempt
+.St "receive <other>, send" Error stasis
+.St "all protocols shut down, send" WantToClose close_wait
+.Se
+.Ss proto_wait
+.St "receive" ProtocolReply stasis
+.St "receive" AuthenticationRequired give_auth1
+.\" .St "receive Error, give up on this protocol" stasis
+.RS
+receive
+.PN Error ,
+give up on this protocol \(-> \fCstasis\fP
+.RE
+.St "receive" WantToClose proto_wait
+.Se
+.Ss give_auth1
+.St "if good auth data, send" AuthenticationReply give_auth2
+.\" .St "if bad auth data, send Error, give up on this protocol" stasis
+.RS
+if bad auth data, send
+.PN Error ,
+give up on this protocol \(-> \fCstasis\fP
+.RE
+.St "receive" WantToClose give_auth1
+.Se
+.Ss give_auth2
+.St "receive" ProtocolReply stasis
+.St "receive" AuthenticationNextPhase give_auth1
+.\" .St "receive Error, give up on this protocol" stasis
+.RS
+receive
+.PN Error ,
+give up on this protocol \(-> \fCstasis\fP
+.RE
+.St "receive" WantToClose give_auth2
+.Se
+.Ss proto_reply
+.St "send" ProtocolReply stasis
+.St "send" AuthenticationRequired take_auth1
+.\" .St "send Error, give up on this protocol" stasis
+.RS
+send
+.PN Error ,
+give up on this protocol \(-> \fCstasis\fP
+.RE
+.Se
+.Ss take_auth1
+.St "receive" AuthenticationReply take_auth2
+.\" .St "receive Error, give up on this protocol" stasis
+.RS
+receive
+.PN Error ,
+give up on this protocol \(-> \fCstasis\fP
+.RE
+.Se
+.Ss take_auth2
+.\" .St "if good auth data" take_auth3
+.RS
+if good auth data \(-> \fCtake_auth3\fP
+.RE
+.\" .St "if bad auth data, send Error, give up on this protocol" stasis
+.RS
+if bad auth data, send
+.PN Error ,
+give up on this protocol \(-> \fCstasis\fP
+.RE
+.Se
+.Ss take_auth3
+.St "if no more auth needed, send" ProtocolReply stasis
+.St "if good auth data, send" AuthenticationNextPhase take_auth1
+.\" .St "if bad auth data, send Error, give up on this protocol" stasis
+.RS
+if bad auth data, send
+.PN Error ,
+give up on this protocol \(-> \fCstasis\fP
+.RE
+.Se
+.Ss ping_wait
+.St "receive" PingReply stasis
+.Se
+.Ss quit
+.RS
+\(-> close connection
+.RE
+.Se
+.sp 1
+Here are the state transitions for shutting down the connection:
+.Ss shutdown_attempt
+.St "if want to stay alive anyway, send" NoClose stasis
+.\" .St "else" quit
+.RS
+else \(-> \fCquit\fP
+.RE
+.Se
+.Ss close_wait
+.St "receive" ProtocolSetup proto_reply
+.St "receive" NoClose stasis
+.St "receive" WantToClose quit
+.\" .St "connection close" quit
+.RS
+connection close \(-> \fCquit\fP
+.RE
+.Se
+.nH 1 "Protocol Encoding"
+.LP
+In the encodings below, the first column is the number of bytes occupied.
+The second column is either the type (if the value is variable) or the
+actual value. The third column is the description of the value (e.g.,
+the parameter name). Receivers must ignore bytes that are designated
+as unused or pad bytes.
+.LP
+This document describes major version 1, minor version 0 of the ICE protocol.
+.LP
+LISTof<type> indicates some number of repetitions of <type>, with no
+additional padding. The number of repetitions must be specified elsewhere
+in the message.
+.KS
+.nH 2 "Primitive Types"
+.LP
+.TS H
+expand;
+lB lB lB
+l l lw(3.5i).
+_
+.sp 6p
+Type Name Length (bytes) Description
+.sp 6p
+_
+.sp 6p
+.TH
+.R
+CARD8 1 8-bit unsigned integer
+CARD16 2 16-bit unsigned integer
+CARD32 4 32-bit unsigned integer
+LPCE 1 T{
+A character from the X Portable Character Set in Latin Portable Character
+Encoding
+T}
+.sp 6p
+_
+.TE
+.KE
+.KS
+.nH 2 "Enumerations"
+.LP
+.TS H
+expand;
+lB lB lB
+l l lw(3.5i).
+_
+.sp 6p
+Type Name Value Description
+.sp 6p
+_
+.sp 6p
+.TH
+.R
+BOOL 0 T{
+.PN False
+T}
+ 1 T{
+.PN True
+T}
+.sp 6p
+_
+.TE
+.KE
+.KS
+.nH 2 "Compound Types"
+.LP
+.TS H
+expand;
+lB lB lB lB
+l l l lw(3.5i).
+_
+.sp 6p
+Type Name Length (bytes) Type Description
+.sp 6p
+_
+.sp 6p
+.TH
+.R
+VERSION
+ 2 CARD16 Major version number
+ 2 CARD16 Minor version number
+STRING
+ 2 CARD16 length of string in bytes
+ n LISTofLPCE string
+ p unused, p = pad(n+2, 4)
+.sp 6p
+_
+.TE
+.KE
+.ne 6
+.nH 2 "ICE Minor opcodes"
+.LP
+.RS
+.TS
+lB cB
+l n.
+_
+.sp 6p
+Message Name Encoding
+.sp 6p
+_
+.sp 6p
+Error 0
+ByteOrder 1
+ConnectionSetup 2
+AuthenticationRequired 3
+AuthenticationReply 4
+AuthenticationNextPhase 5
+ConnectionReply 6
+ProtocolSetup 7
+ProtocolReply 8
+Ping 9
+PingReply 10
+WantToClose 11
+NoClose 12
+.sp 6p
+_
+.TE
+.RE
+.\" XXX - This is hokey, but I don't think you can nest .KS/.KE.
+.ne 16
+.nH 2 "Message Encoding"
+.LP
+.Es Error
+ 1 CARD8 major-opcode
+ 1 0 Error
+ 2 CARD16 class
+ 4 (n+p)/8+1 length
+ 1 CARD8 offending-minor-opcode
+ 1 severity:
+ 0 CanContinue
+ 1 FatalToProtocol
+ 2 FatalToConnection
+ 2 unused
+ 4 CARD32 sequence number of erroneous message
+ n <varies> value(s)
+ p pad, p = pad(n,8)
+.Ee
+.Es ByteOrder
+ 1 0 ICE
+ 1 1 ByteOrder
+ 1 byte-order:
+ 0 LSBfirst
+ 1 MSBfirst
+ 1 unused
+ 4 0 length
+.Ee
+.Es ConnectionSetup
+ 1 0 ICE
+ 1 2 ConnectionSetup
+ 1 CARD8 Number of versions offered
+ 1 CARD8 Number of authentication protocol names offered
+ 4 (i+j+k+m+p)/8+1 length
+ 1 BOOL must-authenticate
+ 7 unused
+ i STRING vendor
+ j STRING release
+ k LISTofSTRING authentication-protocol-names
+ m LISTofVERSION version-list
+ p unused, p = pad(i+j+k+m,8)
+.Ee
+.Es AuthenticationRequired
+ 1 0 ICE
+ 1 3 AuthenticationRequired
+ 1 CARD8 authentication-protocol-index
+ 1 unused
+ 4 (n+p)/8+1 length
+ 2 n length of authentication data
+ 6 unused
+ n <varies> data
+ p unused, p = pad(n,8)
+.Ee
+.Es AuthenticationReply
+ 1 0 ICE
+ 1 4 AuthenticationReply
+ 2 unused
+ 4 (n+p)/8+1 length
+ 2 n length of authentication data
+ 6 unused
+ n <varies> data
+ p unused, p = pad(n,8)
+.Ee
+.Es AuthenticationNextPhase
+ 1 0 ICE
+ 1 5 AuthenticationNextPhase
+ 2 unused
+ 4 (n+p)/8+1 length
+ 2 n length of authentication data
+ 6 unused
+ n <varies> data
+ p unused, p = pad(n,8)
+.Ee
+.Es ConnectionReply
+ 1 0 ICE
+ 1 6 ConnectionReply
+ 1 CARD8 version-index
+ 1 unused
+ 4 (i+j+p)/8 length
+ i STRING vendor
+ j STRING release
+ p unused, p = pad(i+j,8)
+.Ee
+.Es ProtocolSetup
+ 1 0 ICE
+ 1 7 ProtocolSetup
+ 1 CARD8 major-opcode
+ 1 BOOL must-authenticate
+ 4 (i+j+k+m+n+p)/8+1 length
+ 1 CARD8 Number of versions offered
+ 1 CARD8 Number of authentication protocol names offered
+ 6 unused
+ i STRING protocol-name
+ j STRING vendor
+ k STRING release
+ m LISTofSTRING authentication-protocol-names
+ n LISTofVERSION version-list
+ p unused, p = pad(i+j+k+m+n,8)
+.Ee
+.Es ProtocolReply
+ 1 0 ICE
+ 1 8 ProtocolReply
+ 1 CARD8 version-index
+ 1 CARD8 major-opcode
+ 4 (i+j+p)/8 length
+ i STRING vendor
+ j STRING release
+ p unused, p = pad(i+j, 8)
+.Ee
+.Es Ping
+ 1 0 ICE
+ 1 9 Ping
+ 2 0 unused
+ 4 0 length
+.Ee
+.Es PingReply
+ 1 0 ICE
+ 1 10 PingReply
+ 2 0 unused
+ 4 0 length
+.Ee
+.Es WantToClose
+ 1 0 ICE
+ 1 11 WantToClose
+ 2 0 unused
+ 4 0 length
+.Ee
+.Es NoClose
+ 1 0 ICE
+ 1 12 NoClose
+ 2 0 unused
+ 4 0 length
+.Ee
+.nH 2 "Error Class Encoding"
+.LP
+Generic errors have classes in the range 0x8000\-0xFFFF, and
+subprotocol-specific errors are in the range 0x0000\-0x7FFF.
+.nH 3 "Generic Error Class Encoding"
+.LP
+.TS
+lB cB
+l n.
+_
+.sp 6p
+Class Encoding
+.sp 6p
+_
+.sp 6p
+BadMinor 0x8000
+BadState 0x8001
+BadLength 0x8002
+BadValue 0x8003
+.sp 6p
+_
+.TE
+.nH 3 "ICE-specific Error Class Encoding"
+.LP
+.TS
+lB cB
+l n.
+_
+.sp 6p
+Class Encoding
+.sp 6p
+_
+.sp 6p
+BadMajor 0
+NoAuthentication 1
+NoVersion 2
+SetupFailed 3
+AuthenticationRejected 4
+AuthenticationFailed 5
+ProtocolDuplicate 6
+MajorOpcodeDuplicate 7
+UnknownProtocol 8
+.sp 6p
+_
+.TE
+.bp
+.\" Set registers to number the appendixes A.1, B.1, C.1, ...
+.nr H1 0
+.af H1 A
+.cT "Appendix A" no
+.nH 1 "Modification History"
+.nH 2 "Release 6 to Release 6.1"
+.LP
+Release 6.1 added the ICE X rendezvous protocol (Appendix B) and
+updated the document version to 1.1.
+.nH 2 "Release 6.1 to Release 6.3"
+.LP
+Release 6.3 added the listen on well known ports feature.
+.bp
+.cT "Appendix B" no
+.nH 1 "ICE X Rendezvous Protocol"
+.nH 2 "Introduction"
+.LP
+The ICE X rendezvous protocol is designed to answer the need posed
+in Section 2 for one mechanism by which two clients interested in
+communicating via ICE are able to exchange the necessary information.
+This protocol is appropriate for any two ICE clients who also have X
+connections to the same X server.
+.nH 2 "Overview of ICE X Rendezvous"
+.LP
+The ICE X Rendezvous Mechanism requires clients willing to act as ICE
+originating parties to pre-register the ICE subprotocols they support in an
+ICE_PROTOCOLS property on their top-level window. Clients willing to
+act as ICE answering parties then send an ICE_PROTOCOLS X
+.PN ClientMessage
+event to the ICE originating parties. This
+.PN ClientMessage
+event identifies
+the ICE network IDs of the ICE answering party as well as the ICE
+subprotocol it wishes to speak. Upon receipt of this message the ICE
+originating party uses the information to establish an ICE connection
+with the ICE answering party.
+.nH 2 "Registering Known Protocols"
+.LP
+Clients willing to act as ICE originating parties preregister
+the ICE subprotocols they support in a list of atoms held by an
+ICE_PROTOCOLS property on their top-level window. The name of each
+atom listed in ICE_PROTOCOLS must be of the form
+ICE_INITIATE_\fIpname\fP where \fIpname\fP is the name of the ICE
+subprotocol the ICE originating party is willing to speak, as would be
+specified in an ICE
+.PN ProtocolSetup
+message.
+.LP
+Clients with an ICE_INITIATE_\fIpname\fP atom in the ICE_PROTOCOLS property
+on their top-level windows must respond to
+.PN ClientMessage
+events of
+type ICE_PROTOCOLS specifying ICE_INITIATE_\fIpname\fP. If a client does not
+want to respond to these client message events, it should
+remove the ICE_INITIATE_\fIpname\fP atom from its ICE_PROTOCOLS property
+or remove the ICE_PROTOCOLS property entirely.
+.nH 2 "Initiating the Rendezvous"
+.LP
+To initiate the rendezvous a client acting as an ICE answering
+party sends an X
+.PN ClientMessage
+event of type ICE_PROTOCOLS to an ICE
+originating party. This ICE_PROTOCOLS client message contains the
+information the ICE originating party needs to identify the ICE
+subprotocol the two parties will use as well as the ICE network
+identification string of the ICE answering party.
+.LP
+Before the ICE answering party sends the client message event it must
+define a text property on one of its windows. This text property
+contains the ICE answering party's ICE network identification string
+and will be used by ICE originating parties to determine the ICE
+answering party's list of ICE network IDs.
+.LP
+The property name will normally be ICE_NETWORK_IDS, but may be any
+name of the ICE answering party's choosing. The format for this text
+property is as follows:
+.ne 7
+.TS
+lB lB
+lw(1.25i) lw(4i) .
+_
+.sp 6p
+Field Value
+.sp 6p
+_
+.sp 6p
+type XA_STRING
+format 8
+value comma-separated list of ICE network IDs
+.sp 6p
+_
+.TE
+.LP
+Once the ICE answering party has established this text property on one
+of its windows, it initiates the rendezvous by sending an
+ICE_PROTOCOLS
+.PN ClientMessage
+event to an ICE originating party's
+top-level window. This event has the following format
+and must only be sent to windows that have pre-registered the ICE
+subprotocol in an ICE_PROTOCOLS property on their top-level window.
+.ne 13
+.TS
+lB lB
+lw(1.25i) lw(4i) .
+_
+.sp 6p
+Field Value
+.sp 6p
+_
+.sp 6p
+message_type Atom = "ICE_PROTOCOLS"
+format 32
+data.l[0] Atom identifying the ICE subprotocol to speak
+data.l[1] Timestamp
+data.l[2] T{
+ICE answering party's window ID with
+ICE network IDs text property
+T}
+data.l[3] T{
+Atom naming text property containing the ICE
+answering party's ICE network IDs
+T}
+data.l[4] Reserved. Must be 0.
+.sp 6p
+_
+.TE
+The name of the atom in data.l[0] must be of the form
+ICE_INITIATE_\fIpname\fP, where \fIpname\fP is the name of the ICE
+subprotocol the ICE answering party wishes to speak.
+.LP
+When an ICE originating party receives a
+.PN ClientMessage
+event of type
+ICE_PROTOCOLS specifying ICE_INITIATE_\fIpname\fP it can initiate an ICE
+connection with the ICE answering party.
+To open this connection the client retrieves the ICE answering
+party's ICE network IDs from the window specified in data.l[2] using
+the text property specified in data.l[3].
+.LP
+If the connection attempt fails for any reason, the client must
+respond to the client message event by sending a return
+.PN ClientMessage
+event to the window specified in data.l[2]. This return
+event has the following format:
+.ne 13
+.TS
+lB lB
+lw(1.25i) lw(4i) .
+_
+.sp 6p
+Field Value
+.sp 6p
+_
+.sp 6p
+message_type Atom = "ICE_INITIATE_FAILED"
+format 32
+data.l[0] Atom identifying the ICE subprotocol requested
+data.l[1] Timestamp
+data.l[2] T{
+Initiating party's window ID
+(holding ICE_PROTOCOLS)
+T}
+data.l[3] int: reason for failure
+data.l[4] Reserved, must be 0
+.sp 6p
+_
+.TE
+The values of data.l[0] and data.l[1] are copied directly from the
+client message event the client received.
+.LP
+The value in data.l[2] is
+the id of the window to which the ICE_PROTOCOLS.ICE_INITIATE_\fIpname\fP
+client message event was sent.
+.LP
+Data.l[3] has one of the following values:
+.LP
+.ne 21
+.TS
+lB cBw(0.6i) lB
+l n lw(4i) .
+_
+.sp 6p
+Value Encoding Description
+.sp 6p
+_
+.sp 6p
+T{
+.PN OpenFailed
+T} 1 T{
+The client was unable to open the connection
+(e.g. a call to IceOpenConnection() failed). If the
+client is able to distinguish authentication or
+authorization errors from general errors, then
+the preferred reply is
+.PN AuthenticationFailed
+for authorization errors.
+T}
+.sp 4p
+T{
+.PN AuthenticationFailed
+T} 2 T{
+Authentication or authorization of the
+connection or protocol setup was refused.
+This reply will be given only if the client is
+able to distinguish it from
+.PN OpenFailed ;
+otherwise
+.PN OpenFailed
+will be returned.
+T}
+.sp 4p
+T{
+.PN SetupFailed
+T} 3 T{
+The client was unable to initiate the specified
+protocol on the connection (e.g. a call to
+IceProtocolSetup() failed).
+T}
+.sp 4p
+T{
+.PN UnknownProtocol
+T} 4 T{
+The client does not recognize the requested
+protocol. (This represents a semantic error
+on the part of the answering party.)
+T}
+.sp 4p
+T{
+.PN Refused
+T} 5 T{
+The client was in the process of removing
+ICE_INITIATE_\fIpname\fP from its ICE_PROTOCOLS list
+when the client message was sent; the client no
+longer is willing to establish the specified ICE
+communication.
+T}
+.sp 6p
+_
+.TE
+.sp
+.NT "Advice to Implementors"
+Clients willing to act as ICE originating parties must update the
+ICE_PROTOCOLS property on their top-level windows to include the
+ICE_INITIATE_\fIpname\fP atom(s) identifying the ICE subprotocols they
+speak. The method a client uses to update the ICE_PROTOCOLS property
+to include ICE_INITIATE_\fIpname\fP atoms is implementation dependent, but
+the client must ensure the integrity of the list to prevent the
+accidental omission of any atoms previously in the list.
+.LP
+When setting up the ICE network IDs text property on one of its
+windows, the ICE answering party can determine its comma-separated
+list of ICE network IDs by calling IceComposeNetworkIdList() after
+making a call to IceListenForConnections(). The method an ICE
+answering party uses to find the top-level windows of clients willing
+to act as ICE originating parties is dependent upon the nature of the
+answering party. Some may wish to use the approach of requiring the
+user to click on a client's window. Others wishing to find existing
+clients without requiring user interaction might use something similar
+to the XQueryTree() method used by several freely-available
+applications. In order for the ICE answering party to become
+automatically aware of new clients willing to originate ICE
+connections, the ICE answering party might register for
+SubstructureNotify events on the root window of the display. When it
+receives a SubstructureNotify event, the ICE answering party can check
+to see if it was the result of the creation of a new client top-level
+window with an ICE_PROTOCOLS property.
+.LP
+In any case, before attempting to use this ICE X Rendezvous Mechanism
+ICE answering parties wishing to speak ICE subprotocol \fIpname\fP should
+check for the ICE_INITIATE_\fIpname\fP atom in the ICE_PROTOCOLS property on
+a client's top-level window. A client that does not include an
+ICE_INITIATE_\fIpname\fP atom in a ICE_PROTOCOLS property on some top-level
+window should be assumed to ignore
+.PN ClientMessage
+events of type
+ICE_PROTOCOLS specifying ICE_INITIATE_\fIpname\fP for ICE subprotocol
+\fIpname\fP.
+.NE
+.nH 2 "ICE Subprotocol Versioning"
+.LP
+Although the version of the ICE subprotocol could be passed in the
+client message event, ICE provides more a flexible version negotiation
+mechanism than will fit within a single
+.PN ClientMessage
+event. Because
+of this, ICE subprotocol versioning is handled within the ICE protocol
+setup phase.
+.NT Example
+Clients wish to communicate with each other via an ICE subprotocol
+known as "RAP V1.0". In RAP terminology one party, the "agent",
+communicates with other RAP-enabled applications on demand. The
+user may direct the agent to establish communication with a specific
+application by clicking on the application's window, or the agent may
+watch for new application windows to be created and automatically
+establish communication.
+.LP
+During startup the ICE answering party (the agent) first calls
+IceRegisterForProtocolReply() with a list of
+the versions (i.e., 1.0) of RAP the agent can speak. The answering
+party then calls IceListenForConnections() followed by
+IceComposeNetworkIdList() and stores the resulting ICE network IDs
+string in a text property on one of its windows.
+.LP
+When the answering party (agent) finds a client with which it wishes to
+speak, it checks to see if the ICE_INITIATE_RAP atom is in the ICE_PROTOCOLS
+property on the client's top-level window. If it is present the agent
+sends the client's top-level window an ICE_PROTOCOLS client
+message event as described above. When the client receives the client
+message event and is willing to originate an ICE connection using RAP,
+it performs an IceRegisterForProtocolSetup() with a list of the
+versions of RAP the client can speak. The client then retrieves
+the agent's ICE network ID from the property and window specified by
+the agent in the client message event and calls IceOpenConnection().
+After this call succeeds the client calls IceProtocolSetup() specifying
+the RAP protocol. During this
+process, ICE calls the RAP protocol routines that handle the version
+negotiation.
+.LP
+Note that it is not necessary for purposes of this rendezvous that
+the client application call any ICElib functions prior to receipt
+of the client message event.
+.NE
+.YZ 1