Subject: [TLS] Efficiency of ACKing scheme

From: Hanno Becker <[email-masked]>
Date: Fri, 3 Apr 2020 16:35:23 +0000

Hi again,

The DTLS 1.3 ACKing scheme seems to be quite inefficient as it is written,
and I wonder if the current spec matches the authors' intentions.

Example:

Consider a flight broken down as sequence of records 1, 2, .., N.
Assume record 2 gets dropped, while all other records go through
without reordering, corruption or loss; hence, the record sequence
observed on the receiver is 1, 3, 4, ..., N.

Then, according to the spec, the following SHOULD happen:

On the receiver-side, we have the following from Section 7.1:

```
   When an implementation receives a partial flight, it SHOULD generate
   an ACK that covers the messages from that flight which it has
   received so far.  Implementations have some discretion about when to
   generate ACKs, but it is RECOMMENDED that they do so under two
   circumstances:
   *  When they receive a message or fragment which is out of order,
      either because it is not the next expected message or because it
      is not the next piece of the current message.
```

So, when the receiver receives records 1 and 3, it notices that 2 is missing
and immediately sends an ACK for { 1, 3 }.

On the sender-side, we have the following from Section 7.2:

```
7.2.  Receiving ACKs
   When an implementation receives an ACK, it SHOULD record that the
   messages or message fragments sent in the records being ACKed were
   received and omit them from any future retransmissions.  Upon receipt
   of an ACK for only some messages from a flight, an implementation
   SHOULD retransmit the remaining messages or fragments.
```

So, when the receiver receives the ACK for { 1, 3 }, it resends records
2, 4, 5, .., N.

That's obviously not optimal, and probably not what was intended, but what
unambiguously appears to be the recommended behavior according to the spec.

How should this be resolved?

I see two similar and comparably unintrusive options:

1) Send ACKs only after period of inactivity

   Instead of sending ACKs straight away when something hints at
   something going wrong (such as an out-of-order receipt), as
   currently stated in Section 7.1, only send ACKs after a period
   of time where no further messages has been received.

   That is, replace the current version

```
   When an implementation receives a partial flight, it SHOULD generate
   an ACK that covers the messages from that flight which it has
   received so far.  Implementations have some discretion about when to
   generate ACKs, but it is RECOMMENDED that they do so under two
   circumstances:
   *  When they receive a message or fragment which is out of order,
      either because it is not the next expected message or because it
      is not the next piece of the current message.  Implementations
      MUST NOT send ACKs for handshake messages which they discard as
      out-of-order, because otherwise those messages will not be
      retransmitted.
   *  When they have received part of a flight and do not immediately
      receive the rest of the flight (which may be in the same UDP
      datagram).  A reasonable approach here is to set a timer for 1/4
      the current retransmit timer value when the first record in the
      flight is received and then send an ACK when that timer expires.
   In addition, implementations MUST send ACKs upon receiving all of any
   flight which they do not respond to with their own messages.
```

   by something along the following lines:

```
   As long as implementation has received some but not all of the next incoming
   flight, it SHOULD send an ACK message after an implementation-defined period
   a time during which no further messages are received. A reasonable approach
   here is to reset a timer to 1/4 the current retransmission timer with every
   record received in the current flight, and send an ACK when that timer expires.
```

   In the above example, this would mean that as long as records 3,4,..,N arrive
   in close succession, it will only once send an ACK for {1,3,4,...,N} in the end,
   triggering retransmission of record 2 only, which is optimal.

   The drawback of this is that the receiver of a flight does not inform a peer
   about a gap in a flight as soon as it notices it. For this to work, the content
   of an ACK would need to be what's missing instead of what's present, which
   appears to be a too intrusive change to be considered at this stage. The
   benefit of this approach is that it leads to very good retransmission bandwidth.

2. Essentially same as option 1., but 'mirrored': Allow the receiver of a flight
   to send ACKs recurringly (though preferably still bunched, i.e. using some timer
   for the bunching), and replace the part of Section 7.2:

```
7.2.  Receiving ACKs
   When an implementation receives an ACK, it SHOULD record that the
   messages or message fragments sent in the records being ACKed were
   received and omit them from any future retransmissions.  Upon receipt
   of an ACK for only some messages from a flight, an implementation
   SHOULD retransmit the remaining messages or fragments.
```

   by something along the lines of

```
7.2.  Receiving ACKs
   If an implementation receives an ACK for parts of a flight, but doesn't
   immediately receive ACKs for the rest of the flight, it SHOULD retransmit
   the messages that have not been ACKed. A reasonable approach here is to
   reset a timer to 1/4 the current retransmission timer with every ACK record
   received, and retransmit the last outgoing flight when that timer expires.
```

Let me know what you think and which option (if not a completely different one)
you'd prefer.

Cheers,
Hanno
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

---

From: Hanno Becker <[email-masked]>
Date: Fri, 3 Apr 2020 17:00:00 +0000

An additional note: All solutions which retain the paragraph

   Upon receipt

and hence trigger retransmission immediately upon receiving a partial ACK,
suffer from the following problem:

On Low-MTU networks, and looking ahead at the use of Post-Quantum Cryptography,
it might happen that a single ACK is too small to hold the entire list of record
sequence numbers of the flight being ACKed.

Doing the math in an example: If the maximum plaintext size is, say, 512 Bytes,
then a single ACK can not ACK more than 64 Records, each of which contains at
most 512 Bytes of handshake data. Hence, we've got a theoretical max of ~32Kb
flight length we can ACK in a single ACK message.

While this seems a lot, some PQC schemes go beyond that. For example, the SPHINCS
signature scheme has 41Kb signature size.

To avoid this problem, it appears beneficial to go for option 2., that is, don't
retransmit immediately upon receiving an ACK, but accumulate some ACKs first. This
allows to split ACKing a very large flight into multiple ACKs.
________________________________
From: TLS <[email-masked]> on behalf of Hanno Becker <[email-masked]>
Sent: Friday, April 3, 2020 5:35 PM
To: [email-masked] <[email-masked]>
Subject: [TLS] Efficiency of ACKing scheme

Hi again,

Example:

```

```
7.2.  Receiving ACKs

```

```

   In the above example, this would mean that as long as records 3,4,...,N arrive
   in close succession, it will only once send an ACK for {1,3,4,...,N} in the end,
   triggering retransmission of record 2 only, which is optimal.

   appears to be a too intrusive change to be considered at this stage.. The

```
7.2.  Receiving ACKs

```
7.2.  Receiving ACKs

Cheers,
Hanno

---

From: "Martin Thomson" <[email-masked]>
Date: Mon, 06 Apr 2020 11:49:03 +1000

Hi Hanno,

I think that you are assuming a lot about how the loss recovery part of the sender is operating here.

If you receive ACK { 1, 3 }, then it might be reasonable to assume that 2 got lost, but it seems to me that assuming anything about 4 is premature.

As you say, delaying ACKs is a good way to ensure that you capture all incoming data, but it also affects overall latency.  The trade-offs are complex.  The sender can also make some adjustments, without necessarily adhering to a strict interpretation of the recommendations in the spec.

The draft is imprecise about this logic intentionally.  It recommends that the sender send missing data, which will likely work, and be fast.  For large flights, yes, this will be suboptimal, but we are also assuming that this data is not subject to congestion control limits.  If we go to PQ schemes with large amounts of data, then that requires a different set of assumptions.  It might also require that implementations take extra steps to avoid the resulting inefficiencies.

On Sat, Apr 4, 2020, at 04:00, Hanno Becker wrote:
> *From:* TLS <[email-masked]> on behalf of Hanno Becker 
> <[email-masked]>
> *Sent:* Friday, April 3, 2020 5:35 PM
> *To:* [email-masked] <[email-masked]>
> *Subject:* [TLS] Efficiency of ACKing scheme 
> Hi again,
> 
>  IMPORTANT NOTICE: The contents of this email and any attachments are 
> confidential and may also be privileged. If you are not the intended 
> recipient, please notify the sender immediately and do not disclose the 
> contents to any other person, use it for any purpose, or store or copy 
> the information in any medium. Thank you. 
>  IMPORTANT NOTICE: The contents of this email and any attachments are 
> confidential and may also be privileged. If you are not the intended 
> recipient, please notify the sender immediately and do not disclose the 
> contents to any other person, use it for any purpose, or store or copy 
> the information in any medium. Thank you. 
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: Thomas Fossati <[email-masked]>
Date: Mon, 6 Apr 2020 11:01:38 +0000

On 06/04/2020, 02:49, Martin Thomson <[email-masked]> wrote:
> If you receive ACK { 1, 3 }, then it might be reasonable to assume
> that 2 got lost, but it seems to me that assuming anything about 4 is
> premature.

The spec as currently written says that the signal "ACK {1, 3}" means
"retransmit {2, (3, end]}":

   Upon receipt of an ACK for only some messages from a flight, an
   implementation SHOULD retransmit the remaining messages or
   fragments.

This works as expected only if the sender can assume that the receiver
has let enough time pass before generating ACK {1, 3}, but this is not
strongly stated in the description of receiver behaviour.

We should keep in mind that DTLS implementers are not necessarily
transport experts, and that warrants a bit more care in what we say as
well as what we don't say.  In particular, we should try hard to avoid
expert bias.

One example where we can improve: we have a nice sentence about bunching
ACKs at 25% of current RTO halfway through bullet 2 of Section 7.1.  In
fact, avoiding knee-jerk ACKing is one of the basic things to understand
here.  Incidentally, this is how one's solves Hanno's conundrum above
(at least in non-pathological cases) because "retransmit {2, (3, end]}"
would be generated when the receiver has got some confidence about 4 &
co. being actually lost.  Unfortunately, the sentence is oddly placed
and one tends to overlook it and not giving it the high and general
relevance it actually has.

> The sender can also make some adjustments, without necessarily
> adhering to a strict interpretation of the recommendations in the
> spec.

Agree again, but deciding to violate a SHOULD should be an exception,
not the rule.  If I have to implement this, especially on very
low-bandwidth paths that fragment a lot, I probably would never follow
the recommendation: I'd first re-send 3 and sit back for a while waiting
for further ACKs before resending (3, end].

> The draft is imprecise about this logic intentionally.  It recommends
> that the sender send missing data, which will likely work, and be
> fast.  For large flights, yes, this will be suboptimal, but we are
> also assuming that this data is not subject to congestion control
> limits.

Just a note: "large flights" is relative to the available bandwidth so
(very) low-bandwidth would always have suboptimal recovery even if HS
data is not congestion controlled.  And that's the environment where you
absolutely want to have a reliability scheme that is bandwidth
efficient.

> If we go to PQ schemes with large amounts of data, then that requires
> a different set of assumptions.  It might also require that
> implementations take extra steps to avoid the resulting
> inefficiencies.

True that.

Cheers!

---

From: Rob Sayre <[email-masked]>
Date: Mon, 6 Apr 2020 04:17:28 -0700

On Mon, Apr 6, 2020 at 4:02 AM Thomas Fossati <[email-masked]>
wrote:

> transport experts,

Well, so-called "transport experts" have made many mistakes in the past.

Are there decisions here that will be difficult to reverse?

thanks,
Rob

---

From: Hanno Becker <[email-masked]>
Date: Mon, 6 Apr 2020 11:19:15 +0000

Hey Martin,

Thanks a lot for your reply!

> I think that you are assuming a lot about how the loss recovery part of the sender is operating here

My assumptions follow what the spec says SHOULD be done, though - nothing more and nothing less.

> If you receive ACK { 1, 3 }, then it might be
> reasonable to assume that 2 got lost, but it seems
> to me that assuming anything about 4 is premature

I agree, but again this is what the spec unambiguously does by saying implementations SHOULD resend the complement of what was ACKed.

I think in principle we agree on reasonable measures for improving the ACK efficiency. However, I disagree with the assessment that the scheme as-described provides sufficient efficiency for common uses, since large fragmentation and low MTU networks will be a common characteristic for IoT deployments, and DTLS 1.3 'out of the box' implementations should suite these, where by out of the box I mean implementations that do precisely what the spec says they SHOULD do.

On first sight, an easy improvement seems to be mentioning/recommending implementations to buffer ACKs for some time, but we have to be careful with this since it affects the semantics of ACKs in a major way which may lead to interoperability issues: If ACKs are buffered on the receiver, they can be sent recurringly, and also be split. This way, they are no longer 'negative' in the sense that they indicate a disruption, as is the case now. If, in turn, ACKs are not necessarily buffered but trigger immediate retransmission, implementations should not use them recurringly.

Thus, in a nutshell, leaving the question of whether ACKs should be buffered or not on the receiver to the implementor, leads to interoperability issues.

Cheers,
Hanno
________________________________
From: TLS <[email-masked]> on behalf of Thomas Fossati <[email-masked]>
Sent: Monday, April 6, 2020 12:01 PM
To: Martin Thomson <[email-masked]>; [email-masked] <[email-masked]>
Subject: Re: [TLS] Efficiency of ACKing scheme

True that.

Cheers!

---

From: Thomas Fossati <[email-masked]>
Date: Mon, 6 Apr 2020 12:03:39 +0000

> Are there decisions here that will be difficult to reverse?

At a first glance it doesn't seem likely.  The spec is quite malleable
and gives implementations a lot of leeway.

That said, as currently written, this doesn't seem to work particularly
well on paths that are lossy, slow, and with small MTUs (or a
combination thereof), which we need to make sure it's reasonably well
covered as it happens to be one of our main use cases.

I'm inclined to say this could be solved by profiling the reliability
scheme for constrained networks (in I-D.tschofenig-uta-tls13-profile),
but there still things that can be said wrt ACK timing here that can
improve implementations in the general case, I think.

Cheers

---

From: Thomas Fossati <[email-masked]>
Date: Mon, 6 Apr 2020 12:18:47 +0000

Hi Hanno,

On 06/04/2020, 12:19, "Hanno Becker" <[email-masked]> wrote:
> Thus, in a nutshell, leaving the question of whether ACKs should be
> buffered or not on the receiver to the implementor, leads to
> interoperability issues.

I'm not sure this strictly qualifies as an interop issue.

At a subtle level it is, in the sense that the signals coming from one
side don't the same exact semantics when observed from the peer point of
view, but that doesn't result in an interop problem at the macro level.
It does make the reliability scheme suboptimal and maybe even grossly
inefficient in some cases and may have disruptive potential on the
network, agreed.  But the overall "lost in translation" effect depends
greatly on the resources available to the endpoints as well as the
network path rather than the inner logics of the ACKing scheme.

cheers

---

From: Hanno Becker <[email-masked]>
Date: Mon, 6 Apr 2020 14:16:49 +0000

Hi Thomas!

Given we agree that there is a significant inefficiency in the ACKing scheme as stated, I'd prefer we try to improve the spec now provided we find a not too intrusive way to do so, and not postpone the problem.

After all, it seems that there isn't much to be changed if we go for option 2 from the original post, which perhaps isn't far off from the original intention anyway:

* Sending ACKs: ACKs may be sent for any record immediately, but it is recommended to bunch ACKs and in particular send them on any sign of disruption.

* Receiving ACKs: Upon receipt of an ACK, implementations should note which messages have been received and omit them from future retransmissions. It is up to the implementation to decide when to retransmit and what to retransmit, but it is recommended they retransmit after a period of time during which no further ACK messages have been received. They may also proactively retransmit parts of a flight early if an ACK message indicates a gap (note, though, that in this example one would only retransmit the gap, not the gap + tail as before).

The decisive difference to the current draft is that this takes away the character of ACKs as retransmission requests (resulting from the recommendation of immediate retransmission upon receipt of a partial ACK), while it retains flexibility as to how exactly the scheme is implemented.

Cheers,
Hanno

Cheers

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 6 Apr 2020 08:19:40 -0700

On Mon, Apr 6, 2020 at 7:17 AM Hanno Becker <[email-masked]> wrote:

> Given we agree that there is a significant inefficiency in the ACKing
> scheme as stated, I'd prefer we try to improve the spec now provided we
> find a not too intrusive way to do so, and not postpone the problem.
>
> After all, it seems that there isn't much to be changed if we go for
> option 2 from the original post, which perhaps isn't far off from the
> original intention anyway:
>
> * Sending ACKs: ACKs may be sent for any record immediately, but it is
> recommended to bunch ACKs and in particular send them on any sign of
> disruption.
>
> * Receiving ACKs: Upon receipt of an ACK, implementations should note
> which messages have been received and omit them from future
> retransmissions. It is up to the implementation to decide when to
> retransmit and what to retransmit, but it is recommended they retransmit
> after a period of time during which no further ACK messages have been
> received. They may also proactively retransmit parts of a flight early if
> an ACK message indicates a gap (note, though, that in this example one
> would only retransmit the gap, not the gap + tail as before).
>
> The decisive difference to the current draft is that this takes away the
> character of ACKs as retransmission requests (resulting from the
> recommendation of immediate retransmission upon receipt of a partial ACK),
> while it retains flexibility as to how exactly the scheme is implemented.
>

First, let me say that in scenarios like the one you posit we have other
problems besides ACK inefficiency. Specifically, DTLS doesn't do any real
congestion control and so your initial window will be way too big if you
broadcast a 40K message at once. So I don't think a huge amount of
optimization is in order here. By contrast. we do know that DTLS
retransmission is too slow and given that small flights are common, losing
the ability to indicate that you lost a tail seems undesirable.

ISTM that the easiest way to deal with this is to have the sender treat the
current ACK state as the union of the states it has received and permit
receivers to only ACK each packet once (while encouraging them to fill the
ACK packet). Then you would retransmit if your new ACK state was partial
rather than if the ACK was partial.

-Ekr

---

From: Thomas Fossati <[email-masked]>
Date: Mon, 6 Apr 2020 16:02:48 +0000

On 06/04/2020, 15:16, "Hanno Becker" <[email-masked]> wrote:
> scheme as stated, I'd prefer we try to improve the spec now provided
> we find a not too intrusive way to do so, and not postpone the
> problem.
>
> retransmit and what to retransmit, but it is recommended they
> retransmit after a period of time during which no further ACK messages
> have been received. They may also proactively retransmit parts of a
> flight early if an ACK message indicates a gap (note, though, that in
> this example one would only retransmit the gap, not the gap + tail as
> before).

Looks like a sound proposal to me.  The only problem I see with this is
that recovery from tail loss is not efficient, which might or might not
be a problem, depending on the loss pattern of your path.

cheers!

---

From: Thomas Fossati <[email-masked]>
Date: Mon, 6 Apr 2020 16:03:19 +0000

On 06/04/2020, 16:20, "Eric Rescorla" <[email-masked]> wrote:
> First, let me say that in scenarios like the one you posit we have
> other problems besides ACK inefficiency. Specifically, DTLS doesn't do
> any real congestion control and so your initial window will be way too
> big if you broadcast a 40K message at once. So I don't think a huge
> amount of optimization is in order here.

While it is true that there's no explicit congestion control, that
doesn't prevent an implementation to conservatively pace the send
instead of firing off the whole 40K worth of payload at line rate.

> By contrast. we do know that DTLS retransmission is too slow and given
> that small flights are common, losing the ability to indicate that you
> lost a tail seems undesirable.

I agree this should be avoided if possible.

---

From: Hanno Becker <[email-masked]>
Date: Wed, 8 Apr 2020 14:10:57 +0000

Hi Thomas, Hi Ekr,

> I agree this should be avoided if possible.

As far as I see, tail loss indication involves a timer in both cases:

- As it stands, tail loss recovery is triggered by the ACK resulting from the 'lack of progress' indicator of
disruption, described in the second bullet point of https://tools.ietf.org/html/draft- ietf-tls-dtls13-37#section-7.1<https://tools.ietf.org/html/draft-ietf-tls-dtls13-37#section-7.1>
In particular, it only occurs after a 'short' timer triggered on the receiver, where by 'short' I mean that is
has smaller threshold than the ordinary retransmission timer from DTLS 1.2, marking the bottom line
recovery time we want to improve upon.

- Likewise, there's short timer based recovery in the new proposal, but mirrored: The sender retransmits upon
noticing a gap in the ACKs, which too can be detected by a short timer as in the current proposal.

Best,
Hanno

---

From: Thomas Fossati <[email-masked]>
Date: Thu, 9 Apr 2020 11:27:21 +0000

Hey Hanno,

