Skip to content
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

quiche: fix quiche being unable to handle timeout events properly #11654

Closed
wants to merge 3 commits into from

Conversation

oldduckruirui
Copy link
Contributor

@oldduckruirui oldduckruirui commented Aug 11, 2023

According to quiche's document, it is essential to invoke quiche_conn_on_timeout when a timer expires. Failing to call this function can result in quiche being unable to manage various timeout events, including scenarios like retransmitting lost packets and handling idle timeout events.

When packets are sent, the application is responsible for maintaining a timer to react to time-based connection events. The timer expiration can be obtained using the connection's timeout() method.

The application is responsible for providing a timer implementation, which can be specific to the operating system or networking framework used. When a timer expires, the connection's on_timeout() method should be called, after which additional packets might need to be sent on the network:

Set the `QUIC_IDLE_TIMEOUT` parameter to match ngtcp2 for consistency.
In parallel with ngtcp2, quiche also offers the `quiche_conn_on_timeout` interface
for the application to invoke upon timer expiration. Therefore, invoking the `on_timeout`
function of the Connection is crucial to ensure seamless functionality of quiche
with timeout events.
@github-actions github-actions bot added the HTTP/3 h3 or quic related label Aug 11, 2023
@bagder bagder requested a review from icing August 11, 2023 07:40
Copy link
Contributor

@icing icing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR goes in the right direction. But needs to be built on to invoke quiche_conn_on_timeout() only in case the timeout really did happen.

@@ -751,6 +751,12 @@ static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
struct read_ctx readx;
size_t pkt_count, gsolen;

quiche_conn_on_timeout(ctx->qconn);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This calls the function unconditionally on every egress handling. Which is not what the quiche example seem to mandate (guessing through their lack of documentation).

I think we need to handle timeouts more elaborate here. But we can do this based on this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I have made additional modifications to the code. Please check it. :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LPardue @ghedo you think this makes sense?

Copy link
Contributor

@LPardue LPardue Aug 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few things:

  • Calling quiche_conn_on_timeout() before any timeout elapsed is fine, there is no harm other than wasted cycles.
  • It would be better to grab the timeout value once and only fire when expires, than query it every time and check for 0 (optimization)
  • its not clear to me how this relates to the existing timeout_ns that also reads quiche_conn_timeout() for setting a Curl_expire

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • That's right, using a variable to record the value of timeout can improve performance. However, in order to remain consistent with curl_ngtcp2.c and minimize code modifications, I chose not to do this. Maybe we can consider optimizing the implementations of curl_ngtcp2 and curl_quiche together in the future.

  • Reading quiche_conn_timeout again is to promptly update the timing for the next timeout. After processing with quiche_conn_on_timeout, the timeout duration might change. Perhaps I can make a small optimization by placing the update of timeout and the setting of a Curl_expire after calling quiche_conn_on_timeout, which would require querying quiche_conn_timeout only when necessary. But this may cause a little more code modifications.

@bagder
Copy link
Member

bagder commented Aug 15, 2023

@icing you think we should merge this as-is and consider further improvements later? It seems like a step in the right direction at least to me.

@icing
Copy link
Contributor

icing commented Aug 15, 2023

@icing you think we should merge this as-is and consider further improvements later? It seems like a step in the right direction at least to me.

I agree. Let's merge it.

@bagder bagder closed this in 23c3dc2 Aug 15, 2023
@bagder
Copy link
Member

bagder commented Aug 15, 2023

Thanks!

ptitSeb pushed a commit to wasix-org/curl that referenced this pull request Sep 25, 2023
In parallel with ngtcp2, quiche also offers the `quiche_conn_on_timeout`
interface for the application to invoke upon timer
expiration. Therefore, invoking the `on_timeout` function of the
Connection is crucial to ensure seamless functionality of quiche with
timeout events.

Closes curl#11654
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
HTTP/3 h3 or quic related
Development

Successfully merging this pull request may close these issues.

None yet

4 participants