3. Bidirectional negotiation
We now turn to the last case of feature negotiation during
connection-setup, characterised by the
simultaneous negotiation of one
or more identical features (i.e. both
feature
number and
feature location
agree).
For simplicity, and since negotiation of non-overlapping features can
be reduced to one of above the cases, we will here
assume that client and server negotiate an identical set of
features. We further use simplified notation by speaking of a
single feature
F
simultaneously being negotiated, where
- the client is referred
to as `DCCP A' and intends to change the value of F from its default F_default to F_A;
- the server
is referred
to as `DCCP B' and intends
to change the value of F
to F_B.
The underlying situation is now that the client sends a
Request with a
Change(F, F_A), and the
server replies
with a
Response
carrying a
Change(F, F_B). We can understand
F_A and
F_B as
either
scalars (NN feature) or preference lists (SP feature).
3.1 Motivation for feature-initiation states
RFC 4340 leaves open how features
are
initialised: the state
diagram in 6.6.2 begins with the
STABLE
state already entered; the
UNSTABLE
state
is only entered
from the
CHANGING state,
which in turn is reached via the
STABLE
state. Hence we need to clarify how DCCP A and
DCCP B can initially enter
their
STABLE states.
The case is clear when both sides agree to
use only default values. Since each
feature has a known initial value (6.4), the use of defaults implies
entering the
STABLE
state.
We have previously discussed two cases where endpoints were
initially not in the STABLE state (by virtue of changing their
feature values different from the defaults), but reached the
STABLE state after successful
negotiation. In the present case of simultaneous negotiation we again
need to
clarify how the endpoints enter the
STABLE state for
F. We do this by augmenting the
state diagram from 6.6.2 with
two additional (auxiliary) states, which describe the processing
during the initialisation of the endpoints.
The
lower half of the
diagram, as well as the related state transitions
, are exactly as per 6.6.2.
At the top are
two new states:
- DEFAULT, to indicate
the use of the default values from 6.4;
- INITIALISING,
reachable only from DEFAULT,
to indicate the initialisation of features with values other than the
6.4-defaults.
Also shown is the transition from
DEFAULT
to
STABLE which is
implied when both
endpoints `agree' to use their feature defaults. This transition
corresponds to `normal' connection setup, i.e. using the
three-way handshake (as per 8.1.1,
8.1.3, and 8.1.5) without carrying any feature-negotiation
options.
An endpoint in state `
INITIALISING'
enters the
CHANGING state
by virtue of sending a
Change
feature-negotiation option during connection-setup. The term `
connection-setup' here is meant to
cover both previously discussed unidirectional cases:
- the client which
transmits a Change option
on its initial Request;
- the server
which
transmits a Change option
on its Response once
it receives the Request
from the client.
If only
unidirectional feature
negotiation were to be used, then the
INITIALISING state could be
omitted: the endpoint could enter
CHANGING
state immediately,
after piggybacking its
Change
option onto the respective connection-setup message (either
Request or
Response).
For
simultaneous feature negotiation,
however, there are
distinct
advantages in using the
INITIALISING
state as it
allows to take into account how the three-way handshake progresses: we
can thereby eliminate one pair of
redundant
messages: due the rules in
6.6, a
Confirm
must be sent in response to the
Change
sent by the client, but sending the second
Change - and thus
having to
await the corresponding
Confirm
- is not necessary.
This further simplifies the processing rules: since the client
progresses from
INITIALISING
to
CHANGING directly
after sending its
Request,
only servers can receive
Change
options when in state
INITIALISING.
3.1.1 Simultaneous negotiation of NN features
We will first establish that simultaneous negotiation only really
applies
to SP features (as presented in the next sub-section). This is due to
the fact that only
Change L
features are admissible for NN features (6.3.2). Note in this regard
that
crossing
Change L options
is
not what this section is
about: in that case, both endpoints
negotiate the same feature
number,
but at
different locations - this
is
negotiation of disjoint features.
By
simultaneous negotiation, to
repeat, we mean negotiating for the same
feature number
and
feature
location. In terms of message formats this means that a
Change L/R is received by a
server which itself is waiting to
send a
Change R/L,
respectively. This
scenario can in principle
not
occur for NN options, since
Change
R are
invalid negotiation
options for
such features
(6.3.2 and
6.6.8); but a robust
server
must deal
correctly with the reception of such options. There are two issues
here.
Firstly,
the
server can not send
an
empty Confirm L option (as mandated by 6.6.8),
since
Confirm L options
must not be sent for NN features (6.3.2).
Secondly, even if the
server
were
allowed to send a
Confirm L
option, the next logical step for the client would be to
reset the connection, due to the
requirements of 6.6.8 and 6.3.2 (as
Confirm L
options are invalid for this feature). This is a
futile exchange of
messages, since the
Reset
is inevitable. Hence we abbreviate this by sending the
Reset
directly when receiving a
Change
R during
connection setup, as shown in the above diagram.
3.1.2 Simultaneous negotiation of SP features
The specification has only a single example of simultaneously
negotiating SP
features; on page 36 of RFC 4340. This example needs to be
understood with respect to the general state transition diagram of
6.6.2
(i.e. where both
endpoints have been at least once in the STABLE state for the negotiated
feature). In discussing this example, we will motivate a simpler
solution.
The example shown on page 36 displays two problems/limitations.
Firstly, it does not apply
when the
server is in the
UNSTABLE
state, since the processing rules in 6.6.2 state that the received
Change R from the client is to
be ignored - which means that the shown
Confirm L would not have been
generated in the first place. Therefore, the only logically possible
case for the message exchange shown on page 36 is when the
server
changes its preference list
immediately
after receiving the
Change
R, and before sending the
Confirm
L option.
The
second problem is that
the
Change L option of
the
server is
redundant, for
it simply reduplicates/copies the preference list which is already
being sent out via the
Confirm L
message. Since the only state transition in which
Confirm messages can be sent
are those from
CHANGING
to
STABLE (cf. 6.6.2),
the
server enters
STABLE
state, which means that the
Confirm
R then subsequently sent by the client will simply be ignored.
To avoid such a redundancy, in which first the same
information is copied identically into two different
feature-negotiation options, and the subsequent
Confirm option is
then ignored, we propose the solution presented in the next subsection.
3.2 Proposed algorithm for simultaneous negotiation during
connection-setup
Summarising the above, our solution exploits that
- simultaneous negotiation is de facto only applicable to SP features;
- during connection setup, the messages carrying
feature-negotiation content do not
appear in parallel, but in predefined
sequential order
(three-way handshake).
The
starting point here is
that the listening
server
wants to use
F_B (a list) instead of the
default value
F_default
for feature
F;
and that the client wants to use
F_A
(also a list), for
which it sends a
Change(F, F_A) on its
Request.
There are now
two possibilities of
negotiating between
F_A
and
F_B:
1)
There is a
shared entry between F_A
and F_B
In this case, construct
F_A' using
the SP rule from 6.3.1, i.e.
select the first entry,
X,
from
F_B
which also appears in
F_A,
and let
F_A' be the
concatenation of
X and
F_B.
Send a
Confirm(F, F_A') to the client via
the
Response, and let
the
server enter
STABLE state for
F.
2) F_A and F_B do
not have a shared entry (disjoint)
Here we have that both endpoints are negotiating
incompatible sets of
values, which will eventually lead to failure. Still, we
first
try to save the connection using the following idea:
(a)
If F_B
contains F_default, then
let the server use F_default,
add an empty Confirm(F)
option to the Response
sent to the client, and enter the STABLE
feature state for F. The empty
Confirm indicates to the
client that F_A was not
accepted and that the client should use the old value (6.6.7) -
which in
this case means F_default.
(b) If F_B
does not contain F_default,
reset the connection.
In contrast to `
normal' feature
negotiation, the case of
"
feature not understood" is
ruled out, since by assumption both
endpoints negotiate the same feature.
The
following
diagram summarises the implications for the
INITIALISING state at the
server, the next section
then presents the summary flowcharts.
4. Summary and combined algorithm
We now assemble the cases for unidirectional and simultaneous feature
negotiation during connection setup.
4.1 Feature negotiation at the client
Since simultaneous negotiation during connection setup is
transparent
to the client (it is entirely handled by the
server), this is
straightforward.
If the client uses the defaults then changes from
DEFAULT to
STABLE as
soon as the
Response
from the
server arrives.
When this message carries
a
Change option
(unidirectional
server-to-client
negotiation), the client proceeds according to the state transitions
for the
STABLE state
(6.6.2). If there is no such option present in the
Response (i.e. both
endpoints use the defaults), no further processing
is required.
If the client does change feature values at
the begin of the connection, it enters
INITIALISING state and, after
sending its
Request
with the corresponding
Change
options, moves to
CHANGING.
As both unidirectional and simultaneous negotiation are handled
by the
server, the outcome
now depends on the
Confirm
options sent by
the
server on the
Response (as above).
4.2 Feature negotiation at the server
If the server, whose initial
state is
DEFAULT, does
not want to alter the default feature values, it
enters
STABLE once the
connection setup
(
Request) message
arrives. If this message contains a
Change option
(unidirectional client-to-server negotiation), the outcome depends on
the rules for the
STABLE
state (6.6.2).
If the server wants to use values other than the defaults, it moves
from
DEFAULT to
INITIALISING. The next state
now depends on the
Request
sent by the client. If it contains a
Change option with the same
feature number and feature location as the one for which the server
just
entered
INITIALISING
state, then
simultaneous negotiation
takes place. As described in the previous section, the next state is
then
STABLE
(successful negotiation);
or the connection is reset
(error
handling).
If, on the other hand, no
Change
option was present in the
Request
(unidirectional server-to-client negotiation), the server adds its
corresponding
Change
option onto the pending
Response
and
enters
CHANGING state for
this feature. Further processing now depends
on the rules for the
CHANGING
state (6.6.2).
4.3 Processing Change
options during connection setup
To summarise the processing of
Change
options necessary during connection-setup, a flowchart is
presented below. It integrates both client-side and server-side
processing,
and tracks closely the general considerations for processing
Change options presented in the
background section.
Notice how this flowchart separates the
general case from feature
negotiation
during connection-setup
and handling of
simultaneous
negotiation from
unidirectional
negotiation, all through the introduction of the single
auxiliary
INITIALISING
state: only the server is able to receive
Change options in this state,
and at the same time it is the server which detects and resolves
simultaneous negotiation begun by a client.
4.4 Processing Confirm
options during connection setup
No special considerations, in contrast, are necessary for
handling
Confirm options
during connection-setup ,
since their processing takes part in the
CHANGING state and since the
required transitions into this state have been established (cf. above).
Hence the flowchart below is identical with the one presented for the
general case
earlier.
4.5 A final note on multiple-option negotiation
In the above we have used the simplification of talking about
negotiating only a single feature
F during
connection setup. When more than one feature is negotiated, each can be
considered on a
case-by-case
basis using the above types
(i.e. either
unidirectional or simultaneous
negotiation). The
main
difference to be taken care of is the use of "
at
least" conditions to manage the global outcome:
if negotiation of multiple features
fails
for at least one feature,
then feature negotiation
fails as a
whole, and the presented error
rules apply. This
consideration is necessary to avoid partially-undefined feature
parameters.