⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stunclient.cs

📁 破解的飞信源代码
💻 CS
字号:
namespace Imps.Client.Core.P2P.ICE
{
    using Imps.Client.Core.P2P.ICE.Message;
    using Imps.Client.Utils;
    using NCindy;
    using NCindy.Session.AIO;
    using NCindy.Util;
    using NCindy.Util.Logging;
    using System;
    using System.Diagnostics;
    using System.Net;
    using System.Net.Sockets;
    using System.Runtime.CompilerServices;
    using System.Threading;

    public class StunClient
    {
        private EndQuery _endQuery;
        private static StunResult _result;
        private IPEndPoint changedEndPoint;
        private static readonly AutoResetEvent endQueryEvent = new AutoResetEvent(false);
        private static readonly ILogger log = LogFactory.CreateLogger(MethodBase.GetCurrentMethod().ReflectedType);
        private AsyncUdpSession querySession;
        private Step queryStep;
        private IPEndPoint remoteEndPoint;

        protected StunClient()
        {
        }

        protected void BeginQuery(string host, int port, EndQuery endQuery)
        {
            this._endQuery = endQuery;
            this.querySession = new AsyncUdpSession(new IPEndPoint(Dns.GetHostAddresses(host)[0], port));
            this.querySession.PacketDecoder = new StunDecoder();
            this.querySession.PacketEncoder = new StunEncoder();
            this.querySession.ObjectReceived += new EventHandler<SessionEventArgs>(this, (IntPtr) this.OnQueryResultReceived);
            this.querySession.StateChanged += new EventHandler<SessionEventArgs>(this, (IntPtr) this.OnQuerySessionOpened);
            this.querySession.Open();
        }

        private void DoEndQuery(StunResult result)
        {
            try
            {
                if (this._endQuery != null)
                {
                    this._endQuery(result);
                }
            }
            catch (Exception exception)
            {
                log.Error("DoEndQuery failed.", exception);
            }
            finally
            {
                endQueryEvent.Set();
            }
        }

        private static StunMessage DoTransaction(StunMessage request, Socket socket, IPEndPoint remoteEndPoint)
        {
            byte[] buffer = request.ToByteData();
            Stopwatch stopwatch = Stopwatch.StartNew();
            while (stopwatch.get_ElapsedMilliseconds() < 0x7d0)
            {
                try
                {
                    socket.SendTo(buffer, remoteEndPoint);
                    if (!socket.Poll(0x186a0, SelectMode.SelectRead))
                    {
                        continue;
                    }
                    byte[] buffer2 = new byte[0x200];
                    socket.Receive(buffer2);
                    StunMessage message = new StunMessage();
                    message.Parse(buffer2);
                    if (!request.TransactionID.Equals(message.TransactionID))
                    {
                        continue;
                    }
                    return message;
                }
                catch (Exception exception)
                {
                    Console.WriteLine(exception);
                    continue;
                }
            }
            stopwatch.Stop();
            return null;
        }

        public static IPEndPoint GetPublicEndpoint(Socket socket, string host, int port)
        {
            LangHelper.CheckNullArgument("host", host);
            LangHelper.CheckNullArgument("socket", socket);
            try
            {
                if (port < 1)
                {
                    throw new ArgumentException("Port value must be >= 1 !");
                }
                IPEndPoint remoteEndPoint = new IPEndPoint(Dns.GetHostAddresses(host)[0], port);
                socket.set_ReceiveTimeout(0xbb8);
                socket.set_SendTimeout(0xbb8);
                StunMessage request = new StunMessage();
                request.Type = StunMessageType.BindingRequest;
                StunMessage message2 = DoTransaction(request, socket, remoteEndPoint);
                if (message2 == null)
                {
                    return null;
                }
                return message2.MappedAddress;
            }
            catch (Exception exception)
            {
                ClientLogger.WriteException("检测公共端点失败", exception);
            }
            return null;
        }

        private void GetSharedSecret()
        {
        }

        private void OnQueryResultReceived(object sender, SessionEventArgs e)
        {
            StunMessage testResponse = e.Obj as StunMessage;
            IPEndPoint localEndPoint = ((AsyncUdpSession) e.Session).LocalEndPoint;
            switch (this.queryStep)
            {
                case Step.PublicIPTest:
                    this.ProcessPublicIPTestResult(testResponse, localEndPoint);
                    return;

                case Step.OpenInternetTest:
                    this.ProcessOpenInternetTestResult(testResponse, localEndPoint);
                    return;

                case Step.FullConeTest:
                    this.ProcessFullConeTestResult(testResponse, localEndPoint);
                    return;

                case Step.SymmetricTest:
                    this.ProcessSymmetricTestResult(testResponse, localEndPoint);
                    return;

                case Step.RestrictedTest:
                    this.ProcessRestrictedTestResult(testResponse, localEndPoint);
                    break;

                case Step.End:
                    break;

                default:
                    return;
            }
        }

        private void OnQuerySessionOpened(object sender, SessionEventArgs e)
        {
            if (e.Session.State == SessionState.Opened)
            {
                this.queryStep = Step.PublicIPTest;
                StunMessage message = new StunMessage();
                message.Type = StunMessageType.BindingRequest;
                this.querySession.Send(message);
            }
        }

        private void ProcessFullConeTestResult(StunMessage testResponse, IPEndPoint localEndPoint)
        {
            if (testResponse != null)
            {
                this.queryStep = Step.End;
                this.DoEndQuery(new StunResult(StunNetType.FullCone, this.remoteEndPoint, localEndPoint));
            }
            else
            {
                this.queryStep = Step.SymmetricTest;
                StunMessage message = new StunMessage();
                message.Type = StunMessageType.BindingRequest;
                this.querySession.RemoteEndPoint = this.changedEndPoint;
                this.querySession.Send(message);
            }
        }

        private void ProcessOpenInternetTestResult(StunMessage testResponse, IPEndPoint localEndPoint)
        {
            if (testResponse != null)
            {
                this.DoEndQuery(new StunResult(StunNetType.OpenInternet, testResponse.MappedAddress, localEndPoint));
                this.queryStep = Step.End;
            }
            else
            {
                this.DoEndQuery(new StunResult(StunNetType.SymmetricUdpFirewall, this.remoteEndPoint, localEndPoint));
                this.queryStep = Step.End;
            }
        }

        private void ProcessPublicIPTestResult(StunMessage testResponse, IPEndPoint localEndPoint)
        {
            if (testResponse == null)
            {
                this.DoEndQuery(new StunResult(StunNetType.UdpBlocked, null, localEndPoint));
                this.queryStep = Step.End;
            }
            else
            {
                StunMessage message = new StunMessage();
                message.Type = StunMessageType.BindingRequest;
                message.ChangeRequest = new StunChangeRequestParams(true, true);
                this.remoteEndPoint = testResponse.MappedAddress;
                this.changedEndPoint = testResponse.ChangedAddress;
                if (!localEndPoint.Equals(this.remoteEndPoint))
                {
                    this.queryStep = Step.FullConeTest;
                }
                else
                {
                    this.queryStep = Step.OpenInternetTest;
                }
                this.querySession.Send(message);
            }
        }

        private void ProcessRestrictedTestResult(StunMessage testResponse, IPEndPoint localEndPoint)
        {
            this.queryStep = Step.End;
            if (testResponse != null)
            {
                this.DoEndQuery(new StunResult(StunNetType.RestrictedCone, this.remoteEndPoint, localEndPoint));
            }
            else
            {
                this.DoEndQuery(new StunResult(StunNetType.PortRestrictedCone, this.remoteEndPoint, localEndPoint));
            }
        }

        private void ProcessSymmetricTestResult(StunMessage testResponse, IPEndPoint localEndPoint)
        {
            if (testResponse == null)
            {
                this.queryStep = Step.End;
                throw new Exception("Symmetric NAT test did not get resonse !");
            }
            if (!testResponse.MappedAddress.Equals(this.remoteEndPoint))
            {
                this.queryStep = Step.End;
                this.DoEndQuery(new StunResult(StunNetType.Symmetric, this.remoteEndPoint, localEndPoint));
            }
            else
            {
                this.queryStep = Step.RestrictedTest;
                StunMessage message = new StunMessage();
                message.Type = StunMessageType.BindingRequest;
                message.ChangeRequest = new StunChangeRequestParams(false, true);
                this.querySession.RemoteEndPoint = this.changedEndPoint;
                this.querySession.Send(message);
            }
        }

        public static StunResult Query(string host, int port)
        {
            try
            {
                new StunClient().BeginQuery(host, port, delegate (StunResult result) {
                    _result = result;
                });
            }
            catch (Exception exception)
            {
                log.Error("Query failed.", exception);
            }
            endQueryEvent.WaitOne();
            return _result;
        }

        protected delegate void EndQuery(StunResult result);

        private enum Step
        {
            PublicIPTest,
            OpenInternetTest,
            FullConeTest,
            SymmetricTest,
            RestrictedTest,
            End
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -