]> git.kaiwu.me - nginx.git/commitdiff
QUIC: path revalidation after expansion failure.
authorRoman Arutyunyan <arut@nginx.com>
Wed, 29 Nov 2023 06:58:21 +0000 (10:58 +0400)
committerRoman Arutyunyan <arut@nginx.com>
Wed, 29 Nov 2023 06:58:21 +0000 (10:58 +0400)
As per RFC 9000, Section 8.2.1:

    When an endpoint is unable to expand the datagram size to 1200 bytes due
    to the anti-amplification limit, the path MTU will not be validated.
    To ensure that the path MTU is large enough, the endpoint MUST perform a
    second path validation by sending a PATH_CHALLENGE frame in a datagram of
    at least 1200 bytes.

src/event/quic/ngx_event_quic_connection.h
src/event/quic/ngx_event_quic_migration.c

index abd0ebe6cc96a2f92c2004b4d8d8693d12f55d79..4ff0eae4a3734edc43097b98342d967bdf34857a 100644 (file)
@@ -111,7 +111,8 @@ struct ngx_quic_path_s {
     uint64_t                          mtu_pnum[NGX_QUIC_PATH_RETRIES];
     ngx_str_t                         addr_text;
     u_char                            text[NGX_SOCKADDR_STRLEN];
-    ngx_uint_t                        validated; /* unsigned validated:1; */
+    unsigned                          validated:1;
+    unsigned                          mtu_unvalidated:1;
 };
 
 
index 7819ae2f9b66e4b14d26fc77bc6687e9ee155e49..be8e0e304848cfa4655b9920fa21b2043ea20b25 100644 (file)
@@ -169,6 +169,7 @@ valid:
 
             path->mtu = prev->mtu;
             path->max_mtu = prev->max_mtu;
+            path->mtu_unvalidated = 0;
         }
     }
 
@@ -182,6 +183,13 @@ valid:
         qc->congestion.recovery_start = ngx_current_msec;
     }
 
+    path->validated = 1;
+
+    if (path->mtu_unvalidated) {
+        path->mtu_unvalidated = 0;
+        return ngx_quic_validate_path(c, path);
+    }
+
     /*
      * RFC 9000, 9.3.  Responding to Connection Migration
      *
@@ -199,8 +207,6 @@ valid:
 
     ngx_quic_path_dbg(c, "is validated", path);
 
-    path->validated = 1;
-
     ngx_quic_discover_path_mtu(c, path);
 
     return NGX_OK;
@@ -578,7 +584,15 @@ ngx_quic_send_path_challenge(ngx_connection_t *c, ngx_quic_path_t *path)
          * sending a datagram of this size.
          */
 
-        min = (ngx_quic_path_limit(c, path, 1200) < 1200) ? 0 : 1200;
+        if (path->mtu_unvalidated
+            || ngx_quic_path_limit(c, path, 1200) < 1200)
+        {
+            min = 0;
+            path->mtu_unvalidated = 1;
+
+        } else {
+            min = 1200;
+        }
 
         if (ngx_quic_frame_sendto(c, frame, min, path) == NGX_ERROR) {
             return NGX_ERROR;