• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ngtcp2
3  *
4  * Copyright (c) 2019 ngtcp2 contributors
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 #include "ngtcp2_rst.h"
26 
27 #include <assert.h>
28 
29 #include "ngtcp2_rtb.h"
30 #include "ngtcp2_cc.h"
31 #include "ngtcp2_macro.h"
32 
ngtcp2_rs_init(ngtcp2_rs * rs)33 void ngtcp2_rs_init(ngtcp2_rs *rs) {
34   rs->interval = UINT64_MAX;
35   rs->delivered = 0;
36   rs->prior_delivered = 0;
37   rs->prior_ts = 0;
38   rs->tx_in_flight = 0;
39   rs->lost = 0;
40   rs->prior_lost = 0;
41   rs->send_elapsed = 0;
42   rs->ack_elapsed = 0;
43   rs->is_app_limited = 0;
44 }
45 
ngtcp2_rst_init(ngtcp2_rst * rst)46 void ngtcp2_rst_init(ngtcp2_rst *rst) {
47   ngtcp2_rs_init(&rst->rs);
48   ngtcp2_window_filter_init(&rst->wf, 12);
49   rst->delivered = 0;
50   rst->delivered_ts = 0;
51   rst->first_sent_ts = 0;
52   rst->app_limited = 0;
53   rst->next_round_delivered = 0;
54   rst->round_count = 0;
55   rst->is_cwnd_limited = 0;
56   rst->lost = 0;
57 }
58 
ngtcp2_rst_on_pkt_sent(ngtcp2_rst * rst,ngtcp2_rtb_entry * ent,const ngtcp2_conn_stat * cstat)59 void ngtcp2_rst_on_pkt_sent(ngtcp2_rst *rst, ngtcp2_rtb_entry *ent,
60                             const ngtcp2_conn_stat *cstat) {
61   if (cstat->bytes_in_flight == 0) {
62     rst->first_sent_ts = rst->delivered_ts = ent->ts;
63   }
64   ent->rst.first_sent_ts = rst->first_sent_ts;
65   ent->rst.delivered_ts = rst->delivered_ts;
66   ent->rst.delivered = rst->delivered;
67   ent->rst.is_app_limited = rst->app_limited != 0;
68   ent->rst.tx_in_flight = cstat->bytes_in_flight + ent->pktlen;
69   ent->rst.lost = rst->lost;
70 }
71 
ngtcp2_rst_on_ack_recv(ngtcp2_rst * rst,ngtcp2_conn_stat * cstat,uint64_t pkt_delivered)72 int ngtcp2_rst_on_ack_recv(ngtcp2_rst *rst, ngtcp2_conn_stat *cstat,
73                            uint64_t pkt_delivered) {
74   ngtcp2_rs *rs = &rst->rs;
75   uint64_t rate;
76 
77   if (rst->app_limited && rst->delivered > rst->app_limited) {
78     rst->app_limited = 0;
79   }
80 
81   if (pkt_delivered >= rst->next_round_delivered) {
82     rst->next_round_delivered = pkt_delivered;
83     ++rst->round_count;
84   }
85 
86   if (rs->prior_ts == 0) {
87     return 0;
88   }
89 
90   rs->interval = ngtcp2_max(rs->send_elapsed, rs->ack_elapsed);
91 
92   rs->delivered = rst->delivered - rs->prior_delivered;
93   rs->lost = rst->lost - rs->prior_lost;
94 
95   if (rs->interval < cstat->min_rtt) {
96     rs->interval = UINT64_MAX;
97     return 0;
98   }
99 
100   if (!rs->interval) {
101     return 0;
102   }
103 
104   rate = rs->delivered * NGTCP2_SECONDS / rs->interval;
105 
106   if (rate > ngtcp2_window_filter_get_best(&rst->wf) || !rst->app_limited) {
107     ngtcp2_window_filter_update(&rst->wf, rate, rst->round_count);
108     cstat->delivery_rate_sec = ngtcp2_window_filter_get_best(&rst->wf);
109   }
110 
111   return 0;
112 }
113 
ngtcp2_rst_update_rate_sample(ngtcp2_rst * rst,const ngtcp2_rtb_entry * ent,ngtcp2_tstamp ts)114 void ngtcp2_rst_update_rate_sample(ngtcp2_rst *rst, const ngtcp2_rtb_entry *ent,
115                                    ngtcp2_tstamp ts) {
116   ngtcp2_rs *rs = &rst->rs;
117 
118   rst->delivered += ent->pktlen;
119   rst->delivered_ts = ts;
120 
121   if (ent->rst.delivered > rs->prior_delivered) {
122     rs->prior_delivered = ent->rst.delivered;
123     rs->prior_ts = ent->rst.delivered_ts;
124     rs->is_app_limited = ent->rst.is_app_limited;
125     rs->send_elapsed = ent->ts - ent->rst.first_sent_ts;
126     rs->ack_elapsed = rst->delivered_ts - ent->rst.delivered_ts;
127     rs->tx_in_flight = ent->rst.tx_in_flight;
128     rs->prior_lost = ent->rst.lost;
129     rst->first_sent_ts = ent->ts;
130   }
131 }
132 
ngtcp2_rst_update_app_limited(ngtcp2_rst * rst,ngtcp2_conn_stat * cstat)133 void ngtcp2_rst_update_app_limited(ngtcp2_rst *rst, ngtcp2_conn_stat *cstat) {
134   (void)rst;
135   (void)cstat;
136   /* TODO Not implemented */
137 }
138