1.4.1. Customizing Network Transports

1.4.1.1. Background

Note

This documentation assumes basic knowledge of UDP/TCP/IP concepts. However, it is possible to follow it without this knowledge.

Vulcanexus applications, by default, enable two different transports: a UDPv4 transport for inter-host communication, and a shared memory transport (SHM) for inter-process communications with other applications running on the same host. Although the default-enabled transports may be suited for most use-cases, they do not intend to cover the entire spectrum of Vulcanexus deployments. Among the many use-cases that may benefit from a custom transport layer, there are:

  1. Applications communicating over IPv6 networks.

  2. NAT traversing communications over TCP (see Vulcanexus Cloud).

  3. No-network deployments.

  4. Communications enabling TLS.

  5. Limiting Vulcanexus traffic to a subset of the host’s network interfaces.

  6. Limiting IP fragmentation (specially relevant for reliable data delivery over lossy networks).

For these reasons, Vulcanexus allows for the configuration of network and SHM transports leveraging Fast DDS capabilities to configure the middleware’s transport layer. This is achieved by defining the appropriate transport description in a Fast DDS XML configuration file.

This tutorial showcases a configuration in which the Vulcanexus communication is limited to a single network interface (localhost) while avoiding Vulcanexus-sent UDP datagrams to be fragmented at the IP level. This is achieved by setting an interface whitelist, and by limiting the size of the Vulcanexus RTPS (the underlying DDS wire-protocol) datagrams so that complete UDP packets fit into the system’s MTU (typically 1500 B).

The latter is specially beneficial to achieve reliable communication over DDS (through a UDPv4 network transport) when communicating over a lossy network. This is because, although the underlying RTPS protocol can be configured as reliable, UDPv4 is a best-effort protocol over IP (another best-effort protocol), and as such is susceptible to network losses. If the RTPS datagrams (which become payloads of UDPv4 datagrams) have the maximum allowed size for a UDP payload (~65 kiB), then the resulting packet would need to be fragmented into 44 fragments (assuming an 1500 B MTU). In this scenario, losing one of those 44 fragments entails losing the entire UDP datagram, and consequently the entire RTPS datagram. If the network’s packet drop rate is 1/44 or higher, no UDP datagram will ever be reconstructed, resulting in no RTPS datagram ever received, and therefore the RTPS reliability cannot succeed at all. By fragmenting the DDS data into several self-contained, smaller-than-the-MTU UDP datagrams, 43 out of every 44 RTPS fragments will be received at first try (in the considered scenario), and the RTPS reliability will be able to retransmit the missing ones successfully.

1.4.1.2. Prerequisites

Please, remember to source the environment in every terminal used during this tutorial.

source /opt/vulcanexus/iron/setup.bash

Install the ROS 2 image demo package (administrative privileges may be required):

apt update && apt install -y ros-iron-image-tools

1.4.1.3. XML Configuration

Save the following XML configuration file at the desired location, which will be referred as <path_to_xml_config_file> from here onwards.

<?xml version="1.0" encoding="UTF-8" ?>
<dds>
    <profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles" >
        <transport_descriptors>
            <!-- Create a custom transport descriptor -->
            <transport_descriptor>
                <transport_id>custom_udpv4_transport</transport_id>
                <type>UDPv4</type>
                <!-- Limit the RTPS datagrams to 1400 B -->
                <maxMessageSize>1400</maxMessageSize>
                <!-- Limit communication to localhost -->
                <interfaceWhiteList>
                    <address>127.0.0.1</address>
                </interfaceWhiteList>
            </transport_descriptor>
        </transport_descriptors>
        <participant profile_name="participant_profile" is_default_profile="true">
            <rtps>
                <!-- Disable builtin transports -->
                <useBuiltinTransports>false</useBuiltinTransports>
                <!-- Enable custom transport -->
                <userTransports>
                    <transport_id>custom_udpv4_transport</transport_id>
                </userTransports>
            </rtps>
        </participant>
    </profiles>
</dds>

1.4.1.4. Run the example

Note

To run this example using a Vulcanexus docker container, GUI capabilities are required (see Docker installation).

This tutorial leverages the ros-iron-image-tools package to demonstrate that the aforementioned XML configuration indeed achieves communication over localhost with UDPv4 datagrams smaller than the standard 1500 B MTU. To run the tutorial, two shells are required:

source /opt/vulcanexus/iron/setup.bash
export FASTRTPS_DEFAULT_PROFILES_FILE=<path_to_xml_config_file>
ros2 run image_tools showimage

Optionally, as shown in the following video, it is possible to use Wireshark to sniff the RTPS traffic across the localhost interface to corroborate the size of the UDP datagrams containing RTPS fragments: