Skip to content

Commit

Permalink
Release 1.17.6
Browse files Browse the repository at this point in the history
- Add failsafe: resume sending packets after some time

  The change puts a 1-second limit on the amount of time the engine
  will not send packets after some packets are delayed.  This makes
  the library robust in case the user does not unblock the engine
  explicitly using lsquic_engine_send_unsent_packets() call.

- [BUGFIX] Handle corner cases in send controller when packets are
  a) delayed or b) dropped during repackaging.

- [BUGFIX] Memory leak: destroy buffered packets during controller
  cleanup.
  • Loading branch information
Dmitri Tikhonov committed Nov 29, 2018
1 parent bf2c703 commit 8252b0b
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 9 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
2018-11-29
- 1.17.6
- Add failsafe: resume sending packets after some time

The change puts a 1-second limit on the amount of time the engine
will not send packets after some packets are delayed. This makes
the library robust in case the user does not unblock the engine
explicitly using lsquic_engine_send_unsent_packets() call.

- [BUGFIX] Handle corner cases in send controller when packets are
a) delayed or b) dropped during repackaging.
- [BUGFIX] Memory leak: destroy buffered packets during controller
cleanup.

2018-11-16
- 1.17.3
- [BUGFIX] Do not send STOP_WAITING frames when using Q044
Expand Down
2 changes: 1 addition & 1 deletion include/lsquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ extern "C" {

#define LSQUIC_MAJOR_VERSION 1
#define LSQUIC_MINOR_VERSION 17
#define LSQUIC_PATCH_VERSION 3
#define LSQUIC_PATCH_VERSION 6

/**
* Engine flags:
Expand Down
37 changes: 31 additions & 6 deletions src/liblsquic/lsquic_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
#define LSQUIC_LOGGER_MODULE LSQLM_ENGINE
#include "lsquic_logger.h"

#define MIN(a, b) ((a) < (b) ? (a) : (b))


/* The batch of outgoing packets grows and shrinks dynamically */
#define MAX_OUT_BATCH_SIZE 1024
Expand Down Expand Up @@ -168,6 +170,7 @@ struct lsquic_engine
lsquic_time_t last_sent;
unsigned n_conns;
lsquic_time_t deadline;
lsquic_time_t resume_sending_at;
struct out_batch out_batch;
};

Expand Down Expand Up @@ -1025,6 +1028,7 @@ send_batch (lsquic_engine_t *engine, struct conns_out_iter *conns_iter,
if (n_sent < (int) n_to_send)
{
engine->pub.enp_flags &= ~ENPUB_CAN_SEND;
engine->resume_sending_at = now + 1000000;
LSQ_DEBUG("cannot send packets");
EV_LOG_GENERIC_EVENT("cannot send packets");
}
Expand Down Expand Up @@ -1272,6 +1276,15 @@ process_connections (lsquic_engine_t *engine, conn_iter_f next_conn,
TAILQ_INIT(&ticked_conns);
reset_deadline(engine, now);

if (!(engine->pub.enp_flags & ENPUB_CAN_SEND)
&& now > engine->resume_sending_at)
{
LSQ_NOTICE("failsafe activated: resume sending packets again after "
"timeout");
EV_LOG_GENERIC_EVENT("resume sending packets again after timeout");
engine->pub.enp_flags |= ENPUB_CAN_SEND;
}

i = 0;
while ((conn = next_conn(engine))
)
Expand Down Expand Up @@ -1412,8 +1425,8 @@ lsquic_engine_quic_versions (const lsquic_engine_t *engine)
int
lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
{
const lsquic_time_t *next_time;
lsquic_time_t now;
const lsquic_time_t *next_attq_time;
lsquic_time_t now, next_time;

if (((engine->flags & ENG_PAST_DEADLINE)
&& lsquic_mh_count(&engine->conns_out))
Expand All @@ -1423,12 +1436,24 @@ lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
return 1;
}

next_time = attq_next_time(engine->attq);
if (!next_time)
return 0;
next_attq_time = attq_next_time(engine->attq);
if (engine->pub.enp_flags & ENPUB_CAN_SEND)
{
if (next_attq_time)
next_time = *next_attq_time;
else
return 0;
}
else
{
if (next_attq_time)
next_time = MIN(*next_attq_time, engine->resume_sending_at);
else
next_time = engine->resume_sending_at;
}

now = lsquic_time_now();
*diff = (int) ((int64_t) *next_time - (int64_t) now);
*diff = (int) ((int64_t) next_time - (int64_t) now);
return 1;
}

Expand Down
1 change: 1 addition & 0 deletions src/liblsquic/lsquic_packet_out.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ typedef struct lsquic_packet_out
PO_IPv6 = (1 <<20), /* Set if pmi_allocate was passed is_ipv6=1,
* otherwise unset.
*/
PO_LIMITED = (1 <<21), /* Used to credit sc_next_limit if needed. */
} po_flags;
enum quic_ft_bit po_frame_types:16; /* Bitmask of QUIC_FRAME_* */
unsigned short po_data_sz; /* Number of usable bytes in data */
Expand Down
27 changes: 25 additions & 2 deletions src/liblsquic/lsquic_send_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,8 @@ send_ctl_next_packno (lsquic_send_ctl_t *ctl)
void
lsquic_send_ctl_cleanup (lsquic_send_ctl_t *ctl)
{
lsquic_packet_out_t *packet_out;
lsquic_packet_out_t *packet_out, *next;
unsigned n;
lsquic_senhist_cleanup(&ctl->sc_senhist);
while ((packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets)))
{
Expand All @@ -881,6 +882,16 @@ lsquic_send_ctl_cleanup (lsquic_send_ctl_t *ctl)
TAILQ_REMOVE(&ctl->sc_lost_packets, packet_out, po_next);
send_ctl_destroy_packet(ctl, packet_out);
}
for (n = 0; n < sizeof(ctl->sc_buffered_packets) /
sizeof(ctl->sc_buffered_packets[0]); ++n)
{
for (packet_out = TAILQ_FIRST(&ctl->sc_buffered_packets[n].bpq_packets);
packet_out; packet_out = next)
{
next = TAILQ_NEXT(packet_out, po_next);
send_ctl_destroy_packet(ctl, packet_out);
}
}
pacer_cleanup(&ctl->sc_pacer);
#if LSQUIC_SEND_STATS
LSQ_NOTICE("stats: n_total_sent: %u; n_resent: %u; n_delayed: %u",
Expand Down Expand Up @@ -1083,6 +1094,7 @@ lsquic_packet_out_t *
lsquic_send_ctl_next_packet_to_send (lsquic_send_ctl_t *ctl)
{
lsquic_packet_out_t *packet_out;
int dec_limit;

get_packet:
packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets);
Expand All @@ -1093,10 +1105,12 @@ lsquic_send_ctl_next_packet_to_send (lsquic_send_ctl_t *ctl)
!(packet_out->po_frame_types & (1 << QUIC_FRAME_ACK)))
{
if (ctl->sc_next_limit)
--ctl->sc_next_limit;
dec_limit = 1;
else
return NULL;
}
else
dec_limit = 0;

send_ctl_sched_remove(ctl, packet_out);
if (packet_out->po_flags & PO_REPACKNO)
Expand All @@ -1116,6 +1130,13 @@ lsquic_send_ctl_next_packet_to_send (lsquic_send_ctl_t *ctl)
}

ctl->sc_bytes_out += packet_out_total_sz(packet_out);
if (dec_limit)
{
--ctl->sc_next_limit;
packet_out->po_flags |= PO_LIMITED;
}
else
packet_out->po_flags &= ~PO_LIMITED;
return packet_out;
}

Expand All @@ -1126,6 +1147,8 @@ lsquic_send_ctl_delayed_one (lsquic_send_ctl_t *ctl,
{
send_ctl_sched_prepend(ctl, packet_out);
ctl->sc_bytes_out -= packet_out_total_sz(packet_out);
if (packet_out->po_flags & PO_LIMITED)
++ctl->sc_next_limit;
LSQ_DEBUG("packet %"PRIu64" has been delayed", packet_out->po_packno);
#if LSQUIC_SEND_STATS
++ctl->sc_stats.n_delayed;
Expand Down

0 comments on commit 8252b0b

Please sign in to comment.