Reject raw CHAT data before delivery and forwarding

This commit is contained in:
evgeny committed 2026-11-03 19:52:24 +01:00
1 parent 9f6495e4ae
commit f2c8993589
2 files changed
+19 -5

No files matched your search

+4 -2
View File
@@ -81,6 +81,7 @@ void broadcast_destroy(struct TOPO_GROUP* group) {
int broadcast_send(struct TOPO_GROUP* group, const uint8_t* data, uint16_t data_len) {
if (!group || !group->broadcast || !data || data_len > BROADCAST_MAX_DATA) return -1;
if (!topo_group_data_allowed(group, NULL)) return -1;
struct broadcast_ctx* ctx = group->broadcast;
uint8_t uuid[BROADCAST_UUID_SIZE];
@@ -108,7 +109,7 @@ int broadcast_send(struct TOPO_GROUP* group, const uint8_t* data, uint16_t data_
struct ll_entry* se = group->senders_list->head;
while (se) {
struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)se->data;
if (item && item->conn) {
if (item && item->conn && topo_group_data_allowed(group, item->conn)) {
uint16_t total = 1 + 8 + BROADCAST_UUID_SIZE + 2 + data_len;
uint8_t* pkt = u_malloc(total);
if (!pkt) { se = se->next; continue; }
@@ -189,6 +190,7 @@ static void broadcast_cleanup_timer_cb(void* arg) {
void broadcast_recv(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* payload, size_t payload_len) {
if (!group || !group->broadcast || !payload || payload_len < BROADCAST_UUID_SIZE + 2) return;
if (!topo_group_data_allowed(group, from_conn)) return;
struct broadcast_ctx* ctx = group->broadcast;
const uint8_t* uuid = payload;
@@ -217,7 +219,7 @@ void broadcast_recv(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const
struct ll_entry* se = group->senders_list->head;
while (se) {
struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)se->data;
if (item && item->conn && item->conn != from_conn) {
if (item && item->conn && item->conn != from_conn && topo_group_data_allowed(group, item->conn)) {
uint16_t total = 1 + 8 + BROADCAST_UUID_SIZE + 2 + data_len;
uint8_t* pkt = u_malloc(total);
if (!pkt) { se = se->next; continue; }
+15 -3
View File
@@ -217,7 +217,7 @@ static void radio_flood(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn,
struct ll_entry* se = group->senders_list->head;
while (se) {
struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)se->data;
if (item && item->conn && item->conn != from_conn) {
if (item && item->conn && item->conn != from_conn && topo_group_data_allowed(group, item->conn)) {
if (radio_neighbor_has_subscriber(group, item->conn, hop_list, hop_count)) {
radio_send_to(group, item->conn, payload, payload_len);
ctx->c_fwd_frames++;
@@ -332,6 +332,7 @@ static void radio_recv(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn,
const uint8_t* payload, size_t payload_len) {
struct radio_ctx* ctx = radio_of(group);
if (!ctx || !from_conn || payload_len < RADIO_HDR_SIZE) return;
if (!topo_group_data_allowed(group, from_conn)) return;
const uint8_t* p = payload;
uint64_t group_id, src;
@@ -401,10 +402,14 @@ static void radio_recv(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn,
if (group->radio_active && ctx->group) {
struct radio_instance* ri = radio_inst(group->instance);
if (ri && ri->frame_fn) {
for (unsigned i = 0; i < count; i++)
for (unsigned i = 0; i < count; i++) {
if (!topo_group_data_allowed(group, from_conn)) return;
ri->frame_fn(group->instance, group_id, src, stream, (uint16_t)(seq + i), 0, frames[i], lengths[i], ri->frame_arg);
ctx->c_rx_frames++;
}
if (!topo_group_data_allowed(group, from_conn)) return;
if (flags & RADIO_FLAG_FIN) ri->frame_fn(group->instance, group_id, src, stream, seq, 1, NULL, 0, ri->frame_arg);
ctx->c_rx_frames += count + !!(flags & RADIO_FLAG_FIN);
ctx->c_rx_frames += !!(flags & RADIO_FLAG_FIN);
}
/* индикация говорящих: старт/стоп передачи */
if (flags & RADIO_FLAG_FIN) radio_talker_off(ctx, src);
@@ -658,6 +663,11 @@ static void radio_flush(struct radio_ctx* ctx, const char* reason) {
uasync_cancel_timeout(ctx->group->instance->ua, ctx->burst_timer); ctx->burst_timer = NULL;
}
if (!ctx->burst_count) return;
if (!topo_group_data_allowed(ctx->group, NULL)) {
DEBUG_WARN(DEBUG_CATEGORY_RADIO, "radio: discard revoked batch group=%llx frames=%u",
(unsigned long long)ctx->group->group_id, ctx->burst_count);
ctx->burst_count = 0; ctx->burst_bytes = 0; ctx->talking = 0; return;
}
uint64_t self = ctx->group->instance->node_id;
uint8_t out[RADIO_HDR_SIZE + 8 + RADIO_MAX_BODY];
uint16_t first_seq = (uint16_t)(ctx->seq - ctx->burst_count);
@@ -682,6 +692,7 @@ int radio_talk_begin(struct UTUN_INSTANCE* inst, uint64_t group_id) {
if (!group) { DEBUG_WARN(DEBUG_CATEGORY_RADIO, "%s: talk_begin group 0x%016llx not found", RADIO_ID, (unsigned long long)group_id); return -1; }
struct radio_ctx* ctx = radio_of(group);
if (!ctx) return -1;
if (!topo_group_data_allowed(group, NULL)) return -1;
if (ctx->talking) {
DEBUG_WARN(DEBUG_CATEGORY_RADIO, "radio: BEGIN closes unfinished stream=%u", ctx->stream_id);
radio_talk_end(inst, group_id);
@@ -702,6 +713,7 @@ int radio_talk_send(struct UTUN_INSTANCE* inst, uint64_t group_id, const uint8_t
struct TOPO_GROUP* group = topo_groups_find(inst->topo_groups, group_id);
struct radio_ctx* ctx = radio_of(group);
if (!ctx) { DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "radio: send group unavailable group=%llx", (unsigned long long)group_id); return -1; }
if (!topo_group_data_allowed(group, NULL)) { radio_flush(ctx, "revoked"); ctx->talking = 0; return -1; }
if (!ctx->talking) {
/* burst не открыт: хвостовой кадр, пришедший после radio_talk_end (гонка релиза PTT) —
* не переоткрываем передачу, иначе получится burst без FIN и «говорит» зависнет у пиров. */