diff --git a/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h b/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h index 9a826b3933c..b84f513fb04 100644 --- a/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h +++ b/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h @@ -147,7 +147,8 @@ class BuiltinProtocols; typedef struct _PDPFactory { // Pointer to the PDP creator - PDP* (*CreatePDPInstance)(BuiltinProtocols*); + PDP* (*CreatePDPInstance)( + BuiltinProtocols*); // Pointer to the PDP destructor void (* ReleasePDPInstance)( PDP*); @@ -366,6 +367,151 @@ class TypeLookupSettings }; +/** + * Class MutableDiscoverySettings, to define the mutable attributes of the several discovery protocols available + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class MutableDiscoverySettings +{ +public: + + //! Discovery Server initial connections, needed if `discoveryProtocol` = CLIENT | SUPER_CLIENT | SERVER | BACKUP + eprosima::fastdds::rtps::RemoteServerList_t m_DiscoveryServers; + + MutableDiscoverySettings() = default; + + MutableDiscoverySettings( + const DiscoverySettings& discovery_settings) + : m_DiscoveryServers(discovery_settings.m_DiscoveryServers) + { + } + + bool operator ==( + const MutableDiscoverySettings& b) const + { + return (this->m_DiscoveryServers == b.m_DiscoveryServers); + } + +}; + +/** + * Class ConstantDiscoverySettings, to define the constant attributes of the several discovery protocols available + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class ConstantDiscoverySettings +{ +public: + + //! Chosen discovery protocol + DiscoveryProtocol discoveryProtocol = DiscoveryProtocol::SIMPLE; + + /** + * If set to true, SimpleEDP would be used. + */ + bool use_SIMPLE_EndpointDiscoveryProtocol = true; + + /** + * If set to true, StaticEDP based on an XML file would be implemented. + * The XML filename must be provided. + */ + bool use_STATIC_EndpointDiscoveryProtocol = false; + + /** + * Lease Duration of the RTPSParticipant, + * indicating how much time remote RTPSParticipants should consider this RTPSParticipant alive. + */ + fastrtps::Duration_t leaseDuration = { 20, 0 }; + + /** + * The period for the RTPSParticipant to send its Discovery Message to all other discovered RTPSParticipants + * as well as to all Multicast ports. + */ + fastrtps::Duration_t leaseDuration_announcementperiod = { 3, 0 }; + + //!Initial announcements configuration + InitialAnnouncementConfig initial_announcements; + + //!Attributes of the SimpleEDP protocol + SimpleEDPAttributes m_simpleEDP; + + //! function that returns a PDP object (only if EXTERNAL selected) + PDPFactory m_PDPfactory{}; + /** + * The period for the RTPSParticipant to: + * send its Discovery Message to its servers + * check for EDP endpoints matching + */ + fastrtps::Duration_t discoveryServer_client_syncperiod = { 0, 450 * 1000000}; // 450 milliseconds + + //! Filtering participants out depending on location + ParticipantFilteringFlags ignoreParticipantFlags = ParticipantFilteringFlags::NO_FILTER; + + ConstantDiscoverySettings() = default; + + ConstantDiscoverySettings( + const DiscoverySettings& discovery_settings) + : discoveryProtocol(discovery_settings.discoveryProtocol) + , use_SIMPLE_EndpointDiscoveryProtocol(discovery_settings.use_SIMPLE_EndpointDiscoveryProtocol) + , use_STATIC_EndpointDiscoveryProtocol(discovery_settings.use_STATIC_EndpointDiscoveryProtocol) + , leaseDuration(discovery_settings.leaseDuration) + , leaseDuration_announcementperiod(discovery_settings.leaseDuration_announcementperiod) + , initial_announcements(discovery_settings.initial_announcements) + , m_simpleEDP(discovery_settings.m_simpleEDP) + , m_PDPfactory(discovery_settings.m_PDPfactory) + , discoveryServer_client_syncperiod(discovery_settings.discoveryServer_client_syncperiod) + , ignoreParticipantFlags(discovery_settings.ignoreParticipantFlags) + , static_edp_xml_config_(discovery_settings.static_edp_xml_config()) + { + } + + bool operator ==( + const ConstantDiscoverySettings& b) const + { + return (this->discoveryProtocol == b.discoveryProtocol) && + (this->use_SIMPLE_EndpointDiscoveryProtocol == b.use_SIMPLE_EndpointDiscoveryProtocol) && + (this->use_STATIC_EndpointDiscoveryProtocol == b.use_STATIC_EndpointDiscoveryProtocol) && + (this->discoveryServer_client_syncperiod == b.discoveryServer_client_syncperiod) && + (this->m_PDPfactory == b.m_PDPfactory) && + (this->leaseDuration == b.leaseDuration) && + (this->leaseDuration_announcementperiod == b.leaseDuration_announcementperiod) && + (this->initial_announcements == b.initial_announcements) && + (this->m_simpleEDP == b.m_simpleEDP) && + (this->static_edp_xml_config_ == b.static_edp_xml_config_) && + (this->ignoreParticipantFlags == b.ignoreParticipantFlags); + } + + /** + * Get the static endpoint XML configuration. + * @return URI specifying the static endpoint XML configuration. + * The string could contain a filename (file://) or the XML content directly (data://). + */ + const char* static_edp_xml_config() const + { + return static_edp_xml_config_.c_str(); + } + + /** + * Get the static endpoint XML filename + * @return Static endpoint XML filename + */ + FASTRTPS_DEPRECATED("Use static_edp_xml_config()") + const char* getStaticEndpointXMLFilename() const + { + return static_edp_xml_config(); + } + +private: + + //! URI specifying the static EDP XML configuration, only necessary if use_STATIC_EndpointDiscoveryProtocol=true + //! This string could contain a filename or the XML content directly. + std::string static_edp_xml_config_ = ""; + +}; + +// Forward declaration to allow assignment from Constant and Mutable attributes. +class BuiltinConstantAttributes; +class BuiltinMutableAttributes; + /** * Class BuiltinAttributes, to define the behavior of the RTPSParticipant builtin protocols. * @ingroup RTPS_ATTRIBUTES_MODULE @@ -422,6 +568,17 @@ class BuiltinAttributes virtual ~BuiltinAttributes() = default; + /** + * Composes this object from a BuiltinConstantAttributes and a BuiltinMutableAttributes. + * Every field is assigned: constant fields are taken from @c builtin_const, mutable fields + * are taken from @c builtin_mutable. + * @param builtin_const Constant builtin attributes to copy from. + * @param builtin_mutable Mutable builtin attributes to copy from. + */ + void compose( + const BuiltinConstantAttributes& builtin_const, + const BuiltinMutableAttributes& builtin_mutable); + bool operator ==( const BuiltinAttributes& b) const { @@ -444,16 +601,183 @@ class BuiltinAttributes }; +/** + * Class BuiltinMutableAttributes, to define the behavior of the mutable RTPSParticipant builtin protocols. + * This class is a subset of BuiltinAttributes. It is separated to keep the logic of constant and mutable attributes separated. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class BuiltinMutableAttributes +{ +public: + + //! Discovery protocol related attributes + MutableDiscoverySettings discovery_config; + + //! Metatraffic Unicast Locator List + LocatorList_t metatrafficUnicastLocatorList; + + //! The collection of external locators to use for communication on metatraffic topics. + fastdds::rtps::ExternalLocators metatraffic_external_unicast_locators; + + BuiltinMutableAttributes() = default; + + BuiltinMutableAttributes( + const BuiltinAttributes& builtin) + : discovery_config(builtin.discovery_config) + , metatrafficUnicastLocatorList(builtin.metatrafficUnicastLocatorList) + , metatraffic_external_unicast_locators(builtin.metatraffic_external_unicast_locators) + { + } + + ~BuiltinMutableAttributes() = default; + + bool operator ==( + const BuiltinMutableAttributes& b) const + { + return (this->discovery_config == b.discovery_config) && + (this->metatrafficUnicastLocatorList == b.metatrafficUnicastLocatorList) && + (this->metatraffic_external_unicast_locators == b.metatraffic_external_unicast_locators); + } + +}; + +/** + * Class BuiltinConstantAttributes, to define the behavior of the constant RTPSParticipant builtin protocols. + * This class is a subset of BuiltinAttributes. It is separated to keep the logic of constant and mutable attributes separated. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class BuiltinConstantAttributes +{ +public: + + /** + * Discovery protocol related constant attributes. Only the discovery server list is mutable, which must be + * accessed through the BuiltinMutableAttributes class. Its value in this class is only used as initial value. + */ + ConstantDiscoverySettings discovery_config; + + //! Indicates to use the WriterLiveliness protocol. + bool use_WriterLivelinessProtocol = true; + + //! TypeLookup Service settings + TypeLookupSettings typelookup_config; + + //! Network Configuration + NetworkConfigSet_t network_configuration = 0; + + //! Metatraffic Multicast Locator List + LocatorList_t metatrafficMulticastLocatorList; + + //! Initial peers. + LocatorList_t initialPeersList; + + //! Memory policy for builtin readers + MemoryManagementPolicy_t readerHistoryMemoryPolicy = + MemoryManagementPolicy_t::PREALLOCATED_WITH_REALLOC_MEMORY_MODE; + + //! Maximum payload size for builtin readers + uint32_t readerPayloadSize = BUILTIN_DATA_MAX_SIZE; + + //! Memory policy for builtin writers + MemoryManagementPolicy_t writerHistoryMemoryPolicy = + MemoryManagementPolicy_t::PREALLOCATED_WITH_REALLOC_MEMORY_MODE; + + //! Maximum payload size for builtin writers + uint32_t writerPayloadSize = BUILTIN_DATA_MAX_SIZE; + + //! Mutation tries if the port is being used. + uint32_t mutation_tries = 100u; + + //! Set to true to avoid multicast traffic on builtin endpoints + bool avoid_builtin_multicast = true; + + BuiltinConstantAttributes() = default; + + BuiltinConstantAttributes( + const BuiltinAttributes& builtin) + : discovery_config(builtin.discovery_config) + , use_WriterLivelinessProtocol(builtin.use_WriterLivelinessProtocol) + , typelookup_config(builtin.typelookup_config) + , network_configuration(builtin.network_configuration) + , metatrafficMulticastLocatorList(builtin.metatrafficMulticastLocatorList) + , initialPeersList(builtin.initialPeersList) + , readerHistoryMemoryPolicy(builtin.readerHistoryMemoryPolicy) + , readerPayloadSize(builtin.readerPayloadSize) + , writerHistoryMemoryPolicy(builtin.writerHistoryMemoryPolicy) + , writerPayloadSize(builtin.writerPayloadSize) + , mutation_tries(builtin.mutation_tries) + , avoid_builtin_multicast(builtin.avoid_builtin_multicast) + { + } + + ~BuiltinConstantAttributes() = default; + + bool operator ==( + const BuiltinConstantAttributes& b) const + { + return (this->discovery_config == b.discovery_config) && + (this->use_WriterLivelinessProtocol == b.use_WriterLivelinessProtocol) && + (this->typelookup_config.use_client == b.typelookup_config.use_client) && + (this->typelookup_config.use_server == b.typelookup_config.use_server) && + (this->network_configuration == b.network_configuration) && + (this->metatrafficMulticastLocatorList == b.metatrafficMulticastLocatorList) && + (this->initialPeersList == b.initialPeersList) && + (this->readerHistoryMemoryPolicy == b.readerHistoryMemoryPolicy) && + (this->readerPayloadSize == b.readerPayloadSize) && + (this->writerHistoryMemoryPolicy == b.writerHistoryMemoryPolicy) && + (this->writerPayloadSize == b.writerPayloadSize) && + (this->mutation_tries == b.mutation_tries) && + (this->avoid_builtin_multicast == b.avoid_builtin_multicast); + } + +}; + +inline void BuiltinAttributes::compose( + const BuiltinConstantAttributes& builtin_const, + const BuiltinMutableAttributes& builtin_mutable) +{ + // Constant Discovery settings + discovery_config.discoveryProtocol = builtin_const.discovery_config.discoveryProtocol; + discovery_config.use_SIMPLE_EndpointDiscoveryProtocol = + builtin_const.discovery_config.use_SIMPLE_EndpointDiscoveryProtocol; + discovery_config.use_STATIC_EndpointDiscoveryProtocol = + builtin_const.discovery_config.use_STATIC_EndpointDiscoveryProtocol; + discovery_config.leaseDuration = builtin_const.discovery_config.leaseDuration; + discovery_config.leaseDuration_announcementperiod = builtin_const.discovery_config.leaseDuration_announcementperiod; + discovery_config.initial_announcements = builtin_const.discovery_config.initial_announcements; + discovery_config.m_simpleEDP = builtin_const.discovery_config.m_simpleEDP; + discovery_config.m_PDPfactory = builtin_const.discovery_config.m_PDPfactory; + discovery_config.discoveryServer_client_syncperiod = + builtin_const.discovery_config.discoveryServer_client_syncperiod; + discovery_config.ignoreParticipantFlags = builtin_const.discovery_config.ignoreParticipantFlags; + // Mutable Discovery settings + discovery_config.m_DiscoveryServers = builtin_mutable.discovery_config.m_DiscoveryServers; + // Constant settings + use_WriterLivelinessProtocol = builtin_const.use_WriterLivelinessProtocol; + network_configuration = builtin_const.network_configuration; + metatrafficMulticastLocatorList = builtin_const.metatrafficMulticastLocatorList; + initialPeersList = builtin_const.initialPeersList; + readerHistoryMemoryPolicy = builtin_const.readerHistoryMemoryPolicy; + readerPayloadSize = builtin_const.readerPayloadSize; + writerHistoryMemoryPolicy = builtin_const.writerHistoryMemoryPolicy; + writerPayloadSize = builtin_const.writerPayloadSize; + mutation_tries = builtin_const.mutation_tries; + avoid_builtin_multicast = builtin_const.avoid_builtin_multicast; + // Mutable settings + metatrafficUnicastLocatorList = builtin_mutable.metatrafficUnicastLocatorList; + metatraffic_external_unicast_locators = builtin_mutable.metatraffic_external_unicast_locators; +} + /** * Class RTPSParticipantAttributes used to define different aspects of a RTPSParticipant. * @ingroup RTPS_ATTRIBUTES_MODULE */ class RTPSParticipantAttributes { - using FlowControllerDescriptorList = std::vector>; - public: + using FlowControllerDescriptorList = std::vector>; + RTPSParticipantAttributes() = default; virtual ~RTPSParticipantAttributes() = default; @@ -620,6 +944,225 @@ class RTPSParticipantAttributes string_255 name{"RTPSParticipant"}; }; +/** + * Class RTPSParticipantMutableAttributes used to define mutable aspects of a RTPSParticipant. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class RTPSParticipantMutableAttributes +{ +public: + + RTPSParticipantMutableAttributes() = default; + + RTPSParticipantMutableAttributes( + const RTPSParticipantAttributes& attrs) + : defaultUnicastLocatorList(attrs.defaultUnicastLocatorList) + , default_external_unicast_locators(attrs.default_external_unicast_locators) + , userData(attrs.userData) + , builtin(attrs.builtin) + { + } + + ~RTPSParticipantMutableAttributes() = default; + + bool operator ==( + const RTPSParticipantMutableAttributes& b) const + { + return (this->defaultUnicastLocatorList == b.defaultUnicastLocatorList) && + (this->default_external_unicast_locators == b.default_external_unicast_locators) && + (this->userData == b.userData) && + (this->builtin == b.builtin); + } + + /** + * Default list of Unicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the case + * that it was defined with NO UnicastLocators. At least ONE locator should be included in this list. + */ + LocatorList_t defaultUnicastLocatorList; + + /** + * The collection of external locators to use for communication on user created topics. + */ + fastdds::rtps::ExternalLocators default_external_unicast_locators; + + //! User Data of the participant + std::vector userData; + + //! Builtin parameters. + BuiltinMutableAttributes builtin; +}; + +/** + * Class RTPSParticipantConstantAttributes used to define constant aspects of a RTPSParticipant. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class RTPSParticipantConstantAttributes +{ +public: + + using FlowControllerDescriptorList = std::vector>; + + RTPSParticipantConstantAttributes() = default; + + RTPSParticipantConstantAttributes( + const RTPSParticipantAttributes& attrs) + : defaultMulticastLocatorList(attrs.defaultMulticastLocatorList) + , ignore_non_matching_locators(attrs.ignore_non_matching_locators) + , sendSocketBufferSize(attrs.sendSocketBufferSize) + , listenSocketBufferSize(attrs.listenSocketBufferSize) + , netmaskFilter(attrs.netmaskFilter) + , prefix(attrs.prefix) + , builtin(attrs.builtin) + , port(attrs.port) + , participantID(attrs.participantID) + , throughputController(attrs.throughputController) + , userTransports(attrs.userTransports) + , useBuiltinTransports(attrs.useBuiltinTransports) + , allocation(attrs.allocation) + , properties(attrs.properties) + , flow_controllers(attrs.flow_controllers) + , builtin_controllers_sender_thread(attrs.builtin_controllers_sender_thread) + , timed_events_thread(attrs.timed_events_thread) + , discovery_server_thread(attrs.discovery_server_thread) + , builtin_transports_reception_threads(attrs.builtin_transports_reception_threads) +#if HAVE_SECURITY + , security_log_thread(attrs.security_log_thread) +#endif // if HAVE_SECURITY + , max_msg_size_no_frag(attrs.max_msg_size_no_frag) + , name(attrs.getName()) + { + } + + ~RTPSParticipantConstantAttributes() = default; + + bool operator ==( + const RTPSParticipantConstantAttributes& b) const + { + return (this->defaultMulticastLocatorList == b.defaultMulticastLocatorList) && + (this->ignore_non_matching_locators == b.ignore_non_matching_locators) && + (this->sendSocketBufferSize == b.sendSocketBufferSize) && + (this->listenSocketBufferSize == b.listenSocketBufferSize) && + (this->netmaskFilter == b.netmaskFilter) && + (this->builtin == b.builtin) && + (this->port == b.port) && + (this->participantID == b.participantID) && + (this->throughputController == b.throughputController) && + (this->useBuiltinTransports == b.useBuiltinTransports) && + (this->allocation == b.allocation) && + (this->properties == b.properties) && + (this->prefix == b.prefix) && + (this->flow_controllers == b.flow_controllers) && + (this->builtin_controllers_sender_thread == b.builtin_controllers_sender_thread) && + (this->timed_events_thread == b.timed_events_thread) && +#if HAVE_SECURITY + (this->security_log_thread == b.security_log_thread) && +#endif // if HAVE_SECURITY + (this->discovery_server_thread == b.discovery_server_thread) && + (this->builtin_transports_reception_threads == b.builtin_transports_reception_threads); + } + + /** + * Default list of Multicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the + * case that it was defined with NO MulticastLocators. This is usually left empty. + */ + LocatorList_t defaultMulticastLocatorList; + + /** + * Whether locators that don't match with the announced locators should be kept. + */ + bool ignore_non_matching_locators = false; + + /*! + * @brief Send socket buffer size for the send resource. Zero value indicates to use default system buffer size. + * Default value: 0. + */ + uint32_t sendSocketBufferSize = 0; + + /*! Listen socket buffer for all listen resources. Zero value indicates to use default system buffer size. + * Default value: 0. + */ + uint32_t listenSocketBufferSize = 0; + + //! Netmask filter configuration + fastdds::rtps::NetmaskFilterKind netmaskFilter = fastdds::rtps::NetmaskFilterKind::AUTO; + + //! Optionally allows user to define the GuidPrefix_t + GuidPrefix_t prefix; + + inline bool ReadguidPrefix( + const char* pfx) + { + return bool(std::istringstream(pfx) >> prefix); + } + + //! Builtin parameters. + BuiltinConstantAttributes builtin; + + //! Port Parameters + PortParameters port; + + //! Participant ID + int32_t participantID = -1; + + /** + * @brief Throughput controller parameters. Leave default for uncontrolled flow. + * + * @deprecated Use flow_controllers on RTPSParticipantAttributes + */ + ThroughputControllerDescriptor throughputController; + + //! User defined transports to use alongside or in place of builtins. + std::vector> userTransports; + + //! Set as false to disable the creation of the default transports. + bool useBuiltinTransports = true; + + //! Holds allocation limits affecting collections managed by a participant. + RTPSParticipantAllocationAttributes allocation; + + //! Property policies + PropertyPolicy properties; + + //! Get the name of the participant. + inline const char* getName() const + { + return name.c_str(); + } + + //! Flow controllers. + FlowControllerDescriptorList flow_controllers; + + //! Thread settings for the builtin flow controllers sender threads + fastdds::rtps::ThreadSettings builtin_controllers_sender_thread; + + //! Thread settings for the timed events thread + fastdds::rtps::ThreadSettings timed_events_thread; + + //! Thread settings for the discovery server thread + fastdds::rtps::ThreadSettings discovery_server_thread; + + //! Thread settings for the builtin transports reception threads + fastdds::rtps::ThreadSettings builtin_transports_reception_threads; + +#if HAVE_SECURITY + //! Thread settings for the security log thread + fastdds::rtps::ThreadSettings security_log_thread; +#endif // if HAVE_SECURITY + + /*! Maximum message size used to avoid fragmentation, set ONLY in LARGE_DATA. If this value is + * not zero, the network factory will allow the initialization of UDP transports with maxMessageSize + * higher than 65500K. + */ + uint32_t max_msg_size_no_frag = 0; + +private: + + //! Name of the participant. + string_255 name{"RTPSParticipant"}; + +}; + + } // namespace rtps } // namespace fastrtps } // namespace eprosima diff --git a/include/fastdds/rtps/participant/RTPSParticipant.h b/include/fastdds/rtps/participant/RTPSParticipant.h index 1b3a19abd56..0b0af5128d5 100644 --- a/include/fastdds/rtps/participant/RTPSParticipant.h +++ b/include/fastdds/rtps/participant/RTPSParticipant.h @@ -211,11 +211,33 @@ class RTPS_DllAPI RTPSParticipant std::vector getParticipantNames() const; /** - * Get a copy of the actual state of the RTPSParticipantParameters - * @return RTPSParticipantAttributes copy of the params. + * Get a reference of the current state of the RTPSParticipantAttributes. + * @warning The returned reference is not thread safe. It is recommended to use copy_attributes() + * instead to get a thread safe copy of the attributes. + * @return RTPSParticipantAttributes reference. */ const RTPSParticipantAttributes& getRTPSParticipantAttributes() const; + /** + * @brief Get a const reference of RTPSParticipantConstantAttributes of this RTPSParticipantImpl. + * This method is thread safe because it returns a const reference to the internal constant attributes. + * @return A const reference to the RTPSParticipantConstantAttributes of this RTPSParticipantImpl. + */ + const RTPSParticipantConstantAttributes& get_const_attributes() const; + + /** + * @brief Get a const copy of RTPSParticipantMutableAttributes of this RTPSParticipantImpl. + * This method is thread safe because it returns a const copy of the internal mutable attributes. + * @return A const copy of the RTPSParticipantMutableAttributes of this RTPSParticipantImpl. + */ + const RTPSParticipantMutableAttributes get_mutable_attributes() const; + + /** + * Get a copy of the current state of the RTPSParticipantAttributes. + * @return RTPSParticipantAttributes copy. + */ + RTPSParticipantAttributes copy_attributes() const; + /** * Retrieves the maximum message size. */ diff --git a/include/fastdds/rtps/security/accesscontrol/AccessControl.h b/include/fastdds/rtps/security/accesscontrol/AccessControl.h index 8fd6f8825ec..79a72bb39d3 100644 --- a/include/fastdds/rtps/security/accesscontrol/AccessControl.h +++ b/include/fastdds/rtps/security/accesscontrol/AccessControl.h @@ -19,6 +19,7 @@ #define _FASTDDS_RTPS_SECURITY_ACCESSCONTROL_ACCESSCONTROL_H_ #include +#include #include namespace eprosima { @@ -48,7 +49,7 @@ class AccessControl Authentication& auth_plugin, const IdentityHandle& identity, const uint32_t domain_id, - const RTPSParticipantAttributes& participant_attr, + const PropertyPolicy& part_props, SecurityException& exception) = 0; virtual bool get_permissions_token( @@ -88,7 +89,6 @@ class AccessControl virtual bool check_create_participant( const PermissionsHandle& local_handle, const uint32_t domain_id, - const RTPSParticipantAttributes& qos, SecurityException& exception) = 0; virtual bool check_remote_participant( diff --git a/include/fastdds/rtps/security/authentication/Authentication.h b/include/fastdds/rtps/security/authentication/Authentication.h index 263328167c5..c38f065893f 100644 --- a/include/fastdds/rtps/security/authentication/Authentication.h +++ b/include/fastdds/rtps/security/authentication/Authentication.h @@ -69,7 +69,7 @@ class Authentication * @param adjusted_participant_key (out) The GUID_t that the implementation shall use to uniquely identify the * RTPSParticipant on the network. * @param domain_id The Domain Id of the RTPSParticipant. - * @param participant_attr The RTPSParticipantAttributes of the RTPSParticipant. + * @param part_props The PropertyPolicy of the RTPSParticipant. * @param candidate_participant_key The GUID_t that the DDS implementation would have used to uniquely identify * the RTPSParticipant if the Security plugins were not enabled. * @param exception (out) A SecurityException object. @@ -79,7 +79,7 @@ class Authentication IdentityHandle** local_identity_handle, GUID_t& adjusted_participant_key, const uint32_t domain_id, - const RTPSParticipantAttributes& participant_attr, + const PropertyPolicy& part_props, const GUID_t& candidate_participant_key, SecurityException& exception) = 0; diff --git a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupManager.cpp b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupManager.cpp new file mode 100644 index 00000000000..23f38dc2ba6 --- /dev/null +++ b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupManager.cpp @@ -0,0 +1,877 @@ +// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file TypeLookupManager.cpp + * + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace eprosima { + +using namespace fastdds::rtps; + +namespace fastdds { +namespace dds { +namespace builtin { + + +inline SequenceNumber_t sequence_number_rtps_2_dds( + const fastdds::rtps::SequenceNumber_t& seq_number) +{ + return *reinterpret_cast(&seq_number); +} + +inline GUID_t guid_rtps_2_dds( + const fastdds::rtps::GUID_t& rtps_guid) +{ + return *reinterpret_cast(&rtps_guid); +} + +inline fastdds::rtps::GUID_t guid_dds_2_rtps( + const GUID_t& guid) +{ + return *reinterpret_cast(&guid); +} + +TypeLookupManager::TypeLookupManager() +{ +} + +TypeLookupManager::~TypeLookupManager() +{ + if (nullptr != builtin_reply_reader_) + { + participant_->deleteUserEndpoint(builtin_reply_reader_->getGuid()); + } + if (nullptr != builtin_reply_writer_) + { + participant_->deleteUserEndpoint(builtin_reply_writer_->getGuid()); + } + if (nullptr != builtin_request_reader_) + { + participant_->deleteUserEndpoint(builtin_request_reader_->getGuid()); + } + if (nullptr != builtin_request_writer_) + { + participant_->deleteUserEndpoint(builtin_request_writer_->getGuid()); + } + delete builtin_request_writer_history_; + delete builtin_reply_writer_history_; + delete builtin_request_reader_history_; + delete builtin_reply_reader_history_; + + delete reply_listener_; + delete request_listener_; + + delete temp_reader_proxy_data_; + delete temp_writer_proxy_data_; + + for (auto& writer_entry : async_get_type_writer_callbacks_) + { + // Delete the proxies and remove the entry + for (auto& proxy_callback_pair : writer_entry.second) + { + delete proxy_callback_pair.first; + } + } + + for (auto& reader_entry : async_get_type_reader_callbacks_) + { + // Delete the proxies and remove the entry + for (auto& proxy_callback_pair : reader_entry.second) + { + delete proxy_callback_pair.first; + } + } +} + +bool TypeLookupManager::init( + fastdds::rtps::BuiltinProtocols* protocols) +{ + participant_ = protocols->mp_participantImpl; + builtin_protocols_ = protocols; + const auto& locators_allocations = participant_->get_const_attributes().allocation.locators; + + local_instance_name_ = get_instance_name(participant_->getGuid()); + + temp_reader_proxy_data_ = new fastdds::rtps::ReaderProxyData( + locators_allocations.max_unicast_locators, + locators_allocations.max_multicast_locators); + + temp_writer_proxy_data_ = new fastdds::rtps::WriterProxyData( + locators_allocations.max_unicast_locators, + locators_allocations.max_multicast_locators); + + type_propagation_ = participant_->type_propagation(); + + // Check if ReaderProxyData and WriterProxyData objects were created successfully + if (temp_reader_proxy_data_ && temp_writer_proxy_data_) + { + return create_endpoints(); + } + else + { + // Clean up on failure and return false + delete temp_reader_proxy_data_; + delete temp_writer_proxy_data_; + return false; + } +} + +bool TypeLookupManager::assign_remote_endpoints( + const ParticipantProxyData& pdata) +{ + const NetworkFactory& network = participant_->network_factory(); + uint32_t endp = pdata.m_available_builtin_endpoints; + uint32_t auxendp = endp; + + std::lock_guard data_guard(temp_data_lock_); + + temp_writer_proxy_data_->guid.guidPrefix = pdata.guid.guidPrefix; + temp_writer_proxy_data_->persistence_guid.guidPrefix = pdata.guid.guidPrefix; + temp_writer_proxy_data_->set_remote_locators(pdata.metatraffic_locators, network, true, pdata.is_from_this_host()); + temp_writer_proxy_data_->topic_kind = NO_KEY; + temp_writer_proxy_data_->durability.kind = fastdds::dds::VOLATILE_DURABILITY_QOS; + temp_writer_proxy_data_->reliability.kind = fastdds::dds::RELIABLE_RELIABILITY_QOS; + + temp_reader_proxy_data_->clear(); + temp_reader_proxy_data_->expects_inline_qos = false; + temp_reader_proxy_data_->guid.guidPrefix = pdata.guid.guidPrefix; + temp_reader_proxy_data_->set_remote_locators(pdata.metatraffic_locators, network, true, pdata.is_from_this_host()); + temp_reader_proxy_data_->topic_kind = NO_KEY; + temp_reader_proxy_data_->durability.kind = fastdds::dds::VOLATILE_DURABILITY_QOS; + temp_reader_proxy_data_->reliability.kind = fastdds::dds::RELIABLE_RELIABILITY_QOS; + + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "for RTPSParticipant: " << pdata.guid); + + auxendp &= rtps::BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REQUEST_DATA_WRITER; + + if (auxendp != 0 && builtin_request_reader_ != nullptr) + { + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Adding remote writer to the local Builtin Request Reader"); + temp_writer_proxy_data_->guid.entityId = fastdds::rtps::c_EntityId_TypeLookup_request_writer; + temp_writer_proxy_data_->persistence_guid.entityId = fastdds::rtps::c_EntityId_TypeLookup_request_writer; + builtin_request_reader_->matched_writer_add_edp(*temp_writer_proxy_data_); + } + + auxendp = endp; + auxendp &= rtps::BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REPLY_DATA_WRITER; + + if (auxendp != 0 && builtin_reply_reader_ != nullptr) + { + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Adding remote writer to the local Builtin Reply Reader"); + temp_writer_proxy_data_->guid.entityId = fastdds::rtps::c_EntityId_TypeLookup_reply_writer; + temp_writer_proxy_data_->persistence_guid.entityId = fastdds::rtps::c_EntityId_TypeLookup_reply_writer; + builtin_reply_reader_->matched_writer_add_edp(*temp_writer_proxy_data_); + } + + auxendp = endp; + auxendp &= rtps::BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REQUEST_DATA_READER; + + if (auxendp != 0 && builtin_request_writer_ != nullptr) + { + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Adding remote reader to the local Builtin Request Writer"); + temp_reader_proxy_data_->guid.entityId = fastdds::rtps::c_EntityId_TypeLookup_request_reader; + builtin_request_writer_->matched_reader_add_edp(*temp_reader_proxy_data_); + } + + auxendp = endp; + auxendp &= rtps::BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REPLY_DATA_READER; + + if (auxendp != 0 && builtin_reply_writer_ != nullptr) + { + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Adding remote reader to the local Builtin Reply Writer"); + temp_reader_proxy_data_->guid.entityId = fastdds::rtps::c_EntityId_TypeLookup_reply_reader; + builtin_reply_writer_->matched_reader_add_edp(*temp_reader_proxy_data_); + } + + return true; +} + +void TypeLookupManager::remove_remote_endpoints( + fastdds::rtps::ParticipantProxyData* pdata) +{ + fastdds::rtps::GUID_t tmp_guid; + tmp_guid.guidPrefix = pdata->guid.guidPrefix; + + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "for RTPSParticipant: " << pdata->guid); + uint32_t endp = pdata->m_available_builtin_endpoints; + uint32_t partdet = endp; + uint32_t auxendp = endp; + partdet &= rtps::DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR; //Habria que quitar esta linea que comprueba si tiene PDP. + auxendp &= rtps::BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REQUEST_DATA_WRITER; + + if ((auxendp != 0 || partdet != 0) && builtin_request_reader_ != nullptr) + { + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Removing remote writer from the local Builtin Request Reader"); + tmp_guid.entityId = fastdds::rtps::c_EntityId_TypeLookup_request_writer; + builtin_request_reader_->matched_writer_remove(tmp_guid); + } + + auxendp = endp; + auxendp &= rtps::BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REPLY_DATA_WRITER; + + if ((auxendp != 0 || partdet != 0) && builtin_reply_reader_ != nullptr) + { + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Removing remote writer from the local Builtin Reply Reader"); + tmp_guid.entityId = fastdds::rtps::c_EntityId_TypeLookup_reply_writer; + builtin_reply_reader_->matched_writer_remove(tmp_guid); + } + + auxendp = endp; + auxendp &= rtps::BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REQUEST_DATA_READER; + + if ((auxendp != 0 || partdet != 0) && builtin_request_writer_ != nullptr) + { + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Removing remote reader from the local Builtin Request Writer"); + tmp_guid.entityId = fastdds::rtps::c_EntityId_TypeLookup_request_reader; + builtin_request_writer_->matched_reader_remove(tmp_guid); + } + + auxendp = endp; + auxendp &= rtps::BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REPLY_DATA_READER; + + if ((auxendp != 0 || partdet != 0) && builtin_reply_writer_ != nullptr) + { + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Removing remote reader from the local Builtin Reply Writer"); + tmp_guid.entityId = fastdds::rtps::c_EntityId_TypeLookup_reply_reader; + builtin_reply_writer_->matched_reader_remove(tmp_guid); + } +} + +SampleIdentity TypeLookupManager::get_type_dependencies( + const xtypes::TypeIdentifierSeq& id_seq, + const fastdds::rtps::GUID_t& type_server, + const std::vector& continuation_point) const +{ + TypeLookup_getTypeDependencies_In in; + in.type_ids(id_seq); + if (!continuation_point.empty()) + { + in.continuation_point(continuation_point); + } + + // Create a generic TypeLookup_Request + TypeLookup_RequestPubSubType type; + TypeLookup_Request* request = create_request(type_server, type); + + // Add the specific data to the request + request->data().getTypeDependencies(in); + + SampleIdentity id = INVALID_SAMPLE_IDENTITY; + if (send(*request)) + { + id = request->header().requestId(); + } + // Delete request data after sending + type.delete_data(request); + return id; +} + +SampleIdentity TypeLookupManager::get_types( + const xtypes::TypeIdentifierSeq& id_seq, + const fastdds::rtps::GUID_t& type_server) const +{ + TypeLookup_getTypes_In in; + in.type_ids(id_seq); + + // Create a generic TypeLookup_Request + TypeLookup_RequestPubSubType type; + TypeLookup_Request* request = create_request(type_server, type); + + // Add the specific data to the request + request->data().getTypes(in); + + SampleIdentity id = INVALID_SAMPLE_IDENTITY; + if (send(*request)) + { + id = request->header().requestId(); + } + // Delete request data after sending + type.delete_data(request); + return id; +} + +ReturnCode_t TypeLookupManager::async_get_type( + eprosima::ProxyPool::smart_ptr& temp_writer_data, + const fastdds::rtps::GUID_t& type_server, + const AsyncGetTypeWriterCallback& callback) +{ + return check_type_identifier_received( + temp_writer_data, type_server, callback, async_get_type_writer_callbacks_); +} + +ReturnCode_t TypeLookupManager::async_get_type( + eprosima::ProxyPool::smart_ptr& temp_reader_data, + const fastdds::rtps::GUID_t& type_server, + const AsyncGetTypeReaderCallback& callback) +{ + return check_type_identifier_received( + temp_reader_data, type_server, callback, async_get_type_reader_callbacks_); +} + +TypeKind TypeLookupManager::get_type_kind_to_propagate() const +{ + switch (type_propagation_) + { + case utils::TypePropagation::TYPEPROPAGATION_DISABLED: + return xtypes::TK_NONE; + case utils::TypePropagation::TYPEPROPAGATION_ENABLED: + return xtypes::EK_COMPLETE; + case utils::TypePropagation::TYPEPROPAGATION_MINIMAL_BANDWIDTH: + return xtypes::EK_MINIMAL; + case utils::TypePropagation::TYPEPROPAGATION_REGISTRATION_ONLY: + return xtypes::TK_NONE; + default: + return xtypes::EK_COMPLETE; + } +} + +template +ReturnCode_t TypeLookupManager::check_type_identifier_received( + typename eprosima::ProxyPool::smart_ptr& temp_proxy_data, + const fastdds::rtps::GUID_t& type_server, + const AsyncCallback& callback, + std::unordered_map>>& async_get_type_callbacks) +{ + xtypes::TypeIdentfierWithSize type_identifier_with_size = + temp_proxy_data->type_information.type_information.complete().typeid_with_size().type_id()._d() != + TK_NONE ? + temp_proxy_data->type_information.type_information.complete().typeid_with_size() : + temp_proxy_data->type_information.type_information.minimal().typeid_with_size(); + + // Check if the type is known + if (fastdds::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + is_type_identifier_known(type_identifier_with_size)) + { + // The type is already known, invoke the callback + callback(RETCODE_OK, temp_proxy_data.get()); + return RETCODE_OK; + } + + { + // Check if TypeIdentfierWithSize already exists in the map + std::lock_guard lock(async_get_types_mutex_); + auto it = async_get_type_callbacks.find(type_identifier_with_size); + if (it != async_get_type_callbacks.end()) + { + // TypeIdentfierWithSize exists, add the callback + // Make a copy of the proxy to free the EDP pool + ProxyType* temp_proxy_data_copy(new ProxyType(*temp_proxy_data)); + it->second.push_back(std::make_pair(temp_proxy_data_copy, callback)); + // Return without sending new request + return RETCODE_NO_DATA; + } + } + + // TypeIdentfierWithSize doesn't exist, create a new entry + SampleIdentity get_type_dependencies_request = get_type_dependencies( + {type_identifier_with_size.type_id()}, type_server); + if (INVALID_SAMPLE_IDENTITY != get_type_dependencies_request) + { + // Store the sent requests and callback + add_async_get_type_request(get_type_dependencies_request, type_identifier_with_size); + std::vector> types; + // Make a copy of the proxy to free the EDP pool + ProxyType* temp_proxy_data_copy(new ProxyType(*temp_proxy_data)); + types.push_back(std::make_pair(temp_proxy_data_copy, callback)); + async_get_type_callbacks.emplace(type_identifier_with_size, std::move(types)); + + return RETCODE_NO_DATA; + } + else + { + // Failed to send request, return error + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Failed to send get_type_dependencies request"); + return RETCODE_ERROR; + } +} + +void TypeLookupManager::notify_callbacks( + ReturnCode_t request_ret_status, + const xtypes::TypeIdentfierWithSize& type_identifier_with_size) +{ + bool removed = false; + // Check that type is pending to be resolved + auto writer_callbacks_it = async_get_type_writer_callbacks_.find(type_identifier_with_size); + if (writer_callbacks_it != async_get_type_writer_callbacks_.end()) + { + for (auto& proxy_callback_pair : writer_callbacks_it->second) + { + proxy_callback_pair.second(request_ret_status, proxy_callback_pair.first); + } + removed = true; + } + + auto reader_callbacks_it = async_get_type_reader_callbacks_.find(type_identifier_with_size); + if (reader_callbacks_it != async_get_type_reader_callbacks_.end()) + { + for (auto& proxy_callback_pair : reader_callbacks_it->second) + { + proxy_callback_pair.second(request_ret_status, proxy_callback_pair.first); + } + removed = true; + } + + if (removed) + { + // Erase the solved TypeIdentfierWithSize + remove_async_get_type_callback(type_identifier_with_size); + } +} + +bool TypeLookupManager::add_async_get_type_request( + const SampleIdentity& request, + const xtypes::TypeIdentfierWithSize& type_identifier_with_size) +{ + std::lock_guard lock(async_get_types_mutex_); + try + { + async_get_type_requests_.emplace(request, type_identifier_with_size); + return true; + } + catch (const std::exception& e) + { + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, + "Error in TypeLookupManager::add_async_get_type_request: " << e.what()); + return false; + } + +} + +bool TypeLookupManager::remove_async_get_type_callback( + const xtypes::TypeIdentfierWithSize& type_identifier_with_size) +{ + std::lock_guard lock(async_get_types_mutex_); + try + { + bool removed = false; + + // Check if the key is in the writer map + auto writer_it = async_get_type_writer_callbacks_.find(type_identifier_with_size); + if (writer_it != async_get_type_writer_callbacks_.end()) + { + // Delete the proxies and remove the entry + for (auto& proxy_callback_pair : writer_it->second) + { + delete proxy_callback_pair.first; + } + async_get_type_writer_callbacks_.erase(writer_it); + removed = true; + } + // Check if the key is in the reader map + auto reader_it = async_get_type_reader_callbacks_.find(type_identifier_with_size); + if (reader_it != async_get_type_reader_callbacks_.end()) + { + // Delete the proxies and remove the entry + for (auto& proxy_callback_pair : reader_it->second) + { + delete proxy_callback_pair.first; + } + async_get_type_reader_callbacks_.erase(reader_it); + removed = true; + } + + if (!removed) + { + // If not found in either map, log an error + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, + "Error in TypeLookupManager::remove_async_get_type_callback: Key not found"); + } + return removed; + } + catch (const std::exception& e) + { + // Log any exception that might occur during erasure + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, + "Error in TypeLookupManager::remove_async_get_type_callback: " << e.what()); + return false; + } + +} + +bool TypeLookupManager::remove_async_get_type_request( + SampleIdentity request) +{ + std::unique_lock lock(async_get_types_mutex_); + try + { + async_get_type_requests_.erase(request); + return true; + } + catch (const std::exception& e) + { + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, + "Error in TypeLookupManager::remove_async_get_type_request: " << e.what()); + return false; + } +} + +bool TypeLookupManager::create_endpoints() +{ + bool ret = true; + + // Built-in history attributes. + HistoryAttributes hatt; + hatt.initialReservedCaches = 20; + hatt.maximumReservedCaches = 1000; + hatt.payloadMaxSize = TypeLookupManager::typelookup_data_max_size; + + WriterAttributes watt = participant_->pdp()->create_builtin_writer_attributes(); + watt.endpoint.remoteLocatorList = builtin_protocols_->m_initialPeersList; + watt.endpoint.topicKind = fastdds::rtps::NO_KEY; + watt.endpoint.durabilityKind = fastdds::rtps::VOLATILE; + watt.mode = fastdds::rtps::ASYNCHRONOUS_WRITER; + + ReaderAttributes ratt = participant_->pdp()->create_builtin_reader_attributes(); + ratt.endpoint.remoteLocatorList = builtin_protocols_->m_initialPeersList; + ratt.expects_inline_qos = true; + ratt.endpoint.topicKind = fastdds::rtps::NO_KEY; + ratt.endpoint.durabilityKind = fastdds::rtps::VOLATILE; + + // Built-in request writer + request_listener_ = new TypeLookupRequestListener(this); + builtin_request_writer_history_ = new WriterHistory(hatt); + + RTPSWriter* req_writer; + if (participant_->createWriter( + &req_writer, + watt, + builtin_request_writer_history_, + request_listener_, + fastdds::rtps::c_EntityId_TypeLookup_request_writer, + true)) + { + builtin_request_writer_ = dynamic_cast(req_writer); + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Builtin Typelookup request writer created."); + } + else + { + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Typelookup request writer creation failed."); + ret = false; + } + + // Built-in request reader + builtin_request_reader_history_ = new ReaderHistory(hatt); + + RTPSReader* req_reader; + if (participant_->createReader( + &req_reader, + ratt, + builtin_request_reader_history_, + request_listener_, + fastdds::rtps::c_EntityId_TypeLookup_request_reader, + true)) + { + builtin_request_reader_ = dynamic_cast(req_reader); + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Builtin Typelookup request reader created."); + } + else + { + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Typelookup request reader creation failed."); + ret = false; + } + + // Built-in reply writer + reply_listener_ = new TypeLookupReplyListener(this); + builtin_reply_writer_history_ = new WriterHistory(hatt); + + RTPSWriter* rep_writer; + if (participant_->createWriter( + &rep_writer, + watt, + builtin_reply_writer_history_, + reply_listener_, + fastdds::rtps::c_EntityId_TypeLookup_reply_writer, + true)) + { + builtin_reply_writer_ = dynamic_cast(rep_writer); + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Builtin Typelookup reply writer created."); + } + else + { + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Typelookup reply writer creation failed."); + ret = false; + } + + // Built-in reply reader + builtin_reply_reader_history_ = new ReaderHistory(hatt); + + RTPSReader* rep_reader; + if (participant_->createReader( + &rep_reader, + ratt, + builtin_reply_reader_history_, + reply_listener_, + fastdds::rtps::c_EntityId_TypeLookup_reply_reader, + true)) + { + builtin_reply_reader_ = dynamic_cast(rep_reader); + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Builtin Typelookup reply reader created."); + } + else + { + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Typelookup reply reader creation failed."); + ret = false; + } + + // Clean up if something failed. + if (!ret) + { + if (nullptr != builtin_request_writer_history_) + { + delete builtin_request_writer_history_; + builtin_request_writer_history_ = nullptr; + } + + if (nullptr != builtin_reply_writer_history_) + { + delete builtin_reply_writer_history_; + builtin_reply_writer_history_ = nullptr; + } + + if (nullptr != builtin_request_reader_history_) + { + delete builtin_request_reader_history_; + builtin_request_reader_history_ = nullptr; + } + + if (nullptr != builtin_reply_reader_history_) + { + delete builtin_reply_reader_history_; + builtin_reply_reader_history_ = nullptr; + } + + if (nullptr != request_listener_) + { + delete request_listener_; + request_listener_ = nullptr; + } + if (nullptr != reply_listener_) + { + delete reply_listener_; + reply_listener_ = nullptr; + } + } + + return ret; +} + +TypeLookup_Request* TypeLookupManager::create_request( + const fastdds::rtps::GUID_t& type_server, + TypeLookup_RequestPubSubType& pupsubtype) const +{ + TypeLookup_Request* request = static_cast(pupsubtype.create_data()); + request->header().instanceName() = get_instance_name(type_server); + request->header().requestId().writer_guid(guid_rtps_2_dds(builtin_request_writer_->getGuid())); + request->header().requestId().sequence_number(sequence_number_rtps_2_dds(request_seq_number_)); + request_seq_number_++; + return request; +} + +bool TypeLookupManager::send( + TypeLookup_Request& request) const +{ + if (!send_impl(request, &request_type_, builtin_request_writer_history_)) + { + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE, "Error sending request."); + return false; + } + return true; +} + +bool TypeLookupManager::send( + TypeLookup_Reply& reply) const +{ + if (!send_impl(reply, &reply_type_, builtin_reply_writer_history_)) + { + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE, "Error sending reply."); + return false; + } + return true; +} + +template +bool TypeLookupManager::send_impl( + Type& msg, + PubSubType* pubsubtype, + fastdds::rtps::WriterHistory* writer_history) const +{ + // Calculate the serialized size of the message using a CdrSizeCalculator + eprosima::fastcdr::CdrSizeCalculator calculator(eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + uint32_t payload_size = static_cast(calculator.calculate_serialized_size(msg, current_alignment) + 4); + + // Create a new CacheChange_t using the provided StatefulWriter + CacheChange_t* change = writer_history->create_change(payload_size, ALIVE); + + // Check if the creation of CacheChange_t was successful + if (!change) + { + return false; + } + + // Serialize the message using the provided PubSubType + bool result = pubsubtype->serialize(&msg, change->serializedPayload, + DataRepresentationId_t::XCDR2_DATA_REPRESENTATION); + // If serialization was successful, update the change and add it to the WriterHistory + if (result) + { + result = writer_history->add_change(change); + } + // If adding the change to WriterHistory failed, remove the change + if (!result) + { + writer_history->remove_change(change); + } + + return result; +} + +bool TypeLookupManager::prepare_receive_payload( + fastdds::rtps::CacheChange_t& change, + SerializedPayload_t& payload) const +{ + CDRMessage_t msg(change.serializedPayload); + msg.pos += 1; + + payload.max_size = change.serializedPayload.max_size; + payload.length = change.serializedPayload.length; + payload.data = change.serializedPayload.data; + return true; +} + +bool TypeLookupManager::receive( + fastdds::rtps::CacheChange_t& change, + TypeLookup_Request& request) const +{ + if (!receive_impl(change, request, &request_type_)) + { + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE, "Error receiving request."); + return false; + } + + //Compare only the "dds.builtin.TOS." + guid.guidPrefix + if ((request.header().instanceName().to_string()).substr(0, 40) != local_instance_name_.substr(0, 40)) + { + // Ignore request + return false; + } + return true; +} + +bool TypeLookupManager::receive( + fastdds::rtps::CacheChange_t& change, + TypeLookup_Reply& reply) const +{ + if (!receive_impl(change, reply, &reply_type_)) + { + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE, "Error receiving reply."); + return false; + } + + if (guid_dds_2_rtps(reply.header().relatedRequestId().writer_guid()) != builtin_request_writer_->getGuid()) + { + // Ignore reply + return false; + } + return true; +} + +template +bool TypeLookupManager::receive_impl( + fastdds::rtps::CacheChange_t& change, + Type& msg, + PubSubType* pubsubtype) const +{ + SerializedPayload_t payload; + if (!prepare_receive_payload(change, payload)) + { + return false; + } + + bool result = pubsubtype->deserialize(payload, &msg); + payload.data = nullptr; + + return result; +} + +std::string TypeLookupManager::get_instance_name( + const fastdds::rtps::GUID_t guid) const +{ + std::stringstream ss; + ss << std::hex; + for (const auto& elem : guid.guidPrefix.value) + { + ss << std::setw(2) << std::setfill('0') << static_cast(elem); + } + for (const auto& elem : guid.entityId.value) + { + ss << std::setw(2) << std::setfill('0') << static_cast(elem); + } + + std::string str = ss.str(); + std::transform(str.begin(), str.end(), str.begin(), + [](unsigned char c) + { + return static_cast(std::tolower(c)); + }); + return "dds.builtin.TOS." + str; +} + +void TypeLookupManager::remove_builtin_request_writer_history_change( + fastdds::rtps::CacheChange_t* change) +{ + builtin_request_writer_history_->remove_change(change); +} + +void TypeLookupManager::remove_builtin_reply_writer_history_change( + fastdds::rtps::CacheChange_t* change) +{ + builtin_reply_writer_history_->remove_change(change); +} + +} // namespace builtin + +} // namespace dds +} // namespace fastdds +} // namespace eprosima diff --git a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupReplyListener.cpp b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupReplyListener.cpp new file mode 100644 index 00000000000..d13d27fbda4 --- /dev/null +++ b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupReplyListener.cpp @@ -0,0 +1,358 @@ +// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file TypeLookupReplyListener.cpp + * + */ + +#include +#include + +#include +#include +#include + +using eprosima::fastdds::rtps::RTPSReader; +using eprosima::fastdds::rtps::CacheChange_t; +using eprosima::fastdds::rtps::c_EntityId_TypeLookup_reply_writer; + +namespace eprosima { +namespace fastdds { +namespace dds { +namespace builtin { + +TypeLookupReplyListener::TypeLookupReplyListener( + TypeLookupManager* manager) + : typelookup_manager_(manager) +{ + start_reply_processor_thread(); +} + +TypeLookupReplyListener::~TypeLookupReplyListener() +{ + stop_reply_processor_thread(); +} + +void TypeLookupReplyListener::start_reply_processor_thread() +{ + std::unique_lock guard(replies_processor_cv_mutex_); + // Check if is not already in progress and the thread is not joinable + if (!processing_ && !replies_processor_thread.joinable()) + { + processing_ = true; + // Lambda function to be executed by the thread + auto thread_func = [this]() + { + process_reply(); + }; + // Create and start the processing thread + replies_processor_thread = eprosima::create_thread(thread_func, + typelookup_manager_->participant_->get_const_attributes().typelookup_service_thread, + "dds.tls.replies.%u"); + } +} + +void TypeLookupReplyListener::stop_reply_processor_thread() +{ + { + // Set processing_ to false to signal the processing thread to stop + std::unique_lock guard(replies_processor_cv_mutex_); + processing_ = false; + } + + if (replies_processor_thread.joinable()) + { + // Notify the processing thread to wake up and check the exit condition + replies_processor_cv_.notify_all(); + // Check if the calling thread is not the processing thread and join it + if (!replies_processor_thread.is_calling_thread()) + { + replies_processor_thread.join(); + } + } +} + +void TypeLookupReplyListener::process_reply() +{ + std::unique_lock guard(replies_processor_cv_mutex_); + + while (processing_) + { + // Wait until either processing is done or there are replies in the queue + replies_processor_cv_.wait(guard, + [&]() + { + return !processing_ || !replies_queue_.empty(); + }); + + if (!replies_queue_.empty()) + { + TypeLookup_Reply& reply = replies_queue_.front().reply; + + // Check if the received reply SampleIdentity corresponds to an outstanding request + auto& request_id {reply.header().relatedRequestId()}; + auto request_it = typelookup_manager_->async_get_type_requests_.find(request_id); + if (request_it != typelookup_manager_->async_get_type_requests_.end()) + { + xtypes::TypeIdentfierWithSize type_id {request_it->second}; + // Process the TypeLookup_Reply based on its type + switch (reply.return_value()._d()) + { + case TypeLookup_getTypes_HashId: + { + if (RETCODE_OK == reply.return_value().getType()._d()) + { + check_get_types_reply(request_id, type_id, + reply.return_value().getType().result(), reply.header().relatedRequestId()); + } + else + { + typelookup_manager_->notify_callbacks(RETCODE_NO_DATA, type_id); + typelookup_manager_->remove_async_get_type_request(request_id); + } + break; + } + case TypeLookup_getDependencies_HashId: + { + if (RETCODE_OK == reply.return_value().getTypeDependencies()._d()) + { + check_get_type_dependencies_reply( + request_id, type_id, replies_queue_.front().type_server, + reply.return_value().getTypeDependencies().result()); + } + else + { + typelookup_manager_->notify_callbacks(RETCODE_NO_DATA, type_id); + typelookup_manager_->remove_async_get_type_request(request_id); + } + break; + } + default: + // If the type of request is not known, log an error + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REPLY_LISTENER, + "Received unknown reply operation type in type lookup service."); + break; + } + } + // Remove the requests from the queue + replies_queue_.pop(); + } + } +} + +void TypeLookupReplyListener::check_get_types_reply( + const SampleIdentity& request_id, + const xtypes::TypeIdentfierWithSize& type_id, + const TypeLookup_getTypes_Out& reply, + SampleIdentity related_request) +{ + ReturnCode_t register_result = RETCODE_OK; + + if (0 != reply.types().size()) + { + for (xtypes::TypeIdentifierTypeObjectPair pair : reply.types()) + { + xtypes::TypeIdentifierPair type_ids; + type_ids.type_identifier1(pair.type_identifier()); + if (RETCODE_OK != fastdds::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + register_type_object(pair.type_object(), type_ids, false)) + { + // If any of the types is not registered, log error + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REPLY_LISTENER, + "Error registering remote type."); + register_result = RETCODE_ERROR; + } + } + + if (RETCODE_OK == register_result) + { + // Check if the get_type_dependencies related to this reply required a continuation_point + std::unique_lock guard(replies_with_continuation_mutex_); + auto it = std::find(replies_with_continuation_.begin(), + replies_with_continuation_.end(), related_request); + if (it != replies_with_continuation_.end()) + { + // If it did, remove it from the list and continue + replies_with_continuation_.erase(it); + } + else + { + // If it did not, check that the type that originated the request is consistent + // before notifying the callbacks associated with the request + try + { + xtypes::TypeObject type_object; + fastdds::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer().get_type_object( + type_id.type_id(), type_object); + xtypes::TypeObjectUtils::type_object_consistency(type_object); + xtypes::TypeIdentifierPair type_ids; + if (RETCODE_OK != + fastdds::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + register_type_object(type_object, type_ids, true)) + { + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REPLY_LISTENER, + "Cannot register minimal of remote type"); + } + + typelookup_manager_->notify_callbacks(RETCODE_OK, type_id); + } + catch (const std::exception& exception) + { + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE_REPLY_LISTENER, + "Error registering remote type: " << exception.what()); + } + } + } + } + else + { + typelookup_manager_->notify_callbacks(RETCODE_NO_DATA, type_id); + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REPLY_LISTENER, + "Received reply with no types."); + register_result = RETCODE_ERROR; + } + + // Remove the processed SampleIdentity from the outstanding requests + typelookup_manager_->remove_async_get_type_request(request_id); +} + +void TypeLookupReplyListener::check_get_type_dependencies_reply( + const SampleIdentity& request_id, + const xtypes::TypeIdentfierWithSize& type_id, + const fastdds::rtps::GUID_t type_server, + const TypeLookup_getTypeDependencies_Out& reply) +{ + // Add the dependent types to the list for the get_type request + xtypes::TypeIdentifierSeq needed_types; + std::unordered_set unique_types; + + for (xtypes::TypeIdentfierWithSize type : reply.dependent_typeids()) + { + // Check if the type is known + if (!fastdds::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + is_type_identifier_known(type)) + { + // Insert the type into the unordered_set and check if the insertion was successful + if (unique_types.insert(type.type_id()).second) + { + // If the insertion was successful, it means the type was not already in the set + needed_types.push_back(type.type_id()); + } + // If the insertion was not successful, the type is a duplicate and can be ignored + } + } + + // If there is no continuation point, add the parent type + if (reply.continuation_point().empty()) + { + needed_types.push_back(type_id.type_id()); + } + // Make a new request with the continuation point + else + { + SampleIdentity next_request_id = typelookup_manager_-> + get_type_dependencies({type_id.type_id()}, type_server, + reply.continuation_point()); + if (INVALID_SAMPLE_IDENTITY != next_request_id) + { + // Store the sent requests and associated TypeIdentfierWithSize + typelookup_manager_->add_async_get_type_request(next_request_id, type_id); + } + else + { + // Failed to send request + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE_REPLY_LISTENER, "Failed to send get_type_dependencies request"); + } + } + + // Send the type request + SampleIdentity get_types_request = typelookup_manager_->get_types(needed_types, type_server); + + if (INVALID_SAMPLE_IDENTITY != get_types_request) + { + // Store the type request + typelookup_manager_->add_async_get_type_request(get_types_request, type_id); + + // If this get_types request has a continuation_point, store it in the list + if (!reply.continuation_point().empty()) + { + std::unique_lock guard(replies_with_continuation_mutex_); + replies_with_continuation_.push_back(get_types_request); + } + } + else + { + // Failed to send request + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE_REPLY_LISTENER, "Failed to send get_types request"); + } + + // Remove the processed SampleIdentity from the outstanding requests + typelookup_manager_->remove_async_get_type_request(request_id); +} + +void TypeLookupReplyListener::on_new_cache_change_added( + RTPSReader* reader, + const CacheChange_t* const change_in) +{ + CacheChange_t* change = const_cast(change_in); + + // Check if the data is received from the expected TypeLookup Reply writer + if (change->writerGUID.entityId != c_EntityId_TypeLookup_reply_writer) + { + // Log a warning and remove the change from the history + EPROSIMA_LOG_WARNING(TL_REPLY_READER, "Received data from a bad endpoint."); + reader->get_history()->remove_change(change); + return; + } + + // Process the received TypeLookup Reply and handle different types of replies + TypeLookup_Reply reply; + if (typelookup_manager_->receive(*change, reply)) + { + // Check if the reply has any exceptions + if (reply.header().remoteEx() != rpc::RemoteExceptionCode_t::REMOTE_EX_OK) + { + // TODO: Implement specific handling for each exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REPLY_LISTENER, + "Received reply with exception code: " << static_cast(reply.header().remoteEx())); + // If the reply was not ok, ignore it + return; + } + + { + std::unique_lock guard(replies_processor_cv_mutex_); + // Add reply to the processing queue + replies_queue_.push(ReplyWithServerGUID{reply, change->writerGUID}); + // Notify processor + replies_processor_cv_.notify_all(); + } + } + + // Remove the processed cache change from the history + reader->get_history()->remove_change(change); +} + +void TypeLookupReplyListener::on_writer_change_received_by_all( + fastdds::rtps::RTPSWriter*, + fastdds::rtps::CacheChange_t* change) +{ + typelookup_manager_->remove_builtin_reply_writer_history_change(change); +} + +} // namespace builtin + +} // namespace dds +} // namespace fastdds +} // namespace eprosima diff --git a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupRequestListener.cpp b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupRequestListener.cpp new file mode 100644 index 00000000000..e13759f3794 --- /dev/null +++ b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupRequestListener.cpp @@ -0,0 +1,499 @@ +// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file TypeLookupRequestListener.cpp + * + */ + +#include + +#include + +#include +#include +#include +#include + +using eprosima::fastdds::rtps::RTPSReader; +using eprosima::fastdds::rtps::CacheChange_t; +using eprosima::fastdds::dds::Log; + +using eprosima::fastdds::rtps::c_EntityId_TypeLookup_request_writer; + +namespace eprosima { +namespace fastdds { +namespace dds { +namespace builtin { + +//! Constant that specifies the maximum number of dependent types to be included per reply. +//! This number is calculated considering the MTU. +const int32_t MAX_DEPENDENCIES_PER_REPLY = 75; + +/** + * @brief Calculates the opaque value of continuation point. + * @param continuation_point[in] The continuation point. + * @return The value of the continuation_point. + */ +inline size_t calculate_continuation_point( + const std::vector& continuation_point) +{ + size_t result = 0; + for (size_t i = 0; i < continuation_point.size(); ++i) + { + result = (result << 8) | continuation_point[i]; + } + return result; +} + +/** + * @brief Creates a continuation point with the given value. + * @param value[in] The desired value. + * @return The continuation_point. + */ +inline std::vector create_continuation_point( + size_t value) +{ + std::vector continuation_point(32, 0); + + for (size_t value_i = 0; value_i < value; value_i++) + { + for (size_t i = continuation_point.size() - 1; i != SIZE_MAX; --i) + { + if (continuation_point[i] < 255) + { + ++continuation_point[i]; + // Break after successful increment + break; + } + else + { + continuation_point[i] = 0; + } + } + } + return continuation_point; +} + +TypeLookupRequestListener::TypeLookupRequestListener( + TypeLookupManager* manager) + : typelookup_manager_(manager) +{ + start_request_processor_thread(); +} + +TypeLookupRequestListener::~TypeLookupRequestListener() +{ + stop_request_processor_thread(); +} + +void TypeLookupRequestListener::start_request_processor_thread() +{ + std::unique_lock guard(request_processor_cv_mutex_); + // Check if is not already in progress and the thread is not joinable + if (!processing_ && !request_processor_thread.joinable()) + { + processing_ = true; + // Lambda function to be executed by the thread + auto thread_func = [this]() + { + process_requests(); + }; + // Create and start the processing thread + request_processor_thread = eprosima::create_thread(thread_func, + typelookup_manager_->participant_->get_const_attributes().typelookup_service_thread, + "dds.tls.requests.%u"); + } +} + +void TypeLookupRequestListener::stop_request_processor_thread() +{ + { + // Set processing_ to false to signal the processing thread to stop + std::unique_lock guard(request_processor_cv_mutex_); + processing_ = false; + } + + if (request_processor_thread.joinable()) + { + // Notify the processing thread to wake up and check the exit condition + request_processor_cv_.notify_all(); + // Check if the calling thread is not the processing thread and join it + if (!request_processor_thread.is_calling_thread()) + { + request_processor_thread.join(); + } + } +} + +void TypeLookupRequestListener::process_requests() +{ + std::unique_lock guard(request_processor_cv_mutex_); + + while (processing_) + { + // Wait until either processing is done or there are requests in the queue + request_processor_cv_.wait(guard, + [&]() + { + return !processing_ || !requests_queue_.empty(); + }); + + if (!requests_queue_.empty()) + { + std::pair& request = requests_queue_.front(); + { + // Process the TypeLookup_Request based on its type + switch (request.first.data()._d()) + { + case TypeLookup_getTypes_HashId: + { + check_get_types_request(request.first.header().requestId(), + request.first.data().getTypes(), request.second); + break; + } + case TypeLookup_getDependencies_HashId: + { + check_get_type_dependencies_request(request.first.header().requestId(), + request.first.data().getTypeDependencies()); + break; + } + default: + // If the type of request is not known, log an error and answer with an exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Received unknown request in type lookup service."); + answer_request(request.first.header().requestId(), + rpc::RemoteExceptionCode_t::REMOTE_EX_UNKNOWN_OPERATION); + break; + } + } + // Remove the requests from the queue + requests_queue_.pop(); + } + } +} + +void TypeLookupRequestListener::check_get_types_request( + SampleIdentity request_id, + const TypeLookup_getTypes_In& request, + const rtps::VendorId_t& vendor_id) +{ + xtypes::TypeKind type_to_propagate = typelookup_manager_->get_type_kind_to_propagate(); + + // Early return in case type propagation is disabled + if (xtypes::TK_NONE == type_to_propagate) + { + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "getTypes request received for a participant with type propagation disabled."); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_UNKNOWN_EXCEPTION); + return; + } + + TypeLookup_getTypes_Out out; + ReturnCode_t type_result = RETCODE_ERROR; + xtypes::TypeObject obj; + xtypes::TypeIdentifier reply_typeid; + xtypes::TypeIdentifier complete_id; + xtypes::TypeIdentifier minimal_id; + + if (0 == request.type_ids().size()) + { + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Received request with no type identifiers."); + } + + // Iterate through requested type_ids + for (const xtypes::TypeIdentifier& type_id : request.type_ids()) + { + // If TypeIdentifier is EK_MINIMAL add complete_to_minimal to answer + if (type_id._d() == xtypes::EK_MINIMAL && rtps::c_VendorId_opendds != vendor_id) + { + minimal_id = type_id; + reply_typeid = minimal_id; + + // Get complete TypeIdentifier from registry + complete_id = fastdds::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + get_complementary_type_identifier(minimal_id); + + if (xtypes::EK_COMPLETE == type_to_propagate) + { + reply_typeid = complete_id; + + xtypes::TypeIdentifierPair id_pair; + id_pair.type_identifier1(complete_id); + id_pair.type_identifier2(minimal_id); + + // Add the id pair to the result + out.complete_to_minimal().push_back(std::move(id_pair)); + } + + } + else + { + reply_typeid = type_id; + } + + type_result = fastdds::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + get_type_object(reply_typeid, obj); + + if (RETCODE_OK != type_result) + { + // If any object is unknown, abort and answer with exception + break; + } + + xtypes::TypeIdentifierTypeObjectPair id_obj_pair; + id_obj_pair.type_identifier(reply_typeid); + id_obj_pair.type_object(obj); + // Add the id/obj pair to the result + out.types().push_back(std::move(id_obj_pair)); + } + + // Handle the result based on the type_result + if (RETCODE_OK == type_result) + { + // Prepare and send the reply for successful operation + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_OK, out); + } + else if (RETCODE_NO_DATA == type_result) + { + // Log error for type not found and reply with appropriate exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Requested TypeIdentifier is not found in the registry."); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_UNKNOWN_EXCEPTION); + } + else if (RETCODE_PRECONDITION_NOT_MET == type_result) + { + // Log error for invalid argument and reply with appropriate exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Requested TypeIdentifier is not a direct hash."); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_INVALID_ARGUMENT); + } +} + +void TypeLookupRequestListener::check_get_type_dependencies_request( + SampleIdentity request_id, + const TypeLookup_getTypeDependencies_In& request) +{ + std::unordered_set* type_dependencies_ptr {nullptr}; + std::unordered_set type_dependencies; + ReturnCode_t type_dependencies_result = RETCODE_ERROR; + if (!request.type_ids().empty()) + { + // Check if the received request has been done before and needed a continuation point + if (!request.continuation_point().empty()) + { + auto requests_it = requests_with_continuation_.find(request.type_ids()); + if (requests_it != requests_with_continuation_.end()) + { + // Get the dependencies without checking the registry + type_dependencies_ptr = &requests_it->second; + type_dependencies_result = RETCODE_OK; + } + else + { + // If the the received request is not found, log error and answer with exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Error processing ongoing type dependencies request."); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_UNKNOWN_EXCEPTION); + } + } + else + { + // Get the dependencies from the registry + type_dependencies_result = + fastdds::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + get_type_dependencies(request.type_ids(), type_dependencies); + + // If there are too many dependent types, store the type dependencies for future requests + if (type_dependencies_result == RETCODE_OK && type_dependencies.size() > MAX_DEPENDENCIES_PER_REPLY) + { + auto ret = requests_with_continuation_.emplace(request.type_ids(), std::move(type_dependencies)); + type_dependencies_ptr = &ret.first->second; + } + else + { + type_dependencies_ptr = &type_dependencies; + } + } + } + else + { + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, "Type dependencies request is empty."); + } + + // Handle the result based on the type_dependencies_result + if (RETCODE_OK == type_dependencies_result) + { + // Prepare and send the reply for successful operation + TypeLookup_getTypeDependencies_Out out = prepare_get_type_dependencies_response( + request.type_ids(), *type_dependencies_ptr, request.continuation_point()); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_OK, out); + } + else if (RETCODE_NO_DATA == type_dependencies_result) + { + // Log error for type not found and reply with appropriate exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Requested TypeIdentifier is not found in the registry."); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_UNKNOWN_EXCEPTION); + } + else if (RETCODE_BAD_PARAMETER == type_dependencies_result) + { + // Log error for invalid argument and reply with appropriate exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Requested TypeIdentifier is not a direct hash."); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_INVALID_ARGUMENT); + } +} + +TypeLookup_getTypeDependencies_Out TypeLookupRequestListener::prepare_get_type_dependencies_response( + const xtypes::TypeIdentifierSeq& id_seq, + const std::unordered_set& type_dependencies, + const std::vector& continuation_point) +{ + TypeLookup_getTypeDependencies_Out out; + + // Check if all dependencies can be sent in a single response + if (type_dependencies.size() < MAX_DEPENDENCIES_PER_REPLY) + { + for (const auto& type_identifier : type_dependencies) + { + out.dependent_typeids().emplace_back(type_identifier); + } + } + else + { + size_t start_index = 0; + // Check if a continuation point is provided, and calculate starting point if there is + if (!continuation_point.empty()) + { + start_index = calculate_continuation_point(continuation_point) * MAX_DEPENDENCIES_PER_REPLY; + } + + // Copy the dependencies within the specified range directly to out + auto start_it = std::next(type_dependencies.begin(), start_index); + auto end_it = std::next(start_it, std::min(MAX_DEPENDENCIES_PER_REPLY, + type_dependencies.size() - start_index)); + for (auto it = start_it; it != end_it; ++it) + { + out.dependent_typeids().emplace_back(*it); + } + + if ((start_index + MAX_DEPENDENCIES_PER_REPLY) > type_dependencies.size()) + { + // If all dependent types have been sent, remove from map + auto requests_it = requests_with_continuation_.find(id_seq); + if (requests_it != requests_with_continuation_.end()) + { + requests_with_continuation_.erase(requests_it); + } + } + else + { + // Set the continuation point for the next request + out.continuation_point(create_continuation_point(calculate_continuation_point(continuation_point) + 1)); + } + } + + return out; +} + +void TypeLookupRequestListener::answer_request( + SampleIdentity request_id, + rpc::RemoteExceptionCode_t exception_code, + TypeLookup_getTypeDependencies_Out& out) +{ + TypeLookup_Reply* reply = static_cast(typelookup_manager_->reply_type_.create_data()); + TypeLookup_getTypeDependencies_Result result; + result.result(out); + reply->return_value().getTypeDependencies(result); + reply->header().relatedRequestId(request_id); + reply->header().remoteEx(exception_code); + + typelookup_manager_->send(*reply); + typelookup_manager_->reply_type_.delete_data(reply); +} + +void TypeLookupRequestListener::answer_request( + SampleIdentity request_id, + rpc::RemoteExceptionCode_t exception_code, + TypeLookup_getTypes_Out& out) +{ + TypeLookup_Reply* reply = static_cast(typelookup_manager_->reply_type_.create_data()); + TypeLookup_getTypes_Result result; + result.result(out); + reply->return_value().getType(result); + reply->header().relatedRequestId(request_id); + reply->header().remoteEx(exception_code); + + typelookup_manager_->send(*reply); + typelookup_manager_->reply_type_.delete_data(reply); +} + +void TypeLookupRequestListener::answer_request( + SampleIdentity request_id, + rpc::RemoteExceptionCode_t exception_code) +{ + TypeLookup_Reply* reply = static_cast(typelookup_manager_->reply_type_.create_data()); + reply->header().relatedRequestId(request_id); + reply->header().remoteEx(exception_code); + + typelookup_manager_->send(*reply); + typelookup_manager_->reply_type_.delete_data(reply); +} + +void TypeLookupRequestListener::on_new_cache_change_added( + RTPSReader* reader, + const CacheChange_t* const changeIN) +{ + CacheChange_t* change = const_cast(changeIN); + + // Check if the data is received from the expected TypeLookup Request writer + if (change->writerGUID.entityId != c_EntityId_TypeLookup_request_writer) + { + // Log a warning and remove the change from the history + EPROSIMA_LOG_WARNING(TL_REQUEST_READER, "Received data from a bad endpoint."); + reader->get_history()->remove_change(change); + return; + } + + // Process the received TypeLookup Request and handle different types of requests + TypeLookup_Request request; + if (typelookup_manager_->receive(*change, request)) + { + { + std::unique_lock guard(request_processor_cv_mutex_); + // Add request to the processing queue + requests_queue_.push({request, change->vendor_id}); + // Notify processor + request_processor_cv_.notify_all(); + } + } + + // Remove the processed cache change from the history + reader->get_history()->remove_change(change); +} + +void TypeLookupRequestListener::on_writer_change_received_by_all( + fastdds::rtps::RTPSWriter*, + fastdds::rtps::CacheChange_t* change) +{ + typelookup_manager_->remove_builtin_request_writer_history_change(change); +} + +} // namespace builtin + +} // namespace dds +} // namespace fastdds +} // namespace eprosima diff --git a/src/cpp/fastdds/domain/DomainParticipantImpl.cpp b/src/cpp/fastdds/domain/DomainParticipantImpl.cpp index 3ceeadba16e..cd737c7b6ec 100644 --- a/src/cpp/fastdds/domain/DomainParticipantImpl.cpp +++ b/src/cpp/fastdds/domain/DomainParticipantImpl.cpp @@ -429,7 +429,7 @@ ReturnCode_t DomainParticipantImpl::set_qos( else { // Trigger update of network interfaces by calling update_attributes with current attributes - patt = rtps_participant->getRTPSParticipantAttributes(); + patt = rtps_participant->copy_attributes(); } } } @@ -623,7 +623,8 @@ ContentFilteredTopic* DomainParticipantImpl::create_contentfilteredtopic( if (related_topic->get_participant() != get_participant()) { - EPROSIMA_LOG_ERROR(PARTICIPANT, "Creating ContentFilteredTopic with name " << name << + EPROSIMA_LOG_ERROR(PARTICIPANT, "Creating ContentFilteredTopic with name " << name + << ": related_topic not from this participant"); return nullptr; } @@ -669,8 +670,8 @@ ContentFilteredTopic* DomainParticipantImpl::create_contentfilteredtopic( filter_factory->create_content_filter(filter_class_name, related_topic->get_type_name().c_str(), type.get(), filter_expression.c_str(), filter_parameters, filter_instance)) { - EPROSIMA_LOG_ERROR(PARTICIPANT, "Could not create filter of class " << filter_class_name << " for expression \"" << - filter_expression); + EPROSIMA_LOG_ERROR(PARTICIPANT, "Could not create filter of class " << filter_class_name << " for expression \"" + << filter_expression); return nullptr; } @@ -2327,7 +2328,8 @@ bool DomainParticipantImpl::can_qos_be_updated( from.wire_protocol().builtin.discovery_config.ignoreParticipantFlags)))) { updatable = false; - EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK, "WireProtocolConfigQos cannot be changed after the participant is enabled, " + EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK, + "WireProtocolConfigQos cannot be changed after the participant is enabled, " << "with the exception of builtin.discovery_config.m_DiscoveryServers"); } else diff --git a/src/cpp/rtps/builtin/BuiltinProtocols.cpp b/src/cpp/rtps/builtin/BuiltinProtocols.cpp index 005c3aa363d..2fe8bce5fec 100644 --- a/src/cpp/rtps/builtin/BuiltinProtocols.cpp +++ b/src/cpp/rtps/builtin/BuiltinProtocols.cpp @@ -90,7 +90,7 @@ bool BuiltinProtocols::initBuiltinProtocols( filter_server_remote_locators(p_part->network_factory()); - const RTPSParticipantAllocationAttributes& allocation = p_part->getRTPSParticipantAttributes().allocation; + const RTPSParticipantAllocationAttributes& allocation = p_part->get_const_attributes().allocation; // PDP switch (m_att.discovery_config.discoveryProtocol) diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp index d8c031fc7d2..73233d7814d 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp @@ -757,7 +757,8 @@ void EDPSimple::assignRemoteEndpoints( const NetworkFactory& network = mp_RTPSParticipant->network_factory(); uint32_t endp = pdata.m_availableBuiltinEndpoints; uint32_t auxendp; - bool use_multicast_locators = !mp_PDP->getRTPSParticipant()->getAttributes().builtin.avoid_builtin_multicast || + bool use_multicast_locators = + !mp_PDP->getRTPSParticipant()->get_const_attributes().builtin.avoid_builtin_multicast || pdata.metatraffic_locators.unicast.empty(); auto temp_reader_proxy_data = get_temporary_reader_proxies_pool().get(); @@ -825,8 +826,8 @@ void EDPSimple::assignRemoteEndpoints( publications_secure_reader_.first->getGuid(), pdata.m_guid, *temp_writer_proxy_data, publications_secure_reader_.first->getAttributes().security_attributes())) { - EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " << - publications_secure_reader_.first->getGuid()); + EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " + << publications_secure_reader_.first->getGuid()); } } @@ -839,8 +840,8 @@ void EDPSimple::assignRemoteEndpoints( publications_secure_writer_.first->getGuid(), pdata.m_guid, *temp_reader_proxy_data, publications_secure_writer_.first->getAttributes().security_attributes())) { - EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " << - publications_secure_writer_.first->getGuid()); + EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " + << publications_secure_writer_.first->getGuid()); } } @@ -855,8 +856,8 @@ void EDPSimple::assignRemoteEndpoints( subscriptions_secure_reader_.first->getGuid(), pdata.m_guid, *temp_writer_proxy_data, subscriptions_secure_reader_.first->getAttributes().security_attributes())) { - EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " << - subscriptions_secure_reader_.first->getGuid()); + EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " + << subscriptions_secure_reader_.first->getGuid()); } } @@ -870,8 +871,8 @@ void EDPSimple::assignRemoteEndpoints( subscriptions_secure_writer_.first->getGuid(), pdata.m_guid, *temp_reader_proxy_data, subscriptions_secure_writer_.first->getAttributes().security_attributes())) { - EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " << - subscriptions_secure_writer_.first->getGuid()); + EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " + << subscriptions_secure_writer_.first->getGuid()); } } #else diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDPStatic.cpp b/src/cpp/rtps/builtin/discovery/endpoint/EDPStatic.cpp index a616dd6669f..bde9c26a27a 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDPStatic.cpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDPStatic.cpp @@ -134,7 +134,8 @@ bool EDPStatic::initEDP( } // Check there is a Participant's property changing the exchange format. - for (auto& property : mp_RTPSParticipant->getAttributes().properties.properties()) + const auto& properties = mp_RTPSParticipant->get_const_attributes().properties.properties(); + for (const auto& property : properties) { if (0 == property.name().compare(exchange_format_property_name)) { @@ -478,8 +479,9 @@ void EDPStatic::assignRemoteEndpoints( else { EPROSIMA_LOG_WARNING(RTPS_EDP, "EDPStaticProperty with type: " << staticproperty.m_endpointType - << " and status " << staticproperty.m_status << - " not recognized"); + << " and status " + << staticproperty.m_status + << " not recognized"); } } else diff --git a/src/cpp/rtps/builtin/discovery/participant/PDP.cpp b/src/cpp/rtps/builtin/discovery/participant/PDP.cpp index 46970fd4792..d455a29f954 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDP.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDP.cpp @@ -178,7 +178,7 @@ ParticipantProxyData* PDP::add_participant_proxy_data( { // Pool is empty but limit has not been reached, so we create a new entry. ++participant_proxies_number_; - ret_val = new ParticipantProxyData(mp_RTPSParticipant->getRTPSParticipantAttributes().allocation); + ret_val = new ParticipantProxyData(mp_RTPSParticipant->get_const_attributes().allocation); if (participant_guid != mp_RTPSParticipant->getGuid()) { ret_val->lease_duration_event = new TimedEvent(mp_RTPSParticipant->getEventResource(), @@ -191,8 +191,10 @@ ParticipantProxyData* PDP::add_participant_proxy_data( } else { - EPROSIMA_LOG_WARNING(RTPS_PDP, "Maximum number of participant proxies (" << max_proxies << \ - ") reached for participant " << mp_RTPSParticipant->getGuid() << std::endl); + EPROSIMA_LOG_WARNING(RTPS_PDP, "Maximum number of participant proxies (" << max_proxies \ + << ") reached for participant " + << mp_RTPSParticipant->getGuid() + << std::endl); return nullptr; } } @@ -238,10 +240,11 @@ bool PDP::data_matches_with_prefix( void PDP::initializeParticipantProxyData( ParticipantProxyData* participant_data) { - RTPSParticipantAttributes& attributes = mp_RTPSParticipant->getAttributes(); + RTPSParticipantMutableAttributes mutable_attrs = mp_RTPSParticipant->get_mutable_attributes(); bool announce_locators = !mp_RTPSParticipant->is_intraprocess_only(); - participant_data->m_leaseDuration = attributes.builtin.discovery_config.leaseDuration; + participant_data->m_leaseDuration = + mp_RTPSParticipant->get_const_attributes().builtin.discovery_config.leaseDuration; //set_VendorId_eProsima(participant_data->m_VendorId); participant_data->m_VendorId = c_VendorId_eProsima; @@ -249,7 +252,7 @@ void PDP::initializeParticipantProxyData( participant_data->m_availableBuiltinEndpoints |= builtin_endpoints_->builtin_endpoints(); - if (attributes.builtin.use_WriterLivelinessProtocol) + if (mp_RTPSParticipant->get_const_attributes().builtin.use_WriterLivelinessProtocol) { participant_data->m_availableBuiltinEndpoints |= BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER; participant_data->m_availableBuiltinEndpoints |= BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER; @@ -263,13 +266,13 @@ void PDP::initializeParticipantProxyData( #endif // if HAVE_SECURITY } - if (attributes.builtin.typelookup_config.use_server) + if (mp_RTPSParticipant->get_const_attributes().builtin.typelookup_config.use_server) { participant_data->m_availableBuiltinEndpoints |= BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REQUEST_DATA_READER; participant_data->m_availableBuiltinEndpoints |= BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REPLY_DATA_WRITER; } - if (attributes.builtin.typelookup_config.use_client) + if (mp_RTPSParticipant->get_const_attributes().builtin.typelookup_config.use_client) { participant_data->m_availableBuiltinEndpoints |= BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REQUEST_DATA_WRITER; participant_data->m_availableBuiltinEndpoints |= BUILTIN_ENDPOINT_TYPELOOKUP_SERVICE_REPLY_DATA_READER; @@ -284,13 +287,14 @@ void PDP::initializeParticipantProxyData( if (announce_locators) { - participant_data->m_networkConfiguration = attributes.builtin.network_configuration; + participant_data->m_networkConfiguration = + mp_RTPSParticipant->get_const_attributes().builtin.network_configuration; - for (const Locator_t& loc : attributes.defaultUnicastLocatorList) + for (const Locator_t& loc : mutable_attrs.defaultUnicastLocatorList) { participant_data->default_locators.add_unicast_locator(loc); } - for (const Locator_t& loc : attributes.defaultMulticastLocatorList) + for (const Locator_t& loc : mp_RTPSParticipant->get_const_attributes().defaultMulticastLocatorList) { participant_data->default_locators.add_multicast_locator(loc); } @@ -308,7 +312,7 @@ void PDP::initializeParticipantProxyData( // If it has not been set, use guid if (persistent == c_GuidPrefix_Unknown) { - persistent = attributes.prefix; + persistent = mp_RTPSParticipant->get_const_attributes().prefix; } // If persistent is set, set it into the participant proxy @@ -342,13 +346,13 @@ void PDP::initializeParticipantProxyData( } fastdds::rtps::network::external_locators::add_external_locators(*participant_data, - attributes.builtin.metatraffic_external_unicast_locators, - attributes.default_external_unicast_locators); + mutable_attrs.builtin.metatraffic_external_unicast_locators, + mutable_attrs.default_external_unicast_locators); } - participant_data->m_participantName = std::string(attributes.getName()); + participant_data->m_participantName = std::string(mp_RTPSParticipant->get_const_attributes().getName()); - participant_data->m_userData = attributes.userData; + participant_data->m_userData = mutable_attrs.userData; #if HAVE_SECURITY if (mp_RTPSParticipant->is_secure()) @@ -388,7 +392,7 @@ bool PDP::initPDP( { EPROSIMA_LOG_INFO(RTPS_PDP, "Beginning"); mp_RTPSParticipant = part; - m_discovery = mp_RTPSParticipant->getAttributes().builtin; + m_discovery = mp_RTPSParticipant->copy_attributes().builtin; initial_announcements_ = m_discovery.discovery_config.initial_announcements; //CREATE ENDPOINTS if (!createPDPEndpoints()) @@ -875,16 +879,21 @@ ReaderProxyData* PDP::addReaderProxyData( { // Pool is empty but limit has not been reached, so we create a new entry. ++reader_proxies_number_; + + const auto& allocations = mp_RTPSParticipant->get_const_attributes().allocation; + ret_val = new ReaderProxyData( - mp_RTPSParticipant->getAttributes().allocation.locators.max_unicast_locators, - mp_RTPSParticipant->getAttributes().allocation.locators.max_multicast_locators, - mp_RTPSParticipant->getAttributes().allocation.data_limits, - mp_RTPSParticipant->getAttributes().allocation.content_filter); + allocations.locators.max_unicast_locators, + allocations.locators.max_multicast_locators, + allocations.data_limits, + allocations.content_filter); } else { - EPROSIMA_LOG_WARNING(RTPS_PDP, "Maximum number of reader proxies (" << max_proxies << - ") reached for participant " << mp_RTPSParticipant->getGuid() << std::endl); + EPROSIMA_LOG_WARNING(RTPS_PDP, "Maximum number of reader proxies (" << max_proxies + << ") reached for participant " + << mp_RTPSParticipant->getGuid() + << std::endl); return nullptr; } } @@ -974,15 +983,20 @@ WriterProxyData* PDP::addWriterProxyData( { // Pool is empty but limit has not been reached, so we create a new entry. ++writer_proxies_number_; + + const auto& allocations = mp_RTPSParticipant->get_const_attributes().allocation; + ret_val = new WriterProxyData( - mp_RTPSParticipant->getAttributes().allocation.locators.max_unicast_locators, - mp_RTPSParticipant->getAttributes().allocation.locators.max_multicast_locators, - mp_RTPSParticipant->getAttributes().allocation.data_limits); + allocations.locators.max_unicast_locators, + allocations.locators.max_multicast_locators, + allocations.data_limits); } else { - EPROSIMA_LOG_WARNING(RTPS_PDP, "Maximum number of writer proxies (" << max_proxies << - ") reached for participant " << mp_RTPSParticipant->getGuid() << std::endl); + EPROSIMA_LOG_WARNING(RTPS_PDP, "Maximum number of writer proxies (" << max_proxies + << ") reached for participant " + << mp_RTPSParticipant->getGuid() + << std::endl); return nullptr; } } @@ -1503,8 +1517,10 @@ void PDP::set_initial_announcement_interval() void PDP::set_external_participant_properties_( ParticipantProxyData* participant_data) { + const RTPSParticipantConstantAttributes& part_attributes = mp_RTPSParticipant->get_const_attributes(); + // For each property add it if it should be sent (it is propagated) - for (auto const& property : mp_RTPSParticipant->getAttributes().properties.properties()) + for (auto const& property : part_attributes.properties.properties()) { if (property.propagate()) { @@ -1515,7 +1531,7 @@ void PDP::set_external_participant_properties_( // Set participant type property // TODO: This could be done somewhere else that makes more sense. std::stringstream participant_type; - participant_type << mp_RTPSParticipant->getAttributes().builtin.discovery_config.discoveryProtocol; + participant_type << part_attributes.builtin.discovery_config.discoveryProtocol; auto ptype = participant_type.str(); participant_data->m_properties.push_back(fastdds::dds::parameter_property_participant_type, ptype); @@ -1528,8 +1544,8 @@ void PDP::set_external_participant_properties_( }; for (auto physical_property_name : physical_property_names) { - std::string* physical_property = PropertyPolicyHelper::find_property( - mp_RTPSParticipant->getAttributes().properties, physical_property_name); + const std::string* physical_property = PropertyPolicyHelper::find_property( + part_attributes.properties, physical_property_name); if (nullptr != physical_property) { participant_data->m_properties.push_back(physical_property_name, *physical_property); @@ -1539,7 +1555,7 @@ void PDP::set_external_participant_properties_( static void set_builtin_matched_allocation( ResourceLimitedContainerConfig& allocation, - const RTPSParticipantAttributes& pattr) + const RTPSParticipantConstantAttributes& pattr) { // Matched endpoints will depend on total number of participants allocation = pattr.allocation.participants; @@ -1561,8 +1577,6 @@ static void set_builtin_endpoint_locators( const PDP* pdp, const BuiltinProtocols* builtin) { - const RTPSParticipantAttributes& pattr = pdp->getRTPSParticipant()->getRTPSParticipantAttributes(); - auto part_data = pdp->getLocalParticipantProxyData(); if (nullptr == part_data) { @@ -1588,14 +1602,15 @@ static void set_builtin_endpoint_locators( // External locators are always taken from the same place endpoint.external_unicast_locators = pdp->builtin_attributes().metatraffic_external_unicast_locators; - endpoint.ignore_non_matching_locators = pattr.ignore_non_matching_locators; + endpoint.ignore_non_matching_locators = + pdp->getRTPSParticipant()->get_const_attributes().ignore_non_matching_locators; } ReaderAttributes PDP::create_builtin_reader_attributes() const { ReaderAttributes attributes; - const RTPSParticipantAttributes& pattr = getRTPSParticipant()->getRTPSParticipantAttributes(); + const RTPSParticipantConstantAttributes& pattr = getRTPSParticipant()->get_const_attributes(); set_builtin_matched_allocation(attributes.matched_writers_allocation, pattr); // Builtin endpoints are always reliable, transient local, keyed topics @@ -1619,7 +1634,7 @@ WriterAttributes PDP::create_builtin_writer_attributes() const { WriterAttributes attributes; - const RTPSParticipantAttributes& pattr = getRTPSParticipant()->getRTPSParticipantAttributes(); + const RTPSParticipantConstantAttributes& pattr = getRTPSParticipant()->get_const_attributes(); set_builtin_matched_allocation(attributes.matched_readers_allocation, pattr); // Builtin endpoints are always reliable, transient local, keyed topics diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp index 5cde65414cb..e124f9d9f68 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp @@ -105,12 +105,10 @@ void PDPClient::initializeParticipantProxyData( { PDP::initializeParticipantProxyData(participant_data); // TODO: Remember that the PDP version USES security - if ( - getRTPSParticipant()->getAttributes().builtin.discovery_config.discoveryProtocol - != DiscoveryProtocol_t::CLIENT - && - getRTPSParticipant()->getAttributes().builtin.discovery_config.discoveryProtocol - != DiscoveryProtocol_t::SUPER_CLIENT ) + const auto& discovery_config = getRTPSParticipant()->get_const_attributes().builtin.discovery_config; + + if ((DiscoveryProtocol::CLIENT != discovery_config.discoveryProtocol) && + (DiscoveryProtocol::SUPER_CLIENT != discovery_config.discoveryProtocol)) { EPROSIMA_LOG_ERROR(RTPS_PDP, "Using a PDP client object with another user's settings"); } @@ -981,7 +979,8 @@ bool load_environment_server_info( const static std::regex ROS2_IPV6_ADDRESSPORT_PATTERN( R"(^\[?((?:[0-9a-fA-F]{0,4}\:){0,7}[0-9a-fA-F]{0,4})?(?:\])?:?(?:(\d+))?$)"); // Regex to handle DNS and UDPv4/6 expressions - const static std::regex ROS2_DNS_DOMAINPORT_PATTERN(R"(^(UDPv[46]?:\[[\w\.:-]{0,63}\]|[\w\.-]{0,63}):?(?:(\d+))?$)"); + const static std::regex ROS2_DNS_DOMAINPORT_PATTERN( + R"(^(UDPv[46]?:\[[\w\.:-]{0,63}\]|[\w\.-]{0,63}):?(?:(\d+))?$)"); // Regex to handle TCPv4/6 expressions const static std::regex ROS2_DNS_DOMAINPORT_PATTERN_TCP( R"(^(TCPv[46]?:\[[\w\.:-]{0,63}\]):?(?:(\d+))?$)"); diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPListener.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPListener.cpp index a6d210faa94..bff1a7290f4 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPListener.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPListener.cpp @@ -51,7 +51,7 @@ namespace rtps { PDPListener::PDPListener( PDP* parent) : parent_pdp_(parent) - , temp_participant_data_(parent->getRTPSParticipant()->getRTPSParticipantAttributes().allocation) + , temp_participant_data_(parent->getRTPSParticipant()->get_const_attributes().allocation) { } @@ -78,10 +78,11 @@ void PDPListener::onNewCacheChangeAdded( GUID_t guid; iHandle2GUID(guid, change->instanceHandle); + RTPSParticipantImpl* part = parent_pdp_->getRTPSParticipant(); if (change->kind == ALIVE) { // Ignore announcement from own RTPSParticipant - if (guid == parent_pdp_->getRTPSParticipant()->getGuid()) + if (guid == part->getGuid()) { EPROSIMA_LOG_INFO(RTPS_PDP, "Message from own RTPSParticipant, removing"); parent_pdp_->builtin_endpoints_->remove_from_pdp_reader_history(change); @@ -106,23 +107,24 @@ void PDPListener::onNewCacheChangeAdded( // Load information on temp_participant_data_ CDRMessage_t msg(change->serializedPayload); temp_participant_data_.clear(); - if (temp_participant_data_.readFromCDRMessage(&msg, true, parent_pdp_->getRTPSParticipant()->network_factory(), - parent_pdp_->getRTPSParticipant()->has_shm_transport(), true, change_in->vendor_id)) + if (temp_participant_data_.readFromCDRMessage(&msg, true, part->network_factory(), + part->has_shm_transport(), true, change_in->vendor_id)) { // After correctly reading it change->instanceHandle = temp_participant_data_.m_key; guid = temp_participant_data_.m_guid; - if (parent_pdp_->getRTPSParticipant()->is_participant_ignored(guid.guidPrefix)) + if (part->is_participant_ignored(guid.guidPrefix)) { return; } // Filter locators - const auto& pattr = parent_pdp_->getRTPSParticipant()->getAttributes(); + auto mutable_pattr = part->get_mutable_attributes(); fastdds::rtps::network::external_locators::filter_remote_locators(temp_participant_data_, - pattr.builtin.metatraffic_external_unicast_locators, pattr.default_external_unicast_locators, - pattr.ignore_non_matching_locators); + mutable_pattr.builtin.metatraffic_external_unicast_locators, + mutable_pattr.default_external_unicast_locators, + part->get_const_attributes().ignore_non_matching_locators); // Check if participant already exists (updated info) ParticipantProxyData* pdata = nullptr; @@ -163,10 +165,10 @@ void PDPListener::onNewCacheChangeAdded( #ifdef FASTDDS_STATISTICS //! Removal of a participant proxy should trigger //! a connections update on the local participant connection list - if (nullptr != parent_pdp_->getRTPSParticipant()->get_connections_observer()) + if (nullptr != part->get_connections_observer()) { - parent_pdp_->getRTPSParticipant()->get_connections_observer()->on_local_entity_connections_change( - parent_pdp_->getRTPSParticipant()->getGuid()); + part->get_connections_observer()->on_local_entity_connections_change( + part->getGuid()); } #endif //FASTDDS_STATISTICS reader->getMutex().lock(); diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp index fc6d51957c3..3981211ebe0 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp @@ -510,11 +510,10 @@ void PDPServer::initializeParticipantProxyData( { PDP::initializeParticipantProxyData(participant_data); - if (getRTPSParticipant()->getAttributes().builtin.discovery_config.discoveryProtocol != - DiscoveryProtocol_t::SERVER - && - getRTPSParticipant()->getAttributes().builtin.discovery_config.discoveryProtocol != - DiscoveryProtocol_t::BACKUP) + const auto& discovery_config = getRTPSParticipant()->get_const_attributes().builtin.discovery_config; + + if (discovery_config.discoveryProtocol != DiscoveryProtocol::SERVER && + discovery_config.discoveryProtocol != DiscoveryProtocol::BACKUP) { EPROSIMA_LOG_ERROR(RTPS_PDP_SERVER, "Using a PDP Server object with another user's settings"); } @@ -556,7 +555,7 @@ void PDPServer::match_reliable_pdp_endpoints( auto endpoints = static_cast(builtin_endpoints_.get()); const NetworkFactory& network = mp_RTPSParticipant->network_factory(); uint32_t endp = pdata.m_availableBuiltinEndpoints; - bool use_multicast_locators = !mp_RTPSParticipant->getAttributes().builtin.avoid_builtin_multicast || + bool use_multicast_locators = !mp_RTPSParticipant->get_const_attributes().builtin.avoid_builtin_multicast || pdata.metatraffic_locators.unicast.empty(); // only SERVER and CLIENT participants will be received. All builtin must be there @@ -918,7 +917,8 @@ void PDPServer::announceParticipantState( // but the routine thread has not consumed it yet. // This would happen when the routine thread is busy in initializing, i.e. it already has other // DATA(P) to parse before the own one is inserted by update. - EPROSIMA_LOG_WARNING(RTPS_PDP_SERVER, "Local Server DATA(p) uninitialized before local on announcement. " + EPROSIMA_LOG_WARNING(RTPS_PDP_SERVER, + "Local Server DATA(p) uninitialized before local on announcement. " << "It will be sent in next announce iteration."); return; } @@ -1272,7 +1272,8 @@ History::iterator PDPServer::process_change_acknowledgement( // Remove the entry from writer history, but do not release the cache. // This CacheChange will only be released in the case that is substituted by a DATA(Up|Uw|Ur). EPROSIMA_LOG_INFO(RTPS_PDP_SERVER, "Removing change " << c->instanceHandle - << " from history as it has been acked for everyone"); + << + " from history as it has been acked for everyone"); return writer_history->remove_change(cit, false); } } @@ -1563,8 +1564,8 @@ bool PDPServer::pending_ack() EPROSIMA_LOG_INFO(RTPS_PDP_SERVER, "PDP writer history length " << endpoints->writer.history_->getHistorySize()); EPROSIMA_LOG_INFO(RTPS_PDP_SERVER, - "is server " << endpoints->writer.writer_->getGuid() << " acked by all? " << - discovery_db_.server_acked_by_all()); + "is server " << endpoints->writer.writer_->getGuid() << " acked by all? " + << discovery_db_.server_acked_by_all()); EPROSIMA_LOG_INFO(RTPS_PDP_SERVER, "Are there pending changes? " << ret); return ret; } diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPServerListener.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPServerListener.cpp index 5d3dbf37169..c6e5bc27ae8 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPServerListener.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPServerListener.cpp @@ -58,8 +58,8 @@ void PDPServerListener::onNewCacheChangeAdded( EPROSIMA_LOG_INFO(RTPS_PDP_LISTENER, ""); EPROSIMA_LOG_INFO(RTPS_PDP_LISTENER, "------------------ PDP SERVER LISTENER START ------------------"); EPROSIMA_LOG_INFO(RTPS_PDP_LISTENER, - "-------------------- " << pdp_server()->mp_RTPSParticipant->getGuid() << - " --------------------"); + "-------------------- " << pdp_server()->mp_RTPSParticipant->getGuid() + << " --------------------"); EPROSIMA_LOG_INFO(RTPS_PDP_LISTENER, "PDP Server Message received: " << change_in->instanceHandle); auto endpoints = static_cast(pdp_server()->builtin_endpoints_.get()); @@ -149,7 +149,7 @@ void PDPServerListener::onNewCacheChangeAdded( return; } - const auto& pattr = pdp_server()->getRTPSParticipant()->getAttributes(); + const auto pattr = pdp_server()->getRTPSParticipant()->copy_attributes(); fastdds::rtps::network::external_locators::filter_remote_locators(participant_data, pattr.builtin.metatraffic_external_unicast_locators, pattr.default_external_unicast_locators, pattr.ignore_non_matching_locators); @@ -438,8 +438,8 @@ void PDPServerListener::onNewCacheChangeAdded( // happens at this point EPROSIMA_LOG_INFO(RTPS_PDP_LISTENER, - "-------------------- " << pdp_server()->mp_RTPSParticipant->getGuid() << - " --------------------"); + "-------------------- " << pdp_server()->mp_RTPSParticipant->getGuid() + << " --------------------"); EPROSIMA_LOG_INFO(RTPS_PDP_LISTENER, "------------------ PDP SERVER LISTENER END ------------------"); EPROSIMA_LOG_INFO(RTPS_PDP_LISTENER, ""); } diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPSimple.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPSimple.cpp index 9fd2d61760b..0b9f6c4e687 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPSimple.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPSimple.cpp @@ -105,8 +105,9 @@ void PDPSimple::initializeParticipantProxyData( { PDP::initializeParticipantProxyData(participant_data); - if (getRTPSParticipant()->getAttributes().builtin.discovery_config. - use_SIMPLE_EndpointDiscoveryProtocol) + const auto& discovery_config = getRTPSParticipant()->get_const_attributes().builtin.discovery_config; + + if (discovery_config.use_SIMPLE_EndpointDiscoveryProtocol) { if (getRTPSParticipant()->getAttributes().builtin.discovery_config.m_simpleEDP. use_PublicationWriterANDSubscriptionReader) @@ -331,8 +332,7 @@ bool PDPSimple::createPDPEndpoints() bool PDPSimple::create_dcps_participant_endpoints() { - const RTPSParticipantAttributes& pattr = mp_RTPSParticipant->getRTPSParticipantAttributes(); - const RTPSParticipantAllocationAttributes& allocation = pattr.allocation; + const RTPSParticipantAllocationAttributes& allocation = mp_RTPSParticipant->get_const_attributes().allocation; const BuiltinAttributes& builtin_att = mp_builtin->m_att; auto endpoints = dynamic_cast(builtin_endpoints_.get()); assert(nullptr != endpoints); @@ -461,8 +461,7 @@ bool PDPSimple::create_dcps_participant_endpoints() #if HAVE_SECURITY bool PDPSimple::create_dcps_participant_secure_endpoints() { - const RTPSParticipantAttributes& pattr = mp_RTPSParticipant->getRTPSParticipantAttributes(); - const RTPSParticipantAllocationAttributes& allocation = pattr.allocation; + const RTPSParticipantAllocationAttributes& allocation = mp_RTPSParticipant->get_const_attributes().allocation; const BuiltinAttributes& builtin_att = mp_builtin->m_att; auto endpoints = dynamic_cast(builtin_endpoints_.get()); assert(nullptr != endpoints); @@ -632,7 +631,7 @@ void PDPSimple::match_pdp_remote_endpoints( auto endpoints = static_cast(builtin_endpoints_.get()); const NetworkFactory& network = mp_RTPSParticipant->network_factory(); - bool use_multicast_locators = !mp_RTPSParticipant->getAttributes().builtin.avoid_builtin_multicast || + bool use_multicast_locators = !mp_RTPSParticipant->get_const_attributes().builtin.avoid_builtin_multicast || pdata.metatraffic_locators.unicast.empty(); const uint32_t endp = pdata.m_availableBuiltinEndpoints; @@ -679,8 +678,8 @@ void PDPSimple::match_pdp_remote_endpoints( reader->getGuid(), pdata.m_guid, *temp_writer_data, reader->getAttributes().security_attributes())) { - EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " << - temp_writer_data->guid()); + EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " + << temp_writer_data->guid()); } } else @@ -708,8 +707,8 @@ void PDPSimple::match_pdp_remote_endpoints( writer->getGuid(), pdata.m_guid, *temp_reader_data, writer->getAttributes().security_attributes())) { - EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for reader " << - temp_reader_data->guid()); + EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for reader " + << temp_reader_data->guid()); } } else diff --git a/src/cpp/rtps/builtin/discovery/participant/simple/PDPStatelessWriter.cpp b/src/cpp/rtps/builtin/discovery/participant/simple/PDPStatelessWriter.cpp index d2d9758564a..6629190b098 100644 --- a/src/cpp/rtps/builtin/discovery/participant/simple/PDPStatelessWriter.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/simple/PDPStatelessWriter.cpp @@ -41,7 +41,7 @@ PDPStatelessWriter::PDPStatelessWriter( WriterHistory* history, WriterListener* listener) : StatelessWriter(participant, guid, attributes, flow_controller, history, listener) - , interested_readers_(participant->getRTPSParticipantAttributes().allocation.participants) + , interested_readers_(participant->get_const_attributes().allocation.participants) { } diff --git a/src/cpp/rtps/builtin/liveliness/WLP.cpp b/src/cpp/rtps/builtin/liveliness/WLP.cpp index 80ac841e40f..475ea142ce2 100644 --- a/src/cpp/rtps/builtin/liveliness/WLP.cpp +++ b/src/cpp/rtps/builtin/liveliness/WLP.cpp @@ -105,14 +105,14 @@ WLP::WLP( , mp_builtinReaderSecureHistory(nullptr) #endif // if HAVE_SECURITY , temp_reader_proxy_data_( - p->mp_participantImpl->getRTPSParticipantAttributes().allocation.locators.max_unicast_locators, - p->mp_participantImpl->getRTPSParticipantAttributes().allocation.locators.max_multicast_locators, - p->mp_participantImpl->getRTPSParticipantAttributes().allocation.data_limits, - p->mp_participantImpl->getRTPSParticipantAttributes().allocation.content_filter) + p->mp_participantImpl->get_const_attributes().allocation.locators.max_unicast_locators, + p->mp_participantImpl->get_const_attributes().allocation.locators.max_multicast_locators, + p->mp_participantImpl->get_const_attributes().allocation.data_limits, + p->mp_participantImpl->get_const_attributes().allocation.content_filter) , temp_writer_proxy_data_( - p->mp_participantImpl->getRTPSParticipantAttributes().allocation.locators.max_unicast_locators, - p->mp_participantImpl->getRTPSParticipantAttributes().allocation.locators.max_multicast_locators, - p->mp_participantImpl->getRTPSParticipantAttributes().allocation.data_limits) + p->mp_participantImpl->get_const_attributes().allocation.locators.max_unicast_locators, + p->mp_participantImpl->get_const_attributes().allocation.locators.max_multicast_locators, + p->mp_participantImpl->get_const_attributes().allocation.data_limits) { GUID_t tmp_guid = p->mp_participantImpl->getGuid(); tmp_guid.entityId = 0; @@ -233,8 +233,8 @@ bool WLP::initWL( bool WLP::createEndpoints() { - const RTPSParticipantAttributes& pattr = mp_participant->getRTPSParticipantAttributes(); - const ResourceLimitedContainerConfig& participants_allocation = pattr.allocation.participants; + const ResourceLimitedContainerConfig& participants_allocation = + mp_participant->get_const_attributes().allocation.participants; // Built-in writer history HistoryAttributes hatt; @@ -319,8 +319,8 @@ bool WLP::createEndpoints() bool WLP::createSecureEndpoints() { - const RTPSParticipantAttributes& pattr = mp_participant->getRTPSParticipantAttributes(); - const ResourceLimitedContainerConfig& participants_allocation = pattr.allocation.participants; + const ResourceLimitedContainerConfig& participants_allocation = + mp_participant->get_const_attributes().allocation.participants; //CREATE WRITER HistoryAttributes hatt; @@ -454,7 +454,7 @@ bool WLP::assignRemoteEndpoints( const NetworkFactory& network = mp_participant->network_factory(); uint32_t endp = pdata.m_availableBuiltinEndpoints; uint32_t auxendp = endp; - bool use_multicast_locators = !mp_participant->getAttributes().builtin.avoid_builtin_multicast || + bool use_multicast_locators = !mp_participant->get_const_attributes().builtin.avoid_builtin_multicast || pdata.metatraffic_locators.unicast.empty(); std::lock_guard data_guard(temp_data_lock_); @@ -504,8 +504,8 @@ bool WLP::assignRemoteEndpoints( mp_builtinReaderSecure->getGuid(), pdata.m_guid, temp_writer_proxy_data_, mp_builtinReaderSecure->getAttributes().security_attributes())) { - EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for reader " << - mp_builtinReaderSecure->getGuid()); + EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for reader " + << mp_builtinReaderSecure->getGuid()); } } auxendp = endp; @@ -518,8 +518,8 @@ bool WLP::assignRemoteEndpoints( mp_builtinWriterSecure->getGuid(), pdata.m_guid, temp_reader_proxy_data_, mp_builtinWriterSecure->getAttributes().security_attributes())) { - EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " << - mp_builtinWriterSecure->getGuid()); + EPROSIMA_LOG_ERROR(RTPS_EDP, "Security manager returns an error for writer " + << mp_builtinWriterSecure->getGuid()); } } #else diff --git a/src/cpp/rtps/flowcontrol/FlowControllerFactory.cpp b/src/cpp/rtps/flowcontrol/FlowControllerFactory.cpp index aa5860dfd63..e7fce68355e 100644 --- a/src/cpp/rtps/flowcontrol/FlowControllerFactory.cpp +++ b/src/cpp/rtps/flowcontrol/FlowControllerFactory.cpp @@ -22,7 +22,7 @@ void FlowControllerFactory::init( const ThreadSettings& sender_thread_settings = (nullptr == participant_) ? ThreadSettings{} - : participant_->getAttributes().builtin_controllers_sender_thread; + : participant_->get_const_attributes().builtin_controllers_sender_thread; // PureSyncFlowController -> used by volatile besteffort writers. flow_controllers_.insert(decltype(flow_controllers_)::value_type( diff --git a/src/cpp/rtps/flowcontrol/FlowControllerImpl.hpp b/src/cpp/rtps/flowcontrol/FlowControllerImpl.hpp index ab05d3fc843..1bcfb37c02b 100644 --- a/src/cpp/rtps/flowcontrol/FlowControllerImpl.hpp +++ b/src/cpp/rtps/flowcontrol/FlowControllerImpl.hpp @@ -942,7 +942,7 @@ class FlowControllerImpl : public FlowController { if (nullptr != participant) { - participant_id_ = static_cast(participant->getRTPSParticipantAttributes().participantID); + participant_id_ = static_cast(participant->get_const_attributes().participantID); } uint32_t limitation = get_max_payload(); diff --git a/src/cpp/rtps/participant/RTPSParticipant.cpp b/src/cpp/rtps/participant/RTPSParticipant.cpp index f6a32273acb..ab9f79502df 100644 --- a/src/cpp/rtps/participant/RTPSParticipant.cpp +++ b/src/cpp/rtps/participant/RTPSParticipant.cpp @@ -125,6 +125,21 @@ const RTPSParticipantAttributes& RTPSParticipant::getRTPSParticipantAttributes() return mp_impl->getRTPSParticipantAttributes(); } +const RTPSParticipantConstantAttributes& RTPSParticipant::get_const_attributes() const +{ + return mp_impl->get_const_attributes(); +} + +const RTPSParticipantMutableAttributes RTPSParticipant::get_mutable_attributes() const +{ + return mp_impl->get_mutable_attributes(); +} + +RTPSParticipantAttributes RTPSParticipant::copy_attributes() const +{ + return mp_impl->copy_attributes(); +} + uint32_t RTPSParticipant::getMaxMessageSize() const { return mp_impl->getMaxMessageSize(); @@ -291,4 +306,3 @@ bool RTPSParticipant::fill_discovery_data_from_cdr_message( } /* namespace rtps */ } /* namespace fastrtps */ } /* namespace eprosima */ - diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp index 67dbd5ebc02..ded2e8b9ecb 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp @@ -121,8 +121,8 @@ static void set_builtin_transports_from_env_var( "LARGE_DATA", BuiltinTransports::LARGE_DATA, "LARGE_DATAv6", BuiltinTransports::LARGE_DATAv6)) { - EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, "Wrong value '" << env_value << "' for environment variable '" << - env_var_name << "'. Leaving as DEFAULT"); + EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, "Wrong value '" << env_value << "' for environment variable '" + << env_var_name << "'. Leaving as DEFAULT"); } } else if (std::regex_match(env_value, mr, OPTIONS_REGEX, std::regex_constants::match_not_null)) @@ -148,8 +148,8 @@ static void set_builtin_transports_from_env_var( "LARGE_DATAv6", BuiltinTransports::LARGE_DATAv6)) { EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, - "Wrong value '" << env_value << "' for environment variable '" << - env_var_name << "'. Leaving as DEFAULT"); + "Wrong value '" << env_value << "' for environment variable '" + << env_var_name << "'. Leaving as DEFAULT"); } // Max_msg_size parser if (std::regex_search(env_value, mr, msg_size_regex, std::regex_constants::match_not_null)) @@ -181,16 +181,16 @@ static void set_builtin_transports_from_env_var( catch (std::exception& e) { EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, - "Exception parsing environment variable: " << e.what() << - " Leaving LARGE_DATA with default options."); + "Exception parsing environment variable: " << e.what() + << " Leaving LARGE_DATA with default options."); attr.setup_transports(ret_val); return; } } else { - EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, "Wrong value '" << env_value << "' for environment variable '" << - env_var_name << "'. Leaving as DEFAULT"); + EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, "Wrong value '" << env_value << "' for environment variable '" + << env_var_name << "'. Leaving as DEFAULT"); } } attr.setup_transports(ret_val); @@ -384,6 +384,7 @@ RTPSParticipantImpl::RTPSParticipantImpl( RTPSParticipantListener* plisten) : domain_id_(domain_id) , m_att(PParam) + , m_const_att(PParam) , m_guid(guidP, c_EntityId_RTPSParticipant) , mp_builtinProtocols(nullptr) , IdCounter(0) @@ -393,7 +394,7 @@ RTPSParticipantImpl::RTPSParticipantImpl( , internal_metatraffic_locators_(false) , internal_default_locators_(false) #if HAVE_SECURITY - , m_security_manager(this, *this) + , m_security_manager(this, PParam, *this) #endif // if HAVE_SECURITY , mp_participantListener(plisten) , mp_userParticipant(par) @@ -442,7 +443,8 @@ RTPSParticipantImpl::RTPSParticipantImpl( if (pT->listening_ports.empty()) { EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, - "Participant " << m_att.getName() << " with GUID " << m_guid << + "Participant " << m_att.getName() << " with GUID " << m_guid + << " tries to create a TCP server for discovery server without providing a proper listening port."); break; } @@ -490,7 +492,8 @@ RTPSParticipantImpl::RTPSParticipantImpl( if (pT->listening_ports.empty()) { EPROSIMA_LOG_INFO(RTPS_PARTICIPANT, - "Participant " << m_att.getName() << " with GUID " << m_guid << + "Participant " << m_att.getName() << " with GUID " << m_guid + << " tries to create a TCP client for discovery server without providing a proper listening port." << " No TCP participants will be able to connect to this participant, but it will be able make connections."); @@ -633,6 +636,10 @@ RTPSParticipantImpl::RTPSParticipantImpl( // NOTE: all transports already registered before m_att.builtin.network_configuration = m_network_Factory.network_configuration(); + // Update constant attributes. Need to do it at this point to ensure we capture the constant attributes + // set at "setup_" methods, but before setup_builtin_protocols, which already access constant values. + m_const_att = m_att; + mp_builtinProtocols = new BuiltinProtocols(); // Initialize builtin protocols @@ -1674,8 +1681,8 @@ void RTPSParticipantImpl::update_attributes( if (!SystemInfo::update_interfaces()) { EPROSIMA_LOG_WARNING(RTPS_PARTICIPANT, - "Failed to update cached network interfaces during " << temp_atts.getName() << - " attributes update"); + "Failed to update cached network interfaces during " << temp_atts.getName() + << " attributes update"); } // Check if new interfaces have been added @@ -1907,7 +1914,7 @@ void RTPSParticipantImpl::update_attributes( // Update the attributes data member { std::lock_guard guard(*mp_mutex); - m_att = temp_atts; + update_mutable_attributes(temp_atts); } } @@ -1918,6 +1925,18 @@ void RTPSParticipantImpl::update_attributes( } } +void RTPSParticipantImpl::update_mutable_attributes( + const RTPSParticipantAttributes& patt) +{ + // NTS + m_att.builtin.discovery_config.m_DiscoveryServers = patt.builtin.discovery_config.m_DiscoveryServers; + m_att.builtin.metatraffic_external_unicast_locators = patt.builtin.metatraffic_external_unicast_locators; + m_att.builtin.metatrafficUnicastLocatorList = patt.builtin.metatrafficUnicastLocatorList; + m_att.default_external_unicast_locators = patt.default_external_unicast_locators; + m_att.defaultUnicastLocatorList = patt.defaultUnicastLocatorList; + m_att.userData = patt.userData; +} + bool RTPSParticipantImpl::updateLocalWriter( RTPSWriter* Writer, const TopicAttributes& topicAtt, @@ -2146,8 +2165,8 @@ bool RTPSParticipantImpl::createSendResources( { if (!m_network_Factory.build_send_resources(send_resource_list_, (*it))) { - EPROSIMA_LOG_WARNING(RTPS_PARTICIPANT, "Cannot create send resource for endpoint remote locator (" << - pend->getGuid() << ", " << (*it) << ")"); + EPROSIMA_LOG_WARNING(RTPS_PARTICIPANT, "Cannot create send resource for endpoint remote locator (" + << pend->getGuid() << ", " << (*it) << ")"); } } @@ -3050,10 +3069,14 @@ DurabilityKind_t RTPSParticipantImpl::get_persistence_durability_red_line( void RTPSParticipantImpl::environment_file_has_changed() { - RTPSParticipantAttributes patt = m_att; + RTPSParticipantAttributes patt; + { + std::lock_guard guard(*mp_mutex); + patt = m_att; + } // Only if it is a server/backup or a client override - if (DiscoveryProtocol_t::SERVER == m_att.builtin.discovery_config.discoveryProtocol || - DiscoveryProtocol_t::BACKUP == m_att.builtin.discovery_config.discoveryProtocol || + if (DiscoveryProtocol::SERVER == patt.builtin.discovery_config.discoveryProtocol || + DiscoveryProtocol::BACKUP == patt.builtin.discovery_config.discoveryProtocol || client_override_) { if (load_environment_server_info(patt.builtin.discovery_config.m_DiscoveryServers)) @@ -3064,8 +3087,8 @@ void RTPSParticipantImpl::environment_file_has_changed() else { EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK, - "Trying to add Discovery Servers to a participant which is not a SERVER, BACKUP " << - "or an overriden CLIENT (SIMPLE participant transformed into CLIENT with the environment variable)"); + "Trying to add Discovery Servers to a participant which is not a SERVER, BACKUP " + << "or an overriden CLIENT (SIMPLE participant transformed into CLIENT with the environment variable)"); } } @@ -3079,8 +3102,8 @@ void RTPSParticipantImpl::get_default_metatraffic_locators( { uint32_t metatraffic_multicast_port = att.port.getMulticastPort(domain_id_); - if (m_att.builtin.discovery_config.discoveryProtocol != DiscoveryProtocol::CLIENT && - m_att.builtin.discovery_config.discoveryProtocol != DiscoveryProtocol::SUPER_CLIENT) + if (att.builtin.discovery_config.discoveryProtocol != DiscoveryProtocol::CLIENT && + att.builtin.discovery_config.discoveryProtocol != DiscoveryProtocol::SUPER_CLIENT) { m_network_Factory.getDefaultMetatrafficMulticastLocators(att.builtin.metatrafficMulticastLocatorList, metatraffic_multicast_port); @@ -3535,8 +3558,8 @@ bool RTPSParticipantImpl::should_match_local_endpoints( { should_match_local_endpoints = true; EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, - "Unkown value '" << *ignore_local_endpoints << - "' for property 'fastdds.ignore_local_endpoints'. Setting value to 'true'"); + "Unkown value '" << *ignore_local_endpoints + << "' for property 'fastdds.ignore_local_endpoints'. Setting value to 'true'"); } } return should_match_local_endpoints; @@ -3551,10 +3574,22 @@ void RTPSParticipantImpl::update_removed_participant( m_network_Factory.remove_participant_associated_send_resources( send_resource_list_, remote_participant_locators, - m_att.builtin.initialPeersList); + get_const_attributes().builtin.initialPeersList); } } +const RTPSParticipantMutableAttributes RTPSParticipantImpl::get_mutable_attributes() const +{ + std::lock_guard guard(*mp_mutex); + return RTPSParticipantMutableAttributes(m_att); +} + +RTPSParticipantAttributes RTPSParticipantImpl::copy_attributes() const +{ + std::lock_guard guard(*mp_mutex); + return m_att; +} + } /* namespace rtps */ } /* namespace fastrtps */ } /* namespace eprosima */ diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.h b/src/cpp/rtps/participant/RTPSParticipantImpl.h index 3111246bb89..ee5ccecafbf 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.h +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.h @@ -554,6 +554,8 @@ class RTPSParticipantImpl uint32_t domain_id_; //!Attributes of the RTPSParticipant RTPSParticipantAttributes m_att; + //!Constant copy of Attributes of the RTPSParticipant + RTPSParticipantConstantAttributes m_const_att; //! Metatraffic unicast port used by default on this participant uint32_t metatraffic_unicast_port_ = 0; //! Default unicast port used by default on this participant @@ -805,11 +807,39 @@ class RTPSParticipantImpl public: + /** + * @brief Get the RTPSParticipantAttributes of this RTPSParticipantImpl. This method is not thread safe, + * it is recommended to use copy_attributes() instead. + * @return RTPSParticipantAttributes of this RTPSParticipantImpl. + */ const RTPSParticipantAttributes& getRTPSParticipantAttributes() const { return this->m_att; } + /** + * @brief Get a const reference of RTPSParticipantConstantAttributes of this RTPSParticipantImpl. + * This method is thread safe because it returns a const reference to the internal constant attributes. + * @return A const reference to the RTPSParticipantConstantAttributes of this RTPSParticipantImpl. + */ + const RTPSParticipantConstantAttributes& get_const_attributes() const + { + return m_const_att; + } + + /** + * @brief Get a const copy of RTPSParticipantMutableAttributes of this RTPSParticipantImpl. + * This method is thread safe because it returns a const copy of the internal mutable attributes. + * @return A const copy of the RTPSParticipantMutableAttributes of this RTPSParticipantImpl. + */ + const RTPSParticipantMutableAttributes get_mutable_attributes() const; + + /** + * @brief Get a copy of the RTPSParticipantAttributes of this RTPSParticipantImpl in a thread safe manner. + * @return A copy of the RTPSParticipantAttributes of this RTPSParticipantImpl. + */ + RTPSParticipantAttributes copy_attributes() const; + /** * Create a Writer in this RTPSParticipant. * @param Writer Pointer to pointer of the Writer, used as output. Only valid if return==true. @@ -952,6 +982,13 @@ class RTPSParticipantImpl void update_attributes( const RTPSParticipantAttributes& patt); + /** + * Update only mutable participant attributes. + * @param patt New participant attributes. + */ + void update_mutable_attributes( + const RTPSParticipantAttributes& patt); + /** * Update local writer QoS * @param Writer Writer to update diff --git a/src/cpp/rtps/reader/BaseReader.cpp b/src/cpp/rtps/reader/BaseReader.cpp new file mode 100644 index 00000000000..b657f7a1703 --- /dev/null +++ b/src/cpp/rtps/reader/BaseReader.cpp @@ -0,0 +1,569 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* + * BaseReader.cpp + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace eprosima { +namespace fastdds { +namespace rtps { + +BaseReader::BaseReader( + fastdds::rtps::RTPSParticipantImpl* pimpl, + const fastdds::rtps::GUID_t& guid, + const fastdds::rtps::ReaderAttributes& att, + fastdds::rtps::ReaderHistory* hist, + fastdds::rtps::ReaderListener* listen) + : fastdds::rtps::RTPSReader(pimpl, guid, att, hist) + , listener_(listen) + , accept_messages_from_unkown_writers_(att.accept_messages_from_unkown_writers) + , expects_inline_qos_(att.expects_inline_qos) + , history_state_(new fastdds::rtps::ReaderHistoryState(att.matched_writers_allocation.initial)) + , liveliness_kind_(att.liveliness_kind) + , liveliness_lease_duration_(att.liveliness_lease_duration) +{ + PoolConfig cfg = PoolConfig::from_history_attributes(hist->m_att); + std::shared_ptr change_pool; + std::shared_ptr payload_pool; + payload_pool = BasicPayloadPool::get(cfg, change_pool); + + init(payload_pool, change_pool); + setup_datasharing(att); +} + +BaseReader::BaseReader( + fastdds::rtps::RTPSParticipantImpl* pimpl, + const fastdds::rtps::GUID_t& guid, + const fastdds::rtps::ReaderAttributes& att, + const std::shared_ptr& payload_pool, + fastdds::rtps::ReaderHistory* hist, + fastdds::rtps::ReaderListener* listen) + : BaseReader( + pimpl, guid, att, payload_pool, + std::make_shared(PoolConfig::from_history_attributes(hist->m_att)), + hist, listen) +{ +} + +BaseReader::BaseReader( + fastdds::rtps::RTPSParticipantImpl* pimpl, + const fastdds::rtps::GUID_t& guid, + const fastdds::rtps::ReaderAttributes& att, + const std::shared_ptr& payload_pool, + const std::shared_ptr& change_pool, + fastdds::rtps::ReaderHistory* hist, + fastdds::rtps::ReaderListener* listen) + : fastdds::rtps::RTPSReader(pimpl, guid, att, hist) + , listener_(listen) + , accept_messages_from_unkown_writers_(att.accept_messages_from_unkown_writers) + , expects_inline_qos_(att.expects_inline_qos) + , history_state_(new fastdds::rtps::ReaderHistoryState(att.matched_writers_allocation.initial)) + , liveliness_kind_(att.liveliness_kind) + , liveliness_lease_duration_(att.liveliness_lease_duration) +{ + init(payload_pool, change_pool); + setup_datasharing(att); +} + +void BaseReader::local_actions_on_reader_removed() +{ + local_ptr_->deactivate(); +} + +BaseReader::~BaseReader() +{ + EPROSIMA_LOG_INFO(RTPS_READER, "Removing reader " << this->getGuid().entityId); + + for (auto it = history_->changesBegin(); it != history_->changesEnd(); ++it) + { + release_cache(*it); + } + + delete history_state_; + + // As releasing the change pool will delete the cache changes it owns, + // the payload pool may be called to release their payloads, so we should + // ensure that the payload pool is destroyed after the change pool. + change_pool_.reset(); + payload_pool_.reset(); +} + +bool BaseReader::matched_writer_add( + const PublicationBuiltinTopicData& info) +{ + const auto& alloc = mp_RTPSParticipant->get_const_attributes().allocation; + WriterProxyData wdata(alloc.data_limits, info); + + return matched_writer_add_edp(wdata); +} + +ReaderListener* BaseReader::get_listener() const +{ + std::lock_guard lock(mp_mutex); + return listener_; +} + +void BaseReader::set_listener( + ReaderListener* target) +{ + std::lock_guard lock(mp_mutex); + listener_ = target; +} + +bool BaseReader::expects_inline_qos() const +{ + return expects_inline_qos_; +} + +ReaderHistory* BaseReader::get_history() const +{ + return history_; +} + +//! @return The content filter associated to this reader. +IReaderDataFilter* BaseReader::get_content_filter() const +{ + std::lock_guard lock(mp_mutex); + return data_filter_; +} + +//! Set the content filter associated to this reader. +//! @param filter Pointer to the content filter to associate to this reader. +void BaseReader::set_content_filter( + IReaderDataFilter* filter) +{ + std::lock_guard lock(mp_mutex); + data_filter_ = filter; +} + +uint64_t BaseReader::get_unread_count() const +{ + std::lock_guard lock(mp_mutex); + return total_unread_; +} + +uint64_t BaseReader::get_unread_count( + bool mark_as_read) +{ + std::lock_guard lock(mp_mutex); + uint64_t ret_val = total_unread_; + + if (mark_as_read) + { + for (auto it = history_->changesBegin(); 0 < total_unread_ && it != history_->changesEnd(); ++it) + { + fastdds::rtps::CacheChange_t* change = *it; + if (!change->isRead && get_last_notified(change->writerGUID) >= change->sequenceNumber) + { + change->isRead = true; + assert(0 < total_unread_); + --total_unread_; + } + } + assert(0 == total_unread_); + } + return ret_val; +} + +bool BaseReader::wait_for_unread_cache( + const eprosima::fastdds::dds::Duration_t& timeout) +{ + auto time_out = std::chrono::steady_clock::now() + std::chrono::seconds(timeout.seconds) + + std::chrono::nanoseconds(timeout.nanosec); + +#if HAVE_STRICT_REALTIME + std::unique_lock lock(mp_mutex, std::defer_lock); + if (lock.try_lock_until(time_out)) +#else + std::unique_lock lock(mp_mutex); +#endif // HAVE_STRICT_REALTIME + { + if (new_notification_cv_.wait_until( + lock, time_out, + [&]() + { + return total_unread_ > 0; + })) + { + return true; + } + } + + return false; +} + +bool BaseReader::is_sample_valid( + const void* data, + const fastdds::rtps::GUID_t& writer, + const fastdds::rtps::SequenceNumber_t& sn) const +{ + if (is_datasharing_compatible_ && datasharing_listener_->writer_is_matched(writer)) + { + // Check if the payload is dirty + // Note the Payloads used in loans include a mandatory RTPS 2.3 extra header + auto payload = static_cast(data); + payload -= fastdds::rtps::SerializedPayload_t::representation_header_size; + if (!fastdds::rtps::DataSharingPayloadPool::check_sequence_number(payload, sn)) + { + return false; + } + } + return true; +} + +BaseReader* BaseReader::downcast( + fastdds::rtps::RTPSReader* reader) +{ + assert(nullptr != dynamic_cast(reader)); + return static_cast(reader); +} + +BaseReader* BaseReader::downcast( + fastdds::rtps::Endpoint* endpoint) +{ + assert(nullptr != dynamic_cast(endpoint)); + return static_cast(endpoint); +} + +void BaseReader::allow_unknown_writers() +{ + assert(fastdds::rtps::EntityId_t::unknown() != trusted_writer_entity_id_); + accept_messages_from_unkown_writers_ = true; +} + +std::shared_ptr BaseReader::get_local_pointer() +{ + return local_ptr_; +} + +bool BaseReader::reserve_cache( + uint32_t cdr_payload_size, + uint16_t fragment_size, + fastdds::rtps::CacheChange_t*& change) +{ + std::lock_guard guard(mp_mutex); + + change = nullptr; + + // Calculate and validate required payload size + uint32_t reserve_size = fixed_payload_size_ > 0 ? fixed_payload_size_ : cdr_payload_size; + uint32_t payload_size = std::min(reserve_size, cdr_payload_size); + uint32_t min_required_size = 0; + if (!CacheChange_t::calculate_required_fragmented_payload_size(payload_size, fragment_size, min_required_size)) + { + EPROSIMA_LOG_WARNING(RTPS_READER, + "Required payload size calculation overflows for payload size '" << payload_size + << "' and fragment size '" + << fragment_size << "'"); + return false; + } + + if (min_required_size > reserve_size) + { + if (fixed_payload_size_ > 0) + { + EPROSIMA_LOG_WARNING(RTPS_READER, + "Fixed payload size '" << fixed_payload_size_ + << "' is insufficient for fragmentation with fragment size '" + << fragment_size << "'"); + return false; + } + reserve_size = min_required_size; + } + + fastdds::rtps::CacheChange_t* reserved_change = nullptr; + if (!change_pool_->reserve_cache(reserved_change)) + { + EPROSIMA_LOG_WARNING(RTPS_READER, "Problem reserving cache from pool"); + return false; + } + + if (!payload_pool_->get_payload(reserve_size, reserved_change->serializedPayload)) + { + change_pool_->release_cache(reserved_change); + EPROSIMA_LOG_WARNING(RTPS_READER, "Problem reserving payload from pool"); + return false; + } + + change = reserved_change; + return true; +} + +void BaseReader::release_cache( + fastdds::rtps::CacheChange_t* change) +{ + std::lock_guard guard(mp_mutex); + + fastdds::rtps::IPayloadPool* pool = change->serializedPayload.payload_owner; + if (pool) + { + pool->release_payload(change->serializedPayload); + } + change_pool_->release_cache(change); +} + +void BaseReader::update_liveliness_changed_status( + const fastdds::rtps::GUID_t& writer, + int32_t alive_change, + int32_t not_alive_change) +{ + std::lock_guard lock(mp_mutex); + + liveliness_changed_status_.alive_count += alive_change; + liveliness_changed_status_.alive_count_change += alive_change; + liveliness_changed_status_.not_alive_count += not_alive_change; + liveliness_changed_status_.not_alive_count_change += not_alive_change; + liveliness_changed_status_.last_publication_handle = writer; + + if (nullptr != listener_) + { + listener_->on_liveliness_changed(this, liveliness_changed_status_); + + liveliness_changed_status_.alive_count_change = 0; + liveliness_changed_status_.not_alive_count_change = 0; + } +} + +#ifdef FASTDDS_STATISTICS + +bool BaseReader::add_statistics_listener( + std::shared_ptr listener) +{ + return add_statistics_listener_impl(listener); +} + +bool BaseReader::remove_statistics_listener( + std::shared_ptr listener) +{ + return remove_statistics_listener_impl(listener); +} + +void BaseReader::set_enabled_statistics_writers_mask( + uint32_t enabled_writers) +{ + set_enabled_statistics_writers_mask_impl(enabled_writers); +} + +#endif // FASTDDS_STATISTICS + +bool BaseReader::may_remove_history_record( + bool removed_by_lease) +{ + return !removed_by_lease; +} + +void BaseReader::add_persistence_guid( + const fastdds::rtps::GUID_t& guid, + const fastdds::rtps::GUID_t& persistence_guid) +{ + if (fastdds::rtps::c_Guid_Unknown == persistence_guid || persistence_guid == guid) + { + std::lock_guard guard(mp_mutex); + history_state_->persistence_guid_map[guid] = guid; + history_state_->persistence_guid_count[guid]++; + } + else + { + std::lock_guard guard(mp_mutex); + history_state_->persistence_guid_map[guid] = persistence_guid; + history_state_->persistence_guid_count[persistence_guid]++; + + // Could happen that a value has already been stored in the record with the guid and not the persistence guid + // This is because received_change is called before Proxy is created + // In this case, we substitute the guid for the persistence (in case they are not equal) + auto spourious_record = history_state_->history_record.find(guid); + if (spourious_record != history_state_->history_record.end()) + { + EPROSIMA_LOG_INFO(RTPS_READER, "Sporious record found, changing guid " + << guid << " for persistence guid " << persistence_guid); + update_last_notified(guid, spourious_record->second); + history_state_->history_record.erase(spourious_record); + } + } +} + +void BaseReader::remove_persistence_guid( + const fastdds::rtps::GUID_t& guid, + const fastdds::rtps::GUID_t& persistence_guid, + bool removed_by_lease) +{ + std::lock_guard guard(mp_mutex); + auto persistence_guid_stored = (fastdds::rtps::c_Guid_Unknown == persistence_guid) ? guid : persistence_guid; + history_state_->persistence_guid_map.erase(guid); + auto count = --history_state_->persistence_guid_count[persistence_guid_stored]; + if (count <= 0 && may_remove_history_record(removed_by_lease)) + { + history_state_->history_record.erase(persistence_guid_stored); + history_state_->persistence_guid_count.erase(persistence_guid_stored); + } +} + +fastdds::rtps::SequenceNumber_t BaseReader::get_last_notified( + const fastdds::rtps::GUID_t& guid) +{ + fastdds::rtps::SequenceNumber_t ret_val; + std::lock_guard guard(mp_mutex); + fastdds::rtps::GUID_t guid_to_look = guid; + auto p_guid = history_state_->persistence_guid_map.find(guid); + if (p_guid != history_state_->persistence_guid_map.end()) + { + guid_to_look = p_guid->second; + } + + auto p_seq = history_state_->history_record.find(guid_to_look); + if (p_seq != history_state_->history_record.end()) + { + ret_val = p_seq->second; + } + + return ret_val; +} + +fastdds::rtps::SequenceNumber_t BaseReader::update_last_notified( + const fastdds::rtps::GUID_t& guid, + const fastdds::rtps::SequenceNumber_t& seq) +{ + fastdds::rtps::SequenceNumber_t ret_val; + std::lock_guard guard(mp_mutex); + fastdds::rtps::GUID_t guid_to_look = guid; + auto p_guid = history_state_->persistence_guid_map.find(guid); + if (p_guid != history_state_->persistence_guid_map.end()) + { + guid_to_look = p_guid->second; + } + + auto p_seq = history_state_->history_record.find(guid_to_look); + if (p_seq != history_state_->history_record.end()) + { + ret_val = p_seq->second; + } + + if (ret_val < seq) + { + history_state_->history_record[guid_to_look] = seq; + persist_last_notified_nts(guid_to_look, seq); + new_notification_cv_.notify_all(); + } + + return ret_val; +} + +void BaseReader::persist_last_notified_nts( + const fastdds::rtps::GUID_t& peristence_guid, + const fastdds::rtps::SequenceNumber_t& seq) +{ + // Empty base implementation since base behavior is to not persist data + static_cast(peristence_guid); + static_cast(seq); +} + +bool BaseReader::is_datasharing_compatible_with( + const fastdds::rtps::WriterProxyData& wdata) +{ + if (!is_datasharing_compatible_ || + wdata.data_sharing.kind() == fastdds::dds::DataSharingKind::OFF) + { + return false; + } + + for (auto id : wdata.data_sharing.domain_ids()) + { + if (std::find(m_att.data_sharing_configuration().domain_ids().begin(), + m_att.data_sharing_configuration().domain_ids().end(), id) + != m_att.data_sharing_configuration().domain_ids().end()) + { + return true; + } + } + + return false; +} + +void BaseReader::init( + const std::shared_ptr& payload_pool, + const std::shared_ptr& change_pool) +{ + payload_pool_ = payload_pool; + change_pool_ = change_pool; + fixed_payload_size_ = 0; + if (history_->m_att.memoryPolicy == PREALLOCATED_MEMORY_MODE) + { + fixed_payload_size_ = history_->m_att.payloadMaxSize; + } + + local_ptr_ = std::make_shared(this); + + EPROSIMA_LOG_INFO(RTPS_READER, "RTPSReader created correctly"); +} + +void BaseReader::setup_datasharing( + const fastdds::rtps::ReaderAttributes& att) +{ + + if (att.endpoint.data_sharing_configuration().kind() != fastdds::dds::DataSharingKind::OFF) + { + std::shared_ptr notification = DataSharingNotification::create_notification( + getGuid(), att.endpoint.data_sharing_configuration().shm_directory()); + if (notification) + { + is_datasharing_compatible_ = true; + datasharing_listener_.reset(new DataSharingListener( + notification, + att.endpoint.data_sharing_configuration().shm_directory(), + att.data_sharing_listener_thread, + att.matched_writers_allocation, + this)); + + // We can start the listener here, as no writer can be matched already, + // so no notification will occur until the non-virtual instance is constructed. + // But we need to stop the listener in the non-virtual instance destructor. + datasharing_listener_->start(); + } + } +} + +} // namespace rtps +} // namespace fastdds +} // namespace eprosima diff --git a/src/cpp/rtps/reader/StatefulReader.cpp b/src/cpp/rtps/reader/StatefulReader.cpp index 6e7a98acefc..a6bd3a0933b 100644 --- a/src/cpp/rtps/reader/StatefulReader.cpp +++ b/src/cpp/rtps/reader/StatefulReader.cpp @@ -182,10 +182,10 @@ void StatefulReader::init( RTPSParticipantImpl* pimpl, const ReaderAttributes& att) { - const RTPSParticipantAttributes& part_att = pimpl->getRTPSParticipantAttributes(); for (size_t n = 0; n < att.matched_writers_allocation.initial; ++n) { - matched_writers_pool_.push_back(new WriterProxy(this, part_att.allocation.locators, proxy_changes_config_)); + matched_writers_pool_.push_back(new WriterProxy(this, pimpl->get_const_attributes().allocation.locators, + proxy_changes_config_)); } } @@ -255,13 +255,14 @@ bool StatefulReader::matched_writer_add( size_t max_readers = matched_writers_pool_.max_size(); if (getMatchedWritersSize() + matched_writers_pool_.size() < max_readers) { - const RTPSParticipantAttributes& part_att = mp_RTPSParticipant->getRTPSParticipantAttributes(); - wp = new WriterProxy(this, part_att.allocation.locators, proxy_changes_config_); + wp = new WriterProxy(this, mp_RTPSParticipant->get_const_attributes().allocation.locators, + proxy_changes_config_); } else { - EPROSIMA_LOG_WARNING(RTPS_READER, "Maximum number of reader proxies (" << max_readers << \ - ") reached for writer " << m_guid); + EPROSIMA_LOG_WARNING(RTPS_READER, "Maximum number of reader proxies (" << max_readers \ + << ") reached for writer " + << m_guid); return false; } } @@ -719,8 +720,8 @@ bool StatefulReader::processDataFragMsg( if (!pWP->change_was_received(incomingChange->sequenceNumber)) { EPROSIMA_LOG_INFO(RTPS_MSG_IN, - IDSTRING "Trying to add fragment " << incomingChange->sequenceNumber.to64long() << " TO reader: " << - getGuid().entityId); + IDSTRING "Trying to add fragment " << incomingChange->sequenceNumber.to64long() << " TO reader: " + << getGuid().entityId); size_t changes_up_to = pWP->unknown_missing_changes_up_to(incomingChange->sequenceNumber); bool will_never_be_accepted = false; @@ -1110,8 +1111,8 @@ bool StatefulReader::change_received( EPROSIMA_LOG_INFO(RTPS_READER, "Change received from " << a_change->writerGUID << " with sequence number: " - << a_change->sequenceNumber << - " skipped. Higher sequence numbers have been received."); + << a_change->sequenceNumber + << " skipped. Higher sequence numbers have been received."); return false; } } @@ -1320,8 +1321,8 @@ bool StatefulReader::nextUntakenCache( else { EPROSIMA_LOG_WARNING(RTPS_READER, - "Removing change " << (*it)->sequenceNumber << " from " << (*it)->writerGUID << - " because is no longer paired"); + "Removing change " << (*it)->sequenceNumber << " from " << (*it)->writerGUID + << " because is no longer paired"); it = mp_history->remove_change(it); } @@ -1379,8 +1380,8 @@ bool StatefulReader::nextUnreadCache( else { EPROSIMA_LOG_WARNING(RTPS_READER, - "Removing change " << (*it)->sequenceNumber << " from " << (*it)->writerGUID << - " because is no longer paired"); + "Removing change " << (*it)->sequenceNumber << " from " << (*it)->writerGUID + << " because is no longer paired"); it = mp_history->remove_change(it); continue; } diff --git a/src/cpp/rtps/security/SecurityManager.cpp b/src/cpp/rtps/security/SecurityManager.cpp index 6f98111af73..9577651dbc0 100644 --- a/src/cpp/rtps/security/SecurityManager.cpp +++ b/src/cpp/rtps/security/SecurityManager.cpp @@ -75,6 +75,7 @@ inline bool usleep_bool() SecurityManager::SecurityManager( RTPSParticipantImpl* participant, + const RTPSParticipantAttributes& pattr, ISecurityPluginFactory& plugin_factory) : participant_stateless_message_listener_(*this) , participant_volatile_message_secure_listener_(*this) @@ -84,14 +85,14 @@ SecurityManager::SecurityManager( , auth_last_sequence_number_(1) , crypto_last_sequence_number_(1) , temp_reader_proxies_({ - participant->getRTPSParticipantAttributes().allocation.locators.max_unicast_locators, - participant->getRTPSParticipantAttributes().allocation.locators.max_multicast_locators, - participant->getRTPSParticipantAttributes().allocation.data_limits, - participant->getRTPSParticipantAttributes().allocation.content_filter}) + pattr.allocation.locators.max_unicast_locators, + pattr.allocation.locators.max_multicast_locators, + pattr.allocation.data_limits, + pattr.allocation.content_filter}) , temp_writer_proxies_({ - participant->getRTPSParticipantAttributes().allocation.locators.max_unicast_locators, - participant->getRTPSParticipantAttributes().allocation.locators.max_multicast_locators, - participant->getRTPSParticipantAttributes().allocation.data_limits}) + pattr.allocation.locators.max_unicast_locators, + pattr.allocation.locators.max_multicast_locators, + pattr.allocation.data_limits}) { assert(participant != nullptr); } @@ -110,7 +111,7 @@ bool SecurityManager::init( { domain_id_ = participant_->get_domain_id(); const PropertyPolicy log_properties = PropertyPolicyHelper::get_properties_with_prefix( - participant_->getRTPSParticipantAttributes().properties, + participant_->get_const_attributes().properties, "dds.sec.log.builtin.DDS_LogTopic."); // length(log_properties) == 0 considered as logging disable. @@ -199,7 +200,7 @@ bool SecurityManager::init( { // retrieve authentication properties, if any const PropertyPolicy auth_handshake_properties = PropertyPolicyHelper::get_properties_with_prefix( - participant_->getRTPSParticipantAttributes().properties, + participant_->get_const_attributes().properties, "dds.sec.auth.builtin.PKI-DH."); // if auth_handshake_properties is empty, the default values are used @@ -219,7 +220,7 @@ bool SecurityManager::init( ret = authentication_plugin_->validate_local_identity(&local_identity_handle_, adjusted_participant_key, domain_id_, - participant_->getRTPSParticipantAttributes(), + participant_->get_const_attributes().properties, participant_->getGuid(), exception); } @@ -242,7 +243,7 @@ bool SecurityManager::init( local_permissions_handle_ = access_plugin_->validate_local_permissions( *authentication_plugin_, *local_identity_handle_, domain_id_, - participant_->getRTPSParticipantAttributes(), + participant_->get_const_attributes().properties, exception); if (local_permissions_handle_ != nullptr) @@ -250,8 +251,7 @@ bool SecurityManager::init( if (!local_permissions_handle_->nil()) { if (access_plugin_->check_create_participant(*local_permissions_handle_, - domain_id_, - participant_->getRTPSParticipantAttributes(), exception)) + domain_id_, exception)) { // Set credentials. PermissionsCredentialToken* token = nullptr; @@ -934,8 +934,8 @@ bool SecurityManager::on_process_handshake( change->serializedPayload.length = aux_msg.length; // Send - EPROSIMA_LOG_INFO(SECURITY, "Authentication handshake sent to participant " << - participant_data.m_guid); + EPROSIMA_LOG_INFO(SECURITY, "Authentication handshake sent to participant " + << participant_data.m_guid); if (participant_stateless_message_writer_history_->add_change(change)) { handshake_message_send = true; @@ -1114,7 +1114,7 @@ bool SecurityManager::create_participant_stateless_message_writer() { participant_stateless_message_writer_history_ = new WriterHistory(participant_stateless_message_writer_hattr_); - const RTPSParticipantAttributes& pattr = participant_->getRTPSParticipantAttributes(); + RTPSParticipantAttributes pattr = participant_->copy_attributes(); WriterAttributes watt; watt.endpoint.external_unicast_locators = pattr.builtin.metatraffic_external_unicast_locators; @@ -1163,7 +1163,7 @@ bool SecurityManager::create_participant_stateless_message_reader() { participant_stateless_message_reader_history_ = new ReaderHistory(participant_stateless_message_reader_hattr_); - const RTPSParticipantAttributes& pattr = participant_->getRTPSParticipantAttributes(); + RTPSParticipantAttributes pattr = participant_->copy_attributes(); ReaderAttributes ratt; ratt.endpoint.topicKind = NO_KEY; @@ -1263,7 +1263,7 @@ bool SecurityManager::create_participant_volatile_message_secure_writer() participant_volatile_message_secure_writer_history_ = new WriterHistory(participant_volatile_message_secure_hattr_); - const RTPSParticipantAttributes& pattr = participant_->getRTPSParticipantAttributes(); + RTPSParticipantAttributes pattr = participant_->copy_attributes(); WriterAttributes watt; watt.endpoint.endpointKind = WRITER; @@ -1316,7 +1316,7 @@ bool SecurityManager::create_participant_volatile_message_secure_reader() participant_volatile_message_secure_reader_history_ = new ReaderHistory(participant_volatile_message_secure_hattr_); - const RTPSParticipantAttributes& pattr = participant_->getRTPSParticipantAttributes(); + RTPSParticipantAttributes pattr = participant_->copy_attributes(); ReaderAttributes ratt; ratt.endpoint.topicKind = NO_KEY; @@ -1871,8 +1871,8 @@ void SecurityManager::process_participant_volatile_message_secure( } else { - EPROSIMA_LOG_INFO(SECURITY, "Received Reader Cryptography message but not found local writer " << - message.destination_endpoint_key()); + EPROSIMA_LOG_INFO(SECURITY, "Received Reader Cryptography message but not found local writer " + << message.destination_endpoint_key()); } } @@ -1947,8 +1947,8 @@ void SecurityManager::process_participant_volatile_message_secure( } else { - EPROSIMA_LOG_INFO(SECURITY, "Received Writer Cryptography message but not found local reader " << - message.destination_endpoint_key()); + EPROSIMA_LOG_INFO(SECURITY, "Received Writer Cryptography message but not found local reader " + << message.destination_endpoint_key()); } } @@ -2449,8 +2449,9 @@ int SecurityManager::decode_rtps_message( } else { - EPROSIMA_LOG_INFO(SECURITY, "Cannot decode rtps message from participant " << remote_participant_key << - "(" << exception.what() << ")"); + EPROSIMA_LOG_INFO(SECURITY, "Cannot decode rtps message from participant " << remote_participant_key + << "(" << exception.what() + << ")"); } } else @@ -2550,14 +2551,14 @@ bool SecurityManager::get_datawriter_sec_attributes( if ((returned_value = access_plugin_->get_datawriter_sec_attributes(*local_permissions_handle_, topic_name, partitions, security_attributes, exception)) == false) { - EPROSIMA_LOG_ERROR(SECURITY, "Error getting security attributes of local writer " << - " (" << exception.what() << ")" << std::endl); + EPROSIMA_LOG_ERROR(SECURITY, "Error getting security attributes of local writer " + << " (" << exception.what() << ")" << std::endl); } } else { - EPROSIMA_LOG_ERROR(SECURITY, "Error checking creation of local writer " << - " (" << exception.what() << ")" << std::endl); + EPROSIMA_LOG_ERROR(SECURITY, "Error checking creation of local writer " + << " (" << exception.what() << ")" << std::endl); returned_value = false; } } @@ -2732,14 +2733,14 @@ bool SecurityManager::get_datareader_sec_attributes( if ((returned_value = access_plugin_->get_datareader_sec_attributes(*local_permissions_handle_, topic_name, partitions, security_attributes, exception)) == false) { - EPROSIMA_LOG_ERROR(SECURITY, "Error getting security attributes of local reader " << - " (" << exception.what() << ")" << std::endl); + EPROSIMA_LOG_ERROR(SECURITY, "Error getting security attributes of local reader " + << " (" << exception.what() << ")" << std::endl); } } else { - EPROSIMA_LOG_ERROR(SECURITY, "Error checking creation of local reader " << - " (" << exception.what() << ")" << std::endl); + EPROSIMA_LOG_ERROR(SECURITY, "Error checking creation of local reader " + << " (" << exception.what() << ")" << std::endl); returned_value = false; } } @@ -3161,14 +3162,16 @@ bool SecurityManager::discovered_reader( else { EPROSIMA_LOG_ERROR(SECURITY, - "Crypto plugin fails registering remote reader " << remote_reader_data.guid() << - " of participant " << remote_participant_key); + "Crypto plugin fails registering remote reader " << remote_reader_data.guid() + << " of participant " + << remote_participant_key); } } else { - EPROSIMA_LOG_INFO(SECURITY, "Storing remote reader << " << remote_reader_data.guid() << - " of participant " << remote_participant_key << " on pendings"); + EPROSIMA_LOG_INFO(SECURITY, "Storing remote reader << " << remote_reader_data.guid() + << " of participant " + << remote_participant_key << " on pendings"); remote_reader_pending_discovery_messages_.push_back(std::make_tuple(remote_reader_data, remote_participant_key, writer_guid)); @@ -3529,14 +3532,16 @@ bool SecurityManager::discovered_writer( else { EPROSIMA_LOG_ERROR(SECURITY, - "Crypto plugin fails registering remote writer " << remote_writer_data.guid() << - " of participant " << remote_participant_key); + "Crypto plugin fails registering remote writer " << remote_writer_data.guid() + << " of participant " + << remote_participant_key); } } else { - EPROSIMA_LOG_INFO(SECURITY, "Storing remote writer << " << remote_writer_data.guid() << - " of participant " << remote_participant_key << "on pendings"); + EPROSIMA_LOG_INFO(SECURITY, "Storing remote writer << " << remote_writer_data.guid() + << " of participant " + << remote_participant_key << "on pendings"); remote_writer_pending_discovery_messages_.push_back(std::make_tuple(remote_writer_data, remote_participant_key, reader_guid)); @@ -3978,16 +3983,16 @@ bool SecurityManager::participant_authorized( if (!access_plugin_->check_remote_participant(*remote_permissions, domain_id_, participant_data, exception)) { - EPROSIMA_LOG_ERROR(SECURITY, "Error checking remote participant " << - participant_data.m_guid << " (" << exception.what() << ")."); + EPROSIMA_LOG_ERROR(SECURITY, "Error checking remote participant " + << participant_data.m_guid << " (" << exception.what() << ")."); access_plugin_->return_permissions_handle(remote_permissions, exception); remote_permissions = nullptr; } } else { - EPROSIMA_LOG_ERROR(SECURITY, "Error validating remote permissions for " << - participant_data.m_guid << " (" << exception.what() << ")."); + EPROSIMA_LOG_ERROR(SECURITY, "Error validating remote permissions for " + << participant_data.m_guid << " (" << exception.what() << ")."); if (remote_permissions != nullptr) { @@ -4001,8 +4006,8 @@ bool SecurityManager::participant_authorized( } else { - EPROSIMA_LOG_ERROR(SECURITY, "Not receive remote permissions of participant " << - participant_data.m_guid << " (" << exception.what() << ")."); + EPROSIMA_LOG_ERROR(SECURITY, "Not receive remote permissions of participant " + << participant_data.m_guid << " (" << exception.what() << ")."); } } @@ -4288,8 +4293,8 @@ void SecurityManager::resend_handshake_message_token( if (p_change != nullptr) { - EPROSIMA_LOG_INFO(SECURITY, "Authentication handshake resent to participant " << - remote_participant_key); + EPROSIMA_LOG_INFO(SECURITY, "Authentication handshake resent to participant " + << remote_participant_key); if (participant_stateless_message_writer_history_->add_change(p_change)) { remote_participant_info->change_sequence_number_ = p_change->sequenceNumber; @@ -4328,8 +4333,8 @@ void SecurityManager::on_validation_failed( EPROSIMA_LOG_ERROR(SECURITY_AUTHENTICATION, exception.what()); } - EPROSIMA_LOG_INFO(SECURITY, "Authentication failed for participant " << - participant_data.m_guid); + EPROSIMA_LOG_INFO(SECURITY, "Authentication failed for participant " + << participant_data.m_guid); // Inform user about authenticated remote participant. if (participant_->getListener() != nullptr) diff --git a/src/cpp/rtps/security/SecurityManager.h b/src/cpp/rtps/security/SecurityManager.h index 89a6e83706a..acaf388007e 100644 --- a/src/cpp/rtps/security/SecurityManager.h +++ b/src/cpp/rtps/security/SecurityManager.h @@ -82,6 +82,7 @@ class SecurityManager : private WriterListener */ SecurityManager( RTPSParticipantImpl* participant, + const RTPSParticipantAttributes& pattr, ISecurityPluginFactory& plugin_factory); // @brief Destructor diff --git a/src/cpp/security/accesscontrol/Permissions.cpp b/src/cpp/security/accesscontrol/Permissions.cpp index f62fe2d2104..48f298e5911 100644 --- a/src/cpp/security/accesscontrol/Permissions.cpp +++ b/src/cpp/security/accesscontrol/Permissions.cpp @@ -814,10 +814,10 @@ PermissionsHandle* Permissions::validate_local_permissions( Authentication&, const IdentityHandle& identity, const uint32_t domain_id, - const RTPSParticipantAttributes& participant_attr, + const PropertyPolicy& part_props, SecurityException& exception) { - PropertyPolicy access_properties = PropertyPolicyHelper::get_properties_with_prefix(participant_attr.properties, + PropertyPolicy access_properties = PropertyPolicyHelper::get_properties_with_prefix(part_props, "dds.sec.access.builtin.Access-Permissions."); if (PropertyPolicyHelper::length(access_properties) == 0) @@ -1067,7 +1067,6 @@ PermissionsHandle* Permissions::validate_remote_permissions( bool Permissions::check_create_participant( const PermissionsHandle& local_handle, const uint32_t /*domain_id*/, - const RTPSParticipantAttributes&, SecurityException& exception) { bool returned_value = false; diff --git a/src/cpp/security/accesscontrol/Permissions.h b/src/cpp/security/accesscontrol/Permissions.h index bb67b32c69d..a39a854278b 100644 --- a/src/cpp/security/accesscontrol/Permissions.h +++ b/src/cpp/security/accesscontrol/Permissions.h @@ -20,6 +20,7 @@ #define _SECURITY_ACCESSCONTROL_PERMISSIONS_H_ #include +#include #include namespace eprosima { @@ -37,7 +38,7 @@ class Permissions : public AccessControl Authentication& auth_plugin, const IdentityHandle& identity, const uint32_t domain_id, - const RTPSParticipantAttributes& participant_attr, + const PropertyPolicy& part_props, SecurityException& exception) override; bool get_permissions_token( @@ -77,7 +78,6 @@ class Permissions : public AccessControl bool check_create_participant( const PermissionsHandle& local_handle, const uint32_t domain_id, - const RTPSParticipantAttributes& qos, SecurityException& exception) override; bool check_remote_participant( diff --git a/src/cpp/security/authentication/PKIDH.cpp b/src/cpp/security/authentication/PKIDH.cpp index 638b4b24f4d..e4feb563dbc 100644 --- a/src/cpp/security/authentication/PKIDH.cpp +++ b/src/cpp/security/authentication/PKIDH.cpp @@ -240,7 +240,8 @@ static bool verify_certificate( } else { - EPROSIMA_LOG_WARNING(SECURITY_AUTHENTICATION, "Invalidation error of certificate (" << X509_verify_cert_error_string( + EPROSIMA_LOG_WARNING(SECURITY_AUTHENTICATION, + "Invalidation error of certificate (" << X509_verify_cert_error_string( errorCode) << ")"); } } @@ -1058,13 +1059,13 @@ ValidationResult_t PKIDH::validate_local_identity( IdentityHandle** local_identity_handle, GUID_t& adjusted_participant_key, const uint32_t /*domain_id*/, - const RTPSParticipantAttributes& participant_attr, + const PropertyPolicy& part_props, const GUID_t& candidate_participant_key, SecurityException& exception) { assert(local_identity_handle); - PropertyPolicy auth_properties = PropertyPolicyHelper::get_properties_with_prefix(participant_attr.properties, + PropertyPolicy auth_properties = PropertyPolicyHelper::get_properties_with_prefix(part_props, "dds.sec.auth.builtin.PKI-DH."); if (PropertyPolicyHelper::length(auth_properties) == 0) diff --git a/src/cpp/security/authentication/PKIDH.h b/src/cpp/security/authentication/PKIDH.h index c8b687cb3a0..9550d173f74 100644 --- a/src/cpp/security/authentication/PKIDH.h +++ b/src/cpp/security/authentication/PKIDH.h @@ -37,7 +37,7 @@ class PKIDH : public Authentication IdentityHandle** local_identity_handle, GUID_t& adjusted_participant_key, const uint32_t domain_id, - const RTPSParticipantAttributes& participant_attr, + const PropertyPolicy& part_props, const GUID_t& candidate_participant_key, SecurityException& exception) override; diff --git a/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.h b/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.h index 26326c84327..ef0704285e7 100644 --- a/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.h +++ b/test/mock/rtps/RTPSParticipant/fastdds/rtps/participant/RTPSParticipant.h @@ -148,7 +148,7 @@ class RTPS_DllAPI RTPSParticipant MOCK_CONST_METHOD0(disable_monitor_service, bool()); MOCK_METHOD0(is_monitor_service_created, bool()); - MOCK_METHOD1(create_monitor_service, fastdds::statistics::rtps::IStatusObserver* ( + MOCK_METHOD1(create_monitor_service, fastdds::statistics::rtps::IStatusObserver * ( fastdds::statistics::rtps::IStatusQueryable&)); #endif // FASTDDS_STATISTICS @@ -183,7 +183,7 @@ class RTPS_DllAPI RTPSParticipant return mp_event_thr; } - MOCK_CONST_METHOD0(typelookup_manager, fastdds::dds::builtin::TypeLookupManager* ()); + MOCK_CONST_METHOD0(typelookup_manager, fastdds::dds::builtin::TypeLookupManager * ()); MOCK_METHOD3(registerWriter, bool( RTPSWriter * Writer, @@ -204,7 +204,7 @@ class RTPS_DllAPI RTPSParticipant RTPSReader * Reader, const TopicAttributes& topicAtt, const ReaderQos& rqos, - const fastdds::rtps::ContentFilterProperty* content_filter)); + const fastdds::rtps::ContentFilterProperty * content_filter)); MOCK_METHOD3(updateReader, bool( RTPSReader * Reader, @@ -218,7 +218,7 @@ class RTPS_DllAPI RTPSParticipant RTPSReader * Reader, const TopicAttributes& topicAtt, const ReaderQos& rqos, - const fastdds::rtps::ContentFilterProperty* content_filter)); + const fastdds::rtps::ContentFilterProperty * content_filter)); std::vector get_netmask_filter_info() const { @@ -230,6 +230,21 @@ class RTPS_DllAPI RTPSParticipant return attributes_; } + const RTPSParticipantConstantAttributes& get_const_attributes() const + { + return const_attributes_; + } + + const RTPSParticipantMutableAttributes get_mutable_attributes() const + { + return RTPSParticipantMutableAttributes{attributes_}; + } + + RTPSParticipantAttributes copy_attributes() const + { + return attributes_; + } + bool update_attributes( const RTPSParticipantAttributes& patt) { @@ -251,6 +266,7 @@ class RTPS_DllAPI RTPSParticipant const GUID_t m_guid; mutable ResourceEvent mp_event_thr; RTPSParticipantAttributes attributes_; + RTPSParticipantConstantAttributes const_attributes_; }; } /* namespace rtps */ diff --git a/test/mock/rtps/RTPSParticipantAttributes/fastdds/rtps/attributes/RTPSParticipantAttributes.h b/test/mock/rtps/RTPSParticipantAttributes/fastdds/rtps/attributes/RTPSParticipantAttributes.h index 95188a863e0..f0d48354ff3 100644 --- a/test/mock/rtps/RTPSParticipantAttributes/fastdds/rtps/attributes/RTPSParticipantAttributes.h +++ b/test/mock/rtps/RTPSParticipantAttributes/fastdds/rtps/attributes/RTPSParticipantAttributes.h @@ -148,7 +148,8 @@ class BuiltinProtocols; typedef struct _PDPFactory { // Pointer to the PDP creator - PDP* (*CreatePDPInstance)(BuiltinProtocols*); + PDP* (*CreatePDPInstance)( + BuiltinProtocols*); // Pointer to the PDP destructor void (* ReleasePDPInstance)( PDP*); @@ -367,6 +368,152 @@ class TypeLookupSettings }; +/** + * Class MutableDiscoverySettings, to define the mutable attributes of the several discovery protocols available + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class MutableDiscoverySettings +{ +public: + + //! Discovery Server initial connections, needed if `discoveryProtocol` = CLIENT | SUPER_CLIENT | SERVER | BACKUP + eprosima::fastdds::rtps::RemoteServerList_t m_DiscoveryServers; + + MutableDiscoverySettings() = default; + + MutableDiscoverySettings( + const DiscoverySettings& discovery_settings) + : m_DiscoveryServers(discovery_settings.m_DiscoveryServers) + { + } + + bool operator ==( + const MutableDiscoverySettings& b) const + { + return (this->m_DiscoveryServers == b.m_DiscoveryServers); + } + +}; + +/** + * Class ConstantDiscoverySettings, to define the constant attributes of the several discovery protocols available + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class ConstantDiscoverySettings +{ +public: + + //! Chosen discovery protocol + DiscoveryProtocol discoveryProtocol = DiscoveryProtocol::SIMPLE; + + /** + * If set to true, SimpleEDP would be used. + */ + bool use_SIMPLE_EndpointDiscoveryProtocol = true; + + /** + * If set to true, StaticEDP based on an XML file would be implemented. + * The XML filename must be provided. + */ + bool use_STATIC_EndpointDiscoveryProtocol = false; + + /** + * Lease Duration of the RTPSParticipant, + * indicating how much time remote RTPSParticipants should consider this RTPSParticipant alive. + */ + fastrtps::Duration_t leaseDuration = { 20, 0 }; + + /** + * The period for the RTPSParticipant to send its Discovery Message to all other discovered RTPSParticipants + * as well as to all Multicast ports. + */ + fastrtps::Duration_t leaseDuration_announcementperiod = { 3, 0 }; + + //!Initial announcements configuration + InitialAnnouncementConfig initial_announcements; + + //!Attributes of the SimpleEDP protocol + SimpleEDPAttributes m_simpleEDP; + + //! function that returns a PDP object (only if EXTERNAL selected) + PDPFactory m_PDPfactory{}; + /** + * The period for the RTPSParticipant to: + * send its Discovery Message to its servers + * check for EDP endpoints matching + */ + fastrtps::Duration_t discoveryServer_client_syncperiod = { 0, 450 * 1000000}; // 450 milliseconds + + //! Filtering participants out depending on location + ParticipantFilteringFlags ignoreParticipantFlags = ParticipantFilteringFlags::NO_FILTER; + + ConstantDiscoverySettings() = default; + + ConstantDiscoverySettings( + const DiscoverySettings& discovery_settings) + : discoveryProtocol(discovery_settings.discoveryProtocol) + , use_SIMPLE_EndpointDiscoveryProtocol(discovery_settings.use_SIMPLE_EndpointDiscoveryProtocol) + , use_STATIC_EndpointDiscoveryProtocol(discovery_settings.use_STATIC_EndpointDiscoveryProtocol) + , leaseDuration(discovery_settings.leaseDuration) + , leaseDuration_announcementperiod(discovery_settings.leaseDuration_announcementperiod) + , initial_announcements(discovery_settings.initial_announcements) + , m_simpleEDP(discovery_settings.m_simpleEDP) + , m_PDPfactory(discovery_settings.m_PDPfactory) + , discoveryServer_client_syncperiod(discovery_settings.discoveryServer_client_syncperiod) + , ignoreParticipantFlags(discovery_settings.ignoreParticipantFlags) + , static_edp_xml_config_(discovery_settings.static_edp_xml_config()) + { + } + + bool operator ==( + const ConstantDiscoverySettings& b) const + { + return (this->discoveryProtocol == b.discoveryProtocol) && + (this->use_SIMPLE_EndpointDiscoveryProtocol == b.use_SIMPLE_EndpointDiscoveryProtocol) && + (this->use_STATIC_EndpointDiscoveryProtocol == b.use_STATIC_EndpointDiscoveryProtocol) && + (this->discoveryServer_client_syncperiod == b.discoveryServer_client_syncperiod) && + (this->m_PDPfactory == b.m_PDPfactory) && + (this->leaseDuration == b.leaseDuration) && + (this->leaseDuration_announcementperiod == b.leaseDuration_announcementperiod) && + (this->initial_announcements == b.initial_announcements) && + (this->m_simpleEDP == b.m_simpleEDP) && + (this->static_edp_xml_config_ == b.static_edp_xml_config_) && + (this->ignoreParticipantFlags == b.ignoreParticipantFlags); + } + + /** + * Get the static endpoint XML configuration. + * @return URI specifying the static endpoint XML configuration. + * The string could contain a filename (file://) or the XML content directly (data://). + */ + const char* static_edp_xml_config() const + { + return static_edp_xml_config_.c_str(); + } + + /** + * Get the static endpoint XML filename + * @return Static endpoint XML filename + */ + FASTRTPS_DEPRECATED("Use static_edp_xml_config()") + const char* getStaticEndpointXMLFilename() const + { + return static_edp_xml_config(); + } + +private: + + //! URI specifying the static EDP XML configuration, only necessary if use_STATIC_EndpointDiscoveryProtocol=true + //! This string could contain a filename or the XML content directly. + std::string static_edp_xml_config_ = ""; + +}; + +// Forward declaration to allow assignment from Constant and Mutable attributes. +class BuiltinConstantAttributes; +class BuiltinMutableAttributes; + + /** * Class BuiltinAttributes, to define the behavior of the RTPSParticipant builtin protocols. * @ingroup RTPS_ATTRIBUTES_MODULE @@ -423,6 +570,17 @@ class BuiltinAttributes virtual ~BuiltinAttributes() = default; + /** + * Composes this object from a BuiltinConstantAttributes and a BuiltinMutableAttributes. + * Every field is assigned: constant fields are taken from @c builtin_const, mutable fields + * are taken from @c builtin_mutable. + * @param builtin_const Constant builtin attributes to copy from. + * @param builtin_mutable Mutable builtin attributes to copy from. + */ + void compose( + const BuiltinConstantAttributes& builtin_const, + const BuiltinMutableAttributes& builtin_mutable); + bool operator ==( const BuiltinAttributes& b) const { @@ -445,16 +603,183 @@ class BuiltinAttributes }; +/** + * Class BuiltinMutableAttributes, to define the behavior of the mutable RTPSParticipant builtin protocols. + * This class is a subset of BuiltinAttributes. It is separated to keep the logic of constant and mutable attributes separated. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class BuiltinMutableAttributes +{ +public: + + //! Discovery protocol related attributes + MutableDiscoverySettings discovery_config; + + //! Metatraffic Unicast Locator List + LocatorList_t metatrafficUnicastLocatorList; + + //! The collection of external locators to use for communication on metatraffic topics. + fastdds::rtps::ExternalLocators metatraffic_external_unicast_locators; + + BuiltinMutableAttributes() = default; + + BuiltinMutableAttributes( + const BuiltinAttributes& builtin) + : discovery_config(builtin.discovery_config) + , metatrafficUnicastLocatorList(builtin.metatrafficUnicastLocatorList) + , metatraffic_external_unicast_locators(builtin.metatraffic_external_unicast_locators) + { + } + + ~BuiltinMutableAttributes() = default; + + bool operator ==( + const BuiltinMutableAttributes& b) const + { + return (this->discovery_config == b.discovery_config) && + (this->metatrafficUnicastLocatorList == b.metatrafficUnicastLocatorList) && + (this->metatraffic_external_unicast_locators == b.metatraffic_external_unicast_locators); + } + +}; + +/** + * Class BuiltinConstantAttributes, to define the behavior of the constant RTPSParticipant builtin protocols. + * This class is a subset of BuiltinAttributes. It is separated to keep the logic of constant and mutable attributes separated. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class BuiltinConstantAttributes +{ +public: + + /** + * Discovery protocol related constant attributes. Only the discovery server list is mutable, which must be + * accessed through the BuiltinMutableAttributes class. Its value in this class is only used as initial value. + */ + ConstantDiscoverySettings discovery_config; + + //! Indicates to use the WriterLiveliness protocol. + bool use_WriterLivelinessProtocol = true; + + //! TypeLookup Service settings + TypeLookupSettings typelookup_config; + + //! Network Configuration + NetworkConfigSet_t network_configuration = 0; + + //! Metatraffic Multicast Locator List + LocatorList_t metatrafficMulticastLocatorList; + + //! Initial peers. + LocatorList_t initialPeersList; + + //! Memory policy for builtin readers + MemoryManagementPolicy_t readerHistoryMemoryPolicy = + MemoryManagementPolicy_t::PREALLOCATED_WITH_REALLOC_MEMORY_MODE; + + //! Maximum payload size for builtin readers + uint32_t readerPayloadSize = BUILTIN_DATA_MAX_SIZE; + + //! Memory policy for builtin writers + MemoryManagementPolicy_t writerHistoryMemoryPolicy = + MemoryManagementPolicy_t::PREALLOCATED_WITH_REALLOC_MEMORY_MODE; + + //! Maximum payload size for builtin writers + uint32_t writerPayloadSize = BUILTIN_DATA_MAX_SIZE; + + //! Mutation tries if the port is being used. + uint32_t mutation_tries = 100u; + + //! Set to true to avoid multicast traffic on builtin endpoints + bool avoid_builtin_multicast = true; + + BuiltinConstantAttributes() = default; + + BuiltinConstantAttributes( + const BuiltinAttributes& builtin) + : discovery_config(builtin.discovery_config) + , use_WriterLivelinessProtocol(builtin.use_WriterLivelinessProtocol) + , typelookup_config(builtin.typelookup_config) + , network_configuration(builtin.network_configuration) + , metatrafficMulticastLocatorList(builtin.metatrafficMulticastLocatorList) + , initialPeersList(builtin.initialPeersList) + , readerHistoryMemoryPolicy(builtin.readerHistoryMemoryPolicy) + , readerPayloadSize(builtin.readerPayloadSize) + , writerHistoryMemoryPolicy(builtin.writerHistoryMemoryPolicy) + , writerPayloadSize(builtin.writerPayloadSize) + , mutation_tries(builtin.mutation_tries) + , avoid_builtin_multicast(builtin.avoid_builtin_multicast) + { + } + + ~BuiltinConstantAttributes() = default; + + bool operator ==( + const BuiltinConstantAttributes& b) const + { + return (this->discovery_config == b.discovery_config) && + (this->use_WriterLivelinessProtocol == b.use_WriterLivelinessProtocol) && + (this->typelookup_config.use_client == b.typelookup_config.use_client) && + (this->typelookup_config.use_server == b.typelookup_config.use_server) && + (this->network_configuration == b.network_configuration) && + (this->metatrafficMulticastLocatorList == b.metatrafficMulticastLocatorList) && + (this->initialPeersList == b.initialPeersList) && + (this->readerHistoryMemoryPolicy == b.readerHistoryMemoryPolicy) && + (this->readerPayloadSize == b.readerPayloadSize) && + (this->writerHistoryMemoryPolicy == b.writerHistoryMemoryPolicy) && + (this->writerPayloadSize == b.writerPayloadSize) && + (this->mutation_tries == b.mutation_tries) && + (this->avoid_builtin_multicast == b.avoid_builtin_multicast); + } + +}; + +inline void BuiltinAttributes::compose( + const BuiltinConstantAttributes& builtin_const, + const BuiltinMutableAttributes& builtin_mutable) +{ + // Constant Discovery settings + discovery_config.discoveryProtocol = builtin_const.discovery_config.discoveryProtocol; + discovery_config.use_SIMPLE_EndpointDiscoveryProtocol = + builtin_const.discovery_config.use_SIMPLE_EndpointDiscoveryProtocol; + discovery_config.use_STATIC_EndpointDiscoveryProtocol = + builtin_const.discovery_config.use_STATIC_EndpointDiscoveryProtocol; + discovery_config.leaseDuration = builtin_const.discovery_config.leaseDuration; + discovery_config.leaseDuration_announcementperiod = builtin_const.discovery_config.leaseDuration_announcementperiod; + discovery_config.initial_announcements = builtin_const.discovery_config.initial_announcements; + discovery_config.m_simpleEDP = builtin_const.discovery_config.m_simpleEDP; + discovery_config.m_PDPfactory = builtin_const.discovery_config.m_PDPfactory; + discovery_config.discoveryServer_client_syncperiod = + builtin_const.discovery_config.discoveryServer_client_syncperiod; + discovery_config.ignoreParticipantFlags = builtin_const.discovery_config.ignoreParticipantFlags; + // Mutable Discovery settings + discovery_config.m_DiscoveryServers = builtin_mutable.discovery_config.m_DiscoveryServers; + // Constant settings + use_WriterLivelinessProtocol = builtin_const.use_WriterLivelinessProtocol; + network_configuration = builtin_const.network_configuration; + metatrafficMulticastLocatorList = builtin_const.metatrafficMulticastLocatorList; + initialPeersList = builtin_const.initialPeersList; + readerHistoryMemoryPolicy = builtin_const.readerHistoryMemoryPolicy; + readerPayloadSize = builtin_const.readerPayloadSize; + writerHistoryMemoryPolicy = builtin_const.writerHistoryMemoryPolicy; + writerPayloadSize = builtin_const.writerPayloadSize; + mutation_tries = builtin_const.mutation_tries; + avoid_builtin_multicast = builtin_const.avoid_builtin_multicast; + // Mutable settings + metatrafficUnicastLocatorList = builtin_mutable.metatrafficUnicastLocatorList; + metatraffic_external_unicast_locators = builtin_mutable.metatraffic_external_unicast_locators; +} + /** * Class RTPSParticipantAttributes used to define different aspects of a RTPSParticipant. * @ingroup RTPS_ATTRIBUTES_MODULE */ class RTPSParticipantAttributes { - using FlowControllerDescriptorList = std::vector>; - public: + using FlowControllerDescriptorList = std::vector>; + RTPSParticipantAttributes() = default; virtual ~RTPSParticipantAttributes() = default; @@ -646,9 +971,226 @@ class RTPSParticipantAttributes fastdds::rtps::ThreadSettings security_log_thread; #endif // if HAVE_SECURITY - /*! Maximum message size used to avoid fragmentation, setted ONLY in LARGE_DATA. If this value is + /*! Maximum message size used to avoid fragmentation, set ONLY in LARGE_DATA. If this value is + * not zero, the network factory will allow the initialization of UDP transports with maxMessageSize + * higher than 65500K. + */ + uint32_t max_msg_size_no_frag = 0; + +private: + + //! Name of the participant. + string_255 name{"RTPSParticipant"}; +}; + +/** + * Class RTPSParticipantMutableAttributes used to define mutable aspects of a RTPSParticipant. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class RTPSParticipantMutableAttributes +{ +public: + + RTPSParticipantMutableAttributes() = default; + + RTPSParticipantMutableAttributes( + const RTPSParticipantAttributes& attrs) + : defaultUnicastLocatorList(attrs.defaultUnicastLocatorList) + , default_external_unicast_locators(attrs.default_external_unicast_locators) + , userData(attrs.userData) + , builtin(attrs.builtin) + { + } + + ~RTPSParticipantMutableAttributes() = default; + + bool operator ==( + const RTPSParticipantMutableAttributes& b) const + { + return (this->defaultUnicastLocatorList == b.defaultUnicastLocatorList) && + (this->default_external_unicast_locators == b.default_external_unicast_locators) && + (this->userData == b.userData) && + (this->builtin == b.builtin); + } + + /** + * Default list of Unicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the case + * that it was defined with NO UnicastLocators. At least ONE locator should be included in this list. + */ + LocatorList_t defaultUnicastLocatorList; + + /** + * The collection of external locators to use for communication on user created topics. + */ + fastdds::rtps::ExternalLocators default_external_unicast_locators; + + //! User Data of the participant + std::vector userData; + + //! Builtin parameters. + BuiltinMutableAttributes builtin; +}; + +/** + * Class RTPSParticipantConstantAttributes used to define constant aspects of a RTPSParticipant. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class RTPSParticipantConstantAttributes +{ +public: + + using FlowControllerDescriptorList = std::vector>; + + RTPSParticipantConstantAttributes() = default; + + RTPSParticipantConstantAttributes( + const RTPSParticipantAttributes& attrs) + : defaultMulticastLocatorList(attrs.defaultMulticastLocatorList) + , ignore_non_matching_locators(attrs.ignore_non_matching_locators) + , sendSocketBufferSize(attrs.sendSocketBufferSize) + , listenSocketBufferSize(attrs.listenSocketBufferSize) + , netmaskFilter(attrs.netmaskFilter) + , prefix(attrs.prefix) + , builtin(attrs.builtin) + , port(attrs.port) + , participantID(attrs.participantID) + , throughputController(attrs.throughputController) + , userTransports(attrs.userTransports) + , useBuiltinTransports(attrs.useBuiltinTransports) + , allocation(attrs.allocation) + , properties(attrs.properties) + , flow_controllers(attrs.flow_controllers) + , builtin_controllers_sender_thread(attrs.builtin_controllers_sender_thread) + , timed_events_thread(attrs.timed_events_thread) + , discovery_server_thread(attrs.discovery_server_thread) + , builtin_transports_reception_threads(attrs.builtin_transports_reception_threads) +#if HAVE_SECURITY + , security_log_thread(attrs.security_log_thread) +#endif // if HAVE_SECURITY + , max_msg_size_no_frag(attrs.max_msg_size_no_frag) + , name(attrs.getName()) + { + } + + ~RTPSParticipantConstantAttributes() = default; + + bool operator ==( + const RTPSParticipantConstantAttributes& b) const + { + return (this->defaultMulticastLocatorList == b.defaultMulticastLocatorList) && + (this->ignore_non_matching_locators == b.ignore_non_matching_locators) && + (this->sendSocketBufferSize == b.sendSocketBufferSize) && + (this->listenSocketBufferSize == b.listenSocketBufferSize) && + (this->netmaskFilter == b.netmaskFilter) && + (this->builtin == b.builtin) && + (this->port == b.port) && + (this->participantID == b.participantID) && + (this->throughputController == b.throughputController) && + (this->useBuiltinTransports == b.useBuiltinTransports) && + (this->allocation == b.allocation) && + (this->properties == b.properties) && + (this->prefix == b.prefix) && + (this->flow_controllers == b.flow_controllers) && + (this->builtin_controllers_sender_thread == b.builtin_controllers_sender_thread) && + (this->timed_events_thread == b.timed_events_thread) && +#if HAVE_SECURITY + (this->security_log_thread == b.security_log_thread) && +#endif // if HAVE_SECURITY + (this->discovery_server_thread == b.discovery_server_thread) && + (this->builtin_transports_reception_threads == b.builtin_transports_reception_threads); + } + + /** + * Default list of Multicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the + * case that it was defined with NO MulticastLocators. This is usually left empty. + */ + LocatorList_t defaultMulticastLocatorList; + + /** + * Whether locators that don't match with the announced locators should be kept. + */ + bool ignore_non_matching_locators = false; + + /*! + * @brief Send socket buffer size for the send resource. Zero value indicates to use default system buffer size. + * Default value: 0. + */ + uint32_t sendSocketBufferSize = 0; + + /*! Listen socket buffer for all listen resources. Zero value indicates to use default system buffer size. + * Default value: 0. + */ + uint32_t listenSocketBufferSize = 0; + + //! Netmask filter configuration + fastdds::rtps::NetmaskFilterKind netmaskFilter = fastdds::rtps::NetmaskFilterKind::AUTO; + + //! Optionally allows user to define the GuidPrefix_t + GuidPrefix_t prefix; + + inline bool ReadguidPrefix( + const char* pfx) + { + return bool(std::istringstream(pfx) >> prefix); + } + + //! Builtin parameters. + BuiltinConstantAttributes builtin; + + //! Port Parameters + PortParameters port; + + //! Participant ID + int32_t participantID = -1; + + /** + * @brief Throughput controller parameters. Leave default for uncontrolled flow. + * + * @deprecated Use flow_controllers on RTPSParticipantAttributes + */ + ThroughputControllerDescriptor throughputController; + + //! User defined transports to use alongside or in place of builtins. + std::vector> userTransports; + + //! Set as false to disable the creation of the default transports. + bool useBuiltinTransports = true; + + //! Holds allocation limits affecting collections managed by a participant. + RTPSParticipantAllocationAttributes allocation; + + //! Property policies + PropertyPolicy properties; + + //! Get the name of the participant. + inline const char* getName() const + { + return name.c_str(); + } + + //! Flow controllers. + FlowControllerDescriptorList flow_controllers; + + //! Thread settings for the builtin flow controllers sender threads + fastdds::rtps::ThreadSettings builtin_controllers_sender_thread; + + //! Thread settings for the timed events thread + fastdds::rtps::ThreadSettings timed_events_thread; + + //! Thread settings for the discovery server thread + fastdds::rtps::ThreadSettings discovery_server_thread; + + //! Thread settings for the builtin transports reception threads + fastdds::rtps::ThreadSettings builtin_transports_reception_threads; + +#if HAVE_SECURITY + //! Thread settings for the security log thread + fastdds::rtps::ThreadSettings security_log_thread; +#endif // if HAVE_SECURITY + + /*! Maximum message size used to avoid fragmentation, set ONLY in LARGE_DATA. If this value is * not zero, the network factory will allow the initialization of UDP transports with maxMessageSize - * higher than 65500 KB (s_maximumMessageSize). + * higher than 65500K. */ uint32_t max_msg_size_no_frag = 0; diff --git a/test/mock/rtps/RTPSParticipantImpl/rtps/participant/RTPSParticipantImpl.h b/test/mock/rtps/RTPSParticipantImpl/rtps/participant/RTPSParticipantImpl.h index 0e541a7e2a6..da15ea1e94f 100644 --- a/test/mock/rtps/RTPSParticipantImpl/rtps/participant/RTPSParticipantImpl.h +++ b/test/mock/rtps/RTPSParticipantImpl/rtps/participant/RTPSParticipantImpl.h @@ -149,7 +149,7 @@ class RTPSParticipantImpl const EntityId_t& entityId, bool isBuiltin, bool enable)); // *INDENT-ON* - MOCK_CONST_METHOD0(getParticipantMutex, std::recursive_mutex* ()); + MOCK_CONST_METHOD0(getParticipantMutex, std::recursive_mutex * ()); bool createWriter( RTPSWriter** writer, @@ -299,12 +299,27 @@ class RTPSParticipantImpl return attr_; } + const RTPSParticipantConstantAttributes& get_const_attributes() const + { + return const_attr_; + } + + const RTPSParticipantMutableAttributes get_mutable_attributes() const + { + return RTPSParticipantMutableAttributes{attr_}; + } + + RTPSParticipantAttributes copy_attributes() const + { + return attr_; + } + void get_sending_locators( rtps::LocatorList_t& /*locators*/) const { } - template + template static bool preprocess_endpoint_attributes( const EntityId_t&, std::atomic&, @@ -341,6 +356,7 @@ class RTPSParticipantImpl ResourceEvent events_; RTPSParticipantAttributes attr_; + RTPSParticipantConstantAttributes const_attr_; std::map endpoints_; diff --git a/test/mock/rtps/SecurityPluginFactory/rtps/security/MockAccessControlPlugin.h b/test/mock/rtps/SecurityPluginFactory/rtps/security/MockAccessControlPlugin.h index 3767d67d6a9..989c57a686f 100644 --- a/test/mock/rtps/SecurityPluginFactory/rtps/security/MockAccessControlPlugin.h +++ b/test/mock/rtps/SecurityPluginFactory/rtps/security/MockAccessControlPlugin.h @@ -41,7 +41,7 @@ class MockAccessControlPlugin : public AccessControl Authentication & auth_plugin, const IdentityHandle& identity, const uint32_t domain_id, - const RTPSParticipantAttributes& participant_attr, + const PropertyPolicy& part_props, SecurityException & exception), (override)); MOCK_METHOD(bool, get_permissions_token, ( @@ -74,7 +74,6 @@ class MockAccessControlPlugin : public AccessControl MOCK_METHOD(bool, check_create_participant, ( const PermissionsHandle& local_handle, const uint32_t domain_id, - const RTPSParticipantAttributes& qos, SecurityException & exception), (override)); MOCK_METHOD(bool, check_remote_participant, ( diff --git a/test/mock/rtps/SecurityPluginFactory/rtps/security/MockAuthenticationPlugin.h b/test/mock/rtps/SecurityPluginFactory/rtps/security/MockAuthenticationPlugin.h index 74462284bce..cd146160855 100644 --- a/test/mock/rtps/SecurityPluginFactory/rtps/security/MockAuthenticationPlugin.h +++ b/test/mock/rtps/SecurityPluginFactory/rtps/security/MockAuthenticationPlugin.h @@ -44,7 +44,7 @@ class MockAuthenticationPlugin : public Authentication MOCK_METHOD(ValidationResult_t, validate_local_identity, (IdentityHandle * *local_identity_handle, GUID_t & adjusted_participant_key, const uint32_t domain_id, - const RTPSParticipantAttributes& participant_attr, + const PropertyPolicy& part_props, const GUID_t& candidate_participant_key, SecurityException & exception), (override)); diff --git a/test/unittest/dds/participant/ParticipantTests.cpp b/test/unittest/dds/participant/ParticipantTests.cpp index d08dfb46200..8ac0281faaa 100644 --- a/test/unittest/dds/participant/ParticipantTests.cpp +++ b/test/unittest/dds/participant/ParticipantTests.cpp @@ -699,15 +699,22 @@ class DomainParticipantTest : public DomainParticipant }; -void get_rtps_attributes( - const DomainParticipant* participant, - fastrtps::rtps::RTPSParticipantAttributes& att) +fastrtps::rtps::RTPSParticipantAttributes get_rtps_attributes( + const DomainParticipant* participant) { const DomainParticipantTest* participant_test = static_cast(participant); - ASSERT_NE(nullptr, participant_test); + EXPECT_NE(nullptr, participant_test); + if (participant_test == nullptr) + { + return {}; + } const DomainParticipantImpl* participant_impl = participant_test->get_impl(); - ASSERT_NE(nullptr, participant_impl); - att = participant_impl->get_rtps_participant()->getRTPSParticipantAttributes(); + EXPECT_NE(nullptr, participant_impl); + if (participant_impl == nullptr) + { + return {}; + } + return participant_impl->get_rtps_participant()->copy_attributes(); } void helper_wait_for_at_least_entries( @@ -786,8 +793,9 @@ void set_server_qos( } void set_environment_variable( - const std::string environment_servers = "84.22.253.128:8888;;UDPv4:[localhost]:1234;[2a02:ec80:600:ed1a::3]:8783" - ) + const std::string environment_servers = + "84.22.253.128:8888;;UDPv4:[localhost]:1234;[2a02:ec80:600:ed1a::3]:8783" +) { #ifdef _WIN32 ASSERT_EQ(0, _putenv_s(rtps::DEFAULT_ROS2_MASTER_URI, environment_servers.c_str())); @@ -866,8 +874,7 @@ void set_and_check_with_environment_file( // Wait for the file watch callback std::this_thread::sleep_for(std::chrono::milliseconds(100)); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::SERVER); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, output); } @@ -891,8 +898,7 @@ TEST(ParticipantTests, SimpleParticipantRemoteServerListConfiguration) (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::CLIENT); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, output); @@ -929,8 +935,7 @@ TEST(ParticipantTests, NoBuiltinMetatrafficMulticastForClients) (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::CLIENT); EXPECT_EQ(attributes.builtin.metatrafficMulticastLocatorList.size(), 0); @@ -966,8 +971,7 @@ TEST(ParticipantTests, TransformSimpleParticipantToSuperclientByEnvVariable) (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::CLIENT); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, output); @@ -981,8 +985,7 @@ TEST(ParticipantTests, TransformSimpleParticipantToSuperclientByEnvVariable) (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_2); - fastrtps::rtps::RTPSParticipantAttributes attributes_2; - get_rtps_attributes(participant_2, attributes_2); + fastrtps::rtps::RTPSParticipantAttributes attributes_2 = get_rtps_attributes(participant_2); EXPECT_EQ(attributes_2.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::SUPER_CLIENT); EXPECT_EQ(attributes_2.builtin.discovery_config.m_DiscoveryServers, output); @@ -1058,8 +1061,7 @@ TEST(ParticipantTests, SimpleParticipantRemoteServerListConfigurationDNS) PARTICIPANT_QOS_DEFAULT); ASSERT_NE(nullptr, participant); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::CLIENT); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, output); @@ -1101,8 +1103,7 @@ TEST(ParticipantTests, SimpleParticipantDynamicAdditionRemoteServers) DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); // As the environment file does not have the ROS_DISCOVERY_SERVER variable set, this variable has been loaded from // the environment @@ -1110,13 +1111,14 @@ TEST(ParticipantTests, SimpleParticipantDynamicAdditionRemoteServers) // Modify environment file #ifndef __APPLE__ std::ofstream file(filename); - file << + file + << "{\"ROS_DISCOVERY_SERVER\": \"84.22.253.128:8888;192.168.1.133:64863;UDPv4:[localhost]:1234;[2a02:ec80:600:ed1a::3]:8783\"}"; file.close(); // Wait long enought for the file watch callback std::this_thread::sleep_for(std::chrono::milliseconds(100)); - get_rtps_attributes(participant, attributes); + attributes = get_rtps_attributes(participant); rtps::RemoteServerAttributes server; fastrtps::rtps::Locator_t locator; @@ -1149,8 +1151,7 @@ TEST(ParticipantTests, ClientParticipantRemoteServerListConfiguration) DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::CLIENT); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, qos_output); DomainParticipantQos result_qos = participant->get_qos(); @@ -1178,8 +1179,7 @@ TEST(ParticipantTests, ServerParticipantEnvironmentConfiguration) DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, server_qos); ASSERT_NE(nullptr, participant); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::SERVER); EXPECT_TRUE(attributes.builtin.discovery_config.m_DiscoveryServers.empty()); DomainParticipantQos result_qos = participant->get_qos(); @@ -1208,8 +1208,7 @@ TEST(ParticipantTests, ServerParticipantRemoteServerListConfiguration) DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::SERVER); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, qos_output); DomainParticipantQos result_qos = participant->get_qos(); @@ -1248,8 +1247,7 @@ TEST(ParticipantTests, ServerParticipantInconsistentRemoteServerListConfiguratio DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::SERVER); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, qos_output); @@ -1259,7 +1257,7 @@ TEST(ParticipantTests, ServerParticipantInconsistentRemoteServerListConfiguratio file << "{\"ROS_DISCOVERY_SERVER\": \"84.22.253.128:8888;192.168.1.133:64863;localhost:1234\"}"; file.close(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - get_rtps_attributes(participant, attributes); + attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, qos_output); // Capture log warning #ifndef __APPLE__ @@ -1311,8 +1309,7 @@ TEST(ParticipantTests, ServerParticipantInconsistentLocatorsRemoteServerListConf file << "{\"ROS_DISCOVERY_SERVER\": \"172.17.0.5:4321;192.168.1.133:64863\"}"; file.close(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, output); #endif // APPLE DomainParticipantQos result_qos = participant->get_qos(); @@ -1374,8 +1371,7 @@ TEST(ParticipantTests, ServerParticipantCorrectRemoteServerListConfiguration) DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant); - fastrtps::rtps::RTPSParticipantAttributes attributes; - get_rtps_attributes(participant, attributes); + fastrtps::rtps::RTPSParticipantAttributes attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, output); // Add new server through environment file // Even though the server added previously through the environment file is being pinged, it is not really being @@ -1393,7 +1389,7 @@ TEST(ParticipantTests, ServerParticipantCorrectRemoteServerListConfiguration) server.metatrafficUnicastLocatorList.push_back(locator); get_server_client_default_guidPrefix(2, server.guidPrefix); output.push_back(server); - get_rtps_attributes(participant, attributes); + attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, output); // Try to be consistent: add already known server std::this_thread::sleep_for(std::chrono::milliseconds(100)); @@ -1407,7 +1403,7 @@ TEST(ParticipantTests, ServerParticipantCorrectRemoteServerListConfiguration) server.metatrafficUnicastLocatorList.push_back(locator); get_server_client_default_guidPrefix(1, server.guidPrefix); output.push_back(server); - get_rtps_attributes(participant, attributes); + attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, output); result_qos = participant->get_qos(); EXPECT_EQ(ReturnCode_t::RETCODE_OK, participant->set_qos(result_qos)); @@ -1429,7 +1425,7 @@ TEST(ParticipantTests, ServerParticipantCorrectRemoteServerListConfiguration) result_qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(server); EXPECT_EQ(ReturnCode_t::RETCODE_OK, participant->set_qos(result_qos)); output.push_back(server); - get_rtps_attributes(participant, attributes); + attributes = get_rtps_attributes(participant); EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, output); #endif // APPLE result_qos = participant->get_qos(); @@ -4111,14 +4107,13 @@ TEST(ParticipantTests, ParticipantCreationWithBuiltinTransport) { { DomainParticipantQos qos; - fastrtps::rtps::RTPSParticipantAttributes attributes_; qos.setup_transports(rtps::BuiltinTransports::DEFAULT); DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_); - get_rtps_attributes(participant_, attributes_); + fastrtps::rtps::RTPSParticipantAttributes attributes_ = get_rtps_attributes(participant_); auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool { @@ -4139,14 +4134,13 @@ TEST(ParticipantTests, ParticipantCreationWithBuiltinTransport) { DomainParticipantQos qos; - fastrtps::rtps::RTPSParticipantAttributes attributes_; qos.setup_transports(rtps::BuiltinTransports::DEFAULTv6); DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_); - get_rtps_attributes(participant_, attributes_); + fastrtps::rtps::RTPSParticipantAttributes attributes_ = get_rtps_attributes(participant_); auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool { @@ -4167,14 +4161,13 @@ TEST(ParticipantTests, ParticipantCreationWithBuiltinTransport) { DomainParticipantQos qos; - fastrtps::rtps::RTPSParticipantAttributes attributes_; qos.setup_transports(rtps::BuiltinTransports::SHM); DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_); - get_rtps_attributes(participant_, attributes_); + fastrtps::rtps::RTPSParticipantAttributes attributes_ = get_rtps_attributes(participant_); auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool { @@ -4195,14 +4188,13 @@ TEST(ParticipantTests, ParticipantCreationWithBuiltinTransport) { DomainParticipantQos qos; - fastrtps::rtps::RTPSParticipantAttributes attributes_; qos.setup_transports(rtps::BuiltinTransports::UDPv4); DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_); - get_rtps_attributes(participant_, attributes_); + fastrtps::rtps::RTPSParticipantAttributes attributes_ = get_rtps_attributes(participant_); auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool { @@ -4223,14 +4215,13 @@ TEST(ParticipantTests, ParticipantCreationWithBuiltinTransport) { DomainParticipantQos qos; - fastrtps::rtps::RTPSParticipantAttributes attributes_; qos.setup_transports(rtps::BuiltinTransports::UDPv6); DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_); - get_rtps_attributes(participant_, attributes_); + fastrtps::rtps::RTPSParticipantAttributes attributes_ = get_rtps_attributes(participant_); auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool { @@ -4251,14 +4242,13 @@ TEST(ParticipantTests, ParticipantCreationWithBuiltinTransport) { DomainParticipantQos qos; - fastrtps::rtps::RTPSParticipantAttributes attributes_; qos.setup_transports(rtps::BuiltinTransports::LARGE_DATA); DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_); - get_rtps_attributes(participant_, attributes_); + fastrtps::rtps::RTPSParticipantAttributes attributes_ = get_rtps_attributes(participant_); auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool { @@ -4293,14 +4283,13 @@ TEST(ParticipantTests, ParticipantCreationWithBuiltinTransport) { DomainParticipantQos qos; - fastrtps::rtps::RTPSParticipantAttributes attributes_; qos.setup_transports(rtps::BuiltinTransports::LARGE_DATAv6); DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_); - get_rtps_attributes(participant_, attributes_); + fastrtps::rtps::RTPSParticipantAttributes attributes_ = get_rtps_attributes(participant_); auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool { @@ -4349,8 +4338,7 @@ class BuiltinTransportsOptionsTest (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_); - fastrtps::rtps::RTPSParticipantAttributes attr; - get_rtps_attributes(participant_, attr); + fastrtps::rtps::RTPSParticipantAttributes attr = get_rtps_attributes(participant_); EXPECT_TRUE(check_options_attr(attr, options)); EXPECT_EQ(attr.userTransports.size(), 3u); EXPECT_EQ(ReturnCode_t::RETCODE_OK, DomainParticipantFactory::get_instance()->delete_participant(participant_)); @@ -4367,8 +4355,7 @@ class BuiltinTransportsOptionsTest (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_); - fastrtps::rtps::RTPSParticipantAttributes attr; - get_rtps_attributes(participant_, attr); + fastrtps::rtps::RTPSParticipantAttributes attr = get_rtps_attributes(participant_); bool udp_ok = false; for (auto& transportDescriptor : attr.userTransports) { @@ -4400,8 +4387,7 @@ class BuiltinTransportsOptionsTest (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_); - fastrtps::rtps::RTPSParticipantAttributes attr; - get_rtps_attributes(participant_, attr); + fastrtps::rtps::RTPSParticipantAttributes attr = get_rtps_attributes(participant_); EXPECT_TRUE(check_default_participant(attr)); EXPECT_EQ(ReturnCode_t::RETCODE_OK, DomainParticipantFactory::get_instance()->delete_participant(participant_)); } @@ -4552,8 +4538,7 @@ TEST(ParticipantTests, ParticipantCreationWithLargeDataOptionsThroughAPI) (uint32_t)GET_PID() % 230, qos); ASSERT_NE(nullptr, participant_); - fastrtps::rtps::RTPSParticipantAttributes attr; - get_rtps_attributes(participant_, attr); + fastrtps::rtps::RTPSParticipantAttributes attr = get_rtps_attributes(participant_); EXPECT_TRUE(BuiltinTransportsOptionsTest::check_options_attr(attr, options)); EXPECT_EQ(attr.userTransports.size(), 3u); diff --git a/test/unittest/rtps/security/SecurityTests.hpp b/test/unittest/rtps/security/SecurityTests.hpp index 852cd82145e..f8a710ec985 100644 --- a/test/unittest/rtps/security/SecurityTests.hpp +++ b/test/unittest/rtps/security/SecurityTests.hpp @@ -68,6 +68,20 @@ class MockParticipantCrypto typedef HandleImpl MockParticipantCryptoHandle; +struct SecurityTestsGlobalDefaultValues +{ + // Default Values + RTPSParticipantAttributes pattr; + + SecurityTestsGlobalDefaultValues() + { + ::testing::DefaultValue::Set(pattr); + } + +}; + +static SecurityTestsGlobalDefaultValues g_security_default_values_; + class SecurityTest : public ::testing::Test { protected: @@ -141,7 +155,7 @@ class SecurityTest : public ::testing::Test , stateless_reader_(nullptr) , volatile_writer_(nullptr) , volatile_reader_(nullptr) - , manager_(&participant_, plugin_factory_) + , manager_(&participant_, g_security_default_values_.pattr, plugin_factory_) , participant_data_(c_default_RTPSParticipantAllocationAttributes) , default_cdr_message(RTPSMESSAGE_DEFAULT_SIZE) { @@ -217,18 +231,4 @@ class SecurityTest : public ::testing::Test }; -struct SecurityTestsGlobalDefaultValues -{ - // Default Values - RTPSParticipantAttributes pattr; - - SecurityTestsGlobalDefaultValues() - { - ::testing::DefaultValue::Set(pattr); - } - -}; - -static SecurityTestsGlobalDefaultValues g_security_default_values_; - #endif // __TEST_UNITTEST_RTPS_SECURITY_SECURITYTESTS_HPP__ diff --git a/test/unittest/security/accesscontrol/AccessControlTests.cpp b/test/unittest/security/accesscontrol/AccessControlTests.cpp index 3bf45125ce5..28725a7063d 100644 --- a/test/unittest/security/accesscontrol/AccessControlTests.cpp +++ b/test/unittest/security/accesscontrol/AccessControlTests.cpp @@ -169,6 +169,7 @@ void AccessControlTest::get_access_handle( bool should_success) { IdentityHandle* identity_handle = nullptr; + auto part_props = participant_attr.properties; ValidationResult_t result = ValidationResult_t::VALIDATION_FAILED; SecurityException exception; @@ -178,7 +179,7 @@ void AccessControlTest::get_access_handle( &identity_handle, adjusted_participant_key, domain_id, - participant_attr, + part_props, candidate_participant_key, exception); @@ -190,7 +191,7 @@ void AccessControlTest::get_access_handle( authentication_plugin, *identity_handle, domain_id, - participant_attr, + part_props, exception); bool success = *access_handle != nullptr; diff --git a/test/unittest/security/authentication/AuthenticationPluginTests.hpp b/test/unittest/security/authentication/AuthenticationPluginTests.hpp index e3434538cf7..34aac57cd02 100644 --- a/test/unittest/security/authentication/AuthenticationPluginTests.hpp +++ b/test/unittest/security/authentication/AuthenticationPluginTests.hpp @@ -112,7 +112,7 @@ TEST_F(AuthenticationPluginTest, validate_local_identity_validation_ok) result = plugin.validate_local_identity(&local_identity_handle, adjusted_participant_key, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key, exception); @@ -141,7 +141,7 @@ TEST_F(AuthenticationPluginTest, validate_local_identity_wrong_validation) result = plugin.validate_local_identity(&local_identity_handle, adjusted_participant_key, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key, exception); @@ -171,7 +171,7 @@ TEST_F(AuthenticationPluginTest, handshake_process_ok) result = plugin.validate_local_identity(&local_identity_handle1, adjusted_participant_key1, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key1, exception); @@ -183,7 +183,7 @@ TEST_F(AuthenticationPluginTest, handshake_process_ok) result = plugin.validate_local_identity(&local_identity_handle2, adjusted_participant_key2, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key2, exception); diff --git a/test/unittest/security/authentication/BuiltinPKIDHTests.cpp b/test/unittest/security/authentication/BuiltinPKIDHTests.cpp index a2655c7c004..1b90ddabc95 100644 --- a/test/unittest/security/authentication/BuiltinPKIDHTests.cpp +++ b/test/unittest/security/authentication/BuiltinPKIDHTests.cpp @@ -442,7 +442,7 @@ TEST_F(AuthenticationPluginTest, validate_local_identity_kagree_algo) result = plugin.validate_local_identity(&local_identity_handle, adjusted_participant_key, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key, exception); @@ -498,7 +498,7 @@ TEST_F(AuthenticationPluginTest, validate_local_identity_validation_ok_with_pwd) result = plugin.validate_local_identity(&local_identity_handle, adjusted_participant_key, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key, exception); @@ -533,7 +533,7 @@ TEST_F(AuthenticationPluginTest, validate_local_identity_no_pwd) result = plugin.validate_local_identity(&local_identity_handle, adjusted_participant_key, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key, exception); @@ -568,7 +568,7 @@ TEST_F(AuthenticationPluginTest, validate_local_identity_wrong_pwd) result = plugin.validate_local_identity(&local_identity_handle, adjusted_participant_key, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key, exception); @@ -601,7 +601,7 @@ TEST_F(AuthenticationPluginTest, validate_local_identity_wrong_identity_ca) result = plugin.validate_local_identity(&local_identity_handle, adjusted_participant_key, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key, exception); @@ -634,7 +634,7 @@ TEST_F(AuthenticationPluginTest, validate_local_identity_wrong_identity_certific result = plugin.validate_local_identity(&local_identity_handle, adjusted_participant_key, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key, exception); @@ -670,7 +670,7 @@ TEST_F(AuthenticationPluginTest, validate_local_identity_revoked_certificate) result = plugin.validate_local_identity(&local_identity_handle, adjusted_participant_key, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key, exception); @@ -703,7 +703,7 @@ TEST_F(AuthenticationPluginTest, validate_local_identity_revoked_certificate_wit result = plugin.validate_local_identity(&local_identity_handle, adjusted_participant_key, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key, exception); @@ -736,7 +736,7 @@ TEST_F(AuthenticationPluginTest, validate_local_identity_expired_certificate) result = plugin.validate_local_identity(&local_identity_handle, adjusted_participant_key, domain_id, - participant_attr, + participant_attr.properties, candidate_participant_key, exception);