Skip to content

Commit c201607

Browse files
committed
Release 4.3.0
1 parent 148fec8 commit c201607

30 files changed

Lines changed: 353 additions & 161 deletions

CHANGELOG

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
2025-06-17
2+
- 4.3.0
3+
- Add WebTransport support.
4+
- Fix IETF QUIC IP spoofing amplification attack.
5+
- Improve preferred address migration implementation, pass interop tests.
6+
- Add lsquic_conn_get_info() API to retrieve information about a connection.
7+
18
2025-02-18
29
- 4.2.0
310
- Address hash flood attack for lsquic_hash by switching to rapidhash with stronger random seed.

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ OPTION(LSQUIC_BIN "Compile example binaries that use the library" ON)
1111
OPTION(LSQUIC_TESTS "Compile library unit tests" ON)
1212
OPTION(LSQUIC_SHARED_LIB "Compile as shared librarry" OFF)
1313
OPTION(LSQUIC_DEVEL "Compile in development mode" OFF)
14+
OPTION(LSQUIC_WEBTRANSPORT "Enable WebTransport support" OFF)
1415

1516
INCLUDE(GNUInstallDirs)
1617

@@ -80,6 +81,10 @@ IF (LSQUIC_DEVEL)
8081
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_DEVEL=1")
8182
ENDIF()
8283

84+
IF (LSQUIC_WEBTRANSPORT)
85+
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -LSQUIC_WEBTRANSPORT_SERVER_SUPPORT=1")
86+
ENDIF()
87+
8388
IF(LSQUIC_PROFILE EQUAL 1)
8489
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -g -pg")
8590
ENDIF()

bin/http_client.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,13 @@
4646
#include "../src/liblsquic/lsquic_logger.h"
4747
#include "../src/liblsquic/lsquic_int_types.h"
4848
#include "../src/liblsquic/lsquic_util.h"
49-
/* include directly for reset_stream testing */
50-
#include "../src/liblsquic/lsquic_varint.h"
51-
#include "../src/liblsquic/lsquic_hq.h"
52-
#include "../src/liblsquic/lsquic_sfcw.h"
5349
#include "../src/liblsquic/lsquic_hash.h"
50+
#if LSQUIC_QIR
51+
/* include directly for reset_stream testing */
5452
#include "../src/liblsquic/lsquic_stream.h"
5553
/* include directly for retire_cid testing */
5654
#include "../src/liblsquic/lsquic_conn.h"
55+
#endif
5756
#include "lsxpack_header.h"
5857

5958
#define MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -786,6 +785,7 @@ http_client_on_read (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
786785
{
787786
st_h->sh_nread += (size_t) nread;
788787
s_stat_downloaded_bytes += nread;
788+
#if LSQUIC_QIR
789789
/* test stream_reset after some number of read bytes */
790790
if (client_ctx->hcc_reset_after_nbytes &&
791791
s_stat_downloaded_bytes > client_ctx->hcc_reset_after_nbytes)
@@ -801,6 +801,7 @@ http_client_on_read (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
801801
client_ctx->hcc_retire_cid_after_nbytes = 0;
802802
break;
803803
}
804+
#endif
804805
if (!g_header_bypass && !(st_h->sh_flags & PROCESSED_HEADERS))
805806
{
806807
/* First read is assumed to be the first byte */

bin/perf_client.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#include "prog.h"
3232

3333
#include "../src/liblsquic/lsquic_logger.h"
34-
#include "../src/liblsquic/lsquic_int_types.h"
3534
#include "../src/liblsquic/lsquic_byteswap.h"
3635

3736
struct scenario

bin/prog.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,11 @@ prog_init (struct prog *prog, unsigned flags,
8585
prog->prog_api.ea_pmi = &pmi;
8686
prog->prog_api.ea_pmi_ctx = &prog->prog_pba;
8787
prog->prog_api.ea_get_ssl_ctx = get_ssl_ctx;
88-
#if LSQUIC_PREFERRED_ADDR
89-
if (getenv("LSQUIC_PREFERRED_ADDR4") || getenv("LSQUIC_PREFERRED_ADDR6"))
90-
prog->prog_flags |= PROG_SEARCH_ADDRS;
91-
#endif
9288

9389
/* Non prog-specific initialization: */
9490
lsquic_global_init(flags & LSENG_SERVER ? LSQUIC_GLOBAL_SERVER :
9591
LSQUIC_GLOBAL_CLIENT);
96-
lsquic_log_to_fstream(stderr, LLTS_HHMMSSMS);
92+
lsquic_log_to_fstream(stderr, LLTS_HHMMSSUS);
9793
lsquic_logger_lopt("=notice");
9894
return 0;
9995
}
@@ -767,6 +763,13 @@ prog_prep (struct prog *prog)
767763
prog->prog_api.ea_lookup_cert = no_cert;
768764
}
769765

766+
if (prog->prog_engine_flags & LSENG_SERVER)
767+
{
768+
if (memcmp(prog->prog_settings.es_preferred_address,
769+
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) != 0)
770+
prog->prog_flags |= PROG_SEARCH_ADDRS;
771+
}
772+
770773
prog->prog_eb = event_base_new();
771774
prog->prog_engine = lsquic_engine_new(prog->prog_engine_flags,
772775
&prog->prog_api);

bin/prog.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ struct prog
4747
int prog_ipver; /* 0, 4, or 6 */
4848
enum {
4949
PROG_FLAG_COOLDOWN = 1 << 0,
50-
#if LSQUIC_PREFERRED_ADDR
5150
PROG_SEARCH_ADDRS = 1 << 1,
52-
#endif
5351
} prog_flags;
5452
};
5553

bin/test_common.c

Lines changed: 115 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,39 @@ sport_destroy (struct service_port *sport)
228228
}
229229

230230

231+
static char *
232+
sockaddr2str (const struct sockaddr *addr, char *buf, size_t sz)
233+
{
234+
unsigned short port;
235+
int len;
236+
237+
switch (addr->sa_family)
238+
{
239+
case AF_INET:
240+
port = ntohs(((struct sockaddr_in *) addr)->sin_port);
241+
if (!inet_ntop(AF_INET, &((struct sockaddr_in *) addr)->sin_addr,
242+
buf, sz))
243+
buf[0] = '\0';
244+
break;
245+
case AF_INET6:
246+
port = ntohs(((struct sockaddr_in6 *) addr)->sin6_port);
247+
if (!inet_ntop(AF_INET6, &((struct sockaddr_in6 *) addr)->sin6_addr,
248+
buf, sz))
249+
buf[0] = '\0';
250+
break;
251+
default:
252+
port = 0;
253+
(void) snprintf(buf, sz, "<invalid family %d>", addr->sa_family);
254+
break;
255+
}
256+
257+
len = strlen(buf);
258+
if (len < (int) sz)
259+
snprintf(buf + len, sz - (size_t) len, ":%hu", port);
260+
return buf;
261+
}
262+
263+
231264
struct service_port *
232265
sport_new (const char *optarg, struct prog *prog)
233266
{
@@ -600,6 +633,14 @@ read_one_packet (struct read_iter *iter)
600633
sport->drop_init = 1;
601634
sport->n_dropped = n_dropped;
602635
#endif
636+
char localaddr_str[80];
637+
char remoteaddr_str[80];
638+
LSQ_DEBUG("[%s] RX packet %zd bytes from: %s",
639+
sockaddr2str((struct sockaddr *)local_addr, localaddr_str,
640+
sizeof(localaddr_str)),
641+
nread, sockaddr2str(
642+
(struct sockaddr *)&packs_in->peer_addresses[iter->ri_idx],
643+
remoteaddr_str, sizeof(remoteaddr_str)));
603644

604645
#ifndef WIN32
605646
packs_in->vecs[iter->ri_idx].iov_len = nread;
@@ -1557,7 +1598,6 @@ send_packets_using_sendmmsg (const struct lsquic_out_spec *specs,
15571598
#endif
15581599

15591600

1560-
#if LSQUIC_PREFERRED_ADDR
15611601
static const struct service_port *
15621602
find_sport (struct prog *prog, const struct sockaddr *local_sa)
15631603
{
@@ -1574,6 +1614,17 @@ find_sport (struct prog *prog, const struct sockaddr *local_sa)
15741614
: sizeof(struct sockaddr_in6);
15751615
if (0 == memcmp(addr, local_sa, len))
15761616
return sport;
1617+
if (((struct sockaddr_in *)addr)->sin_port ==
1618+
((struct sockaddr_in *)local_sa)->sin_port)
1619+
{
1620+
if ((addr->sa_family == AF_INET
1621+
&& ((struct sockaddr_in *)addr)->sin_addr.s_addr
1622+
== INADDR_ANY)
1623+
||(addr->sa_family == AF_INET6
1624+
&& (IN6_IS_ADDR_UNSPECIFIED(
1625+
&((struct sockaddr_in6 *)addr)->sin6_addr))))
1626+
return sport;
1627+
}
15771628
}
15781629
}
15791630

@@ -1582,9 +1633,6 @@ find_sport (struct prog *prog, const struct sockaddr *local_sa)
15821633
}
15831634

15841635

1585-
#endif
1586-
1587-
15881636
static int
15891637
send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
15901638
{
@@ -1655,10 +1703,8 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
16551703
do
16561704
{
16571705
sport = specs[n].peer_ctx;
1658-
#if LSQUIC_PREFERRED_ADDR
16591706
if (sport->sp_prog->prog_flags & PROG_SEARCH_ADDRS)
16601707
sport = find_sport(sport->sp_prog, specs[n].local_sa);
1661-
#endif
16621708
#ifndef WIN32
16631709
msg.msg_name = (void *) specs[n].dest_sa;
16641710
msg.msg_namelen = (AF_INET == specs[n].dest_sa->sa_family ?
@@ -1734,6 +1780,14 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
17341780
#endif
17351781
break;
17361782
}
1783+
char localaddr_str[80];
1784+
char remoteaddr_str[80];
1785+
LSQ_DEBUG("[%s] TX packet %d bytes to: %s",
1786+
sockaddr2str((struct sockaddr *)&sport->sp_local_addr,
1787+
localaddr_str, sizeof(localaddr_str)),
1788+
s, sockaddr2str(specs[n].dest_sa,
1789+
remoteaddr_str, sizeof(remoteaddr_str)));
1790+
17371791
++n;
17381792
}
17391793
while (n < count);
@@ -1779,6 +1833,47 @@ sport_packets_out (void *ctx, const struct lsquic_out_spec *specs,
17791833
}
17801834

17811835

1836+
int
1837+
set_perferred_address(uint8_t *addr, uint16_t *port, const char *s, int family)
1838+
{
1839+
char addr_buf[1024];
1840+
const char *colon;
1841+
if (s && strlen(s) < sizeof(addr_buf) && (colon = strrchr(s, ':')))
1842+
{
1843+
strncpy(addr_buf, s, colon - s);
1844+
addr_buf[colon - s] = '\0';
1845+
if (inet_pton(family, addr_buf, addr))
1846+
{
1847+
*port = atoi(colon + 1);
1848+
//params.tp_set |= 1 << TPI_PREFERRED_ADDRESS;
1849+
return 1;
1850+
}
1851+
else
1852+
{
1853+
struct addrinfo hints, *res = NULL;
1854+
int ret;
1855+
memset(&hints, 0, sizeof(hints));
1856+
hints.ai_flags = AI_NUMERICSERV;
1857+
hints.ai_family = family;
1858+
ret = getaddrinfo(addr_buf, colon + 1, &hints, &res);
1859+
if (ret != 0)
1860+
{
1861+
LSQ_ERROR("could not resolve %s:%s: %s", addr_buf, colon + 1,
1862+
gai_strerror(ret));
1863+
return 0;
1864+
}
1865+
if (family == AF_INET)
1866+
memcpy(addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr, 4);
1867+
else
1868+
memcpy(addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16);
1869+
*port = atoi(colon + 1);
1870+
return 1;
1871+
}
1872+
}
1873+
return 0;
1874+
}
1875+
1876+
17821877
int
17831878
set_engine_option (struct lsquic_engine_settings *settings,
17841879
int *version_cleared, const char *name)
@@ -1981,6 +2076,20 @@ set_engine_option (struct lsquic_engine_settings *settings,
19812076
settings->es_delayed_acks = atoi(val);
19822077
return 0;
19832078
}
2079+
if (0 == strncmp(name, "preferred_v4", 12))
2080+
{
2081+
set_perferred_address(settings->es_preferred_address,
2082+
(uint16_t *)&settings->es_preferred_address[4], val, AF_INET);
2083+
return 0;
2084+
}
2085+
if (0 == strncmp(name, "preferred_v6", 12))
2086+
{
2087+
set_perferred_address(&settings->es_preferred_address[6],
2088+
(uint16_t *)&settings->es_preferred_address[22],
2089+
val, AF_INET6);
2090+
return 0;
2091+
}
2092+
19842093
break;
19852094
case 13:
19862095
if (0 == strncmp(name, "support_tcid0", 13))

bin/test_common.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,7 @@ create_lsquic_reader_ctx (const char *filename);
138138
void
139139
destroy_lsquic_reader_ctx (struct reader_ctx *ctx);
140140

141-
#define STRINGIFY(x) #x
142-
#define TOSTRING(x) STRINGIFY(x)
143-
#define LITESPEED_ID "lsquic" "/" TOSTRING(LSQUIC_MAJOR_VERSION) "." \
144-
TOSTRING(LSQUIC_MINOR_VERSION) "." TOSTRING(LSQUIC_PATCH_VERSION)
141+
#define LITESPEED_ID "lsquic/" LSQUIC_VERSION_STR
145142

146143
struct header_buf
147144
{

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.2'
27+
version = u'4.3'
2828
# The full version, including alpha/beta/rc tags
29-
release = u'4.2.0'
29+
release = u'4.3.0'
3030

3131

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

include/lsquic.h

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212

1313
#include <stdarg.h>
14-
#include <lsquic_types.h>
14+
#include "lsquic_types.h"
1515
#ifndef WIN32
1616
#include <sys/uio.h>
1717
#include <time.h>
@@ -26,9 +26,14 @@ extern "C" {
2626
#endif
2727

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

32+
#define LSQUIC_QUOTE(x) #x
33+
#define LSQUIC_SVAL(v) LSQUIC_QUOTE(v)
34+
#define LSQUIC_VERSION_STR LSQUIC_SVAL(LSQUIC_MAJOR_VERSION) "." \
35+
LSQUIC_SVAL(LSQUIC_MINOR_VERSION) "." LSQUIC_SVAL(LSQUIC_PATCH_VERSION)
36+
3237
/**
3338
* Engine flags:
3439
*/
@@ -1123,6 +1128,17 @@ struct lsquic_engine_settings {
11231128
*/
11241129
int es_send_verneg;
11251130

1131+
/**
1132+
* This is the preferred_address used in server's transport parameter
1133+
* It contains an address and port for both IPv4 and IPv6. It is copied directly
1134+
* as the addresses part of preferred_address value. Includes:
1135+
* Four-byte IPv4 Address, two-byte IPv4 Port,
1136+
* a 16-byte IPv6 Address, two-byte IPv6 Port.
1137+
*
1138+
* The default is all zero, which indicates perferred_address is not set
1139+
*/
1140+
uint8_t es_preferred_address[24];
1141+
11261142
#if LSQUIC_WEBTRANSPORT_SERVER_SUPPORT
11271143
/**
11281144
* Enable datagram extension for http3 server. Allowed values are 0 and 1.
@@ -2102,6 +2118,25 @@ lsquic_conn_get_sni (lsquic_conn_t *);
21022118
void
21032119
lsquic_conn_abort (lsquic_conn_t *);
21042120

2121+
struct lsquic_conn_info
2122+
{
2123+
uint32_t lci_cwnd;
2124+
uint32_t lci_pmtu;
2125+
uint32_t lci_rtt;
2126+
uint32_t lci_rttvar;
2127+
uint32_t lci_rtt_min;
2128+
uint64_t lci_bytes_rcvd;
2129+
uint64_t lci_bytes_sent;
2130+
uint64_t lci_pkts_rcvd;
2131+
uint64_t lci_pkts_sent;
2132+
uint64_t lci_pkts_lost;
2133+
uint64_t lci_pkts_retx;
2134+
uint64_t lci_bw_estimate;
2135+
};
2136+
2137+
int
2138+
lsquic_conn_get_info (lsquic_conn_t *conn, struct lsquic_conn_info *info);
2139+
21052140
/**
21062141
* Helper function: convert list of versions as specified in the argument
21072142
* bitmask to string that can be included as argument to "v=" part of the

0 commit comments

Comments
 (0)