New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
You don't always need the draining period #871
Comments
I agree, the text is confusing. From what I understand, the spec is to absorb packets and occasionally repeat the CONNECTION_CLOSE (or APPLICATION_CLOSE) for 3* RTO. The peer is not supposed to do anything with the packets, just count them and send a repeat if the count reaches a threshold. Arguably, if the peer receives a CONNECTION CLOSE, it does not even need repeating its own close again. The only real requirement is to NOT send a stateless reset during that time. There is a related issue about entering a draining period after idle timeout. How is that a different behavior from adding 3*RTO to the idle timeout period? |
Also, the text does not explicitly say what the receiver of the CONNECTION_CLOSE shall do. From what I read, it is OK to just go away, no draining period required. |
As @ekr points out, there was definitely more than one closing state. I've modified this to the following three: 1. draining - when you know that the other side is closing, this is just to absorb stray packets 2. closing - when you have initiated the close and you need to re-send the close in addition to absorbing stray packets (this could be longer than the 3RTO period if we like, but I've opted for keeping a shared timer) 3. timed out - when you timed out, and you are willing to revive the connection if new packets arrive; this one being optional In the process I realized that we needed greater clarity about how to respond to a closing frame (thanks to @huitema for the prompting). I allow the recipient to generate one closing frame, but no more than that. They enter the draining period thereafter and can't send any more packets. Having two peers in the closing state could result in a constant back-and-forth. Editorial: I added the term "closing frame" to cover CONNECTION_CLOSE and APPLICATION_CLOSE collectively, which were getting cumbersome. Closes #871.
As @ekr points out, there was definitely more than one closing state. I've modified this to the following three: 1. draining - when you know that the other side is closing, this is just to absorb stray packets 2. closing - when you have initiated the close and you need to re-send the close in addition to absorbing stray packets (this could be longer than the 3RTO period if we like, but I've opted for keeping a shared timer) 3. timed out - when you timed out, and you are willing to revive the connection if new packets arrive; this one being optional In the process I realized that we needed greater clarity about how to respond to a closing frame (thanks to @huitema for the prompting). I allow the recipient to generate one closing frame, but no more than that. They enter the draining period thereafter and can't send any more packets. Having two peers in the closing state could result in a constant back-and-forth. Editorial: I added the term "closing frame" to cover CONNECTION_CLOSE and APPLICATION_CLOSE collectively, which were getting cumbersome. Closes #871.
As @ekr points out, there was definitely more than one closing state. I've modified this to the following three: 1. draining - when you know that the other side is closing, this is just to absorb stray packets 2. closing - when you have initiated the close and you need to re-send the close in addition to absorbing stray packets (this could be longer than the 3RTO period if we like, but I've opted for keeping a shared timer) 3. timed out - when you timed out, and you are willing to revive the connection if new packets arrive; this one being optional In the process I realized that we needed greater clarity about how to respond to a closing frame (thanks to @huitema for the prompting). I allow the recipient to generate one closing frame, but no more than that. They enter the draining period thereafter and can't send any more packets. Having two peers in the closing state could result in a constant back-and-forth. Editorial: I added the term "closing frame" to cover CONNECTION_CLOSE and APPLICATION_CLOSE collectively, which were getting cumbersome. Closes #871.
As @ekr points out, there was definitely more than one closing state. I've modified this to the following three: 1. draining - when you know that the other side is closing, this is just to absorb stray packets 2. closing - when you have initiated the close and you need to re-send the close in addition to absorbing stray packets (this could be longer than the 3RTO period if we like, but I've opted for keeping a shared timer) 3. timed out - when you timed out, and you are willing to revive the connection if new packets arrive; this one being optional In the process I realized that we needed greater clarity about how to respond to a closing frame (thanks to @huitema for the prompting). I allow the recipient to generate one closing frame, but no more than that. They enter the draining period thereafter and can't send any more packets. Having two peers in the closing state could result in a constant back-and-forth. Editorial: I added the term "closing frame" to cover CONNECTION_CLOSE and APPLICATION_CLOSE collectively, which were getting cumbersome. Closes #871.
I think that I've addressed these comments in a new PR. I agree with @ekr that splitting the states makes things clearer. I've also tried to address the confusion that @huitema had. To answer the questions:
The difference would be that you tell the application that the connection is done with after the idle timeout runs out, which might result in the packets being poorly handled otherwise. The draining period would remain to ensure that the other side didn't somehow send just before their timer ran down. #899 allows a bit of flexibility here, and likely could be made more concrete in future, but all possibilities are allowed (drop the packets, send a CONNECTION_CLOSE, or even revive the connection).
It sort of did say that you can just go away if you string things together, but I think that was a mistake. You might receive reordered packets after the close, so you should hang around still. |
* Rework draining period into two (or three) states As @ekr points out, there was definitely more than one closing state. I've modified this to the following three: 1. draining - when you know that the other side is closing, this is just to absorb stray packets 2. closing - when you have initiated the close and you need to re-send the close in addition to absorbing stray packets (this could be longer than the 3RTO period if we like, but I've opted for keeping a shared timer) 3. timed out - when you timed out, and you are willing to revive the connection if new packets arrive; this one being optional In the process I realized that we needed greater clarity about how to respond to a closing frame (thanks to @huitema for the prompting). I allow the recipient to generate one closing frame, but no more than that. They enter the draining period thereafter and can't send any more packets. Having two peers in the closing state could result in a constant back-and-forth. Editorial: I added the term "closing frame" to cover CONNECTION_CLOSE and APPLICATION_CLOSE collectively, which were getting cumbersome. Closes #871. * Updates based on review feedback
PR#868 doubled down on the draining and the proposal for PR#870 is about creating an exception to the draining period.
The basic problem here is spec confusion about the draining period, specifically, whether it's some sort "do nothing state" or whether it's a state where you're supposed to send packets. So, we have:
However, in the specific case of stateless reset, the only thing that the connection needs to do is the thing in the fourth paragraph, which is after the draining period, namely discard packets (note that it can't send a stateless reset because that's forbidden).
The right fix for this is to have two states:
A state where you're expected to occasionally respond to new packets with something that says "go away" (e.g., CONNECTION_CLOSE) and where we're prescriptive about you doing that.
A state where you're expected to silently discard packets (perhaps with a stateless reset).
The text was updated successfully, but these errors were encountered: