diff --git a/src/cpp/rtps/transport/TCPv4Transport.cpp b/src/cpp/rtps/transport/TCPv4Transport.cpp index 4419ceb9943..ad6e823e11e 100644 --- a/src/cpp/rtps/transport/TCPv4Transport.cpp +++ b/src/cpp/rtps/transport/TCPv4Transport.cpp @@ -101,10 +101,17 @@ TCPv4Transport::TCPv4Transport( } } - for (uint16_t& port : configuration_.listening_ports) + if (!configuration_.listening_ports.empty()) { - Locator locator(LOCATOR_KIND_TCPv4, port); - port = create_acceptor_socket(locator); + if (configuration_.listening_ports.size() > 1) + { + EPROSIMA_LOG_ERROR(RTCP, + "Only one listening port is allowed for TCP transport. Only the first port will be used."); + configuration_.listening_ports.erase( + configuration_.listening_ports.begin() + 1, configuration_.listening_ports.end()); + } + Locator locator(LOCATOR_KIND_TCPv4, configuration_.listening_ports.front()); + configuration_.listening_ports.front() = create_acceptor_socket(locator); } #if !TLS_FOUND diff --git a/src/cpp/rtps/transport/TCPv6Transport.cpp b/src/cpp/rtps/transport/TCPv6Transport.cpp index 9718a783c64..9ad8db7a5ba 100644 --- a/src/cpp/rtps/transport/TCPv6Transport.cpp +++ b/src/cpp/rtps/transport/TCPv6Transport.cpp @@ -105,10 +105,17 @@ TCPv6Transport::TCPv6Transport( } } - for (uint16_t& port : configuration_.listening_ports) + if (!configuration_.listening_ports.empty()) { - Locator locator(LOCATOR_KIND_TCPv6, port); - port = create_acceptor_socket(locator); + if (configuration_.listening_ports.size() > 1) + { + EPROSIMA_LOG_ERROR(RTCP, + "Only one listening port is allowed for TCP transport. Only the first port will be used."); + configuration_.listening_ports.erase( + configuration_.listening_ports.begin() + 1, configuration_.listening_ports.end()); + } + Locator locator(LOCATOR_KIND_TCPv6, configuration_.listening_ports.front()); + configuration_.listening_ports.front() = create_acceptor_socket(locator); } #if !TLS_FOUND diff --git a/test/blackbox/common/BlackboxTestsTransportTCP.cpp b/test/blackbox/common/BlackboxTestsTransportTCP.cpp index ef352def2b7..d7ed5b9d1fe 100644 --- a/test/blackbox/common/BlackboxTestsTransportTCP.cpp +++ b/test/blackbox/common/BlackboxTestsTransportTCP.cpp @@ -842,6 +842,93 @@ TEST_P(TransportTCP, large_data_topology) writers.clear(); } +// This test verifies that if having a server with several listening ports, only the first one is used. +TEST_P(TransportTCP, multiple_listening_ports) +{ + // Create a server with several listening ports + PubSubReader* server = new PubSubReader(TEST_TOPIC_NAME); + uint16_t server_port_1 = 10000; + uint16_t server_port_2 = 10001; + + std::shared_ptr server_transport; + if (use_ipv6) + { + server_transport = std::make_shared(); + } + else + { + server_transport = std::make_shared(); + } + server_transport->add_listener_port(server_port_1); + server_transport->add_listener_port(server_port_2); + server->disable_builtin_transport().add_user_transport_to_pparams(server_transport).init(); + ASSERT_TRUE(server->isInitialized()); + + // Create two clients each one connecting to a different port + PubSubWriter* client_1 = new PubSubWriter(TEST_TOPIC_NAME); + PubSubWriter* client_2 = new PubSubWriter(TEST_TOPIC_NAME); + std::shared_ptr client_transport_1; + std::shared_ptr client_transport_2; + Locator_t initialPeerLocator_1; + Locator_t initialPeerLocator_2; + if (use_ipv6) + { + client_transport_1 = std::make_shared(); + client_transport_2 = std::make_shared(); + initialPeerLocator_1.kind = LOCATOR_KIND_TCPv6; + initialPeerLocator_2.kind = LOCATOR_KIND_TCPv6; + IPLocator::setIPv6(initialPeerLocator_1, "::1"); + IPLocator::setIPv6(initialPeerLocator_2, "::1"); + } + else + { + client_transport_1 = std::make_shared(); + client_transport_2 = std::make_shared(); + initialPeerLocator_1.kind = LOCATOR_KIND_TCPv4; + initialPeerLocator_2.kind = LOCATOR_KIND_TCPv4; + IPLocator::setIPv4(initialPeerLocator_1, 127, 0, 0, 1); + IPLocator::setIPv4(initialPeerLocator_2, 127, 0, 0, 1); + } + client_1->disable_builtin_transport().add_user_transport_to_pparams(client_transport_1); + client_2->disable_builtin_transport().add_user_transport_to_pparams(client_transport_2); + initialPeerLocator_1.port = server_port_1; + initialPeerLocator_2.port = server_port_2; + LocatorList_t initial_peer_list_1; + LocatorList_t initial_peer_list_2; + initial_peer_list_1.push_back(initialPeerLocator_1); + initial_peer_list_2.push_back(initialPeerLocator_2); + client_1->initial_peers(initial_peer_list_1); + client_2->initial_peers(initial_peer_list_2); + client_1->init(); + client_2->init(); + ASSERT_TRUE(client_1->isInitialized()); + ASSERT_TRUE(client_2->isInitialized()); + + // Wait for discovery. + server->wait_discovery(); + client_1->wait_discovery(); + client_2->wait_discovery(std::chrono::seconds(1)); + EXPECT_EQ(server->get_matched(), 1U); + EXPECT_EQ(client_1->get_matched(), 1U); + EXPECT_EQ(client_2->get_matched(), 0U); + + // Send data + auto data = default_helloworld_data_generator(); + server->startReception(data); + client_1->send(data); + // In this test all data should be sent. + ASSERT_TRUE(data.empty()); + // Block server until reception finished. + server->block_for_all(); + // Wait for all data to be acked. + EXPECT_TRUE(client_1->waitForAllAcked(std::chrono::milliseconds(100))); + + // Release TCP client and server resources. + delete client_1; + delete client_2; + delete server; +} + #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 d333e280941..c116cbc00e7 100644 --- a/test/unittest/transport/TCPv4Tests.cpp +++ b/test/unittest/transport/TCPv4Tests.cpp @@ -1909,22 +1909,6 @@ TEST_F(TCPv4Tests, autofill_port) 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); } // This test verifies server's channel resources mapping keys uniqueness, where keys are clients locators. diff --git a/test/unittest/transport/TCPv6Tests.cpp b/test/unittest/transport/TCPv6Tests.cpp index 1054ecf926c..9f49c591a26 100644 --- a/test/unittest/transport/TCPv6Tests.cpp +++ b/test/unittest/transport/TCPv6Tests.cpp @@ -197,22 +197,6 @@ TEST_F(TCPv6Tests, autofill_port) 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); } static void GetIP6s(