algesten / str0m

A Sans I/O WebRTC implementation in Rust.
MIT License
324 stars 50 forks source link

Understanding what the ICE agent provides #562

Closed PaulOlteanu closed 1 month ago

PaulOlteanu commented 1 month ago

Hello, I'm tring to use str0m and I don't quite understand what is and isn't provider regarding ICE and STUN. I'm not super familiar with WebRTC at this low a level so I may be completely off in my understanding of things.

I see in the IceAgent there's code related to STUN binding requests, which makes me think I don't need to implement a STUN client myself. On the other hand, the only API available to interact with ICE is via the Rtc add_local_candidate and add_remote_candidate calls which make me think I actually do need to implement a STUN client myself.

Is my understanding that I need to implement a STUN client correct? Is there an example of this done somewhere I can reference?

Thanks

algesten commented 1 month ago

Hi @PaulOlteanu, welcome to str0m!

Str0m's IceAgent implements a STUN client. In the most basic setup, you would add_local_candidate for the local UDP sockets you've bound. Then you apply an SDP offer (or answer) from a remote client, which would contain the remote candidates (that internally does add_remote_candidate).

Once local and remote candidates are in, you poll_output() and handle_input() to get instructions to send/receive data via the UDP socket.

The http-post.rs and chat.rs example shows you a very basic setup.

  1. Figure out local IP address (you'll struggle to use loopback for WebRTC): https://github.com/algesten/str0m/blob/main/examples/http-post.rs#L70
  2. Bind a UDP socket at the IP address: https://github.com/algesten/str0m/blob/main/examples/http-post.rs#L73
  3. Add it as local candidate: https://github.com/algesten/str0m/blob/main/examples/http-post.rs#L76
  4. Handle incoming SDP offer with remote candidates: https://github.com/algesten/str0m/blob/main/examples/http-post.rs#L81
  5. poll_output to get instructions to send data: https://github.com/algesten/str0m/blob/main/examples/http-post.rs#L108
  6. Receive incoming UDP data: https://github.com/algesten/str0m/blob/main/examples/http-post.rs#L131
PaulOlteanu commented 1 month ago

Perhaps I should specify, I'm interested in using str0m in a p2p manner, not as an SFU.

So in that case I believe I need to add_local_candidate with server reflexive candidates because host candidates will likely be useless? Thus I would need to use stun initially anyway to discover the public IP that the UDP socket has?

algesten commented 1 month ago

Yes, whether it's host candidates or server reflexive does not make much difference to str0m itself. A browser typically adds everything they can find (host and discovered reflexively, ipv4 and ipv6, udp and maybe even tcp). Then try and see what sticks. The same strategy works in str0m.

When you get an Output event instructing you to send some data, it uses the Transmit data structure. The source socket address combined with proto should give enough clues to identify how to send it. These would correspond to a host or reflexive address you add_local_candidate with earlier.