pub struct SecurityBuiltinStack {
pub stateless_writer: StatelessMessageWriter,
pub stateless_reader: StatelessMessageReader,
pub volatile_writer: VolatileSecureMessageWriter,
pub volatile_reader: VolatileSecureMessageReader,
/* private fields */
}Expand description
Bundle of the four security builtin endpoints.
Fields§
§stateless_writer: StatelessMessageWriterStateless auth writer (Spec §7.4.4).
stateless_reader: StatelessMessageReaderStateless auth reader.
volatile_writer: VolatileSecureMessageWriterVolatile-Secure writer (Spec §7.4.5).
volatile_reader: VolatileSecureMessageReaderVolatile-Secure reader.
Implementations§
Source§impl SecurityBuiltinStack
impl SecurityBuiltinStack
Sourcepub fn new(local_prefix: GuidPrefix, vendor_id: VendorId) -> Self
pub fn new(local_prefix: GuidPrefix, vendor_id: VendorId) -> Self
Creates a fresh stack without remote proxies and without a handshake driver (pure proxy plumbing, backward-compat).
Sourcepub fn with_auth(
local_prefix: GuidPrefix,
vendor_id: VendorId,
auth: Arc<Mutex<dyn AuthenticationPlugin>>,
local_identity: IdentityHandle,
local_guid: [u8; 16],
) -> Self
pub fn with_auth( local_prefix: GuidPrefix, vendor_id: VendorId, auth: Arc<Mutex<dyn AuthenticationPlugin>>, local_identity: IdentityHandle, local_guid: [u8; 16], ) -> Self
Creates a stack WITH a handshake driver (FU2). The auth plugin
is shared via Arc<Mutex> — the same instance must be attached as
the SharedSecretProvider on the crypto plugin (security-runtime
Gap 1), so that the secret returned after Complete is resolvable
there.
local_identity comes from validate_local_identity,
local_guid is the 16-byte participant GUID of this stack.
Sourcepub fn local_prefix(&self) -> GuidPrefix
pub fn local_prefix(&self) -> GuidPrefix
Local GuidPrefix.
Sourcepub fn handle_remote_endpoints(&mut self, peer: &DiscoveredParticipant)
pub fn handle_remote_endpoints(&mut self, peer: &DiscoveredParticipant)
Wires reader/writer proxies based on the BuiltinEndpointSet bits announced by the peer (Spec §7.4.7.1):
- Bits 22+23 (
PARTICIPANT_STATELESS_MESSAGE_*) → stateless slot - Bits 24+25 (
PARTICIPANT_VOLATILE_MESSAGE_SECURE_*) → volatile slot
We route over metatraffic_unicast_locator (PID 0x0032),
falling back to default_unicast_locator. Self-discovery
(peer.sender_prefix == self.local_prefix) is ignored.
Sourcepub fn on_participant_lost(&mut self, prefix: GuidPrefix) -> (usize, usize)
pub fn on_participant_lost(&mut self, prefix: GuidPrefix) -> (usize, usize)
Cleanup after an SPDP lease timeout: removes all proxies of this
prefix. Returns (stateless_pairs_removed, volatile_pairs_removed).
Sourcepub fn poll(
&mut self,
now: Duration,
) -> Result<Vec<OutboundDatagram>, WireError>
pub fn poll( &mut self, now: Duration, ) -> Result<Vec<OutboundDatagram>, WireError>
Tick over all endpoints. Returns HEARTBEATs/resends from the volatile writer plus ACKNACK/NACK_FRAG from the volatile reader. Stateless has no tick (BestEffort, no resend state).
§Errors
Wire encode errors from the reliable layer.
Sourcepub fn peer_secret(
&self,
remote_prefix: GuidPrefix,
) -> Option<SharedSecretHandle>
pub fn peer_secret( &self, remote_prefix: GuidPrefix, ) -> Option<SharedSecretHandle>
Returns the SharedSecretHandle of a peer once the handshake is
complete on this side (otherwise None). FU2: lets the DCPS layer
(and tests) check whether a peer has been authenticated.
Sourcepub fn completed_peer_prefixes(&self) -> Vec<GuidPrefix>
pub fn completed_peer_prefixes(&self) -> Vec<GuidPrefix>
All peers whose handshake is complete on this side (secret set).
Lets the DCPS tick send per-endpoint crypto tokens to every
authenticated peer as soon as the local user endpoints exist (FU2
step 6b — the handshake completes before the benchmark creates the
user endpoints).
Sourcepub fn note_remote_vendor(
&mut self,
remote_prefix: GuidPrefix,
vendor: VendorId,
)
pub fn note_remote_vendor( &mut self, remote_prefix: GuidPrefix, vendor: VendorId, )
FU2 handshake driver: starts the auth handshake with a freshly
discovered peer (Spec §8.3.2). Called from the SPDP hot path after
handle_remote_endpoints as soon as the peer’s
PID_IDENTITY_TOKEN is available.
Validates the remote identity, determines the role via GUID
comparison (SMALLER local GUID = initiator) and — if initiator —
sends the AUTH_REQUEST over the stateless writer. The replier
only creates its peer state and waits for the request.
Without a configured auth plugin (new instead of with_auth)
this is a no-op (empty datagram list).
The initiator convention (smaller local GUID ⇒ initiator) is cyclone-verified (c2c handshake FSM trace: the smaller GUID sends the request, the larger one replies). Both sides MUST choose the same direction, otherwise neither/both initiate.
Records the VendorId of a remote participant (from the SPDP RTPS
header) for vendor-specific handshake quirks (e.g. OpenDDS’
NUL-terminated algorithm strings). Should be set BEFORE
Self::begin_handshake_with/Self::on_stateless_message;
if it is not, the NUL-free spec/FastDDS/Cyclone default applies.
Sourcepub fn begin_handshake_with(
&mut self,
remote_prefix: GuidPrefix,
remote_guid: [u8; 16],
remote_identity_token: &[u8],
) -> SecurityResult<Vec<OutboundDatagram>>
pub fn begin_handshake_with( &mut self, remote_prefix: GuidPrefix, remote_guid: [u8; 16], remote_identity_token: &[u8], ) -> SecurityResult<Vec<OutboundDatagram>>
§Errors
SecurityError on failed remote identity validation or wire
encode of the request token.
Sourcepub fn handshake_peer_count(&self) -> usize
pub fn handshake_peer_count(&self) -> usize
Number of remote peers with established handshake state (initiator as well as replier). Read-only observability for the discovery trigger.
Sourcepub fn on_stateless_message(
&mut self,
remote_prefix: GuidPrefix,
msg: &ParticipantGenericMessage,
) -> SecurityResult<HandshakeStepResult>
pub fn on_stateless_message( &mut self, remote_prefix: GuidPrefix, msg: &ParticipantGenericMessage, ) -> SecurityResult<HandshakeStepResult>
FU2 handshake driver: processes an incoming stateless auth
message (Spec §8.3.2). Dispatch by message_class_id:
AUTH_REQUEST(replier side) →begin_handshake_reply, sends the reply token back.- otherwise (
AUTH= reply at the initiator / final at the replier) →process_handshake; aSendMessageoutcome (initiator: final token) is sent.
Returns (outbound_datagrams, Option<(remote_identity, shared_secret)>). The secret tuple is Some as soon as the
handshake derives the SharedSecret on this side (initiator after
reply processing, replier on Complete). The DCPS caller passes
it on to gate.register_remote_with_token —
important: the auth lock held here is already released at
return time (the crypto SharedSecretProvider takes the same
mutex), otherwise deadlock.
Without a configured auth plugin, a no-op.
§Errors
SecurityError from the plugin step or wire encode of the response.