ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
lib/network/acip/server.c
Go to the documentation of this file.
1
13#include "network/acip/server.h"
14#include "network/acip/send.h"
16#include "network/packet.h"
17#include "buffer_pool.h"
18#include "log/logging.h"
19#include "common.h"
20#include "util/endian.h"
21#include "util/overflow.h"
22#include "network/crc32.h"
23#include <string.h>
24
25// =============================================================================
26// Server Receive (from client)
27// =============================================================================
28
30 const acip_server_callbacks_t *callbacks) {
31 if (!transport || !callbacks) {
32 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid transport or callbacks");
33 }
34
35 // Get socket from transport for low-level packet reception
36 socket_t sock = transport->methods->get_socket(transport);
37 if (sock == INVALID_SOCKET_VALUE) {
38 return SET_ERRNO(ERROR_NETWORK, "Transport has no valid socket");
39 }
40
41 // Check if transport is connected
42 if (!transport->methods->is_connected(transport)) {
43 return SET_ERRNO(ERROR_NETWORK, "Transport not connected");
44 }
45
46 // Receive packet with automatic decryption
47 packet_envelope_t envelope;
48 bool enforce_encryption = (transport->crypto_ctx != NULL);
49 packet_recv_result_t result = receive_packet_secure(sock, transport->crypto_ctx, enforce_encryption, &envelope);
50
51 // Handle receive errors
52 if (result != PACKET_RECV_SUCCESS) {
53 if (result == PACKET_RECV_EOF) {
54 return SET_ERRNO(ERROR_NETWORK, "Connection closed (EOF)");
55 } else if (result == PACKET_RECV_SECURITY_VIOLATION) {
56 return SET_ERRNO(ERROR_CRYPTO, "Security violation: unencrypted packet when encryption required");
57 } else {
58 return SET_ERRNO(ERROR_NETWORK, "Failed to receive packet");
59 }
60 }
61
62 // Dispatch packet to appropriate ACIP handler
63 asciichat_error_t dispatch_result =
64 acip_handle_server_packet(transport, envelope.type, envelope.data, envelope.len, client_ctx, callbacks);
65
66 // Always free the allocated buffer (even if handler failed)
67 if (envelope.allocated_buffer) {
68 buffer_pool_free(NULL, envelope.allocated_buffer, envelope.allocated_size);
69 }
70
71 // Return handler result
72 return dispatch_result;
73}
74
75// =============================================================================
76// Server Send (to client)
77// =============================================================================
78
79asciichat_error_t acip_send_ascii_frame(acip_transport_t *transport, const char *frame_data, uint32_t width,
80 uint32_t height) {
81 if (!transport || !frame_data) {
82 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid transport or frame_data");
83 }
84
85 size_t frame_size = strlen(frame_data);
86 if (frame_size == 0) {
87 return SET_ERRNO(ERROR_INVALID_PARAM, "Empty frame data");
88 }
89
90 // Calculate CRC32 checksum of frame data for integrity verification
91 uint32_t checksum_value = asciichat_crc32(frame_data, frame_size);
92
93 // Create ASCII frame packet header
95 header.width = HOST_TO_NET_U32(width);
96 header.height = HOST_TO_NET_U32(height);
97 header.original_size = HOST_TO_NET_U32((uint32_t)frame_size);
98 header.compressed_size = 0;
99 header.checksum = HOST_TO_NET_U32(checksum_value);
100 header.flags = 0;
101
102 // Calculate total packet size
103 size_t total_size;
104 if (checked_size_add(sizeof(header), frame_size, &total_size) != ASCIICHAT_OK) {
105 return SET_ERRNO(ERROR_INVALID_PARAM, "Packet size overflow");
106 }
107
108 // Allocate buffer
109 uint8_t *buffer = buffer_pool_alloc(NULL, total_size);
110 if (!buffer) {
111 return SET_ERRNO(ERROR_MEMORY, "Failed to allocate buffer: %zu bytes", total_size);
112 }
113
114 // Build packet: header + data
115 memcpy(buffer, &header, sizeof(header));
116 memcpy(buffer + sizeof(header), frame_data, frame_size);
117
118 // Send via transport
119 asciichat_error_t result = packet_send_via_transport(transport, PACKET_TYPE_ASCII_FRAME, buffer, total_size);
120
121 buffer_pool_free(NULL, buffer, total_size);
122 return result;
123}
124
126 if (!transport) {
127 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid transport");
128 }
129
130 return packet_send_via_transport(transport, PACKET_TYPE_CLEAR_CONSOLE, NULL, 0);
131}
132
134 if (!transport || !state) {
135 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid transport or state");
136 }
137
138 return packet_send_via_transport(transport, PACKET_TYPE_SERVER_STATE, state, sizeof(*state));
139}
🗃️ Lock-Free Unified Memory Buffer Pool with Lazy Allocation
Hardware-Accelerated CRC32 Checksum Computation.
🔄 Network byte order conversion helpers
#define HOST_TO_NET_U32(val)
Definition endian.h:71
void buffer_pool_free(buffer_pool_t *pool, void *data, size_t size)
Free a buffer back to the pool (lock-free)
void * buffer_pool_alloc(buffer_pool_t *pool, size_t size)
Allocate a buffer from the pool (lock-free fast path)
unsigned int uint32_t
Definition common.h:58
unsigned char uint8_t
Definition common.h:56
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it.
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:46
@ ERROR_NETWORK
Definition error_codes.h:69
@ ERROR_MEMORY
Definition error_codes.h:53
@ ASCIICHAT_OK
Definition error_codes.h:48
@ ERROR_CRYPTO
Definition error_codes.h:88
@ ERROR_INVALID_PARAM
uint32_t width
Terminal width in characters.
Definition packet.h:742
void * allocated_buffer
Buffer that needs to be freed by caller (may be NULL if not allocated)
Definition packet.h:990
uint32_t checksum
CRC32 checksum of original ASCII data.
Definition packet.h:750
uint32_t original_size
Size of original uncompressed ASCII data in bytes.
Definition packet.h:746
uint32_t height
Terminal height in characters.
Definition packet.h:744
uint32_t compressed_size
Size of compressed data (0 = not compressed)
Definition packet.h:748
size_t allocated_size
Size of allocated buffer in bytes.
Definition packet.h:992
size_t len
Length of payload data in bytes.
Definition packet.h:986
void * data
Packet payload data (decrypted and decompressed if applicable)
Definition packet.h:984
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.
Definition packet.c:568
packet_type_t type
Packet type (from packet_types.h)
Definition packet.h:982
uint32_t flags
Frame flags bitmask (HAS_COLOR, IS_COMPRESSED, etc.)
Definition packet.h:752
packet_recv_result_t
Packet reception result codes.
Definition packet.h:1003
@ PACKET_RECV_EOF
Connection closed (EOF)
Definition packet.h:1007
@ PACKET_RECV_SECURITY_VIOLATION
Encryption policy violation (e.g., unencrypted packet when encryption required)
Definition packet.h:1011
@ PACKET_RECV_SUCCESS
Packet received successfully.
Definition packet.h:1005
@ PACKET_TYPE_SERVER_STATE
Server sends current state to clients.
Definition packet.h:310
@ PACKET_TYPE_CLEAR_CONSOLE
Server tells client to clear console.
Definition packet.h:308
@ PACKET_TYPE_ASCII_FRAME
Complete ASCII frame with all metadata.
Definition packet.h:286
int socket_t
Socket handle type (POSIX: int)
Definition socket.h:50
#define INVALID_SOCKET_VALUE
Invalid socket value (POSIX: -1)
Definition socket.h:52
#define asciichat_crc32(data, len)
Main CRC32 dispatcher macro - use this in application code.
Definition crc32.h:144
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)
Handle incoming packet on server side.
Definition handlers.c:534
ACIP protocol packet handlers (transport-agnostic)
asciichat_error_t acip_send_server_state(acip_transport_t *transport, const server_state_packet_t *state)
Send server state update to client (server → client)
asciichat_error_t acip_server_receive_and_dispatch(acip_transport_t *transport, void *client_ctx, const acip_server_callbacks_t *callbacks)
Receive packet from client and dispatch to callbacks.
asciichat_error_t acip_send_ascii_frame(acip_transport_t *transport, const char *frame_data, uint32_t width, uint32_t height)
Send ASCII frame to client (server → client)
asciichat_error_t acip_send_clear_console(acip_transport_t *transport)
Send clear console command to client (server → client)
ACIP server-side protocol library.
📝 Logging API with multiple log levels and terminal output control
✅ Safe Integer Arithmetic and Overflow Detection
Packet protocol implementation with encryption and compression support.
asciichat_error_t packet_send_via_transport(acip_transport_t *transport, packet_type_t type, const void *payload, size_t payload_len)
Send packet via transport with proper header (exported for generic wrappers)
Definition send.c:40
ACIP shared/bidirectional packet sending functions.
Server-side packet handler callbacks.
Definition handlers.h:130
bool(* is_connected)(acip_transport_t *transport)
Check if transport is connected.
Definition transport.h:149
socket_t(* get_socket)(acip_transport_t *transport)
Get underlying socket (if applicable)
Definition transport.h:141
Transport instance structure.
Definition transport.h:169
const acip_transport_methods_t * methods
Method table (virtual functions)
Definition transport.h:170
crypto_context_t * crypto_ctx
Optional encryption context.
Definition transport.h:171
ASCII frame packet structure (Packet Type 2)
Definition packet.h:740
Packet envelope containing received packet data.
Definition packet.h:980
Server state packet structure.
Definition packet.h:598