Subject: Re: [quicwg/base-drafts] Retire My Own CID (#2645)

From: Mike Bishop <[email-masked]>
Date: Tue, 04 Jun 2019 11:09:31 -0700

I think I prefer the semantics of retiring everything up to a stated offset.  That avoids messing with sequence numbers of sequence numbers, which just seems cleaner.  The field needn't be always present; the value can only advance, so if you've ever seen a value, you need to retire everything below that value.

Corner case to consider:  What if I've received CIDs 1,2,3,5,8 and I get a `RetirePriorTo`=7?  Do I need to retire 4 and 6 that haven't arrived yet, or do I need to retire them upon receipt?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-498781802

---

From: ianswett <[email-masked]>
Date: Tue, 04 Jun 2019 12:03:17 -0700

@MikeBishop I think you need to retire 4 and 6 immediately.

Overall, I think this proposal is nice.  At the cost of a single varint, we achieve clearer connection ID management semantics and the ability to retire CIDs proactively.  I can see this being pretty useful.

One note is that this means a client really has to support changing CIDs, whereas at the moment a client could support it during the handshake and never again.  I don't think that's overly onerous, but it's worth pointing out and may be a pro or a con depending upon one's perspective.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-498801192

---

From: Nick Banks <[email-masked]>
Date: Tue, 04 Jun 2019 12:09:57 -0700

I agree with @ianswett that you need to retire everything (and practically, remember the limit in case you get a heavily reordered packet offering the old one later).

If folks are happy with this design, I can write up a PR.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-498803523

---

From: Eric Kinnear <[email-masked]>
Date: Wed, 05 Jun 2019 17:21:19 +0000 (UTC)

Thanks for writing up #2769 @nibanks! 
I think either of the following two approaches could be a good path forward (discussing here rather than on the PR): 

1. The current PR, each new connection ID comes with a "retire CIDs before sequence number X", which keeps us from having issues around holes in the set of valid sequence numbers for a CID. 
This is kind of nice, because we can be a little looser with how we handle being at the max number of CIDs and needing to send some more/add new ones. 

Example: 
I want to retire all the CIDs that are outstanding. I've issued 1, 2, 3, 4 in NCID frames and we've got the handshake at 0. I send a single packet with: 
```
NCID(retireBefore: 1, CID: 5)
NCID(retireBefore: 2, CID: 6)
NCID(retireBefore: 3, CID: 7)
NCID(retireBefore: 4, CID: 8)
NCID(retireBefore: 5, CID: 9)
```
Note that sending `retireBefore: 5` for all could be specified as valid or invalid, although if valid it doesn't really help with requiring replacement. We'd also then want to consider writing a bunch of other somewhat messy text to require retiring them in order from oldest to newest, which seems somewhat icky.

2. A new frame for just the retire side, called something like `PLEASE_RETIRE_CONNECTION_ID`. 
- This would be a request, and an endpoint receiving it SHOULD retire immediately, along with a warning that the other endpoint may choose to close the connection if it doesn't. 
- The endpoint also SHOULD move to a new CID if the one it's currently using is requested to be retired.
- It's probably worth being a little bit careful about how strongly we make not moving a protocol violation, because it seems like it wouldn't be too difficult for an endpoint whose peer had to migrate off the one it was currently using to end up receiving packets from the old CID for a good while/draining period.

If we do (2), in order to have the guarantee that they're replaced, we should just include that all `PLEASE_RETIRE_CONNECTION_ID` frames MUST also be accompanied by a `NEW_CONNECTION_ID` frame, and have the receiver close the connection if that's not the case. (Timing/[not] keeping things in the same packet strikes me as a part of the text here that needs to be written carefully.)

Same example from above: 
```
PRCID(retireAllBefore: 5)
NCID(5)
NCID(6)
NCID(7)
NCID(8)
NCID(9) 
```

In my mind, the common text between both approaches is: 
- The endpoint being asked to retire CIDs SHOULD retire them immediately, and move to a new CID if necessary. If not, the other end MAY close the connection (plus note about not being *too* aggressive here to handle draining).
- The endpoint asking to retire them MUST replace them. If not, the other end closes.
- How we handle "bad" sequence numbers being sent (too low, also a little weird to send a number higher than the peer's limit away from what's active).
- How you handle when you're at the max specified by the peer's limit
- Any preferred address and handshake CIDs should probably explicitly be called out as affected, although they do have sequence numbers
- If someone requests to retire CIDs that you haven't seen yet, you respond to `NEW_CONNECTION_ID` frames containing them by immediately retiring them. This doesn't add too much state since you just need to keep a single counter of the highest invalid/lowest valid sequence number.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-499176700

---

From: MikkelFJ <[email-masked]>
Date: Wed, 05 Jun 2019 10:26:02 -0700

I don’t think we should have dependencies on other frames, then I’d rather
have a single frame. It would mess up retransmission logic etc.

On 5 June 2019 at 19.21.11, Eric Kinnear ([email-masked]) wrote:

If we do (2), in order to have the guarantee that they're replaced, we
should just include that allPLEASE_RETIRE_CONNECTION_ID frames MUST also be
accompanied by a NEW_CONNECTION_ID frame, and have the receiver close the
connection if that's not the case. (Timing/[not] keeping things in the same
packet strikes me as a part of the text here that needs to be written
carefully.)

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-499178469

---

From: Nick Banks <[email-masked]>
Date: Wed, 05 Jun 2019 10:32:44 -0700

@erickinnear why couldn't we make it a "MUST immediately retire" instead of a SHOULD? What reasons would an endpoint have to ACK the packets but not retire the CIDs at the same time?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-499180920

---

From: David Schinazi <[email-masked]>
Date: Thu, 06 Jun 2019 05:20:16 -0700

@nibanks in some implementations the ACK logic is not next to the connection ID management logic. For some of these implementations it would be very hard to ensure that the ACK isn't sent with the CID you'd like to retire. "MUST immediately retire" would add significant complexity to those implementations for very limited benefit.

Also, having the use of a CID you've asked to retire trigger a protocol violation is a security risk. It allows an attacker to close the connection by delaying a valid packet.

I like the idea of adding a `Retire Prior To` field in NEW_CONNECTION_ID frames, but we should make it advisory and not mandatory. Sending it tells the peer that if they keep sending with this CID packets might not get through at some point. But I don't think we should have MUSTs, immediatelys or protocol violations involved.

Is there any reason that wouldn't  serve the needs of your use case?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-499470589

---

From: MikkelFJ <[email-masked]>
Date: Thu, 06 Jun 2019 05:51:36 -0700

I argued about the same as @DavidSchinazi in the associated PR.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-499480143

---

From: Nick Banks <[email-masked]>
Date: Thu, 06 Jun 2019 06:22:50 -0700

I'm going to try to answer all the comments/questions from both the Issue and the PR here, so as to not clutter up the PR.

It now seems that most people actually prefer the immediate switch of the CIDs instead of allowing for delay. I agree key update is a good example / pattern to follow here. You get a packet with the NEW_CONNECTION_ID frame to replace existing CIDs, you locally update all CIDs and then you mark the packet for ACK. 

@DavidSchinazi I understand that some implementations might have extra difficulties, but I'm not sure why it would be that much different from key update. Additionally, you only ACK a packet after it has been fully processed, so if you process the NEW_CONNECTION_ID frame before the "packet fully processed state" and update CIDs there, then there shouldn't be an order of operations problem.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-499491414

---

From: Eric Kinnear <[email-masked]>
Date: Thu, 06 Jun 2019 14:02:13 -0700

As @DavidSchinazi said: 
> Sending it tells the peer that if they keep sending with this CID packets might not get through at some point.

Previously this had been proposed as a way to think about it, and I think it's probably the right balance to strike. You don't work to hurt the client if they don't switch right away, they may have reasons for a slight delay there. A client knows that the request from the other side serves as fair warning that the CID may not work indefinitely. 

It's still up to the client to use RETIRE_CONNECTION_ID and all of the draining logic there still applies -- we don't need to reinvent additional signals for that.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-499666254

---

From: Mike Bishop <[email-masked]>
Date: Fri, 07 Jun 2019 09:23:13 -0700

Immediate is a little strong.  There are valid implementation reasons that an "immediate" switch might not be possible -- or at least impossible to guarantee.  The immediacy guarantees are that when the implementation sends RETIRE, it has completed whatever is needed to ensure everything is done.  An ACK doesn't logically carry the same guarantees -- it just guarantees that the consumer knows about the request.

It can be mandatory for the client to retire the CID, enforced by permitting the issuer to kill the connection if it's not done soon enough, but mandatory *immediate* retirement probably doesn't work.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-499949749

---

From: Martin Thomson <[email-masked]>
Date: Mon, 10 Jun 2019 17:05:44 -0700

Just to pile on here.  If there is an implementation that is distributed, with multiple entities producing packets (which is entirely possible with some coordination), then retirement requests can take a little time to propagate.

I think that the ACK here should be taken to mean, as @MikeBishop says, I got your request, not coupled so tightly to compliance.

I don't believe that we have any other such things in the transport.  STOP_SENDING is perhaps the closest analogue, but that doesn't require that you send a RESET_STREAM in the packet that acknowledges the STOP_SENDING.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500636818

---

From: ianswett <[email-masked]>
Date: Mon, 10 Jun 2019 18:55:10 -0700

I don't have a strong opinion on this, but the new discard keys PR that landed has that shape: https://github.com/quicwg/base-drafts/pull/2673

Later packet numbers not using a given key is fairly similar to later packet numbers not using a given connection ID.  Enforcement seems comparably or slightly more difficult, so one could go with MUST retire/MAY close the connection.

@martinthomson Once you're talking about distributed peers, I think we're well in the space of multi-machine multipath?  Or is there some other use case you have in mind?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500655651

---

From: Eric Kinnear <[email-masked]>
Date: Mon, 10 Jun 2019 18:57:15 -0700

@ianswett I think this is a little bit different, since we have a mechanism to retire CIDs and it this is a request to use that mechanism, not an implicit retirement of the CID?
It seems like it would be fine to require that after a CID is retired that later packet numbers not use it (I think that's already a requirement?), but doing anything based on the ACK of the "please retire" message doesn't seem like the right path forward here.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500656014

---

From: Nick Banks <[email-masked]>
Date: Mon, 10 Jun 2019 19:27:44 -0700

@erickinnear we have strengthened the text, so that it's no longer a request, but a requirement that the peer retire the CID. I also agree with @ianswett that this is very similar to key update, and if an implementation can synchronize keys and packet numbers, I see no reason why CIDs and packet numbers also cannot be synchronized. Practically, for every packet you send, you pick a CID, a key and a packet number to use at about the same time.

The only scenario that I've heard that gives me some pause is if the peer is currently trying to probe on a new path when you are trying to force the CIDs to be retired. It _might_ be easier for the probing logic to continue using the CID it started the probe with. But I'm still not completely convinced. For one, what if that new path has a MUCH bigger RTT than the old one? That would make it a lot more likely it could hit the 3 PTO timer on the primary path. Also, I see no reason why you couldn't immediately switch the CID used for probing as well.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500662145

---

From: ianswett <[email-masked]>
Date: Mon, 10 Jun 2019 19:28:34 -0700

I'm fine with the "please retire" semantics, but wanted to point out an existing case in the QUIC specs we say you must retire something in a similar circumstance.  I hate timers, so I suspect my implementation will do that even if the spec doesn't require it, because I believe it's more straightforward to implement.

If you supply a CID with sequence number X and I've specified that I'm only going to store Y sequence numbers via active_connection_id_limit, can you assume the peer is unlikely/unwilling to use CIDs with sequence number < X-Y(modulo reordering).  That would be true for my implementation, but possibly it's also related to the 3RTO issue?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500662343

---

From: David Schinazi <[email-masked]>
Date: Tue, 11 Jun 2019 10:10:12 -0700

I don't think this is analogous to key updates. Due to the design of key updates, when you receive a packet with a new key phase, you need to install the new keys, otherwise you just can't decrypt it. The requirement to start sending using those new keys is not much of a stretch. Here, when you ask me to retire a CID, there's nothing I actually need to do to keep parsing packets. Asking the peer to retire a CID is closer to STOP_SENDING than it is to key updates.

That said, our implementation will probably retire the CID immediately, but I really do not want text in the spec about closing the connection after some timer, because that opens up new avenues for attack.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500937119

---

From: ianswett <[email-masked]>
Date: Tue, 11 Jun 2019 10:16:28 -0700

@DavidSchinazi what attacks did you have in mind?  Obviously, our implementation should not do that if we think it creates new attacks.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500939592

---

From: Nick Banks <[email-masked]>
Date: Tue, 11 Jun 2019 10:18:39 -0700

With the current text, we aren't explicitly closing the connection, but just implicitly retiring the CIDs after some time, if the peer doesn't do it themselves. So long as the new CIDs have different stateless reset tokens than the CIDs they replaced, I don't see any way for an attacker to cause the connection to be killed.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500940454

---

From: David Schinazi <[email-masked]>
Date: Tue, 11 Jun 2019 10:43:08 -0700

@ianswett Consider a MITM attacker that can intercept packets (prevent them from arriving now, and save them for replay later). Assume the server says "please retire CID X", the client switches from CID X to CID Y, and the attacker intercepts the last packet the client sent with CID X. Then the attacker waits 4 PTO and sends that packet to the server. If the server used the same reset token for both CID X and CID Y, then the server will send a stateless reset and the client will close the connection upon receiving it. There is no text in the spec today that says the server MUST pick different stateless reset tokens for different CIDs. Therefore, the ability to request to retire CIDs does open an avenue of attack similar to TCP RST.

If we want to have a safe mechanism to request retiring CIDs, then we have two solutions:
(1) we require the peer to retire the CID immediately
(2) we make this a best-effort request with no enforcement of actually retiring the CID

As discussed earlier, (1) is not practical. What does "immediately" mean when it takes time for packets to travel between endpoints? If it means send it on the same packet that carries the ACK, what happens when that packet gets lost? Do I need to send RETIRE_CID on every single packet in this window until one gets ACKed? I think this quickly because a mess full of corner-cases with security vulnerabilities at play, and I'm not confident we can get to the bottom of it rapidly.

Option (2) is similar to STOP_SENDING. It's a way of telling the peer that they should do something because what their sending won't do anything useful.

@nibanks I understand why you'd rather have (1) but I don't think the benefits you'll get from it outweigh the security risks. Even if we pick (2), I think everyone will implement this as retiring the CID either in their next outgoing packet or maybe at worst a couple packets later. And that gets you what you want without adding security risks.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500949711

---

From: Nick Banks <[email-masked]>
Date: Tue, 11 Jun 2019 10:50:05 -0700

@DavidSchinazi I agree with you. My question to you is: what in the current text do you not like? You mentioned before that you'd like me to remove the 3-PTO text. I'm not sure I can do that. If I remove that text, then how quickly is the endpoint requiring the retirement supposed to wait before just retiring the CIDs any ways? If you're saying it's never allowed to retire them anyways, then that's an attack vector by the peer, IMO.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500952339

---

From: MikkelFJ <[email-masked]>
Date: Tue, 11 Jun 2019 11:16:32 -0700

>  I remove that text, then how quickly is the endpoint requiring the retirement supposed to wait before just retiring the CIDs any ways?

You can start retiring when you receive RETIRE_CONNECTION_ID.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500962300

---

From: David Schinazi <[email-masked]>
Date: Tue, 11 Jun 2019 11:28:17 -0700

@nibanks I would phrase the text as:

```
An endpoint can request that its peer retire connection IDs by sending
a NEW_CONNECTION_ID frame with an increased Retire Prior To field.  
Upon receipt, the peer SHOULD retire the corresponding connection IDs
and send the corresponding RETIRE_CONNECTION_ID frame in a timely
manner.  Failing to do so can cause packets to be delayed or lost and
harm connection performance as the original endpoint might not route
those connection IDs optimally after some delay.

The sender of the Retire Prior To field MUST keep track of the connection
IDs it wishes to retire until it has received a corresponding
RETIRE_CONNECTION_ID frame.
```

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500966596

---

From: Nick Banks <[email-masked]>
Date: Tue, 11 Jun 2019 11:36:45 -0700

What if the peer never retires the CIDs? You're saying I'm never allowed to eventually drop the CIDs anyways? The way you have the text, the feature is optional, as long as you're willing to accept a possible performance hit.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500969821

---

From: ianswett <[email-masked]>
Date: Tue, 11 Jun 2019 11:39:04 -0700

I like STOP_SENDING as an analogy overall.   @nibanks I made a suggestion on the PR about what the client should do if it receives a stateless reset token for a retired connection ID.  I think that may both allows the sender to immediately retire and provides the peer some advice on what to do if it sees a reset that's associated with an old CID?

This approach basically allows the server to wait as long as they think is necessary, and if they really need to stop using the CID, they can send a stateless reset to force it.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500970677

---

From: MikkelFJ <[email-masked]>
Date: Tue, 11 Jun 2019 11:40:46 -0700

@nibanks That is the catch-22, but retiring them before receiving a retired frame is somewhat pointless. Closing the connection is a security hazard. 

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500971271

---

From: MikkelFJ <[email-masked]>
Date: Tue, 11 Jun 2019 11:41:53 -0700

I'd say, if you have to wait for the retire frame to remain operational. If you give up, you should use a reset not a close to avoid the security risk.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500971709

---

From: Nick Banks <[email-masked]>
Date: Tue, 11 Jun 2019 11:55:07 -0700

@mikkelfj I think we're all agreed now that explicitly closing the connection is not the answer, because of the security concerns with a delayed packet. But a stateless reset doesn't have those security concerns. Receiving a stateless reset sent in response to a packet using the retired CID only effects the peer if they haven't actually retired the CID yet.

@ianswett STOP_SENDING isn't quite the same. When I send a STOP_SENDING frame, I've already made the decision to start dropping everything else I receive for that stream on the floor. So by the time the peer receives the frame, a whole flight of data might have been dropped. And we're all OK with that, because it doesn't effect the overall connection state.

That's definitely not the case with connection IDs. If I were to start dropping all packets with those retired CIDs first, then best case I lose an entire flight of packets. Much worse if my packet was lost as well.

In my scenario, I need to dump these CIDs right now, but the peer is still using them, so I need to give them some time to make the change. I keep the CIDs in my lookup/routing tables and send the frame out telling them to retire. Eventually they acknowledge the frame, so I know they got the new CIDs and the requirement to retire the old ones.

This is where we seem to start having differing views. I cannot allow a peer to go on forever using the CIDs I told them to retire. Continued usage of those CIDs is causing all kinds of performance issues, with cross processor locking/contention, for all connections on the effected processors. Since this scenario should be infrequent, I'm OK to accept the perf hit for a while, but eventually enough is enough. I want the text to be clear that if a peer doesn't switch CIDs, then the connection will go away eventually.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500976670

---

From: MikkelFJ <[email-masked]>
Date: Tue, 11 Jun 2019 12:02:10 -0700

@nibanks yes, but I suggest that you wait for retire frame unless you run out of patience rather than closing you eyes and counting to three. If you get tired of waiting, you can start to reset, but that may depend on the endpoint more than a specific 3-PTO timeout. Hence it goes both ways: receiver should make an best effort to be timely, and sender should have a grown ups patience.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500979150

---

From: David Schinazi <[email-masked]>
Date: Tue, 11 Jun 2019 12:11:50 -0700

@nibanks Here is part of your original description of this issue:

> I have a scenario where I want to move a connection from one "partition" to another "partition" on the same machine. I use some bits from the CID to indicate the partition ID. My problem is, I've already sent out a CID to the peer indicating the old partition ID. If I change, I'm going to get a cross-partition lookup perf-hit for the rest of time on this connection.

If the peer keeps using a CID you want to retire, the only impact is performance. So this is in line with what I proposed: keep this feature a SHOULD that is not enforced. Any attempt at enforcing this will open up security risks.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500982333

---

From: MikkelFJ <[email-masked]>
Date: Tue, 11 Jun 2019 12:49:06 -0700

The more I think about this problem, the more pointless it seems to send a stateless reset, especially one that should explicitly be ignored, and one which the sender already knows will have that effect.

It's not like that implementation that receives a stateless reset will say "oh bummer, I forgot, I better hurry up!". No, either it is not implemented, or more time is required.

A reset just becomes another way of retransmitting a NEW CID frame with a prior to field.

So ultimately I think @DavidSchinazi is right in stating "a Should that is not enforced".

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500996376

---

From: Nick Banks <[email-masked]>
Date: Tue, 11 Jun 2019 12:53:03 -0700

@DavidSchinazi can you explain the security risk of responding to an old CID with a stateless reset, sometime after the NEW_CONNECTION_ID frame was acknowledged?

@mikkelfj if the peer continues to use the old CID after acknowledging the NEW_CONNECTION_ID frame, why would it assume the "sender already knows it will have that effect"? The peer doesn't seem to be doing as expected already, why assume anything else at that point? If the peer is ignoring the stateless reset AND continuing to use the old CID, I don't care if they mess things up for themselves. It has solved the performance problem affecting ALL connections on the related processors.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-500997793

---

From: David Schinazi <[email-masked]>
Date: Tue, 11 Jun 2019 15:06:40 -0700

@nibanks the issue is that an attacker can close the connection if the stateless reset tokens are the same for different CIDs. Perhaps this wording gets you what you want:

```

The sender of the Retire Prior To field MUST keep track of the connection
IDs it wishes to retire until it has received a corresponding
RETIRE_CONNECTION_ID frame, with one exception: if the sender of the
Retire Prior To field has used distinct stateless reset tokens for all of
their issued connection IDs, and 3 times the PTO has elapsed since it
received an acknowledgment for its Retire Prior To field, then it MAY lose
track of that connection ID, and respond to packets with that connection
ID with the corresponding stateless reset token.
```

This allows you to implement the enforcement you want while keeping the spec written in such a way that most implementations don't accidentally allow this attack by being overly enthusiastic in enforcing this.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-501041204

---

From: Nick Banks <[email-masked]>
Date: Tue, 11 Jun 2019 15:18:52 -0700

@DavidSchinazi looks good to me. I will update the PR. Thanks for the proposed text.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-501044354

---

From: Mike Bishop <[email-masked]>
Date: Wed, 12 Jun 2019 11:20:02 -0700

Technically, the SRTs don't *all* have to have been distinct, there just has to be zero overlap between the Retire Prior To set and the later ones.  So you could do as @mikkelfj has alluded to earlier, using the same SRT for a period of time, then forcing the retirement of all of those because you changed some input to your generation function, and everything you issue new has moved to a different SRT.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-501395541

---

From: Mike Bishop <[email-masked]>
Date: Wed, 12 Jun 2019 11:22:01 -0700

> @martinthomson Once you're talking about distributed peers, I think we're well in the space of multi-machine multipath? Or is there some other use case you have in mind?

Not Martin, but I think this could as easily be different processes/partitions on the same machine.  With UDP, they could all be sending from the same source port, after all.  Regardless, I think 3PTO is a totally reasonable period of time to expect them to get their coordination sorted out.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2645#issuecomment-501396276