Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1f39d53

Browse files
committed
Release 4.2.0
1 parent 5915733 commit 1f39d53

File tree

11 files changed

+452
-29
lines changed

11 files changed

+452
-29
lines changed

‎CHANGELOG‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
2025年02月18日
2+
- 4.2.0
3+
- Address hash flood attack for lsquic_hash by switching to rapidhash with stronger random seed.
4+
- Fix packet packing problem for post-quantum support.
5+
- Add configuration to control version negotiation and amplification factor.
6+
17
2024年12月16日
28
- 4.1.0
39
- Update to ls-qpack v2.6.1 to fix a infinite loop.
4-
- Fix packet packing problem for post-quantum support
510
- Add lsquic_engine_get_conns_count() API
611
- Updated ea_generate_scid() API
712
- Fix retry packet SCID generation to follow engine API.

‎docs/conf.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
author = u'LiteSpeed Technologies'
2525

2626
# The short X.Y version
27-
version = u'4.1'
27+
version = u'4.2'
2828
# The full version, including alpha/beta/rc tags
29-
release = u'4.1.0'
29+
release = u'4.2.0'
3030

3131

3232
# -- General configuration ---------------------------------------------------

‎include/lsquic.h‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ extern "C" {
2626
#endif
2727

2828
#define LSQUIC_MAJOR_VERSION 4
29-
#define LSQUIC_MINOR_VERSION 1
29+
#define LSQUIC_MINOR_VERSION 2
3030
#define LSQUIC_PATCH_VERSION 0
3131

3232
/**
@@ -335,6 +335,12 @@ typedef struct ssl_ctx_st * (*lsquic_lookup_cert_f)(
335335
*/
336336
#define LSQUIC_DF_SEND_PRST 0
337337

338+
/**
339+
* By default, LSQUIC will send Version Negotiation packets in response to
340+
* packets that specify unknown versions.
341+
*/
342+
#define LSQUIC_DF_SEND_VERNEG 1
343+
338344
/** By default, infinite loop checks are turned on */
339345
#define LSQUIC_DF_PROGRESS_CHECK 1000
340346

@@ -398,6 +404,9 @@ typedef struct ssl_ctx_st * (*lsquic_lookup_cert_f)(
398404
/** Turn on timestamp extension by default */
399405
#define LSQUIC_DF_TIMESTAMPS 1
400406

407+
/** default anti-amplification factor is 3 */
408+
#define LSQUIC_DF_AMP_FACTOR 3
409+
401410
/* Use Adaptive CC by default */
402411
#define LSQUIC_DF_CC_ALGO 3
403412

@@ -1092,6 +1101,20 @@ struct lsquic_engine_settings {
10921101
* Default value is @ref LSQUIC_DF_CHECK_TP_SANITY
10931102
*/
10941103
int es_check_tp_sanity;
1104+
1105+
/**
1106+
* This is the anti-amplification factor when peer address has not be verified.
1107+
*
1108+
* Default value is @ref LSQUIC_DF_AMP_FACTOR
1109+
*/
1110+
int es_amp_factor;
1111+
1112+
/**
1113+
* If set to true value, the library will send Version Negotiation packets
1114+
* in response to incoming packets with unsupported versions.
1115+
* The default is @ref LSQUIC_DF_SEND_VERNEG.
1116+
*/
1117+
int es_send_verneg;
10951118
};
10961119

10971120
/* Initialize `settings' to default values */

‎src/liblsquic/lsquic_engine.c‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#endif
4444

4545
#include <openssl/aead.h>
46+
#include <openssl/rand.h>
4647

4748
#include "lsquic.h"
4849
#include "lsquic_types.h"
@@ -398,6 +399,8 @@ lsquic_engine_init_settings (struct lsquic_engine_settings *settings,
398399
settings->es_ptpc_err_divisor= LSQUIC_DF_PTPC_ERR_DIVISOR;
399400
settings->es_delay_onclose = LSQUIC_DF_DELAY_ONCLOSE;
400401
settings->es_check_tp_sanity = LSQUIC_DF_CHECK_TP_SANITY;
402+
settings->es_amp_factor = LSQUIC_DF_AMP_FACTOR;
403+
settings->es_send_verneg = LSQUIC_DF_SEND_VERNEG;
401404
}
402405

403406

@@ -545,6 +548,7 @@ lsquic_engine_new (unsigned flags,
545548
size_t alpn_len;
546549
unsigned i;
547550
char err_buf[100];
551+
uint64_t seed;
548552

549553
if (!api->ea_packets_out)
550554
{
@@ -669,6 +673,8 @@ lsquic_engine_new (unsigned flags,
669673
if (hash_conns_by_addr(engine))
670674
engine->flags |= ENG_CONNS_BY_ADDR;
671675
engine->conns_hash = lsquic_hash_create();
676+
RAND_bytes((uint8_t *)&seed, 8);
677+
lsquic_hash_set_seed(engine->conns_hash, seed);
672678
engine->pub.enp_tokgen = lsquic_tg_new(&engine->pub);
673679
if (!engine->pub.enp_tokgen)
674680
return NULL;
@@ -1094,6 +1100,8 @@ insert_conn_into_hash (struct lsquic_engine *engine, struct lsquic_conn *conn,
10941100
{
10951101
cce = &conn->cn_cces[n];
10961102
assert(!(cce->cce_hash_el.qhe_flags & QHE_HASHED));
1103+
LSQ_DEBUGC("Insert into connection hash-table by CID %"CID_FMT,
1104+
CID_BITS(&cce->cce_cid));
10971105
if (lsquic_hash_insert(engine->conns_hash, cce->cce_cid.idbuf,
10981106
cce->cce_cid.len, conn, &cce->cce_hash_el))
10991107
done |= 1 << n;
@@ -1413,6 +1421,8 @@ find_or_create_conn (lsquic_engine_t *engine, lsquic_packet_in_t *packet_in,
14131421
LSQ_DEBUG("packet header does not have connection ID: discarding");
14141422
return NULL;
14151423
}
1424+
LSQ_DEBUGC("To find connection by CID %"CID_FMT,
1425+
CID_BITS(&packet_in->pi_conn_id));
14161426
el = lsquic_hash_find(engine->conns_hash,
14171427
packet_in->pi_conn_id.idbuf, packet_in->pi_conn_id.len);
14181428

@@ -1492,7 +1502,8 @@ find_or_create_conn (lsquic_engine_t *engine, lsquic_packet_in_t *packet_in,
14921502
switch (version_matches(engine, packet_in, &version))
14931503
{
14941504
case VER_UNSUPPORTED:
1495-
if (engine->flags & ENG_SERVER)
1505+
if ((engine->flags & ENG_SERVER) &&
1506+
engine->pub.enp_settings.es_send_verneg)
14961507
schedule_req_packet(engine, PACKET_REQ_VERNEG, packet_in,
14971508
sa_local, sa_peer, peer_ctx);
14981509
return NULL;
@@ -3564,8 +3575,10 @@ lsquic_engine_retire_cid (struct lsquic_engine_public *enpub,
35643575
assert(cce_idx < conn->cn_n_cces);
35653576

35663577
if (cce->cce_hash_el.qhe_flags & QHE_HASHED)
3578+
{
3579+
LSQ_DEBUGC("drop from conn hash-table CID %"CID_FMT, CID_BITS(&cce->cce_cid));
35673580
lsquic_hash_erase(engine->conns_hash, &cce->cce_hash_el);
3568-
3581+
}
35693582
if (engine->purga)
35703583
{
35713584
peer_ctx = lsquic_conn_get_peer_ctx(conn, NULL);

‎src/liblsquic/lsquic_full_conn_ietf.c‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6210,7 +6210,6 @@ process_max_stream_data_frame (struct ietf_full_conn *conn,
62106210
LSQ_DEBUG("Connection closing: ignore frame");
62116211
return parsed_len;
62126212
}
6213-
62146213
const lsquic_stream_id_t max_allowed =
62156214
conn->ifc_max_allowed_stream_id[stream_id & SIT_MASK];
62166215
if (stream_id >= max_allowed)

‎src/liblsquic/lsquic_hash.c‎

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,17 @@
88
#include <stdlib.h>
99
#include <string.h>
1010
#include <sys/queue.h>
11+
#include <time.h>
12+
1113
#ifdef WIN32
1214
#include <vc_compat.h>
15+
#else
16+
#include <sys/time.h>
17+
#include <unistd.h>
1318
#endif
1419

1520
#include "lsquic_hash.h"
16-
#include "lsquic_xxhash.h"
21+
#include "lsquic_rapidhash.h"
1722

1823
TAILQ_HEAD(hels_head, lsquic_hash_elem);
1924

@@ -26,15 +31,47 @@ struct lsquic_hash
2631
qh_all;
2732
struct lsquic_hash_elem *qh_iter_next;
2833
int (*qh_cmp)(const void *, const void *, size_t);
29-
unsigned (*qh_hash)(const void *, size_t, unsigned seed);
34+
uint64_t (*qh_hash)(const void *, size_t, uint64_t seed);
3035
unsigned qh_count;
3136
unsigned qh_nbits;
37+
uint64_t qh_hash_seed;
3238
};
3339

3440

41+
static uint64_t get_seed()
42+
{
43+
static uint64_t seed = 0;
44+
if (seed == 0)
45+
{
46+
#if defined(WIN32)
47+
LARGE_INTEGER counter;
48+
QueryPerformanceCounter(&counter);
49+
seed = counter.QuadPart;
50+
#elif defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
51+
struct timespec ts;
52+
(void) clock_gettime(CLOCK_MONOTONIC, &ts);
53+
seed = ts.tv_sec * 1000000000 + ts.tv_nsec;
54+
#elif defined(__APPLE__)
55+
seed = mach_absolute_time();
56+
#else
57+
struct timeval tv;
58+
gettimeofday(&tv, NULL);
59+
seed = tv.tv_sec * 1000000000 + tv.tv_usec * 1000;
60+
#endif
61+
srand(seed);
62+
for(unsigned i = 0; i < (seed & 0xf) + 1; ++i)
63+
{
64+
seed = (seed << 8) | (seed >> 56);
65+
seed ^= rand();
66+
}
67+
}
68+
return seed;
69+
}
70+
71+
3572
struct lsquic_hash *
3673
lsquic_hash_create_ext (int (*cmp)(const void *, const void *, size_t),
37-
unsigned (*hashf)(const void *, size_t, unsigned seed))
74+
uint64_t (*hashf)(const void *, size_t, uint64_t seed))
3875
{
3976
struct hels_head *buckets;
4077
struct lsquic_hash *hash;
@@ -62,14 +99,26 @@ lsquic_hash_create_ext (int (*cmp)(const void *, const void *, size_t),
6299
hash->qh_nbits = nbits;
63100
hash->qh_iter_next = NULL;
64101
hash->qh_count = 0;
102+
hash->qh_hash_seed = get_seed() ^ (uint64_t)hash
103+
^ ((uint64_t)buckets << 32) ^ rand();
65104
return hash;
66105
}
67106

68107

69108
struct lsquic_hash *
70109
lsquic_hash_create (void)
71110
{
72-
return lsquic_hash_create_ext(memcmp, XXH32);
111+
return lsquic_hash_create_ext(memcmp, rapidhash_withSeed);
112+
}
113+
114+
115+
int
116+
lsquic_hash_set_seed (struct lsquic_hash * hash, uint64_t seed)
117+
{
118+
if (hash->qh_count > 0)
119+
return -1;
120+
hash->qh_hash_seed = seed;
121+
return 0;
73122
}
74123

75124

@@ -119,7 +168,8 @@ struct lsquic_hash_elem *
119168
lsquic_hash_insert (struct lsquic_hash *hash, const void *key,
120169
unsigned key_sz, void *value, struct lsquic_hash_elem *el)
121170
{
122-
unsigned buckno, hash_val;
171+
uint64_t hash_val;
172+
unsigned buckno;
123173

124174
if (el->qhe_flags & QHE_HASHED)
125175
return NULL;
@@ -128,7 +178,7 @@ lsquic_hash_insert (struct lsquic_hash *hash, const void *key,
128178
0 != lsquic_hash_grow(hash))
129179
return NULL;
130180

131-
hash_val = hash->qh_hash(key, key_sz, (uintptr_t) hash);
181+
hash_val = hash->qh_hash(key, key_sz, hash->qh_hash_seed);
132182
buckno = BUCKNO(hash->qh_nbits, hash_val);
133183
TAILQ_INSERT_TAIL(&hash->qh_all, el, qhe_next_all);
134184
TAILQ_INSERT_TAIL(&hash->qh_buckets[buckno], el, qhe_next_bucket);
@@ -145,10 +195,11 @@ lsquic_hash_insert (struct lsquic_hash *hash, const void *key,
145195
struct lsquic_hash_elem *
146196
lsquic_hash_find (struct lsquic_hash *hash, const void *key, unsigned key_sz)
147197
{
148-
unsigned buckno, hash_val;
198+
uint64_t hash_val;
199+
unsigned buckno;
149200
struct lsquic_hash_elem *el;
150201

151-
hash_val = hash->qh_hash(key, key_sz, (uintptr_t) hash);
202+
hash_val = hash->qh_hash(key, key_sz, hash->qh_hash_seed);
152203
buckno = BUCKNO(hash->qh_nbits, hash_val);
153204
TAILQ_FOREACH(el, &hash->qh_buckets[buckno], qhe_next_bucket)
154205
if (hash_val == el->qhe_hash_val &&

‎src/liblsquic/lsquic_hash.h‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#ifndef LSQUIC_HASH_H
77
#define LSQUIC_HASH_H
88

9+
#include <inttypes.h>
10+
911
#ifdef __cplusplus
1012
extern "C" {
1113
#endif
@@ -20,7 +22,7 @@ struct lsquic_hash_elem
2022
const void *qhe_key_data;
2123
void *qhe_value;
2224
unsigned qhe_key_len;
23-
unsigned qhe_hash_val;
25+
uint64_t qhe_hash_val;
2426
enum {
2527
QHE_HASHED = 1 << 0,
2628
} qhe_flags;
@@ -31,7 +33,10 @@ lsquic_hash_create (void);
3133

3234
struct lsquic_hash *
3335
lsquic_hash_create_ext (int (*cmp)(const void *, const void *, size_t),
34-
unsigned (*hash)(const void *, size_t, unsigned seed));
36+
uint64_t (*hash)(const void *, size_t, uint64_t seed));
37+
38+
int
39+
lsquic_hash_set_seed (struct lsquic_hash *, uint64_t seed);
3540

3641
void
3742
lsquic_hash_destroy (struct lsquic_hash *);

‎src/liblsquic/lsquic_mini_conn_ietf.c‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -318,11 +318,11 @@ imico_stream_write (void *stream, const void *bufp, size_t bufsz)
318318
if (!packet_out)
319319
return -1;
320320
// NOTE: reduce the size of first crypto frame to combine packets
321-
int avail = lsquic_packet_out_avail(packet_out);
321+
unsigned avail = lsquic_packet_out_avail(packet_out);
322322
int coalescing = 0;
323323
if (cryst->mcs_enc_level == ENC_LEV_HSK
324324
&& cryst->mcs_write_off == 0
325-
&& avail > (int)conn->imc_hello_pkt_remain - conn->imc_long_header_sz)
325+
&& avail > (unsigned)conn->imc_hello_pkt_remain - conn->imc_long_header_sz)
326326
{
327327
avail = conn->imc_hello_pkt_remain - conn->imc_long_header_sz;
328328
conn->imc_hello_pkt_remain = 0;
@@ -339,7 +339,7 @@ imico_stream_write (void *stream, const void *bufp, size_t bufsz)
339339
packet_out->po_data_sz += len;
340340
packet_out->po_frame_types |= 1 << QUIC_FRAME_CRYPTO;
341341
packet_out->po_flags |= PO_HELLO;
342-
if (coalescing && len < avail)
342+
if (coalescing && len < (int)avail)
343343
{
344344
LSQ_DEBUG("generated PADDING frame: %d bytes for packet %"PRIu64,
345345
avail - len, packet_out->po_packno);
@@ -810,7 +810,8 @@ static int
810810
imico_can_send (const struct ietf_mini_conn *conn, size_t size)
811811
{
812812
return (conn->imc_flags & IMC_ADDR_VALIDATED)
813-
|| conn->imc_bytes_in * 3 >= conn->imc_bytes_out + size
813+
|| conn->imc_bytes_in * conn->imc_enpub->enp_settings.es_amp_factor
814+
>= conn->imc_bytes_out + size
814815
;
815816
}
816817

@@ -2331,6 +2332,8 @@ ietf_mini_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now)
23312332
(IMC_HAVE_TP|IMC_ADDR_VALIDATED|IMC_BAD_TRANS_PARAMS))
23322333
&& conn->imc_enpub->enp_settings.es_support_srej)
23332334
{
2335+
if (conn->imc_flags & IMC_ERROR)
2336+
goto close_on_error;
23342337
LSQ_DEBUG("Peer not validated and do not have transport parameters "
23352338
"on the first tick: retry");
23362339
return TICK_RETRY|TICK_CLOSE;
@@ -2356,7 +2359,7 @@ ietf_mini_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now)
23562359
close_on_error:
23572360
if (!(conn->imc_flags & IMC_CLOSE_RECVD))
23582361
imico_generate_conn_close(conn);
2359-
tick |= TICK_CLOSE;
2362+
tick = TICK_CLOSE;
23602363
}
23612364
else if (conn->imc_flags & IMC_HSK_OK)
23622365
{

‎src/liblsquic/lsquic_pr_queue.c‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#include "lsquic_engine_public.h"
3838
#include "lsquic_sizes.h"
3939
#include "lsquic_handshake.h"
40-
#include "lsquic_xxhash.h"
40+
#include "lsquic_rapidhash.h"
4141
#include "lsquic_crand.h"
4242

4343
#define LSQUIC_LOGGER_MODULE LSQLM_PRQ
@@ -134,13 +134,13 @@ comp_reqs (const void *s1, const void *s2, size_t n)
134134
}
135135

136136

137-
static unsigned
138-
hash_req (const void *p, size_t len, unsigned seed)
137+
static uint64_t
138+
hash_req (const void *p, size_t len, uint64_t seed)
139139
{
140140
const struct packet_req *req;
141141

142142
req = p;
143-
return XXH32(req->pr_dcid.idbuf, req->pr_dcid.len, seed);
143+
return rapidhash_withSeed(req->pr_dcid.idbuf, req->pr_dcid.len, seed);
144144
}
145145

146146

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /