Skip to content

Commit 4e74eb8

Browse files
committed
he-wait-for-h3-increase-initially
1 parent c7deea5 commit 4e74eb8

7 files changed

Lines changed: 44 additions & 18 deletions

File tree

lib/core-net/client/connect2.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,9 @@ lws_client_connect_2_dnsreq_MAY_CLOSE_WSI(struct lws *wsi)
377377
if (wsi->udp) {
378378
struct lws_client_connect_info i;
379379
wsi->tried_quic = 1;
380+
#if defined(LWS_ROLE_QUIC)
381+
wsi->quic.quic_race_start_us = lws_now_usecs();
382+
#endif
380383
memset(&i, 0, sizeof(i));
381384
i.method = "QUIC";
382385
i.alpn = "h3";

lib/core-net/client/connect3.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,11 @@ lws_client_h3_grace_cb(lws_sorted_usec_list_t *sul)
8282

8383
/* Mark H3 as FAILED in cache with 5s TTL */
8484
if (wsi->a.context->h3_cap_cache && wsi->stash && wsi->stash->cis[CIS_HOST]) {
85-
lws_h3_state_t state = LWS_H3_STATE_FAILED_IGNORE;
85+
lws_h3_cap_info_t cap;
86+
memset(&cap, 0, sizeof(cap));
87+
cap.state = LWS_H3_STATE_FAILED_IGNORE;
8688
lws_cache_write_through(wsi->a.context->h3_cap_cache, wsi->stash->cis[CIS_HOST],
87-
(const uint8_t *)&state, sizeof(state),
89+
(const uint8_t *)&cap, sizeof(cap),
8890
lws_now_usecs() + (5000000ll), NULL);
8991
}
9092

@@ -1005,14 +1007,17 @@ lws_client_connect_3_connect(struct lws *wsi, const char *ads,
10051007
return wsi;
10061008
} else if (!is_parallel && wsi->role_ops && !strcmp(wsi->role_ops->name, "quic")) {
10071009
/* QUIC connect immediately succeeds. Schedule grace and happy eyeballs. */
1008-
uint32_t grace_us = 200000;
1010+
uint32_t grace_us = LWS_QUIC_GRACE_DEFAULT_US;
10091011
if (wsi->a.context->h3_cap_cache && wsi->stash && wsi->stash->cis[CIS_HOST]) {
10101012
const void *item = NULL;
10111013
size_t item_len = 0;
1012-
if (!lws_cache_item_get(wsi->a.context->h3_cap_cache, wsi->stash->cis[CIS_HOST], &item, &item_len)) {
1013-
lws_h3_state_t state = *(lws_h3_state_t *)item;
1014-
if (state == LWS_H3_STATE_KNOWN_GOOD || state == LWS_H3_STATE_HTTPS_RECORD_EXISTS)
1015-
grace_us = 3000000;
1014+
if (!lws_cache_item_get(wsi->a.context->h3_cap_cache, wsi->stash->cis[CIS_HOST], &item, &item_len) &&
1015+
item_len == sizeof(lws_h3_cap_info_t)) {
1016+
const lws_h3_cap_info_t *cap = (const lws_h3_cap_info_t *)item;
1017+
if (cap->state == LWS_H3_STATE_KNOWN_GOOD)
1018+
grace_us = cap->latency_us + LWS_QUIC_GRACE_MARGIN_US;
1019+
else if (cap->state == LWS_H3_STATE_HTTPS_RECORD_EXISTS)
1020+
grace_us = LWS_QUIC_GRACE_DEFAULT_US;
10161021
}
10171022
}
10181023
lwsl_wsi_notice(wsi, "QUIC socket created, starting grace timer %uus", (unsigned int)grace_us);

lib/core/context.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1626,7 +1626,7 @@ lws_create_context(const struct lws_context_creation_info *info)
16261626
cci.name = "H3CAP";
16271627
cci.max_footprint = 4096;
16281628
cci.max_items = 256;
1629-
cci.max_payload = 8; /* Just an enum */
1629+
cci.max_payload = sizeof(lws_h3_cap_info_t);
16301630

16311631
context->h3_cap_cache = lws_cache_create(&cci);
16321632
if (!context->h3_cap_cache) {

lib/core/private-lib-core.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,14 @@ typedef enum {
443443
LWS_H3_STATE_FAILED_IGNORE
444444
} lws_h3_state_t;
445445

446+
#define LWS_QUIC_GRACE_DEFAULT_US 2000000
447+
#define LWS_QUIC_GRACE_MARGIN_US 200000
448+
449+
typedef struct {
450+
lws_h3_state_t state;
451+
uint32_t latency_us;
452+
} lws_h3_cap_info_t;
453+
446454
/*
447455
* the rest is managed per-context, that includes
448456
*

lib/roles/http/server/server.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,8 @@ _lws_vhost_init_server(const struct lws_context_creation_info *info,
583583
#if defined(LWS_ROLE_QUIC)
584584
if (!vhost->context->lws_stub &&
585585
LWS_SSL_ENABLED(vhost) &&
586+
vhost->tls.alpn &&
587+
(strstr(vhost->tls.alpn, "h3") || strstr(vhost->tls.alpn, "lws-quic")) &&
586588
!lws_vhost_foreach_listen_wsi(vhost->context, &a, check_extant_quic)) {
587589

588590
#if defined(LWS_WITH_IPV6)

lib/roles/quic/ops-quic.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2259,6 +2259,11 @@ rops_alpn_negotiated_quic(struct lws *wsi, const char *alpn)
22592259
struct lws *nwsi;
22602260
const struct lws_role_ops *role;
22612261

2262+
#if defined(LWS_WITH_CLIENT)
2263+
if (lwsi_role_client(wsi))
2264+
lws_sul_cancel(&wsi->sul_h3_grace);
2265+
#endif
2266+
22622267
if (strcmp(alpn, "h3") && strcmp(alpn, "lws-quic"))
22632268
return 0;
22642269

@@ -2373,11 +2378,9 @@ rops_alpn_negotiated_quic(struct lws *wsi, const char *alpn)
23732378

23742379
#if defined(LWS_WITH_CLIENT)
23752380
/*
2376-
* QUIC succeeded! Resolve the race by cancelling the grace timer
2377-
* and killing parallel TCP connections.
2381+
* QUIC succeeded! Resolve the race by killing parallel TCP connections.
23782382
*/
23792383
if (lwsi_role_client(wsi)) {
2380-
lws_sul_cancel(&wsi->sul_h3_grace);
23812384

23822385
for (int i = 0; i < wsi->parallel_count; i++) {
23832386
if (wsi->parallel_conns[i].is_valid) {
@@ -2387,9 +2390,12 @@ rops_alpn_negotiated_quic(struct lws *wsi, const char *alpn)
23872390
wsi->parallel_count = 0;
23882391

23892392
if (wsi->a.context->h3_cap_cache && wsi->stash && wsi->stash->cis[CIS_HOST]) {
2390-
lws_h3_state_t state = LWS_H3_STATE_KNOWN_GOOD;
2391-
lws_cache_write_through(wsi->a.context->h3_cap_cache, wsi->stash->cis[CIS_HOST],
2392-
(const uint8_t *)&state, sizeof(state),
2393+
lws_h3_cap_info_t cap;
2394+
cap.state = LWS_H3_STATE_KNOWN_GOOD;
2395+
cap.latency_us = (uint32_t)(lws_now_usecs() - wsi->quic.quic_race_start_us);
2396+
2397+
lws_cache_write_through(wsi->a.context->h3_cap_cache, wsi->stash->cis[CIS_HOST],
2398+
(const uint8_t *)&cap, sizeof(cap),
23932399
lws_now_usecs() + (3600ll * LWS_US_PER_SEC), NULL);
23942400
}
23952401
}

lib/roles/quic/private-lib-roles-quic.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,13 @@ lws_quic_parse_transport_parameters(struct lws *wsi, const uint8_t *buf, size_t
376376
#define LWS_QUIC_DEFAULT_PTO_US 500000 /* 500ms baseline PTO for early dev */
377377

378378
struct _lws_quic_related {
379-
struct lws_quic_netconn *qn; /* malloc'd for root net conn */
380-
struct lws_quic_stream *qs; /* malloc'd for stream child wsi */
379+
struct lws_quic_netconn *qn; /* malloc'd for root net conn */
380+
struct lws_quic_stream *qs; /* malloc'd for stream child wsi */
381381

382-
uint8_t initialized:1;
383-
uint8_t tx_blocked_sent:1;
382+
lws_usec_t quic_race_start_us;
383+
384+
uint8_t initialized:1;
385+
uint8_t tx_blocked_sent:1;
384386
};
385387

386388
#endif

0 commit comments

Comments
 (0)