gavv / webrtc-cli

WebRTC command-line peer.
MIT License
225 stars 24 forks source link

Works on same network but not on diffferent networks #4

Open M0LTE opened 4 years ago

M0LTE commented 4 years ago

Hi there

When spinning up webrtc-cli on one machine and your HTML sample in a browser on another machine on the same network, audio flows fine.

When one machine is moved to a different network, the audio never connects.

Both networks are behind NAT, one is my home internet connection, the other is my laptop tethered to my phone using its 4G.

I notice you can specify a STUN server in webrtc-cli, but the internet suggests this may not be enough, and TURN might be needed.

Any ideas? I can grab wireshark traces if helpful.

Cheers.

gavv commented 4 years ago

Sorry for late reply.

Hm, both STUN and TURN are implemented by pion framework. Although our parameter is called STUN, it seems that actually can be both STUN or TURN url.

(I guess we should rename --stun to --ice).

So you can just try to provide an url of a TURN server (starting with turn: or turns:). AFAIK, google doesn't provide a free TURN server. So you'll have to find another one or run your own.

Unfortunately I didn't work with TURN before, so can't provide more details. Let me know if I can help somehow.

M0LTE commented 4 years ago

Good pointer, thanks. Great software too, by the way.

Can I just clarify, would you have expected webrtc-cli to have worked in the scenario I described, or is this expected?

gavv commented 4 years ago

So far I used webrtc-cli only when one of the hosts was behind NAT, and on the other host a range of ports was open. However, WebRTC is supposed to work with both hosts behind the NAT too, so if Pion implements everything needed, it should work. However probably there are some difficulties with finding or running a TURN server, I don't know.

gavv commented 4 years ago

I guess we should rename --stun to --ice

Done. (--stun is still present for compatibility, but is now deprecated).

M0LTE commented 4 years ago

So far I used webrtc-cli only when one of the hosts was behind NAT, and on the other host a range of ports was open. However, WebRTC is supposed to work with both hosts behind the NAT too, so if Pion implements everything needed, it should work. However probably there are some difficulties with finding or running a TURN server, I don't know.

Okay, I’ll give TURN a go and report back.

M0LTE commented 4 years ago

Hi @gavv I've spun up a TURN server. While STUN servers don't seem to require authentication, since TURN servers cost real money to host and run they generally do seem to require authentication. My Go isn't very good, but here, it looks like just a URL is being passed, with no obvious way to pass any credentials. This spec looks to suggest that parameters other than "urls" are available - username and credential. Is there any chance of you adding this support please? I can provide a URL, username and password if you wish for testing. Thank you!

gavv commented 4 years ago

I've added --ice-username and --ice-password options and pushed them to ice branch. Could you check it please?

If it wont work, yes you could send me credentials so I can debug it..

BTW, what TURN server are you using?

BTW2, have you looked at http://numb.viagenie.ca/ ?

M0LTE commented 4 years ago

Hey, I'm seeing:

a=end-of-candidates
-------------------------->8--------------------------
Starting recording...
ICE connection state changed to checking
Starting playback...
ICE connection state changed to failed

I appear to get the same thing with a numb.viagenie.ca account.

I'll try and find a way to send you creds to my (unverified) TURN server securely.

M0LTE commented 4 years ago

Yeah I can confirm I see the same using --ice turn:numb.viagenie.ca:3478 --ice-username my@email.com --ice-password xxxxxxx whereas the browser reaches "connected"

M0LTE commented 4 years ago

Hey @gavv sorry to pester but anything I can do to help with the above?

elmeyer commented 4 years ago

Hi! First of all thanks @gavv for this great piece of software, it's been very useful for us already.

Now, to the issue: Relay via TURN servers will not work with webrtc-cli in its current state, because the final choice of relay candidates for the communication has to happen over the signaling channel. One of the involved parties (called the controlling agent) has to nominate candidates and inform the other party/parties (the controlled agent(s)) of their choice of best candidate that should be used, which happens after the initial SDP exchange. So the current solution of copying SDP around is not enough for this, also because the signaling channel is technically meant to be permanently open, so that new candidates can be picked in case of network changes.

We've been working on adding simple signaling via WebSockets to webrtc-cli, but it needs some more time before it's ready. Planning to make a PR once it's working.

M0LTE commented 4 years ago

This is fantastic @elmeyer thank you so much!

gavv commented 4 years ago

Sorry for late reply again, being busy and tired these days.

@M0LTE Thanks for checking it out.

@elmeyer Thanks for the detailed explanation. Looking forward for a PR!

trojek commented 3 years ago

Hi.

Are there any plans to implement turn server support?

M0LTE commented 3 years ago

@elmeyer any progress on your work? Would dearly love to see this.

elmeyer commented 3 years ago

Sorry, cannot give an ETA yet. I'm changing jobs at the moment which will delay things for a while, but I have not forgotten about this.

M0LTE commented 3 years ago

Hey @elmeyer how's the job move? :-)

M0LTE commented 3 years ago

@gavv In lieu of the solution from @elmeyer I had the maybe daft idea of putting two copies of webrtc-cli back-to-back on a box with a public IP, then have each of the clients behind NATs connect to one of the two instances of webrtc-cli. Besides some fiddly orchestration, can you see that working?

soundex-dele commented 3 years ago

If you want to connect two webrtc-cli on the public network, you need to set up a turn server and a signaling server (I use websocket). After the answer and offer are exchanged for sdp, you also need to exchange the candidates. Use AddICECandidate on both client to add candidates.

elmeyer commented 3 years ago

Hi all. @M0LTE, thanks for asking - job move going well so far and I'm enjoying the new work. However life has managed to throw yet more stuff in the way, so still no ETA... sorry. @X-Dele's comment describes almost exactly what is needed, though (you don't strictly need a TURN server depending on your network setup; STUN may suffice). The solution we have is, as I mentioned, also based on a simple WebSocket listener. It just has to be part of webrtc-cli since the post-initial-offer/answer candidate exchange (as of yet not present in webrtc-cli) needs (multiple) AddICECandidate calls and therefore a more persistent signaling connection.

gavv commented 3 years ago

@gavv In lieu of the solution from @elmeyer I had the maybe daft idea of putting two copies of webrtc-cli back-to-back on a box with a public IP, then have each of the clients behind NATs connect to one of the two instances of webrtc-cli. Besides some fiddly orchestration, can you see that working?

Yes, I guess this would work, with a cost of higher latency.