Skip to content

Commit 9861edc

Browse files
Refactor reliability struct
1 parent d5948b7 commit 9861edc

File tree

7 files changed

+98
-43
lines changed

7 files changed

+98
-43
lines changed

DOC.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -644,8 +644,8 @@ Arguments:
644644
- `reliability`: a structure of reliability settings containing:
645645
- `unordered`: if `true`, the Data Channel will not enforce message ordering, else it will be ordered
646646
- `unreliable`: if `true`, the Data Channel will not enforce strict reliability, else it will be reliable
647-
- `maxPacketLifeTime`: if unreliable, maximum packet life time in milliseconds
648-
- `maxRetransmits`: if unreliable and maxPacketLifeTime is 0, maximum number of retransmissions (0 means no retransmission)
647+
- `maxPacketLifeTime`: if unreliable, time window in milliseconds during which transmissions and retransmissions may occur
648+
- `maxRetransmits`: if unreliable and maxPacketLifeTime is 0, maximum number of attempted retransmissions (0 means no retransmission)
649649
- `protocol` (optional): a user-defined UTF-8 string representing the Data Channel protocol, empty if NULL
650650
- `negotiated`: if `true`, the Data Channel is assumed to be negotiated by the user and won't be negotiated by the WebRTC layer
651651
- `manualStream`: if `true`, the Data Channel will use `stream` as stream ID, else an available id is automatically selected

include/rtc/reliability.hpp

+18-3
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,25 @@
1616
namespace rtc {
1717

1818
struct Reliability {
19-
enum class Type { Reliable = 0, Rexmit, Timed };
20-
21-
Type type = Type::Reliable;
19+
// It true, the channel does not enforce message ordering and out-of-order delivery is allowed
2220
bool unordered = false;
21+
22+
// If both maxPacketLifeTime or maxRetransmits are unset, the channel is reliable.
23+
// If either maxPacketLifeTime or maxRetransmits is set, the channel is unreliable.
24+
// (The settings are exclusive so both maxPacketLifetime and maxRetransmits must not be set.)
25+
26+
// Time window during which transmissions and retransmissions may occur
27+
optional<std::chrono::milliseconds> maxPacketLifeTime;
28+
29+
// Maximum number of retransmissions that are attempted
30+
optional<unsigned int> maxRetransmits;
31+
32+
// For backward compatibility, do not use
33+
enum class Type { Reliable = 0, Rexmit, Timed };
34+
union {
35+
Type typeDeprecated = Type::Reliable;
36+
[[deprecated("Use maxPacketLifeTime or maxRetransmits")]] Type type;
37+
};
2338
variant<int, std::chrono::milliseconds> rexmit = 0;
2439
};
2540

include/rtc/rtc.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ RTC_C_EXPORT int rtcReceiveMessage(int id, char *buffer, int *size);
245245
typedef struct {
246246
bool unordered;
247247
bool unreliable;
248-
int maxPacketLifeTime; // ignored if reliable
249-
int maxRetransmits; // ignored if reliable
248+
unsigned int maxPacketLifeTime; // ignored if reliable
249+
unsigned int maxRetransmits; // ignored if reliable
250250
} rtcReliability;
251251

252252
typedef struct {

pages/content/pages/reference.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -647,8 +647,8 @@ Arguments:
647647
- `reliability`: a structure of reliability settings containing:
648648
- `unordered`: if `true`, the Data Channel will not enforce message ordering, else it will be ordered
649649
- `unreliable`: if `true`, the Data Channel will not enforce strict reliability, else it will be reliable
650-
- `maxPacketLifeTime`: if unreliable, maximum packet life time in milliseconds
651-
- `maxRetransmits`: if unreliable and maxPacketLifeTime is 0, maximum number of retransmissions (0 means no retransmission)
650+
- `maxPacketLifeTime`: if unreliable, time window in milliseconds during which transmissions and retransmissions may occur
651+
- `maxRetransmits`: if unreliable and maxPacketLifeTime is 0, maximum number of attempted retransmissions (0 means no retransmission)
652652
- `protocol` (optional): a user-defined UTF-8 string representing the Data Channel protocol, empty if NULL
653653
- `negotiated`: if `true`, the Data Channel is assumed to be negotiated by the user and won't be negotiated by the WebRTC layer
654654
- `manualStream`: if `true`, the Data Channel will use `stream` as stream ID, else an available id is automatically selected

src/capi.cpp

+8-13
Original file line numberDiff line numberDiff line change
@@ -901,15 +901,10 @@ int rtcCreateDataChannelEx(int pc, const char *label, const rtcDataChannelInit *
901901
auto *reliability = &init->reliability;
902902
dci.reliability.unordered = reliability->unordered;
903903
if (reliability->unreliable) {
904-
if (reliability->maxPacketLifeTime > 0) {
905-
dci.reliability.type = Reliability::Type::Timed;
906-
dci.reliability.rexmit = milliseconds(reliability->maxPacketLifeTime);
907-
} else {
908-
dci.reliability.type = Reliability::Type::Rexmit;
909-
dci.reliability.rexmit = reliability->maxRetransmits;
910-
}
911-
} else {
912-
dci.reliability.type = Reliability::Type::Reliable;
904+
if (reliability->maxPacketLifeTime > 0)
905+
dci.reliability.maxPacketLifeTime.emplace(milliseconds(reliability->maxPacketLifeTime));
906+
else
907+
dci.reliability.maxRetransmits.emplace(reliability->maxRetransmits);
913908
}
914909

915910
dci.negotiated = init->negotiated;
@@ -971,12 +966,12 @@ int rtcGetDataChannelReliability(int dc, rtcReliability *reliability) {
971966
Reliability dcr = dataChannel->reliability();
972967
std::memset(reliability, 0, sizeof(*reliability));
973968
reliability->unordered = dcr.unordered;
974-
if (dcr.type == Reliability::Type::Timed) {
969+
if(dcr.maxPacketLifeTime) {
975970
reliability->unreliable = true;
976-
reliability->maxPacketLifeTime = int(std::get<milliseconds>(dcr.rexmit).count());
977-
} else if (dcr.type == Reliability::Type::Rexmit) {
971+
reliability->maxPacketLifeTime = static_cast<unsigned int>(dcr.maxPacketLifeTime->count());
972+
} else if (dcr.maxRetransmits) {
978973
reliability->unreliable = true;
979-
reliability->maxRetransmits = std::get<int>(dcr.rexmit);
974+
reliability->maxRetransmits = *dcr.maxRetransmits;
980975
} else {
981976
reliability->unreliable = false;
982977
}

src/impl/datachannel.cpp

+50-18
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,13 @@ bool DataChannel::IsOpenMessage(message_ptr message) {
7474
DataChannel::DataChannel(weak_ptr<PeerConnection> pc, string label, string protocol,
7575
Reliability reliability)
7676
: mPeerConnection(pc), mLabel(std::move(label)), mProtocol(std::move(protocol)),
77-
mReliability(std::make_shared<Reliability>(std::move(reliability))),
78-
mRecvQueue(RECV_QUEUE_LIMIT, message_size_func) {}
77+
mRecvQueue(RECV_QUEUE_LIMIT, message_size_func) {
78+
79+
if(reliability.maxPacketLifeTime && reliability.maxRetransmits)
80+
throw std::invalid_argument("Both maxPacketLifeTime and maxRetransmits are set");
81+
82+
mReliability = std::make_shared<Reliability>(std::move(reliability));
83+
}
7984

8085
DataChannel::~DataChannel() {
8186
PLOG_VERBOSE << "Destroying DataChannel";
@@ -247,22 +252,35 @@ void OutgoingDataChannel::open(shared_ptr<SctpTransport> transport) {
247252

248253
uint8_t channelType;
249254
uint32_t reliabilityParameter;
250-
switch (mReliability->type) {
251-
case Reliability::Type::Rexmit:
255+
if (mReliability->maxPacketLifeTime) {
256+
channelType = CHANNEL_PARTIAL_RELIABLE_TIMED;
257+
reliabilityParameter = uint32_t(mReliability->maxPacketLifeTime->count());
258+
} else if (mReliability->maxRetransmits) {
252259
channelType = CHANNEL_PARTIAL_RELIABLE_REXMIT;
253-
reliabilityParameter = uint32_t(std::max(std::get<int>(mReliability->rexmit), 0));
254-
break;
260+
reliabilityParameter = uint32_t(*mReliability->maxRetransmits);
261+
}
262+
// else {
263+
// channelType = CHANNEL_RELIABLE;
264+
// reliabilityParameter = 0;
265+
// }
266+
// Deprecated
267+
else
268+
switch (mReliability->typeDeprecated) {
269+
case Reliability::Type::Rexmit:
270+
channelType = CHANNEL_PARTIAL_RELIABLE_REXMIT;
271+
reliabilityParameter = uint32_t(std::max(std::get<int>(mReliability->rexmit), 0));
272+
break;
255273

256-
case Reliability::Type::Timed:
257-
channelType = CHANNEL_PARTIAL_RELIABLE_TIMED;
258-
reliabilityParameter = uint32_t(std::get<milliseconds>(mReliability->rexmit).count());
259-
break;
274+
case Reliability::Type::Timed:
275+
channelType = CHANNEL_PARTIAL_RELIABLE_TIMED;
276+
reliabilityParameter = uint32_t(std::get<milliseconds>(mReliability->rexmit).count());
277+
break;
260278

261-
default:
262-
channelType = CHANNEL_RELIABLE;
263-
reliabilityParameter = 0;
264-
break;
265-
}
279+
default:
280+
channelType = CHANNEL_RELIABLE;
281+
reliabilityParameter = 0;
282+
break;
283+
}
266284

267285
if (mReliability->unordered)
268286
channelType |= 0x80;
@@ -329,17 +347,31 @@ void IncomingDataChannel::processOpenMessage(message_ptr message) {
329347
mProtocol.assign(end + open.labelLength, open.protocolLength);
330348

331349
mReliability->unordered = (open.channelType & 0x80) != 0;
350+
mReliability->maxPacketLifeTime.reset();
351+
mReliability->maxRetransmits.reset();
352+
switch (open.channelType & 0x7F) {
353+
case CHANNEL_PARTIAL_RELIABLE_REXMIT:
354+
mReliability->maxRetransmits.emplace(open.reliabilityParameter);
355+
break;
356+
case CHANNEL_PARTIAL_RELIABLE_TIMED:
357+
mReliability->maxPacketLifeTime.emplace(milliseconds(open.reliabilityParameter));
358+
break;
359+
default:
360+
break;
361+
}
362+
363+
// Deprecated
332364
switch (open.channelType & 0x7F) {
333365
case CHANNEL_PARTIAL_RELIABLE_REXMIT:
334-
mReliability->type = Reliability::Type::Rexmit;
366+
mReliability->typeDeprecated = Reliability::Type::Rexmit;
335367
mReliability->rexmit = int(open.reliabilityParameter);
336368
break;
337369
case CHANNEL_PARTIAL_RELIABLE_TIMED:
338-
mReliability->type = Reliability::Type::Timed;
370+
mReliability->typeDeprecated = Reliability::Type::Timed;
339371
mReliability->rexmit = milliseconds(open.reliabilityParameter);
340372
break;
341373
default:
342-
mReliability->type = Reliability::Type::Reliable;
374+
mReliability->typeDeprecated = Reliability::Type::Reliable;
343375
mReliability->rexmit = int(0);
344376
}
345377

src/impl/sctptransport.cpp

+16-3
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ bool SctpTransport::send(message_ptr message) {
387387

388388
PLOG_VERBOSE << "Send size=" << message->size();
389389

390-
if(message->size() > mMaxMessageSize)
390+
if (message->size() > mMaxMessageSize)
391391
throw std::invalid_argument("Message is too large");
392392

393393
// Flush the queue, and if nothing is pending, try to send directly
@@ -522,7 +522,7 @@ void SctpTransport::doRecv() {
522522
} else {
523523
// SCTP message
524524
mPartialMessage.insert(mPartialMessage.end(), buffer, buffer + len);
525-
if(mPartialMessage.size() > mMaxMessageSize) {
525+
if (mPartialMessage.size() > mMaxMessageSize) {
526526
PLOG_WARNING << "SCTP message is too large, truncating it";
527527
mPartialMessage.resize(mMaxMessageSize);
528528
}
@@ -646,7 +646,20 @@ bool SctpTransport::trySendMessage(message_ptr message) {
646646
if (reliability.unordered)
647647
spa.sendv_sndinfo.snd_flags |= SCTP_UNORDERED;
648648

649-
switch (reliability.type) {
649+
if (reliability.maxPacketLifeTime) {
650+
spa.sendv_flags |= SCTP_SEND_PRINFO_VALID;
651+
spa.sendv_prinfo.pr_policy = SCTP_PR_SCTP_TTL;
652+
spa.sendv_prinfo.pr_value = to_uint32(reliability.maxPacketLifeTime->count());
653+
} else if (reliability.maxRetransmits) {
654+
spa.sendv_flags |= SCTP_SEND_PRINFO_VALID;
655+
spa.sendv_prinfo.pr_policy = SCTP_PR_SCTP_RTX;
656+
spa.sendv_prinfo.pr_value = to_uint32(*reliability.maxRetransmits);
657+
}
658+
// else {
659+
// spa.sendv_prinfo.pr_policy = SCTP_PR_SCTP_NONE;
660+
// }
661+
// Deprecated
662+
else switch (reliability.typeDeprecated) {
650663
case Reliability::Type::Rexmit:
651664
spa.sendv_flags |= SCTP_SEND_PRINFO_VALID;
652665
spa.sendv_prinfo.pr_policy = SCTP_PR_SCTP_RTX;

0 commit comments

Comments
 (0)