mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 2.10.4
- [BUGFIX] Send HANDSHAKE_DONE only after Finished is received. - [BUGFIX] Don't treat garbage UDP padding as library error; ignore it instead. - [BUGFIX] Fix compilation on FreeBSD (missing header).
This commit is contained in:
parent
45aae370f6
commit
e68b045258
9 changed files with 170 additions and 9 deletions
|
@ -1,3 +1,11 @@
|
|||
2020-02-11
|
||||
- 2.10.4
|
||||
- [BUGFIX] Send HANDSHAKE_DONE only after Finished is received.
|
||||
- [BUGFIX] Don't treat garbage UDP padding as library error; ignore
|
||||
it instead.
|
||||
- [BUGFIX] Fix compilation on FreeBSD (missing header).
|
||||
- Code cleanup: remove unnecessary #includes.
|
||||
|
||||
2020-01-31
|
||||
- 2.10.3
|
||||
- [BUGFIX] Cancel path responses and challenges on old path when
|
||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
|||
|
||||
#define LSQUIC_MAJOR_VERSION 2
|
||||
#define LSQUIC_MINOR_VERSION 10
|
||||
#define LSQUIC_PATCH_VERSION 3
|
||||
#define LSQUIC_PATCH_VERSION 4
|
||||
|
||||
/**
|
||||
* Engine flags:
|
||||
|
|
|
@ -296,6 +296,13 @@ struct enc_session_funcs_iquic
|
|||
|
||||
void
|
||||
(*esfi_handshake_confirmed)(enc_session_t *);
|
||||
|
||||
int
|
||||
(*esfi_in_init)(enc_session_t *);
|
||||
|
||||
int
|
||||
(*esfi_data_in)(enc_session_t *, enum enc_level,
|
||||
const unsigned char *, size_t);
|
||||
};
|
||||
|
||||
extern
|
||||
|
|
|
@ -2238,6 +2238,55 @@ iquic_esfi_handshake_confirmed (enc_session_t *sess)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
iquic_esfi_in_init (enc_session_t *sess)
|
||||
{
|
||||
struct enc_sess_iquic *enc_sess = (struct enc_sess_iquic *) sess;
|
||||
int in_init;
|
||||
|
||||
if (enc_sess->esi_ssl)
|
||||
{
|
||||
in_init = SSL_in_init(enc_sess->esi_ssl);
|
||||
LSQ_DEBUG("in_init: %d", in_init);
|
||||
return in_init;
|
||||
}
|
||||
else
|
||||
{
|
||||
LSQ_DEBUG("no SSL object, in_init: 0");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
iquic_esfi_data_in (enc_session_t *sess, enum enc_level enc_level,
|
||||
const unsigned char *buf, size_t len)
|
||||
{
|
||||
struct enc_sess_iquic *enc_sess = (struct enc_sess_iquic *) sess;
|
||||
int s;
|
||||
size_t str_sz;
|
||||
char str[MAX(1500 * 5, ERR_ERROR_STRING_BUF_LEN)];
|
||||
|
||||
if (!enc_sess->esi_ssl)
|
||||
return -1;
|
||||
|
||||
s = SSL_provide_quic_data(enc_sess->esi_ssl,
|
||||
(enum ssl_encryption_level_t) enc_level, buf, len);
|
||||
if (!s)
|
||||
{
|
||||
LSQ_WARN("SSL_provide_quic_data returned false: %s",
|
||||
ERR_error_string(ERR_get_error(), str));
|
||||
return -1;
|
||||
}
|
||||
LSQ_DEBUG("provided %zu bytes of %u-level data to SSL", len, enc_level);
|
||||
str_sz = lsquic_hexdump(buf, len, str, sizeof(str));
|
||||
LSQ_DEBUG("\n%.*s", (int) str_sz, str);
|
||||
s = SSL_do_handshake(enc_sess->esi_ssl);
|
||||
LSQ_DEBUG("do_handshake returns %d", s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void iquic_esfi_shake_stream (enc_session_t *sess,
|
||||
struct lsquic_stream *stream, const char *what);
|
||||
|
||||
|
@ -2255,6 +2304,8 @@ const struct enc_session_funcs_iquic lsquic_enc_session_iquic_ietf_v1 =
|
|||
.esfi_shake_stream = iquic_esfi_shake_stream,
|
||||
.esfi_handshake_confirmed
|
||||
= iquic_esfi_handshake_confirmed,
|
||||
.esfi_in_init = iquic_esfi_in_init,
|
||||
.esfi_data_in = iquic_esfi_data_in,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2657,8 +2657,8 @@ lsquic_engine_packet_in (lsquic_engine_t *engine,
|
|||
{
|
||||
LSQ_DEBUG("Cannot parse incoming packet's header");
|
||||
lsquic_mm_put_packet_in(&engine->pub.enp_mm, packet_in);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
s = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
packet_in_data += packet_in->pi_data_sz;
|
||||
|
|
|
@ -160,6 +160,7 @@ enum send
|
|||
SEND_MAX_STREAMS_BIDI = SEND_MAX_STREAMS + SD_BIDI,
|
||||
SEND_MAX_STREAMS_UNI = SEND_MAX_STREAMS + SD_UNI,
|
||||
SEND_STOP_SENDING,
|
||||
SEND_HANDSHAKE_DONE,
|
||||
N_SEND
|
||||
};
|
||||
|
||||
|
@ -183,6 +184,7 @@ enum send_flags
|
|||
SF_SEND_MAX_STREAMS_BIDI = 1 << SEND_MAX_STREAMS_BIDI,
|
||||
SF_SEND_MAX_STREAMS_UNI = 1 << SEND_MAX_STREAMS_UNI,
|
||||
SF_SEND_STOP_SENDING = 1 << SEND_STOP_SENDING,
|
||||
SF_SEND_HANDSHAKE_DONE = 1 << SEND_HANDSHAKE_DONE,
|
||||
};
|
||||
|
||||
#define SF_SEND_PATH_CHAL_ALL \
|
||||
|
@ -1321,6 +1323,12 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub,
|
|||
|
||||
assert(mini_conn->cn_flags & LSCONN_HANDSHAKE_DONE);
|
||||
conn->ifc_conn.cn_flags |= LSCONN_HANDSHAKE_DONE;
|
||||
if (mini_conn->cn_version > LSQVER_ID24
|
||||
&& !(imc->imc_flags & IMC_HSK_DONE_SENT))
|
||||
{
|
||||
LSQ_DEBUG("HANDSHAKE_DONE not yet sent, will process CRYPTO frames");
|
||||
conn->ifc_flags |= IFC_PROC_CRYPTO;
|
||||
}
|
||||
|
||||
conn->ifc_conn.cn_enc_session = mini_conn->cn_enc_session;
|
||||
mini_conn->cn_enc_session = NULL;
|
||||
|
@ -2530,7 +2538,7 @@ drop_crypto_streams (struct ietf_full_conn *conn)
|
|||
struct lsquic_stream **streamp;
|
||||
unsigned count;
|
||||
|
||||
if (!(conn->ifc_flags & IFC_PROC_CRYPTO))
|
||||
if ((conn->ifc_flags & (IFC_SERVER|IFC_PROC_CRYPTO)) != IFC_PROC_CRYPTO)
|
||||
return;
|
||||
|
||||
conn->ifc_flags &= ~IFC_PROC_CRYPTO;
|
||||
|
@ -3809,6 +3817,34 @@ generate_ping_frame (struct ietf_full_conn *conn, lsquic_time_t unused)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_handshake_done_frame (struct ietf_full_conn *conn,
|
||||
lsquic_time_t unused)
|
||||
{
|
||||
struct lsquic_packet_out *packet_out;
|
||||
unsigned need;
|
||||
int sz;
|
||||
|
||||
need = conn->ifc_conn.cn_pf->pf_handshake_done_frame_size();
|
||||
packet_out = get_writeable_packet(conn, need);
|
||||
if (!packet_out)
|
||||
return;
|
||||
sz = conn->ifc_conn.cn_pf->pf_gen_handshake_done_frame(
|
||||
packet_out->po_data + packet_out->po_data_sz,
|
||||
lsquic_packet_out_avail(packet_out));
|
||||
if (sz < 0)
|
||||
{
|
||||
ABORT_ERROR("generate_handshake_done_frame failed");
|
||||
return;
|
||||
}
|
||||
|
||||
lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, sz);
|
||||
packet_out->po_frame_types |= QUIC_FTBIT_HANDSHAKE_DONE;
|
||||
LSQ_DEBUG("generated HANDSHAKE_DONE frame");
|
||||
conn->ifc_send_flags &= ~SF_SEND_HANDSHAKE_DONE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_path_chal_frame (struct ietf_full_conn *conn, lsquic_time_t now,
|
||||
unsigned path_id)
|
||||
|
@ -4518,8 +4554,48 @@ discard_crypto_frame (struct ietf_full_conn *conn,
|
|||
}
|
||||
|
||||
|
||||
/* In the server, we only wait for Finished frame */
|
||||
static unsigned
|
||||
process_crypto_frame (struct ietf_full_conn *conn,
|
||||
process_crypto_frame_server (struct ietf_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
{
|
||||
struct stream_frame stream_frame;
|
||||
int parsed_len;
|
||||
|
||||
parsed_len = conn->ifc_conn.cn_pf->pf_parse_crypto_frame(p, len,
|
||||
&stream_frame);
|
||||
if (parsed_len < 0)
|
||||
return 0;
|
||||
|
||||
if (!(conn->ifc_flags & IFC_PROC_CRYPTO))
|
||||
{
|
||||
LSQ_DEBUG("discard %d-byte CRYPTO frame", parsed_len);
|
||||
return (unsigned) parsed_len;
|
||||
}
|
||||
|
||||
if (0 != conn->ifc_conn.cn_esf.i->esfi_data_in(
|
||||
conn->ifc_conn.cn_enc_session,
|
||||
lsquic_packet_in_enc_level(packet_in),
|
||||
stream_frame.data_frame.df_data,
|
||||
stream_frame.data_frame.df_size))
|
||||
{
|
||||
LSQ_DEBUG("feeding CRYPTO frame to enc session failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!conn->ifc_conn.cn_esf.i->esfi_in_init(conn->ifc_conn.cn_enc_session))
|
||||
{
|
||||
LSQ_DEBUG("handshake confirmed: send HANDSHAKE_DONE");
|
||||
conn->ifc_flags &= ~IFC_PROC_CRYPTO;
|
||||
conn->ifc_send_flags |= SF_SEND_HANDSHAKE_DONE;
|
||||
}
|
||||
|
||||
return (unsigned) parsed_len;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
process_crypto_frame_client (struct ietf_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
{
|
||||
struct stream_frame *stream_frame;
|
||||
|
@ -4607,6 +4683,17 @@ process_crypto_frame (struct ietf_full_conn *conn,
|
|||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
process_crypto_frame (struct ietf_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
{
|
||||
if (conn->ifc_flags & IFC_SERVER)
|
||||
return process_crypto_frame_server(conn, packet_in, p, len);
|
||||
else
|
||||
return process_crypto_frame_client(conn, packet_in, p, len);
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
process_stream_frame (struct ietf_full_conn *conn,
|
||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||
|
@ -6283,6 +6370,7 @@ static void (*const send_funcs[N_SEND])(
|
|||
[SEND_PATH_RESP_PATH_0] = generate_path_resp_0,
|
||||
[SEND_PATH_RESP_PATH_1] = generate_path_resp_1,
|
||||
[SEND_PING] = generate_ping_frame,
|
||||
[SEND_HANDSHAKE_DONE] = generate_handshake_done_frame,
|
||||
};
|
||||
|
||||
|
||||
|
@ -6292,7 +6380,7 @@ static void (*const send_funcs[N_SEND])(
|
|||
|SF_SEND_MAX_STREAMS_UNI|SF_SEND_MAX_STREAMS_BIDI\
|
||||
|SF_SEND_PATH_CHAL_PATH_0|SF_SEND_PATH_CHAL_PATH_1\
|
||||
|SF_SEND_PATH_RESP_PATH_0|SF_SEND_PATH_RESP_PATH_1\
|
||||
|SF_SEND_PING\
|
||||
|SF_SEND_PING|SF_SEND_HANDSHAKE_DONE\
|
||||
|SF_SEND_STOP_SENDING)
|
||||
|
||||
static enum tick_st
|
||||
|
|
|
@ -1645,6 +1645,7 @@ imico_generate_handshake_done (struct ietf_mini_conn *conn)
|
|||
packet_out->po_frame_types |= 1 << QUIC_FRAME_HANDSHAKE_DONE;
|
||||
packet_out->po_data_sz += sz;
|
||||
LSQ_DEBUG("generated HANDSHAKE_DONE frame");
|
||||
conn->imc_flags |= IMC_HSK_DONE_SENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1685,9 +1686,13 @@ ietf_mini_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now)
|
|||
}
|
||||
else if (conn->imc_flags & IMC_HSK_OK)
|
||||
{
|
||||
if (conn->imc_conn.cn_version > LSQVER_ID24
|
||||
&& 0 != imico_generate_handshake_done(conn))
|
||||
goto close_on_error;
|
||||
if (conn->imc_conn.cn_version > LSQVER_ID24)
|
||||
{
|
||||
if (lconn->cn_esf.i->esfi_in_init(lconn->cn_enc_session))
|
||||
LSQ_DEBUG("still in init, defer HANDSHAKE_DONE");
|
||||
else if (0 != imico_generate_handshake_done(conn))
|
||||
goto close_on_error;
|
||||
}
|
||||
tick |= TICK_PROMOTE;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ struct ietf_mini_conn
|
|||
IMC_CLOSE_RECVD = 1 << 19,
|
||||
IMC_PARSE_FAILED = 1 << 20,
|
||||
IMC_PATH_CHANGED = 1 << 21,
|
||||
IMC_HSK_DONE_SENT = 1 << 22,
|
||||
} imc_flags;
|
||||
struct mini_crypto_stream imc_streams[N_ENC_LEVS];
|
||||
void *imc_stream_ps[N_ENC_LEVS];
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#if !(defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0) && defined(__APPLE__)
|
||||
#include <mach/mach_time.h>
|
||||
|
|
Loading…
Reference in a new issue