diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2010-06-08 20:12:53 -0700 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2010-06-08 20:12:53 -0700 |
commit | 9b54f509832c50c1fac0edc0cb78e1a3454a56dc (patch) | |
tree | ac194e791e05a3fd2c7feedc4d4373b014001f84 /doc | |
parent | 1967c04c021a4cfd7b3cdd4efdc13610b4385a65 (diff) |
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.ms | 3400 | ||||
-rw-r--r-- | doc/Makefile.am | 1 | ||||
-rw-r--r-- | doc/ice.ms | 1878 |
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 |