async Task <StunResult> RunImpl() { if (m_Future != null) { throw new Exception("already run"); } if (m_RemoteEP == null) { m_RemoteEP = await GetEndPoint(); } var test1 = await DoTransaction(m_RemoteEP); if (test1 == null) { return(Result = new StunResult(NatType.Unspecified, null, await GetLocalEndPoint())); } var test2 = await DoTransaction(true, true, m_RemoteEP); if (m_Socket.LocalEndPoint.Equals(test1.MappedAddress)) { if (test2 != null) { return(new StunResult(NatType.OpenInternet, test1.MappedAddress.EndPoint, await GetLocalEndPoint())); } else { return(new StunResult(NatType.SymmetricUDPFirewall, test1.MappedAddress.EndPoint, await GetLocalEndPoint())); } } else if (test2 != null) { return(new StunResult(NatType.FullCone, test1.MappedAddress.EndPoint, await GetLocalEndPoint())); } var test12 = await DoTransaction(test1.ChangedAddress.EndPoint); if (test12 == null) { throw new Exception("STUN Test I(II) fail."); } else if (!test12.MappedAddress.Equals(test1.MappedAddress)) { return(new StunResult(NatType.Symmetric, test1.MappedAddress.EndPoint, await GetLocalEndPoint())); } var test3 = await DoTransaction(false, true, test1.ChangedAddress.EndPoint); if (test3 != null) { return(new StunResult(NatType.Restricted, test1.MappedAddress.EndPoint, await GetLocalEndPoint())); } else { return(new StunResult(NatType.PortRestricted, test1.MappedAddress.EndPoint, await GetLocalEndPoint())); } }
public async Task <StunResult> Run(CancellationToken token) { m_Token = token; if (m_RunTask != null) { await m_RunTask; } m_RunTask = RunImpl(); Result = await m_RunTask; m_RunTask = null; return(Result); }