pion / ice

A Go implementation of ICE
https://pion.ly/
MIT License
444 stars 158 forks source link

different ice candidate behavior as chrome #440

Closed cnderrauber closed 2 years ago

cnderrauber commented 2 years ago

Your environment.

What did you do?

I have more than one interfaces, 1 wireless(172.19.4.x), 1 wire(172.19.20.x), 2 vpn. And enable udp mux at 7884 and network interface filter only include the en0 (wireless).

That will cause udp mux listen on(0.0.0.0), but only send candidate 172.19.4.x, chrome first nominate 172.19.4.x candidate and accept by pion, then it discover the new reachable address not announced (172.19.20.x), and try nominate this new candidate, pion response to the ping request with ‘use-candidate’, but reject switch to the new candidate because it already have one. But chrome switch to the new candidate(because it received the ping response) and stop ping the old one, so after some seconds, timeout and disconnected.

Pion:

ice INFO: 2022/04/11 14:36:34 Setting new connection state: Connected
ice TRACE: 14:36:34.088768 agent.go:964: ping STUN from udp4 host 172.19.4.80:7884 to udp4 host 172.19.4.80:63531
pc INFO: 2022/04/11 14:36:34 ICE connection state changed: connected
ice TRACE: 14:36:34.090198 selection.go:221: inbound STUN (SuccessResponse) from udp4 host 172.19.4.80:63531 to udp4 host 172.19.4.80:7884
ice TRACE: 14:36:34.090215 selection.go:231: Found valid candidate pair: prio 9114756778549174527 (local, prio 2130706431) udp4 host 172.19.4.80:7884 <-> udp4 host 172.19.4.80:63531 (remote, prio 2122194687)

chrome:

[3639:83971:0411/143634.040308:INFO:p2p_transport_channel.cc(306)] Switching selected connection due to: candidate pair state changed
[3639:83971:0411/143634.040318:INFO:p2p_transport_channel.cc(1821)] Channel[0|1|__]: New selected connection: Conn[44a800:0:Net[en0:172.19.4.x/22:Wifi:id=1]:rzwnBbZR:1:0:local:udp:172.19.4.x:63531->S5o7kJ      mC:1:2130706431:local:udp:172.19.4.x:7884|CRWS|S|0|0|9114756780671369214|18]

................

[3639:83971:0411/143634.187853:INFO:p2p_transport_channel.cc(1818)] Channel[0|1|RW]: Previous selected connection: Conn[44a800:0:Net[en0:172.19.4.x/22:Wifi:id=1]:rzwnBbZR:1:0:local:udp:172.19.4.x:63531->S      5o7kJmC:1:2130706431:local:udp:172.19.4.x:7884|CRWS|-|0|0|9114756780671369214|10]
[3639:83971:0411/143634.187873:INFO:p2p_transport_channel.cc(1821)] Channel[0|1|RW]: New selected connection: Conn[44f800:0:Net[en7:172.19.20.x/22:Ethernet:id=2]:aJepAjnq:1:0:local:udp:172.19.20.x:58485->      LqEBX0Qm:1:2130706431:prflx:udp:172.19.20.x:7884|CRWS|S|0|0|9115038255648079870|1]

chrome first nominate 172.19.4.x, then nominate 172.19.20.x. Pion response to both nominate, but only select the first one and expect ping request from first one.

After a few seconds, pion disconnect because no check alive ping request received.

ice TRACE: 14:36:56.935129 selection.go:221: inbound STUN (SuccessResponse) from udp4 host 172.19.20.119:58485 to udp4 host 172.19.4.80:7884
ice TRACE: 14:36:56.935182 selection.go:231: Found valid candidate pair: prio 9115038253525819647 (local, prio 2130706431) udp4 host 172.19.4.80:7884 <-> udp4 host 172.19.20.119:58485 (remote, prio 2122260223)
mdns WARNING: 2022/04/11 14:36:57 Failed to parse mDNS packet parsing/packing of this type isn't available yet
mdns WARNING: 2022/04/11 14:36:57 Failed to parse mDNS packet parsing/packing of this type isn't available yet
ice INFO: 2022/04/11 14:36:58 Setting new connection state: Disconnected
pc INFO: 2022/04/11 14:36:58 ICE connection state changed: disconnected
pc INFO: 2022/04/11 14:36:58 peer connection state changed: disconnected

From log we can see chrome send ping reqeust from the latter candidate, but pion expect the first one.

What did you expect?

Pion select the second nominated candidate if it has higher priority than the previous one, or don't response to the stun bind request with 'Use-Candidate' attribute if it don't want to switch to.

What happened?

Pion response to the second request, but not switch to it, state inconsistency with client

In https://datatracker.ietf.org/doc/html/rfc8445#section-8

Once the controlling agent has successfully nominated a candidate pair (Section 7.2.5.3.4), the agent MUST NOT nominate another pair for same component of the data stream within the ICE session. Doing so requires an ICE restart.

Looks chrome don't compliant this.

And Pion seems not compliant below behavior

A controlling agent that does not support this specification (i.e., it is implemented according to RFC 5245) might nominate more than one candidate pair. This was referred to as "aggressive nomination" in RFC 5245. If more than one candidate pair is nominated by the controlling agent, and if the controlled agent accepts multiple nominations requests, the agents MUST produce the selected pairs and use the pairs with the highest priority.

cnderrauber commented 2 years ago

Try to make a local pr that response 400 to the new nominate request, will cause chrome period ice disconnect, so what's the best solution for this case?

cnderrauber commented 2 years ago

I believe this belong to pion/ice, and we need aggressive nominate things, how about make it a SettingEngine option? @Sean-Der