Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initialization of DataChannelId on connection #2222

Merged
merged 4 commits into from
Oct 3, 2019

Conversation

alvestrand
Copy link
Contributor

@alvestrand alvestrand commented Jul 8, 2019

Fixes #1818

Note that this initializes DataChannelId on connecting
the SctpTransport, not when the DTLS role is determined.


Preview | Diff

Copy link
Contributor

@aboba aboba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lines 9151-52: The DTLS role is not determined as part of the SCTP association setup process. So I would suggest deleting the reference to the DTLS role in line 9150 (the DTLS role will have been determined, so it isn't relevant).

@aboba aboba requested review from henbos and jan-ivar July 11, 2019 14:35
webrtc.html Outdated
to a value generated by the
user agent, according to [[!RTCWEB-DATA-PROTOCOL]].
If no available ID could be generated,
<a>throw</a> an <code>OperationError</code> exception.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't throw an exception here, we're in a queued task, we're not in a function

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should fail like we do below?

Copy link
Contributor

@lgrahl lgrahl Jul 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. Actually, these two steps can be merged.

Edit: This was a reply to @henbos' comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

webrtc.html Outdated
<p>If <var>channel</var>'s <a>[[\DataChannelId]]</a> slot is
<code>null</code>, initialize <a>[[\DataChannelId]]</a>
to a value generated by the
user agent, according to [[!RTCWEB-DATA-PROTOCOL]].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's important that the underlying data transport's ID matches this label. I think we either need to say that this generation took place as part of the underlying connection procedure and is surfaced here, or we have to generate the ID here and then "in parallel" update the underlying data transport to match this ID.

Copy link
Contributor

@lgrahl lgrahl Jul 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't quite follow that. Can you elaborate? I think it's okay to not say anything here as the referenced IETF document explains the procedure well.

Edit: This was a reply to @henbos' comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took "generated by the user agent" to be so obvioiusly the underlying data transport's ID that it didn't need to be called out.

Copy link
Contributor

@henbos henbos Aug 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarification:

Each RTCDataChannel has an associated underlying data transport.
Whenever something happens to the underlying transport, like connecting or closing which could happen in parallel on a network thread, we queue a task to update the RTCDataChannel to match. We need to be careful about keeping these two objects (the JS version and the actual SCTP implementation) in sync.

For example, when creating an RTCDataChannel with createDataChannel(), there's a step to "Create channel's associated underlying data transport and configure it according to the relevant properties of channel." meaning we pass down the ID to the underlying transport. Likewise when a data channel is created by the underlying sctp transport, we queue a task to to create an RTCDataChannel to match the configuration received from the underlying data transport.

So if we modify the [DataChannelId] internal slot, we need to inform the underlying data transport that this is the ID that it should use.

Do we need to add "In parallel, update the underlying data transport's id"?

Or better: Can we say "If [DataChannelId] is null, update it to match the ID received from the underlying sctp data channel that was generated as specified in [RTCWEB-DATA-PROTOCOL]"? This implies that we already did generate it in parallel, as we should have?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took "generated by the user agent" to be so obvioiusly the underlying data transport's ID that it didn't need to be called out.

The concern isn't so much that they mismatch since that clearly is the intent but that it is unclear if the ID is generated before or after the queuing of a task.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The id is not a modifiable property. It's a settable property. Once it's set to a non-null value, it can't be changed. So we don't have to deal with synchronization of changes - either it's set at creation (in JS, communicated to lower layers) or it's set in the protocol machine (in lower layers, communicated to JS). This makes thinking about synchronization somewhat easier.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this to "initialize [[DataChannelId]] to the value generated by the underlying sctp data channel, according to..."

Copy link
Contributor

@lgrahl lgrahl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is phrased as if it only prevents the first of the three cases listed in #1818. See inline comments for suggestions.

webrtc.html Outdated
populated once the DTLS role is determined during the
process of <a data-lt="set the RTCSessionDescription">
setting an <code>RTCSessionDescription</code></a>.
populated during the process of
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This references conected but indicates connecting. I'd instead suggest: "[...] it will be populated once the SCTP association has been established."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The section is called "connected procedure". I guess I should call it that.

@@ -9287,7 +9287,15 @@ <h4 id="sctp-transport-connected">Connected procedure</h4>
<p>Let <var>channel</var> be the <code><a>RTCDataChannel</a></code> object.</p>
</li>
<li>
<p>If the <var>channel</var>'s <a>[[\DataChannelId]]</a> slot is greater or
<p>If <var>channel</var>'s <a>[[\DataChannelId]]</a> slot is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the statechange event is being caught by the application, is it ensured that the ids have been populated? Probably yes since the event is being appended to the event loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure. I moved the statechange event to after the ID assignment, but that causes "announce the channel as open" to move before the statechange event. Does that matter?
I don't think so, because the "Announcing a data channel as open" section starts off with "MUST queue a task".

webrtc.html Outdated
<p>If <var>channel</var>'s <a>[[\DataChannelId]]</a> slot is
<code>null</code>, initialize <a>[[\DataChannelId]]</a>
to a value generated by the
user agent, according to [[!RTCWEB-DATA-PROTOCOL]].
Copy link
Contributor

@lgrahl lgrahl Jul 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't quite follow that. Can you elaborate? I think it's okay to not say anything here as the referenced IETF document explains the procedure well.

Edit: This was a reply to @henbos' comment.

webrtc.html Outdated
to a value generated by the
user agent, according to [[!RTCWEB-DATA-PROTOCOL]].
If no available ID could be generated,
<a>throw</a> an <code>OperationError</code> exception.
Copy link
Contributor

@lgrahl lgrahl Jul 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. Actually, these two steps can be merged.

Edit: This was a reply to @henbos' comment.

webrtc.html Outdated
<p>If <var>channel</var>'s <a>[[\DataChannelId]]</a> slot is
<code>null</code>, initialize <a>[[\DataChannelId]]</a>
to a value generated by the
user agent, according to [[!RTCWEB-DATA-PROTOCOL]].
Copy link
Contributor

@henbos henbos Aug 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarification:

Each RTCDataChannel has an associated underlying data transport.
Whenever something happens to the underlying transport, like connecting or closing which could happen in parallel on a network thread, we queue a task to update the RTCDataChannel to match. We need to be careful about keeping these two objects (the JS version and the actual SCTP implementation) in sync.

For example, when creating an RTCDataChannel with createDataChannel(), there's a step to "Create channel's associated underlying data transport and configure it according to the relevant properties of channel." meaning we pass down the ID to the underlying transport. Likewise when a data channel is created by the underlying sctp transport, we queue a task to to create an RTCDataChannel to match the configuration received from the underlying data transport.

So if we modify the [DataChannelId] internal slot, we need to inform the underlying data transport that this is the ID that it should use.

Do we need to add "In parallel, update the underlying data transport's id"?

Or better: Can we say "If [DataChannelId] is null, update it to match the ID received from the underlying sctp data channel that was generated as specified in [RTCWEB-DATA-PROTOCOL]"? This implies that we already did generate it in parallel, as we should have?

<a>throw</a> an <code>OperationError</code> exception.
</p>
<li>
<p>If <var>channel</var>'s <a>[[\DataChannelId]]</a> slot is greater or
equal to <var>transport</var>'s <a>[[\MaxChannels]]</a> slot,
<a data-lt="data-channel-failure"> close the <var>channel</var> due to a failure
</a>. Otherwise, <a data-lt="announce the rtcdatachannel as open">announce the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not new in this PR: We are inside of steps invoking "announce the rtcdatachannel as open" and "close the channel due to failure". The referenced algorithm queues a task. We should refactor this so that we can invoke the algorithms without queuing a task; the queuing of a task is in response to something happening in parallel.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not addressed in this PR.

@alvestrand
Copy link
Contributor Author

I think it has a test. Will look to check that it actually tests.

alvestrand and others added 3 commits September 27, 2019 13:17
Fixes #1818

Note that this initializes DataChannelId on connecting
the SctpTransport, not when the DTLS role is determined.
@alvestrand
Copy link
Contributor Author

Please re-review. I changed text.

<a data-lt="data-channel-failure"> close the <var>channel</var> due to a failure
</a>. Otherwise, <a data-lt="announce the rtcdatachannel as open">announce the
<var>channel</var> as open</a>.</p>
</li>
</ol>
</li>
<li>
<p><a>Fire an event</a> named <code><a data-lt="
RTCSctpTransport state change">statechange</a></code> at <var>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The event fire order can now be misinterpreted easily. The individual open events fire after the statechange event because the open event is scheduled in yet another task. When we refactor that as suggested by @henbos, we need to ensure not to break that order: statechange, then for each data channel, open.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a note seems reasonable.

@alvestrand
Copy link
Contributor Author

Updated with note (and a drive-by grammar edit).

@lgrahl
Copy link
Contributor

lgrahl commented Oct 3, 2019

LGTM now

Copy link
Contributor

@henbos henbos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@henbos henbos merged commit 8917c57 into master Oct 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RTCDataChannel.id assignment
4 participants