pion / webrtc

Pure Go implementation of the WebRTC API
https://pion.ly
MIT License
13.36k stars 1.63k forks source link

IPv6 Support #1315

Open sipsorcery opened 4 years ago

sipsorcery commented 4 years ago

Your environment.

aaron@pcdodo:~/go/src/github.com/pion/webrtc/examples/data-channels$ go version
go version go1.13.8 linux/amd64
aaron@pcdodo:~/go/src/github.com/pion/webrtc/examples/data-channels$ lsb_release -a
 No LSB modules are available.
 Distributor ID: 
 Ubuntu
 Description:    Ubuntu 20.04 
 LTS
 Release:        20.04 
 Codename:       focal
aaron@pcdodo:~/go/src/github.com/pion/webrtc/examples/data-channels$ uname -a
Linux pcdodo 4.4.0-19041-Microsoft #1-Microsoft Fri Dec 06 14:06:00 PST 2019 x86_64 x86_64 x86_64 GNU/Linux
aaron@pcdodo:~/go/src/github.com/pion/webrtc/examples/data-channels$ 

What did you do?

Attempted to run the data-channels example using:

echo <sdp offer> | go run main.go

What happened?

aaron@pcdodo:~/go/src/github.com/pion/webrtc/examples/data-channels$ echo eyJ0eXBlIjoib2ZmZXIiLCJzZHAiOiJ2PTBcclxubz0tIDY5MjkwIDAgSU4gSVA0IDEyNy4wLjAuMVxyXG5zPS1cclxudD0wIDBcclxuYT1maW5nZXJwcmludDpzaGEtMjU2IEM2OkVEOjhDOjlEOjA2OjUwOjc3OjIzOjBBOjRBOkQ4OjQyOjY4OjI5OkQwOjcwOjJGOkJCOkM3OjcyOkVDOjk4OjVDOjYyOjA3OjFCOjBDOjVEOkNCOkNFOkJFOkNEXHJcbmE9Z3JvdXA6QlVORExFIDBcclxubT1hcHBsaWNhdGlvbiA5IFVEUC9EVExTL1NDVFAgd2VicnRjLWRhdGFjaGFubmVsXHJcbmM9SU4gSVA0IDAuMC4wLjBcclxuYT1pY2UtdWZyYWc6V05HUVxyXG5hPWljZS1wd2Q6SU9aUEdWSFdaTkZXRlJORVNJVEVGSVZOXHJcbmE9ZmluZ2VycHJpbnQ6c2hhLTI1NiBDNjpFRDo4Qzo5RDowNjo1MDo3NzoyMzowQTo0QTpEODo0Mjo2ODoyOTpEMDo3MDoyRjpCQjpDNzo3MjpFQzo5ODo1Qzo2MjowNzoxQjowQzo1RDpDQjpDRTpCRTpDRFxyXG5hPWNhbmRpZGF0ZToyNDQxIDEgdWRwIDY1OTEzNiBmZTgwOjo1NGE5OmQyMzg6YjJlZTpjZWIlMjEgNjA3MjAgdHlwIGhvc3QgZ2VuZXJhdGlvbiAwXHJcbmE9Y2FuZGlkYXRlOjI5NDQgMSB1ZHAgNjU5MTM2IDE5Mi4xNjguMTEuNTAgNjA3MjAgdHlwIGhvc3QgZ2VuZXJhdGlvbiAwXHJcbmE9aWNlLW9wdGlvbnM6aWNlMix0cmlja2xlXHJcbmE9bWlkOjBcclxuYT1lbmQtb2YtY2FuZGlkYXRlc1xyXG5hPXNldHVwOmFjdHBhc3NcclxuYT1zY3RwLXBvcnQ6NDAwMFxyXG5hPW1heC1tZXNzYWdlLXNpemU6MjYyMTQ0XHJcbiJ9 | go run main.go

panic: failed to parse address

goroutine 1 [running]:
main.main()
        /home/aaron/go/src/github.com/pion/webrtc/examples/data-channels/main.go:68 +0x431
exit status 2

The deserialised SDP is as below. If the ICE candidate with the IPv6 line is removed then the error does not occur.

v=0
o=- 69290 0 IN IP4 127.0.0.1
s=-
t=0 0
a=fingerprint:sha-256 C6:ED:8C:9D:06:50:77:23:0A:4A:D8:42:68:29:D0:70:2F:BB:C7:72:EC:98:5C:62:07:1B:0C:5D:CB:CE:BE:CD
a=group:BUNDLE 0
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=ice-ufrag:WNGQ
a=ice-pwd:IOZPGVHWZNFWFRNESITEFIVN
a=fingerprint:sha-256 C6:ED:8C:9D:06:50:77:23:0A:4A:D8:42:68:29:D0:70:2F:BB:C7:72:EC:98:5C:62:07:1B:0C:5D:CB:CE:BE:CD
a=candidate:2441 1 udp 659136 fe80::54a9:d238:b2ee:ceb%21 60720 typ host generation 0
a=candidate:2944 1 udp 659136 192.168.11.50 60720 typ host generation 0
a=ice-options:ice2,trickle
a=mid:0
a=end-of-candidates
a=setup:actpass
a=sctp-port:4000
a=max-message-size:262144

