comparison src/event/quic/ngx_event_quic_output.c @ 9078:9553eea74f2a quic

QUIC: optimized immediate close. Previously, before sending CONNECTION_CLOSE to client, all pending frames were sent. This is redundant and could prevent CONNECTION_CLOSE from being sent due to congestion control. Now pending frames are freed and CONNECTION_CLOSE is sent without congestion control, as advised by RFC 9002: Packets containing frames besides ACK or CONNECTION_CLOSE frames count toward congestion control limits and are considered to be in flight.
author Roman Arutyunyan <arut@nginx.com>
date Tue, 02 May 2023 17:54:53 +0400
parents 12b756caaf16
children 9ae24a9ba763
comparison
equal deleted inserted replaced
9077:8f2f40d3fd18 9078:9553eea74f2a
880 880
881 881
882 ngx_int_t 882 ngx_int_t
883 ngx_quic_send_cc(ngx_connection_t *c) 883 ngx_quic_send_cc(ngx_connection_t *c)
884 { 884 {
885 ngx_quic_frame_t *frame; 885 ngx_quic_frame_t frame;
886 ngx_quic_connection_t *qc; 886 ngx_quic_connection_t *qc;
887 887
888 qc = ngx_quic_get_connection(c); 888 qc = ngx_quic_get_connection(c);
889 889
890 if (qc->draining) { 890 if (qc->draining) {
896 { 896 {
897 /* dot not send CC too often */ 897 /* dot not send CC too often */
898 return NGX_OK; 898 return NGX_OK;
899 } 899 }
900 900
901 frame = ngx_quic_alloc_frame(c); 901 ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
902 if (frame == NULL) { 902
903 return NGX_ERROR; 903 frame.level = qc->error_level;
904 } 904 frame.type = qc->error_app ? NGX_QUIC_FT_CONNECTION_CLOSE_APP
905 905 : NGX_QUIC_FT_CONNECTION_CLOSE;
906 frame->level = qc->error_level; 906 frame.u.close.error_code = qc->error;
907 frame->type = qc->error_app ? NGX_QUIC_FT_CONNECTION_CLOSE_APP 907 frame.u.close.frame_type = qc->error_ftype;
908 : NGX_QUIC_FT_CONNECTION_CLOSE;
909 frame->u.close.error_code = qc->error;
910 frame->u.close.frame_type = qc->error_ftype;
911 908
912 if (qc->error_reason) { 909 if (qc->error_reason) {
913 frame->u.close.reason.len = ngx_strlen(qc->error_reason); 910 frame.u.close.reason.len = ngx_strlen(qc->error_reason);
914 frame->u.close.reason.data = (u_char *) qc->error_reason; 911 frame.u.close.reason.data = (u_char *) qc->error_reason;
915 } 912 }
916
917 ngx_quic_queue_frame(qc, frame);
918 913
919 qc->last_cc = ngx_current_msec; 914 qc->last_cc = ngx_current_msec;
920 915
921 return ngx_quic_output(c); 916 return ngx_quic_frame_sendto(c, &frame, 0, qc->path);
922 } 917 }
923 918
924 919
925 ngx_int_t 920 ngx_int_t
926 ngx_quic_send_early_cc(ngx_connection_t *c, ngx_quic_header_t *inpkt, 921 ngx_quic_send_early_cc(ngx_connection_t *c, ngx_quic_header_t *inpkt,