mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
- Add echo client and server to the distibution. - Add MD5 client and server to the distibution. - Fix http_client: check command-line arguments better, prevent crash. - Fix IETF conn: can_write_ack() should only care about APP PNS. - Client: delay stream creation until handshake succeds. - Reset HTTP stream whose write end is closed prematurely. - Fix tickable(): mirror behavior of tick() wrt buffered packets. - Log reason why engine is tickable.
228 lines
5.1 KiB
C
228 lines
5.1 KiB
C
/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <sys/queue.h>
|
|
|
|
#include "lsquic.h"
|
|
#include "lsquic_types.h"
|
|
#include "lsquic_int_types.h"
|
|
#include "lsquic_attq.h"
|
|
#include "lsquic_hash.h"
|
|
#include "lsquic_conn.h"
|
|
|
|
|
|
static char curiosity[] =
|
|
"Dogs say cats love too much, are irresponsible,"
|
|
"are changeable, marry too many wives,"
|
|
"desert their children, chill all dinner tables"
|
|
"with tales of their nine lives."
|
|
"Well, they are lucky. Let them be"
|
|
"nine-lived and contradictory,"
|
|
"curious enough to change, prepared to pay"
|
|
"the cat price, which is to die"
|
|
"and die again and again,"
|
|
"each time with no less pain."
|
|
"A cat minority of one"
|
|
"is all that can be counted on"
|
|
"to tell the truth. And what cats have to tell"
|
|
"on each return from hell"
|
|
"is this: that dying is what the living do,"
|
|
"that dying is what the loving do,"
|
|
"and that dead dogs are those who do not know"
|
|
"that dying is what, to live, each has to do."
|
|
;
|
|
|
|
|
|
static int
|
|
cmp_chars_asc (const void *ap, const void *bp)
|
|
{
|
|
char a = * (char *) ap;
|
|
char b = * (char *) bp;
|
|
return (a > b) - (b > a);
|
|
}
|
|
|
|
|
|
static int
|
|
cmp_chars_desc (const void *ap, const void *bp)
|
|
{
|
|
char a = * (char *) ap;
|
|
char b = * (char *) bp;
|
|
return (a < b) - (b < a);
|
|
}
|
|
|
|
|
|
enum sort_action { SORT_NONE, SORT_ASC, SORT_DESC, };
|
|
|
|
static void
|
|
test_attq_ordering (enum sort_action sa)
|
|
{
|
|
struct attq *q;
|
|
struct lsquic_conn *conns, *conn;
|
|
const struct attq_elem *next_attq;
|
|
lsquic_time_t prev;
|
|
lsquic_time_t t;
|
|
unsigned i;
|
|
int s;
|
|
|
|
switch (sa)
|
|
{
|
|
case SORT_NONE:
|
|
break;
|
|
case SORT_ASC:
|
|
qsort(curiosity, sizeof(curiosity) *
|
|
sizeof(curiosity[0]), sizeof(curiosity[0]), cmp_chars_asc);
|
|
break;
|
|
case SORT_DESC:
|
|
qsort(curiosity, sizeof(curiosity) *
|
|
sizeof(curiosity[0]), sizeof(curiosity[0]), cmp_chars_desc);
|
|
break;
|
|
}
|
|
|
|
q = attq_create();
|
|
|
|
for (i = 0; i < sizeof(curiosity); ++i)
|
|
{
|
|
unsigned count_before = attq_count_before(q, curiosity[i]);
|
|
assert(count_before == 0);
|
|
}
|
|
|
|
conns = calloc(sizeof(curiosity), sizeof(conns[0]));
|
|
for (i = 0; i < sizeof(curiosity); ++i)
|
|
{
|
|
s = attq_add(q, &conns[i], (lsquic_time_t) curiosity[i], 0);
|
|
assert(s == 0);
|
|
}
|
|
|
|
for (i = 0; i < sizeof(curiosity); ++i)
|
|
assert(conns[i].cn_attq_elem);
|
|
|
|
if (sa == SORT_ASC)
|
|
{
|
|
unsigned counts[ sizeof(curiosity) ];
|
|
unsigned count_before;
|
|
counts[0] = 0;
|
|
for (i = 1; i < sizeof(curiosity); ++i)
|
|
{
|
|
if (curiosity[i - 1] == curiosity[i])
|
|
counts[i] = counts[i - 1];
|
|
else
|
|
counts[i] = i;
|
|
}
|
|
for (i = 1; i < sizeof(curiosity); ++i)
|
|
{
|
|
count_before = attq_count_before(q, curiosity[i]);
|
|
assert(count_before == counts[i]);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < sizeof(curiosity); ++i)
|
|
{
|
|
next_attq = attq_next(q);
|
|
assert(next_attq);
|
|
t = next_attq->ae_adv_time;
|
|
if (i > 0)
|
|
assert(t >= prev);
|
|
prev = t;
|
|
conn = attq_pop(q, ~0ULL);
|
|
assert(conn);
|
|
}
|
|
|
|
next_attq = attq_next(q);
|
|
assert(!next_attq);
|
|
conn = attq_pop(q, ~0ULL);
|
|
assert(!conn);
|
|
|
|
free(conns);
|
|
attq_destroy(q);
|
|
}
|
|
|
|
|
|
/* Filter up */
|
|
static void
|
|
test_attq_removal_1 (void)
|
|
{
|
|
struct attq *q;
|
|
struct lsquic_conn *conns;
|
|
|
|
q = attq_create();
|
|
conns = calloc(6, sizeof(conns[0]));
|
|
|
|
attq_add(q, &conns[0], 1, 0);
|
|
attq_add(q, &conns[1], 4, 0);
|
|
attq_add(q, &conns[2], 2, 0);
|
|
attq_add(q, &conns[3], 5, 0);
|
|
attq_add(q, &conns[4], 6, 0);
|
|
attq_add(q, &conns[5], 3, 0);
|
|
|
|
attq_remove(q, &conns[3]);
|
|
|
|
free(conns);
|
|
attq_destroy(q);
|
|
}
|
|
|
|
|
|
/* Filter down */
|
|
static void
|
|
test_attq_removal_2 (void)
|
|
{
|
|
struct attq *q;
|
|
struct lsquic_conn *conns;
|
|
|
|
q = attq_create();
|
|
conns = calloc(9, sizeof(conns[0]));
|
|
|
|
attq_add(q, &conns[0], 1, 0);
|
|
attq_add(q, &conns[1], 5, 0);
|
|
attq_add(q, &conns[2], 6, 0);
|
|
attq_add(q, &conns[3], 9, 0);
|
|
attq_add(q, &conns[4], 11, 0);
|
|
attq_add(q, &conns[5], 8, 0);
|
|
attq_add(q, &conns[6], 15, 0);
|
|
attq_add(q, &conns[7], 17, 0);
|
|
attq_add(q, &conns[8], 21, 0);
|
|
|
|
attq_remove(q, &conns[1]);
|
|
|
|
free(conns);
|
|
attq_destroy(q);
|
|
}
|
|
|
|
|
|
/* Filter up */
|
|
static void
|
|
test_attq_removal_3 (void)
|
|
{
|
|
struct attq *q;
|
|
struct lsquic_conn *conns;
|
|
|
|
q = attq_create();
|
|
conns = calloc(9, sizeof(conns[0]));
|
|
|
|
attq_add(q, &conns[0], 1, 0);
|
|
attq_add(q, &conns[1], 9, 0);
|
|
attq_add(q, &conns[2], 22, 0);
|
|
attq_add(q, &conns[3], 17, 0);
|
|
attq_add(q, &conns[4], 11, 0);
|
|
attq_add(q, &conns[5], 33, 0);
|
|
attq_add(q, &conns[6], 27, 0);
|
|
attq_add(q, &conns[7], 21, 0);
|
|
attq_add(q, &conns[8], 19, 0);
|
|
|
|
attq_remove(q, &conns[1]);
|
|
|
|
free(conns);
|
|
attq_destroy(q);
|
|
}
|
|
|
|
|
|
int
|
|
main (void)
|
|
{
|
|
test_attq_ordering(SORT_NONE);
|
|
test_attq_ordering(SORT_ASC);
|
|
test_attq_ordering(SORT_DESC);
|
|
test_attq_removal_1();
|
|
test_attq_removal_2();
|
|
test_attq_removal_3();
|
|
return 0;
|
|
}
|