Cross-Vendor / Inter-Distro Interop

Back to overview

The pain

DDS promises interoperability — that is the whole point of a wire standard. In ROS 2 practice it frequently breaks (32 reports):

  • Mixed-RMW fleets don’t talk. A rmw_fastrtps node and a rmw_cyclonedds node on the same topic may not exchange data; services and actions (built on pub/sub) are effectively vendor-locked even when plain pub/sub works.
  • Cross-vendor deserialization mismatches can be worse than a no-match — a malformed cross-RMW request has triggered out-of-memory on the server.
  • Inter-distro is unsupported. A Humble node and an Eloquent/Jazzy node on the same domain often cannot communicate, stranding incremental fleet upgrades.
  • XTypes encoding drift. Even compliant-looking stacks disagree on CDR / XCDR2 encoding details, so type matching silently fails.

Most recent example

rmw_cyclonedds#577 — “Cross-RMW service interoperability: ListParameters request from rmw_cyclonedds_cpp client can be misdeserialized and trigger OOM on rmw_fastrtps_cpp server” (2026-04-02). A cross-vendor service call is not just incompatible — it is mis-deserialized into an allocation that crashes the server. Interop failure as a denial-of-service.

Reference list (most recent)

Date Source Problem
2026-04-02 rmw_cyclonedds#577 Cross-RMW service deserialization → OOM crash
2025-06-12 RTI KB Connext default CDR non-compliant with XTypes 1.3
2025-05-14 ROS Discourse Incompatibility between ROS 2 distributions
2024-09-18 ROS Discourse “DDS design vs reality”: services/actions vendor-locked
2024-08-05 cyclonedds#2062 Cyclone ↔︎ Micro XRCE-DDS comms

How ZeroDDS solves it

Interop is the design center, and it is continuously tested against four vendors.

  • Native RTPS 2.5 on the wire. ZeroDDS is verified interoperable with Cyclone DDS, Fast DDS, OpenDDS and RTI Connext, maintained as a cross-vendor matrix (including a security matrix) — the same places where Fast DDS ↔︎ Cyclone breaks in the field are regression cells for us.
  • Live ROS 2 interop, both directions. rmw_zerodds exchanges data with a real rmw_cyclonedds talker/listener on rt/chatter 20/20 in both directions. The bug that originally blocked this (keyed-vs-keyless entity kind) is fixed by consulting DdsType::HAS_KEY.
  • XCDR1 and XCDR2. ZeroDDS models DataRepresentationQosPolicy and offers both encodings; ros_defaults() offers XCDR1 for ROS writers out of the box, so the “compliant-but-doesn’t-match” encoding drift is handled. ZeroDDS’s XCDR2 alignment was validated byte-for-byte against a cross-vendor capture.
  • Full XTypes 1.3 + DDS-RPC. TypeObject/TypeLookup and assignability are implemented, and the DDS-RPC spec (services) is implemented to the standard — the foundation services/actions need to stop being vendor-locked.
  • Memory-safe parsing. A malformed cross-vendor request cannot be mis-deserialized into an OOM the way rmw_cyclonedds#577 describes: decoding runs in safe Rust with explicit bounds and DoS caps.

Why it no longer has to be a pain

Interop breaks when each vendor’s “compliant” diverges in the encoding and entity-kind details, and when parsers trust the wire. ZeroDDS treats cross-vendor interop as a first-class, continuously-tested requirement (four vendors, both directions) and parses defensively — so a heterogeneous fleet is a supported configuration, not a gamble.

Reproduce it yourself

# rmw_zerodds ↔ real rmw_cyclonedds, bidirectional, on rt/chatter:
crates/ros2-rmw/interop/run_interop.sh

# Cross-vendor, multicast-free:
crates/ros2-rmw/interop/run_multicast_free_xvendor.sh

See also the cross-vendor validation record in ../spec-coverage/cross-vendor-validation.md.

Back to overview · Next: Configuration complexity

Cross-Vendor- / Inter-Distro-Interop

Zurück zur Übersicht

Der Schmerz

