Test radio invitation isolation and active invitation revocation
This commit is contained in:
1 parent
8b9adff206
commit
509368b76d
1 file changed
+54
-2
@@ -9,7 +9,10 @@
|
||||
#include "config_updater.h"
|
||||
#include "broadcast.h"
|
||||
#include "chat/member_sync.h"
|
||||
#include "chat/chat_event.h"
|
||||
#include "radio/radio.h"
|
||||
#include "radio/radio_call.h"
|
||||
#include "ntp_time.h"
|
||||
#include "member_files/private.h"
|
||||
#include "member_files/disk.h"
|
||||
#include "routing_layer/topo_group.h"
|
||||
@@ -46,6 +49,8 @@ static struct {
|
||||
pthread_cond_t disk_condition;
|
||||
int disk_started, disk_released;
|
||||
uint64_t block_request;
|
||||
unsigned call_incoming[2][2], call_finished[2];
|
||||
uint8_t call_reason[2];
|
||||
} fixture = { .disk_mutex = PTHREAD_MUTEX_INITIALIZER, .disk_condition = PTHREAD_COND_INITIALIZER };
|
||||
|
||||
/* Лог содержит и проверяемый эффект, и результат; отрицательный тест не обрывает соседние проверки. */
|
||||
@@ -317,6 +322,52 @@ static void file_response(void* arg, const struct mf_message* response) {
|
||||
mf_status_text(response->status), response->data_len);
|
||||
}
|
||||
|
||||
static void invitation_event(struct UTUN_INSTANCE* inst, int type, const uint8_t* data, int bytes) {
|
||||
if (type != CHAT_EVT_RADIO_CALL || bytes != 27) return;
|
||||
unsigned node = inst == fixture.nodes[0] ? 0 : 1;
|
||||
uint64_t group; memcpy(&group, data + 8, 8);
|
||||
if (data[24] == RADIO_CALL_INCOMING && group >= 111 && group <= 112) fixture.call_incoming[node][group - 111]++;
|
||||
if (data[24] == RADIO_CALL_FINISHED) { fixture.call_finished[node]++; fixture.call_reason[node] = data[25]; }
|
||||
}
|
||||
|
||||
static int invitation_isolation(void) {
|
||||
struct UTUN_INSTANCE* server = fixture.nodes[0]; struct UTUN_INSTANCE* client = fixture.nodes[1];
|
||||
REQUIRE(sqlite3_exec(server->topo_sqlite_db, "UPDATE peers_112 SET admitted=1", NULL, NULL, NULL) == SQLITE_OK);
|
||||
for (unsigned i = 0; i < 2; i++) { REQUIRE(!radio_call_init(fixture.nodes[i])); chat_event_set_handler(fixture.nodes[i], invitation_event); }
|
||||
struct radio_call_request request = {.inst = client, .id = 7000, .group = 112, .peer = server->node_id, .action = RADIO_CALL_START};
|
||||
radio_call_execute(&request);
|
||||
uint64_t deadline = get_time_tb() + 10000;
|
||||
while (!fixture.call_incoming[0][1] && get_time_tb() < deadline) uasync_poll(fixture.ua, 1);
|
||||
REQUIRE(fixture.call_incoming[0][1] == 1 && radio_call_busy(server));
|
||||
check("admitted radio invitation reaches B", 1);
|
||||
struct ETCP_ROUTER_CONN* route = etcp_router_conn_get(server, 112, client->node_id, ETCP_RT_ID_RADIO_CALL); REQUIRE(route);
|
||||
struct SVC_ROUTE_HDR saved = {.cmd = ETCP_ID_SVC_ROUTE, .group_id = 112, .src_node_id = client->node_id,
|
||||
.dst_node_id = server->node_id, .svc_id = ETCP_RT_ID_RADIO_CALL, .reset_id = route->peer_reset_id,
|
||||
.peer_reset_id = route->reset_id, .seq = route->rx_seq};
|
||||
char sql[160]; snprintf(sql, sizeof(sql), "UPDATE peers_112 SET admitted=0 WHERE node_id=%lld", (long long)client->node_id);
|
||||
REQUIRE(sqlite3_exec(server->topo_sqlite_db, sql, NULL, NULL, NULL) == SQLITE_OK);
|
||||
topo_group_revalidate_members(fixture.groups[0][1]);
|
||||
check("revocation stops incoming radio invitation", !radio_call_busy(server) && fixture.call_finished[0] == 1 &&
|
||||
fixture.call_reason[0] == RADIO_CALL_UNAVAILABLE);
|
||||
uint8_t payload[18] = {1}; // RC_INVITE: command, id, expiry_us, reason.
|
||||
uint64_t id = 7001; int64_t expires = ntp_time_get_us(client) + 2000000;
|
||||
memcpy(payload + 1, &id, 8); memcpy(payload + 9, &expires, 8);
|
||||
REQUIRE(!send_routed(&saved, payload, sizeof(payload), ROUTE_CRYPTO_SIGN | ROUTE_CRYPTO_ENCRYPT));
|
||||
check("revoked signed invitation creates no incoming call", !radio_call_busy(server) && fixture.call_incoming[0][1] == 1);
|
||||
struct radio_call_request denied = {.inst = server, .id = 7001, .group = 112, .peer = client->node_id, .action = RADIO_CALL_START};
|
||||
radio_call_execute(&denied);
|
||||
check("local radio invitation obeys current group admission", !radio_call_busy(server) && fixture.call_finished[0] == 2 &&
|
||||
fixture.call_reason[0] == RADIO_CALL_UNAVAILABLE);
|
||||
request.action = RADIO_CALL_CANCEL; radio_call_execute(&request);
|
||||
request.id = 7002; request.group = 111; request.action = RADIO_CALL_START; radio_call_execute(&request);
|
||||
deadline = get_time_tb() + 10000;
|
||||
while (!fixture.call_incoming[0][0] && get_time_tb() < deadline) uasync_poll(fixture.ua, 1);
|
||||
check("radio invitation in neighbouring A still works", fixture.call_incoming[0][0] == 1 && radio_call_busy(server) &&
|
||||
fixture.transport == instance_find_conn(client, server->node_id) && fixture.transport->links_up);
|
||||
for (unsigned i = 0; i < 2; i++) { radio_call_destroy(fixture.nodes[i]); chat_event_set_handler(fixture.nodes[i], NULL); }
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int file_isolation(unsigned running) {
|
||||
struct UTUN_INSTANCE* server = fixture.nodes[0];
|
||||
struct UTUN_INSTANCE* client = fixture.nodes[1];
|
||||
@@ -401,7 +452,7 @@ int main(void) {
|
||||
debug_set_category_level(DEBUG_CATEGORY_BGP, DEBUG_LEVEL_INFO);
|
||||
debug_set_category_level(DEBUG_CATEGORY_MEDIA, DEBUG_LEVEL_DEBUG);
|
||||
}
|
||||
if (setup() || run()) fixture.failed++;
|
||||
if (setup() || run() || invitation_isolation()) fixture.failed++;
|
||||
else {
|
||||
for (unsigned i = 0; i < 2; i++) if (member_files_init(fixture.nodes[i])) fixture.failed++;
|
||||
if (!fixture.failed) {
|
||||
@@ -423,7 +474,8 @@ int main(void) {
|
||||
pthread_mutex_unlock(&fixture.disk_mutex);
|
||||
for (unsigned i = 0; i < 2; i++) if (fixture.handles[i]) conn_mgr_close(fixture.handles[i]);
|
||||
for (unsigned i = 0; i < 2; i++) if (fixture.nodes[i]) {
|
||||
member_files_destroy(fixture.nodes[i]); member_sync_destroy(fixture.nodes[i]); utun_instance_destroy(fixture.nodes[i]);
|
||||
radio_call_destroy(fixture.nodes[i]); member_files_destroy(fixture.nodes[i]);
|
||||
member_sync_destroy(fixture.nodes[i]); utun_instance_destroy(fixture.nodes[i]);
|
||||
}
|
||||
if (fixture.ua) uasync_destroy(fixture.ua, 0);
|
||||
pthread_cond_destroy(&fixture.disk_condition); pthread_mutex_destroy(&fixture.disk_mutex);
|
||||
|
||||
Reference in new issue
Block a user