[PATCH] QUIC: fixed unsent MTU probe acknowledgement

Roman Arutyunyan arut at nginx.com
Fri Feb 9 09:56:42 UTC 2024


# HG changeset patch
# User Roman Arutyunyan <arut at nginx.com>
# Date 1707472496 -14400
#      Fri Feb 09 13:54:56 2024 +0400
# Node ID 9b89f44ddd3637afc939e31de348c7986ae9e76d
# Parent  73eb75bee30f4aee66edfb500270dbb14710aafd
QUIC: fixed unsent MTU probe acknowledgement.

Previously if an MTU probe send failed early in ngx_quic_frame_sendto()
due to allocation error or congestion control, the application level packet
number was not increased, but was still saved as MTU probe packet number.
Later when a packet with this number was acknowledged, the unsent MTU probe
was acknowledged as well.  This could result in discovering a bigger MTU than
supported by the path, which could lead to EMSGSIZE (Message too long) errors
while sending further packets.

The problem existed since PMTUD was introduced in 58afcd72446f (1.25.2).
Back then only the unlikely memory allocation error could trigger it.  However
in efcdaa66df2e congestion control was added to ngx_quic_frame_sendto() which
can now trigger the issue with a higher probability.

diff --git a/src/event/quic/ngx_event_quic_migration.c b/src/event/quic/ngx_event_quic_migration.c
--- a/src/event/quic/ngx_event_quic_migration.c
+++ b/src/event/quic/ngx_event_quic_migration.c
@@ -925,12 +925,6 @@ ngx_quic_send_path_mtu_probe(ngx_connect
 
     qc = ngx_quic_get_connection(c);
     ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application);
-    path->mtu_pnum[path->tries] = ctx->pnum;
-
-    ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                   "quic path seq:%uL send probe "
-                   "mtu:%uz pnum:%uL tries:%ui",
-                   path->seqnum, path->mtud, ctx->pnum, path->tries);
 
     log_error = c->log_error;
     c->log_error = NGX_ERROR_IGNORE_EMSGSIZE;
@@ -943,14 +937,26 @@ ngx_quic_send_path_mtu_probe(ngx_connect
     path->mtu = mtu;
     c->log_error = log_error;
 
+    if (rc == NGX_OK) {
+        path->mtu_pnum[path->tries] = ctx->pnum;
+
+        ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                       "quic path seq:%uL send probe "
+                       "mtu:%uz pnum:%uL tries:%ui",
+                       path->seqnum, path->mtud, ctx->pnum, path->tries);
+
+        return NGX_OK;
+    }
+
+    path->mtu_pnum[path->tries] = NGX_QUIC_UNSET_PN;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                   "quic path seq:%uL rejected mtu:%uz",
+                   path->seqnum, path->mtud);
+
     if (rc == NGX_ERROR) {
         if (c->write->error) {
             c->write->error = 0;
-
-            ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                           "quic path seq:%uL rejected mtu:%uz",
-                           path->seqnum, path->mtud);
-
             return NGX_DECLINED;
         }
 


More information about the nginx-devel mailing list