Subject: [hybi] method of allocation of reserved bits to extensions

From: Brodie Thiesfield <[email-masked]>
Date: Thu, 28 Apr 2011 10:12:11 +0900

All,

The WebSocket spec permits extensions to use reserved bits, however I
can't see that it provides any way to negotiate which bit should be
used in the presence of multiple extensions competing for a reserved
bit. If a negotiation method is not prescribed, each extension will
just state "using RSV1" or similar in their spec and then either that
bit will become the "extension X bit" or that extension will not be
compatible with other extensions that want to use the same bit.

For example, a "deflate-payload" extension that allows optional
compression might want to use a bit in the frame to denote
compression. If it is used with the "mux-a-million" extension that
also wants to use a reserved bit, both server and client need to agree
on which bits are used. The server needs to allocate these reserved
bits to the extensions that require them.

I propose the following addition to the extensions section:

8.2 Negotiating Reserved Bits

An extension may require or desire the use of a reserved bit in the
framing for proper operation. It is the responsibility of the server
to allocate the reserved bits to those extensions that require them.
Because the server must know all extension requirements before
negotiating its use, requirements for mandatory or optional use of a
reserved frame bit is assumed to be known by the server. Extensions
that allocated a reserved frame bit will have that allocation included
in the response as a bit allocation header.

If an extension requires the use of one or more reserved bits but it
has not been allocated all required bits, the extension MUST NOT be
included in the list of negotiated extensions in the response. If an
extension can optionally use a reserved bit but it has not been
allocated the bit, the extension MAY be included in the list of
negotiated extensions but a bit allocation will not be present in the
response for that extension. The selection of extensions and
allocation of reserved frame bits to the extensions is at the
discretion of the server. Extensions MUST NOT depend on the reserved
bit staying the same as any previous allocation.

The server MUST return a bit reservation header, and include an entry
for each extension that has been allocated a reserved frame bit:

bit-reservation-header = "Sec-WebSocket-Reserved-Bits:" bit-allocation
bit-allocation = extension-token "=" allocated-bits
allocated-bits = bitnum *(";" bitnum)
bitnum = 1#digit

The bitnum is the number of the reserved bit corresponding to the
WebSocket protocol specification section 4.2 where "1" is RSV1, "2" is
RSV2, etc.

For example, to allocate RSV3 to deflate-payload and RSV1 to
mux-a-million would add the following two headers to the response:

Sec-WebSocket-Reserved-Bits: deflate-payload=3
Sec-WebSocket-Reserved-Bits: mux-a-million=1

Note that like other HTTP headers, this header MAY be split or
combined across multiple lines.  Ergo, the following header is
equivalent to the two headers above:

Sec-WebSocket-Reserved-Bits: deflate-payload=3, mux-a-million=1

If an extension has been allocated the use of multiple bits, multiple
allocations MUST follow it's token. An extension token MUST NOT appear
more than once in the Sec-WebSocket-Reserved-Bits header. For example,
if it assumed that the "mux-a-million" extension requires the use of a
single bit, but can optionally use another bit. If the server
allocates two bits to the extension, the following header may be
returned:

Sec-WebSocket-Reserved-Bits: mux-a-million=1;3

The order of the bits within the allocated-bits field is significant
and should be interpreted as appropriate by the extension. The order
of the bit-allocation fields within the Sec-WebSocket-Reserved-Bits is
not significant.

If an extension is negotiated which requires a frame bit, but the
server fails to allocate that frame bit, the client MUST disconnect.

However the allocation works, for the sake of extensibility of the
protocol, I think that we need to get some method of allocating these
bits into the spec before final. Note that I have used the Sec- header
prefix just for consistency with other headers.

Regards,
Brodie

---

From: John Tamplin <[email-masked]>
Date: Wed, 27 Apr 2011 21:16:41 -0400

> prefix just for consistency with other headers.

We had this discussion during the framing discussion, and we couldn't reach
consensus then.  So, instead we simply said that each extension defines how
bits are to be interpreted.   That could mean the bits are statically
allocated, or it could mean some negotiation scheme like what you propose.

I would be opposed to delaying the spec to try and get consensus on
negotiating the usage of reserved bits into the base spec, since it can be
just as easily postponed until the first extension that wants to make use of
some reserved bit.

-- 
John A. Tamplin
Software Engineer (GWT), Google

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 28 Apr 2011 11:38:31 +1000

> just as easily postponed until the first extension that wants to make use of

I also am not keen to see any unreasonable delay.   But I think that
many of the issues surrounding framing and extensions are now better
understood and I think that it is worth while to at least revisit
unresolved issues such as these to see if we can resolve them.

Currently we have the assumption that if we look at a negotiated WS
connection and if we know all the extensions that have been
negotiated, then we will be able to decode the bytes on the wire.
Unfortunately, as Brodie has pointed out, that does not hold if there
is more than one extension that uses reserved bits.     I think this
is an oversight that must be fixed, but I'm not sure that we need
additional headers etc. for it.

I think it would be sufficient to say that reserved bits are allocated
to extensions in the order in which the extensions are negotiated (and
I don't think we need optional bits):

For example: if we have 3 extensions:

   deflate-frame:   uses 1 reserved bit
   sign-frame: uses 0 reserved bits
   mux-o-magic: users 2 reserved bits

the following extension ordering

   mux-o-magic, sign-frame, deflate-frame

then mux-o-magic would get bits RSV1 and RSV2  and defkate-frame would get  RSV3

This is really just a simple convention and requires no extra bytes
sent during handshake.

cheers

---

From: Brodie Thiesfield <[email-masked]>
Date: Thu, 28 Apr 2011 10:43:52 +0900

> unresolved issues such as these to see if we can resolve them.

Agreed.

> I don't think we need optional bits):

This would work. I'd be happy with this too.

Brodie

---

From: John Tamplin <[email-masked]>
Date: Wed, 27 Apr 2011 22:13:09 -0400

> This is really just a simple convention and requires no extra bytes

I disagree that a complicated method of allocating bits is required.  For
example, given the number of likely extensions that would want to use
reserved bits, it seems reasonable to simply define that the Foo extension
allocates RSV2.  If another extension also statically allocates RSV2, then
obviously they couldn't be used together.  Or, the Foo and Bar extensions
could say they use the WS-Reserved-Bit-Spec to allocate the bits, and any
extensions which want to dynamically allocate reserved bits could use that
spec.  That is what I mean by there is no need to define that method now,
and until we actually have a an extension that wants to allocate reserved
bits there is no need.

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 28 Apr 2011 12:29:51 +1000

On 28 April 2011 12:13, John Tamplin <[email-masked]> wrote:
> I disagree that a complicated method of allocating bits is required.

I'm not proposing a complicated method.

I'm proposing a convention to allocate in order of declaration.

> That is what I mean by there is no need to define that method now,

We already have an extension that wants to allocate a reserved bit.
So that time is now.

cheers

---

From: Brodie Thiesfield <[email-masked]>
Date: Thu, 28 Apr 2011 11:57:30 +0900

If we accept Greg's suggestion, then the following text can be a base:

8.2 Allocating Reserved Bits

An extension may require the use of a reserved bit in the framing for
proper operation. Because both the server and client must know all
extension requirements before negotiating their use, requirements for
use of reserved frame bit are known.

The server and client will allocate reserved frame bits in a
predefined order. The order for the reserved bits is defined as the
number of the reserved bit as defined in section 4.2, i.e. RSV1 ->
RSV2 -> RSV3. The order of the extensions is defined by the order of
the extensions in the the Sec-WebSockets-Extensions response header.

Example;

The client requests the following 3 extensions:
Sec-WebSocket-Extensions: deflate-frame, sign-frame, mux-o-magic

The server supports all extensions and sends the response header:
Sec-WebSocket-Extensions: deflate-frame, sign-frame, mux-o-magic

If the deflate-frame extension requires 1 reserved bit and the
mux-o-magic extension requires 2 reserved bits, then the bits are
allocated as:

deflate-frame: RSV1
mux-o-magic: RSV2, RSV3

If the server response used a different ordering of extensions, the
allocated bits will be different according to the response extension
ordering.

For example, given the following server response header:
Sec-WebSocket-Extensions: mux-o-magic, deflate-frame, sign-frame

The reserved bits would be allocated as:
mux-o-magic: RSV1, RSV2
deflate-frame: RSV3

If there are no available reserved bits to be allocated to an
extension the server MUST NOT agree to use the extension.

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 28 Apr 2011 13:04:20 +1000

On 28 April 2011 12:13, John Tamplin <[email-masked]> wrote:
> obviously they couldn't be used together.

It might be reasonable if you are google, as you will have the market
share such that any decision you make to allocated a reserved bit for
your own extensions will effectively allocate that bit to you forever.

Imagine I'm an intermediary vender and I develop a private extension
for my WS aggregator to talk to the servers behind it that uses a
reserve bit.    If google chrome subsequently comes out with a very
popular extension that uses the same reserved bit, then my
intermediary product will have been badly impacted.  I will either
have to redeploy all my intermediaries using another reserved bit or
lose market share because I don't support googles latest extension.

it is not a level playing field.

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 28 Apr 2011 13:11:26 +1000

Brodie,

this is good. But I think we also need to say the same for op-codes.

I think each extension needs to say how many bits, data op-codes and
control op-codes it needs and then these should all be allocated in
order.

This will mean a minor inconvenience to developers of extensions, as
they need to not have constant op-codes, but it is not a difficult
thing we ask and it will give us interoperability of extensions.

cheers

---

From: Andy Green <[email-masked]>
Date: Fri, 29 Apr 2011 01:47:17 +0800

On 04/28/2011 11:04 AM, Somebody in the thread at some point said:
> On 28 April 2011 12:13, John Tamplin<[email-masked]>  wrote:

It makes me squiffy to think how little one can look at this traffic and 
know what it is by eye, but I have to agree your logic for reserved bit 
and reserved opcode allocation for non-control opcodes seems pretty 
sound.  Stuff won't play well together without it if it wants to use 
them, and x-google-mux does want an opcode at least.

You're right John can hope to mandate that and we would be dead in the 
water doing the same with out own extensions, having to come cap in hand 
begging for a bit or opcode that we already is a jealously guarded 
resource.  But if they are dynamically allocated everyone can exploit 
them without central control or politics.

-Andy

---

From: Timothy Meade <[email-masked]>
Date: Thu, 28 Apr 2011 15:31:10 -0400

> this is good. But I think we also need to say the same for op-codes.

It might be instructive to look at X Protocol opcodes for core and
extensions and how that played out over time.
> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi

--
Timothy Meade
Real-time web developer
Founder, Jobitr

---

From: Brodie Thiesfield <[email-masked]>
Date: Fri, 29 Apr 2011 11:16:32 +0900

Hi Timothy,

> extensions and how that played out over time.

I found the following description of the opcodes:
http://www.x.org/wiki/Development/Documentation/Protocol/OpCodes

>From the summary of the scheme above:
* each extension is assigned a single major identifying opcode
* the extension then defines sub-codes for itself if necessary

So this is pretty much the same as we are looking at in websockets but
we have a lot less opcode space to allocate.

Can you supply a pointer to a summary of the problems that occurred
with the X scheme? I'm assuming that it didn't turn out all rosy.

Regards,
Brodie

---

From: Timothy Meade <[email-masked]>
Date: Fri, 29 Apr 2011 00:07:29 -0400

Oh, great apparently Gmail was sending emails without my name for the
last six years, great to have that fixed.

>>> > extension the server MUST NOT agree to use the extension.

Hi Brodie,

I would have included references in the original email, though I'm
sure either of the two experts I cc'd can be much more helpful in that
regard.

Quoting from http://wiki.x.org/wiki/Development/X12#Compositedbydefault:

Extension space is too small

The first 128 requests are core protocol; the remaining 128 are
single-entry multiplex functions for extensions. It's sort of
ridiculous to have XPolyFillArc on the same footing as GLX.

The minor opcode "convention" should be formalized and made part of
the standard. The core protocol should be assigned major number zero
and use minor numbers.

The first 128 requests are core protocol; the remaining 128 are
single-entry multiplex functions for extensions. It's sort of
ridiculous to have XPolyFillArc on the same footing as GLX.

The minor opcode "convention" should be formalized and made part of
the standard. The core protocol should be assigned major number zero
and use minor numbers.

also see, though this is much more general dealing with more than
protocol issues:

Why X is not our Ideal Window System
http://www.std.org/~msm/common/protocol.pdf

--
Timothy Meade
Real-time web developer
Founder, Jobitr

---

From: Brodie Thiesfield <[email-masked]>
Date: Fri, 29 Apr 2011 15:07:52 +0900

On Fri, Apr 29, 2011 at 1:01 PM, Alan Coopersmith
<[email-masked]> wrote:
> On 04/28/11 07:16 PM, Brodie Thiesfield wrote:
>> Hi Timothy,
>>
> I don't know why you'd assume that, since the X extension mechanism is
> the key that's kept the X protocol alive for 25 years as graphics
> technology changed rapidly.

Just the phrasing that Timothy used sounded to me like there had been
problems that would be relevant to websockets.

The problems that X sees with debugging dynamic opcode space is going
to also be a problem that websockets faces, but again that will need
to be solved via debug information dumped by each end.

Referring to Timothy's own reply though, he was pointing out that the
amount of extension opcode space in websockets is probably
insufficient. Given that we only have 4 bits of opcode space to start
with, and only 10 opcodes left available (%3-7 and %xB-F), it is quite
possible that websockets could run into extension space problems.

Unfortunately, the framing argument was a long and arduous journey, so
attempting to change part of the framing (i.e. to introduce more
extension opcode/reserved bits) is a hard sell. Given also that the
protocol is now officially into last call, it would seem impossible.

Unfortunately, I think that the current framing does need some changes
because of the partitioning of the opcode space.

1) opcode partitioning

Partitioning the opcode space is I believe a good decision, however it
has left us with the equivalent of a reserved bit in the middle of
what was supposed to be the opcode growth space. The frame is now
essentially:

Byte 1:
  FIN
  RSV1
  RSV2
  RSV3
  opcode (4) = CTRL BIT (is this a control frame or not) + opcode(3)

One idea for the RSV3 bit was to allow growth of the opcode space, but
that cannot happen sanely with the equivalent of the CTRL bit in the
middle of it. IF we want to keep that ability, then it would make more
sense to move CTRL next to FIN and say that opcodes are unique only
within the namespace created by the CTRL bit. e.g.

Byte 1:
  FIN
  CTRL (is this a control frame or not)
  RSV1
  RSV2
  RSV3
  opcode (3)

Fitting that into the current spec, it would be:
control frames: FIN(1), CTRL(1), opcodes: 0 = reserved, 1 = close, 2 =
ping, 3 = pong
data frames: FIN(0 or 1), CTRL(0), opcodes: 0 = continuation, 1 =
text, 2 = binary

This sort of rearrangement is only required if we want to keep the
ability to expand to RSV3. If we do the following, it isn't
necessary...

2) extra opcode space

Whether we will use more opcode or not, or even require them is still
debatable, but it is better to design for the future at least. Let's
reserve opcode 7 (or opcodes 7 and F in the current opcode method). If
they are reserved, then in a future websockets protocol version, they
can be defined to mean that the frame has an extended opcode space. If
both opcodes 7 and F are reserved, we maintain the semantics of data
versus control being visible via the opcode top bit, and therefore
backward compatibility with intermediaries using this version of the
spec.

3) extensions

One possible problem with Greg's idea of having both server and client
assuming which bit is in use, is that it breaks when a new version of
the protocol actually uses one of the reserved bits. I assume though
that if that happens (i.e. a new version of the protocol which
requires the use of reserved bits), that somehow the client and server
will agree on the protocol version in the handshake.

Regards,
Brodie

> The primary problem I'm aware of is that while each extension got one of
> the 128 available requests, and bundled all it's actions into subcodes of
> that request, they didn't do similar "namespacing" for event & error codes.
>
> We've not yet had a situation where we needed more than 128 extensions
> simulataneously active, but have hit the limits of 64 extension events
> and errors, as some extensions used quite a few.
>
> It does occasionally make user bug reports challenging as the dynamic
> assignment of extension codes based on which ones are enabled during
> the build and runtime of the X server means that getting an error report
> of a failed request 153 doesn't let you know which extension it was.
> (This is why the standard libX11 error handler always prints the extension
> names, but some applications and toolkits use custom error handlers that
> do not.)
>
> --
>        -Alan Coopersmith-        [email-masked]
>         Oracle Solaris Platform Engineering: X Window System
>
>

---

From: Alan Coopersmith <[email-masked]>
Date: Thu, 28 Apr 2011 21:01:13 -0700