AlexxIT / go2rtc

Ultimate camera streaming application with support RTSP, RTMP, HTTP-FLV, WebRTC, MSE, HLS, MP4, MJPEG, HomeKit, FFmpeg, etc.
https://github.com/AlexxIT/Blog
MIT License
4.66k stars 378 forks source link

STUN candidate returns only one address in dualstack configuration #1153

Open elarsson1 opened 4 months ago

elarsson1 commented 4 months ago

My ISP provides dual-stack IPv4 and IPv6 networking, so my clients all have private IPv4 addresses behind a single NATed public IPv4 as well as public IPv6 addresses from a delegated /56. I have allowed port 8555 in my firewall for IPv6 and also set up a NAT port forward from the public IPv4 on port 8555 to go2rtc running as the Home Assistant add-on.

What I'm finding is that go2rtc is not offering my public IPv4 at port 8555 as a candidate. It seems like STUN is preferring and only returning the IPv6 address. When troubleshooting in the browser console, I do see my public IPv4 offered as a candidate, but on.a random port. I think this is the default ICE behavior though, not the explicit candidate setting in my config file which specifies port 8555. I also see the machine's public IPv6 address offered as a candidate, on port 8555, which I assume is coming form the STUN entry.

The result is that I can get WebRTC connectivity fine from external clients that also are on the IPv6 internet, but not when I'm connecting from an IPv4 only network. Is there any way to get go2rtc to detect both my external IPv4 and IPv6 addresses and offer them as candidates on the port I specify? For the moment, I've hardcoded my public IPv4 and that works, but not ideal as my ISP can change that at whim. I've also tried using a public hostname, which seems to be passed through as a candidate untouched, but browsers seem to ignore that (I believe WebRTC spec is expecting only IP addresses as candidates).

Here is my go2rtc configuration from the Home Assistant add-on:

api:
  listen: "127.0.0.1:1984" # localhost

rtsp:
  listen: "127.0.0.1:8554" # localhost

webrtc:
  listen: ":8555" # external TCP/UDP port
  candidates:
    - stun:8555
AlexxIT commented 4 months ago

WebRTC supports domain name as candidate. And go2rtc supports this. Unfortunately I don't have IPv6 to debug and fix your problem.

mattlqx commented 2 months ago

Having a similar issue here... with go2rtc spawned from a Frigate container, go2rtc ports will only listen on tcp6.

config:

api:
  origin: '*'
hass:
  config: /config
log:
  format: text
rtsp:
  default_query: mp4
  listen: 0.0.0.0:8554
webrtc:
  candidates:
  - stun:8555

Listen ports in the container:

root@frigate-0:/opt/frigate# netstat -lnp 
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN      128/nginx: master p 
tcp        0      0 0.0.0.0:8971            0.0.0.0:*               LISTEN      128/nginx: master p 
tcp        0      0 127.0.0.1:8082          0.0.0.0:*               LISTEN      407/frigate.output  
tcp        0      0 127.0.0.1:5002          0.0.0.0:*               LISTEN      107/python3         
tcp        0      0 127.0.0.1:5001          0.0.0.0:*               LISTEN      107/python3         
tcp6       0      0 :::1984                 :::*                    LISTEN      98/go2rtc           
tcp6       0      0 :::8555                 :::*                    LISTEN      98/go2rtc           
tcp6       0      0 :::8554                 :::*                    LISTEN      98/go2rtc   

I've tried every variation of listen config that I can think of but can't force it to listen on ipv4.