Skip to content

eclipse-ecal/ecaludp

Repository files navigation

License

Windows Ubuntu macOS

ecaludp

ecaludp is the underlying implementation for UDP traffic in eCAL. It transparently fragments and reassembles messages to provide support for big messages. An ecaludp socket is not limited to the ordinary UDP datagram size of ~64KiB. It can transport messages up to 4 GiB.

ecaludp has npcap support for efficient receiving of multicast traffic in Windows. For that, the udpcap library is used.

ecaludp requires C++14.

Sample Projects

ecalupd features an asio-style API. Check out the following samples to see its usage:

Dependencies

The following dependencies are always required to build ecaludp:

Dependency License Default Integration
asio Boost Software License git submodule
recycle BSD-3 git submodule

Additionally, when building with Npcap, the following dependencies are required:

Dependency License Default Integration
Udpcap Apache 2.0 git submodule
npcap
(SDK only)
Npcap License Fetched by CMake
Pcap++ Unlicense Fetched by CMake

When building the tests, the following dependency is required:

Dependency License Default Integration
Googletest BSD-3 git submodule

How to checkout and build

  1. Install cmake and git / git-for-windows

  2. Checkout this repo and the asio submodule

    git clone https://github.com/eclipse-ecal/ecaludp.git
    cd ecaludp
    git submodule init
    git submodule update
  3. CMake the project (check the next section for available CMake options)

    mkdir _build
    cd _build
    cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=_install
  4. Build the project

    • Linux: make
    • Windows: Open _build\ecaludp.sln with Visual Studio and build the example project
  5. Check the functionality with the udpcap_sample /.exe sample project!

CMake Options

You can set the following CMake Options to control how ecaludp is built:

Option Type Default Explanation
ECALUDP_ENABLE_NPCAP BOOL OFF Enable the NPCAP based socket emulation to receive UDP data without actually opening a socket.
ECALUDP_BUILD_SAMPLES BOOL ON Build the ecaludp sample project.
ECALUDP_BUILD_TESTS BOOL OFF Build the the ecaludp tests. Requires gtest to be available. If ecaludp is built as static or object library, additional tests will be built that test the internal implementation that is not available as public API.
ECALUDP_USE_BUILTIN_ASIO BOOL ON Use the builtin asio submodule. If set to OFF, asio must be available from somewhere else (e.g. system libs).
ECALUDP_USE_BUILTIN_RECYCLE BOOL ON Use the builtin steinwurf::recycle submodule. If set to OFF, recycle must be available from somewhere else (e.g. system libs).
ECALUDP_USE_BUILTIN_UDPCAP BOOL ON
(when building with npcap)
Use the builtin udpcap submodule. Only needed if ECALUDP_ENABLE_NPCAP is ON. If set to OFF, udpcap must be available from somewhere else (e.g. system libs). Setting this option to ON will also use the default dependencies of udpcap (npcap-sdk, pcapplusplus).
ECALUDP_USE_BUILTIN_GTEST BOOL ON
(when building tests)
Use the builtin GoogleTest submodule. Only needed if FINEFTP_SERVER_BUILD_TESTS is ON. If set to OFF, GoogleTest must be available from somewhere else (e.g. system libs).
ECALUDP_LIBRARY_TYPE STRING Controls the library type of Ecaludp by injecting the string into the add_library call. Can be set to STATIC / SHARED / OBJECT. If set, this will override the regular BUILD_SHARED_LIBS CMake option. If not set, CMake will use the default setting, which is controlled by BUILD_SHARED_LIBS.

Protocol Specification (Version 5)

An ecaludp message consists of one or multiple datagrams. How many datagrams that will be is determined by the fragmentation.

Each datagram carries a header starting at byte 0. The header is defined in header_v5.h. Alien datagrams can be eliminated by comparing the magic bytes with a predefined value. Some datagrams may also carry payload directly after the header.

size Name Explanation
32 bit magic User-defined binary data. Used for identifying and dropping alien traffic.
8 bit version Header version. Must be 5 for protocol version 5
24 bit reserved Must be sent as 0.
32 bit
little-endian
type Datagram type. Must be one of:
1: fragmented_message_info
2: fragment
3: non_fragmented_message
32 bit
signed little-endian
id Random ID to match fragmented parts of a message. Used differently depending on the message type:
- type == fragmented_message_info (1): The Random ID that this fragmentation info will be applied to
- type == fragment (2): The Random ID that this fragment belongs to. Used to match fragments to their fragmentation info
- type == non_fragmented_message (3): Unused field. Must be sent as -1. Must not be evaluated.
32 bit
unsigned little-endian
num Fragment number. Used differently depending on the datagram type:
- type == fragmented_message_info (1): Amount of fragments that this message was split into.
- type == fragment (2): The number of this fragment
- type == non_fragmented_message (3): Unused field. Must be sent as 1. Must not be evaluated.
32 bit
unsigned little-endian
len Payload length. Used differently depending on the datagram type. The payload must start directly after the header.
- type == fragmented_message_info (1): Length of the original message before it got fragmented. Messages of this type must not carry any payload themselves.
- type == fragment (2): The payload lenght of this fragment
- type == non_fragmented_message (3): The payload length of this message
len bytes payload Payload of the message or fragment.

Message Types

There are two different types of messages that can be sent: Messages that are fragmented and messages that are not fragmented.

  1. Non-fragmented data

    • The entire message consists of 1 datagram carrying both a header and the payload.
    • The header looks as follows:
      • type is set to non_fragmented_message (3)
      • id is -1
      • num is 1
      • length is the amount of payload bytes following after the header
  2. Fragmented data

    A message which had to be fragmented into $n \in \mathbb{N}_0$ parts consists of $n+1$ datagrams:

    • $1\times$ Fragmentation info

      • The first datagram carries the fragmentation info.
      • The header looks as follows:
        • type is set to fragmented_message_info (1)
        • id is a random number. It is used to match the fragments to their fragmentation info and therefore must be unique for each fragmented message.
        • num is the amount of fragments that the message was split into (i.e. $n$)
        • length is the length of the original message before it got fragmented
      • This datagram must not carry any payload.
    • $n\times$ Fragments

      • The following $n$ datagrams carry the fragments.
      • The header looks as follows:
        • type is set to fragment (2)
        • id is the random number that was used in the fragmentation info
        • num is the number of this fragment (i.e. $1$ to $n$)
        • length is the length of the payload of this fragment.
      • The payload of each fragment is a part of the original message.

Communication diagram

The following diagram shows the communication between the sender and the receiver. The sender sends a non-fragmented message and a fragmented message. The fragmented message consists of n fragments.

  Sender                              Receiver
    |                                    |
    |  Non-fragmented message            |
    |----------------------------------->|
    |                                    |
    |  Fragmentation info (n fragments)  |
    |----------------------------------->|
    |                                    |
    |  Fragment 1                        |
    |----------------------------------->|
    |                                    |
    |  Fragment 2                        |
    |----------------------------------->|
    |                                    |
    |  ...                               |
    |----------------------------------->|
    |                                    |
    |  Fragment (n)                      |
    |----------------------------------->|
    |                                    |
    |                                    |