Mercurial > hg > nginx
comparison src/event/quic/ngx_event_quic_migration.c @ 9208:2ed3f57dca0a
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.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Wed, 14 Feb 2024 16:56:28 +0400 |
parents | 6c8595b77e66 |
children |
comparison
equal
deleted
inserted
replaced
9207:73eb75bee30f | 9208:2ed3f57dca0a |
---|---|
907 | 907 |
908 static ngx_int_t | 908 static ngx_int_t |
909 ngx_quic_send_path_mtu_probe(ngx_connection_t *c, ngx_quic_path_t *path) | 909 ngx_quic_send_path_mtu_probe(ngx_connection_t *c, ngx_quic_path_t *path) |
910 { | 910 { |
911 size_t mtu; | 911 size_t mtu; |
912 uint64_t pnum; | |
912 ngx_int_t rc; | 913 ngx_int_t rc; |
913 ngx_uint_t log_error; | 914 ngx_uint_t log_error; |
914 ngx_quic_frame_t *frame; | 915 ngx_quic_frame_t *frame; |
915 ngx_quic_send_ctx_t *ctx; | 916 ngx_quic_send_ctx_t *ctx; |
916 ngx_quic_connection_t *qc; | 917 ngx_quic_connection_t *qc; |
923 frame->level = ssl_encryption_application; | 924 frame->level = ssl_encryption_application; |
924 frame->type = NGX_QUIC_FT_PING; | 925 frame->type = NGX_QUIC_FT_PING; |
925 | 926 |
926 qc = ngx_quic_get_connection(c); | 927 qc = ngx_quic_get_connection(c); |
927 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); | 928 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); |
928 path->mtu_pnum[path->tries] = ctx->pnum; | 929 pnum = ctx->pnum; |
929 | 930 |
930 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | 931 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, |
931 "quic path seq:%uL send probe " | 932 "quic path seq:%uL send probe " |
932 "mtu:%uz pnum:%uL tries:%ui", | 933 "mtu:%uz pnum:%uL tries:%ui", |
933 path->seqnum, path->mtud, ctx->pnum, path->tries); | 934 path->seqnum, path->mtud, ctx->pnum, path->tries); |
941 rc = ngx_quic_frame_sendto(c, frame, path->mtud, path); | 942 rc = ngx_quic_frame_sendto(c, frame, path->mtud, path); |
942 | 943 |
943 path->mtu = mtu; | 944 path->mtu = mtu; |
944 c->log_error = log_error; | 945 c->log_error = log_error; |
945 | 946 |
947 if (rc == NGX_OK) { | |
948 path->mtu_pnum[path->tries] = pnum; | |
949 return NGX_OK; | |
950 } | |
951 | |
952 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
953 "quic path seq:%uL rejected mtu:%uz", | |
954 path->seqnum, path->mtud); | |
955 | |
946 if (rc == NGX_ERROR) { | 956 if (rc == NGX_ERROR) { |
947 if (c->write->error) { | 957 if (c->write->error) { |
948 c->write->error = 0; | 958 c->write->error = 0; |
949 | |
950 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
951 "quic path seq:%uL rejected mtu:%uz", | |
952 path->seqnum, path->mtud); | |
953 | |
954 return NGX_DECLINED; | 959 return NGX_DECLINED; |
955 } | 960 } |
956 | 961 |
957 return NGX_ERROR; | 962 return NGX_ERROR; |
958 } | 963 } |
974 | 979 |
975 for (i = 0; i < NGX_QUIC_PATH_RETRIES; i++) { | 980 for (i = 0; i < NGX_QUIC_PATH_RETRIES; i++) { |
976 pnum = path->mtu_pnum[i]; | 981 pnum = path->mtu_pnum[i]; |
977 | 982 |
978 if (pnum == NGX_QUIC_UNSET_PN) { | 983 if (pnum == NGX_QUIC_UNSET_PN) { |
979 break; | 984 continue; |
980 } | 985 } |
981 | 986 |
982 if (pnum < min || pnum > max) { | 987 if (pnum < min || pnum > max) { |
983 continue; | 988 continue; |
984 } | 989 } |