diff --git a/src/cpp/rtps/transport/TCPAcceptor.cpp b/src/cpp/rtps/transport/TCPAcceptor.cpp index d4c2ba32552..2db4b9dcc4b 100644 --- a/src/cpp/rtps/transport/TCPAcceptor.cpp +++ b/src/cpp/rtps/transport/TCPAcceptor.cpp @@ -31,6 +31,7 @@ TCPAcceptor::TCPAcceptor( , locator_(locator) , io_service_(&io_service) { + locator_.port = acceptor_.local_endpoint().port(); endpoint_ = asio::ip::tcp::endpoint(parent->generate_protocol(), IPLocator::getPhysicalPort(locator_)); } @@ -43,6 +44,7 @@ TCPAcceptor::TCPAcceptor( , locator_(locator) , io_service_(&io_service) { + locator_.port = acceptor_.local_endpoint().port(); endpoint_ = asio::ip::tcp::endpoint(asio::ip::address::from_string(interface), IPLocator::getPhysicalPort(locator_)); } diff --git a/src/cpp/rtps/transport/TCPTransportInterface.cpp b/src/cpp/rtps/transport/TCPTransportInterface.cpp index f375da66701..a8c514a7e3d 100644 --- a/src/cpp/rtps/transport/TCPTransportInterface.cpp +++ b/src/cpp/rtps/transport/TCPTransportInterface.cpp @@ -252,9 +252,10 @@ void TCPTransportInterface::calculate_crc( header.crc = crc; } -bool TCPTransportInterface::create_acceptor_socket( +uint16_t TCPTransportInterface::create_acceptor_socket( const Locator& locator) { + uint16_t final_port = 0; try { if (is_interface_whitelist_empty()) @@ -264,16 +265,18 @@ bool TCPTransportInterface::create_acceptor_socket( { std::shared_ptr acceptor = std::make_shared(io_service_, this, locator); - acceptors_[locator] = acceptor; + acceptors_[acceptor->locator()] = acceptor; acceptor->accept(this, ssl_context_); + final_port = static_cast(acceptor->locator().port); } else #endif // if TLS_FOUND { std::shared_ptr acceptor = std::make_shared(io_service_, this, locator); - acceptors_[locator] = acceptor; + acceptors_[acceptor->locator()] = acceptor; acceptor->accept(this); + final_port = static_cast(acceptor->locator().port); } EPROSIMA_LOG_INFO(RTCP, " OpenAndBindInput (physical: " << IPLocator::getPhysicalPort( @@ -291,16 +294,18 @@ bool TCPTransportInterface::create_acceptor_socket( { std::shared_ptr acceptor = std::make_shared(io_service_, sInterface, locator); - acceptors_[locator] = acceptor; + acceptors_[acceptor->locator()] = acceptor; acceptor->accept(this, ssl_context_); + final_port = static_cast(acceptor->locator().port); } else #endif // if TLS_FOUND { std::shared_ptr acceptor = std::make_shared(io_service_, sInterface, locator); - acceptors_[locator] = acceptor; + acceptors_[acceptor->locator()] = acceptor; acceptor->accept(this); + final_port = static_cast(acceptor->locator().port); } EPROSIMA_LOG_INFO(RTCP, " OpenAndBindInput (physical: " << IPLocator::getPhysicalPort( @@ -324,7 +329,7 @@ bool TCPTransportInterface::create_acceptor_socket( return false; } - return true; + return final_port; } void TCPTransportInterface::fill_rtcp_header( diff --git a/src/cpp/rtps/transport/TCPTransportInterface.h b/src/cpp/rtps/transport/TCPTransportInterface.h index f21f61b2e3f..d9b9cede221 100644 --- a/src/cpp/rtps/transport/TCPTransportInterface.h +++ b/src/cpp/rtps/transport/TCPTransportInterface.h @@ -136,7 +136,7 @@ class TCPTransportInterface : public TransportInterface std::shared_ptr& channel); //! Creates a TCP acceptor to wait for incoming connections by the given locator. - bool create_acceptor_socket( + uint16_t create_acceptor_socket( const Locator& locator); virtual void get_ips( diff --git a/src/cpp/rtps/transport/TCPv4Transport.cpp b/src/cpp/rtps/transport/TCPv4Transport.cpp index f2322950c96..22eecf5fbab 100644 --- a/src/cpp/rtps/transport/TCPv4Transport.cpp +++ b/src/cpp/rtps/transport/TCPv4Transport.cpp @@ -81,10 +81,10 @@ TCPv4Transport::TCPv4Transport( interface_whitelist_.emplace_back(ip::address_v4::from_string(interface)); } - for (uint16_t port : configuration_.listening_ports) + for (uint16_t& port : configuration_.listening_ports) { Locator locator(LOCATOR_KIND_TCPv4, port); - create_acceptor_socket(locator); + port = create_acceptor_socket(locator); } #if !TLS_FOUND diff --git a/src/cpp/rtps/transport/TCPv6Transport.cpp b/src/cpp/rtps/transport/TCPv6Transport.cpp index 842dad6f13f..ae0a225cfcd 100644 --- a/src/cpp/rtps/transport/TCPv6Transport.cpp +++ b/src/cpp/rtps/transport/TCPv6Transport.cpp @@ -85,10 +85,10 @@ TCPv6Transport::TCPv6Transport( interface_whitelist_.emplace_back(ip::address_v6::from_string(interface)); } - for (uint16_t port : configuration_.listening_ports) + for (uint16_t& port : configuration_.listening_ports) { Locator locator(LOCATOR_KIND_TCPv6, port); - create_acceptor_socket(locator); + port = create_acceptor_socket(locator); } #if !TLS_FOUND diff --git a/test/blackbox/CMakeLists.txt b/test/blackbox/CMakeLists.txt index debfb27a600..2d6cd78d8f3 100644 --- a/test/blackbox/CMakeLists.txt +++ b/test/blackbox/CMakeLists.txt @@ -237,7 +237,7 @@ if(NOT LibP11_FOUND) endif() # LibP11_FOUND if(EPROSIMA_TEST_DNS_NOT_SET_UP) - set(dns_filter "Discovery.ServerClientEnvironmentSetUpDNS") + set(dns_filter "-Discovery.ServerClientEnvironmentSetUpDNS") endif() file(GLOB RTPS_BLACKBOXTESTS_TEST_SOURCE "common/RTPSBlackboxTests*.cpp") diff --git a/test/blackbox/common/BlackboxTestsTransportTCP.cpp b/test/blackbox/common/BlackboxTestsTransportTCP.cpp index a7254f60d8d..74f72ffd89d 100644 --- a/test/blackbox/common/BlackboxTestsTransportTCP.cpp +++ b/test/blackbox/common/BlackboxTestsTransportTCP.cpp @@ -15,6 +15,8 @@ #include "BlackboxTests.hpp" #include "TCPReqRepHelloWorldRequester.hpp" #include "TCPReqRepHelloWorldReplier.hpp" +#include "PubSubReader.hpp" +#include "PubSubWriter.hpp" #include @@ -594,7 +596,7 @@ TEST_P(TransportTCP, TCPv6_equal_operator) // Test copy constructor and copy assignment for TCPv6 TEST_P(TransportTCP, TCPv6_copy) { - // Change some varibles in order to check the non default cretion + // Change some varibles in order to check the non default creation TCPv6TransportDescriptor tcpv6_transport; tcpv6_transport.enable_tcp_nodelay = !tcpv6_transport.enable_tcp_nodelay; // change default value tcpv6_transport.max_logical_port = tcpv6_transport.max_logical_port + 10; // change default value @@ -670,6 +672,66 @@ TEST(TransportTCP, Client_reconnection) delete requester; } +// Test copy constructor and copy assignment for TCPv4 +TEST_P(TransportTCP, TCPv4_autofill_port) +{ + PubSubReader p1(TEST_TOPIC_NAME); + PubSubReader p2(TEST_TOPIC_NAME); + + // Add TCP Transport with listening port 0 + auto p1_transport = std::make_shared(); + p1_transport->add_listener_port(0); + p1.disable_builtin_transport().add_user_transport_to_pparams(p1_transport); + p1.init(); + ASSERT_TRUE(p1.isInitialized()); + + // Add TCP Transport with listening port different from 0 + uint16_t port = 12345; + auto p2_transport = std::make_shared(); + p2_transport->add_listener_port(port); + p2.disable_builtin_transport().add_user_transport_to_pparams(p2_transport); + p2.init(); + ASSERT_TRUE(p2.isInitialized()); + + LocatorList_t p1_locators; + p1.get_native_reader().get_listening_locators(p1_locators); + EXPECT_TRUE(IPLocator::getPhysicalPort(p1_locators.begin()[0]) != 0); + + LocatorList_t p2_locators; + p2.get_native_reader().get_listening_locators(p2_locators); + EXPECT_TRUE(IPLocator::getPhysicalPort(p2_locators.begin()[0]) == port); +} + +// Test copy constructor and copy assignment for TCPv6 +TEST_P(TransportTCP, TCPv6_autofill_port) +{ + PubSubReader p1(TEST_TOPIC_NAME); + PubSubReader p2(TEST_TOPIC_NAME); + + // Add TCP Transport with listening port 0 + auto p1_transport = std::make_shared(); + p1_transport->add_listener_port(0); + p1.disable_builtin_transport().add_user_transport_to_pparams(p1_transport); + p1.init(); + ASSERT_TRUE(p1.isInitialized()); + + // Add TCP Transport with listening port different from 0 + uint16_t port = 12345; + auto p2_transport = std::make_shared(); + p2_transport->add_listener_port(port); + p2.disable_builtin_transport().add_user_transport_to_pparams(p2_transport); + p2.init(); + ASSERT_TRUE(p2.isInitialized()); + + LocatorList_t p1_locators; + p1.get_native_reader().get_listening_locators(p1_locators); + EXPECT_TRUE(IPLocator::getPhysicalPort(p1_locators.begin()[0]) != 0); + + LocatorList_t p2_locators; + p2.get_native_reader().get_listening_locators(p2_locators); + EXPECT_TRUE(IPLocator::getPhysicalPort(p2_locators.begin()[0]) == port); +} + #ifdef INSTANTIATE_TEST_SUITE_P #define GTEST_INSTANTIATE_TEST_MACRO(x, y, z, w) INSTANTIATE_TEST_SUITE_P(x, y, z, w) #else diff --git a/test/unittest/transport/TCPv4Tests.cpp b/test/unittest/transport/TCPv4Tests.cpp index 121af55fd48..504283dfa10 100644 --- a/test/unittest/transport/TCPv4Tests.cpp +++ b/test/unittest/transport/TCPv4Tests.cpp @@ -1620,6 +1620,44 @@ TEST_F(TCPv4Tests, header_read_interrumption) thread.join(); } +// This test verifies that the autofill port feature correctly sets an automatic port when +// the descriptors's port is set to 0. +TEST_F(TCPv4Tests, autofill_port) +{ + // Check normal port assignation + TCPv4TransportDescriptor test_descriptor; + test_descriptor.add_listener_port(g_default_port); + TCPv4Transport transportUnderTest(test_descriptor); + transportUnderTest.init(); + + EXPECT_TRUE(transportUnderTest.configuration()->listening_ports[0] == g_default_port); + + // Check default port assignation + TCPv4TransportDescriptor test_descriptor_autofill; + test_descriptor_autofill.add_listener_port(0); + TCPv4Transport transportUnderTest_autofill(test_descriptor_autofill); + transportUnderTest_autofill.init(); + + EXPECT_TRUE(transportUnderTest_autofill.configuration()->listening_ports[0] != 0); + EXPECT_TRUE(transportUnderTest_autofill.configuration()->listening_ports.size() == 1); + + uint16_t port = 12345; + TCPv4TransportDescriptor test_descriptor_multiple_autofill; + test_descriptor_multiple_autofill.add_listener_port(0); + test_descriptor_multiple_autofill.add_listener_port(port); + test_descriptor_multiple_autofill.add_listener_port(0); + TCPv4Transport transportUnderTest_multiple_autofill(test_descriptor_multiple_autofill); + transportUnderTest_multiple_autofill.init(); + + EXPECT_TRUE(transportUnderTest_multiple_autofill.configuration()->listening_ports[0] != 0); + EXPECT_TRUE(transportUnderTest_multiple_autofill.configuration()->listening_ports[1] == port); + EXPECT_TRUE(transportUnderTest_multiple_autofill.configuration()->listening_ports[2] != 0); + EXPECT_TRUE( + transportUnderTest_multiple_autofill.configuration()->listening_ports[0] != + transportUnderTest_multiple_autofill.configuration()->listening_ports[2]); + EXPECT_TRUE(transportUnderTest_multiple_autofill.configuration()->listening_ports.size() == 3); +} + void TCPv4Tests::HELPER_SetDescriptorDefaults() { descriptor.add_listener_port(g_default_port); diff --git a/test/unittest/transport/TCPv6Tests.cpp b/test/unittest/transport/TCPv6Tests.cpp index f144a16deb1..9198370c99d 100644 --- a/test/unittest/transport/TCPv6Tests.cpp +++ b/test/unittest/transport/TCPv6Tests.cpp @@ -175,6 +175,44 @@ TEST_F(TCPv6Tests, opening_and_closing_input_channel) ASSERT_FALSE (transportUnderTest.IsInputChannelOpen(multicastFilterLocator)); ASSERT_FALSE (transportUnderTest.CloseInputChannel(multicastFilterLocator)); } + +// This test verifies that the autofill port feature correctly sets an automatic port when +// the descriptors's port is set to 0. +TEST_F(TCPv6Tests, autofill_port) +{ + // Check normal port assignation + TCPv6TransportDescriptor test_descriptor; + test_descriptor.add_listener_port(g_default_port); + TCPv6Transport transportUnderTest(test_descriptor); + transportUnderTest.init(); + + EXPECT_TRUE(transportUnderTest.configuration()->listening_ports[0] == g_default_port); + + // Check default port assignation + TCPv6TransportDescriptor test_descriptor_autofill; + test_descriptor_autofill.add_listener_port(0); + TCPv6Transport transportUnderTest_autofill(test_descriptor_autofill); + transportUnderTest_autofill.init(); + + EXPECT_TRUE(transportUnderTest_autofill.configuration()->listening_ports[0] != 0); + EXPECT_TRUE(transportUnderTest_autofill.configuration()->listening_ports.size() == 1); + + uint16_t port = 12345; + TCPv6TransportDescriptor test_descriptor_multiple_autofill; + test_descriptor_multiple_autofill.add_listener_port(0); + test_descriptor_multiple_autofill.add_listener_port(port); + test_descriptor_multiple_autofill.add_listener_port(0); + TCPv6Transport transportUnderTest_multiple_autofill(test_descriptor_multiple_autofill); + transportUnderTest_multiple_autofill.init(); + + EXPECT_TRUE(transportUnderTest_multiple_autofill.configuration()->listening_ports[0] != 0); + EXPECT_TRUE(transportUnderTest_multiple_autofill.configuration()->listening_ports[1] == port); + EXPECT_TRUE(transportUnderTest_multiple_autofill.configuration()->listening_ports[2] != 0); + EXPECT_TRUE( + transportUnderTest_multiple_autofill.configuration()->listening_ports[0] != + transportUnderTest_multiple_autofill.configuration()->listening_ports[2]); + EXPECT_TRUE(transportUnderTest_multiple_autofill.configuration()->listening_ports.size() == 3); +} /* TEST_F(TCPv6Tests, send_and_receive_between_both_secure_ports) {