MINOR: quic: Drop packets with STREAM frames with wrong direction.

A server initiates streams with odd-numbered stream IDs.
Also add useful traces when parsing STREAM frames.
This commit is contained in:
Frdric Lcaille 2020-12-31 12:45:38 +01:00 committed by Willy Tarreau
parent 129a351a3f
commit 242fb1b639
4 changed files with 36 additions and 7 deletions

View File

@ -88,9 +88,14 @@ enum quic_frame_type {
#define QUIC_FT_PKT_TYPE____1_BITMASK QUIC_FT_PKT_TYPE_1_BITMASK
#define QUIC_STREAM_FRAME_FIN_BIT 0x01
#define QUIC_STREAM_FRAME_LEN_BIT 0x02
#define QUIC_STREAM_FRAME_OFF_BIT 0x04
#define QUIC_STREAM_FRAME_TYPE_FIN_BIT 0x01
#define QUIC_STREAM_FRAME_TYPE_LEN_BIT 0x02
#define QUIC_STREAM_FRAME_TYPE_OFF_BIT 0x04
/* Servers have the stream initiator bit set. */
#define QUIC_STREAM_FRAME_ID_INITIATOR_BIT 0x01
/* Unidirectional streams have the direction bit set. */
#define QUIC_STREAM_FRAME_ID_DIR_BIT 0x02
#define QUIC_PATH_CHALLENGE_LEN 8

View File

@ -201,6 +201,7 @@ enum quic_pkt_type {
#define QUIC_EV_CONN_ADDDATA (1ULL << 25)
#define QUIC_EV_CONN_FFLIGHT (1ULL << 26)
#define QUIC_EV_CONN_SSLALERT (1ULL << 27)
#define QUIC_EV_CONN_PSTRM (1ULL << 28)
#define QUIC_EV_CONN_RTTUPDT (1ULL << 29)
#define QUIC_EV_CONN_CC (1ULL << 30)
#define QUIC_EV_CONN_SPPKTS (1ULL << 31)

View File

@ -377,8 +377,8 @@ static int quic_build_stream_frame(unsigned char **buf, const unsigned char *end
struct quic_stream *stream = &frm->stream;
if (!quic_enc_int(buf, end, stream->id) ||
((frm->type & QUIC_STREAM_FRAME_OFF_BIT) && !quic_enc_int(buf, end, stream->offset)) ||
((frm->type & QUIC_STREAM_FRAME_LEN_BIT) &&
((frm->type & QUIC_STREAM_FRAME_TYPE_OFF_BIT) && !quic_enc_int(buf, end, stream->offset)) ||
((frm->type & QUIC_STREAM_FRAME_TYPE_LEN_BIT) &&
(!quic_enc_int(buf, end, stream->len) || end - *buf < stream->len)))
return 0;
@ -400,14 +400,14 @@ static int quic_parse_stream_frame(struct quic_frame *frm, struct quic_conn *qc,
return 0;
/* Offset parsing */
if (!(frm->type & QUIC_STREAM_FRAME_OFF_BIT)) {
if (!(frm->type & QUIC_STREAM_FRAME_TYPE_OFF_BIT)) {
stream->offset = 0;
}
else if (!quic_dec_int(&stream->offset, buf, end))
return 0;
/* Length parsing */
if (!(frm->type & QUIC_STREAM_FRAME_LEN_BIT)) {
if (!(frm->type & QUIC_STREAM_FRAME_TYPE_LEN_BIT)) {
stream->len = end - *buf;
}
else if (!quic_dec_int(&stream->len, buf, end) || end - *buf < stream->len)

View File

@ -571,6 +571,18 @@ static void quic_trace(enum trace_level level, uint64_t mask, const struct trace
if (sz3)
chunk_appendf(&trace_buf, " %llu", (unsigned long long)*sz3);
}
if (mask & QUIC_EV_CONN_PSTRM) {
const struct quic_frame *frm = a2;
const struct quic_stream *s = &frm->stream;
chunk_appendf(&trace_buf, " uni=%d fin=%d id=%llu off=%llu len=%llu",
!!(s->id & QUIC_STREAM_FRAME_ID_DIR_BIT),
!!(frm->type & QUIC_STREAM_FRAME_TYPE_FIN_BIT),
(unsigned long long)s->id,
(unsigned long long)s->offset,
(unsigned long long)s->len);
}
}
if (mask & QUIC_EV_CONN_LPKT) {
const struct quic_rx_packet *pkt = a2;
@ -1642,6 +1654,17 @@ static int qc_parse_pkt_frms(struct quic_rx_packet *pkt, struct quic_conn_ctx *c
case QUIC_FT_STREAM_D:
case QUIC_FT_STREAM_E:
case QUIC_FT_STREAM_F:
{
struct quic_stream *stream = &frm.stream;
TRACE_PROTO("STREAM frame", QUIC_EV_CONN_PSTRM, ctx->conn, &frm);
if (objt_listener(ctx->conn->target)) {
if (stream->id & QUIC_STREAM_FRAME_ID_INITIATOR_BIT)
goto err;
} else if (!(stream->id & QUIC_STREAM_FRAME_ID_INITIATOR_BIT))
goto err;
break;
}
case QUIC_FT_NEW_CONNECTION_ID:
break;
case QUIC_FT_CONNECTION_CLOSE: