h2: client: keep POLLOUT asserted while netconn has pps pending#3613
Closed
saghul wants to merge 3 commits into
Closed
h2: client: keep POLLOUT asserted while netconn has pps pending#3613saghul wants to merge 3 commits into
saghul wants to merge 3 commits into
Conversation
Integrate OpenHiTLS as a new TLS backend option for libwebsockets, providing an alternative to OpenSSL, mbedTLS, and other TLS libraries. Core changes: - CMake detection and build configuration for OpenHiTLS - Complete TLS client and server implementation - X.509 certificate operations (parse, verify, load) - Crypto primitives: AES, RSA, EC, Hash operations - TLS 1.2 and TLS 1.3 support with session management - SNI, ALPN, and keylog callback support - BSL_UIO wrapper layer for OpenHiTLS I/O abstraction Technical details: - New cmake/FindOpenHITLS.cmake for library detection - Backend-specific code in lib/tls/openhitls/ - Integration with lws TLS abstraction layer - Support for both memory and file-based certificates - Error mapping between OpenHiTLS and lws error codes
rops_perform_user_POLLOUT_h2() ends by calling lws_wsi_mux_action_pending_writeable_reqs(), which decides POLLOUT purely from child streams' requested_POLLOUT and clears POLLOUT when no child wants it. It ignores the network connection's own queued protocol sends (wsi->h2.h2n->pps), e.g. a connection- or stream-level WINDOW_UPDATE that grants the peer receive-window credit. When such a pps is queued but no child stream currently wants POLLOUT, POLLOUT is cleared and the pps is never flushed, so the peer never gets the credit and the transfer stalls. This is easy to hit on the client with a bodyless request (e.g. a plain GET): the request stream goes HALF_CLOSED_LOCAL as soon as the headers are sent with END_STREAM, so no child wants POLLOUT, while the netconn still needs to emit the WINDOW_UPDATE that opens the receive window. The response headers arrive but the body stalls at the flow-control window (the stream window, or 65535 at the connection level) until the peer resets the stream. Fix: keep POLLOUT asserted while the netconn still has pps pending, before falling through to the child-only reconciler. Observed only with the mbedtls TLS backend; the byte-identical code under GnuTLS/OpenSSL happens to flush via different read/POLLOUT interleaving, which is likely why this has gone unnoticed.
04492e6 to
d8b4769
Compare
Member
|
Thanks I extracted just the patch and added it to main. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
rops_perform_user_POLLOUT_h2() ends by calling
lws_wsi_mux_action_pending_writeable_reqs(), which decides POLLOUT purely
from child streams' requested_POLLOUT and clears POLLOUT when no child
wants it. It ignores the network connection's own queued protocol sends
(wsi->h2.h2n->pps), e.g. a connection- or stream-level WINDOW_UPDATE that
grants the peer receive-window credit. When such a pps is queued but no
child stream currently wants POLLOUT, POLLOUT is cleared and the pps is
never flushed, so the peer never gets the credit and the transfer stalls.
This is easy to hit on the client with a bodyless request (e.g. a plain
GET): the request stream goes HALF_CLOSED_LOCAL as soon as the headers are
sent with END_STREAM, so no child wants POLLOUT, while the netconn still
needs to emit the WINDOW_UPDATE that opens the receive window. The
response headers arrive but the body stalls at the flow-control window
(the stream window, or 65535 at the connection level) until the peer
resets the stream.
Fix: keep POLLOUT asserted while the netconn still has pps pending, before
falling through to the child-only reconciler.
Observed only with the mbedtls TLS backend; the byte-identical code under
GnuTLS/OpenSSL happens to flush via different read/POLLOUT interleaving,
which is likely why this has gone unnoticed.