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
|
2020-01-31
|
||||||
- 2.10.3
|
- 2.10.3
|
||||||
- [BUGFIX] Cancel path responses and challenges on old path when
|
- [BUGFIX] Cancel path responses and challenges on old path when
|
||||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
||||||
|
|
||||||
#define LSQUIC_MAJOR_VERSION 2
|
#define LSQUIC_MAJOR_VERSION 2
|
||||||
#define LSQUIC_MINOR_VERSION 10
|
#define LSQUIC_MINOR_VERSION 10
|
||||||
#define LSQUIC_PATCH_VERSION 3
|
#define LSQUIC_PATCH_VERSION 4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Engine flags:
|
* Engine flags:
|
||||||
|
|
|
@ -296,6 +296,13 @@ struct enc_session_funcs_iquic
|
||||||
|
|
||||||
void
|
void
|
||||||
(*esfi_handshake_confirmed)(enc_session_t *);
|
(*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
|
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,
|
static void iquic_esfi_shake_stream (enc_session_t *sess,
|
||||||
struct lsquic_stream *stream, const char *what);
|
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_shake_stream = iquic_esfi_shake_stream,
|
||||||
.esfi_handshake_confirmed
|
.esfi_handshake_confirmed
|
||||||
= iquic_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");
|
LSQ_DEBUG("Cannot parse incoming packet's header");
|
||||||
lsquic_mm_put_packet_in(&engine->pub.enp_mm, packet_in);
|
lsquic_mm_put_packet_in(&engine->pub.enp_mm, packet_in);
|
||||||
errno = EINVAL;
|
s = 1;
|
||||||
return -1;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_in_data += packet_in->pi_data_sz;
|
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_BIDI = SEND_MAX_STREAMS + SD_BIDI,
|
||||||
SEND_MAX_STREAMS_UNI = SEND_MAX_STREAMS + SD_UNI,
|
SEND_MAX_STREAMS_UNI = SEND_MAX_STREAMS + SD_UNI,
|
||||||
SEND_STOP_SENDING,
|
SEND_STOP_SENDING,
|
||||||
|
SEND_HANDSHAKE_DONE,
|
||||||
N_SEND
|
N_SEND
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -183,6 +184,7 @@ enum send_flags
|
||||||
SF_SEND_MAX_STREAMS_BIDI = 1 << SEND_MAX_STREAMS_BIDI,
|
SF_SEND_MAX_STREAMS_BIDI = 1 << SEND_MAX_STREAMS_BIDI,
|
||||||
SF_SEND_MAX_STREAMS_UNI = 1 << SEND_MAX_STREAMS_UNI,
|
SF_SEND_MAX_STREAMS_UNI = 1 << SEND_MAX_STREAMS_UNI,
|
||||||
SF_SEND_STOP_SENDING = 1 << SEND_STOP_SENDING,
|
SF_SEND_STOP_SENDING = 1 << SEND_STOP_SENDING,
|
||||||
|
SF_SEND_HANDSHAKE_DONE = 1 << SEND_HANDSHAKE_DONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SF_SEND_PATH_CHAL_ALL \
|
#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);
|
assert(mini_conn->cn_flags & LSCONN_HANDSHAKE_DONE);
|
||||||
conn->ifc_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;
|
conn->ifc_conn.cn_enc_session = mini_conn->cn_enc_session;
|
||||||
mini_conn->cn_enc_session = NULL;
|
mini_conn->cn_enc_session = NULL;
|
||||||
|
@ -2530,7 +2538,7 @@ drop_crypto_streams (struct ietf_full_conn *conn)
|
||||||
struct lsquic_stream **streamp;
|
struct lsquic_stream **streamp;
|
||||||
unsigned count;
|
unsigned count;
|
||||||
|
|
||||||
if (!(conn->ifc_flags & IFC_PROC_CRYPTO))
|
if ((conn->ifc_flags & (IFC_SERVER|IFC_PROC_CRYPTO)) != IFC_PROC_CRYPTO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
conn->ifc_flags &= ~IFC_PROC_CRYPTO;
|
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
|
static void
|
||||||
generate_path_chal_frame (struct ietf_full_conn *conn, lsquic_time_t now,
|
generate_path_chal_frame (struct ietf_full_conn *conn, lsquic_time_t now,
|
||||||
unsigned path_id)
|
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
|
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 lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
||||||
{
|
{
|
||||||
struct stream_frame *stream_frame;
|
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
|
static unsigned
|
||||||
process_stream_frame (struct ietf_full_conn *conn,
|
process_stream_frame (struct ietf_full_conn *conn,
|
||||||
struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
|
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_0] = generate_path_resp_0,
|
||||||
[SEND_PATH_RESP_PATH_1] = generate_path_resp_1,
|
[SEND_PATH_RESP_PATH_1] = generate_path_resp_1,
|
||||||
[SEND_PING] = generate_ping_frame,
|
[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_MAX_STREAMS_UNI|SF_SEND_MAX_STREAMS_BIDI\
|
||||||
|SF_SEND_PATH_CHAL_PATH_0|SF_SEND_PATH_CHAL_PATH_1\
|
|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_PATH_RESP_PATH_0|SF_SEND_PATH_RESP_PATH_1\
|
||||||
|SF_SEND_PING\
|
|SF_SEND_PING|SF_SEND_HANDSHAKE_DONE\
|
||||||
|SF_SEND_STOP_SENDING)
|
|SF_SEND_STOP_SENDING)
|
||||||
|
|
||||||
static enum tick_st
|
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_frame_types |= 1 << QUIC_FRAME_HANDSHAKE_DONE;
|
||||||
packet_out->po_data_sz += sz;
|
packet_out->po_data_sz += sz;
|
||||||
LSQ_DEBUG("generated HANDSHAKE_DONE frame");
|
LSQ_DEBUG("generated HANDSHAKE_DONE frame");
|
||||||
|
conn->imc_flags |= IMC_HSK_DONE_SENT;
|
||||||
|
|
||||||
return 0;
|
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)
|
else if (conn->imc_flags & IMC_HSK_OK)
|
||||||
{
|
{
|
||||||
if (conn->imc_conn.cn_version > LSQVER_ID24
|
if (conn->imc_conn.cn_version > LSQVER_ID24)
|
||||||
&& 0 != imico_generate_handshake_done(conn))
|
{
|
||||||
goto close_on_error;
|
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;
|
tick |= TICK_PROMOTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct ietf_mini_conn
|
||||||
IMC_CLOSE_RECVD = 1 << 19,
|
IMC_CLOSE_RECVD = 1 << 19,
|
||||||
IMC_PARSE_FAILED = 1 << 20,
|
IMC_PARSE_FAILED = 1 << 20,
|
||||||
IMC_PATH_CHANGED = 1 << 21,
|
IMC_PATH_CHANGED = 1 << 21,
|
||||||
|
IMC_HSK_DONE_SENT = 1 << 22,
|
||||||
} imc_flags;
|
} imc_flags;
|
||||||
struct mini_crypto_stream imc_streams[N_ENC_LEVS];
|
struct mini_crypto_stream imc_streams[N_ENC_LEVS];
|
||||||
void *imc_stream_ps[N_ENC_LEVS];
|
void *imc_stream_ps[N_ENC_LEVS];
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#if !(defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0) && defined(__APPLE__)
|
#if !(defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0) && defined(__APPLE__)
|
||||||
#include <mach/mach_time.h>
|
#include <mach/mach_time.h>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue