Skip to content

Commit

Permalink
Release 2.4.2
Browse files Browse the repository at this point in the history
- [BUGFIX] H3 framing: fix zero-byte write when space is available
- [BUGFIX] Don't send STREAM frame when incoming unidirectgional stream
  is closed
- [BUGFIX] Cancel all pending writes by stream reset by a GOAWAY
- [BUGFIX] Fix use-after-free in IETF full conn
- [OPTIMIZATION] Wait for session tickets for two seconds and then drop
  SSL object and crypto streams.
  • Loading branch information
Dmitri Tikhonov committed Sep 23, 2019
1 parent 3ff30b2 commit 65728dc
Show file tree
Hide file tree
Showing 11 changed files with 320 additions and 109 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
2019-09-23
- 2.4.2
- [BUGFIX] H3 framing: fix zero-byte write when space is available
- [BUGFIX] Don't send STREAM frame when incoming unidirectgional stream
is closed
- [BUGFIX] Cancel all pending writes by stream reset by a GOAWAY
- [BUGFIX] Fix use-after-free in IETF full conn
- [OPTIMIZATION] Wait for session tickets for two seconds and then drop
SSL object and crypto streams.

2019-09-18
- 2.4.0
- [FEATURE] QUIC and HTTP/3 Internet Draft 23 support
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 0
#define LSQUIC_PATCH_VERSION 2

/**
* Engine flags:
Expand Down
1 change: 1 addition & 0 deletions src/liblsquic/lsquic_alarmset.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ static const char *const lsquic_alid2str[] =
[AL_CID_THROT] = "CID_THROT",
[AL_PATH_CHAL_0] = "PATH_CHAL_0",
[AL_PATH_CHAL_1] = "PATH_CHAL_1",
[AL_SESS_TICKET] = "SESS_TICKET",
};


Expand Down
2 changes: 2 additions & 0 deletions src/liblsquic/lsquic_alarmset.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum alarm_id {
AL_PATH_CHAL,
AL_PATH_CHAL_0 = AL_PATH_CHAL,
AL_PATH_CHAL_1,
AL_SESS_TICKET,
MAX_LSQUIC_ALARMS
};

Expand All @@ -54,6 +55,7 @@ enum alarm_id_bit {
ALBIT_PATH_CHAL = 1 << AL_PATH_CHAL,
ALBIT_PATH_CHAL_0 = 1 << AL_PATH_CHAL_0,
ALBIT_PATH_CHAL_1 = 1 << AL_PATH_CHAL_1,
ALBIT_SESS_TICKET = 1 << AL_SESS_TICKET,
};


Expand Down
4 changes: 4 additions & 0 deletions src/liblsquic/lsquic_conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ struct conn_iface

const lsquic_cid_t *
(*ci_get_log_cid) (const struct lsquic_conn *);

/* Optional method. Only used by the IETF client code. */
void
(*ci_drop_crypto_streams) (struct lsquic_conn *);
};

#define LSCONN_CCE_BITS 3
Expand Down
4 changes: 3 additions & 1 deletion src/liblsquic/lsquic_enc_sess.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#ifndef LSQUIC_ENC_SESS_H
#define LSQUIC_ENC_SESS_H 1

struct lsquic_alarmset;
struct lsquic_engine_public;
struct lsquic_packet_out;
struct lsquic_packet_in;
Expand Down Expand Up @@ -262,7 +263,8 @@ struct enc_session_funcs_iquic
struct lsquic_conn *, const struct lsquic_cid *,
const struct ver_neg *, void *(crypto_streams)[4],
const struct crypto_stream_if *,
const unsigned char *, size_t);
const unsigned char *, size_t,
struct lsquic_alarmset *);

void
(*esfi_destroy) (enc_session_t *);
Expand Down
96 changes: 82 additions & 14 deletions src/liblsquic/lsquic_enc_sess_ietf.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "lsquic_frab_list.h"
#include "lsquic_tokgen.h"
#include "lsquic_ietf.h"
#include "lsquic_alarmset.h"

#if __GNUC__
# define UNLIKELY(cond) __builtin_expect(cond, 0)
Expand Down Expand Up @@ -106,6 +107,10 @@ iquic_esf_get_server_cert_chain (enc_session_t *);
static void
maybe_drop_SSL (struct enc_sess_iquic *);

static void
no_sess_ticket (enum alarm_id alarm_id, void *ctx,
lsquic_time_t expiry, lsquic_time_t now);


typedef void (*gen_hp_mask_f)(struct enc_sess_iquic *,
const struct header_prot *, unsigned cliser,
Expand Down Expand Up @@ -236,6 +241,7 @@ struct enc_sess_iquic
ESI_ALPN_CHECKED = 1 << 8,
ESI_CACHED_INFO = 1 << 9,
ESI_1RTT_ACKED = 1 << 10,
ESI_WANT_TICKET = 1 << 11,
} esi_flags;
enum evp_aead_direction_t
esi_dir[2]; /* client, server */
Expand Down Expand Up @@ -264,6 +270,8 @@ struct enc_sess_iquic
struct frab_list esi_frals[N_ENC_LEVS];
struct transport_params
esi_peer_tp;
struct lsquic_alarmset
*esi_alset;
};


Expand Down Expand Up @@ -651,7 +659,8 @@ iquic_esfi_create_client (const char *hostname,
struct lsquic_engine_public *enpub, struct lsquic_conn *lconn,
const lsquic_cid_t *dcid, const struct ver_neg *ver_neg,
void *crypto_streams[4], const struct crypto_stream_if *cryst_if,
const unsigned char *zero_rtt, size_t zero_rtt_sz)
const unsigned char *zero_rtt, size_t zero_rtt_sz,
struct lsquic_alarmset *alset)
{
struct enc_sess_iquic *enc_sess;

Expand Down Expand Up @@ -720,6 +729,12 @@ iquic_esfi_create_client (const char *hostname,
enc_sess->esi_zero_rtt_sz = 0;
}

if (enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info)
enc_sess->esi_flags |= ESI_WANT_TICKET;
enc_sess->esi_alset = alset;
lsquic_alarmset_init_alarm(enc_sess->esi_alset, AL_SESS_TICKET,
no_sess_ticket, enc_sess);

return enc_sess;
}

Expand Down Expand Up @@ -1192,6 +1207,8 @@ iquic_new_session_cb (SSL *ssl, SSL_SESSION *session)
enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info(enc_sess->esi_conn,
buf, buf_sz);
free(buf);
enc_sess->esi_flags &= ~ESI_WANT_TICKET;
lsquic_alarmset_unset(enc_sess->esi_alset, AL_SESS_TICKET);
return 0;
}

Expand Down Expand Up @@ -2202,6 +2219,20 @@ cache_info (struct enc_sess_iquic *enc_sess)
}


static void
drop_SSL (struct enc_sess_iquic *enc_sess)
{
LSQ_DEBUG("drop SSL object");
if (enc_sess->esi_conn->cn_if->ci_drop_crypto_streams)
enc_sess->esi_conn->cn_if->ci_drop_crypto_streams(
enc_sess->esi_conn);
cache_info(enc_sess);
SSL_free(enc_sess->esi_ssl);
enc_sess->esi_ssl = NULL;
free_handshake_keys(enc_sess);
}


static void
maybe_drop_SSL (struct enc_sess_iquic *enc_sess)
{
Expand All @@ -2216,15 +2247,32 @@ maybe_drop_SSL (struct enc_sess_iquic *enc_sess)
&& enc_sess->esi_ssl
&& lsquic_frab_list_empty(&enc_sess->esi_frals[ENC_LEV_FORW]))
{
LSQ_DEBUG("drop SSL object");
cache_info(enc_sess);
SSL_free(enc_sess->esi_ssl);
enc_sess->esi_ssl = NULL;
free_handshake_keys(enc_sess);
if ((enc_sess->esi_flags & (ESI_SERVER|ESI_WANT_TICKET))
!= ESI_WANT_TICKET)
drop_SSL(enc_sess);
else if (enc_sess->esi_alset
&& !lsquic_alarmset_is_set(enc_sess->esi_alset, AL_SESS_TICKET))
{
LSQ_DEBUG("no session ticket: delay dropping SSL object");
lsquic_alarmset_set(enc_sess->esi_alset, AL_SESS_TICKET,
/* Wait up to two seconds for session tickets */
lsquic_time_now() + 2000000);
}
}
}


static void
no_sess_ticket (enum alarm_id alarm_id, void *ctx,
lsquic_time_t expiry, lsquic_time_t now)
{
struct enc_sess_iquic *enc_sess = ctx;

LSQ_DEBUG("no session tickets forthcoming -- drop SSL");
drop_SSL(enc_sess);
}


typedef char enums_have_the_same_value[
(int) ssl_encryption_initial == (int) ENC_LEV_CLEAR &&
(int) ssl_encryption_early_data == (int) ENC_LEV_EARLY &&
Expand Down Expand Up @@ -2583,23 +2631,43 @@ readf_cb (void *ctx, const unsigned char *buf, size_t len, int fin)
}


static size_t
discard_cb (void *ctx, const unsigned char *buf, size_t len, int fin)
{
return len;
}


static void
chsk_ietf_on_read (struct lsquic_stream *stream, lsquic_stream_ctx_t *ctx)
{
struct enc_sess_iquic *const enc_sess = (void *) ctx;
enum enc_level enc_level = enc_sess->esi_cryst_if->csi_enc_level(stream);
struct readf_ctx readf_ctx = { enc_sess, enc_level, 0, };
ssize_t nread;


ssize_t nread = enc_sess->esi_cryst_if->csi_readf(stream,
readf_cb, &readf_ctx);

if (!(nread < 0 || readf_ctx.err))
iquic_esfi_shake_stream((enc_session_t *)enc_sess, stream, "on_read");
if (enc_sess->esi_ssl)
{
nread = enc_sess->esi_cryst_if->csi_readf(stream, readf_cb, &readf_ctx);
if (!(nread < 0 || readf_ctx.err))
iquic_esfi_shake_stream((enc_session_t *)enc_sess, stream,
"on_read");
else
enc_sess->esi_conn->cn_if->ci_internal_error(enc_sess->esi_conn,
"shaking stream failed: nread: %zd, err: %d, SSL err: %"PRIu32,
nread, readf_ctx.err, ERR_get_error());
}
else
enc_sess->esi_conn->cn_if->ci_internal_error(enc_sess->esi_conn,
"shaking stream failed: nread: %zd, err: %d, SSL err: %"PRIu32,
nread, readf_ctx.err, ERR_get_error());
{
/* This branch is reached when we don't want TLS ticket and drop
* the SSL object before we process TLS tickets that have been
* already received and waiting in the incoming stream buffer.
*/
nread = enc_sess->esi_cryst_if->csi_readf(stream, discard_cb, NULL);
lsquic_stream_wantread(stream, 0);
LSQ_DEBUG("no SSL object: discard %zd bytes of SSL data", nread);
}
}


Expand Down
Loading

0 comments on commit 65728dc

Please sign in to comment.