mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Latest changes
- [API Change] Add optional callback to call when handshake is done - [API Change, BUGFIX] After send failure, wait until transport available
This commit is contained in:
parent
04468d215d
commit
c44946ecd7
10 changed files with 107 additions and 3 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2018-05-21
|
||||||
|
|
||||||
|
- [API Change] Add optional callback to call when handshake is done
|
||||||
|
- [API Change, BUGFIX] After send failure, wait until transport available
|
||||||
|
|
||||||
2018-05-18
|
2018-05-18
|
||||||
|
|
||||||
- [API] Expose useful lsquic_ver2str[] in lsquic.h
|
- [API] Expose useful lsquic_ver2str[] in lsquic.h
|
||||||
|
|
13
EXAMPLES.txt
13
EXAMPLES.txt
|
@ -97,6 +97,13 @@ LSQUIC_CUBIC_SAMPLING_RATE
|
||||||
|
|
||||||
Only available in debug builds.
|
Only available in debug builds.
|
||||||
|
|
||||||
|
LSQUIC_RANDOM_SEND_FAILURE
|
||||||
|
|
||||||
|
Frequency with which sending of packets fails: one out of this many
|
||||||
|
times on average.
|
||||||
|
|
||||||
|
Only available when compiled with -DLSQUIC_RANDOM_SEND_FAILURE=1
|
||||||
|
|
||||||
Control Network-Related Stuff
|
Control Network-Related Stuff
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
@ -141,3 +148,9 @@ More Compilation Options
|
||||||
|
|
||||||
Add relatively expensive run-time sanity checks
|
Add relatively expensive run-time sanity checks
|
||||||
|
|
||||||
|
-DLSQUIC_RANDOM_SEND_FAILURE=1
|
||||||
|
|
||||||
|
Simulate failure to send packets to test send resumption logic. When
|
||||||
|
this flag is specified, sending of packets will randomly fail, about
|
||||||
|
one out of every 10 attempts. Set environment variable
|
||||||
|
LSQUIC_RANDOM_SEND_FAILURE to change this frequency.
|
||||||
|
|
|
@ -143,6 +143,14 @@ struct lsquic_stream_if {
|
||||||
void (*on_read) (lsquic_stream_t *s, lsquic_stream_ctx_t *h);
|
void (*on_read) (lsquic_stream_t *s, lsquic_stream_ctx_t *h);
|
||||||
void (*on_write) (lsquic_stream_t *s, lsquic_stream_ctx_t *h);
|
void (*on_write) (lsquic_stream_t *s, lsquic_stream_ctx_t *h);
|
||||||
void (*on_close) (lsquic_stream_t *s, lsquic_stream_ctx_t *h);
|
void (*on_close) (lsquic_stream_t *s, lsquic_stream_ctx_t *h);
|
||||||
|
/**
|
||||||
|
* When handshake is completed, this callback is called. `ok' is set
|
||||||
|
* to true if handshake was successful; otherwise, `ok' is set to
|
||||||
|
* false.
|
||||||
|
*
|
||||||
|
* This callback is optional.
|
||||||
|
*/
|
||||||
|
void (*on_hsk_done)(lsquic_conn_t *c, int ok);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -428,7 +436,9 @@ struct lsquic_out_spec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns number of packets successfully sent out or -1 on error. -1 should
|
* Returns number of packets successfully sent out or -1 on error. -1 should
|
||||||
* only be returned if no packets were sent out.
|
* only be returned if no packets were sent out. If -1 is returned,
|
||||||
|
* no packets will be attempted to be sent out until
|
||||||
|
* @ref lsquic_engine_send_unsent_packets() is called.
|
||||||
*/
|
*/
|
||||||
typedef int (*lsquic_packets_out_f)(
|
typedef int (*lsquic_packets_out_f)(
|
||||||
void *packets_out_ctx,
|
void *packets_out_ctx,
|
||||||
|
@ -519,6 +529,10 @@ lsquic_engine_has_unsent_packets (lsquic_engine_t *engine);
|
||||||
/**
|
/**
|
||||||
* Send out as many unsent packets as possibe: until we are out of unsent
|
* Send out as many unsent packets as possibe: until we are out of unsent
|
||||||
* packets or until @ref ea_packets_out() fails.
|
* packets or until @ref ea_packets_out() fails.
|
||||||
|
*
|
||||||
|
* If @ref ea_packets_out() does fail (that is, it returns an error), this
|
||||||
|
* function must be called to signify that sending of packets is possible
|
||||||
|
* again.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
lsquic_engine_send_unsent_packets (lsquic_engine_t *engine);
|
lsquic_engine_send_unsent_packets (lsquic_engine_t *engine);
|
||||||
|
|
|
@ -302,6 +302,7 @@ lsquic_engine_new (unsigned flags,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
engine->pub.enp_ver_tags_len = tag_buf_len;
|
engine->pub.enp_ver_tags_len = tag_buf_len;
|
||||||
|
engine->pub.enp_flags = ENPUB_CAN_SEND;
|
||||||
|
|
||||||
engine->flags = flags;
|
engine->flags = flags;
|
||||||
engine->stream_if = api->ea_stream_if;
|
engine->stream_if = api->ea_stream_if;
|
||||||
|
@ -951,7 +952,9 @@ send_batch (lsquic_engine_t *engine, struct conns_out_iter *conns_iter,
|
||||||
LSQ_DEBUG("packets out returned %d (out of %u)", n_sent, n_to_send);
|
LSQ_DEBUG("packets out returned %d (out of %u)", n_sent, n_to_send);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
engine->pub.enp_flags &= ~ENPUB_CAN_SEND;
|
||||||
LSQ_DEBUG("packets out returned an error: %s", strerror(errno));
|
LSQ_DEBUG("packets out returned an error: %s", strerror(errno));
|
||||||
|
EV_LOG_GENERIC_EVENT("cannot send packets");
|
||||||
n_sent = 0;
|
n_sent = 0;
|
||||||
}
|
}
|
||||||
if (n_sent > 0)
|
if (n_sent > 0)
|
||||||
|
@ -1147,6 +1150,12 @@ lsquic_engine_send_unsent_packets (lsquic_engine_t *engine)
|
||||||
|
|
||||||
STAILQ_INIT(&closed_conns);
|
STAILQ_INIT(&closed_conns);
|
||||||
reset_deadline(engine, lsquic_time_now());
|
reset_deadline(engine, lsquic_time_now());
|
||||||
|
if (!(engine->pub.enp_flags & ENPUB_CAN_SEND))
|
||||||
|
{
|
||||||
|
LSQ_DEBUG("can send again");
|
||||||
|
EV_LOG_GENERIC_EVENT("can send again");
|
||||||
|
engine->pub.enp_flags |= ENPUB_CAN_SEND;
|
||||||
|
}
|
||||||
|
|
||||||
send_packets_out(engine, &closed_conns);
|
send_packets_out(engine, &closed_conns);
|
||||||
|
|
||||||
|
@ -1199,7 +1208,8 @@ process_connections (lsquic_engine_t *engine, conn_iter_f next_conn,
|
||||||
STAILQ_INSERT_TAIL(&ticked_conns, conn, cn_next_ticked);
|
STAILQ_INSERT_TAIL(&ticked_conns, conn, cn_next_ticked);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lsquic_engine_has_unsent_packets(engine))
|
if ((engine->pub.enp_flags & ENPUB_CAN_SEND)
|
||||||
|
&& lsquic_engine_has_unsent_packets(engine))
|
||||||
send_packets_out(engine, &closed_conns);
|
send_packets_out(engine, &closed_conns);
|
||||||
|
|
||||||
while ((conn = STAILQ_FIRST(&closed_conns))) {
|
while ((conn = STAILQ_FIRST(&closed_conns))) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ struct lsquic_engine_public {
|
||||||
ENPUB_PROC = (1 << 0), /* Being processed by one of the user-facing
|
ENPUB_PROC = (1 << 0), /* Being processed by one of the user-facing
|
||||||
* functions.
|
* functions.
|
||||||
*/
|
*/
|
||||||
|
ENPUB_CAN_SEND = (1 << 1),
|
||||||
} enp_flags;
|
} enp_flags;
|
||||||
unsigned char enp_ver_tags_buf[ sizeof(lsquic_ver_tag_t) * N_LSQVER ];
|
unsigned char enp_ver_tags_buf[ sizeof(lsquic_ver_tag_t) * N_LSQVER ];
|
||||||
unsigned enp_ver_tags_len;
|
unsigned enp_ver_tags_len;
|
||||||
|
|
|
@ -3033,6 +3033,8 @@ full_conn_ci_handshake_ok (lsquic_conn_t *lconn)
|
||||||
lconn->cn_flags |= LSCONN_HANDSHAKE_DONE;
|
lconn->cn_flags |= LSCONN_HANDSHAKE_DONE;
|
||||||
else
|
else
|
||||||
conn->fc_flags |= FC_ERROR;
|
conn->fc_flags |= FC_ERROR;
|
||||||
|
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, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3043,6 +3045,8 @@ full_conn_ci_handshake_failed (lsquic_conn_t *lconn)
|
||||||
LSQ_DEBUG("handshake failed");
|
LSQ_DEBUG("handshake failed");
|
||||||
lsquic_alarmset_unset(&conn->fc_alset, AL_HANDSHAKE);
|
lsquic_alarmset_unset(&conn->fc_alset, AL_HANDSHAKE);
|
||||||
conn->fc_flags |= FC_HSK_FAILED;
|
conn->fc_flags |= FC_HSK_FAILED;
|
||||||
|
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, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3389,7 +3393,8 @@ full_conn_ci_is_tickable (lsquic_conn_t *lconn)
|
||||||
if (!TAILQ_EMPTY(&conn->fc_pub.service_streams))
|
if (!TAILQ_EMPTY(&conn->fc_pub.service_streams))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (lsquic_send_ctl_can_send(&conn->fc_send_ctl)
|
if ((conn->fc_enpub->enp_flags & ENPUB_CAN_SEND)
|
||||||
|
&& lsquic_send_ctl_can_send(&conn->fc_send_ctl)
|
||||||
&& (should_generate_ack(conn) ||
|
&& (should_generate_ack(conn) ||
|
||||||
!lsquic_send_ctl_sched_is_blocked(&conn->fc_send_ctl)))
|
!lsquic_send_ctl_sched_is_blocked(&conn->fc_send_ctl)))
|
||||||
{
|
{
|
||||||
|
|
|
@ -147,6 +147,13 @@ http_client_on_conn_closed (lsquic_conn_t *conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
http_client_on_hsk_done (lsquic_conn_t *conn, int ok)
|
||||||
|
{
|
||||||
|
LSQ_INFO("handshake %s", ok ? "completed successfully" : "failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct lsquic_stream_ctx {
|
struct lsquic_stream_ctx {
|
||||||
lsquic_stream_t *stream;
|
lsquic_stream_t *stream;
|
||||||
struct http_client_ctx *client_ctx;
|
struct http_client_ctx *client_ctx;
|
||||||
|
@ -398,6 +405,7 @@ const struct lsquic_stream_if http_client_if = {
|
||||||
.on_read = http_client_on_read,
|
.on_read = http_client_on_read,
|
||||||
.on_write = http_client_on_write,
|
.on_write = http_client_on_write,
|
||||||
.on_close = http_client_on_close,
|
.on_close = http_client_on_close,
|
||||||
|
.on_hsk_done = http_client_on_hsk_done,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
21
test/prog.c
21
test/prog.c
|
@ -419,3 +419,24 @@ prog_is_stopped (void)
|
||||||
{
|
{
|
||||||
return prog_stopped != 0;
|
return prog_stopped != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_unsent (evutil_socket_t fd, short what, void *arg)
|
||||||
|
{
|
||||||
|
struct prog *const prog = arg;
|
||||||
|
assert(prog->prog_send);
|
||||||
|
event_del(prog->prog_send);
|
||||||
|
event_free(prog->prog_send);
|
||||||
|
prog->prog_send = NULL;
|
||||||
|
lsquic_engine_send_unsent_packets(prog->prog_engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
prog_sport_cant_send (struct prog *prog, int fd)
|
||||||
|
{
|
||||||
|
assert(!prog->prog_send);
|
||||||
|
prog->prog_send = event_new(prog->prog_eb, fd, EV_WRITE, send_unsent, prog);
|
||||||
|
event_add(prog->prog_send, NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ struct prog
|
||||||
int prog_version_cleared;
|
int prog_version_cleared;
|
||||||
struct event_base *prog_eb;
|
struct event_base *prog_eb;
|
||||||
struct event *prog_timer,
|
struct event *prog_timer,
|
||||||
|
*prog_send,
|
||||||
*prog_usr1;
|
*prog_usr1;
|
||||||
struct sport_head *prog_sports;
|
struct sport_head *prog_sports;
|
||||||
struct lsquic_engine *prog_engine;
|
struct lsquic_engine *prog_engine;
|
||||||
|
@ -83,4 +84,7 @@ prog_is_stopped (void);
|
||||||
void
|
void
|
||||||
prog_process_conns (struct prog *);
|
prog_process_conns (struct prog *);
|
||||||
|
|
||||||
|
void
|
||||||
|
prog_sport_cant_send (struct prog *, int fd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -875,6 +875,23 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
|
||||||
if (0 == count)
|
if (0 == count)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#if LSQUIC_RANDOM_SEND_FAILURE
|
||||||
|
{
|
||||||
|
const char *freq_str = getenv("LSQUIC_RANDOM_SEND_FAILURE");
|
||||||
|
int freq;
|
||||||
|
if (freq_str)
|
||||||
|
freq = atoi(freq_str);
|
||||||
|
else
|
||||||
|
freq = 10;
|
||||||
|
if (rand() % freq == 0)
|
||||||
|
{
|
||||||
|
assert(count > 0);
|
||||||
|
sport = specs[0].peer_ctx;
|
||||||
|
LSQ_NOTICE("sending \"randomly\" fails");
|
||||||
|
goto random_send_failure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (n = 0; n < count; ++n)
|
for (n = 0; n < count; ++n)
|
||||||
{
|
{
|
||||||
|
@ -931,7 +948,13 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
return n;
|
return n;
|
||||||
else if (s < 0)
|
else if (s < 0)
|
||||||
|
{
|
||||||
|
#if LSQUIC_RANDOM_SEND_FAILURE
|
||||||
|
random_send_failure:
|
||||||
|
#endif
|
||||||
|
prog_sport_cant_send(sport->sp_prog, sport->fd);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue