diff --git a/include/fastdds/rtps/attributes/RTPSParticipantAllocationAttributes.hpp b/include/fastdds/rtps/attributes/RTPSParticipantAllocationAttributes.hpp index 5d3019b6eb5..a8a23af90d3 100644 --- a/include/fastdds/rtps/attributes/RTPSParticipantAllocationAttributes.hpp +++ b/include/fastdds/rtps/attributes/RTPSParticipantAllocationAttributes.hpp @@ -67,7 +67,8 @@ struct SendBuffersAllocationAttributes const SendBuffersAllocationAttributes& b) const { return (this->preallocated_number == b.preallocated_number) && - (this->dynamic == b.dynamic); + (this->dynamic == b.dynamic) && + (this->network_buffers_config == b.network_buffers_config); } /** Initial number of send buffers to allocate. @@ -86,6 +87,15 @@ struct SendBuffersAllocationAttributes * buffer to be returned. This is a trade-off between latency and dynamic allocations. */ bool dynamic = false; + + /** Configuration for the network buffers. + * + * This attribute controls the allocation behavior of the network buffers used by each + * send buffer. The default value will use a value of 16 network buffers for both + * the preallocated buffers and the dynamic increment allocation, with no maximum limit. + */ + ResourceLimitedContainerConfig network_buffers_config = ResourceLimitedContainerConfig(16u, + std::numeric_limits::max dummy_avoid_winmax (), 16u); }; /** diff --git a/include/fastdds/rtps/messages/RTPSMessageSenderInterface.hpp b/include/fastdds/rtps/messages/RTPSMessageSenderInterface.hpp index 3925d2aa440..925ba9da8ec 100644 --- a/include/fastdds/rtps/messages/RTPSMessageSenderInterface.hpp +++ b/include/fastdds/rtps/messages/RTPSMessageSenderInterface.hpp @@ -26,6 +26,7 @@ #include #include +#include namespace eprosima { namespace fastrtps { @@ -75,11 +76,13 @@ class RTPSMessageSenderInterface /** * Send a message through this interface. * - * @param message Pointer to the buffer with the message already serialized. + * @param buffers Vector of NetworkBuffers to send with data already serialized. + * @param total_bytes Total number of bytes to send. Should be equal to the sum of the @c size field of all buffers. * @param max_blocking_time_point Future timepoint where blocking send should end. */ virtual bool send( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, std::chrono::steady_clock::time_point max_blocking_time_point) const = 0; /*! diff --git a/include/fastdds/rtps/transport/ChainingTransport.h b/include/fastdds/rtps/transport/ChainingTransport.h index 364718c5499..6fdf2562ed7 100644 --- a/include/fastdds/rtps/transport/ChainingTransport.h +++ b/include/fastdds/rtps/transport/ChainingTransport.h @@ -313,12 +313,12 @@ class ChainingTransport : public TransportInterface * At the end the function must call to the low-level transport's `send()` function. * @code{.cpp} // Example of calling the low-level transport `send()` function. - return low_sender_resource->send(send_buffer, send_buffer_size, destination_locators_begin, + return low_sender_resource->send(buffers, total_bytes, destination_locators_begin, destination_locators_end, timeout); @endcode * @param low_sender_resource SenderResource generated by the lower transport. - * @param send_buffer Slice into the raw data to send. - * @param send_buffer_size Size of the raw data. It will be used as a bounds check for the previous argument. + * @param buffers Vector of buffers to send. + * @param total_bytes Length of all buffers to be sent. Will be used as a boundary for the previous parameter. * It must not exceed the \c sendBufferSize fed to this class during construction. * @param destination_locators_begin First iterator of the list of Locators describing the remote destinations * we're sending to. @@ -328,8 +328,8 @@ class ChainingTransport : public TransportInterface */ FASTDDS_EXPORTED_API virtual bool send( fastrtps::rtps::SenderResource* low_sender_resource, - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point& timeout) = 0; diff --git a/include/fastdds/rtps/transport/NetworkBuffer.hpp b/include/fastdds/rtps/transport/NetworkBuffer.hpp new file mode 100644 index 00000000000..7ad62012bb7 --- /dev/null +++ b/include/fastdds/rtps/transport/NetworkBuffer.hpp @@ -0,0 +1,62 @@ +// Copyright 2024 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. + +/** + * @file NetworkBuffer.hpp + */ + +#ifndef _FASTDDS_RTPS_NETWORK_NETWORKBUFFER_HPP +#define _FASTDDS_RTPS_NETWORK_NETWORKBUFFER_HPP + +#include + +namespace asio { +// Forward declaration of asio::const_buffer +class const_buffer; +} // namespace asio + +namespace eprosima { +namespace fastdds { +namespace rtps { + +/** + * A slice of data to be sent to one or more transports. + * An RTPS datagram is made up of headers and one or more NetworkBuffer instances. + */ +struct NetworkBuffer final +{ + //! Pointer to the buffer where the data is stored. + const void* buffer = nullptr; + //! Number of bytes to use starting at @c buffer. + uint32_t size = 0; + + NetworkBuffer() = default; + + NetworkBuffer( + const void* ptr, + uint32_t s) + : buffer(ptr) + , size(s) + { + } + + //! Conversion operator to asio::const_buffer. + operator asio::const_buffer() const; +}; + +} // namespace rtps +} // namespace fastdds +} // namespace eprosima + +#endif // _FASTDDS_RTPS_NETWORK_NETWORKBUFFER_HPP diff --git a/include/fastdds/rtps/transport/SenderResource.h b/include/fastdds/rtps/transport/SenderResource.h index 4a2f272451d..a3d869a8240 100644 --- a/include/fastdds/rtps/transport/SenderResource.h +++ b/include/fastdds/rtps/transport/SenderResource.h @@ -19,10 +19,12 @@ #include #include +#include #include #include #include +#include namespace eprosima { namespace fastrtps { @@ -42,10 +44,12 @@ class SenderResource { public: + using NetworkBuffer = eprosima::fastdds::rtps::NetworkBuffer; + /** * Sends to a destination locator, through the channel managed by this resource. - * @param data Raw data slice to be sent. - * @param dataLength Length of the data to be sent. Will be used as a boundary for + * @param buffers Vector of buffers to send. + * @param total_bytes Length of all buffers to be sent. Will be used as a boundary for * the previous parameter. * @param destination_locators_begin destination endpoint Locators iterator begin. * @param destination_locators_end destination endpoint Locators iterator end. @@ -53,21 +57,14 @@ class SenderResource * @return Success of the send operation. */ bool send( - const octet* data, - uint32_t dataLength, + const std::vector& buffers, + const uint32_t& total_bytes, LocatorsIterator* destination_locators_begin, LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point& max_blocking_time_point) { - bool returned_value = false; - - if (send_lambda_) - { - returned_value = send_lambda_(data, dataLength, destination_locators_begin, destination_locators_end, - max_blocking_time_point); - } - - return returned_value; + return send_buffers_lambda_(buffers, total_bytes, destination_locators_begin, destination_locators_end, + max_blocking_time_point); } /** @@ -78,7 +75,7 @@ class SenderResource SenderResource&& rValueResource) { clean_up.swap(rValueResource.clean_up); - send_lambda_.swap(rValueResource.send_lambda_); + send_buffers_lambda_.swap(rValueResource.send_buffers_lambda_); } virtual ~SenderResource() = default; @@ -110,12 +107,13 @@ class SenderResource int32_t transport_kind_; std::function clean_up; + std::function&, uint32_t, LocatorsIterator* destination_locators_begin, LocatorsIterator* destination_locators_end, - const std::chrono::steady_clock::time_point&)> send_lambda_; + const std::chrono::steady_clock::time_point&)> send_buffers_lambda_; private: diff --git a/include/fastdds/rtps/writer/LocatorSelectorSender.hpp b/include/fastdds/rtps/writer/LocatorSelectorSender.hpp index 149d948912c..7829104a71c 100644 --- a/include/fastdds/rtps/writer/LocatorSelectorSender.hpp +++ b/include/fastdds/rtps/writer/LocatorSelectorSender.hpp @@ -1,6 +1,8 @@ #ifndef _FASTDDS_RTPS_WRITER_LOCATORSELECTORSENDER_HPP_ #define _FASTDDS_RTPS_WRITER_LOCATORSELECTORSENDER_HPP_ +#include + #include #include #include @@ -69,11 +71,13 @@ class LocatorSelectorSender : public RTPSMessageSenderInterface /*! * Send a message through this interface. * - * @param message Pointer to the buffer with the message already serialized. + * @param buffers Vector of NetworkBuffers to send with data already serialized. + * @param total_bytes Total number of bytes to send. Should be equal to the sum of the @c size field of all buffers. * @param max_blocking_time_point Future timepoint where blocking send should end. */ bool send( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, std::chrono::steady_clock::time_point max_blocking_time_point) const override; /*! diff --git a/include/fastdds/rtps/writer/RTPSWriter.h b/include/fastdds/rtps/writer/RTPSWriter.h index 68cea5dd79d..a4c1d620bad 100644 --- a/include/fastdds/rtps/writer/RTPSWriter.h +++ b/include/fastdds/rtps/writer/RTPSWriter.h @@ -518,13 +518,15 @@ class RTPSWriter /** * Send a message through this interface. * - * @param message Pointer to the buffer with the message already serialized. + * @param buffers Vector of NetworkBuffers to send with data already serialized. + * @param total_bytes Total number of bytes to send. Should be equal to the sum of the @c size field of all buffers. * @param locator_selector RTPSMessageSenderInterface reference uses for selecting locators. The reference has to * be a member of this RTPSWriter object. * @param max_blocking_time_point Future timepoint where blocking send should end. */ virtual bool send_nts( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, const LocatorSelectorSender& locator_selector, std::chrono::steady_clock::time_point& max_blocking_time_point) const; diff --git a/resources/xsd/fastdds_profiles.xsd b/resources/xsd/fastdds_profiles.xsd index ee7593eba44..e85067db314 100644 --- a/resources/xsd/fastdds_profiles.xsd +++ b/resources/xsd/fastdds_profiles.xsd @@ -876,6 +876,7 @@ + diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index a7d73bd3309..463948e9f39 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -168,6 +168,7 @@ set(${PROJECT_NAME}_source_files rtps/messages/submessages/DataMsg.hpp rtps/messages/submessages/GapMsg.hpp rtps/messages/submessages/HeartbeatMsg.hpp + rtps/network/NetworkBuffer.cpp rtps/network/NetworkFactory.cpp rtps/network/ReceiverResource.cpp rtps/network/utils/external_locators.cpp diff --git a/src/cpp/rtps/builtin/discovery/participant/DirectMessageSender.cpp b/src/cpp/rtps/builtin/discovery/participant/DirectMessageSender.cpp index 40ea83b5cac..6de9430e71c 100644 --- a/src/cpp/rtps/builtin/discovery/participant/DirectMessageSender.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/DirectMessageSender.cpp @@ -93,14 +93,16 @@ const std::vector& DirectMessageSender::remote_guids() const /** * Send a message through this interface. * - * @param message Pointer to the buffer with the message already serialized. + * @param buffers Vector of NetworkBuffers to send. + * @param total_bytes Total number of bytes to send. Should be equal to the sum of the @c size field of all buffers. * @param max_blocking_time_point Future timepoint where blocking send should end. */ bool DirectMessageSender::send( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, std::chrono::steady_clock::time_point max_blocking_time_point) const { - return participant_->sendSync(message, participant_->getGuid(), + return participant_->sendSync(buffers, total_bytes, participant_->getGuid(), Locators(locators_->begin()), Locators(locators_->end()), max_blocking_time_point); } diff --git a/src/cpp/rtps/builtin/discovery/participant/DirectMessageSender.hpp b/src/cpp/rtps/builtin/discovery/participant/DirectMessageSender.hpp index da25156da4b..756f56b99bc 100644 --- a/src/cpp/rtps/builtin/discovery/participant/DirectMessageSender.hpp +++ b/src/cpp/rtps/builtin/discovery/participant/DirectMessageSender.hpp @@ -22,6 +22,8 @@ #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC +#include + #include #include @@ -78,11 +80,13 @@ class DirectMessageSender : public RTPSMessageSenderInterface /** * Send a message through this interface. * - * @param message Pointer to the buffer with the message already serialized. + * @param buffers Vector of NetworkBuffers to send with data already serialized. + * @param total_bytes Total number of bytes to send. Should be equal to the sum of the @c size field of all buffers. * @param max_blocking_time_point Future timepoint where blocking send should end. */ virtual bool send( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, std::chrono::steady_clock::time_point max_blocking_time_point) const override; /* diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp index 3ceba316ccb..df3a2a1ad95 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp @@ -64,7 +64,7 @@ static void direct_send( RTPSParticipantImpl* participant, LocatorList& locators, std::vector& remote_readers, - const CacheChange_t& change, + CacheChange_t& change, fastrtps::rtps::Endpoint& sender_endpt) { DirectMessageSender sender(participant, &remote_readers, &locators); @@ -78,7 +78,7 @@ static void direct_send( static void direct_send( RTPSParticipantImpl* participant, LocatorList& locators, - const CacheChange_t& change) + CacheChange_t& change) { FakeWriter writer(participant, c_EntityId_SPDPWriter); std::vector remote_readers; diff --git a/src/cpp/rtps/messages/RTPSMessageCreator.hpp b/src/cpp/rtps/messages/RTPSMessageCreator.hpp index 0adacdc2bd6..f586130ac61 100644 --- a/src/cpp/rtps/messages/RTPSMessageCreator.hpp +++ b/src/cpp/rtps/messages/RTPSMessageCreator.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -31,6 +32,8 @@ namespace eprosima { namespace fastrtps { namespace rtps { +using NetworkBuffer = eprosima::fastdds::rtps::NetworkBuffer; + //!An interface to add inline qos parameters to a CDRMessage class InlineQosWriter { @@ -127,7 +130,6 @@ class RTPSMessageCreator const EntityId_t& readerId, bool expectsInlineQos, InlineQosWriter* inlineQos); - static bool addSubmessageData( CDRMessage_t* msg, const CacheChange_t* change, @@ -135,7 +137,10 @@ class RTPSMessageCreator const EntityId_t& readerId, bool expectsInlineQos, InlineQosWriter* inlineQos, - bool* is_big_submessage); + bool& is_big_submessage, + bool copy_data, + NetworkBuffer& pending_buffer, + uint8_t& pending_padding); static bool addMessageDataFrag( CDRMessage_t* msg, @@ -154,7 +159,10 @@ class RTPSMessageCreator TopicKind_t topicKind, const EntityId_t& readerId, bool expectsInlineQos, - InlineQosWriter* inlineQos); + InlineQosWriter* inlineQos, + bool copy_data, + NetworkBuffer& pending_buffer, + uint8_t& pending_padding); static bool addMessageGap( CDRMessage_t* msg, diff --git a/src/cpp/rtps/messages/RTPSMessageGroup.cpp b/src/cpp/rtps/messages/RTPSMessageGroup.cpp index ec683aeb865..e238f65b76a 100644 --- a/src/cpp/rtps/messages/RTPSMessageGroup.cpp +++ b/src/cpp/rtps/messages/RTPSMessageGroup.cpp @@ -103,6 +103,65 @@ static bool append_message( return ret_val; } +bool RTPSMessageGroup::append_submessage() +{ + // Three possible cases: + // - If the RTPS message is protected, append submessages and use 1 buffer --> buffers_to_send_ of size: 1 + // Final msg Struct: | header_msg_ | + // - Else: + // a. If the submessage contains the payload --> buffers_to_send_ of size: (submessages_added) + // Final msg Struct: | header_msg_[RTPS + submsg1] | header_msg_[submsg2] | header_msg_[submsg3] | ... + // b. If the submessage does NOT contain the payload --> buffers_to_send_ of size: ((2 + PAD) * submessages_added) + // Final msg Struct: | header_msg_[RTPS + submsg1] | payload | padding | header_msg_[submsg2] | payload | padding | ... + // Note that case 1 and 2 might be intercalated, combining submessages with and without payloads if the RTPSMessageGroup + // is shared between different writers + + uint32_t pos_header = header_msg_->pos; + uint32_t length_submsg = submessage_msg_->length; + if (header_msg_->pos == RTPSMESSAGE_HEADER_SIZE && header_msg_->length == RTPSMESSAGE_HEADER_SIZE) + { + // Include the RTPS header into the buffer that will be added to buffers_to_send_ vector + pos_header = 0; + length_submsg += RTPSMESSAGE_HEADER_SIZE; + } + + // Copy the submessage to the header message. + // The submessage will contain the payload if copy_data is enabled, otherwise gather-send will be used and the + // submessage will only contain the header. The payload will be added with pending_buffer_, as an extra buffer + if (!append_message(participant_, header_msg_, submessage_msg_)) + { + return false; + } + +#if HAVE_SECURITY + // If the RTPS message is protected, the whole message will be encrypted at once + // so we need to keep the whole message in a single buffer + if (participant_->security_attributes().is_rtps_protected && endpoint_->supports_rtps_protection()) + { + return true; + } +#endif // if HAVE_SECURITY + + // Add into buffers_to_send_ the submessage added to header_msg_ + buffers_to_send_->emplace_back(&header_msg_->buffer[pos_header], length_submsg); + buffers_bytes_ += length_submsg; + + if (nullptr != pending_buffer_.buffer) + { + // Add pending buffer & padding to buffers_to_send_ + buffers_to_send_->emplace_back(pending_buffer_); + buffers_bytes_ += pending_buffer_.size; + pending_buffer_ = NetworkBuffer(); + if (pending_padding_ > 0) + { + buffers_to_send_->emplace_back(padding_, pending_padding_); + buffers_bytes_ += pending_padding_; + pending_padding_ = 0; + } + } + return true; +} + bool sort_changes_group ( CacheChange_t* c1, CacheChange_t* c2) @@ -215,8 +274,10 @@ RTPSMessageGroup::RTPSMessageGroup( )); } - full_msg_ = &(send_buffer_->rtpsmsg_fullmsg_); + header_msg_ = &(send_buffer_->rtpsmsg_fullmsg_); submessage_msg_ = &(send_buffer_->rtpsmsg_submessage_); + buffers_to_send_ = &(send_buffer_->buffers_); + payloads_to_send_ = &(send_buffer_->payloads_); // Init RTPS message. reset_to_header(); @@ -230,6 +291,7 @@ RTPSMessageGroup::RTPSMessageGroup( CDRMessage::initCDRMsg(encrypt_msg_); } #endif // if HAVE_SECURITY + } RTPSMessageGroup::RTPSMessageGroup( @@ -255,6 +317,8 @@ RTPSMessageGroup::~RTPSMessageGroup() noexcept(false) { if (!internal_buffer_) { + buffers_to_send_->clear(); + payloads_to_send_->clear(); participant_->return_send_buffer(std::move(send_buffer_)); } throw; @@ -262,15 +326,23 @@ RTPSMessageGroup::~RTPSMessageGroup() noexcept(false) if (!internal_buffer_) { + buffers_to_send_->clear(); + // Payloads are released in the destructor + payloads_to_send_->clear(); participant_->return_send_buffer(std::move(send_buffer_)); } } void RTPSMessageGroup::reset_to_header() { - CDRMessage::initCDRMsg(full_msg_); - full_msg_->pos = RTPSMESSAGE_HEADER_SIZE; - full_msg_->length = RTPSMESSAGE_HEADER_SIZE; + CDRMessage::initCDRMsg(header_msg_); + header_msg_->pos = RTPSMESSAGE_HEADER_SIZE; + header_msg_->length = RTPSMESSAGE_HEADER_SIZE; + + buffers_to_send_->clear(); + buffers_bytes_ = 0; + // Payloads are released in the destructor + payloads_to_send_->clear(); } void RTPSMessageGroup::flush() @@ -284,10 +356,9 @@ void RTPSMessageGroup::send() { if (endpoint_ && sender_) { + CDRMessage_t* msgToSend = header_msg_; - CDRMessage_t* msgToSend = full_msg_; - - if (full_msg_->length > RTPSMESSAGE_HEADER_SIZE) + if (header_msg_->length > RTPSMESSAGE_HEADER_SIZE) { std::lock_guard lock(*sender_); @@ -296,12 +367,12 @@ void RTPSMessageGroup::send() if (participant_->security_attributes().is_rtps_protected && endpoint_->supports_rtps_protection()) { CDRMessage::initCDRMsg(encrypt_msg_); - full_msg_->pos = RTPSMESSAGE_HEADER_SIZE; + header_msg_->pos = RTPSMESSAGE_HEADER_SIZE; encrypt_msg_->pos = RTPSMESSAGE_HEADER_SIZE; encrypt_msg_->length = RTPSMESSAGE_HEADER_SIZE; - memcpy(encrypt_msg_->buffer, full_msg_->buffer, RTPSMESSAGE_HEADER_SIZE); + memcpy(encrypt_msg_->buffer, header_msg_->buffer, RTPSMESSAGE_HEADER_SIZE); - if (!participant_->security_manager().encode_rtps_message(*full_msg_, *encrypt_msg_, + if (!participant_->security_manager().encode_rtps_message(*header_msg_, *encrypt_msg_, sender_->remote_participants())) { EPROSIMA_LOG_ERROR(RTPS_WRITER, "Error encoding rtps message."); @@ -309,17 +380,22 @@ void RTPSMessageGroup::send() } msgToSend = encrypt_msg_; + buffers_to_send_->emplace_back(msgToSend->buffer, msgToSend->length); + buffers_bytes_ += msgToSend->length; } #endif // if HAVE_SECURITY - eprosima::fastdds::statistics::rtps::add_statistics_submessage(msgToSend); +#ifdef FASTDDS_STATISTICS + add_stats_submsg(); +#endif // FASTDDS_STATISTICS - if (!sender_->send(msgToSend, + if (!sender_->send(*buffers_to_send_, + buffers_bytes_, max_blocking_time_point_)) { throw timeout(); } - current_sent_bytes_ += msgToSend->length; + current_sent_bytes_ += buffers_bytes_; } } } @@ -365,17 +441,17 @@ bool RTPSMessageGroup::insert_submessage( const GuidPrefix_t& destination_guid_prefix, bool is_big_submessage) { - if (!append_message(participant_, full_msg_, submessage_msg_)) + uint32_t total_size = submessage_msg_->length + pending_buffer_.size + buffers_bytes_ + pending_padding_; + if (!check_space(header_msg_, total_size)) { - // Retry - flush_and_reset(); - add_info_dst_in_buffer(full_msg_, destination_guid_prefix); + flush(); + add_info_dst_in_buffer(header_msg_, destination_guid_prefix); + } - if (!append_message(participant_, full_msg_, submessage_msg_)) - { - EPROSIMA_LOG_ERROR(RTPS_WRITER, "Cannot add RTPS submesage to the CDRMessage. Buffer too small"); - return false; - } + if (!append_submessage()) + { + EPROSIMA_LOG_ERROR(RTPS_WRITER, "Cannot add RTPS submesage to the CDRMessage. Buffer too small"); + return false; } // Messages with a submessage bigger than 64KB cannot have more submessages and should be flushed @@ -387,13 +463,32 @@ bool RTPSMessageGroup::insert_submessage( return true; } +bool RTPSMessageGroup::check_space( + CDRMessage_t* msg, + const uint32_t length) +{ + uint32_t extra_size = 0; + +#if HAVE_SECURITY + // Avoid full message growing over estimated extra size for RTPS encryption + extra_size += participant_->calculate_extra_size_for_rtps_message(); +#endif // HAVE_SECURITY + +#ifdef FASTDDS_STATISTICS + // Keep room for the statistics submessage by reducing max_size while appending submessage + extra_size += eprosima::fastdds::statistics::rtps::statistics_submessage_length; +#endif // FASTDDS_STATISTICS + + return msg && ((msg->pos + length) <= (msg->max_size - extra_size)); +} + bool RTPSMessageGroup::add_info_dst_in_buffer( CDRMessage_t* buffer, const GuidPrefix_t& destination_guid_prefix) { #if HAVE_SECURITY // Add INFO_SRC when we are at the beginning of the message and RTPS protection is enabled - if ((full_msg_->length == RTPSMESSAGE_HEADER_SIZE) && + if ((header_msg_->length == RTPSMESSAGE_HEADER_SIZE) && participant_->security_attributes().is_rtps_protected && endpoint_->supports_rtps_protection()) { RTPSMessageCreator::addSubmessageInfoSRC(buffer, c_ProtocolVersion, c_VendorId_eProsima, @@ -457,16 +552,17 @@ bool RTPSMessageGroup::add_info_ts_in_buffer( } bool RTPSMessageGroup::add_data( - const CacheChange_t& change, + CacheChange_t& change, bool expectsInlineQos) { assert(nullptr != sender_); - EPROSIMA_LOG_INFO(RTPS_WRITER, "Sending relevant changes as DATA/DATA_FRAG messages"); + EPROSIMA_LOG_INFO(RTPS_WRITER, "Sending relevant changes as DATA messages"); // Check limitation uint32_t data_size = change.serializedPayload.length; - if (data_exceeds_limitation(data_size, sent_bytes_limitation_, current_sent_bytes_, full_msg_->length)) + if (data_exceeds_limitation(data_size, sent_bytes_limitation_, current_sent_bytes_, + buffers_bytes_)) { flush_and_reset(); throw limit_exceeded(); @@ -480,8 +576,13 @@ bool RTPSMessageGroup::add_data( InlineQosWriter* inline_qos; inline_qos = (change.inline_qos.length > 0 && nullptr != change.inline_qos.data) ? &qos_writer : nullptr; + bool copy_data = false; #if HAVE_SECURITY uint32_t from_buffer_position = submessage_msg_->pos; + bool protect_payload = endpoint_->getAttributes().security_attributes().is_payload_protected; + bool protect_submessage = endpoint_->getAttributes().security_attributes().is_submessage_protected; + bool protect_rtps = participant_->security_attributes().is_rtps_protected; + copy_data = protect_payload || protect_submessage || protect_rtps; #endif // if HAVE_SECURITY const EntityId_t& readerId = get_entity_id(sender_->remote_guids()); @@ -492,7 +593,7 @@ bool RTPSMessageGroup::add_data( change_to_add.writerGUID = endpoint_->getGuid(); #if HAVE_SECURITY - if (endpoint_->getAttributes().security_attributes().is_payload_protected) + if (protect_payload) { SerializedPayload_t encrypt_payload; encrypt_payload.data = encrypt_msg_->buffer; @@ -517,7 +618,7 @@ bool RTPSMessageGroup::add_data( // TODO (Ricardo). Check to create special wrapper. bool is_big_submessage; if (!RTPSMessageCreator::addSubmessageData(submessage_msg_, &change_to_add, endpoint_->getAttributes().topicKind, - readerId, expectsInlineQos, inline_qos, &is_big_submessage)) + readerId, expectsInlineQos, inline_qos, is_big_submessage, copy_data, pending_buffer_, pending_padding_)) { EPROSIMA_LOG_ERROR(RTPS_WRITER, "Cannot add DATA submsg to the CDRMessage. Buffer too small"); change_to_add.serializedPayload.data = nullptr; @@ -526,7 +627,7 @@ bool RTPSMessageGroup::add_data( change_to_add.serializedPayload.data = nullptr; #if HAVE_SECURITY - if (endpoint_->getAttributes().security_attributes().is_submessage_protected) + if (protect_submessage) { submessage_msg_->pos = from_buffer_position; CDRMessage::initCDRMsg(encrypt_msg_); @@ -551,17 +652,27 @@ bool RTPSMessageGroup::add_data( } #endif // if HAVE_SECURITY - return insert_submessage(is_big_submessage); + if (insert_submessage(is_big_submessage)) + { + // If gather-send is possible, get payload + if (!copy_data) + { + get_payload(change); + } + return true; + } + + return false; } bool RTPSMessageGroup::add_data_frag( - const CacheChange_t& change, + CacheChange_t& change, const uint32_t fragment_number, bool expectsInlineQos) { assert(nullptr != sender_); - EPROSIMA_LOG_INFO(RTPS_WRITER, "Sending relevant changes as DATA/DATA_FRAG messages"); + EPROSIMA_LOG_INFO(RTPS_WRITER, "Sending relevant changes as DATA_FRAG messages"); // Calculate fragment start uint32_t fragment_start = change.getFragmentSize() * (fragment_number - 1); @@ -569,7 +680,8 @@ bool RTPSMessageGroup::add_data_frag( uint32_t fragment_size = fragment_number < change.getFragmentCount() ? change.getFragmentSize() : change.serializedPayload.length - fragment_start; // Check limitation - if (data_exceeds_limitation(fragment_size, sent_bytes_limitation_, current_sent_bytes_, full_msg_->length)) + if (data_exceeds_limitation(fragment_size, sent_bytes_limitation_, current_sent_bytes_, + buffers_bytes_)) { flush_and_reset(); throw limit_exceeded(); @@ -583,8 +695,13 @@ bool RTPSMessageGroup::add_data_frag( InlineQosWriter* inline_qos; inline_qos = (change.inline_qos.length > 0 && nullptr != change.inline_qos.data) ? &qos_writer : nullptr; + bool copy_data = false; #if HAVE_SECURITY uint32_t from_buffer_position = submessage_msg_->pos; + bool protect_payload = endpoint_->getAttributes().security_attributes().is_payload_protected; + bool protect_submessage = endpoint_->getAttributes().security_attributes().is_submessage_protected; + bool protect_rtps = participant_->security_attributes().is_rtps_protected; + copy_data = protect_payload || protect_submessage || protect_rtps; #endif // if HAVE_SECURITY const EntityId_t& readerId = get_entity_id(sender_->remote_guids()); @@ -596,7 +713,7 @@ bool RTPSMessageGroup::add_data_frag( change_to_add.writerGUID = endpoint_->getGuid(); #if HAVE_SECURITY - if (endpoint_->getAttributes().security_attributes().is_payload_protected) + if (protect_payload) { SerializedPayload_t encrypt_payload; encrypt_payload.data = encrypt_msg_->buffer; @@ -620,7 +737,7 @@ bool RTPSMessageGroup::add_data_frag( if (!RTPSMessageCreator::addSubmessageDataFrag(submessage_msg_, &change, fragment_number, change_to_add.serializedPayload, endpoint_->getAttributes().topicKind, readerId, - expectsInlineQos, inline_qos)) + expectsInlineQos, inline_qos, copy_data, pending_buffer_, pending_padding_)) { EPROSIMA_LOG_ERROR(RTPS_WRITER, "Cannot add DATA_FRAG submsg to the CDRMessage. Buffer too small"); change_to_add.serializedPayload.data = nullptr; @@ -654,7 +771,16 @@ bool RTPSMessageGroup::add_data_frag( } #endif // if HAVE_SECURITY - return insert_submessage(false); + if (insert_submessage(false)) + { + // If gather-send is possible, get payload + if (!copy_data) + { + get_payload(change); + } + return true; + } + return false; } bool RTPSMessageGroup::add_heartbeat( @@ -814,6 +940,30 @@ bool RTPSMessageGroup::create_gap_submessage( return true; } +void RTPSMessageGroup::get_payload( + CacheChange_t& change) +{ + payloads_to_send_->emplace_back(); + // Get payload to avoid returning it to the pool before sending + change.serializedPayload.payload_owner->get_payload(change.serializedPayload, payloads_to_send_->back()); +} + +#ifdef FASTDDS_STATISTICS +void RTPSMessageGroup::add_stats_submsg() +{ + // Use empty space of header_msg_ buffer to create the msg + uint32_t stats_pos = header_msg_->pos; + + eprosima::fastdds::statistics::rtps::add_statistics_submessage(header_msg_); + + // Add into buffers_to_send_ the submessage added to header_msg_ + buffers_to_send_->emplace_back(&header_msg_->buffer[stats_pos], + eprosima::fastdds::statistics::rtps::statistics_submessage_length); + buffers_bytes_ += eprosima::fastdds::statistics::rtps::statistics_submessage_length; +} + +#endif // FASTDDS_STATISTICS + bool RTPSMessageGroup::add_acknack( const SequenceNumberSet_t& SNSet, int32_t count, diff --git a/src/cpp/rtps/messages/RTPSMessageGroup.hpp b/src/cpp/rtps/messages/RTPSMessageGroup.hpp index fce14d51319..3823721237c 100644 --- a/src/cpp/rtps/messages/RTPSMessageGroup.hpp +++ b/src/cpp/rtps/messages/RTPSMessageGroup.hpp @@ -25,9 +25,12 @@ #include #include #include +#include #include #include +#include +#include #include @@ -116,7 +119,7 @@ class RTPSMessageGroup * @return True when message was added to the group. */ bool add_data( - const CacheChange_t& change, + CacheChange_t& change, bool expects_inline_qos); /** @@ -127,7 +130,7 @@ class RTPSMessageGroup * @return True when message was added to the group. */ bool add_data_frag( - const CacheChange_t& change, + CacheChange_t& change, const uint32_t fragment_number, bool expects_inline_qos); @@ -242,7 +245,7 @@ class RTPSMessageGroup inline uint32_t get_current_bytes_processed() const { - return current_sent_bytes_ + full_msg_->length; + return current_sent_bytes_ + buffers_bytes_; } private: @@ -274,6 +277,35 @@ class RTPSMessageGroup const GuidPrefix_t& destination_guid_prefix, bool is_big_submessage); + /** + * @brief Checks if there is enough space in the CDRMessage to accommodate the given length. + * + * @param msg Pointer to the CDRMessage to be checked. + * @param length The length to be checked for space availability. + * @return True if there is enough space, false otherwise. + */ + bool check_space( + CDRMessage_t* msg, + const uint32_t length); + + /** + * Appends a submessage to the RTPS Message so it can be sent. + * The submessage is copied into the header_msg_ buffer. The submessage might contain a data payload + * or not, in case it is possible to avoid the copy of the payload. + * The payload will be added later to buffers_to_send_ if it exists in pending_buffer_. + * The copied submessage in added to buffers_to_send_ through a pointer to its position in header_msg_ and + * its length. + * + * In gather-send operation, the submessage appended only contains the header and pending_buffer_ + * points to the data payload. + * + * If gather-send operation is not possible (i.e. Security), the submessage received will contain + * the header AND the data payload. The whole submessage will be copied into header_msg_. + * + * @return True if the submessage was successfully appended, false if the copy operation failed. + */ + bool append_submessage(); + bool add_info_dst_in_buffer( CDRMessage_t* buffer, const GuidPrefix_t& destination_guid_prefix); @@ -286,11 +318,19 @@ class RTPSMessageGroup const SequenceNumberSet_t& gap_bitmap, const EntityId_t& reader_id); + void get_payload( + CacheChange_t& change); + +#ifdef FASTDDS_STATISTICS + //! Append the Statistics message to the header_msg_ and add the corresponding buffer to buffers_to_send_. + void add_stats_submsg(); +#endif // FASTDDS_STATISTICS + RTPSMessageSenderInterface* sender_ = nullptr; Endpoint* endpoint_ = nullptr; - CDRMessage_t* full_msg_ = nullptr; + CDRMessage_t* header_msg_ = nullptr; CDRMessage_t* submessage_msg_ = nullptr; @@ -313,9 +353,27 @@ class RTPSMessageGroup uint32_t sent_bytes_limitation_ = 0; uint32_t current_sent_bytes_ = 0; + + // Next buffer that will be sent + eprosima::fastdds::rtps::NetworkBuffer pending_buffer_; + + // Vector of buffers that will be sent along the header + ResourceLimitedVector* buffers_to_send_ = nullptr; + + // Vector of payloads of which the RTPSMessageGroup is the owner + ResourceLimitedVector* payloads_to_send_ = nullptr; + + // Bytes to send in the next list of buffers + uint32_t buffers_bytes_ = 0; + + // Size of the pending padding + uint8_t pending_padding_ = 0; + + // Fixed padding to be used whenever needed + const octet padding_[3] = {0, 0, 0}; }; -} /* namespace rtps */ +} /* namespace rtps */ } /* namespace fastrtps */ } /* namespace eprosima */ diff --git a/src/cpp/rtps/messages/RTPSMessageGroup_t.hpp b/src/cpp/rtps/messages/RTPSMessageGroup_t.hpp index 1c8d2cdc90e..e74e235a7b6 100644 --- a/src/cpp/rtps/messages/RTPSMessageGroup_t.hpp +++ b/src/cpp/rtps/messages/RTPSMessageGroup_t.hpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include namespace eprosima { namespace fastrtps { @@ -48,6 +50,8 @@ class RTPSMessageGroup_t #if HAVE_SECURITY , rtpsmsg_encrypt_(0u) #endif // if HAVE_SECURITY + , buffers_(ResourceLimitedContainerConfig(16, std::numeric_limits::max dummy_avoid_winmax (), 16)) + , payloads_(ResourceLimitedContainerConfig(16, std::numeric_limits::max dummy_avoid_winmax (), 16)) { rtpsmsg_fullmsg_.reserve(payload); rtpsmsg_submessage_.reserve(payload); @@ -68,12 +72,15 @@ class RTPSMessageGroup_t bool has_security, #endif // if HAVE_SECURITY uint32_t payload, - const GuidPrefix_t& participant_guid) + const GuidPrefix_t& participant_guid, + ResourceLimitedContainerConfig nb_config) : rtpsmsg_submessage_(0u) , rtpsmsg_fullmsg_(0u) #if HAVE_SECURITY , rtpsmsg_encrypt_(0u) #endif // if HAVE_SECURITY + , buffers_(nb_config) + , payloads_(nb_config) { rtpsmsg_fullmsg_.init(buffer_ptr, payload); buffer_ptr += payload; @@ -104,6 +111,12 @@ class RTPSMessageGroup_t #if HAVE_SECURITY CDRMessage_t rtpsmsg_encrypt_; #endif // if HAVE_SECURITY + + //! Vector to store the NetworkBuffers that will be used to form the RTPS message. + eprosima::fastrtps::ResourceLimitedVector buffers_; + + //! Mirror vector of buffers_ to store the serialized payloads. + eprosima::fastrtps::ResourceLimitedVector payloads_; }; } // namespace rtps diff --git a/src/cpp/rtps/messages/SendBuffersManager.cpp b/src/cpp/rtps/messages/SendBuffersManager.cpp index 38a6e2d83f0..d327fea0495 100644 --- a/src/cpp/rtps/messages/SendBuffersManager.cpp +++ b/src/cpp/rtps/messages/SendBuffersManager.cpp @@ -27,8 +27,10 @@ namespace rtps { SendBuffersManager::SendBuffersManager( size_t reserved_size, - bool allow_growing) + bool allow_growing, + ResourceLimitedContainerConfig network_buffers_config) : allow_growing_(allow_growing) + , network_buffers_config_(network_buffers_config) { pool_.reserve(reserved_size); } @@ -67,7 +69,7 @@ void SendBuffersManager::init( #if HAVE_SECURITY secure, #endif // if HAVE_SECURITY - payload_size, guid_prefix + payload_size, guid_prefix, network_buffers_config_ )); raw_buffer += advance; ++n_created_; diff --git a/src/cpp/rtps/messages/SendBuffersManager.hpp b/src/cpp/rtps/messages/SendBuffersManager.hpp index bb6a1ecf828..4b9cb97e433 100644 --- a/src/cpp/rtps/messages/SendBuffersManager.hpp +++ b/src/cpp/rtps/messages/SendBuffersManager.hpp @@ -47,10 +47,13 @@ class SendBuffersManager * Construct a SendBuffersManager. * @param reserved_size Initial size for the pool. * @param allow_growing Whether we allow creation of more than reserved_size elements. + * @param num_network_buffers Number of network buffers to allocate for each send buffer. + * @param inc_network_buffers Number of network buffers to dynamically allocate when growing the vector. */ SendBuffersManager( size_t reserved_size, - bool allow_growing); + bool allow_growing, + ResourceLimitedContainerConfig network_buffers_config); ~SendBuffersManager() { @@ -99,6 +102,10 @@ class SendBuffersManager bool allow_growing_ = true; //!To wait for a buffer to be returned to the pool. TimedConditionVariable available_cv_; + //!Configuration for the network buffers. + ResourceLimitedContainerConfig network_buffers_config_ = ResourceLimitedContainerConfig(16u, + std::numeric_limits::max dummy_avoid_winmax (), 16u); + }; } /* namespace rtps */ diff --git a/src/cpp/rtps/messages/submessages/DataMsg.hpp b/src/cpp/rtps/messages/submessages/DataMsg.hpp index 65e11a48d60..359b142a244 100644 --- a/src/cpp/rtps/messages/submessages/DataMsg.hpp +++ b/src/cpp/rtps/messages/submessages/DataMsg.hpp @@ -21,6 +21,9 @@ #include #include +#include + +using NetworkBuffer = eprosima::fastdds::rtps::NetworkBuffer; namespace eprosima { namespace fastrtps { @@ -168,9 +171,12 @@ bool RTPSMessageCreator::addMessageData( RTPSMessageCreator::addSubmessageInfoTS_Now(msg, false); + NetworkBuffer pending_buffer; + uint8_t pending_padding = 0; + bool is_big_submessage; RTPSMessageCreator::addSubmessageData(msg, change, topicKind, readerId, expectsInlineQos, inlineQos, - &is_big_submessage); + is_big_submessage, true, pending_buffer, pending_padding); msg->length = msg->pos; @@ -184,10 +190,19 @@ bool RTPSMessageCreator::addSubmessageData( const EntityId_t& readerId, bool expectsInlineQos, InlineQosWriter* inlineQos, - bool* is_big_submessage) + bool& is_big_submessage, + bool copy_data, + NetworkBuffer& pending_buffer, + uint8_t& pending_padding) { octet status = 0; octet flags = 0; + + // Initialize output parameters + is_big_submessage = false; + pending_buffer = NetworkBuffer(); + pending_padding = 0; + //Find out flags bool dataFlag = false; bool keyFlag = false; @@ -235,7 +250,20 @@ bool RTPSMessageCreator::addSubmessageData( //Add Serialized Payload if (dataFlag) { - added_no_error &= CDRMessage::addData(msg, change->serializedPayload.data, change->serializedPayload.length); + if (copy_data) + { + added_no_error &= + CDRMessage::addData(msg, change->serializedPayload.data, change->serializedPayload.length); + } + else if (msg->pos + change->serializedPayload.length > msg->max_size) + { + return false; + } + else + { + pending_buffer = NetworkBuffer(change->serializedPayload.data, change->serializedPayload.length); + msg->pos += pending_buffer.size; + } } if (keyFlag) @@ -261,16 +289,18 @@ bool RTPSMessageCreator::addSubmessageData( } // Align submessage to rtps alignment (4). - uint32_t align = (4 - msg->pos % 4) & 3; - for (uint32_t count = 0; count < align; ++count) + uint8_t align = (4 - msg->pos % 4) & 3; + if (copy_data) { - added_no_error &= CDRMessage::addOctet(msg, 0); + for (uint32_t count = 0; count < align; ++count) + { + added_no_error &= CDRMessage::addOctet(msg, 0); + } } - - //if(align > 0) + else { - //submsgElem.pos += align; - //submsgElem.length += align; + pending_padding = align; + msg->pos += align; } uint32_t size32 = msg->pos - position_size_count_size; @@ -288,13 +318,18 @@ bool RTPSMessageCreator::addSubmessageData( msg->buffer[submessage_size_pos] = *(o + 1); msg->buffer[submessage_size_pos + 1] = *(o); } - - *is_big_submessage = false; } else { - // Submessage > 64KB - *is_big_submessage = true; + // Submessage > 64 KB + is_big_submessage = true; + } + + // Rewind position when not copying data. Needed for size checks. + if (!copy_data) + { + msg->pos -= pending_padding; + msg->pos -= pending_buffer.size; } msg->msg_endian = old_endianess; @@ -327,8 +362,11 @@ bool RTPSMessageCreator::addMessageDataFrag( payload.data = change->serializedPayload.data + fragment_start; payload.length = fragment_size; + NetworkBuffer pending_buffer; + uint8_t pending_padding = 0; + RTPSMessageCreator::addSubmessageDataFrag(msg, change, fragment_number, payload, - topicKind, readerId, expectsInlineQos, inlineQos); + topicKind, readerId, expectsInlineQos, inlineQos, true, pending_buffer, pending_padding); payload.data = NULL; @@ -344,7 +382,10 @@ bool RTPSMessageCreator::addSubmessageDataFrag( TopicKind_t topicKind, const EntityId_t& readerId, bool expectsInlineQos, - InlineQosWriter* inlineQos) + InlineQosWriter* inlineQos, + bool copy_data, + NetworkBuffer& pending_buffer, + uint8_t& pending_padding) { octet status = 0; octet flags = 0; @@ -353,6 +394,10 @@ bool RTPSMessageCreator::addSubmessageDataFrag( bool keyFlag = false; bool inlineQosFlag = false; + // Initialize output parameters + pending_buffer = NetworkBuffer(); + pending_padding = 0; + Endianness_t old_endianess = msg->msg_endian; #if FASTDDS_IS_BIG_ENDIAN_TARGET msg->msg_endian = BIGEND; @@ -390,7 +435,19 @@ bool RTPSMessageCreator::addSubmessageDataFrag( //Add Serialized Payload XXX TODO if (!keyFlag) // keyflag = 0 means that the serializedPayload SubmessageElement contains the serialized Data { - added_no_error &= CDRMessage::addData(msg, payload.data, payload.length); + if (copy_data) + { + added_no_error &= CDRMessage::addData(msg, payload.data, payload.length); + } + else if (msg->pos + payload.length > msg->max_size) + { + return false; + } + else + { + pending_buffer = NetworkBuffer(payload.data, payload.length); + msg->pos += pending_buffer.size; + } } else { @@ -414,9 +471,21 @@ bool RTPSMessageCreator::addSubmessageDataFrag( // TODO(Ricardo) This should be on cachechange. // Align submessage to rtps alignment (4). submessage_size = uint16_t(msg->pos - position_size_count_size); - for (; submessage_size& 3; ++submessage_size) + for (; 0 != (submessage_size & 3); ++submessage_size) + { + if (copy_data) + { + added_no_error &= CDRMessage::addOctet(msg, 0); + } + else + { + ++pending_padding; + } + } + + if (!copy_data) { - added_no_error &= CDRMessage::addOctet(msg, 0); + msg->pos -= pending_buffer.size; } //TODO(Ricardo) Improve. diff --git a/src/cpp/rtps/network/NetworkBuffer.cpp b/src/cpp/rtps/network/NetworkBuffer.cpp new file mode 100644 index 00000000000..217e5de4dd7 --- /dev/null +++ b/src/cpp/rtps/network/NetworkBuffer.cpp @@ -0,0 +1,31 @@ +// Copyright 2024 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 { + +//! NetworkBuffer conversion operator to asio::const_buffer. +NetworkBuffer::operator asio::const_buffer() const +{ + return asio::const_buffer(buffer, size); +} + +} // namespace rtps +} // namespace fastdds +} // namespace eprosima diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp index 807fa291394..44302cad1e2 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp @@ -707,7 +707,8 @@ void RTPSParticipantImpl::setup_output_traffic() } // Create buffer pool - send_buffers_.reset(new SendBuffersManager(num_send_buffers, allow_growing_buffers)); + send_buffers_.reset(new SendBuffersManager(num_send_buffers, allow_growing_buffers, + m_att.allocation.send_buffers.network_buffers_config)); send_buffers_->init(this); // Initialize flow controller factory. diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.h b/src/cpp/rtps/participant/RTPSParticipantImpl.h index bf617bc3ba0..b28c9d16132 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.h +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.h @@ -29,6 +29,7 @@ #include #include #include +#include #if defined(_WIN32) #include @@ -284,7 +285,8 @@ class RTPSParticipantImpl /** * Send a message to several locations - * @param msg Message to send. + * @param buffers Vector of buffers to send. + * @param total_bytes Total number of bytes to send. * @param sender_guid GUID of the producer of the message. * @param destination_locators_begin Iterator at the first destination locator. * @param destination_locators_end Iterator at the end destination locator. @@ -293,7 +295,8 @@ class RTPSParticipantImpl */ template bool sendSync( - CDRMessage_t* msg, + const std::vector& buffers, + const uint32_t& total_bytes, const GUID_t& sender_guid, const LocatorIteratorT& destination_locators_begin, const LocatorIteratorT& destination_locators_end, @@ -313,7 +316,7 @@ class RTPSParticipantImpl { LocatorIteratorT locators_begin = destination_locators_begin; LocatorIteratorT locators_end = destination_locators_end; - send_resource->send(msg->buffer, msg->length, &locators_begin, &locators_end, + send_resource->send(buffers, total_bytes, &locators_begin, &locators_end, max_blocking_time_point); } @@ -324,7 +327,7 @@ class RTPSParticipantImpl sender_guid, destination_locators_begin, destination_locators_end, - msg->length); + total_bytes); // checkout if sender is a discovery endpoint on_discovery_packet( diff --git a/src/cpp/rtps/reader/StatefulReader.cpp b/src/cpp/rtps/reader/StatefulReader.cpp index 1340de7fdcc..4033be9b608 100644 --- a/src/cpp/rtps/reader/StatefulReader.cpp +++ b/src/cpp/rtps/reader/StatefulReader.cpp @@ -1635,10 +1635,12 @@ void StatefulReader::send_acknack( } bool StatefulReader::send_sync_nts( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, const Locators& locators_begin, const Locators& locators_end, std::chrono::steady_clock::time_point& max_blocking_time_point) { - return mp_RTPSParticipant->sendSync(message, m_guid, locators_begin, locators_end, max_blocking_time_point); + return mp_RTPSParticipant->sendSync(buffers, total_bytes, m_guid, locators_begin, locators_end, + max_blocking_time_point); } diff --git a/src/cpp/rtps/reader/StatefulReader.hpp b/src/cpp/rtps/reader/StatefulReader.hpp index 861b36a4038..fc9d6b74ac7 100644 --- a/src/cpp/rtps/reader/StatefulReader.hpp +++ b/src/cpp/rtps/reader/StatefulReader.hpp @@ -22,6 +22,7 @@ #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC #include +#include #include #include @@ -258,13 +259,15 @@ class StatefulReader : public fastdds::rtps::BaseReader /** * Use the participant of this reader to send a message to certain locator. - * @param message Message to be sent. + * @param buffers Vector of buffers to send. + * @param total_bytes Total number of bytes to send. * @param locators_begin Destination locators iterator begin. * @param locators_end Destination locators iterator end. * @param max_blocking_time_point Future time point where any blocking should end. */ bool send_sync_nts( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, const Locators& locators_begin, const Locators& locators_end, std::chrono::steady_clock::time_point& max_blocking_time_point); diff --git a/src/cpp/rtps/reader/WriterProxy.cpp b/src/cpp/rtps/reader/WriterProxy.cpp index 0a5a4d25054..a52b95702fb 100644 --- a/src/cpp/rtps/reader/WriterProxy.cpp +++ b/src/cpp/rtps/reader/WriterProxy.cpp @@ -620,7 +620,8 @@ void WriterProxy::update_heartbeat_response_interval( } bool WriterProxy::send( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, std::chrono::steady_clock::time_point max_blocking_time_point) const { if (is_on_same_process_) @@ -630,7 +631,8 @@ bool WriterProxy::send( const ResourceLimitedVector& remote_locators = remote_locators_shrinked(); - return reader_->send_sync_nts(message, + return reader_->send_sync_nts(buffers, + total_bytes, Locators(remote_locators.begin()), Locators(remote_locators.end()), max_blocking_time_point); diff --git a/src/cpp/rtps/reader/WriterProxy.h b/src/cpp/rtps/reader/WriterProxy.h index d8cf1eb6021..c641690dddb 100644 --- a/src/cpp/rtps/reader/WriterProxy.h +++ b/src/cpp/rtps/reader/WriterProxy.h @@ -34,6 +34,7 @@ #include #include +#include // Testing purpose #ifndef TEST_FRIENDS @@ -314,11 +315,13 @@ class WriterProxy : public RTPSMessageSenderInterface /** * Send a message through this interface. * - * @param message Pointer to the buffer with the message already serialized. + * @param buffers Vector of NetworkBuffers to send with data already serialized. + * @param total_bytes Total number of bytes to send. Should be equal to the sum of the @c size field of all buffers. * @param max_blocking_time_point Future timepoint where blocking send should end. */ virtual bool send( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, std::chrono::steady_clock::time_point max_blocking_time_point) const override; bool is_on_same_process() const diff --git a/src/cpp/rtps/transport/ChainingSenderResource.hpp b/src/cpp/rtps/transport/ChainingSenderResource.hpp index 2b3ee7a4bcc..cafbf917561 100644 --- a/src/cpp/rtps/transport/ChainingSenderResource.hpp +++ b/src/cpp/rtps/transport/ChainingSenderResource.hpp @@ -39,16 +39,16 @@ class ChainingSenderResource : public fastrtps::rtps::SenderResource // low_sender_resources_ makes its clean up on destruction. }; - send_lambda_ = [this, &transport]( - const fastrtps::rtps::octet* data, - uint32_t dataSize, + send_buffers_lambda_ = [this, &transport]( + const std::vector& buffers, + uint32_t total_bytes, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point& timeout) -> bool { if (low_sender_resource_) { - return transport.send(low_sender_resource_.get(), data, dataSize, + return transport.send(low_sender_resource_.get(), buffers, total_bytes, destination_locators_begin, destination_locators_end, timeout); } diff --git a/src/cpp/rtps/transport/TCPChannelResource.h b/src/cpp/rtps/transport/TCPChannelResource.h index 589ae6221e7..85d2e189428 100644 --- a/src/cpp/rtps/transport/TCPChannelResource.h +++ b/src/cpp/rtps/transport/TCPChannelResource.h @@ -137,11 +137,46 @@ class TCPChannelResource : public ChannelResource std::size_t size, asio::error_code& ec) = 0; + /** + * Sends the provided TCP header and data over the TCP channel. + * Used solely during TCP connection negotiations. + * + * @param header Pointer to the octet array containing the TCP header. + * @param header_size Size of the TCP header array. + * @param data Pointer to the octet array containing the data. + * @param data_size Size of the data array. + * @param ec Reference to the asio::error_code object to store any error that occurs during the send operation. + * @return The number of bytes actually sent. + */ + size_t send( + const fastrtps::rtps::octet* header, + size_t header_size, + const fastrtps::rtps::octet* data, + uint32_t data_size, + asio::error_code& ec) + { + NetworkBuffer buffers(data, data_size); + std::vector buffer_list; + buffer_list.push_back(buffers); + return send(header, header_size, buffer_list, data_size, ec); + } + + /** + * Sends the provided TCP header and data over the TCP channel. + * Used for TCP metatraffic and data transmission. + * + * @param header Pointer to the TCP header data. + * @param header_size Size of the TCP header data. + * @param buffers Vector of network buffers containing the data to be sent. + * @param total_bytes Total number of bytes to be sent. + * @param ec Reference to an asio::error_code object to store any error that occurs during the send operation. + * @return The number of bytes actually sent. + */ virtual size_t send( const fastrtps::rtps::octet* header, size_t header_size, - const fastrtps::rtps::octet* buffer, - size_t size, + const std::vector& buffers, + uint32_t total_bytes, asio::error_code& ec) = 0; /** diff --git a/src/cpp/rtps/transport/TCPChannelResourceBasic.cpp b/src/cpp/rtps/transport/TCPChannelResourceBasic.cpp index 879bdb23718..ca1b5a56c7e 100644 --- a/src/cpp/rtps/transport/TCPChannelResourceBasic.cpp +++ b/src/cpp/rtps/transport/TCPChannelResourceBasic.cpp @@ -143,8 +143,8 @@ uint32_t TCPChannelResourceBasic::read( size_t TCPChannelResourceBasic::send( const octet* header, size_t header_size, - const octet* data, - size_t size, + const std::vector& buffers, + uint32_t total_bytes, asio::error_code& ec) { size_t bytes_sent = 0; @@ -154,22 +154,19 @@ size_t TCPChannelResourceBasic::send( std::lock_guard send_guard(send_mutex_); if (parent_->configuration()->non_blocking_send && - !check_socket_send_buffer(header_size + size, socket_->native_handle())) + !check_socket_send_buffer(header_size + total_bytes, socket_->native_handle())) { return 0; } + // Use a list of const_buffers to send the message + std::list asio_buffers; if (header_size > 0) { - std::array buffers; - buffers[0] = asio::buffer(header, header_size); - buffers[1] = asio::buffer(data, size); - bytes_sent = asio::write(*socket_.get(), buffers, ec); - } - else - { - bytes_sent = asio::write(*socket_.get(), asio::buffer(data, size), ec); + asio_buffers.push_back(asio::buffer(header, header_size)); } + asio_buffers.insert(asio_buffers.end(), buffers.begin(), buffers.end()); + bytes_sent = asio::write(*socket_.get(), asio_buffers, ec); } return bytes_sent; diff --git a/src/cpp/rtps/transport/TCPChannelResourceBasic.h b/src/cpp/rtps/transport/TCPChannelResourceBasic.h index 20928f0f494..8d661d1da34 100644 --- a/src/cpp/rtps/transport/TCPChannelResourceBasic.h +++ b/src/cpp/rtps/transport/TCPChannelResourceBasic.h @@ -61,8 +61,8 @@ class TCPChannelResourceBasic : public TCPChannelResource size_t send( const fastrtps::rtps::octet* header, size_t header_size, - const fastrtps::rtps::octet* data, - size_t size, + const std::vector& buffers, + uint32_t total_bytes, asio::error_code& ec) override; // Throwing asio calls diff --git a/src/cpp/rtps/transport/TCPChannelResourceSecure.cpp b/src/cpp/rtps/transport/TCPChannelResourceSecure.cpp index 0ac617a6774..e415c025e1f 100644 --- a/src/cpp/rtps/transport/TCPChannelResourceSecure.cpp +++ b/src/cpp/rtps/transport/TCPChannelResourceSecure.cpp @@ -202,8 +202,8 @@ uint32_t TCPChannelResourceSecure::read( size_t TCPChannelResourceSecure::send( const octet* header, size_t header_size, - const octet* data, - size_t size, + const std::vector& buffers, + uint32_t total_bytes, asio::error_code& ec) { size_t bytes_sent = 0; @@ -211,18 +211,19 @@ size_t TCPChannelResourceSecure::send( if (eConnecting < connection_status_) { if (parent_->configuration()->non_blocking_send && - !check_socket_send_buffer(header_size + size, + !check_socket_send_buffer(header_size + total_bytes, secure_socket_->lowest_layer().native_handle())) { return 0; } - std::vector buffers; + // Use a list of const_buffers to send the message + std::vector asio_buffers; if (header_size > 0) { - buffers.push_back(asio::buffer(header, header_size)); + asio_buffers.push_back(asio::buffer(header, header_size)); } - buffers.push_back(asio::buffer(data, size)); + asio_buffers.insert(asio_buffers.end(), buffers.begin(), buffers.end()); // Work around meanwhile std::promise write_bytes_promise; @@ -233,7 +234,7 @@ size_t TCPChannelResourceSecure::send( { if (socket->lowest_layer().is_open()) { - size_t bytes_transferred = asio::write(*socket, buffers, ec); + size_t bytes_transferred = asio::write(*socket, asio_buffers, ec); if (!ec) { write_bytes_promise.set_value(bytes_transferred); diff --git a/src/cpp/rtps/transport/TCPChannelResourceSecure.h b/src/cpp/rtps/transport/TCPChannelResourceSecure.h index 31226292b4b..8ed2abf2956 100644 --- a/src/cpp/rtps/transport/TCPChannelResourceSecure.h +++ b/src/cpp/rtps/transport/TCPChannelResourceSecure.h @@ -61,8 +61,8 @@ class TCPChannelResourceSecure : public TCPChannelResource size_t send( const fastrtps::rtps::octet* header, size_t header_size, - const fastrtps::rtps::octet* data, - size_t size, + const std::vector& buffers, + uint32_t total_bytes, asio::error_code& ec) override; // Throwing asio calls diff --git a/src/cpp/rtps/transport/TCPSenderResource.hpp b/src/cpp/rtps/transport/TCPSenderResource.hpp index 57e92e8ba89..65673836141 100644 --- a/src/cpp/rtps/transport/TCPSenderResource.hpp +++ b/src/cpp/rtps/transport/TCPSenderResource.hpp @@ -42,14 +42,14 @@ class TCPSenderResource : public fastrtps::rtps::SenderResource transport.SenderResourceHasBeenClosed(locator_); }; - send_lambda_ = [this, &transport]( - const fastrtps::rtps::octet* data, - uint32_t dataSize, + send_buffers_lambda_ = [this, &transport]( + const std::vector& buffers, + uint32_t total_bytes, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point&) -> bool { - return transport.send(data, dataSize, locator_, destination_locators_begin, + return transport.send(buffers, total_bytes, locator_, destination_locators_begin, destination_locators_end); }; } diff --git a/src/cpp/rtps/transport/TCPTransportInterface.cpp b/src/cpp/rtps/transport/TCPTransportInterface.cpp index 0375ef5069f..2e215259927 100644 --- a/src/cpp/rtps/transport/TCPTransportInterface.cpp +++ b/src/cpp/rtps/transport/TCPTransportInterface.cpp @@ -313,13 +313,17 @@ bool TCPTransportInterface::check_crc( void TCPTransportInterface::calculate_crc( TCPHeader& header, - const octet* data, - uint32_t size) const + const std::vector& buffers) const { uint32_t crc(0); - for (uint32_t i = 0; i < size; ++i) + for (const NetworkBuffer& buffer : buffers) { - crc = RTCPMessageManager::addToCRC(crc, data[i]); + size_t size = buffer.size; + const octet* data = static_cast(buffer.buffer); + for (size_t i = 0; i < size; ++i) + { + crc = RTCPMessageManager::addToCRC(crc, data[i]); + } } header.crc = crc; } @@ -415,15 +419,15 @@ uint16_t TCPTransportInterface::create_acceptor_socket( void TCPTransportInterface::fill_rtcp_header( TCPHeader& header, - const octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, uint16_t logical_port) const { - header.length = send_buffer_size + static_cast(TCPHeader::size()); + header.length = total_bytes + static_cast(TCPHeader::size()); header.logical_port = logical_port; if (configuration()->calculate_crc) { - calculate_crc(header, send_buffer, send_buffer_size); + calculate_crc(header, buffers); } } @@ -1421,8 +1425,8 @@ bool TCPTransportInterface::Receive( } bool TCPTransportInterface::send( - const octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, const fastrtps::rtps::Locator_t& locator, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end) @@ -1435,7 +1439,7 @@ bool TCPTransportInterface::send( { if (IsLocatorSupported(*it)) { - ret &= send(send_buffer, send_buffer_size, locator, *it); + ret &= send(buffers, total_bytes, locator, *it); } ++it; @@ -1445,8 +1449,8 @@ bool TCPTransportInterface::send( } bool TCPTransportInterface::send( - const octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, const fastrtps::rtps::Locator_t& locator, const Locator& remote_locator) { @@ -1471,7 +1475,7 @@ bool TCPTransportInterface::send( } } - if (locator_mismatch || send_buffer_size > configuration()->sendBufferSize) + if (locator_mismatch || total_bytes > configuration()->sendBufferSize) { return false; } @@ -1522,21 +1526,22 @@ bool TCPTransportInterface::send( scoped_lock.lock(); } TCPHeader tcp_header; - statistics_info_.set_statistics_message_data(remote_locator, send_buffer, send_buffer_size); - fill_rtcp_header(tcp_header, send_buffer, send_buffer_size, logical_port); + // Statistics submessage is always the last buffer to be added + statistics_info_.set_statistics_message_data(remote_locator, buffers.back(), total_bytes); + fill_rtcp_header(tcp_header, buffers, total_bytes, logical_port); { asio::error_code ec; size_t sent = channel->send( (octet*)&tcp_header, static_cast(TCPHeader::size()), - send_buffer, - send_buffer_size, + buffers, + total_bytes, ec); - if (sent != static_cast(TCPHeader::size() + send_buffer_size) || ec) + if (sent != static_cast(TCPHeader::size() + total_bytes) || ec) { EPROSIMA_LOG_WARNING(DEBUG, "Failed to send RTCP message (" << sent << " of " << - TCPHeader::size() + send_buffer_size << " b): " << ec.message()); + TCPHeader::size() + total_bytes << " b): " << ec.message()); success = false; } else diff --git a/src/cpp/rtps/transport/TCPTransportInterface.h b/src/cpp/rtps/transport/TCPTransportInterface.h index 7a1143d37c4..6f95c4d874e 100644 --- a/src/cpp/rtps/transport/TCPTransportInterface.h +++ b/src/cpp/rtps/transport/TCPTransportInterface.h @@ -143,13 +143,12 @@ class TCPTransportInterface : public TransportInterface void calculate_crc( TCPHeader& header, - const fastrtps::rtps::octet* data, - uint32_t size) const; + const std::vector& buffers) const; void fill_rtcp_header( TCPHeader& header, - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, uint16_t logical_port) const; //! Closes the given p_channel_resource and unbind it from every resource. @@ -225,8 +224,8 @@ class TCPTransportInterface : public TransportInterface * There must exist a channel bound to the locator, otherwise the send will be skipped. */ bool send( - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, const eprosima::fastrtps::rtps::Locator_t& locator, const Locator& remote_locator); @@ -389,9 +388,9 @@ class TCPTransportInterface : public TransportInterface Locator& remote_locator); /** - * Blocking Send through the channel inside channel_resources_ matching the locator provided. - * @param send_buffer Slice into the raw data to send. - * @param send_buffer_size Size of the raw data. It will be used as a bounds check for the previous argument. + * Blocking Send through the specified channel. + * @param buffers Vector of buffers to send. + * @param total_bytes Total amount of bytes to send. It will be used as a bounds check for the previous argument. * It must not exceed the send_buffer_size fed to this class during construction. * @param locator Physical locator we're sending to. * @param destination_locators_begin pointer to destination locators iterator begin, the iterator can be advanced inside this fuction @@ -400,8 +399,8 @@ class TCPTransportInterface : public TransportInterface * so should not be reuse. */ bool send( - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, const fastrtps::rtps::Locator_t& locator, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end); diff --git a/src/cpp/rtps/transport/UDPSenderResource.hpp b/src/cpp/rtps/transport/UDPSenderResource.hpp index 5d6211d3324..4c960581955 100644 --- a/src/cpp/rtps/transport/UDPSenderResource.hpp +++ b/src/cpp/rtps/transport/UDPSenderResource.hpp @@ -46,14 +46,14 @@ class UDPSenderResource : public fastrtps::rtps::SenderResource transport.SenderResourceHasBeenClosed(socket_); }; - send_lambda_ = [this, &transport]( - const fastrtps::rtps::octet* data, - uint32_t dataSize, + send_buffers_lambda_ = [this, &transport]( + const std::vector& buffers, + uint32_t total_bytes, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point& max_blocking_time_point) -> bool { - return transport.send(data, dataSize, socket_, destination_locators_begin, + return transport.send(buffers, total_bytes, socket_, destination_locators_begin, destination_locators_end, only_multicast_purpose_, whitelisted_, max_blocking_time_point); }; diff --git a/src/cpp/rtps/transport/UDPTransportInterface.cpp b/src/cpp/rtps/transport/UDPTransportInterface.cpp index 90bfcd32d4a..0ec478b2f48 100644 --- a/src/cpp/rtps/transport/UDPTransportInterface.cpp +++ b/src/cpp/rtps/transport/UDPTransportInterface.cpp @@ -493,8 +493,8 @@ bool UDPTransportInterface::transform_remote_locator( } bool UDPTransportInterface::send( - const octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, eProsimaUDPSocket& socket, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, @@ -513,8 +513,8 @@ bool UDPTransportInterface::send( { if (IsLocatorSupported(*it)) { - ret &= send(send_buffer, - send_buffer_size, + ret &= send(buffers, + total_bytes, socket, *it, only_multicast_purpose, @@ -529,8 +529,8 @@ bool UDPTransportInterface::send( } bool UDPTransportInterface::send( - const octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, eProsimaUDPSocket& socket, const Locator& remote_locator, bool only_multicast_purpose, @@ -539,7 +539,7 @@ bool UDPTransportInterface::send( { using namespace eprosima::fastdds::statistics::rtps; - if (send_buffer_size > configuration()->sendBufferSize) + if (total_bytes > configuration()->sendBufferSize) { return false; } @@ -571,9 +571,9 @@ bool UDPTransportInterface::send( #endif // ifndef _WIN32 asio::error_code ec; - statistics_info_.set_statistics_message_data(remote_locator, send_buffer, send_buffer_size); - bytesSent = getSocketPtr(socket)->send_to(asio::buffer(send_buffer, - send_buffer_size), destinationEndpoint, 0, ec); + // Statistics submessage is always the last buffer to be added + statistics_info_.set_statistics_message_data(remote_locator, buffers.back(), total_bytes); + bytesSent = getSocketPtr(socket)->send_to(buffers, destinationEndpoint, 0, ec); if (!!ec) { if ((ec.value() == asio::error::would_block) || diff --git a/src/cpp/rtps/transport/UDPTransportInterface.h b/src/cpp/rtps/transport/UDPTransportInterface.h index f70b30b0f22..669f967b8ec 100644 --- a/src/cpp/rtps/transport/UDPTransportInterface.h +++ b/src/cpp/rtps/transport/UDPTransportInterface.h @@ -111,8 +111,8 @@ class UDPTransportInterface : public TransportInterface * Blocking Send through the specified channel. In both modes, using a localLocator of 0.0.0.0 will * send through all whitelisted interfaces provided the channel is open. * - * @param send_buffer Slice into the raw data to send. - * @param send_buffer_size Size of the raw data. It will be used as a bounds check for the previous argument. + * @param buffers Vector of buffers to send. + * @param total_bytes Total amount of bytes to send. It will be used as a bounds check for the previous argument. * It must not exceed the send_buffer_size fed to this class during construction. * @param socket channel we're sending from. * @param destination_locators_begin pointer to destination locators iterator begin, the iterator can be advanced inside this fuction @@ -126,8 +126,8 @@ class UDPTransportInterface : public TransportInterface * @pre Open the output channel of each remote locator by invoking \ref OpenOutputChannel function. */ virtual bool send( - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, eProsimaUDPSocket& socket, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, @@ -281,11 +281,11 @@ class UDPTransportInterface : public TransportInterface const std::string&) = 0; /** - * Send a buffer to a destination + * Send a Vector of buffers to a destination */ bool send( - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, eProsimaUDPSocket& socket, const Locator& remote_locator, bool only_multicast_purpose, diff --git a/src/cpp/rtps/transport/shared_mem/SharedMemSenderResource.hpp b/src/cpp/rtps/transport/shared_mem/SharedMemSenderResource.hpp index 48ea3fbd3a7..269c6f7b6a1 100644 --- a/src/cpp/rtps/transport/shared_mem/SharedMemSenderResource.hpp +++ b/src/cpp/rtps/transport/shared_mem/SharedMemSenderResource.hpp @@ -38,14 +38,14 @@ class SharedMemSenderResource : public fastrtps::rtps::SenderResource // No cleanup is required }; - send_lambda_ = [&transport]( - const fastrtps::rtps::octet* data, - uint32_t dataSize, + send_buffers_lambda_ = [&transport]( + const std::vector& buffers, + uint32_t total_bytes, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point& max_blocking_time_point) -> bool { - return transport.send(data, dataSize, destination_locators_begin, destination_locators_end, + return transport.send(buffers, total_bytes, destination_locators_begin, destination_locators_end, max_blocking_time_point); }; diff --git a/src/cpp/rtps/transport/shared_mem/SharedMemTransport.cpp b/src/cpp/rtps/transport/shared_mem/SharedMemTransport.cpp index a65523a1939..4c670797d09 100644 --- a/src/cpp/rtps/transport/shared_mem/SharedMemTransport.cpp +++ b/src/cpp/rtps/transport/shared_mem/SharedMemTransport.cpp @@ -418,23 +418,36 @@ bool SharedMemTransport::transform_remote_locator( } std::shared_ptr SharedMemTransport::copy_to_shared_buffer( - const octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, const std::chrono::steady_clock::time_point& max_blocking_time_point) { + using namespace eprosima::fastdds::statistics::rtps; + assert(shared_mem_segment_); std::shared_ptr shared_buffer = - shared_mem_segment_->alloc_buffer(send_buffer_size, max_blocking_time_point); + shared_mem_segment_->alloc_buffer(total_bytes, max_blocking_time_point); + uint8_t* pos = static_cast(shared_buffer->data()); + + // Statistics submessage is always the last buffer to be added + // If statistics message is present, skip last buffer + auto it_end = remove_statistics_buffer(buffers.back(), total_bytes) ? std::prev(buffers.end()) : buffers.end(); - memcpy(shared_buffer->data(), send_buffer, send_buffer_size); + + for (auto it = buffers.begin(); it != it_end; ++it) + { + // Direct copy from the const_buffer to the mutable shared_buffer + memcpy(pos, (it->buffer), it->size); + pos += it->size; + } return shared_buffer; } bool SharedMemTransport::send( - const octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point& max_blocking_time_point) @@ -460,8 +473,7 @@ bool SharedMemTransport::send( // Only copy the first time if (shared_buffer == nullptr) { - remove_statistics_submessage(send_buffer, send_buffer_size); - shared_buffer = copy_to_shared_buffer(send_buffer, send_buffer_size, max_blocking_time_point); + shared_buffer = copy_to_shared_buffer(buffers, total_bytes, max_blocking_time_point); } ret &= send(shared_buffer, *it); diff --git a/src/cpp/rtps/transport/shared_mem/SharedMemTransport.h b/src/cpp/rtps/transport/shared_mem/SharedMemTransport.h index f1262aba62d..e96c406160a 100644 --- a/src/cpp/rtps/transport/shared_mem/SharedMemTransport.h +++ b/src/cpp/rtps/transport/shared_mem/SharedMemTransport.h @@ -22,6 +22,7 @@ #include #include +#include namespace eprosima { namespace fastdds { @@ -145,17 +146,17 @@ class SharedMemTransport : public TransportInterface /** * Blocking Send through the specified channel. In both modes, using a localLocator of 0.0.0.0 will * send through all whitelisted interfaces provided the channel is open. - * @param send_buffer Slice into the raw data to send. - * @param send_buffer_size Size of the raw data. It will be used as a bounds check for the previous argument. - * It must not exceed the send_buffer_size fed to this class during construction. + * @param buffers Vector of buffers to send. + * @param send_buffer_size Total amount of bytes to send. It will be used as a bounds check for the previous + * argument. It must not exceed the send_buffer_size fed to this class during construction. * @param socket channel we're sending from. * @param remote_locator Locator describing the remote destination we're sending to. * @param only_multicast_purpose * @param timeout Maximum time this function will block */ virtual bool send( - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point& max_blocking_time_point); @@ -247,9 +248,15 @@ class SharedMemTransport : public TransportInterface private: + /** + * Copies a Vector of buffers into the shared_buffer. + * @param buffers Vector of buffers to copy. + * @param total_bytes Total amount of bytes of the whole list of buffers. + * @param max_blocking_time_point Maximum time this function will block. + */ std::shared_ptr copy_to_shared_buffer( - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + const uint32_t total_bytes, const std::chrono::steady_clock::time_point& max_blocking_time_point); bool send( diff --git a/src/cpp/rtps/transport/shared_mem/test_SharedMemTransport.cpp b/src/cpp/rtps/transport/shared_mem/test_SharedMemTransport.cpp index 104a61b2c4c..651295ff530 100644 --- a/src/cpp/rtps/transport/shared_mem/test_SharedMemTransport.cpp +++ b/src/cpp/rtps/transport/shared_mem/test_SharedMemTransport.cpp @@ -49,18 +49,18 @@ TransportInterface* test_SharedMemTransportDescriptor::create_transport() const } bool test_SharedMemTransport::send( - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point& max_blocking_time_point) { - if (send_buffer_size >= big_buffer_size_) + if (total_bytes >= big_buffer_size_) { (*big_buffer_size_send_count_)++; } - return SharedMemTransport::send(send_buffer, send_buffer_size, destination_locators_begin, + return SharedMemTransport::send(buffers, total_bytes, destination_locators_begin, destination_locators_end, max_blocking_time_point); } diff --git a/src/cpp/rtps/transport/shared_mem/test_SharedMemTransport.h b/src/cpp/rtps/transport/shared_mem/test_SharedMemTransport.h index 1188d0f112b..1eb9f35580e 100644 --- a/src/cpp/rtps/transport/shared_mem/test_SharedMemTransport.h +++ b/src/cpp/rtps/transport/shared_mem/test_SharedMemTransport.h @@ -30,8 +30,8 @@ class test_SharedMemTransport : public SharedMemTransport const test_SharedMemTransportDescriptor&); bool send( - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point& max_blocking_time_point) override; diff --git a/src/cpp/rtps/transport/test_UDPv4Transport.cpp b/src/cpp/rtps/transport/test_UDPv4Transport.cpp index fb008ff565a..4254540b0c7 100644 --- a/src/cpp/rtps/transport/test_UDPv4Transport.cpp +++ b/src/cpp/rtps/transport/test_UDPv4Transport.cpp @@ -204,8 +204,8 @@ LocatorList test_UDPv4Transport::NormalizeLocator( } bool test_UDPv4Transport::send( - const octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, eProsimaUDPSocket& socket, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, @@ -229,8 +229,8 @@ bool test_UDPv4Transport::send( if (now < max_blocking_time_point) { - ret &= send(send_buffer, - send_buffer_size, + ret &= send(buffers, + total_bytes, socket, *it, only_multicast_purpose, @@ -250,8 +250,8 @@ bool test_UDPv4Transport::send( } bool test_UDPv4Transport::send( - const octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, eProsimaUDPSocket& socket, const Locator& remote_locator, bool only_multicast_purpose, @@ -261,15 +261,15 @@ bool test_UDPv4Transport::send( bool is_multicast_remote_address = fastrtps::rtps::IPLocator::IPLocator::isMulticast(remote_locator); if (is_multicast_remote_address == only_multicast_purpose || whitelisted) { - if (packet_should_drop(send_buffer, send_buffer_size) || should_drop_locator(remote_locator)) + if (packet_should_drop(buffers, total_bytes) || should_drop_locator(remote_locator)) { - statistics_info_.set_statistics_message_data(remote_locator, send_buffer, send_buffer_size); - log_drop(send_buffer, send_buffer_size); + statistics_info_.set_statistics_message_data(remote_locator, buffers.back(), total_bytes); + log_drop(buffers, total_bytes); return true; } else { - return UDPv4Transport::send(send_buffer, send_buffer_size, socket, remote_locator, only_multicast_purpose, + return UDPv4Transport::send(buffers, total_bytes, socket, remote_locator, only_multicast_purpose, whitelisted, timeout); } } @@ -323,17 +323,24 @@ bool test_UDPv4Transport::should_drop_locator( } bool test_UDPv4Transport::packet_should_drop( - const octet* send_buffer, - uint32_t send_buffer_size) + const std::vector& buffers, + uint32_t total_bytes) { if (test_UDPv4Transport_ShutdownAllNetwork) { return true; } - CDRMessage_t cdrMessage(0); - cdrMessage.init(const_cast(send_buffer), send_buffer_size); - cdrMessage.length = send_buffer_size; + // Reconstruction of the CDRMessage_t + CDRMessage_t cdrMessage(total_bytes); + size_t n_bytes = 0; + for (auto it = buffers.begin(); it != buffers.end(); ++it) + { + memcpy(&cdrMessage.buffer[n_bytes], it->buffer, it->size); + n_bytes += it->size; + } + assert(total_bytes == n_bytes); + cdrMessage.length = total_bytes; if (cdrMessage.length < RTPSMESSAGE_HEADER_SIZE) { @@ -521,13 +528,19 @@ bool test_UDPv4Transport::packet_should_drop( } bool test_UDPv4Transport::log_drop( - const octet* buffer, + const std::vector& buffers, uint32_t size) { + static_cast(size); if (test_UDPv4Transport_DropLog.size() < test_UDPv4Transport_DropLogLength) { vector message; - message.assign(buffer, buffer + size); + for (const auto& buf: buffers) + { + auto byte_data = static_cast(buf.buffer); + message.insert(message.end(), byte_data, byte_data + buf.size); + } + assert(message.size() == size); test_UDPv4Transport_DropLog.push_back(message); return true; } diff --git a/src/cpp/rtps/transport/test_UDPv4Transport.h b/src/cpp/rtps/transport/test_UDPv4Transport.h index b4a3511fbeb..b924fb6d48a 100644 --- a/src/cpp/rtps/transport/test_UDPv4Transport.h +++ b/src/cpp/rtps/transport/test_UDPv4Transport.h @@ -41,8 +41,8 @@ class test_UDPv4Transport : public UDPv4Transport const test_UDPv4TransportDescriptor& descriptor); virtual bool send( - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& send_buffer, + uint32_t total_bytes, eProsimaUDPSocket& socket, fastrtps::rtps::LocatorsIterator* destination_locators_begin, fastrtps::rtps::LocatorsIterator* destination_locators_end, @@ -111,18 +111,18 @@ class test_UDPv4Transport : public UDPv4Transport const Locator& remote_locator); bool log_drop( - const fastrtps::rtps::octet* buffer, + const std::vector& buffer, uint32_t size); bool packet_should_drop( - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size); + const std::vector& buffers, + uint32_t total_bytes); bool random_chance_drop(); bool should_be_dropped( PercentageData* percentage); bool send( - const fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& send_buffer, + uint32_t total_bytes, eProsimaUDPSocket& socket, const Locator& remote_locator, bool only_multicast_purpose, diff --git a/src/cpp/rtps/writer/LocatorSelectorSender.cpp b/src/cpp/rtps/writer/LocatorSelectorSender.cpp index 9ef1d310eac..ab585939357 100644 --- a/src/cpp/rtps/writer/LocatorSelectorSender.cpp +++ b/src/cpp/rtps/writer/LocatorSelectorSender.cpp @@ -6,10 +6,11 @@ namespace fastrtps { namespace rtps { bool LocatorSelectorSender::send( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, std::chrono::steady_clock::time_point max_blocking_time_point) const { - return writer_.send_nts(message, *this, max_blocking_time_point); + return writer_.send_nts(buffers, total_bytes, *this, max_blocking_time_point); } } // namespace rtps diff --git a/src/cpp/rtps/writer/RTPSWriter.cpp b/src/cpp/rtps/writer/RTPSWriter.cpp index 3d982403b5e..0a0fd75a4cc 100644 --- a/src/cpp/rtps/writer/RTPSWriter.cpp +++ b/src/cpp/rtps/writer/RTPSWriter.cpp @@ -449,14 +449,15 @@ bool RTPSWriter::is_pool_initialized() const } bool RTPSWriter::send_nts( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, const LocatorSelectorSender& locator_selector, std::chrono::steady_clock::time_point& max_blocking_time_point) const { RTPSParticipantImpl* participant = getRTPSParticipant(); return locator_selector.locator_selector.selected_size() == 0 || - participant->sendSync(message, m_guid, locator_selector.locator_selector.begin(), + participant->sendSync(buffers, total_bytes, m_guid, locator_selector.locator_selector.begin(), locator_selector.locator_selector.end(), max_blocking_time_point); } diff --git a/src/cpp/rtps/writer/ReaderLocator.cpp b/src/cpp/rtps/writer/ReaderLocator.cpp index b46b783d213..4db19a6e0bf 100644 --- a/src/cpp/rtps/writer/ReaderLocator.cpp +++ b/src/cpp/rtps/writer/ReaderLocator.cpp @@ -182,21 +182,22 @@ void ReaderLocator::stop() } bool ReaderLocator::send( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, std::chrono::steady_clock::time_point max_blocking_time_point) const { if (general_locator_info_.remote_guid != c_Guid_Unknown && !is_local_reader_) { if (general_locator_info_.unicast.size() > 0) { - return participant_owner_->sendSync(message, owner_->getGuid(), + return participant_owner_->sendSync(buffers, total_bytes, owner_->getGuid(), Locators(general_locator_info_.unicast.begin()), Locators( general_locator_info_.unicast.end()), max_blocking_time_point); } else { - return participant_owner_->sendSync(message, owner_->getGuid(), + return participant_owner_->sendSync(buffers, total_bytes, owner_->getGuid(), Locators(general_locator_info_.multicast.begin()), Locators(general_locator_info_.multicast.end()), max_blocking_time_point); diff --git a/src/cpp/rtps/writer/ReaderLocator.hpp b/src/cpp/rtps/writer/ReaderLocator.hpp index a86007828a8..e315b99dc26 100644 --- a/src/cpp/rtps/writer/ReaderLocator.hpp +++ b/src/cpp/rtps/writer/ReaderLocator.hpp @@ -182,11 +182,13 @@ class ReaderLocator : public RTPSMessageSenderInterface /** * Send a message through this interface. * - * @param message Pointer to the buffer with the message already serialized. + * @param buffers Vector of NetworkBuffers to send with data already serialized. + * @param total_bytes Total number of bytes to send. Should be equal to the sum of the @c size field of all buffers. * @param max_blocking_time_point Future timepoint where blocking send should end. */ bool send( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, std::chrono::steady_clock::time_point max_blocking_time_point) const override; /** diff --git a/src/cpp/rtps/writer/StatelessWriter.cpp b/src/cpp/rtps/writer/StatelessWriter.cpp index 81e16a538e2..29d1ccfa981 100644 --- a/src/cpp/rtps/writer/StatelessWriter.cpp +++ b/src/cpp/rtps/writer/StatelessWriter.cpp @@ -713,17 +713,18 @@ void StatelessWriter::unsent_changes_reset() } bool StatelessWriter::send_nts( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, const LocatorSelectorSender& locator_selector, std::chrono::steady_clock::time_point& max_blocking_time_point) const { - if (!RTPSWriter::send_nts(message, locator_selector, max_blocking_time_point)) + if (!RTPSWriter::send_nts(buffers, total_bytes, locator_selector, max_blocking_time_point)) { return false; } return fixed_locators_.empty() || - mp_RTPSParticipant->sendSync(message, m_guid, + mp_RTPSParticipant->sendSync(buffers, total_bytes, m_guid, Locators(fixed_locators_.begin()), Locators(fixed_locators_.end()), max_blocking_time_point); } diff --git a/src/cpp/rtps/writer/StatelessWriter.hpp b/src/cpp/rtps/writer/StatelessWriter.hpp index 7944a6952be..65d1df71e48 100644 --- a/src/cpp/rtps/writer/StatelessWriter.hpp +++ b/src/cpp/rtps/writer/StatelessWriter.hpp @@ -21,9 +21,9 @@ #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC #include -#include #include #include +#include #include #include @@ -194,13 +194,15 @@ class StatelessWriter : public RTPSWriter /** * Send a message through this interface. * - * @param message Pointer to the buffer with the message already serialized. + * @param buffers Vector of NetworkBuffers to send with data already serialized. + * @param total_bytes Total number of bytes to send. Should be equal to the sum of the @c size field of all buffers. * @param locator_selector RTPSMessageSenderInterface reference uses for selecting locators. The reference has to * be a member of this RTPSWriter object. * @param max_blocking_time_point Future timepoint where blocking send should end. */ bool send_nts( - CDRMessage_t* message, + const std::vector& buffers, + const uint32_t& total_bytes, const LocatorSelectorSender& locator_selector, std::chrono::steady_clock::time_point& max_blocking_time_point) const override; diff --git a/src/cpp/statistics/rtps/messages/OutputTrafficManager.hpp b/src/cpp/statistics/rtps/messages/OutputTrafficManager.hpp index fa557b8c589..220bdce41e7 100644 --- a/src/cpp/statistics/rtps/messages/OutputTrafficManager.hpp +++ b/src/cpp/statistics/rtps/messages/OutputTrafficManager.hpp @@ -70,12 +70,12 @@ class OutputTrafficManager */ inline void set_statistics_message_data( const eprosima::fastrtps::rtps::Locator_t& locator, - const eprosima::fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size) + const eprosima::fastdds::rtps::NetworkBuffer& send_buffer, + const uint32_t& total_bytes) { static_cast(locator); static_cast(send_buffer); - static_cast(send_buffer_size); + static_cast(total_bytes); #ifdef FASTDDS_STATISTICS auto search = [locator](const entry_type& entry) -> bool @@ -84,7 +84,7 @@ class OutputTrafficManager }; auto it = std::find_if(collection_.begin(), collection_.end(), search); assert(it != collection_.end()); - set_statistics_submessage_from_transport(locator, send_buffer, send_buffer_size, it->second); + set_statistics_submessage_from_transport(locator, send_buffer, total_bytes, it->second); #endif // FASTDDS_STATISTICS } diff --git a/src/cpp/statistics/rtps/messages/RTPSStatisticsMessages.hpp b/src/cpp/statistics/rtps/messages/RTPSStatisticsMessages.hpp index d17ac8fe1d8..28fb200b5d7 100644 --- a/src/cpp/statistics/rtps/messages/RTPSStatisticsMessages.hpp +++ b/src/cpp/statistics/rtps/messages/RTPSStatisticsMessages.hpp @@ -168,34 +168,42 @@ inline uint32_t get_statistics_message_pos( return statistics_pos; } +inline bool is_statistics_buffer( + const eprosima::fastdds::rtps::NetworkBuffer& stat_buffer) +{ + return statistics_submessage_length == stat_buffer.size && + FASTDDS_STATISTICS_NETWORK_SUBMESSAGE == + static_cast(stat_buffer.buffer)[0]; +} + #endif // FASTDDS_STATISTICS inline void set_statistics_submessage_from_transport( const eprosima::fastrtps::rtps::Locator_t& destination, - const eprosima::fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const eprosima::fastdds::rtps::NetworkBuffer& send_buffer, + const uint32_t& total_bytes, StatisticsSubmessageData::Sequence& sequence) { static_cast(destination); static_cast(send_buffer); - static_cast(send_buffer_size); + static_cast(total_bytes); static_cast(sequence); #ifdef FASTDDS_STATISTICS using namespace eprosima::fastrtps::rtps; - uint32_t statistics_pos = get_statistics_message_pos(send_buffer, send_buffer_size); - - if ( 0 != statistics_pos ) + if (is_statistics_buffer(send_buffer)) { + uint32_t statistics_pos = 0; + // Accumulate bytes on sequence - sequence.add_message(send_buffer_size); + sequence.add_message(total_bytes); // Skip the submessage header statistics_pos += RTPSMESSAGE_SUBMESSAGEHEADER_SIZE; // Set current timestamp and sequence - auto current_pos = &send_buffer[statistics_pos]; + auto current_pos = &static_cast(send_buffer.buffer)[statistics_pos]; Time_t ts; Time_t::now(ts); @@ -219,20 +227,21 @@ inline void set_statistics_submessage_from_transport( #endif // FASTDDS_STATISTICS } -inline void remove_statistics_submessage( - const eprosima::fastrtps::rtps::octet* send_buffer, - uint32_t& send_buffer_size) +inline bool remove_statistics_buffer( + const eprosima::fastdds::rtps::NetworkBuffer& stat_buffer, + uint32_t& total_bytes) { - static_cast(send_buffer); - static_cast(send_buffer_size); + static_cast(stat_buffer); + static_cast(total_bytes); #ifdef FASTDDS_STATISTICS - uint32_t statistics_pos = get_statistics_message_pos(send_buffer, send_buffer_size); - if ( 0 != statistics_pos ) + if (is_statistics_buffer(stat_buffer)) { - send_buffer_size = statistics_pos; + total_bytes -= statistics_submessage_length; + return true; } #endif // FASTDDS_STATISTICS + return false; } } // namespace rtps diff --git a/src/cpp/xmlparser/XMLElementParser.cpp b/src/cpp/xmlparser/XMLElementParser.cpp index bccbc06e047..dc6b16624f5 100644 --- a/src/cpp/xmlparser/XMLElementParser.cpp +++ b/src/cpp/xmlparser/XMLElementParser.cpp @@ -347,6 +347,7 @@ XMLP_ret XMLParser::getXMLSendBuffersAllocationAttributes( + */ @@ -376,6 +377,14 @@ XMLP_ret XMLParser::getXMLSendBuffersAllocationAttributes( } allocation.dynamic = tmp_bool; } + else if (strcmp(name, NETWORK_BUFFERS_CONFIG) == 0) + { + // preallocated_network_buffers - uint32Type + if (XMLP_ret::XML_OK != getXMLContainerAllocationConfig(p_aux0, allocation.network_buffers_config, ident)) + { + return XMLP_ret::XML_ERROR; + } + } else { EPROSIMA_LOG_ERROR(XMLPARSER, diff --git a/src/cpp/xmlparser/XMLParserCommon.cpp b/src/cpp/xmlparser/XMLParserCommon.cpp index 5a7444f4374..107da2f9067 100644 --- a/src/cpp/xmlparser/XMLParserCommon.cpp +++ b/src/cpp/xmlparser/XMLParserCommon.cpp @@ -141,6 +141,7 @@ const char* TOTAL_WRITERS = "total_writers"; const char* SEND_BUFFERS = "send_buffers"; const char* PREALLOCATED_NUMBER = "preallocated_number"; const char* DYNAMIC_LC = "dynamic"; +const char* NETWORK_BUFFERS_CONFIG = "network_buffers_config"; const char* MAX_PROPERTIES = "max_properties"; const char* MAX_USER_DATA = "max_user_data"; const char* MAX_PARTITIONS = "max_partitions"; diff --git a/src/cpp/xmlparser/XMLParserCommon.h b/src/cpp/xmlparser/XMLParserCommon.h index 360b36712ba..d3e31030f95 100644 --- a/src/cpp/xmlparser/XMLParserCommon.h +++ b/src/cpp/xmlparser/XMLParserCommon.h @@ -157,6 +157,7 @@ extern const char* TOTAL_WRITERS; extern const char* SEND_BUFFERS; extern const char* PREALLOCATED_NUMBER; extern const char* DYNAMIC_LC; +extern const char* NETWORK_BUFFERS_CONFIG; extern const char* MAX_PROPERTIES; extern const char* MAX_USER_DATA; extern const char* MAX_PARTITIONS; diff --git a/test/blackbox/common/BlackboxTestsTransportCustom.cpp b/test/blackbox/common/BlackboxTestsTransportCustom.cpp index f0ebca33fcf..f9be8625886 100644 --- a/test/blackbox/common/BlackboxTestsTransportCustom.cpp +++ b/test/blackbox/common/BlackboxTestsTransportCustom.cpp @@ -22,12 +22,14 @@ #include #include #include +#include #include "PubSubReader.hpp" #include "PubSubWriter.hpp" using BuiltinTransports = eprosima::fastdds::rtps::BuiltinTransports; using BuiltinTransportsOptions = eprosima::fastdds::rtps::BuiltinTransportsOptions; +using NetworkBuffer = eprosima::fastdds::rtps::NetworkBuffer; class TestChainingTransportDescriptor : public eprosima::fastdds::rtps::ChainingTransportDescriptor { @@ -82,8 +84,8 @@ class TestChainingTransport : public eprosima::fastdds::rtps::ChainingTransport bool send( eprosima::fastrtps::rtps::SenderResource* low_sender_resource, - const eprosima::fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, eprosima::fastrtps::rtps::LocatorsIterator* destination_locators_begin, eprosima::fastrtps::rtps::LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point& timeout) override @@ -91,7 +93,7 @@ class TestChainingTransport : public eprosima::fastdds::rtps::ChainingTransport descriptor_.send_function_called(); // Call low level transport - return low_sender_resource->send(send_buffer, send_buffer_size, destination_locators_begin, + return low_sender_resource->send(buffers, total_bytes, destination_locators_begin, destination_locators_end, timeout); } diff --git a/test/blackbox/common/DDSBlackboxTestsBasic.cpp b/test/blackbox/common/DDSBlackboxTestsBasic.cpp index 3fb378fde8d..c0b7a49af52 100644 --- a/test/blackbox/common/DDSBlackboxTestsBasic.cpp +++ b/test/blackbox/common/DDSBlackboxTestsBasic.cpp @@ -797,9 +797,15 @@ TEST(DDSBasic, endpoint_custom_payload_pools) std::this_thread::sleep_for(std::chrono::seconds(2)); - // Two consecutive calls to get_payload are expected + // There are 4 calls to get_payload, two for the reader and two for the writer: + // 1. Reader: + // a. The first time the payload allocated in stack is processed (no payload_owner) + // b. Payload used to add the change in reception ASSERT_EQ(reader_payload_pool->requested_payload_count, 2u); - ASSERT_EQ(writer_payload_pool->requested_payload_count, 1u); + // 2. Writer: + // a. Payload requested to the pool when creating the change + // b. Extra call using gather-send to avoid releasing the payload that contains the data before sending it + ASSERT_EQ(writer_payload_pool->requested_payload_count, 2u); participant->delete_contained_entities(); } diff --git a/test/blackbox/common/DatagramInjectionTransport.hpp b/test/blackbox/common/DatagramInjectionTransport.hpp index 03ca287ad61..9ef719f28c8 100644 --- a/test/blackbox/common/DatagramInjectionTransport.hpp +++ b/test/blackbox/common/DatagramInjectionTransport.hpp @@ -72,13 +72,13 @@ class DatagramInjectionTransport : public ChainingTransport bool send( eprosima::fastrtps::rtps::SenderResource* low_sender_resource, - const eprosima::fastrtps::rtps::octet* send_buffer, - uint32_t send_buffer_size, + const std::vector& buffers, + uint32_t total_bytes, eprosima::fastrtps::rtps::LocatorsIterator* destination_locators_begin, eprosima::fastrtps::rtps::LocatorsIterator* destination_locators_end, const std::chrono::steady_clock::time_point& timeout) override { - return low_sender_resource->send(send_buffer, send_buffer_size, destination_locators_begin, + return low_sender_resource->send(buffers, total_bytes, destination_locators_begin, destination_locators_end, timeout); } diff --git a/test/mock/rtps/RTPSWriter/fastdds/rtps/writer/RTPSWriter.h b/test/mock/rtps/RTPSWriter/fastdds/rtps/writer/RTPSWriter.h index 8df4be32e50..e8418c45a44 100644 --- a/test/mock/rtps/RTPSWriter/fastdds/rtps/writer/RTPSWriter.h +++ b/test/mock/rtps/RTPSWriter/fastdds/rtps/writer/RTPSWriter.h @@ -20,6 +20,7 @@ #define _FASTDDS_RTPS_RTPSWRITER_H_ #include +#include #include @@ -151,8 +152,9 @@ class RTPSWriter : public Endpoint LocatorSelectorSender&, const std::chrono::time_point&)); - MOCK_METHOD3(send_nts, bool( - CDRMessage_t*, + MOCK_METHOD4(send_nts, bool( + const std::vector&, + const uint32_t&, const LocatorSelectorSender&, std::chrono::steady_clock::time_point&)); diff --git a/test/mock/rtps/ReaderLocator/rtps/writer/ReaderLocator.hpp b/test/mock/rtps/ReaderLocator/rtps/writer/ReaderLocator.hpp index 47dd24847ee..7347b39a32d 100644 --- a/test/mock/rtps/ReaderLocator/rtps/writer/ReaderLocator.hpp +++ b/test/mock/rtps/ReaderLocator/rtps/writer/ReaderLocator.hpp @@ -185,11 +185,13 @@ class ReaderLocator : public RTPSMessageSenderInterface /** * Send a message through this interface. * - * @param message Pointer to the buffer with the message already serialized. + * @param buffers Vector of NetworkBuffers to send with data already serialized. + * @param total_bytes Total number of bytes to send. Should be equal to the sum of the @c size field of all buffers. * @param max_blocking_time_point Future timepoint where blocking send should end. */ bool send( - CDRMessage_t* /*message*/, + const std::vector& /*buffers*/, + const uint32_t& /*total_bytes*/, std::chrono::steady_clock::time_point /*max_blocking_time_point*/) const override { return true; diff --git a/test/mock/rtps/StatefulReader/rtps/reader/StatefulReader.hpp b/test/mock/rtps/StatefulReader/rtps/reader/StatefulReader.hpp index c05f48d269d..b0fa9b97e00 100644 --- a/test/mock/rtps/StatefulReader/rtps/reader/StatefulReader.hpp +++ b/test/mock/rtps/StatefulReader/rtps/reader/StatefulReader.hpp @@ -19,9 +19,12 @@ #ifndef RTPS_READER__STATEFULREADER_HPP #define RTPS_READER__STATEFULREADER_HPP +#include + #include #include #include +#include #include namespace eprosima { @@ -104,7 +107,8 @@ class StatefulReader : public fastdds::rtps::BaseReader MOCK_METHOD0(getEventResource, ResourceEvent & ()); bool send_sync_nts( - CDRMessage_t* /*message*/, + const std::vector& /*buffers*/, + const uint32_t& /*total_bytes*/, const LocatorsIterator& /*destination_locators_begin*/, const LocatorsIterator& /*destination_locators_end*/, std::chrono::steady_clock::time_point& /*max_blocking_time_point*/) diff --git a/test/system/tools/xmlvalidation/XMLTesterExample_profile.xml b/test/system/tools/xmlvalidation/XMLTesterExample_profile.xml index 5188be534d5..5c863fbf277 100644 --- a/test/system/tools/xmlvalidation/XMLTesterExample_profile.xml +++ b/test/system/tools/xmlvalidation/XMLTesterExample_profile.xml @@ -337,6 +337,11 @@ 113 true + + 16 + 0 + 16 + diff --git a/test/system/tools/xmlvalidation/all_profile.xml b/test/system/tools/xmlvalidation/all_profile.xml index 3b9941b6bb3..577e3b09bd5 100644 --- a/test/system/tools/xmlvalidation/all_profile.xml +++ b/test/system/tools/xmlvalidation/all_profile.xml @@ -372,6 +372,11 @@ 113 false + + 16 + 0 + 16 + diff --git a/test/system/tools/xmlvalidation/domainParticipant_profile.xml b/test/system/tools/xmlvalidation/domainParticipant_profile.xml index 54cca85719c..b7bbe2fa7bb 100644 --- a/test/system/tools/xmlvalidation/domainParticipant_profile.xml +++ b/test/system/tools/xmlvalidation/domainParticipant_profile.xml @@ -371,6 +371,11 @@ 127 true + + 16 + 0 + 16 + diff --git a/test/unittest/dds/profiles/test_xml_for_string_profile.xml b/test/unittest/dds/profiles/test_xml_for_string_profile.xml index 689b4c811d9..50fd319b31e 100644 --- a/test/unittest/dds/profiles/test_xml_for_string_profile.xml +++ b/test/unittest/dds/profiles/test_xml_for_string_profile.xml @@ -191,6 +191,11 @@ 127 true + + 16 + 0 + 16 + diff --git a/test/unittest/dds/profiles/test_xml_profile.xml b/test/unittest/dds/profiles/test_xml_profile.xml index c5a59d265a8..bc723d85573 100644 --- a/test/unittest/dds/profiles/test_xml_profile.xml +++ b/test/unittest/dds/profiles/test_xml_profile.xml @@ -27,6 +27,11 @@ 65 true + + 16 + 0 + 16 + @@ -188,6 +193,11 @@ 65 true + + 16 + 0 + 16 + diff --git a/test/unittest/dds/publisher/CMakeLists.txt b/test/unittest/dds/publisher/CMakeLists.txt index d594146c2e2..348eab958bf 100644 --- a/test/unittest/dds/publisher/CMakeLists.txt +++ b/test/unittest/dds/publisher/CMakeLists.txt @@ -129,6 +129,7 @@ set(DATAWRITERTESTS_SOURCE DataWriterTests.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageCreator.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageGroup.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/SendBuffersManager.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/ReceiverResource.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/external_locators.cpp diff --git a/test/unittest/rtps/discovery/CMakeLists.txt b/test/unittest/rtps/discovery/CMakeLists.txt index 84bd42b5ab6..4c88823dad6 100644 --- a/test/unittest/rtps/discovery/CMakeLists.txt +++ b/test/unittest/rtps/discovery/CMakeLists.txt @@ -127,6 +127,7 @@ set(PDPTESTS_SOURCE PDPTests.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/SerializedPayload.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/Time_t.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/flowcontrol/FlowControllerConsts.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/netmask_filter.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/network.cpp diff --git a/test/unittest/rtps/network/CMakeLists.txt b/test/unittest/rtps/network/CMakeLists.txt index 0629dadbed1..e28cf657a75 100644 --- a/test/unittest/rtps/network/CMakeLists.txt +++ b/test/unittest/rtps/network/CMakeLists.txt @@ -24,6 +24,7 @@ set(NETWORKFACTORYTESTS_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/Time_t.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/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/netmask_filter.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/network.cpp diff --git a/test/unittest/rtps/reader/CMakeLists.txt b/test/unittest/rtps/reader/CMakeLists.txt index f613d1431b1..4fc074567ad 100644 --- a/test/unittest/rtps/reader/CMakeLists.txt +++ b/test/unittest/rtps/reader/CMakeLists.txt @@ -225,6 +225,7 @@ set(STATEFUL_READER_TESTS_SOURCE StatefulReaderTests.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageCreator.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageGroup.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/SendBuffersManager.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/ReceiverResource.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/external_locators.cpp diff --git a/test/unittest/statistics/dds/CMakeLists.txt b/test/unittest/statistics/dds/CMakeLists.txt index 8d99bd1e2d8..b08d33f54ec 100644 --- a/test/unittest/statistics/dds/CMakeLists.txt +++ b/test/unittest/statistics/dds/CMakeLists.txt @@ -231,6 +231,7 @@ if (SQLITE3_SUPPORT AND FASTDDS_STATISTICS AND NOT QNX) ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageCreator.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageGroup.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/SendBuffersManager.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/ReceiverResource.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/external_locators.cpp @@ -408,6 +409,7 @@ if (SQLITE3_SUPPORT AND FASTDDS_STATISTICS AND NOT QNX) ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageCreator.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/RTPSMessageGroup.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/SendBuffersManager.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/ReceiverResource.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/external_locators.cpp diff --git a/test/unittest/statistics/rtps/CMakeLists.txt b/test/unittest/statistics/rtps/CMakeLists.txt index 5bcd322a7f3..f0a109ee321 100644 --- a/test/unittest/statistics/rtps/CMakeLists.txt +++ b/test/unittest/statistics/rtps/CMakeLists.txt @@ -79,6 +79,7 @@ set(STATISTICS_RTPS_MONITORSERVICETESTS_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/history/TopicPayloadPool.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/history/TopicPayloadPoolRegistry.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/CDRMessage.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/netmask_filter.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/network.cpp diff --git a/test/unittest/transport/CMakeLists.txt b/test/unittest/transport/CMakeLists.txt index c231ddac502..85570703bc6 100644 --- a/test/unittest/transport/CMakeLists.txt +++ b/test/unittest/transport/CMakeLists.txt @@ -75,6 +75,7 @@ set(UDPV4TESTS_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/SerializedPayload.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/Time_t.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/CDRMessage.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/netmask_filter.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/network.cpp @@ -104,6 +105,7 @@ set(UDPV6TESTS_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/SerializedPayload.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/Time_t.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/CDRMessage.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/netmask_filter.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/network.cpp @@ -137,6 +139,7 @@ set(TCPV4TESTS_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/Time_t.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/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/netmask_filter.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/network.cpp @@ -184,6 +187,7 @@ set(TCPV6TESTS_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/Time_t.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/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/netmask_filter.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/network.cpp @@ -228,6 +232,7 @@ set(SHAREDMEMTESTS_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/LocatorWithMask.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/SerializedPayload.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/Time_t.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkBuffer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/netmask_filter.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/utils/network.cpp diff --git a/test/unittest/transport/SharedMemTests.cpp b/test/unittest/transport/SharedMemTests.cpp index 906d13de8a8..3457ccefcd0 100644 --- a/test/unittest/transport/SharedMemTests.cpp +++ b/test/unittest/transport/SharedMemTests.cpp @@ -742,6 +742,11 @@ TEST_F(SHMTransportTests, send_and_receive_between_ports) ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(unicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } std::function recCallback = [&]() { @@ -758,7 +763,7 @@ TEST_F(SHMTransportTests, send_and_receive_between_ports) Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(message, 5, &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); }; @@ -804,6 +809,11 @@ TEST_F(SHMTransportTests, port_and_segment_overflow_discard) ASSERT_TRUE(transportUnderTest.OpenOutputChannel(send_resource_list, outputChannelLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[4] = { 'H', 'e', 'l', 'l'}; + std::vector buffer_list; + for (size_t i = 0; i < 4; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } LocatorList locator_list; locator_list.push_back(unicastLocator); @@ -814,8 +824,10 @@ TEST_F(SHMTransportTests, port_and_segment_overflow_discard) // Internally the segment is bigger than "my_descriptor.segment_size" so a bigger buffer is tried // to cause segment overflow octet message_big[4096] = { 'H', 'e', 'l', 'l'}; + std::vector buffer_list_big; + buffer_list_big.emplace_back(message_big, 4096); - EXPECT_TRUE(send_resource_list.at(0)->send(message_big, sizeof(message_big), &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list_big, sizeof(message_big), &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -826,7 +838,7 @@ TEST_F(SHMTransportTests, port_and_segment_overflow_discard) Locators locators_end(locator_list.end()); // At least 4 msgs of 4 bytes are allowed - EXPECT_TRUE(send_resource_list.at(0)->send(message, sizeof(message), &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, sizeof(message), &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -844,7 +856,7 @@ TEST_F(SHMTransportTests, port_and_segment_overflow_discard) Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(message, sizeof(message), &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, sizeof(message), &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -853,7 +865,7 @@ TEST_F(SHMTransportTests, port_and_segment_overflow_discard) Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(message, sizeof(message), &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, sizeof(message), &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -2055,6 +2067,11 @@ TEST_F(SHMTransportTests, dump_file) ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(unicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } std::function recCallback = [&]() { @@ -2071,7 +2088,7 @@ TEST_F(SHMTransportTests, dump_file) Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(message, 5, &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(1000)))); }; diff --git a/test/unittest/transport/TCPv4Tests.cpp b/test/unittest/transport/TCPv4Tests.cpp index cc11a5b1d50..37bd6cbb068 100644 --- a/test/unittest/transport/TCPv4Tests.cpp +++ b/test/unittest/transport/TCPv4Tests.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,7 @@ using TCPChannelResourceBasic = eprosima::fastdds::rtps::TCPChannelResourceBasic using TCPHeader = eprosima::fastdds::rtps::TCPHeader; using TCPv4Transport = eprosima::fastdds::rtps::TCPv4Transport; using TCPv4TransportDescriptor = eprosima::fastdds::rtps::TCPv4TransportDescriptor; +using NetworkBuffer = eprosima::fastdds::rtps::NetworkBuffer; #if defined(_WIN32) #define GET_PID _getpid @@ -283,6 +285,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_ports) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -302,7 +309,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_ports) Locators input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -342,7 +349,9 @@ TEST_F(TCPv4Tests, send_is_rejected_if_buffer_size_is_bigger_to_size_specified_i // Then std::vector receiveBufferWrongSize(descriptor.sendBufferSize + 1); - ASSERT_FALSE(send_resource_list.at(0)->send(receiveBufferWrongSize.data(), (uint32_t)receiveBufferWrongSize.size(), + std::vector buffer_list; + buffer_list.emplace_back(receiveBufferWrongSize.data(), (uint32_t)receiveBufferWrongSize.size()); + ASSERT_FALSE(send_resource_list.at(0)->send(buffer_list, (uint32_t)receiveBufferWrongSize.size(), &destination_begin, &destination_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -408,7 +417,12 @@ TEST_F(TCPv4Tests, send_to_wrong_interface) Locators wrong_end(locator_list.end()); std::vector message = { 'H', 'e', 'l', 'l', 'o' }; - ASSERT_FALSE(send_resource_list.at(0)->send(message.data(), (uint32_t)message.size(), &wrong_begin, &wrong_end, + std::vector buffer_list; + for (size_t i = 0; i < message.size(); ++i) + { + buffer_list.emplace_back(&message[i], 1); + } + ASSERT_FALSE(send_resource_list.at(0)->send(buffer_list, (uint32_t)message.size(), &wrong_begin, &wrong_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -438,7 +452,12 @@ TEST_F(TCPv4Tests, send_to_blocked_interface) Locators wrong_end(locator_list.end()); std::vector message = { 'H', 'e', 'l', 'l', 'o' }; - ASSERT_FALSE(send_resource_list.at(0)->send(message.data(), (uint32_t)message.size(), &wrong_begin, &wrong_end, + std::vector buffer_list; + for (size_t i = 0; i < message.size(); ++i) + { + buffer_list.emplace_back(&message[i], 1); + } + ASSERT_FALSE(send_resource_list.at(0)->send(buffer_list, (uint32_t)message.size(), &wrong_begin, &wrong_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -498,6 +517,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_allowed_interfaces_ports) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } bool bOk = false; std::function recCallback = [&]() { @@ -514,7 +538,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_allowed_interfaces_ports) Locators input_end(locator_list.end()); bool sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!bFinish && !sent) { @@ -522,7 +546,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_allowed_interfaces_ports) Locators input_end2(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &input_begin2, &input_end2, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin2, &input_end2, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -606,6 +630,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_allowed_interfaces_ports_by_name) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } bool bOk = false; std::function recCallback = [&]() { @@ -622,7 +651,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_allowed_interfaces_ports_by_name) Locators input_end(locator_list.end()); bool sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!bFinish && !sent) { @@ -630,7 +659,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_allowed_interfaces_ports_by_name) Locators input_end2(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &input_begin2, &input_end2, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin2, &input_end2, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -745,6 +774,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_client_verifies) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -761,7 +795,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_client_verifies) Locators input_end(locator_list.end()); bool sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!sent) { @@ -769,7 +803,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_client_verifies) Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, + send_resource_list.at(0)->send(buffer_list, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -844,6 +878,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_server_verifies) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -860,7 +899,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_server_verifies) Locators input_end(locator_list.end()); bool sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!sent) { @@ -868,7 +907,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_server_verifies) Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, + send_resource_list.at(0)->send(buffer_list, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -946,6 +985,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_both_secure_ports) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -962,7 +1006,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_both_secure_ports) Locators input_end(locator_list.end()); bool sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!sent) { @@ -970,7 +1014,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_both_secure_ports) Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, + send_resource_list.at(0)->send(buffer_list, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -1048,6 +1092,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_both_secure_ports_untrusted) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -1065,7 +1114,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_both_secure_ports_untrusted) Locators input_end(locator_list.end()); bool sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); int count = 0; while (!sent && count < 30) @@ -1074,7 +1123,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_both_secure_ports_untrusted) Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, + send_resource_list.at(0)->send(buffer_list, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); ++count; @@ -1154,6 +1203,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_clients_1) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -1170,7 +1224,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_clients_1) Locators input_end(locator_list.end()); bool sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!sent) { @@ -1178,7 +1232,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_clients_1) Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, + send_resource_list.at(0)->send(buffer_list, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -1253,6 +1307,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_untrusted_server) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -1270,7 +1329,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_untrusted_server) Locators input_end(locator_list.end()); bool sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); int count = 0; while (!sent && count < 30) @@ -1278,7 +1337,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_untrusted_server) Locators l_input_begin(locator_list.begin()); Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, + send_resource_list.at(0)->send(buffer_list, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); ++count; @@ -1363,6 +1422,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_both_secure_ports_with_sni) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -1379,7 +1443,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_both_secure_ports_with_sni) Locators input_end(locator_list.end()); bool sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!sent) { @@ -1387,7 +1451,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_both_secure_ports_with_sni) Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, + send_resource_list.at(0)->send(buffer_list, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -1521,10 +1585,13 @@ TEST_F(TCPv4Tests, secure_non_blocking_send) std::vector message(msg_size * 2, 0); const octet* data = message.data(); size_t size = message.size(); + NetworkBuffer buffers(data, size); + std::vector buffer_list; + buffer_list.push_back(buffers); // Send the message with no header. Since TCP actually allocates twice the size of the buffer requested // it should be able to send a message of msg_size*2. - size_t bytes_sent = sender_channel_resource->send(nullptr, 0, data, size, ec); + size_t bytes_sent = sender_channel_resource->send(nullptr, 0, buffer_list, size, ec); ASSERT_EQ(bytes_sent, size); // Now wait until the receive buffer is flushed (send buffer will be empty too) @@ -1538,7 +1605,9 @@ TEST_F(TCPv4Tests, secure_non_blocking_send) message.resize(msg_size * 2 + 1); data = message.data(); size = message.size(); - bytes_sent = sender_channel_resource->send(nullptr, 0, data, size, ec); + buffer_list.clear(); + buffer_list.emplace_back(data, size); + bytes_sent = sender_channel_resource->send(nullptr, 0, buffer_list, size, ec); ASSERT_EQ(bytes_sent, 0u); secure_socket->lowest_layer().close(ec); @@ -1589,6 +1658,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_allowed_localhost_interfaces_ports) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } bool bOk = false; std::function recCallback = [&]() { @@ -1605,7 +1679,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_allowed_localhost_interfaces_ports) Locators input_end(locator_list.end()); bool sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!bFinish && !sent) { @@ -1613,7 +1687,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_allowed_localhost_interfaces_ports) Locators input_end2(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &input_begin2, &input_end2, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin2, &input_end2, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -1684,6 +1758,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_blocked_interfaces_ports) ASSERT_TRUE(sendTransportUnderTest.OpenOutputChannel(send_resource_list, outputLocator)); ASSERT_FALSE(send_resource_list.empty()); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } bool bOk = false; std::function recCallback = [&]() { @@ -1700,7 +1779,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_blocked_interfaces_ports) Locators input_end(locator_list.end()); bool sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin, &input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!bFinished && !sent) { @@ -1708,7 +1787,7 @@ TEST_F(TCPv4Tests, send_and_receive_between_blocked_interfaces_ports) Locators input_end2(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &input_begin2, &input_end2, + send_resource_list.at(0)->send(buffer_list, 5, &input_begin2, &input_end2, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -2035,10 +2114,13 @@ TEST_F(TCPv4Tests, non_blocking_send) std::vector message(msg_size * 2, 0); const octet* data = message.data(); size_t size = message.size(); + NetworkBuffer buffers(data, size); + std::vector buffer_list; + buffer_list.push_back(buffers); // Send the message with no header. Since TCP actually allocates twice the size of the buffer requested // it should be able to send a message of msg_size*2. - size_t bytes_sent = sender_channel_resource->send(nullptr, 0, data, size, ec); + size_t bytes_sent = sender_channel_resource->send(nullptr, 0, buffer_list, size, ec); ASSERT_EQ(bytes_sent, size); // Now wait until the receive buffer is flushed (send buffer will be empty too) @@ -2050,7 +2132,9 @@ TEST_F(TCPv4Tests, non_blocking_send) message.resize(msg_size * 2 + 1); data = message.data(); size = message.size(); - bytes_sent = sender_channel_resource->send(nullptr, 0, data, size, ec); + buffer_list.clear(); + buffer_list.emplace_back(data, size); + bytes_sent = sender_channel_resource->send(nullptr, 0, buffer_list, size, ec); ASSERT_EQ(bytes_sent, 0u); socket.shutdown(asio::ip::tcp::socket::shutdown_both); diff --git a/test/unittest/transport/TCPv6Tests.cpp b/test/unittest/transport/TCPv6Tests.cpp index ee7f5a7361e..6817382a9f9 100644 --- a/test/unittest/transport/TCPv6Tests.cpp +++ b/test/unittest/transport/TCPv6Tests.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,7 @@ using namespace eprosima::fastrtps::rtps; using namespace eprosima::fastrtps; using TCPv6Transport = eprosima::fastdds::rtps::TCPv6Transport; using TCPv6TransportDescriptor = eprosima::fastdds::rtps::TCPv6TransportDescriptor; +using NetworkBuffer = eprosima::fastdds::rtps::NetworkBuffer; #if defined(_WIN32) #define GET_PID _getpid @@ -442,10 +444,13 @@ TEST_F(TCPv6Tests, non_blocking_send) std::vector message(msg_size * 2, 0); const octet* data = message.data(); size_t size = message.size(); + NetworkBuffer buffers(data, size); + std::vector buffer_list; + buffer_list.push_back(buffers); // Send the message with no header. Since TCP actually allocates twice the size of the buffer requested // it should be able to send a message of msg_size*2. - size_t bytes_sent = sender_channel_resource->send(nullptr, 0, data, size, ec); + size_t bytes_sent = sender_channel_resource->send(nullptr, 0, buffer_list, size, ec); ASSERT_EQ(bytes_sent, size); // Now wait until the receive buffer is flushed (send buffer will be empty too) @@ -457,7 +462,9 @@ TEST_F(TCPv6Tests, non_blocking_send) message.resize(msg_size * 2 + 1); data = message.data(); size = message.size(); - bytes_sent = sender_channel_resource->send(nullptr, 0, data, size, ec); + buffer_list.clear(); + buffer_list.emplace_back(data, size); + bytes_sent = sender_channel_resource->send(nullptr, 0, buffer_list, size, ec); ASSERT_EQ(bytes_sent, 0u); socket.shutdown(asio::ip::tcp::socket::shutdown_both); diff --git a/test/unittest/transport/UDPv4Tests.cpp b/test/unittest/transport/UDPv4Tests.cpp index 54bfc4561ef..88c924750d9 100644 --- a/test/unittest/transport/UDPv4Tests.cpp +++ b/test/unittest/transport/UDPv4Tests.cpp @@ -205,6 +205,11 @@ TEST_F(UDPv4Tests, send_and_receive_between_ports) ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(multicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -225,7 +230,7 @@ TEST_F(UDPv4Tests, send_and_receive_between_ports) { Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - sent |= send_resource->send(message, 5, &locators_begin, &locators_end, + sent |= send_resource->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); if (sent) { @@ -265,6 +270,11 @@ TEST_F(UDPv4Tests, send_to_loopback) ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(multicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -285,7 +295,7 @@ TEST_F(UDPv4Tests, send_to_loopback) { Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - sent |= send_resource->send(message, 5, &locators_begin, &locators_end, + sent |= send_resource->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); if (sent) { @@ -326,7 +336,9 @@ TEST_F(UDPv4Tests, send_is_rejected_if_buffer_size_is_bigger_to_size_specified_i // Then std::vector receiveBufferWrongSize(descriptor.sendBufferSize + 1); - ASSERT_FALSE(send_resource_list.at(0)->send(receiveBufferWrongSize.data(), (uint32_t)receiveBufferWrongSize.size(), + std::vector buffer_list; + buffer_list.emplace_back(receiveBufferWrongSize.data(), (uint32_t)receiveBufferWrongSize.size()); + ASSERT_FALSE(send_resource_list.at(0)->send(buffer_list, (uint32_t)receiveBufferWrongSize.size(), &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -390,8 +402,13 @@ TEST_F(UDPv4Tests, send_to_wrong_interface) Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - std::vector message = { 'H', 'e', 'l', 'l', 'o' }; - ASSERT_FALSE(send_resource_list.at(0)->send(message.data(), (uint32_t)message.size(), &locators_begin, + octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } + ASSERT_FALSE(send_resource_list.at(0)->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -452,8 +469,13 @@ TEST_F(UDPv4Tests, send_to_allowed_interface) Locators locators_end(locator_list.end()); // Sending through a ALLOWED IP will work - std::vector message = { 'H', 'e', 'l', 'l', 'o' }; - ASSERT_TRUE(send_resource_list.at(0)->send(message.data(), (uint32_t)message.size(), + octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } + ASSERT_TRUE(send_resource_list.at(0)->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -505,6 +527,11 @@ TEST_F(UDPv4Tests, send_and_receive_between_allowed_sockets_using_localhost) ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(unicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -520,7 +547,7 @@ TEST_F(UDPv4Tests, send_and_receive_between_allowed_sockets_using_localhost) Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(message, 5, &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); }; @@ -566,6 +593,11 @@ TEST_F(UDPv4Tests, send_and_receive_between_allowed_sockets_using_unicast) ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(unicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -581,7 +613,7 @@ TEST_F(UDPv4Tests, send_and_receive_between_allowed_sockets_using_unicast) Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(message, 5, &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); }; @@ -628,6 +660,12 @@ TEST_F(UDPv4Tests, send_and_receive_between_allowed_sockets_using_unicast_to_mul ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(unicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } + Semaphore sem; std::function recCallback = [&]() @@ -643,7 +681,7 @@ TEST_F(UDPv4Tests, send_and_receive_between_allowed_sockets_using_unicast_to_mul Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(message, 5, &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); }; @@ -720,6 +758,11 @@ TEST_F(UDPv4Tests, simple_throughput) octet sample_data[sample_size]; memset(sample_data, 0, sizeof(sample_data)); + std::vector buffer_list; + for (size_t i = 0; i < sample_size; ++i) + { + buffer_list.emplace_back(&sample_data[i], 1); + } Locator_t sub_locator; sub_locator.kind = LOCATOR_KIND_UDPv4; @@ -761,7 +804,7 @@ TEST_F(UDPv4Tests, simple_throughput) Locators locators_begin(send_locators_list.begin()); Locators locators_end(send_locators_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(sample_data, sizeof(sample_data), &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, sizeof(sample_data), &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::milliseconds(100)))); } diff --git a/test/unittest/transport/UDPv6Tests.cpp b/test/unittest/transport/UDPv6Tests.cpp index 44497c72abb..acb696f3876 100644 --- a/test/unittest/transport/UDPv6Tests.cpp +++ b/test/unittest/transport/UDPv6Tests.cpp @@ -242,6 +242,11 @@ TEST_F(UDPv6Tests, send_and_receive_between_ports) ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(multicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -262,7 +267,7 @@ TEST_F(UDPv6Tests, send_and_receive_between_ports) { Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - sent |= send_resource->send(message, 5, &locators_begin, &locators_end, + sent |= send_resource->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); if (sent) { @@ -302,6 +307,11 @@ TEST_F(UDPv6Tests, send_to_loopback) ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(multicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -322,7 +332,7 @@ TEST_F(UDPv6Tests, send_to_loopback) { Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - sent |= send_resource->send(message, 5, &locators_begin, &locators_end, + sent |= send_resource->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); if (sent) { @@ -363,7 +373,9 @@ TEST_F(UDPv6Tests, send_is_rejected_if_buffer_size_is_bigger_to_size_specified_i // Then std::vector receiveBufferWrongSize(descriptor.sendBufferSize + 1); - ASSERT_FALSE(send_resource_list.at(0)->send(receiveBufferWrongSize.data(), (uint32_t)receiveBufferWrongSize.size(), + std::vector buffer_list; + buffer_list.emplace_back(receiveBufferWrongSize.data(), (uint32_t)receiveBufferWrongSize.size()); + ASSERT_FALSE(send_resource_list.at(0)->send(buffer_list, (uint32_t)receiveBufferWrongSize.size(), &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -430,7 +442,12 @@ TEST_F(UDPv6Tests, send_to_wrong_interface) Locators locators_end(locator_list.end()); std::vector message = { 'H', 'e', 'l', 'l', 'o' }; - ASSERT_FALSE(send_resource_list.at(0)->send(message.data(), (uint32_t)message.size(), &locators_begin, + std::vector buffer_list; + for (size_t i = 0; i < message.size(); ++i) + { + buffer_list.emplace_back(&message[i], 1); + } + ASSERT_FALSE(send_resource_list.at(0)->send(buffer_list, (uint32_t)message.size(), &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -492,7 +509,12 @@ TEST_F(UDPv6Tests, send_to_allowed_interface) // Sending through a ALLOWED IP will work std::vector message = { 'H', 'e', 'l', 'l', 'o' }; - ASSERT_TRUE(send_resource_list.at(0)->send(message.data(), (uint32_t)message.size(), + std::vector buffer_list; + for (size_t i = 0; i < message.size(); ++i) + { + buffer_list.emplace_back(&message[i], 1); + } + ASSERT_TRUE(send_resource_list.at(0)->send(buffer_list, (uint32_t)message.size(), &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); } @@ -545,6 +567,11 @@ TEST_F(UDPv6Tests, send_and_receive_between_allowed_sockets_using_localhost) ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(unicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -560,7 +587,7 @@ TEST_F(UDPv6Tests, send_and_receive_between_allowed_sockets_using_localhost) Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(message, 5, &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); }; @@ -606,6 +633,11 @@ TEST_F(UDPv6Tests, send_and_receive_between_allowed_sockets_using_unicast) ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(unicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -621,7 +653,7 @@ TEST_F(UDPv6Tests, send_and_receive_between_allowed_sockets_using_unicast) Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(message, 5, &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); }; @@ -668,6 +700,11 @@ TEST_F(UDPv6Tests, send_and_receive_between_allowed_sockets_using_unicast_to_mul ASSERT_FALSE(send_resource_list.empty()); ASSERT_TRUE(transportUnderTest.IsInputChannelOpen(unicastLocator)); octet message[5] = { 'H', 'e', 'l', 'l', 'o' }; + std::vector buffer_list; + for (size_t i = 0; i < 5; ++i) + { + buffer_list.emplace_back(&message[i], 1); + } Semaphore sem; std::function recCallback = [&]() @@ -683,7 +720,7 @@ TEST_F(UDPv6Tests, send_and_receive_between_allowed_sockets_using_unicast_to_mul Locators locators_begin(locator_list.begin()); Locators locators_end(locator_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(message, 5, &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, 5, &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100)))); }; @@ -760,6 +797,11 @@ TEST_F(UDPv6Tests, simple_throughput) octet sample_data[sample_size]; memset(sample_data, 0, sizeof(sample_data)); + std::vector buffer_list; + for (size_t i = 0; i < sample_size; ++i) + { + buffer_list.emplace_back(&sample_data[i], 1); + } Locator_t sub_locator; sub_locator.kind = LOCATOR_KIND_UDPv6; @@ -801,7 +843,7 @@ TEST_F(UDPv6Tests, simple_throughput) Locators locators_begin(send_locators_list.begin()); Locators locators_end(send_locators_list.end()); - EXPECT_TRUE(send_resource_list.at(0)->send(sample_data, sizeof(sample_data), &locators_begin, &locators_end, + EXPECT_TRUE(send_resource_list.at(0)->send(buffer_list, sizeof(sample_data), &locators_begin, &locators_end, (std::chrono::steady_clock::now() + std::chrono::milliseconds(100)))); } diff --git a/test/unittest/transport/mock/MockTCPChannelResource.cpp b/test/unittest/transport/mock/MockTCPChannelResource.cpp index c22ad835f0e..7eef964f4b9 100644 --- a/test/unittest/transport/mock/MockTCPChannelResource.cpp +++ b/test/unittest/transport/mock/MockTCPChannelResource.cpp @@ -55,6 +55,16 @@ size_t MockTCPChannelResource::send( return 0; } +size_t MockTCPChannelResource::send( + const octet*, + size_t, + const std::vector&, + uint32_t, + asio::error_code&) +{ + return 0; +} + asio::ip::tcp::endpoint MockTCPChannelResource::remote_endpoint() const { asio::ip::tcp::endpoint ep; diff --git a/test/unittest/transport/mock/MockTCPChannelResource.h b/test/unittest/transport/mock/MockTCPChannelResource.h index ecdb186a0fc..87b69e73d68 100644 --- a/test/unittest/transport/mock/MockTCPChannelResource.h +++ b/test/unittest/transport/mock/MockTCPChannelResource.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace eprosima { namespace fastrtps { @@ -28,6 +29,7 @@ class MockTCPChannelResource; using TCPChannelResource = eprosima::fastdds::rtps::TCPChannelResource; using TCPTransportDescriptor = eprosima::fastdds::rtps::TCPTransportDescriptor; using TCPTransportInterface = eprosima::fastdds::rtps::TCPTransportInterface; +using NetworkBuffer = eprosima::fastdds::rtps::NetworkBuffer; class MockTCPChannelResource : public TCPChannelResource { @@ -51,8 +53,15 @@ class MockTCPChannelResource : public TCPChannelResource size_t send( const octet* header, size_t header_size, - const octet* buffer, - size_t size, + const octet* data, + size_t data_size, + asio::error_code& ec); + + size_t send( + const octet* header, + size_t header_size, + const std::vector& buffers, + uint32_t total_bytes, asio::error_code& ec) override; asio::ip::tcp::endpoint remote_endpoint() const override; diff --git a/test/unittest/transport/mock/MockTCPv4Transport.h b/test/unittest/transport/mock/MockTCPv4Transport.h index 414b3c52c3b..f8d176f4f5c 100644 --- a/test/unittest/transport/mock/MockTCPv4Transport.h +++ b/test/unittest/transport/mock/MockTCPv4Transport.h @@ -15,6 +15,8 @@ #ifndef MOCK_TRANSPORT_TCP4_STUFF_H #define MOCK_TRANSPORT_TCP4_STUFF_H +#include + #include #include @@ -58,10 +60,13 @@ class MockTCPv4Transport : public TCPv4Transport bool send( const fastrtps::rtps::octet* send_buffer, uint32_t send_buffer_size, - const fastrtps::rtps::Locator_t& send_resource_locator, + const Locator_t& send_resource_locator, const Locator_t& remote_locator) { - return TCPv4Transport::send(send_buffer, send_buffer_size, send_resource_locator, remote_locator); + eprosima::fastdds::rtps::NetworkBuffer buffers(send_buffer, send_buffer_size); + std::vector buffer_list; + buffer_list.push_back(buffers); + return TCPv4Transport::send(buffer_list, send_buffer_size, send_resource_locator, remote_locator); } const std::map>& get_channel_pending_logical_ports() const diff --git a/test/unittest/transport/mock/MockTCPv6Transport.h b/test/unittest/transport/mock/MockTCPv6Transport.h index f65088d4bb4..765f705b08e 100644 --- a/test/unittest/transport/mock/MockTCPv6Transport.h +++ b/test/unittest/transport/mock/MockTCPv6Transport.h @@ -15,6 +15,8 @@ #ifndef MOCK_TRANSPORT_TCP6_STUFF_H #define MOCK_TRANSPORT_TCP6_STUFF_H +#include + #include #include @@ -62,7 +64,10 @@ class MockTCPv6Transport : public TCPv6Transport const fastrtps::rtps::Locator_t& send_resource_locator, const Locator_t& remote_locator) { - return TCPv6Transport::send(send_buffer, send_buffer_size, send_resource_locator, remote_locator); + eprosima::fastdds::rtps::NetworkBuffer buffers(send_buffer, send_buffer_size); + std::vector buffer_list; + buffer_list.push_back(buffers); + return TCPv6Transport::send(buffer_list, send_buffer_size, send_resource_locator, remote_locator); } const std::map>& get_channel_pending_logical_ports() const diff --git a/test/unittest/xmlparser/XMLElementParserTests.cpp b/test/unittest/xmlparser/XMLElementParserTests.cpp index 7c2f5f76d99..3c788db09b7 100644 --- a/test/unittest/xmlparser/XMLElementParserTests.cpp +++ b/test/unittest/xmlparser/XMLElementParserTests.cpp @@ -3356,6 +3356,7 @@ TEST_F(XMLParserTests, getXMLDiscoverySettings_NegativeClauses) * 1. Check an invalid tag of: * * + * * 2. Check invalid element */ TEST_F(XMLParserTests, getXMLSendBuffersAllocationAttributes_NegativeClauses) @@ -3388,6 +3389,7 @@ TEST_F(XMLParserTests, getXMLSendBuffersAllocationAttributes_NegativeClauses) { "preallocated_number", "dynamic", + "network_buffers_config" }; for (std::string tag : field_vec) diff --git a/test/unittest/xmlparser/XMLProfileParserTests.cpp b/test/unittest/xmlparser/XMLProfileParserTests.cpp index 3054ecbd13a..765f0f0c431 100644 --- a/test/unittest/xmlparser/XMLProfileParserTests.cpp +++ b/test/unittest/xmlparser/XMLProfileParserTests.cpp @@ -504,6 +504,9 @@ TEST_P(XMLProfileParserTests, XMLParserParticipant) EXPECT_EQ(rtps_atts.allocation.writers.increment, 2u); EXPECT_EQ(rtps_atts.allocation.send_buffers.preallocated_number, 127u); EXPECT_EQ(rtps_atts.allocation.send_buffers.dynamic, true); + EXPECT_EQ(rtps_atts.allocation.send_buffers.network_buffers_config.initial, 10u); + EXPECT_EQ(rtps_atts.allocation.send_buffers.network_buffers_config.maximum, 127u); + EXPECT_EQ(rtps_atts.allocation.send_buffers.network_buffers_config.increment, 10u); IPLocator::setIPv4(locator, 192, 168, 1, 2); locator.port = 2019; diff --git a/test/unittest/xmlparser/test_xml_deprecated.xml b/test/unittest/xmlparser/test_xml_deprecated.xml index db54bcd0bb6..1b9034bce09 100644 --- a/test/unittest/xmlparser/test_xml_deprecated.xml +++ b/test/unittest/xmlparser/test_xml_deprecated.xml @@ -27,6 +27,11 @@ 127 true + + 16 + 0 + 16 + diff --git a/test/unittest/xmlparser/test_xml_profile.xml b/test/unittest/xmlparser/test_xml_profile.xml index 2e77e787db1..2e11f2658a6 100644 --- a/test/unittest/xmlparser/test_xml_profile.xml +++ b/test/unittest/xmlparser/test_xml_profile.xml @@ -46,6 +46,11 @@ 127 true + + 10 + 127 + 10 + diff --git a/test/unittest/xmlparser/test_xml_profile_env_var.xml b/test/unittest/xmlparser/test_xml_profile_env_var.xml index 6199da9384c..b4ddb022277 100644 --- a/test/unittest/xmlparser/test_xml_profile_env_var.xml +++ b/test/unittest/xmlparser/test_xml_profile_env_var.xml @@ -27,6 +27,11 @@ ${XML_PROFILES_ENV_VAR_13} ${XML_PROFILES_ENV_VAR_14} + + ${XML_PROFILES_ENV_VAR_4} + ${XML_PROFILES_ENV_VAR_13} + ${XML_PROFILES_ENV_VAR_4} + diff --git a/versions.md b/versions.md index 40807c0068d..974d0d18d68 100644 --- a/versions.md +++ b/versions.md @@ -51,6 +51,10 @@ Forthcoming * `SerializedPayload_t` copies are now forbidden. * Refactor of `get_payload` methods. * Use `PID_DOMAIN_ID` during PDP. +* Creation of RTPS messages refactor: + * New Gather-send method is now used by default, avoiding an extra copy during the creation of the RTPS message. + * New attribute in `SendBuffersAllocationAttributes` to configure allocation of `NetworkBuffer` vector. + * `SenderResource` and Transport APIs now receive a collection of `NetworkBuffer` on their `send` method. Version 2.14.0 --------------