godotengine / webrtc-native

The official GDNative WebRTC implementation for non-html exports.
MIT License
198 stars 27 forks source link

`Invalid candidate format` When adding an ice candidate generated from browser WebRTC #128

Open rylydou opened 6 months ago

rylydou commented 6 months ago

Godot version

v4.2.1.rc1.official [daeb1c729]

Plugin version

1.0.3

System information

Fedora 39

Issue description

When trying to set up a WebRTC connect between Godot and the browser the browser successfully connects but Godot fails when receiving ice candidates from the browser (Invalid candidate format). According the libdatachannel it should be compatible with the browser. There also datachannel-wasm for the browser which might offer better compatibility but I have not done any testing because it would require setting up WebAssembly.

Why am I doing all this? Although WebSockets exists the only way to send UDP (or UDP like) packets in a browser is with WebRTC or WebTransport. WebTransport is not supported in Safari yet, a deal breaker for smartphones leaving the only other option being WebRTC.

Steps to reproduce

See the attached example project.

Minimal reproduction project

Godot Remote - An in-development addon to provide functionality for using a smartphone as a remote controller, sort of like jackbox.tv.

rylydou commented 6 months ago

UPDATE: I switched to using SIP Sorcery for WebRTC communication and got it to work, check it out here.

It still would be nice if the GDNative plugin worked especially since it seams so close to working. Maybe I'm doing something wrong somewhere?

Faless commented 6 months ago

When trying to set up a WebRTC connect between Godot and the browser the browser successfully connects but Godot fails when receiving ice candidates from the browser (Invalid candidate format).

Would be great if you could post the candidate data that is failing so we can better understand if it's a problem with the Godot wrapper or libdatachannel itself (in which case we should report it upstream).

rylydou commented 6 months ago

Of course!

The client sends 3 candidates in total + an empty one which is discarded and not sent:

  1. sdp_mid=0 sdp_index=0 candidate=candidate:0 1 UDP 2122252543 f2de9f8c-ebcf-4a03-8396-6d93eadb5e43.local 58521 typ host
  2. sdp_mid=0 sdp_index=0 candidate=candidate:2 1 TCP 2105524479 f2de9f8c-ebcf-4a03-8396-6d93eadb5e43.local 9 typ host tcptype active
  3. sdp_mid=0 sdp_index=0 candidate=candidate:1 1 UDP 1686052863 174.34.10.163 58521 typ srflx raddr 0.0.0.0 rport 0

Here are the complete logs:

Sever Log

Godot Engine v4.2.1.rc1.official.daeb1c729 - https://godotengine.org
Vulkan API 1.3.260 - Forward Mobile - Using Vulkan Device #0: NVIDIA - NVIDIA GeForce GTX 1650 SUPER

[Remote] Available IP addresses: ["192.168.68.65", "fe80:0:0:0:e8b7:dd3b:a85b:4241", "127.0.0.1", "0:0:0:0:0:0:0:1"]
[Remote] Using IP address: 192.168.68.65
[Remote] Starting servers
[Remote/HTTP] Finding an open port starting at: 8080
[Remote/HTTP] Server started at address: http://192.168.68.65:8080
[Remote/Driver] Finding an open port starting at: 8081
[Remote/Driver] Server started on port #8081
[RTC] Creating client #572495
[RTC] Received Description: type=offer sdp=v=0
o=mozilla...THIS_IS_SDPARTA-99.0 7944487523876583680 0 IN IP4 0.0.0.0
s=-
t=0 0
a=fingerprint:sha-256 68:AD:86:04:34:62:BA:E5:53:D0:63:E5:D5:A1:22:C1:55:A8:2C:96:65:80:23:1A:60:C3:22:47:36:5A:13:DD
a=group:BUNDLE 0
a=ice-options:trickle
a=msid-semantic:WMS *
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=sendrecv
a=ice-pwd:5407e75bfb1d7c8f1181a4966de4f88d
a=ice-ufrag:cb12c021
a=mid:0
a=setup:actpass
a=sctp-port:5000
a=max-message-size:1073741823

[RTC] set_remote_description: OK
[RTC] Received Candidate: sdp_mid=0 sdp_index=0 candidate=candidate:0 1 UDP 2122252543 f2de9f8c-ebcf-4a03-8396-6d93eadb5e43.local 58521 typ host
[RTC] add_ice_candidate: Failed
[RTC] Received Candidate: sdp_mid=0 sdp_index=0 candidate=candidate:2 1 TCP 2105524479 f2de9f8c-ebcf-4a03-8396-6d93eadb5e43.local 9 typ host tcptype active
[RTC] add_ice_candidate: Failed
[RTC] Created Description: type=answer sdp=v=0
o=rtc 727515107 0 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=msid-semantic:WMS *
a=setup:active
a=ice-ufrag:4saw
a=ice-pwd:kJv0CB5g1KGb9l7WfLiT4t
a=ice-options:ice2,trickle
a=fingerprint:sha-256 E1:21:30:1F:5F:E7:38:CC:32:57:A8:DF:29:4C:7A:1B:E3:C1:48:1E:00:DD:CC:5A:D0:28:BB:66:36:6B:8A:AD
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=mid:0
a=sendrecv
a=sctp-port:5000
a=max-message-size:262144

[RTC] set_local_description: OK
[RTC] Created Candidate: media=0 index=0 name=candidate:1 1 UDP 2122317823 192.168.68.65 56108 typ host
[RTC] Received Candidate: sdp_mid=0 sdp_index=0 candidate=candidate:1 1 UDP 1686052863 174.34.10.163 58521 typ srflx raddr 0.0.0.0 rport 0
[RTC] add_ice_candidate: Failed
[RTC] Created Candidate: media=0 index=0 name=candidate:2 1 UDP 1686109951 174.34.10.163 56108 typ srflx raddr 0.0.0.0 rport 0
Client Log

[RTC] Creating offer. [index2.js:112:15](http://localhost:8080/index2.js)
Object { type: "offer", sdp: "v=0\r\no=mozilla...THIS_IS_SDPARTA-99.0 7944487523876583680 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 68:AD:86:04:34:62:BA:E5:53:D0:63:E5:D5:A1:22:C1:55:A8:2C:96:65:80:23:1A:60:C3:22:47:36:5A:13:DD\r\na=group:BUNDLE 0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:5407e75bfb1d7c8f1181a4966de4f88d\r\na=ice-ufrag:cb12c021\r\na=mid:0\r\na=setup:actpass\r\na=sctp-port:5000\r\na=max-message-size:1073741823\r\n" }
[index2.js:114:15](http://localhost:8080/index2.js)
[RTC] Setting local description to offer. [index2.js:115:15](http://localhost:8080/index2.js)
[RTC] Sending offer. [index2.js:117:15](http://localhost:8080/index2.js)
[RTC] Local candidate:  
RTCIceCandidate { candidate: "candidate:0 1 UDP 2122252543 f2de9f8c-ebcf-4a03-8396-6d93eadb5e43.local 58521 typ host", sdpMid: "0", sdpMLineIndex: 0, usernameFragment: "cb12c021" }
[index2.js:84:17](http://localhost:8080/index2.js)
[RTC] Local candidate:  
RTCIceCandidate { candidate: "candidate:2 1 TCP 2105524479 f2de9f8c-ebcf-4a03-8396-6d93eadb5e43.local 9 typ host tcptype active", sdpMid: "0", sdpMLineIndex: 0, usernameFragment: "cb12c021" }
[index2.js:84:17](http://localhost:8080/index2.js)
[WebSocket] Message:  {"_":"description","sdp":"v=0\r\no=rtc 727515107 0 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=msid-semantic:WMS *\r\na=setup:active\r\na=ice-ufrag:4saw\r\na=ice-pwd:kJv0CB5g1KGb9l7WfLiT4t\r\na=ice-options:ice2,trickle\r\na=fingerprint:sha-256 E1:21:30:1F:5F:E7:38:CC:32:57:A8:DF:29:4C:7A:1B:E3:C1:48:1E:00:DD:CC:5A:D0:28:BB:66:36:6B:8A:AD\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 0.0.0.0\r\na=mid:0\r\na=sendrecv\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n","type":"answer"} [index3.js:16:17](http://localhost:8080/index3.js)
[RTC] Received answer: v=0
o=rtc 727515107 0 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=msid-semantic:WMS *
a=setup:active
a=ice-ufrag:4saw
a=ice-pwd:kJv0CB5g1KGb9l7WfLiT4t
a=ice-options:ice2,trickle
a=fingerprint:sha-256 E1:21:30:1F:5F:E7:38:CC:32:57:A8:DF:29:4C:7A:1B:E3:C1:48:1E:00:DD:CC:5A:D0:28:BB:66:36:6B:8A:AD
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=mid:0
a=sendrecv
a=sctp-port:5000
a=max-message-size:262144

[index2.js:98:17](http://localhost:8080/index2.js)
[RTC] Setting desc [index2.js:99:17](http://localhost:8080/index2.js)
[WebSocket] Message:  {"_":"candidate","candidate":"candidate:1 1 UDP 2122317823 192.168.68.65 56108 typ host","sdp_index":0,"sdp_mid":"0"} [index3.js:16:17](http://localhost:8080/index3.js)
[RTC] Received candidate: 
Object { candidate: "candidate:1 1 UDP 2122317823 192.168.68.65 56108 typ host", sdp_mid: "0", sdp_index: 0 }
[index2.js:104:17](http://localhost:8080/index2.js)
[RTC] Peer: connecting [index2.js:94:17](http://localhost:8080/index2.js)
[RTC] Local candidate:  
RTCIceCandidate { candidate: "candidate:1 1 UDP 1686052863 174.34.10.163 58521 typ srflx raddr 0.0.0.0 rport 0", sdpMid: "0", sdpMLineIndex: 0, usernameFragment: "cb12c021" }
[index2.js:84:17](http://localhost:8080/index2.js)
[RTC] Local candidate:  
RTCIceCandidate { candidate: "", sdpMid: "0", sdpMLineIndex: 0, usernameFragment: "cb12c021" }
[index2.js:84:17](http://localhost:8080/index2.js)
[RTC] Local candidate:  null [index2.js:84:17](http://localhost:8080/index2.js)
[WebSocket] Message:  {"_":"candidate","candidate":"candidate:2 1 UDP 1686109951 174.34.10.163 56108 typ srflx raddr 0.0.0.0 rport 0","sdp_index":0,"sdp_mid":"0"} [index3.js:16:17](http://localhost:8080/index3.js)
[RTC] Received candidate: 
Object { candidate: "candidate:2 1 UDP 1686109951 174.34.10.163 56108 typ srflx raddr 0.0.0.0 rport 0", sdp_mid: "0", sdp_index: 0 }
[index2.js:104:17](http://localhost:8080/index2.js)
[RTC] Peer: connected [index2.js:94:17](http://localhost:8080/index2.js)
[RTC] Reliable channel opened. [index2.js:46:17](http://localhost:8080/index2.js)
[RTC] Unreliable channel opened. [index2.js:64:17](http://localhost:8080/index2.js)
[Client] Connected.