On 08/04/2020, 15:11, "Hanno Becker" <[email-masked]> wrote:
> - As it stands, tail loss recovery is triggered by the ACK resulting
>   from the 'lack of progress' indicator of disruption, described in
>   the second bullet point of draft-ietf-tls-dtls13-37#section-7.1
>   In particular, it only occurs after a 'short' timer triggered on the
>   receiver, where by 'short' I mean that is has smaller threshold than
>   the ordinary retransmission timer from DTLS 1.2, marking the bottom
>   line recovery time we want to improve upon.
>
> - Likewise, there's short timer based recovery in the new proposal,
>   but mirrored: The sender retransmits upon noticing a gap in the
>   ACKs, which too can be detected by a short timer as in the current
>   proposal.

You are right, this wouldn't have worse tail-loss recovery than what is
currently specified.  So, all things considered it looks like a real
improvement compared to dtls13-37.

Could collect the text from this thread in a PR against Section 7?  This
way folks that haven't followed the discussion closely can see how your
proposal looks overall.

cheers, thanks!

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 9 Apr 2020 06:20:15 -0700

Assuming I understand Hanno's proposal, I do not believe that this is in
fact an improvement, as it does not cover the important case where the
record containing the SH is lost and then the rest of the messages from the
server are uninterpretable.

-Ekr

On Thu, Apr 9, 2020 at 4:27 AM Thomas Fossati <[email-masked]>
wrote:

> contents to any other person, use it for any purpose, or store or copy the
> information in any medium. Thank you.

---

From: Thomas Fossati <[email-masked]>
Date: Thu, 9 Apr 2020 13:59:27 +0000

On 09/04/2020, 14:20, "Eric Rescorla" <[email-masked]> wrote:
> Assuming I understand Hanno's proposal, I do not believe that this is
> in fact an improvement, as it does not cover the important case where
> the record containing the SH is lost and then the rest of the messages
> from the server are uninterpretable.

I don't want to speak for Hanno here but the refinement proposed in [1],
specifically the bit that says:

  [...] They may also proactively retransmit parts of a flight early if
  an ACK message indicates a gap.

should cover the case you mention I think.

[1] https://mailarchive.ietf.org/arch/msg/tls/w2nEYEB3ZMs5bzejqcHVEO-OBVQ/

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 9 Apr 2020 07:17:27 -0700

> should cover the case you mention I think.

But this requires being able to send an empty ACK that means "I got
nothing". In which case, I don't see how it's really different from the
current text except that it gives the sender less guidance.

-Ekr

---

From: Thomas Fossati <[email-masked]>
Date: Thu, 9 Apr 2020 14:28:08 +0000

On 09/04/2020, 15:18, "Eric Rescorla" <[email-masked]> wrote:
> > On Thu, Apr 9, 2020 at 6:59 AM Thomas Fossati <[email-masked]> wrote:
> > > Assuming I understand Hanno's proposal, I do not believe that this
> > > is in fact an improvement, as it does not cover the important case
> > > where the record containing the SH is lost and then the rest of
> > > the messages from the server are uninterpretable.
> >
> > I don't want to speak for Hanno here but the refinement proposed in
> > [1], specifically the bit that says:
> >
> >   [...] They may also proactively retransmit parts of a flight early
> >   if an ACK message indicates a gap.
> >
> nothing". In which case, I don't see how it's really different from
> the current text except that it gives the sender less guidance.

Not sure there's an "empty ACK" in Hanno's proposal.  This is how I
interpret it in the context of your example: in the second flight, if
rec#0 (containing SH) is lost and rec#1 gets through, the receiver sends
ACK {1}.  From that the sender can infer the gap and retransmit rec#0.

(But again, I'm not him and that's why I suggested collecting all the
pieces of this discussion together in one PR.)

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 9 Apr 2020 07:33:26 -0700

> ACK {1}.  From that the sender can infer the gap and retransmit rec#0.

You can't send ACK{1} because you can't  decrypt it because it is out of
order with respect to the DH key. This is the point of the empty ACK.

-Ekr

---

From: Hannes Tschofenig <[email-masked]>
Date: Thu, 9 Apr 2020 15:09:37 +0000

Hi Thomas, Hi Ekr,

It seems we need to fix Figure 11 of Section 7.1 of
https://www.ietf.org/id/draft-ietf-tls-dtls13-37.html<https://www.ietf.org/id/draft-ietf-tls-dtls13-37.html#section-7.1>
(ACK[1] should actually be ACK[])

It should follow the “empty ACK” description of the last paragraph of the same section.

Good catch!

Ciao
Hannes

From: TLS <[email-masked]> On Behalf Of Eric Rescorla
Sent: Thursday, April 9, 2020 4:33 PM
To: Thomas Fossati <[email-masked]>
Cc: [email-masked]
Subject: Re: [TLS] Efficiency of ACKing scheme

On Thu, Apr 9, 2020 at 7:28 AM Thomas Fossati <[email-masked]<mailto:[email-masked]>> wrote:
On 09/04/2020, 15:18, "Eric Rescorla" <[email-masked]<mailto:[email-masked]>> wrote:
> > On Thu, Apr 9, 2020 at 6:59 AM Thomas Fossati <[email-masked]<mailto:[email-masked]>> wrote:
> > On 09/04/2020, 14:20, "Eric Rescorla" <[email-masked]<mailto:[email-masked]>> wrote:

You can't send ACK{1} because you can't  decrypt it because it is out of order with respect to the DH key. This is the point of the empty ACK.

-Ekr

---

From: Thomas Fossati <[email-masked]>
Date: Thu, 9 Apr 2020 15:12:13 +0000

On 09/04/2020, 15:34, "Eric Rescorla" <[email-masked]> wrote:
> > > But this requires being able to send an empty ACK that means "I
> > > got nothing". In which case, I don't see how it's really different
> > > from the current text except that it gives the sender less
> > > guidance.
> >
> > interpret it in the context of your example: in the second flight,
> > if rec#0 (containing SH) is lost and rec#1 gets through, the
> > receiver sends ACK {1}.  From that the sender can infer the gap and
> > retransmit rec#0.
> >
> > You can't send ACK{1} because you can't  decrypt it because it is
> > out of order with respect to the DH key. This is the point of the
> > empty ACK.

True, so you send ACK{} (as per last para of Section 7.1) and similarly
the receiver can deduce a gap -- indeed a very precise one -- and
re-send record containing the SH.

---

From: Hanno Becker <[email-masked]>
Date: Tue, 14 Apr 2020 07:13:46 +0000

Hi,

Apologies for the late reply.

First, let me say that foremost I wanted to highlight the potential
efficiency problem with the current solution. The mentioned alternative
isn't yet fully thought through, so it may well have drawbacks itself
that render it no better than the current version. However, in any
case I'd hope we can in the end find a solution which doesn't suffer from
the current inefficiency, as this seems prohibitive for IoT deployments.

Replying to Ekr's initial comment first:
> ISTM that the easiest way to deal with this is to have the sender
> treat the current ACK state as the union of the states it has received
> and permit receivers to only ACK each packet once (while encouraging them
> to fill the ACK packet). Then you would retransmit if your new ACK state
> was partial rather than if the ACK was partial.

I agree, something along those lines should work and I was attempting that
with the proposed text, though spelling out the details doesn't seem entirely
straightforward. For example, we don't want to retransmit immediately if we
receive an ACK such that the new cumulative ACK state is partial, because
otherwise we'd retransmit many times while building up the ACK state. The
proposed text therefore recommends to retransmit after a sufficiently
long period during which no further ACK is received.

Receivers, in turn, may send ACKs one-by-one, though it is encouraged
to fill them, as you said.

So if I understand your comment above correctly, it appears
to be in line with the intention of the proposed new text.

Note that the proposal leaves it open whether receivers send
ACKs recurringly, even if everything is transmitted perfectly,
or only when they notice a disruption. The only recommendation
I think the text should make is that once an implementation decides
to start ACKing, it shouldn't leave a too large time-gap between
two consecutive ACKs: This is for the recommended heuristic of
"retransmission on ACK-less period" on the sender to work.

Best,
Hanno
________________________________
From: Thomas Fossati <[email-masked]>
Sent: Thursday, April 9, 2020 4:12 PM
To: Eric Rescorla <[email-masked]>
Cc: Hanno Becker <[email-masked]>; Rob Sayre <[email-masked]>; [email-masked] <[email-masked]>; Thomas Fossati <[email-masked]>
Subject: Re: [TLS] Efficiency of ACKing scheme