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 }