Cover empty NODEINFO outputs and malformed BGP preservation
This commit is contained in:
1 parent
790978458c
commit
acd9dcd1a8
3 files changed
+40
No files matched your search
@@ -6,6 +6,14 @@
|
||||
заменяются вместе. Timestamp входит в подпись. Групповые пути и подсети
|
||||
остаются в `TOPO_GROUP_NODE` и не являются частью общей записи узла.
|
||||
|
||||
В NODEINFO секции подсетей присутствуют только при `TOPO_FLAG_SEND_SUBNETS`.
|
||||
Без флага оба счётчика подсетей равны нулю; противоречащий этому заголовок отклоняется.
|
||||
Parser проверяет точную длину пакета и проходит все присутствующие секции независимо
|
||||
от запрошенных `out_*`: например, `out_subnets=NULL` отключает создание объектов подсетей,
|
||||
но сохраняет проверку префиксов и правильное положение следующего hop-list.
|
||||
Выходы выдаются только после полного успеха; при ошибке они обнулены, частичные объекты
|
||||
освобождены. Подпись и допустимость пути проверяются после структурного разбора.
|
||||
|
||||
Получатель проверяет подпись до изменения реестра или маршрутов. Более свежая
|
||||
запись заменяет старую целиком, включая пустые списки адресов. Старые записи
|
||||
игнорируются; разные подписанные записи с одинаковым timestamp — конфликт.
|
||||
|
||||
@@ -159,6 +159,11 @@ static void test_bgp(struct UTUN_INSTANCE* signer) {
|
||||
assert(topo_group_process_nodeinfo(&group, &from, packet, (size_t)len + sizeof(struct TOPOMSG_HEADER)) == 0);
|
||||
assert(queue_entry_count(peer->paths) == 1);
|
||||
struct TOPOMSG_NODEINFO_PKT* wire = (struct TOPOMSG_NODEINFO_PKT*)packet;
|
||||
wire->node.local_v4_subnets = 1; /* malformed CHAT не меняет уже принятую запись и маршрут */
|
||||
assert(topo_group_process_nodeinfo(&group, &from, packet, (size_t)len + sizeof(struct TOPOMSG_HEADER)) < 0);
|
||||
assert(topo_node_find_by_id(&group, ni->node_id) == peer && queue_entry_count(peer->paths) == 1);
|
||||
assert(peer->last_timestamp == ni->timestamp && topo_node_registry_find(signer->topo_groups, ni->node_id)->timestamp == ni->timestamp);
|
||||
wire->node.local_v4_subnets = 0;
|
||||
wire->node.timestamp++; /* подделка не удаляет узел и ранее принятый маршрут */
|
||||
assert(topo_group_process_nodeinfo(&group, &from, packet, (size_t)len + sizeof(struct TOPOMSG_HEADER)) < 0);
|
||||
assert(topo_node_find_by_id(&group, ni->node_id) == peer && queue_entry_count(peer->paths) == 1);
|
||||
|
||||
@@ -216,6 +216,32 @@ static void test_encoder(struct wire_fixture *f) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "[PASS] NODEINFO encoder emits only selected sections and checks exact buffer capacity");
|
||||
}
|
||||
|
||||
static void test_empty_and_arguments(struct wire_fixture *f) {
|
||||
memset(f->wire, 0, sizeof(f->wire));
|
||||
struct TOPOMSG_NODE *h = (struct TOPOMSG_NODE *)f->wire;
|
||||
for (unsigned with_flag = 0; with_flag < 2; with_flag++) {
|
||||
h->flags = with_flag ? TOPO_FLAG_SEND_SUBNETS : 0;
|
||||
struct TOPO_NODE *node = NULL; struct TOPO_NODESUBNETS *subnets = (void *)(uintptr_t)1;
|
||||
uint64_t *hops = (void *)(uintptr_t)1; uint8_t count = 99; uint16_t rtt = 99;
|
||||
assert(!topo_node_deserialize(&f->group, f->wire, TOPOMSG_NODE_HDR_SIZE, &node, &subnets, &hops, &count, &rtt));
|
||||
assert(node && !node->node_name && !node->v4_addrs && !node->v6_addrs && !subnets && !hops && !count && !rtt);
|
||||
result_free(f, node, subnets, hops);
|
||||
}
|
||||
struct TOPO_NODE *node = (void *)(uintptr_t)1;
|
||||
assert(topo_node_deserialize(NULL, f->wire, TOPOMSG_NODE_HDR_SIZE, &node, NULL, NULL, NULL, NULL) < 0 && !node);
|
||||
assert(topo_node_deserialize(&f->group, NULL, TOPOMSG_NODE_HDR_SIZE, &node, NULL, NULL, NULL, NULL) < 0 && !node);
|
||||
assert(topo_node_deserialize(&f->group, f->wire, TOPOMSG_NODE_HDR_SIZE, NULL, NULL, NULL, NULL, NULL) < 0);
|
||||
assert(topo_node_dyn_size(NULL) < 0);
|
||||
fixture_packet(f, TOPO_FLAG_SEND_SUBNETS, 0);
|
||||
struct TOPOMSG_SUBNET4 *v4 = (struct TOPOMSG_SUBNET4 *)(f->wire + f->subnet4_offset);
|
||||
struct TOPOMSG_SUBNET6 *v6 = (struct TOPOMSG_SUBNET6 *)(f->wire + f->subnet6_offset);
|
||||
v4[0].prefix_length = 0; v4[1].prefix_length = 32;
|
||||
v6[0].prefix_length = 0; v6[1].prefix_length = 128;
|
||||
assert(!topo_node_deserialize(&f->group, f->wire, f->length, &node, NULL, NULL, NULL, NULL));
|
||||
topo_node_destroy(&f->groups, node);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "[PASS] NODEINFO empty sections, missing arguments and prefix boundaries");
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
static void test_allocation_failures(struct wire_fixture *f) {
|
||||
fixture_packet(f, TOPO_FLAG_SEND_SUBNETS, 2);
|
||||
@@ -246,6 +272,7 @@ int main(void) {
|
||||
test_invalid_packets(&fixture);
|
||||
test_optional_outputs(&fixture);
|
||||
test_encoder(&fixture);
|
||||
test_empty_and_arguments(&fixture);
|
||||
#ifdef __linux__
|
||||
test_allocation_failures(&fixture);
|
||||
#endif
|
||||
|
||||
Reference in new issue
Block a user