1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
20e7c6aadSDmitri Tikhonov#include <assert.h>
30e7c6aadSDmitri Tikhonov#include <stdio.h>
40e7c6aadSDmitri Tikhonov#include <stdlib.h>
50e7c6aadSDmitri Tikhonov#include <string.h>
65392f7a3SLiteSpeed Tech#include <sys/queue.h>
7461e84d8SAmol Deshpande#ifndef WIN32
80e7c6aadSDmitri Tikhonov#include <unistd.h>
9461e84d8SAmol Deshpande#else
10461e84d8SAmol Deshpande#include <getopt.h>
11461e84d8SAmol Deshpande#endif
120e7c6aadSDmitri Tikhonov
130e7c6aadSDmitri Tikhonov#include "lsquic.h"
140e7c6aadSDmitri Tikhonov#include "lsquic_int_types.h"
155392f7a3SLiteSpeed Tech#include "lsquic_cong_ctl.h"
160e7c6aadSDmitri Tikhonov#include "lsquic_cubic.h"
170e7c6aadSDmitri Tikhonov#include "lsquic_logger.h"
185392f7a3SLiteSpeed Tech#include "lsquic_hash.h"
195392f7a3SLiteSpeed Tech#include "lsquic_conn.h"
205392f7a3SLiteSpeed Tech#include "lsquic_sfcw.h"
215392f7a3SLiteSpeed Tech#include "lsquic_conn_flow.h"
225392f7a3SLiteSpeed Tech#include "lsquic_varint.h"
235392f7a3SLiteSpeed Tech#include "lsquic_hq.h"
245392f7a3SLiteSpeed Tech#include "lsquic_stream.h"
255392f7a3SLiteSpeed Tech#include "lsquic_rtt.h"
265392f7a3SLiteSpeed Tech#include "lsquic_conn_public.h"
275392f7a3SLiteSpeed Tech#include "lsquic_packet_common.h"
285392f7a3SLiteSpeed Tech#include "lsquic_packet_out.h"
295392f7a3SLiteSpeed Tech
30f07b3eaeSTyler Young//static const struct cong_ctl_if *const cci = &lsquic_cong_cubic_if; // will not work on MSVC
31f07b3eaeSTyler Young#define cci ((const struct cong_ctl_if *const)&lsquic_cong_cubic_if)
320e7c6aadSDmitri Tikhonov
330e7c6aadSDmitri Tikhonovstatic void
340e7c6aadSDmitri Tikhonovtest_post_quiescence_explosion (void)
350e7c6aadSDmitri Tikhonov{
360e7c6aadSDmitri Tikhonov    struct lsquic_cubic cubic;
370e7c6aadSDmitri Tikhonov    lsquic_time_t const rtt = 10000;
380e7c6aadSDmitri Tikhonov    lsquic_time_t t = 12345600;
395392f7a3SLiteSpeed Tech    struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 8);
405392f7a3SLiteSpeed Tech    struct lsquic_conn_public conn_pub = { .lconn = &lconn, };
410e7c6aadSDmitri Tikhonov    int i;
42fb3e20e0SDmitri Tikhonov    struct lsquic_packet_out packet_out; memset(&packet_out, 0, sizeof(packet_out));
430e7c6aadSDmitri Tikhonov
445392f7a3SLiteSpeed Tech    cci->cci_init(&cubic, &conn_pub, 0);
450e7c6aadSDmitri Tikhonov    cubic.cu_ssthresh = cubic.cu_cwnd = 32 * 1370;
460e7c6aadSDmitri Tikhonov
470e7c6aadSDmitri Tikhonov    for (i = 0; i < 10; ++i)
485392f7a3SLiteSpeed Tech    {
495392f7a3SLiteSpeed Tech        packet_out.po_sent = t - rtt;
505392f7a3SLiteSpeed Tech        cci->cci_ack(&cubic, &packet_out, 1370, t, 0);
515392f7a3SLiteSpeed Tech    }
520e7c6aadSDmitri Tikhonov
535392f7a3SLiteSpeed Tech    assert(cci->cci_get_cwnd(&cubic) == 47026);
540e7c6aadSDmitri Tikhonov
550e7c6aadSDmitri Tikhonov    t += 25 * 1000 * 1000;
565392f7a3SLiteSpeed Tech    cci->cci_was_quiet(&cubic, t, 0 /* bytes in flight (unused) */);
575392f7a3SLiteSpeed Tech    packet_out.po_sent = t - rtt;
585392f7a3SLiteSpeed Tech    cci->cci_ack(&cubic, &packet_out, 1370, t, 0);
595392f7a3SLiteSpeed Tech    assert(cci->cci_get_cwnd(&cubic) == 47060);
600e7c6aadSDmitri Tikhonov
610e7c6aadSDmitri Tikhonov    t += 2 * 1000 * 1000;
625392f7a3SLiteSpeed Tech    packet_out.po_sent = t - rtt;
635392f7a3SLiteSpeed Tech    cci->cci_ack(&cubic, &packet_out, 1370, t, 0);
640e7c6aadSDmitri Tikhonov}
650e7c6aadSDmitri Tikhonov
660e7c6aadSDmitri Tikhonov
670e7c6aadSDmitri Tikhonovstatic void
680e7c6aadSDmitri Tikhonovtest_post_quiescence_explosion2 (void)
690e7c6aadSDmitri Tikhonov{
700e7c6aadSDmitri Tikhonov    struct lsquic_cubic cubic;
710e7c6aadSDmitri Tikhonov    lsquic_time_t const rtt = 10000;
720e7c6aadSDmitri Tikhonov    lsquic_time_t t = 12345600;
735392f7a3SLiteSpeed Tech    struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 8);
745392f7a3SLiteSpeed Tech    struct lsquic_conn_public conn_pub = { .lconn = &lconn, };
750e7c6aadSDmitri Tikhonov    int i;
76fb3e20e0SDmitri Tikhonov    struct lsquic_packet_out packet_out; memset(&packet_out, 0, sizeof(packet_out));
770e7c6aadSDmitri Tikhonov
785392f7a3SLiteSpeed Tech    cci->cci_init(&cubic, &conn_pub, 0);
790e7c6aadSDmitri Tikhonov    cubic.cu_ssthresh = cubic.cu_cwnd = 32 * 1370;
800e7c6aadSDmitri Tikhonov
810e7c6aadSDmitri Tikhonov    for (i = 0; i < 10; ++i)
825392f7a3SLiteSpeed Tech    {
835392f7a3SLiteSpeed Tech        packet_out.po_sent = t - rtt;
845392f7a3SLiteSpeed Tech        cci->cci_ack(&cubic, &packet_out, 1370, t, 1);
855392f7a3SLiteSpeed Tech    }
860e7c6aadSDmitri Tikhonov
875392f7a3SLiteSpeed Tech    assert(cci->cci_get_cwnd(&cubic) == 45300);
880e7c6aadSDmitri Tikhonov
890e7c6aadSDmitri Tikhonov    t += 25 * 1000 * 1000;
905392f7a3SLiteSpeed Tech    cci->cci_was_quiet(&cubic, t, 0 /* bytes in flight (unused) */);
915392f7a3SLiteSpeed Tech    packet_out.po_sent = t - rtt;
925392f7a3SLiteSpeed Tech    cci->cci_ack(&cubic, &packet_out, 1370, t, 0);
935392f7a3SLiteSpeed Tech    assert(cci->cci_get_cwnd(&cubic) == 46754);
940e7c6aadSDmitri Tikhonov
950e7c6aadSDmitri Tikhonov    t += 2 * 1000 * 1000;
965392f7a3SLiteSpeed Tech    packet_out.po_sent = t - rtt;
975392f7a3SLiteSpeed Tech    cci->cci_ack(&cubic, &packet_out, 1370, t, 1);
980e7c6aadSDmitri Tikhonov}
990e7c6aadSDmitri Tikhonov
1000e7c6aadSDmitri Tikhonov
1010e7c6aadSDmitri Tikhonov
1020e7c6aadSDmitri Tikhonovint
1030e7c6aadSDmitri Tikhonovmain (int argc, char **argv)
1040e7c6aadSDmitri Tikhonov{
1050e7c6aadSDmitri Tikhonov    int opt;
1060e7c6aadSDmitri Tikhonov
1070e7c6aadSDmitri Tikhonov    lsquic_log_to_fstream(stderr, LLTS_NONE);
1080e7c6aadSDmitri Tikhonov
1090e7c6aadSDmitri Tikhonov    while (-1 != (opt = getopt(argc, argv, "l:")))
1100e7c6aadSDmitri Tikhonov    {
1110e7c6aadSDmitri Tikhonov        switch (opt)
1120e7c6aadSDmitri Tikhonov        {
1130e7c6aadSDmitri Tikhonov        case 'l':
1140e7c6aadSDmitri Tikhonov            lsquic_logger_lopt(optarg);
1150e7c6aadSDmitri Tikhonov            break;
1160e7c6aadSDmitri Tikhonov        default:
1170e7c6aadSDmitri Tikhonov            exit(EXIT_FAILURE);
1180e7c6aadSDmitri Tikhonov            break;
1190e7c6aadSDmitri Tikhonov        }
1200e7c6aadSDmitri Tikhonov    }
1210e7c6aadSDmitri Tikhonov
1220e7c6aadSDmitri Tikhonov    test_post_quiescence_explosion();
1230e7c6aadSDmitri Tikhonov    test_post_quiescence_explosion2();
1240e7c6aadSDmitri Tikhonov
1250e7c6aadSDmitri Tikhonov    exit(EXIT_SUCCESS);
1260e7c6aadSDmitri Tikhonov}
127