Skip to content

Commit

Permalink
Add Autofill port to TCP Transport (#4061)
Browse files Browse the repository at this point in the history
* Refs #20019: Blackbox Test

Signed-off-by: cferreiragonz <[email protected]>

* Refs #20019: Unittest autofill port

Signed-off-by: cferreiragonz <[email protected]>

* Refs #20019: TCP Autofill port

Signed-off-by: cferreiragonz <[email protected]>

Rearrange update of port

Signed-off-by: cferreiragonz <[email protected]>

* Refs #20019: Uncrustify

Signed-off-by: cferreiragonz <[email protected]>

* Refs #20019: Add static_cast conversion

Signed-off-by: cferreiragonz <[email protected]>

* Refs #20019: Apply revision changes

Signed-off-by: cferreiragonz <[email protected]>

---------

Signed-off-by: cferreiragonz <[email protected]>
  • Loading branch information
cferreiragonz authored Dec 4, 2023
1 parent 1a07097 commit 36f31dd
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/cpp/rtps/transport/TCPAcceptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_));
}

Expand All @@ -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_));
}
Expand Down
17 changes: 11 additions & 6 deletions src/cpp/rtps/transport/TCPTransportInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,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())
Expand All @@ -300,16 +301,18 @@ bool TCPTransportInterface::create_acceptor_socket(
{
std::shared_ptr<TCPAcceptorSecure> acceptor =
std::make_shared<TCPAcceptorSecure>(io_service_, this, locator);
acceptors_[locator] = acceptor;
acceptors_[acceptor->locator()] = acceptor;
acceptor->accept(this, ssl_context_);
final_port = static_cast<uint16_t>(acceptor->locator().port);
}
else
#endif // if TLS_FOUND
{
std::shared_ptr<TCPAcceptorBasic> acceptor =
std::make_shared<TCPAcceptorBasic>(io_service_, this, locator);
acceptors_[locator] = acceptor;
acceptors_[acceptor->locator()] = acceptor;
acceptor->accept(this);
final_port = static_cast<uint16_t>(acceptor->locator().port);
}

EPROSIMA_LOG_INFO(RTCP, " OpenAndBindInput (physical: " << IPLocator::getPhysicalPort(
Expand All @@ -327,16 +330,18 @@ bool TCPTransportInterface::create_acceptor_socket(
{
std::shared_ptr<TCPAcceptorSecure> acceptor =
std::make_shared<TCPAcceptorSecure>(io_service_, sInterface, locator);
acceptors_[locator] = acceptor;
acceptors_[acceptor->locator()] = acceptor;
acceptor->accept(this, ssl_context_);
final_port = static_cast<uint16_t>(acceptor->locator().port);
}
else
#endif // if TLS_FOUND
{
std::shared_ptr<TCPAcceptorBasic> acceptor =
std::make_shared<TCPAcceptorBasic>(io_service_, sInterface, locator);
acceptors_[locator] = acceptor;
acceptors_[acceptor->locator()] = acceptor;
acceptor->accept(this);
final_port = static_cast<uint16_t>(acceptor->locator().port);
}

EPROSIMA_LOG_INFO(RTCP, " OpenAndBindInput (physical: " << IPLocator::getPhysicalPort(
Expand All @@ -360,7 +365,7 @@ bool TCPTransportInterface::create_acceptor_socket(
return false;
}

return true;
return final_port;
}

void TCPTransportInterface::fill_rtcp_header(
Expand Down
2 changes: 1 addition & 1 deletion src/cpp/rtps/transport/TCPTransportInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class TCPTransportInterface : public TransportInterface
std::shared_ptr<TCPChannelResource>& 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(
Expand Down
4 changes: 2 additions & 2 deletions src/cpp/rtps/transport/TCPv4Transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/cpp/rtps/transport/TCPv6Transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/blackbox/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,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")
Expand Down
66 changes: 64 additions & 2 deletions test/blackbox/common/BlackboxTestsTransportTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

#include "TCPReqRepHelloWorldRequester.hpp"
#include "TCPReqRepHelloWorldReplier.hpp"
#include "PubSubReader.hpp"
#include "PubSubWriter.hpp"

using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
Expand Down Expand Up @@ -598,7 +600,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
Expand Down Expand Up @@ -674,6 +676,66 @@ TEST(TransportTCP, Client_reconnection)
delete requester;
}

// Test copy constructor and copy assignment for TCPv4
TEST_P(TransportTCP, TCPv4_autofill_port)
{
PubSubReader<HelloWorldPubSubType> p1(TEST_TOPIC_NAME);
PubSubReader<HelloWorldPubSubType> p2(TEST_TOPIC_NAME);

// Add TCP Transport with listening port 0
auto p1_transport = std::make_shared<TCPv4TransportDescriptor>();
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<TCPv4TransportDescriptor>();
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<HelloWorldPubSubType> p1(TEST_TOPIC_NAME);
PubSubReader<HelloWorldPubSubType> p2(TEST_TOPIC_NAME);

// Add TCP Transport with listening port 0
auto p1_transport = std::make_shared<TCPv6TransportDescriptor>();
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<TCPv6TransportDescriptor>();
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
Expand All @@ -694,4 +756,4 @@ GTEST_INSTANTIATE_TEST_MACRO(TransportTCP,
return "Transport" + suffix;
}

});
});
38 changes: 38 additions & 0 deletions test/unittest/transport/TCPv4Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
38 changes: 38 additions & 0 deletions test/unittest/transport/TCPv6Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down

0 comments on commit 36f31dd

Please sign in to comment.