32 {
34 log_dev_every(4500 * US_PER_MS_INT,
35 "ACIP_SERVER_DISPATCH: Entry, transport=%p, client_ctx=%p, callbacks=%p, timestamp=%llu",
36 (void *)transport, client_ctx, (const void *)callbacks, (unsigned long long)dispatch_start_ns);
37
38 if (!transport) {
39 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid transport (NULL)");
40 }
41 if (!callbacks) {
42 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid callbacks (NULL)");
43 }
44
45
46 if (!transport->methods->is_connected(transport)) {
47 return SET_ERRNO(ERROR_NETWORK, "Transport not connected");
48 }
49
50 packet_envelope_t envelope;
51 bool enforce_encryption = (transport->crypto_ctx != NULL);
52
53
54 socket_t sock = transport->methods->get_socket(transport);
55 log_dev_every(4500 * US_PER_MS_INT, "ACIP_SERVER_DISPATCH: Socket=%d (INVALID=%d)", sock, INVALID_SOCKET_VALUE);
56
57 if (sock != INVALID_SOCKET_VALUE) {
58
59 packet_recv_result_t result =
receive_packet_secure(sock, transport->crypto_ctx, enforce_encryption, &envelope);
60
61
62 if (result != PACKET_RECV_SUCCESS) {
63 if (result == PACKET_RECV_EOF) {
64 return SET_ERRNO(ERROR_NETWORK, "Connection closed (EOF)");
65 } else if (result == PACKET_RECV_SECURITY_VIOLATION) {
66 return SET_ERRNO(ERROR_CRYPTO, "Security violation: unencrypted packet when encryption required");
67 } else {
68 return SET_ERRNO(ERROR_NETWORK, "Failed to receive packet");
69 }
70 }
71 } else {
72
73 void *packet_data = NULL;
74 void *allocated_buffer = NULL;
75 size_t packet_len = 0;
76
78 asciichat_error_t recv_result = transport->methods->recv(transport, &packet_data, &packet_len, &allocated_buffer);
80
81 if (recv_result != ASCIICHAT_OK) {
82 char recv_duration_str[32];
83 format_duration_ns((
double)(recv_end_ns - recv_start_ns), recv_duration_str,
sizeof(recv_duration_str));
84 log_warn("[ACIP_RECV_ERROR] recv() failed after %s (result=%d)", recv_duration_str, recv_result);
85 return SET_ERRNO(ERROR_NETWORK, "Transport recv() failed");
86 }
87
88 char recv_duration_str[32];
89 format_duration_ns((
double)(recv_end_ns - recv_start_ns), recv_duration_str,
sizeof(recv_duration_str));
90 log_info("[ACIP_RECV_SUCCESS] Received %zu bytes in %s", packet_len, recv_duration_str);
91
92
93 if (packet_len < sizeof(packet_header_t)) {
95 return SET_ERRNO(ERROR_NETWORK, "Packet too small: %zu < %zu", packet_len, sizeof(packet_header_t));
96 }
97
98 const packet_header_t *header = (const packet_header_t *)packet_data;
99 envelope.type = NET_TO_HOST_U16(header->type);
100 envelope.len = NET_TO_HOST_U32(header->length);
101 envelope.data = (uint8_t *)packet_data + sizeof(packet_header_t);
102 envelope.allocated_buffer = allocated_buffer;
103 envelope.allocated_size = packet_len;
104
105 log_dev_every(4500 * US_PER_MS_INT, "ACIP_SERVER_DISPATCH: WebRTC packet parsed: type=%d, len=%u", envelope.type,
106 envelope.len);
107
108
109 if (envelope.type == PACKET_TYPE_ENCRYPTED && transport->crypto_ctx) {
111 uint8_t *ciphertext = (uint8_t *)envelope.data;
112 size_t ciphertext_len = envelope.len;
113
114
115 size_t plaintext_size = ciphertext_len + 1024;
117 if (!plaintext) {
119 return SET_ERRNO(ERROR_MEMORY, "Failed to allocate plaintext buffer for decryption");
120 }
121
122 size_t plaintext_len;
123 crypto_result_t crypto_result =
124 crypto_decrypt(transport->crypto_ctx, ciphertext, ciphertext_len, plaintext, plaintext_size, &plaintext_len);
125
126
128
129 if (crypto_result != CRYPTO_OK) {
131 return SET_ERRNO(ERROR_CRYPTO, "Failed to decrypt WebSocket packet: %s",
133 }
134
135 if (plaintext_len < sizeof(packet_header_t)) {
137 return SET_ERRNO(ERROR_CRYPTO, "Decrypted packet too small: %zu < %zu", plaintext_len, sizeof(packet_header_t));
138 }
139
140
141 const packet_header_t *inner_header = (const packet_header_t *)plaintext;
142 envelope.type = NET_TO_HOST_U16(inner_header->type);
143 envelope.len = NET_TO_HOST_U32(inner_header->length);
144 envelope.data = plaintext + sizeof(packet_header_t);
145 envelope.allocated_buffer = plaintext;
146 envelope.allocated_size = plaintext_size;
147
149 char decrypt_duration_str[32];
151 sizeof(decrypt_duration_str));
152 log_info("[WS_TIMING] Decrypt %zu bytes → %zu bytes in %s (inner_type=%d)", ciphertext_len, plaintext_len,
153 decrypt_duration_str, envelope.type);
154 }
155 }
156
157
158
159 log_info("ACIP_DISPATCH_PKT: type=%d, len=%zu, client_ctx=%p", envelope.type, envelope.len, client_ctx);
160 uint64_t dispatch_handler_start_ns =
time_get_ns();
161 asciichat_error_t dispatch_result =
164 char handler_duration_str[32];
165 format_duration_ns((
double)(dispatch_handler_end_ns - dispatch_handler_start_ns), handler_duration_str,
166 sizeof(handler_duration_str));
167 log_info("[WS_TIMING] Handler for type=%d took %s (result=%d)", envelope.type, handler_duration_str, dispatch_result);
168
169
170 if (envelope.allocated_buffer) {
172 }
173
174
175 return dispatch_result;
176}
const char * crypto_result_to_string(crypto_result_t result)
crypto_result_t crypto_decrypt(crypto_context_t *ctx, const uint8_t *ciphertext, size_t ciphertext_len, uint8_t *plaintext_out, size_t plaintext_out_size, size_t *plaintext_len_out)
asciichat_error_t acip_handle_server_packet(acip_transport_t *transport, packet_type_t type, const void *payload, size_t payload_len, void *client_ctx, const acip_server_callbacks_t *callbacks)
packet_recv_result_t receive_packet_secure(socket_t sockfd, void *crypto_ctx, bool enforce_encryption, packet_envelope_t *envelope)
Receive a packet with decryption and decompression support.
uint64_t time_get_ns(void)
int format_duration_ns(double nanoseconds, char *buffer, size_t buffer_size)