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 }); }
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(); } }