diff --git a/include/fastdds/dds/domain/DomainParticipant.hpp b/include/fastdds/dds/domain/DomainParticipant.hpp index f7078f2a2df..f140fc65b81 100644 --- a/include/fastdds/dds/domain/DomainParticipant.hpp +++ b/include/fastdds/dds/domain/DomainParticipant.hpp @@ -426,9 +426,7 @@ class DomainParticipant : public Entity * @note This action is not reversible. * * @param handle Identifier of the remote participant to ignore - * @return RETURN_OK code if everything correct, error code otherwise - * - * @warning Not supported yet. Currently returns RETCODE_UNSUPPORTED + * @return RETURN_OK code if everything correct, RETCODE_BAD_PARAMENTER otherwise * */ RTPS_DllAPI ReturnCode_t ignore_participant( diff --git a/include/fastdds/dds/domain/DomainParticipantListener.hpp b/include/fastdds/dds/domain/DomainParticipantListener.hpp index 5a05d8019da..18534edeef4 100644 --- a/include/fastdds/dds/domain/DomainParticipantListener.hpp +++ b/include/fastdds/dds/domain/DomainParticipantListener.hpp @@ -91,9 +91,8 @@ class DomainParticipantListener : fastrtps::rtps::ParticipantDiscoveryInfo&& info, bool& should_be_ignored) { - static_cast(participant); - static_cast(info); - static_cast(should_be_ignored); + on_participant_discovery(participant, std::move(info)); + should_be_ignored = false; } #if HAVE_SECURITY diff --git a/include/fastdds/rtps/messages/MessageReceiver.h b/include/fastdds/rtps/messages/MessageReceiver.h index 508f2f5cdce..51e25742a1e 100644 --- a/include/fastdds/rtps/messages/MessageReceiver.h +++ b/include/fastdds/rtps/messages/MessageReceiver.h @@ -157,6 +157,7 @@ class MessageReceiver * -Return an error if the message is malformed. * @param[in,out] msg Pointer to the message * @param[in] smh Pointer to the submessage header + * @param[out] WriterID Writer EntityID (only for DATA messages) * @return True if correct, false otherwise */ @@ -165,11 +166,13 @@ class MessageReceiver * * @param msg * @param smh + * @param writerID * @return */ bool proc_Submsg_Data( CDRMessage_t* msg, - SubmessageHeader_t* smh) const; + SubmessageHeader_t* smh, + EntityId_t& writerID) const; bool proc_Submsg_DataFrag( CDRMessage_t* msg, SubmessageHeader_t* smh) const; diff --git a/include/fastdds/rtps/participant/RTPSParticipantListener.h b/include/fastdds/rtps/participant/RTPSParticipantListener.h index 69e869a332e..deb8f7234ee 100644 --- a/include/fastdds/rtps/participant/RTPSParticipantListener.h +++ b/include/fastdds/rtps/participant/RTPSParticipantListener.h @@ -78,9 +78,8 @@ class RTPS_DllAPI RTPSParticipantListener ParticipantDiscoveryInfo&& info, bool& should_be_ignored) { - static_cast(participant); - static_cast(info); - static_cast(should_be_ignored); + onParticipantDiscovery(participant, std::move(info)); + should_be_ignored = false; } #if HAVE_SECURITY diff --git a/src/cpp/fastdds/domain/DomainParticipant.cpp b/src/cpp/fastdds/domain/DomainParticipant.cpp index c293025dae5..693380368af 100644 --- a/src/cpp/fastdds/domain/DomainParticipant.cpp +++ b/src/cpp/fastdds/domain/DomainParticipant.cpp @@ -271,8 +271,7 @@ const Subscriber* DomainParticipant::get_builtin_subscriber() const ReturnCode_t DomainParticipant::ignore_participant( const InstanceHandle_t& handle) { - static_cast (handle); - return ReturnCode_t::RETCODE_UNSUPPORTED; + return impl_->ignore_participant(handle); } ReturnCode_t DomainParticipant::ignore_topic( diff --git a/src/cpp/fastdds/domain/DomainParticipantImpl.cpp b/src/cpp/fastdds/domain/DomainParticipantImpl.cpp index aac79811f11..a457b20e595 100644 --- a/src/cpp/fastdds/domain/DomainParticipantImpl.cpp +++ b/src/cpp/fastdds/domain/DomainParticipantImpl.cpp @@ -17,7 +17,10 @@ * */ +#include "fastdds/rtps/common/Guid.h" +#include "fastdds/rtps/common/GuidPrefix_t.hpp" #include +#include #include #include @@ -827,12 +830,12 @@ PublisherImpl* DomainParticipantImpl::create_publisher_impl( } */ -bool DomainParticipantImpl::ignore_participant( +ReturnCode_t DomainParticipantImpl::ignore_participant( const InstanceHandle_t& handle) { - static_cast(handle); - EPROSIMA_LOG_ERROR(PARTICIPANT, "Not implemented."); - return false; + return (nullptr == rtps_participant_) ? ReturnCode_t::RETCODE_NOT_ENABLED : + rtps_participant_->ignore_participant(iHandle2GUID(handle).guidPrefix) ? ReturnCode_t::RETCODE_OK : + ReturnCode_t::RETCODE_BAD_PARAMETER; } /* TODO @@ -1528,12 +1531,14 @@ ReturnCode_t DomainParticipantImpl::unregister_type( void DomainParticipantImpl::MyRTPSParticipantListener::onParticipantDiscovery( RTPSParticipant*, - ParticipantDiscoveryInfo&& info) + ParticipantDiscoveryInfo&& info, + bool& should_be_ignored) { Sentry sentinel(this); if (sentinel) { - participant_->listener_->on_participant_discovery(participant_->participant_, std::move(info)); + participant_->listener_->on_participant_discovery(participant_->participant_, std::move(info), + should_be_ignored); } } diff --git a/src/cpp/fastdds/domain/DomainParticipantImpl.hpp b/src/cpp/fastdds/domain/DomainParticipantImpl.hpp index 6a6ac87c26d..d93792c241d 100644 --- a/src/cpp/fastdds/domain/DomainParticipantImpl.hpp +++ b/src/cpp/fastdds/domain/DomainParticipantImpl.hpp @@ -332,9 +332,12 @@ class DomainParticipantImpl * @brief Locally ignore a remote domain participant. * * @param[in] handle Identifier of the remote participant to ignore. - * @return true if correctly ignored. False otherwise. + * @return RETCODE_NOT_ENABLED if the participant is not enabled. + * RETCODE_ERROR if unable to ignore. + * RETCODE_OK if successful. + * */ - bool ignore_participant( + ReturnCode_t ignore_participant( const InstanceHandle_t& handle); /* TODO @@ -658,7 +661,8 @@ class DomainParticipantImpl void onParticipantDiscovery( fastrtps::rtps::RTPSParticipant* participant, - fastrtps::rtps::ParticipantDiscoveryInfo&& info) override; + fastrtps::rtps::ParticipantDiscoveryInfo&& info, + bool& should_be_ignored) override; #if HAVE_SECURITY void onParticipantAuthentication( diff --git a/src/cpp/rtps/builtin/discovery/participant/PDP.cpp b/src/cpp/rtps/builtin/discovery/participant/PDP.cpp index 577ee918dd8..c7bf9d7c733 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDP.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDP.cpp @@ -1060,7 +1060,9 @@ bool PDP::remove_remote_participant( std::lock_guard lock(callback_mtx_); ParticipantDiscoveryInfo info(*pdata); info.status = reason; - listener->onParticipantDiscovery(mp_RTPSParticipant->getUserRTPSParticipant(), std::move(info)); + bool should_be_ignored = false; + listener->onParticipantDiscovery(mp_RTPSParticipant->getUserRTPSParticipant(), std::move( + info), should_be_ignored); } this->mp_mutex->lock(); diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPListener.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPListener.cpp index af20b93f739..f56f3b1d042 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPListener.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPListener.cpp @@ -109,6 +109,11 @@ void PDPListener::onNewCacheChangeAdded( change->instanceHandle = temp_participant_data_.m_key; guid = temp_participant_data_.m_guid; + if (parent_pdp_->getRTPSParticipant()->is_participant_ignored(guid.guidPrefix)) + { + return; + } + // Filter locators const auto& pattr = parent_pdp_->getRTPSParticipant()->getAttributes(); fastdds::rtps::ExternalLocatorsProcessor::filter_remote_locators(temp_participant_data_, @@ -147,13 +152,23 @@ void PDPListener::onNewCacheChangeAdded( RTPSParticipantListener* listener = parent_pdp_->getRTPSParticipant()->getListener(); if (listener != nullptr) { - std::lock_guard cb_lock(parent_pdp_->callback_mtx_); - ParticipantDiscoveryInfo info(*pdata); - info.status = status; + bool should_be_ignored = false; + { + std::lock_guard cb_lock(parent_pdp_->callback_mtx_); + ParticipantDiscoveryInfo info(*pdata); + info.status = status; + + + listener->onParticipantDiscovery( + parent_pdp_->getRTPSParticipant()->getUserRTPSParticipant(), + std::move(info), + should_be_ignored); + } + if (should_be_ignored) + { + parent_pdp_->getRTPSParticipant()->ignore_participant(guid.guidPrefix); + } - listener->onParticipantDiscovery( - parent_pdp_->getRTPSParticipant()->getUserRTPSParticipant(), - std::move(info)); } // Assigning remote endpoints implies sending a DATA(p) to all matched and fixed readers, since @@ -190,13 +205,22 @@ void PDPListener::onNewCacheChangeAdded( RTPSParticipantListener* listener = parent_pdp_->getRTPSParticipant()->getListener(); if (listener != nullptr) { - std::lock_guard cb_lock(parent_pdp_->callback_mtx_); - ParticipantDiscoveryInfo info(*pdata); - info.status = status; + bool should_be_ignored = false; + + { + std::lock_guard cb_lock(parent_pdp_->callback_mtx_); + ParticipantDiscoveryInfo info(*pdata); + info.status = status; - listener->onParticipantDiscovery( - parent_pdp_->getRTPSParticipant()->getUserRTPSParticipant(), - std::move(info)); + listener->onParticipantDiscovery( + parent_pdp_->getRTPSParticipant()->getUserRTPSParticipant(), + std::move(info), + should_be_ignored); + } + if (should_be_ignored) + { + parent_pdp_->getRTPSParticipant()->ignore_participant(temp_participant_data_.m_guid.guidPrefix); + } } } diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPServerListener.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPServerListener.cpp index ff0082a80d7..fd83df39863 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPServerListener.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPServerListener.cpp @@ -142,6 +142,11 @@ void PDPServerListener::onNewCacheChangeAdded( pdp_server()->getRTPSParticipant()->network_factory(), pdp_server()->getRTPSParticipant()->has_shm_transport())) { + if (parent_pdp_->getRTPSParticipant()->is_participant_ignored(participant_data.m_guid.guidPrefix)) + { + return; + } + const auto& pattr = pdp_server()->getRTPSParticipant()->getAttributes(); fastdds::rtps::ExternalLocatorsProcessor::filter_remote_locators(participant_data, pattr.builtin.metatraffic_external_unicast_locators, pattr.default_external_unicast_locators, @@ -363,13 +368,20 @@ void PDPServerListener::onNewCacheChangeAdded( RTPSParticipantListener* listener = pdp_server()->getRTPSParticipant()->getListener(); if (listener != nullptr) { - std::lock_guard cb_lock(pdp_server()->callback_mtx_); - ParticipantDiscoveryInfo info(*pdata); - info.status = status; - - listener->onParticipantDiscovery( - pdp_server()->getRTPSParticipant()->getUserRTPSParticipant(), - std::move(info)); + bool should_be_ignored = false; + { + std::lock_guard cb_lock(pdp_server()->callback_mtx_); + ParticipantDiscoveryInfo info(*pdata); + info.status = status; + + listener->onParticipantDiscovery( + pdp_server()->getRTPSParticipant()->getUserRTPSParticipant(), + std::move(info), should_be_ignored); + } + if (should_be_ignored) + { + parent_pdp_->getRTPSParticipant()->ignore_participant(guid.guidPrefix); + } } } diff --git a/src/cpp/rtps/messages/MessageReceiver.cpp b/src/cpp/rtps/messages/MessageReceiver.cpp index ba54a8f0bab..720db00314d 100644 --- a/src/cpp/rtps/messages/MessageReceiver.cpp +++ b/src/cpp/rtps/messages/MessageReceiver.cpp @@ -17,6 +17,8 @@ * */ +#include +#include #include #include @@ -334,6 +336,8 @@ void MessageReceiver::processCDRMsg( int decode_ret = 0; #endif // if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) + bool ignore_submessages; + { std::lock_guard guard(mtx_); @@ -349,7 +353,11 @@ void MessageReceiver::processCDRMsg( return; } - notify_network_statistics(source_locator, reception_locator, msg); + ignore_submessages = participant_->is_participant_ignored(source_guid_prefix_); + if (!ignore_submessages) + { + notify_network_statistics(source_locator, reception_locator, msg); + } #if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) decode_ret = security.decode_rtps_message(*msg, *auxiliary_buffer, source_guid_prefix_); @@ -375,6 +383,8 @@ void MessageReceiver::processCDRMsg( bool valid; SubmessageHeader_t submsgh; //Current submessage header + bool ignore_current_submessage; + while (msg->pos < msg->length)// end of the message { CDRMessage_t* submessage = msg; @@ -402,124 +412,142 @@ void MessageReceiver::processCDRMsg( valid = true; uint32_t next_msg_pos = submessage->pos; next_msg_pos += (submsgh.submessageLength + 3u) & ~3u; - switch (submsgh.submessageId) + + // We ignore submessage if the source participant is to be ignored, unless the submessage king is INFO_SRC + // which triggers a reevaluation of the flag. + ignore_current_submessage = ignore_submessages && + submsgh.submessageId != INFO_SRC; + + if (!ignore_current_submessage) { - case DATA: - { - if (dest_guid_prefix_ != participantGuidPrefix) - { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Data Submsg ignored, DST is another RTPSParticipant"); - } - else - { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Data Submsg received, processing."); - valid = proc_Submsg_Data(submessage, &submsgh); - } - break; - } - case DATA_FRAG: - if (dest_guid_prefix_ != participantGuidPrefix) - { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "DataFrag Submsg ignored, DST is another RTPSParticipant"); - } - else - { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "DataFrag Submsg received, processing."); - valid = proc_Submsg_DataFrag(submessage, &submsgh); - } - break; - case GAP: - { - if (dest_guid_prefix_ != participantGuidPrefix) - { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Gap Submsg ignored, DST is another RTPSParticipant..."); - } - else - { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Gap Submsg received, processing..."); - valid = proc_Submsg_Gap(submessage, &submsgh); - } - break; - } - case ACKNACK: + + switch (submsgh.submessageId) { - if (dest_guid_prefix_ != participantGuidPrefix) + case DATA: { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, - IDSTRING "Acknack Submsg ignored, DST is another RTPSParticipant..."); - } - else - { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Acknack Submsg received, processing..."); - valid = proc_Submsg_Acknack(submessage, &submsgh); + if (dest_guid_prefix_ != participantGuidPrefix) + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Data Submsg ignored, DST is another RTPSParticipant"); + } + else + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Data Submsg received, processing."); + EntityId_t writerId = c_EntityId_Unknown; + valid = proc_Submsg_Data(submessage, &submsgh, writerId); + if (valid && writerId == c_EntityId_SPDPWriter) + { + ignore_submessages = participant_->is_participant_ignored(source_guid_prefix_); + } + } + break; } - break; - } - case NACK_FRAG: - { - if (dest_guid_prefix_ != participantGuidPrefix) + case DATA_FRAG: + if (dest_guid_prefix_ != participantGuidPrefix) + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, + IDSTRING "DataFrag Submsg ignored, DST is another RTPSParticipant"); + } + else + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "DataFrag Submsg received, processing."); + valid = proc_Submsg_DataFrag(submessage, &submsgh); + } + break; + case GAP: { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, - IDSTRING "NackFrag Submsg ignored, DST is another RTPSParticipant..."); + if (dest_guid_prefix_ != participantGuidPrefix) + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, + IDSTRING "Gap Submsg ignored, DST is another RTPSParticipant..."); + } + else + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Gap Submsg received, processing..."); + valid = proc_Submsg_Gap(submessage, &submsgh); + } + break; } - else + case ACKNACK: { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "NackFrag Submsg received, processing..."); - valid = proc_Submsg_NackFrag(submessage, &submsgh); + if (dest_guid_prefix_ != participantGuidPrefix) + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, + IDSTRING "Acknack Submsg ignored, DST is another RTPSParticipant..."); + } + else + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Acknack Submsg received, processing..."); + valid = proc_Submsg_Acknack(submessage, &submsgh); + } + break; } - break; - } - case HEARTBEAT: - { - if (dest_guid_prefix_ != participantGuidPrefix) + case NACK_FRAG: { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "HB Submsg ignored, DST is another RTPSParticipant..."); + if (dest_guid_prefix_ != participantGuidPrefix) + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, + IDSTRING "NackFrag Submsg ignored, DST is another RTPSParticipant..."); + } + else + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "NackFrag Submsg received, processing..."); + valid = proc_Submsg_NackFrag(submessage, &submsgh); + } + break; } - else + case HEARTBEAT: { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Heartbeat Submsg received, processing..."); - valid = proc_Submsg_Heartbeat(submessage, &submsgh); + if (dest_guid_prefix_ != participantGuidPrefix) + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "HB Submsg ignored, DST is another RTPSParticipant..."); + } + else + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Heartbeat Submsg received, processing..."); + valid = proc_Submsg_Heartbeat(submessage, &submsgh); + } + break; } - break; - } - case HEARTBEAT_FRAG: - { - if (dest_guid_prefix_ != participantGuidPrefix) + case HEARTBEAT_FRAG: { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "HBFrag Submsg ignored, DST is another RTPSParticipant..."); + if (dest_guid_prefix_ != participantGuidPrefix) + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, + IDSTRING "HBFrag Submsg ignored, DST is another RTPSParticipant..."); + } + else + { + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "HeartbeatFrag Submsg received, processing..."); + valid = proc_Submsg_HeartbeatFrag(submessage, &submsgh); + } + break; } - else + case PAD: + EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "PAD messages not yet implemented, ignoring"); + break; + case INFO_DST: + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "InfoDST message received, processing..."); + valid = proc_Submsg_InfoDST(submessage, &submsgh); + break; + case INFO_SRC: + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "InfoSRC message received, processing..."); + valid = proc_Submsg_InfoSRC(submessage, &submsgh); + ignore_submessages = participant_->is_participant_ignored(source_guid_prefix_); + break; + case INFO_TS: { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "HeartbeatFrag Submsg received, processing..."); - valid = proc_Submsg_HeartbeatFrag(submessage, &submsgh); + EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "InfoTS Submsg received, processing..."); + valid = proc_Submsg_InfoTS(submessage, &submsgh); + break; } - break; - } - case PAD: - EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "PAD messages not yet implemented, ignoring"); - break; - case INFO_DST: - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "InfoDST message received, processing..."); - valid = proc_Submsg_InfoDST(submessage, &submsgh); - break; - case INFO_SRC: - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "InfoSRC message received, processing..."); - valid = proc_Submsg_InfoSRC(submessage, &submsgh); - break; - case INFO_TS: - { - EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "InfoTS Submsg received, processing..."); - valid = proc_Submsg_InfoTS(submessage, &submsgh); - break; + case INFO_REPLY: + break; + case INFO_REPLY_IP4: + break; + default: + break; } - case INFO_REPLY: - break; - case INFO_REPLY_IP4: - break; - default: - break; } - if (!valid || submsgh.is_last) { break; @@ -684,7 +712,8 @@ void MessageReceiver::findAllReaders( bool MessageReceiver::proc_Submsg_Data( CDRMessage_t* msg, - SubmessageHeader_t* smh) const + SubmessageHeader_t* smh, + EntityId_t& writerID) const { eprosima::shared_lock guard(mtx_); @@ -740,6 +769,8 @@ bool MessageReceiver::proc_Submsg_Data( ch.writerGUID.guidPrefix = source_guid_prefix_; valid &= CDRMessage::readEntityId(msg, &ch.writerGUID.entityId); + writerID = ch.writerGUID.entityId; + //Get sequence number valid &= CDRMessage::readSequenceNumber(msg, &ch.sequenceNumber); diff --git a/src/cpp/rtps/participant/RTPSParticipant.cpp b/src/cpp/rtps/participant/RTPSParticipant.cpp index 62c1d573bfc..66ddcddb8ff 100644 --- a/src/cpp/rtps/participant/RTPSParticipant.cpp +++ b/src/cpp/rtps/participant/RTPSParticipant.cpp @@ -179,9 +179,9 @@ void RTPSParticipant::enable() } bool RTPSParticipant::ignore_participant( - const GuidPrefix_t& /*participant_guid*/) + const GuidPrefix_t& participant_guid) { - return false; + return mp_impl->ignore_participant(participant_guid); } bool RTPSParticipant::ignore_writer( diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp index 9610a546f35..045265b7fc5 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp @@ -17,7 +17,6 @@ * */ -#include #include #include @@ -29,11 +28,14 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include @@ -57,6 +59,7 @@ #include #include #include +#include #include #include @@ -2510,9 +2513,10 @@ void RTPSParticipantImpl::get_default_unicast_locators() } bool RTPSParticipantImpl::is_participant_ignored( - const GuidPrefix_t& /*participant_guid*/) + const GuidPrefix_t& participant_guid) { - return false; + shared_lock _(ignored_mtx_); + return ignored_participants_.find(participant_guid) != ignored_participants_.end(); } bool RTPSParticipantImpl::is_writer_ignored( @@ -2528,9 +2532,35 @@ bool RTPSParticipantImpl::is_reader_ignored( } bool RTPSParticipantImpl::ignore_participant( - const GuidPrefix_t& /*participant_guid*/) + const GuidPrefix_t& participant_guid) { - return false; + if (participant_guid == m_guid.guidPrefix) + { + EPROSIMA_LOG_WARNING(RTPS_PARTICIPANT, "A participant is unable to ignore itself"); + return false; + } + { + shared_lock _(mp_builtinProtocols->getDiscoveryMutex()); + + for (auto server_it = m_att.builtin.discovery_config.m_DiscoveryServers.begin(); + server_it != m_att.builtin.discovery_config.m_DiscoveryServers.end(); server_it++) + { + if (server_it->guidPrefix == participant_guid) + { + EPROSIMA_LOG_WARNING(RTPS_PARTICIPANT, "Cannot ignore one of this participant Discovery Servers"); + return false; + } + } + } + { + std::unique_lock _(ignored_mtx_); + ignored_participants_.insert(participant_guid); + } + pdp()->remove_remote_participant(GUID_t(participant_guid, c_EntityId_RTPSParticipant), + ParticipantDiscoveryInfo::DISCOVERY_STATUS::IGNORED_PARTICIPANT); + + return true; + } bool RTPSParticipantImpl::ignore_writer( diff --git a/test/blackbox/common/DDSBlackboxTestsBasic.cpp b/test/blackbox/common/DDSBlackboxTestsBasic.cpp index 6495d2d4db4..3b4e050db19 100644 --- a/test/blackbox/common/DDSBlackboxTestsBasic.cpp +++ b/test/blackbox/common/DDSBlackboxTestsBasic.cpp @@ -12,11 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include +#include #include #include #include +#include + #include #include @@ -34,6 +38,7 @@ #include #include #include +#include #include #include @@ -460,6 +465,89 @@ TEST(DDSBasic, PidRelatedSampleIdentity) ASSERT_EQ(related_sample_identity_, info.related_sample_identity); } +/** + * This test checks that PID_RELATED_SAMPLE_IDENTITY and + * PID_CUSTOM_RELATED_SAMPLE_IDENTITY are being sent as parameter, + * and that the new PID_RELATED_SAMPLE_IDENTITY is being properly + * interpreted. + * Inside the transport filter, both PIDs are indentified, and the old PID is overwritten. + * Reader only receives the new PID, and identifies the related sample identity. + */ +TEST(DDSBasic, IgnoreParticipant) +{ + + struct IgnoringDomainParticipantListener : public DomainParticipantListener + { + std::atomic_int num_matched{0}; + std::atomic_int num_ignored{0}; + + void on_participant_discovery( + DomainParticipant* /*participant*/, + eprosima::fastrtps::rtps::ParticipantDiscoveryInfo&& info, + bool& should_be_ignored) override + { + std::cout << "Using custom listener" << std::endl; + if (info.status == info.DISCOVERED_PARTICIPANT) + { + std::cout << "Discovered participant" << std::endl; + if (info.info.m_userData == std::vector({ 'i', 'g', 'n' })) + { + std::cout << "Ignoring participant" << std::endl; + should_be_ignored = true; + num_ignored++; + } + else + { + std::cout << "Accepting participant" << std::endl; + num_matched++; + } + } + } + + }; + // Set DomainParticipantFactory to create disabled entities + DomainParticipantFactoryQos factory_qos; + DomainParticipantFactory* factory = DomainParticipantFactory::get_instance(); + + DomainParticipantQos ignored_participant_qos; + DomainParticipantQos valid_participant_qos; + DomainParticipantQos other_participant_qos; + + const char* prefix = "00.00.00.00.00.00.FF.FF.FF.FF.FF.FF"; + + std::istringstream is(prefix); + + is >> ignored_participant_qos.wire_protocol().prefix; + + ignored_participant_qos.user_data().data_vec({ 'i', 'g', 'n' }); + valid_participant_qos.user_data().data_vec({ 'o', 'k' }); + + IgnoringDomainParticipantListener ignListener; + DomainParticipant* participant_listener = factory->create_participant( + (uint32_t)GET_PID() % 230, other_participant_qos, &ignListener); + std::this_thread::sleep_for(std::chrono::seconds(2)); + DomainParticipant* participant_ign = + factory->create_participant((uint32_t)GET_PID() % 230, ignored_participant_qos); + std::this_thread::sleep_for(std::chrono::seconds(2)); + DomainParticipant* participant_valid = + factory->create_participant((uint32_t)GET_PID() % 230, valid_participant_qos); + std::this_thread::sleep_for(std::chrono::seconds(2)); + + factory->delete_participant(participant_ign); + + ignored_participant_qos.user_data().data_vec({ 'o', 'k' }); + std::this_thread::sleep_for(std::chrono::seconds(2)); + participant_ign = factory->create_participant((uint32_t)GET_PID() % 230, ignored_participant_qos); + std::this_thread::sleep_for(std::chrono::seconds(2)); + ASSERT_EQ (ignListener.num_matched.load(), 1); + ASSERT_EQ (ignListener.num_ignored.load(), 1); + + factory->delete_participant(participant_valid); + factory->delete_participant(participant_listener); + factory->delete_participant(participant_ign); + +} + } // namespace dds } // namespace fastdds } // namespace eprosima diff --git a/test/mock/dds/DomainParticipantImpl/fastdds/domain/DomainParticipantImpl.hpp b/test/mock/dds/DomainParticipantImpl/fastdds/domain/DomainParticipantImpl.hpp index c8de2ff9c27..bb7fc5dd580 100644 --- a/test/mock/dds/DomainParticipantImpl/fastdds/domain/DomainParticipantImpl.hpp +++ b/test/mock/dds/DomainParticipantImpl/fastdds/domain/DomainParticipantImpl.hpp @@ -16,6 +16,7 @@ #define _FASTDDS_PARTICIPANTIMPL_HPP_ #include +#include #include #include #include @@ -375,6 +376,10 @@ class DomainParticipantImpl MOCK_METHOD1(find_content_filter_factory, IContentFilterFactory * ( const char* filter_class_name)); + MOCK_METHOD1(ignore_participant, bool ( + const fastrtps::rtps::InstanceHandle_t& handle)); + + TopicDescription* lookup_topicdescription( const std::string& topic_name) const { diff --git a/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.h b/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.h index b699edf8b2b..909178c0a4b 100644 --- a/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.h +++ b/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.h @@ -169,6 +169,9 @@ class RTPS_DllAPI RTPSParticipant const TopicAttributes& topicAtt, const ReaderQos& rqos)); + MOCK_METHOD1(ignore_participant, bool( + const GuidPrefix_t& participant_guid)); + MOCK_METHOD4(updateReader, bool( RTPSReader * Reader, const TopicAttributes& topicAtt, diff --git a/test/unittest/dds/participant/ParticipantTests.cpp b/test/unittest/dds/participant/ParticipantTests.cpp index 92810ce58ed..3b05ba58160 100644 --- a/test/unittest/dds/participant/ParticipantTests.cpp +++ b/test/unittest/dds/participant/ParticipantTests.cpp @@ -3668,7 +3668,6 @@ TEST(ParticipantTests, ContentFilterInterfaces) * create_multitopic * delete_multitopic * get_builtin_subscriber - * ignore_participant * ignore_topic * ignore_publication * ignore_subscription @@ -3705,7 +3704,6 @@ TEST(ParticipantTests, UnsupportedMethods) ASSERT_EQ(participant->get_builtin_subscriber(), nullptr); - ASSERT_EQ(participant->ignore_participant(InstanceHandle_t()), ReturnCode_t::RETCODE_UNSUPPORTED); ASSERT_EQ(participant->ignore_topic(InstanceHandle_t()), ReturnCode_t::RETCODE_UNSUPPORTED); ASSERT_EQ(participant->ignore_publication(InstanceHandle_t()), ReturnCode_t::RETCODE_UNSUPPORTED); ASSERT_EQ(participant->ignore_subscription(InstanceHandle_t()), ReturnCode_t::RETCODE_UNSUPPORTED); diff --git a/versions.md b/versions.md index 032a46a9255..8f642b0ba72 100644 --- a/versions.md +++ b/versions.md @@ -1,6 +1,8 @@ Forthcoming ----------- +* Added `ignore_participant` implementation. + Version 2.10.0 --------------