There was a feature in the retransmission queue to avoid fragmenting
large messages when the congestion window was large. This was a feature
that intended to improve data channel performance under Chrome, where
communication with the network process (over MOJO) was lossy and losing
messages with small fragments could result in unnecessary
retransmissions. But back then, the implementation for fast retransmit
wasn't implemented correctly, so the benchmarking result don't
reproduce any longer.
So just improve the algorithm by removing this code. This aligns it with
the RFC and makes it easier to implement pluggable congestion control
algorithms (that wouldn't want this feature).
Bug: webrtc:42223116
Change-Id: Ifaaa82dac4b8fe2f55418158ae8b3da97199212f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/359681
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42797}
Since the code measuring the RTT has been converted to using TimeDelta
which internally stores the duration in microseconds, from DurationMs
which uses milliseconds, the RTO calculation can use the higher
precision to calculate lower non-zero durations on really fast networks
such within a data center.
Before this CL, which is from the initial drop of dcSCTP, the RTO
calculation was done using the algorithm from the paper "V. Jacobson:
Congestion avoidance and control", but now we're using the original
algorith from https://tools.ietf.org/html/rfc4960#section-6.3.1, which
comes from https://datatracker.ietf.org/doc/html/rfc6298#section-2.
Two issues were found and corrected:
1. The min RTT variance that is specified in the config file was
previously incorrectly divided by 8. That was not its intention,
but we're keeping that behaviour as other clients have actually
measured a good value to put there. This represents "G" in
the "basic algorithm" above, and since that is multiplied with K,
which is four, the default value of 220 wouldn't make sense if it
wasn't scaled down, as that would make the RTO easily saturate to
the RTO_max (800ms).
2. The previous algorithm had large round-off errors (probably because
the code used milliseconds), which makes fairly big changes to the
calculated RTO in some situations.
Bug: webrtc:15593
Change-Id: I95a3e137c2bbbe7bf8b99c016381e9e63fd01d87
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/349000
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42170}
Keeping the old setting for the total queue size
limit, which avoids breaking a downstream.
This reverts commit 47ce449afaf9ba38785437fdd338630cad24a77b
and relands commit 4c990e2e56157175324e651f95f3d8c6a0e5c030.
Bug: chromium:40072842
Change-Id: I1e7d14b5d0026232d1fc9277172b6947b8be3490
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/343120
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41907}
This reverts commit 4c990e2e56157175324e651f95f3d8c6a0e5c030.
Reason for revert: Breaks downstream build.
Original change's description:
> dcsctp: Add per-stream-limit, refactor limits.
>
> The limits have been moved out from the Send Queue as they were enforced
> outside the queue anyway (in the socket). That was a preparation for
> adding even more limits; There is now also a per-stream limit, allowing
> individual streams to have one (global) limit, and the entire socket to
> have another limit.
>
> These limits are very small in the default options. In Chrome, the limit
> is 16MB per stream, so expect the defaults to be updated when the
> additional buffering outside dcSCTP is removed.
>
> Bug: chromium:41221056
> Change-Id: I9f835be05d349cbfce3e9235d34b5ea0e2fe87d1
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/342481
> Reviewed-by: Florent Castelli <orphis@webrtc.org>
> Commit-Queue: Victor Boivie <boivie@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#41895}
Bug: chromium:41221056
Change-Id: Icd57fbfca87d6b512cfc7f7682ae709000c2bcad
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/343080
Commit-Queue: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Victor Boivie <boivie@webrtc.org>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#41901}
The limits have been moved out from the Send Queue as they were enforced
outside the queue anyway (in the socket). That was a preparation for
adding even more limits; There is now also a per-stream limit, allowing
individual streams to have one (global) limit, and the entire socket to
have another limit.
These limits are very small in the default options. In Chrome, the limit
is 16MB per stream, so expect the defaults to be updated when the
additional buffering outside dcSCTP is removed.
Bug: chromium:41221056
Change-Id: I9f835be05d349cbfce3e9235d34b5ea0e2fe87d1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/342481
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41895}
This will be done by splitting the use of variables values prior to performing std:move
Bug: webrtc:15771
Change-Id: Ia88e733c3a4edf729e440295ae271d3cd9926ec5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/334461
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41532}
OutstandingData::NackItem nacks a chunk, and if that chunk reaches its
partial reliability critera, it will abandon the entire message. If that
message hasn't been sent in full, a placeholder "end" message is
inserted (see https://crbug.com/webrtc/12812). And when the message is
inserted, any iterators may be invalidated (if e.g. std::deque would
want to grow the deque).
So ensure that there are no iterators used after having called NackItem.
By changing the interface of NackItem, and not passing an Item, but just
the TSN, this is encouraged. NackAll was rewritten as a two-pass
algorithm to first collect TSNs, then iterating that list, looking up
the items in the second pass (constant complexity).
Bug: chromium:1510364
Change-Id: I5156b6d6a683184f290e71c98f16bc68ea2a562f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/331320
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41374}
And the same for outstanding items, which become unacked items. The old
names were unfortunate - especially since they were managed by a class
called OutstandingData.
To make this less complicated, these variables have been renamed to
something that is easier to understand; "Unacked bytes/items". Simply
what has been sent but hasn't been acked or nacked yet. So likely what's
in-flight, but could possibly be lost and not found to be lost yet.
Bug: None
Change-Id: I877d7f2cac5d164bf2f9f66cb32ae1f6d850ad2c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/329761
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41313}
A std::map is a fairly inefficient data structure. Accessing an item
is O(log(N)), but as every item is a separate allocation, iterating it
and searching for items is not very kind to the data caches.
As the outstanding data is a contiguous list (no gaps) where you only
append to the end and remove from the front, use a std::deque instead.
Bug: webrtc:15699
Co-authored-by: Daniel Collins <dpcollins@google.com>
Change-Id: I1f5fe97d06204c75b2b9553856af24e50f2ce715
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/329422
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41310}
Before this CL, the next_tsn was stored as a variable, but that was
not needed as it can be calculated from the higest outstanding TSN. The
next TSN is simply the value after the highest outstanding TSN.
The highest outstanding TSN calculation could be simplified as well,
as the outstanding_data_ is contiguous list of TSNs counted from
last_cumulative_tsn_ack_.
Bug: None
Change-Id: Iafe188683427b5f2959d5ce2b19b5943d4760791
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/329421
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41303}
A similar function was defined in rtc_base/openssl_adapter. Moving it from net/dcsctp/common/ to rtc_base/strings/. I'm planning to use StrJoin in a video codec test (a follow-up change).
Bug: webrtc:14852
Change-Id: Ie657c03e7f9fb52c189c127af6f66ec505b512ae
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/327322
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41166}
While this is a fairly big CL, it's fairly straightforward. It replaces
uses of TimeMs with webrtc::Timestamp, and additionally does some
cleanup of DurationMs to webrtc::TimeDelta that are now easier to do.
Bug: webrtc:15593
Change-Id: Id0e3edcba0533e0e8df3358b1778b6995c344243
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/326560
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41138}
With this, the code base should be mostly converted from using
DurationMs to rtc::TimeDelta, and the work can continue to replace
TimeMs with rtc::Timestamp.
Bug: webrtc:15593
Change-Id: I083fee6eccb173efc0232bb8d46e2554a5fbee5b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/326161
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41101}
It's still doing the calculations in milliseconds, which will be updated
in follow-up CLs.
Bug: webrtc:15593
Change-Id: I7fb93d4687d58f409db182db40db720d82feb3dd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/325524
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41074}
This commit replaces the internal use of DurationMs, with millisecond
precision, to webrtc::TimeDelta, which uses microsecond precision.
This is just a refactoring. The only change to the public API is
convenience methods to convert between DurationMs and webrtc::TimeDelta.
Bug: webrtc:15593
Change-Id: Ida861bf585c716be5f898d0e7ef98da2c15268b7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/325402
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41062}
When a timer expires, it can optionally return a new expiration value.
Clearly, that value can't be zero, as that would make it expire
immediately again.
To simplify the interface, and make it easier to migrate to
rtc::TimeDelta, change it from an optional value to an always-present
value that - if zero - means that the expiration time should be
unchanged.
This is just an internal refactoring, and not part of any external
interface.
Bug: webrtc:15593
Change-Id: I6e7010d2dbe774ccb260e14fd6b9861c319e2411
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/325281
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41045}
Before this CL, a message was identified by the triple (stream_id,
is_unordered, MID) (and yes, the MID is always present in the send
queue, even when interleaved message is not enabled.). So when a chunk
was abandoned due to e.g. having reached the retransmission limit, all
other chunks for that message in the retransmission queue, and all
unsent chunks in the send queue were discarded as well.
This works well, except for the fact that resetting a stream will result
in the MID being set to zero again, which can result in two different
messages having the same identifying triple. And due to the
implementation, both messages would get abandoned.
In WebRTC, an entire data channels is either reliable or unreliable, and
for a message to be abandoned, the channel must be unreliable. So this
means that in the case of stream resets - meaning that a channel was
closed and then reopened, an abandoned message from the old (now closed)
channel would result in abandoning another message sent on the re-opened
data channel.
This CL introduces a new internal property on messages while in the
retransmission and send queue; The "outgoing message id". It's a
monotonically increasing identifier - shared among all streams - that is
never reset to zero in the event of a stream reset. And now a message is
actually only identified by the outgoing message id, but often used
together with the stream identifier, as all data in the send queue is
partitioned by stream. This identifier is 32 bits wide, allowing at most
four billion messages to be in-flight, which is not a limitation, as the
TSN is also 32 bits wide.
Bug: webrtc:14600
Change-Id: I33c23fb0e4bde95327b15d1999e76aa43f5fa7db
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/322603
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40881}
MID is a RFC8260 property on an I-DATA chunk, replacing the SSN property
on the DATA chunk in non-interleaved message. The MID stands for
"Message Identifier", and it was frequently named "message_id" in the
source code, but sometimes "mid". To be consistent and using the same
terminology as is most common in the RFC, use "mid" everywhere.
This was triggered by the need to introduce yet another "message
identifier" - but for now, this is just a refacotring CL.
Bug: None
Change-Id: I9cca898d9f3a2f162d6f2e4508ec1b4bc8d7308f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/322500
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40876}
This was a fun bug which proved to be challenging to find a good
solution for. The issue comes from the combination of partial
reliability and stream resetting, which are covered in different RFCs,
and where they don't refer to each other...
Stream resetting (RFC 6525) is used in WebRTC for closing a Data
Channel, and is done by signaling to the receiver that the stream
sequence number (SSN) should be set to zero (0) at some time. Partial
reliability (RFC 3758) - and expiring messages that will not be
retransmitted - is done by signaling that the SSN should be set to a
certain value at a certain TSN, as the messages up until the provided
SSN are not to be expected to be sent again.
As these two functionalities both work by signaling to the receiver
what the next expected SSN should be, they need to do it correctly not
to overwrite each others' intent. And here was the bug. An example
scenario where this caused issues, where we are Z (the receiver),
getting packets from the sender (A):
5 A->Z DATA (TSN=30, B, SID=2, SSN=0)
6 Z->A SACK (Ack=30)
7 A->Z DATA (TSN=31, E, SID=2, SSN=0)
8 A->Z RE_CONFIG (REQ=30, TSN=31, SID=2)
9 Z->A RE_CONFIG (RESP=30, Performed)
10 Z->A SACK (Ack=31)
11 A->Z DATA (TSN=32, SID=1)
12 A->Z FORWARD_TSN (TSN=32, SID=2, SSN=0)
Let's assume that the path Z->A had packet loss and A never really
received our responses (#6, #9, #10) in time.
At #5, Z receives a DATA fragment, which it acks, and at #7 the end of
that message. The stream is then reset (#8) which it signals that it
was performed (#9) and acked (#10), and data on another stream (2) was
received (#11). Since A hasn't received any ACKS yet, and those chunks
on SID=2 all expired, A sends a FORWARD-TSN saying that "Skip to TSN=32,
and don't expect SID=2, SSN=0". That makes the receiver expect the SSN
on SID=2 to be SSN=1 next time at TSN=32.
But that's not good at all - A reset the stream at #8 and will want to
send the next message on SID=2 using SSN=0 - not 1. The FORWARD-TSN
clearly can't have a TSN that is beyond the stream reset TSN for that
stream.
This is just one example - combining stream resetting and partial
reliability, together with a lossy network, and different variants of
this can occur, which results in the receiver possibly not delivering
packets because it expects a different SSN than the one the sender is
later using.
So this CL adds "breakpoints" to how far a FORWARD-TSN can stretch. It
will simply not cross any Stream Reset last assigned TSNs, and only when
a receiver has acked that all TSNs up till the Stream Reset last
assigned TSN has been received, it will proceed expiring chunks after
that.
Bug: webrtc:14600
Change-Id: Ibae8c9308f5dfe8d734377d42cce653e69e95731
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/321600
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40829}
The log_prefix frequently used in dcSCTP is intended to be used
to separate logs from different sockets within the same log output,
typically in unit tests. Every log entry always has the file and
line, so it's not important to add more information to the log prefix
that indicates _where_ it's logged. So those have been removed.
Also, since log_prefix is a string (typically 32 bytes) and it's
never changing during the lifetime of the socket, pass and store it
as a absl::string_view to save memory.
Bug: None
Change-Id: I10466710ca6c2badfcd3adc5630426a90ca74204
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/274704
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39571}
The RTT will quickly be updated whenever a DATA chunk is acked, but
the initial value was set to zero. In unit tests, which often are
short and rarely increase the simulated time between a DATA is sent,
and acked, the smoothed RTT would usually stay at 0, which causes
e.g. the rate limiting of FORWARD not to work.
Bug: None
Change-Id: Ieb515fe875ce88d001777b00d6efd9762565a09d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/273900
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38013}
This adds the final piece, which makes the socket and the retransmission
queue generate the callbacks.
Bug: webrtc:5696
Change-Id: I1e28c98e9660bd018e817a3ba0fa6b03940fcd33
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/264125
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37455}
For all messages where the last fragment was _not_ put on the wire, the
send queue is responsible for generating lifecycle events, but once all
fragments have been put on the wire, it's the retransmission queue that
is responsible. It does that by marking the final fragment of a message
with the lifecycle identifier, and once that message has been fully
acked by the cumulative ack TSN, it's clear that the peer has fully
received all fragments of the message, as the last fragment was acked.
For abandoned messages - where FORWARD-TSNs are sent, those will be
replied to by a SACK as well, and then we report abandoned messages
separately, to later trigger `OnLifecycleMessageExpired`.
This CL adds support in OutstandingData, which doesn't generate the
callbacks itself, but just reports them in the AckInfo.
Bug: webrtc:5696
Change-Id: I64092f13bcfda685443b7df9967b04d54aedd36a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/264124
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37448}
The send queue is responsible for generating lifecycle events for all
messages that are still in the queue. Because, if they are still in the
queue, that means that the last fragment of the message hasn't been sent
yet (because then it would have been in the retransmission queue
instead). And if the last fragment hasn't been sent, the send queue is
responsible for generating the
`OnLifecycleMessageExpired(/*maybe_sent=*/false)` event.
Bug: webrtc:5696
Change-Id: Icd5956d6aa0f392cae54f2a05bd20728d9f7f0a6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/264144
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37419}
Minor refactoring of the API, to put optional arguments last. Also
changed internal structures to reflect that order, for consistency.
Also reduced size of Item from 88 to 72 bytes, by packing fields better.
Bug: webrtc:5696
Change-Id: I1b9d50831a8e9a358224682d06a782a3269b8416
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/264123
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37403}
Let the OutgoingStream reference the parent instead of passing
references to individual items it needs, as follow-up CLs will add even
more items.
No functional change - pure refactoring.
Bug: webrtc:5696
Change-Id: I914e590c0d90e898d7d230a16170cf4faff2338c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/264142
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37398}
Before this CL, some components, e.g. the SendQueue, was first created
and then later restored from handover state, while some were created from
the handover state, as an optional parameter to their constructors.
This CL will make it consistent, by always creating the components in a
pristine state, and then modifying it when restoring them from handover
state. The name "RestoreFromState" was used to be consistent with SendQueue
and the socket.
This is just refactoring.
Bug: None
Change-Id: Ifad2d2e84a74a12a93abbfb0fe1027ebb9580e73
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/267006
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37384}
This adds support to enable message interleaving in the stream scheduler
from the socket, proxied by the send queue.
It also adds socket unit tests to ensure that prioritization and
interleaving works. Also, send queue test has been added to validate the
integration of the stream scheduler. But the actual scheduling parts of
it will be tested in the stream scheduler unit tests.
Bug: webrtc:5696
Change-Id: Ic7d3d2dc28405c77a107f0148f0096882961eec7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262248
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37355}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}