mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
7d09751dbb
- [BUGFIX] Initial packet size check for IETF mini conn applies to UDP payload, not QUIC packet. - Support old and new school loss_bits transport parameter. - Use Q run length of 64 as suggested in the loss bits Draft. - Undo square wave count when packet is delayed. - Code cleanup; minor fixes.
174 lines
5.2 KiB
C
174 lines
5.2 KiB
C
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc. See LICENSE. */
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/queue.h>
|
|
#ifndef WIN32
|
|
#include <sys/time.h>
|
|
#endif
|
|
|
|
#include "lsquic.h"
|
|
#include "lsquic_types.h"
|
|
#include "lsquic_packet_common.h"
|
|
#include "lsquic_parse.h"
|
|
#include "lsquic_parse_common.h"
|
|
#include "lsquic_mm.h"
|
|
#include "lsquic_packet_in.h"
|
|
#include "lsquic_engine_public.h"
|
|
#include "lsquic_version.h"
|
|
|
|
|
|
/* The struct is used to test both generation and parsing of version
|
|
* negotiation packet.
|
|
*/
|
|
struct gen_ver_nego_test {
|
|
int gvnt_lineno;
|
|
/* Generate: inputs; parse: outputs */
|
|
enum lsquic_version
|
|
gvnt_gen_ver;
|
|
uint64_t gvnt_cid;
|
|
unsigned gvnt_versions;
|
|
size_t gvnt_bufsz;
|
|
/* Generate: outputs; parse: inputs */
|
|
int gvnt_len; /* Retval */
|
|
char gvnt_buf[0x40]; /* Contents */
|
|
};
|
|
|
|
|
|
static const struct gen_ver_nego_test tests[] = {
|
|
|
|
{ .gvnt_lineno = __LINE__,
|
|
.gvnt_cid = 0x0102030405060708UL,
|
|
.gvnt_versions = (1 << LSQVER_039),
|
|
.gvnt_gen_ver = LSQVER_039,
|
|
.gvnt_bufsz = 13,
|
|
.gvnt_len = 13,
|
|
.gvnt_buf = {
|
|
PACKET_PUBLIC_FLAGS_VERSION|
|
|
PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID,
|
|
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Connection ID */
|
|
'Q', '0', '3', '9',
|
|
},
|
|
},
|
|
|
|
{ .gvnt_lineno = __LINE__,
|
|
.gvnt_cid = 0x0102030405060708UL,
|
|
.gvnt_versions = (1 << LSQVER_039),
|
|
.gvnt_gen_ver = LSQVER_039,
|
|
.gvnt_bufsz = 12,
|
|
.gvnt_len = -1, /* Buffer size is too small */
|
|
},
|
|
|
|
{ .gvnt_lineno = __LINE__,
|
|
.gvnt_cid = 0x0102030405060708UL,
|
|
.gvnt_versions = (1 << LSQVER_039) | (1 << N_LSQVER),
|
|
.gvnt_gen_ver = LSQVER_039,
|
|
.gvnt_bufsz = 20,
|
|
.gvnt_len = -1, /* Invalid version specified in the bitmask */
|
|
},
|
|
|
|
{ .gvnt_lineno = __LINE__,
|
|
.gvnt_cid = 0x0102030405060708UL,
|
|
.gvnt_versions = (1 << LSQVER_039) | (1 << LSQVER_043),
|
|
.gvnt_gen_ver = LSQVER_039,
|
|
.gvnt_bufsz = 17,
|
|
.gvnt_len = 17,
|
|
.gvnt_buf = {
|
|
PACKET_PUBLIC_FLAGS_VERSION|
|
|
PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID,
|
|
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Connection ID */
|
|
'Q', '0', '3', '9',
|
|
'Q', '0', '4', '3',
|
|
},
|
|
},
|
|
|
|
};
|
|
|
|
|
|
static void
|
|
test_parsing_ver_nego (const struct gen_ver_nego_test *gvnt)
|
|
{
|
|
int s;
|
|
lsquic_packet_in_t *packet_in;
|
|
struct lsquic_mm mm;
|
|
struct ver_iter vi;
|
|
lsquic_ver_tag_t ver_tag;
|
|
enum lsquic_version version;
|
|
struct packin_parse_state ppstate;
|
|
unsigned version_bitmask = gvnt->gvnt_versions;
|
|
|
|
lsquic_mm_init(&mm);
|
|
packet_in = lsquic_mm_get_packet_in(&mm);
|
|
packet_in->pi_data = lsquic_mm_get_packet_in_buf(&mm, 1370);
|
|
packet_in->pi_flags |= PI_OWN_DATA;
|
|
memcpy(packet_in->pi_data, gvnt->gvnt_buf, gvnt->gvnt_len);
|
|
s = lsquic_parse_packet_in_begin(packet_in, gvnt->gvnt_len, 0, GQUIC_CID_LEN, &ppstate);
|
|
assert(s == 0);
|
|
|
|
for (s = packet_in_ver_first(packet_in, &vi, &ver_tag); s;
|
|
s = packet_in_ver_next(&vi, &ver_tag))
|
|
{
|
|
version = lsquic_tag2ver(ver_tag);
|
|
assert(version < N_LSQVER);
|
|
assert(version_bitmask & (1 << version));
|
|
version_bitmask &= ~(1 << version);
|
|
}
|
|
|
|
assert(0 == version_bitmask);
|
|
|
|
lsquic_mm_put_packet_in(&mm, packet_in);
|
|
lsquic_mm_cleanup(&mm);
|
|
}
|
|
|
|
|
|
static void
|
|
run_gvnt (int i)
|
|
{
|
|
const struct gen_ver_nego_test *const gvnt = &tests[i];
|
|
lsquic_cid_t scid, dcid;
|
|
int len;
|
|
|
|
memset(&dcid, 0, sizeof(dcid));
|
|
dcid.len = sizeof(gvnt->gvnt_cid);
|
|
memcpy(dcid.idbuf, &gvnt->gvnt_cid, sizeof(gvnt->gvnt_cid));
|
|
|
|
unsigned char out[0x40];
|
|
assert(sizeof(out) <= sizeof(gvnt->gvnt_buf)); /* Internal sanity check */
|
|
|
|
if ((1 << gvnt->gvnt_gen_ver) & LSQUIC_GQUIC_HEADER_VERSIONS)
|
|
len = lsquic_gquic_gen_ver_nego_pkt(out, gvnt->gvnt_bufsz, &dcid,
|
|
gvnt->gvnt_versions);
|
|
else
|
|
{
|
|
/* XXX this is never executed, as there is no test case for this */
|
|
scid = (lsquic_cid_t) { .len = 0, };
|
|
len = lsquic_Q046_gen_ver_nego_pkt(out, gvnt->gvnt_bufsz, &dcid,
|
|
&scid, gvnt->gvnt_versions, ((unsigned char) rand()) & 0xF);
|
|
}
|
|
assert(("Packet length is correct", len == gvnt->gvnt_len));
|
|
|
|
if (gvnt->gvnt_len > 0)
|
|
{
|
|
if ((1 << gvnt->gvnt_gen_ver) & LSQUIC_GQUIC_HEADER_VERSIONS)
|
|
assert(("Packet contents are correct",
|
|
0 == memcmp(out, gvnt->gvnt_buf, gvnt->gvnt_len)));
|
|
else
|
|
{
|
|
assert(("Packet contents are correct",
|
|
0 == memcmp(out + 1, gvnt->gvnt_buf + 1, gvnt->gvnt_len - 1)));
|
|
assert(out[0] & 0x80); /* Other 7 bits are random */
|
|
}
|
|
test_parsing_ver_nego(gvnt);
|
|
}
|
|
}
|
|
|
|
|
|
int
|
|
main (void)
|
|
{
|
|
unsigned i;
|
|
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
|
|
run_gvnt(i);
|
|
return 0;
|
|
}
|