From 76e2cfc99a370f46d27f84a924472cef7e285ad4 Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Fri, 17 Apr 2020 12:07:22 -0400 Subject: [PATCH] Fix: a connection is tickable if it has unsent packets --- src/liblsquic/lsquic_full_conn.c | 5 +++++ src/liblsquic/lsquic_full_conn_ietf.c | 5 +++++ src/liblsquic/lsquic_mini_conn.c | 20 +++++++++++++++----- src/liblsquic/lsquic_mini_conn_ietf.c | 20 +++++++++++++++----- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/liblsquic/lsquic_full_conn.c b/src/liblsquic/lsquic_full_conn.c index 14e6a2f..43586d4 100644 --- a/src/liblsquic/lsquic_full_conn.c +++ b/src/liblsquic/lsquic_full_conn.c @@ -4193,6 +4193,11 @@ 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_n_scheduled(&conn->fc_send_ctl) > 0) + { + LSQ_DEBUG("tickable: has scheduled packets"); + return 1; /* Don't check can_send */ + } if ((conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE) && lsquic_send_ctl_has_buffered(&conn->fc_send_ctl)) { diff --git a/src/liblsquic/lsquic_full_conn_ietf.c b/src/liblsquic/lsquic_full_conn_ietf.c index f53925b..0a964d1 100644 --- a/src/liblsquic/lsquic_full_conn_ietf.c +++ b/src/liblsquic/lsquic_full_conn_ietf.c @@ -3541,6 +3541,11 @@ 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_n_scheduled(&conn->ifc_send_ctl) > 0) + { + LSQ_DEBUG("tickable: has scheduled packets"); + return 1; /* Don't check can_send */ + } if (conn->ifc_conn.cn_flags & LSCONN_SEND_BLOCKED) { LSQ_DEBUG("tickable: send DATA_BLOCKED frame"); diff --git a/src/liblsquic/lsquic_mini_conn.c b/src/liblsquic/lsquic_mini_conn.c index ea03751..bf0dbfd 100644 --- a/src/liblsquic/lsquic_mini_conn.c +++ b/src/liblsquic/lsquic_mini_conn.c @@ -2071,14 +2071,24 @@ mini_conn_ci_hsk_done (struct lsquic_conn *lconn, enum lsquic_hsk_status status) } +/* A mini connection is only tickable if it has unsent packets. This can + * occur when packet sending is delayed. + * + * Otherwise, a mini connection is not tickable: Either there are incoming + * packets, in which case, the connection is going to be ticked, or there is + * an alarm pending, in which case it will be handled via the attq. + */ static int mini_conn_ci_is_tickable (struct lsquic_conn *lconn) { - /* A mini connection is never tickable: Either there are incoming - * packets, in which case, the connection is going to be ticked, or - * there is an alarm pending, in which case it will be handled via - * the attq. - */ + struct mini_conn *const mc = (struct mini_conn *) lconn; + const struct lsquic_packet_out *packet_out; + + if (mc->mc_enpub->enp_flags & ENPUB_CAN_SEND) + TAILQ_FOREACH(packet_out, &mc->mc_packets_out, po_next) + if (!(packet_out->po_flags & PO_SENT)) + return 1; + return 0; } diff --git a/src/liblsquic/lsquic_mini_conn_ietf.c b/src/liblsquic/lsquic_mini_conn_ietf.c index b27152f..98c5484 100644 --- a/src/liblsquic/lsquic_mini_conn_ietf.c +++ b/src/liblsquic/lsquic_mini_conn_ietf.c @@ -574,14 +574,24 @@ ietf_mini_conn_ci_tls_alert (struct lsquic_conn *lconn, uint8_t alert) } +/* A mini connection is only tickable if it has unsent packets. This can + * occur when packet sending is delayed. + * + * Otherwise, a mini connection is not tickable: Either there are incoming + * packets, in which case, the connection is going to be ticked, or there is + * an alarm pending, in which case it will be handled via the attq. + */ static int ietf_mini_conn_ci_is_tickable (struct lsquic_conn *lconn) { - /* A mini connection is never tickable: Either there are incoming - * packets, in which case, the connection is going to be ticked, or - * there is an alarm pending, in which case it will be handled via - * the attq. - */ + struct ietf_mini_conn *const conn = (struct ietf_mini_conn *) lconn; + const struct lsquic_packet_out *packet_out; + + if (conn->imc_enpub->enp_flags & ENPUB_CAN_SEND) + TAILQ_FOREACH(packet_out, &conn->imc_packets_out, po_next) + if (!(packet_out->po_flags & PO_SENT)) + return 1; + return 0; }