Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[21036] Handle errors when setting socket buffer sizes (backport #4760) #4795

Merged
merged 25 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5961e4f
Refs #20972. Move code into new private methods.
MiguelCompany May 8, 2024
6796720
Refs #20972. Refactor on configure_send_buffer_size.
MiguelCompany May 8, 2024
6395907
Refs #20972. Refactor on configure_receive_buffer_size.
MiguelCompany May 8, 2024
c2a39b6
Refs #20972. Check user configuration at the beginning of init method.
MiguelCompany May 8, 2024
a468693
Refs #20972. Use maxMessageSize as minimum possible value.
MiguelCompany May 8, 2024
9edfd2a
Refs #20972. Applying changes on OpenAndBindUnicastOutputSocket.
MiguelCompany May 8, 2024
defef4d
Refs #20972. Add helper header with template method.
MiguelCompany May 9, 2024
058dd6f
Refs #20972. Configure methods return boolean.
MiguelCompany May 9, 2024
bfad614
Refs #20972. Configure methods use new template method.
MiguelCompany May 9, 2024
c0e9e68
Refs #20972. OpenAndBindUnicastOutputSocket uses new template method.
MiguelCompany May 9, 2024
acd3d6e
Refs #20972. Changes in OpenAndBindInputSocket.
MiguelCompany May 9, 2024
321e8c6
Refs #20972.Setting options on TCP channels.
MiguelCompany May 9, 2024
1a83532
Refs #20972. Doxygen.
MiguelCompany May 9, 2024
bba9cb2
Refs #20972. Check limits of configured sizes.
MiguelCompany May 9, 2024
0061620
Refs #20972. Add UDP unit tests.
MiguelCompany May 9, 2024
f3049ff
Refs #20972. Add TCP unit tests.
MiguelCompany May 10, 2024
d2e6926
Refs #20972. Move checks in TCP to beginning of init.
MiguelCompany May 10, 2024
08c6dc2
Refs #20972. Refactor for common code in UDP.
MiguelCompany May 10, 2024
26eb529
Refs #20972. Refactor for common code in TCP.
MiguelCompany May 13, 2024
523c9bf
Refs #20972. Remove unused constants in UDP tests.
MiguelCompany May 13, 2024
918a29b
Refs #20972. Check final configuration on unit tests.
MiguelCompany May 13, 2024
d3e9d1d
Refs #20972. Uncrustify.
MiguelCompany May 14, 2024
267c6e2
Refs #20972. Less strict tests.
MiguelCompany May 14, 2024
3afe94b
Refs #20972. Remove `s_minimumSocketBuffer` from tests.
MiguelCompany May 16, 2024
fd8a041
Refs #20972. Deprecate `s_minimumSocketBuffer`.
MiguelCompany May 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/fastdds/rtps/transport/TransportInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ namespace rtps {
constexpr uint32_t s_maximumMessageSize = 65500;
//! Default maximum initial peers range
constexpr uint32_t s_maximumInitialPeersRange = 4;
//! Default minimum socket buffer
// Default minimum socket buffer
FASTDDS_DEPRECATED_UNTIL(3, s_minimumSocketBuffer, "Minimum socket buffer is now taken from the maximum msg size")
constexpr uint32_t s_minimumSocketBuffer = 65536;
//! Default IPv4 address
static const std::string s_IPv4AddressAny = "0.0.0.0";
Expand Down
3 changes: 2 additions & 1 deletion include/fastrtps/transport/TransportInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ using TransportInterface = fastdds::rtps::TransportInterface;

static const uint32_t s_maximumMessageSize = fastdds::rtps::s_maximumMessageSize;
static const uint32_t s_maximumInitialPeersRange = fastdds::rtps::s_maximumInitialPeersRange;
static const uint32_t s_minimumSocketBuffer = fastdds::rtps::s_minimumSocketBuffer;
FASTDDS_DEPRECATED_UNTIL(3, s_minimumSocketBuffer, "Minimum socket buffer is now taken from the maximum msg size")
static const uint32_t s_minimumSocketBuffer = 65536;
static const std::string s_IPv4AddressAny = fastdds::rtps::s_IPv4AddressAny;
static const std::string s_IPv6AddressAny = fastdds::rtps::s_IPv6AddressAny;

Expand Down
49 changes: 48 additions & 1 deletion src/cpp/rtps/transport/TCPChannelResource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <thread>

#include <fastrtps/utils/IPLocator.h>
#include <rtps/transport/asio_helpers.hpp>
#include <rtps/transport/TCPTransportInterface.h>

namespace eprosima {
Expand Down Expand Up @@ -370,6 +371,52 @@ bool TCPChannelResource::check_socket_send_buffer(
return true;
}

void TCPChannelResource::set_socket_options(
asio::basic_socket<asio::ip::tcp>& socket,
const TCPTransportDescriptor* options)
{
uint32_t minimum_value = options->maxMessageSize;

// Set the send buffer size
{
uint32_t desired_value = options->sendBufferSize;
uint32_t configured_value = 0;
if (!asio_helpers::try_setting_buffer_size<asio::socket_base::send_buffer_size>(
socket, desired_value, minimum_value, configured_value))
{
EPROSIMA_LOG_ERROR(TCP_TRANSPORT,
"Couldn't set send buffer size to minimum value: " << minimum_value);
}
else if (desired_value != configured_value)
{
EPROSIMA_LOG_WARNING(TCP_TRANSPORT,
"Couldn't set send buffer size to desired value. "
<< "Using " << configured_value << " instead of " << desired_value);
}
}

// Set the receive buffer size
{
uint32_t desired_value = options->receiveBufferSize;
uint32_t configured_value = 0;
if (!asio_helpers::try_setting_buffer_size<asio::socket_base::receive_buffer_size>(
socket, desired_value, minimum_value, configured_value))
{
EPROSIMA_LOG_ERROR(TCP_TRANSPORT,
"Couldn't set receive buffer size to minimum value: " << minimum_value);
}
else if (desired_value != configured_value)
{
EPROSIMA_LOG_WARNING(TCP_TRANSPORT,
"Couldn't set receive buffer size to desired value. "
<< "Using " << configured_value << " instead of " << desired_value);
}
}

// Set the TCP_NODELAY option
socket.set_option(asio::ip::tcp::no_delay(options->enable_tcp_nodelay));
}

} // namespace rtps
} // namespace fastrtps
} // namespace fastdds
} // namespace eprosima
10 changes: 10 additions & 0 deletions src/cpp/rtps/transport/TCPChannelResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,16 @@ class TCPChannelResource : public ChannelResource
const size_t& msg_size,
const asio::ip::tcp::socket::native_handle_type& socket_native_handle);

/**
* @brief Set descriptor options on a socket.
*
* @param socket Socket on which to set the options.
* @param options Descriptor with the options to set.
*/
static void set_socket_options(
asio::basic_socket<asio::ip::tcp>& socket,
const TCPTransportDescriptor* options);

TCPConnectionType tcp_connection_type_;

friend class TCPTransportInterface;
Expand Down
4 changes: 1 addition & 3 deletions src/cpp/rtps/transport/TCPChannelResourceBasic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,7 @@ asio::ip::tcp::endpoint TCPChannelResourceBasic::local_endpoint(
void TCPChannelResourceBasic::set_options(
const TCPTransportDescriptor* options)
{
socket_->set_option(socket_base::receive_buffer_size(options->receiveBufferSize));
socket_->set_option(socket_base::send_buffer_size(options->sendBufferSize));
socket_->set_option(ip::tcp::no_delay(options->enable_tcp_nodelay));
TCPChannelResource::set_socket_options(*socket_, options);
}

void TCPChannelResourceBasic::cancel()
Expand Down
4 changes: 1 addition & 3 deletions src/cpp/rtps/transport/TCPChannelResourceSecure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,7 @@ asio::ip::tcp::endpoint TCPChannelResourceSecure::local_endpoint(
void TCPChannelResourceSecure::set_options(
const TCPTransportDescriptor* options)
{
secure_socket_->lowest_layer().set_option(socket_base::receive_buffer_size(options->receiveBufferSize));
secure_socket_->lowest_layer().set_option(socket_base::send_buffer_size(options->sendBufferSize));
secure_socket_->lowest_layer().set_option(ip::tcp::no_delay(options->enable_tcp_nodelay));
TCPChannelResource::set_socket_options(secure_socket_->lowest_layer(), options);
}

void TCPChannelResourceSecure::set_tls_verify_mode(
Expand Down
92 changes: 57 additions & 35 deletions src/cpp/rtps/transport/TCPTransportInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@

#include <rtps/transport/TCPTransportInterface.h>

#include <set>
#include <utility>
#include <cstring>
#include <algorithm>
#include <cstring>
#include <chrono>
#include <limits>
#include <set>
#include <utility>

#include <asio/steady_timer.hpp>
#include <fastdds/dds/log/Log.hpp>
#include <fastrtps/utils/IPLocator.h>
#include <fastrtps/utils/System.h>

#include <rtps/transport/tcp/RTCPMessageManager.h>
#include <rtps/transport/TCPSenderResource.hpp>
#include <rtps/transport/TCPChannelResourceBasic.h>
Expand All @@ -32,6 +34,8 @@
#include <rtps/transport/TCPChannelResourceSecure.h>
#include <rtps/transport/TCPAcceptorSecure.h>
#endif // if TLS_FOUND

#include <rtps/transport/asio_helpers.hpp>
#include <statistics/rtps/messages/RTPSStatisticsMessages.hpp>
#include <utils/SystemInfo.hpp>

Expand Down Expand Up @@ -405,6 +409,42 @@ bool TCPTransportInterface::DoInputLocatorsMatch(
bool TCPTransportInterface::init(
const fastrtps::rtps::PropertyPolicy* properties)
{
uint32_t maximumMessageSize = s_maximumMessageSize;
uint32_t cfg_max_msg_size = configuration()->maxMessageSize;
uint32_t cfg_send_size = configuration()->sendBufferSize;
uint32_t cfg_recv_size = configuration()->receiveBufferSize;
uint32_t max_int_value = static_cast<uint32_t>(std::numeric_limits<int32_t>::max());

if (cfg_max_msg_size > maximumMessageSize)
{
EPROSIMA_LOG_ERROR(TRANSPORT_TCP, "maxMessageSize cannot be greater than " << maximumMessageSize);
return false;
}

if (cfg_send_size > max_int_value)
{
EPROSIMA_LOG_ERROR(TRANSPORT_TCP, "sendBufferSize cannot be greater than " << max_int_value);
return false;
}

if (cfg_recv_size > max_int_value)
{
EPROSIMA_LOG_ERROR(TRANSPORT_TCP, "receiveBufferSize cannot be greater than " << max_int_value);
return false;
}

if ((cfg_send_size > 0) && (cfg_max_msg_size > cfg_send_size))
{
EPROSIMA_LOG_ERROR(TRANSPORT_TCP, "maxMessageSize cannot be greater than sendBufferSize");
return false;
}

if ((cfg_recv_size > 0) && (cfg_max_msg_size > cfg_recv_size))
{
EPROSIMA_LOG_ERROR(TRANSPORT_TCP, "maxMessageSize cannot be greater than receiveBufferSize");
return false;
}

if (!apply_tls_config())
{
// TODO decide wether the Transport initialization should keep working after this error
Expand Down Expand Up @@ -437,48 +477,30 @@ bool TCPTransportInterface::init(
}

// Check system buffer sizes.
if (configuration()->sendBufferSize == 0)
{
socket_base::send_buffer_size option;
initial_peer_local_locator_socket_->get_option(option);
set_send_buffer_size(option.value());

if (configuration()->sendBufferSize < s_minimumSocketBuffer)
{
set_send_buffer_size(s_minimumSocketBuffer);
}
}

if (configuration()->receiveBufferSize == 0)
uint32_t send_size = 0;
uint32_t recv_size = 0;
if (!asio_helpers::configure_buffer_sizes(
*initial_peer_local_locator_socket_, *configuration(), send_size, recv_size))
{
socket_base::receive_buffer_size option;
initial_peer_local_locator_socket_->get_option(option);
set_receive_buffer_size(option.value());

if (configuration()->receiveBufferSize < s_minimumSocketBuffer)
{
set_receive_buffer_size(s_minimumSocketBuffer);
}
}

if (configuration()->maxMessageSize > s_maximumMessageSize)
{
EPROSIMA_LOG_ERROR(RTCP_MSG_OUT, "maxMessageSize cannot be greater than 65000");
EPROSIMA_LOG_ERROR(TRANSPORT_TCP, "Couldn't set buffer sizes to minimum value: " << cfg_max_msg_size);
return false;
}

if (configuration()->maxMessageSize > configuration()->sendBufferSize)
if (cfg_send_size > 0 && send_size != cfg_send_size)
{
EPROSIMA_LOG_ERROR(RTCP_MSG_OUT, "maxMessageSize cannot be greater than send_buffer_size");
return false;
EPROSIMA_LOG_WARNING(TRANSPORT_TCP, "UDPTransport sendBufferSize could not be set to the desired value. "
<< "Using " << send_size << " instead of " << cfg_send_size);
}

if (configuration()->maxMessageSize > configuration()->receiveBufferSize)
if (cfg_recv_size > 0 && recv_size != cfg_recv_size)
{
EPROSIMA_LOG_ERROR(RTCP_MSG_OUT, "maxMessageSize cannot be greater than receive_buffer_size");
return false;
EPROSIMA_LOG_WARNING(TRANSPORT_TCP, "UDPTransport receiveBufferSize could not be set to the desired value. "
<< "Using " << recv_size << " instead of " << cfg_recv_size);
}

set_send_buffer_size(send_size);
set_receive_buffer_size(recv_size);

if (!rtcp_message_manager_)
{
rtcp_message_manager_ = std::make_shared<RTCPMessageManager>(this);
Expand Down
Loading
Loading