H2 GOAWAY review
In the context of #4284 I read rfc9113 again, cross-checking with our code, and I now think that our GOAWAY handling is incomplete to wrong.
We have a single goaway flag
https://github.com/varnishcache/varnish-cache/blob/440319deb628ab65a53ebace729aa2579eef9710/bin/varnishd/http2/cache_http2.h#L174
Yet the semantics are different:
Sending it means "I will ignore any new streams", and, because we do not implement PUSH, we are the only endpoint which could want this semantic. But a client is also free to use it to signal the intend of a graceful shutdown: a client GOAWAY does not mean to abort everything, it means "finish current streams". If a client wanted to get rid of open streams, it would reset them.
Activity on streams numbered lower than or equal to the last stream identifier might still complete successfully. The sender of a GOAWAY frame might gracefully shut down a connection by sending a GOAWAY frame, maintaining the connection in an "open" state until all in-progress streams complete.
Once the flag is set, we never send a goaway
https://github.com/varnishcache/varnish-cache/blob/440319deb628ab65a53ebace729aa2579eef9710/bin/varnishd/http2/cache_http2_proto.c#L421-L422
See before: We would have good reason to send a goaway even after having received one
Once the flag is set, we stop receiving data
https://github.com/varnishcache/varnish-cache/blob/440319deb628ab65a53ebace729aa2579eef9710/bin/varnishd/http2/cache_http2_proto.c#L1478-L1479
We absolutely MUST not do this
However, any frames that alter connection state cannot be completely ignored. For instance, HEADERS, PUSH_PROMISE, and CONTINUATION frames MUST be minimally processed to ensure that the state maintained for field section compression is consistent (see Section 4.3); similarly, DATA frames MUST be counted toward the connection flow-control window. Failure to process these frames can cause flow control or field section compression state to become unsynchronized.
When we receive a goaway, we simply set the last stream id
https://github.com/varnishcache/varnish-cache/blob/440319deb628ab65a53ebace729aa2579eef9710/bin/varnishd/http2/cache_http2_proto.c#L397-L411
but we must check the last stream id to be lower than any previous one
Endpoints MUST NOT increase the value they send in the last stream identifier, since the peers might already have retried unprocessed requests on another connection.
Side notes
We do not implement the "graceful shutdown" procedure
A server that is attempting to gracefully shut down a connection SHOULD send an initial GOAWAY frame with the last stream identifier set to 231-1 and a NO_ERROR code. This signals to the client that a shutdown is imminent and that initiating further requests is prohibited. After allowing time for any in-flight stream creation (at least one round-trip time), the server MAY send another GOAWAY frame with an updated last stream identifier. This ensures that a connection can be cleanly shut down without losing requests.
We do not do this because we do not currently implement the "graceful shutdown"