Date: Sat, 16 Nov 2019 12:00:23 +0000 (UTC) From: Michael Tuexen <tuexen@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354774 - head/sys/netinet/cc Message-ID: <201911161200.xAGC0NqW006340@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tuexen Date: Sat Nov 16 12:00:22 2019 New Revision: 354774 URL: https://svnweb.freebsd.org/changeset/base/354774 Log: Add boundary and overflow checks to the formulas used in the TCP CUBIC congestion control module. Submitted by: Richard Scheffenegger Reviewed by: rgrimes@ Differential Revision: https://reviews.freebsd.org/D19118 Modified: head/sys/netinet/cc/cc_cubic.c head/sys/netinet/cc/cc_cubic.h Modified: head/sys/netinet/cc/cc_cubic.c ============================================================================== --- head/sys/netinet/cc/cc_cubic.c Sat Nov 16 11:57:12 2019 (r354773) +++ head/sys/netinet/cc/cc_cubic.c Sat Nov 16 12:00:22 2019 (r354774) @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/kernel.h> +#include <sys/limits.h> #include <sys/malloc.h> #include <sys/module.h> #include <sys/socket.h> @@ -140,7 +141,14 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type) cubic_data->min_rtt_ticks == TCPTV_SRTTBASE) newreno_cc_algo.ack_received(ccv, type); else { - ticks_since_cong = ticks - cubic_data->t_last_cong; + if ((ticks_since_cong = + ticks - cubic_data->t_last_cong) < 0) { + /* + * dragging t_last_cong along + */ + ticks_since_cong = INT_MAX; + cubic_data->t_last_cong = ticks - INT_MAX; + } /* * The mean RTT is used to best reflect the equations in @@ -159,12 +167,14 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type) ccv->flags &= ~CCF_ABC_SENTAWND; - if (w_cubic_next < w_tf) + if (w_cubic_next < w_tf) { /* * TCP-friendly region, follow tf * cwnd growth. */ - CCV(ccv, snd_cwnd) = w_tf; + if (CCV(ccv, snd_cwnd) < w_tf) + CCV(ccv, snd_cwnd) = ulmin(w_tf, INT_MAX); + } else if (CCV(ccv, snd_cwnd) < w_cubic_next) { /* @@ -172,12 +182,14 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type) * cwnd growth. */ if (V_tcp_do_rfc3465) - CCV(ccv, snd_cwnd) = w_cubic_next; + CCV(ccv, snd_cwnd) = ulmin(w_cubic_next, + INT_MAX); else - CCV(ccv, snd_cwnd) += ((w_cubic_next - + CCV(ccv, snd_cwnd) += ulmax(1, + ((ulmin(w_cubic_next, INT_MAX) - CCV(ccv, snd_cwnd)) * CCV(ccv, t_maxseg)) / - CCV(ccv, snd_cwnd); + CCV(ccv, snd_cwnd)); } /* Modified: head/sys/netinet/cc/cc_cubic.h ============================================================================== --- head/sys/netinet/cc/cc_cubic.h Sat Nov 16 11:57:12 2019 (r354773) +++ head/sys/netinet/cc/cc_cubic.h Sat Nov 16 12:00:22 2019 (r354774) @@ -41,6 +41,8 @@ #ifndef _NETINET_CC_CUBIC_H_ #define _NETINET_CC_CUBIC_H_ +#include <sys/limits.h> + /* Number of bits of precision for fixed point math calcs. */ #define CUBIC_SHIFT 8 @@ -70,6 +72,12 @@ /* Don't trust s_rtt until this many rtt samples have been taken. */ #define CUBIC_MIN_RTT_SAMPLES 8 +/* + * (2^21)^3 is long max. Dividing (2^63) by Cubic_C_factor + * and taking cube-root yields 448845 as the effective useful limit + */ +#define CUBED_ROOT_MAX_ULONG 448845 + /* Userland only bits. */ #ifndef _KERNEL @@ -172,8 +180,13 @@ cubic_cwnd(int ticks_since_cong, unsigned long wmax, u /* K is in fixed point form with CUBIC_SHIFT worth of precision. */ /* t - K, with CUBIC_SHIFT worth of precision. */ - cwnd = ((int64_t)(ticks_since_cong << CUBIC_SHIFT) - (K * hz)) / hz; + cwnd = (((int64_t)ticks_since_cong << CUBIC_SHIFT) - (K * hz)) / hz; + if (cwnd > CUBED_ROOT_MAX_ULONG) + return INT_MAX; + if (cwnd < -CUBED_ROOT_MAX_ULONG) + return 0; + /* (t - K)^3, with CUBIC_SHIFT^3 worth of precision. */ cwnd *= (cwnd * cwnd); @@ -183,9 +196,13 @@ cubic_cwnd(int ticks_since_cong, unsigned long wmax, u * CUBIC_SHIFT included in the value. 3 from the cubing of cwnd above, * and an extra from multiplying through by CUBIC_C_FACTOR. */ - cwnd = ((cwnd * CUBIC_C_FACTOR * smss) >> CUBIC_SHIFT_4) + wmax; - return ((unsigned long)cwnd); + cwnd = ((cwnd * CUBIC_C_FACTOR) >> CUBIC_SHIFT_4) * smss + wmax; + + /* + * for negative cwnd, limiting to zero as lower bound + */ + return (lmax(0,cwnd)); } /* @@ -223,8 +240,10 @@ tf_cwnd(int ticks_since_cong, int rtt_ticks, unsigned { /* Equation 4 of I-D. */ - return (((wmax * CUBIC_BETA) + (((THREE_X_PT3 * ticks_since_cong * - smss) << CUBIC_SHIFT) / TWO_SUB_PT3 / rtt_ticks)) >> CUBIC_SHIFT); + return (((wmax * CUBIC_BETA) + + (((THREE_X_PT3 * (unsigned long)ticks_since_cong * + (unsigned long)smss) << CUBIC_SHIFT) / (TWO_SUB_PT3 * rtt_ticks))) + >> CUBIC_SHIFT); } #endif /* _NETINET_CC_CUBIC_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911161200.xAGC0NqW006340>