Skip to content

In secuirty mode, when the authentication fails, the cancel timer does not work. #5936

@Barry-Xu-2018

Description

@Barry-Xu-2018

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

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:

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();

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.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageIssue pending classification

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions