The dcSCTP receiver was advertising available window space (arwnd) based
solely on payload bytes, while the sender's rwnd estimation included
packet headers. This mismatch caused the sender to underestimate the
receiver's available buffer, potentially leading to reduced throughput.
This commit resolves the issue by ensuring both sender and receiver use
payload bytes, as headers have been removed on the receiver side while
in the reassembly queue.
Bug: webrtc:396373001
Change-Id: I508419efb09cabf2fb011f952f5f4a06586a4019
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/377122
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43899}
To reduce latency when delivering messages on channel with low traffic
volume and with packet loss, where retransmissions are not driven by
fast retransmit but by T3-RTX timer, set the I-SACK bit (RFC7053) when
the congestion window is low.
Note that RFC7053 doesn't have to be negotiated, as is explained in
https://www.rfc-editor.org/rfc/rfc7053.html#section-6, and if the
receiver doesn't support it, it will delay SACKs as is done today.
When T3-RTX fires, the congestion window will be set to one MTU and any
future sent message will only send one MTU's worth of data before waiting
for the receiver's SACK until more data is sent. Delayed SACK, which is
normally used, could delay the next packet from being sent unecessarily
long. Setting I-SACK when the congestion window is small will make the
receiver always send a SACK for every received packet with a DATA chunk
in it. By not setting it always, it will not affect the packet rate when
the channel is fully utilized.
This modification improves latency in the aforementioned situations
without significantly affecting bandwidth. While this change increases
SACK frequency in specific scenarios, the impact on overall network load
is expected to be minimal.
Bug: webrtc:396080535
Change-Id: If4a5aa960969f1385c9ea59baa7e2d52caf25626
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/377140
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43897}
A few tests in dcsctp_socket_test was named DcSctpSocketResendInitTest
instead of DcSctpSocketTest. There is no reason for that.
Bug: None
Change-Id: I845eb0ab6150c4e5d457307e12f056486f86e468
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/369820
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43470}
This is a rollback of a change list [1] that was an attempt to avoid a
bug in usrsctp[2], but it wasn't very successful. But with the usrsctp
bug fixed, we can revert to the desired state; that we bundle
FORWARD-TSN with other control and data chunks in a SCTP packet.
[1] https://webrtc-review.googlesource.com/c/src/+/229101
[2] https://github.com/sctplab/usrsctp/issues/597
Bug: webrtc:42223134
Change-Id: I2f3b511c91639e6b9516160190600beb0c04b5fa
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/361862
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42976}
This was unintentionally removed in change
https://webrtc-review.googlesource.com/c/src/+/359681 due to a dirty
workspace.
Re-adding it.
Bug: None
Change-Id: Icff55b7a656ed9b504b0e10e7aeb947e8df78e85
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/360540
Auto-Submit: Victor Boivie <boivie@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42846}
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}
e.g all files in the api/test folder not including subdirectories
Bug: webrtc:42226242
Change-Id: I18d74a18f8feec41eb252faa9acfffd1d6f45ce4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/359420
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Dor Hen <dorhen@meta.com>
Cr-Commit-Position: refs/heads/main@{#42773}
The elements in it can be packet better. This saves one byte.
The state cookie is only used from one peer to itself, so there is no
considerations around backwards or forwards compatibility.
Bug: None
Change-Id: I4f9a44f4c825626c7ed84bff52ed3155f5025a69
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/353142
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Auto-Submit: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42421}
Before this change, the heartbeat timer was restarted every time a
packet was sent on the socket. On an idle connection, if the peer is
sending heartbeats, just responding to those heartbeats (with a
HEARTBEAT-ACK) would restart the timer, and then this socket wouldn't
do any heartbeating itself because the next hearbeat by the peer would
be received before the timer expires.
This is not according to the specification, where
https://datatracker.ietf.org/doc/html/rfc9260#section-8.3 states that
"A destination transport address is considered "idle" if no new chunk
that can be used for updating path RTT (usually including first
transmission DATA, INIT, COOKIE ECHO, or HEARTBEAT chunks, etc.)"
There are already timers running when INIT, and COOKIE-ECHO are sent
and not acked, so the heartbeat shouldn't be sent then. This is further
confirmed in the same section in the RFC which says that "The sending of
HEARTBEAT chunks MAY begin upon reaching the ESTABLISHED state". And
when INIT and COOKIE-ECHO are sent, the connection is not yet
established.
This CL changes so that the heartbeat timer is only restarted when any
DATA or I-DATA chunk is sent. This will make both sides send heartbeats
on an idle connection.
Bug: webrtc:343600379
Change-Id: I5ab159b7901e2ec9d37b24aaf845891b60a53c13
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/352841
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42409}
Replace usage of BuiltInNetworkBehaviorConfig.link_capacity_kbps in tests with DataRate link_capacity.
Bug: webrtc:14525
Change-Id: Id1c1b8d20eb2be5e9d1461704bb7c37c61c491f0
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/350300
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42306}
Old target and call/simulated.h exist but refer to new target in test/network.
Bug: webrtc:14525
Change-Id: Ida04cef17913f2f829d7e925ae454dc40d5e8240
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/349264
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Owners-Override: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42191}
With a previous refactoring, which made the data tracker responsible for
ensuring that the reassembly queue doesn't see any duplicate received
chunks, it no longer needs to know the initial peer's TSN. Removing.
Bug: None
Change-Id: I0e2aef1de0293f1860b46dee0089757c9c300aea
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/345701
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41997}
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}
https://datatracker.ietf.org/doc/draft-ietf-tsvwg-sctp-zero-checksum/06/
The previous implementation was for version 00, and since then changes
have been made. The chunk that is used to negotiate this capability has
now grown to include an additional property - the sender's alternate
error detection method.
Bug: webrtc:14997
Change-Id: I78043d187b79f40bbadbcba02eae6eedf54f30f9
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336380
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41759}
The DcSctpSocket is thread compatible. As long as you serialize accesses
to it - either by calling it from the same thread, or using some kind of
concurrency primitive (e.g. mutex) to avoid calling the API methods from
different threads concurrently, it's fine.
Using the sequence checker, we can verify that the socket is called from
the thread it was created on, or from the same task queue. This provided
a more strict verification, as it didn't allow e.g. creating a socket on
one thread, and then handing it to a different thread where it was used.
Nor did it allow having multiple threads use it, protecting any calls to
it using an external mutex.
One can avoid these checks using webrtc::CurrentTaskQueueSetter to allow
the sequence checker to believe it's running where it's not running, but
this is a hack.
This CL removes the sequence checker in the socket, to simplify using it
in environments that don't use task queues for synchronization. Since it
is still kept in dcsctp::TaskQueueTimeoutFactory, it's still used in all
environments where the task queue is used (e.g. Chrome).
This makes it easier to use dcSCTP without WebRTC.
Bug: None
Change-Id: I2674d7cd902bad45ed3d0816c908ecf3ee971727
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/333801
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41482}
The push_back pattern results in frequent vector growth which has performance overhead. This is .5% of our server's CPU
Bug: webrtc:15723
Change-Id: Ic151c81a4b49a7d48a354b75f62694bc6f9a1ee4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/331440
Reviewed-by: Victor Boivie <boivie@webrtc.org>
Commit-Queue: Daniel Collins <dpcollins@google.com>
Cr-Commit-Position: refs/heads/main@{#41388}
This should substantially reduce the overhead due to deferred callbacks in profiles.
Bug: webrtc:15723
Change-Id: I4c52beb91eb08c9b0ac2d1ce9a4e11839aa35e38
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/331020
Reviewed-by: Victor Boivie <boivie@webrtc.org>
Commit-Queue: Daniel Collins <dpcollins@google.com>
Cr-Commit-Position: refs/heads/main@{#41363}
In the example below, the association is being established between peer
A and Z, and A is the initiating party.
Before this CL, when an association was about to be established, Z would
after having received the INIT chunk, persist state in the socket about
which verification tag and initial TSN that was picked. These would be
re-generated on every incoming INIT (that's fine), but when A had
extracted the cookie from INIT_ACK and sent a reply (COOKIE_ECHO) with
the state cookie, that could fail validation when it's received by Z, if
the sent cookie was not the most recent one or if the COOKIE_ECHO had a
verification tag coming not from the most recent INIT_ACK, because Z had
replaced the state in the socket with the one generated when the second
INIT_ACK chunk was generated - state it used for validation of future
received data.
In other words:
A -> INIT 1
<timeout>
A -> INIT 2 (retransmission of INIT 1)
INIT 1 -> Z - sends INIT_ACK 1 with verification_tag=1, initial_tsn=1,
cookie 1 (and records these to socket state)
INIT 2 -> Z - sends INIT_ACK 2 with verification_tag=2, initial_tsn=2,
cookie 2 (replaces socket state with the new data)
INIT_ACK 1 -> A -> sends COOKIE_ECHO with verification_tag=1, cookie 1
COOKIE_ECHO (cookie 1) -> Z <FAILS, as the state isn't as expected>.
The solution is really to do what RFC4960 says, to not maintain any
state as the receiving peer until COOKIE_ECHO has been received. This
was initially not done because the underlying reason why this is
important in SCTP is to avoid denial of service, and this is why SCTP
has the four-way handshake. But for Data Channels - SCTP over DTLS -
this attack vector isn't available. So the implementation was
"simplified" by keeping socket state instead of encoding it in the
state cookie, but that obviously had downsides.
So with this CL, the non-initiating peer in connection establishment
doesn't keep any socket state, and puts all that state in the state
cookie instead. This allows any COOKIE_ECHO to be received by Z.
Bug: webrtc:15712
Change-Id: I596c7330ce27292612d3c9f86b21c712f6f4e408
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/330440
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41340}
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 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}
This callback is identical to TimeMillis, but returns a
webrtc::Timestamp instead of a TimeMs.
When all callers have migrated to Now() (and all dcsctp code),
TimeMillis will be removed.
Bug: webrtc:15593
Change-Id: I608387607537f29989736af5bf98c7f184f52ebc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/326500
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41127}
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}
This does the bulk of the remaining refactoring, except timers since
they are an even bigger part - but more isolated.
Bug: webrtc:15593
Change-Id: I7afa349e2119be7592797ee6b3b198e6de4f697a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/326160
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41090}
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 change, a timer could have an optional max duration. Either
that value was present, and that limited the max duration of the timer,
or it was absl::nullopt, which represented "no limit".
To simplify the interface, this CL makes that value "not optional" by
having it always present. The previous "no limit" is now represented by
DurationMs::InfiniteDuration.
This is just a refactoring of internal interfaces - public interfaces
are left untouched.
Bug: webrtc:15593
Change-Id: I80df1d9b2f4d208411ce6cb5045db0a57865e3b4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/325280
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41040}
When a sender has requested a stream to be reset, and the last sender
assigned TSN hasn't been received yet, the receiver will enter deferred
reset mode, where it will store any data chunks received after that
given TSN, and replay those later, when the stream has been reset.
Before this CL, leaving deferred mode was done as soon as the sender's
last assigned TSN was received. That's actually not how the RFC
describes the process[1], but was done that way to properly handle some
sequences of RE-CONFIG and FORWARD-TSN. But after having read the RFCs
again, and realizing that whenever RFC6525 mention "any data arriving",
this also applies to any FORWARD-TSN[2] - it's better to reset streams
synchronously with the incoming requests, and defer not just DATA past
the sender last assigned TSN, but also any FORWARD-TSN after that TSN.
This mostly simplifies the code and is mostly a refactoring, but most
importantly aligns it with how the resetting procedure is explained in
the RFC. It also fixes two bugs:
* It defers FORWARD-TSN *as well as* DATA chunks with a TSN later
than the sender's last assigned TSN - see test case. The old
implementation tried to handle that by exiting the deferred reset
processing as soon as it reached the sender's last assigned TSN, but
it didn't manage to do that in all cases.
* It only defers DATA chunks for streams that are to be reset, not
all DATA chunks with a TSN > sender's last assigned TSN. This was
missed in the old implementation, but as it's now implemented
strictly according to the RFC, this was now done.
[1] https://datatracker.ietf.org/doc/html/rfc6525#section-5.2.2
[2] RFC6525 cover stream resetting, and RFC3758 cover FORWARD-TSN, and
the combination of these is not covered in the RFCs.
Bug: webrtc:14600
Change-Id: Ief878b755291b9c923aa6fb4317b0f5c00231df4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/322623
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40889}
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}
Similar to change I602a8552a9a4c853684fcf105309ec3d8073f2c2, which
ensured that only new DATA chunks would be processed by the reassembly
queue by utilizing the data tracker, the same is done for FORWARD-TSN
chunks.
By having the data tracker gate keeping what is provided to the
reassembly queue, the reassembly queue can be simplified as well, which
is an added bonus, by removing last_assembled_tsn_watermark_ and
reassembled_messages_ as those were protecting the queue from
re-delivering messages it had already delivered, but as now the data
tracker would ensure that it wouldn't re-process DATA/FORWARD-TSNs, that
would have the same effect. In this CL, we will still update those
variables and save to the handover state, but not actually read from
them, and then when this change has been rolled out on the servers, I
can remove the variables as well.
The core change is to move validation from ReassemblyQueue::Handle
to DataTracker::HandleForwardTsn.
Some tests have been moved/replicated into data_tracker_test.cc to
ensure that it catches the issues that the reassembly queue did earlier.
Bug: webrtc:14600
Change-Id: I75c1d5911185d594f73c8b1e6bcf776e88f5b7c7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/321603
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40856}
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}
https://datatracker.ietf.org/doc/html/rfc6525#section-5.2.2:
E2: If the Sender's Last Assigned TSN is greater than the cumulative
acknowledgment point, then the endpoint MUST enter "deferred
reset processing". ... until the cumulative
acknowledgment point reaches the Sender's Last Assigned TSN.
The cumulative acknowledgement point can not only be reached by
receiving DATA chunks, but also by receiving a FORWARD-TSN that
instructs the receiver to skip them. This was only done for DATA and not
for FORWARD-TSN, which is now corrected.
Additionally, an unnecessary implicit sending of SACK after having
received FORWARD-TSN was removed as this is done anyway every time a
packet has been received. This unifies the processing of DATA and
FORWARD-TSN more.
Bug: webrtc:14600
Change-Id: If797d3c46e741074fe05e322d0aebec765a87968
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/321400
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40811}
More general matches that can be reused, less specialized ones.
Bug: None
Change-Id: I12ea98caf4f566168566173a509c204bd25e5a13
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/321123
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40804}
The handover state has been added with
commit daaa6ab5a8c74b87d9d6ded07342d8a2c50c73f7.
This reverts commit 014cbed9d2377ec0a0b15f2c48b21a562f770366.
Bug: webrtc:14997
Change-Id: Ie84f3184f3ea67aaa6438481634046ba18b497a6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/320941
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Jeremy Leconte <jleconte@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40794}