Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
kcenon::network::protocols::quic::frame_parser Class Reference

Parser for QUIC frames (RFC 9000 Section 12) More...

#include <frame.h>

Collaboration diagram for kcenon::network::protocols::quic::frame_parser:
Collaboration graph

Static Public Member Functions

static auto parse (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 Parse a single frame from buffer.
 
static auto parse_all (std::span< const uint8_t > data) -> Result< std::vector< frame > >
 Parse all frames from buffer.
 
static auto peek_type (std::span< const uint8_t > data) -> Result< std::pair< uint64_t, size_t > >
 Get the frame type from raw data without full parsing.
 

Static Private Member Functions

static auto parse_padding (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_ping (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_ack (std::span< const uint8_t > data, bool has_ecn) -> Result< std::pair< frame, size_t > >
 
static auto parse_reset_stream (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_stop_sending (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_crypto (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_new_token (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_stream (std::span< const uint8_t > data, uint8_t flags) -> Result< std::pair< frame, size_t > >
 
static auto parse_max_data (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_max_stream_data (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_max_streams (std::span< const uint8_t > data, bool bidi) -> Result< std::pair< frame, size_t > >
 
static auto parse_data_blocked (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_stream_data_blocked (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_streams_blocked (std::span< const uint8_t > data, bool bidi) -> Result< std::pair< frame, size_t > >
 
static auto parse_new_connection_id (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_retire_connection_id (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_path_challenge (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_path_response (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 
static auto parse_connection_close (std::span< const uint8_t > data, bool is_app) -> Result< std::pair< frame, size_t > >
 
static auto parse_handshake_done (std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
 

Detailed Description

Parser for QUIC frames (RFC 9000 Section 12)

Parses raw bytes into QUIC frame structures. Handles all frame types defined in RFC 9000 Section 19.

Definition at line 24 of file frame.h.

Member Function Documentation

◆ parse()

auto kcenon::network::protocols::quic::frame_parser::parse ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscard

Parse a single frame from buffer.

Parameters
dataInput buffer containing frame data
Returns
Result containing (parsed_frame, bytes_consumed) or error

Definition at line 122 of file frame.cpp.

124{
125 if (data.empty())
126 {
127 return make_error<std::pair<frame, size_t>>(
129 "Empty frame data");
130 }
131
132 // Parse frame type
133 auto type_result = varint::decode(data);
134 if (type_result.is_err())
135 {
136 return make_error<std::pair<frame, size_t>>(
138 "Failed to decode frame type");
139 }
140
141 auto [type_value, type_len] = type_result.value();
142 auto remaining = data.subspan(type_len);
143
144 // Check for STREAM frames (0x08-0x0f)
145 if (is_stream_frame(type_value))
146 {
147 auto result = parse_stream(remaining, get_stream_flags(type_value));
148 if (result.is_err()) return result;
149 auto& [f, consumed] = result.value();
150 return ok(std::make_pair(std::move(f), type_len + consumed));
151 }
152
153 // Dispatch based on frame type
154 switch (static_cast<frame_type>(type_value))
155 {
157 return parse_padding(data);
158
159 case frame_type::ping:
160 {
161 auto result = parse_ping(remaining);
162 if (result.is_err()) return result;
163 auto& [f, consumed] = result.value();
164 return ok(std::make_pair(std::move(f), type_len + consumed));
165 }
166
167 case frame_type::ack:
168 {
169 auto result = parse_ack(remaining, false);
170 if (result.is_err()) return result;
171 auto& [f, consumed] = result.value();
172 return ok(std::make_pair(std::move(f), type_len + consumed));
173 }
174
176 {
177 auto result = parse_ack(remaining, true);
178 if (result.is_err()) return result;
179 auto& [f, consumed] = result.value();
180 return ok(std::make_pair(std::move(f), type_len + consumed));
181 }
182
184 {
185 auto result = parse_reset_stream(remaining);
186 if (result.is_err()) return result;
187 auto& [f, consumed] = result.value();
188 return ok(std::make_pair(std::move(f), type_len + consumed));
189 }
190
192 {
193 auto result = parse_stop_sending(remaining);
194 if (result.is_err()) return result;
195 auto& [f, consumed] = result.value();
196 return ok(std::make_pair(std::move(f), type_len + consumed));
197 }
198
200 {
201 auto result = parse_crypto(remaining);
202 if (result.is_err()) return result;
203 auto& [f, consumed] = result.value();
204 return ok(std::make_pair(std::move(f), type_len + consumed));
205 }
206
208 {
209 auto result = parse_new_token(remaining);
210 if (result.is_err()) return result;
211 auto& [f, consumed] = result.value();
212 return ok(std::make_pair(std::move(f), type_len + consumed));
213 }
214
216 {
217 auto result = parse_max_data(remaining);
218 if (result.is_err()) return result;
219 auto& [f, consumed] = result.value();
220 return ok(std::make_pair(std::move(f), type_len + consumed));
221 }
222
224 {
225 auto result = parse_max_stream_data(remaining);
226 if (result.is_err()) return result;
227 auto& [f, consumed] = result.value();
228 return ok(std::make_pair(std::move(f), type_len + consumed));
229 }
230
232 {
233 auto result = parse_max_streams(remaining, true);
234 if (result.is_err()) return result;
235 auto& [f, consumed] = result.value();
236 return ok(std::make_pair(std::move(f), type_len + consumed));
237 }
238
240 {
241 auto result = parse_max_streams(remaining, false);
242 if (result.is_err()) return result;
243 auto& [f, consumed] = result.value();
244 return ok(std::make_pair(std::move(f), type_len + consumed));
245 }
246
248 {
249 auto result = parse_data_blocked(remaining);
250 if (result.is_err()) return result;
251 auto& [f, consumed] = result.value();
252 return ok(std::make_pair(std::move(f), type_len + consumed));
253 }
254
256 {
257 auto result = parse_stream_data_blocked(remaining);
258 if (result.is_err()) return result;
259 auto& [f, consumed] = result.value();
260 return ok(std::make_pair(std::move(f), type_len + consumed));
261 }
262
264 {
265 auto result = parse_streams_blocked(remaining, true);
266 if (result.is_err()) return result;
267 auto& [f, consumed] = result.value();
268 return ok(std::make_pair(std::move(f), type_len + consumed));
269 }
270
272 {
273 auto result = parse_streams_blocked(remaining, false);
274 if (result.is_err()) return result;
275 auto& [f, consumed] = result.value();
276 return ok(std::make_pair(std::move(f), type_len + consumed));
277 }
278
280 {
281 auto result = parse_new_connection_id(remaining);
282 if (result.is_err()) return result;
283 auto& [f, consumed] = result.value();
284 return ok(std::make_pair(std::move(f), type_len + consumed));
285 }
286
288 {
289 auto result = parse_retire_connection_id(remaining);
290 if (result.is_err()) return result;
291 auto& [f, consumed] = result.value();
292 return ok(std::make_pair(std::move(f), type_len + consumed));
293 }
294
296 {
297 auto result = parse_path_challenge(remaining);
298 if (result.is_err()) return result;
299 auto& [f, consumed] = result.value();
300 return ok(std::make_pair(std::move(f), type_len + consumed));
301 }
302
304 {
305 auto result = parse_path_response(remaining);
306 if (result.is_err()) return result;
307 auto& [f, consumed] = result.value();
308 return ok(std::make_pair(std::move(f), type_len + consumed));
309 }
310
312 {
313 auto result = parse_connection_close(remaining, false);
314 if (result.is_err()) return result;
315 auto& [f, consumed] = result.value();
316 return ok(std::make_pair(std::move(f), type_len + consumed));
317 }
318
320 {
321 auto result = parse_connection_close(remaining, true);
322 if (result.is_err()) return result;
323 auto& [f, consumed] = result.value();
324 return ok(std::make_pair(std::move(f), type_len + consumed));
325 }
326
328 {
329 auto result = parse_handshake_done(remaining);
330 if (result.is_err()) return result;
331 auto& [f, consumed] = result.value();
332 return ok(std::make_pair(std::move(f), type_len + consumed));
333 }
334
335 default:
336 return make_error<std::pair<frame, size_t>>(
338 "Unknown frame type",
339 "type=" + std::to_string(type_value));
340 }
341}
static auto parse_connection_close(std::span< const uint8_t > data, bool is_app) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:825
static auto parse_path_response(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:810
static auto parse_max_stream_data(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:644
static auto parse_ack(std::span< const uint8_t > data, bool has_ecn) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:394
static auto parse_ping(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:387
static auto parse_reset_stream(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:476
static auto parse_data_blocked(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:679
static auto parse_retire_connection_id(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:782
static auto parse_max_streams(std::span< const uint8_t > data, bool bidi) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:665
static auto parse_stream_data_blocked(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:692
static auto parse_stream(std::span< const uint8_t > data, uint8_t flags) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:576
static auto parse_path_challenge(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:795
static auto parse_padding(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:367
static auto parse_new_connection_id(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:727
static auto parse_crypto(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:524
static auto parse_stop_sending(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:503
static auto parse_new_token(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:553
static auto parse_max_data(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:631
static auto parse_handshake_done(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:869
static auto parse_streams_blocked(std::span< const uint8_t > data, bool bidi) -> Result< std::pair< frame, size_t > >
Definition frame.cpp:713
static auto decode(std::span< const uint8_t > data) -> Result< std::pair< uint64_t, size_t > >
Decode variable-length integer from buffer.
Definition varint.cpp:146
constexpr auto is_stream_frame(uint64_t type) noexcept -> bool
Check if a frame type value represents a STREAM frame.
Definition frame_types.h:73
frame_type
QUIC frame types as defined in RFC 9000 Section 12.4.
Definition frame_types.h:25
constexpr auto get_stream_flags(uint64_t type) noexcept -> uint8_t
Extract STREAM flags from frame type.
Definition frame_types.h:81
VoidResult ok()

References kcenon::network::protocols::quic::ack, kcenon::network::protocols::quic::ack_ecn, kcenon::network::protocols::quic::connection_close, kcenon::network::protocols::quic::connection_close_app, kcenon::network::protocols::quic::crypto, kcenon::network::protocols::quic::data_blocked, kcenon::network::protocols::quic::varint::decode(), kcenon::network::protocols::quic::get_stream_flags(), kcenon::network::protocols::quic::handshake_done, kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::protocols::quic::is_stream_frame(), kcenon::network::protocols::quic::max_data, kcenon::network::protocols::quic::max_stream_data, kcenon::network::protocols::quic::max_streams_bidi, kcenon::network::protocols::quic::max_streams_uni, kcenon::network::protocols::quic::new_connection_id, kcenon::network::protocols::quic::new_token, kcenon::network::ok(), kcenon::network::protocols::quic::padding, kcenon::network::protocols::quic::path_challenge, kcenon::network::protocols::quic::path_response, kcenon::network::protocols::quic::ping, kcenon::network::protocols::quic::reset_stream, kcenon::network::protocols::quic::retire_connection_id, kcenon::network::protocols::quic::stop_sending, kcenon::network::protocols::quic::stream_data_blocked, kcenon::network::protocols::quic::streams_blocked_bidi, and kcenon::network::protocols::quic::streams_blocked_uni.

Here is the call graph for this function:

◆ parse_ack()

auto kcenon::network::protocols::quic::frame_parser::parse_ack ( std::span< const uint8_t > data,
bool has_ecn ) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 394 of file frame.cpp.

396{
397 size_t offset = 0;
398 ack_frame f;
399
400 // Largest Acknowledged
401 auto largest = varint::decode(data.subspan(offset));
402 if (largest.is_err()) return make_error<std::pair<frame, size_t>>(
403 error_codes::common_errors::invalid_argument, "Failed to parse largest acknowledged");
404 f.largest_acknowledged = largest.value().first;
405 offset += largest.value().second;
406
407 // ACK Delay
408 auto delay = varint::decode(data.subspan(offset));
409 if (delay.is_err()) return make_error<std::pair<frame, size_t>>(
410 error_codes::common_errors::invalid_argument, "Failed to parse ack delay");
411 f.ack_delay = delay.value().first;
412 offset += delay.value().second;
413
414 // ACK Range Count
415 auto range_count = varint::decode(data.subspan(offset));
416 if (range_count.is_err()) return make_error<std::pair<frame, size_t>>(
417 error_codes::common_errors::invalid_argument, "Failed to parse ack range count");
418 offset += range_count.value().second;
419
420 // First ACK Range
421 auto first_range = varint::decode(data.subspan(offset));
422 if (first_range.is_err()) return make_error<std::pair<frame, size_t>>(
423 error_codes::common_errors::invalid_argument, "Failed to parse first ack range");
424 offset += first_range.value().second;
425
426 // The first range implicitly starts at largest_acknowledged
427 // Additional ranges
428 for (uint64_t i = 0; i < range_count.value().first; ++i)
429 {
430 ack_range range;
431
432 auto gap = varint::decode(data.subspan(offset));
433 if (gap.is_err()) return make_error<std::pair<frame, size_t>>(
434 error_codes::common_errors::invalid_argument, "Failed to parse ack gap");
435 range.gap = gap.value().first;
436 offset += gap.value().second;
437
438 auto length = varint::decode(data.subspan(offset));
439 if (length.is_err()) return make_error<std::pair<frame, size_t>>(
440 error_codes::common_errors::invalid_argument, "Failed to parse ack range length");
441 range.length = length.value().first;
442 offset += length.value().second;
443
444 f.ranges.push_back(range);
445 }
446
447 // ECN Counts (if present)
448 if (has_ecn)
449 {
450 ecn_counts ecn;
451
452 auto ect0 = varint::decode(data.subspan(offset));
453 if (ect0.is_err()) return make_error<std::pair<frame, size_t>>(
454 error_codes::common_errors::invalid_argument, "Failed to parse ECT(0) count");
455 ecn.ect0 = ect0.value().first;
456 offset += ect0.value().second;
457
458 auto ect1 = varint::decode(data.subspan(offset));
459 if (ect1.is_err()) return make_error<std::pair<frame, size_t>>(
460 error_codes::common_errors::invalid_argument, "Failed to parse ECT(1) count");
461 ecn.ect1 = ect1.value().first;
462 offset += ect1.value().second;
463
464 auto ecn_ce = varint::decode(data.subspan(offset));
465 if (ecn_ce.is_err()) return make_error<std::pair<frame, size_t>>(
466 error_codes::common_errors::invalid_argument, "Failed to parse ECN-CE count");
467 ecn.ecn_ce = ecn_ce.value().first;
468 offset += ecn_ce.value().second;
469
470 f.ecn = ecn;
471 }
472
473 return ok(std::make_pair(frame{f}, offset));
474}
std::variant< padding_frame, ping_frame, ack_frame, reset_stream_frame, stop_sending_frame, crypto_frame, new_token_frame, stream_frame, max_data_frame, max_stream_data_frame, max_streams_frame, data_blocked_frame, stream_data_blocked_frame, streams_blocked_frame, new_connection_id_frame, retire_connection_id_frame, path_challenge_frame, path_response_frame, connection_close_frame, handshake_done_frame > frame
Variant type holding any QUIC frame.

References kcenon::network::protocols::quic::ack_frame::ack_delay, kcenon::network::protocols::quic::varint::decode(), kcenon::network::protocols::quic::ack_frame::ecn, kcenon::network::protocols::quic::ecn_counts::ecn_ce, kcenon::network::protocols::quic::ecn_ce, kcenon::network::protocols::quic::ecn_counts::ect0, kcenon::network::protocols::quic::ect0, kcenon::network::protocols::quic::ecn_counts::ect1, kcenon::network::protocols::quic::ect1, kcenon::network::protocols::quic::ack_range::gap, kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::protocols::quic::ack_frame::largest_acknowledged, kcenon::network::protocols::quic::ack_range::length, kcenon::network::ok(), and kcenon::network::protocols::quic::ack_frame::ranges.

Here is the call graph for this function:

◆ parse_all()

auto kcenon::network::protocols::quic::frame_parser::parse_all ( std::span< const uint8_t > data) -> Result<std::vector<frame>>
staticnodiscard

Parse all frames from buffer.

Parameters
dataInput buffer containing one or more frames
Returns
Result containing vector of parsed frames or error

Definition at line 343 of file frame.cpp.

345{
346 std::vector<frame> frames;
347 size_t offset = 0;
348
349 while (offset < data.size())
350 {
351 auto result = parse(data.subspan(offset));
352 if (result.is_err())
353 {
354 return make_error<std::vector<frame>>(
356 "Failed to parse frame at offset " + std::to_string(offset));
357 }
358
359 auto& [f, consumed] = result.value();
360 frames.push_back(std::move(f));
361 offset += consumed;
362 }
363
364 return ok(std::move(frames));
365}
static auto parse(std::span< const uint8_t > data) -> Result< std::pair< frame, size_t > >
Parse a single frame from buffer.
Definition frame.cpp:122

References kcenon::network::error_codes::common_errors::invalid_argument, and kcenon::network::ok().

Referenced by kcenon::network::internal::quic_socket::handle_packet(), and kcenon::network::protocols::quic::connection::process_frames().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_connection_close()

auto kcenon::network::protocols::quic::frame_parser::parse_connection_close ( std::span< const uint8_t > data,
bool is_app ) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 825 of file frame.cpp.

827{
828 size_t offset = 0;
829 connection_close_frame f;
830 f.is_application_error = is_app;
831
832 // Error Code
833 auto error_code = varint::decode(data.subspan(offset));
834 if (error_code.is_err()) return make_error<std::pair<frame, size_t>>(
835 error_codes::common_errors::invalid_argument, "Failed to parse error code");
836 f.error_code = error_code.value().first;
837 offset += error_code.value().second;
838
839 // Frame Type (transport close only)
840 if (!is_app)
841 {
842 auto frame_type_val = varint::decode(data.subspan(offset));
843 if (frame_type_val.is_err()) return make_error<std::pair<frame, size_t>>(
844 error_codes::common_errors::invalid_argument, "Failed to parse frame type");
845 f.frame_type = frame_type_val.value().first;
846 offset += frame_type_val.value().second;
847 }
848
849 // Reason Phrase Length
850 auto reason_len = varint::decode(data.subspan(offset));
851 if (reason_len.is_err()) return make_error<std::pair<frame, size_t>>(
852 error_codes::common_errors::invalid_argument, "Failed to parse reason phrase length");
853 offset += reason_len.value().second;
854
855 // Reason Phrase
856 if (data.size() - offset < reason_len.value().first)
857 {
858 return make_error<std::pair<frame, size_t>>(
859 error_codes::common_errors::invalid_argument, "Insufficient reason phrase data");
860 }
861
862 f.reason_phrase.assign(reinterpret_cast<const char*>(data.data() + offset),
863 reason_len.value().first);
864 offset += reason_len.value().first;
865
866 return ok(std::make_pair(frame{f}, offset));
867}
error_code
HTTP/2 error codes (RFC 7540 Section 7)
Definition frame.h:471

References kcenon::network::protocols::quic::varint::decode(), kcenon::network::protocols::quic::connection_close_frame::error_code, kcenon::network::protocols::quic::connection_close_frame::frame_type, kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::protocols::quic::connection_close_frame::is_application_error, kcenon::network::ok(), and kcenon::network::protocols::quic::connection_close_frame::reason_phrase.

Here is the call graph for this function:

◆ parse_crypto()

auto kcenon::network::protocols::quic::frame_parser::parse_crypto ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 524 of file frame.cpp.

526{
527 size_t offset = 0;
528 crypto_frame f;
529
530 auto crypto_offset = varint::decode(data.subspan(offset));
531 if (crypto_offset.is_err()) return make_error<std::pair<frame, size_t>>(
532 error_codes::common_errors::invalid_argument, "Failed to parse crypto offset");
533 f.offset = crypto_offset.value().first;
534 offset += crypto_offset.value().second;
535
536 auto length = varint::decode(data.subspan(offset));
537 if (length.is_err()) return make_error<std::pair<frame, size_t>>(
538 error_codes::common_errors::invalid_argument, "Failed to parse crypto length");
539 offset += length.value().second;
540
541 if (data.size() - offset < length.value().first)
542 {
543 return make_error<std::pair<frame, size_t>>(
544 error_codes::common_errors::invalid_argument, "Insufficient crypto data");
545 }
546
547 f.data.assign(data.begin() + offset, data.begin() + offset + length.value().first);
548 offset += length.value().first;
549
550 return ok(std::make_pair(frame{f}, offset));
551}

References kcenon::network::protocols::quic::crypto_frame::data, kcenon::network::protocols::quic::varint::decode(), kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::protocols::quic::crypto_frame::offset, and kcenon::network::ok().

Here is the call graph for this function:

◆ parse_data_blocked()

auto kcenon::network::protocols::quic::frame_parser::parse_data_blocked ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 679 of file frame.cpp.

681{
682 data_blocked_frame f;
683
684 auto max_data = varint::decode(data);
685 if (max_data.is_err()) return make_error<std::pair<frame, size_t>>(
686 error_codes::common_errors::invalid_argument, "Failed to parse max data");
687 f.maximum_data = max_data.value().first;
688
689 return ok(std::make_pair(frame{f}, max_data.value().second));
690}

References kcenon::network::protocols::quic::varint::decode(), kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::protocols::quic::max_data, kcenon::network::protocols::quic::data_blocked_frame::maximum_data, and kcenon::network::ok().

Here is the call graph for this function:

◆ parse_handshake_done()

auto kcenon::network::protocols::quic::frame_parser::parse_handshake_done ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 869 of file frame.cpp.

871{
872 return ok(std::make_pair(frame{handshake_done_frame{}}, size_t{0}));
873}

References kcenon::network::ok().

Here is the call graph for this function:

◆ parse_max_data()

auto kcenon::network::protocols::quic::frame_parser::parse_max_data ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 631 of file frame.cpp.

633{
634 max_data_frame f;
635
636 auto max_data = varint::decode(data);
637 if (max_data.is_err()) return make_error<std::pair<frame, size_t>>(
638 error_codes::common_errors::invalid_argument, "Failed to parse max data");
639 f.maximum_data = max_data.value().first;
640
641 return ok(std::make_pair(frame{f}, max_data.value().second));
642}

References kcenon::network::protocols::quic::varint::decode(), kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::protocols::quic::max_data, kcenon::network::protocols::quic::max_data_frame::maximum_data, and kcenon::network::ok().

Here is the call graph for this function:

◆ parse_max_stream_data()

auto kcenon::network::protocols::quic::frame_parser::parse_max_stream_data ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 644 of file frame.cpp.

646{
647 size_t offset = 0;
648 max_stream_data_frame f;
649
650 auto stream_id = varint::decode(data.subspan(offset));
651 if (stream_id.is_err()) return make_error<std::pair<frame, size_t>>(
652 error_codes::common_errors::invalid_argument, "Failed to parse stream id");
653 f.stream_id = stream_id.value().first;
654 offset += stream_id.value().second;
655
656 auto max_data = varint::decode(data.subspan(offset));
657 if (max_data.is_err()) return make_error<std::pair<frame, size_t>>(
658 error_codes::common_errors::invalid_argument, "Failed to parse max stream data");
659 f.maximum_stream_data = max_data.value().first;
660 offset += max_data.value().second;
661
662 return ok(std::make_pair(frame{f}, offset));
663}

References kcenon::network::protocols::quic::varint::decode(), kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::protocols::quic::max_data, kcenon::network::protocols::quic::max_stream_data_frame::maximum_stream_data, kcenon::network::ok(), and kcenon::network::protocols::quic::max_stream_data_frame::stream_id.

Here is the call graph for this function:

◆ parse_max_streams()

auto kcenon::network::protocols::quic::frame_parser::parse_max_streams ( std::span< const uint8_t > data,
bool bidi ) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 665 of file frame.cpp.

667{
668 max_streams_frame f;
669 f.bidirectional = bidi;
670
671 auto max_streams = varint::decode(data);
672 if (max_streams.is_err()) return make_error<std::pair<frame, size_t>>(
673 error_codes::common_errors::invalid_argument, "Failed to parse max streams");
674 f.maximum_streams = max_streams.value().first;
675
676 return ok(std::make_pair(frame{f}, max_streams.value().second));
677}

References kcenon::network::protocols::quic::max_streams_frame::bidirectional, kcenon::network::protocols::quic::varint::decode(), kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::protocols::quic::max_streams_frame::maximum_streams, and kcenon::network::ok().

Here is the call graph for this function:

◆ parse_new_connection_id()

auto kcenon::network::protocols::quic::frame_parser::parse_new_connection_id ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 727 of file frame.cpp.

729{
730 size_t offset = 0;
731 new_connection_id_frame f;
732
733 // Sequence Number
734 auto seq = varint::decode(data.subspan(offset));
735 if (seq.is_err()) return make_error<std::pair<frame, size_t>>(
736 error_codes::common_errors::invalid_argument, "Failed to parse sequence number");
737 f.sequence_number = seq.value().first;
738 offset += seq.value().second;
739
740 // Retire Prior To
741 auto retire = varint::decode(data.subspan(offset));
742 if (retire.is_err()) return make_error<std::pair<frame, size_t>>(
743 error_codes::common_errors::invalid_argument, "Failed to parse retire prior to");
744 f.retire_prior_to = retire.value().first;
745 offset += retire.value().second;
746
747 // Connection ID Length (1 byte, not varint)
748 if (data.size() <= offset)
749 {
750 return make_error<std::pair<frame, size_t>>(
751 error_codes::common_errors::invalid_argument, "Missing connection id length");
752 }
753 uint8_t cid_len = data[offset++];
754 if (cid_len > 20)
755 {
756 return make_error<std::pair<frame, size_t>>(
757 error_codes::common_errors::invalid_argument, "Connection ID too long");
758 }
759
760 // Connection ID
761 if (data.size() - offset < cid_len)
762 {
763 return make_error<std::pair<frame, size_t>>(
764 error_codes::common_errors::invalid_argument, "Insufficient connection id data");
765 }
766 f.connection_id.assign(data.begin() + offset, data.begin() + offset + cid_len);
767 offset += cid_len;
768
769 // Stateless Reset Token (16 bytes)
770 if (data.size() - offset < 16)
771 {
772 return make_error<std::pair<frame, size_t>>(
773 error_codes::common_errors::invalid_argument, "Insufficient reset token data");
774 }
775 std::copy(data.begin() + offset, data.begin() + offset + 16,
776 f.stateless_reset_token.begin());
777 offset += 16;
778
779 return ok(std::make_pair(frame{f}, offset));
780}

References kcenon::network::protocols::quic::new_connection_id_frame::connection_id, kcenon::network::protocols::quic::varint::decode(), kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::ok(), kcenon::network::protocols::quic::new_connection_id_frame::retire_prior_to, kcenon::network::protocols::quic::new_connection_id_frame::sequence_number, and kcenon::network::protocols::quic::new_connection_id_frame::stateless_reset_token.

Here is the call graph for this function:

◆ parse_new_token()

auto kcenon::network::protocols::quic::frame_parser::parse_new_token ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 553 of file frame.cpp.

555{
556 size_t offset = 0;
557 new_token_frame f;
558
559 auto length = varint::decode(data.subspan(offset));
560 if (length.is_err()) return make_error<std::pair<frame, size_t>>(
561 error_codes::common_errors::invalid_argument, "Failed to parse token length");
562 offset += length.value().second;
563
564 if (data.size() - offset < length.value().first)
565 {
566 return make_error<std::pair<frame, size_t>>(
567 error_codes::common_errors::invalid_argument, "Insufficient token data");
568 }
569
570 f.token.assign(data.begin() + offset, data.begin() + offset + length.value().first);
571 offset += length.value().first;
572
573 return ok(std::make_pair(frame{f}, offset));
574}

References kcenon::network::protocols::quic::varint::decode(), kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::ok(), and kcenon::network::protocols::quic::new_token_frame::token.

Here is the call graph for this function:

◆ parse_padding()

auto kcenon::network::protocols::quic::frame_parser::parse_padding ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 367 of file frame.cpp.

369{
370 // Count consecutive padding bytes
371 size_t count = 0;
372 while (count < data.size() && data[count] == 0x00)
373 {
374 ++count;
375 }
376
377 if (count == 0)
378 {
379 count = 1; // At least one padding byte was consumed (the type)
380 }
381
382 padding_frame f;
383 f.count = count;
384 return ok(std::make_pair(frame{f}, count));
385}

References kcenon::network::protocols::quic::padding_frame::count, and kcenon::network::ok().

Here is the call graph for this function:

◆ parse_path_challenge()

auto kcenon::network::protocols::quic::frame_parser::parse_path_challenge ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 795 of file frame.cpp.

797{
798 if (data.size() < 8)
799 {
800 return make_error<std::pair<frame, size_t>>(
801 error_codes::common_errors::invalid_argument, "Insufficient path challenge data");
802 }
803
804 path_challenge_frame f;
805 std::copy(data.begin(), data.begin() + 8, f.data.begin());
806
807 return ok(std::make_pair(frame{f}, size_t{8}));
808}

References kcenon::network::protocols::quic::path_challenge_frame::data, kcenon::network::error_codes::common_errors::invalid_argument, and kcenon::network::ok().

Here is the call graph for this function:

◆ parse_path_response()

auto kcenon::network::protocols::quic::frame_parser::parse_path_response ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 810 of file frame.cpp.

812{
813 if (data.size() < 8)
814 {
815 return make_error<std::pair<frame, size_t>>(
816 error_codes::common_errors::invalid_argument, "Insufficient path response data");
817 }
818
819 path_response_frame f;
820 std::copy(data.begin(), data.begin() + 8, f.data.begin());
821
822 return ok(std::make_pair(frame{f}, size_t{8}));
823}

References kcenon::network::protocols::quic::path_response_frame::data, kcenon::network::error_codes::common_errors::invalid_argument, and kcenon::network::ok().

Here is the call graph for this function:

◆ parse_ping()

auto kcenon::network::protocols::quic::frame_parser::parse_ping ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 387 of file frame.cpp.

389{
390 // PING frame has no payload after type
391 return ok(std::make_pair(frame{ping_frame{}}, size_t{0}));
392}

References kcenon::network::ok().

Here is the call graph for this function:

◆ parse_reset_stream()

auto kcenon::network::protocols::quic::frame_parser::parse_reset_stream ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 476 of file frame.cpp.

478{
479 size_t offset = 0;
480 reset_stream_frame f;
481
482 auto stream_id = varint::decode(data.subspan(offset));
483 if (stream_id.is_err()) return make_error<std::pair<frame, size_t>>(
484 error_codes::common_errors::invalid_argument, "Failed to parse stream id");
485 f.stream_id = stream_id.value().first;
486 offset += stream_id.value().second;
487
488 auto error_code = varint::decode(data.subspan(offset));
489 if (error_code.is_err()) return make_error<std::pair<frame, size_t>>(
490 error_codes::common_errors::invalid_argument, "Failed to parse error code");
491 f.application_error_code = error_code.value().first;
492 offset += error_code.value().second;
493
494 auto final_size = varint::decode(data.subspan(offset));
495 if (final_size.is_err()) return make_error<std::pair<frame, size_t>>(
496 error_codes::common_errors::invalid_argument, "Failed to parse final size");
497 f.final_size = final_size.value().first;
498 offset += final_size.value().second;
499
500 return ok(std::make_pair(frame{f}, offset));
501}

References kcenon::network::protocols::quic::reset_stream_frame::application_error_code, kcenon::network::protocols::quic::varint::decode(), kcenon::network::protocols::quic::reset_stream_frame::final_size, kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::ok(), and kcenon::network::protocols::quic::reset_stream_frame::stream_id.

Here is the call graph for this function:

◆ parse_retire_connection_id()

auto kcenon::network::protocols::quic::frame_parser::parse_retire_connection_id ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 782 of file frame.cpp.

784{
785 retire_connection_id_frame f;
786
787 auto seq = varint::decode(data);
788 if (seq.is_err()) return make_error<std::pair<frame, size_t>>(
789 error_codes::common_errors::invalid_argument, "Failed to parse sequence number");
790 f.sequence_number = seq.value().first;
791
792 return ok(std::make_pair(frame{f}, seq.value().second));
793}

References kcenon::network::protocols::quic::varint::decode(), kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::ok(), and kcenon::network::protocols::quic::retire_connection_id_frame::sequence_number.

Here is the call graph for this function:

◆ parse_stop_sending()

auto kcenon::network::protocols::quic::frame_parser::parse_stop_sending ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 503 of file frame.cpp.

505{
506 size_t offset = 0;
507 stop_sending_frame f;
508
509 auto stream_id = varint::decode(data.subspan(offset));
510 if (stream_id.is_err()) return make_error<std::pair<frame, size_t>>(
511 error_codes::common_errors::invalid_argument, "Failed to parse stream id");
512 f.stream_id = stream_id.value().first;
513 offset += stream_id.value().second;
514
515 auto error_code = varint::decode(data.subspan(offset));
516 if (error_code.is_err()) return make_error<std::pair<frame, size_t>>(
517 error_codes::common_errors::invalid_argument, "Failed to parse error code");
518 f.application_error_code = error_code.value().first;
519 offset += error_code.value().second;
520
521 return ok(std::make_pair(frame{f}, offset));
522}

References kcenon::network::protocols::quic::stop_sending_frame::application_error_code, kcenon::network::protocols::quic::varint::decode(), kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::ok(), and kcenon::network::protocols::quic::stop_sending_frame::stream_id.

Here is the call graph for this function:

◆ parse_stream()

auto kcenon::network::protocols::quic::frame_parser::parse_stream ( std::span< const uint8_t > data,
uint8_t flags ) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 576 of file frame.cpp.

578{
579 size_t offset = 0;
580 stream_frame f;
581
582 // Stream ID
583 auto stream_id = varint::decode(data.subspan(offset));
584 if (stream_id.is_err()) return make_error<std::pair<frame, size_t>>(
585 error_codes::common_errors::invalid_argument, "Failed to parse stream id");
586 f.stream_id = stream_id.value().first;
587 offset += stream_id.value().second;
588
589 // Offset (if OFF bit set)
590 if (flags & stream_flags::off)
591 {
592 auto stream_offset = varint::decode(data.subspan(offset));
593 if (stream_offset.is_err()) return make_error<std::pair<frame, size_t>>(
594 error_codes::common_errors::invalid_argument, "Failed to parse stream offset");
595 f.offset = stream_offset.value().first;
596 offset += stream_offset.value().second;
597 }
598
599 // Length (if LEN bit set)
600 uint64_t length = 0;
601 if (flags & stream_flags::len)
602 {
603 auto len_result = varint::decode(data.subspan(offset));
604 if (len_result.is_err()) return make_error<std::pair<frame, size_t>>(
605 error_codes::common_errors::invalid_argument, "Failed to parse stream length");
606 length = len_result.value().first;
607 offset += len_result.value().second;
608 }
609 else
610 {
611 // Without LEN, data extends to end of packet
612 length = data.size() - offset;
613 }
614
615 // FIN bit
616 f.fin = (flags & stream_flags::fin) != 0;
617
618 // Data
619 if (data.size() - offset < length)
620 {
621 return make_error<std::pair<frame, size_t>>(
622 error_codes::common_errors::invalid_argument, "Insufficient stream data");
623 }
624
625 f.data.assign(data.begin() + offset, data.begin() + offset + length);
626 offset += length;
627
628 return ok(std::make_pair(frame{f}, offset));
629}
constexpr uint8_t fin
Stream is finished.
Definition frame_types.h:63
constexpr uint8_t len
Length field present.
Definition frame_types.h:64
constexpr uint8_t off
Offset field present.
Definition frame_types.h:65

References kcenon::network::protocols::quic::stream_frame::data, kcenon::network::protocols::quic::varint::decode(), kcenon::network::protocols::quic::stream_flags::fin, kcenon::network::protocols::quic::stream_frame::fin, kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::protocols::quic::stream_flags::len, kcenon::network::protocols::quic::stream_flags::off, kcenon::network::protocols::quic::stream_frame::offset, kcenon::network::ok(), and kcenon::network::protocols::quic::stream_frame::stream_id.

Here is the call graph for this function:

◆ parse_stream_data_blocked()

auto kcenon::network::protocols::quic::frame_parser::parse_stream_data_blocked ( std::span< const uint8_t > data) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 692 of file frame.cpp.

694{
695 size_t offset = 0;
696 stream_data_blocked_frame f;
697
698 auto stream_id = varint::decode(data.subspan(offset));
699 if (stream_id.is_err()) return make_error<std::pair<frame, size_t>>(
700 error_codes::common_errors::invalid_argument, "Failed to parse stream id");
701 f.stream_id = stream_id.value().first;
702 offset += stream_id.value().second;
703
704 auto max_data = varint::decode(data.subspan(offset));
705 if (max_data.is_err()) return make_error<std::pair<frame, size_t>>(
706 error_codes::common_errors::invalid_argument, "Failed to parse max stream data");
707 f.maximum_stream_data = max_data.value().first;
708 offset += max_data.value().second;
709
710 return ok(std::make_pair(frame{f}, offset));
711}

References kcenon::network::protocols::quic::varint::decode(), kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::protocols::quic::max_data, kcenon::network::protocols::quic::stream_data_blocked_frame::maximum_stream_data, kcenon::network::ok(), and kcenon::network::protocols::quic::stream_data_blocked_frame::stream_id.

Here is the call graph for this function:

◆ parse_streams_blocked()

auto kcenon::network::protocols::quic::frame_parser::parse_streams_blocked ( std::span< const uint8_t > data,
bool bidi ) -> Result<std::pair<frame, size_t>>
staticnodiscardprivate

Definition at line 713 of file frame.cpp.

715{
716 streams_blocked_frame f;
717 f.bidirectional = bidi;
718
719 auto max_streams = varint::decode(data);
720 if (max_streams.is_err()) return make_error<std::pair<frame, size_t>>(
721 error_codes::common_errors::invalid_argument, "Failed to parse max streams");
722 f.maximum_streams = max_streams.value().first;
723
724 return ok(std::make_pair(frame{f}, max_streams.value().second));
725}

References kcenon::network::protocols::quic::streams_blocked_frame::bidirectional, kcenon::network::protocols::quic::varint::decode(), kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::protocols::quic::streams_blocked_frame::maximum_streams, and kcenon::network::ok().

Here is the call graph for this function:

◆ peek_type()

auto kcenon::network::protocols::quic::frame_parser::peek_type ( std::span< const uint8_t > data) -> Result<std::pair<uint64_t, size_t>>
staticnodiscard

Get the frame type from raw data without full parsing.

Parameters
dataInput buffer
Returns
Result containing (frame_type_value, bytes_consumed) or error

Definition at line 116 of file frame.cpp.

118{
119 return varint::decode(data);
120}

References kcenon::network::protocols::quic::varint::decode().

Here is the call graph for this function:

The documentation for this class was generated from the following files: