Video Room is not generating local candidates

I need some guidance.

Using a Native Android WebRTC client, Janus 1.1.3 with libnice (tried with 0.1.17 and 0.1.21) using TURN only via Coturn with Turn API handled by my signaling server. Janus and Coturn are installed on the same ubuntu server on a local network at the moment while I finish development of features, so addresses are all in the 192.168.0.x space. Also, as such, I can share any configs as needed.

I cannot get janus to produce local candidates for a video room publisher. I cannot find any errors, it just does not progress past the gathering stage.

Video Room created
Join as publisher
Start publishing, send offer SDP.
Janus responds with Answer SDP.
client sends local relay ICE candidates with the trickle request to Janus followed by completed: true. Janus acks each of these messages.
I can see in the janus server log that it is calling the Turn API to get URL and credentials.
I can see in the Coturn logs the turn allocation that Janus is given
I receive a WebRTC event for remote candidate with a candidate description, but I do not receive a trickle event from Janus.
Janus admin for the session and handle show both offer and answer, shows the remote candidates, but no local candidates, and the handle shows “state”: “gathering” and “ready”: -1.

I feel like I am missing something obvious but I have been working at this non-stop for 5 days without any progress. What am I overlooking? I tried setting the remote candidate from the remote-candidate message but that didn’t work (and I didn’t think it would).

Why are you configuring TURN for Janus? As clearly explained in the configuration documentation, in 99% of the cases TURN is only needed by users, not Janus.

Thank you for the quick reply.

I read all the warnings about that in the docs, but the likely deployment scenario will have Janus internal to a network with Coturn being the only edge of the network.

But let’s take that scenario:
Coturn is at the edge of the network (exposed to the Internet) along with the signaling server
Janus is on a private cloud
Janus can reach Coturn. Janus might have egress to the Internet through a corporate firewall, but there will not be ingress to Janus from the Internet.

If a client must use Turn and presents a relay candidate, what does Janus have as a local candidate option? This is unclear to me. And I may be overthinking this. If the client must use TURN, does Janus also need to use it to be able to confirm connectivity to that peer? Doesn’t that require providing Janus with Turn settings as well?

If I do not force TURN I get a stable host connection from both sides on my local network but that will not reflect the reality of the production environment where I know 100% of the calls will involve as least one party using TURN.

Again, I may be overthinking it.

I’d argue that keeping Janus in a private network is going to severely affect performance. Even so, though, you’d use STUN and not TURN, unless there’s also firewalls in place.

If the client must use TURN, does Janus also need to use it to be able to confirm connectivity to that peer? Doesn’t that require providing Janus with Turn settings as well?

No. When the client uses TURN, the TURN server provides relay candidates that the peer (Janus in this case) can talk to directly.

Again, thank you for the quick reply!

I know you don’t normally work on the deployment side (I’ve seen that in some of your replies to others), but I come from a background of financial software services where you expose absolutely nothing unless you have no other options. WebRTC requires a shift in thinking and I am still trying to find my comfort level with what is exposed and what is not.

Are there any white papers on securely deploying, optimal firewall configurations, etc, that anyone has encountered?