From 63c950d09ec71869ee86fd4d5e007f3be1cac888 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Thu, 29 Oct 2020 12:08:56 -0400 Subject: [PATCH 1/5] VarInt decoding pseudocode --- draft-ietf-quic-transport.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index b242445ee7..82cf3cbec9 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -4345,10 +4345,7 @@ encoding properties. | 11 | 8 | 62 | 0-4611686018427387903 | {: #integer-summary title="Summary of Integer Encodings"} -For example, the eight byte sequence c2 19 7c 5e ff 14 e8 8c (in hexadecimal) -decodes to the decimal value 151288809941952652; the four byte sequence 9d 7f 3e -7d decodes to 494878333; the two byte sequence 7b bd decodes to 15293; and the -single byte 25 decodes to 37 (as does the two byte sequence 40 25). +Examples and a sample decoding algorithm are shown in {{sample-varint}}. Versions ({{versions}}) and packet numbers sent in the header ({{packet-encoding}}) are described using integers, but do not use this @@ -7486,6 +7483,28 @@ ECN to be disabled. For those rare cases where marked packets are discarded by the path, the short duration of the testing period limits the number of losses incurred. +# Sample Variable-Length Integer Decoding {#sample-varint} + +The pseudo-code in {{alg-varint}} shows how a variable-length integer can be +read from a stream of bytes. The function ReadVarint takes a single argument, a +sequence of bytes to read from. + +~~~ +ReadVarint(data): + first_byte = data.peek() + prefix = first_byte >> 6 + num_bytes = 1 << prefix + mask = (1 << (num_bytes * 8 - 2)) - 1 + + return data.read(num_bytes) & mask +~~~ +{: #alg-varint title="Sample Variable-Length Integer Decoding Algorithm"} + +For example, the eight-byte sequence 0xc2197c5eff14e88c decodes to the decimal +value 151,288,809,941,952,652; the four-byte sequence 0x9d7f3e7d decodes to +494,878,333; the two-byte sequence 0x7bbd decodes to 15,293; and the single byte +0x25 decodes to 37 (as does the two-byte sequence 0x4025). + # Change Log From 75a56bf5d9a03bbdef8ba13b5a8f988d381e045d Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 30 Oct 2020 11:01:30 -0400 Subject: [PATCH 2/5] Apply suggestions from code review Co-authored-by: Martin Thomson --- draft-ietf-quic-transport.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 82cf3cbec9..4078b15796 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -7491,12 +7491,12 @@ sequence of bytes to read from. ~~~ ReadVarint(data): - first_byte = data.peek() - prefix = first_byte >> 6 - num_bytes = 1 << prefix - mask = (1 << (num_bytes * 8 - 2)) - 1 - - return data.read(num_bytes) & mask + v = data.next_byte() + length = (1 << (v >> 6)) + v = v & 0x3f + repeat length-1 times: + v = (v << 8) + data.next_byte() + return v ~~~ {: #alg-varint title="Sample Variable-Length Integer Decoding Algorithm"} From e4213677504e4b326bc5beba0a4a98f78bbc699f Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 30 Oct 2020 11:04:07 -0400 Subject: [PATCH 3/5] Add comments --- draft-ietf-quic-transport.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 4078b15796..d8194816c8 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -7491,8 +7491,13 @@ sequence of bytes to read from. ~~~ ReadVarint(data): + // The length of variable-length integers is encoded in the + // first two bits of the first byte. v = data.next_byte() length = (1 << (v >> 6)) + + // Once the length is known, remove these bits and read any + // remaining bytes. v = v & 0x3f repeat length-1 times: v = (v << 8) + data.next_byte() From 5b60a9a8a0b3da85214e448d590a9fb8b0c48a42 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 30 Oct 2020 11:05:24 -0400 Subject: [PATCH 4/5] Lars's comment --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index d8194816c8..4f08159266 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -7487,7 +7487,7 @@ incurred. The pseudo-code in {{alg-varint}} shows how a variable-length integer can be read from a stream of bytes. The function ReadVarint takes a single argument, a -sequence of bytes to read from. +sequence of bytes which can be read in network byte order. ~~~ ReadVarint(data): From 5c18ee9353f87f9f70bfcba806ef9699a7752030 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 30 Oct 2020 11:11:22 -0400 Subject: [PATCH 5/5] Expand for clarity --- draft-ietf-quic-transport.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 4f08159266..ab73a44897 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -7494,7 +7494,8 @@ ReadVarint(data): // The length of variable-length integers is encoded in the // first two bits of the first byte. v = data.next_byte() - length = (1 << (v >> 6)) + prefix = v >> 6 + length = 1 << prefix // Once the length is known, remove these bits and read any // remaining bytes.