lsquic_cfcw.c revision 7d09751d
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
2#include <inttypes.h>
3#include <stdint.h>
4#include <stdlib.h>
5#include <string.h>
6#include <sys/queue.h>
7
8#include "lsquic.h"
9#include "lsquic_types.h"
10#include "lsquic_int_types.h"
11#include "lsquic_rtt.h"
12#include "lsquic_conn_flow.h"
13#include "lsquic_sfcw.h"
14#include "lsquic_varint.h"
15#include "lsquic_hq.h"
16#include "lsquic_hash.h"
17#include "lsquic_stream.h"
18#include "lsquic_conn_public.h"
19#include "lsquic_mm.h"
20#include "lsquic_engine_public.h"
21#include "lsquic_util.h"
22#include "lsquic_conn.h"
23#include "lsquic_ev_log.h"
24
25#define LSQUIC_LOGGER_MODULE LSQLM_CFCW
26#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(fc->cf_conn_pub->lconn)
27#include "lsquic_logger.h"
28
29
30void
31lsquic_cfcw_init (struct lsquic_cfcw *fc, struct lsquic_conn_public *cpub,
32                                                unsigned max_recv_window)
33{
34    memset(fc, 0, sizeof(*fc));
35    fc->cf_max_recv_win = max_recv_window;
36    fc->cf_conn_pub = cpub;
37    (void) lsquic_cfcw_fc_offsets_changed(fc);
38}
39
40
41static void
42cfcw_maybe_increase_max_window (struct lsquic_cfcw *fc)
43{
44    unsigned new_max_window;
45
46    new_max_window = fc->cf_max_recv_win * 2;
47
48    /* Do not increase past explicitly specified maximum */
49    if (new_max_window > fc->cf_conn_pub->enpub->enp_settings.es_max_cfcw)
50        new_max_window = fc->cf_conn_pub->enpub->enp_settings.es_max_cfcw;
51
52    if (new_max_window > fc->cf_max_recv_win)
53    {
54        LSQ_DEBUG("max window increase %u -> %u", fc->cf_max_recv_win,
55                                                            new_max_window);
56        EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID,
57            "max CFCW increase %u -> %u", fc->cf_max_recv_win,
58                                                            new_max_window);
59        fc->cf_max_recv_win = new_max_window;
60    }
61    else
62        LSQ_DEBUG("max window could use an increase, but we're stuck "
63            "at %u", fc->cf_max_recv_win);
64}
65
66
67int
68lsquic_cfcw_fc_offsets_changed (struct lsquic_cfcw *fc)
69{
70    lsquic_time_t now, since_last_update, srtt;
71
72    if (fc->cf_recv_off - fc->cf_read_off >= fc->cf_max_recv_win / 2)
73        return 0;
74
75    now = lsquic_time_now();
76    since_last_update = now - fc->cf_last_updated;
77    fc->cf_last_updated = now;
78
79    srtt = lsquic_rtt_stats_get_srtt(&fc->cf_conn_pub->rtt_stats);
80    if (since_last_update < srtt * 2)
81        cfcw_maybe_increase_max_window(fc);
82
83    fc->cf_recv_off = fc->cf_read_off + fc->cf_max_recv_win;
84    LSQ_DEBUG("recv_off changed: read_off: %"PRIu64"; recv_off: %"
85        PRIu64"", fc->cf_read_off, fc->cf_recv_off);
86    return 1;
87}
88
89
90int
91lsquic_cfcw_incr_max_recv_off (struct lsquic_cfcw *fc, uint64_t incr)
92{
93    if (fc->cf_max_recv_off + incr <= fc->cf_recv_off)
94    {
95        fc->cf_max_recv_off += incr;
96        LSQ_DEBUG("max_recv_off goes from %"PRIu64" to %"PRIu64"",
97                    fc->cf_max_recv_off - incr, fc->cf_max_recv_off);
98        return 1;
99    }
100    else
101    {
102        LSQ_WARN("flow control violation: received at offset %"PRIu64", while "
103            "flow control receive offset is %"PRIu64,
104            fc->cf_max_recv_off + incr, fc->cf_recv_off);
105        return 0;
106    }
107}
108
109
110void
111lsquic_cfcw_incr_read_off (struct lsquic_cfcw *fc, uint64_t incr)
112{
113    fc->cf_read_off += incr;
114    LSQ_DEBUG("read_off goes from %"PRIu64" to %"PRIu64,
115        fc->cf_read_off - incr, fc->cf_read_off);
116}
117