Commit graph

116 commits

Author SHA1 Message Date
Felix Walter
e16ec4c579 Enable building a BPv7 decoder binary
This adds a target `data-decoder` which builds a binary to decode a
specified binary file using uD3TN's parsing logic (based on the CLA RX
subsystem) and print details about it. In this first version only the
decoding of BPv7 bundles is implemented.

This binary can be used, e.g., for fuzz testing.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-16 11:34:14 +02:00
Felix Walter
6880b22b90 hal_semaphore/hal_queue: Accept 64-bit timestamps as delay
Previously the maximum waiting time was just over 24 days. In a DTN
setup we may want to wait longer, e.g., for contacts to occur. This
allows for waiting about 292 years. If the provided delay exceeds this
threshold, an infinite delay is assumed.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-15 11:39:29 +02:00
Felix Walter
adb80c8938 simple_queue: Remove queueItemsWaiting
We cannot easily support this on MacOS, but we do not use it except in
tests. Thus, remove it and make the tests only run on Linux and use
`sem_getvalue` directly.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-15 11:01:34 +02:00
Felix Walter
1e8d86548c hal: Add a hal_semaphore implementation that works on MacOS
Unnamed semaphores are unsupported there, which is why we were seeing
segfaults.

See also: https://stackoverflow.com/a/27847103

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-15 11:01:34 +02:00
Felix Walter
f07262b909 Rename fallthrough macro to fallthrough_ok to prevent conflict
There is the compiler attribute `fallthrough` already. This
re-definition makes checking for it using __has_attribute impossible.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-15 11:01:34 +02:00
Marius Feldmann
11b0d49796 Validate contact intervals in RoutingTable
So far the contact interval check was done in the
config parser. As this is a semantical and not
syntactical check it is moved to the RoutingTable.

Modified @ 2022-12-21 by Felix Walter to adapt to new state of codebase,
adding the check to `node_prepare_and_verify` in `node.c` instead.

Closes: #47

Signed-off-by: Marius Feldmann <marius.feldmann@d3tn.com>
Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-12 10:43:43 +02:00
Felix Walter
00d5d2d050 external, hal: Remove unused crypto (HMAC, SHA2) and JSON functions
This removes all external functions currently unused in uD3TN.
We may re-introduce esp. JSON at a later point in time, but should
include updated libraries anyway.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-12 09:12:30 +02:00
Felix Walter
d9bd711c9a bundle6: Allow for receiving CBHE-encoded bundles
This also adds a test for it, sending bundles from within ION to uD3TN
in the "minimal forwarding test".

Fixes: #7

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-12 08:07:42 +02:00
Felix Walter
379f09d7af hal_time, agents: Remove the function to set the system time
This should be a function offered by the operating system, not by a
userland process like uD3TN.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-11 16:59:13 +02:00
Felix Walter
97d520db34 node: Adapt contact interval DTN timestamp unit to milliseconds
This changes the "from" and "to" fields in the contact struct to
milliseconds-based timestamps and adapts all dependent code. The contact
data format is kept second-based for backward compatibility.

The commit also introduces a new function to work with millisecond
timestamps in the remaining capacity calculation and modifies the tests
related to the latter such that they do not need to change the timestamp.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-11 16:59:13 +02:00
Felix Walter
a46fd3b53b node: Remove unused bundle count field
This was set but never read (anymore).

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-11 16:59:13 +02:00
Felix Walter
3cd89eb6a5 bundle, agents: Switch time unit to milliseconds
...to align with the general decision to make DTN timestamps
millisecond-based.

See: #53

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-11 16:59:13 +02:00
Felix Walter
d9bd61fd63 bundle: Add function to get bundle expiration time in milliseconds
This introduces a function to work with milliseconds-based timestamps
also in case of the expiration time.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-11 16:59:13 +02:00
Felix Walter
7a3816ca42 node: Add unit suffix to contact interval fields
This clearly identifies that we are working with seconds here.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-11 16:59:13 +02:00
Felix Walter
67fe84a395 node: Identify unit for bitrate in field name
Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-11 16:59:13 +02:00
Felix Walter
9e08c42ed3 Enable agents to send bundles via direct function invocation
This removes the need to send them via the queue which might result in a
deadlock as described in #115. The bundle processor context is passed as
an opaque pointer that can be used for calling BP functions from agent
callbacks (which run inside the BP thread).

Fixes: #115

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 17:23:55 +02:00
Felix Walter
85f20e8b25 config_agent: Do not send command via BP queue
This may cause a deadlock which we observed sometimes in the routing
integration test in CI as one slot in the BP queue is always needed to
finish processing the Bundle in the BP (that causes `agent_forward` in
this case).

This makes the config agent directly invoke the BP function.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 17:23:55 +02:00
Felix Walter
1237eaa2db Remove heap-allocated Task_t
`hal_task_create` returned a reference to the new task allocated on the
heap via `malloc`. We commonly used the pattern to `free` this reference
from the new thread which, however, could result in race conditions and
other synchronization issues. We added a fix using a semaphore in the
application agent, but this would have been needed in other places (CLA,
...) as well. As we do not make use of the task reference anywhere
besides in the CLA for error handling, we can remove the heap-allocated
value altogether and replace it with an `enum ud3tn_result` to simplify
things and circumvent the named synchronization issues.

In the case of the CLA function `cla_link_init`, logic is introduced to
request the RX task to exit immediately in case the TX task cannot be
launched.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 17:23:55 +02:00
Felix Walter
995a4263bf bundle_processor: Remove unnecessary router queue field
Not used anymore since we reoved the router task...

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 17:23:55 +02:00
Felix Walter
69e4095dcb Remove hal_random
The test was returning indeterministic errors and we did not even use
the function anymore.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 17:23:55 +02:00
Felix Walter
65d7582a88 Provide LOGERROR() macro for errno logging and remove strerror
`strerror()` is not thread-safe, thus, we have to use an alternative. If
we want to prevent allocating a temporary buffer (e.g., for
`strerror_r`), we need to use `perror()`. To allow writing stored
`errno` values, the function sets `errno` from an argument passed to it,
which should be safe according to the manual.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 15:37:02 +02:00
Felix Walter
e27c157107 hal_platform: Remove unnecessary platform-dependent functions
This removes some functions solely useful for the STM32, debugging and
error handling with these boards. When doing a future uC port, we should
move such functions to the platform-specific part.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 15:07:16 +02:00
Felix Walter
90fd0b4c33 routing_table: Explicitly free contact list upon deletion
There was a rare memory leak if the contact was not found in the target
list (e.g., already deleted earlier).

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 15:07:16 +02:00
Felix Walter
af462184b3 CLA: Synchronize access to link parameter data structure
The primary issue that was also identified by Clang's thread sanitizer
was that we were accessing fields like `link->active` from multiple
threads concurrently. See [1], especially under optimizations such a
variable cannot be used to tell other threads when to terminate.

The primary fix here is to introduce a guarding mutex (binary semaphore)
around the "link parameters" data structures in all connection-oriented
CLAs. The mutex is only locked when working with the structure and
should always be unlocked when a blocking operation (e.g., `accept()`,
`send()`, `recv()`) is executed. To achieve this, we sometimes store the
return value of such functions in a temporary variable before re-locking
the mutex and adapting the param struct.

The `cla_link_wait_cleanup` routine is split in two parts so that during
the "wait" operation the mutex can be unlocked and when cleaning up the
link (consequently needing to update and drop resources from the link
parameters) it can be locked.

The "serializer functions" (`*_begin_packet`, `*_send_packet_data`,
`*_end_packet`) do not need to ckech for `link->active` anymore (which
is removed) as it is made sure to terminate the TX task invoking the
serializer before invalidating the link structures. If anything is
invalidated by the OS (e.g., by the TCP connection breaking), an error
will occur in these functions and propagate to the TX task, leading to a
call to the `cla_disconnect_handler`, in turn tearing down the link, but
the link parameters will be 100% valid the whole time.

Additionally, to notify the RX task when it should exit, another semaphore
is introduced. The TX task already has a thread-safe queue to send a
notification to it to terminate, removing the need for another check.

The locking of the "param hash table", where the "link parameters" are
stored is revised such that it is always locked while changes occur to
it or the values stored inside it (as long as they are not locked
themselves by the specific param semaphore.

[1] https://github.com/google/sanitizers/wiki/ThreadSanitizerPopularDataRaces

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 15:07:13 +02:00
Felix Walter
e31a865bf8 hal_semaphore: Supply proper function to check if blocked
The previous polling method was not clean in that it left the semaphore
locked and did not return whether the operation was successful or not.
This adds a more descriptive and correct method to chieve the goal of
checking the semaphore's status.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 14:37:11 +02:00
Felix Walter
1a328ab681 contact_manager: Do not leak the task pointer implicitly
This returns the pointer to the caller so it can be de-allocated later
on.

Found by ASAN.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 14:37:11 +02:00
Felix Walter
baf1aac4c2 hal_io: Forward all logs to stderr and make it line-buffered
This switches all log messages to `stderr`, which is intended for
diagnostic purposes (i.e., matches the intent of our log messages). This
makes it easy to distinguish the log output from actual output (which
the uD3TN daemon does not have, but a program based on libud3tn might).

This also flushes stderr after every log message (i.e., makes it
line-buffered) to prevent delays when outputting the logs.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 14:32:56 +02:00
Felix Walter
96a7c02a21 bundle, parser: Force enum types to be signed
Enum fields, by the standard, are always of a signed integer type.
However, sometimes compilers choose to make variables declared with the
enum type unsigned. This leads to value-changing conversions when
removing flags in flag-enums via `value &= ~FLAG;`. A field with value
-1 ensures that the enum-type variables always get a signed type.

Found by Clang's UB sanitizer.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 14:32:47 +02:00
Felix Walter
dd6d34d707 hal_time: Make time functions thread-safe
Do not return a reference to a non-thread-safe global variable:
ctime() is not thread safe. As we only use the function in logging, we
can directly print the return value, protected by a mutex.

This also adapts the tests and makes the initialization routine always
run. To use the system time again, UINT64_MAX can be passed.

Found by Clang's thread (data race) sanitizer.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 14:32:47 +02:00
Felix Walter
2fc9e11b7e bundle: Fix potential uint wrap-around in expiration time calculation
We were taking the current time value in milliseconds and sometimes
subtracting larger values from it. This cleans up the calculations to
always determine the expiration time as uint64_t and compare it against
the current uint64_t timestamp.

It further removes the unnecessary "current timestamp" parameter in
`bundle_get_expiration_time_s` (we now store the reception time with the
bundle, so, do not need this anymore) and avoids a integer wrap-around
case in the function.

Note that the current time cancels out in the age block-based
calculation as we can use the reception timestamp there and offset it by
the calculated relative remaining lifetime.

Found by Clang's UB sanitizer.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 14:31:17 +02:00
Felix Walter
e5f90b41a1 contact_manager: Rework queue delay calculation
This prevents an integer overflow and removes the unnecessary "maximum
delay". We do not need periodic checking in case the CM is notified on
every bundle and contact, which is already the case.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 14:26:28 +02:00
Felix Walter
3f818c8ce8 common.h: Disable abort on ASSERT() in release mode
Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 11:22:51 +02:00
Felix Walter
2b3a76c409 cla_bibe: Fix out-of-bound write
The BIBE CLA allocated a buffer the size of sizeof(struct aap_message)
but then serialized an AAP message into it. It should have used
aap_get_serialized_size(), though, this change directly removes the
unnecessary buffer in between and directly writes out the data.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2023-05-10 11:10:24 +02:00
Felix Walter
69eab551ab Transmit the whole list of bundles in the TX queue
This reduces the number of queue sends as the whole bundle list is
transmitted by the CM to the TX task which then consumes it iteratively.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 21:02:38 +01:00
Felix Walter
3a35280a58 Contact Manager: Remove global state and reduce locking
This adds a context struct for the contact manager state and removes the
lock during bundle transmission to the TX task. Before any contact is
evaluated and bundles are transmitted, a check occurs whether the
contact is still part of the routing table.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 21:02:38 +01:00
Felix Walter
93a58ed387 Merge Bundle Processor and Router Task
This refactors the Router Task into synchronous functions called by the
BP, preventing the need of circular notifications between them.
The router queue is replaced by new signals in the BP queue.

This additionally removes the global state in the bundle processor.

Closes: #11

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 21:02:36 +01:00
Felix Walter
f8395e8d94 router: Remove probabilities and struct routed_bundle
The probability-based routing was never used productively. It implied
that we store all the contacts for which a bundle was scheduled (as
there may be more than one) and keep it, doing reference counting before
we drop the data structure, and so on. This change removes everything
probability-related. The field in the config commands is kept to ensure
backwards compatibility if this is specified.

The removal of struct routed_bundle allows for a major simplification of
all routing-related code.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 20:59:43 +01:00
Felix Walter
3ade800bd5 Always spawn an RX task in TCP CLAs
We need to recv() on the TCP socket to detect it when the connection is
closed or reset.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 20:56:39 +01:00
Felix Walter
6663ac4f8f CLA: Allow unidirectional links and specify directions upon link init
Some CLAs such as MTCP use unidirectional links. In these cases, we
should not start a TX _and_ RX task. This adds two parameters to
cla_link_init to specify the direction(s) used by the created link.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 20:56:39 +01:00
Felix Walter
6932ee635f router: Annotate void pointer options of the router_signal data field
Due to the adjustments in the code, the possibilities that the `data` field of the `router_signal` struct can contain have changed. For this reason, the comment must also be adjusted.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 20:36:49 +01:00
Felix Walter
097459ac1e CLA: TX: Report CLA address and transmitted bundle to router
Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 20:36:49 +01:00
Felix Walter
db293b5020 CLA: Report proper CLA address to router
Previously we did not include the CLA name. This also removes the
unnecessary `cla_type` field in the struct, whose value can easily be
obtained by the `cla_name_get()` function.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 20:36:49 +01:00
Felix Walter
4d8bbd9a8e CLA: Communicate CLA address in link up/down signals
This informs the router also of the address of the connected peer in the
relevant signals issued by the CLA subsystem to the router task

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 20:36:49 +01:00
Tobias Nöthlich
faa0d456e5 Add ROUTER_SIGNAL_LINK_DOWN
Besides the signal when a new link is established, the CLA now also
generates a signal when a connection ends.

Signed-off-by: Tobias Nöthlich <tobias.noethlich@d3tn.com>
2022-12-07 20:36:49 +01:00
Felix Walter
00ab1577ab Explicitly check the maximum bundle size (and nothing more) in parsers
For BPv6 we had a "bundle quota" check, which is not present for BPv7
anymore and not possible after the removal of the bundle storage manager.
The AAP parser had an equivalent function, which was, however, not used
by the Application Agent.

A more flexible implementation and a new "bundle quota" check are
tracked by issue #105.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 17:42:21 +01:00
Felix Walter
b0f89aa39d Do not inform BP of successful bundle scheduling
As we do not provide persistent storage, we do not need to inform the
Bundle Processor when a bundle has been scheduled. (This would only be
needed to signal custody acceptance.)

In fact, we were even seeing potential deadlocks resulting from this
circular interaction between the Router Task and the BP.

Fixes: #3

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 17:42:21 +01:00
Felix Walter
d6f3c0ac09 Remove Custody Manager
We do not have persistent storage and, also, we only supported custody
for BPv6. This completely removes the unnecessary logic until we do a
re-implementation based on BIBE.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 17:42:21 +01:00
Felix Walter
6279aa633d Remove Router Optimizer
The "Router Optimizer" was a task that re-ordered bundles according to
the stated priority. As this was only supported for BPv6 and can be
easily exploited by a sender by always stating the highest priority for
their bundles, it is considered unnecessary for future versions of
uD3TN.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 17:42:21 +01:00
Felix Walter
cd959647f8 Remove bundle ID and storage and replace the ID by the bundle pointer
This removes the unnecessary bundle storage manager that was built for
persistent storage but never used for that purpose. We will implement a
proper persistent storage in the new Rust version. For simplifying the
following adaptations this removes everything storage-related and
replaces the used bundle ID by the pointer.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-12-07 17:42:21 +01:00
Felix Walter
d8fef5c776 TCPSPP: Ensure the maximum SPP size is never exceeded
This will abort execution in case the CLA attempts to issue an SPP
packet larger than the maximum SPP size. For this purpose a
configuration parameter is added that may be adapted to the connected
communication subsystem. The router ensures that this should not occur,
but we add an additional safety check as some CCSDS engines may be
placed into an invalid state in case they are confronted with too large
SPP packets, which must not occur in productive environments.

Signed-off-by: Felix Walter <felix.walter@d3tn.com>
2022-11-24 20:28:14 +01:00