mirror of
https://gitlab.com/d3tn/ud3tn.git
synced 2026-08-13 12:33:27 +02:00
This may happen for status reports addressed to the administrative endpoint. Before we would just call `strcmp`, leading to a segfault. Signed-off-by: Felix Walter <felix.walter@d3tn.com>
383 lines
12 KiB
C
383 lines
12 KiB
C
// SPDX-License-Identifier: BSD-3-Clause OR Apache-2.0
|
|
#include "ud3tn/agent_manager.h"
|
|
#include "ud3tn/bundle.h"
|
|
#include "ud3tn/common.h"
|
|
#include "ud3tn/fib.h"
|
|
|
|
#include "testud3tn_unity.h"
|
|
#include "testud3tn_eid_helpers.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
static const char *ADM_SECRET = "this_is_a_very_secure_adm_secret";
|
|
static const agent_no_t FIRST_AGENT_NO = 1;
|
|
static const char *VALID_DEMUX_CHARS = (
|
|
"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
|
|
);
|
|
static const char *VALID_DEMUX_CHARS_PLUS_SPACE = (
|
|
"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ "
|
|
);
|
|
|
|
static struct agent_manager *am, *am2;
|
|
static void *test_ptr1, *test_ptr2, *test_ptr3, *test_ptr4, *test_ptr5;
|
|
|
|
TEST_GROUP(agent_manager);
|
|
|
|
TEST_SETUP(agent_manager)
|
|
{
|
|
am = agent_manager_create(EID_DTN_UD3TN, ADM_SECRET);
|
|
am2 = agent_manager_create(EID_IPN_10, ADM_SECRET);
|
|
test_ptr1 = malloc(1);
|
|
test_ptr2 = malloc(1);
|
|
test_ptr3 = malloc(1);
|
|
test_ptr4 = malloc(1);
|
|
test_ptr5 = malloc(1);
|
|
}
|
|
|
|
TEST_TEAR_DOWN(agent_manager)
|
|
{
|
|
agent_manager_free(am);
|
|
agent_manager_free(am2);
|
|
free(test_ptr1);
|
|
free(test_ptr2);
|
|
free(test_ptr3);
|
|
free(test_ptr4);
|
|
free(test_ptr5);
|
|
}
|
|
|
|
TEST(agent_manager, create_free)
|
|
{
|
|
struct agent_manager *am_test;
|
|
|
|
TEST_ASSERT_NOT_NULL(am);
|
|
TEST_ASSERT_NOT_NULL(am2);
|
|
TEST_ASSERT_NULL(agent_manager_create(EID_INVALID, ADM_SECRET));
|
|
TEST_ASSERT_NULL(agent_manager_create(EID_NULL_DTN, ADM_SECRET));
|
|
TEST_ASSERT_NULL(agent_manager_create(EID_NULL_IPN, ADM_SECRET));
|
|
am_test = agent_manager_create(EID_IPN_10, ADM_SECRET);
|
|
TEST_ASSERT_NOT_NULL(am_test);
|
|
agent_manager_free(am_test);
|
|
am_test = agent_manager_create(EID_IPN_10, NULL);
|
|
if (IS_DEBUG_BUILD) {
|
|
TEST_ASSERT_NOT_NULL(am_test);
|
|
agent_manager_free(am_test);
|
|
} else {
|
|
TEST_ASSERT_NULL(am_test);
|
|
}
|
|
am_test = agent_manager_create(EID_IPN_10, NULL);
|
|
if (IS_DEBUG_BUILD) {
|
|
TEST_ASSERT_NOT_NULL(am_test);
|
|
agent_manager_free(am_test);
|
|
} else {
|
|
TEST_ASSERT_NULL(am_test);
|
|
}
|
|
TEST_ASSERT_GREATER_OR_EQUAL(1, AAP2_MINIMUM_PRE_SHARED_SECRET_LENGTH);
|
|
am_test = agent_manager_create(EID_IPN_10, "a");
|
|
if (IS_DEBUG_BUILD) {
|
|
TEST_ASSERT_NOT_NULL(am_test);
|
|
agent_manager_free(am_test);
|
|
} else {
|
|
TEST_ASSERT_NULL(am_test);
|
|
}
|
|
agent_manager_free(NULL);
|
|
}
|
|
|
|
static void am_test_trx(struct bundle_adu data,
|
|
void *param, const void *bp_context)
|
|
{
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr1, param);
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr2, bp_context);
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr3, data.payload);
|
|
}
|
|
|
|
static void am_test_fib(const struct fib_entry *fib_entry, const char *node_id,
|
|
enum fib_link_status link_status,
|
|
void *param, const void *bp_context)
|
|
{
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr1, param);
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr2, bp_context);
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr3, fib_entry);
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr4, node_id);
|
|
TEST_ASSERT_EQUAL(FIB_LINK_STATUS_UP, link_status);
|
|
}
|
|
|
|
static bool am_test_bdm(struct bundle *bundle,
|
|
enum bundle_dispatch_reason reason,
|
|
const char *node_id,
|
|
const char *cla_addr,
|
|
void *param, const void *bp_context)
|
|
{
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr1, param);
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr2, bp_context);
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr3, bundle);
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr4, node_id);
|
|
TEST_ASSERT_EQUAL_PTR(test_ptr5, cla_addr);
|
|
TEST_ASSERT_EQUAL(DISPATCH_REASON_TX_FAILED, reason);
|
|
return true;
|
|
}
|
|
|
|
static bool am_test_alive_true(void *param)
|
|
{
|
|
(void)param;
|
|
return true;
|
|
}
|
|
|
|
static bool am_test_alive_false(void *param)
|
|
{
|
|
(void)param;
|
|
return false;
|
|
}
|
|
|
|
TEST(agent_manager, reg)
|
|
{
|
|
struct agent testagent1 = {
|
|
.auth_trx = true,
|
|
.is_subscriber = false,
|
|
.trx_callback = am_test_trx,
|
|
.param = test_ptr1,
|
|
}, testagent2;
|
|
agent_no_t rv = AGENT_NO_INVALID, rv2 = AGENT_NO_INVALID;
|
|
|
|
// The following is not strictly necessary but can prevent some issues
|
|
// when forgetting to set the number.
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, testagent1.agent_no);
|
|
// dtn tests
|
|
rv = agent_register(am, testagent1); // register without sink
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.is_subscriber = true;
|
|
rv = agent_register(am, testagent1); // register without sink
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.is_subscriber = false;
|
|
testagent1.sink_identifier = VALID_DEMUX_CHARS_PLUS_SPACE;
|
|
rv = agent_register(am, testagent1); // register invalid sink
|
|
testagent1.sink_identifier = VALID_DEMUX_CHARS;
|
|
rv = agent_register(am, testagent1); // register valid sink
|
|
TEST_ASSERT_EQUAL(FIRST_AGENT_NO, rv);
|
|
rv2 = agent_register(am, testagent1); // register again
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv2);
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am, rv));
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, agent_deregister(am, rv)); // twice
|
|
// test liveliness check
|
|
testagent1.is_alive_callback = am_test_alive_true;
|
|
rv = agent_register(am, testagent1); // register valid sink
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
rv2 = agent_register(am, testagent1); // register again
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv2); // same as above
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am, rv));
|
|
testagent1.is_alive_callback = am_test_alive_false;
|
|
rv = agent_register(am, testagent1); // register valid sink
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
rv2 = agent_register(am, testagent1); // register again
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv2); // auto-deregistered
|
|
TEST_ASSERT_EQUAL(rv2, agent_deregister(am, rv2));
|
|
testagent1.is_alive_callback = NULL;
|
|
// ipn tests
|
|
rv = agent_register(am2, testagent1); // invalid sink for ipn
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.sink_identifier = "1"; // valid
|
|
rv = agent_register(am2, testagent1);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am2, rv));
|
|
testagent1.sink_identifier = "0"; // admin. endpoint is also valid
|
|
rv = agent_register(am2, testagent1);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am2, rv));
|
|
// reg. secret tests
|
|
rv = agent_register(am, testagent1); // register again after deregister
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent2 = testagent1;
|
|
testagent2.is_subscriber = true;
|
|
rv2 = agent_register(am, testagent2); // register other direction
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv2); // fails: secret == NULL
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am, rv));
|
|
TEST_ASSERT_EQUAL(rv2, agent_deregister(am, rv2));
|
|
testagent2.secret = "my-secret-123";
|
|
rv2 = agent_register(am, testagent2); // register again w/ secret
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv2);
|
|
rv = agent_register(am, testagent1); // w/o secret
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.secret = "my-secret-456";
|
|
rv = agent_register(am, testagent1); // w/ wrong secret
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.secret = "my-secret-123";
|
|
rv = agent_register(am, testagent1); // w/ correct secret
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am, rv));
|
|
testagent1.secret = ADM_SECRET;
|
|
rv = agent_register(am, testagent1); // w/ admin secret
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am, rv));
|
|
TEST_ASSERT_EQUAL(rv2, agent_deregister(am, rv2));
|
|
// test missing callback
|
|
testagent1.is_subscriber = true;
|
|
testagent1.trx_callback = NULL;
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.is_subscriber = false;
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am, rv));
|
|
// test FIB registration
|
|
testagent1.is_subscriber = true;
|
|
testagent1.auth_trx = false;
|
|
testagent1.auth_fib = true;
|
|
rv = agent_register(am, testagent1); // missing callback
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.fib_callback = am_test_fib;
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am, rv));
|
|
// test BDM registration
|
|
testagent1.auth_bdm = true;
|
|
rv = agent_register(am, testagent1); // missing callback
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.bdm_callback = am_test_bdm;
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
// 2nd sub. BDM should NOT work
|
|
testagent2 = testagent1;
|
|
rv2 = agent_register(am, testagent2);
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv2);
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am, rv));
|
|
// other direction
|
|
testagent1.bdm_callback = NULL;
|
|
testagent1.is_subscriber = false;
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
// 2nd RPC BDM should work
|
|
testagent2 = testagent1;
|
|
rv2 = agent_register(am, testagent2);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv2);
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am, rv));
|
|
TEST_ASSERT_EQUAL(rv2, agent_deregister(am, rv2));
|
|
// test wrong secret
|
|
testagent1.trx_callback = am_test_trx;
|
|
testagent1.bdm_callback = am_test_bdm;
|
|
testagent1.secret = "my-secret-123";
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.is_subscriber = true;
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.auth_bdm = false;
|
|
testagent1.is_subscriber = true;
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.is_subscriber = false;
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.auth_fib = false;
|
|
testagent1.is_subscriber = true;
|
|
rv = agent_register(am, testagent1); // no auth specified
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.is_subscriber = false;
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv);
|
|
testagent1.auth_trx = true;
|
|
testagent1.is_subscriber = true;
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am, rv));
|
|
testagent1.is_subscriber = false;
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
TEST_ASSERT_EQUAL(rv, agent_deregister(am, rv));
|
|
}
|
|
|
|
TEST(agent_manager, fwd_to_sub)
|
|
{
|
|
struct agent testagent1 = {
|
|
.auth_trx = true,
|
|
.is_subscriber = false,
|
|
.sink_identifier = VALID_DEMUX_CHARS,
|
|
.param = test_ptr1,
|
|
.secret = ADM_SECRET,
|
|
}, testagent2;
|
|
agent_no_t rv, rv2, rv3;
|
|
int rvi;
|
|
struct bundle_adu data_bdl = {
|
|
.payload = malloc(1),
|
|
};
|
|
|
|
rv = agent_register(am, testagent1);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv);
|
|
rv2 = agent_forward(am, VALID_DEMUX_CHARS, data_bdl, test_ptr2);
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv2);
|
|
data_bdl.payload = test_ptr3; // was freed by agent_forward!
|
|
testagent2 = testagent1;
|
|
testagent2.is_subscriber = true;
|
|
testagent2.trx_callback = am_test_trx;
|
|
rv3 = agent_register(am, testagent2);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv3);
|
|
// TRX fwd test
|
|
rv2 = agent_forward(am, VALID_DEMUX_CHARS, data_bdl, test_ptr2);
|
|
TEST_ASSERT_EQUAL(rv3, rv2);
|
|
data_bdl.payload = malloc(1); // was freed by agent_forward!
|
|
rv2 = agent_forward(am, NULL, data_bdl, test_ptr2);
|
|
TEST_ASSERT_EQUAL(AGENT_NO_INVALID, rv2);
|
|
// FIB fwd test
|
|
rvi = agent_send_fib_info(
|
|
am,
|
|
test_ptr3,
|
|
test_ptr4,
|
|
FIB_LINK_STATUS_UP,
|
|
test_ptr2
|
|
);
|
|
TEST_ASSERT_EQUAL(-1, rvi); // unregistered as FIB agent
|
|
testagent2.is_subscriber = false;
|
|
testagent2.auth_trx = false; // same sink -- if not TRX we can re-reg.
|
|
testagent2.auth_fib = true;
|
|
testagent2.fib_callback = am_test_fib;
|
|
rv2 = agent_register(am, testagent2);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv2);
|
|
rvi = agent_send_fib_info(
|
|
am,
|
|
test_ptr3,
|
|
test_ptr4,
|
|
FIB_LINK_STATUS_UP,
|
|
test_ptr2
|
|
);
|
|
TEST_ASSERT_EQUAL(-1, rvi); // no subscriber
|
|
TEST_ASSERT_EQUAL(rv2, agent_deregister(am, rv2));
|
|
testagent2.is_subscriber = true;
|
|
rv2 = agent_register(am, testagent2);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv2);
|
|
rvi = agent_send_fib_info(
|
|
am,
|
|
test_ptr3,
|
|
test_ptr4,
|
|
FIB_LINK_STATUS_UP,
|
|
test_ptr2
|
|
);
|
|
TEST_ASSERT_EQUAL(0, rvi);
|
|
rvi = agent_handover_to_dispatch(
|
|
am,
|
|
test_ptr3,
|
|
DISPATCH_REASON_TX_FAILED,
|
|
test_ptr4,
|
|
test_ptr5,
|
|
test_ptr2
|
|
);
|
|
TEST_ASSERT_EQUAL(-1, rvi); // unregistered as BDM agent
|
|
TEST_ASSERT_EQUAL(rv2, agent_deregister(am, rv2));
|
|
testagent2.auth_bdm = true;
|
|
testagent2.bdm_callback = am_test_bdm;
|
|
rv2 = agent_register(am, testagent2);
|
|
TEST_ASSERT_NOT_EQUAL(AGENT_NO_INVALID, rv2);
|
|
rvi = agent_handover_to_dispatch(
|
|
am,
|
|
test_ptr3,
|
|
DISPATCH_REASON_TX_FAILED,
|
|
test_ptr4,
|
|
test_ptr5,
|
|
test_ptr2
|
|
);
|
|
TEST_ASSERT_EQUAL(0, rvi);
|
|
}
|
|
|
|
TEST_GROUP_RUNNER(agent_manager)
|
|
{
|
|
RUN_TEST_CASE(agent_manager, create_free);
|
|
RUN_TEST_CASE(agent_manager, reg);
|
|
RUN_TEST_CASE(agent_manager, fwd_to_sub);
|
|
}
|