mirror of
https://github.com/mii443/libdatachannel.git
synced 2025-08-31 03:19:29 +00:00
Implemented max message size negociation
This commit is contained in:
@ -56,6 +56,7 @@ public:
|
|||||||
bool isOpen(void) const;
|
bool isOpen(void) const;
|
||||||
bool isClosed(void) const;
|
bool isClosed(void) const;
|
||||||
size_t availableAmount() const;
|
size_t availableAmount() const;
|
||||||
|
size_t maxMessageSize() const;
|
||||||
|
|
||||||
unsigned int stream() const;
|
unsigned int stream() const;
|
||||||
string label() const;
|
string label() const;
|
||||||
@ -68,7 +69,7 @@ private:
|
|||||||
void incoming(message_ptr message);
|
void incoming(message_ptr message);
|
||||||
void processOpenMessage(message_ptr message);
|
void processOpenMessage(message_ptr message);
|
||||||
|
|
||||||
const std::shared_ptr<PeerConnection> mPeerConnection; // keeps the PeerConnection alive
|
const std::shared_ptr<PeerConnection> mPeerConnection;
|
||||||
std::shared_ptr<SctpTransport> mSctpTransport;
|
std::shared_ptr<SctpTransport> mSctpTransport;
|
||||||
|
|
||||||
unsigned int mStream;
|
unsigned int mStream;
|
||||||
|
@ -44,9 +44,11 @@ public:
|
|||||||
string mid() const;
|
string mid() const;
|
||||||
std::optional<string> fingerprint() const;
|
std::optional<string> fingerprint() const;
|
||||||
std::optional<uint16_t> sctpPort() const;
|
std::optional<uint16_t> sctpPort() const;
|
||||||
|
std::optional<size_t> maxMessageSize() const;
|
||||||
|
|
||||||
void setFingerprint(string fingerprint);
|
void setFingerprint(string fingerprint);
|
||||||
void setSctpPort(uint16_t port);
|
void setSctpPort(uint16_t port);
|
||||||
|
void setMaxMessageSize(size_t size);
|
||||||
|
|
||||||
void addCandidate(Candidate candidate);
|
void addCandidate(Candidate candidate);
|
||||||
void endCandidates();
|
void endCandidates();
|
||||||
@ -62,6 +64,7 @@ private:
|
|||||||
string mIceUfrag, mIcePwd;
|
string mIceUfrag, mIcePwd;
|
||||||
std::optional<string> mFingerprint;
|
std::optional<string> mFingerprint;
|
||||||
std::optional<uint16_t> mSctpPort;
|
std::optional<uint16_t> mSctpPort;
|
||||||
|
std::optional<size_t> mMaxMessageSize;
|
||||||
std::vector<Candidate> mCandidates;
|
std::vector<Candidate> mCandidates;
|
||||||
bool mTrickle;
|
bool mTrickle;
|
||||||
|
|
||||||
|
@ -43,7 +43,10 @@ using std::uint8_t;
|
|||||||
|
|
||||||
const size_t MAX_NUMERICNODE_LEN = 48; // Max IPv6 string representation length
|
const size_t MAX_NUMERICNODE_LEN = 48; // Max IPv6 string representation length
|
||||||
const size_t MAX_NUMERICSERV_LEN = 6; // Max port string representation length
|
const size_t MAX_NUMERICSERV_LEN = 6; // Max port string representation length
|
||||||
|
|
||||||
const uint16_t DEFAULT_SCTP_PORT = 5000; // SCTP port to use by default
|
const uint16_t DEFAULT_SCTP_PORT = 5000; // SCTP port to use by default
|
||||||
|
const size_t DEFAULT_MAX_MESSAGE_SIZE = 65536; // Remote max message size if not specified in SDP
|
||||||
|
const size_t LOCAL_MAX_MESSAGE_SIZE = 256 * 1024; // Local max message size
|
||||||
|
|
||||||
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
||||||
template <class... Ts> overloaded(Ts...)->overloaded<Ts...>;
|
template <class... Ts> overloaded(Ts...)->overloaded<Ts...>;
|
||||||
|
@ -44,6 +44,7 @@ struct Message : binary {
|
|||||||
using message_ptr = std::shared_ptr<const Message>;
|
using message_ptr = std::shared_ptr<const Message>;
|
||||||
using mutable_message_ptr = std::shared_ptr<Message>;
|
using mutable_message_ptr = std::shared_ptr<Message>;
|
||||||
using message_callback = std::function<void(message_ptr message)>;
|
using message_callback = std::function<void(message_ptr message)>;
|
||||||
|
|
||||||
constexpr auto message_size_func = [](const message_ptr &m) -> size_t {
|
constexpr auto message_size_func = [](const message_ptr &m) -> size_t {
|
||||||
return m->type != Message::Control ? m->size() : 0;
|
return m->type != Message::Control ? m->size() : 0;
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "datachannel.hpp"
|
#include "datachannel.hpp"
|
||||||
|
#include "include.hpp"
|
||||||
#include "peerconnection.hpp"
|
#include "peerconnection.hpp"
|
||||||
#include "sctptransport.hpp"
|
#include "sctptransport.hpp"
|
||||||
|
|
||||||
@ -128,6 +129,15 @@ bool DataChannel::isClosed(void) const { return mIsClosed; }
|
|||||||
|
|
||||||
size_t DataChannel::availableAmount() const { return mRecvQueue.amount(); }
|
size_t DataChannel::availableAmount() const { return mRecvQueue.amount(); }
|
||||||
|
|
||||||
|
size_t DataChannel::maxMessageSize() const {
|
||||||
|
size_t max = DEFAULT_MAX_MESSAGE_SIZE;
|
||||||
|
if (auto description = mPeerConnection->remoteDescription())
|
||||||
|
if (auto maxMessageSize = description->maxMessageSize())
|
||||||
|
return *maxMessageSize > 0 ? *maxMessageSize : LOCAL_MAX_MESSAGE_SIZE;
|
||||||
|
|
||||||
|
return std::min(max, LOCAL_MAX_MESSAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int DataChannel::stream() const { return mStream; }
|
unsigned int DataChannel::stream() const { return mStream; }
|
||||||
|
|
||||||
string DataChannel::label() const { return mLabel; }
|
string DataChannel::label() const { return mLabel; }
|
||||||
@ -169,7 +179,11 @@ void DataChannel::open(shared_ptr<SctpTransport> sctpTransport) {
|
|||||||
|
|
||||||
void DataChannel::outgoing(mutable_message_ptr message) {
|
void DataChannel::outgoing(mutable_message_ptr message) {
|
||||||
if (mIsClosed || !mSctpTransport)
|
if (mIsClosed || !mSctpTransport)
|
||||||
return;
|
throw std::runtime_error("DataChannel is closed");
|
||||||
|
|
||||||
|
if (message->size() > maxMessageSize())
|
||||||
|
throw std::runtime_error("Message size exceeds limit");
|
||||||
|
|
||||||
// Before the ACK has been received on a DataChannel, all messages must be sent ordered
|
// Before the ACK has been received on a DataChannel, all messages must be sent ordered
|
||||||
message->reliability = mIsOpen ? mReliability : nullptr;
|
message->reliability = mIsOpen ? mReliability : nullptr;
|
||||||
message->stream = mStream;
|
message->stream = mStream;
|
||||||
|
@ -81,6 +81,8 @@ Description::Description(const string &sdp, Type type, Role role)
|
|||||||
mIcePwd = line.substr(line.find(':') + 1);
|
mIcePwd = line.substr(line.find(':') + 1);
|
||||||
} else if (hasprefix(line, "a=sctp-port")) {
|
} else if (hasprefix(line, "a=sctp-port")) {
|
||||||
mSctpPort = uint16_t(std::stoul(line.substr(line.find(':') + 1)));
|
mSctpPort = uint16_t(std::stoul(line.substr(line.find(':') + 1)));
|
||||||
|
} else if (hasprefix(line, "a=max-message-size")) {
|
||||||
|
mMaxMessageSize = size_t(std::stoul(line.substr(line.find(':') + 1)));
|
||||||
} else if (hasprefix(line, "a=candidate")) {
|
} else if (hasprefix(line, "a=candidate")) {
|
||||||
addCandidate(Candidate(line.substr(2), mMid));
|
addCandidate(Candidate(line.substr(2), mMid));
|
||||||
} else if (hasprefix(line, "a=end-of-candidates")) {
|
} else if (hasprefix(line, "a=end-of-candidates")) {
|
||||||
@ -103,12 +105,16 @@ std::optional<string> Description::fingerprint() const { return mFingerprint; }
|
|||||||
|
|
||||||
std::optional<uint16_t> Description::sctpPort() const { return mSctpPort; }
|
std::optional<uint16_t> Description::sctpPort() const { return mSctpPort; }
|
||||||
|
|
||||||
|
std::optional<size_t> Description::maxMessageSize() const { return mMaxMessageSize; }
|
||||||
|
|
||||||
void Description::setFingerprint(string fingerprint) {
|
void Description::setFingerprint(string fingerprint) {
|
||||||
mFingerprint.emplace(std::move(fingerprint));
|
mFingerprint.emplace(std::move(fingerprint));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Description::setSctpPort(uint16_t port) { mSctpPort.emplace(port); }
|
void Description::setSctpPort(uint16_t port) { mSctpPort.emplace(port); }
|
||||||
|
|
||||||
|
void Description::setMaxMessageSize(size_t size) { mMaxMessageSize.emplace(size); }
|
||||||
|
|
||||||
void Description::addCandidate(Candidate candidate) {
|
void Description::addCandidate(Candidate candidate) {
|
||||||
mCandidates.emplace_back(std::move(candidate));
|
mCandidates.emplace_back(std::move(candidate));
|
||||||
}
|
}
|
||||||
@ -145,7 +151,8 @@ Description::operator string() const {
|
|||||||
sdp << "a=fingerprint:sha-256 " << *mFingerprint << "\n";
|
sdp << "a=fingerprint:sha-256 " << *mFingerprint << "\n";
|
||||||
if (mSctpPort)
|
if (mSctpPort)
|
||||||
sdp << "a=sctp-port:" << *mSctpPort << "\n";
|
sdp << "a=sctp-port:" << *mSctpPort << "\n";
|
||||||
|
if (mMaxMessageSize)
|
||||||
|
sdp << "a=max-message-size:" << *mMaxMessageSize << "\n";
|
||||||
for (const auto &candidate : mCandidates) {
|
for (const auto &candidate : mCandidates) {
|
||||||
sdp << string(candidate) << "\n";
|
sdp << string(candidate) << "\n";
|
||||||
}
|
}
|
||||||
|
@ -359,6 +359,7 @@ void PeerConnection::processLocalDescription(Description description) {
|
|||||||
mLocalDescription.emplace(std::move(description));
|
mLocalDescription.emplace(std::move(description));
|
||||||
mLocalDescription->setFingerprint(mCertificate->fingerprint());
|
mLocalDescription->setFingerprint(mCertificate->fingerprint());
|
||||||
mLocalDescription->setSctpPort(remoteSctpPort.value_or(DEFAULT_SCTP_PORT));
|
mLocalDescription->setSctpPort(remoteSctpPort.value_or(DEFAULT_SCTP_PORT));
|
||||||
|
mLocalDescription->setMaxMessageSize(LOCAL_MAX_MESSAGE_SIZE);
|
||||||
|
|
||||||
mLocalDescriptionCallback(*mLocalDescription);
|
mLocalDescriptionCallback(*mLocalDescription);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user