17uint32_t rd_be32(
const uint8_t *p)
19 return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | p[3];
21void wr_be32(uint8_t *p, uint32_t v)
23 p[0] = (uint8_t)(v >> 24);
24 p[1] = (uint8_t)(v >> 16);
25 p[2] = (uint8_t)(v >> 8);
30bool quic_is_long_header(uint8_t first)
32 return (first & 0x80) != 0;
35bool quic_parse_long_header(
const uint8_t *buf,
size_t len, QuicLongHeader *out)
37 if (len < 7 || !(buf[0] & 0x80))
40 out->version = rd_be32(buf + 1);
41 out->type = (uint8_t)((buf[0] & 0x30) >> 4);
43 uint8_t dcl = buf[pos++];
44 if (dcl > QUIC_MAX_CID_LEN || pos + dcl + 1 > len)
46 memcpy(out->dcid, buf + pos, dcl);
49 uint8_t scl = buf[pos++];
50 if (scl > QUIC_MAX_CID_LEN || pos + scl > len)
52 memcpy(out->scid, buf + pos, scl);
59size_t quic_build_long_header(uint8_t *out,
size_t cap, uint8_t type, uint32_t version,
const uint8_t *dcid,
60 uint8_t dcid_len,
const uint8_t *scid, uint8_t scid_len, uint8_t pn_len)
62 if (dcid_len > QUIC_MAX_CID_LEN || scid_len > QUIC_MAX_CID_LEN || pn_len < 1 || pn_len > 4)
64 size_t need = 1 + 4 + 1 + dcid_len + 1 + scid_len;
68 out[0] = (uint8_t)(0x80 | 0x40 | ((type & 0x03) << 4) | ((pn_len - 1) & 0x03));
69 wr_be32(out + 1, version);
71 out[pos++] = dcid_len;
72 memcpy(out + pos, dcid, dcid_len);
74 out[pos++] = scid_len;
75 memcpy(out + pos, scid, scid_len);
80bool quic_parse_short_header(
const uint8_t *buf,
size_t len, uint8_t dcid_len, QuicShortHeader *out)
82 if (dcid_len > QUIC_MAX_CID_LEN || len < (
size_t)1 + dcid_len || (buf[0] & 0x80))
85 out->spin = (uint8_t)((buf[0] & 0x20) ? 1 : 0);
86 out->key_phase = (uint8_t)((buf[0] & 0x04) ? 1 : 0);
87 out->pn_len = (uint8_t)((buf[0] & 0x03) + 1);
88 memcpy(out->dcid, buf + 1, dcid_len);
89 out->dcid_len = dcid_len;
90 out->hdr_len = (size_t)1 + dcid_len;
94size_t quic_build_version_negotiation(uint8_t *out,
size_t cap,
const uint8_t *dcid, uint8_t dcid_len,
95 const uint8_t *scid, uint8_t scid_len,
const uint32_t *versions,
size_t nversions)
97 if (dcid_len > QUIC_MAX_CID_LEN || scid_len > QUIC_MAX_CID_LEN)
99 size_t need = 1 + 4 + 1 + dcid_len + 1 + scid_len + nversions * 4;
102 out[0] = 0x80 | 0x40;
105 out[pos++] = dcid_len;
106 memcpy(out + pos, dcid, dcid_len);
108 out[pos++] = scid_len;
109 memcpy(out + pos, scid, scid_len);
111 for (
size_t i = 0; i < nversions; i++)
113 wr_be32(out + pos, versions[i]);
119uint8_t quic_pn_length(uint64_t full_pn, int64_t largest_acked)
122 uint64_t num_unacked = (largest_acked < 0) ? (full_pn + 1) : (full_pn - (uint64_t)largest_acked);
124 for (uint8_t k = 1; k < 4; k++)
125 if (((uint64_t)1 << (8 * k)) >= (num_unacked << 1))
130size_t quic_pn_encode(uint8_t *out,
size_t cap, uint64_t full_pn, int64_t largest_acked)
132 uint8_t n = quic_pn_length(full_pn, largest_acked);
135 for (uint8_t i = 0; i < n; i++)
136 out[i] = (uint8_t)(full_pn >> (8 * (n - 1 - i)));
140uint64_t quic_pn_decode(uint64_t largest_pn, uint64_t truncated_pn, uint8_t pn_nbits)
142 uint64_t expected = largest_pn + 1;
143 uint64_t pn_win = (uint64_t)1 << pn_nbits;
144 uint64_t pn_hwin = pn_win / 2;
145 uint64_t pn_mask = pn_win - 1;
146 uint64_t candidate = (expected & ~pn_mask) | (truncated_pn & pn_mask);
148 if (candidate + pn_hwin <= expected && candidate < (((uint64_t)1 << 62) - pn_win))
149 return candidate + pn_win;
150 if (candidate > expected + pn_hwin && candidate >= pn_win)
151 return candidate - pn_win;
QUIC packet headers and packet-number coding (RFC 9000 sec 17).