lsquic_cfcw.c revision 8ae5ecb4
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_INFO("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