Skip to main content

Transport Priority QoS Policy

The Transport Priority policy provides a hint to the DDS middleware about the importance of data, which can be used to control network-level prioritization through DSCP (Differentiated Services Code Point) or ToS (Type of Service) IP header fields.

Purpose​

Transport Priority enables traffic differentiation:

  • High-priority data (alarms, commands) gets preferential network treatment
  • Normal data (sensors, status) uses default network handling
  • Low-priority data (logs, diagnostics) yields to other traffic
info

Transport Priority is a hint to the middleware. Actual network prioritization depends on OS socket options (SO_PRIORITY, IP_TOS), NIC capabilities, and network infrastructure (DSCP-aware switches and routers).

Configuration​

use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("priority_app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

// High-priority alarm writer
let alarm_writer = participant
.topic::<Alert>("system/alarms")?
.writer()
.qos(QoS::reliable().transport_priority(10))
.build()?;

// Normal-priority telemetry writer
let telemetry_writer = participant
.topic::<SensorData>("sensors/temperature")?
.writer()
.qos(QoS::best_effort().transport_priority(0))
.build()?;

// Low-priority log writer
let log_writer = participant
.topic::<LogEntry>("system/logs")?
.writer()
.qos(QoS::best_effort().transport_priority_low())
.build()?;
#include <hdds.h>

/* High-priority alarm writer */
struct HddsQoS* qos_alarm = hdds_qos_reliable();
hdds_qos_set_transport_priority(qos_alarm, 10);

struct HddsDataWriter* alarm_writer = hdds_writer_create_with_qos(
participant, "system/alarms", qos_alarm);
hdds_qos_destroy(qos_alarm);

/* Low-priority telemetry writer */
struct HddsQoS* qos_telem = hdds_qos_reliable();
hdds_qos_set_transport_priority(qos_telem, 0);

struct HddsDataWriter* telem_writer = hdds_writer_create_with_qos(
participant, "sensors/temperature", qos_telem);
hdds_qos_destroy(qos_telem);

Default Value​

Default is 0 (normal priority):

let qos = QoS::reliable();
// transport_priority.value = 0 (normal)

Fluent Builder Methods​

MethodDescription
.transport_priority(value)Set custom priority value (higher = more important)
.transport_priority_high()Set high priority (value: 50)
.transport_priority_low()Set low priority (value: -50)
.transport_priority_normal()Set normal priority (value: 0)

Priority Values and DSCP Mapping​

The value field is an integer where higher values indicate more important data. The middleware maps this to network-level priority mechanisms:

Common DSCP Values​

DSCP ValueNameDescription
0Best Effort (BE)Default, no special treatment
10Assured Forwarding 1 (AF11)Low priority assured
18Assured Forwarding 2 (AF21)Medium priority assured
26Assured Forwarding 3 (AF31)Medium-high priority assured
34Assured Forwarding 4 (AF41)High priority assured
46Expedited Forwarding (EF)Low latency, low loss

Priority Queue Diagram​

                    Priority Queues
+------------------+
Alarm (pri=10) -->| HIGH [A][A][A] |---> Network (DSCP EF)
+------------------+
| |
Telemetry (0) -->| LOW [T][T][T] |---> Network (DSCP BE)
+------------------+

Under congestion, high-priority traffic is sent first.
OS and NIC must support traffic classification for full effect.

Compatibility Rules​

Transport Priority does not affect compatibility. Writers and readers always match regardless of their priority settings.

Use Cases​

Emergency Data Prioritization​

use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("safety_system")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

// Emergency stop: highest priority
let e_stop_writer = participant
.topic::<EmergencyStop>("safety/e_stop")?
.writer()
.qos(QoS::reliable().transport_priority(100))
.build()?;

// Normal sensor: default priority
let sensor_writer = participant
.topic::<SensorData>("sensors/data")?
.writer()
.qos(QoS::best_effort().transport_priority(0))
.build()?;

Multi-Tier Traffic Classification​

use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("classified_app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

// Tier 1: Safety-critical (highest)
let safety = participant
.topic::<SafetyData>("safety/data")?
.writer()
.qos(QoS::reliable().transport_priority(100))
.build()?;

// Tier 2: Control commands (high)
let control = participant
.topic::<ControlData>("control/commands")?
.writer()
.qos(QoS::reliable().transport_priority_high())
.build()?;

// Tier 3: Telemetry (normal)
let telemetry = participant
.topic::<SensorData>("sensors/data")?
.writer()
.qos(QoS::best_effort().transport_priority_normal())
.build()?;

// Tier 4: Logging (low)
let logs = participant
.topic::<LogEntry>("system/logs")?
.writer()
.qos(QoS::best_effort().transport_priority_low())
.build()?;

DSCP-Aware Network Integration​

use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("dscp_app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

// Map to DSCP Expedited Forwarding (46)
let ef_writer = participant
.topic::<VoiceData>("voice/stream")?
.writer()
.qos(QoS::best_effort().transport_priority(46))
.build()?;

// Map to DSCP Assured Forwarding (26)
let af_writer = participant
.topic::<VideoData>("video/stream")?
.writer()
.qos(QoS::best_effort().transport_priority(26))
.build()?;

Interaction with Other Policies​

Transport Priority + Reliability​

PriorityReliabilityBehavior
Highreliable()Prioritized packets + guaranteed delivery
Highbest_effort()Prioritized packets, may still be lost
Lowreliable()Lower network priority but delivery guaranteed

Transport Priority + Latency Budget​

Both are transport-layer hints:

PriorityBudgetNet Effect
High0msImmediate send with preferential network handling
High100msMay batch but packets get priority when sent
Low0msImmediate send but lower network priority

OS Configuration for DSCP​

For Transport Priority to have real effect, the operating system must be configured:

Linux​

# Set DSCP marking via tc (traffic control)
tc qdisc add dev eth0 root handle 1: prio

# Or via iptables
iptables -t mangle -A OUTPUT -p udp --dport 7400:7500 \
-m tos --tos 0xB8 -j MARK --set-mark 1

Socket-Level​

The middleware maps the priority value to IP_TOS or SO_PRIORITY socket options:

int tos = 0xB8;  /* DSCP EF (46) << 2 */
setsockopt(sock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));

Common Pitfalls​

  1. No OS/network support: Without DSCP-aware infrastructure, transport priority has no effect on actual delivery. The middleware sets the appropriate socket options, but switches and routers must honor them.

  2. Negative priority values: HDDS supports negative values (e.g., -50 for low()), which map to below-normal handling. Some network stacks may not support negative priorities.

  3. IntraProcess mode: Transport priority has no effect in IntraProcess transport mode since there are no network packets to prioritize.

  4. Root/CAP_NET_ADMIN: On Linux, setting high DSCP values may require elevated privileges (CAP_NET_ADMIN capability).

Performance Notes​

  • Transport Priority adds zero runtime overhead (set once at entity creation)
  • Actual prioritization depends on OS network stack and hardware
  • On QoS-aware networks, priority can significantly reduce latency for critical traffic
  • Without network support, all traffic is treated equally regardless of priority setting

Next Steps​