DDS verspricht Interoperabilität — das ist der ganze Sinn eines Wire-Standards. In der ROS-2-Praxis bricht es häufig (32 Reports):

  • Mixed-RMW-Flotten reden nicht. Ein rmw_fastrtps-Node und ein rmw_cyclonedds-Node auf demselben Topic tauschen womöglich keine Daten aus; Services und Actions (auf Pub/Sub gebaut) sind effektiv vendor-locked, selbst wenn reines Pub/Sub funktioniert.
  • Cross-Vendor-Deserialisierungs-Mismatches können schlimmer sein als ein No-Match — ein fehlerhafter Cross-RMW-Request hat Out-of-Memory auf dem Server ausgelöst.
  • Inter-Distro wird nicht unterstützt. Ein Humble-Node und ein Eloquent-/Jazzy-Node auf derselben Domain können oft nicht kommunizieren und stranden inkrementelle Flotten-Upgrades.
  • XTypes-Encoding-Drift. Selbst compliant aussehende Stacks sind sich über CDR-/XCDR2-Encoding-Details uneinig, sodass Type-Matching still scheitert.

Jüngstes Beispiel

rmw_cyclonedds#577 — „Cross-RMW service interoperability: ListParameters request from rmw_cyclonedds_cpp client can be misdeserialized and trigger OOM on rmw_fastrtps_cpp server” (2026-04-02). Ein Cross-Vendor-Service-Call ist nicht nur inkompatibel — er wird in eine Allocation fehl-deserialisiert, die den Server crasht. Interop-Fehler als Denial-of-Service.

Referenzliste (jüngste zuerst)

Datum Quelle Problem
2026-04-02 rmw_cyclonedds#577 Cross-RMW-Service-Deserialisierung → OOM-Crash
2025-06-12 RTI KB Connext-Default-CDR nicht konform mit XTypes 1.3
2025-05-14 ROS Discourse Inkompatibilität zwischen ROS-2-Distributionen
2024-09-18 ROS Discourse „DDS-Design vs Realität”: Services/Actions vendor-locked
2024-08-05 cyclonedds#2062 Cyclone ↔︎ Micro XRCE-DDS Comms

Wie ZeroDDS es löst

Interop ist das Design-Zentrum, und es wird kontinuierlich gegen vier Vendoren getestet.

  • Natives RTPS 2.5 auf dem Draht. ZeroDDS ist verifiziert interoperabel mit Cyclone DDS, Fast DDS, OpenDDS und RTI Connext, gepflegt als Cross-Vendor-Matrix (inkl. Security-Matrix) — dieselben Stellen, an denen Fast DDS ↔︎ Cyclone im Feld bricht, sind für uns Regressions-Zellen.
  • Live-ROS-2-Interop, beide Richtungen. rmw_zerodds tauscht Daten mit einem echten rmw_cyclonedds-Talker/Listener auf rt/chatter aus, 20/20 in beide Richtungen. Der Bug, der dies ursprünglich blockierte (Keyed-vs-Keyless-Entity-Kind), ist durch Konsultieren von DdsType::HAS_KEY gefixt.
  • XCDR1 und XCDR2. ZeroDDS modelliert DataRepresentationQosPolicy und bietet beide Encodings; ros_defaults() bietet XCDR1 für ROS-Writer out of the box, sodass der „compliant-but-doesn’t-match”-Encoding-Drift behandelt ist. Das XCDR2-Alignment von ZeroDDS wurde byte-für-byte gegen ein Cross-Vendor-Capture validiert.
  • Volle XTypes 1.3 + DDS-RPC. TypeObject/TypeLookup und Assignability sind implementiert, und die DDS-RPC-Spec (Services) ist standardkonform implementiert — das Fundament, das Services/Actions brauchen, um nicht mehr vendor-locked zu sein.
  • Memory-safe Parsing. Ein fehlerhafter Cross-Vendor-Request kann nicht so in ein OOM fehl-deserialisiert werden, wie rmw_cyclonedds#577 es beschreibt: das Decoding läuft in sicherem Rust mit expliziten Bounds und DoS-Caps.

Warum es kein Schmerz mehr sein muss

Interop bricht, wenn das „compliant” jedes Vendors in den Encoding- und Entity-Kind-Details divergiert, und wenn Parser dem Draht vertrauen. ZeroDDS behandelt Cross-Vendor-Interop als First-Class-Anforderung mit kontinuierlichen Tests (vier Vendoren, beide Richtungen) und parst defensiv — sodass eine heterogene Flotte eine unterstützte Konfiguration ist, kein Glücksspiel.

Selbst reproduzieren

# rmw_zerodds ↔ echtes rmw_cyclonedds, bidirektional, auf rt/chatter:
crates/ros2-rmw/interop/run_interop.sh

# Cross-Vendor, multicast-frei:
crates/ros2-rmw/interop/run_multicast_free_xvendor.sh

Siehe auch den Cross-Vendor-Validierungs-Record in ../spec-coverage/cross-vendor-validation.md.

Zurück zur Übersicht · Weiter: Konfigurations-Komplexität