ud3tn/components/bundle6/create.c
Felix Walter 6a16e94808 bundle: Switch all flags and length fields to 64bit and do not filter
- The standard defines 64 bits for all flags.
- Also see https://www.rfc-editor.org/rfc/rfc9171.html#section-4.2.3-6:
  "Bundle processing control flags that are unrecognized MUST be ignored,
  as future definitions of additional flags might not be integrated
  simultaneously into the Bundle Protocol implementations operating at
  all nodes."
- Similar for blocks:
  https://www.rfc-editor.org/rfc/rfc9171.html#section-4.2.4-2
- The primary block length is calculated internally based on the bundle
  length -- to prevent overflow, we use 64 bit here as well. (We might
  introduce additional checks in the future, but the input being CBOR
  with the validations in the BPv7 parser should already work to
  only allow a "sane" primary block length. For BPv6 we enforce still
  parsing only 16 bits for it.)
- Also define a bit mask for BPv6 flags (`BP_V6_FLAGS`)

Closes: #247, #237

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2026-03-19 18:58:07 +01:00

82 lines
2.2 KiB
C

// SPDX-License-Identifier: BSD-3-Clause OR Apache-2.0
#include "bundle6/create.h"
#include "ud3tn/bundle.h"
#include "ud3tn/common.h"
#include "ud3tn/eid.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
struct bundle *bundle6_create_local(
void *payload, size_t payload_length,
const struct eid source, const struct eid destination, const struct eid report_to,
uint64_t creation_time_ms, uint64_t sequence_number,
uint64_t lifetime_ms, uint64_t proc_flags)
{
if (!payload)
return NULL;
if (eid_is_error(source) || eid_is_error(destination) || eid_is_error(report_to)) {
free(payload);
return NULL;
}
struct bundle *bundle = bundle_init();
if (bundle == NULL) {
free(payload);
return NULL;
}
bundle->protocol_version = 0x6;
bundle->proc_flags = proc_flags | BUNDLE_V6_FLAG_SINGLETON_ENDPOINT;
// Creation time
bundle->creation_timestamp_ms = creation_time_ms;
bundle->sequence_number = sequence_number;
bundle->lifetime_ms = lifetime_ms;
// Create payload block and block list
bundle->payload_block = bundle_block_create(BUNDLE_BLOCK_TYPE_PAYLOAD);
bundle->payload_block->flags = BUNDLE_V6_BLOCK_FLAG_LAST_BLOCK;
bundle->blocks = bundle_block_entry_create(bundle->payload_block);
if (bundle->payload_block == NULL || bundle->blocks == NULL)
goto fail;
bundle->source = eid_dup(source);
if (eid_is_error(bundle->source))
goto fail;
bundle->destination = eid_dup(destination);
if (eid_is_error(bundle->destination))
goto fail; // bundle_free takes care of source
bundle->report_to = eid_dup(report_to);
if (eid_is_error(bundle->report_to))
goto fail; // bundle_free takes care of source and destination
bundle->destination_str = eid_to_string(bundle->destination);
bundle->source_str = eid_to_string(bundle->source);
bundle->report_to_str = eid_to_string(bundle->report_to);
bundle->current_custodian = eid_get_null();
bundle->payload_block->data = payload;
bundle->payload_block->length = payload_length;
if (bundle_recalculate_header_length(bundle) == UD3TN_FAIL) {
bundle->payload_block->data = NULL; // prevent double-free
goto fail;
}
return bundle;
fail:
free(payload);
bundle_free(bundle);
return NULL;
}