[BEEPwg] Trouble with TLS and transport mappings

Jered Floyd jered@permabit.com
19 Nov 2001 15:43:03 -0500


Greetings,

I have encountered another (somewhat obscure) case in RFC 3080 where I
am unsure what the proper behaviour is for a BEEP library; or rather,
I am sure what the proper behaviour is, and also sure that it would
lead to deadlock.

RFC 3080, Section 3.1.3.1 states:

  When a BEEP peer sends the "ready" element, it MUST NOT send any
  further traffic on the underlying transport service until a
  corresponding reply ("proceed" or "error") is received; ...
  [emphasis mine]

This clearly includes SEQ frames, and must do so to ensure the
connection streams are in a consistent state when the underlying
negotiation process begins.

If the peer that sends the "ready" element cannot send SEQ frames for
the channel upon which it expects a reply (zero in the case of a
piggybacked request, some other channel in the case of a started
channel) it is not always possible for the remote peer to send its
response.  If the response to be sent exceeds the channel window size,
the peer that sent the "ready" element has no way to indicate to the
responding peer that more space is available after it partially
processes the response, as it is unable to send SEQ frames.

This cannot be fixed by allowing SEQ frames until the last frame of
the response is received; the peer has know way of knowing if the last
frame is already 'on the wire' when it sends a SEQ, and thus could
send a SEQ after the remote peer believes that the next bytes to be
received should correspond to the underlying negotiation process.

An example of a TLS negotation attempt that must result in deadlock
under the current guidelines:

C: MSG 0 1 . 52 158
C: Content-Type: application/beep+xml
C:
C: <start number='1'>
C:    <profile uri='http://iana.org/beep/TLS'>
C:       <![CDATA[<ready />]]>
C:    </profile>
C: </start>
C: END
S: RPY 0 1 * 110 4096
S: Content-Type: application/beep+xml
S:
S: <profile uri='http://iana.org/beep/TLS'>
S:    <![CDATA[<error code='554'>This is a very long error response
S:             that is still within the 4K limit for an initialization
S:             message embedded in a "start" transaction, but brings
S:             the channel zero message size to above the size of
S:             the channel zero TCP mapping window [more data here
S:             to reach 4K within this frame...]
S: END
<peer 'S' is now waiting for window space to become available so that
 it may send the remainder of RPY 1.>

(A successful negotation request for TLS that results in deadlock
would be extremely contrived, but this may not be the case for other
profiles that implement transport level security.)

It is insufficient to limit the full channel zero response to a tuning
request to less than 4K, as there's no reason in RFC 3081 for the peer
to necessarily have advertised that it has a completely empty window
(thus at least 4K).

The only solution I have come up with is to declare at the transport
level that channels implementing a tuning profile disregard the window
mechanism; the sending peer may send data at any time and the
recipient must be prepared to accept it.  I don't find this solution
particularly pleasing.

Does anyone have a better counter-proposal?

--Jered