mirror of
https://gitlab.com/d3tn/ud3tn.git
synced 2026-08-13 12:33:27 +02:00
- A new `struct eid` is introduced, which can represent EIDs in a
scheme-based manner; specifically, this means that `ipn` EIDs are
now represented as tuples of two 64-bit integers and the `dtn` null
endpoint is now represented as a `NULL` pointer (similar to the CBOR
representation in RFC 9171).
- We assume that any `struct eid` instance has been validated before,
e.g. by decoding a string via `eid_from_string`.
- Note that the FIB is still using the (normalized) string format of
node IDs. It performs a lookup in a hash table anyway and, later, we
plan to support EID patterns (current IETF draft).
- Changes to parsers and serializers:
- The BPv7 parser validates EIDs separately from `eid_from_string`.
This is intentional: No full normalizationis performed for incoming
bundles; as long as the EID is valid, it is passed through, to
prevent changes to the immutable (as per RFC9171) primary block.
This means that, e.g., there are two representations of the null
endpoint (`dtn:none` and `ipn:0.0`), which are kept as such now.
- The BPv6 parser and serializer will rewrite the primary block of
passing bundles -- they do this anyway as the "dictionary" is
re-constructed by the serializer.
- Dedicated string representations of the EIDs (`source_str`, etc.)
are added to the bundle struct on reception (`cla_contact_tx_task`)
and creation -- this is done for convenience when processing the
bundle further (especially to still be able to print log messages
referring to the EIDs in the BP and so on). We may remove it in the
future to reduce the number of EID-to-string conversions.
- Other changes:
- Some terminology is cleaned up in the process: e.g., variables
referring to the local administrative endpoint identifier are
renamed as such. The previously-used terms "local node ID" or,
worse, "local EID" are inaccurate -- according to the standards,
any locally registered singleton EID is a node ID of the local
bundle node.
- In some places, log messages are harmonized (e.g. by always using
quotes around EIDs and no quotes for agent sink IDs). Sometimes,
EIDs were printed in logs which have been removed now to prevent
an unnecessary EID-to-string conversion.
- `aap2_agent`: the manual deallocation of string parts of the AAP2
message is now replaced by a less fragile `pb_release` in most
cases.
- `bundle.h`: `struct endpoint_list` is replaced in BPv6 by a
`struct eid_list` containing the new `struct eid`; the DFCF
("compat") router still uses the old variant with strings
- `init`: `preprocess_local_eid` is simplified and moved to
`cmdline.c`. It now uses `eid_from_string`, which tolerates missing
trailing slashes for `dtn`. Also, we do not support `ipn:x` without
service number anymore on the command line, as it is an invalid
format and only makes the coe more complex.
It is recommended to review the changes to `ud3tn/eid.[c|h]` and the
associated unit tests (`test_eid.c`) first, to get an overall idea of
the added and adapted functionality plus the expected behaviors. Before
reviewing the individual changes to all functions dealing with EIDs, it
is also advisable to take a quick look at the other associated
(following) commits.
Signed-off-by: Felix Walter <felix.walter@d3tn.com>
173 lines
4.3 KiB
C
173 lines
4.3 KiB
C
// SPDX-License-Identifier: BSD-3-Clause OR Apache-2.0
|
|
#include "bundle7/fragment.h"
|
|
|
|
#include "ud3tn/bundle.h"
|
|
#include "ud3tn/eid.h"
|
|
|
|
#include "testud3tn_unity.h"
|
|
#include "testud3tn_eid_helpers.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
static struct bundle *bundle;
|
|
static struct bundle *fragment1, *fragment2;
|
|
|
|
|
|
TEST_GROUP(bundle7Fragmentation);
|
|
|
|
TEST_SETUP(bundle7Fragmentation)
|
|
{
|
|
bundle = NULL;
|
|
fragment1 = NULL;
|
|
fragment2 = NULL;
|
|
}
|
|
|
|
TEST_TEAR_DOWN(bundle7Fragmentation)
|
|
{
|
|
if (bundle != NULL)
|
|
bundle_free(bundle);
|
|
|
|
if (fragment1 != NULL)
|
|
bundle_free(fragment1);
|
|
|
|
if (fragment2 != NULL)
|
|
bundle_free(fragment2);
|
|
}
|
|
|
|
TEST(bundle7Fragmentation, fragment_bundle)
|
|
{
|
|
bundle = bundle_init();
|
|
|
|
TEST_ASSERT_NOT_NULL(bundle);
|
|
|
|
bundle->protocol_version = 7;
|
|
bundle->crc_type = BUNDLE_CRC_TYPE_32;
|
|
|
|
bundle->destination = eid_dup(EID_IPN_10);
|
|
bundle->source = eid_dup(EID_DTN_UD3TN_AGENT);
|
|
bundle->report_to = eid_dup(EID_DTN_UD3TN);
|
|
|
|
bundle->creation_timestamp_ms = 0;
|
|
bundle->sequence_number = 0;
|
|
bundle->lifetime_ms = 86400;
|
|
|
|
struct bundle_block_list *prev;
|
|
struct bundle_block_list *entry;
|
|
struct bundle_block *block;
|
|
|
|
// Previous node block
|
|
block = bundle_block_create(BUNDLE_BLOCK_TYPE_PREVIOUS_NODE);
|
|
entry = bundle_block_entry_create(block);
|
|
|
|
bundle->blocks = entry;
|
|
prev = entry;
|
|
|
|
uint8_t previous_node[6] = {
|
|
0x82, 0x01, 0x63, 0x47, 0x53, 0x34
|
|
};
|
|
|
|
block->number = 2;
|
|
block->crc_type = bundle->crc_type;
|
|
block->length = sizeof(previous_node);
|
|
block->data = malloc(sizeof(previous_node));
|
|
TEST_ASSERT_NOT_NULL(block->data);
|
|
memcpy(block->data, previous_node, sizeof(previous_node));
|
|
|
|
// Hop count block
|
|
block = bundle_block_create(BUNDLE_BLOCK_TYPE_HOP_COUNT);
|
|
entry = bundle_block_entry_create(block);
|
|
|
|
prev->next = entry;
|
|
prev = entry;
|
|
|
|
uint8_t hop_count[4] = { 0x82, 0x18, 0x1e, 0x00 };
|
|
|
|
block->number = 3;
|
|
block->flags |= BUNDLE_BLOCK_FLAG_MUST_BE_REPLICATED;
|
|
block->crc_type = bundle->crc_type;
|
|
block->length = sizeof(hop_count);
|
|
block->data = malloc(sizeof(hop_count));
|
|
TEST_ASSERT_NOT_NULL(block->data);
|
|
memcpy(block->data, hop_count, sizeof(hop_count));
|
|
|
|
// Payload
|
|
block = bundle_block_create(BUNDLE_BLOCK_TYPE_PAYLOAD);
|
|
entry = bundle_block_entry_create(block);
|
|
|
|
prev->next = entry;
|
|
|
|
// "Hello world"
|
|
uint8_t payload[13] = {
|
|
0x4c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72,
|
|
0x6c, 0x64, 0x21
|
|
};
|
|
|
|
block->number = 0;
|
|
block->crc_type = bundle->crc_type;
|
|
block->length = sizeof(payload);
|
|
block->data = malloc(sizeof(payload));
|
|
TEST_ASSERT_NOT_NULL(block->data);
|
|
memcpy(block->data, payload, sizeof(payload));
|
|
bundle->payload_block = block;
|
|
|
|
// NOTE: The calculation is pessimistic, assuming the biggest possible
|
|
// header size (fragment offset == ADU length), thus, 47 and not 45 b.
|
|
TEST_ASSERT_EQUAL(47, bundle_get_first_fragment_min_size(bundle));
|
|
|
|
// Split payload:
|
|
//
|
|
// 13 = 7 + 6
|
|
//
|
|
fragment1 = bundle7_fragment_bundle(bundle, 0, 7);
|
|
fragment2 = bundle7_fragment_bundle(bundle, 7, 6);
|
|
|
|
TEST_ASSERT_NOT_NULL(fragment1);
|
|
TEST_ASSERT_NOT_NULL(fragment2);
|
|
TEST_ASSERT_NOT_EQUAL(bundle, fragment1);
|
|
TEST_ASSERT_NOT_EQUAL(bundle, fragment2);
|
|
TEST_ASSERT_NOT_NULL(fragment1->payload_block);
|
|
TEST_ASSERT_NOT_NULL(fragment2->payload_block);
|
|
|
|
// 1st Fragment
|
|
//
|
|
// Previous Node Block
|
|
entry = fragment1->blocks;
|
|
TEST_ASSERT_NOT_NULL(entry);
|
|
TEST_ASSERT_EQUAL(BUNDLE_BLOCK_TYPE_PREVIOUS_NODE, entry->data->type);
|
|
|
|
// Hop-Count Block
|
|
entry = entry->next;
|
|
TEST_ASSERT_NOT_NULL(entry);
|
|
TEST_ASSERT_EQUAL(BUNDLE_BLOCK_TYPE_HOP_COUNT, entry->data->type);
|
|
|
|
// Payload Block
|
|
entry = entry->next;
|
|
TEST_ASSERT_NOT_NULL(entry);
|
|
TEST_ASSERT_EQUAL_PTR(fragment1->payload_block, entry->data);
|
|
TEST_ASSERT_EQUAL(BUNDLE_BLOCK_TYPE_PAYLOAD, entry->data->type);
|
|
TEST_ASSERT_EQUAL(7, fragment1->payload_block->length);
|
|
TEST_ASSERT_NULL(entry->next);
|
|
|
|
// 2nd Fragment
|
|
//
|
|
|
|
// Hop-Count Block
|
|
entry = fragment2->blocks;
|
|
TEST_ASSERT_NOT_NULL(entry);
|
|
TEST_ASSERT_EQUAL(BUNDLE_BLOCK_TYPE_HOP_COUNT, entry->data->type);
|
|
|
|
// Payload Block
|
|
entry = entry->next;
|
|
TEST_ASSERT_NOT_NULL(entry);
|
|
TEST_ASSERT_EQUAL_PTR(fragment2->payload_block, entry->data);
|
|
TEST_ASSERT_EQUAL(BUNDLE_BLOCK_TYPE_PAYLOAD, entry->data->type);
|
|
TEST_ASSERT_EQUAL(6, fragment2->payload_block->length);
|
|
TEST_ASSERT_NULL(entry->next);
|
|
}
|
|
|
|
TEST_GROUP_RUNNER(bundle7Fragmentation)
|
|
{
|
|
RUN_TEST_CASE(bundle7Fragmentation, fragment_bundle);
|
|
}
|