This reverts commit a736f30a5f.
Due to a downstream project not supporting this
new handover state, it fails. Handover state needs
to be submitted first, then downstream project needs
to be updated, and finally the code changes can be
submitted.
Bug: webrtc:14997
Change-Id: I8551e349408d9bf4eb593cb948279d659467fe20
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/302821
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Victor Boivie <boivie@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39923}
If configured, attempt to negotiate "zero checksum
acceptable" capability, which will make the outgoing
packets have a fixed checksum of zero. Received
packets will not be verified for a correct checksum
if it's zero.
Also includes some boilerplate:
- Setting capability in state cookie
- Adding capability to handover state
- Adding metric to know if the feature is used
This feature is not enabled by default, as it will be
first evaluated with an A/B experiment before making
it the default.
When the feature is enabled, lower CPU consumption for
both receiving and sending packets is expected. How
much depends on the architecture, as some architectures
have better support for generating CRC32 in hardware
than others.
Bug: webrtc:14997
Change-Id: If23f73e87220c7d42bd4f9a92772cda16bc18fcb
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/299076
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39920}
This reverts commit 45eae34693.
It was found not to be the root cause of the performance
regression, so it's safe to reland.
Bug: webrtc:14997
Change-Id: I67c90752875bf4071cbdd5adfa462a37f4d4ceab
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/302162
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#39910}
This reverts commit bd46bb7660.
Reason for revert: There is a slight performance degradation
pointing to this CL, so revert this to be able to confirm if
it is the culprit.
Original change's description:
> dcsctp: Support zero checksum packets
>
> If configured, the packet parser will allow packets with
> a set checksum of zero. In that case, the correct checksum
> will not even be calculated, avoiding a CPU intensive
> calculation.
>
> Also, if specified when building a packet, the checksum can
> be opted to be not calculated and written to the packet.
> This is to be used when draft-tuexen-tsvwg-sctp-zero-checksum
> has been negotiated, except for some packets during association
> establishment.
>
> This is mainly a preparation CL and follow-up CL will enable
> this feature.
>
> Low-Coverage-Reason: Affects debug logging code not run in tests
> Bug: webrtc:14997
> Change-Id: I3207ac3a626df039ee2990403c2edd6429f17617
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/298481
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Commit-Queue: Victor Boivie <boivie@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#39737}
Bug: webrtc:14997
Change-Id: Ie22267abb4bcd25d5af07875eb933c51ed5be853
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/301580
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39878}
If configured, the packet parser will allow packets with
a set checksum of zero. In that case, the correct checksum
will not even be calculated, avoiding a CPU intensive
calculation.
Also, if specified when building a packet, the checksum can
be opted to be not calculated and written to the packet.
This is to be used when draft-tuexen-tsvwg-sctp-zero-checksum
has been negotiated, except for some packets during association
establishment.
This is mainly a preparation CL and follow-up CL will enable
this feature.
Low-Coverage-Reason: Affects debug logging code not run in tests
Bug: webrtc:14997
Change-Id: I3207ac3a626df039ee2990403c2edd6429f17617
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/298481
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39737}
When a stream reset response has been received, this may result
in unpausing the streams (either because it was successful or
because it failed - but streams will be unpaused). Directly after
receiving the response, send out any pending chunks that are
ready to be sent.
Before this CL, they would eventually be sent out, but that is
unnecessary and undeterministic.
Bug: webrtc:14277
Change-Id: Ic1ab38bc3cea96cfec7419e25001f12807523a3a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/273800
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38009}
When a RECONFIG has been received with a last assigned TSN that is
not yet seen by the receiver, it will enter deferred reset mode
(https://www.rfc-editor.org/rfc/rfc6525#section-5.2.2, E2).
When more DATA is received, moving the cumulative acknowledgment point,
the request will finally be processed. But the last chunk that has the
same TSN as the last assigned TSN was before this CL not applied before
doing the reset - it was applied after.
This would result of a message getting lost or possibly getting
truncated or incorrectly merged with another.
Handling the message before resetting the stream is the simple
solution here.
Bug: webrtc:14277
Change-Id: Iea9fa227778077a9ff2f78bc77b5d93cc32b702b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/273323
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37993}
To allow the transport to be able to know which ranges of
stream identifiers it can use, the negotiated incoming/inbound
and outgoing/outbound stream counts will be exposed. They are
added to Metrics, and guaranteed to be available from within
the OnConnected callback.
In this CL, dcSCTP will not validate that the client is sending
on a stream that is within the negotiated bounds. That will be
done as a follow-up CL.
Bug: webrtc:14277
Change-Id: Ic764e5f93f53d55633ee547df86246022f4097cf
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/272321
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37876}
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}
There was also some refactoring to create the TCB at the same time,
to ensure the metric is always set.
Bug: webrtc:13052, webrtc:5696
Change-Id: I5557ad5f0fc4a0520de1eaaafa15459b3200c4f5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262259
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37388}
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 is a re-land of commit 3180a5ad06.
This is an issue found in fuzzer, and doesn't really happen in WebRTC
as it never closes the connection and reconnects.
The issue is that the send queue outlives any connection since you're
allowed to send messages (well, enqueue them) before the association is
fully connected. So the send queue is always present but the TCB
(information about the connection) is torn down when the connection is
closed for example. And the TCB holds the Stream Reset handler, which is
responsible for e.g. keeping track of stream reset sequence numbers and
such - which is tied to the connection.
So to ensure that the Stream Reset Handler is in charge of deciding
if a stream reset is taking place, make sure that the send queue is in
a known good state when the Stream Reset handler is created.
Bug: webrtc:13994, chromium:1320194
Change-Id: Ib8254488523c7abb58057c602f76f411fce896fa
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/265000
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37115}
This is a reland of commit 17a02a31d7.
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 17a02a31d7.
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}
This CL first restricts Metrics to be retrievable when the socket is
created. This avoids having most fields as optional and makes it
easier to add more metrics.
Secondly, the peer implementation is moved into Metrics.
Bug: webrtc:13052
Change-Id: I6cb53eeef3f84ac34f3efc883853338f903cc758
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262256
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36888}
This reverts commit 3180a5ad06.
Reason for revert: Speculative revert due to failures in downstream tests.
Original change's description:
> dcsctp: Reset send queue when recreating TCB
>
> This is an issue found in fuzzer, and doesn't really happen in WebRTC
> as it never closes the connection and reconnects.
>
> The issue is that the send queue outlives any connection since you're
> allowed to send messages (well, enqueue them) before the association is
> fully connected. So the send queue is always present but the TCB
> (information about the connection) is torn down when the connection is
> closed for example. And the TCB holds the Stream Reset handler, which is
> responsible for e.g. keeping track of stream reset sequence numbers and
> such - which is tied to the connection.
>
> So to ensure that the Stream Reset Handler is in charge of deciding
> if a stream reset is taking place, make sure that the send queue is in
> a known good state when the Stream Reset handler is created.
>
> Bug: webrtc:13994, chromium:1320194
> Change-Id: I940e4690ac9237ac99dd69a9ffc060cdac61711d
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261260
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Commit-Queue: Victor Boivie <boivie@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#36779}
Bug: webrtc:13994, chromium:1320194
Change-Id: I89bb9cae60adc53902c1304e79047d18e72594a5
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261302
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Auto-Submit: Björn Terelius <terelius@webrtc.org>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Owners-Override: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Victor Boivie <boivie@google.com>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36783}
This is an issue found in fuzzer, and doesn't really happen in WebRTC
as it never closes the connection and reconnects.
The issue is that the send queue outlives any connection since you're
allowed to send messages (well, enqueue them) before the association is
fully connected. So the send queue is always present but the TCB
(information about the connection) is torn down when the connection is
closed for example. And the TCB holds the Stream Reset handler, which is
responsible for e.g. keeping track of stream reset sequence numbers and
such - which is tied to the connection.
So to ensure that the Stream Reset Handler is in charge of deciding
if a stream reset is taking place, make sure that the send queue is in
a known good state when the Stream Reset handler is created.
Bug: webrtc:13994, chromium:1320194
Change-Id: I940e4690ac9237ac99dd69a9ffc060cdac61711d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261260
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36779}
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}
This proved to be not very efficient unfortunately, so revert it and
keep bundling FORWARD-TSN with other packets to be more efficient.
https://github.com/sctplab/usrsctp/issues/597 is still unresolved.
Note that this is not a clean revert; The logic to rate limit the
sending of FORWARD-TSN is kept, as it still makes sense.
This partly reverts commit 0ca62e3752.
Bug: webrtc:12961
Change-Id: I42728434290e7ece19e9c23f24ef6f3d3b171315
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/259520
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36584}
When resetting several streams in sequence, only the first stream will
be included in the first RE_CONFIG chunk as it's created eagerly
whenever someone calls ResetStreams. The remaining ones are queued as
pending. When the first request finishes, the remaining ones should
continue to be processed, but this wasn't done prior to this commit.
This would only happen if two streams would be reset with shorter time
between them than a RTT, so that there would be an outstanding request
forcing the second reset to be enqueued.
Bug: chromium:1312009
Change-Id: Id74b375d1d1720406a3bca4ec60df5780ca7edba
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/257306
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36404}
This is a solution to some problems that have been found locally when
running the fuzzer for a long time. The fuzzer keeps on fuzzing, and has
found a way to trigger a consistency check to fail when a client
intentionally sends different messages - unordered and ordered - using
the same TSNs. As the reassembly queue has different handling of ordered
and unordered chunks due to how they are reassembled, it will not notice
if it receives two different chunks with the same TSN. They will both go
to their respective reassembly streams, as those are separate by design.
The data tracker - which keeps track of all received DATA chunks as it
needs to generate SACKs, has a global understanding of all received
chunks. By having it indicate if this is a duplicate received chunk, the
socket can avoid forwarding both chunks to the reassembly queue; only
one chunk will get there.
Bug: None
Change-Id: I602a8552a9a4c853684fcf105309ec3d8073f2c2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/256110
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36316}
When a FORWARD-TSN is received as the first chunk on an ordered stream,
it will fail to set the new "next expected SSN" that is present in the
FORWARD-TSN as that stream hasn't been allocated yet. It's allocated
when the first DATA is received on that stream.
This is a non-issue for ordinary data channels as the first message on
any stream will be the "Data Channel Establishment Protocol" messages,
which are always sent reliably. But if prenegotiated channels are used,
and the very first packet received on an ordered data channel is lost
_and_ signaled to the receiver as lost _before_ the receiver has
received any other fragments on that data channel, future messages will
not be delivered on that channel.
Bug: webrtc:13799
Change-Id: Ide5c656243b3a51a2ed9d76615cfc3631cfe900c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/253902
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36155}
Following https://abseil.io/tips/122 to make tests easier to understand
and adds a bit of flexibility to create sockets with custom parameters.
This also simplifies handover tests.
Additionally, AdvanceTime will now also run timers, as that was easily
forgotten previously.
Bug: None
Change-Id: Ieb5eece7aca51c98a7634ed1c61646383ad1712d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/253782
Reviewed-by: Sergey Sukhanov <sergeysu@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36141}
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}
It's to be used for clients to record metrics and to e.g. attribute
metrics to which SCTP implementation the peer was using.
This is not explicitly signaled, so heuristics are used. These are not
guaranteed to come to the correct conclusion, and the data is not always
available.
Note: The behavior of dcSCTP will not change depending on the assumed
implementation - only by explicitly signaled capabilities.
Bug: webrtc:13216
Change-Id: I2f58054d17d53d947ed5845df7a08f974d42f918
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/233100
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35103}
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}
This will be useful in future socket handover tests.
Bug: webrtc:13154
Change-Id: Ia789ae971edd9d2832be088f2f8f7dd50c9ce52d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/231222
Reviewed-by: Victor Boivie <boivie@webrtc.org>
Commit-Queue: Sergey Sukhanov <sergeysu@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#34931}
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}
dcSCTP seems to be able to provoke usrsctp to send ABORT in some
situations, as described in
https://github.com/sctplab/usrsctp/issues/597. Using a packetdrill
script, it seems as a contributing factor to this behavior is when a
FORWARD-TSN chunk is bundled with a DATA chunk. This is a valid and
recommended pattern in RFC3758:
"F2) The data sender SHOULD always attempt to bundle an outgoing
FORWARD TSN with outbound DATA chunks for efficiency."
However, that seems to be a rare event in usrsctp, which generally sends
each FORWARD-TSN in a separate packet.
By doing the same, the assumption is that this scenario will generally
be avoided.
With many browsers and other clients using usrsctp, and which will not
be upgraded for a long time, there is an advantage of avoiding the issue
even if it is according to specification.
Before this change, a FORWARD-TSN was bundled with outgoing DATA and due
to this, it wasn't rate limited as the overhead was very little. With
this change, a rate limiting behavior has been added to avoid sending
too many FORWARD-TSN in small packets. It will be sent every RTT, or
200 ms, whichever is smallest. This is also described in the RFC.
Bug: webrtc:12961
Change-Id: I3d8036a34f999f405958982534bfa0e99e330da3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/229101
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34801}
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}
Some deployments, e.g. Chromium, has a limited send buffer. It's
reasonable that it's quite small, as it avoids queuing too much, which
typically results in increased latency for real-time communication. To
avoid SCTP to fill up the entire buffer at once - especially when doing
fast retransmissions - limit the amount of packets that are sent in one
go.
In a typical scenario, SCTP will not send more than three packets for
each incoming packet, which is is the case when a SACK is received which
has acknowledged two large packets, and which also adds the MTU to the
congestion window (due to in slow-start mode), which then may result in
sending three packets. So setting this value to four makes any
retransmission not use that much more of the send buffer.
This is analogous to usrsctp_sysctl_set_sctp_fr_max_burst_default in
usrsctp, which also has the default value of four (4).
Bug: webrtc:12943
Change-Id: Iff76a1668beadc8776fab10312ef9ee26f24e442
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/228480
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34744}
To support implementing RTCSctpTransportStats, a few metrics are needed.
Some more were added that are useful for metric collection in SFUs.
Bug: webrtc:13052
Change-Id: Idafd49e1084922d01d3e6c5860715f63aea08b7d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/228243
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@{#34708}
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}
This is needed to be able to debug test cases when they fail.
Bug: webrtc:12961
Change-Id: I39bfe532709d02acb328ff5fdd005d33be4dc31c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/225544
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34452}
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}
While in the COOKIE ECHO state, there is a TCB and there might be data
in the send buffer, and RFC4960 allows the COOKIE ECHO chunk to bundle
additional DATA chunks in the same packet, but there mustn't be more
than one such packet sent, and that packet must have a COOKIE ECHO chunk
as the first chunk in it.
When the COOKIE ACK chunk has been received, the socket is allowed to
send multiple packets.
Previously, this was state managed by the socket and not the TCB, as
the socket is responsible for moving between the different states. And
when the COOKIE ECHO chunk was sent, the TCB was instructed to only send
a single packet by the socket.
However, if there were retransmissions or anything else that could
result in calling TransmissionControlBlock::SendBufferedChunks, it would
do as instructed and send those, even if the socket was in a state where
that wasn't allowed.
When the peer was dcSCTP, this didn't cause any issues as dcSCTP tries
to be tolerant in what it receives (but strict in what it sends, except
for when there are bugs). When the peer was usrsctp, it would send an
ABORT for each received packet that didn't have a COOKIE ECHO as the
first chunk, and then restart the handshake (sending an INIT). So this
resulted in a longer handshake, but the connection would eventually be
correctly established and any DATA chunks that resulted in the ABORTs
would've been retransmitted.
By making the TCB aware of that particular state, and to make it
responsible for creating the SCTP packet with the COOKIE ECHO chunk
first, and also to only send a single packet when it is in that state,
there will not be any way to bypass this limitation.
Also, while not explicitly mentioned in the RFC, the retransmission
timer will not affect resending any outstanding DATA chunks that were
bundled together with the COOKIE ECHO chunk, as then there would be two
timers that both would drive resending COOKIE ECHO and DATA chunks.
Bug: webrtc:12880
Change-Id: I76f215a03cceab5bafe9f16eb4775f3dc68a6f05
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/222645
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34329}
While it's not strictly defined, the expectation is that sending a
message with a lifetime parameter set to zero (0) ms should allow it to
be sent if it can be sent without being buffered. If it can't be
directly sent, it should be discarded.
This is initial support for it. Small messages can now be delivered fine
if they are not to be buffered, but fragmented messages could be partly
sent (if this fills up the congestion window), which means that the
message will then fail to be sent whenever the congestion window frees
up again. It would be better to - at a higher level - realize early that
the message can't be sent in full, and discard it without sending
anything. But that's an optimization that can be done later.
A few off-by-one errors were found when strictly defining that the
message is alive during its entire lifetime. It will expire just _after_
its lifetime.
Sending messages with a lifetime of zero may not supported in all
libraries, so a workaround would be to set a very small timeout instead,
which is tested as well.
Bug: webrtc:12614
Change-Id: I9a00bedb639ad7b3b565b750ef2a49c9020745f1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/217562
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33977}
When the shutdown timer has expired, the socket will abort/close and the
TCB is not valid after InternalClose.
Bug: webrtc:12614
Change-Id: I09a94a049f0cda4577225dd9c80a92a8ec7e0423
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/217767
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33956}
If Shutdown is called when the socket is being established and while the
connection timers are running, it will put the socket in an inconsistent
state, which is verified in debug builds.
Bug: webrtc:12614
Change-Id: I66f07d1170ac8f0ad9fd485d77d6aef4c365f150
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/217765
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33949}
This makes it easier to understand which socket that experience an error
or abort. Aborts are now also logged, which was missed previously.
Bug: webrtc:12614
Change-Id: Ie5e4357b3e5450106cc6cc28c1e9578ad53d073a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/217764
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33947}
In real life, when a Timeout expires, the caller is supposed to call
DcSctpSocket::HandleTimeout directly, as the Timeout that just expired
is stopped (it just expired), but the Timer still believes it's running.
The system is not in a consistent state.
In tests, all timeouts were evaluated at the same time, which, if two
timeouts expired at the same time, would put them both as "not running",
and with their timers believing they were running. So if you would do
any operation on a timer whose timeout had just expired, the timeout
would assert saying that "you can't stop a stopped timeout" or similar.
This isn't relevant in non-test scenarios.
Solved by expiring timeouts one by one.
Bug: webrtc:12614
Change-Id: I79d006f4d3e96854d77cec3eb0080aa23b8569cb
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/217560
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33925}
This completes the basic implementation of the dcSCTP library. There
are a few remaining commits to e.g. add compatibility tests and
benchmarks, as well as more support for e.g. RFC8260, but those are not
strictly vital for evaluation of the library.
The Socket contains the connection establishment and teardown sequences
as well as the general chunk dispatcher.
Bug: webrtc:12614
Change-Id: I313b6c8f4accc144e3bb88ddba22269ebb8eb3cd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/214342
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33890}