-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Earlier today I rewrote the section of 3920bis on stream features,
expanding it to cover the stream negotiation process in general. Thanks
to Jehan Pagès for pointing out to me in private conversation that this
topic was underspecified. My provisional text follows. I will review
this again next, but as always feedback is welcome.
######
5.2. Stream Negotiation
5.2.1. Overview
Because the receiving entity for a stream acts as a gatekeeper to the
domains it services, it imposes certain conditions for connecting as
a client or as a peer server. At a minimum, the initiating entity
needs to authenticate with the receiving entity before it is allowed
to send stanzas to the receiving entity, typically using SASL as
described under Section 7. However, the receiving entity can require
other conditions in addition to authentication, such as encryption
using TLS as described under Section 6. The receiving entity informs
the initiating entity about such conditions by communicating STREAM
FEATURES: the set of particular protocol interactions that are
mandatory for the initiating entity to complete before the receiving
entity will accept XML stanzas from the initiating entity (e.g.,
authentication), as well as any protocol interactions that are
voluntary but that might improve the handling of an XML stream (e.g.,
establishment of application-layer compression).
The existence of such conditions implies that streams need to be
negotiated, and the order of layers (TCP, then TLS, then SASL, then
XMPP; see Section 14.5) implies that stream negotiation is a well-
defined process. Furthermore, stream features can be either
mandatory or voluntary; this imposes further structure on the
negotiation process. Finally, for security reasons, the parties to a
stream need to discard knowledge that they gained during the
negotiation process after successfully completing the protocol
interactions defined for certain features (e.g., TLS and SASL); this
is done by flushing the old stream context and exchanging new stream
headers over the existing TCP connection.
5.2.2. Stream Features Format
If the initiating entity includes the 'version' attribute set to a
value of at least "1.0" in the initial stream header, after sending
the response stream header the receiving entity MUST send a
<features/> child element (prefixed by the streams namespace prefix)
to the initiating entity in order to announce any conditions for
continuation of the stream negotiation process. Each condition takes
the form of a child element of the <features/> element, qualified by
a namespace that is different from the streams namespace and the
default namespace.
If negotiation of a particular stream feature is mandatory, the
stream feature advertisement MUST include an empty <required/> child
element.
If negotiation of a particular stream feature is voluntary, the
stream feature advertisement MAY include an empty <optional/> child
element. However, because every stream feature defaults to
voluntary, the inclusion of an empty <optional/> child element is not
necessary to indicate that a stream feature is voluntary.
For security reasons, certain stream features necessitate the
initiating entity to send a new initial stream header upon successful
negotiation of the feature (e.g., TLS and SASL). If a stream restart
is necessary for any given feature, the <optional/> or <required/>
child element MUST include a boolean 'restart' attribute with a value
of "true" or "1" (this optional attribute defaults to false).
Although it is expected that stream restarts will be necessary only
for mandatory features, voluntary features are also allowed to
necessitate restarts.
Aside from the <optional/> child element, <required/> child element,
and 'restart' attribute, the syntax and semantics of each particular
feature are defined by an appropriate specification of that feature;
several such features are defined in this document but stream
features can be defined by other documents, as well.
A <features/> element that contains at least one mandatory feature
indicates that the stream negotiation is not complete and that the
initiating entity MUST negotiate further features.
R: <stream:features>
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
<required/>
</starttls>
</stream:features>
A <features/> element MAY contain more than one mandatory feature.
This means that the initiating entity can choose among the mandatory
features. For example, perhaps a future technology will perform
roughly the same function as TLS, so the receiving entity might
advertise support for both TLS and the future technology.
A <features/> element that contains only voluntary features indicates
that the stream negotiation is complete and that the initiating
entity is cleared to send XML stanzas, but that the initiating entity
MAY negotiate further features if desired.
R: <stream:features>
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'>
<optional/>
</session>
<compression xmlns='http://jabber.org/features/compress'>
<method>zlib</method>
<method>lzw</method>
<optional/>
</compression>
</stream:features>
A <features/> element that contains both mandatory and voluntary
features indicates that the negotiation is not complete but but that
the initiating entity MAY complete the voluntary feature(s) before it
attempts to negotiate the mandatory feature(s).
R: <stream:features>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<required/>
</bind>
<compression xmlns='http://jabber.org/features/compress'>
<method>zlib</method>
<method>lzw</method>
<optional/>
</compression>
</stream:features>
An empty <features/> element indicates that the stream negotiation is
complete and that the initiating entity is cleared to send XML
stanzas.
R: <stream:features/>
Note: The order of child elements contained in any given
<features/> element is not significant.
If the initiating entity does not understand or support a feature
that has been advertised, it MUST still inspect the feature
advertisement to determine if negotiation of the feature is
mandatory. If negotiation of an unsupported feature is mandatory and
the receiving entity has offered no other mandatory features at that
stage of the negotiation process, then the initiating entity MUST
abort the stream negotiation process and SHOULD return an
<unsupported-feature/> stream error to the receiving entity. If
negotiation of an unsupported feature is voluntary, the entity MUST
silently ignore the associated feature advertisement and proceed with
the stream negotiation process.
Note: Implementations based on an earlier revision of this
specification do not include the <optional/> child element and
they include the <required/> child element only in the case of the
STARTTLS feature. Entities MUST accept stream feature
advertisements without the child elements, and MUST consider
negotiation of such features to be voluntary.
5.2.3. Restarts
On successful negotiation of a feature that requires a stream
restart, both parties MUST consider the previous stream to be
replaced but MUST NOT terminate the underlying TCP connection;
instead, the parties MUST reuse the existing connection, which might
be in a new state (e.g., encrypted as a result of TLS negotiation).
The initiating entity then MUST send a new initial stream header,
which SHOULD be preceded by an XML declaration as described under
Section 12.5. When the receiving entity receives the new initial
stream header, it MUST generate a new stream ID (instead of re-using
the old stream ID) before sending a new response stream header (which
SHOULD be preceded by an XML declaration as described under
Section 12.5).
5.2.4. Resending Features
After completing negotiation of any stream feature (even stream
features that do not require a stream restart), the receiving entity
MUST send an updated list of stream features to the initiating
entity, where the list MAY be empty if there are no further features
to be advertised.
At any time after stream establishment and before closing of the
stream, the receiving entity MAY send additional or modified stream
feature advertisements to the initiating entity (e.g., because a new
feature has been enabled).
5.2.5. Completion of Stream Negotiation
The receiving entity indicates completion of the stream negotiation
process by sending to the initiating entity either an empty
<features/> element or a <features/> element that contains only
voluntary features. Once stream negotiation is complete, the
initiating entity is cleared to send XML stanzas over the stream for
as long as the stream is maintained by both parties.
The initiating entity MUST NOT attempt to send XML stanzas
(Section 9) over the stream until stream negotiation has been
completed. However, if it does attempt to do so, the receiving
entity MUST NOT accept such stanzas and MUST return a <not-
authorized/> stream error. This rule applies to XML stanzas only
(i.e., <message/>, <presence/>, and <iq/> elements qualified by the
default namespace) and not to XML elements used for stream
negotiation (e.g., elements used to complete TLS negotiation
(Section 6) or SASL negotiation (Section 7)).
5.2.6. State Chart
We summarize the foregoing rules in the following non-normative state
chart, presented from the perspective of the initiating entity.
+------------+
| open TCP |
| connection |
+------------+
|
+---------------+
| send initial |<-------------------------------------------+
| stream header | |
+---------------+ |
| |
+------------------+ |
| receive response | |
| stream header | |
+------------------+ |
| |
+----------------+ |
| receive stream | |
| features | |
+----------------+ |
| |
{empty?} ---> {all voluntary?} ---> {some mandatory?} |
| no | no | |
| yes | yes | |
| | | |
| +---------------+ +----------------+ |
| | MAY negotiate | | MUST negotiate | |
| | any feature | | one feature | |
| +---------------+ +----------------+ |
| | | |
| +--->-------+---<------+ |
| | |
| [restart required?] ------------>+
| | yes
| no |
| |
| +-------------+
| | negotiation |
+-------------------->| complete |
+-------------+
######
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkrGn+MACgkQNL8k5A2w/vzDUQCg45C5e2YNky1nzmaa3+C72N9f
0PIAoOzrVqmXXgh1QPbFRyOsv7qyLJe3
=ZwmO
-----END PGP SIGNATURE-----
Note Well: Messages sent to this mailing list are the opinions of the senders and do not imply endorsement by the IETF.