Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Support graceful connection close #1181

Open
oremanj opened this issue Jan 23, 2019 · 6 comments
Open

Support graceful connection close #1181

oremanj opened this issue Jan 23, 2019 · 6 comments

Comments

@oremanj
Copy link

oremanj commented Jan 23, 2019

RFC 7540 section 6.8 seems to indicate that traffic can continue flowing in both directions after a GOAWAY frame, with the only restriction being that the recipient can't open new streams after receiving the GOAWAY:

   A GOAWAY frame might not immediately precede closing of the
   connection; a receiver of a GOAWAY that has no more use for the
   connection SHOULD still send a GOAWAY frame before terminating the
   connection.
...
   Activity on streams numbered lower 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.

But, h2's connection state machine immediately transitions to CLOSED upon sending or receiving a GOAWAY, effectively prohibiting any further traffic. Would you be interested in a patch to fix this, or is there some disconnect I'm missing between the wording of the RFC and actual implementations?

@pgjones
Copy link
Member

pgjones commented Jan 24, 2019

I'm not familiar enough with the code to know the answer to this, but I'm happy to review a patch if you research it.

@dimaqq
Copy link

dimaqq commented Feb 28, 2020

Code in question: https://github.com/python-hyper/hyper-h2/blob/570dc7daa480d34bcf0676e88d241112c51b1796/h2/connection.py#L1825-L1844

TL;DR as far as I understand the RFC:

  • having received GOAWAY with error code 0:
    • we can't create more streams
    • we are free to send and receive on the existing streams (up to GOAWAY's last stream id)
    • higher level library is free to retry requests with higher stream ids (peer either never saw them, or never parsed them)
  • having receive GOAWAY with non-zero error:
    • we can't create new streams
    • we can't send more data on existing streams
    • we should probably keep the data already received for our user
    • we should treat this as ConnectionError and [dunno about response] and close the connection

Cross-link: https://github.com/encode/httpx/issues/828

@dimaqq
Copy link

dimaqq commented Apr 1, 2020

Would it help to split the input two ways:

  • RECV_GOAWAY for errors error_code != 0
  • RECV_GRACEFUL_SHUTDOWN or RECV_LAST_STREAM_ID for error_code == 0?

@ech0-py
Copy link

ech0-py commented Mar 8, 2021

+1 on this issue
Since such software like HAProxy terminates connections by sending GOAWAY first and HEADERS/DATA frames right after - the current transition states are unable to handle this.
Wireshark_vtA0SONNpX

@stephenc-pace
Copy link

Any updates on this?

@zanieb
Copy link

zanieb commented Nov 30, 2022

I've looked at fixing this and it seems like it'd be a lot of work. I'm very hesitant to dig into it without guidance from maintainers. It seems this is further complicated by two-stage GOAWAY handling but that does not appear to be well supported in general, for example https://mailman.nginx.org/pipermail/nginx-devel/2021-April/013956.html.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants