mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
bfc7bfd842
- [API Change] lsquic_engine_connect() returns pointer to the connection object. - [API Change] Add lsquic_conn_get_engine() to get engine object from connection object. - [API Change] Add lsquic_conn_status() to query connection status. - [API Change] Add add lsquic_conn_set_ctx(). - [API Change] Add new timestamp format, e.g. 2017-03-21 13:43:46.671345 - [OPTIMIZATION] Process handshake STREAM frames as soon as packet arrives. - [OPTIMIZATION] Do not compile expensive send controller sanity check by default. - [OPTIMIZATION] Add fast path to gquic_be_gen_reg_pkt_header. - [OPTIMIZATION] Only make squeeze function call if necessary. - [OPTIMIZATION] Speed up Q039 ACK frame parsing. - [OPTIMIZATION] Fit most used elements of packet_out into first 64 bytes. - [OPTIMIZATION] Keep track of scheduled bytes instead of calculating. - [OPTIMIZATION] Prefetch next unacked packet when processing ACK. - [OPTIMIZATION] Leverage fact that ACK ranges and unacked list are. ordered. - [OPTIMIZATION] Reduce function pointer use for STREAM frame generation - Fix: reset incoming streams that arrive after we send GOAWAY. - Fix: delay client on_new_conn() call until connection is fully set up. - Fixes to buffered packets logic: splitting, STREAM frame elision. - Fix: do not dispatch on_write callback if no packets are available. - Fix WINDOW_UPDATE send and resend logic. - Fix STREAM frame extension code. - Fix: Drop unflushed data when stream is reset. - Switch to tracking CWND using bytes rather than packets. - Fix TCP friendly adjustment in cubic. - Fix: do not generate invalid STOP_WAITING frames during high packet loss. - Pacer fixes.
145 lines
3.8 KiB
C
145 lines
3.8 KiB
C
/* Copyright (c) 2017 LiteSpeed Technologies Inc. See LICENSE. */
|
|
/*
|
|
* This is not really a test: this program prints out cwnd histogram
|
|
* for visual inspection.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/ioctl.h>
|
|
#include <termios.h>
|
|
#include <unistd.h>
|
|
|
|
#include "lsquic_types.h"
|
|
#include "lsquic_int_types.h"
|
|
#include "lsquic_cubic.h"
|
|
|
|
|
|
#define MS(n) ((n) * 1000) /* MS: Milliseconds */
|
|
|
|
enum event { EV_ACK, EV_LOSS, EV_TIMEOUT, };
|
|
|
|
static const char *const evstr[] = {
|
|
[EV_ACK] = "ACK",
|
|
[EV_LOSS] = "LOSS",
|
|
[EV_TIMEOUT] = "TIMEOUT",
|
|
};
|
|
|
|
struct rec
|
|
{
|
|
enum event event;
|
|
unsigned cwnd;
|
|
};
|
|
|
|
#define REC(ev) do { \
|
|
if (i >= n_recs_alloc) \
|
|
{ \
|
|
if (n_recs_alloc) \
|
|
n_recs_alloc *= 2; \
|
|
else \
|
|
n_recs_alloc = 20; \
|
|
recs = realloc(recs, n_recs_alloc * \
|
|
sizeof(recs[0])); \
|
|
} \
|
|
recs[i].event = ev; \
|
|
recs[i].cwnd = lsquic_cubic_get_cwnd(&cubic); \
|
|
if (max_cwnd < recs[i].cwnd) \
|
|
max_cwnd = recs[i].cwnd; \
|
|
} while (0)
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
int i, n, opt;
|
|
int n_recs_alloc = 0;
|
|
int app_limited = 0;
|
|
unsigned unit = 100; /* Default to 100 ms */
|
|
unsigned rtt_ms = 10; /* Default to 10 ms */
|
|
struct lsquic_cubic cubic;
|
|
struct rec *recs = NULL;
|
|
unsigned max_cwnd, width;
|
|
char *line;
|
|
struct winsize winsize;
|
|
enum cubic_flags flags;
|
|
|
|
lsquic_cubic_init(&cubic, 0);
|
|
max_cwnd = 0;
|
|
i = 0;
|
|
|
|
while (-1 != (opt = getopt(argc, argv, "s:u:r:f:l:A:L:T:")))
|
|
{
|
|
switch (opt)
|
|
{
|
|
case 's':
|
|
cubic.cu_ssthresh = atoi(optarg);
|
|
break;
|
|
case 'r':
|
|
rtt_ms = atoi(optarg);
|
|
break;
|
|
case 'f':
|
|
flags = atoi(optarg);
|
|
lsquic_cubic_init_ext(&cubic, 0, flags);
|
|
break;
|
|
case 'l':
|
|
app_limited = atoi(optarg);
|
|
break;
|
|
case 'A':
|
|
n = i + atoi(optarg);
|
|
for ( ; i < n; ++i)
|
|
{
|
|
lsquic_cubic_ack(&cubic, MS(unit * i), MS(rtt_ms), app_limited, 1370);
|
|
REC(EV_ACK);
|
|
}
|
|
break;
|
|
case 'L':
|
|
n = i + atoi(optarg);
|
|
for ( ; i < n; ++i)
|
|
{
|
|
lsquic_cubic_loss(&cubic);
|
|
REC(EV_LOSS);
|
|
}
|
|
break;
|
|
case 'T':
|
|
n = i + atoi(optarg);
|
|
for ( ; i < n; ++i)
|
|
{
|
|
lsquic_cubic_timeout(&cubic);
|
|
REC(EV_TIMEOUT);
|
|
}
|
|
break;
|
|
case 'u':
|
|
unit = atoi(optarg);
|
|
break;
|
|
default:
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
if (isatty(STDIN_FILENO))
|
|
{
|
|
if (0 == ioctl(STDIN_FILENO, TIOCGWINSZ, &winsize))
|
|
width = winsize.ws_col;
|
|
else
|
|
{
|
|
perror("ioctl");
|
|
width = 80;
|
|
}
|
|
}
|
|
else
|
|
width = 80;
|
|
|
|
width -= 5 /* cwnd */ + 1 /* space */ + 1 /* event type */ +
|
|
1 /* space */ + 1 /* newline */;
|
|
line = malloc(width);
|
|
memset(line, '+', width);
|
|
|
|
for (n = i, i = 0; i < n; ++i)
|
|
printf("%c % 5d %.*s\n", *evstr[recs[i].event], recs[i].cwnd,
|
|
(int) ((float) recs[i].cwnd / max_cwnd * width), line);
|
|
|
|
free(recs);
|
|
free(line);
|
|
|
|
return 0;
|
|
}
|