meetecho / simple-whip-client

Simple WHIP Client (based on GStreamer's webrtcbin)
GNU General Public License v3.0
71 stars 19 forks source link

Support for STUN/TURN autoconfiguration via Link headers #4

Closed lminiero closed 2 years ago

lminiero commented 2 years ago

The new version of the WHIP draft adds support for an automatic configuration of STUN/TURN servers to use in WHIP clients:

https://www.ietf.org/archive/id/draft-ietf-wish-whip-01.html#name-stun-turn-server-configurat

The way it works is that WHIP servers can return a series of STUN/TURN servers (and credentials, if needed) in Link headers in the 201 in response to the HTTP POST (or optionally in response to the OPTIONS too), e.g.:

Link: stun:stun.example.net; rel="ice-server";
Link: turn:turn.example.net?transport=udp; rel="ice-server"; username="user"; credential: "myPassword"; credential-type: "password";
Link: turn:turn.example.net?transport=tcp; rel="ice-server"; username="user"; credential: "myPassword"; credential-type: "password";
Link: turns:turn.example.net?transport=tcp; rel="ice-server"; username="user"; credential: "myPassword"; credential-type: "password";

The WHIP client can then parse those Link values and add the STUN/TURN servers to its own stack for gathering.

Unfortunately, this seems not to work as expected with GStreamer's webrtcbin. While there is, for instance, an add-turn-server signal that can be used to add a TURN server dynamically (which is what we now use for adding TURN servers at startup too, as implemented in #2), that doesn't seem to have any effect after the pipeline has been started. I tried delaying the set-local-description call to after we set the servers, and that didn't help.

Checking the code:

The internal method that actually adds the TURN server to the libnice stack via nice_agent_set_relay_info, though, is _add_turn_server, which is only called by gst_webrtc_ice_add_stream. Since we add a stream when we first create our pipeline, and so always before we prepare an offer, trying to add a STUN/TURN server after that will not work.

The WHIP draft does have some text about this:

There are some webrtc implementations that do not support updating the ICE server configuration after the local offer has been created. In order to support these clients, the WHIP endpoint MAY also include the ICE server configuration on the responses to an authenticated OPTIONS request sent to the WHIP endpoint URL sent before the POST requests.

As such, I'll try to modify the WHIP server to also return a set of STUN/TURN servers in response to an OPTIONS on the endpoint URL, rather than just to the POST as I do now. This way, I can issue an OPTIONS request from the WHIP client before we create the pipeline, which should give us access to STUN/TURN servers we can actually use.