mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.5.1
- [BUGFIX] Fix double-free when emptying a packet number space. - [BUGFIX] http_server: fix md5sum handler: handle EOF correctly. - [BUGFIX] Use random values in bits 4 and 5 of the first byte of verneg packets (regression introduced in 2.5.0). - [OPTIMIZATION] Don't compile in expensive attq checks by default. - [OPTIMIZATION] http_server: compile regexes only once.
This commit is contained in:
parent
a0e1aeeee0
commit
1c9cee3ed5
8 changed files with 95 additions and 36 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2019-11-04
|
||||||
|
- 2.5.1
|
||||||
|
- [BUGFIX] Fix double-free when emptying a packet number space.
|
||||||
|
- [BUGFIX] http_server: fix md5sum handler: handle EOF correctly.
|
||||||
|
- [BUGFIX] Use random values in bits 4 and 5 of the first byte of
|
||||||
|
verneg packets (regression introduced in 2.5.0).
|
||||||
|
- [OPTIMIZATION] Don't compile in expensive attq checks by default.
|
||||||
|
- [OPTIMIZATION] http_server: compile regexes only once.
|
||||||
|
|
||||||
2019-10-31
|
2019-10-31
|
||||||
- 2.5.0
|
- 2.5.0
|
||||||
- [API] lsquic_engine_connect() can now be passed QUIC version to use.
|
- [API] lsquic_engine_connect() can now be passed QUIC version to use.
|
||||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
||||||
|
|
||||||
#define LSQUIC_MAJOR_VERSION 2
|
#define LSQUIC_MAJOR_VERSION 2
|
||||||
#define LSQUIC_MINOR_VERSION 5
|
#define LSQUIC_MINOR_VERSION 5
|
||||||
#define LSQUIC_PATCH_VERSION 0
|
#define LSQUIC_PATCH_VERSION 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Engine flags:
|
* Engine flags:
|
||||||
|
|
|
@ -72,7 +72,7 @@ attq_destroy (struct attq *q)
|
||||||
#define AE_RCHILD(i) (2 * i + 2)
|
#define AE_RCHILD(i) (2 * i + 2)
|
||||||
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#if LSQUIC_EXTRA_CHECKS && !defined(NDEBUG)
|
||||||
static void
|
static void
|
||||||
attq_verify (struct attq *q)
|
attq_verify (struct attq *q)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1846,7 +1846,7 @@ lsquic_ietf_v1_gen_ver_nego_pkt (unsigned char *buf, size_t bufsz,
|
||||||
if (need > bufsz)
|
if (need > bufsz)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*buf++ = 0x80 | 0x40 | (rand & 0xF);
|
*buf++ = 0x80 | 0x40 | rand;
|
||||||
memset(buf, 0, 4);
|
memset(buf, 0, 4);
|
||||||
buf += 4;
|
buf += 4;
|
||||||
|
|
||||||
|
|
|
@ -561,7 +561,7 @@ lsquic_Q046_gen_ver_nego_pkt (unsigned char *buf, size_t bufsz,
|
||||||
if (need > bufsz)
|
if (need > bufsz)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*buf++ = 0x80 | 0x40 | (rand & 0xF);
|
*buf++ = 0x80 | 0x40 | rand;
|
||||||
memset(buf, 0, 4);
|
memset(buf, 0, 4);
|
||||||
buf += 4;
|
buf += 4;
|
||||||
|
|
||||||
|
|
|
@ -491,7 +491,7 @@ prq_next_conn (struct pr_queue *prq)
|
||||||
len = gen_verneg(packet_out->po_data, max_bufsz(prq),
|
len = gen_verneg(packet_out->po_data, max_bufsz(prq),
|
||||||
/* Flip SCID/DCID here: */ &req->pr_dcid, &req->pr_scid,
|
/* Flip SCID/DCID here: */ &req->pr_dcid, &req->pr_scid,
|
||||||
prq->prq_enpub->enp_settings.es_versions,
|
prq->prq_enpub->enp_settings.es_versions,
|
||||||
get_rand_nybble(prq));
|
get_rand_byte(prq));
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
packet_out->po_data_sz = len;
|
packet_out->po_data_sz = len;
|
||||||
else
|
else
|
||||||
|
|
|
@ -2636,14 +2636,45 @@ lsquic_send_ctl_empty_pns (struct lsquic_send_ctl *ctl, enum packnum_space pns)
|
||||||
unsigned count, packet_sz;
|
unsigned count, packet_sz;
|
||||||
struct lsquic_packets_tailq *const *q;
|
struct lsquic_packets_tailq *const *q;
|
||||||
struct lsquic_packets_tailq *const queues[] = {
|
struct lsquic_packets_tailq *const queues[] = {
|
||||||
&ctl->sc_scheduled_packets,
|
|
||||||
&ctl->sc_unacked_packets[pns],
|
|
||||||
&ctl->sc_lost_packets,
|
&ctl->sc_lost_packets,
|
||||||
&ctl->sc_buffered_packets[0].bpq_packets,
|
&ctl->sc_buffered_packets[0].bpq_packets,
|
||||||
&ctl->sc_buffered_packets[1].bpq_packets,
|
&ctl->sc_buffered_packets[1].bpq_packets,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Don't bother with chain destruction, as all chains members are always
|
||||||
|
* within the same packet number space
|
||||||
|
*/
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
for (packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets); packet_out;
|
||||||
|
packet_out = next)
|
||||||
|
{
|
||||||
|
next = TAILQ_NEXT(packet_out, po_next);
|
||||||
|
if (pns == lsquic_packet_out_pns(packet_out))
|
||||||
|
{
|
||||||
|
send_ctl_maybe_renumber_sched_to_right(ctl, packet_out);
|
||||||
|
send_ctl_sched_remove(ctl, packet_out);
|
||||||
|
send_ctl_destroy_packet(ctl, packet_out);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (packet_out = TAILQ_FIRST(&ctl->sc_unacked_packets[pns]); packet_out;
|
||||||
|
packet_out = next)
|
||||||
|
{
|
||||||
|
next = TAILQ_NEXT(packet_out, po_next);
|
||||||
|
if (packet_out->po_flags & PO_LOSS_REC)
|
||||||
|
TAILQ_REMOVE(&ctl->sc_unacked_packets[pns], packet_out, po_next);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet_sz = packet_out_sent_sz(packet_out);
|
||||||
|
send_ctl_unacked_remove(ctl, packet_out, packet_sz);
|
||||||
|
lsquic_packet_out_ack_streams(packet_out);
|
||||||
|
}
|
||||||
|
send_ctl_destroy_packet(ctl, packet_out);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
for (q = queues; q < queues + sizeof(queues) / sizeof(queues[0]); ++q)
|
for (q = queues; q < queues + sizeof(queues) / sizeof(queues[0]); ++q)
|
||||||
for (packet_out = TAILQ_FIRST(*q); packet_out; packet_out = next)
|
for (packet_out = TAILQ_FIRST(*q); packet_out; packet_out = next)
|
||||||
{
|
{
|
||||||
|
@ -2651,16 +2682,6 @@ lsquic_send_ctl_empty_pns (struct lsquic_send_ctl *ctl, enum packnum_space pns)
|
||||||
if (pns == lsquic_packet_out_pns(packet_out))
|
if (pns == lsquic_packet_out_pns(packet_out))
|
||||||
{
|
{
|
||||||
TAILQ_REMOVE(*q, packet_out, po_next);
|
TAILQ_REMOVE(*q, packet_out, po_next);
|
||||||
if (*q == &ctl->sc_unacked_packets[pns])
|
|
||||||
{
|
|
||||||
if (0 == (packet_out->po_flags & PO_LOSS_REC))
|
|
||||||
{
|
|
||||||
packet_sz = packet_out_sent_sz(packet_out);
|
|
||||||
send_ctl_unacked_remove(ctl, packet_out, packet_sz);
|
|
||||||
lsquic_packet_out_ack_streams(packet_out);
|
|
||||||
}
|
|
||||||
send_ctl_destroy_chain(ctl, packet_out, &next);
|
|
||||||
}
|
|
||||||
send_ctl_destroy_packet(ctl, packet_out);
|
send_ctl_destroy_packet(ctl, packet_out);
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -646,11 +646,13 @@ struct req_map
|
||||||
enum {
|
enum {
|
||||||
RM_WANTBODY = 1 << 0,
|
RM_WANTBODY = 1 << 0,
|
||||||
RM_REGEX = 1 << 1,
|
RM_REGEX = 1 << 1,
|
||||||
|
RM_COMPILED = 1 << 2,
|
||||||
} flags;
|
} flags;
|
||||||
|
regex_t re;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct req_map req_maps[] =
|
static struct req_map req_maps[] =
|
||||||
{
|
{
|
||||||
{ GET, "/", IOH_INDEX_HTML, "200", 0, },
|
{ GET, "/", IOH_INDEX_HTML, "200", 0, },
|
||||||
{ GET, "/index.html", IOH_INDEX_HTML, "200", 0, },
|
{ GET, "/index.html", IOH_INDEX_HTML, "200", 0, },
|
||||||
|
@ -670,34 +672,55 @@ static const struct req_map req_maps[] =
|
||||||
#define MAX_MATCHES 5
|
#define MAX_MATCHES 5
|
||||||
|
|
||||||
|
|
||||||
static const struct req_map *
|
static void
|
||||||
find_handler (enum method method, const char *path, regmatch_t *matches)
|
init_map_regexes (void)
|
||||||
{
|
{
|
||||||
const struct req_map *map;
|
struct req_map *map;
|
||||||
regex_t re;
|
|
||||||
|
|
||||||
for (map = req_maps; map < req_maps + sizeof(req_maps)
|
for (map = req_maps; map < req_maps + sizeof(req_maps)
|
||||||
/ sizeof(req_maps[0]); ++map)
|
/ sizeof(req_maps[0]); ++map)
|
||||||
if (method == map->method)
|
|
||||||
{
|
|
||||||
if (map->flags & RM_REGEX)
|
if (map->flags & RM_REGEX)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
int s;
|
int s;
|
||||||
s =
|
s =
|
||||||
#endif
|
#endif
|
||||||
regcomp(&re, map->path, REG_EXTENDED|REG_ICASE);
|
regcomp(&map->re, map->path, REG_EXTENDED|REG_ICASE);
|
||||||
assert(0 == s);
|
assert(0 == s);
|
||||||
if (0 == regexec(&re, path, MAX_MATCHES + 1, matches, 0))
|
map->flags |= RM_COMPILED;
|
||||||
{
|
|
||||||
regfree(&re);
|
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
regfree(&re);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_map_regexes (void)
|
||||||
|
{
|
||||||
|
struct req_map *map;
|
||||||
|
|
||||||
|
for (map = req_maps; map < req_maps + sizeof(req_maps)
|
||||||
|
/ sizeof(req_maps[0]); ++map)
|
||||||
|
if (map->flags & RM_COMPILED)
|
||||||
|
{
|
||||||
|
regfree(&map->re);
|
||||||
|
map->flags &= ~RM_COMPILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct req_map *
|
||||||
|
find_handler (enum method method, const char *path, regmatch_t *matches)
|
||||||
|
{
|
||||||
|
const struct req_map *map;
|
||||||
|
|
||||||
|
for (map = req_maps; map < req_maps + sizeof(req_maps)
|
||||||
|
/ sizeof(req_maps[0]); ++map)
|
||||||
|
if (map->flags & RM_COMPILED)
|
||||||
|
{
|
||||||
|
if (0 == regexec(&map->re, path, MAX_MATCHES + 1, matches, 0))
|
||||||
|
return map;
|
||||||
}
|
}
|
||||||
else if (0 == strcasecmp(path, map->path))
|
else if (0 == strcasecmp(path, map->path))
|
||||||
return map;
|
return map;
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -868,6 +891,8 @@ http_server_interop_on_read (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
|
||||||
LSQ_ERROR("could not read from stream for MD5: %s", strerror(errno));
|
LSQ_ERROR("could not read from stream for MD5: %s", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (nw == 0)
|
||||||
|
st_h->interop_u.md5c.done = 1;
|
||||||
if (st_h->interop_u.md5c.done)
|
if (st_h->interop_u.md5c.done)
|
||||||
{
|
{
|
||||||
MD5_Final(md5sum, &st_h->interop_u.md5c.md5ctx);
|
MD5_Final(md5sum, &st_h->interop_u.md5c.md5ctx);
|
||||||
|
@ -1285,6 +1310,7 @@ main (int argc, char **argv)
|
||||||
if (!server_ctx.document_root)
|
if (!server_ctx.document_root)
|
||||||
{
|
{
|
||||||
LSQ_NOTICE("Document root is not set: start in Interop Mode");
|
LSQ_NOTICE("Document root is not set: start in Interop Mode");
|
||||||
|
init_map_regexes();
|
||||||
prog.prog_api.ea_stream_if = &interop_http_server_if;
|
prog.prog_api.ea_stream_if = &interop_http_server_if;
|
||||||
prog.prog_api.ea_hsi_if = &header_bypass_api;
|
prog.prog_api.ea_hsi_if = &header_bypass_api;
|
||||||
prog.prog_api.ea_hsi_ctx = NULL;
|
prog.prog_api.ea_hsi_ctx = NULL;
|
||||||
|
@ -1301,6 +1327,9 @@ main (int argc, char **argv)
|
||||||
s = prog_run(&prog);
|
s = prog_run(&prog);
|
||||||
prog_cleanup(&prog);
|
prog_cleanup(&prog);
|
||||||
|
|
||||||
|
if (!server_ctx.document_root)
|
||||||
|
free_map_regexes();
|
||||||
|
|
||||||
exit(0 == s ? EXIT_SUCCESS : EXIT_FAILURE);
|
exit(0 == s ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue