68 Commits

Author SHA1 Message Date
Victor Boivie
e39f1b5907 dcsctp: Add priority support to send queue
This mainly modifies the stream scheduler to add a weighted fair queuing
algorithm in addition to its round robin algorithm. The WFQ algorithm is
selected whenever interleaving is enabled, to ensure that the socket
stays backwards compatible in the normal (non-interleaved) scenario.

Adaptation to send queue and socket comes in a follow-up CL.

Bug: webrtc:5696
Change-Id: I8f0dbfa8c2f40f2e84cee536ea821e7ef4af6310
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261947
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37330}
2022-06-25 22:55:40 +00:00
Victor Boivie
3bd0f865f3 Reland "dcsctp: Use stream scheduler in send queue"
This is a revert of the revert of commit d729d12454906d924d5a142deb3432
which was reverted because it caused upstream test failures.

Contains fix in StreamScheduler::GetActiveStreamsForTesting.

This reverts commit 5df960d3073630c5619e00d79f89937bf6fabd69.

Bug: webrtc:5696
Change-Id: I89dada257a6fb1f149f50067ab66b17e24a7c01a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/266368
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37299}
2022-06-22 08:41:12 +00:00
Victor Boivie
c8e8e767e2 dcsctp: Restart T3-RTX on fast rtx of lowest TSN
RFC 4960, 7.2.4.  Fast Retransmit on Gap Reports

4)  Restart the T3-rtx timer only if the last SACK acknowledged the
    lowest outstanding TSN number sent to that address, or the
    endpoint is retransmitting the first outstanding DATA chunk sent
    to that address.

The second part of this sentence, "or the endpoint is retransmitting the
first outstanding DATA chunk sent to that address."

This means that on fast retransmit, and if the retransmitted chunks
weren't quickly acknowledged by the peer, the retransmission timer would
expire too quickly. With this CL, it will restart, as it should.

Bug: webrtc:12943
Change-Id: I7627253718530876acc516460562e66bfcc79533
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/265620
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37193}
2022-06-13 10:10:46 +00:00
Victor Boivie
5df960d307 Revert "dcsctp: Use stream scheduler in send queue"
This reverts commit d729d12454906d924d5a142deb3432e2d5fa97ae.

Reason for revert: Breaks downstream project.

Original change's description:
> dcsctp: Use stream scheduler in send queue
>
> Changing the currently embedded scheduler that was implemented using a
> revolving pointer, to the parameterized stream scheduler that is
> implemented using a "virtual finish time" approach.
>
> Also renamed StreamCallback to StreamProducer, per review comments.
>
> Bug: webrtc:5696
> Change-Id: I7719678776ddbe05b688ada1b52887e5ca2fb206
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262160
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Commit-Queue: Victor Boivie <boivie@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#37170}

Bug: webrtc:5696
Change-Id: Iaf3608b52a31eb31b4ca604539edb2e8ca89399b
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/265389
Auto-Submit: Victor Boivie <boivie@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#37172}
2022-06-10 06:29:35 +00:00
Victor Boivie
d729d12454 dcsctp: Use stream scheduler in send queue
Changing the currently embedded scheduler that was implemented using a
revolving pointer, to the parameterized stream scheduler that is
implemented using a "virtual finish time" approach.

Also renamed StreamCallback to StreamProducer, per review comments.

Bug: webrtc:5696
Change-Id: I7719678776ddbe05b688ada1b52887e5ca2fb206
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262160
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37170}
2022-06-09 21:41:44 +00:00
Victor Boivie
d70186367c dcsctp: Add virtual time stream scheduler
This adds a stream scheduler using virtual finish time (as defined in
e.g. many Fair Queuing scheduler implementations), which indicates when
a stream's next sent packet is supposed to be sent.

In the initial version, this will be used to implement a round robin
scheduler, by emulating that a stream's virtual finish time - when
scheduled - is the "one more" than all existing virtual finish times.
That will make the scheduler simply iterate between the streams in
round robin order.

The stream scheduler component is tested in isolation, and follow-up
CLs will integrate it into the send queue.

Bug: webrtc:5696
Change-Id: Iaa2c204f9b9a00517f55355cb11cfd25bb415f9e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261946
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37157}
2022-06-08 23:33:50 +00:00
Victor Boivie
0e230fd022 dcsctp: Refactor Send Queue
Make HasDataToSend not mutate any state, and let the Produce method  do
all state mutation and possibly indicate if there is nothing that can be
sent. This is helpful preparation for extracting the scheduling part of
the send queue to a separate component.

Bug: webrtc:5696
Change-Id: I132779e77d3ce6a41e5fcf4432140d3728d03cdc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261945
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37141}
2022-06-07 15:01:32 +00:00
Victor Boivie
7726b7d067 dcsctp: Abandon chunks marked for fast retransmit
The current code assumed that chunks that were scheduled for fast
retransmission would never be abandoned, as chunks marked for fast
retransmission would be immediately sent after the SACK has been
processed, giving no time for them to be abandoned.

But fuzzers keep on fuzzing, and can craft a sequence of chunks that
result in a SACK that both marks the chunks for fast retransmission and
later (while processing the same SACK) abandons them.

Bug: chromium:1331087
Change-Id: Id218607e18a6f3a9d6d51044dccb920e1e77372a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/264960
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Auto-Submit: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37108}
2022-06-03 09:05:23 +00:00
Victor Boivie
7e897aeb92 dcsctp: Add public API for setting priorities
This is a reland of commit 17a02a31d7d2897b75ad69fdac5d10e7475a5865.

This is the first part of supporting stream priorities, and adds the API
and very basic support for setting and retrieving the stream priority.

This commit doesn't in any way change the actual packet sending - the
specified priority values are stored, but not acted on.

This is all that is client visible, so clients can start using the API
as written, and they would never notice that things are missing.

Bug: webrtc:5696
Change-Id: I04d64a63cbaec67568496ad99667e14eba85f2e0
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/264424
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37081}
2022-06-01 20:46:25 +00:00
Björn Terelius
51e5bacb8b Revert "dcsctp: Add public API for setting priorities"
This reverts commit 17a02a31d7d2897b75ad69fdac5d10e7475a5865.

Reason for revert: Breaks downstream test

Original change's description:
> dcsctp: Add public API for setting priorities
>
> This is the first part of supporting stream priorities, and adds the API
> and very basic support for setting and retrieving the stream priority.
>
> This commit doesn't in any way change the actual packet sending - the
> specified priority values are stored, but not acted on.
>
> This is all that is client visible, so clients can start using the API
> as written, and they would never notice that things are missing.
>
> Bug: webrtc:5696
> Change-Id: I24fce8cbb6f3cba187df99d1d3f45e73621c93c6
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261943
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Commit-Queue: Victor Boivie <boivie@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#37034}

Bug: webrtc:5696
Change-Id: If172d9c9dbce7aae72152abbbae1ccc77340bbc1
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/264444
Owners-Override: Björn Terelius <terelius@webrtc.org>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Björn Terelius <terelius@webrtc.org>
Auto-Submit: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37039}
2022-05-30 14:12:34 +00:00
Victor Boivie
17a02a31d7 dcsctp: Add public API for setting priorities
This is the first part of supporting stream priorities, and adds the API
and very basic support for setting and retrieving the stream priority.

This commit doesn't in any way change the actual packet sending - the
specified priority values are stored, but not acted on.

This is all that is client visible, so clients can start using the API
as written, and they would never notice that things are missing.

Bug: webrtc:5696
Change-Id: I24fce8cbb6f3cba187df99d1d3f45e73621c93c6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261943
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37034}
2022-05-30 10:05:03 +00:00
Victor Boivie
d7fd0f9744 dcsctp: Handle rapid closing of streams
When streams were to be reset, but there was already an ongoing
stream reset command in-flight, those streams wouldn't be properly
reset. When multiple streams were reset close to each other (within
an RTT), some streams would not have their SSNs reset, which resulted
in the stream resuming the SSN sequence. This could result in ordered
streams not delivering all messages as the receiver wouldn't deliver any
messages with SSN different from the expected SSN=0.

In WebRTC data channels, this would be triggered if multiple channels
were closed at roughly the same time, then re-opened, and continued
to be used in ordered mode. Unordered messages would still be delivered,
but the stream state could be wrong as the DATA_CHANNEL_ACK message is
sent ordered, and possibly not delivered.

There were unit tests for this, but not on the socket level using
real components, but just on the stream reset handler using mocks,
where this issue wasn't found. Also, those mocks didn't validate that
the correct parameters were provided, so that's fixed now.

The root cause was the PrepareResetStreams was only called if there
wasn't an ongoing stream reset operation in progress. One may try to
solve it by always calling PrepareResetStreams also when there is an
ongoing request, or to call it when the request has finished. One would
then realize that when the response of the outgoing stream request is
received, and CommitResetStreams is called, it would reset all paused
and (prepared) to-be-reset streams - not just the ones in the outgoing
stream request.

One cause of this was the lack of a single source of truth of the stream
states. The SendQueue kept track of which streams that were paused, but
the stream reset handler kept track of which streams that were
resetting. As that's error prone, this CL moves the source of truth
completely to the SendQueue and defining explicit stream pause states. A
stream can be in one of these possible states:

  * Not paused. This is the default for an active stream.
  * Pending to be paused. This is when it's about to be reset, but
    there is a message that has been partly sent, with fragments
    remaining to be sent before it can be paused.
  * Paused, with no partly sent message. In this state, it's ready to
    be reset.
  * Resetting. A stream transitions into this state when it has been
    paused and has been included in an outgoing stream reset request.
    When this request has been responded to, the stream can really be
    reset (SSN=0, MID=0).

This CL also improves logging, and adds socket tests to catch this
issue.

Bug: webrtc:13994, chromium:1320194
Change-Id: I883570d1f277bc01e52b1afad62d6be2aca930a2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261180
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36771}
2022-05-05 07:30:58 +00:00
Victor Boivie
5e354d9969 dcsctp: Improve fast retransmission support
Before this CL, fast retransmission didn't follow the SHOULDs:

https://datatracker.ietf.org/doc/html/rfc4960#section-7.2.4
 * "the sender SHOULD ignore the value of cwnd (...)"
 * "(...) and SHOULD NOT delay retransmission for this single
   packet."

With this CL, chunks that are eligible for fast retransmission (limited
to what can fit in a single packet) will be sent just after having
received the SACK that reported them missing and transitioned the socket
into fast recovery, and they will be sent even if the congestion window
is full.

Bug: webrtc:13969
Change-Id: I12c7e191a8ffd67973db7f083bad8a6061549fa2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/259866
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36724}
2022-05-02 08:29:52 +00:00
Victor Boivie
a5fecb3917 dcsctp: Add proper fast retransmission support
This CL makes OutstandingData keep track of chunks that are eligible for
fast retransmission. When the socket goes into fast recovery, the
reported missing chunks can be retransmitted quickly (ignoring the
congestion window) according to
https://datatracker.ietf.org/doc/html/rfc4960#section-7.2.4.

The CL also adds the new API to OutstandingData to retrieve only the
chunks that are eligible for fast retransmission, and moves the
remaining chunks to the ordinary list of chunks to be retransmitted
later.

This solves an issue where the retransmission timer wouldn't start if
there wouldn't be any chunks to fast-retransmit.

It doesn't, however, make sure that chunks that should be fast
retransmitted can send even when the congestion window is full. That
will be solved in the follow-up CL.

Bug: webrtc:13969
Change-Id: If4012d1cb284ef4a2d815683ed60cbbbff5b3c3b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/259865
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36721}
2022-05-02 07:03:42 +00:00
Victor Boivie
8ec4a2eca3 dcsctp: Refactor chunk lifecycle state flag
This CL replaces two booleans, that could never be active at the same
time (there is no such thing as an abandoned chunk that is scheduled
for retransmission), with a single enum.

Just for increased readability, and to understand that there is no such
thing as an abandoned chunk that will be retransmitted.

Bug: None
Change-Id: I1682c383aed692db07fd4ae1f84c0166db86c062
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/259864
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36707}
2022-04-29 13:38:41 +00:00
Victor Boivie
01a0db2e74 dcsctp: Don't re-nack a fragment until sent again
This is mainly an issue when sending items with partial reliability,
with high bandwidth on a link with packet loss.

In SCTP, when a fragment isn't included in the SACK a number of times,
it's scheduled to be retransmitted or abandoned, if it has been
retransmitted too many times already (depending configuration). Before
this CL, if a fragment was NACKed and scheduled for retransmission, but
couldn't be retransmitted immediately (due to congestion window not
allowing it), future received SACKs - that would still indicate that the
fragment hasn't been received yet - would still increment the
retransmission counter. Which wasn't fair, because this fragment hasn't
had a chance to be retransmitted yet.

With this CL, the fragment will only have its retransmission counter
increased when it is not already scheduled to be retransmitted, but
actually sent on the wire and considered in-flight again.

Bug: webrtc:12943
Change-Id: I2af08255650221c044cc14591a5835c885e94c58
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/259825
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36683}
2022-04-28 08:28:33 +00:00
Florent Castelli
c3e6e3a3e8 Remove dependency on rtc_base_approved from most targets
Bug: webrtc:9838
Change-Id: Ibd0199803597eff48ca139a5cecdc3209c62c5d2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/259873
Auto-Submit: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36643}
2022-04-25 12:15:30 +00:00
Florent Castelli
57aa81bce7 Remove //rtc_base:stringutils from public deps
Bug: webrtc:8603
Change-Id: Ic2dfbe28d310cb4b35983b73e895fc95e8439669
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/257913
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Auto-Submit: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36453}
2022-04-05 22:42:19 +00:00
Florent Castelli
0af55ba60d Remove //rtc_base:logging from public deps
Bug: webrtc:8603
Change-Id: I2704da8618f88032adac7ae9eb2a0f47fce4a836
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/257908
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Auto-Submit: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36443}
2022-04-05 10:31:19 +00:00
Victor Boivie
8beccd5c47 dcsctp: Remove limit of message fragmentation
This was available in the beginning, as a way to increase the chance of
a message sent with partial reliability to be delivered, by avoiding it
to be fragmented in too small fragments.

This however added a few downsides:
 * Packet efficiency goes down, as the entire MTU isn't always used
 * Complexity increases when adding message interleaving, since if one
   stream refuses to produce messages, but there is another stream with
   a very small message that could fit in its place, it should be used
   instead.

Removing this feature altogether is much easier. It's hard to defend.

Bug: webrtc:5696
Change-Id: Ie2f296e052f4a32a281497d379c0d528a2df3308
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/257168
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36396}
2022-03-31 13:47:46 +00:00
Victor Boivie
fbf0ac0ecd dcsctp: Clarify current behavior of stream reset
RFC8831, section 6.7 states that closing a data channel MUST be signaled
as resetting an outgoing stream, and that will ensure that all messages
are either delivered or abandoned before the stream is reset. In the
current implementation, dcSCTP has opted to abandoned any queued
messages that haven't been partially sent.

And this CL simply adds more documentation around this choice. It's
subject to change and a client implementation shouldn't depend on any
such behavior as the RFC allows the implementation to decide.

Bug: None
Change-Id: I60305fe396a6a3f494d823c71e092acfeb6075b7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/257167
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36395}
2022-03-31 13:36:12 +00:00
Victor Boivie
0cfaa610ca dcsctp: Add test case for pending paused streams
This use case was missing test coverage and sufficient comments in the
code.

Bug: None
Change-Id: I95b54a64f714b68a347fdbeef79eb38e715adbc3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/257166
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36393}
2022-03-31 12:20:43 +00:00
Victor Boivie
9848890590 dcsctp: Remove handover_state from RRSendQueue
It's not used as a constructor parameter, but instead invoked by calling
RestoreFromState. Removing this parameter avoids confusion.

Bug: None
Change-Id: I3bb8a0135808e3ae010be6d37439513517f71832
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/254820
Auto-Submit: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Sergey Sukhanov <sergeysu@webrtc.org>
Commit-Queue: Sergey Sukhanov <sergeysu@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36188}
2022-03-14 12:19:56 +00:00
Henrik Boström
b951dc6f4c Allow specifying delayed task precision of dcsctp::Timer.
Context: The timer precision of PostDelayedTask() is about to be lowered
to include up to 17 ms leeway. In order not to break use cases that
require high precision timers, PostDelayedHighPrecisionTask() will
continue to have the same precision that PostDelayedTask() has today.
webrtc::TaskQueueBase has an enum (kLow, kHigh) to decide which
precision to use when calling PostDelayedTaskWithPrecision().

See go/postdelayedtask-precision-in-webrtc for motivation and a table of
delayed task use cases in WebRTC that are "high" or "low" precision.

Most timers in DCSCTP are believed to only be needing low precision (see
table), but the delayed_ack_timer_ of DataTracker[1] is an example of a
use case that is likely to break if the timer precision is lowered (if
ACK is sent too late, retransmissions may occur). So this is considered
a high precision use case.

This CL makes it possible to specify the precision of dcsctp::Timer.
In a follow-up CL we will update delayed_ack_timer_ to kHigh precision.

[1] https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/net/dcsctp/rx/data_tracker.cc;l=340

Bug: webrtc:13604
Change-Id: I8eec5ce37044096978b5dd1985fbb00bc0d8fb7e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/249081
Reviewed-by: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35809}
2022-01-26 18:40:24 +00:00
Victor Boivie
29159ca979 dcsctp: Use c++17 structured bindings
As WebRTC now supports C++17, simplify the code of dcSCTP by binding
return values from std::pair or std::tuple to separate names.

Bug: webrtc:13220
Change-Id: Ie49154ff4c823e1528deaef7e372cbc550923bc2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/246442
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35773}
2022-01-24 13:57:30 +00:00
Victor Boivie
4b7024b572 Revert "dcsctp: Use rtc::CopyOnWriteBuffer"
This reverts commit 2db59a6584eca54245794a0e657ca9ded9e6707f.

Reason for revert: Causes msan-issue in crc32c, reading uninitialized
memory.

Bug: webrtc:12943, chromium:1275559
Change-Id: I05f1012d896aeaca86c4562e0df15fa7ea326d60
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/239560
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35461}
2021-12-02 12:33:46 +00:00
Victor Boivie
2db59a6584 dcsctp: Use rtc::CopyOnWriteBuffer
This avoids copying the payload at all. Future CL will change the
transport.

In performance tests, memcpy was visible in the performance profiles
prior to this change.

Bug: webrtc:12943
Change-Id: I507a1a316165db748e73cf0d58c1be62cc76a2d2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/236346
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35428}
2021-11-29 11:53:19 +00:00
Victor Boivie
42a850d250 dcsctp: Use strong type for MaxRetransmits
It's put in the public folder since the intention is to expose it in
SendOptions.

Additionally, use TimeMs::InfiniteFuture() to represent sending a
message with no limited lifetime (i.e. to send it reliably).

One benefit for these two is avoiding using absl::optional more than
necessary, as it results in larger struct sizes for the outstanding
data chunks.

Bug: webrtc:12943
Change-Id: I87a340f0e0905342878fe9d2a74869bfcd6b0076
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/235984
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35323}
2021-11-08 20:14:15 +00:00
Victor Boivie
71604ebf64 dcsctp: Refactor out OutstandingData
RetransmissionQueue was growing too long (almost 1000 lines), and as
there is reason to believe that more changes are necessary in it for
performance reasons, the data structure that handles managing the
in-flight outstanding data has been extracted as a separate class with
its own test cases. What remains in RetransmissionQueue is that it holds
OutstandingData, fetch data from the SendQueue and manage all congestion
control variables and algorithms.

Bug: webrtc:12943
Change-Id: I46062a774e0e76b44e36c66f836b7d992508bf5f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/235980
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35279}
2021-10-29 09:03:49 +00:00
Victor Boivie
7bb853f549 dcsctp: Remove debug-log-only TSN collection
A vector of which TSNs that were acked for each received SACK was
created, but only used in debug logs, which aren't enabled by default.

Removing them, as they don't add that much value and cost a bit
of performance.

Bug: webrtc:12943
Change-Id: Ice323cf46ca6e469fbbcf2a268ad67ca883bb2f5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/235985
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35265}
2021-10-26 15:11:51 +00:00
Victor Boivie
3f981ee979 dcsctp: Support zero window probing
This is explained in RFC 4960, section 6.1, A.

  ... However, regardless of the value of rwnd (including if it
  is 0), the data sender can always have one DATA chunk in flight to
  the receiver if allowed by cwnd ...  This rule
  allows the sender to probe for a change in rwnd that the sender
  missed due to the SACK's having been lost in transit from the data
  receiver to the data sender.

Before this change, when a receiver has advertised a zero receiver
window size (a_rwnd=0) and a subsequent SACK advertising a non-zero
receiver window was lost, the sender was blocked from sending and since
SACKs are only sent when a DATA chunk is received, it would be
deadlocked. The retransmission timer would fire, but nothing would be
retransmitted (as it respected the zero receiver window).

With this change, when the retransmission timer fires (after RTO), it
would send a single packet with DATA chunk(s) and then SACKs would
eventually be received, with the non-zero receiver window and the socket
would recover.

Bug: chromium:1258225
Change-Id: I1ea62fb3c002150eeada28d3e703dbc09cfd038e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/235280
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35215}
2021-10-15 09:08:24 +00:00
Victor Boivie
adfe54c965 dcsctp: Remove the TCP style cwnd doubling
It wasn't correct and not enabled by default, so just remove it.

Bug: webrtc:12943
Change-Id: Idd426abd0da4ae259e519dd01239b4303296756a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232609
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35075}
2021-09-23 08:06:46 +00:00
Victor Boivie
d68f18ee6e dcsctp: Allow specifying minimum RTT variance
This is mentioned in
https://datatracker.ietf.org/doc/html/rfc4960#section-6.3.1 and further
described in https://datatracker.ietf.org/doc/html/rfc6298#section-4.

The TCP RFCs mentioned G as the clock granularity, but in SCTP it should
be set much higher, to account for the delayed ack timeout (ATO) of the
peer (as that can be seen as a very high clock granularity). That one is
set to 200ms by default in many clients, so a reasonable default limit
could be set to 220 ms.

If the measured variance is higher, it will be used instead.

Bug: webrtc:12943
Change-Id: Ifc217daa390850520da8b3beb0ef214181ff8c4e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232614
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35068}
2021-09-22 20:22:54 +00:00
Victor Boivie
7d7afc6468 dcsctp: Fix accidental re-use of variable
This was caused by change 231229 and was later caught when reviewing the
code. The rtt variable was accidentally re-used for another purpose, and
then assumed to still be used to represent the rtt.

There have been no issues found with this re-use, but it was wrong.

Bug: webrtc:12614
Change-Id: If1a180315cf833e293f78c54c3c3b29394a19a20
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232610
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35064}
2021-09-22 13:27:37 +00:00
Sergey Sukhanov
72435325c6 dcsctp: hand over RRSendQueue streams state
Bug: webrtc:13154
Change-Id: I560b59ad2f5bcd2deafc3a37e3af853108b572b2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232605
Commit-Queue: Sergey Sukhanov <sergeysu@webrtc.org>
Reviewed-by: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35053}
2021-09-21 12:59:46 +00:00
Sergey Sukhanov
3852698ad9 dcsctp: support handover state serialization testing
dcSCTP library users can set their custom
g_handover_state_transformer_for_test that can serialize and
deserialize the state. All dcSCTP handover tests call
g_handover_state_transformer_for_test. If some part of the state is
serialized incorrectly or is forgotten, high chance that it will
fail the tests.

Bug: webrtc:13154
Change-Id: I251a099be04dda7611e9df868d36e3a76dc7d1e1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232325
Commit-Queue: Sergey Sukhanov <sergeysu@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35035}
2021-09-20 10:08:58 +00:00
Victor Boivie
25b5e08094 dcsctp: implement congestion control errata
When re-reading through the errata for RFC4960 in RFC8540, it was found
that two erratas were not applied to dcSCTP:

https://datatracker.ietf.org/doc/html/rfc8540#section-3.11
https://datatracker.ietf.org/doc/html/rfc8540#section-3.12

They are now applied. Re-running throughput tests show no difference.

Bug: webrtc:12943
Change-Id: I9d73d0d257eab8442954924dc414d8efa2c41e8b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232221
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35024}
2021-09-17 10:49:13 +00:00
Victor Boivie
80e96de5ba dcsctp: Add more consistency checks
When there is no outstanding data, then next TSN to allocate should
always be one more than what the client has last ACKed.

Bug: None
Change-Id: Ieb8b5b23912d77d96fe3749fb53fd53652d97066
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232002
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35016}
2021-09-16 13:31:51 +00:00
Sergey Sukhanov
8f486f94e6 dcsctp: support socket handover in RetransmissionQueue
Bug: webrtc:13154
Change-Id: I9c73b1153b65409eb026e015804c22f3e874ff82
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232022
Reviewed-by: Victor Boivie <boivie@webrtc.org>
Commit-Queue: Sergey Sukhanov <sergeysu@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35009}
2021-09-16 05:18:29 +00:00
Victor Boivie
3ed2b8d0b4 dcsctp: Use integer math in RTO calculations
Following Congestion avoidance and control by V. Jacobson at
https://dl.acm.org/doi/10.1145/52324.52356, use integer math instead
of floating point. Not that it matters, but it results in some code size
savings, and is more efficient. Due to not using floating point math,
some golden values in test cases were rounded a bit differently.

Bug: webrtc:12614
Change-Id: I0b7d54b8fd9ce7156e6b2582437ef5720f8838ea
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/231229
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#34956}
2021-09-08 22:06:04 +00:00
Victor Boivie
9680d29e8d dcsctp: Support unlimited max_retransmissions
The restart limit for timers can already be limitless, but the
RetransmissionErrorCounter didn't support this. With this change, the
max_retransmissions and max_init_retransmits can be absl::nullopt to
indicate that there should be infinite retries.

Bug: webrtc:13129
Change-Id: Ia6e91cccbc2e1bb77b3fdd7f37436290adc2f483
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/230701
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#34882}
2021-08-31 10:57:48 +00:00
Victor Boivie
3ec9e03f73 dcsctp: Removing all references to unordered_map
Replacing with std::map and webrtc::flat_map where applicable.

Bug: webrtc:12689
Change-Id: Id0fdb88bd3d52957b1616911eb487fc581d3b7d8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/229182
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34797}
2021-08-18 19:55:07 +00:00
Victor Boivie
14ef6338b0 dcsctp: Don't send small packets when cwnd full
The congestion window is unlikely to be even divisible by the size
of a packet, so when the congestion window is almost full, there is
often just a few bytes remaining in it. Before this change, a small
packet was created to fill the remaining bytes in the congestion window,
to make it really full.

Small packets don't add much. The cost of sending a small packet is
often the same as sending a large one, and you usually get lower
throughput sending many small packets compared to few larger ones.'

This mode will only be enabled when the congestion window is large, so
if the congestion window is small - e.g. due to poor network conditions,
it will allow packets to become fragmented into small parts, in order to
fully utilize the congestion window.

Bug: webrtc:12943
Change-Id: I8522459174bc72df569edd57f5cc4a494a4b93a8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/228526
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34778}
2021-08-17 09:03:36 +00:00
Victor Boivie
be9281b92b dcsctp: Increase cwnd by serialized chunk size
For symmetry, as the outstanding_bytes is increased/decreased by
the serialized chunk size (not just the payload) - which is compared
to the congestion window, the congestion window should be increased
by the serialized size of chunks acked - not just their payload.

Bug: webrtc:12943
Change-Id: I0a06033e8ca0d58433138df6442ca80494918cf2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/228525
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34775}
2021-08-17 07:04:26 +00:00
Victor Boivie
d912446f52 dcsctp: Refactor chunk acking
The same code was done for both acking chunks due to moving the
cum-ack-tsn and when acking gap-ack-blocks. Unify them completely
to have a single code path.

Bug: webrtc:12943
Change-Id: I3b864e41cc2ec674460517660c23b72a70edf720
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/228521
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34773}
2021-08-16 20:20:55 +00:00
Victor Boivie
82ea522b27 dcsctp: Track the number of inflight DATA items
This corresponds to one part of sstat_unackdata in RFC6458. The
remaining part is the data in the send queue, which isn't packetized
yet, so it must be estimated. But the DATA items in the retransmission
queue is already determined, so it can be easily tracked and retrieved.

Bug: webrtc:13052
Change-Id: I16c3b5b61eb6b3022d7104e6457d943d5df3d6b9
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/228240
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34706}
2021-08-10 18:00:26 +00:00
Victor Boivie
bf15e567e8 dcsctp: Abandon chunks consistently
The previous logic to abandon chunks when partial reliability was used
was a bit too eager and trigger happy.

 * Chunks with limited retransmissions should only be abandoned when a
   chunk is really considered lost. It should follow the same rules as
   for retransmitting chunks - that it must be nacked three times or
   due to a T3-RTX expiration. Before this change, a single SACK not
   referencing it would be enough to abandon it. This resulted in a lot
   of unnecessary sent FORWARD-TSN and undelivered messages - especially
   if running with zero retransmissions.

   The logic to expire chunks by limited retransmissions will now only
   be applied when a chunk is actually nacked.

 * The second partial reliability trigger - expiration time - wasn't
   evaluated when producing a middle chunk of a larger message.

A number of test cases were added and updated as chunks will now be
abandoned immediately instead of first scheduled for retransmission and
later abandoned.

Bug: webrtc:12961
Change-Id: I0ae17b2672568bdbdc32073a99d4c24b09ff5fe9
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/225548
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34458}
2021-07-12 22:47:51 +00:00
Victor Boivie
8bd26e12ed dcsctp: Only reset paused streams when peer acks
When a single stream is reset, and an outgoing SSN reset request is sent
and later acked by the peer sending a reconfiguration response with
status=Performed, the sender should unpause the paused stream and reset
the SSNs of that (ordered) stream. But only the single stream that was
paused, and not all streams. In this scenario, dcSCTP would - when the
peer acked the SSN reset request - reset the SSN of all streams.

This was found by orphis@webrtc.org using a data channel test
application. The peer, if it's a usrsctp client, will ABORT with
PROTOCOL_VIOLATION as it has already seen that SSN on that stream but
with a different TSN.

This bug was introduced when implementing the Round Robin scheduler in
https://webrtc-review.googlesource.com/c/src/+/219682. The FCFS
scheduler prior to this change was implemented correctly.

Bug: webrtc:12952
Change-Id: I3ea144a1df303145f69a5b03aada7f448c8c8163
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/225266
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34436}
2021-07-08 10:49:11 +00:00
Victor Boivie
1c7ff0d001 dcsctp: Stay in stream if not producing fragment
If there is only little space left in a packet, and the remaining data
for a partially sent message is much larger, it will not generate a
small fragment for this message. This is to avoid fragmenting a message
into too many packets, as that increases the risk of losing messages
when partial reliability is enabled.

And when a stream doesn't want to generate a too small fragment, the
scheduler should _not_ switch streams. It should only switch streams
when a message has been fully sent. Previously, it would switch stream
when a stream doesn't want to produce a message, but as noted above,
that could happen for other reasons.

This required some refactoring, which also increased its robustness by
now only doing explicit stream switching on fully produced messages.

Bug: webrtc:12832
Change-Id: Icb213774fd0d26fba5640b00aac0407d393e4bfc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/220937
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34197}
2021-06-02 09:45:59 +00:00
Victor Boivie
803fdc4106 dcsctp: Stay within stream while producing from it
The way that the "next stream" was picked when round-robin cycling was
flawed. When a message was produced in its entirety, the "next stream"
would be put at a stream identifier value that was just larger than what
was previously used. And then, for each fragment that was to be created,
it would try to resolve the nearest stream (above or equal to that
number) that had messages to send - always starting from that stream id
that didn't necessarily point to the stream for which fragments were
actually produced.

For example, if the previous stream ID for which a message was fully
produced on was 5, then the next_stream_id would be set to 6, and then
when producing next fragment, it might have produced something from
stream_id=1, because that was the only stream with messages in it. It
wouldn't update next_stream_id at this time; it would still be 6.

After a single fragment had been produced from that stream, a message
was queued on stream_id=6. The next time a fragment was to be produced,
it would not continue one stream_id=1, but instead pick the new stream,
which would suddenly produce a new fragment (with B flag set) while the
previous message (from stream_id=1) wasn't finished yet.

The fix is simple; Just ensure that we continue iterating from where we
ever produce a fragment from.

Bug: webrtc:12832
Change-Id: Icc761c572ed200db607a7609dab1ac6a8aeb2f04
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/220938
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34190}
2021-06-01 17:24:06 +00:00