Pluggable Transport

APIs related to RTI Connext pluggable transports

Modules

Summary: APIs related to RTI Connext pluggable transports

Overview

RTI Connext has a pluggable transports architecture. The core of RTI Connext is transport agnostic; it does not make any assumptions about the actual transports used to send and receive messages. Instead, the RTI Connext core uses an abstract "transport API" to interact with the transport plugins which implement that API.

A transport plugin implements the abstract transport API and performs the actual work of sending and receiving messages over a physical transport. A collection of builtin plugins (see NDDS_TransportBuiltinsComponent) is delivered with RTI Connext for commonly used transports. New transport plugins can easily be created, thus enabling RTI Connext applications to run over transports that may not even be conceived yet. This is a powerful capability and that distinguishes RTI Connext from competing middleware approaches.

RTI Connext also provides a set of APIs for installing and configuring transport plugins to be used in an application. So that RTI Connext applications work out of the box, a subset of the builtin transport plugins is preconfigured by default (see DDS.TransportBuiltinQosPolicy). You can "turn-off" some or all of the builtin transport plugins. In addition, you can configure other transport plugins for use by the application.

Transport Aliases

In order to use a transport plugin instance in an RTI Connext application, it must be registered with a DDS.DomainParticipant. When you register a transport, you specify a sequence of "alias" strings to symbolically refer to the transport plugin. The same alias strings can be used to register more than one transport plugin.

You can register multiple transport plugins with a DDS.DomainParticipant. An alias symbolically refers to one or more transport plugins registered with the DDS.DomainParticipant. Builtin transport plugin instances can be referred to using preconfigured aliases (see DDSTransportBuiltinQosModule).

A transport plugin's class name is automatically used as an implicit alias. It can be used to refer to all the transport plugin instances of that class.

You can use aliases to refer to transport plugins, in order to specify:

- the transport plugins to use for discovery (see DDS.DiscoveryQosPolicy.enabled_transports), and for DDS.DataWriter and DDS.DataReader entities (see DDS.TransportSelectionQosPolicy).

- the multicast addresses on which to receive discovery messages (see DDS.DiscoveryQosPolicy.multicast_receive_addresses), and the multicast addresses and ports on which to receive user data (see DDS.DataReaderQos.multicast).

- the unicast ports used for user data (see DDS.TransportUnicastQosPolicy) on both DDS.DataWriter and DDS.DataReader entities.

- the transport plugins used to parse an address string in a locator (NDDS_DISCOVERY_PEERS_locator_format and NDDS_DISCOVERY_PEERS).

A DDS.DomainParticipant (and contained its entities) start using a transport plugin after the DDS.DomainParticipant is enabled (see DDS.Entity.enable). An entity will use all the transport plugins that match the specified transport QoS policy. All transport plugins are treated uniformly, regardless of how they were created or registered; there is no notion of some transports being more "special" that others.

Transport Lifecycle

A transport plugin is owned by whomever creates it. Thus, if you create and register a transport plugin with a DDS.DomainParticipant, you are responsible for deleting it by calling its destructor. Note that builtin transport plugins (DDSTransportBuiltinQosModule) and transport plugins that are loaded through the DDSPropertyQosModule QoS policy (see NDDSTransportLoadPluginModule) are automatically managed by dds.

A user-created transport plugin must not be deleted while it is still in use by a DDS.DomainParticipant. This generally means that a user-created transport plugin instance can only be deleted after the DDS.DomainParticipant with which it was registered is deleted (see DDS.DomainParticipantFactory.delete_participant). Note that a transport plugin cannot be "unregistered" from a DDS.DomainParticipant.

A transport plugin instance cannot be registered with more than one DDS.DomainParticipant at a time. This requirement is necessary to guarantee the multi-threaded safety of the transport API.

If the same physical transport resources are to be used with more than one DDS.DomainParticipant in the same address space, the transport plugin should be written in such a way so that it can be instantiated multiple times---once for each DDS.DomainParticipant in the address space. Note that it is always possible to write the transport plugin so that multiple transport plugin instances share the same underlying resources; however the burden (if any) of guaranteeing multi-threaded safety to access shared resource shifts to the transport plugin developer.

Transport Class Attributes

A transport plugin instance is associated with two kinds of attributes:

- the class attributes that are decided by the plugin writer; these are invariant across all instances of the transport plugin class, and

- the instance attributes that can be set on a per instance basis by the transport plugin user.

Every transport plugin must specify the following class attributes.

transport class id (see NDDS_Transport_Property_t.classid)
Identifies a transport plugin implementation class. It denotes a unique "class" to which the transport plugin instance belongs. The class is used to distinguish between different transport plugin implementations. Thus, a transport plugin vendor should ensure that its transport plugin implementation has a unique class.

Two transport plugin instances report the same class iff they have compatible implementations. Transport plugin instances with mismatching classes are not allowed (by the RTI Connext Core) to communicate with one another.

Multiple implementations (possibly from different vendors) for a physical transport mechanism can co-exist in an RTI Connext application, provided they use different transport class IDs.

The class ID can also be used to distinguish between different transport protocols over the same physical transport network (e.g., UDP vs. TCP over the IP routing infrastructure).

transport significant address bit count (see NDDS_Transport_Property_t.address_bit_count)
dds's addressing is modeled after the IPv6 and uses 128-bit addresses ( java.net.InetAddress ) to route messages.

A transport plugin is expected to map the transport's internal addressing scheme to 128-bit addresses. Depending on the sign of this attribute, this mapping uses only N least significant bits (LSB) if positive or N most significant bits (MSB) if negative; these bits are specified by this attribute.

 >-------------- netmask ----------------<
 +---------------------------------------+----------------------------+
 |          Network Address              |   Transport Local Address  |
 +---------------------------------------+----------------------------+
                                         >------------  N ------------<
                                               address_bits_count
  
                                             Only these bits are used
                                             by the transport plugin 
                                             if sign is positive.

                                         >--------- netmask ----------<
 +---------------------------------------+----------------------------+
 |      Transport Local Address          |       Network Address      |
 +---------------------------------------+----------------------------+
 >-----------------  N  -----------------<
            address_bits_count
 
          Only these bits are used
          by the transport plugin 
          if sign is negative.

The remaining bits of an address using the 128 - abs(bit address) representation will be considered as part of the "network address" (see NDDSTransportModule_net_address) and thus ignored by the transport plugin's internal addressing scheme.

For unicast addresses, the transport plugin is expected to ignore the higher (128 - NDDS_Transport_Property_t.address_bit_count) bits. RTI Connext is free to manipulate those bits freely in the addresses passed in/out to the transport plugin APIs.

Theoretically, the significant address bits count, N is related to the size of the underlying transport network as follows: [ address\_bits\_count >= ceil(log_2(total\_addressable\_transport\_unicast\_interfaces)) ] The equality holds when the most compact (theoretical) internal address mapping scheme is used. A practical address mapping scheme may waste some bits.

Transport Instance Attributes

The per instance attributes to configure the plugin instance are generally passed in to the plugin constructor. These are defined by the transport plugin writer, and can be used to:

- customize the behavior of an instance of a transport plugin, including the send and the receiver buffer sizes, the maximum message size, various transport level classes of service (CoS), and so on.

- specify the resource values, network interfaces to use, various transport level policies, and so on.

RTI Connext requires that every transport plugin instance must specify the NDDS_Transport_Property_t.message_size_max and NDDS_Transport_Property_t.gather_send_buffer_count_max.

It is up to the transport plugin developer to make these available for configuration to transport plugin user.

Note that it is important that the instance attributes are "compatible" between the sending side and the receiving side of communicating applications using different instances of a transport plugin class. For example, if one side is configured to send messages larger than can be received by the other side, then communications via the plugin may fail.

Transport Network Address

The address bits not used by the transport plugin for its internal addressing constitute its network address bits.

In order for RTI Connext to properly route the messages, each unicast interface in the RTI Connext domain must have a unique address. RTI Connext allows the user to specify the value of the network address when installing a transport plugin via the NDDSTransportSupport.register_transport() API.

The network address for a transport plugin should be chosen such that the resulting fully qualified 128-bit address will be unique in the RTI Connext domain. Thus, if two instances of a transport plugin are registered with a DDS.DomainParticipant, they will be at different network addresses in order for their unicast interfaces to have unique fully qualified 128-bit addresses. It is also possible to create multiple transports with the same network address, as it can be useful for certain use cases; note that this will require special entity configuration for most transports to avoid clashes in resource use (e.g. sockets for UDPv4 transport).

Transport Send Route

By default, a transport plugin is configured to send outgoing messages destined to addresses in the network address range at which the plugin was registered.

RTI Connext allows the user to configure the routing of outgoing messages via the NDDSTransportSupport.add_send_route() API, so that a transport plugin will be used to send messages only to certain ranges of destination addresses. The procedure can be called multiple times for a transport plugin, with different address ranges.

 
  +--------------------------------------------------------------------+
  |         Outgoing Address Range 1     ->      Transport Plugin      |
  +--------------------------------------------------------------------+
  |              :                       ->              :             |
  +--------------------------------------------------------------------+
  |         Outgoing Address Range K     ->      Transport Plugin      |
  +--------------------------------------------------------------------+

The user can set up a routing table to restrict the use of a transport plugin to send messages to selected addresses ranges.

Transport Receive Route

By default, a transport plugin is configured to receive incoming messages destined to addresses in the network address range at which the plugin was registered.

RTI Connext allows the user to configure the routing of incoming messages via the NDDSTransportSupport.add_receive_route() API, so that a transport plugin will be used to receive messages only on certain ranges of addresses. The procedure can be called multiple times for a transport plugin, with different address ranges.

 
  +--------------------------------------------------------------------+
  |          Transport Plugin            <-  Incoming Address Range 1  |
  +--------------------------------------------------------------------+
  |                 :                    <-           :                |
  +--------------------------------------------------------------------+
  |          Transport Plugin            <-  Incoming Address Range M  |
  +--------------------------------------------------------------------+

The user can set up a routing table to restrict the use of a transport plugin to receive messages from selected ranges. For example, the user may restrict a transport plugin to

- receive messages from a certain multicast address range.

- receive messages only on certain unicast interfaces (when multiple unicast interfaces are available on the transport plugin).