usr/src/doc/rad-dev/a-protocol.xml
changeset 760 5220578b3b77
child 761 ffd45e0b2905
equal deleted inserted replaced
759:0aa521216e66 760:5220578b3b77
       
     1 <?xml version="1.0" encoding="UTF-8"?>
       
     2 <!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
       
     3 <!--
       
     4   PDL HEADER START
       
     5 
       
     6   Public Documentation License Notice
       
     7 
       
     8   The contents of this Documentation are subject to the Public
       
     9   Documentation License Version 1.01 (the "License"); you may only
       
    10   use this Documentation if you comply with the terms of this License.
       
    11   A copy of the License is available at
       
    12   http://www.opensolaris.org/os/community/documentation/license.
       
    13 
       
    14   PDL HEADER END
       
    15 
       
    16   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
       
    17 -->
       
    18 
       
    19 <appendix xmlns:rm="rad-macros">
       
    20 <title><command>rad</command> binary protocol</title>
       
    21 
       
    22 <!--
       
    23   While it's not a very traditional way to document binary protocols,
       
    24   BNF might be a clearer way to communicate some of the optional
       
    25   paths.  We should consider adding it as an addition to the textual /
       
    26   diagrammatical description.
       
    27 -->
       
    28 
       
    29 <para>
       
    30 In addition to supporting multiple transports, <command>rad</command>
       
    31 is capable of talking different protocols.  The default (and currently
       
    32 only) protocol is a proprietary binary protocol designated
       
    33 <literal>rad</literal>.  This appendix documents version 1 of this
       
    34 protocol.
       
    35 </para>
       
    36 
       
    37 <section><title>Overview</title>
       
    38     <para> 
       
    39     The <literal>rad</literal> protocol is a bi-directional binary protocol
       
    40     that operates over a single stream.  Communication in both directions
       
    41     takes the form of discrete messages.  These messages are framed using
       
    42     <acronym>RPC</acronym> record marking (See <quote>RECORD MARKING
       
    43     STANDARD</quote> in <citation>RPC</citation>).
       
    44     </para>
       
    45 
       
    46     <para> 
       
    47     The individual messages take the formats documented below.  Even though
       
    48     <acronym>RPC</acronym> record marking permits skipping messages of
       
    49     unknown format, both the client and the server are free to immediately
       
    50     drop the connection when an invalid message is seen.
       
    51     </para>
       
    52 
       
    53     <para>
       
    54     The <literal>rad</literal> protocol is built using
       
    55     <citation>XDR</citation>, so for simplicity and clarity the
       
    56     <acronym>XDR</acronym> primitive type names and syntax will be used
       
    57     throughout this appendix.  For example:
       
    58     </para>
       
    59 
       
    60     <itemizedlist>
       
    61     <listitem>
       
    62     <quote><literal>FOO&lt;&gt;</literal></quote> would represent a
       
    63     variable-length array of <literal>FOO</literal>s, communicated as
       
    64     an <literal>unsigned int</literal> containing the size followed by
       
    65     that number of <literal>FOO</literal>s.
       
    66     </listitem>
       
    67     <listitem>
       
    68     <quote><literal>FOO[n]</literal></quote> would represent a
       
    69     fixed-length array of a predetermined size, communicated only as
       
    70     the <literal>n</literal> <literal>FOO</literal>s.
       
    71     </listitem>
       
    72     <listitem>
       
    73     <quote><literal>FOO *</literal></quote> would represent an optional
       
    74     value, communicated as a <literal>boolean</literal> value followed
       
    75     by a <literal>FOO</literal> if and only if the
       
    76     <literal>boolean</literal> value was true.
       
    77     </listitem>
       
    78     </itemizedlist>
       
    79 
       
    80 </section>
       
    81 
       
    82 <section><title>Common data formats</title>
       
    83     <para>
       
    84     There are a few types and concepts that appear repeatedly
       
    85     throughout the <literal>rad</literal> protocol.  They are described
       
    86     here.
       
    87     </para>
       
    88 
       
    89     <section id="op-data-def"><title>Operations</title>
       
    90     <para>
       
    91     The various operations one can perform against the server are
       
    92     communicated with an operation code.
       
    93     </para>
       
    94 
       
    95     <rm:proto name="OP-CODE">
       
    96 	<rm:data field="op_code" size="4" type="int">
       
    97 	<rm:codedef label="operation" prefix="oc">
       
    98 	    <rm:code num="0" name="INVOKE" />
       
    99 	    <rm:code num="1" name="GETATTR" />
       
   100 	    <rm:code num="2" name="SETATTR" />
       
   101 	    <rm:code num="3" name="LOOKUP" />
       
   102 	    <rm:code num="4" name="DEFINE" />
       
   103 	    <rm:code num="5" name="LIST" />
       
   104 	    <rm:code num="6" name="SUB" />
       
   105 	    <rm:code num="7" name="UNSUB" />
       
   106 	</rm:codedef>
       
   107 	</rm:data>
       
   108     </rm:proto>
       
   109     </section>
       
   110 
       
   111     <section id="error-data-def"><title>Errors</title>
       
   112     <para>
       
   113     Errors in the <literal>rad</literal> protocol are communicated by
       
   114     an error code, and optionally structured error data.
       
   115     </para>
       
   116 
       
   117     <rm:proto name="ERROR-CODE">
       
   118 	<rm:data field="error_code" size="4" type="int">
       
   119 	<rm:codedef label="error" prefix="ec">
       
   120 	    <rm:code num="0" name="ok" />
       
   121 	    <rm:code num="1" name="object" />
       
   122 	    <rm:code num="2" name="nomem" />
       
   123 	    <rm:code num="3" name="notfound" />
       
   124 	    <rm:code num="4" name="priv" />
       
   125 	    <rm:code num="5" name="system" />
       
   126 	    <rm:code num="6" name="exists" />
       
   127 	    <rm:code num="7" name="mismatch" />
       
   128 	    <rm:code num="8" name="illegal" />
       
   129 	</rm:codedef>
       
   130 	</rm:data>
       
   131     </rm:proto>
       
   132     
       
   133     <para>
       
   134     For object-specific errors, <literal>EC-OBJECT</literal>, the
       
   135     format of the structured data is defined by the object's interface
       
   136     definition.  For the remainder, save for <literal>EC-OK</literal>
       
   137     (which is defined for completeness, but should never appear in the
       
   138     protocol), the format is defined during the initial connection
       
   139     handshake.  See <xref linkend="proto-handshake" />.
       
   140     </para>
       
   141     </section>
       
   142 
       
   143     <section id="time-data-def"><title>Time</title>
       
   144     <para>
       
   145     When a time needs to be represented in the <literal>rad</literal>
       
   146     protocol, it is communicated as seconds and nanoseconds offset from
       
   147     the epoch (January 1, 1970 UTC).  
       
   148     </para>
       
   149     
       
   150     <para>
       
   151     It is important to note that the accuracy of such time data is
       
   152     determined by its context.  In most, if not all, cases, the full
       
   153     nanosecond precision is only relevant when compared to time data
       
   154     obtained from the same host.
       
   155     </para>
       
   156 
       
   157 <rm:proto name="TIME-DATA">
       
   158     <rm:data field="secs" size="8" type="hyper">
       
   159 	number of seconds
       
   160     </rm:data>
       
   161     <rm:data field="nsecs" size="4" type="int">
       
   162 	number of nanoseconds (<mathphrase>0 &le; nsec &le;
       
   163 	10<superscript>9</superscript></mathphrase>)
       
   164     </rm:data>
       
   165 </rm:proto>
       
   166     </section>
       
   167 
       
   168     <section id="name-data-def"><title>Object names</title>
       
   169     <para>
       
   170     <command>rad</command> object names are structured, consisting of a
       
   171     domain and one or more key-value pairs.  When an object name or
       
   172     pattern needs to be represented in the <literal>rad</literal>
       
   173     protocol, this structure is flattened to a canonical string
       
   174     format.  This string format consists of the domain, followed by a
       
   175     colon (':'), followed by comma-separated key-value pairs.  Each
       
   176     key-value pair consists of the name, followed by an equals sign
       
   177     ('='), followed by the value.
       
   178     </para>
       
   179 
       
   180     <para>
       
   181     Because keys and values may contain the special characters '=' or
       
   182     ',', a quoting algorithm is applied when constructing the string.
       
   183     The following substitutions are applied to keys and values:
       
   184     </para>
       
   185 
       
   186     <table><title>Object Name Escaping</title>
       
   187     <tgroup cols='2'>
       
   188     <thead>
       
   189     <row><entry>Plain Text</entry><entry>Escaped Text</entry></row>
       
   190     </thead>
       
   191     <tbody>
       
   192     <row><entry>\</entry><entry>\S</entry></row>
       
   193     <row><entry>,</entry><entry>\C</entry></row>
       
   194     <row><entry>=</entry><entry>\E</entry></row>
       
   195     </tbody>
       
   196     </tgroup>
       
   197     </table>
       
   198 
       
   199     <para>
       
   200     Note that under this transformation, backslashes are only found as
       
   201     part of quoted characters, and commas and equals signs, when
       
   202     present, always have their special meaning.  Object names that use
       
   203     no special characters are passed through unchanged.  These facts
       
   204     can be used to simplify parsing or preprocessing of
       
   205     string-formatted object names.
       
   206     </para>
       
   207 
       
   208 <rm:proto name="NAME-DATA">
       
   209     <rm:data field="name" size="variable" type="string&lt;&gt;">
       
   210 	flattened object name
       
   211     </rm:data>
       
   212 </rm:proto>
       
   213 
       
   214     <example>
       
   215     An object name in the domain <quote>com.example</quote> with the
       
   216     following keys and values:
       
   217 
       
   218     <informaltable>
       
   219     <tgroup cols='2'>
       
   220     <thead>
       
   221     <row><entry>Key</entry><entry>Value</entry></row>
       
   222     </thead>
       
   223     <tbody>
       
   224     <row><entry>directory</entry><entry>C:\</entry></row>
       
   225     <row><entry>first,last</entry><entry>Doe,John</entry></row>
       
   226     </tbody>
       
   227     </tgroup>
       
   228     </informaltable>
       
   229 
       
   230     would be represented by the string
       
   231     <quote>com.example:directory=C:\S,first\Clast=Doe\CJohn</quote>.
       
   232     </example>
       
   233     </section>
       
   234 
       
   235     <section id="adr-data"><title><acronym>ADR</acronym> data</title>
       
   236     <para>
       
   237     Central to the <literal>rad</literal> protocol is the communication
       
   238     of data defined by <acronym>ADR</acronym>.  Most
       
   239     <acronym>ADR</acronym> primitives map directly to
       
   240     <acronym>XDR</acronym> types:
       
   241     </para>
       
   242 
       
   243     <table>
       
   244     <title>Primitive <acronym>ADR</acronym> to Wire Type Mapping</title>
       
   245     <tgroup cols='2'>
       
   246     <thead>
       
   247     <row>
       
   248     <entry><acronym>ADR</acronym> Type</entry>
       
   249     <entry>Wire Type</entry>
       
   250     </row>
       
   251     </thead>
       
   252     <tbody>
       
   253     <row>
       
   254     <entry>boolean</entry>
       
   255     <entry><acronym>XDR</acronym> <literal>boolean</literal></entry>
       
   256     </row>
       
   257     <row>
       
   258     <entry>integer</entry>
       
   259     <entry><acronym>XDR</acronym> <literal>int</literal></entry>
       
   260     </row>
       
   261     <row>
       
   262     <entry>uinteger</entry>
       
   263     <entry><acronym>XDR</acronym> <literal>unsigned int</literal></entry>
       
   264     </row>
       
   265     <row>
       
   266     <entry>long</entry>
       
   267     <entry><acronym>XDR</acronym> <literal>hyper</literal></entry>
       
   268     </row>
       
   269     <row>
       
   270     <entry>ulong</entry>
       
   271     <entry><acronym>XDR</acronym> <literal>unsigned hyper</literal></entry>
       
   272     </row>
       
   273     <row>
       
   274     <entry>float</entry>
       
   275     <entry><acronym>XDR</acronym> <literal>float</literal></entry>
       
   276     </row>
       
   277     <row>
       
   278     <entry>double</entry>
       
   279     <entry><acronym>XDR</acronym> <literal>double</literal></entry>
       
   280     </row>
       
   281     <row>
       
   282     <entry>string</entry>
       
   283     <entry><acronym>XDR</acronym> <literal>string&lt;&gt;</literal></entry>
       
   284     </row>
       
   285     <row>
       
   286     <entry>opaque</entry>
       
   287     <entry><acronym>XDR</acronym> <literal>opaque&lt;&gt;</literal></entry>
       
   288     </row>
       
   289     <row>
       
   290     <entry>password</entry>
       
   291     <entry><acronym>XDR</acronym> <literal>string&lt;&gt;</literal></entry>
       
   292     </row>
       
   293     <row>
       
   294     <entry>time</entry>
       
   295     <entry><literal>TIME-DATA</literal>
       
   296     (see <xref linkend="time-data-def" />)</entry>
       
   297     </row>
       
   298     <row>
       
   299     <entry>name</entry>
       
   300     <entry><literal>NAME-DATA</literal>
       
   301     (see <xref linkend="name-data-def" />)</entry>
       
   302     </row>
       
   303     </tbody>
       
   304     </tgroup>
       
   305     </table>
       
   306 
       
   307     <para>
       
   308     Optional <acronym>ADR</acronym> data of any type is represented as
       
   309     <acronym>XDR</acronym> optional data.
       
   310     </para>
       
   311 
       
   312     <rm:proto name="OPTIONAL-DATA">
       
   313 	<rm:data field="data" size="varies" type="ADR-DATA *">
       
   314 	    Optional encoded data
       
   315 	</rm:data>
       
   316     </rm:proto>
       
   317 
       
   318     <para>
       
   319     Array data is communicated as an <acronym>XDR</acronym> array of
       
   320     the element data.  That is, it is represented by an
       
   321     <acronym>XDR</acronym> <literal>unsigned int</literal> whose value
       
   322     is the number of array elements, followed by that number of element
       
   323     data.
       
   324     </para>
       
   325 
       
   326     <rm:proto name="ARRAY-DATA">
       
   327 	<rm:data field="elements" size="varies" type="ADR-DATA&lt;&gt;">
       
   328 	    array elements
       
   329 	</rm:data>
       
   330     </rm:proto>
       
   331 
       
   332     <para>
       
   333     Structure data is communicated by communicating each structure
       
   334     field in the order they are defined.  This may consist of a mixture
       
   335     of optional and non-optional data.
       
   336     </para>
       
   337 
       
   338     <rm:proto name="STRUCT-DATA">
       
   339 	<rm:data field="fields" size="varies" type="ADR-DATA[n]">
       
   340 	    fixed-length array of structure fields
       
   341 	    (n = type-defined field count)
       
   342 	</rm:data>
       
   343     </rm:proto>
       
   344 
       
   345     <para>
       
   346     Enumeration data is communicated as an <acronym>XDR</acronym>
       
   347     <literal>unsigned int</literal> whose value is the 1-based index
       
   348     into the list of enumerated values (i.e. 1 would be the first
       
   349     enumerated value, n would be the nth enumerated value).  A value of
       
   350     0 represents the fallback value.  For enumerations without a
       
   351     fallback value, the 0 value is unused.
       
   352     </para>
       
   353 
       
   354     <rm:proto name="ENUM-DATA">
       
   355 	<rm:data field="value" size="4" type="unsigned int">
       
   356 	    0 if fallback, 1-based index otherwise
       
   357 	</rm:data>
       
   358     </rm:proto>
       
   359 
       
   360     <para>
       
   361     Union data is communicated as an <acronym>XDR</acronym>
       
   362     <literal>unsigned int</literal> whose value is the 1-based index
       
   363     into the list of union arms.  A value of 0 represents the default
       
   364     arm.  When a non-default arm is selected, the arm is followed by
       
   365     that arm's data.  When the default arm is selected, it is first
       
   366     followed by the discriminant data value, and then is followed by
       
   367     the default arm's data.
       
   368     </para>
       
   369 
       
   370     <rm:proto name="UNION-DATA (non default)">
       
   371 	<rm:data field="arm_index" size="4" type="unsigned int">
       
   372 	    1-based index into list of arms
       
   373 	</rm:data>
       
   374 	<rm:data field="arm_data" size="varies" type="ADR-DATA">
       
   375 	    Arm data
       
   376 	</rm:data>
       
   377     </rm:proto>
       
   378 
       
   379     <rm:proto name="UNION-DATA (default)">
       
   380 	<rm:data field="arm_index" size="4" type="unsigned int">
       
   381 	    0
       
   382 	</rm:data>
       
   383 	<rm:data field="discriminant" size="4" type="ENUM-DATA | boolean">
       
   384 	    discriminant value
       
   385 	</rm:data>
       
   386 	<rm:data field="arm_data" size="varies" type="ADR-DATA">
       
   387 	    Arm data
       
   388 	</rm:data>
       
   389     </rm:proto>
       
   390 
       
   391     </section>
       
   392 
       
   393     <!-- Consider switching this section and the previous section -->
       
   394     <section><title><acronym>ADR</acronym> types</title>
       
   395     <para>
       
   396     As discussed in <xref linkend="adr-data" />, the
       
   397     <acronym>ADR</acronym> data communicated by the
       
   398     <literal>rad</literal> protocol has a structure determined by its
       
   399     type.  Before that data can be communicated to the client, however,
       
   400     the types themselves must be communicated.
       
   401     </para>
       
   402 
       
   403     <para>
       
   404     For efficiency, type data is communicated using a system of type
       
   405     spaces and type references.  A type space is an array of type
       
   406     definitions that is referenced by a protocol-defined set of
       
   407     consumers.  A consumer referring to a type will use a type
       
   408     reference, which points to either a primitive type or to an element
       
   409     of the type space.
       
   410     </para>
       
   411 
       
   412     <para>
       
   413     Both type references and type spaces need to refer to the various
       
   414     types.  They do this using an integral type code:
       
   415     </para>
       
   416 
       
   417     <rm:proto name="TYPE-CODE">
       
   418 	<rm:data field="type_code" size="4" type="int">
       
   419 	<rm:codedef label="type" prefix="tc">
       
   420 	    <rm:code num="0" name="void" />
       
   421 	    <rm:code num="1" name="boolean" />
       
   422 	    <rm:code num="2" name="integer" />
       
   423 	    <rm:code num="3" name="uinteger" />
       
   424 	    <rm:code num="4" name="long" />
       
   425 	    <rm:code num="5" name="ulong" />
       
   426 	    <rm:code num="6" name="float" />
       
   427 	    <rm:code num="7" name="double" />
       
   428 	    <rm:code num="8" name="time" />
       
   429 	    <rm:code num="9" name="string" />
       
   430 	    <rm:code num="10" name="opaque" />
       
   431 	    <rm:code num="11" name="password" />
       
   432 	    <rm:code num="12" name="name" />
       
   433 	    <rm:code num="13" name="enum" />
       
   434 	    <rm:code num="14" name="array" />
       
   435 	    <rm:code num="15" name="struct" />
       
   436 	    <rm:code num="16" name="union" />
       
   437 	</rm:codedef>
       
   438 	</rm:data>
       
   439     </rm:proto>
       
   440 
       
   441     <para>
       
   442     Concretely, a type reference consists of an XDR int whose value is
       
   443     one of the above type constants.  If the type is an enum, array,
       
   444     union, or struct, the type reference also includes an XDR int whose
       
   445     value is an index into the current type space:
       
   446     </para>
       
   447 
       
   448     <rm:proto name="TYPEREF (basic type)">
       
   449 	<rm:data field="type_code" size="4" type="TYPE-CODE">
       
   450 	    a primitive type code
       
   451 	</rm:data>
       
   452     </rm:proto>
       
   453 
       
   454     <rm:proto name="TYPEREF (derived type)">
       
   455 	<rm:data field="type_code" size="4" type="TYPE-CODE">
       
   456 	    <literal>TC-ENUM</literal>, <literal>TC-ARRAY</literal>,
       
   457 	    <literal>TC-STRUCT</literal>, or <literal>TC-UNION</literal>
       
   458 	</rm:data>
       
   459 	<rm:data field="type_index" size="4" type="int">
       
   460 	    type space index
       
   461 	</rm:data>
       
   462     </rm:proto>
       
   463 
       
   464     <para>
       
   465     A type space is a topologically sorted array of type definitions.
       
   466     A derived type may only reference derived types defined earlier in
       
   467     the type space.  That is, a type reference used by the type at
       
   468     index <mathphrase>X</mathphrase> may only reference a primitive
       
   469     type or a derived type a index less than
       
   470     <mathphrase>X</mathphrase>.  Recursively defined types are not
       
   471     supported.
       
   472     </para>
       
   473 
       
   474     <para>
       
   475     Apart from a common distinguishing type code, each derived type is
       
   476     defined differently.  Arrays are the simplest.  An array definition
       
   477     consists of only a reference to the element type:
       
   478     </para>
       
   479 
       
   480     <rm:proto name="ARRAY-TYPE">
       
   481 	<rm:data field="type_code" size="4" type="TYPE-CODE">
       
   482 	    <literal>TC-ARRAY</literal>
       
   483 	</rm:data>
       
   484 	<rm:data field="element_type" size="varies" type="TYPEREF">
       
   485 	    the element type
       
   486 	</rm:data>
       
   487     </rm:proto>
       
   488 
       
   489     <para>
       
   490     A structure type definition consists of a name and an array of
       
   491     field definitions.  The order in which the fields are specified in
       
   492     <literal>STRUCT-TYPE</literal> is the order used to serialize the
       
   493     fields in <literal>STRUCT-DATA</literal>.
       
   494     </para>
       
   495 
       
   496     <rm:proto name="FIELD-TYPE">
       
   497 	<rm:data field="name" size="varies" type="string&lt;&gt;">
       
   498 	    the field name
       
   499 	</rm:data>
       
   500 	<rm:data field="optional" size="4" type="boolean">
       
   501 	    is the field value optional?
       
   502 	</rm:data>
       
   503 	<rm:data field="type" size="varies" type="TYPEREF">
       
   504 	    the field type
       
   505 	</rm:data>
       
   506     </rm:proto>
       
   507 
       
   508     <rm:proto name="STRUCT-TYPE">
       
   509 	<rm:data field="type_code" size="4" type="TYPE-CODE">
       
   510 	    <literal>TC-STRUCT</literal>
       
   511 	</rm:data>
       
   512 	<rm:data field="name" size="varies" type="string&lt;&gt;">
       
   513 	    the structure name
       
   514 	</rm:data>
       
   515 	<rm:data field="fields" size="varies" type="FIELD-TYPE&lt;&gt;">
       
   516 	    ordered list of structure fields
       
   517 	</rm:data>
       
   518     </rm:proto>
       
   519 
       
   520     <para>
       
   521     A union type definition consists of a name, a reference to the
       
   522     discriminant type, optionally a default arm specification, and an
       
   523     array of arm definitions.  The arm index referenced by
       
   524     <literal>UNION-DATA</literal> is an index into the array of arms
       
   525     defined by the corresponding <literal>UNION-TYPE</literal>.
       
   526     </para>
       
   527 
       
   528     <rm:proto name="ARM-TYPE">
       
   529 	<rm:data field="value" size="4" type="ENUM-DATA | boolean">
       
   530 	    the discriminant value that selects this arm
       
   531 	</rm:data>
       
   532 	<rm:data field="optional" size="4" type="boolean">
       
   533 	    is the arm's value optional?
       
   534 	</rm:data>
       
   535 	<rm:data field="type" size="varies" type="TYPEREF">
       
   536 	    the arm's type
       
   537 	</rm:data>
       
   538     </rm:proto>
       
   539 
       
   540     <rm:proto name="UNION-TYPE (without default arm)">
       
   541 	<rm:data field="type_code" size="4" type="TYPE-CODE">
       
   542 	    <literal>TC-UNION</literal>
       
   543 	</rm:data>
       
   544 	<rm:data field="name" size="varies" type="string&lt;&gt;">
       
   545 	    the union name
       
   546 	</rm:data>
       
   547 	<rm:data field="disc_type" size="varies" type="TYPEREF">
       
   548 	    the discriminant type
       
   549 	</rm:data>
       
   550 	<rm:data field="hasdefault" size="4" type="boolean">
       
   551 	    false
       
   552 	</rm:data>
       
   553 	<rm:data field="arms" size="varies" type="ARM-TYPE&lt;&gt;">
       
   554 	    ordered list of arms
       
   555 	</rm:data>
       
   556     </rm:proto>
       
   557 
       
   558     <rm:proto name="UNION-TYPE (with default arm)">
       
   559 	<rm:data field="type_code" size="4" type="TYPE-CODE">
       
   560 	    <literal>TC-UNION</literal>
       
   561 	</rm:data>
       
   562 	<rm:data field="name" size="varies" type="string&lt;&gt;">
       
   563 	    the union name
       
   564 	</rm:data>
       
   565 	<rm:data field="disc_type" size="varies" type="TYPEREF">
       
   566 	    the discriminant type
       
   567 	</rm:data>
       
   568 	<rm:data field="hasdefault" size="4" type="boolean">
       
   569 	    true
       
   570 	</rm:data>
       
   571 	<rm:data field="def_optional" size="4" type="boolean">
       
   572 	    is the default arm value optional?
       
   573 	</rm:data>
       
   574 	<rm:data field="def_type" size="varies" type="TYPEREF">
       
   575 	    the default arm type
       
   576 	</rm:data>
       
   577 	<rm:data field="arms" size="varies" type="ARM-TYPE&lt;&gt;">
       
   578 	    ordered list of arms
       
   579 	</rm:data>
       
   580     </rm:proto>
       
   581 
       
   582     <para>
       
   583     Lastly, an enum type definition consists of a name, an optional
       
   584     fallback value, and a list of enumeration values.  The value index
       
   585     referenced by <literal>ENUM-DATA</literal> is an index into the
       
   586     array of values defined by the corresponding
       
   587     <literal>ENUM-TYPE</literal>.
       
   588     </para>
       
   589 
       
   590     <rm:proto name="VALUE-TYPE">
       
   591 	<rm:data field="name" size="varies" type="string&lt;&gt;">
       
   592 	    the value's name
       
   593 	</rm:data>
       
   594 	<rm:data field="value" size="4" type="int">
       
   595 	    the value's assigned value
       
   596 	</rm:data>
       
   597     </rm:proto>
       
   598 
       
   599     <rm:proto name="ENUM-TYPE">
       
   600 	<rm:data field="type_code" size="4" type="TYPE-CODE">
       
   601 	    <literal>TC-ENUM</literal>
       
   602 	</rm:data>
       
   603 	<rm:data field="name" size="varies" type="string&lt;&gt;">
       
   604 	    the enum name
       
   605 	</rm:data>
       
   606 	<rm:data field="fb_name" size="varies" type="string&lt;&gt; *">
       
   607 	    the fallback value's name, if one exists
       
   608 	</rm:data>
       
   609 	<rm:data field="values" size="varies" type="VALUE-TYPE&lt;&gt;">
       
   610 	    ordered list of values
       
   611 	</rm:data>
       
   612     </rm:proto>
       
   613 
       
   614     <para>
       
   615     The type space itself is an array.  Each element is one of these
       
   616     four type definitions (<literal>ARRAY-TYPE</literal>,
       
   617     <literal>STRUCT-TYPE</literal>, <literal>UNION-TYPE</literal>, or
       
   618     <literal>ENUM-TYPE</literal>).
       
   619     </para>
       
   620 
       
   621     <rm:proto name="TYPESPACE">
       
   622 	<rm:data field="types" size="varies" type="?-TYPE&lt;&gt;">
       
   623 	    ordered list of types in the type space
       
   624 	</rm:data>
       
   625     </rm:proto>
       
   626 
       
   627     </section>
       
   628 
       
   629     <section><title><acronym>API</acronym> definitions</title>
       
   630     <para>
       
   631     The ultimate description of the interactions permitted with a
       
   632     particular object is its <acronym>API</acronym> definition.  An
       
   633     <acronym>API</acronym> definition contains many elements: an
       
   634     interface name, a list of versioned <acronym>API</acronym> names
       
   635     the <acronym>API</acronym> supports, and definitions of the
       
   636     <acronym>API</acronym>'s attributes, methods, and events.
       
   637     </para>
       
   638 
       
   639     <para>
       
   640     Each <acronym>API</acronym> name has a set of stabilities and
       
   641     versions:
       
   642     </para>
       
   643 
       
   644     <rm:proto name="STABILITY-CODE">
       
   645 	<rm:data field="stability_code" size="4" type="int">
       
   646 	<rm:codedef label="stability" prefix="sc">
       
   647 	    <rm:code num="1" name="private" />
       
   648 	    <rm:code num="2" name="uncommitted" />
       
   649 	    <rm:code num="3" name="committed" />
       
   650 	</rm:codedef>
       
   651 	</rm:data>
       
   652     </rm:proto>
       
   653 
       
   654     <rm:proto name="VERSION-DATA">
       
   655 	<rm:data field="stability" size="4" type="STABILITY-CODE">
       
   656 	    stability version applies to
       
   657 	</rm:data>
       
   658 	<rm:data field="major" size="4" type="int">
       
   659 	    major version number
       
   660 	</rm:data>
       
   661 	<rm:data field="minor" size="4" type="int">
       
   662 	    minor version number
       
   663 	</rm:data>
       
   664     </rm:proto>
       
   665 
       
   666     <rm:proto name="APINAME-DATA">
       
   667 	<rm:data field="api_name" size="varies" type="string&lt;&gt;">
       
   668 	    API name
       
   669 	</rm:data>
       
   670 	<rm:data field="versions" size="varies" type="VERSION-DATA&lt;&gt;">
       
   671 	    API versions by stability
       
   672 	</rm:data>
       
   673     </rm:proto>
       
   674 
       
   675     <para>
       
   676     An attribute consists of a name, stability, various flags, a type,
       
   677     and separate, optional read and write error types.
       
   678     </para>
       
   679 
       
   680     <rm:proto name="ATTRIBUTE-TYPE">
       
   681 	<rm:data field="aname" size="varies" type="string&lt;&gt;">
       
   682 	    attribute name
       
   683 	</rm:data>
       
   684 	<rm:data field="stability" size="4" type="STABILITY-CODE">
       
   685 	    stability
       
   686 	</rm:data>
       
   687 	<rm:data field="readable" size="4" type="boolean">
       
   688 	    is attribute readable?
       
   689 	</rm:data>
       
   690 	<rm:data field="writable" size="4" type="boolean">
       
   691 	    is attribute writable?
       
   692 	</rm:data>
       
   693 	<rm:data field="optional" size="4" type="boolean">
       
   694 	    is attribute optional?
       
   695 	</rm:data>
       
   696 	<rm:data field="type" size="varies" type="TYPEREF">
       
   697 	    attribute type
       
   698 	</rm:data>
       
   699 	<rm:data field="read_error" size="varies" type="TYPEREF *">
       
   700 	    error data on read, if applicable
       
   701 	</rm:data>
       
   702 	<rm:data field="write_error" size="varies" type="TYPEREF *">
       
   703 	    error data on write, if applicable
       
   704 	</rm:data>
       
   705     </rm:proto>
       
   706 
       
   707     <para>
       
   708     A method looks a lot like an attribute.  It has a name, stability,
       
   709     a result type, only a single optional error type, and an array of
       
   710     argument definitions.
       
   711     </para>
       
   712 
       
   713     <rm:proto name="ARGUMENT-TYPE">
       
   714 	<rm:data field="argname" size="varies" type="string&lt;&gt;">
       
   715 	    argument name
       
   716 	</rm:data>
       
   717 	<rm:data field="optional" size="4" type="boolean">
       
   718 	    is argument optional?
       
   719 	</rm:data>
       
   720 	<rm:data field="type" size="varies" type="TYPEREF">
       
   721 	    argument type
       
   722 	</rm:data>
       
   723     </rm:proto>
       
   724 
       
   725     <rm:proto name="METHOD-TYPE">
       
   726 	<rm:data field="mname" size="varies" type="string&lt;&gt;">
       
   727 	    method name
       
   728 	</rm:data>
       
   729 	<rm:data field="stability" size="4" type="STABILITY-CODE">
       
   730 	    stability
       
   731 	</rm:data>
       
   732 	<rm:data field="optional" size="4" type="boolean">
       
   733 	    is result optional?
       
   734 	</rm:data>
       
   735 	<rm:data field="result_type" size="varies" type="TYPEREF">
       
   736 	    result type
       
   737 	</rm:data>
       
   738 	<rm:data field="error" size="varies" type="TYPEREF *">
       
   739 	    error data, if applicable
       
   740 	</rm:data>
       
   741 	<rm:data field="args" size="varies" type="ARGUMENT-TYPE&lt;&gt;">
       
   742 	    arguments
       
   743 	</rm:data>
       
   744     </rm:proto>
       
   745 
       
   746     <para>
       
   747     An event consists only of a name, stability, and type.
       
   748     </para>
       
   749 
       
   750     <rm:proto name="EVENT-TYPE">
       
   751 	<rm:data field="ename" size="varies" type="string&lt;&gt;">
       
   752 	    method name
       
   753 	</rm:data>
       
   754 	<rm:data field="stability" size="4" type="STABILITY-CODE">
       
   755 	    stability
       
   756 	</rm:data>
       
   757 	<rm:data field="event_type" size="varies" type="TYPEREF">
       
   758 	    event type
       
   759 	</rm:data>
       
   760     </rm:proto>
       
   761 
       
   762     <para>
       
   763     Finally, an API definition combines all the above elements.
       
   764     </para>
       
   765 
       
   766     <rm:proto name="API-TYPE">
       
   767 	<rm:data field="ifname" size="varies" type="string&lt;&gt;">
       
   768 	    interface name (domain)
       
   769 	</rm:data>
       
   770 	<rm:data field="apis" size="varies" type="APINAME-DATA&lt;&gt;">
       
   771 	    API names and versions implemented
       
   772 	</rm:data>
       
   773 	<rm:data field="types" size="varies" type="TYPESET&lt;&gt;">
       
   774 	    Types used by API definition
       
   775 	</rm:data>
       
   776 	<rm:data field="attributes" size="varies" type="ATTRIBUTE-TYPE&lt;&gt;">
       
   777 	    API attributes
       
   778 	</rm:data>
       
   779 	<rm:data field="methods" size="varies" type="METHOD-TYPE&lt;&gt;">
       
   780 	    API methods
       
   781 	</rm:data>
       
   782 	<rm:data field="events" size="varies" type="EVENT-TYPE&lt;&gt;">
       
   783 	    API events
       
   784 	</rm:data>
       
   785     </rm:proto>
       
   786 
       
   787     </section>
       
   788 
       
   789 </section>
       
   790 <section id="proto-handshake"><title>Connection Initialization</title>
       
   791     <para>
       
   792     Once a connection has been established between a client and server,
       
   793     a short synchronous handshake initiates the rad protocol.  The
       
   794     server begins by sending a <literal>SERVER-HELLO</literal>
       
   795     message.  This message specifies the minimum and maximum protocol
       
   796     versions (inclusive) recognized by the server.
       
   797     </para>
       
   798 
       
   799     <rm:proto name="SERVER-HELLO">
       
   800 	<rm:data field="protocol" size="3" type="string[3]">
       
   801 	    <quote>RAD</quote>
       
   802 	</rm:data>
       
   803 	<rm:data field="min_ver" size="4" type="int">
       
   804 	    minimum supported version
       
   805 	</rm:data>
       
   806 	<rm:data field="max_ver" size="4" type="int">
       
   807 	    maximum supported version
       
   808 	</rm:data>
       
   809     </rm:proto>
       
   810 
       
   811     <para>
       
   812     The client then replies with a <literal>CLIENT-HELLO</literal>
       
   813     message specifying the version it wishes to use.  This version may
       
   814     not be less than the server's minimum version or greater than the
       
   815     server's maximum version.
       
   816     </para>
       
   817 
       
   818     <rm:proto name="CLIENT-HELLO">
       
   819 	<rm:data field="protocol" size="3" type="string[3]">
       
   820 	    <quote>RAD</quote>
       
   821 	</rm:data>
       
   822 	<rm:data field="version" size="4" type="int">
       
   823 	    client-selected version
       
   824 	</rm:data>
       
   825 	<rm:data field="locale" size="varies" type="string&lt;256&gt;">
       
   826 	    client locale
       
   827 	</rm:data>
       
   828     </rm:proto>
       
   829 
       
   830     <para>
       
   831     Part of the <literal>rad</literal> protocol is the communication of
       
   832     structured error data on request failures.  For consistency with
       
   833     the object-specific errors that server-side objects are permitted
       
   834     to return, the errors returned by rad when requests fail for other
       
   835     reasons are also defined using <acronym>ADR</acronym>.  After the
       
   836     server receives and accepts a <literal>CLIENT-HELLO</literal>
       
   837     message, it replies with <literal>ERRORS</literal> to communicate
       
   838     those type definitions:
       
   839     </para>
       
   840 
       
   841     <rm:proto name="ERRORS">
       
   842 	<rm:data field="error_space" size="varies" type="TYPESPACE">
       
   843 	    typespace containing error types
       
   844 	</rm:data>
       
   845 	<rm:data field="errors" size="varies" type="TYPEREF&lt;&gt;">
       
   846 	    errors types, starting with <literal>EC-NOMEM</literal>
       
   847 	</rm:data>
       
   848     </rm:proto>
       
   849 
       
   850     <para>
       
   851     The <literal>TYPEREF</literal>s refer to the types defined in the
       
   852     <literal>error_space</literal> <literal>TYPESPACE</literal>.  The
       
   853     types define the first <literal>error_count</literal> errors,
       
   854     starting from the first non object-specific error,
       
   855     <literal>EC-NOMEM</literal>.  Any errors for which types are not
       
   856     defined have type <quote>void</quote>.
       
   857     </para>
       
   858 
       
   859     <!--
       
   860       These errors are defined in ADR for convenience and for
       
   861       architectural consistency.  However, from a interface perspective
       
   862       they should be part of the protocol and documented here.
       
   863     -->
       
   864 
       
   865     <para>
       
   866     At this point, the handshake is complete and normal client-server
       
   867     communication can occur.
       
   868     </para>
       
   869 </section>
       
   870 
       
   871 
       
   872 <section><title>Messages</title>
       
   873     <para>
       
   874     Normal communication consists of an asynchronous exchange of
       
   875     messages: <literal>REQUEST</literal>s from the client to the
       
   876     server, <literal>RESPONSE</literal>s from the server to the client,
       
   877     and <literal>EVENT</literal>s from the server to the client.
       
   878     </para>
       
   879 
       
   880     <para>
       
   881     A <literal>REQUEST</literal> is the <literal>rad</literal>
       
   882     equivalent of a low-level remote procedure call.  It consists of a
       
   883     client-selected, non-zero serial number, an operation code, and an
       
   884     opaque, operation-specific, variable-length payload.
       
   885     </para>
       
   886 
       
   887     <rm:proto name="REQUEST">
       
   888 	<rm:data field="serial" size="8" type="hyper">
       
   889 	    client-specified serial number
       
   890 	</rm:data>
       
   891 	<rm:data field="opcode" size="4" type="OP-CODE">
       
   892 	    operation code (see <xref linkend="op-data-def" />)
       
   893 	</rm:data>
       
   894 	<rm:data field="payload" size="varies" type="opaque&lt;&gt;">
       
   895 	    request payload
       
   896 	</rm:data>
       
   897     </rm:proto>
       
   898 
       
   899     <para>
       
   900     The server will respond to every <literal>REQUEST</literal> with a
       
   901     <literal>RESPONSE</literal>.  The structure of a
       
   902     <literal>RESPONSE</literal> varies depending on whether the server
       
   903     was successful in processing the client's request.  A
       
   904     <literal>RESPONSE</literal> consists of the serial number of the
       
   905     corresponding <literal>REQUEST</literal>, a boolean indicating
       
   906     whether the request was successful, and either an
       
   907     operation-specific opaque payload (in the case of success), or an
       
   908     error code and an error-specific error payload (in the case of
       
   909     failure):
       
   910     </para>
       
   911 
       
   912     <rm:proto name="RESPONSE (successful)">
       
   913 	<rm:data field="serial" size="8" type="hyper">
       
   914 	    serial number of REQUEST
       
   915 	</rm:data>
       
   916 	<rm:data field="success" size="4" type="boolean">
       
   917 	    true
       
   918 	</rm:data>
       
   919 	<rm:data field="payload" size="varies" type="opaque&lt;&gt;">
       
   920 	    response payload
       
   921 	</rm:data>
       
   922     </rm:proto>
       
   923 
       
   924     <rm:proto name="RESPONSE (failure)">
       
   925 	<rm:data field="serial" size="8" type="hyper">
       
   926 	    serial number of REQUEST
       
   927 	</rm:data>
       
   928 	<rm:data field="success" size="4" type="boolean">
       
   929 	    false
       
   930 	</rm:data>
       
   931 	<rm:data field="error" size="4" type="ERROR-CODE">
       
   932 	    error code (see <xref linkend="error-data-def" />)
       
   933 	</rm:data>
       
   934 	<rm:data field="payload" size="varies" type="opaque&lt;&gt;">
       
   935 	    error payload
       
   936 	</rm:data>
       
   937     </rm:proto>
       
   938 
       
   939     <para>
       
   940     The <literal>rad</literal> protocol doesn't require the client to
       
   941     wait for a <literal>RESPONSE</literal> before sending another
       
   942     <literal>REQUEST</literal>.  However, the server implementation may
       
   943     place limits on the number of outstanding requests that can be
       
   944     handled simultaneously.  A client with an outstanding
       
   945     <literal>REQUEST</literal> must assume that a subsequent
       
   946     <literal>REQUEST</literal> will block until the
       
   947     <literal>RESPONSE</literal> from the outstanding
       
   948     <literal>REQUEST</literal> is read.
       
   949     </para>
       
   950 
       
   951     <para>
       
   952     Lastly, a client may (via a <literal>REQUEST</literal>) subscribe
       
   953     to asynchronous event sources.  When an event occurs, the server
       
   954     will send an <literal>EVENT</literal> message to the client.  An
       
   955     <literal>EVENT</literal> message will include the object ID of the
       
   956     source object (more later), the time of the event, the name of the
       
   957     event, and an event-specific opaque payload.  An
       
   958     <literal>EVENT</literal> message is distinguished from a
       
   959     <literal>RESPONSE</literal> by having a serial number of 0.
       
   960     </para>
       
   961 
       
   962     <rm:proto name="EVENT">
       
   963 	<rm:data field="serial" size="8" type="hyper">
       
   964 	    0
       
   965 	</rm:data>
       
   966 	<rm:data field="source" size="8" type="hyper">
       
   967 	    id of generating object
       
   968 	</rm:data>
       
   969 	<rm:data field="sequence" size="8" type="hyper">
       
   970 	    sequence number of event
       
   971 	</rm:data>
       
   972 	<rm:data field="timestamp" size="12" type="TIME-DATA">
       
   973 	    time of event
       
   974 	</rm:data>
       
   975 	<rm:data field="name" size="varies" type="string&lt;&gt;">
       
   976 	    event name
       
   977 	</rm:data>
       
   978 	<rm:data field="payload" size="varies" type="opaque&lt;&gt;">
       
   979 	    event payload
       
   980 	</rm:data>
       
   981     </rm:proto>
       
   982 
       
   983 </section>
       
   984 
       
   985 
       
   986 <section><title>Operations</title>
       
   987     <para>
       
   988     Each operation that a client can perform against a
       
   989     <command>rad</command> server has its own request and response
       
   990     payloads.  To facilitate processing without needing to fully decode
       
   991     the payload, they are communicated as variable-lengthed
       
   992     <literal>opaque</literal> data in the <literal>REQUEST</literal>
       
   993     and <literal>RESPONSE</literal>.
       
   994     </para>
       
   995 
       
   996     <para>
       
   997     For consistency and flexibility, all <acronym>ADR</acronym> data
       
   998     referenced by these payloads is communicated as
       
   999     <literal>OPTIONAL-DATA</literal>, which in turn is wrapped as
       
  1000     <literal>opaque</literal> data.
       
  1001     </para>
       
  1002 
       
  1003     <rm:proto name="PAYLOAD-DATA">
       
  1004 	<rm:data field="data" size="varies" type="opaque&lt;&gt;">
       
  1005 	    encapsulated <literal>OPTIONAL-DATA</literal>
       
  1006 	</rm:data>
       
  1007     </rm:proto>
       
  1008 
       
  1009     <section><title>INVOKE</title>
       
  1010 
       
  1011     <para>
       
  1012     INVOKE makes a method call against a <command>rad</command> object,
       
  1013     identified by its object ID.
       
  1014     </para>
       
  1015 
       
  1016     <rm:proto name="INVOKE-REQUEST">
       
  1017 	<rm:data field="objectid" size="8" type="hyper">
       
  1018 	    Object ID, returned by lookup
       
  1019 	</rm:data>
       
  1020 	<rm:data field="mname" size="varies" type="string&lt;&gt;">
       
  1021 	    the method to invoke
       
  1022 	</rm:data>
       
  1023 	<rm:data field="arguments" size="varies" type="PAYLOAD-DATA&lt;&gt;">
       
  1024 	    array of method arguments
       
  1025 	</rm:data>
       
  1026     </rm:proto>
       
  1027 
       
  1028     <rm:proto name="INVOKE-RESPONSE">
       
  1029 	<rm:data field="result" size="varies" type="PAYLOAD-DATA">
       
  1030 	    the return value of method call, if any
       
  1031 	</rm:data>
       
  1032     </rm:proto>
       
  1033 
       
  1034     <rm:errors op="INVOKE">
       
  1035 	<rm:error code="EC-OBJECT">
       
  1036 	    The method call was made but failed for an object-specific
       
  1037 	    reason.
       
  1038 	</rm:error>
       
  1039 	<rm:error code="EC-NOTFOUND">
       
  1040 	    <literal>objectid</literal> isn't a known object id, or the
       
  1041 	    object doesn't have the method <literal>mname</literal>.
       
  1042 	</rm:error>
       
  1043 	<rm:error code="EC-MISMATCH">
       
  1044 	    The wrong number of arguments were provided, or a
       
  1045 	    non-optional argument was missing.
       
  1046 	</rm:error>
       
  1047 	<rm:error code="EC-NOMEM">
       
  1048 	    The server had insufficient resources to complete the
       
  1049 	    operation.
       
  1050 	</rm:error>
       
  1051 	<rm:error code="EC-SYSTEM">
       
  1052 	    An unexpected internal error occurred.
       
  1053 	</rm:error>
       
  1054     </rm:errors>
       
  1055 
       
  1056     </section>
       
  1057 
       
  1058     <section><title>GETATTR</title>
       
  1059 
       
  1060     <para>
       
  1061     GETATTR reads an attribute of a <command>rad</command> object,
       
  1062     identified by its object ID.
       
  1063     </para>
       
  1064 
       
  1065     <rm:proto name="GETATTR-REQUEST">
       
  1066 	<rm:data field="objectid" size="8" type="hyper">
       
  1067 	    Object ID, returned by lookup
       
  1068 	</rm:data>
       
  1069 	<rm:data field="aname" size="varies" type="string&lt;&gt;">
       
  1070 	    the attribute to read
       
  1071 	</rm:data>
       
  1072     </rm:proto>
       
  1073 
       
  1074     <rm:proto name="GETATTR-RESPONSE">
       
  1075 	<rm:data field="result" size="varies" type="PAYLOAD-DATA">
       
  1076 	    the value of the attribute
       
  1077 	</rm:data>
       
  1078     </rm:proto>
       
  1079 
       
  1080     <rm:errors op="GETATTR">
       
  1081 	<rm:error code="EC-OBJECT">
       
  1082 	    An attempt to read the attribute was made, but failed for
       
  1083 	    an object-specific reason.
       
  1084 	</rm:error>
       
  1085 	<rm:error code="EC-NOTFOUND">
       
  1086 	    <literal>objectid</literal> isn't a known object id, or the
       
  1087 	    object doesn't have the attribute <literal>aname</literal>.
       
  1088 	</rm:error>
       
  1089 	<rm:error code="EC-ILLEGAL">
       
  1090 	    <literal>aname</literal> refers to a write-only attribute.
       
  1091 	</rm:error>
       
  1092 	<rm:error code="EC-NOMEM">
       
  1093 	    The server had insufficient resources to complete the
       
  1094 	    operation.
       
  1095 	</rm:error>
       
  1096 	<rm:error code="EC-SYSTEM">
       
  1097 	    An unexpected internal error occurred.
       
  1098 	</rm:error>
       
  1099     </rm:errors>
       
  1100 
       
  1101     </section>
       
  1102 
       
  1103     <section><title>SETATTR</title>
       
  1104 
       
  1105     <para>
       
  1106     SETATTR reads an attribute of a <command>rad</command> object,
       
  1107     identified by its object ID.  The response payload for a SETATTR
       
  1108     request is empty.
       
  1109     </para>
       
  1110 
       
  1111     <rm:proto name="SETATTR-REQUEST">
       
  1112 	<rm:data field="objectid" size="8" type="hyper">
       
  1113 	    Object ID, returned by lookup
       
  1114 	</rm:data>
       
  1115 	<rm:data field="aname" size="varies" type="string&lt;&gt;">
       
  1116 	    the attribute to write
       
  1117 	</rm:data>
       
  1118 	<rm:data field="value" size="varies" type="PAYLOAD-DATA">
       
  1119 	    the new value of the attribute
       
  1120 	</rm:data>
       
  1121     </rm:proto>
       
  1122 
       
  1123     <rm:errors op="SETATTR">
       
  1124 	<rm:error code="EC-OBJECT">
       
  1125 	    An attempt to write the attribute was made, but failed for
       
  1126 	    an object-specific reason.
       
  1127 	</rm:error>
       
  1128 	<rm:error code="EC-NOTFOUND">
       
  1129 	    <literal>objectid</literal> isn't a known object id, or the
       
  1130 	    object doesn't have the attribute <literal>aname</literal>.
       
  1131 	</rm:error>
       
  1132 	<rm:error code="EC-MISMATCH">
       
  1133 	    <literal>aname</literal> has a non-optional value and
       
  1134 	    <literal>value</literal> was NULL.
       
  1135 	</rm:error>
       
  1136 	<rm:error code="EC-ILLEGAL">
       
  1137 	    <literal>aname</literal> refers to a read-only attribute.
       
  1138 	</rm:error>
       
  1139 	<rm:error code="EC-NOMEM">
       
  1140 	    The server had insufficient resources to complete the
       
  1141 	    operation.
       
  1142 	</rm:error>
       
  1143 	<rm:error code="EC-SYSTEM">
       
  1144 	    An unexpected internal error occurred.
       
  1145 	</rm:error>
       
  1146     </rm:errors>
       
  1147 
       
  1148     </section>
       
  1149 
       
  1150     <section><title>LOOKUP</title>
       
  1151 
       
  1152     <para>
       
  1153     LOOKUP attempts to find the named object in the server's namespace,
       
  1154     returning the object and API IDs of the object if it exists.  Since
       
  1155     an object isn't usable until its API has been DEFINEed, the client
       
  1156     may request the API definition be provided as part of the LOOKUP
       
  1157     response.  For the same reason, the server may unilaterally decide
       
  1158     to provide the API definition if it believes the client hasn't seen
       
  1159     it yet.
       
  1160     </para>
       
  1161 
       
  1162     <rm:proto name="LOOKUP-REQUEST">
       
  1163 	<rm:data field="name" size="varies" type="NAME-DATA">
       
  1164 	    object name
       
  1165 	</rm:data>
       
  1166 	<rm:data field="define" size="4" type="boolean">
       
  1167 	    include object definition?
       
  1168 	</rm:data>
       
  1169     </rm:proto>
       
  1170 
       
  1171     <rm:proto name="LOOKUP-RESPONSE">
       
  1172 	<rm:data field="objectid" size="8" type="hyper">
       
  1173 	    ID of the object
       
  1174 	</rm:data>
       
  1175 	<rm:data field="apiid" size="8" type="hyper">
       
  1176 	    ID of the object's API
       
  1177 	</rm:data>
       
  1178 	<rm:data field="definition" size="varies" type="API-TYPE *">
       
  1179 	    the definition of the object's API
       
  1180 	</rm:data>
       
  1181     </rm:proto>
       
  1182 
       
  1183     <rm:errors op="LOOKUP">
       
  1184 	<rm:error code="EC-NOTFOUND">
       
  1185 	    <literal>name</literal> doesn't exist.
       
  1186 	</rm:error>
       
  1187 	<rm:error code="EC-NOMEM">
       
  1188 	    The server had insufficient resources to complete the
       
  1189 	    operation.
       
  1190 	</rm:error>
       
  1191 	<rm:error code="EC-SYSTEM">
       
  1192 	    An unexpected internal error occurred.
       
  1193 	</rm:error>
       
  1194     </rm:errors>
       
  1195 
       
  1196     </section>
       
  1197 
       
  1198     <section><title>DEFINE</title>
       
  1199 
       
  1200     <para>
       
  1201     DEFINE requests a definition of the specified API ID.
       
  1202     </para>
       
  1203 
       
  1204     <rm:proto name="DEFINE-REQUEST">
       
  1205 	<rm:data field="apiid" size="8" type="hyper">
       
  1206 	    API ID
       
  1207 	</rm:data>
       
  1208     </rm:proto>
       
  1209 
       
  1210     <rm:proto name="DEFINE-RESPONSE">
       
  1211 	<rm:data field="definition" size="varies" type="API-TYPE">
       
  1212 	    the definition of the API
       
  1213 	</rm:data>
       
  1214     </rm:proto>
       
  1215 
       
  1216     <rm:errors op="DEFINE">
       
  1217 	<rm:error code="EC-NOTFOUND">
       
  1218 	    <literal>apiid</literal> isn't a known
       
  1219 	    <acronym>API</acronym> ID.
       
  1220 	</rm:error>
       
  1221 	<rm:error code="EC-NOMEM">
       
  1222 	    The server had insufficient resources to complete the
       
  1223 	    operation.
       
  1224 	</rm:error>
       
  1225 	<rm:error code="EC-SYSTEM">
       
  1226 	    An unexpected internal error occurred.
       
  1227 	</rm:error>
       
  1228     </rm:errors>
       
  1229 
       
  1230     </section>
       
  1231 
       
  1232     <section><title>LIST</title>
       
  1233 
       
  1234     <para>
       
  1235     LIST requests an enumeration of all objects present in the server
       
  1236     that match the specified object name pattern.  The empty string
       
  1237     matches all server objects.
       
  1238     </para>
       
  1239 
       
  1240     <rm:proto name="LIST-REQUEST">
       
  1241 	<rm:data field="pattern" size="varies" type="NAME-DATA">
       
  1242 	    object name pattern
       
  1243 	</rm:data>
       
  1244     </rm:proto>
       
  1245 
       
  1246     <rm:proto name="LIST-RESPONSE">
       
  1247 	<rm:data field="names" size="varies" type="NAME-DATA&lt;&gt;">
       
  1248 	    the definition of the API
       
  1249 	</rm:data>
       
  1250     </rm:proto>
       
  1251 
       
  1252     <rm:errors op="LIST">
       
  1253 	<rm:error code="EC-NOMEM">
       
  1254 	    The server had insufficient resources to complete the
       
  1255 	    operation.
       
  1256 	</rm:error>
       
  1257 	<rm:error code="EC-SYSTEM">
       
  1258 	    An unexpected internal error occurred.
       
  1259 	</rm:error>
       
  1260     </rm:errors>
       
  1261 
       
  1262     </section>
       
  1263 
       
  1264     <section><title>SUB and UNSUB</title>
       
  1265 
       
  1266     <para>
       
  1267     SUB and UNSUB subscribe and unsubscribe, respectively, to the named
       
  1268     event of the specified object.  The response payload for a
       
  1269     successful SUB or UNSUB is empty.
       
  1270     </para>
       
  1271     
       
  1272     <para>
       
  1273     Note that it is possible to receive an <literal>EVENT</literal>
       
  1274     that has been UNSUBed after a successful UNSUB.
       
  1275     </para>
       
  1276 
       
  1277     <rm:proto name="SUB-REQUEST">
       
  1278 	<rm:data field="objectid" size="8" type="hyper">
       
  1279 	    ID of the object
       
  1280 	</rm:data>
       
  1281 	<rm:data field="event" size="varies" type="string&lt;&gt;">
       
  1282 	    event name
       
  1283 	</rm:data>
       
  1284     </rm:proto>
       
  1285 
       
  1286     <rm:proto name="UNSUB-RESPONSE">
       
  1287 	<rm:data field="objectid" size="8" type="hyper">
       
  1288 	    ID of the object
       
  1289 	</rm:data>
       
  1290 	<rm:data field="event" size="varies" type="string&lt;&gt;">
       
  1291 	    event name
       
  1292 	</rm:data>
       
  1293     </rm:proto>
       
  1294 
       
  1295     <rm:errors op="SUB">
       
  1296 	<rm:error code="EC-NOTFOUND">
       
  1297 	    <literal>objectid</literal> isn't a known object id, or the
       
  1298 	    object doesn't have the event <literal>event</literal>.
       
  1299 	</rm:error>
       
  1300 	<rm:error code="EC-EXISTS">
       
  1301 	    The client is already subscribed to <literal>event</literal>.
       
  1302 	</rm:error>
       
  1303 	<rm:error code="EC-NOMEM">
       
  1304 	    The server had insufficient resources to complete the
       
  1305 	    operation.
       
  1306 	</rm:error>
       
  1307 	<rm:error code="EC-SYSTEM">
       
  1308 	    An unexpected internal error occurred.
       
  1309 	</rm:error>
       
  1310     </rm:errors>
       
  1311 
       
  1312     <rm:errors op="UNSUB">
       
  1313 	<rm:error code="EC-NOTFOUND">
       
  1314 	    <literal>objectid</literal> isn't a known object id, the
       
  1315 	    object doesn't have the event <literal>event</literal>, or
       
  1316 	    the client isn't subscribed to <literal>event</literal>.
       
  1317 	</rm:error>
       
  1318 	<rm:error code="EC-NOMEM">
       
  1319 	    The server had insufficient resources to complete the
       
  1320 	    operation.
       
  1321 	</rm:error>
       
  1322 	<rm:error code="EC-SYSTEM">
       
  1323 	    An unexpected internal error occurred.
       
  1324 	</rm:error>
       
  1325     </rm:errors>
       
  1326 
       
  1327     </section>
       
  1328 
       
  1329 </section>
       
  1330 
       
  1331 </appendix>