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/acip/security.c
Go to the documentation of this file.
2#include <defer.h>
9#include <string.h>
10
12 if (!security)
13 return;
16}
17
19 if (!security || !transport || security->mode > ACIP_CRYPTO_FULL ||
21 return SET_ERRNO(ERROR_INVALID_STATE, "Invalid peer security initialization");
22 security->handshake.addressless_transport = true;
23 transport->crypto_ctx = &security->handshake.crypto_ctx;
25 if (security->handshake.is_server)
26 return ASCIICHAT_OK;
28 protocol_version_packet_init(&version, security->mode);
29 return packet_send_via_transport(transport, PACKET_TYPE_PROTOCOL_VERSION, &version, sizeof(version), 0);
30}
31
33 const void *payload, size_t length) {
34 if (!security || !transport || (!payload && length) || security->ready)
35 return SET_ERRNO(ERROR_INVALID_STATE, "Unexpected peer security packet");
36 crypto_handshake_context_t *ctx = &security->handshake;
38 if (!security->version_received) {
39 if (type != PACKET_TYPE_PROTOCOL_VERSION || length != sizeof(protocol_version_packet_t))
40 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Expected peer security negotiation before media");
42 memcpy(&version, payload, sizeof(version));
43 uint8_t mode = version.supports_encryption;
47 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Unsupported peer security protocol");
48 if (ctx->is_server) {
49 // Match secure WebSocket policy: defaults do not override a client's explicit no-encrypt.
50 if ((ctx->has_password || ctx->require_client_auth) && !ACIP_CRYPTO_HAS_AUTH(mode))
51 return SET_ERRNO(ERROR_CRYPTO_AUTH, "Peer omitted required authentication");
52 if (security->require_encryption && !ACIP_CRYPTO_HAS_ENCRYPT(mode))
53 return SET_ERRNO(ERROR_CRYPTO, "Peer omitted required encryption");
54 if (security->forbid_encryption && ACIP_CRYPTO_HAS_ENCRYPT(mode))
55 return SET_ERRNO(ERROR_CRYPTO, "Peer requires encryption but local policy disables it");
56 version.supports_encryption = mode;
57 result = packet_send_via_transport(transport, PACKET_TYPE_PROTOCOL_VERSION, &version, sizeof(version), 0);
58 if (result != ASCIICHAT_OK)
59 return result;
60 } else if ((mode & security->mode) != security->mode) {
61 return SET_ERRNO(ERROR_CRYPTO, "Peer attempted to downgrade requested security");
62 }
63 if (security->forbid_encryption && ACIP_CRYPTO_HAS_ENCRYPT(mode))
64 return SET_ERRNO(ERROR_CRYPTO, "Peer requires encryption but local policy disables it");
65 security->mode = mode;
66 security->version_received = true;
68 if (mode == ACIP_CRYPTO_NONE) {
70 security->ready = true;
71 return ASCIICHAT_OK;
72 }
73 if (!ctx->is_server)
74 return ASCIICHAT_OK;
75 result = crypto_handshake_server_send_parameters(ctx, transport);
76 if (result == ASCIICHAT_OK)
77 result = crypto_handshake_server_start(ctx, transport);
78 return result;
79 }
80 if (ctx->is_server) {
82 result = crypto_handshake_server_auth_challenge(ctx, transport, type, payload, length);
84 result = crypto_handshake_server_complete(ctx, transport, type, payload, length);
85 else
86 result = SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Unexpected peer authentication state");
87 } else {
88 switch (type) {
90 if (security->parameters_received || ctx->state != CRYPTO_HANDSHAKE_INIT ||
91 length != sizeof(crypto_parameters_packet_t))
92 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Invalid peer crypto parameters");
93 result = crypto_handshake_set_parameters(ctx, payload);
94 if (result == ASCIICHAT_OK && ctx->crypto_ctx.encrypt_data != !!ACIP_CRYPTO_HAS_ENCRYPT(security->mode))
95 return SET_ERRNO(ERROR_CRYPTO, "Peer cipher does not match negotiated policy");
96 security->parameters_received = result == ASCIICHAT_OK;
97 break;
99 if (!security->parameters_received)
100 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Missing peer crypto parameters");
101 if (ctx->verify_server_key && length == ctx->crypto_ctx.public_key_size)
102 return SET_ERRNO(ERROR_CRYPTO_AUTH, "Peer omitted the required identity key");
103 result = crypto_handshake_client_key_exchange(ctx, transport, type, payload, length);
104 break;
106 result = crypto_handshake_client_auth_response(ctx, transport, type, payload, length);
107 break;
110 return SET_ERRNO(ERROR_CRYPTO_AUTH, "Peer skipped required mutual authentication");
111 result = crypto_handshake_client_complete(ctx, transport, type, payload, length);
112 break;
115 result = crypto_handshake_client_complete(ctx, transport, type, payload, length);
116 break;
117 default:
118 result = SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Application packet before peer authentication");
119 }
120 }
121 if (result == ASCIICHAT_OK)
122 security->ready = ctx->state == CRYPTO_HANDSHAKE_READY;
123 else
125 if (result == ASCIICHAT_OK && security->ready)
126 result = acip_security_activate(transport);
127 return result;
128}
129
130static const packet_type_t rekey_types[] = {0,
137
138static crypto_rekey_message_t rekey_message(uint16_t type) {
139 for (unsigned i = 1; i < sizeof(rekey_types) / sizeof(rekey_types[0]); ++i)
140 if (rekey_types[i] == type)
141 return (crypto_rekey_message_t)i;
142 return CRYPTO_REKEY_NONE;
143}
144
146 return rekey_message(type) != CRYPTO_REKEY_NONE;
147}
148
150 size_t length, void *packet, size_t capacity, size_t *written) {
151 if (type <= CRYPTO_REKEY_NONE || type > CRYPTO_REKEY_NEEDED || flow >= CRYPTO_RECORD_CHANNELS)
152 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid rekey message");
153 return packet_encode(rekey_types[type], payload, length, flow, packet, capacity, written);
154}
155
157 acip_delivery_t delivery, const void *packet, size_t length, uint64_t now,
158 bool *consumed) {
159 packet_header_t header;
160 asciichat_error_t result = packet_validate(packet, length, 0, &header);
161 if (result != ASCIICHAT_OK)
162 return result;
163 return crypto_rekey_session_receive(session, flow, delivery, rekey_message(NET_TO_HOST_U16(header.type)),
164 (const uint8_t *)packet + sizeof(header), length - sizeof(header), now, consumed);
165}
166
168 const void *payload, size_t length, uint8_t **wire, size_t *written) {
170 size_t packet_length = 0;
171 asciichat_error_t result =
172 acip_security_rekey_encode(flow, message, payload, length, packet, sizeof(packet), &packet_length);
173 return result == ASCIICHAT_OK ? acip_packet_seal(records, (acip_traffic_class_t)flow, ACIP_DELIVERY_RELIABLE, packet,
174 packet_length, wire, written)
175 : result;
176}
177
179 if (!transport)
180 return SET_ERRNO(ERROR_INVALID_PARAM, "Missing secure transport");
181 crypto_context_t *crypto = transport->crypto_ctx;
182 if (!crypto || !crypto->encrypt_data)
183 return ASCIICHAT_OK;
184 crypto_session_t *session = NULL;
185 asciichat_error_t result = crypto_session_lock(crypto, &session);
186 if (result == ASCIICHAT_OK) {
187 crypto_session_unlock(session);
188 atomic_store_bool(&transport->packet_security_active, true);
189 }
190 return result;
191}
192
193asciichat_error_t acip_security_decrypt(crypto_context_t *crypto, unsigned flow, unsigned delivery, const void *payload,
194 size_t length, uint8_t **output, size_t *written, uint64_t *sequence,
195 bool *consumed) {
196 if (!output || !written || !consumed)
197 return SET_ERRNO(ERROR_INVALID_PARAM, "Missing security receive output");
198 *output = NULL;
199 *written = 0;
200 *consumed = false;
201 crypto_session_t *session = NULL;
202 asciichat_error_t result = crypto_session_lock(crypto, &session);
203 if (result != ASCIICHAT_OK)
204 return result;
205 result = acip_packet_decrypt_payload(&session->records, flow, delivery, payload, length, output, written, sequence);
206 if (result == ASCIICHAT_OK) {
207 packet_header_t header;
208 memcpy(&header, *output, sizeof(header));
209 result = crypto_session_receive(session, session->records.last_receive_channel, delivery,
210 rekey_message(NET_TO_HOST_U16(header.type)), *output + sizeof(header),
211 *written - sizeof(header), time_get_ns(), consumed);
212 }
213 crypto_session_unlock(session);
214 if (result != ASCIICHAT_OK) {
215 buffer_release(*output);
216 *output = NULL;
217 *written = 0;
218 }
219 return result;
220}
221
223 size_t *length) {
224 if (!flow || !wire || !length)
225 return SET_ERRNO(ERROR_INVALID_PARAM, "Missing security output");
226 *wire = NULL;
227 *length = 0;
228 crypto_session_t *session = NULL;
229 asciichat_error_t result = crypto_session_lock(crypto, &session);
230 if (result != ASCIICHAT_OK)
231 return result;
232 defer(crypto_session_unlock(session));
233 result = crypto_session_tick(session, time_get_ns());
234 if (result == ASCIICHAT_OK && session->count) {
235 crypto_session_message_t *message = &session->messages[session->head];
236 *flow = (acip_traffic_class_t)message->channel;
237 result = acip_security_rekey_seal(&session->records, message->channel, message->type, message->payload,
238 message->length, wire, length);
239 if (result == ASCIICHAT_OK) {
240 memset(message, 0, sizeof(*message));
241 session->head = (session->head + 1) % CRYPTO_SESSION_MESSAGES;
242 --session->count;
243 }
244 }
245 return result;
246}
247
249 if (!transport || !atomic_load_bool(&transport->packet_security_active))
250 return ASCIICHAT_OK;
251 for (unsigned i = 0; i < CRYPTO_SESSION_MESSAGES; ++i) {
252 uint8_t *wire = NULL;
253 size_t length = 0;
255 asciichat_error_t result = acip_security_next_control(transport->crypto_ctx, &channel, &wire, &length);
256 if (result != ASCIICHAT_OK || !wire)
257 return result;
258 defer(buffer_release(wire));
259 socket_buffer_t slice = {wire, length};
260 acip_send_options_t options = {.traffic_class = channel, .delivery = ACIP_DELIVERY_RELIABLE};
261 if (transport->methods->sendv_ex)
262 result = transport->methods->sendv_ex(transport, &slice, 1, &options);
263 else if (transport->methods->sendv)
264 result = transport->methods->sendv(transport, &slice, 1);
265 else
266 result = transport->methods->send(transport, wire, length);
267 if (result != ASCIICHAT_OK)
268 return result;
269 }
270 return ASCIICHAT_OK;
271}
272
274 if (!transport || !transport->crypto_ctx || !transport->crypto_ctx->encrypt_data)
275 return SET_ERRNO(ERROR_INVALID_STATE, "An encrypted authenticated session is required for rotation");
276 crypto_session_t *session = NULL;
277 asciichat_error_t result = crypto_session_lock(transport->crypto_ctx, &session);
278 if (result == ASCIICHAT_OK) {
279 result = crypto_rekey_session_request(&session->rotation, time_get_ns());
280 crypto_session_unlock(session);
281 }
282 return result;
283}
284
286 const void *packet, size_t length, uint8_t **output, size_t *written) {
287 crypto_session_t *session = NULL;
288 asciichat_error_t result = crypto_session_lock(crypto, &session);
289 if (result == ASCIICHAT_OK) {
290 result = acip_packet_seal(&session->records, flow, delivery, packet, length, output, written);
291 crypto_session_unlock(session);
292 }
293 return result;
294}
295
297 const void *packet, size_t length, uint8_t **output, size_t *written,
298 uint64_t *sequence, bool *consumed) {
299 packet_header_t header;
300 asciichat_error_t result = packet_validate(packet, length, 0, &header);
301 if (result != ASCIICHAT_OK)
302 return result;
303 if (NET_TO_HOST_U16(header.type) != PACKET_TYPE_ENCRYPTED)
304 return SET_ERRNO(ERROR_CRYPTO, "Expected authenticated session record");
305 return acip_security_decrypt(crypto, flow, delivery, (const uint8_t *)packet + sizeof(header),
306 length - sizeof(header), output, written, sequence, consumed);
307}
#define SET_ERRNO(code,...)
#define buffer_release(data)
Definition buffer.h:91
void crypto_handshake_destroy(crypto_handshake_context_t *ctx)
Cleanup crypto handshake context with secure memory wiping.
asciichat_error_t crypto_handshake_set_parameters(crypto_handshake_context_t *ctx, const crypto_parameters_packet_t *params)
Set crypto parameters from crypto_parameters_packet_t.
@ CRYPTO_HANDSHAKE_FAILED
@ CRYPTO_HANDSHAKE_AUTHENTICATING
@ CRYPTO_HANDSHAKE_INIT
@ CRYPTO_HANDSHAKE_DISABLED
@ CRYPTO_HANDSHAKE_KEY_EXCHANGE
@ CRYPTO_HANDSHAKE_READY
🔄 Network byte order conversion helpers
#define NET_TO_HOST_U16(val)
Definition endian.h:111
unsigned short uint16_t
Definition common.h:61
#define SAFE_FREE(ptr)
Definition common.h:377
unsigned long long uint64_t
Definition common.h:63
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_INVALID_STATE
@ ERROR_NETWORK_PROTOCOL
Definition error_codes.h:76
@ ASCIICHAT_OK
Definition error_codes.h:46
@ ERROR_CRYPTO_AUTH
Definition error_codes.h:95
@ ERROR_CRYPTO
Definition error_codes.h:93
@ ERROR_INVALID_PARAM
key_type_t type
Definition key_types.h:98
@ KEY_TYPE_ED25519
Definition key_types.h:54
asciichat_error_t packet_validate(const void *packet, size_t length, size_t limit, packet_header_t *output)
Definition packet.c:86
asciichat_error_t packet_encode(packet_type_t type, const void *payload, size_t length, uint32_t client_id, void *output, size_t capacity, size_t *written)
Definition packet.c:67
#define ACIP_CRYPTO_NONE
No encryption, no authentication (plaintext only).
Definition packet.h:1138
void protocol_version_packet_init(protocol_version_packet_t *version, uint8_t supports_encryption)
Initialize a protocol version packet with the current wire version.
Definition packet.c:37
#define ACIP_CRYPTO_HAS_AUTH(mode)
Check if crypto mode includes authentication.
Definition packet.h:1155
#define ACIP_CRYPTO_HAS_ENCRYPT(mode)
Check if crypto mode includes payload encryption.
Definition packet.h:1148
packet_type_t
Network protocol packet type enumeration.
Definition packet.h:301
#define ACIP_CRYPTO_FULL
Full crypto: encryption + authentication.
Definition packet.h:1141
@ PACKET_TYPE_CRYPTO_HANDSHAKE_COMPLETE
Server -> Client: "encryption ready" (UNENCRYPTED).
Definition packet.h:338
@ PACKET_TYPE_CRYPTO_KEY_EXCHANGE_INIT
Server -> Client: {server_pubkey[32]} (UNENCRYPTED).
Definition packet.h:326
@ PACKET_TYPE_CRYPTO_EPOCH_MARKER
Definition packet.h:345
@ PACKET_TYPE_CRYPTO_REKEY_COMPLETE
Initiator -> Responder: Empty (encrypted with NEW key, but still handshake).
Definition packet.h:361
@ PACKET_TYPE_CRYPTO_AUTH_FAILED
Server -> Client: "authentication failed" (UNENCRYPTED).
Definition packet.h:334
@ PACKET_TYPE_ENCRYPTED
Encrypted packet (after handshake completion).
Definition packet.h:355
@ PACKET_TYPE_CRYPTO_REKEY_REQUEST
Initiator -> Responder: {new_ephemeral_pk[32]} (UNENCRYPTED during rekey).
Definition packet.h:357
@ PACKET_TYPE_CRYPTO_SERVER_AUTH_RESP
Server -> Client: {HMAC[32]} server proves knowledge (UNENCRYPTED).
Definition packet.h:336
@ PACKET_TYPE_PROTOCOL_VERSION
Protocol version and capabilities negotiation.
Definition packet.h:303
@ PACKET_TYPE_CRYPTO_EPOCH_ACK
Definition packet.h:347
@ PACKET_TYPE_CRYPTO_AUTH_CHALLENGE
Server -> Client: {nonce[32]} (UNENCRYPTED).
Definition packet.h:330
@ PACKET_TYPE_CRYPTO_PARAMETERS
Server -> Client: Chosen algorithms + data sizes (UNENCRYPTED).
Definition packet.h:324
@ PACKET_TYPE_CRYPTO_REKEY_NEEDED
Definition packet.h:346
@ PACKET_TYPE_CRYPTO_REKEY_RESPONSE
Responder -> Initiator: {new_ephemeral_pk[32]} (UNENCRYPTED during rekey).
Definition packet.h:359
#define PROTOCOL_VERSION_MAJOR
Major protocol version number.
#define PROTOCOL_VERSION_MINOR
Minor protocol version number.
#define PROTOCOL_VERSION_PATCH
Patch protocol version number.
struct acip_transport acip_transport_t
Forward declaration of ACIP transport.
Definition host.h:506
Client-side handshake functions.
Server-side handshake functions.
struct crypto_session crypto_session_t
For crypto session, this is the live record that ties owner, mutex, records, rotation together....
#define CRYPTO_SESSION_MESSAGES
struct acip_security acip_security_t
acip security is intentionally a small, concrete record. Fields such as handshake,...
asciichat_error_t crypto_handshake_client_complete(crypto_handshake_context_t *ctx, acip_transport_t *transport, packet_type_t packet_type, const uint8_t *payload, size_t payload_len)
Client: Wait for handshake complete confirmation.
asciichat_error_t crypto_handshake_client_key_exchange(crypto_handshake_context_t *ctx, acip_transport_t *transport, packet_type_t packet_type, const uint8_t *payload, size_t payload_len)
Client: Process server's public key and send our public key.
asciichat_error_t crypto_handshake_client_auth_response(crypto_handshake_context_t *ctx, acip_transport_t *transport, packet_type_t packet_type, const uint8_t *payload, size_t payload_len)
Client: Process auth challenge and send response.
asciichat_error_t crypto_handshake_server_send_parameters(crypto_handshake_context_t *ctx, acip_transport_t *transport)
Server: Send CRYPTO_PARAMETERS and set handshake context sizes.
asciichat_error_t crypto_handshake_server_complete(crypto_handshake_context_t *ctx, acip_transport_t *transport, packet_type_t packet_type, const uint8_t *payload, size_t payload_len)
Server: Process auth response and complete handshake.
asciichat_error_t crypto_handshake_server_auth_challenge(crypto_handshake_context_t *ctx, acip_transport_t *transport, packet_type_t packet_type, const uint8_t *payload, size_t payload_len)
Server: Process client's public key and send auth challenge.
asciichat_error_t crypto_handshake_server_start(crypto_handshake_context_t *ctx, acip_transport_t *transport)
Server: Start crypto handshake by sending public key.
asciichat_error_t crypto_session_tick(crypto_session_t *session, uint64_t now)
asciichat_error_t crypto_session_receive(crypto_session_t *session, unsigned channel, unsigned delivery, crypto_rekey_message_t type, const void *payload, size_t length, uint64_t now, bool *consumed)
void crypto_session_unlock(crypto_session_t *session)
asciichat_error_t crypto_session_lock(crypto_context_t *crypto, crypto_session_t **output)
asciichat_error_t acip_security_rekey_encode(unsigned flow, crypto_rekey_message_t type, const void *payload, size_t length, void *packet, size_t capacity, size_t *written)
asciichat_error_t acip_security_start(acip_security_t *security, acip_transport_t *transport)
asciichat_error_t acip_security_next_control(crypto_context_t *crypto, acip_traffic_class_t *flow, uint8_t **wire, size_t *length)
asciichat_error_t acip_security_request_rekey(acip_transport_t *transport)
asciichat_error_t acip_security_rekey_seal(crypto_record_t *records, unsigned flow, crypto_rekey_message_t message, const void *payload, size_t length, uint8_t **wire, size_t *written)
void acip_security_cleanup(acip_security_t *security)
asciichat_error_t acip_security_seal(crypto_context_t *crypto, acip_traffic_class_t flow, acip_delivery_t delivery, const void *packet, size_t length, uint8_t **output, size_t *written)
asciichat_error_t acip_security_rekey_receive(crypto_rekey_session_t *session, acip_traffic_class_t flow, acip_delivery_t delivery, const void *packet, size_t length, uint64_t now, bool *consumed)
asciichat_error_t acip_security_open(crypto_context_t *crypto, acip_traffic_class_t flow, acip_delivery_t delivery, const void *packet, size_t length, uint8_t **output, size_t *written, uint64_t *sequence, bool *consumed)
asciichat_error_t acip_security_decrypt(crypto_context_t *crypto, unsigned flow, unsigned delivery, const void *payload, size_t length, uint8_t **output, size_t *written, uint64_t *sequence, bool *consumed)
bool acip_security_rekey_packet(uint16_t type)
asciichat_error_t acip_security_activate(acip_transport_t *transport)
asciichat_error_t acip_security_flush(acip_transport_t *transport)
asciichat_error_t acip_security_receive(acip_security_t *security, acip_transport_t *transport, packet_type_t type, const void *payload, size_t length)
asciichat_error_t acip_packet_decrypt_payload(crypto_record_t *records, unsigned flow, unsigned delivery, const void *payload, size_t length, uint8_t **output, size_t *written, uint64_t *sequence)
Definition prepare.c:188
asciichat_error_t acip_packet_seal(crypto_record_t *records, acip_traffic_class_t flow, acip_delivery_t delivery, const void *packet, size_t length, uint8_t **output, size_t *written)
Definition prepare.c:125
Protocol version, features, compression, and frame flag constants.
struct crypto_record crypto_record_t
When code needs to work with crypto record, it keeps crypto, key_epoch, last_receive_epoch,...
#define CRYPTO_RECORD_CHANNELS
Definition record.h:7
asciichat_error_t crypto_rekey_session_receive(crypto_rekey_session_t *s, unsigned flow, unsigned delivery, crypto_rekey_message_t type, const void *payload, size_t bytes, uint64_t now, bool *consumed)
Definition rekey.c:127
asciichat_error_t crypto_rekey_session_request(crypto_rekey_session_t *s, uint64_t now)
Definition rekey.c:118
crypto_rekey_message_t
Definition rekey.h:6
@ CRYPTO_REKEY_NONE
Definition rekey.h:7
@ CRYPTO_REKEY_NEEDED
Definition rekey.h:13
asciichat_error_t packet_send_via_transport(acip_transport_t *transport, packet_type_t type, const void *payload, size_t payload_len, uint32_t client_id)
Definition send.c:190
ACIP shared/bidirectional packet sending functions.
#define CRYPTO_PUBLIC_KEY_SIZE
Public key size (X25519).
Definition sizes.h:67
🔤 String Manipulation and Shell Escaping Utilities
crypto_handshake_context_t handshake
asciichat_error_t(* send)(acip_transport_t *transport, const void *data, size_t len)
Send data through this transport.
asciichat_error_t(* sendv)(acip_transport_t *transport, const socket_buffer_t *buffers, size_t count)
Custom destroy implementation (optional).
asciichat_error_t(* sendv_ex)(acip_transport_t *transport, const socket_buffer_t *buffers, size_t count, const acip_send_options_t *options)
atomic_t packet_security_active
Publishes the stable post-handshake crypto owner.
const acip_transport_methods_t * methods
Method table (virtual functions).
crypto_context_t * crypto_ctx
Optional encryption context.
Endpoint cryptographic state for handshake, packet protection, authentication, and rekeying.
Cryptographic handshake context structure.
crypto_handshake_state_t state
Crypto parameters packet structure (Packet Type 15).
Definition packet.h:1037
unsigned last_receive_channel
Definition record.h:26
crypto rekey session is intentionally a small, concrete record. Fields such as security,...
Definition rekey.h:20
uint8_t payload[CRYPTO_PUBLIC_KEY_SIZE]
crypto_session_message_t messages[16]
crypto_rekey_session_t rotation
Fixed prefix shared by every ACIP packet on the wire.
Definition packet.h:628
Protocol version negotiation packet structure (Packet Type 1).
Definition packet.h:860
uint16_t protocol_patch
Patch protocol revision.
Definition packet.h:866
uint16_t protocol_revision
Minor protocol revision (server can be newer).
Definition packet.h:864
uint16_t protocol_version
Major protocol version (must match for compatibility).
Definition packet.h:862
uint8_t supports_encryption
Encryption & authentication mode bitmask (ACIP_CRYPTO_* constants: NONE, ENCRYPT, AUTH,...
Definition packet.h:868
acip_traffic_class_t
Definition traffic.h:5
@ ACIP_TRAFFIC_CONTROL
Definition traffic.h:6
acip_delivery_t
Definition traffic.h:11
@ ACIP_DELIVERY_RELIABLE
Definition traffic.h:12