Draft: draft-ietf-quic-transport

Commentary: This avoids " no smaller than " , unqualified " total increase " , and other such ambiguities . However , in doing this , I realized that I might interpret the original language as allowing a network to ADD markings . That seems wrong . But it 's a non - editorial change . This version has that change . I 'll make another PR with the hole left in place in case I 'm wrong . 
 OK , I realize now my mistake . The draft allows for an increase because of the possibility of ACK loss . Counts might increase more than there are newly acknowledged packets because an endpoint might not receive an ACK for every packet that is accounted for in the increased count . I think that 's worth a note . Though now I 'm concerned about the third clause , which does n't include any protection against this problem . I 'll open an issue for that . 
 Sorry to ask for another review , but I had a few misfires yesterday ( apparently ) . I think that this structure is much better . I have removed the check that uses the sum of ECT0+ECT1+CE . Any check on ECT0+CE or ECT1+CE is more precise anyway . The sum is only able to detect double - counting of CE - marked packets , but as the check is an inequality , we would allow what to happen . ( That was what motivated my proposed additional check , but I agree that is not worth documenting . ) 
 QUIC does n't guarantee that every received packet will be acknowledged . At the same time , ECN validation uses counts of every received packet . The net effect of this is captured in this statement : -- For example , if a sender sends 10 ECT - marked packets and all of them arrive , they might only receive acknowledgments for 8 of these . The receiver will still report an increase of 10 for the corresponding markings . The sender compensates for this error by allowing this deviation and using the new reference number for future packets . Note that validation also depends on the receiver counting but not acknowledging a packet , then later changing its mind and acknowledging the packet . We do n't state this , but we should n't have to . But that allowance only applies to the validation performed on the sum of ECT(0 ) , ECT(1 ) and ECN - CE counts . The validation for cross - marking of ECT(0 ) to ECT(1 ) or vice versa does not include this same protection . Thus , failure to acknowledge a packet will probably result in ECN validation failing . There are a few ways we might fix this . We could just allow for an increase here too . The net effect though is that we do n't get to watch for cross - marking . We do n't get any protection against cross marking like this . In other words , we can remove the check . It might be better to limit the allowed increase by the total excess in the total . That is , if then the check is and . The combined check becomes . That is , increases to ECT(X ) + CE above what was newly acknowledged has to be represented in the total unaccounted value . If all unaccounted packets were CE marked , then they will be unaccounted for twice in the individual counts . If none of the unaccounted packets were CE marked , then they will be counted just once . That suggests the following text for the third check : This third check is now more precise than the second check , so I would suggest removing the combined check that we have current as step 2 . A new combined check might detect remarking between ECT(0 ) and ECT(1 ): And finally , because most stacks only apply one type of marking : 
 I 'm not convinced this needs fixing . To your point above : It is an exceedingly rare corner case , since this requires an ACK for a packet to not be sent or received , and then for there to be cross - marking within that fraction of connections . And in this case , ECN validation fails and is turned off . We knew corner cases existed , but we also had the escape hatch of turning off ECN when things were not " quite right " . Why is that answer not good enough any more ? ( Or am I missing something ? ) 
 The problem is that we fixed this in one place , but not another . And we explicitly call out the need for the fix . The goal of validation was - by my understanding - finding obvious mistakes . But this creates false positives . If we want to do something minimal , then I would suggest that we simplify . That is , reduce the checks to or . 
 That 's how I read the third validation check : but I agree it 's not very clear . I think the intent was to do the minimal version you suggest above ( which is why it 's " either " instead of " both " in the text ) . I would be happy with us clarifying the text to say that more clearly . 
 Before this gets stuck . I 'm abandoning this . 
 So , I am finally implementing this , and have questions . Section 13.4.2.2 says : What is meant by " total increase " here ? I guess it is a delta , but against what ? Against the values in the last received ACK frame ? Against the " local reference counts " ( which are n't really described well either , see below ) ? Or something else ? Also , I guess the " total increase " compared here is a sum of these individual deltas ? Again , " increase " relative to what ? Same question about " total increase " . And what are the " local reference counts " , and how are they maintained ? 
 You are supposed to keep three counters for the number of each ECT(0 ) and ECT(1 ) and CE marks reported so far on this connection ( for this ack space ) . Increase means the difference of the count reported in the latest ACK compared to the current local counter value . Total increase is increase of ECT(0)+increase of ECT(1)+increase if CE compared to local current count of ECT(0)+ECT(1)+CE . Does that help ? 
 It does , thanks . It would probably be useful to introduce those local reference counts before the bullet list , describe how they are maintained , and then use them when describing how to validate . 
 Yes . Will try to propose a PR . Thanks for implementing ! 
 Actually , this does n't make sense to me : The increase is the value in the current ACK frame minus the current local reference value . A sum of those increases is always going to be less than the sum of the total reference values ? 
 Yes , sorry , in the text you do n't compare the total increase to the local value of course . You compare the total increase to the number of packets acknowledged in an ACK frame 
 and then you also compare the increase of ECT(0)+increase in CE to number of packet sent with ECT(0 ) from the newly acknowledge packets , and same for ETC(1 ) . So you need to remember which packet was sent with which ECN codepoint if not all packets are send with the same codepoint . 
 So let me tell you what my code is doing now to verify incoming ACK - ECNs , and then you tell me if this is correct : I maintain ECN reference counter vectors ( ) per packet number space . These hold the last counts received in an ACK - ECN from the peer . I count new ACKs for ECN - marked packets that I sent in a vector . ( I only send ECNECT0 packets though , so this is n't really a vector , just a variable . ) When I receive a new ACK - ECN with ECN counts ( ) , I compute the vector as . I then do the verification per Section 13.4.2.2 : ( First bullet in 13.4.2.2 is easy , omitted here ) Second bullet in 13.4.2.2 : = verification failed Third bullet in 13.4.2.2 : = verification failed . ( Since I only send ECNECT0 , I can omit looking at ECNECT1 , I believe . ) If verification succeeds , I assign . If it fails , I stop sending ECNECT0 marked packets , and I stop trying to verify any future ACK - ECN information . 
 ping ? 
 Sorry , long weekend in Germany . Yep this sounds right . If you only have ECT(0 ) , you can simplify test 2 to just do what you do in 3 ( ' ecninc[ECNECT0 ] + ecncnt[ECNCE ] < newack[ECNECT0 ] ' ) and for test 3 you just need to check if there are any ECT(1 ) marking at all and fail if you ever get feedback that ECT(1 ) was observed . 
 Maybe use < = rather than < though . 
 I 'm not sure that 's correct ? 
 Oh yes , did n't see that . I also think it should be < = . why do think it should be < ? 
 Because if the number of marked packets in the ACK is = = the number of marked packets I sent , that is not a verification failure ? ( Or am I misunderstanding something ? ) 
 Right ... I got confused that the condition is about moving into failure mode . So usually the numbers should always be exactly equal ; only if some marked packets get not ack'ed at all the received count could be larger than the number of marked sent and ack'ed packet . I guess , if you know that this is not the case you could be even stricter . Otherwise if there are no unack'ed packets and the received count would be larger , it would mean you have some remarking from Not - ECT to ECT or CE . That less a problem in terms of hiding congestion but might still indicate that something is wrong ... however , given that you mark all packet in your implementation with ECT(0 ) that case should not happen . 
 And as noted the primary failure mode where increase of reference counter can be larger than newely ACKed packets is lost ACKs . Section 13.4.1 is clear on that duplicate packets shall be surpressed prior to increasing the relevant ECN counter .
Paragraph (version B):
Erroneous application of ECN marks in the network can result in
degraded connection performance.  An endpoint that receives an ACK
frame with ECN counts therefore validates the counts before using
them.  It performs this validation by comparing newly received counts
against those from the last successfully processed ACK frame.  Any
increase in ECN counts is validated based on the markings that were
applied to packets that are newly acknowledged in the ACK frame.
Paragraph (version B):
If an ACK frame newly acknowledges a packet that the endpoint sent
with either ECT(0) or ECT(1) codepoints set, ECN validation fails if
ECN counts are not present in the ACK frame.  This check detects a
network element that zeroes out ECN bits or a peer that is unable to
access ECN markings.
Paragraph (version B):
ECN validation fails if the sum of the increase in ECT(0) and ECN-CE
counts is less than the number of newly acknowledged packets that
were originally sent with an ECT(0) marking.  Similarly, ECN
validation fails if the sum of the increases to ECT(1) and ECN-CE
counts is less than the number of newly acknowledged packets sent
with an ECT(1) marking.  These checks can detect removal of ECN
markings in the network.
Paragraph (version B):
An endpoint could miss acknowledgements for a packet when ACK frames
are lost.  It is therefore possible for the total increase in ECT(0),
ECT(1), and ECN-CE counts to be greater than the number of packets
acknowledged in an ACK frame.  This is why counts are permitted to be
larger than might be accounted for by newly acknowledged packets.
Paragraph (version B):
ECN validation MAY fail if the total count for an ECT(0) or ECT(1)
marking exceeds the total number of packets sent with the
corresponding marking.  In particular, an endpoint that never applies
a particular marking can fail validation when a non-zero count for
the corresponding marking is received.  This check can detect when
packets are marked ECT(0) or ECT(1) in the network.
Paragraph (version B):
Processing ECN counts out of order can result in validation failure.
An endpoint SHOULD skip ECN validation on an ACK frame that does not
increase the largest acknowledged packet number.