Close connection properly when packet encryption fails
This commit is contained in:
parent
18ae74fd12
commit
e98f5deb04
|
@ -1,3 +1,11 @@
|
|||
2018-05-24
|
||||
|
||||
- Close connection properly when packet encryption fails
|
||||
|
||||
2018-05-23
|
||||
|
||||
- [BUGFIX] Do not produce packet sequence gaps due to delayed packets
|
||||
|
||||
2018-05-21
|
||||
|
||||
- [API Change] Add optional callback to call when handshake is done
|
||||
|
|
|
@ -24,6 +24,7 @@ struct parse_funcs;
|
|||
struct attq_elem;
|
||||
|
||||
enum lsquic_conn_flags {
|
||||
LSCONN_TICKED = (1 << 0),
|
||||
LSCONN_HAS_OUTGOING = (1 << 1),
|
||||
LSCONN_HASHED = (1 << 2),
|
||||
LSCONN_HAS_PEER_SA = (1 << 4),
|
||||
|
@ -92,7 +93,7 @@ struct lsquic_conn
|
|||
*cn_esf;
|
||||
lsquic_cid_t cn_cid;
|
||||
STAILQ_ENTRY(lsquic_conn) cn_next_closed_conn;
|
||||
STAILQ_ENTRY(lsquic_conn) cn_next_ticked;
|
||||
TAILQ_ENTRY(lsquic_conn) cn_next_ticked;
|
||||
TAILQ_ENTRY(lsquic_conn) cn_next_out,
|
||||
cn_next_hash;
|
||||
const struct conn_iface *cn_if;
|
||||
|
|
|
@ -98,7 +98,7 @@ force_close_conn (lsquic_engine_t *engine, lsquic_conn_t *conn);
|
|||
(e)->pub.enp_flags &= ~ENPUB_PROC; \
|
||||
} while (0)
|
||||
|
||||
/* A connection can be referenced from one of five places:
|
||||
/* A connection can be referenced from one of six places:
|
||||
*
|
||||
* 1. Connection hash: a connection starts its life in one of those.
|
||||
*
|
||||
|
@ -111,6 +111,8 @@ force_close_conn (lsquic_engine_t *engine, lsquic_conn_t *conn);
|
|||
* 5. Closing connections queue. This is a transient queue -- it only
|
||||
* exists for the duration of process_connections() function call.
|
||||
*
|
||||
* 6. Ticked connections queue. Another transient queue, similar to (5).
|
||||
*
|
||||
* The idea is to destroy the connection when it is no longer referenced.
|
||||
* For example, a connection tick may return TICK_SEND|TICK_CLOSE. In
|
||||
* that case, the connection is referenced from two places: (2) and (5).
|
||||
|
@ -124,6 +126,7 @@ force_close_conn (lsquic_engine_t *engine, lsquic_conn_t *conn);
|
|||
#define CONN_REF_FLAGS (LSCONN_HASHED \
|
||||
|LSCONN_HAS_OUTGOING \
|
||||
|LSCONN_TICKABLE \
|
||||
|LSCONN_TICKED \
|
||||
|LSCONN_CLOSING \
|
||||
|LSCONN_ATTQ)
|
||||
|
||||
|
@ -624,6 +627,7 @@ refflags2str (enum lsquic_conn_flags flags, char s[6])
|
|||
*s = 'O'; s += !!(flags & LSCONN_HAS_OUTGOING);
|
||||
*s = 'T'; s += !!(flags & LSCONN_TICKABLE);
|
||||
*s = 'A'; s += !!(flags & LSCONN_ATTQ);
|
||||
*s = 'K'; s += !!(flags & LSCONN_TICKED);
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
|
@ -631,7 +635,7 @@ refflags2str (enum lsquic_conn_flags flags, char s[6])
|
|||
static void
|
||||
engine_incref_conn (lsquic_conn_t *conn, enum lsquic_conn_flags flag)
|
||||
{
|
||||
char str[2][6];
|
||||
char str[2][7];
|
||||
assert(flag & CONN_REF_FLAGS);
|
||||
assert(!(conn->cn_flags & flag));
|
||||
conn->cn_flags |= flag;
|
||||
|
@ -645,7 +649,7 @@ static lsquic_conn_t *
|
|||
engine_decref_conn (lsquic_engine_t *engine, lsquic_conn_t *conn,
|
||||
enum lsquic_conn_flags flags)
|
||||
{
|
||||
char str[2][6];
|
||||
char str[2][7];
|
||||
assert(flags & CONN_REF_FLAGS);
|
||||
assert(conn->cn_flags & flags);
|
||||
#ifndef NDEBUG
|
||||
|
@ -821,6 +825,7 @@ encrypt_packet (lsquic_engine_t *engine, const lsquic_conn_t *conn,
|
|||
|
||||
|
||||
STAILQ_HEAD(conns_stailq, lsquic_conn);
|
||||
TAILQ_HEAD(conns_tailq, lsquic_conn);
|
||||
|
||||
|
||||
struct conns_out_iter
|
||||
|
@ -893,18 +898,6 @@ coi_deactivate (struct conns_out_iter *iter, lsquic_conn_t *conn)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
coi_remove (struct conns_out_iter *iter, lsquic_conn_t *conn)
|
||||
{
|
||||
assert(conn->cn_flags & LSCONN_COI_ACTIVE);
|
||||
if (conn->cn_flags & LSCONN_COI_ACTIVE)
|
||||
{
|
||||
TAILQ_REMOVE(&iter->coi_active_list, conn, cn_next_out);
|
||||
conn->cn_flags &= ~LSCONN_COI_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
coi_reactivate (struct conns_out_iter *iter, lsquic_conn_t *conn)
|
||||
{
|
||||
|
@ -1016,6 +1009,7 @@ check_deadline (lsquic_engine_t *engine)
|
|||
|
||||
static void
|
||||
send_packets_out (struct lsquic_engine *engine,
|
||||
struct conns_tailq *ticked_conns,
|
||||
struct conns_stailq *closed_conns)
|
||||
{
|
||||
unsigned n, w, n_sent, n_batches_sent;
|
||||
|
@ -1061,7 +1055,12 @@ send_packets_out (struct lsquic_engine *engine,
|
|||
if (conn->cn_flags & LSCONN_HASHED)
|
||||
remove_conn_from_hash(engine, conn);
|
||||
}
|
||||
coi_remove(&conns_iter, conn);
|
||||
coi_deactivate(&conns_iter, conn);
|
||||
if (conn->cn_flags & LSCONN_TICKED)
|
||||
{
|
||||
TAILQ_REMOVE(ticked_conns, conn, cn_next_ticked);
|
||||
engine_decref_conn(engine, conn, LSCONN_TICKED);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case ENCPA_OK:
|
||||
|
@ -1147,6 +1146,7 @@ lsquic_engine_send_unsent_packets (lsquic_engine_t *engine)
|
|||
{
|
||||
lsquic_conn_t *conn;
|
||||
struct conns_stailq closed_conns;
|
||||
struct conns_tailq ticked_conns = TAILQ_HEAD_INITIALIZER(ticked_conns);
|
||||
|
||||
STAILQ_INIT(&closed_conns);
|
||||
reset_deadline(engine, lsquic_time_now());
|
||||
|
@ -1157,7 +1157,7 @@ lsquic_engine_send_unsent_packets (lsquic_engine_t *engine)
|
|||
engine->pub.enp_flags |= ENPUB_CAN_SEND;
|
||||
}
|
||||
|
||||
send_packets_out(engine, &closed_conns);
|
||||
send_packets_out(engine, &ticked_conns, &closed_conns);
|
||||
|
||||
while ((conn = STAILQ_FIRST(&closed_conns))) {
|
||||
STAILQ_REMOVE_HEAD(&closed_conns, cn_next_closed_conn);
|
||||
|
@ -1175,12 +1175,13 @@ process_connections (lsquic_engine_t *engine, conn_iter_f next_conn,
|
|||
enum tick_st tick_st;
|
||||
unsigned i;
|
||||
lsquic_time_t next_tick_time;
|
||||
struct conns_stailq closed_conns, ticked_conns;
|
||||
struct conns_stailq closed_conns;
|
||||
struct conns_tailq ticked_conns;
|
||||
|
||||
eng_hist_tick(&engine->history, now);
|
||||
|
||||
STAILQ_INIT(&closed_conns);
|
||||
STAILQ_INIT(&ticked_conns);
|
||||
TAILQ_INIT(&ticked_conns);
|
||||
reset_deadline(engine, now);
|
||||
|
||||
i = 0;
|
||||
|
@ -1205,12 +1206,15 @@ process_connections (lsquic_engine_t *engine, conn_iter_f next_conn,
|
|||
remove_conn_from_hash(engine, conn);
|
||||
}
|
||||
else
|
||||
STAILQ_INSERT_TAIL(&ticked_conns, conn, cn_next_ticked);
|
||||
{
|
||||
TAILQ_INSERT_TAIL(&ticked_conns, conn, cn_next_ticked);
|
||||
engine_incref_conn(conn, LSCONN_TICKED);
|
||||
}
|
||||
}
|
||||
|
||||
if ((engine->pub.enp_flags & ENPUB_CAN_SEND)
|
||||
&& lsquic_engine_has_unsent_packets(engine))
|
||||
send_packets_out(engine, &closed_conns);
|
||||
send_packets_out(engine, &ticked_conns, &closed_conns);
|
||||
|
||||
while ((conn = STAILQ_FIRST(&closed_conns))) {
|
||||
STAILQ_REMOVE_HEAD(&closed_conns, cn_next_closed_conn);
|
||||
|
@ -1220,9 +1224,10 @@ process_connections (lsquic_engine_t *engine, conn_iter_f next_conn,
|
|||
/* TODO Heapification can be optimized by switching to the Floyd method:
|
||||
* https://en.wikipedia.org/wiki/Binary_heap#Building_a_heap
|
||||
*/
|
||||
while ((conn = STAILQ_FIRST(&ticked_conns)))
|
||||
while ((conn = TAILQ_FIRST(&ticked_conns)))
|
||||
{
|
||||
STAILQ_REMOVE_HEAD(&ticked_conns, cn_next_ticked);
|
||||
TAILQ_REMOVE(&ticked_conns, conn, cn_next_ticked);
|
||||
engine_decref_conn(engine, conn, LSCONN_TICKED);
|
||||
if (!(conn->cn_flags & LSCONN_TICKABLE)
|
||||
&& conn->cn_if->ci_is_tickable(conn))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue