Subject: [tsvwg] OCS option in draft-ietf-tsvwg-udp-options-06

From: "C. M. Heard" <[email-masked]>
Date: Thu, 7 Mar 2019 08:36:33 -0800

Greetings,

First, thanks to Joe Touch for this update. That said, it appears to me
that the edits to the description of OCS are incomplete.  I see in the
first paragraph

   The Option Checksum (OCS) is conventional Internet checksum that
   covers all of the UDP options.

and further down

   >> OCS SHOULD be half-word aligned to the start of the UDP packet.
   This is to help ensure that the option, together with the other
   options, result in an overall zero ones-complement sum, which may
   help the UDP options traverse devices that incorrectly attempt to
   checksum the surplus area (as originally proposed as the Checksum
   Compensation Option [Fa18]).

However, the second paragraph (which is consistent with the diagram) says

   OCS is calculated by computing the ones-complement of the 8-bit
   ones-complement checksum (i.e., Internet checksum) sum of the
   options area.

Perhaps I am missing something, but it seems to me that OCS cannot perform
the function of the proposed Checksum Compensation Option (CCO) unless it
is computed as the  the 16 bit one's complement of the one's complement sum
of all 16 bit half-words in the options area, subject to the following
alignment requirements:

- if the options area begins on an odd octet boundary, then it conceptually
prepended by a zero-valued octet for the purposes of checksum computation;

- if the options area ends on an odd octet boundary, then it is conceptually
padded by a zero-valued octet for the purposes of checksum computation;

- the OCS option is preceded by a NOP option if necessary so that the
checksum itself is 16-bit aligned (i.e., is on an even octet boundary).

This can all be achieved with an option that has kind = 2 followed by a 16-bit
checksum, without a length value.  That actually has better properties than
CCO as originally proposed, because it is never required to be more than
four octets in length, including any padding needed for half-word alignment.

If I am missing something (which happens all too often these days) I would
like to hear what it is.

Thanks and regards,

Mike Heard

---

From: Joe Touch <[email-masked]>
Date: Thu, 7 Mar 2019 08:56:19 -0800

> On Mar 7, 2019, at 8:36 AM, C. M. Heard <[email-masked]> wrote:
> 
> Greetings,
> 
> that the edits to the description of OCS are incomplete.  

Yes - sorry about that. I wanted to get a quick update out for initial feedback, but there are probably more than a few rough edges where things need to be made consistent. 

So I appreciate the feedback - comments below...

> I see in the

Yeah - in my rush, I didn’t fix that.

> of all 16 bit half-words in the options area,

The intent is as you assume; the text needs to be updated accordingly.

> subject to the following

These seem complete to me - I’d like the CCO people to check, though.

Note that the trailing ‘virtual zero’ is already part of how the Internet checksum works for odd byte-lengths. The new part here is to force the virtual zero on the front - however, that’s not really needed.

We can compute the checksum starting wherever we want. If we start on an odd boundary, then just swap the bytes when we’re done.

So the simpler variant is:
	- precede by NOP if not 16-bit aligned
	- do IP checksum as per RFC 1071
	- if NOP was added, just insert the result
	- if NOP wasn’t added, swap bytes of the sum and insert the result

(we can explain why this works)

---

From: raffaele <[email-masked]>
Date: Thu, 07 Mar 2019 21:04:03 +0000

Hello,
I am Raffaele Zullo, former researcher at the University of Aberdeen.
I have previously worked on CCO.

On 2019-03-07 16:56, Joe Touch wrote:
> Yes - sorry about that. I wanted to get a quick update out for initial
> feedback, but there are probably more than a few rough edges where
> things need to be made consistent.
> 

Yes, an implicit length of 3 can save 1 byte without changing CCO 
benefit.

(Actually we also explored another scheme for CCO that doesn't need 
half-word alignment so it never requires padding.
The computation is a bit more complicated so considering it saved only 
0-1 byte it has not been included in the CCO draft.)

I would only add that the checksum has also to cover the 2 bytes 
pseudo-header containing UDP Options length other than UDP Options area 
bytes.

> Note that the trailing ‘virtual zero’ is already part of how the
> Internet checksum works for odd byte-lengths. The new part here is to
> force the virtual zero on the front - however, that’s not really
> needed.
> We can compute the checksum starting wherever we want. If we start on
> an odd boundary, then just swap the bytes when we’re done.

Yes, this solution works.

Considering we have also to include UDP Options length in the sum,
another option could be loading
UDP options length + the first odd byte, if present,
into checksum value before applying Internet Checksum from the first 
even byte of the Options.

> (we can explain why this works)

Yes, the simpler variant works.
If I am not wrong it assumes the 3-bytes OCS is always the first option 
(excluding NOP padding).
Are you going to make this mandatory?

>> If I am missing something (which happens all too often these days) I 

I am new to the WG so please be nice :)

Thank you,
Raffaele Zullo

---

From: Derek Fawcus <[email-masked]>
Date: Thu, 7 Mar 2019 21:23:11 +0000

> Are you going to make this mandatory?

I don't think that is necessary for it to be first, as long as the 16 bits
of checksum are correctly aligned for how they're swapped, the checksum
can be at any offset in the payload.

I believe the result of the CCO experiment was that it, or this new OCS,
would always have to be present in order to guarentee a packet passes
through certain middleboxes.  Except possibly th the case where the
UDP header checksum is zero?

Given that wouldn't it make sense for this option to be both mandatory to
implement, and always present in the options area?

DF

---

From: Tom Herbert <[email-masked]>
Date: Thu, 7 Mar 2019 13:23:29 -0800

> Are you going to make this mandatory?
If it's mandatory, it's not longer an option. It has been suggested a
number of time that the UDP option space should be preceded by header
that includes the checksum and and length of the space.

Tom

---

From: Joe Touch <[email-masked]>
Date: Thu, 7 Mar 2019 19:47:22 -0800

Hi, Derek,

> On Mar 7, 2019, at 1:23 PM, Derek Fawcus <[email-masked]> wrote:
> 

You’ve already partly answered your own question.

The other case is ACS, in which case (currently) there would be no OCS. It would be somewhat wasteful in both space and computation to include both, unless passing such middle boxes is needed.

Note - traversal of incorrectly implemented middle boxes is not a primary design consideration for UDP options. We are absolutely not designing a “byzantine” protocol, i.e., one that survives arbitrary attacks by intermediate boxes, whether deliberate or accidental.

Joe

---

From: Joe Touch <[email-masked]>
Date: Thu, 7 Mar 2019 19:48:40 -0800

> On Mar 7, 2019, at 1:04 PM, raffaele <[email-masked]> wrote:
> 
> I would only add that the checksum has also to cover the 2 bytes pseudo-header containing UDP Options length other than UDP Options area bytes.

There is no such pseudo header. It has been proposed, but it is not in the current design.

Joe

---

From: Gorry Fairhurst <[email-masked]>
Date: Fri, 08 Mar 2019 07:09:58 +0000

On 08/03/2019, 03:47, Joe Touch wrote:
> Hi, Derek,
>
>> On Mar 7, 2019, at 1:23 PM, Derek Fawcus 
>> <[email-masked] 
>> <mailto:[email-masked]>> wrote:
>>
> The other case is ACS, in which case (currently) there would be no 
> OCS. It would be somewhat wasteful in both space and computation to 
> include both, unless passing such middle boxes is needed.
>
> Note - traversal of incorrectly implemented middle boxes is not a 
> primary design consideration for UDP options. We are absolutely not 
> designing a “byzantine” protocol, i.e., one that survives arbitrary 
> attacks by intermediate boxes, whether deliberate or accidental.
>
> Joe
>
To be clear: This is not just a middlebox, NAT, etc consideration, there 
are also hosts that offload UDP option checks, that can black-hole the 
UDP Options that do not have the "CCO" like OCS value.

As an individual in the IETF (rather than the WG Chair), I think your 
note is a fair point for more discussion about whether we should design 
for deployability. It seems that a large number of people in the QUIC WG 
are specifically designing their new transport to optimise the chance of 
working through network paths that have middleboxes. At least with 
respect to IPv4, I could see merit in requiring the OCS in the options area.

Gorry

---

From: Joe Touch <[email-masked]>
Date: Thu, 7 Mar 2019 23:16:48 -0800

Hi, Gorry,

Designing for deployability to me involves adapting to MAYs and
exceptions to SHOULDs - i.e., legitimate deployment options.

Designing to overcome bugs or deliberate deviations from specs is a
losing battle. It helps endorse and entrench bad behavior and undermines
the very nature of specs.

If that's where we are, let's all save each other's time and call it the
"wild west".

In this specific case, there's a cost to requiring OCS - additional
effort exactly where it users decide it isn't needed (e.g., when UDP
CS=0 or the entire packet is covered by another layer, such as protected
tunneled transit) or where they decide the IP sum isn't enough (e.g,
when using ACS).

The default can be to include it, but IMO that's as much as we should do
here.

Joe

On 3/7/2019 11:09 PM, Gorry Fairhurst wrote:
> To be clear: This is not just a middlebox, NAT, etc consideration,
> there are also hosts that offload UDP option checks, that can
> black-hole the UDP Options that do not have the "CCO" like OCS value.
>
> note is a fair point for more discussion about whether we should
> design for deployability. It seems that a large number of people in
> the QUIC WG are specifically designing their new transport to optimise
> the chance of working through network paths that have middleboxes. At
> least with respect to IPv4, I could see merit in requiring the OCS in
> the options area.
>
> Gorry
>
>

---

From: Joe Touch <[email-masked]>
Date: Thu, 7 Mar 2019 23:41:08 -0800

Derek,

> can be at any offset in the payload.

Yes - this is true.

We should be able to ignore any of the other constraints and simply
compute OCS over the entire checksum area, so long as the result is
inserted with the same alignment as it is computed.

I.e., if the checksum field is word-aligned to the start of the option
area, then insert the calculated value (regardless of the alignment of
the option area start relative to the native alignment of memory).
Otherwise swap the bytes.

-----

Note, however, there's a problem with LITE: the whole point of LITE is
that it is not checksummed. We can't make OCS cover the LITE area - that
would be the opposite of our goal. And we can't force the LITE area to
be aligned.

So AFAICT although OCS will still work, it won't fix the bug - nor will
CCO - for either LITE or LITE+FRAG.

Joe

---

From: Derek Fawcus <[email-masked]>
Date: Fri, 8 Mar 2019 08:51:25 +0000

> The other case is ACS, in which case (currently) there would be no OCS. It would be somewhat wasteful in both space and computation to include both, unless passing such middle boxes is needed.

Except (as I recall) isn't the ACS intended to cover the base UDP payload?

So they perform different purposes, and this ACS case would only apply when
and if the UDP options are being used to carry ACS alone.  As soon as some
other option is also present together with ACS, the case for OCS being
present arises.

(One could argue that OCS adds value in the ACS alone case, as it allows
 the presence & use of the options hence ACS to be validated.)

DF

---

From: Derek Fawcus <[email-masked]>
Date: Fri, 8 Mar 2019 13:24:51 +0000

> > The other case is ACS, in which case (currently) there would be no OCS. It would be somewhat wasteful in both space and computation to include both, unless passing such middle boxes is needed.

[snip]

> this ACS case would only apply when and if the UDP options
> are being used to carry ACS alone.  As soon as some other option
> is also present together with ACS, the case for OCS being present arises.

Actually, I have to go back to my original position.  Sending ACS alone w/o
OCS could still suffer from the CCO highlighted deployability issue.

Hence the only time options could be safely used w/o OCS would
be when the UDP checksum was zero.

So I guess we continue this in the deployability sub-thread.

DF

---

From: Derek Fawcus <[email-masked]>
Date: Fri, 8 Mar 2019 13:24:51 +0000

[snip]

DF

---

From: Joe Touch <[email-masked]>
Date: Fri, 8 Mar 2019 08:49:53 -0800

> Except (as I recall) isn't the ACS intended to cover the base UDP payload?

You're right; in my rush to get the update out, I got spun around on
that one...

The bigger issue is LITE and FRAG+LITE. Even if OCS is present, it won't
help either case get past these bugs.

---

That said, I'm going to suggest a more productive track than this
rat-hole of gaming a bug.

Pure and simple - NAME NAMES.

If there is a system that you know of that does this errant thing, tell
us the make, model, and firmware/sw version. Let's contact the vendor
and get them fixed.

That is the only useful way forward - especially because LITE+FRAG is a
key expected use case.

Joe

---

From: "C. M. Heard" <[email-masked]>
Date: Fri, 8 Mar 2019 20:56:22 -0800

> inserted with the same alignment as it is computed.

s/checksum area/options area/ in the above paragraph

> Otherwise swap the bytes.

Indeed, that is much more elegant than my initial suggestion. The sender
has the option to pre-align the checksum to a half-word boundary if it
is convenient, but that is not required; it is an implementation choice.

> would be the opposite of our goal. And we can't force the LITE area to

I agree, and I understand that's why why OCS is (and always has been)
defined so that it covers the UDP options (including LITE, if present),
but excludes the LITE data.

> CCO - for either LITE or LITE+FRAG.

Indeed, the updated version of OCS will not fix (or rather bypass) the
middlebox checksum computation bug for either LITE or LITE+FRAG.

That being said, there is a way around the problem with LITE+FRAG, and
that would be to define an updated version of CCO that is the same as
the updated version of OCS except that it covers LITE data as well as
UDP options. This of course would defeat the purpose of LITE without
FRAG, but it would allow LITE+FRAG to traverse the errant middleboxes.

I expect that we will disagree on this matter, but I think that designing
for deployability is vital in order for UDP options to get traction. This
can be tempered by providing a migration path around undesirable workarounds
for a better day when a NAME and SHAME campaign has succeeded in squashing
errant middlebox behavior. Think of EDNS0 in DNS and the recent DNS flag day.

Mike Heard

---

From: Joe Touch <[email-masked]>
Date: Fri, 8 Mar 2019 21:47:40 -0800

> FRAG, but it would allow LITE+FRAG to traverse the errant middleboxes.

So the problem is compounded in the case of LITE+FRAG.

One point of the LITE+FRAG solution is NOT checksum the contents of the
fragments, but TO checksum the resulting reassembled set - the rationale
being the E2E argument, that we should trust only the final step.

So not only would you be doing "unnecessary" work for LITE, but for
LITE+FRAG you'd be more than doubling the checksum overhead of
fragmentation.

Again, I would table further discussion on this topic until we have more
detail on either the network location of these alleged devices or the
names of their manufacturers and details, if known at endpoints. There's
simply no point in designing for a transient error.

Joe

---

From: Derek Fawcus <[email-masked]>
Date: Sat, 9 Mar 2019 10:37:06 +0000

> being the E2E argument, that we should trust only the final step.

As I recall the LITE+FRAG use case has no data in the UDP payload
(i.e UDP header length is zero)?

For this case, there is another way to work around a broken path (be it
boxes, NICs, or whatever), that is simply to send with UDP header checksum
of zero, and contain any necessary checksums in the UDP slack space.

Since the devices on path won't attempt to verify such packets, they
should pass unimpeded; and we can then control whatever checksum
behaviour is desired for the transported data with the contents of
the UDP options.

A similar approach can be used whenever UDP len is zero, it obviously
can't work when we have UDP data and meaningful data in the slack
space.

The OCS/CCO case can cover that, except for the LITE (w/o FRAG) case.

For the latter I guess we could also use UDP checksum of zero, and have
an option to restore a proper checksum for the UDP data at the receiver,
however that will still leave legacy receivers experiencing such packets
as unchecksumed.

Given that we're supposed to veryify such receivers can accept
LITE (w/o FRAG) and hold soft state, maybe this is acceptable?
i.e. we'de verify LITE comprehension by initially sending it
with a CCO like option; once the state is built, we can send
LITE (w/o FRAG) using UDP checksum of zero, and the additional
option encoding the actual checksum for the UDP data.

This additional checksum could simply be the existing defined
ACS option.

This would seem to avoid doubling of work, and also avoid performing
a checksum upon the LITE data portion.

DF

---

From: Derek Fawcus <[email-masked]>
Date: Sat, 9 Mar 2019 10:38:34 +0000

> simply no point in designing for a transient error.

I'd have to disagree on that.

We know there are issues, we won't find all of them up front,
but for those we've already found (even if we can't identify the
faulty devices), we should work around them where we can.

We have to cope with the world as we find it, not as we'd desire
it to be, otherwise the UDP options will simply end up being
a non-deployable academic exercise; and I view deployability
as trumping a lot of the other considerations.

I'd like to be able to use the result, vs the situation we have
with UDP-Lite.  So I'd say we have to make it work for a
sufficiently large portion of use cases that we get a foothold,
and that provides the pressure for others to fix their products.

That making it work task may well mean choices which seem to
be pandering to the broken devices currently deployed, but
so be it, otherwise there is a good chance this this effort
is simply wasted.

DF

---

From: "C. M. Heard" <[email-masked]>
Date: Sat, 9 Mar 2019 03:47:39 -0800

> as trumping a lot of the other considerations.

+1 to all of that, particularly when the workarounds can be made
relatively painless.

Mike Heard

---

From: Joe Touch <[email-masked]>
Date: Sat, 9 Mar 2019 11:04:30 -0800

OK, but at a MINIMUM we need to deal with these in parallel.

We do need to live with the real world, which means FIXING THE POTHOLES, not just building tanks that don’t care about them…

Joe

> On Mar 9, 2019, at 3:47 AM, C. M. Heard <[email-masked]> wrote:
>

---

From: Tom Herbert <[email-masked]>
Date: Sat, 9 Mar 2019 11:31:37 -0800

> as trumping a lot of the other considerations.
The only way you can know if UDP options are deployable is to actually
try to deploy them. This discussion is reminiscent of TFO where every
effort was made to define a deployable protocol, but when it started
in deployment unforeseen issues appeared where intermediate nodes were
dropping SYNs with data. It was quite a bit of work to identify and
the root out all the issues.

Tom

---

From: Joe Touch <[email-masked]>
Date: Sat, 9 Mar 2019 11:38:22 -0800

> On Mar 9, 2019, at 11:31 AM, Tom Herbert <[email-masked]> wrote:
> 

Perhaps, but we had similar issues with multilevel tunnels not working.

Instead of trying to design an encapsulation protocol to get around things, we tracked down the issues and fixed the bugs. 

Now we have a clean solution that works (just do multiple encapsulations) rather than a maze of twisty little passages as an artifact of tolerating errors rather than fixing them.

Joe