Fix panic if remote causes local to reset a stream before opening

This commit is contained in:
Sean McArthur
2021-10-21 12:12:58 -07:00
parent f52d5e6290
commit 405972739b
3 changed files with 85 additions and 0 deletions

View File

@@ -544,4 +544,14 @@ impl Send {
true
}
}
pub(super) fn maybe_reset_next_stream_id(&mut self, id: StreamId) {
if let Ok(next_id) = self.next_stream_id {
// Peer::is_local_init should have been called beforehand
debug_assert_eq!(id.is_server_initiated(), next_id.is_server_initiated());
if id >= next_id {
self.next_stream_id = id.next_id();
}
}
}
}

View File

@@ -865,6 +865,24 @@ impl Inner {
let key = match self.store.find_entry(id) {
Entry::Occupied(e) => e.key(),
Entry::Vacant(e) => {
// Resetting a stream we don't know about? That could be OK...
//
// 1. As a server, we just received a request, but that request
// was bad, so we're resetting before even accepting it.
// This is totally fine.
//
// 2. The remote may have sent us a frame on new stream that
// it's *not* supposed to have done, and thus, we don't know
// the stream. In that case, sending a reset will "open" the
// stream in our store. Maybe that should be a connection
// error instead? At least for now, we need to update what
// our vision of the next stream is.
if self.counts.peer().is_local_init(id) {
// We normally would open this stream, so update our
// next-send-id record.
self.actions.send.maybe_reset_next_stream_id(id);
}
let stream = Stream::new(id, 0, 0);
e.insert(stream)