awslabs / amazon-kinesis-video-streams-webrtc-sdk-c

Amazon Kinesis Video Streams Webrtc SDK is for developers to install and customize realtime communication between devices and enable secure streaming of video, audio to Kinesis Video Streams.
https://awslabs.github.io/amazon-kinesis-video-streams-webrtc-sdk-c/group__PublicMemberFunctions.html
Apache License 2.0
1.02k stars 307 forks source link

[QUESTION] Are createIceCandidatePairs calls for local srflx candidates unnecessary? #1040

Closed yuma-m closed 3 years ago

yuma-m commented 3 years ago

createIceCandidatePairs is called for local host, prflx, relay candidates but not called for local srflx candidate. Is this implementation correct?

Any design considerations/constraints

createIceCandidatePairs function is called from iceAgentAddRemoteCandidate, iceAgentInitHostCandidate, iceAgentGatherCandidateTimerCallback (but only create candidate pairs against relay candidate) and iceAgentCheckPeerReflexiveCandidate. However, there looks no createIceCandidatePairs calls for local srflx candidate.

https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-c/blob/cd002e5d1b09dc4175aa3ca5339fd16cec4b85fa/src/source/Ice/IceAgent.c#L1007

According to this implementation, it looks a local srflx candidate is only paired with remote candidates which arrives after the srflx candidate is found. Should be createIceCandidatePairs call for local srflx candidates added to around the following lines? https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-c/blob/cd002e5d1b09dc4175aa3ca5339fd16cec4b85fa/src/source/Ice/IceAgent.c#L1516-L1521

yuma-m commented 3 years ago

Related to this question, this behavior (a local srflx candidate is not paired) tend to be occurred when the C-SDK is in a slow network environment. To reproduce this, you can insert sleep(5); in the following line. This can emulate an environment with poor network with the STUN server. https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-c/blob/6cf2beedef82c065c7e1217243f5f198427d3852/src/source/Ice/IceAgent.c#L2408

MushMal commented 3 years ago

https://tools.ietf.org/html/rfc8445#section-5.1.1.2 contains the design which the C WebRTC SDK Ice agent tries to adhere to.

Namely, in case of server-reflexive candidates. We submit a STUN packet and get the response. In case of the successful response (STUN packet), we check whether the XOR-ed address is the same as the host address. If it's the same then we ignore it. If not, we then find the corresponding local candidate and replace its address with the server reflexive address. From that point on, the ICE will continue with the local candidate which has the server reflexive address.

Here is the handling code for the received successful bind packet from the STUN server https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-c/blob/master/src/source/Ice/IceAgent.c#L2544-L2555

Your later comment about introducing 5 second sleep is not relevant as we have timeouts which would invalidate the pair.

Resolving. Please continue discussion if you have more questions.

yuma-m commented 3 years ago

Hi @MushMal, thank you for your answer.

From that point on, the ICE will continue with the local candidate which has the server reflexive address.

From the C-SDK logs which is also sent to you on the email thread, a local server-reflexive candidate f8ixT/1tN whose address is not same as the host address is found, but is not paired with any remote candidate. On the other hand, a local host candidate hg5imiY8u and a local relay candidate HgYFSUfYK (which is found after f8ixT/1tN) are paired with remote candidates.

I couldn't find a reason why a local server-reflexive candidate isn't paired with remote candidate from https://tools.ietf.org/html/rfc8445#section-5.1.1.2. Could you tell why f8ixT/1tN isn't paired?

MushMal commented 3 years ago

Here is what I replied:

Master is receiving an offer with ice_options set to trickle renominate. We reply with trickle answer. Start receiving candidates and start gathering and sending candidates. The first candidate got sent was

2020-12-03 05:39:28 DEBUG iceAgentLogNewCandidate(): New local ice candidate discovered. Id: hg5imiY8u. Ip: 192.168.5.142:50574. Type: host. Protocol: UDP.

Immediately following this pairing gets initiated by the viewer and we succeed pairing the first candidate.

We do continue gathering and here where we discover the next candidate

2020-12-03 05:39:28 DEBUG iceAgentLogNewCandidate(): New local ice candidate discovered. Id: f8ixT/1tN. Ip: 180.63.138.129:45118. Type: srflx. Protocol: UDP.

Though, it seems that the first got connection checked and nominated by the viewer agent.

What I think is going on is the viewer is capable of renominating and it’s rushing to start pairing and checking connections and once it succeeds, it nominates the first one and proceeds.