mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.26.0
- [OPTIMIZATION] Adjust packet reordering threshold when spurious losses are detected. - [API] Pass pointer to local sockaddr to ea_get_ssl_ctx() callback.
This commit is contained in:
parent
7f96c7c7f3
commit
fcbdf653b6
11 changed files with 98 additions and 25 deletions
|
@ -1,3 +1,9 @@
|
|||
2020-12-09
|
||||
- 2.26.0
|
||||
- [OPTIMIZATION] Adjust packet reordering threshold when spurious losses
|
||||
are detected.
|
||||
- [API] Pass pointer to local sockaddr to ea_get_ssl_ctx() callback.
|
||||
|
||||
2020-12-04
|
||||
- 2.25.0
|
||||
- [API, FEATURE] Add es_delay_onclose option to delay on_close until all
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
static int prog_stopped;
|
||||
|
||||
static SSL_CTX * get_ssl_ctx (void *);
|
||||
static SSL_CTX * get_ssl_ctx (void *, const struct sockaddr *);
|
||||
|
||||
static const struct lsquic_packout_mem_if pmi = {
|
||||
.pmi_allocate = pba_allocate,
|
||||
|
@ -417,7 +417,7 @@ prog_init_client (struct prog *prog)
|
|||
|
||||
|
||||
static SSL_CTX *
|
||||
get_ssl_ctx (void *peer_ctx)
|
||||
get_ssl_ctx (void *peer_ctx, const struct sockaddr *unused)
|
||||
{
|
||||
const struct service_port *const sport = peer_ctx;
|
||||
return sport->sp_prog->prog_ssl_ctx;
|
||||
|
|
|
@ -257,10 +257,10 @@ optional members.
|
|||
|
||||
Look up certificate. Mandatory in server mode.
|
||||
|
||||
.. member:: struct ssl_ctx_st * (*ea_get_ssl_ctx)(void *peer_ctx)
|
||||
.. member:: struct ssl_ctx_st * (*ea_get_ssl_ctx)(void *peer_ctx, const struct sockaddr *local)
|
||||
|
||||
Get SSL_CTX associated with a peer context. Mandatory in server
|
||||
mode. This is use for default values for SSL instantiation.
|
||||
mode. This is used for default values for SSL instantiation.
|
||||
|
||||
.. member:: const struct lsquic_hset_if *ea_hsi_if
|
||||
.. member:: void *ea_hsi_ctx
|
||||
|
|
|
@ -24,9 +24,9 @@ copyright = u'2020, LiteSpeed Technologies'
|
|||
author = u'LiteSpeed Technologies'
|
||||
|
||||
# The short X.Y version
|
||||
version = u'2.25'
|
||||
version = u'2.26'
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = u'2.25.0'
|
||||
release = u'2.26.0'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
|
|
@ -863,7 +863,8 @@ The server requires SSL callbacks to be present. The basic required callback is
|
|||
struct lsquic_engine_api {
|
||||
lsquic_lookup_cert_f ea_lookup_cert;
|
||||
void *ea_cert_lu_ctx;
|
||||
struct ssl_ctx_st * (*ea_get_ssl_ctx)(void *peer_ctx);
|
||||
struct ssl_ctx_st * (*ea_get_ssl_ctx)(void *peer_ctx,
|
||||
const struct sockaddr *local);
|
||||
/* (Other members of the struct are not shown) */
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define LSQUIC_MAJOR_VERSION 2
|
||||
#define LSQUIC_MINOR_VERSION 25
|
||||
#define LSQUIC_MINOR_VERSION 26
|
||||
#define LSQUIC_PATCH_VERSION 0
|
||||
|
||||
/**
|
||||
|
@ -1274,7 +1274,8 @@ struct lsquic_engine_api
|
|||
lsquic_lookup_cert_f ea_lookup_cert;
|
||||
void *ea_cert_lu_ctx;
|
||||
/** Mandatory callback for server, optional for client. */
|
||||
struct ssl_ctx_st * (*ea_get_ssl_ctx)(void *peer_ctx);
|
||||
struct ssl_ctx_st * (*ea_get_ssl_ctx)(void *peer_ctx,
|
||||
const struct sockaddr *local);
|
||||
/**
|
||||
* Shared hash interface is optional. If set to zero, performance of
|
||||
* multiple LSQUIC instances will be degraded.
|
||||
|
|
|
@ -888,11 +888,20 @@ iquic_esfi_create_client (const char *hostname,
|
|||
enc_sess->esi_alpn = am->alpn;
|
||||
}
|
||||
|
||||
if (enc_sess->esi_enpub->enp_get_ssl_ctx
|
||||
&& (ssl_ctx = enc_sess->esi_enpub->enp_get_ssl_ctx(peer_ctx)))
|
||||
set_app_ctx = 1;
|
||||
if (enc_sess->esi_enpub->enp_get_ssl_ctx)
|
||||
{
|
||||
struct network_path *const path =
|
||||
enc_sess->esi_conn->cn_if->ci_get_path(enc_sess->esi_conn, NULL);
|
||||
ssl_ctx = enc_sess->esi_enpub->enp_get_ssl_ctx(peer_ctx,
|
||||
NP_LOCAL_SA(path));
|
||||
if (ssl_ctx)
|
||||
set_app_ctx = 1;
|
||||
else
|
||||
goto create_new_ssl_ctx;
|
||||
}
|
||||
else
|
||||
{
|
||||
create_new_ssl_ctx:
|
||||
LSQ_DEBUG("Create new SSL_CTX");
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
if (!ssl_ctx)
|
||||
|
@ -1363,6 +1372,7 @@ static int
|
|||
iquic_esfi_init_server (enc_session_t *enc_session_p)
|
||||
{
|
||||
struct enc_sess_iquic *const enc_sess = enc_session_p;
|
||||
struct network_path *path;
|
||||
const struct alpn_map *am;
|
||||
unsigned quic_ctx_idx;
|
||||
int transpa_len;
|
||||
|
@ -1390,8 +1400,9 @@ iquic_esfi_init_server (enc_session_t *enc_session_p)
|
|||
ok: enc_sess->esi_alpn = am->alpn;
|
||||
}
|
||||
|
||||
ssl_ctx = enc_sess->esi_enpub->enp_get_ssl_ctx(
|
||||
lsquic_conn_get_peer_ctx(enc_sess->esi_conn, NULL));
|
||||
path = enc_sess->esi_conn->cn_if->ci_get_path(enc_sess->esi_conn, NULL);
|
||||
ssl_ctx = enc_sess->esi_enpub->enp_get_ssl_ctx(path->np_peer_ctx,
|
||||
NP_LOCAL_SA(path));
|
||||
if (!ssl_ctx)
|
||||
{
|
||||
LSQ_ERROR("fetching SSL context associated with peer context failed");
|
||||
|
|
|
@ -20,6 +20,7 @@ struct ssl_ctx_st;
|
|||
struct crand;
|
||||
struct evp_aead_ctx_st;
|
||||
struct lsquic_server_config;
|
||||
struct sockaddr;
|
||||
|
||||
enum warning_type
|
||||
{
|
||||
|
@ -37,7 +38,8 @@ struct lsquic_engine_public {
|
|||
struct token_generator *enp_tokgen;
|
||||
lsquic_lookup_cert_f enp_lookup_cert;
|
||||
void *enp_cert_lu_ctx;
|
||||
struct ssl_ctx_st * (*enp_get_ssl_ctx)(void *peer_ctx);
|
||||
struct ssl_ctx_st * (*enp_get_ssl_ctx)(void *peer_ctx,
|
||||
const struct sockaddr *);
|
||||
const struct lsquic_shared_hash_if
|
||||
*enp_shi;
|
||||
void *enp_shi_ctx;
|
||||
|
|
|
@ -166,6 +166,7 @@ typedef struct lsquic_packet_out
|
|||
POL_HEADER_PROT = 1 << 9, /* Header protection applied */
|
||||
#endif
|
||||
POL_LIMITED = 1 << 10, /* Used to credit sc_next_limit if needed. */
|
||||
POL_FACKED = 1 << 11, /* Lost due to FACK check */
|
||||
} po_lflags:16;
|
||||
unsigned char *po_data;
|
||||
|
||||
|
|
|
@ -417,6 +417,13 @@ lsquic_send_ctl_init (lsquic_send_ctl_t *ctl, struct lsquic_alarmset *alset,
|
|||
ctl->sc_can_send = send_ctl_can_send_pre_hsk;
|
||||
else
|
||||
ctl->sc_can_send = send_ctl_can_send;
|
||||
ctl->sc_reord_thresh = N_NACKS_BEFORE_RETX;
|
||||
#if LSQUIC_DEVEL
|
||||
const char *s;
|
||||
s = getenv("LSQUIC_DYN_PTHRESH");
|
||||
if (s == NULL || atoi(s))
|
||||
ctl->sc_flags |= SC_DYN_PTHRESH;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -884,7 +891,7 @@ send_ctl_destroy_chain (struct lsquic_send_ctl *ctl,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
static struct lsquic_packet_out *
|
||||
send_ctl_record_loss (struct lsquic_send_ctl *ctl,
|
||||
struct lsquic_packet_out *packet_out)
|
||||
{
|
||||
|
@ -909,16 +916,21 @@ send_ctl_record_loss (struct lsquic_send_ctl *ctl,
|
|||
* remove from the list:
|
||||
*/
|
||||
TAILQ_INSERT_BEFORE(packet_out, loss_record, po_next);
|
||||
return loss_record;
|
||||
}
|
||||
else
|
||||
{
|
||||
LSQ_INFO("cannot allocate memory for loss record");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static struct lsquic_packet_out *
|
||||
send_ctl_handle_regular_lost_packet (struct lsquic_send_ctl *ctl,
|
||||
lsquic_packet_out_t *packet_out, struct lsquic_packet_out **next)
|
||||
{
|
||||
struct lsquic_packet_out *loss_record;
|
||||
unsigned packet_sz;
|
||||
|
||||
assert(ctl->sc_n_in_flight_all);
|
||||
|
@ -952,11 +964,11 @@ send_ctl_handle_regular_lost_packet (struct lsquic_send_ctl *ctl,
|
|||
{
|
||||
LSQ_DEBUG("lost retransmittable packet %"PRIu64,
|
||||
packet_out->po_packno);
|
||||
send_ctl_record_loss(ctl, packet_out);
|
||||
loss_record = send_ctl_record_loss(ctl, packet_out);
|
||||
send_ctl_unacked_remove(ctl, packet_out, packet_sz);
|
||||
TAILQ_INSERT_TAIL(&ctl->sc_lost_packets, packet_out, po_next);
|
||||
packet_out->po_flags |= PO_LOST;
|
||||
return 1;
|
||||
return loss_record;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -965,7 +977,7 @@ send_ctl_handle_regular_lost_packet (struct lsquic_send_ctl *ctl,
|
|||
send_ctl_unacked_remove(ctl, packet_out, packet_sz);
|
||||
send_ctl_destroy_chain(ctl, packet_out, next);
|
||||
send_ctl_destroy_packet(ctl, packet_out);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -993,7 +1005,7 @@ send_ctl_handle_lost_packet (struct lsquic_send_ctl *ctl,
|
|||
struct lsquic_packet_out *packet_out, struct lsquic_packet_out **next)
|
||||
{
|
||||
if (0 == (packet_out->po_flags & PO_MTU_PROBE))
|
||||
return send_ctl_handle_regular_lost_packet(ctl, packet_out, next);
|
||||
return send_ctl_handle_regular_lost_packet(ctl, packet_out, next) != NULL;
|
||||
else
|
||||
return send_ctl_handle_lost_mtu_probe(ctl, packet_out);
|
||||
}
|
||||
|
@ -1031,7 +1043,7 @@ static int
|
|||
send_ctl_detect_losses (struct lsquic_send_ctl *ctl, enum packnum_space pns,
|
||||
lsquic_time_t time)
|
||||
{
|
||||
lsquic_packet_out_t *packet_out, *next;
|
||||
struct lsquic_packet_out *packet_out, *next, *loss_record;
|
||||
lsquic_packno_t largest_retx_packno, largest_lost_packno;
|
||||
|
||||
largest_retx_packno = largest_retx_packet_number(ctl, pns);
|
||||
|
@ -1047,14 +1059,22 @@ send_ctl_detect_losses (struct lsquic_send_ctl *ctl, enum packnum_space pns,
|
|||
if (packet_out->po_flags & (PO_LOSS_REC|PO_POISON))
|
||||
continue;
|
||||
|
||||
if (packet_out->po_packno + N_NACKS_BEFORE_RETX <
|
||||
if (packet_out->po_packno + ctl->sc_reord_thresh <
|
||||
ctl->sc_largest_acked_packno)
|
||||
{
|
||||
LSQ_DEBUG("loss by FACK detected, packet %"PRIu64,
|
||||
LSQ_DEBUG("loss by FACK detected (dist: %"PRIu64"), packet %"PRIu64,
|
||||
ctl->sc_largest_acked_packno - packet_out->po_packno,
|
||||
packet_out->po_packno);
|
||||
if (0 == (packet_out->po_flags & PO_MTU_PROBE))
|
||||
{
|
||||
largest_lost_packno = packet_out->po_packno;
|
||||
(void) send_ctl_handle_lost_packet(ctl, packet_out, &next);
|
||||
loss_record = send_ctl_handle_regular_lost_packet(ctl,
|
||||
packet_out, &next);
|
||||
if (loss_record)
|
||||
loss_record->po_lflags |= POL_FACKED;
|
||||
}
|
||||
else
|
||||
send_ctl_handle_lost_mtu_probe(ctl, packet_out);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1120,6 +1140,26 @@ send_ctl_mtu_probe_acked (struct lsquic_send_ctl *ctl,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
send_ctl_maybe_increase_reord_thresh (struct lsquic_send_ctl *ctl,
|
||||
const struct lsquic_packet_out *loss_record,
|
||||
lsquic_packno_t prev_largest_acked)
|
||||
{
|
||||
#if LSQUIC_DEVEL
|
||||
if (ctl->sc_flags & SC_DYN_PTHRESH)
|
||||
#endif
|
||||
if ((loss_record->po_lflags & POL_FACKED)
|
||||
&& loss_record->po_packno + ctl->sc_reord_thresh
|
||||
< prev_largest_acked)
|
||||
{
|
||||
ctl->sc_reord_thresh = prev_largest_acked - loss_record->po_packno;
|
||||
LSQ_DEBUG("packet %"PRIu64" was a spurious loss by FACK, increase "
|
||||
"reordering threshold to %u", loss_record->po_packno,
|
||||
ctl->sc_reord_thresh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl,
|
||||
const struct ack_info *acki,
|
||||
|
@ -1129,6 +1169,7 @@ lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl,
|
|||
&acki->ranges[ acki->n_ranges - 1 ];
|
||||
lsquic_packet_out_t *packet_out, *next;
|
||||
lsquic_packno_t smallest_unacked;
|
||||
lsquic_packno_t prev_largest_acked;
|
||||
lsquic_packno_t ack2ed[2];
|
||||
unsigned packet_sz;
|
||||
int app_limited, losses_detected;
|
||||
|
@ -1190,6 +1231,7 @@ lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl,
|
|||
ctl->sc_cur_rt_end = lsquic_senhist_largest(&ctl->sc_senhist);
|
||||
}
|
||||
|
||||
prev_largest_acked = ctl->sc_largest_acked_packno;
|
||||
do_rtt = 0, skip_checks = 0;
|
||||
app_limited = -1;
|
||||
do
|
||||
|
@ -1234,6 +1276,8 @@ lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl,
|
|||
po_next);
|
||||
LSQ_DEBUG("acking via loss record %"PRIu64,
|
||||
packet_out->po_packno);
|
||||
send_ctl_maybe_increase_reord_thresh(ctl, packet_out,
|
||||
prev_largest_acked);
|
||||
#if LSQUIC_CONN_STATS
|
||||
++ctl->sc_conn_pub->conn_stats->out.acked_via_loss;
|
||||
#endif
|
||||
|
|
|
@ -54,6 +54,9 @@ enum send_ctl_flags {
|
|||
SC_ACK_RECV_HSK = SC_ACK_RECV_INIT << PNS_HSK,
|
||||
SC_ACK_RECV_APP = SC_ACK_RECV_INIT << PNS_APP,
|
||||
SC_ROUGH_RTT = 1 << 22,
|
||||
#if LSQUIC_DEVEL
|
||||
SC_DYN_PTHRESH = 1 << 31u, /* dynamic packet threshold enabled */
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct lsquic_send_ctl {
|
||||
|
@ -110,6 +113,9 @@ typedef struct lsquic_send_ctl {
|
|||
* This information is used to drop stale ACK frames from packets in
|
||||
* buffered queues.
|
||||
*/
|
||||
/* XXX We have both sc_largest_acked_packno and sc_largest_acked. Rename
|
||||
* the latter to make the code more readable.
|
||||
*/
|
||||
lsquic_packno_t sc_largest_acked;
|
||||
lsquic_time_t sc_loss_to;
|
||||
uint64_t sc_ecn_total_acked[N_PNS];
|
||||
|
@ -137,6 +143,7 @@ typedef struct lsquic_send_ctl {
|
|||
lsquic_packno_t sc_gap;
|
||||
unsigned sc_loss_count; /* Used to set loss bit */
|
||||
unsigned sc_square_count;/* Used to set square bit */
|
||||
unsigned sc_reord_thresh;
|
||||
signed char sc_cidlen; /* For debug purposes */
|
||||
} lsquic_send_ctl_t;
|
||||
|
||||
|
|
Loading…
Reference in a new issue