16void pc_quic_tp_defaults(QuicTransportParams *tp)
18 memset(tp, 0,
sizeof(*tp));
19 tp->max_udp_payload_size = 65527;
20 tp->ack_delay_exponent = 3;
21 tp->max_ack_delay = 25;
22 tp->active_connection_id_limit = 2;
28bool put_param(uint8_t *out,
size_t cap,
size_t *p, uint64_t
id,
const uint8_t *val,
size_t val_len)
30 size_t n = pc_quic_varint_encode(out + *p, cap - *p,
id);
36 n = pc_quic_varint_encode(out + *p, cap - *p, val_len);
46 if (val_len > cap - *p)
50 memcpy(out + *p, val, val_len);
57bool put_varint_param(uint8_t *out,
size_t cap,
size_t *p, uint64_t
id, uint64_t value)
60 size_t vlen = pc_quic_varint_encode(v,
sizeof(v), value);
65 return put_param(out, cap, p,
id, v, vlen);
69size_t pc_quic_tp_encode(
const QuicTransportParams *tp, uint8_t *out,
size_t cap)
73 if (tp->has_original_dcid)
77 ok = ok && put_param(out, cap, &p, QuicTp::QUIC_TP_ORIGINAL_DCID, tp->original_dcid,
78 tp->original_dcid_len);
80 if (tp->has_initial_scid)
82 ok = ok && put_param(out, cap, &p, QuicTp::QUIC_TP_INITIAL_SCID, tp->initial_scid, tp->initial_scid_len);
84 if (tp->has_retry_scid)
86 ok = ok && put_param(out, cap, &p, QuicTp::QUIC_TP_RETRY_SCID, tp->retry_scid, tp->retry_scid_len);
89 ok = ok && put_varint_param(out, cap, &p, QuicTp::QUIC_TP_INITIAL_MAX_DATA, tp->initial_max_data);
90 ok = ok && put_varint_param(out, cap, &p, QuicTp::QUIC_TP_INITIAL_MAX_SD_BIDI_LOCAL, tp->initial_max_sd_bidi_local);
92 put_varint_param(out, cap, &p, QuicTp::QUIC_TP_INITIAL_MAX_SD_BIDI_REMOTE, tp->initial_max_sd_bidi_remote);
93 ok = ok && put_varint_param(out, cap, &p, QuicTp::QUIC_TP_INITIAL_MAX_SD_UNI, tp->initial_max_sd_uni);
94 ok = ok && put_varint_param(out, cap, &p, QuicTp::QUIC_TP_INITIAL_MAX_STREAMS_BIDI, tp->initial_max_streams_bidi);
95 ok = ok && put_varint_param(out, cap, &p, QuicTp::QUIC_TP_INITIAL_MAX_STREAMS_UNI, tp->initial_max_streams_uni);
96 ok = ok && put_varint_param(out, cap, &p, QuicTp::QUIC_TP_MAX_IDLE_TIMEOUT, tp->max_idle_timeout);
97 ok = ok && put_varint_param(out, cap, &p, QuicTp::QUIC_TP_MAX_UDP_PAYLOAD_SIZE, tp->max_udp_payload_size);
98 ok = ok && put_varint_param(out, cap, &p, QuicTp::QUIC_TP_ACTIVE_CID_LIMIT, tp->active_connection_id_limit);
99 if (tp->disable_active_migration)
101 ok = ok && put_param(out, cap, &p, QuicTp::QUIC_TP_DISABLE_ACTIVE_MIGRATION,
nullptr, 0);
110bool value_varint(
const uint8_t *val,
size_t len, uint64_t *out)
113 if (!pc_quic_varint_decode(val, len, out, &consumed))
117 return consumed == len;
121bool copy_cid(
const uint8_t *val,
size_t len, uint8_t *dst, uint8_t *dst_len,
bool *has)
123 if (len > QUIC_MAX_CID_LEN)
127 memcpy(dst, val, len);
128 *dst_len = (uint8_t)len;
135bool pc_quic_tp_apply_cid(uint64_t
id,
const uint8_t *val,
size_t vlen, QuicTransportParams *tp,
bool *handled)
140 case QuicTp::QUIC_TP_ORIGINAL_DCID:
141 return copy_cid(val, vlen, tp->original_dcid, &tp->original_dcid_len, &tp->has_original_dcid);
142 case QuicTp::QUIC_TP_INITIAL_SCID:
143 return copy_cid(val, vlen, tp->initial_scid, &tp->initial_scid_len, &tp->has_initial_scid);
144 case QuicTp::QUIC_TP_RETRY_SCID:
145 return copy_cid(val, vlen, tp->retry_scid, &tp->retry_scid_len, &tp->has_retry_scid);
153bool pc_quic_tp_apply_varint(uint64_t
id,
const uint8_t *val,
size_t vlen, QuicTransportParams *tp,
bool *handled)
158 case QuicTp::QUIC_TP_MAX_IDLE_TIMEOUT:
159 return value_varint(val, vlen, &tp->max_idle_timeout);
160 case QuicTp::QUIC_TP_MAX_UDP_PAYLOAD_SIZE:
161 return value_varint(val, vlen, &tp->max_udp_payload_size) && tp->max_udp_payload_size >= 1200;
162 case QuicTp::QUIC_TP_INITIAL_MAX_DATA:
163 return value_varint(val, vlen, &tp->initial_max_data);
164 case QuicTp::QUIC_TP_INITIAL_MAX_SD_BIDI_LOCAL:
165 return value_varint(val, vlen, &tp->initial_max_sd_bidi_local);
166 case QuicTp::QUIC_TP_INITIAL_MAX_SD_BIDI_REMOTE:
167 return value_varint(val, vlen, &tp->initial_max_sd_bidi_remote);
168 case QuicTp::QUIC_TP_INITIAL_MAX_SD_UNI:
169 return value_varint(val, vlen, &tp->initial_max_sd_uni);
170 case QuicTp::QUIC_TP_INITIAL_MAX_STREAMS_BIDI:
171 return value_varint(val, vlen, &tp->initial_max_streams_bidi);
172 case QuicTp::QUIC_TP_INITIAL_MAX_STREAMS_UNI:
173 return value_varint(val, vlen, &tp->initial_max_streams_uni);
174 case QuicTp::QUIC_TP_ACK_DELAY_EXPONENT:
175 return value_varint(val, vlen, &tp->ack_delay_exponent) && tp->ack_delay_exponent <= 20;
176 case QuicTp::QUIC_TP_MAX_ACK_DELAY:
177 return value_varint(val, vlen, &tp->max_ack_delay) && tp->max_ack_delay < (1u << 14);
178 case QuicTp::QUIC_TP_ACTIVE_CID_LIMIT:
179 return value_varint(val, vlen, &tp->active_connection_id_limit) && tp->active_connection_id_limit >= 2;
188bool pc_quic_tp_apply(uint64_t
id,
const uint8_t *val,
size_t vlen, QuicTransportParams *tp)
190 bool handled =
false;
191 if (!pc_quic_tp_apply_cid(
id, val, vlen, tp, &handled))
199 if (!pc_quic_tp_apply_varint(
id, val, vlen, tp, &handled))
207 if (
id == QuicTp::QUIC_TP_DISABLE_ACTIVE_MIGRATION)
213 tp->disable_active_migration =
true;
219bool pc_quic_tp_parse(
const uint8_t *buf,
size_t len, QuicTransportParams *tp)
221 pc_quic_tp_defaults(tp);
230 if (!pc_quic_varint_decode(buf + off, len - off, &
id, &c))
235 if (!pc_quic_varint_decode(buf + off, len - off, &vlen, &c))
240 if (off + vlen > len)
244 const uint8_t *val = buf + off;
249 uint32_t bit = 1u << id;
257 if (!pc_quic_tp_apply(
id, val, vlen, tp))