diff --git a/include/fastdds/rtps/transport/TransportInterface.hpp b/include/fastdds/rtps/transport/TransportInterface.hpp index b5e0e5dcc9f..f8f1b15b768 100644 --- a/include/fastdds/rtps/transport/TransportInterface.hpp +++ b/include/fastdds/rtps/transport/TransportInterface.hpp @@ -262,7 +262,11 @@ class FASTDDS_EXPORTED_API TransportInterface uint32_t domainId, LocatorList& list) const = 0; - //! Assign port to the given unicast locator if not already defined + /** + * Assign only the port to the given unicast locator if not already defined + * Note: As the default address is usually valid for unicast, this method + * does not assign a new value + */ virtual bool fillUnicastLocator( Locator& locator, uint32_t well_known_port) const = 0; diff --git a/src/cpp/rtps/network/NetworkFactory.cpp b/src/cpp/rtps/network/NetworkFactory.cpp index 895b18f0e19..c7ef2cb51a7 100644 --- a/src/cpp/rtps/network/NetworkFactory.cpp +++ b/src/cpp/rtps/network/NetworkFactory.cpp @@ -25,6 +25,7 @@ #include #include +#include #include using namespace std; @@ -488,6 +489,23 @@ bool NetworkFactory::getDefaultUnicastLocators( return result; } +bool NetworkFactory::getDefaultMulticastLocators( + LocatorList_t& locators, + uint32_t port) const +{ + bool result = false; + for (auto& transport : mRegisteredTransports) + { + const MulticastTransportInterface* multicast_transport = + dynamic_cast(transport.get()); + if (multicast_transport) + { + result |= multicast_transport->getDefaultMulticastLocators(locators, port); + } + } + return result; +} + bool NetworkFactory::fill_default_locator_port( Locator_t& locator, uint32_t port) const @@ -503,6 +521,26 @@ bool NetworkFactory::fill_default_locator_port( return result; } +bool NetworkFactory::fill_default_multicast_locator( + Locator_t& locator, + uint32_t port) const +{ + bool result = false; + for (auto& transport : mRegisteredTransports) + { + if (transport->IsLocatorSupported(locator)) + { + const MulticastTransportInterface* multicast_transport = + dynamic_cast(transport.get()); + if (multicast_transport) + { + result |= multicast_transport->fillMulticastLocator(locator, port); + } + } + } + return result; +} + void NetworkFactory::Shutdown() { for (auto& transport : mRegisteredTransports) diff --git a/src/cpp/rtps/network/NetworkFactory.hpp b/src/cpp/rtps/network/NetworkFactory.hpp index 4e282106988..07d5ca0ed12 100644 --- a/src/cpp/rtps/network/NetworkFactory.hpp +++ b/src/cpp/rtps/network/NetworkFactory.hpp @@ -297,6 +297,16 @@ class NetworkFactory LocatorList_t& locators, uint32_t port) const; + /** + * Add the default multicast locator to the given locator list. + * + * @param locators List to be filled with the default multicast locator. + * @param port Port to be used in the default multicast locator. + * */ + bool getDefaultMulticastLocators( + LocatorList_t& locators, + uint32_t port) const; + /** * Fill the locator with the default unicast configuration. * */ @@ -304,6 +314,13 @@ class NetworkFactory Locator_t& locator, uint32_t port) const; + /** + * Fill the locator with the default multicast configuration. + * */ + bool fill_default_multicast_locator( + Locator_t& locator, + uint32_t port) const; + /** * Shutdown method to close the connections of the transports. */ diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp index f75fce58048..d60800da995 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp @@ -678,6 +678,7 @@ void RTPSParticipantImpl::setup_user_traffic() std::for_each(m_att.defaultUnicastLocatorList.begin(), m_att.defaultUnicastLocatorList.end(), [&](Locator_t& loc) { + // This methods always leaves the address unchanged m_network_Factory.fill_default_locator_port(loc, default_unicast_port_); }); m_network_Factory.NormalizeLocators(m_att.defaultUnicastLocatorList); @@ -687,7 +688,8 @@ void RTPSParticipantImpl::setup_user_traffic() std::for_each(m_att.defaultMulticastLocatorList.begin(), m_att.defaultMulticastLocatorList.end(), [&](Locator_t& loc) { - m_network_Factory.fill_default_locator_port(loc, multicast_port); + // This methods leaves the address unchanged if it was already set + m_network_Factory.fill_default_multicast_locator(loc, multicast_port); }); } @@ -2332,7 +2334,7 @@ void RTPSParticipantImpl::normalize_endpoint_locators( uint32_t multicast_port = m_network_Factory.calculate_well_known_port(domain_id_, m_att, true); for (Locator_t& loc : endpoint_att.multicastLocatorList) { - m_network_Factory.fill_default_locator_port(loc, multicast_port); + m_network_Factory.fill_default_multicast_locator(loc, multicast_port); } // Normalize unicast locators diff --git a/src/cpp/rtps/transport/MulticastTransportInterface.cpp b/src/cpp/rtps/transport/MulticastTransportInterface.cpp new file mode 100644 index 00000000000..ba03e5fd76c --- /dev/null +++ b/src/cpp/rtps/transport/MulticastTransportInterface.cpp @@ -0,0 +1,47 @@ +// Copyright 2026 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. + +#include + +#include + +namespace eprosima { +namespace fastdds { +namespace rtps { + +bool MulticastTransportInterface::fillMulticastLocator( + Locator& locator, + uint32_t well_known_port) const +{ + LocatorList defaults; + getDefaultMulticastLocators(defaults, well_known_port); + if (!defaults.empty()) + { + const Locator& default_loc = *defaults.begin(); + if (locator.port == 0) + { + locator.port = default_loc.port; + } + if (!IsAddressDefined(locator)) + { + IPLocator::copy_address(default_loc, locator); + } + } + + return true; +} + +} // namespace rtps +} // namespace fastdds +} // namespace eprosima diff --git a/src/cpp/rtps/transport/MulticastTransportInterface.hpp b/src/cpp/rtps/transport/MulticastTransportInterface.hpp new file mode 100644 index 00000000000..6d9dacbf42c --- /dev/null +++ b/src/cpp/rtps/transport/MulticastTransportInterface.hpp @@ -0,0 +1,46 @@ +// Copyright 2026 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. + +#ifndef _FASTDDS_MULTICAST_TRANSPORT_INTERFACE_HPP_ +#define _FASTDDS_MULTICAST_TRANSPORT_INTERFACE_HPP_ + +#include + +#include +#include + +namespace eprosima { +namespace fastdds { +namespace rtps { + +class MulticastTransportInterface +{ +public: + + virtual ~MulticastTransportInterface() = default; + + virtual bool getDefaultMulticastLocators( + LocatorList& locators, + uint32_t multicast_port) const = 0; + + virtual bool fillMulticastLocator( + Locator& locator, + uint32_t well_known_port) const; +}; + +} // namespace rtps +} // namespace fastdds +} // namespace eprosima + +#endif // _FASTDDS_MULTICAST_TRANSPORT_INTERFACE_HPP_ diff --git a/src/cpp/rtps/transport/TCPTransportInterface.cpp b/src/cpp/rtps/transport/TCPTransportInterface.cpp index 2369d8f77ef..44e4a94efec 100644 --- a/src/cpp/rtps/transport/TCPTransportInterface.cpp +++ b/src/cpp/rtps/transport/TCPTransportInterface.cpp @@ -1690,7 +1690,7 @@ bool TCPTransportInterface::getDefaultMetatrafficMulticastLocators( uint32_t ) const { // TCP doesn't have multicast support - return true; + return false; } bool TCPTransportInterface::getDefaultMetatrafficUnicastLocators( @@ -1722,7 +1722,7 @@ bool TCPTransportInterface::fillMetatrafficMulticastLocator( uint32_t) const { // TCP doesn't have multicast support - return true; + return false; } bool TCPTransportInterface::fillMetatrafficUnicastLocator( diff --git a/src/cpp/rtps/transport/TCPTransportInterface.h b/src/cpp/rtps/transport/TCPTransportInterface.h index c3faf50b38a..b304cb21d72 100644 --- a/src/cpp/rtps/transport/TCPTransportInterface.h +++ b/src/cpp/rtps/transport/TCPTransportInterface.h @@ -452,6 +452,10 @@ class TCPTransportInterface : public TransportInterface */ virtual std::vector get_binding_interfaces_list() = 0; + /** + * This method should never be called because TCP interfaces do not support + * multicast locators. It always returns false + */ bool getDefaultMetatrafficMulticastLocators( LocatorList& locators, uint32_t metatraffic_multicast_port) const override; @@ -464,6 +468,10 @@ class TCPTransportInterface : public TransportInterface LocatorList& locators, uint32_t unicast_port) const override; + /** + * This method should never be called because TCP interfaces do not support + * multicast locators. It always returns false + */ bool fillMetatrafficMulticastLocator( Locator& locator, uint32_t metatraffic_multicast_port) const override; diff --git a/src/cpp/rtps/transport/UDPTransportInterface.cpp b/src/cpp/rtps/transport/UDPTransportInterface.cpp index 710ec34971c..4aab1333a9b 100644 --- a/src/cpp/rtps/transport/UDPTransportInterface.cpp +++ b/src/cpp/rtps/transport/UDPTransportInterface.cpp @@ -724,9 +724,19 @@ bool UDPTransportInterface::fillMetatrafficMulticastLocator( Locator& locator, uint32_t metatraffic_multicast_port) const { - if (locator.port == 0) + LocatorList defaults; + getDefaultMetatrafficMulticastLocators(defaults, metatraffic_multicast_port); + if (!defaults.empty()) { - locator.port = metatraffic_multicast_port; + const Locator& default_loc = *defaults.begin(); + if (locator.port == 0) + { + locator.port = default_loc.port; + } + if (!IsAddressDefined(locator)) + { + IPLocator::copy_address(default_loc, locator); + } } return true; } diff --git a/src/cpp/rtps/transport/UDPTransportInterface.h b/src/cpp/rtps/transport/UDPTransportInterface.h index 1309574b399..6aababffae9 100644 --- a/src/cpp/rtps/transport/UDPTransportInterface.h +++ b/src/cpp/rtps/transport/UDPTransportInterface.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -36,7 +37,9 @@ namespace eprosima { namespace fastdds { namespace rtps { -class UDPTransportInterface : public TransportInterface +class UDPTransportInterface + : public TransportInterface + , public MulticastTransportInterface { friend class UDPSenderResource; friend struct TSN_UDPSender; diff --git a/src/cpp/rtps/transport/UDPv4Transport.cpp b/src/cpp/rtps/transport/UDPv4Transport.cpp index 5eca5e5abdd..9826638f4bc 100644 --- a/src/cpp/rtps/transport/UDPv4Transport.cpp +++ b/src/cpp/rtps/transport/UDPv4Transport.cpp @@ -261,6 +261,18 @@ bool UDPv4Transport::getDefaultMetatrafficMulticastLocators( return true; } +bool UDPv4Transport::getDefaultMulticastLocators( + LocatorList& locators, + uint32_t multicast_port) const +{ + Locator locator; + locator.kind = LOCATOR_KIND_UDPv4; + locator.port = static_cast(multicast_port); + IPLocator::setIPv4(locator, DEFAULT_MULTICAST_ADDRESS); + locators.push_back(locator); + return true; +} + bool UDPv4Transport::getDefaultMetatrafficUnicastLocators( LocatorList& locators, uint32_t metatraffic_unicast_port) const diff --git a/src/cpp/rtps/transport/UDPv4Transport.h b/src/cpp/rtps/transport/UDPv4Transport.h index ceabb4c4a3a..b491f26ce66 100644 --- a/src/cpp/rtps/transport/UDPv4Transport.h +++ b/src/cpp/rtps/transport/UDPv4Transport.h @@ -81,6 +81,10 @@ class UDPv4Transport : public UDPTransportInterface LocatorList& locators, uint32_t metatraffic_unicast_port) const override; + bool getDefaultMulticastLocators( + LocatorList& locators, + uint32_t multicast_port) const override; + bool getDefaultUnicastLocators( LocatorList& locators, uint32_t unicast_port) const override; @@ -169,6 +173,9 @@ class UDPv4Transport : public UDPTransportInterface }; const char* const DEFAULT_METATRAFFIC_MULTICAST_ADDRESS = "239.255.0.1"; +// Metatraffic multicast address is the same as default multicast address, +// but we keep this definition in case we want to differentiate them in the future +const char* const DEFAULT_MULTICAST_ADDRESS = DEFAULT_METATRAFFIC_MULTICAST_ADDRESS; } // namespace rtps } // namespace fastdds diff --git a/src/cpp/rtps/transport/UDPv6Transport.cpp b/src/cpp/rtps/transport/UDPv6Transport.cpp index f144c28c108..7a488520d0d 100644 --- a/src/cpp/rtps/transport/UDPv6Transport.cpp +++ b/src/cpp/rtps/transport/UDPv6Transport.cpp @@ -257,7 +257,7 @@ bool UDPv6Transport::getDefaultMetatrafficMulticastLocators( Locator locator; locator.kind = LOCATOR_KIND_UDPv6; locator.port = static_cast(metatraffic_multicast_port); - IPLocator::setIPv6(locator, "ff1e::ffff:efff:1"); + IPLocator::setIPv6(locator, DEFAULT_METATRAFFIC_MULTICAST_ADDRESS_v6); locators.push_back(locator); return true; } @@ -275,6 +275,18 @@ bool UDPv6Transport::getDefaultMetatrafficUnicastLocators( return true; } +bool UDPv6Transport::getDefaultMulticastLocators( + LocatorList& locators, + uint32_t multicast_port) const +{ + Locator locator; + locator.kind = LOCATOR_KIND_UDPv6; + locator.port = static_cast(multicast_port); + IPLocator::setIPv6(locator, DEFAULT_MULTICAST_ADDRESS_v6); + locators.push_back(locator); + return true; +} + bool UDPv6Transport::getDefaultUnicastLocators( LocatorList& locators, uint32_t unicast_port) const @@ -293,7 +305,7 @@ void UDPv6Transport::AddDefaultOutputLocator( { // TODO What is the default IPv6 address? Locator temp; - IPLocator::createLocator(LOCATOR_KIND_UDPv6, "ff1e::ffff:efff:1", 0, temp); + IPLocator::createLocator(LOCATOR_KIND_UDPv6, DEFAULT_MULTICAST_ADDRESS_v6, 0, temp); defaultList.push_back(temp); } diff --git a/src/cpp/rtps/transport/UDPv6Transport.h b/src/cpp/rtps/transport/UDPv6Transport.h index 0f4d4fb5758..6fd40c28488 100644 --- a/src/cpp/rtps/transport/UDPv6Transport.h +++ b/src/cpp/rtps/transport/UDPv6Transport.h @@ -78,6 +78,10 @@ class UDPv6Transport : public UDPTransportInterface LocatorList& locators, uint32_t metatraffic_unicast_port) const override; + bool getDefaultMulticastLocators( + LocatorList& locators, + uint32_t multicast_port) const override; + bool getDefaultUnicastLocators( LocatorList& locators, uint32_t unicast_port) const override; @@ -166,6 +170,9 @@ class UDPv6Transport : public UDPTransportInterface const std::string& ip2); }; +const char* const DEFAULT_METATRAFFIC_MULTICAST_ADDRESS_v6 = "ff1e::ffff:efff:1"; +const char* const DEFAULT_MULTICAST_ADDRESS_v6 = DEFAULT_METATRAFFIC_MULTICAST_ADDRESS_v6; + } // namespace rtps } // namespace fastdds } // namespace eprosima diff --git a/src/cpp/source.cmake b/src/cpp/source.cmake index 6a0b9d64e90..cd0071e2d3a 100644 --- a/src/cpp/source.cmake +++ b/src/cpp/source.cmake @@ -178,6 +178,7 @@ set(${PROJECT_NAME}_source_files ${FASTDDS_SOURCE_DIR}/rtps/domain/RTPSDomain.cpp ${FASTDDS_SOURCE_DIR}/rtps/transport/ChainingTransport.cpp ${FASTDDS_SOURCE_DIR}/rtps/transport/ChannelResource.cpp + ${FASTDDS_SOURCE_DIR}/rtps/transport/MulticastTransportInterface.cpp ${FASTDDS_SOURCE_DIR}/rtps/transport/network/NetmaskFilterKind.cpp ${FASTDDS_SOURCE_DIR}/rtps/transport/network/NetworkInterface.cpp ${FASTDDS_SOURCE_DIR}/rtps/transport/network/NetworkInterfaceWithFilter.cpp diff --git a/test/unittest/dds/publisher/CMakeLists.txt b/test/unittest/dds/publisher/CMakeLists.txt index 0bdb9d63911..e38664dd946 100644 --- a/test/unittest/dds/publisher/CMakeLists.txt +++ b/test/unittest/dds/publisher/CMakeLists.txt @@ -159,6 +159,7 @@ set(DATAWRITERTESTS_SOURCE DataWriterTests.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/domain/RTPSDomain.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/domain/RTPSDomainExtras.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/ChannelResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/MulticastTransportInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetmaskFilterKind.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterfaceWithFilter.cpp diff --git a/test/unittest/rtps/discovery/CMakeLists.txt b/test/unittest/rtps/discovery/CMakeLists.txt index e105270d448..7cd940727a0 100644 --- a/test/unittest/rtps/discovery/CMakeLists.txt +++ b/test/unittest/rtps/discovery/CMakeLists.txt @@ -93,11 +93,11 @@ gtest_discover_tests(EdpTests) #PDP TESTS set(TCPTransportInterface_SOURCE - ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TransportInterface.cpp - ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/ChannelResource.cpp - ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/PortBasedTransportDescriptor.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/CDRMessage.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageCreator.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/ChannelResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/MulticastTransportInterface.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/PortBasedTransportDescriptor.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/tcp/RTCPMessageManager.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/tcp/TCPControlMessage.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TCPAcceptor.cpp @@ -105,6 +105,7 @@ set(TCPTransportInterface_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TCPChannelResource.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TCPChannelResourceBasic.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TCPTransportInterface.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TransportInterface.cpp ) if(TLS_FOUND) set(TCPTransportInterface_SOURCE diff --git a/test/unittest/rtps/network/CMakeLists.txt b/test/unittest/rtps/network/CMakeLists.txt index f1d9a84475d..40e8d42cccf 100644 --- a/test/unittest/rtps/network/CMakeLists.txt +++ b/test/unittest/rtps/network/CMakeLists.txt @@ -34,6 +34,7 @@ set(NETWORKFACTORYTESTS_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/resources/TimedEvent.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/resources/TimedEventImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/ChannelResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/MulticastTransportInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetmaskFilterKind.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterfaceWithFilter.cpp diff --git a/test/unittest/rtps/network/NetworkFactoryTests.cpp b/test/unittest/rtps/network/NetworkFactoryTests.cpp index 5b073d52a2f..0df90d6e730 100644 --- a/test/unittest/rtps/network/NetworkFactoryTests.cpp +++ b/test/unittest/rtps/network/NetworkFactoryTests.cpp @@ -660,6 +660,111 @@ TEST_F(NetworkTests, LocatorShrink) } } +TEST_F(NetworkTests, FillDefaultMulticastLocator_UDPv4_fills_default_attributes_when_empty) +{ + // Register UDPv4 transport + NetworkFactory f{pattr}; + eprosima::fastdds::rtps::UDPv4TransportDescriptor udpv4; + f.RegisterTransport(&udpv4); + + const uint32_t test_port = 7400; + + // Case 1: empty address + zero port -> both address and port are filled + { + Locator_t locator; + locator.kind = LOCATOR_KIND_UDPv4; + locator.port = 0; + locator.set_Invalid_Address(); + + ASSERT_TRUE(f.fill_default_multicast_locator(locator, test_port)); + ASSERT_EQ(locator.port, test_port); + ASSERT_TRUE(IsAddressDefined(locator)); + + Locator_t expected; + IPLocator::createLocator(LOCATOR_KIND_UDPv4, "239.255.0.1", test_port, expected); + ASSERT_EQ(IPLocator::toIPv4string(locator), IPLocator::toIPv4string(expected)); + } + + // Case 2: empty address + nonzero port -> only address is filled, port preserved + { + Locator_t locator; + locator.kind = LOCATOR_KIND_UDPv4; + locator.port = 7500; + locator.set_Invalid_Address(); + + ASSERT_TRUE(f.fill_default_multicast_locator(locator, test_port)); + ASSERT_EQ(locator.port, static_cast(7500)); + ASSERT_TRUE(IsAddressDefined(locator)); + + Locator_t expected; + IPLocator::createLocator(LOCATOR_KIND_UDPv4, "239.255.0.1", 7500, expected); + ASSERT_EQ(IPLocator::toIPv4string(locator), IPLocator::toIPv4string(expected)); + } + + // Case 3: address already defined -> address is NOT overwritten + { + Locator_t locator; + IPLocator::createLocator(LOCATOR_KIND_UDPv4, "239.255.1.1", 0, locator); + + ASSERT_TRUE(f.fill_default_multicast_locator(locator, test_port)); + ASSERT_EQ(locator.port, test_port); + ASSERT_EQ(IPLocator::toIPv4string(locator), std::string("239.255.1.1")); + } +} + +TEST_F(NetworkTests, FillDefaultMulticastLocator_UDPv6_fills_default_attributes_when_empty) +{ + // Register UDPv6 transport + NetworkFactory f{pattr}; + eprosima::fastdds::rtps::UDPv6TransportDescriptor udpv6; + f.RegisterTransport(&udpv6); + + const uint32_t test_port = 7400; + + // Case 1: empty address -> address is filled with default UDPv6 multicast address + { + Locator_t locator; + locator.kind = LOCATOR_KIND_UDPv6; + locator.port = 0; + locator.set_Invalid_Address(); + + ASSERT_TRUE(f.fill_default_multicast_locator(locator, test_port)); + ASSERT_EQ(locator.port, test_port); + ASSERT_TRUE(IsAddressDefined(locator)); + + Locator_t expected; + IPLocator::createLocator(LOCATOR_KIND_UDPv6, "ff1e::ffff:efff:1", test_port, expected); + ASSERT_EQ(IPLocator::toIPv6string(locator), IPLocator::toIPv6string(expected)); + } + + // Case 2: empty address + nonzero port -> only address is filled, port preserved + { + Locator_t locator; + locator.kind = LOCATOR_KIND_UDPv6; + locator.port = 7500; + locator.set_Invalid_Address(); + + ASSERT_TRUE(f.fill_default_multicast_locator(locator, test_port)); + ASSERT_EQ(locator.port, static_cast(7500)); + ASSERT_TRUE(IsAddressDefined(locator)); + + Locator_t expected; + IPLocator::createLocator(LOCATOR_KIND_UDPv6, "ff1e::ffff:efff:1", 7500, expected); + ASSERT_EQ(IPLocator::toIPv6string(locator), IPLocator::toIPv6string(expected)); + } + + // Case 3: address already defined -> address is NOT overwritten + { + Locator_t locator; + IPLocator::createLocator(LOCATOR_KIND_UDPv6, "ff1e::1", 0, locator); + std::string original_address = IPLocator::toIPv6string(locator); + + ASSERT_TRUE(f.fill_default_multicast_locator(locator, test_port)); + ASSERT_EQ(locator.port, test_port); + ASSERT_EQ(IPLocator::toIPv6string(locator), original_address); + } +} + int main( int argc, char** argv) diff --git a/test/unittest/rtps/reader/CMakeLists.txt b/test/unittest/rtps/reader/CMakeLists.txt index 33385c73547..b6f84d32b9f 100644 --- a/test/unittest/rtps/reader/CMakeLists.txt +++ b/test/unittest/rtps/reader/CMakeLists.txt @@ -280,6 +280,7 @@ set(STATEFUL_READER_TESTS_SOURCE StatefulReaderTests.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/domain/RTPSDomain.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/domain/RTPSDomainExtras.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/ChannelResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/MulticastTransportInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetmaskFilterKind.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterfaceWithFilter.cpp @@ -543,6 +544,7 @@ set(STATELESS_READER_TESTS_SOURCE StatelessReaderTests.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/domain/RTPSDomain.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/domain/RTPSDomainExtras.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/ChannelResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/MulticastTransportInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetmaskFilterKind.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterfaceWithFilter.cpp diff --git a/test/unittest/statistics/dds/CMakeLists.txt b/test/unittest/statistics/dds/CMakeLists.txt index b1bd5dcc2dd..b7dc0b559c6 100644 --- a/test/unittest/statistics/dds/CMakeLists.txt +++ b/test/unittest/statistics/dds/CMakeLists.txt @@ -265,6 +265,7 @@ if (SQLITE3_SUPPORT AND FASTDDS_STATISTICS AND NOT QNX) ${PROJECT_SOURCE_DIR}/src/cpp/rtps/domain/RTPSDomain.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/domain/RTPSDomainExtras.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/ChannelResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/MulticastTransportInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetmaskFilterKind.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterfaceWithFilter.cpp @@ -454,6 +455,7 @@ if (SQLITE3_SUPPORT AND FASTDDS_STATISTICS AND NOT QNX) ${PROJECT_SOURCE_DIR}/src/cpp/rtps/domain/RTPSDomain.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/domain/RTPSDomainExtras.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/ChannelResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/MulticastTransportInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetmaskFilterKind.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterfaceWithFilter.cpp diff --git a/test/unittest/statistics/rtps/CMakeLists.txt b/test/unittest/statistics/rtps/CMakeLists.txt index d85caf9c6b6..e52586f5714 100644 --- a/test/unittest/statistics/rtps/CMakeLists.txt +++ b/test/unittest/statistics/rtps/CMakeLists.txt @@ -47,10 +47,10 @@ target_link_libraries(RTPSStatisticsTests gtest_discover_tests(RTPSStatisticsTests) set(TCPTransportInterface_SOURCE - ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TransportInterface.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageCreator.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/ChannelResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/MulticastTransportInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/PortBasedTransportDescriptor.cpp - ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageCreator.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/tcp/RTCPMessageManager.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/tcp/TCPControlMessage.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TCPAcceptor.cpp @@ -58,6 +58,7 @@ set(TCPTransportInterface_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TCPChannelResource.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TCPChannelResourceBasic.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TCPTransportInterface.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TransportInterface.cpp ) if(TLS_FOUND) set(TCPTransportInterface_SOURCE diff --git a/test/unittest/transport/CMakeLists.txt b/test/unittest/transport/CMakeLists.txt index 9491059d35b..318e29e23f2 100644 --- a/test/unittest/transport/CMakeLists.txt +++ b/test/unittest/transport/CMakeLists.txt @@ -49,6 +49,7 @@ endif() set(TCPTransportInterface_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/CDRMessage.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageCreator.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/MulticastTransportInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/tcp/RTCPMessageManager.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/tcp/TCPControlMessage.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/TCPAcceptor.cpp @@ -189,6 +190,7 @@ set(TCPV4TESTS_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/resources/TimedEvent.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/resources/TimedEventImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/ChannelResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/MulticastTransportInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetmaskFilterKind.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterfaceWithFilter.cpp @@ -240,6 +242,7 @@ set(TCPV6TESTS_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/resources/TimedEvent.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/resources/TimedEventImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/ChannelResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/MulticastTransportInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetmaskFilterKind.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterface.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/transport/network/NetworkInterfaceWithFilter.cpp