Browse Source

Test mailbox admission, exact deletion and late PUT replay

master
evgeny 2 weeks ago
parent
commit
1740bec94f
  1. 46
      tests/test_dm_e2e.c

46
tests/test_dm_e2e.c

@ -20,6 +20,8 @@
#include "../routing_layer/topo_node.h"
#include "../utun_instance.h"
#include "../transport_layer/etcp.h"
#include "../transport_layer/etcp_api.h"
#include "../routing_layer/etcp_router.h"
#include "../transport_layer/secure_channel.h"
#include "../ntp_time.h"
#include "../lib/u_async.h"
@ -250,8 +252,29 @@ static size_t test_body(struct UTUN_INSTANCE* author, uint64_t seq, const char*
return 39 + enc_len + 64;
}
/* Вход сервиса после аутентификации router; отдельно от реального UDP-сценария ниже. */
static int mailbox_packet(struct UTUN_INSTANCE* dst, uint64_t source, uint8_t cmd, const uint8_t* body, size_t len) {
struct ETCP_CONN* conn = instance_find_conn(dst, dst->node_id == g_sh.nid[IDX_C] ? g_sh.nid[IDX_A] : g_sh.nid[IDX_C]);
if (!conn || !dst->router_bindings.callbacks[ETCP_RT_ID_DM_MAILBOX]) return -1;
struct ll_entry* e = queue_entry_new(0);
if (!e) return -1;
e->len = (uint16_t)(ROUTER_SVC_PAYLOAD_OFF + 1 + len);
e->dgram = u_calloc(1, e->len);
if (!e->dgram) { queue_entry_free(e); return -1; }
uint64_t gid = strtoull(CH_ID, NULL, 10);
e->dgram[0] = ETCP_RT_ID_DM_MAILBOX;
memcpy(e->dgram + ROUTER_SVC_SRC_OFF, &source, 8);
memcpy(e->dgram + ROUTER_SVC_DST_OFF, &dst->node_id, 8);
memcpy(e->dgram + ROUTER_SVC_GROUP_OFF, &gid, 8);
e->dgram[ROUTER_SVC_FLAGS_OFF] = ROUTER_FLAG_SIGNED;
e->dgram[ROUTER_SVC_PAYLOAD_OFF] = cmd;
memcpy(e->dgram + ROUTER_SVC_PAYLOAD_OFF + 1, body, len);
dst->router_bindings.callbacks[ETCP_RT_ID_DM_MAILBOX](conn, e);
return 0;
}
/* Ошибочный commit, tamper, точные повторы и ACK чужого тела не теряют pending. */
static int protocol_checks(struct UTUN_INSTANCE* A, struct UTUN_INSTANCE* B) {
static int protocol_checks(struct UTUN_INSTANCE* A, struct UTUN_INSTANCE* B, struct UTUN_INSTANCE* C) {
uint8_t body[512], receipt[DM_RECEIPT_SIZE], again[DM_RECEIPT_SIZE];
size_t len = test_body(A, 100, "higher", body);
if (!len || dm_accept_message(B, body, len, receipt) != 0 ||
@ -291,6 +314,25 @@ static int protocol_checks(struct UTUN_INSTANCE* A, struct UTUN_INSTANCE* B) {
int seq_unchanged = sqlite3_step(st) == SQLITE_ROW && sqlite3_column_int64(st, 0) == 1;
sqlite3_finalize(st);
if (!seq_unchanged) return -1;
/* Суперузел хранит только проверенные тела и удаляет только точный подтверждённый экземпляр. */
len = test_body(A, 97, "mailbox-exact-receipt", body);
if (!len) return -1;
uint8_t put[8 + 512];
memcpy(put, &B->node_id, 8);
memcpy(put + 8, body, len);
if (mailbox_packet(A, A->node_id, 1, put, len + 8) != 0 || dm_mail_count(A) != 0) return -1; /* A без роли. */
put[8 + len - 1] ^= 1;
if (mailbox_packet(C, A->node_id, 1, put, len + 8) != 0 || dm_mail_count(C) != 0) return -1;
put[8 + len - 1] ^= 1;
if (mailbox_packet(C, A->node_id, 1, put, len + 8) != 0 || dm_mail_count(C) != 1) return -1;
if (dm_accept_message(B, body, len, receipt) != 0) return -1;
memcpy(again, receipt, sizeof(again));
again[40] ^= 1;
if (sc_ed25519_sign(B->my_ed25519_privkey, again, 72, again + 72) != SC_OK) return -1;
if (mailbox_packet(C, B->node_id, 3, again, sizeof(again)) != 0 || dm_mail_count(C) != 1) return -1;
if (mailbox_packet(C, C->node_id, 3, receipt, sizeof(receipt)) != 0 || dm_mail_count(C) != 1) return -1;
if (mailbox_packet(C, B->node_id, 3, receipt, sizeof(receipt)) != 0 || dm_mail_count(C) != 0) return -1;
if (mailbox_packet(C, A->node_id, 1, put, len + 8) != 0 || dm_mail_count(C) != 0) return -1; /* Поздний PUT. */
DEBUG_INFO(DEBUG_CATEGORY_DM, "protocol checks passed: reorder, dedup, tamper, DB rollback, exact receipt");
return 0;
}
@ -394,7 +436,7 @@ static void dm_tick(void* arg) {
break;
case P_SEND1:
if (dm_start(A, nb, g_sh.x_pub[IDX_B], g_sh.ed_pub[IDX_B], "B", CH_ID) != 0
|| dm_send(A, g_sh.conv_id, "text", (const uint8_t*)"hello1", 6) != 0 || protocol_checks(A, B) != 0) {
|| dm_send(A, g_sh.conv_id, "text", (const uint8_t*)"hello1", 6) != 0 || protocol_checks(A, B, C) != 0) {
fprintf(stderr, "A: dm_start/send hello1 failed\n");
t->result = 2;
} else {

Loading…
Cancel
Save