Draft: draft-ietf-quic-transport

Commentary: Problem statement : At the moment , the draft states that ack delay is a variable - length integer representing the time delta in microseconds between when the ACK frame was sent and when the largest acknowledged packet was received by this peer . ( ) . I think that the definition is incorrect . Consider the case of a slow endpoint that needs to spend 10ms for processing one packet . When the true RTT of the network is 50ms , the RTT estimate of the peer would become 50ms , as latestrtt would be 60ms and by this definition , the slow endpoint would report an ackdelay of 10ms . This estimate of 50ms is too aggressive , as the peer can not expect to see an ACK before 60ms . IIUC , we have thought that the issue is negligible as we have a mechanism using minrtt , for detecting and ignoring excessive ackdelay values being reported . But , as stated in , I am becoming skeptical if that defense works well when the path is being utilized , as the true RTT when the path is congested tends to be greater than when the path is not congested , and because minrtt would normally reflect the value of the latter . In case of the example above , the defense does not work if the non - congested RTT of that path was 25ms and if minrtt reflected that value . Solution : The definition of ack delay should be changed to : the amount of time an endpoint withheld an ack from the moment when it would have sent an immediate ack . 
 This came up in and the resolution was along the lines of what you 're describing , so I think this is a matter of clarifying the text . 
 Thank you for pointing that out . So glad to know that this is an editorial problem . 
 From So I think the text is there , but maybe a reference to this section from section 19.3 and some editorial cleanup would help . 
 We 've had a long standing requirement that stream ( see Section 3.2.1 ) by each peer By the way I interpret this , I put a check in my implementation that does n't permit any frame until SETTINGS is received . Am I interpreting things correctly ? It would be more consistent to allow reserved frame types to appear at any point on any stream that carries frames . However , I 'm fine with this requirement as is but it means there is a little more effort needed to handle reserved frame types across streams . 
 In our implementation we are interpreting this in the same way : any frame on the control stream received before SETTINGS is a connection error . Even reserved frame types . In general the way we handle this is by discarding frame types that are forbidden rather than checking frame types that are allowed on each stream . Here is a snippet from our code . In this way we avoid the extra effort needed to handle reserved frame types that you mentioned , if I am reading your statement correctly . Basically , some frame types are explicitly disallowed . All other frame types are equal , reserved or non - reserved . Do you foresee an extension possibly benefiting from sending a frame before settings ? 
 Thanks you made me realise I asked the question wrong . This is about reserved and non - core frames . Section 7 says : extensible protocol elements . Implementations MUST discard frames ... I have no strong use case for delivering frames before SETTINGS . But I worry it falls into a slight grey area that might affect interop . I think the correct answer is that the control stream is special case and we should clarify that in Section 7 . 
 My preference goes to retaining the requirement as - is . This is the way H2 has worked , and I am not sure if there is a practical reason to change . FWIW , we have a similar requirement for PRIORITY frame too , which I 'm also fine with : A PRIORITY frame received after other frames on a request stream MUST be treated as a connection error of type HTTPUNEXPECTEDFRAME ( ) . 
 Ooh yeah , that 's a good catch too . Table 1 in section 4 seems to actually highlight this behaviour with the notation . And we sort of have some text that captures this in section 4 : We could add tweaks or further guidance to this paragraph ( in a PR that also that makes things explicitly clear . 
 On receipt , reserved is irrelevant -- it 's just an unknown frame type . The reservation is simply to permit senders to generate unknown frame types without accidental collision to a real extension the client might support . So the question is whether " ignoring " unknown frame types means pretending that they were n't even there , and therefore the subsequent frame might still be the first frame on the stream . I 'm inclined to say no -- you take no action on a frame you do n't recognize , but that does n't mean that the next frame was the first frame . 
 Thanks a lot ! LGTM.Nit : larger and lower imply a comparison . Otherwise , LGTM .
Paragraph (version B):
Since the acknowledgement delay is not used for Initial and Handshake
packets, the ACK Delay field in acknowledgements for those packet
types SHOULD be set to 0.
Paragraph (version A):
A variable-length integer representing the time delta in
microseconds between when the largest acknowledged packet, as
indicated in the Largest Acknowledged field, was received and the
ACK frame was sent.  The ACK Delay field carries this encoded time
difference.  It is decoded by multiplying the value in the ACK
Delay field by 2 to the power of the value of the
ack_delay_exponent transport parameter set by the sender of the
ACK frame; see transport-parameter-definitions.  Scaling in this
fashion allows for a larger range of values with a shorter
encoding at the cost of lower resolution.  Because the receiver
doesn't use the value in the ACK Delay field of Initial and
Handshake packets, a sender SHOULD send a value of 0.
Paragraph (version B):
A variable-length integer encoding the acknowledgement delay in
microseconds; see host-delay.  It is decoded by multiplying the
value in the field by 2 to the power of the ack_delay_exponent
transport parameter sent by the sender of the ACK frame; see
transport-parameter-definitions.  Compared to simply expressing
the delay as an integer, this encoding allows for a larger range
of values within the same number of bytes, at the cost of lower
resolution.