Subject: [tsvwg] Comments on UDP TIME Option

From: "C. M. Heard" <[email-masked]>
Date: Sun, 19 Sep 2021 14:10:46 -0700

I would like to offer some comments on the UDP TIME Option with the intent
of improving its description in the next iteration of the draft. I will put
my comments in-line with the text from the -13 draft.

   The Timestamp (TIME) option exchanges two four-byte timestamp
   fields. It serves a similar purpose to TCP's TS option [RFC7323],
   enabling UDP to estimate the round trip time (RTT) between hosts.
   For UDP, this RTT can be useful for establishing UDP fragment
   reassembly timeouts or transport-layer rate-limiting [RFC8085].

        +--------+--------+------------------+------------------+
        | Kind=8 | Len=10 |      TSval       |      TSecr       |
        +--------+--------+------------------+------------------+
          1 byte   1 byte       4 bytes            4 bytes

                    Figure 16   UDP TIME option format

   TS Value (TSval) and TS Echo Reply (TSecr) are used in a similar
   manner to the TCP TS option [RFC7323]. On transmitted segments using
   the option, TS Value is always set based on the local "time" value.

That last requirement above (to always set TSVAL based on the local "time"
value) assumes that the usage is bidirectional and symmetric, as in TCP.

Question: why does a receiver which just wants to echo the timestamp need
to set a TSVAL (or implement a local time counter) if it has no requirement
to measure RTT?  In contrast to TCP, we don't (in general) have a
bidirectional acknowledged transfer of messages in UDP. One plausible use
case would be a PLPMTUD probe packet exchange, as in:

Probe (empty user data, REQ(nonce), TIME(TSval=time, 0), PADDED_LENGTH =
probe size, DONT_FRAG ) =>

<= Any datagram (any user data, RES(nonce), TIME(0, TSecr=time) )

TIME is not strictly needed in this instance, since the sender can cache
the sent time value for each outstanding nonce. But it can be convenient.

   Received TSval and TSecr values are provided to the application,
   which can pass the TSval value to be used as TSecr on UDP messages
   sent in response (i.e., to echo the received TSval). A received
   TSecr of zero indicates that the TSval was not echoed by the
   transmitter, i.e., from a previously received UDP packet.

So far, so good. The production and consumption of timestamp values is
in the hands of the application.

   >> TIME MAY use an RTT estimate based on nonzero Timestamp values as
   a hint for fragmentation reassembly, rate limiting, or other
   mechanisms that benefit from such an estimate.

   >> TIME SHOULD make this RTT estimate available to the user
   application.

But the two paragraphs above imply under-the-hood machinery that UDP does
not provide and that has not been specified.

IMO what should be said is that the application may make an RTT estimate
and use it for the above purposes.

   UDP timestamps are modeled after TCP timestamps and have similar
   expectations. In particular, they are expected to be:

   o  Values are monotonic and non-decreasing except for anticipated
      number-space rollover events

   o  Values should "increase" (allowing for rollover) according to a
      typical 'tick' time

   o  A request is defined as "reply=0" and a reply is defined as both
      fields being non-zero.

I would say instead: A request is defined as "TSVAL != 0" and a reply is
defined as "TSecr != 0."

   o  A receiver should always respond to a request with the highest
      TSval received (allowing for rollover), which is not necessarily
      the most recently received.

   Rollover can be handled as a special case or more completely using
   sequence number extension [RFC5925].

That last sentence is a bit cryptic; I presume that it means to treat TSVal
/ TSecr as the 32-bit LSBs of a 64-bit number and maintain rollover
counters. That's probably not necessary with reasonable "time tick" values.
But there is another subtlety to consider, and that is that if the value 0
is reserved to mean "no value" then we really need to treat the time stamps
as 1s complement numbers (modulo 2^32-1) and not 2s complement numbers
(modulo 2^32) -- in other words, use end-around carry as in the Internet
checksum when incrementing the timestamp counter and when taking the
difference if two timestamps. Note that TCP timestamps do not have this
issue; per RFC 7323, TSVal is always required (since the option is present
in every segment) and TSecr is valid only when the ACK bit is set. RFC 7323
RECOMMENDS that TSecr be set to zero when not used, but zero is not a
reserved value. UDP has no ACK bit and so cannot use that expedient.

There is also the issue of whether this option can appear as a per-fragment
option, as well as a per-datagram option, and if so, what that means. If I
correctly understood the discussion in
https://mailarchive.ietf.org/arch/msg/tsvwg/fqWaOvS1faNDyz7STaQOUc_lRzc/
(and related messages in that thread), options are passed between UDP and
the upper/application later on a per-datagram basis, and to me, how this
would work if TIME is a per-datagram option is quite clear. But previous
discussions on this matter (see
https://mailarchive.ietf.org/arch/msg/tsvwg/cwb6WVYWnTSb089viLjSW59nlXM/
and follow up messages) did not come to any kind of consensus:

On  Fri, 30 July 2021 23:07 UTC  , C. M. Heard wrote:

> If TIME can be requested by the upper layer, what is the meaning if the
> option is requested for a datagram that gets split into multiple fragments,
> and the option is replicated in every fragment? I can see the per-fragment
> argument but only when the option is produced and consumed at the UDP layer
> -- as is the case for the corresponding TCP option (which appears on every
> segment if it is negotiated). If it's intended to be produced and consumed
> by the higher layer, it should be per-datagram.
>

On Sat, 31 July 2021 00:18 UTC Joseph Touch replied:
>
> Time for fragmented packets can be a sequence of values or (depending on
> whether the API might support this) a range (high/low). That information
> can be useful to the higher layer in setting parameters of UDP, e.g., how
> long to keep fragments before discard. Or it could be used within the UDP
> layer for that sort of tuning automatically.
>

I do not think we want vague statements like "can be a sequence of values
or (depending on whether the API might support this) a range (high/low)."
The services offered by UDP to the upper layer interface should be
well-defined, in order to promote interoperability. Making this option
per-datagram only seems to me to be the best way to accomplish that
objective. But a clear explanation of what would happen if TIME is set on a
per-fragment basis could also achieve that objective.

Thanks,

Mike Heard

---

From: Gorry Fairhurst <[email-masked]>
Date: Mon, 20 Sep 2021 09:07:43 +0100

On 19/09/2021 22:10, C. M. Heard wrote:
> I would like to offer some comments on the UDP TIME Option with the 
> intent of improving its description in the next iteration of the 
> draft. I will put my comments in-line with the text from the -13 draft.
>
> That last requirement above (to always set TSVAL based on the local 
> "time" value) assumes that the usage is bidirectional and symmetric, 
> as in TCP.
>
> Question: why does a receiver which just wants to echo the timestamp 
> need to set a TSVAL (or implement a local time counter) if it has no 
> requirement to measure RTT?  In contrast to TCP, we don't (in general) 
> have a bidirectional acknowledged transfer of messages in UDP. One 
> plausible use case would be a PLPMTUD probe packet exchange, as in:
>
> Probe (empty user data, REQ(nonce), TIME(TSval=time, 0), PADDED_LENGTH 
> = probe size, DONT_FRAG ) =>
>
> TIME is not strictly needed in this instance, since the sender can 
> cache the sent time value for each outstanding nonce. But it can be 
> convenient.
> So far, so good. The production and consumption of timestamp values is in the hands of the application.
> But the two paragraphs above imply under-the-hood machinery that UDP 
> does not provide and that has not been specified.
>
> IMO what should be said is that the application may make an RTT 
> estimate and use it for the above purposes.
>
> I would say instead: A request is defined as "TSVAL != 0" and a reply 
> is defined as "TSecr != 0."
>
> That last sentence is a bit cryptic; I presume that it means to treat 
> TSVal / TSecr as the 32-bit LSBs of a 64-bit number and maintain 
> rollover counters. That's probably not necessary with reasonable "time 
> tick" values. But there is another subtlety to consider, and that is 
> that if the value 0 is reserved to mean "no value" then we really need 
> to treat the time stamps as 1s complement numbers (modulo 2^32-1) and 
> not 2s complement numbers (modulo 2^32) -- in other words, use 
> end-around carry as in the Internet checksum when incrementing the 
> timestamp counter and when taking the difference if two timestamps. 
> Note that TCP timestamps do not have this issue; per RFC 7323, TSVal 
> is always required (since the option is present in every segment) and 
> TSecr is valid only when the ACK bit is set. RFC 7323 RECOMMENDS that 
> TSecr be set to zero when not used, but zero is not a reserved value. 
> UDP has no ACK bit and so cannot use that expedient.
>
> There is also the issue of whether this option can appear as a 
> per-fragment option, as well as a per-datagram option, and if so, what 
> that means. If I correctly understood the discussion in 
> <https://mailarchive.ietf.org/arch/msg/tsvwg/fqWaOvS1faNDyz7STaQOUc_lRzc/> 
> (and related messages in that thread), options are passed between UDP 
> and the upper/application later on a per-datagram basis, and to me, 
> how this would work if TIME is a per-datagram option is quite clear. 
> But previous discussions on this matter (see 
> <https://mailarchive.ietf.org/arch/msg/tsvwg/cwb6WVYWnTSb089viLjSW59nlXM/> 
>     If TIME can be requested by the upper layer, what is the meaning
>     if the option is requested for a datagram that gets split into
>     multiple fragments, and the option is replicated in every
>     fragment? I can see the per-fragment argument but only when the
>     option is produced and consumed at the UDP layer -- as is the case
>     for the corresponding TCP option (which appears on every segment
>     if it is negotiated). If it's intended to be produced and consumed
>     Time for fragmented packets can be a sequence of values or
>     (depending on whether the API might support this) a range
>     (high/low). That information can be useful to the higher layer in
>     setting parameters of UDP, e.g., how long to keep fragments before
>     discard. Or it could be used within the UDP layer for that sort of
>     tuning automatically.
>
>
> I do not think we want vague statements like "can be a sequence of 
> values or (depending on whether the API might support this) a range 
> (high/low)." The services offered by UDP to the upper layer interface 
> should be well-defined, in order to promote interoperability. Making 
> this option per-datagram only seems to me to be the best way to 
> accomplish that objective. But a clear explanation of what would 
> happen if TIME is set on a per-fragment basis could also achieve that 
> objective.
>
> Thanks,
>
> Mike Heard

I'd like to add support for this last point. An application that employs 
the Fragmentation feature does actually experience an RTT for the UDP 
service that includes the additional delays from performing 
fragmentation, therefore the reported RTT should be the actual time it 
takes to deliver the complete datagram across the service provided. 
That's the value an app needs to calculate a window size, timer for loss 
recovery, etc.

Implementations could always do more than required, but I think the ID 
should only specify the minimum that is needed.

Best wishes,

Gorry

---

From: "[email-masked]" <[email-masked]>
Date: Mon, 20 Sep 2021 10:21:42 -0700

Hi, Mike,

Notes below…

Joe

—
Joe Touch, temporal epistemologist
www.strayalpha.com

> On Sep 19, 2021, at 2:10 PM, C. M. Heard <[email-masked]> wrote:
> 
> I would like to offer some comments on the UDP TIME Option with the intent of improving its description in the next iteration of the draft. I will put my comments in-line with the text from the -13 draft.
> 
> That last requirement above (to always set TSVAL based on the local "time" value) assumes that the usage is bidirectional and symmetric, as in TCP.
> 
> Question: why does a receiver which just wants to echo the timestamp need to set a TSVAL (or implement a local time counter) if it has no requirement to measure RTT?  In contrast to TCP, we don't (in general) have a bidirectional acknowledged transfer of messages in UDP. One plausible use case would be a PLPMTUD probe packet exchange, as in:
> 
> Probe (empty user data, REQ(nonce), TIME(TSval=time, 0), PADDED_LENGTH = probe size, DONT_FRAG ) =>
> 
> TIME is not strictly needed in this instance, since the sender can cache the sent time value for each outstanding nonce. But it can be convenient.
> 
> But the two paragraphs above imply under-the-hood machinery that UDP does not provide and that has not been specified.

Agreed.

> IMO what should be said is that the application may make an RTT estimate and use it for the above purposes.

Agreed.

> I would say instead: A request is defined as "TSVAL != 0" and a reply is defined as "TSecr != 0."

OK.

> That last sentence is a bit cryptic; I presume that it means to treat TSVal / TSecr as the 32-bit LSBs of a 64-bit number and maintain rollover counters.

Yes.

> That's probably not necessary with reasonable "time tick" values.

And that can be noted as well.

> But there is another subtlety to consider, and that is that if the value 0 is reserved to mean "no value" then we really need to treat the time stamps as 1s complement numbers (modulo 2^32-1) and not 2s complement numbers (modulo 2^32) -- in other words, use end-around carry as in the Internet checksum when incrementing the timestamp counter and when taking the difference if two timestamps.

Ones complement kills half the range (as negative); it’s sufficient to just say “don’t use zero”, i.e, to hop over that value if it ever occurs.

> Note that TCP timestamps do not have this issue; per RFC 7323, TSVal is always required (since the option is present in every segment) and TSecr is valid only when the ACK bit is set. RFC 7323 RECOMMENDS that TSecr be set to zero when not used, but zero is not a reserved value. UDP has no ACK bit and so cannot use that expedient.
> 
> There is also the issue of whether this option can appear as a per-fragment option, as well as a per-datagram option, and if so, what that means. If I correctly understood the discussion in https://mailarchive.ietf.org/arch/msg/tsvwg/fqWaOvS1faNDyz7STaQOUc_lRzc/ <https://mailarchive.ietf.org/arch/msg/tsvwg/fqWaOvS1faNDyz7STaQOUc_lRzc/> (and related messages in that thread), options are passed between UDP and the upper/application later on a per-datagram basis, and to me, how this would work if TIME is a per-datagram option is quite clear. But previous discussions on this matter (see https://mailarchive.ietf.org/arch/msg/tsvwg/cwb6WVYWnTSb089viLjSW59nlXM/ <https://mailarchive.ietf.org/arch/msg/tsvwg/cwb6WVYWnTSb089viLjSW59nlXM/> and follow up messages) did not come to any kind of consensus:
> 
> If TIME can be requested by the upper layer, what is the meaning if the option is requested for a datagram that gets split into multiple fragments, and the option is replicated in every fragment? I can see the per-fragment argument but only when the option is produced and consumed at the UDP layer -- as is the case for the corresponding TCP option (which appears on every segment if it is negotiated). If it's intended to be produced and consumed by the higher layer, it should be per-datagram.
> 
> Time for fragmented packets can be a sequence of values or (depending on whether the API might support this) a range (high/low). That information can be useful to the higher layer in setting parameters of UDP, e.g., how long to keep fragments before discard. Or it could be used within the UDP layer for that sort of tuning automatically.

I should have said “as a sequence of values or (depending on whether an extended API might support this), a range (high/low) [or other representation, e.g., avg/variability]….

By “extended API”, I mean that the API can evolve, e.g., there may be a shim somewhere (in the OS or another layer) that performs range extraction or averaging.

> I do not think we want vague statements like "can be a sequence of values or (depending on whether the API might support this) a range (high/low)." The services offered by UDP to the upper layer interface should be well-defined, in order to promote interoperability. Making this option per-datagram only seems to me to be the best way to accomplish that objective. But a clear explanation of what would happen if TIME is set on a per-fragment basis could also achieve that objective.

We don’t need to force this option as per-datagram. If someone wants to use it that way, they set it as such. If they want per-fragment, then they just get a list back.

Joe

---

From: "C. M. Heard" <[email-masked]>
Date: Mon, 20 Sep 2021 13:16:29 -0700

On Mon, Sep 20, 2021 at 10:21 AM Joe Touch wrote:

> Ones complement kills half the range (as negative); it’s sufficient to
> just say “don’t use zero”, i.e, to hop over that value if it ever occurs.
>

Actually ones complement can be interpreted as signed or unsigned. Skipping
over zero is precisely what the end-around carry accomplishes.

We don’t need to force this option as per-datagram. If someone wants to use
> it that way, they set it as such. If they want per-fragment, then they just
> get a list back.
>

I'm with Gorry on this one. Implementations of the UDP TIME option should
not be required to respond to TIME requests received in fragments, nor
should they be required to process TIME responses received in fragments,
nor to transmit either one in fragments. Support for the per-datagram
behaviour is enough to accomplish the basic objective of measuring RTT, and
that's all that the specification should spend the words to describe.

Mike

---

From: "[email-masked]" <[email-masked]>
Date: Mon, 20 Sep 2021 17:05:13 -0700

—

> On Sep 20, 2021, at 1:16 PM, C. M. Heard <[email-masked]> wrote:
> 
> Actually ones complement can be interpreted as signed or unsigned

One’s complement and two’s complement are definitions based only on how negative numbers are interpreted.

Take away the negative numbers (unsigned) and there’s no “complement” anymore.

> . Skipping over zero is precisely what the end-around carry accomplishes.

Time isn’t always implemented as a hardware counter; if it is, it’s often twos-complement where the end-around carry is just a second carry-add step.

> I'm with Gorry on this one. Implementations of the UDP TIME option should not be required to respond to TIME requests received in fragments, nor should they be required to process TIME responses received in fragments, nor to transmit either one in fragments. Support for the per-datagram behaviour is enough to accomplish the basic objective of measuring RTT, and that's all that the specification should spend the words to describe.

I didn’t get that from anything Gorry wrote; he agreed with your last paragraph, that appeared to want to avoid RTT as a UDP service - not that per-fragment would never be useful. It might just not be useful to his PLPMTUD.

It can still be useful when evaluating the ‘spread’ of fragments by a network, e.g., as a fragment-level packet-pair mechanism.

Again, unless something is inherently undefined, I see no reason to prohibit it. In this case, it would simply be that a frag-level TIME option would have all the values passed up with the reassembled datagram, for whatever purpose the user wanted.

Joe

---

From: "C. M. Heard" <[email-masked]>
Date: Mon, 20 Sep 2021 18:07:20 -0700

On Mon, Sep 20, 2021 at 5:05 PM [email-masked] <[email-masked]>
wrote:

> > Skipping over zero is precisely what the end-around carry accomplishes.
>
>
> Time isn’t always implemented as a hardware counter; if it is, it’s often
> twos-complement where the end-around carry is just a second carry-add step.
>

It is well-known how to do that in software; see any detailed description
of how to compute the Internet checksum, or look at some code.

> We don’t need to force this option as per-datagram. If someone wants to
>> use it that way, they set it as such. If they want per-fragment, then they
>> just get a list back.
>>
>
> I didn’t get that from anything Gorry wrote; he agreed with your last
> paragraph, that appeared to want to avoid RTT as a UDP service - not that
> per-fragment would never be useful. It might just not be useful to his
> PLPMTUD.
>
> It can still be useful when evaluating the ‘spread’ of fragments by a
> network, e.g., as a fragment-level packet-pair mechanism.
>
> Again, unless something is inherently undefined, I see no reason to
> prohibit it. In this case, it would simply be that a frag-level TIME option
> would have all the values passed up with the reassembled datagram, for
> whatever purpose the user wanted.
>
> Again, unless something is inherently undefined, I see no reason to
> prohibit it. In this case, it would simply be that a frag-level TIME option
> would have all the values passed up with the reassembled datagram, for
> whatever purpose the user wanted.
>

I said  "The services offered by UDP to the upper layer interface should be
well-defined, in order to promote interoperability." Gorry (I think)
seconded this and added that per-datagram was enough to meet the needs, and
that we should not put more into the document. If you want to offer
per-fragment services (of any kind, for any option) the service interface
needs to be fully spelled out, at a minimum. That requires WG resources to
review and verify. Full standardization will require multiple interoperable
implementations. IMO that's actually a pretty heavy lift (though I suppose
that your mileage may vary).

Do you actually have a use case for the above per-fragment TIME proposal?
Or is it purely "it might be useful, so let's throw it in?"

Mike

---

From: "[email-masked]" <[email-masked]>
Date: Mon, 20 Sep 2021 19:24:53 -0700

—

> On Sep 20, 2021, at 6:07 PM, C. M. Heard <[email-masked]> wrote:
> 
> On Mon, Sep 20, 2021 at 5:05 PM [email-masked] <mailto:[email-masked]> <[email-masked] <mailto:[email-masked]>> wrote:
> It is well-known how to do that in software; see any detailed description of how to compute the Internet checksum, or look at some code.

I don’t disagree, but don’t think we should specify how the counter is implemented. All we need to say is “don’t use zero”.

> I said  "The services offered by UDP to the upper layer interface should be well-defined, in order to promote interoperability."

Agreed, but you also said "But a clear explanation of what would happen if TIME is set on a per-fragment basis could also achieve that objective.”

I gave the explanation.

> Gorry (I think) seconded this

He can clarify as needed.

> and added that per-datagram was enough to meet the needs,

His needs, yes.

> and that we should not put more into the document.

I read that as “don’t put in RTT calculation”, not “prohibit this option for fragments”. In fact, putting in that prohibition would be the “more” I don’t want to add.

AFAICT, *all* options should be “use at your own risk” and passed to the recipient for their decision (though an OS can cache that behavior if needed per socket pair).

> If you want to offer per-fragment services (of any kind, for any option) the service interface needs to be fully spelled out, at a minimum.

Every option is defined for both cases, except where it is very obviously a bad idea or meaningless (e.g., MRSS, if it varies per fragment).

> That requires WG resources to review and verify. Full standardization will require multiple interoperable implementations. IMO that's actually a pretty heavy lift (though I suppose that your mileage may vary).

It also takes resources to determine whether a given option should be prohibited for either case. Either one takes resources - not clear there’s a resource minimization there, but we’re not int he business of optimizing WG time here.

> Do you actually have a use case for the above per-fragment TIME proposal? Or is it purely "it might be useful, so let's throw it in?”

I already stated one - packet-pair, i.e., using the dispersion of packets in time as a path metric.

Joe

---

From: "C. M. Heard" <[email-masked]>
Date: Tue, 21 Sep 2021 00:46:04 -0700

On Mon, Sep 20, 2021 at 7:25 PM Joe Touch wrote:

> I don’t disagree, but don’t think we should specify how the counter is
> implemented. All we need to say is “don’t use zero”.
>

Agreed, that is sufficient.

Back to the per-datagram vs per-fragment issue:

> I said  "The services offered by UDP to the upper layer interface should
> be well-defined, in order to promote interoperability."
>
>
> Agreed, but you also said "But a clear explanation of what would happen
> if TIME is set on a per-fragment basis could also achieve that objective.”
>
> I gave the explanation.
>

Here I do not agree.

As I said at the beginning of this thread, I understood the specification to
say that the production and consumption of timestamp values is in the hands
of the application -- that is, that the application, not UDP, provides the
TSval and the TSecr to be sent in a particular datagram. That seemed
reasonable, for based on this text from the draft:

the application must have access to  on the local "time" value from which
TSval is set in order to use a received TSecr value to compute RTT. So,
based on that and the previous discussion that the upper layer interface
(ULI) is per-datagram, I assumed that the application would provide the
TSval for an outgoing datagram. This clearly works fine for a per-datagram
option. But it does not work for a per-fragment option, because it leaves
no basis for UDP to put a different TSval on each fragment.

In order to measure dispersion of arrival times using a per-fragment
version of TIME, UDP (not the application) would have to insert the TSVal
when a fragment is sent and would have to record the the local "time" value
when a fragment arrives. In other words, the measurements would have to be
done via under-the-hood machinery, not by the application (unless we
provide the upper layer with a high degree of visibility into fragments,
which I don't think we want to do).

If there is an expectation that the UDP TIME option will provide such
under-the-hood machinery, that needs to be spelled out, as do the knobs
that the ULI provides control the machinery and the information that the is
provided to the application.

Mike

---

From: "[email-masked]" <[email-masked]>
Date: Tue, 21 Sep 2021 12:04:18 -0700

Hi, Mike, 

See below..
—

> On Sep 21, 2021, at 12:46 AM, C. M. Heard <[email-masked]> wrote:
> 
>> On Sep 20, 2021, at 6:07 PM, C. M. Heard <[email-masked] <mailto:[email-masked]>> wrote:
>> 
> As I said at the beginning of this thread, I understood the specification to say that the production and consumption of timestamp values is in the hands of the application -- that is, that the application, not UDP, provides the TSval and the TSecr to be sent in a particular datagram. That seemed reasonable, for based on this text from the draft:
> 

The text says *received* values are provide to the application, not that the application sets the values on transmit.

> the application must have access to  on the local "time" value from which TSval is set in order to use a received TSecr value to compute RTT. So, based on that and the previous discussion that the upper layer interface (ULI) is per-datagram, I assumed that the application would provide the TSval for an outgoing datagram. This clearly works fine for a per-datagram option. But it does not work for a per-fragment option, because it leaves no basis for UDP to put a different TSval on each fragment. 

	"On transmitted segments using
	   the option, TS Value is always set based on the local "time" value.”

I should have been more clear - I was assuming that could happen at the UDP layer. 

However, as per the info on the received segments above, users can pass TSecr to UDP for outbound segments. For fragments, a single TSecr would be repeated in each fragment, but TSval would be set by the local clock inside UDP.

> In order to measure dispersion of arrival times using a per-fragment version of TIME, UDP (not the application) would have to insert the TSVal when a fragment is sent and would have to record the the local "time" value when a fragment arrives

Yes.

> . In other words, the measurements would have to be done via under-the-hood machinery, not by the application (unless we provide the upper layer with a high degree of visibility into fragments, which I don't think we want to do).

Measurements - i.e., computing RTT or delay - happens above UDP (in the user layer or could occur in shim software). 

> If there is an expectation that the UDP TIME option will provide such under-the-hood machinery, that needs to be spelled out, as do the knobs that the ULI provides control the machinery and the information that the is provided to the application.
> 
> Mike