Skip to content

Commit

Permalink
Release 2.4.7
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
Dmitri Tikhonov committed Oct 15, 2019
1 parent ad08470 commit 0adf085
Show file tree
Hide file tree
Showing 27 changed files with 1,668 additions and 92 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
2019-10-15
- 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.

2019-10-11
- 2.4.6
- Minor code cleanup and logging improvements.
Expand Down
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ ELSE()
ENDIF()

add_executable(http_server test/http_server.c test/prog.c test/test_common.c test/test_cert.c)
add_executable(md5_server test/md5_server.c test/prog.c test/test_common.c test/test_cert.c)
add_executable(md5_client test/md5_client.c test/prog.c test/test_common.c test/test_cert.c)
add_executable(echo_server test/echo_server.c test/prog.c test/test_common.c test/test_cert.c)
add_executable(echo_client test/echo_client.c test/prog.c test/test_common.c test/test_cert.c)


SET(LIBS lsquic ${EVENT_LIB} ${BORINGSSL_LIB_ssl} ${BORINGSSL_LIB_crypto} ${ZLIB_LIB} ${LIBS})
Expand Down Expand Up @@ -230,6 +234,10 @@ ENDIF()

TARGET_LINK_LIBRARIES(http_client ${LIBS})
TARGET_LINK_LIBRARIES(http_server ${LIBS})
TARGET_LINK_LIBRARIES(md5_server ${LIBS})
TARGET_LINK_LIBRARIES(md5_client ${LIBS})
TARGET_LINK_LIBRARIES(echo_server ${LIBS})
TARGET_LINK_LIBRARIES(echo_client ${LIBS})

add_subdirectory(src)

Expand Down
17 changes: 17 additions & 0 deletions EXAMPLES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ LSQUIC comes with several examples of how the library is used.
The client and server programs described below are built on a common
framework and share many options.

Echo client and server
----------------------

Echo client and server (see test/echo_{client,server}.c) are for simple
line-based request and reply communication. Only one stream per connection
is supported for simplicity. The client reads input from stdin.

MD5 client and server
---------------------

See test/md5_{client,server}.c

MD5 server accepts connections, computes MD5 sum of streams' (one or more)
payload, and sends back the checksum. MD5 client sends one or more file
contents to the server. Both client and server support various options to
exercise different aspects of LSQUIC.

HTTP client and server
----------------------

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 2
#define LSQUIC_MINOR_VERSION 4
#define LSQUIC_PATCH_VERSION 6
#define LSQUIC_PATCH_VERSION 7

/**
* Engine flags:
Expand Down
10 changes: 6 additions & 4 deletions src/liblsquic/lsquic_alarmset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/liblsquic/lsquic_alarmset.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
29 changes: 25 additions & 4 deletions src/liblsquic/lsquic_attq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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";
}
}
19 changes: 16 additions & 3 deletions src/liblsquic/lsquic_attq.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};


Expand All @@ -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 *);
Expand All @@ -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
2 changes: 1 addition & 1 deletion src/liblsquic/lsquic_conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
9 changes: 9 additions & 0 deletions src/liblsquic/lsquic_enc_sess_ietf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
};


Expand Down
72 changes: 57 additions & 15 deletions src/liblsquic/lsquic_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion src/liblsquic/lsquic_engine_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *,
Expand Down
Loading

0 comments on commit 0adf085

Please sign in to comment.