Überblick
DDSI-RTPS 2.5 §8.3 spezifiziert das Wire-Format als transport-agnostisch. Jedes Submessage-Octet-Layout ist gleich, egal ob's über UDP, TCP, Shared-Memory oder Unix-Domain-Sockets läuft. ZeroDDS unterstützt fünf konkrete Backends, jeweils als eigener Crate:
- UDP — Default, Multicast-Discovery + Unicast-Datagram. Internet-ready.
- TCP — Stream-Backend mit Length-Framing + Handshake; NAT-Traversal-fähig.
- Shared-Memory — In-Box-Pfad ohne Kernel-Round-Trip; nur Same-Host.
- Unix-Domain-Sockets — Container-Sidecar-Pattern; Datagram-Mode.
- TSN — Time-Sensitive-Networking; DSCP + Frame-Pre-emption für Hard-Realtime.
Alle fünf implementieren das gleiche Transport-Trait; die DCPS-Runtime wählt zur Laufzeit pro Locator den passenden Backend.
Transport-Matrix
Welche Backend für welchen Use-Case. Default-MTU bezieht sich auf das Wire-Datagram (nicht inkl. RTPS-Header).
| Backend |
Crate |
Locator-Kind |
Default-MTU |
Multicast? |
Plattform |
Anwendungsfall |
UDP |
transport-udp |
UDPv4 / UDPv6 |
65 507 B (UDP-Payload-Limit) |
✓ (IGMP / MLD) |
Linux · macOS · Windows · *BSD |
Default; LAN/WAN; SPDP-Multicast |
TCP |
transport-tcp |
TCPv4 / TCPv6 |
unbegrenzt (Stream) |
— |
Linux · macOS · Windows · *BSD |
NAT-Traversal, Firewall-friendly |
SHM |
transport-shm |
SHMEM |
konfigurierbar (Default 4 MB Segment) |
— |
POSIX (Linux · macOS · *BSD) |
In-Box-IPC ohne Kernel-Roundtrip |
UDS |
transport-uds |
UDS (filesystem path) |
kernel-default (Linux ~212 KB) |
— |
Linux · macOS · *BSD |
Container-Sidecar, /run/zerodds/ |
TSN |
transport-tsn |
UDPv4 + DSCP-Tag |
kernel-default (1500 B mit Pre-emption) |
✓ |
Linux (kernel ≥5.10 mit etf/taprio) |
Hard-Realtime mit Bandwidth-Reservation |
Das Transport-Trait
Alle fünf Backends implementieren die gleiche minimale Surface aus crates/transport/src/lib.rs:
pub trait Transport {
fn send(&self, dest: &Locator, data: &[u8]) -> Result<(), SendError>;
fn recv(&self) -> Result<ReceivedDatagram, RecvError>;
fn local_locator(&self) -> Locator;
}
▶ Runnable example: rust-transport-trait
Locator ist DDSI-RTPS 2.5 §8.3.2 (16-Byte Address + 4-Byte Port + 4-Byte Kind). SendError klassifiziert PayloadTooLarge, UnsupportedLocator und Io. RecvError liefert Timeout oder Io.
Die DCPS-Runtime hält eine Transport-Registry und routet pro Locator zum passenden Backend. Anwender konfigurieren die Liste der aktiven Backends per RuntimeConfig::transports (siehe Multi-Transport-Failover-Rezept).
UDP
UDP — Default-Backend DDSI-RTPS 2.5 §8.3.2 LocatorKind UDPv4=1 / UDPv6=2
Crate: zerodds-transport-udp · Builder in udp_transport.rs::UdpTransport
Tuning-Knobs:
UdpTransport::bind(local_addr) — Local-Bind, IPv4 oder IPv6.
.with_timeout(Some(Duration)) — Recv-Timeout (None = blocking).
.set_multicast_ttl(u32) — TTL für Multicast-Pakete (Default 1 = LAN-only).
- Send/Recv-Buffer: per OS-Kernel-Default. Tuning via
sysctl net.core.{rmem,wmem}_default (Linux); für Hochfrequenz auf 8-16 MB hochsetzen.
- SO_REUSEADDR / SO_REUSEPORT: automatisch für Multicast-Sockets gesetzt.
Discovery-Default: SPDP nutzt Multicast-Group 239.255.0.1 Port 7400 + 250*domain_id (DDSI-RTPS §9.6.1.4). Für Cross-Subnet-Setups: Multicast-Routing oder Static-Peers (siehe Cookbook).
MTU-Edge-Cases: Bei Payloads >65 507 B (UDP-Limit) triggert der RTPS-Stack DATA_FRAG-Fragmentation (DDSI-RTPS §8.3.7.5). Konfig dafür in zerodds-rtps, nicht hier.
TCP
TCP — Stream-Backend DDSI-RTPS 2.5 §8.3.2 LocatorKind TCPv4=4 / TCPv6=8
Crate: zerodds-transport-tcp · Length-Framing in framing.rs · TCP-Handshake in handshake.rs
Tuning-Knobs:
TcpTransport::listen(local_addr) — Server-Mode; bind+listen.
TcpTransport::connect(remote_addr) — Client-Mode.
- Length-Framing: 4-Byte BE-Length-Prefix vor jedem RTPS-Datagram. Konfigurierbares Max via
framing::MAX_DATAGRAM_SIZE (Default 64 MB) — schützt vor OOM bei kompromittiertem Peer.
- TCP-Handshake: 16-Byte Magic + 4-Byte Vendor-ID + 4-Byte Version (DDSI-RTPS-TCP-PSM §10).
- TCP_NODELAY: per Default an (kleines RTPS-Frames; kein Nagle).
- SO_KEEPALIVE: ja, mit Default 30 s.
NAT-Traversal: TCP eignet sich für Setups, in denen UDP-Multicast nicht erreichbar ist (Cloud-Cross-Region, Firewall-restricted Office-Setups). Voraussetzung: ein bekannter Static-Peer + offener TCP-Port; SPDP läuft dann via TCP-Unicast statt Multicast.
Limitierung: kein nativer Multicast — Discovery muss über Static-Peers oder Discovery-Service laufen.
Shared-Memory
SHM — In-Box-IPC DDSI-RTPS 2.5 §8.3.2 LocatorKind SHMEM=16 (Vendor-Extension)
Crate: zerodds-transport-shm · POSIX-Backend in posix.rs
Tuning-Knobs:
ShmTransport::new(segment_name, size) — Segment-Name (POSIX shm_open) und Größe (Default 4 MB).
- Segment-Layout: Lock-free SPSC-Ring-Buffer pro Reader-Writer-Paar; Slot-Größe konfigurierbar.
- Zero-Copy: RTPS-Submessages werden direkt in den Ring geschrieben; Reader mmap-liest ohne
memcpy.
- Garbage-Collection: Wenn ein Reader/Writer abstirbt, räumt der nächste
send()/recv() den Slot auf (Best-Effort).
- Permissions:
shm_open mit O_CREAT | 0644; gemeinsame Group-ID erforderlich für Cross-User-Setups.
Plattform: POSIX (Linux/macOS/*BSD). Windows-Support über CreateFileMapping ist Roadmap.
Limitierung: Same-Host nur. Cross-Host fällt automatisch auf UDP zurück (wenn beide aktiv).
Unix-Domain-Sockets
UDS — Filesystem-Sockets DDSI-RTPS 2.5 §8.3.2 LocatorKind UDS=24 (Vendor-Extension)
Crate: zerodds-transport-uds · Datagram-Mode in abstract_dgram.rs
Tuning-Knobs:
UdsTransport::bind(path) — Filesystem-Path (z.B. /run/zerodds/agent.sock) oder Linux-Abstract-Namespace (@zerodds-agent).
- Datagram-Mode (SOCK_DGRAM): ein
send() = ein RTPS-Submessage. Kein Framing-Overhead.
- Permissions: Über Filesystem (umask, ACL, SELinux). Für Container-Sidecar typisch
0660 + gemeinsame Group-ID.
- MTU: Kernel-Default ~212 KB (Linux); konfigurierbar via
sysctl net.core.wmem_max.
Use-Case: Container-Sidecar (App-Container ⇄ DDS-Sidecar im selben Pod), Service-Mesh-Local-Bus, oder als Sicherheits-Anker (keine Network-Exposure).
TSN
TSN — Time-Sensitive-Networking OMG DDS-TSN 1.0 + IEEE 802.1Qbu/Qbv
Crate: zerodds-transport-tsn · Config-Loader (DDS-TSN XML/JSON-PSM) in config.rs · Frame-Builder in data_frame.rs · DSCP-Mapping in dscp.rs
Tuning-Knobs:
- DSCP-Tag: Pro Topic-/Stream-ID ein DSCP-Wert (siehe IEEE 802.1Qbv-Time-Aware-Shaper). Konfig über DDS-TSN-PIM (XML/JSON).
- Frame-Pre-emption (IEEE 802.1Qbu): Express-Traffic kann den preemptable Best-Effort-Traffic unterbrechen; Tagging im DSCP-Byte.
- etf/taprio (Linux qdisc): Kernel-Side Time-Triggered-Transmission; ZeroDDS-TSN-Stack rendert die qdisc-Konfig aus der PIM-Beschreibung.
- YAML/XML/JSON-Loader:
parse_xml_config / parse_json_config in config.rs — folgt DDS-TSN 1.0 §7.3.
Plattform: Linux Kernel ≥5.10 mit aktivierten NETIF_F_HW_TX_TIMESTAMP + SO_TXTIME. NICs: Intel i210/i225, Marvell Octeon — siehe Deployment-Topologies.
Spec-Coverage: DDS-TSN 1.0 Spec-Coverage →