diff --git a/include/rtc/message.hpp b/include/rtc/message.hpp index a7394e7..23416fa 100644 --- a/include/rtc/message.hpp +++ b/include/rtc/message.hpp @@ -37,6 +37,8 @@ struct Message : binary { Message(Iterator begin_, Iterator end_, Type type_ = Binary) : binary(begin_, end_), type(type_) {} + Message(binary &&data, Type type_ = Binary) : binary(std::move(data)), type(type_) {} + Type type; unsigned int stream = 0; std::shared_ptr reliability; @@ -68,6 +70,15 @@ inline message_ptr make_message(size_t size, Message::Type type = Message::Binar return message; } +inline message_ptr make_message(binary &&data, Message::Type type = Message::Binary, + unsigned int stream = 0, + std::shared_ptr reliability = nullptr) { + auto message = std::make_shared(std::move(data), type); + message->stream = stream; + message->reliability = reliability; + return message; +} + } // namespace rtc #endif diff --git a/src/sctptransport.cpp b/src/sctptransport.cpp index ab809fc..94704cb 100644 --- a/src/sctptransport.cpp +++ b/src/sctptransport.cpp @@ -479,32 +479,22 @@ int SctpTransport::handleRecv(struct socket * /*sock*/, union sctp_sockstore /*a // therefore partial notifications and messages need to be handled separately. if (flags & MSG_NOTIFICATION) { // SCTP event notification + mPartialNotification.insert(mPartialNotification.end(), data, data + len); if (flags & MSG_EOR) { - if (!mPartialNotification.empty()) { - mPartialNotification.insert(mPartialNotification.end(), data, data + len); - data = mPartialNotification.data(); - len = mPartialNotification.size(); - } // Notification is complete, process it - processNotification(reinterpret_cast(data), len); + processNotification( + reinterpret_cast(mPartialNotification.data()), + mPartialNotification.size()); mPartialNotification.clear(); - } else { - mPartialNotification.insert(mPartialNotification.end(), data, data + len); } - } else { // SCTP message + mPartialMessage.insert(mPartialMessage.end(), data, data + len); if (flags & MSG_EOR) { - if (!mPartialMessage.empty()) { - mPartialMessage.insert(mPartialMessage.end(), data, data + len); - data = mPartialMessage.data(); - len = mPartialMessage.size(); - } // Message is complete, process it - processData(data, len, info.rcv_sid, PayloadId(htonl(info.rcv_ppid))); + processData(std::move(mPartialMessage), info.rcv_sid, + PayloadId(htonl(info.rcv_ppid))); mPartialMessage.clear(); - } else { - mPartialMessage.insert(mPartialMessage.end(), data, data + len); } } @@ -539,62 +529,56 @@ int SctpTransport::handleWrite(byte *data, size_t len, uint8_t /*tos*/, uint8_t return 0; // success } -void SctpTransport::processData(const byte *data, size_t len, uint16_t sid, PayloadId ppid) { - PLOG_VERBOSE << "Process data, len=" << len; +void SctpTransport::processData(binary &&data, uint16_t sid, PayloadId ppid) { + PLOG_VERBOSE << "Process data, size=" << data.size(); // The usage of the PPIDs "WebRTC String Partial" and "WebRTC Binary Partial" is deprecated. // See https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-13#section-6.6 // We handle them at reception for compatibility reasons but should never send them. switch (ppid) { case PPID_CONTROL: - recv(make_message(data, data + len, Message::Control, sid)); + recv(make_message(std::move(data), Message::Control, sid)); break; case PPID_STRING_PARTIAL: // deprecated - mPartialStringData.insert(mPartialStringData.end(), data, data + len); + mPartialStringData.insert(mPartialStringData.end(), data.begin(), data.end()); break; case PPID_STRING: if (mPartialStringData.empty()) { - mBytesReceived += len; - recv(make_message(data, data + len, Message::String, sid)); + mBytesReceived += data.size(); + recv(make_message(std::move(data), Message::String, sid)); } else { - mPartialStringData.insert(mPartialStringData.end(), data, data + len); + mPartialStringData.insert(mPartialStringData.end(), data.begin(), data.end()); mBytesReceived += mPartialStringData.size(); - recv(make_message(mPartialStringData.begin(), mPartialStringData.end(), Message::String, - sid)); + recv(make_message(std::move(mPartialStringData), Message::String, sid)); mPartialStringData.clear(); } break; case PPID_STRING_EMPTY: - // This only accounts for when the partial data is empty - recv(make_message(mPartialStringData.begin(), mPartialStringData.end(), Message::String, - sid)); + recv(make_message(std::move(mPartialStringData), Message::String, sid)); mPartialStringData.clear(); break; case PPID_BINARY_PARTIAL: // deprecated - mPartialBinaryData.insert(mPartialBinaryData.end(), data, data + len); + mPartialBinaryData.insert(mPartialBinaryData.end(), data.begin(), data.end()); break; case PPID_BINARY: if (mPartialBinaryData.empty()) { - mBytesReceived += len; - recv(make_message(data, data + len, Message::Binary, sid)); + mBytesReceived += data.size(); + recv(make_message(std::move(data), Message::Binary, sid)); } else { - mPartialBinaryData.insert(mPartialBinaryData.end(), data, data + len); + mPartialBinaryData.insert(mPartialBinaryData.end(), data.begin(), data.end()); mBytesReceived += mPartialBinaryData.size(); - recv(make_message(mPartialBinaryData.begin(), mPartialBinaryData.end(), Message::Binary, - sid)); + recv(make_message(std::move(mPartialBinaryData), Message::Binary, sid)); mPartialBinaryData.clear(); } break; case PPID_BINARY_EMPTY: - // This only accounts for when the partial data is empty - recv(make_message(mPartialBinaryData.begin(), mPartialBinaryData.end(), Message::Binary, - sid)); + recv(make_message(std::move(mPartialBinaryData), Message::Binary, sid)); mPartialBinaryData.clear(); break; diff --git a/src/sctptransport.hpp b/src/sctptransport.hpp index a7f4388..05939d8 100644 --- a/src/sctptransport.hpp +++ b/src/sctptransport.hpp @@ -86,7 +86,7 @@ private: int handleSend(size_t free); int handleWrite(byte *data, size_t len, uint8_t tos, uint8_t set_df); - void processData(const byte *data, size_t len, uint16_t streamId, PayloadId ppid); + void processData(binary &&data, uint16_t streamId, PayloadId ppid); void processNotification(const union sctp_notification *notify, size_t len); const uint16_t mPort;