ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
lib/network/quic/stream.c
Go to the documentation of this file.
1#include "stream.h"
2
5#include <string.h>
6
7static const uint8_t stream_magic[4] = {'A', 'C', 'Q', 'S'};
8
11 if (!output || (unsigned)traffic_class > ACIP_TRAFFIC_VISUAL)
12 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid QUIC stream traffic class");
13 memcpy(output, stream_magic, sizeof(stream_magic));
14 output[4] = 1;
15 output[5] = (uint8_t)traffic_class;
16 output[6] = output[7] = 0;
17 return ASCIICHAT_OK;
18}
19
30
31static asciichat_error_t emit_packet(const void *packet, size_t size, void *arg) {
32 emit_context_t *context = arg;
33 if (size < sizeof(packet_header_t))
34 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Truncated ACIP packet on QUIC stream");
35 packet_header_t header;
36 memcpy(&header, packet, sizeof(header));
37 uint16_t type = NET_TO_HOST_U16(header.type);
39 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "ACIP packet does not match QUIC stream class");
40 return context->emit(context->reader->traffic_class, packet, size, context->context);
41}
42
43asciichat_error_t quic_stream_read(quic_stream_reader_t *reader, const void *bytes, size_t length,
44 quic_stream_emit_fn emit, void *context) {
45 if (!reader || (!bytes && length) || !emit || reader->failed || reader->finished)
46 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid QUIC stream input");
47 const uint8_t *input = bytes;
48 if (reader->preamble_used < sizeof(reader->preamble)) {
49 size_t take = sizeof(reader->preamble) - reader->preamble_used;
50 if (take > length)
51 take = length;
52 if (take) {
53 memcpy(reader->preamble + reader->preamble_used, input, take);
54 reader->preamble_used += take;
55 input += take;
56 length -= take;
57 }
58 if (reader->preamble_used < sizeof(reader->preamble))
59 return ASCIICHAT_OK;
60 if (memcmp(reader->preamble, stream_magic, sizeof(stream_magic)) != 0 || reader->preamble[4] != 1 ||
61 reader->preamble[5] > ACIP_TRAFFIC_VISUAL || reader->preamble[6] || reader->preamble[7]) {
62 reader->failed = true;
63 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Invalid QUIC stream preamble");
64 }
65 reader->traffic_class = (acip_traffic_class_t)reader->preamble[5];
66 }
67 emit_context_t emit_context = {.reader = reader, .emit = emit, .context = context};
68 asciichat_error_t result = packet_decoder_feed(&reader->packets, input, length, emit_packet, &emit_context);
69 if (result != ASCIICHAT_OK)
70 reader->failed = true;
71 return result;
72}
73
75 if (!reader || reader->failed || reader->finished)
76 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid QUIC stream finish");
77 if (reader->preamble_used != sizeof(reader->preamble) || packet_decoder_pending(&reader->packets)) {
78 reader->failed = true;
79 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Truncated QUIC stream");
80 }
81 reader->finished = true;
82 return ASCIICHAT_OK;
83}
84
86 if (reader) {
88 memset(reader, 0, sizeof(*reader));
89 }
90}
#define SET_ERRNO(code,...)
🔄 Network byte order conversion helpers
#define NET_TO_HOST_U16(val)
Definition endian.h:111
unsigned short uint16_t
Definition common.h:61
unsigned char uint8_t
Definition common.h:60
asciichat_error_t
Error and exit codes - unified status values (0-255).
Definition error_codes.h:44
@ ERROR_NETWORK_PROTOCOL
Definition error_codes.h:76
@ ASCIICHAT_OK
Definition error_codes.h:46
@ ERROR_INVALID_PARAM
@ PACKET_TYPE_ENCRYPTED
Encrypted packet (after handshake completion).
Definition packet.h:355
asciichat_error_t quic_stream_read(quic_stream_reader_t *reader, const void *bytes, size_t length, quic_stream_emit_fn emit, void *context)
asciichat_error_t quic_stream_preamble(acip_traffic_class_t traffic_class, uint8_t output[8])
asciichat_error_t quic_stream_finish(quic_stream_reader_t *reader)
void quic_stream_reset(quic_stream_reader_t *reader)
asciichat_error_t(* quic_stream_emit_fn)(acip_traffic_class_t traffic_class, const void *packet, size_t size, void *context)
#define ACIP_QUIC_STREAM_PREAMBLE_SIZE
bool packet_decoder_pending(const packet_decoder_t *decoder)
void packet_decoder_reset(packet_decoder_t *decoder)
asciichat_error_t packet_decoder_feed(packet_decoder_t *decoder, const void *data, size_t length, packet_decoder_fn emit, void *arg)
🔤 String Manipulation and Shell Escaping Utilities
quic_stream_emit_fn emit
quic_stream_reader_t * reader
Fixed prefix shared by every ACIP packet on the wire.
Definition packet.h:628
acip_traffic_class_t traffic_class
acip_traffic_class_t acip_packet_traffic_class(uint16_t type)
Definition traffic.c:4
acip_traffic_class_t
Definition traffic.h:5
@ ACIP_TRAFFIC_VISUAL
Definition traffic.h:8