Subject: Why is MAX_DATA in units of 1024 octets?

From: Dmitri Tikhonov <[email-masked]>
Date: Wed, 23 Aug 2017 16:50:58 -0400

Hello,

I would like to know why maximum data is defined as it is, "in units
of 1024 octets:"

 " The fields in the MAX_DATA frame are as follows:
 "
 " Maximum Data:  A 64-bit unsigned integer indicating the maximum
 "    amount of data that can be sent on the entire connection, in units
 "    of 1024 octets.  That is, the updated connection-level data limit
 "    is determined by multiplying the encoded value by 1024.

(I did not see a discussion regarding this on GitHub or on the mailing
list.  If I missed a resource, please let me know.)

This requirement means having to write extra code to handle what is
effectively a 74-bit integer for something that is not likely to
occur, as 2^64 bytes is a lot of data.  I am tempted to say that a
smart implementation would close the connection when Maximum Data
starts to approach 2^54 and not bother.

  - Dmitri.

---

From: Ian Swett <[email-masked]>
Date: Wed, 23 Aug 2017 16:55:46 -0400

I believe the thinking was that if we allow 2^32 streams and 2^64 packets
that the max connection level flow control value becomes the limiting
factor of connection lifetime.

However, you make a good point that integers longer than 64 bits are very
non-standard and this could be a source of bugs.  I will note that there is
no requirement a sender or receiver ever send or allow receipt of more than
2^64 bytes.  But if the peer advertised a connection level flow control
value that large, they'd have to handle it correctly.

---

From: Martin Thomson <[email-masked]>
Date: Thu, 24 Aug 2017 07:19:26 +1000

Ian has it right, if 2^74 is hard for you, stop before you get there.
You don't have to advertise a window that large, and you don't have to
send that much data.

On 24 August 2017 at 06:55, Ian Swett <[email-masked]> wrote:
> that the max connection level flow control value becomes the limiting factor
> of connection lifetime.
>
> On Wed, Aug 23, 2017 at 4:50 PM, Dmitri Tikhonov
> <[email-masked]> wrote:
>>
>> Hello,
>>

---

From: Dmitri Tikhonov <[email-masked]>
Date: Thu, 24 Aug 2017 09:15:56 -0400

I would like to point out that the maximum numbers of streams and
packets are picked a) to be large enough and b) to match standard
integer sizes.  The (b) part of the rationale is obvious and is
usually not stated; for the purposes of my argument, however, it
needs to be noted.

Take away (b), and the limits imposed are arbitrary.  For example,
why 2^32 and not 2^31 or 2^34?

Does QUIC protocol need these limits?  One could encode an integer
of any size and not worry about hitting a limit.  Yet QUIC chooses
to have limits, and that is because, I believe, it wants to avoid
forcing implementations to use specialized math routines to calculate
byte offsets.

Going back to (a), 2^64 is really large enough for both stream and
connection offset limits: sending this many bytes at 10 Gbps will
take about 467 years [1].  It will just not happen on a single QUIC
connection.  If, in fifty years, network transfer speeds are much
faster, QUIC v2 (this is why QUIC has versions) can use 128-bit
integers which, by that time, are sure to be supported natively by
most processors.

On Wed, Aug 23, 2017 at 04:55:46PM -0400, Ian Swett wrote:
> But if the peer advertised a connection level flow control value
> that large, they'd have to handle it correctly.
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^

That's the thing: every QUIC implementation will have code to
handle -- and unit tests to test -- a condition that will never occur.

  - Dmitri.

1. http://www.wolframalpha.com/input/?i=16+exbibytes+%2F+10+gbps

---

From: Martin Thomson <[email-masked]>
Date: Fri, 25 Aug 2017 08:26:48 +1000

Most of the integers we have need to be encoded.  That naturally leads
to multiples of 8 bits.  That's the first reason for having the
numbers as they are.

And terabit rates aren't implausible.

> handle -- and unit tests to test -- a condition that will never occur.

As I said, you don't have to send that much.  If you have a limit of
2^50, then when someone sends you a value of 2^40 or higher, stop
paying attention to the flow control limit and rely on your own limit.
It's not that hard.

---

From: Dmitri Tikhonov <[email-masked]>
Date: Fri, 25 Aug 2017 09:24:59 -0400

> to multiples of 8 bits.  That's the first reason for having the

That's not what I wrote.  I wrote:

  " the maximum numbers of streams and packets are picked a) to be
  " large enough and b) to match standard integer sizes.
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

How numbers are encoded is not important here; what's important is
that there are limits at all.  And it's those limit sizes -- after
decoding -- is at the root of the discussion.

> And terabit rates aren't implausible.

Fine, so my hypothetical scenario would take 4.5 years, which is still
quite unlikely to occur.  Speaking of likelihoods, why cap the maximum
stream data at 2^64 and connection stream data at 2^74 -- is it more
likely that a connection will have a combination of streams whose data
will exceed 2^64 than a single stream that needs to transfer more than
2^64?  Why not also allow more than 2^64 packets?  At what point do we
stop or don't stop any why?

I argue that 2^64 is "large enough."  In other words, for all intents
and purposes 2^64 is infinity in the context of a QUIC connection.
The explanation that Ian Swett provided, that

  " the thinking was that if we allow 2^32 streams and 2^64 packets
  " that the max connection level flow control value becomes the
  " limiting factor of connection lifetime

does not explain the *need* for a number larger that 2^64.  Yes, one
infinity can be larger than another, but in practice we just do not
care: we are unlikely to hit 2^64 packets, 2^64 bytes per stream, or
2^64 bytes per connection.

2^64 is a very large number that is easy to use because it fits into
a standard integer size.  Including a 2^74 number in the draft would
do well with an explicit justification.

> paying attention to the flow control limit and rely on your own limit.

You made my point.

  - Dmitri.

---

From: Martin Thomson <[email-masked]>
Date: Mon, 28 Aug 2017 12:55:47 +1000

On 25 August 2017 at 23:24, Dmitri Tikhonov <[email-masked]> wrote:
> That's not what I wrote.

Yes, but I'm disagreeing with you.

---

From: Dmitri Tikhonov <[email-masked]>
Date: Mon, 28 Aug 2017 09:27:17 -0400

> Yes, but I'm disagreeing with you.

OK, I should have written "that's not what I meant," for encoding
itself is not the issue.  (In regards to encoding, however, I do not
see how the need to encode integers "naturally leads to multiples of
8 bits."  It is convenient to have an *encoded representation* be
a multiple of 8 bits, not the value itself.)

The [draft-ietf-quic-transport] document states that it "describes
the core QUIC protocol, including the conceptual design."  I think
the limitations associated with the packet numbers and byte offsets
should be explained.

The questions are:

    1. Why are there packet number and byte offset limits?  In
       other words, why are there limits on the duration of a
       connection?  (That's the "conceptual design" part).

    2. How are particular limits chosen?

Since QUIC is a transport protocol, it will be compared to TCP.  The
draft does that in several places, and QUIC invariably ends up being
better than TCP.  Yet TCP does not place a limit on the amount of data
that can be sent over a single connection.

  - Dmitri.