]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http2: Use KEEP_SEND_HOLD for flow control in HTTP/2
authorStefan Eissing <stefan@eissing.org>
Mon, 13 Mar 2023 10:44:26 +0000 (11:44 +0100)
committerJay Satiro <raysatiro@yahoo.com>
Tue, 14 Mar 2023 07:26:57 +0000 (03:26 -0400)
- use the defined, but so far not used, KEEP_SEND_HOLD bit for flow
  control based suspend of sending in transfers.

Prior to this change KEEP_SEND_PAUSE bit was used instead, but that can
interfere with pausing streams from the user side via curl_easy_pause.

Fixes https://github.com/curl/curl/issues/10751
Closes https://github.com/curl/curl/pull/10753

lib/http2.c
lib/transfer.c
lib/vquic/curl_ngtcp2.c
lib/vquic/curl_quiche.c

index 94250bf6eb694af996bc110589a07e1c8afba00f..b0ce87d98793525f05bdb43082a02cc905a442f9 100644 (file)
@@ -958,12 +958,12 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
     break;
   case NGHTTP2_WINDOW_UPDATE:
     DEBUGF(LOG_CF(data, cf, "[h2sid=%u] recv WINDOW_UPDATE", stream_id));
-    if((data_s->req.keepon & KEEP_SEND_PAUSE) &&
+    if((data_s->req.keepon & KEEP_SEND_HOLD) &&
        (data_s->req.keepon & KEEP_SEND)) {
-      data_s->req.keepon &= ~KEEP_SEND_PAUSE;
+      data_s->req.keepon &= ~KEEP_SEND_HOLD;
       drain_this(cf, data_s);
       Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
-      DEBUGF(LOG_CF(data, cf, "[h2sid=%u] unpausing after win update",
+      DEBUGF(LOG_CF(data, cf, "[h2sid=%u] un-holding after win update",
                     stream_id));
     }
     break;
@@ -2055,8 +2055,8 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
           /* We cannot upload more as the stream's remote window size
            * is 0. We need to receive WIN_UPDATEs before we can continue.
            */
-          data->req.keepon |= KEEP_SEND_PAUSE;
-          DEBUGF(LOG_CF(data, cf, "[h2sid=%u] pausing send as remote flow "
+          data->req.keepon |= KEEP_SEND_HOLD;
+          DEBUGF(LOG_CF(data, cf, "[h2sid=%u] holding send as remote flow "
                  "window is exhausted", stream->stream_id));
         }
     }
@@ -2189,7 +2189,7 @@ static int cf_h2_get_select_socks(struct Curl_cfilter *cf,
 
   /* we're (still uploading OR the HTTP/2 layer wants to send data) AND
      there's a window to send data in */
-  if((((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND) ||
+  if((((k->keepon & KEEP_SENDBITS) == KEEP_SEND) ||
       nghttp2_session_want_write(ctx->h2)) &&
      (nghttp2_session_get_remote_window_size(ctx->h2) &&
       nghttp2_session_get_stream_remote_window_size(ctx->h2,
index 140895113ed1d947bbf1d103a9febde56f767d31..a28395233c8799417b2b6bd18944acfa11aac952 100644 (file)
@@ -1234,8 +1234,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
   }
 
   /* Now update the "done" boolean we return */
-  *done = (0 == (k->keepon&(KEEP_RECV|KEEP_SEND|
-                            KEEP_RECV_PAUSE|KEEP_SEND_PAUSE))) ? TRUE : FALSE;
+  *done = (0 == (k->keepon&(KEEP_RECVBITS|KEEP_SENDBITS))) ? TRUE : FALSE;
   result = CURLE_OK;
 out:
   if(result)
index 4ff87ae5dc9058f3517bcd4a0137971d57c43060..d2d0a3a5af3226a8026a40713d2716c873ad8107 100644 (file)
@@ -903,7 +903,7 @@ static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
   rv |= GETSOCK_READSOCK(0);
 
   /* we're still uploading or the HTTP/2 layer wants to send data */
-  if((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND &&
+  if((k->keepon & KEEP_SENDBITS) == KEEP_SEND &&
      (!stream->h3out || stream->h3out->used < H3_SEND_SIZE) &&
      ngtcp2_conn_get_cwnd_left(ctx->qconn) &&
      ngtcp2_conn_get_max_data_left(ctx->qconn) &&
index 0c48c1c2ebea6ed296b789a52ef771937baacf1d..87a221cc18045e9150608646a6af53d6f520b17f 100644 (file)
@@ -950,7 +950,7 @@ static int cf_quiche_get_select_socks(struct Curl_cfilter *cf,
   rv |= GETSOCK_READSOCK(0);
 
   /* we're still uploading or the HTTP/3 layer wants to send data */
-  if(((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND)
+  if(((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
      && stream_is_writeable(cf, data))
     rv |= GETSOCK_WRITESOCK(0);