Re: [quicwg/base-drafts] Improve ACK_ECN frame encoding (e.g., use bit-vector) (#1439)

Martin Thomson <notifications@github.com> Wed, 01 August 2018 01:50 UTC

Return-Path: <noreply@github.com>
X-Original-To: quic-issues@ietfa.amsl.com
Delivered-To: quic-issues@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id E8C65130F14 for <quic-issues@ietfa.amsl.com>; Tue, 31 Jul 2018 18:50:47 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -6.109
X-Spam-Level:
X-Spam-Status: No, score=-6.109 tagged_above=-999 required=5 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, MAILING_LIST_MULTI=-1, RCVD_IN_DNSWL_HI=-5, SPF_PASS=-0.001, T_DKIMWL_WL_HIGH=-0.01, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=github.com
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 wYXoiL31o55t for <quic-issues@ietfa.amsl.com>; Tue, 31 Jul 2018 18:50:44 -0700 (PDT)
Received: from out-7.smtp.github.com (out-7.smtp.github.com [192.30.252.198]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id E43B7130F0A for <quic-issues@ietf.org>; Tue, 31 Jul 2018 18:50:43 -0700 (PDT)
Date: Tue, 31 Jul 2018 18:50:43 -0700
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=github.com; s=pf2014; t=1533088243; bh=OiqUKj81lAkvgtqVLNIvEbxDtycExK9Bq2vbCvLCdTw=; h=Date:From:Reply-To:To:Cc:In-Reply-To:References:Subject:List-ID: List-Archive:List-Post:List-Unsubscribe:From; b=RNl14uQtGU2S8O+oxlRmzhXaOOFMrBxkOIjx2bo4kaV11dXZUn0ogsANX1BEJWDyx Bd/U/0QLk/dw9jq4COges8xWpFhTscM8BdXutMxwSJEytPVLZ/vcNNiaWGxmILYrFJ +K7T1QDXbauoQ0qexjT5oBYgyVXTImffZAM4zjsc=
From: Martin Thomson <notifications@github.com>
Reply-To: quicwg/base-drafts <reply+0166e4ab58ec8562b6d35ec1685eff97dd1bc81a0aa3066092cf000000011778d3f392a169ce13c0caa7@reply.github.com>
To: quicwg/base-drafts <base-drafts@noreply.github.com>
Cc: Subscribed <subscribed@noreply.github.com>
Message-ID: <quicwg/base-drafts/issues/1439/409422427@github.com>
In-Reply-To: <quicwg/base-drafts/issues/1439@github.com>
References: <quicwg/base-drafts/issues/1439@github.com>
Subject: Re: [quicwg/base-drafts] Improve ACK_ECN frame encoding (e.g., use bit-vector) (#1439)
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="--==_mimepart_5b6111f31085c_73773fde5a0d45bc969ee"; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Precedence: list
X-GitHub-Sender: martinthomson
X-GitHub-Recipient: quic-issues
X-GitHub-Reason: subscribed
X-Auto-Response-Suppress: All
X-GitHub-Recipient-Address: quic-issues@ietf.org
Archived-At: <https://mailarchive.ietf.org/arch/msg/quic-issues/lryW8AEXXOqwbPZ8ziI3_ONxm8k>
X-BeenThere: quic-issues@ietf.org
X-Mailman-Version: 2.1.27
List-Id: Notification list for GitHub issues related to the QUIC WG <quic-issues.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/quic-issues>, <mailto:quic-issues-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/quic-issues/>
List-Post: <mailto:quic-issues@ietf.org>
List-Help: <mailto:quic-issues-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/quic-issues>, <mailto:quic-issues-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 01 Aug 2018 01:50:48 -0000

Coming back to this (because I want this closed, and the current situation is annoying me a little).

In general, there are three common things that we might want to signal:

1. a packet was received and it had the default marking (whatever the expectations are regarding that)
2. a packet was not received (a gap)
3. a packet was received with an ECN-CE marking

Receiving a packet with a non-default marking (either no marking at all, or ECT(1) if ECT(0) is expected) is an error condition and one that we don't necessarily want to optimize for.

So here is my suggestion, stealing the design @kazuho proposed, which includes bit-packing varints (something I'm not super-happy about, but the alternatives all seem to be worse, so I'm holding my nose a little).

```
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Largest Acknowledged (i)                ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          ACK Delay (i)                      ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Marking(8)  |        ACK Block Count (i)                  ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           ACK (i)                          ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          [ACK (i) ...]                     ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```

Largest Acknowledged and ACK Delay are the same as always.

The Marking field takes three values that describes what the "default marking" is for packets that are acknowledged in this frame.  It takes three values: 0 means that it's ECT(0), 1 means ECT(1), and 2 means that there is no marking.  This means that if you get non-default markings, or you lose markings, then you might need to send multiple ACK frames.  (This is just for the sake of an example; I imagine that it would be better to define three types of ACK frame here to save the octet.)

The ACK Block Count indicates how many additional ACK blocks are signaled past the first.

Each ACK is a single varint.  A type is encoded into the lowest bit of the integer value.  Recovering type is stateful.  The observation is that though there are three types, the same type can't be repeated.  So, starting with the assumption that things start with a type of "gap", you can cover all possible angles.

Thus, a frame can be decoded using the following pseudocode:

```python
largest_acknowledged = read_varint()
ack_delay = read_varint()
default_marking = read_octet()
ack_count = read_varint()

ack_type = 0
default_types = [ 'ECT(0)', 'ECT(1)', 'unmarked' ]
ack_types  = ['gap', default_types[default_marking], 'marked']
start = largest_acknowledged
for i in range(0, ack_count+1):
   ack = read_varint()
   ack_type =  (ack_type + 1 + (ack&1)) % 3
   end = start + 1 + (ack>>1)
   print(f'{ack_types[ack_type]} from {start} to {end}\n')
   start = end + 1
```

The consequences of a change like this that I can see:

* It is much less efficient to signal changes in default marking (a design goal, see above)
* Markings are expressed perfectly (no counts and the associated problems with overcounting we have today)
* A gap can be signaled at the end of a block (we might want to forbid this explicitly: I can't see any point in allowing it)
* There is just one ACK frame format, even if it takes three frame type codepoints to express

Yes, the processing is a tiny bit more complicated, but I think that these changes represent a net win.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1439#issuecomment-409422427