ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
Validation Helpers

Reusable validation macros for protocol handlers. More...

Topics

 Image Validation Functions

Files

file  validation.h
 Common validation macros to reduce duplication in protocol handlers.

Macros

#define VALIDATE_NOTNULL_DATA(client, data, packet_name)
#define VALIDATE_MIN_SIZE(client, len, min_size, packet_name)
#define VALIDATE_EXACT_SIZE(client, len, expected_size, packet_name)
#define VALIDATE_AUDIO_STREAM_ENABLED(client, packet_name)
#define VALIDATE_AUDIO_SAMPLE_COUNT(client, num_samples, max_samples, packet_name)
#define VALIDATE_AUDIO_ALIGNMENT(client, len, sample_size, packet_name)
#define VALIDATE_RESOURCE_INITIALIZED(client, resource, resource_name)
#define VALIDATE_PACKET_SIZE(client, data, len, expected_size, packet_name)
#define VALIDATE_NONZERO(client, value, value_name, packet_name)
#define VALIDATE_RANGE(client, value, min_val, max_val, value_name, packet_name)
#define VALIDATE_CAPABILITY_FLAGS(client, flags, valid_mask, packet_name)
#define VALIDATE_FLAGS_MASK(client, flags, valid_mask, packet_name)
#define VALIDATE_PACKET_NOT_NULL(client, data, packet_name)

Typedefs

typedef struct client_info client_info_t

Functions

void disconnect_client_for_bad_data (client_info_t *client, const char *format,...)

Detailed Description

Reusable validation macros for protocol handlers.

Provides standardized validation macros for protocol handlers to:

  • Check for NULL pointers
  • Validate payload sizes
  • Verify client state flags
  • Reduce code duplication across handlers

All macros call disconnect_client_for_bad_data() on validation failure and return from the calling function immediately.

Usage:

void handle_packet(client_info_t *client, const void *data, size_t len) {
VALIDATE_NOTNULL_DATA(client, data, "PACKET_TYPE");
VALIDATE_MIN_SIZE(client, len, 16, "PACKET_TYPE");
VALIDATE_AUDIO_STREAM_ENABLED(client, "PACKET_TYPE");
// ... continue processing ...
}
struct client_info client_info_t
#define VALIDATE_AUDIO_STREAM_ENABLED(client, packet_name)
#define VALIDATE_MIN_SIZE(client, len, min_size, packet_name)
#define VALIDATE_NOTNULL_DATA(client, data, packet_name)

Macro Definition Documentation

◆ VALIDATE_AUDIO_ALIGNMENT

#define VALIDATE_AUDIO_ALIGNMENT ( client,
len,
sample_size,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if ((len) % (sample_size) != 0) { \
disconnect_client_for_bad_data((client), "%s payload not aligned (len=%zu, sample_size=%zu)", (packet_name), \
(len), (sample_size)); \
return; \
} \
} while (0)

Validate that audio sample alignment is correct (must be multiple of sample size). Disconnects client and returns if alignment is incorrect.

Definition at line 111 of file util/validation.h.

111#define VALIDATE_AUDIO_ALIGNMENT(client, len, sample_size, packet_name) \
112 do { \
113 if ((len) % (sample_size) != 0) { \
114 disconnect_client_for_bad_data((client), "%s payload not aligned (len=%zu, sample_size=%zu)", (packet_name), \
115 (len), (sample_size)); \
116 return; \
117 } \
118 } while (0)

Referenced by handle_audio_packet().

◆ VALIDATE_AUDIO_SAMPLE_COUNT

#define VALIDATE_AUDIO_SAMPLE_COUNT ( client,
num_samples,
max_samples,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if ((num_samples) <= 0 || (num_samples) > (max_samples)) { \
disconnect_client_for_bad_data((client), "%s invalid sample count: %d (max %d)", (packet_name), (num_samples), \
(max_samples)); \
return; \
} \
} while (0)

Validate that audio sample count is within acceptable bounds. Disconnects client and returns if sample count is invalid.

Definition at line 98 of file util/validation.h.

98#define VALIDATE_AUDIO_SAMPLE_COUNT(client, num_samples, max_samples, packet_name) \
99 do { \
100 if ((num_samples) <= 0 || (num_samples) > (max_samples)) { \
101 disconnect_client_for_bad_data((client), "%s invalid sample count: %d (max %d)", (packet_name), (num_samples), \
102 (max_samples)); \
103 return; \
104 } \
105 } while (0)

Referenced by handle_audio_packet().

◆ VALIDATE_AUDIO_STREAM_ENABLED

#define VALIDATE_AUDIO_STREAM_ENABLED ( client,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if (!atomic_load_bool(&(client)->is_sending_audio)) { \
disconnect_client_for_bad_data((client), "%s received before audio stream enabled", (packet_name)); \
return; \
} \
} while (0)

Validate that audio stream is enabled for this client. Disconnects client and returns if audio stream is not enabled.

Definition at line 86 of file util/validation.h.

86#define VALIDATE_AUDIO_STREAM_ENABLED(client, packet_name) \
87 do { \
88 if (!atomic_load_bool(&(client)->is_sending_audio)) { \
89 disconnect_client_for_bad_data((client), "%s received before audio stream enabled", (packet_name)); \
90 return; \
91 } \
92 } while (0)

Referenced by handle_audio_batch_packet(), handle_audio_opus_batch_packet(), and handle_audio_packet().

◆ VALIDATE_CAPABILITY_FLAGS

#define VALIDATE_CAPABILITY_FLAGS ( client,
flags,
valid_mask,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if (((flags) & (valid_mask)) == 0) { \
disconnect_client_for_bad_data((client), "%s no valid capability flags set (flags=0x%x, valid=0x%x)", \
(packet_name), (unsigned)(flags), (unsigned)(valid_mask)); \
return; \
} \
} while (0)

Validate that at least one capability flag is set. Disconnects client and returns if all flags are zero or invalid.

Definition at line 178 of file util/validation.h.

178#define VALIDATE_CAPABILITY_FLAGS(client, flags, valid_mask, packet_name) \
179 do { \
180 if (((flags) & (valid_mask)) == 0) { \
181 disconnect_client_for_bad_data((client), "%s no valid capability flags set (flags=0x%x, valid=0x%x)", \
182 (packet_name), (unsigned)(flags), (unsigned)(valid_mask)); \
183 return; \
184 } \
185 } while (0)

Referenced by handle_client_join_packet(), handle_stream_start_packet(), and handle_stream_stop_packet().

◆ VALIDATE_EXACT_SIZE

#define VALIDATE_EXACT_SIZE ( client,
len,
expected_size,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if ((len) != (expected_size)) { \
disconnect_client_for_bad_data((client), "%s payload size mismatch (len=%zu, expected=%zu)", (packet_name), \
(len), (expected_size)); \
return; \
} \
} while (0)

Validate that payload size is exactly the expected size. Disconnects client and returns if len != expected_size.

Definition at line 73 of file util/validation.h.

73#define VALIDATE_EXACT_SIZE(client, len, expected_size, packet_name) \
74 do { \
75 if ((len) != (expected_size)) { \
76 disconnect_client_for_bad_data((client), "%s payload size mismatch (len=%zu, expected=%zu)", (packet_name), \
77 (len), (expected_size)); \
78 return; \
79 } \
80 } while (0)

◆ VALIDATE_FLAGS_MASK

#define VALIDATE_FLAGS_MASK ( client,
flags,
valid_mask,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if (((flags) & ~(valid_mask)) != 0) { \
disconnect_client_for_bad_data((client), "%s unknown flags set (flags=0x%x, valid=0x%x)", (packet_name), \
(unsigned)(flags), (unsigned)(valid_mask)); \
return; \
} \
} while (0)

Validate that only known/valid flags are set. Disconnects client and returns if unknown flags are present.

Definition at line 191 of file util/validation.h.

191#define VALIDATE_FLAGS_MASK(client, flags, valid_mask, packet_name) \
192 do { \
193 if (((flags) & ~(valid_mask)) != 0) { \
194 disconnect_client_for_bad_data((client), "%s unknown flags set (flags=0x%x, valid=0x%x)", (packet_name), \
195 (unsigned)(flags), (unsigned)(valid_mask)); \
196 return; \
197 } \
198 } while (0)

Referenced by handle_client_join_packet(), handle_stream_start_packet(), and handle_stream_stop_packet().

◆ VALIDATE_MIN_SIZE

#define VALIDATE_MIN_SIZE ( client,
len,
min_size,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if ((len) < (min_size)) { \
disconnect_client_for_bad_data((client), "%s payload too small (len=%zu, min=%zu)", (packet_name), (len), \
(min_size)); \
return; \
} \
} while (0)

Validate that payload size is at least the minimum required. Disconnects client and returns if len < min_size.

Definition at line 60 of file util/validation.h.

60#define VALIDATE_MIN_SIZE(client, len, min_size, packet_name) \
61 do { \
62 if ((len) < (min_size)) { \
63 disconnect_client_for_bad_data((client), "%s payload too small (len=%zu, min=%zu)", (packet_name), (len), \
64 (min_size)); \
65 return; \
66 } \
67 } while (0)

Referenced by handle_audio_batch_packet().

◆ VALIDATE_NONZERO

#define VALIDATE_NONZERO ( client,
value,
value_name,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if ((value) == 0) { \
disconnect_client_for_bad_data((client), "%s %s cannot be zero", (packet_name), (value_name)); \
return; \
} \
} while (0)

Validate that a numeric value is non-zero (for dimensions, counts, etc). Disconnects client and returns if value is zero.

Definition at line 153 of file util/validation.h.

153#define VALIDATE_NONZERO(client, value, value_name, packet_name) \
154 do { \
155 if ((value) == 0) { \
156 disconnect_client_for_bad_data((client), "%s %s cannot be zero", (packet_name), (value_name)); \
157 return; \
158 } \
159 } while (0)

Referenced by handle_audio_batch_packet(), handle_audio_opus_batch_packet(), and handle_size_packet().

◆ VALIDATE_NOTNULL_DATA

#define VALIDATE_NOTNULL_DATA ( client,
data,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if (!(data)) { \
disconnect_client_for_bad_data((client), "%s payload missing", (packet_name)); \
return; \
} \
} while (0)

Validate that payload data pointer is not NULL. Disconnects client and returns if data is NULL.

Definition at line 48 of file util/validation.h.

48#define VALIDATE_NOTNULL_DATA(client, data, packet_name) \
49 do { \
50 if (!(data)) { \
51 disconnect_client_for_bad_data((client), "%s payload missing", (packet_name)); \
52 return; \
53 } \
54 } while (0)

Referenced by handle_audio_batch_packet(), handle_audio_opus_batch_packet(), and handle_audio_packet().

◆ VALIDATE_PACKET_NOT_NULL

#define VALIDATE_PACKET_NOT_NULL ( client,
data,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
({ \
int _validation_failed = 0; \
if (!(data)) { \
disconnect_client_for_bad_data((client), packet_name " payload missing"); \
_validation_failed = 1; \
} \
_validation_failed; \
})

Validate packet payload pointer is not NULL. Returns true if validation failed (data is NULL), false if valid.

Definition at line 204 of file util/validation.h.

204#define VALIDATE_PACKET_NOT_NULL(client, data, packet_name) \
205 ({ \
206 int _validation_failed = 0; \
207 if (!(data)) { \
208 disconnect_client_for_bad_data((client), packet_name " payload missing"); \
209 _validation_failed = 1; \
210 } \
211 _validation_failed; \
212 })

Referenced by handle_audio_opus_packet().

◆ VALIDATE_PACKET_SIZE

#define VALIDATE_PACKET_SIZE ( client,
data,
len,
expected_size,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if (!(data)) { \
disconnect_client_for_bad_data((client), packet_name " payload missing"); \
return; \
} \
if ((len) != (expected_size)) { \
disconnect_client_for_bad_data((client), packet_name " payload size %zu (expected %zu)", (len), \
(expected_size)); \
return; \
} \
} while (0)

Validate packet payload size and presence. Checks if data pointer is non-NULL and payload matches expected size.

Definition at line 136 of file util/validation.h.

136#define VALIDATE_PACKET_SIZE(client, data, len, expected_size, packet_name) \
137 do { \
138 if (!(data)) { \
139 disconnect_client_for_bad_data((client), packet_name " payload missing"); \
140 return; \
141 } \
142 if ((len) != (expected_size)) { \
143 disconnect_client_for_bad_data((client), packet_name " payload size %zu (expected %zu)", (len), \
144 (expected_size)); \
145 return; \
146 } \
147 } while (0)

Referenced by handle_client_join_packet(), handle_size_packet(), handle_stream_start_packet(), and handle_stream_stop_packet().

◆ VALIDATE_RANGE

#define VALIDATE_RANGE ( client,
value,
min_val,
max_val,
value_name,
packet_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if ((value) < (min_val) || (value) > (max_val)) { \
disconnect_client_for_bad_data((client), "%s %s out of range: %u (valid: %u-%u)", (packet_name), (value_name), \
(unsigned)(value), (unsigned)(min_val), (unsigned)(max_val)); \
return; \
} \
} while (0)

Validate that a numeric value is within a specified range (inclusive). Disconnects client and returns if value is outside range.

Definition at line 165 of file util/validation.h.

165#define VALIDATE_RANGE(client, value, min_val, max_val, value_name, packet_name) \
166 do { \
167 if ((value) < (min_val) || (value) > (max_val)) { \
168 disconnect_client_for_bad_data((client), "%s %s out of range: %u (valid: %u-%u)", (packet_name), (value_name), \
169 (unsigned)(value), (unsigned)(min_val), (unsigned)(max_val)); \
170 return; \
171 } \
172 } while (0)

Referenced by handle_audio_opus_batch_packet(), and handle_size_packet().

◆ VALIDATE_RESOURCE_INITIALIZED

#define VALIDATE_RESOURCE_INITIALIZED ( client,
resource,
resource_name )

#include <include/ascii-chat/util/validation.h>

Value:
do { \
if (!(resource)) { \
disconnect_client_for_bad_data((client), "%s not initialized", (resource_name)); \
return; \
} \
} while (0)

Validate that a required resource/buffer is initialized. Disconnects client and returns if resource is NULL.

Definition at line 124 of file util/validation.h.

124#define VALIDATE_RESOURCE_INITIALIZED(client, resource, resource_name) \
125 do { \
126 if (!(resource)) { \
127 disconnect_client_for_bad_data((client), "%s not initialized", (resource_name)); \
128 return; \
129 } \
130 } while (0)

Referenced by handle_audio_opus_batch_packet(), and handle_audio_packet().

Typedef Documentation

◆ client_info_t

Function Documentation

◆ disconnect_client_for_bad_data()

void disconnect_client_for_bad_data ( client_info_t * client,
const char * format,
... )

#include <include/ascii-chat/util/validation.h>

Definition at line 167 of file server/protocol.c.

167 {
168 if (!client) {
169 return;
170 }
171
172 protocol_cleanup_thread_locals();
173
174 // Atomically set the disconnect flag and get the old value
175 // This ensures only one thread proceeds to disconnect (the first one)
176 bool already_requested = atomic_exchange_bool(&client->protocol_disconnect_requested, true);
177 if (already_requested) {
178 return; // Already disconnecting, don't do it again
179 }
180
181 char reason[BUFFER_SIZE_SMALL] = {0};
182 if (format) {
183 va_list args;
184 va_start(args, format);
185 safe_vsnprintf(reason, sizeof(reason), format, args);
186 va_end(args);
187 } else {
188 SAFE_STRNCPY(reason, "Protocol violation", sizeof(reason));
189 }
190
191 const char *reason_str = reason[0] != '\0' ? reason : "Protocol violation";
192 const char *client_id = client->client_id;
193
194 log_warn("Disconnecting client %s due to protocol violation: %s", client_id, reason_str);
195 mutex_lock(&client->send_mutex);
196 if (client->transport)
198 mutex_unlock(&client->send_mutex);
199
200 log_debug("Setting active=false (client_id=%s, reason=%s)", client_id, reason_str);
201 atomic_store_bool(&client->active, false);
202 atomic_store_bool(&client->shutting_down, true);
204 atomic_store_bool(&client->video_render_thread_running, false);
205 atomic_store_bool(&client->audio_render_thread_running, false);
206}
action_args_t args
Definition actions.c:78
#define BUFFER_SIZE_SMALL
Small buffer size (256 bytes).
#define SAFE_STRNCPY(dst, src, size)
Definition common.h:423
@ ERROR_NETWORK_PROTOCOL
Definition error_codes.h:76
#define log_warn(...)
Log a WARN message.
Definition log/log.h:621
#define log_debug(...)
Log a DEBUG message.
Definition log/log.h:595
int safe_vsnprintf(char *buffer, size_t buffer_size, const char *format, va_list ap)
Platform-safe vsnprintf wrapper.
void network_connection_request_stop(network_connection_t *c)
asciichat_error_t acip_send_error(acip_transport_t *transport, uint32_t error_code, const char *message)
Send error message packet.
Definition send.c:415
network_connection_t * network_connection
char client_id[MAX_CLIENT_ID_LEN]

References acip_send_error(), client_info::active, args, client_info::audio_render_thread_running, BUFFER_SIZE_SMALL, client_info::client_id, ERROR_NETWORK_PROTOCOL, log_debug, log_warn, client_info::network_connection, network_connection_request_stop(), client_info::protocol_disconnect_requested, SAFE_STRNCPY, safe_vsnprintf(), client_info::send_mutex, client_info::shutting_down, client_info::transport, and client_info::video_render_thread_running.

Referenced by handle_audio_batch_packet(), handle_audio_opus_batch_packet(), handle_audio_opus_packet(), handle_client_capabilities_packet(), handle_client_join_packet(), handle_image_frame_h264_packet(), handle_image_frame_h265_packet(), handle_image_frame_packet(), handle_protocol_version_packet(), handle_remote_log_packet_from_client(), and process_decrypted_packet().