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

Implement WebRTC messages framing #2896

Merged
merged 23 commits into from
Oct 19, 2022
Merged

Conversation

tomaka
Copy link
Contributor

@tomaka tomaka commented Oct 18, 2022

cc libp2p/specs#412
cc #1712

This PR finishes implementing the WebRTC spec by adding the last remaining item: the messages framing.

Implementing this messages framing while minimizing the amount of data copies is rather challenging.
Instead of going for the complicated solution, I went for the more easy solution of having an intermediate read buffer where data is first copied.
Going for the simple solution decreases the chances of bugs and increases the ease of debugging, so it's preferable at the moment.

In the future, once WebRTC is fully working, we can rewrite this messages framing code in a more optimized way.

Copy link
Contributor

@mergify mergify bot left a comment

Choose a reason for hiding this comment

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

Automatically approving tomaka's pull requests. This auto-approval will be removed once more maintainers are active.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 18, 2022

twiggy diff report

Difference in .wasm size before and after this pull request.


 Delta Bytes │ Item
─────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       -8588 ┊ <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h0487131d4c491b93
       +8588 ┊ <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h801956d7493f1941
       -3556 ┊ <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h3107aa82f3270ecf
       +3556 ┊ <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::hc5a072cb1d299ae1
       -3305 ┊ <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h9c82c520cf398c6d
       +3227 ┊ <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::hb52fe97072de8226
       +2219 ┊ smoldot::libp2p::connection::established::multi_stream::MultiStream<TNow,TSubId,TRqUd,TNotifUd>::substream_read_write::h1bff5e6e66178745
       +1290 ┊ smoldot::libp2p::collection::multi_stream::MultiStreamConnectionTask<TNow,TSubId>::substream_read_write::h588b905c4bd92eae
        -983 ┊ hashbrown::raw::RawTable<T,A>::reserve_rehash::ha927364891a8e5ba
        +983 ┊ hashbrown::raw::RawTable<T,A>::reserve_rehash::hb54d82e16dda9027
        +975 ┊ <F as nom::internal::Parser<I,O,E>>::parse::h55db268c0db3260e
        +975 ┊ <F as nom::internal::Parser<I,O,E>>::parse::hee9629e946c75926
        +967 ┊ hashbrown::raw::RawTable<T,A>::reserve_rehash::h567f0b8a2cb017e5
        -655 ┊ smoldot::libp2p::connection::established::multi_stream::MultiStream<TNow,TSubId,TRqUd,TNotifUd>::on_substream_event::h92465f384b4efc0f
        +647 ┊ smoldot::libp2p::connection::established::multi_stream::MultiStream<TNow,TSubId,TRqUd,TNotifUd>::on_substream_event::h5ba4e91323587d5f
        +528 ┊ data[0]
        +429 ┊ <F as nom::internal::Parser<I,O,E>>::parse::h59c484db9d5243f2
        +429 ┊ <F as nom::internal::Parser<I,O,E>>::parse::h7e5d4ea4b1140b21
        +414 ┊ core::ptr::drop_in_place<core::future::from_generator::GenFuture<smoldot_light::network_service::tasks::connection_task<smoldot_light_wasm::platform::Platform>::{{closure}}>>::h5025e80c68d0931b
        -414 ┊ core::ptr::drop_in_place<core::future::from_generator::GenFuture<smoldot_light::network_service::tasks::connection_task<smoldot_light_wasm::platform::Platform>::{{closure}}>>::hbc454602a8b2d1ad
       +7098 ┊ ... and 479 more.
      +23156 ┊ Σ [499 Total Rows]

@tomaka
Copy link
Contributor Author

tomaka commented Oct 18, 2022

This PR turned into a bit of a "fix every WebRTC issue" PR, but it is much more productive to just push everything onto a branch instead of analyze each bug individually.

"o=- 0 0 IN IP" + ipVersion + " " + targetIp + "\n" +
// Name for the session. We are allowed to pass a dummy `-`. (RFC8866)
"s=-" + "\n" +
// Start and end of the validity of the session. `0 0` means that the session never
// expires. (RFC8866)
"t=0 0" + "\n" +
// A lite implementation is only appropriate for devices that will
// *always* be connected to the public Internet and have a public
// A non-lite implementation is only appropriate for devices that will
Copy link
Contributor

Choose a reason for hiding this comment

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

??? This was a copy from the specification. Did something change?

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 specification doesn't contain this text. It's me who wrote it. It has a mistake in it, it says that lite implementations are only for publicly-accessible devices. But no, it's non-lite implementations that are for public devices. We're not a public device, so we use the lite implementation.

Copy link
Contributor

Choose a reason for hiding this comment

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

"Certain ICE agents will always be connected to the public Internet
and have a public IP address at which it can receive packets from any
correspondent. To make it easier for these devices to support ICE,
ICE defines a special type of implementation called "lite" (in
contrast to the normal full implementation). Lite agents only use
host candidates and do not generate connectivity checks or run state
machines, though they need to be able to respond to connectivity
checks." https://datatracker.ietf.org/doc/rfc8445/

Copy link
Contributor

Choose a reason for hiding this comment

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

By specifying ice-lite in server's SDP (that we're pretending we've received through some channel, but instead construct manually), we're saying that server is publicly accessible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To be honest this text doesn't make sense to me no matter whether it says "lite" or "not lite", so I've just reverted it 🤷

@@ -303,8 +304,9 @@ export function start(options?: ClientOptions): Client {
// (UDP or TCP)
"a=sctp-port:5000" + "\n" +
// The maximum SCTP user message size (in bytes) (RFC8841)
"a=max-message-size:100000" + "\n" +
// A transport address for a candidate that can be used for connectivity checks (RFC8839).
"a=max-message-size:16384" + "\n" + // TODO: should this be part of the spec?
Copy link
Contributor

Choose a reason for hiding this comment

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

subject to a change, but yes!

Copy link
Contributor

Choose a reason for hiding this comment

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

@tomaka tomaka added the automerge Automatically merge pull request as soon as possible label Oct 19, 2022
@mergify mergify bot merged commit b7d13d7 into paritytech:main Oct 19, 2022
@tomaka tomaka deleted the messages-framing branch October 19, 2022 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge Automatically merge pull request as soon as possible
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants