]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
QUIC: on connect, keep on trying on draining server
authorStefan Eissing <stefan@eissing.org>
Wed, 11 Sep 2024 11:53:44 +0000 (13:53 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 12 Sep 2024 06:24:10 +0000 (08:24 +0200)
Do not give up connect on servers that are in draining state. This might
indicate the QUIC server restarting and the UDP packet routing still
hitting the instance shutting down.

Instead keep on connecting until the overall TIMEOUT fires.

Closes #14863

lib/connect.c
lib/vquic/curl_ngtcp2.c
lib/vquic/curl_osslq.c
lib/vquic/curl_quiche.c
tests/http/test_03_goaway.py

index b9da7c16216e5ba9403a36b72f634500b496fe8c..20275163b52cdcffc171295fb9cc6a7c7a353851 100644 (file)
@@ -547,9 +547,11 @@ static CURLcode baller_start_next(struct Curl_cfilter *cf,
 {
   if(cf->sockindex == FIRSTSOCKET) {
     baller_next_addr(baller);
-    /* If we get inconclusive answers from the server(s), we make
-     * a second iteration over the address list */
-    if(!baller->addr && baller->inconclusive && !baller->rewinded)
+    /* If we get inconclusive answers from the server(s), we start
+     * again until this whole thing times out. This allows us to
+     * connect to servers that are gracefully restarting and the
+     * packet routing to the new instance has not happened yet (e.g. QUIC). */
+    if(!baller->addr && baller->inconclusive)
       baller_rewind(baller);
     baller_start(cf, data, baller, timeoutms);
   }
index b0a100eb66347e3153a97edfcb9f60faacfb829f..3b958e2279f56536c13a08f4da6424456fbb7735 100644 (file)
@@ -129,7 +129,6 @@ struct cf_ngtcp2_ctx {
   nghttp3_settings h3settings;
   struct curltime started_at;        /* time the current attempt started */
   struct curltime handshake_at;      /* time connect handshake finished */
-  struct curltime reconnect_at;      /* time the next attempt should start */
   struct bufc_pool stream_bufcp;     /* chunk pool for streams */
   struct dynbuf scratch;             /* temp buffer for header construction */
   struct Curl_hash streams;          /* hash `data->mid` to `h3_stream_ctx` */
@@ -2311,12 +2310,6 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
 
   CF_DATA_SAVE(save, cf, data);
 
-  if(ctx->reconnect_at.tv_sec && Curl_timediff(now, ctx->reconnect_at) < 0) {
-    /* Not time yet to attempt the next connect */
-    CURL_TRC_CF(data, cf, "waiting for reconnect time");
-    goto out;
-  }
-
   if(!ctx->qconn) {
     ctx->started_at = now;
     result = cf_connect_start(cf, data, &pktx);
index ffe3ca0c113d7decf0d363a463abbf8265501125..6121b2f893859660a62740cd3c13f75887598bd7 100644 (file)
@@ -288,7 +288,6 @@ struct cf_osslq_ctx {
   struct curltime started_at;        /* time the current attempt started */
   struct curltime handshake_at;      /* time connect handshake finished */
   struct curltime first_byte_at;     /* when first byte was recvd */
-  struct curltime reconnect_at;      /* time the next attempt should start */
   struct bufc_pool stream_bufcp;     /* chunk pool for streams */
   struct Curl_hash streams;          /* hash `data->mid` to `h3_stream_ctx` */
   size_t max_stream_window;          /* max flow window for one stream */
@@ -1686,12 +1685,6 @@ static CURLcode cf_osslq_connect(struct Curl_cfilter *cf,
   now = Curl_now();
   CF_DATA_SAVE(save, cf, data);
 
-  if(ctx->reconnect_at.tv_sec && Curl_timediff(now, ctx->reconnect_at) < 0) {
-    /* Not time yet to attempt the next connect */
-    CURL_TRC_CF(data, cf, "waiting for reconnect time");
-    goto out;
-  }
-
   if(!ctx->tls.ossl.ssl) {
     ctx->started_at = now;
     result = cf_osslq_ctx_start(cf, data);
index 9182fe9e4774d23a6b2f976aa2397e7b818f410b..768a5f2ae19e072c23477e1a2707659c8e5a84ea 100644 (file)
@@ -96,7 +96,6 @@ struct cf_quiche_ctx {
   uint8_t scid[QUICHE_MAX_CONN_ID_LEN];
   struct curltime started_at;        /* time the current attempt started */
   struct curltime handshake_at;      /* time connect handshake finished */
-  struct curltime reconnect_at;      /* time the next attempt should start */
   struct bufc_pool stream_bufcp;     /* chunk pool for streams */
   struct Curl_hash streams;          /* hash `data->mid` to `stream_ctx` */
   curl_off_t data_recvd;
@@ -1406,13 +1405,6 @@ static CURLcode cf_quiche_connect(struct Curl_cfilter *cf,
   *done = FALSE;
   vquic_ctx_update_time(&ctx->q);
 
-  if(ctx->reconnect_at.tv_sec &&
-     Curl_timediff(ctx->q.last_op, ctx->reconnect_at) < 0) {
-    /* Not time yet to attempt the next connect */
-    CURL_TRC_CF(data, cf, "waiting for reconnect time");
-    goto out;
-  }
-
   if(!ctx->qconn) {
     result = cf_quiche_ctx_open(cf, data);
     if(result)
index cef5840847983b517d4061437bf66e1b3e897c21..26d57bbe32db480835d8afd4536ededbfea12bb3 100644 (file)
@@ -36,7 +36,6 @@ from testenv import Env, CurlClient, ExecResult
 log = logging.getLogger(__name__)
 
 
-@pytest.mark.skipif(condition=Env().ci_run, reason="not suitable for CI runs")
 class TestGoAway:
 
     @pytest.fixture(autouse=True, scope='class')
@@ -83,8 +82,6 @@ class TestGoAway:
         proto = 'h3'
         if proto == 'h3' and env.curl_uses_lib('msh3'):
             pytest.skip("msh3 stalls here")
-        if proto == 'h3' and env.curl_uses_lib('quiche'):
-            pytest.skip("does not work in CI, but locally for some reason")
         if proto == 'h3' and env.curl_uses_ossl_quic():
             pytest.skip('OpenSSL QUIC fails here')
         count = 3