Packages
hackney
3.0.2
4.7.2
4.7.1
4.7.0
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.5
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
3.2.1
3.2.0
3.1.2
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
retired
2.0.1
2.0.0
2.0.0-beta.1
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.1
1.20.0
1.19.1
1.19.0
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.0
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.0
1.13.0
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.0
1.7.1
1.7.0
1.6.6
retired
1.6.5
1.6.4
retired
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.6
1.0.5
1.0.2
1.0.1
0.15.2
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
Simple HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
c_src/lsquic/src/liblsquic/lsquic_parse_common.c
/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
#include <assert.h>
#include <string.h>
#include <sys/queue.h>
#include <sys/types.h>
#include "lsquic.h"
#include "lsquic_types.h"
#include "lsquic_int_types.h"
#include "lsquic_packet_common.h"
#include "lsquic_packet_in.h"
#include "lsquic_parse_common.h"
#include "lsquic_parse.h"
#include "lsquic_enc_sess.h"
#include "lsquic_version.h"
#include "lsquic_qtags.h"
static int
parse_ietf_v1_or_Q046plus_long_begin (struct lsquic_packet_in *packet_in,
size_t length, int is_server, unsigned cid_len,
struct packin_parse_state *state)
{
enum lsquic_version version;
if (length < 6)
return -1;
version = lsquic_tag2ver_fast(packet_in->pi_data + 1);
if (version != N_LSQVER)
{
packet_in->pi_version = version;
packet_in->pi_flags |= PI_VER_PARSED;
}
switch (version)
{
case LSQVER_046:
return lsquic_Q046_parse_packet_in_long_begin(packet_in, length,
is_server, cid_len, state);
case LSQVER_050:
return lsquic_Q050_parse_packet_in_long_begin(packet_in, length,
is_server, cid_len, state);
default:
return lsquic_ietf_v1_parse_packet_in_long_begin(packet_in, length,
is_server, cid_len, state);
}
}
static int (* const parse_begin_funcs[32]) (struct lsquic_packet_in *,
size_t length, int is_server, unsigned cid_len,
struct packin_parse_state *) =
{
/* Xs vary, Gs are iGnored: */
#define PBEL(mask) [(mask) >> 3]
/* 1X11 XGGG: */
PBEL(0x80|0x40|0x20|0x10|0x08) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x00|0x20|0x10|0x08) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x40|0x20|0x10|0x00) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x00|0x20|0x10|0x00) = parse_ietf_v1_or_Q046plus_long_begin,
/* 1X00 XGGG: */
PBEL(0x80|0x40|0x00|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x00|0x00|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x40|0x00|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x00|0x00|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin,
/* 1X01 XGGG: */
PBEL(0x80|0x40|0x00|0x10|0x08) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x00|0x00|0x10|0x08) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x40|0x00|0x10|0x00) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x00|0x00|0x10|0x00) = parse_ietf_v1_or_Q046plus_long_begin,
/* 1X10 XGGG: */
PBEL(0x80|0x40|0x20|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x00|0x20|0x00|0x08) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x40|0x20|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin,
PBEL(0x80|0x00|0x20|0x00|0x00) = parse_ietf_v1_or_Q046plus_long_begin,
/* 01XX XGGG */
PBEL(0x00|0x40|0x00|0x00|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin,
PBEL(0x00|0x40|0x00|0x00|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin,
PBEL(0x00|0x40|0x00|0x10|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin,
PBEL(0x00|0x40|0x00|0x10|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin,
PBEL(0x00|0x40|0x20|0x00|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin,
PBEL(0x00|0x40|0x20|0x00|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin,
PBEL(0x00|0x40|0x20|0x10|0x00) = lsquic_ietf_v1_parse_packet_in_short_begin,
PBEL(0x00|0x40|0x20|0x10|0x08) = lsquic_ietf_v1_parse_packet_in_short_begin,
/* 00XX 0GGG */
PBEL(0x00|0x00|0x00|0x00|0x00) = lsquic_Q046_parse_packet_in_short_begin,
PBEL(0x00|0x00|0x00|0x10|0x00) = lsquic_Q046_parse_packet_in_short_begin,
PBEL(0x00|0x00|0x20|0x00|0x00) = lsquic_Q046_parse_packet_in_short_begin,
PBEL(0x00|0x00|0x20|0x10|0x00) = lsquic_Q046_parse_packet_in_short_begin,
/* 00XX 1GGG */
PBEL(0x00|0x00|0x00|0x00|0x08) = lsquic_gquic_parse_packet_in_begin,
PBEL(0x00|0x00|0x00|0x10|0x08) = lsquic_gquic_parse_packet_in_begin,
PBEL(0x00|0x00|0x20|0x00|0x08) = lsquic_gquic_parse_packet_in_begin,
PBEL(0x00|0x00|0x20|0x10|0x08) = lsquic_gquic_parse_packet_in_begin,
#undef PBEL
};
int
lsquic_parse_packet_in_server_begin (struct lsquic_packet_in *packet_in,
size_t length, int is_server_UNUSED, unsigned cid_len,
struct packin_parse_state *state)
{
if (length)
return parse_begin_funcs[ packet_in->pi_data[0] >> 3 ](
packet_in, length, 1, cid_len, state);
else
return -1;
}
int
lsquic_parse_packet_in_begin (lsquic_packet_in_t *packet_in, size_t length,
int is_server, unsigned cid_len, struct packin_parse_state *state)
{
if (length > 0)
{
switch (packet_in->pi_data[0] & 0xC0)
{
case 0xC0:
case 0x80:
return parse_ietf_v1_or_Q046plus_long_begin(packet_in,
length, is_server, cid_len, state);
case 0x00:
return lsquic_gquic_parse_packet_in_begin(packet_in, length,
is_server, cid_len, state);
default:
return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in,
length, is_server, cid_len, state);
}
}
else
return -1;
}
int
lsquic_ietf_v1_parse_packet_in_begin (struct lsquic_packet_in *packet_in,
size_t length, int is_server, unsigned cid_len,
struct packin_parse_state *state)
{
if (length > 0)
{
if (0 == (packet_in->pi_data[0] & 0x80))
return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in, length,
is_server, cid_len, state);
else
return lsquic_ietf_v1_parse_packet_in_long_begin(packet_in, length,
is_server, cid_len, state);
}
else
return -1;
}
int
lsquic_Q046_parse_packet_in_begin (struct lsquic_packet_in *packet_in,
size_t length, int is_server, unsigned cid_len,
struct packin_parse_state *state)
{
assert(!is_server);
assert(cid_len == GQUIC_CID_LEN);
if (length > 0)
{
if (0 == (packet_in->pi_data[0] & 0x80))
return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in, length,
is_server, is_server ? cid_len : 0, state);
else
return lsquic_Q046_parse_packet_in_long_begin(packet_in, length,
is_server, cid_len, state);
}
else
return -1;
}
int
lsquic_Q050_parse_packet_in_begin (struct lsquic_packet_in *packet_in,
size_t length, int is_server, unsigned cid_len,
struct packin_parse_state *state)
{
assert(!is_server);
assert(cid_len == GQUIC_CID_LEN);
if (length > 0)
{
if (0 == (packet_in->pi_data[0] & 0x80))
return lsquic_ietf_v1_parse_packet_in_short_begin(packet_in, length,
is_server, is_server ? cid_len : 0, state);
else
return lsquic_Q050_parse_packet_in_long_begin(packet_in, length,
is_server, cid_len, state);
}
else
return -1;
}
/* TODO This function uses the full packet parsing functionality to get at
* the CID. This is an overkill and could be optimized -- at the cost of
* some code duplication, of course.
*/
int
lsquic_cid_from_packet (const unsigned char *buf, size_t bufsz,
lsquic_cid_t *cid)
{
struct lsquic_packet_in packet_in;
struct packin_parse_state pps;
int s;
packet_in.pi_data = (unsigned char *) buf;
s = lsquic_parse_packet_in_server_begin(&packet_in, bufsz, 1, 8, &pps);
if (0 == s && (packet_in.pi_flags & PI_CONN_ID))
{
*cid = packet_in.pi_dcid;
return 0;
}
else
return -1;
}
int
lsquic_dcid_from_packet (const unsigned char *buf, size_t bufsz,
unsigned server_cid_len, unsigned *cid_len)
{
const unsigned char *p;
unsigned dcil, scil;
if (bufsz < 9)
return -1;
switch (buf[0] >> 3)
{
/* Xs vary, Gs are iGnored: */
/* 1X11 XGGG: */
/*
case (0x80|0x40|0x20|0x10|0x08) >> 3:
case (0x80|0x00|0x20|0x10|0x08) >> 3:
case (0x80|0x40|0x20|0x10|0x00) >> 3:
case (0x80|0x00|0x20|0x10|0x00) >> 3:
*/
Q046_long:
/* lsquic_Q046_parse_packet_in_long_begin */
if (bufsz < 14)
return -1;
p = buf + 5;
dcil = p[0] >> 4;
if (dcil)
dcil += 3;
scil = p[0] & 0xF;
if (scil)
scil += 3;
++p;
if (dcil == GQUIC_CID_LEN && scil == 0)
{
*cid_len = GQUIC_CID_LEN;
return (unsigned) (p - buf);
}
else
return -1;
/* 1X00 XGGG: */
/*
case (0x80|0x40|0x00|0x00|0x08) >> 3:
case (0x80|0x00|0x00|0x00|0x08) >> 3:
case (0x80|0x40|0x00|0x00|0x00) >> 3:
case (0x80|0x00|0x00|0x00|0x00) >> 3:
case (0x80|0x40|0x00|0x10|0x08) >> 3:
case (0x80|0x00|0x00|0x10|0x08) >> 3:
case (0x80|0x40|0x00|0x10|0x00) >> 3:
case (0x80|0x00|0x00|0x10|0x00) >> 3:
case (0x80|0x40|0x20|0x00|0x08) >> 3:
case (0x80|0x00|0x20|0x00|0x08) >> 3:
case (0x80|0x40|0x20|0x00|0x00) >> 3:
case (0x80|0x00|0x20|0x00|0x00) >> 3:
*/
default:
/* parse_ietf_v1_or_Q046plus_long_begin */
if (buf[4] == (unsigned) '6')
goto Q046_long;
/* lsquic_Q050_parse_packet_in_long_begin or
lsquic_ietf_v1_parse_packet_in_long_begin */
if (bufsz < 14)
return -1;
dcil = buf[5];
if (dcil <= MAX_CID_LEN && 6 + dcil < bufsz)
{
*cid_len = dcil;
return 6;
}
else
return -1;
/* 01XX XGGG */
case (0x00|0x40|0x00|0x00|0x00) >> 3:
case (0x00|0x40|0x00|0x00|0x08) >> 3:
case (0x00|0x40|0x00|0x10|0x00) >> 3:
case (0x00|0x40|0x00|0x10|0x08) >> 3:
case (0x00|0x40|0x20|0x00|0x00) >> 3:
case (0x00|0x40|0x20|0x00|0x08) >> 3:
case (0x00|0x40|0x20|0x10|0x00) >> 3:
case (0x00|0x40|0x20|0x10|0x08) >> 3:
/* lsquic_ietf_v1_parse_packet_in_short_begin */
if (1 + server_cid_len <= bufsz)
{
*cid_len = server_cid_len;
return 1;
}
else
return -1;
/* 00XX 0GGG */
case (0x00|0x00|0x00|0x00|0x00) >> 3:
case (0x00|0x00|0x00|0x10|0x00) >> 3:
case (0x00|0x00|0x20|0x00|0x00) >> 3:
case (0x00|0x00|0x20|0x10|0x00) >> 3:
/* lsquic_Q046_parse_packet_in_short_begin */
if (1 + server_cid_len <= bufsz && (buf[0] & 0x40))
{
*cid_len = server_cid_len;
return 1;
}
else
return -1;
/* 00XX 1GGG */
case (0x00|0x00|0x00|0x00|0x08) >> 3:
case (0x00|0x00|0x00|0x10|0x08) >> 3:
case (0x00|0x00|0x20|0x00|0x08) >> 3:
case (0x00|0x00|0x20|0x10|0x08) >> 3:
/* lsquic_gquic_parse_packet_in_begin */
if (1 + GQUIC_CID_LEN <= bufsz
&& (buf[0] & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID))
{
*cid_len = server_cid_len;
return 1;
}
else
return -1;
}
}
/* See [draft-ietf-quic-transport-28], Section 12.4 (Table 3) */
const enum quic_ft_bit lsquic_legal_frames_by_level[N_LSQVER][N_ENC_LEVS] =
{
[LSQVER_I002] = {
[ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
[ENC_LEV_0RTT] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
| QUIC_FTBIT_BLOCKED | QUIC_FTBIT_CONNECTION_CLOSE
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
| QUIC_FTBIT_STREAMS_BLOCKED
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
| QUIC_FTBIT_PATH_CHALLENGE
| QUIC_FTBIT_DATAGRAM
| QUIC_FTBIT_RETIRE_CONNECTION_ID,
[ENC_LEV_HSK] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE,
[ENC_LEV_APP] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
| QUIC_FTBIT_BLOCKED
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
| QUIC_FTBIT_STREAMS_BLOCKED
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
| QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
| QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY
| QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN
| QUIC_FTBIT_TIMESTAMP
| QUIC_FTBIT_DATAGRAM
,
},
[LSQVER_I001] = {
[ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
[ENC_LEV_0RTT] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
| QUIC_FTBIT_BLOCKED | QUIC_FTBIT_CONNECTION_CLOSE
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
| QUIC_FTBIT_STREAMS_BLOCKED
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
| QUIC_FTBIT_PATH_CHALLENGE
| QUIC_FTBIT_DATAGRAM
| QUIC_FTBIT_RETIRE_CONNECTION_ID,
[ENC_LEV_HSK] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE,
[ENC_LEV_APP] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
| QUIC_FTBIT_BLOCKED
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
| QUIC_FTBIT_STREAMS_BLOCKED
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
| QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
| QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY
| QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN
| QUIC_FTBIT_TIMESTAMP
| QUIC_FTBIT_DATAGRAM
,
},
[LSQVER_ID29] = {
[ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
[ENC_LEV_0RTT] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
| QUIC_FTBIT_BLOCKED | QUIC_FTBIT_CONNECTION_CLOSE
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
| QUIC_FTBIT_STREAMS_BLOCKED
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
| QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
| QUIC_FTBIT_DATAGRAM
| QUIC_FTBIT_RETIRE_CONNECTION_ID,
[ENC_LEV_HSK] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE,
[ENC_LEV_APP] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
| QUIC_FTBIT_BLOCKED
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
| QUIC_FTBIT_STREAMS_BLOCKED
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
| QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
| QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY
| QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN
| QUIC_FTBIT_TIMESTAMP
| QUIC_FTBIT_DATAGRAM
,
},
[LSQVER_ID27] = {
[ENC_LEV_INIT] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
[ENC_LEV_0RTT] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
| QUIC_FTBIT_BLOCKED
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
| QUIC_FTBIT_STREAMS_BLOCKED
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
| QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
| QUIC_FTBIT_RETIRE_CONNECTION_ID
| QUIC_FTBIT_DATAGRAM
,
[ENC_LEV_HSK] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE,
[ENC_LEV_APP] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
| QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE
| QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
| QUIC_FTBIT_BLOCKED
| QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
| QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
| QUIC_FTBIT_STREAMS_BLOCKED
| QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
| QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
| QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY
| QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN
| QUIC_FTBIT_TIMESTAMP
| QUIC_FTBIT_DATAGRAM
,
},
};