-
Notifications
You must be signed in to change notification settings - Fork 860
Description
Is there an already existing issue for this?
- I have searched the existing issues
Expected behavior
While the authentication fails, the related timer can be cancelled correctly.
Current behavior
While authentication fails, the previously canceled timer can activate.
Steps to reproduce
This issue was discovered in an environment using DDS-Router and Humble. Since the version of FastDDS used in Humble is no longer maintained, I compared code with the latest code of FastDDS and I think the problem likely still exists.
So, I’ll describe the scenario in which the issue occurs.
The timer handle is
Fast-DDS/src/cpp/rtps/security/SecurityManager.cpp
Lines 647 to 653 in 5c091a3
remote_participant_info->event_.reset(new TimedEvent(participant_->getEventResource(), | |
[&, guid]() -> bool | |
{ | |
resend_handshake_message_token(guid); | |
return true; | |
}, | |
static_cast<double>(auth_handshake_props_.initial_handshake_resend_period_ms_))); |
Note: The callback always returns True.
The code that calls the callback is as follows:
Fast-DDS/src/cpp/rtps/resources/TimedEventImpl.cpp
Lines 85 to 108 in 5c091a3
void TimedEventImpl::trigger( | |
std::chrono::steady_clock::time_point current_time, | |
std::chrono::steady_clock::time_point cancel_time) | |
{ | |
if (callback_) | |
{ | |
StateCode expected = StateCode::WAITING; | |
if (state_.compare_exchange_strong(expected, StateCode::INACTIVE)) | |
{ | |
//Exec | |
bool restart = callback_(); | |
if (restart) | |
{ | |
expected = StateCode::INACTIVE; | |
if (state_.compare_exchange_strong(expected, StateCode::WAITING)) | |
{ | |
next_trigger_time_ = current_time + interval_microsec_.load(); | |
return; | |
} | |
} | |
} | |
Before entering the callback function, the status of the time event has already been set to INACTIVE.
In callback, it will call remote_participant_info->event_->cancel_timer();
Fast-DDS/src/cpp/rtps/security/SecurityManager.cpp
Lines 4244 to 4256 in 5c091a3
if (remote_participant_info->auth_status_ != AUTHENTICATION_FAILED) | |
{ | |
SecurityException exception; | |
remote_participant_info->event_->cancel_timer(); | |
remote_participant_info->auth_status_ = AUTHENTICATION_FAILED; | |
on_validation_failed(dp_it->second->participant_data(), exception); | |
if (remote_participant_info->change_sequence_number_ != SequenceNumber_t::unknown()) | |
{ | |
participant_stateless_message_writer_history_->remove_change( | |
remote_participant_info->change_sequence_number_); | |
remote_participant_info->change_sequence_number_ = SequenceNumber_t::unknown(); | |
} | |
} |
Since the time event's status is already INACTIVE at this point, calling cancel_timer() returns false and effectively does nothing.
Since the callback always returns true, the timer will be set with the next trigger time.
Fast-DDS/src/cpp/rtps/resources/TimedEventImpl.cpp
Lines 96 to 106 in 5c091a3
bool restart = callback_(); | |
if (restart) | |
{ | |
expected = StateCode::INACTIVE; | |
if (state_.compare_exchange_strong(expected, StateCode::WAITING)) | |
{ | |
next_trigger_time_ = current_time + interval_microsec_.load(); | |
return; | |
} | |
} |
So the timer is not canceled, and as a result, the timer event will keep getting triggered.
Fast DDS version/commit
v3.3.0
Platform/Architecture
Other. Please specify in Additional context section.
Transport layer
Default configuration, UDPv4 & SHM
Additional context
Platform: Ubuntu 24.04 (x86_64)
XML configuration file
Relevant log output
Network traffic capture
No response