Пример #1
0
        public async void ChecklistConstructionUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            var rtpIceChannel = new RtpIceChannel(null, RTCIceComponent.rtp, null);

            rtpIceChannel.StartGathering();

            Assert.NotNull(rtpIceChannel);
            Assert.NotEmpty(rtpIceChannel.Candidates);

            foreach (var hostCandidate in rtpIceChannel.Candidates)
            {
                logger.LogDebug($"host candidate: {hostCandidate}");
            }

            var remoteCandidate = RTCIceCandidate.Parse("candidate:408132416 1 udp 2113937151 192.168.11.50 51268 typ host generation 0 ufrag CI7o network-cost 999");

            rtpIceChannel.AddRemoteCandidate(remoteCandidate);

            var remoteCandidate2 = RTCIceCandidate.Parse("candidate:408132417 1 udp 2113937150 192.168.11.50 51268 typ host generation 0 ufrag CI7o network-cost 999");

            rtpIceChannel.AddRemoteCandidate(remoteCandidate2);

            await Task.Delay(500);

            foreach (var entry in rtpIceChannel._checklist)
            {
                logger.LogDebug($"checklist entry: {entry.LocalCandidate.ToShortString()}->{entry.RemoteCandidate.ToShortString()}");
            }

            Assert.Single(rtpIceChannel._checklist);
        }
Пример #2
0
        public void SortChecklistUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            var rtpIceChannel = new RtpIceChannel(null, RTCIceComponent.rtp, null);

            rtpIceChannel.StartGathering();

            Assert.NotNull(rtpIceChannel);
            Assert.NotEmpty(rtpIceChannel.Candidates);

            foreach (var hostCandidate in rtpIceChannel.Candidates)
            {
                logger.LogDebug(hostCandidate.ToString());
            }

            var remoteCandidate = RTCIceCandidate.Parse("candidate:408132416 1 udp 2113937151 192.168.11.50 51268 typ host generation 0 ufrag CI7o network-cost 999");

            rtpIceChannel.AddRemoteCandidate(remoteCandidate);

            var remoteCandidate2 = RTCIceCandidate.Parse("candidate:408132417 1 udp 2113937150 192.168.11.51 51268 typ host generation 0 ufrag CI7o network-cost 999");

            rtpIceChannel.AddRemoteCandidate(remoteCandidate2);

            foreach (var entry in rtpIceChannel._checklist)
            {
                logger.LogDebug($"checklist entry priority {entry.Priority}.");
            }
        }
Пример #3
0
        public async void ChecklistProcessingToFailStateUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            var rtpIceChannel = new RtpIceChannel(null, RTCIceComponent.rtp, null);

            rtpIceChannel.StartGathering();

            Assert.NotNull(rtpIceChannel);
            Assert.NotEmpty(rtpIceChannel.Candidates);

            foreach (var hostCandidate in rtpIceChannel.Candidates)
            {
                logger.LogDebug($"host candidate: {hostCandidate}");
            }

            var remoteCandidate = RTCIceCandidate.Parse("candidate:408132416 1 udp 2113937151 192.168.11.50 51268 typ host generation 0 ufrag CI7o network-cost 999");

            rtpIceChannel.AddRemoteCandidate(remoteCandidate);

            rtpIceChannel.SetRemoteCredentials("CI7o", "xxxxxxxxxxxx");

            logger.LogDebug($"ICE session retry interval {rtpIceChannel.RTO}ms.");

            await Task.Delay(1000);

            rtpIceChannel._checklist.Single().FirstCheckSentAt = DateTime.Now.Subtract(TimeSpan.FromSeconds(RtpIceChannel.FAILED_TIMEOUT_PERIOD));

            await Task.Delay(1000);

            Assert.Equal(ChecklistEntryState.Failed, rtpIceChannel._checklist.Single().State);
            Assert.Equal(ChecklistState.Failed, rtpIceChannel._checklistState);
            Assert.Equal(RTCIceConnectionState.failed, rtpIceChannel.IceConnectionState);
        }
Пример #4
0
        public async void ChecklistProcessingUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            var rtpIceChannel = new RtpIceChannel(null, RTCIceComponent.rtp, null);

            rtpIceChannel.StartGathering();

            Assert.NotNull(rtpIceChannel);
            Assert.NotEmpty(rtpIceChannel.Candidates);

            foreach (var hostCandidate in rtpIceChannel.Candidates)
            {
                logger.LogDebug($"host candidate: {hostCandidate}");
            }

            var remoteCandidate = RTCIceCandidate.Parse("candidate:408132416 1 udp 2113937151 192.168.11.50 51268 typ host generation 0 ufrag CI7o network-cost 999");

            rtpIceChannel.AddRemoteCandidate(remoteCandidate);

            rtpIceChannel.SetRemoteCredentials("CI7o", "xxxxxxxxxxxx");
            rtpIceChannel.StartGathering();

            await Task.Delay(2000);

            var checklistEntry = rtpIceChannel._checklist.Single();

            logger.LogDebug($"Checklist entry state {checklistEntry.State}, last check sent at {checklistEntry.LastCheckSentAt}.");

            Assert.Equal(ChecklistEntryState.InProgress, checklistEntry.State);
        }
Пример #5
0
        public async void ChecklistProcessingToFailStateUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            var rtpIceChannel = new RtpIceChannel(null, RTCIceComponent.rtp, null);

            rtpIceChannel.StartGathering();

            Assert.NotNull(rtpIceChannel);
            Assert.NotEmpty(rtpIceChannel.Candidates);

            foreach (var hostCandidate in rtpIceChannel.Candidates)
            {
                logger.LogDebug($"host candidate: {hostCandidate}");
            }

            var remoteCandidate = RTCIceCandidate.Parse("candidate:408132416 1 udp 2113937151 192.168.11.50 51268 typ host generation 0 ufrag CI7o network-cost 999");

            rtpIceChannel.AddRemoteCandidate(remoteCandidate);

            rtpIceChannel.SetRemoteCredentials("CI7o", "xxxxxxxxxxxx");

            logger.LogDebug($"ICE session retry interval {rtpIceChannel.RTO}ms.");

            // The defaults are 5 STUN requests and for a checklist with one entry they will be 500ms apart.
            await Task.Delay(4000);

            Assert.Equal(ChecklistEntryState.Failed, rtpIceChannel._checklist.Single().State);
            Assert.Equal(ChecklistState.Failed, rtpIceChannel._checklistState);
            Assert.Equal(RTCIceConnectionState.failed, rtpIceChannel.IceConnectionState);
        }
Пример #6
0
        public async void CheckSuccessfulConnectionForRelayCandidatesUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            using (MockTurnServer mockTurnServer = new MockTurnServer())
            {
                var iceServers = new List <RTCIceServer> {
                    new RTCIceServer
                    {
                        urls = $"turn:{mockTurnServer.ListeningEndPoint}",
                    }
                };
                var rtpIceChannelRelay = new RtpIceChannel(null, RTCIceComponent.rtp, iceServers, RTCIceTransportPolicy.relay);
                rtpIceChannelRelay.IsController = true;
                logger.LogDebug($"RTP ICE channel RTP socket local end point {rtpIceChannelRelay.RTPLocalEndPoint}.");

                var rtpIceChannelHost = new RtpIceChannel();
                logger.LogDebug($"RTP ICE channel RTP socket local end point {rtpIceChannelHost.RTPLocalEndPoint}.");

                rtpIceChannelRelay.StartGathering();
                rtpIceChannelHost.StartGathering();

                // Need to give some time for the relay channel to connect to the mock TURN server.
                await Task.Delay(200);

                Assert.Single(rtpIceChannelRelay.Candidates);   // Should only have the single local relay candidate.
                Assert.NotEmpty(rtpIceChannelHost.Candidates);
                Assert.Equal(RTCIceGatheringState.complete, rtpIceChannelRelay.IceGatheringState);
                Assert.Equal(RTCIceConnectionState.@new, rtpIceChannelRelay.IceConnectionState);
                Assert.Equal(RTCIceGatheringState.complete, rtpIceChannelHost.IceGatheringState);
                Assert.Equal(RTCIceConnectionState.@new, rtpIceChannelHost.IceConnectionState);

                // Exchange ICE user and passwords.
                rtpIceChannelRelay.SetRemoteCredentials(rtpIceChannelHost.LocalIceUser, rtpIceChannelHost.LocalIcePassword);
                rtpIceChannelHost.SetRemoteCredentials(rtpIceChannelRelay.LocalIceUser, rtpIceChannelRelay.LocalIcePassword);

                Assert.Equal(RTCIceConnectionState.checking, rtpIceChannelRelay.IceConnectionState);
                Assert.Equal(RTCIceConnectionState.checking, rtpIceChannelHost.IceConnectionState);

                // Exchange ICE candidates.
                rtpIceChannelRelay.Candidates.ForEach(x => rtpIceChannelHost.AddRemoteCandidate(x));
                rtpIceChannelHost.Candidates.ForEach(x => rtpIceChannelRelay.AddRemoteCandidate(x));

                await Task.Delay(1000);

                Assert.Equal(RTCIceConnectionState.connected, rtpIceChannelRelay.IceConnectionState);
                Assert.Equal(RTCIceConnectionState.connected, rtpIceChannelHost.IceConnectionState);
                Assert.NotNull(rtpIceChannelRelay.NominatedEntry);
                Assert.NotNull(rtpIceChannelHost.NominatedEntry);
            }
        }
Пример #7
0
        /// <summary>
        /// Adds a remote ICE candidate to the list this peer is attempting to connect against.
        /// </summary>
        /// <param name="candidateInit">The remote candidate to add.</param>
        public void addIceCandidate(RTCIceCandidateInit candidateInit)
        {
            RTCIceCandidate candidate = new RTCIceCandidate(candidateInit);

            if (_rtpIceChannel.Component == candidate.component)
            {
                _rtpIceChannel.AddRemoteCandidate(candidate);
            }
            else
            {
                logger.LogWarning($"Remote ICE candidate not added as no available ICE session for component {candidate.component}.");
            }
        }
Пример #8
0
        public async void CheckSuccessfulConnectionForHostCandidatesUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            var rtpIceChannelA = new RtpIceChannel();

            rtpIceChannelA.IsController = true;
            logger.LogDebug($"RTP ICE channel RTP socket local end point {rtpIceChannelA.RTPLocalEndPoint}.");

            var rtpIceChannelB = new RtpIceChannel();

            logger.LogDebug($"RTP ICE channel RTP socket local end point {rtpIceChannelB.RTPLocalEndPoint}.");

            rtpIceChannelA.StartGathering();
            rtpIceChannelB.StartGathering();

            Assert.NotEmpty(rtpIceChannelA.Candidates);
            Assert.NotEmpty(rtpIceChannelB.Candidates);

            // Because there are no ICE servers gathering completes after the host candidates are gathered.
            Assert.Equal(RTCIceGatheringState.complete, rtpIceChannelA.IceGatheringState);
            Assert.Equal(RTCIceGatheringState.complete, rtpIceChannelB.IceGatheringState);
            Assert.Equal(RTCIceConnectionState.@new, rtpIceChannelA.IceConnectionState);
            Assert.Equal(RTCIceConnectionState.@new, rtpIceChannelB.IceConnectionState);

            // Exchange ICE user and passwords.
            rtpIceChannelA.SetRemoteCredentials(rtpIceChannelB.LocalIceUser, rtpIceChannelB.LocalIcePassword);
            rtpIceChannelB.SetRemoteCredentials(rtpIceChannelA.LocalIceUser, rtpIceChannelA.LocalIcePassword);

            Assert.Equal(RTCIceConnectionState.checking, rtpIceChannelA.IceConnectionState);
            Assert.Equal(RTCIceConnectionState.checking, rtpIceChannelB.IceConnectionState);

            // Give the RTP channel listeners time to start.
            await Task.Delay(500);

            // Exchange ICE candidates.
            rtpIceChannelA.Candidates.ForEach(x => rtpIceChannelB.AddRemoteCandidate(x));
            rtpIceChannelB.Candidates.ForEach(x => rtpIceChannelA.AddRemoteCandidate(x));

            // Give the RTP ICE channel checklists time to send the first few checks.
            await Task.Delay(4000);

            Assert.Equal(RTCIceConnectionState.connected, rtpIceChannelA.IceConnectionState);
            Assert.Equal(RTCIceConnectionState.connected, rtpIceChannelB.IceConnectionState);
            Assert.NotNull(rtpIceChannelA.NominatedEntry);
            Assert.NotNull(rtpIceChannelB.NominatedEntry);
        }
Пример #9
0
        public async void CheckPeerReflexiveReplacedByHostCandidatesUnitTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            var rtpIceChannelA = new RtpIceChannel();

            rtpIceChannelA.IsController = true;
            logger.LogDebug($"RTP ICE channel RTP socket local end point {rtpIceChannelA.RTPLocalEndPoint}.");

            var rtpIceChannelB = new RtpIceChannel();

            logger.LogDebug($"RTP ICE channel RTP socket local end point {rtpIceChannelB.RTPLocalEndPoint}.");

            // Set up the triggers so the test can proceed at the right pace.
            ManualResetEventSlim connected = new ManualResetEventSlim();

            rtpIceChannelA.OnIceConnectionStateChange += (state) => { if (state == RTCIceConnectionState.connected)
                                                                      {
                                                                          connected.Set();
                                                                      }
            };

            rtpIceChannelA.StartGathering();
            rtpIceChannelB.StartGathering();

            Assert.NotEmpty(rtpIceChannelA.Candidates);
            Assert.NotEmpty(rtpIceChannelB.Candidates);

            // Because there are no ICE servers gathering completes after the host candidates are gathered.
            Assert.Equal(RTCIceGatheringState.complete, rtpIceChannelA.IceGatheringState);
            Assert.Equal(RTCIceGatheringState.complete, rtpIceChannelB.IceGatheringState);
            Assert.Equal(RTCIceConnectionState.@new, rtpIceChannelA.IceConnectionState);
            Assert.Equal(RTCIceConnectionState.@new, rtpIceChannelB.IceConnectionState);

            // Exchange ICE user and passwords.
            //rtpIceChannelA.SetRemoteCredentials(rtpIceChannelB.LocalIceUser, rtpIceChannelB.LocalIcePassword);
            rtpIceChannelB.SetRemoteCredentials(rtpIceChannelA.LocalIceUser, rtpIceChannelA.LocalIcePassword);

            Assert.Equal(RTCIceConnectionState.@new, rtpIceChannelA.IceConnectionState);
            Assert.Equal(RTCIceConnectionState.checking, rtpIceChannelB.IceConnectionState);

            // Only give the non-controlling peer the remote candidates.
            rtpIceChannelA.Candidates.ForEach(x => rtpIceChannelB.AddRemoteCandidate(x));
            //rtpIceChannelB.Candidates.ForEach(x => rtpIceChannelA.AddRemoteCandidate(x));

            // Want channel B to send checks to A so that it create peer reflexive candidates.
            int retries = 0;

            while (rtpIceChannelA._remoteCandidates.Count == 0 && retries < 5)
            {
                logger.LogDebug("Waiting for channel A to acquire peer reflexive candidates.");
                retries++;
                await Task.Delay(500);
            }

            Assert.True(rtpIceChannelA._remoteCandidates.Count > 0);

            logger.LogDebug("Adding remote candidates from B to A.");

            rtpIceChannelB.Candidates.ForEach(x => rtpIceChannelA.AddRemoteCandidate(x));

            // This pause is so that channel A can process the new remote candidates supplied by B.
            // These candidates are host candidates and should replace the peer reflexive candidates
            // that were automatically created previously.
            await Task.Delay(1000);

            logger.LogDebug("Setting remote credentials for channel A.");

            rtpIceChannelA.SetRemoteCredentials(rtpIceChannelB.LocalIceUser, rtpIceChannelB.LocalIcePassword);

            Assert.True(connected.Wait(3000));

            Assert.Equal(RTCIceConnectionState.connected, rtpIceChannelA.IceConnectionState);
            Assert.Equal(RTCIceConnectionState.connected, rtpIceChannelB.IceConnectionState);
            Assert.NotNull(rtpIceChannelA.NominatedEntry);
            Assert.NotNull(rtpIceChannelB.NominatedEntry);
            Assert.Equal(RTCIceCandidateType.host, rtpIceChannelA.NominatedEntry.LocalCandidate.type);
            Assert.Equal(RTCIceCandidateType.host, rtpIceChannelB.NominatedEntry.LocalCandidate.type);
        }