A separate related issue is the SDP answer received from the data-channels example isn't setting the ICE candidate's `foundation value. An example SDP answer is below:

eyJ0eXBlIjoiYW5zd2VyIiwic2RwIjoidj0wXHJcbm89LSAzNTA1NTg0OTUgMTU5NDY3NjE0NCBJTiBJUDQgMC4wLjAuMFxyXG5zPS1cclxudD0wIDBcclxuYT1maW5nZXJwcmludDpzaGEtMjU2IDQzOjEyOjIwOjlFOjYwOkQxOjBBOkM2OjZCOkMxOkU5OkZGOjY0OkQ2OkYxOjEyOkQwOjA3OjY0OjE5OkMxOkI3OjMxOjI1OjQ5OkQzOjIzOkIxOkI1OkFBOkI5OjI5XHJcbmE9Z3JvdXA6QlVORExFIDBcclxubT1hcHBsaWNhdGlvbiA5IERUTFMvU0NUUCA1MDAwXHJcbmM9SU4gSVA0IDAuMC4wLjBcclxuYT1zZXR1cDphY3RpdmVcclxuYT1taWQ6MFxyXG5hPXNlbmRyZWN2XHJcbmE9c2N0cG1hcDo1MDAwIHdlYnJ0Yy1kYXRhY2hhbm5lbCAxMDI0XHJcbmE9aWNlLXVmcmFnOkFkaWNRZWdaSVBsWnByaUNcclxuYT1pY2UtcHdkOkxpWWJISXd6c05FT0hJUnFxWW1vUWpwZFh0bFNUcGpGXHJcbmE9Y2FuZGlkYXRlOmZvdW5kYXRpb24gMSB1ZHAgMjEzMDcwNjQzMSAxOTIuMTY4LjExLjUwIDUxNzk5IHR5cCBob3N0IGdlbmVyYXRpb24gMFxyXG5hPWNhbmRpZGF0ZTpmb3VuZGF0aW9uIDIgdWRwIDIxMzA3MDY0MzEgMTkyLjE2OC4xMS41MCA1MTc5OSB0eXAgaG9zdCBnZW5lcmF0aW9uIDBcclxuYT1jYW5kaWRhdGU6Zm91bmRhdGlvbiAxIHVkcCAyMTMwNzA2NDMxIDE3Mi4yOS4xNjAuMSA1MTgwMCB0eXAgaG9zdCBnZW5lcmF0aW9uIDBcclxuYT1jYW5kaWRhdGU6Zm91bmRhdGlvbiAyIHVkcCAyMTMwNzA2NDMxIDE3Mi4yOS4xNjAuMSA1MTgwMCB0eXAgaG9zdCBnZW5lcmF0aW9uIDBcclxuYT1jYW5kaWRhdGU6Zm91bmRhdGlvbiAxIHVkcCAyMTMwNzA2NDMxIDE5Mi4xNjguNjQuMSA1MTgwMSB0eXAgaG9zdCBnZW5lcmF0aW9uIDBcclxuYT1jYW5kaWRhdGU6Zm91bmRhdGlvbiAyIHVkcCAyMTMwNzA2NDMxIDE5Mi4xNjguNjQuMSA1MTgwMSB0eXAgaG9zdCBnZW5lcmF0aW9uIDBcclxuYT1jYW5kaWRhdGU6Zm91bmRhdGlvbiAxIHVkcCAyMTMwNzA2NDMxIDE5Mi4xNjguMTM3LjEgNTE4MDYgdHlwIGhvc3QgZ2VuZXJhdGlvbiAwXHJcbmE9Y2FuZGlkYXRlOmZvdW5kYXRpb24gMiB1ZHAgMjEzMDcwNjQzMSAxOTIuMTY4LjEzNy4xIDUxODA2IHR5cCBob3N0IGdlbmVyYXRpb24gMFxyXG5hPWNhbmRpZGF0ZTpmb3VuZGF0aW9uIDEgdWRwIDE2OTQ0OTg4MTUgMzcuMjI4LjI0My4xMDcgMjQ0MTMgdHlwIHNyZmx4IHJhZGRyIDAuMC4wLjAgcnBvcnQgNTE4MTIgZ2VuZXJhdGlvbiAwXHJcbmE9Y2FuZGlkYXRlOmZvdW5kYXRpb24gMiB1ZHAgMTY5NDQ5ODgxNSAzNy4yMjguMjQzLjEwNyAyNDQxMyB0eXAgc3JmbHggcmFkZHIgMC4wLjAuMCBycG9ydCA1MTgxMiBnZW5lcmF0aW9uIDBcclxuYT1lbmQtb2YtY2FuZGlkYXRlc1xyXG4ifQ==

Deserialised:

v=0
o=- 350558495 1594676144 IN IP4 0.0.0.0
s=-
t=0 0
a=fingerprint:sha-256 43:12:20:9E:60:D1:0A:C6:6B:C1:E9:FF:64:D6:F1:12:D0:07:64:19:C1:B7:31:25:49:D3:23:B1:B5:AA:B9:29
a=group:BUNDLE 0
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=setup:active
a=mid:0
a=sendrecv
a=sctpmap:5000 webrtc-datachannel 1024
a=ice-ufrag:AdicQegZIPlZpriC
a=ice-pwd:LiYbHIwzsNEOHIRqqYmoQjpdXtlSTpjF
a=candidate:foundation 1 udp 2130706431 192.168.11.50 51799 typ host generation 0
a=candidate:foundation 2 udp 2130706431 192.168.11.50 51799 typ host generation 0
a=candidate:foundation 1 udp 2130706431 172.29.160.1 51800 typ host generation 0
a=candidate:foundation 2 udp 2130706431 172.29.160.1 51800 typ host generation 0
a=candidate:foundation 1 udp 2130706431 192.168.64.1 51801 typ host generation 0
a=candidate:foundation 2 udp 2130706431 192.168.64.1 51801 typ host generation 0
a=candidate:foundation 1 udp 2130706431 192.168.137.1 51806 typ host generation 0
a=candidate:foundation 2 udp 2130706431 192.168.137.1 51806 typ host generation 0
a=candidate:foundation 1 udp 1694498815 37.228.243.107 24413 typ srflx raddr 0.0.0.0 rport 51812 generation 0
a=candidate:foundation 2 udp 1694498815 37.228.243.107 24413 typ srflx raddr 0.0.0.0 rport 51812 generation 0
a=end-of-candidates
Sean-Der commented 4 years ago

Thanks for the report @sipsorcery ! I will check this out this weekend.

I haven't put any time myself in getting IPv6 working. Will drop an estimate or a PR if things go really well :)

jech commented 4 years ago
a=candidate:2441 1 udp 659136 fe80::54a9:d238:b2ee:ceb%21 60720 typ host generation 0

That's a link-local IPv6 address with an interface identifier. The interface identifier is local to the sending host, and therefore doesn't make any sense in this context. It is not legal according to the grammar given in Section 15.1 of RFC 5245 (which ultimately refers to the IP6-address production in Section 9 of RFC 4566).

@Sean-Der, it's a matter of opinion, but I think that in the interest of robustness Pion should ignore malformed candidate lines rather than failing the whole SDP.

sipsorcery commented 4 years ago

Pion should ignore malformed candidate lines rather than failing the whole SDP.

An alternative would be to snip the zone ID prefix off the IPv6 address.

RFC 4007: IPv6 Scoped Address Architecture, which deals with the zone ID (Windows) or scope ID (Linux), does indicate it can be ignored if not understood.

jech commented 4 years ago

Pion should ignore malformed candidate lines rather than failing the whole SDP.

An alternative would be to snip the zone ID prefix off the IPv6 address.

That's not going to work with link-locals: a link-local is not usable without the scope identifier (you get EINVAL from send/connect).

RFC 4007: IPv6 Scoped Address Architecture, which deals with the zone ID (Windows) or scope ID (Linux), does indicate it can be ignored if not understood.

Site-local is obsolete for unicast (RFC 3879), so the only unicast scoped addresses left are link-local, which don't work without the scope identifier. So it's not going to do you any good.

sipsorcery commented 4 years ago

That's not going to work with link-locals: a link-local is not usable without the scope identifier (you get EINVAL from send/connect).

On Windows 10 connection attempts to IPv6 link local addresses work fine.

The telnet connection attempt from a Windows 10 machine to an Ubuntu machine works.

> telnet fe80::bcc:137b:3bc1:b926 8081

Ubuntu running:

nc -6 -l 8081

On Ubuntu the IPv6 link local addresses don't seem very usable to be even able to ping the local address on the machine the interface name is required. And I wasn't able to find any permutation where Ubuntu could ping a Windows link local address.

ping -6 fe80::bcc:137b:3bc1:b926%eno1

So I guess in short the IPv6 link local address ICE candidates are useful on Windows and not so much on Linux. Supporting them is probably not that critical in either case.

jech commented 4 years ago

On Windows 10 connection attempts to IPv6 link local addresses work fine.

Interesting.

However, I think we can agree that the SDP initially in this bug report is malformed.

jech commented 2 years ago

Probably related to 2699584e9a5b818dec5594a06925170c63dbfa25 and 6160e8033fc0e3a9cf63c21f393edcd896521d50.