mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.4.7
- Add echo client and server to the distibution. - Add MD5 client and server to the distibution. - Fix http_client: check command-line arguments better, prevent crash. - Fix IETF conn: can_write_ack() should only care about APP PNS. - Client: delay stream creation until handshake succeds. - Reset HTTP stream whose write end is closed prematurely. - Fix tickable(): mirror behavior of tick() wrt buffered packets. - Log reason why engine is tickable.
This commit is contained in:
parent
ad08470cea
commit
0adf085acf
27 changed files with 1668 additions and 92 deletions
|
@ -32,7 +32,7 @@ lsquic_alarmset_init_alarm (lsquic_alarmset_t *alset, enum alarm_id al_id,
|
|||
}
|
||||
|
||||
|
||||
static const char *const lsquic_alid2str[] =
|
||||
const char *const lsquic_alid2str[] =
|
||||
{
|
||||
[AL_HANDSHAKE] = "HANDSHAKE",
|
||||
[AL_RETX_INIT] = "RETX_INIT",
|
||||
|
@ -75,20 +75,22 @@ lsquic_alarmset_ring_expired (lsquic_alarmset_t *alset, lsquic_time_t now)
|
|||
|
||||
|
||||
lsquic_time_t
|
||||
lsquic_alarmset_mintime (const lsquic_alarmset_t *alset)
|
||||
lsquic_alarmset_mintime (const lsquic_alarmset_t *alset, enum alarm_id *idp)
|
||||
{
|
||||
lsquic_time_t expiry;
|
||||
enum alarm_id al_id;
|
||||
enum alarm_id al_id, ret_id;
|
||||
|
||||
if (alset->as_armed_set)
|
||||
{
|
||||
expiry = UINT64_MAX;
|
||||
for (al_id = 0; al_id < MAX_LSQUIC_ALARMS; ++al_id)
|
||||
for (al_id = 0, ret_id = 0; al_id < MAX_LSQUIC_ALARMS; ++al_id)
|
||||
if ((alset->as_armed_set & (1 << al_id))
|
||||
&& alset->as_expiry[al_id] < expiry)
|
||||
{
|
||||
expiry = alset->as_expiry[al_id];
|
||||
ret_id = al_id;
|
||||
}
|
||||
*idp = ret_id;
|
||||
return expiry;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -94,6 +94,8 @@ void
|
|||
lsquic_alarmset_ring_expired (lsquic_alarmset_t *, lsquic_time_t now);
|
||||
|
||||
lsquic_time_t
|
||||
lsquic_alarmset_mintime (const lsquic_alarmset_t *);
|
||||
lsquic_alarmset_mintime (const lsquic_alarmset_t *, enum alarm_id *);
|
||||
|
||||
extern const char *const lsquic_alid2str[];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "lsquic_types.h"
|
||||
#include "lsquic_int_types.h"
|
||||
#include "lsquic_attq.h"
|
||||
#include "lsquic_packet_common.h"
|
||||
#include "lsquic_alarmset.h"
|
||||
#include "lsquic_malo.h"
|
||||
#include "lsquic_hash.h"
|
||||
#include "lsquic_conn.h"
|
||||
|
@ -107,7 +109,7 @@ attq_swap (struct attq *q, unsigned a, unsigned b)
|
|||
|
||||
int
|
||||
attq_add (struct attq *q, struct lsquic_conn *conn,
|
||||
lsquic_time_t advisory_time)
|
||||
lsquic_time_t advisory_time, enum ae_why why)
|
||||
{
|
||||
struct attq_elem *el, **heap;
|
||||
unsigned n, i;
|
||||
|
@ -129,6 +131,7 @@ attq_add (struct attq *q, struct lsquic_conn *conn,
|
|||
if (!el)
|
||||
return -1;
|
||||
el->ae_adv_time = advisory_time;
|
||||
el->ae_why = why;
|
||||
|
||||
/* The only place linkage between conn and attq_elem occurs: */
|
||||
el->ae_conn = conn;
|
||||
|
@ -256,11 +259,29 @@ attq_count_before (struct attq *q, lsquic_time_t cutoff)
|
|||
}
|
||||
|
||||
|
||||
const lsquic_time_t *
|
||||
attq_next_time (struct attq *q)
|
||||
const struct attq_elem *
|
||||
attq_next (struct attq *q)
|
||||
{
|
||||
if (q->aq_nelem > 0)
|
||||
return &q->aq_heap[0]->ae_adv_time;
|
||||
return q->aq_heap[0];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
lsquic_attq_why2str (enum ae_why why)
|
||||
{
|
||||
switch (why)
|
||||
{
|
||||
case AEW_PACER:
|
||||
return "PACER";
|
||||
case AEW_MINI_EXPIRE:
|
||||
return "MINI-EXPIRE";
|
||||
default:
|
||||
why -= N_AEWS;
|
||||
if ((unsigned) why < (unsigned) MAX_LSQUIC_ALARMS)
|
||||
return lsquic_alid2str[why];
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,15 @@ struct attq_elem
|
|||
struct lsquic_conn *ae_conn;
|
||||
lsquic_time_t ae_adv_time;
|
||||
unsigned ae_heap_idx;
|
||||
/* The "why" describes why the connection is in the Advisory Tick Time
|
||||
* Queue. Values past the range describe different alarm types (see
|
||||
* enum alarm_id).
|
||||
*/
|
||||
enum ae_why {
|
||||
AEW_PACER,
|
||||
AEW_MINI_EXPIRE,
|
||||
N_AEWS
|
||||
} ae_why;
|
||||
};
|
||||
|
||||
|
||||
|
@ -29,7 +38,8 @@ attq_destroy (struct attq *);
|
|||
|
||||
/* Return 0 on success, -1 on failure (malloc) */
|
||||
int
|
||||
attq_add (struct attq *, struct lsquic_conn *, lsquic_time_t advisory_time);
|
||||
attq_add (struct attq *, struct lsquic_conn *, lsquic_time_t advisory_time,
|
||||
enum ae_why);
|
||||
|
||||
void
|
||||
attq_remove (struct attq *, struct lsquic_conn *);
|
||||
|
@ -40,7 +50,10 @@ attq_pop (struct attq *, lsquic_time_t cutoff);
|
|||
unsigned
|
||||
attq_count_before (struct attq *, lsquic_time_t cutoff);
|
||||
|
||||
const lsquic_time_t *
|
||||
attq_next_time (struct attq *);
|
||||
const struct attq_elem *
|
||||
attq_next (struct attq *);
|
||||
|
||||
const char *
|
||||
lsquic_attq_why2str (enum ae_why);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -123,7 +123,7 @@ struct conn_iface
|
|||
(*ci_is_tickable) (struct lsquic_conn *);
|
||||
|
||||
lsquic_time_t
|
||||
(*ci_next_tick_time) (struct lsquic_conn *);
|
||||
(*ci_next_tick_time) (struct lsquic_conn *, unsigned *why);
|
||||
|
||||
int
|
||||
(*ci_can_write_ack) (struct lsquic_conn *);
|
||||
|
|
|
@ -2138,6 +2138,14 @@ iquic_esf_alg_keysize (enc_session_t *enc_session_p)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
iquic_esf_zero_rtt_enabled (enc_session_t *enc_session_p)
|
||||
{
|
||||
struct enc_sess_iquic *const enc_sess = enc_session_p;
|
||||
return enc_sess->esi_zero_rtt_buf != NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
iquic_esfi_reset_dcid (enc_session_t *enc_session_p,
|
||||
const lsquic_cid_t *old_dcid, const lsquic_cid_t *new_dcid)
|
||||
|
@ -2204,6 +2212,7 @@ const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1 =
|
|||
.esf_cipher = iquic_esf_cipher,
|
||||
.esf_keysize = iquic_esf_keysize,
|
||||
.esf_alg_keysize = iquic_esf_alg_keysize,
|
||||
.esf_is_zero_rtt_enabled = iquic_esf_zero_rtt_enabled,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1179,7 +1179,7 @@ lsquic_engine_add_conn_to_tickable (struct lsquic_engine_public *enpub,
|
|||
|
||||
void
|
||||
lsquic_engine_add_conn_to_attq (struct lsquic_engine_public *enpub,
|
||||
lsquic_conn_t *conn, lsquic_time_t tick_time)
|
||||
lsquic_conn_t *conn, lsquic_time_t tick_time, unsigned why)
|
||||
{
|
||||
lsquic_engine_t *const engine = (lsquic_engine_t *) enpub;
|
||||
if (conn->cn_flags & LSCONN_TICKABLE)
|
||||
|
@ -1194,11 +1194,11 @@ lsquic_engine_add_conn_to_attq (struct lsquic_engine_public *enpub,
|
|||
if (lsquic_conn_adv_time(conn) != tick_time)
|
||||
{
|
||||
attq_remove(engine->attq, conn);
|
||||
if (0 != attq_add(engine->attq, conn, tick_time))
|
||||
if (0 != attq_add(engine->attq, conn, tick_time, why))
|
||||
engine_decref_conn(engine, conn, LSCONN_ATTQ);
|
||||
}
|
||||
}
|
||||
else if (0 == attq_add(engine->attq, conn, tick_time))
|
||||
else if (0 == attq_add(engine->attq, conn, tick_time, why))
|
||||
engine_incref_conn(conn, LSCONN_ATTQ);
|
||||
}
|
||||
|
||||
|
@ -2355,7 +2355,7 @@ process_connections (lsquic_engine_t *engine, conn_iter_f next_conn,
|
|||
{
|
||||
lsquic_conn_t *conn;
|
||||
enum tick_st tick_st;
|
||||
unsigned i;
|
||||
unsigned i, why;
|
||||
lsquic_time_t next_tick_time;
|
||||
struct conns_stailq closed_conns;
|
||||
struct conns_tailq ticked_conns;
|
||||
|
@ -2453,10 +2453,10 @@ process_connections (lsquic_engine_t *engine, conn_iter_f next_conn,
|
|||
}
|
||||
else if (!(conn->cn_flags & LSCONN_ATTQ))
|
||||
{
|
||||
next_tick_time = conn->cn_if->ci_next_tick_time(conn);
|
||||
next_tick_time = conn->cn_if->ci_next_tick_time(conn, &why);
|
||||
if (next_tick_time)
|
||||
{
|
||||
if (0 == attq_add(engine->attq, conn, next_tick_time))
|
||||
if (0 == attq_add(engine->attq, conn, next_tick_time, why))
|
||||
engine_incref_conn(conn, LSCONN_ATTQ);
|
||||
}
|
||||
else
|
||||
|
@ -2590,38 +2590,80 @@ lsquic_engine_cooldown (lsquic_engine_t *engine)
|
|||
int
|
||||
lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
|
||||
{
|
||||
const lsquic_time_t *next_attq_time;
|
||||
const struct attq_elem *next_attq;
|
||||
lsquic_time_t now, next_time;
|
||||
const struct lsquic_conn *conn;
|
||||
const lsquic_cid_t *cid;
|
||||
const enum lsq_log_level L = LSQ_LOG_DEBUG; /* Easy toggle */
|
||||
|
||||
ENGINE_CALLS_INCR(engine);
|
||||
|
||||
if (((engine->flags & ENG_PAST_DEADLINE)
|
||||
if ((engine->flags & ENG_PAST_DEADLINE)
|
||||
&& lsquic_mh_count(&engine->conns_out))
|
||||
|| (engine->pr_queue && prq_have_pending(engine->pr_queue))
|
||||
|| lsquic_mh_count(&engine->conns_tickable))
|
||||
{
|
||||
conn = lsquic_mh_peek(&engine->conns_out);
|
||||
cid = lsquic_conn_log_cid(conn);
|
||||
LSQ_LOGC(L, "next advisory tick is now: went past deadline last time "
|
||||
"and have %u outgoing connection%.*s (%"CID_FMT" first)",
|
||||
lsquic_mh_count(&engine->conns_out),
|
||||
lsquic_mh_count(&engine->conns_out) != 1, "s", CID_BITS(cid));
|
||||
*diff = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
next_attq_time = attq_next_time(engine->attq);
|
||||
if (engine->pr_queue && prq_have_pending(engine->pr_queue))
|
||||
{
|
||||
LSQ_LOG(L, "next advisory tick is now: have pending PRQ elements");
|
||||
*diff = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lsquic_mh_count(&engine->conns_tickable))
|
||||
{
|
||||
conn = lsquic_mh_peek(&engine->conns_tickable);
|
||||
cid = lsquic_conn_log_cid(conn);
|
||||
LSQ_LOGC(L, "next advisory tick is now: have %u tickable "
|
||||
"connection%.*s (%"CID_FMT" first)",
|
||||
lsquic_mh_count(&engine->conns_tickable),
|
||||
lsquic_mh_count(&engine->conns_tickable) != 1, "s", CID_BITS(cid));
|
||||
*diff = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
next_attq = attq_next(engine->attq);
|
||||
if (engine->pub.enp_flags & ENPUB_CAN_SEND)
|
||||
{
|
||||
if (next_attq_time)
|
||||
next_time = *next_attq_time;
|
||||
if (next_attq)
|
||||
next_time = next_attq->ae_adv_time;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (next_attq_time)
|
||||
next_time = MIN(*next_attq_time, engine->resume_sending_at);
|
||||
if (next_attq)
|
||||
{
|
||||
next_time = next_attq->ae_adv_time;
|
||||
if (engine->resume_sending_at < next_time)
|
||||
{
|
||||
next_time = engine->resume_sending_at;
|
||||
next_attq = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
next_time = engine->resume_sending_at;
|
||||
}
|
||||
|
||||
now = lsquic_time_now();
|
||||
*diff = (int) ((int64_t) next_time - (int64_t) now);
|
||||
if (next_attq)
|
||||
{
|
||||
cid = lsquic_conn_log_cid(next_attq->ae_conn);
|
||||
LSQ_LOGC(L, "next advisory tick is %d usec away: conn %"CID_FMT
|
||||
": %s", *diff, CID_BITS(cid),
|
||||
lsquic_attq_why2str(next_attq->ae_why));
|
||||
}
|
||||
else
|
||||
LSQ_LOG(L, "next advisory tick is %d usec away: resume sending", *diff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ lsquic_engine_add_conn_to_tickable (struct lsquic_engine_public *,
|
|||
*/
|
||||
void
|
||||
lsquic_engine_add_conn_to_attq (struct lsquic_engine_public *enpub,
|
||||
lsquic_conn_t *, lsquic_time_t);
|
||||
lsquic_conn_t *, lsquic_time_t, unsigned why);
|
||||
|
||||
void
|
||||
lsquic_engine_retire_cid (struct lsquic_engine_public *,
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "lsquic_version.h"
|
||||
#include "lsquic_headers.h"
|
||||
#include "lsquic_handshake.h"
|
||||
#include "lsquic_attq.h"
|
||||
|
||||
#include "lsquic_conn.h"
|
||||
#include "lsquic_conn_public.h"
|
||||
|
@ -1326,11 +1327,21 @@ full_conn_ci_n_avail_streams (const lsquic_conn_t *lconn)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
handshake_done_or_doing_zero_rtt (const struct full_conn *conn)
|
||||
{
|
||||
return (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
|
||||
|| conn->fc_conn.cn_esf_c->esf_is_zero_rtt_enabled(
|
||||
conn->fc_conn.cn_enc_session);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
full_conn_ci_make_stream (struct lsquic_conn *lconn)
|
||||
{
|
||||
struct full_conn *conn = (struct full_conn *) lconn;
|
||||
if (full_conn_ci_n_avail_streams(lconn) > 0)
|
||||
if (handshake_done_or_doing_zero_rtt(conn)
|
||||
&& full_conn_ci_n_avail_streams(lconn) > 0)
|
||||
{
|
||||
if (!new_stream(conn, generate_stream_id(conn), SCF_CALL_ON_NEW))
|
||||
ABORT_ERROR("could not create new stream: %s", strerror(errno));
|
||||
|
@ -3440,9 +3451,7 @@ full_conn_ci_tick (lsquic_conn_t *lconn, lsquic_time_t now)
|
|||
}
|
||||
|
||||
lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 0);
|
||||
if (!(conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE) &&
|
||||
!conn->fc_conn.cn_esf_c->esf_is_zero_rtt_enabled(
|
||||
conn->fc_conn.cn_enc_session))
|
||||
if (!handshake_done_or_doing_zero_rtt(conn))
|
||||
{
|
||||
process_hsk_stream_write_events(conn);
|
||||
goto end_write;
|
||||
|
@ -3623,12 +3632,14 @@ full_conn_ci_hsk_done (lsquic_conn_t *lconn, enum lsquic_hsk_status status)
|
|||
if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done)
|
||||
conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done(lconn,
|
||||
status);
|
||||
if ((status == LSQ_HSK_OK || status == LSQ_HSK_0RTT_OK)
|
||||
&& conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_zero_rtt_info)
|
||||
if (status == LSQ_HSK_OK || status == LSQ_HSK_0RTT_OK)
|
||||
{
|
||||
conn->fc_conn.cn_esf.g->esf_maybe_dispatch_zero_rtt(
|
||||
conn->fc_conn.cn_enc_session, &conn->fc_conn,
|
||||
conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_zero_rtt_info);
|
||||
if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_zero_rtt_info)
|
||||
conn->fc_conn.cn_esf.g->esf_maybe_dispatch_zero_rtt(
|
||||
conn->fc_conn.cn_enc_session, &conn->fc_conn,
|
||||
conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_zero_rtt_info);
|
||||
if (conn->fc_n_delayed_streams)
|
||||
create_delayed_streams(conn);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4227,7 +4238,8 @@ full_conn_ci_is_tickable (lsquic_conn_t *lconn)
|
|||
LSQ_DEBUG("tickable: flags: 0x%X", conn->fc_flags & send_flags);
|
||||
goto check_can_send;
|
||||
}
|
||||
if (lsquic_send_ctl_has_buffered(&conn->fc_send_ctl))
|
||||
if ((conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
|
||||
&& lsquic_send_ctl_has_buffered(&conn->fc_send_ctl))
|
||||
{
|
||||
LSQ_DEBUG("tickable: has buffered packets");
|
||||
goto check_can_send;
|
||||
|
@ -4237,9 +4249,7 @@ full_conn_ci_is_tickable (lsquic_conn_t *lconn)
|
|||
LSQ_DEBUG("tickable: there are sending streams");
|
||||
goto check_can_send;
|
||||
}
|
||||
if ((conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE) ||
|
||||
conn->fc_conn.cn_esf_c->esf_is_zero_rtt_enabled(
|
||||
conn->fc_conn.cn_enc_session))
|
||||
if (handshake_done_or_doing_zero_rtt(conn))
|
||||
{
|
||||
TAILQ_FOREACH(stream, &conn->fc_pub.write_streams,
|
||||
next_write_stream)
|
||||
|
@ -4283,12 +4293,13 @@ full_conn_ci_is_tickable (lsquic_conn_t *lconn)
|
|||
|
||||
|
||||
static lsquic_time_t
|
||||
full_conn_ci_next_tick_time (lsquic_conn_t *lconn)
|
||||
full_conn_ci_next_tick_time (lsquic_conn_t *lconn, unsigned *why)
|
||||
{
|
||||
struct full_conn *conn = (struct full_conn *) lconn;
|
||||
lsquic_time_t alarm_time, pacer_time, now;
|
||||
enum alarm_id al_id;
|
||||
|
||||
alarm_time = lsquic_alarmset_mintime(&conn->fc_alset);
|
||||
alarm_time = lsquic_alarmset_mintime(&conn->fc_alset, &al_id);
|
||||
pacer_time = lsquic_send_ctl_next_pacer_time(&conn->fc_send_ctl);
|
||||
|
||||
if (pacer_time && LSQ_LOG_ENABLED(LSQ_LOG_DEBUG))
|
||||
|
@ -4302,14 +4313,28 @@ full_conn_ci_next_tick_time (lsquic_conn_t *lconn)
|
|||
if (alarm_time && pacer_time)
|
||||
{
|
||||
if (alarm_time < pacer_time)
|
||||
{
|
||||
*why = N_AEWS + al_id;
|
||||
return alarm_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
*why = AEW_PACER;
|
||||
return pacer_time;
|
||||
}
|
||||
}
|
||||
else if (alarm_time)
|
||||
{
|
||||
*why = N_AEWS + al_id;
|
||||
return alarm_time;
|
||||
else
|
||||
}
|
||||
else if (pacer_time)
|
||||
{
|
||||
*why = AEW_PACER;
|
||||
return pacer_time;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "lsquic.h"
|
||||
#include "lsquic_types.h"
|
||||
#include "lsquic_int_types.h"
|
||||
#include "lsquic_attq.h"
|
||||
#include "lsquic_packet_common.h"
|
||||
#include "lsquic_packet_ietf.h"
|
||||
#include "lsquic_packet_in.h"
|
||||
|
@ -1301,7 +1302,8 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub,
|
|||
|
||||
|
||||
static int
|
||||
should_generate_ack (struct ietf_full_conn *conn)
|
||||
should_generate_ack (struct ietf_full_conn *conn,
|
||||
enum ifull_conn_flags ack_queued)
|
||||
{
|
||||
unsigned lost_acks;
|
||||
|
||||
|
@ -1312,7 +1314,7 @@ should_generate_ack (struct ietf_full_conn *conn)
|
|||
if (lost_acks)
|
||||
conn->ifc_flags |= lost_acks << IFCBIT_ACK_QUED_SHIFT;
|
||||
|
||||
return (conn->ifc_flags & IFC_ACK_QUEUED) != 0;
|
||||
return (conn->ifc_flags & ack_queued) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1320,7 +1322,7 @@ static int
|
|||
ietf_full_conn_ci_can_write_ack (struct lsquic_conn *lconn)
|
||||
{
|
||||
struct ietf_full_conn *conn = (struct ietf_full_conn *) lconn;
|
||||
return should_generate_ack(conn);
|
||||
return should_generate_ack(conn, IFC_ACK_QUED_APP);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3226,7 +3228,7 @@ ietf_full_conn_ci_is_tickable (struct lsquic_conn *lconn)
|
|||
}
|
||||
|
||||
if ((conn->ifc_enpub->enp_flags & ENPUB_CAN_SEND)
|
||||
&& (should_generate_ack(conn) ||
|
||||
&& (should_generate_ack(conn, IFC_ACK_QUEUED) ||
|
||||
!lsquic_send_ctl_sched_is_blocked(&conn->ifc_send_ctl)))
|
||||
{
|
||||
/* XXX What about queued ACKs: why check but not make tickable? */
|
||||
|
@ -3235,7 +3237,9 @@ ietf_full_conn_ci_is_tickable (struct lsquic_conn *lconn)
|
|||
LSQ_DEBUG("tickable: send flags: 0x%X", conn->ifc_send_flags);
|
||||
goto check_can_send;
|
||||
}
|
||||
if (lsquic_send_ctl_has_buffered(&conn->ifc_send_ctl))
|
||||
if (conn->ifc_conn.cn_flags & LSCONN_HANDSHAKE_DONE ?
|
||||
lsquic_send_ctl_has_buffered(&conn->ifc_send_ctl) :
|
||||
lsquic_send_ctl_has_buffered_high(&conn->ifc_send_ctl))
|
||||
{
|
||||
LSQ_DEBUG("tickable: has buffered packets");
|
||||
goto check_can_send;
|
||||
|
@ -3683,12 +3687,13 @@ ietf_full_conn_ci_next_packet_to_send (struct lsquic_conn *lconn, size_t size)
|
|||
|
||||
|
||||
static lsquic_time_t
|
||||
ietf_full_conn_ci_next_tick_time (struct lsquic_conn *lconn)
|
||||
ietf_full_conn_ci_next_tick_time (struct lsquic_conn *lconn, unsigned *why)
|
||||
{
|
||||
struct ietf_full_conn *conn = (struct ietf_full_conn *) lconn;
|
||||
lsquic_time_t alarm_time, pacer_time, now;
|
||||
enum alarm_id al_id;
|
||||
|
||||
alarm_time = lsquic_alarmset_mintime(&conn->ifc_alset);
|
||||
alarm_time = lsquic_alarmset_mintime(&conn->ifc_alset, &al_id);
|
||||
pacer_time = lsquic_send_ctl_next_pacer_time(&conn->ifc_send_ctl);
|
||||
|
||||
if (pacer_time && LSQ_LOG_ENABLED(LSQ_LOG_DEBUG))
|
||||
|
@ -3702,14 +3707,28 @@ ietf_full_conn_ci_next_tick_time (struct lsquic_conn *lconn)
|
|||
if (alarm_time && pacer_time)
|
||||
{
|
||||
if (alarm_time < pacer_time)
|
||||
{
|
||||
*why = N_AEWS + al_id;
|
||||
return alarm_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
*why = AEW_PACER;
|
||||
return pacer_time;
|
||||
}
|
||||
}
|
||||
else if (alarm_time)
|
||||
{
|
||||
*why = N_AEWS + al_id;
|
||||
return alarm_time;
|
||||
else
|
||||
}
|
||||
else if (pacer_time)
|
||||
{
|
||||
*why = AEW_PACER;
|
||||
return pacer_time;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5981,7 +6000,7 @@ ietf_full_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now)
|
|||
have_delayed_packets =
|
||||
lsquic_send_ctl_maybe_squeeze_sched(&conn->ifc_send_ctl);
|
||||
|
||||
if (should_generate_ack(conn))
|
||||
if (should_generate_ack(conn, IFC_ACK_QUEUED))
|
||||
{
|
||||
if (have_delayed_packets)
|
||||
lsquic_send_ctl_reset_packnos(&conn->ifc_send_ctl);
|
||||
|
@ -6263,12 +6282,21 @@ ietf_full_conn_ci_n_avail_streams (const struct lsquic_conn *lconn)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
handshake_done_or_doing_zero_rtt (const struct ietf_full_conn *conn)
|
||||
{
|
||||
return (conn->ifc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
|
||||
|| conn->ifc_conn.cn_esf_c->esf_is_zero_rtt_enabled(
|
||||
conn->ifc_conn.cn_enc_session);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ietf_full_conn_ci_make_stream (struct lsquic_conn *lconn)
|
||||
{
|
||||
struct ietf_full_conn *const conn = (struct ietf_full_conn *) lconn;
|
||||
|
||||
if ((lconn->cn_flags & LSCONN_HANDSHAKE_DONE)
|
||||
if (handshake_done_or_doing_zero_rtt(conn)
|
||||
&& ietf_full_conn_ci_n_avail_streams(lconn) > 0)
|
||||
{
|
||||
if (0 != create_bidi_stream_out(conn))
|
||||
|
|
|
@ -29,6 +29,8 @@ lsquic_mh_insert (struct min_heap *, struct lsquic_conn *conn, uint64_t val);
|
|||
struct lsquic_conn *
|
||||
lsquic_mh_pop (struct min_heap *);
|
||||
|
||||
#define lsquic_mh_peek(heap) ((heap)->mh_elems[0].mhe_conn)
|
||||
|
||||
#define lsquic_mh_count(heap) (+(heap)->mh_nelem)
|
||||
|
||||
#define lsquic_mh_nalloc(heap) (+(heap)->mh_nalloc)
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#include "lsquic_rechist.h"
|
||||
#include "lsquic_ev_log.h"
|
||||
#include "lsquic_qtags.h"
|
||||
#include "lsquic_attq.h"
|
||||
#include "lsquic_alarmset.h"
|
||||
|
||||
#define LSQUIC_LOGGER_MODULE LSQLM_MINI_CONN
|
||||
#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(&mc->mc_conn)
|
||||
|
@ -1892,7 +1894,7 @@ mini_conn_ci_is_tickable (struct lsquic_conn *lconn)
|
|||
|
||||
|
||||
static lsquic_time_t
|
||||
mini_conn_ci_next_tick_time (struct lsquic_conn *lconn)
|
||||
mini_conn_ci_next_tick_time (struct lsquic_conn *lconn, unsigned *why)
|
||||
{
|
||||
struct mini_conn *mc = (struct mini_conn *) lconn;
|
||||
lsquic_packet_out_t *packet_out;
|
||||
|
@ -1905,11 +1907,18 @@ mini_conn_ci_next_tick_time (struct lsquic_conn *lconn)
|
|||
{
|
||||
retx_time = packet_out->po_sent + calc_retx_timeout(mc);
|
||||
if (retx_time < exp_time)
|
||||
{
|
||||
*why = N_AEWS + AL_RETX_HSK;
|
||||
return retx_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
*why = AEW_MINI_EXPIRE;
|
||||
return exp_time;
|
||||
}
|
||||
}
|
||||
|
||||
*why = AEW_MINI_EXPIRE;
|
||||
return exp_time;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "lsquic_trans_params.h"
|
||||
#include "lsquic_ietf.h"
|
||||
#include "lsquic_packet_ietf.h"
|
||||
#include "lsquic_attq.h"
|
||||
#include "lsquic_alarmset.h"
|
||||
|
||||
#define LSQUIC_LOGGER_MODULE LSQLM_MINI_CONN
|
||||
#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(&conn->imc_conn)
|
||||
|
@ -532,7 +534,7 @@ imico_calc_retx_timeout (const struct ietf_mini_conn *conn)
|
|||
|
||||
|
||||
static lsquic_time_t
|
||||
ietf_mini_conn_ci_next_tick_time (struct lsquic_conn *lconn)
|
||||
ietf_mini_conn_ci_next_tick_time (struct lsquic_conn *lconn, unsigned *why)
|
||||
{
|
||||
struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn;
|
||||
const struct lsquic_packet_out *packet_out;
|
||||
|
@ -546,11 +548,18 @@ ietf_mini_conn_ci_next_tick_time (struct lsquic_conn *lconn)
|
|||
{
|
||||
retx_time = packet_out->po_sent + imico_calc_retx_timeout(conn);
|
||||
if (retx_time < exp_time)
|
||||
{
|
||||
*why = N_AEWS + AL_RETX_HSK;
|
||||
return retx_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
*why = AEW_MINI_EXPIRE;
|
||||
return exp_time;
|
||||
}
|
||||
}
|
||||
|
||||
*why = AEW_MINI_EXPIRE;
|
||||
return exp_time;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "lsquic_enc_sess.h"
|
||||
#include "lsquic_hash.h"
|
||||
#include "lsquic_malo.h"
|
||||
#include "lsquic_attq.h"
|
||||
|
||||
#define LSQUIC_LOGGER_MODULE LSQLM_SENDCTL
|
||||
#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(ctl->sc_conn_pub->lconn)
|
||||
|
@ -1294,7 +1295,8 @@ lsquic_send_ctl_can_send (lsquic_send_ctl_t *ctl)
|
|||
{
|
||||
ctl->sc_flags &= ~SC_SCHED_TICK;
|
||||
lsquic_engine_add_conn_to_attq(ctl->sc_enpub,
|
||||
ctl->sc_conn_pub->lconn, pacer_next_sched(&ctl->sc_pacer));
|
||||
ctl->sc_conn_pub->lconn, pacer_next_sched(&ctl->sc_pacer),
|
||||
AEW_PACER);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -281,6 +281,9 @@ lsquic_send_ctl_schedule_buffered (lsquic_send_ctl_t *, enum buf_packet_type);
|
|||
TAILQ_FIRST(&(ctl)->sc_buffered_packets[BPT_HIGHEST_PRIO].bpq_packets) \
|
||||
|| TAILQ_FIRST(&(ctl)->sc_buffered_packets[BPT_OTHER_PRIO].bpq_packets ))
|
||||
|
||||
#define lsquic_send_ctl_has_buffered_high(ctl) ( \
|
||||
!TAILQ_EMPTY(&(ctl)->sc_buffered_packets[BPT_HIGHEST_PRIO].bpq_packets))
|
||||
|
||||
#define lsquic_send_ctl_invalidate_bpt_cache(ctl) do { \
|
||||
(ctl)->sc_cached_bpt.stream_id = UINT64_MAX; \
|
||||
} while (0)
|
||||
|
|
|
@ -1536,7 +1536,13 @@ stream_shutdown_write (lsquic_stream_t *stream)
|
|||
&& !stream_is_incoming_unidir(stream)
|
||||
&& !(stream->sm_qflags & SMQF_SEND_RST))
|
||||
{
|
||||
if (stream->sm_n_buffered == 0)
|
||||
if ((stream->sm_bflags & SMBF_USE_HEADERS)
|
||||
&& !(stream->stream_flags & STREAM_HEADERS_SENT))
|
||||
{
|
||||
LSQ_DEBUG("headers not sent, send a reset");
|
||||
lsquic_stream_reset(stream, 0);
|
||||
}
|
||||
else if (stream->sm_n_buffered == 0)
|
||||
{
|
||||
if (0 == lsquic_send_ctl_turn_on_fin(stream->conn_pub->send_ctl,
|
||||
stream))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue