Re: Unified ACK frame encoding

"Brian Trammell (IETF)" <ietf@trammell.ch> Thu, 09 August 2018 07:52 UTC

Return-Path: <ietf@trammell.ch>
X-Original-To: quic@ietfa.amsl.com
Delivered-To: quic@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 3DDA8124C04 for <quic@ietfa.amsl.com>; Thu, 9 Aug 2018 00:52:16 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.599
X-Spam-Level:
X-Spam-Status: No, score=-2.599 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id U9cJGu8I0um8 for <quic@ietfa.amsl.com>; Thu, 9 Aug 2018 00:52:13 -0700 (PDT)
Received: from gozo.iway.ch (gozo.iway.ch [IPv6:2001:8e0:40:325::36]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 0CF3D130DFA for <quic@ietf.org>; Thu, 9 Aug 2018 00:52:11 -0700 (PDT)
Received: from gozo.iway.ch (localhost [127.0.0.1]) by localhost (Postfix) with ESMTP id 9220B340D9C; Thu, 9 Aug 2018 09:52:09 +0200 (CEST)
Received: from localhost (localhost [127.0.0.1]) by localhost (ACF/6030.23181); Thu, 9 Aug 2018 09:52:09 +0200 (CEST)
Received: from switchplus-mail.ch (switchplus-mail.ch [212.25.8.236]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by gozo.iway.ch (Postfix) with ESMTPS; Thu, 9 Aug 2018 09:52:09 +0200 (CEST)
Received: from nb-10604.ethz.ch (account ietf@trammell.ch [82.130.102.91] verified) by switchplus-mail.ch (CommuniGate Pro SMTP 6.1.18) with ESMTPSA id 63658247; Thu, 09 Aug 2018 09:52:09 +0200
From: "Brian Trammell (IETF)" <ietf@trammell.ch>
Message-Id: <116ABD4F-4707-4F15-B7D1-C4B4727534C6@trammell.ch>
Content-Type: multipart/signed; boundary="Apple-Mail=_6C2F056F-0D9C-40CA-A3CB-C9D0D4CF6923"; protocol="application/pgp-signature"; micalg="pgp-sha512"
Mime-Version: 1.0 (Mac OS X Mail 11.5 \(3445.9.1\))
Subject: Re: Unified ACK frame encoding
Date: Thu, 09 Aug 2018 09:52:08 +0200
In-Reply-To: <CACpbDcda5zh0SAVRWBGkvoZs-MTetg0sz6JYOmnMrdMNhGd2iQ@mail.gmail.com>
Cc: Martin Thomson <martin.thomson@gmail.com>, Magnus Westerlund <magnus.westerlund@ericsson.com>, QUIC WG <quic@ietf.org>
To: Jana Iyengar <jri.ietf@gmail.com>
References: <CABkgnnX6T9nZWVZH5_PTjrKt+VBpaoAC+eCFTZ_ZLRD4kjnW3Q@mail.gmail.com> <CACpbDcda5zh0SAVRWBGkvoZs-MTetg0sz6JYOmnMrdMNhGd2iQ@mail.gmail.com>
X-Mailer: Apple Mail (2.3445.9.1)
Archived-At: <https://mailarchive.ietf.org/arch/msg/quic/q8Icg8xRVOD5c8IylH7Wn9EoiWo>
X-BeenThere: quic@ietf.org
X-Mailman-Version: 2.1.27
Precedence: list
List-Id: Main mailing list of the IETF QUIC working group <quic.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/quic>, <mailto:quic-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/quic/>
List-Post: <mailto:quic@ietf.org>
List-Help: <mailto:quic-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/quic>, <mailto:quic-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 09 Aug 2018 07:52:16 -0000

hi Jana, all,

Also fried, but I've had a quick look at this...

> On 9 Aug 2018, at 08:36, Jana Iyengar <jri.ietf@gmail.com> wrote:
> 
> Thanks for picking this one up, Martin. As I've said to you and to Kazuho, I think if we can unify ACK and ACK_ECN frames "reasonably", I think there's a lot of value in having a single frame format. The question of course is if we can make this reasonable, so thanks for trying.
> 
> I need to think some more when I'm not as fried as I am right now, but I'm not convinced about the encoding yet.

+1 to this -- if we find not-quite-varints in packet numbers uncomfortable, I can't see us finding rolling five-in-four encoding in the low bits of a different not-quite-varint less so.

> A couple of more simplifying assumptions might help:
> 1. A receiver receives 3 types of packets: Non-ECT, ECT, CE. It only reports packets it has received.
> 2. We can assume that a sender uses ECT(0) or ECT(1), not both. Let's call this default-ECT. If a future mechanism wants to use both, they can define a new ACK frame. (Magnus and I checked on this with David Black, and he agrees on the use of a single default ECT value..)

This also seems reasonable to me, and AFAICT lines up with all the current proposals for using ECT0/1 signaling.

> This means that you only need to report 3 types of ranges.
> 
> Further, if you have a separate bit to communicate ECN/non-ECN, meaning that the receiver has seen ECT/CE bits and will echo them back, or the receiver has not seen ECT/CE bits and won't echo them back, then you have 1 or 2 types of ranges.
> ECN bit = 0: every range is of packets received, there's no ECN echo. This is exactly the same ACK format as what we have now.
> ECN bit = 1: ranges are of 2 types, default-ECT or CE. We need exactly 1 bit here to distinguish between these two ranges.
> 
> I'm aware that if we move this ECN bit to the frame type, then we end up with two ACK frames again, but this is still far more unified than what we have now.

+1. I'm really not bothered by pushing some of the ACK signaling bits into the frame type (especially if we describe these frames in a unified way, as we do with STREAM frames), as long as the structure of the frames is identical.

Cheers,

Brian

> I'm also aware that we need a way for a receiver to say that it received non-default ECT, but that can be separate, or an error even, and a receiver could stop reporting ECN assuming that a network box is messing with the bits.
> 
> On Wed, Aug 8, 2018 at 8:54 PM Martin Thomson <martin.thomson@gmail.com> wrote:
> (More long emails. Sorry, I'm trying to either close these issues or
> prepare us for the interim.)
> 
> We decided to take ACK_ECN to address an immediate need, but
> recognized that the encoding was suboptimal.  In the issue (see
> https://github.com/quicwg/base-drafts/issues/1439) we've
> beendiscussing an option for frame encoding that fixes a bunch of
> issues. That discussion covered a lot of ground, but here is my
> summary.
> 
> This is what we have currently (using C/TLS style notation because I
> don't think ASCII art works in email):
> 
>    struct ACK {
>       varint largest_acknowledged;
>       varint delay;
>       varint additional_block_count;
>       varint first_block;
>       struct {
>          varint gap;
>          varint block;
>       } blocks[additional_block_count];
>    };
> 
>    struct ACK_ECN {
>       ACK ack;
>       varint ect0_count;
>       varint ect1_count;
>       varint ecnce_count;
>    };
> 
> The most obvious issues are:
> 
> A. There are two inconsistent encodings for acknowledgments depending
> on whether ECN is enabled.
> B. ACK_ECN has more overhead than ACK.  Ideally there are fewer
> disincentives to use ACK_ECN.
> C. The counting scheme is imprecise (you don't always know which
> packet was CE marked, and that could matter), which makes counting of
> ECN markings fragile in the presence of ACK loss.  This can lead to
> ECN being disabled despite it being fully functional.
> D. ECN counters always increase, and so they take more space to encode
> over time.
> 
> Kazuho suggested a scheme that adds some modest complexity, but I
> think that it works and reduces other complexities such that it's
> probably a net win on the complexity front.  It also fixes these
> issues at the same time.
> 
> The observation is that there are 5 things that you might want to say
> about any given packet number:
> 
> 0. say nothing (i.e., I'm not acknowledging this packet; this is a gap)
> 1. packet received, no marking
> 2. packet received with an ECT(0) marking
> 3. packet received with an ECT(1) marking
> 4. packet received with an ECN-CE marking
> 
> Now, the current system of describing ranges of packets is still
> pretty good.  An expression of the form "the next N packets are of
> type X" gets us an encoding that is small and fits traffic patterns
> well.  No point changing what is a fundamentally good encoding.
> 
> So, we retain the maximum packet number and the idea of expressing
> ranges of packets. But each range is a tuple that expresses both the
> type of acknowledgement (or lack thereof) for that range and how many
> packets are in the range.
> 
> That would produce an ACK frame in the following basic shape:
> 
>    struct ACK {
>       varint largest_acknowledged;
>       varint delay;
>       varint range_count;
>       struct {
>          enum {gap,unmarked,ect0,ect1,ecnce} type;
>          varint count;
>       } ranges[range_count];
>    };
> 
> The problem now is that we lost efficiency in a big way because the
> enum takes up a ton of space, for just 5 values.
> 
> If we observe that there are 5 types, but you don't need to repeat the
> same type, then we can express the type in two bits.  That is, the
> type is interpreted as:
> 
>    type = last_type + 1 + encoded_type (mod 5)
> 
> Kazuho suggested that we pack these bits into the low two bits of a
> varint.  It's a little ugly, but I can't see a better option.  For
> instance, defining a new varint type would be considerably worse.  In
> addition to not being able to reuse varint code, my testing on
> encodings showed that a defining a new type with flags before the
> 2-bit length is surprisingly expensive.
> 
> This produces a format like this:
> 
>    struct ACK {
>       varint largest_acknowledged;
>       varint delay;
>       varint range_count;
>       varint ranges[range_count];
>    };
> 
> As you can see, this is a considerable simplification.  The only trick
> is that more data is packed into each range value.  These values are
> encoded using something like:
> 
>    encoded_type = (type + 4 - last_type) % 5
>        // encoded_type = type - last_type - 1 (mod 5)
>    range = encoded_type | (count << 2)
> 
> The cost is that ranges take one more byte once they get above 16
> packets rather than at 64 packets as before.  It's also possible with
> this to encode a non-acknowledgment at the end of an ACK frame, which
> I think we can either prohibit or ignore.  But it fixes all the above
> problems.
> 
> Is this a change worth making?
> 
> Cheers,
> Martin
> 
> 
> A side note: This works whether we encode a count (as here) or a total
> number of octets (as has been proposed).  Similarly, we could count
> from the bottom rather than the top if we wanted to.  Those decisions
> are orthogonal to this; I'm trying as much as possible to retain the
> current design.
> 
> Another note: We already have an issue on file for an ACK frame
> example.  That is still planned and that should help with interpreting
> the text.
>