Re: [hybi] Framing take IV

"Thomson, Martin" <Martin.Thomson@andrew.com> Fri, 06 August 2010 04:20 UTC

Return-Path: <Martin.Thomson@andrew.com>
X-Original-To: hybi@core3.amsl.com
Delivered-To: hybi@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 79CDF3A6888 for <hybi@core3.amsl.com>; Thu, 5 Aug 2010 21:20:29 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.968
X-Spam-Level:
X-Spam-Status: No, score=-2.968 tagged_above=-999 required=5 tests=[AWL=-0.369, BAYES_00=-2.599]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id l5GQwIWRCCqM for <hybi@core3.amsl.com>; Thu, 5 Aug 2010 21:20:26 -0700 (PDT)
Received: from csmailgw1.commscope.com (csmailgw1.commscope.com [198.135.207.244]) by core3.amsl.com (Postfix) with ESMTP id 3C4F63A6358 for <hybi@ietf.org>; Thu, 5 Aug 2010 21:20:26 -0700 (PDT)
Received: from [10.86.20.103] ([10.86.20.103]:62329 "EHLO ACDCE7HC2.commscope.com") by csmailgw1.commscope.com with ESMTP id S29545126Ab0HFEU4 (ORCPT <rfc822; hybi@ietf.org>); Thu, 5 Aug 2010 23:20:56 -0500
Received: from SISPE7HC2.commscope.com (10.97.4.13) by ACDCE7HC2.commscope.com (10.86.20.103) with Microsoft SMTP Server (TLS) id 8.1.436.0; Thu, 5 Aug 2010 23:20:56 -0500
Received: from SISPE7MB1.commscope.com ([fe80::9d82:a492:85e3:a293]) by SISPE7HC2.commscope.com ([fe80::58c3:2447:f977:57c3%10]) with mapi; Fri, 6 Aug 2010 12:20:53 +0800
From: "Thomson, Martin" <Martin.Thomson@andrew.com>
To: Jamie Lokier <jamie@shareable.org>, Greg Wilkins <gregw@webtide.com>
Date: Fri, 06 Aug 2010 12:23:06 +0800
Thread-Topic: [hybi] Framing take IV
Thread-Index: Acs1HY7RWxtApWiJTD2C8PTonIVfwAAAN83w
Message-ID: <8B0A9FCBB9832F43971E38010638454F03EB8B0470@SISPE7MB1.commscope.com>
References: <AANLkTinyrDoG5d_Ur6HVRy=SgMPjLzJtpJ++Ye=1DQdj@mail.gmail.com> <20100804022719.GT27827@shareable.org> <AANLkTi=MENta8H4A_ota=R==EJ3j0zAkPc7ai2qmsZiT@mail.gmail.com> <AANLkTinZE8-HSi-BJD8Oq3z3+9BXY8eMnZ4DAnOaiuT=@mail.gmail.com> <20100804031917.GV27827@shareable.org> <AANLkTikMuVDwUyKYetCvj2GWv8dW+sWa5RLOVVOVPcBF@mail.gmail.com> <20100805020304.GY27827@shareable.org> <AANLkTi=HHNhWsg8by3p-F_V-dctH+hv=c44qUGRiWF7P@mail.gmail.com> <20100806041204.GM27827@shareable.org>
In-Reply-To: <20100806041204.GM27827@shareable.org>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
acceptlanguage: en-US
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
MIME-Version: 1.0
X-BCN: Meridius 1000 Version 3.4 on csmailgw1.commscope.com
X-BCN-Sender: Martin.Thomson@andrew.com
Cc: "hybi@ietf.org" <hybi@ietf.org>
Subject: Re: [hybi] Framing take IV
X-BeenThere: hybi@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: Server-Initiated HTTP <hybi.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/hybi>
List-Post: <mailto:hybi@ietf.org>
List-Help: <mailto:hybi-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 06 Aug 2010 04:20:29 -0000

Hi Jamie,

This sounds great to me!

There are a few interactions between the different concepts (the order that you apply multiplexing + chunking for example), but I think that you have described a perfectly workable protocol.

The best part is that it scales in complexity.

--Martin

...

> The client doesn't know, and it doesn't need to know.
> 
> The client is defining which opcodes it will use, so that it can use
> them before the server has responded in negotiation.
> 
> The server ignores frames whose opcode it doesn't recognise.
> 
> The client does not know which messages the server will act on, and
> which it will ignore, until the server has responded.  That's ok, it
> just means only fancy clients would use this feature; simple ones
> would wait for the server.
> 
> The details of handshake etc. aren't that important: This mechanism
> applies whether it's a embedded in the TLS phase, in the HTTP-like
> handshake, after handshake prior to server response, or even later.
> 
> The point is, if it's done this way, there's a basis whereby
> latency-avoiding setup costs can be avoided, even if actually doing so
> is reserved for the future and an extension.
> 
> If it's the server which decides the opcodes from the start, then even
> future extensions won't have any way to encode latency-avoiding
> initial messages from the client.
> 
> Note that if any feature is proposed by the server and needs to wait
> for the client to confirm, the server should define the opcode in that
> case.  Rule: "Proposer defines opcode(s)".
> 
> > Surely it is best for the client to simply list the extensions it may
> > support and then the server picks the final list and allocates
> opcodes
> > (and/or bits)?
> 
> No, because that prevents sending any message until the server has
> responded.  It adds an unnecessary round trip delay.  There is no cost
> to the client choosing the values instead of the server, and it is
> more versatile regarding latency avoidance in future.
> 
> This is a general principle of dynamic protocol design to avoid round
> trips.  When defining something to use, the first sender/proposer
> should do the defining, and just use it, not wait for agreement.
> Multiplexing should do similar: Allow the first sender to create a
> stream and use it immediately.  If creation fails, it will find out,
> and the messages sent will just be ignored.  (The designer of the X
> windowing protocol noted this as a design mistake in that one... it
> makes X applications start slower)
> 
> > Could you possible do some more worked examples of how you see this
> > working - eg if I wanted to negotiate fragments, mime messages and
> > compressed frames.
> 
> I think you're already got the basic idea.  Client sends negotiation
> text which defines opcodes, and uses them after negotiation.
> 
> Note that length in all cases includes the frame's opcodes, parameters
> etc. so that whole frames are skippable, as well as easily forwarded.
> 
> Negotiated fragments are simple enough: Client doesn't send fragment
> opcodes until it's negotiated with the server.  It can only send whole
> messages.  (Or client may send them prior to that, but on learning
> that the server doesn't support them, it'll have to resend the
> pre-sent content in whole messages only.  How much to pre-send is an
> implementation detail, and would tend to vary over the years according
> to typical server features.)  Fragments/chunks:
> 
>     length1 chunk-opcode final=0 message-opcode data1
>     length2 chunk-opcode final=0 data2
>     length3 chunk-opcode final=1 data3
> 
> Being equivalent to:
> 
>     (length1+length2+length3-adjustment) message-opcode
> data1+data2+data3
> 
> (The message-opcode is actually just part of the data, as far as the
> chunks are concerned.  When concatenated together, it is interpreted
> as a message).
> 
> Maybe final could always have no data; it's a stylistic detail.
> 
> Mime messages:
> 
>     length mime-opcode mime-headers data
> 
> But I see you're going to want split MIME frames, so like this:
> 
>     length1 chunk-opcode final=0 mime-opcode mime-headers data1
>     length2 chunk-opcode final=0 data2
>     length3 chunk-opcode final=1 data3
> 
> A split could occur inside the mime-headers, naturally.  Or even after
> the opcode; as far as chunks are concerned, the whole body is an
> opaque blob to reassamble and then interpret.
> 
> Compressed frames:
> 
>     length lzo-opcode lzo(data)
> 
> If you wanted a CRC and incremental LZO compression together, where
> the CRC is of the compressed data:
> 
>     length crc32-opcode lzo-opcode lzo(data) crc32(lzo(data))
> 
> This begs a question: CRC and compress the message before splitting,
> or each chunk?  Either way around is permissible in general, but
> specific opcode definitions may mandate only one order is acceptable
> use of them, and multiplexing and chunking specifically do that.
> 
> Compressed chunks looks a bit complicated.  At risk of putting people
> off, this is a whole message compressed, and then the compressed
> version is split:
> 
>     length1 chunk-opcode final=0 lzo-opcode lzo(data)1
>     length2 chunk-opcode final=0 lzo(data)2
>     length3 chunk-opcode final=1 lzo(data)3
> 
> This is a message split first, and then each chunk compressed:
> 
>     length1 lzo-opcode chunk-opcode final=0 lzo(data1)
>     length2 lzo-opcode chunk-opcode final=0 lzo(data2)
>     length3 lzo-opcode chunk-opcode final=1 lzo(data3)
> 
> CRCs could be combined with compression, and various flavours of
> compression work.  Both incremental compression (of the whole stream)
> and individual message or chunk compression, and switching off
> compression for specific chunks.
> 
> It should be clear that this scheme accomodates both "chunk" opcodes
> and "message" opcodes without having to define the difference.
> 
> Now multiplexing:
> 
> Multiplex encoding must be fast at identifying the stream id and
> length for fast forwarding.  So the definition of multiplex-opcode
> will say that it can only be used as an "outer" opcode (we might
> permit it inside compression and/or checksums, maybe).
> 
> Multiplexing is extremely simple:
> 
>     length multiplex-opcode stream-id ....
> 
> Where .... is any other message- or chunk-opcode and its
> parameters/data.  It really can't get much simpler.  That doesn't
> cover any per-stream setup negotiation or flow control.  I'm sure this
> works:
> 
>     length multiplex-setup-opcode new-stream-id parameters....
>     length multiplex-setup-response-opcode new-stream-id response...
>     length multiplex-flow-opcode stream-id amount
> 
> With a good extension mechanism, an interesting question is what's the
> _simplest_ base protocol that can be implemented and will still be
> fully compatible with the most featureful future implementations.
> 
> Probably that is just this, and nothing more, in a simplest
> implementation:
> 
>     length text-utf8-opcode data
> 
> Or this:
> 
>     length basic-data-opcode data
> 
> Thus fragmentation, multiplexing, compression and MIME would all be
> optional extensions, and all implementations of them would be expected
> to work with any implementation including the most basic, if it's
> meaningfully possible.
> 
> That way, we cover a wide spectrum of implementations from "amateur
> programmer", to "person who can program but right now wants to write a
> short Perl script", to "lead programmer at Google Wave".  We get good
> scalability, it's future-extensible, and everything across the
> spectrum will interoperate beautifully.  Like HTTP but better.(*)
> 
> (*) Free software comes without warranty etc.
> 
> > Eitherway, if opcodes were able to be negotiated, then would you
> agree
> > that this would work with the binary framing more or less how it is
> > currently
> > specified;
> >
> >     op-code(8) + BER length + data
> 
> Yes.
> 
> > I ask this because the current framing is our starting point.  I know
> > there are arguments for
> >     opcode + fixed length
> >     opcode + BER length
> >     BER opcode + BER length
> >     fix length + opcode
> >     BER length + opcode
> >     BER length + BER opcode
> >
> > but I think they are secondary to the basic extension mechanism and
> > I'd really like to separate out discussion of what is the best length
> > encoding from what is a sufficient extension mechanism.
> 
> I agree, separating detailed style/range from the fields is sensible.
> 
> The order of fields just isn't very important, although I could make a
> case for "fixed fields", "length", "variable fields including
> opcode(s)", and Dave Cridland makes a good case for stream id being in
> an easily found place, for fast forwarding.
> 
> The range arguments affect things like: Whether parsing split messages
> needs to be mandatory in the most basic protocol (for simple
> implementations).
> 
> For opcodes, we could, maybe, reserve opcode bytes >= 0x80, and put
> off deciding if that starts a BER or not ;-) as long as the length
> comes before it.  It'll just be an ignored frame either way.
> 
> -- Jamie
> _______________________________________________
> hybi mailing list
> hybi@ietf.org
> https://www.ietf.org/mailman/listinfo/hybi