Пример #1
0
        private async Task <StunResult5389> BindingTestBaseAsync(IPEndPoint remote, bool notifyChanged, CancellationToken token)
        {
            BindingTestResult res;
            var test = new StunMessage5389 {
                StunMessageType = StunMessageType.BindingRequest
            };

            var(response1, _, local1) = await TestAsync(test, remote, remote, token);

            var mappedAddress1 = AttributeExtensions.GetXorMappedAddressAttribute(response1);
            var otherAddress   = AttributeExtensions.GetOtherAddressAttribute(response1);
            var local          = local1 == null ? null : new IPEndPoint(local1, LocalEndPoint.Port);

            if (response1 == null)
            {
                res = BindingTestResult.Fail;
            }
            else if (mappedAddress1 == null)
            {
                res = BindingTestResult.UnsupportedServer;
            }
            else
            {
                res = BindingTestResult.Success;
            }

            if (notifyChanged)
            {
                _bindingSubj.OnNext(res);
                PubSubj.OnNext(mappedAddress1);
            }
            LocalSubj.OnNext(LocalEndPoint);

            return(new StunResult5389
            {
                BindingTestResult = res,
                LocalEndPoint = local,
                PublicEndPoint = mappedAddress1,
                OtherEndPoint = otherAddress
            });
        }
Пример #2
0
        public async Task <StunResult5389> QueryAsync()
        {
            var result = new StunResult5389();

            try
            {
                _bindingSubj.OnNext(result.BindingTestResult);
                _mappingBehaviorSubj.OnNext(result.MappingBehavior);
                _filteringBehaviorSubj.OnNext(result.FilteringBehavior);
                PubSubj.OnNext(result.PublicEndPoint);

                using var cts = new CancellationTokenSource(Timeout);

                await Proxy.ConnectAsync(cts.Token);

                result = await FilteringBehaviorTestBaseAsync(cts.Token);

                if (result.BindingTestResult != BindingTestResult.Success ||
                    result.FilteringBehavior == FilteringBehavior.UnsupportedServer
                    )
                {
                    return(result);
                }

                if (Equals(result.PublicEndPoint, result.LocalEndPoint))
                {
                    result.MappingBehavior = MappingBehavior.Direct;
                    return(result);
                }

                // MappingBehaviorTest test II
                var result2 = await BindingTestBaseAsync(new IPEndPoint(result.OtherEndPoint.Address, RemoteEndPoint.Port), false, cts.Token);

                if (result2.BindingTestResult != BindingTestResult.Success)
                {
                    result.MappingBehavior = MappingBehavior.Fail;
                    return(result);
                }

                if (Equals(result2.PublicEndPoint, result.PublicEndPoint))
                {
                    result.MappingBehavior = MappingBehavior.EndpointIndependent;
                    return(result);
                }

                // MappingBehaviorTest test III
                var result3 = await BindingTestBaseAsync(result.OtherEndPoint, false, cts.Token);

                if (result3.BindingTestResult != BindingTestResult.Success)
                {
                    result.MappingBehavior = MappingBehavior.Fail;
                    return(result);
                }

                result.MappingBehavior = Equals(result3.PublicEndPoint, result2.PublicEndPoint) ? MappingBehavior.AddressDependent : MappingBehavior.AddressAndPortDependent;

                return(result);
            }
            finally
            {
                _mappingBehaviorSubj.OnNext(result.MappingBehavior);
                await Proxy.DisconnectAsync();
            }
        }