comparison src/event/quic/ngx_event_quic_ack.c @ 8885:da112e7f8de6 quic

QUIC: switched to integer arithmetic in rtt calculations. RFC 9002 uses constants implying effective implementation, i.e. using bit shift operations instead of floating point.
author Vladimir Homutov <vl@nginx.com>
date Tue, 19 Oct 2021 14:32:50 +0300
parents 1798acc01970
children b42a041d23a2
comparison
equal deleted inserted replaced
8884:1798acc01970 8885:da112e7f8de6
12 12
13 #define NGX_QUIC_MAX_ACK_GAP 2 13 #define NGX_QUIC_MAX_ACK_GAP 2
14 14
15 /* RFC 9002, 6.1.1. Packet Threshold: kPacketThreshold */ 15 /* RFC 9002, 6.1.1. Packet Threshold: kPacketThreshold */
16 #define NGX_QUIC_PKT_THR 3 /* packets */ 16 #define NGX_QUIC_PKT_THR 3 /* packets */
17 /* RFC 9002, 6.1.2. Time Threshold: kTimeThreshold, kGranularity */ 17 /* RFC 9002, 6.1.2. Time Threshold: kGranularity */
18 #define NGX_QUIC_TIME_THR 1.125
19 #define NGX_QUIC_TIME_GRANULARITY 1 /* ms */ 18 #define NGX_QUIC_TIME_GRANULARITY 1 /* ms */
20 19
21 /* RFC 9002, 7.6.1. Duration: kPersistentCongestionThreshold */ 20 /* RFC 9002, 7.6.1. Duration: kPersistentCongestionThreshold */
22 #define NGX_QUIC_PERSISTENT_CONGESTION_THR 3 21 #define NGX_QUIC_PERSISTENT_CONGESTION_THR 3
23
24 #define ngx_quic_lost_threshold(qc) \
25 ngx_max(NGX_QUIC_TIME_THR * ngx_max((qc)->latest_rtt, (qc)->avg_rtt), \
26 NGX_QUIC_TIME_GRANULARITY)
27 22
28 23
29 /* send time of ACK'ed packets */ 24 /* send time of ACK'ed packets */
30 typedef struct { 25 typedef struct {
31 ngx_msec_t max_pn; 26 ngx_msec_t max_pn;
32 ngx_msec_t oldest; 27 ngx_msec_t oldest;
33 ngx_msec_t newest; 28 ngx_msec_t newest;
34 } ngx_quic_ack_stat_t; 29 } ngx_quic_ack_stat_t;
35 30
36 31
32 static ngx_inline ngx_msec_t ngx_quic_lost_threshold(ngx_quic_connection_t *qc);
37 static void ngx_quic_rtt_sample(ngx_connection_t *c, ngx_quic_ack_frame_t *ack, 33 static void ngx_quic_rtt_sample(ngx_connection_t *c, ngx_quic_ack_frame_t *ack,
38 enum ssl_encryption_level_t level, ngx_msec_t send_time); 34 enum ssl_encryption_level_t level, ngx_msec_t send_time);
39 static ngx_int_t ngx_quic_handle_ack_frame_range(ngx_connection_t *c, 35 static ngx_int_t ngx_quic_handle_ack_frame_range(ngx_connection_t *c,
40 ngx_quic_send_ctx_t *ctx, uint64_t min, uint64_t max, 36 ngx_quic_send_ctx_t *ctx, uint64_t min, uint64_t max,
41 ngx_quic_ack_stat_t *st); 37 ngx_quic_ack_stat_t *st);
48 static void ngx_quic_congestion_lost(ngx_connection_t *c, 44 static void ngx_quic_congestion_lost(ngx_connection_t *c,
49 ngx_quic_frame_t *frame); 45 ngx_quic_frame_t *frame);
50 static void ngx_quic_lost_handler(ngx_event_t *ev); 46 static void ngx_quic_lost_handler(ngx_event_t *ev);
51 47
52 48
49 /* RFC 9002, 6.1.2. Time Threshold: kTimeThreshold, kGranularity */
50 static ngx_inline ngx_msec_t
51 ngx_quic_lost_threshold(ngx_quic_connection_t *qc)
52 {
53 ngx_msec_t thr;
54
55 thr = ngx_max(qc->latest_rtt, qc->avg_rtt);
56 thr += thr >> 3;
57
58 return ngx_max(thr, NGX_QUIC_TIME_GRANULARITY);
59 }
60
61
53 ngx_int_t 62 ngx_int_t
54 ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, 63 ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
55 ngx_quic_frame_t *f) 64 ngx_quic_frame_t *f)
56 { 65 {
57 ssize_t n; 66 ssize_t n;
196 205
197 if (qc->min_rtt + ack_delay < latest_rtt) { 206 if (qc->min_rtt + ack_delay < latest_rtt) {
198 adjusted_rtt -= ack_delay; 207 adjusted_rtt -= ack_delay;
199 } 208 }
200 209
201 qc->avg_rtt = 0.875 * qc->avg_rtt + 0.125 * adjusted_rtt; 210 qc->avg_rtt += (adjusted_rtt >> 3) - (qc->avg_rtt >> 3);
202 rttvar_sample = ngx_abs((ngx_msec_int_t) (qc->avg_rtt - adjusted_rtt)); 211 rttvar_sample = ngx_abs((ngx_msec_int_t) (qc->avg_rtt - adjusted_rtt));
203 qc->rttvar = 0.75 * qc->rttvar + 0.25 * rttvar_sample; 212 qc->rttvar += (rttvar_sample >> 2) - (qc->rttvar >> 2);
204 } 213 }
205 214
206 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, 215 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
207 "quic rtt sample latest:%M min:%M avg:%M var:%M", 216 "quic rtt sample latest:%M min:%M avg:%M var:%M",
208 latest_rtt, qc->min_rtt, qc->avg_rtt, qc->rttvar); 217 latest_rtt, qc->min_rtt, qc->avg_rtt, qc->rttvar);