示例#1
0
        private void StunRequest(EndPoint stunEndPoint, StunPacket packet, Action <StunPacket> callback)
        {
            bool hasresponded = false;

            Action <EndPoint, byte[]> action = null;

            //---------------------------------------
            // the stun response handler.
            //---------------------------------------

            action = new Action <EndPoint, byte[]>((endpoint, data) => {
                //---------------------------------------------
                // here, we try and catch any parse errors, which
                // may originate from other things attempting to
                // send data to this socket.
                //---------------------------------------------

                try {
                    StunPacket response = new StunPacket();

                    response.Parse(data);

                    this.OnMessage -= action;

                    hasresponded = true;

                    callback(response);
                }
                catch {
                }
            });

            //---------------------------------------
            // setup timeout in case of no response.
            //---------------------------------------

            Reactor.Timeout.Create(() => {
                if (!hasresponded)
                {
                    this.OnMessage -= action;

                    callback(null);
                }
            }, 2000);

            //---------------------------------------
            // set on response, make request.
            //---------------------------------------

            this.OnMessage += action;

            this.Send(stunEndPoint, packet.ToByteData());
        }
示例#2
0
        private void StunRequest(EndPoint stunEndPoint, StunPacket packet, Action<StunPacket> callback)
        {
            bool hasresponded = false;

            Action<EndPoint, byte[]> action = null;

            //---------------------------------------
            // the stun response handler.
            //---------------------------------------

            action = new Action<EndPoint, byte[]>((endpoint, data) => {

                //---------------------------------------------
                // here, we try and catch any parse errors, which
                // may originate from other things attempting to
                // send data to this socket.
                //---------------------------------------------

                try {

                    StunPacket response = new StunPacket();

                    response.Parse(data);

                    this.OnMessage -= action;

                    hasresponded    = true;

                    callback(response);
                }
                catch {

                }
            });

            //---------------------------------------
            // setup timeout in case of no response.
            //---------------------------------------

            Reactor.Timeout.Create(() => {

                if (!hasresponded) {

                    this.OnMessage -= action;

                    callback(null);
                }

            }, 2000);

            //---------------------------------------
            // set on response, make request.
            //---------------------------------------

            this.OnMessage += action;

            this.Send(stunEndPoint, packet.ToByteData());
        }
示例#3
0
        /// <summary>
        /// Pings a stun server and obtains a limited time public ip and port for this UDP socket.
        /// </summary>
        /// <param name="Host">The IP address of the Stun Server.</param>
        /// <param name="Port">The port of the Stun Server.</param>
        /// <param name="callback">A callback with the Stun response.</param>
        public void Stun(string Host, int Port, Action <Exception, StunResponse> callback)
        {
            //----------------------------------------------------------------
            // save any events on this socket.
            //----------------------------------------------------------------

            var actions = new List <Action <EndPoint, byte[]> >();

            if (this.OnMessage != null)
            {
                foreach (var _action in this.OnMessage.GetInvocationList())
                {
                    var action = (Action <EndPoint, byte[]>)_action;

                    actions.Add(action);

                    this.OnMessage -= action;
                }
            }

            //----------------------------------------------------------------
            // resolve stun endpoint.
            //----------------------------------------------------------------

            Reactor.Net.Dns.GetHostAddresses(Host, (exception0, addresses) => {
                if (exception0 != null)
                {
                    callback(exception0, null);

                    return;
                }


                var remoteEP = new IPEndPoint(addresses[0], Port);

                StunPacket test1 = new StunPacket();

                test1.Type = PacketType.BindingRequest;

                this.StunRequest(remoteEP, test1, (test1response) =>
                {
                    if (test1response == null)
                    {
                        foreach (var action in actions)
                        {
                            this.OnMessage += action;
                        }

                        callback(null, new StunResponse(NatType.UdpBlocked, null));
                    }
                    else
                    {
                        if (this.LocalEndPoint.Equals(test1response.MappedAddress))
                        {
                            StunPacket test2 = new StunPacket();

                            test2.Type = PacketType.BindingRequest;

                            test2.ChangeRequest = new ChangeRequest(true, true);

                            this.StunRequest(remoteEP, test2, (test2response) =>
                            {
                                if (test2response == null)
                                {
                                    foreach (var action in actions)
                                    {
                                        this.OnMessage += action;
                                    }

                                    callback(null, new StunResponse(NatType.SymmetricUdpFirewall, test1response.MappedAddress));
                                }
                                else
                                {
                                    foreach (var action in actions)
                                    {
                                        this.OnMessage += action;
                                    }

                                    callback(null, new StunResponse(NatType.OpenInternet, test1response.MappedAddress));
                                }
                            });
                        }
                        else
                        {
                            StunPacket test2 = new StunPacket();

                            test2.Type = PacketType.BindingRequest;

                            test2.ChangeRequest = new ChangeRequest(true, true);

                            this.StunRequest(remoteEP, test2, (test2response) =>
                            {
                                if (test2response != null)
                                {
                                    foreach (var action in actions)
                                    {
                                        this.OnMessage += action;
                                    }

                                    callback(null, new StunResponse(NatType.FullCone, test1response.MappedAddress));
                                }
                                else
                                {
                                    // Test I(II)
                                    StunPacket test12 = new StunPacket();

                                    test12.Type = PacketType.BindingRequest;

                                    this.StunRequest(remoteEP, test12, (test12response) =>
                                    {
                                        if (test12response == null)
                                        {
                                            foreach (var action in actions)
                                            {
                                                this.OnMessage += action;
                                            }

                                            callback(null, new StunResponse(NatType.UdpBlocked, null));
                                        }
                                        else
                                        {
                                            StunPacket test3 = new StunPacket();

                                            test3.Type = PacketType.BindingRequest;

                                            test3.ChangeRequest = new ChangeRequest(false, true);

                                            this.StunRequest(remoteEP, test3, (test3response) =>
                                            {
                                                if (test3response == null)
                                                {
                                                    foreach (var action in actions)
                                                    {
                                                        this.OnMessage += action;
                                                    }

                                                    callback(null, new StunResponse(NatType.PortRestrictedCone, test1response.MappedAddress));
                                                }
                                                else
                                                {
                                                    foreach (var action in actions)
                                                    {
                                                        this.OnMessage += action;
                                                    }

                                                    callback(null, new StunResponse(NatType.RestrictedCone, test1response.MappedAddress));
                                                }
                                            });
                                        }
                                    });
                                }
                            });
                        }
                    }
                });
            });
        }
示例#4
0
        /// <summary>
        /// Pings a stun server and obtains a limited time public ip and port for this UDP socket.
        /// </summary>
        /// <param name="Host">The IP address of the Stun Server.</param>
        /// <param name="Port">The port of the Stun Server.</param>
        /// <param name="callback">A callback with the Stun response.</param>
        public void Stun(string Host, int Port, Action<Exception, StunResponse> callback)
        {
            //----------------------------------------------------------------
            // save any events on this socket.
            //----------------------------------------------------------------

            var actions = new List<Action<EndPoint, byte[]>>();

            if(this.OnMessage != null) {

                foreach(var _action in this.OnMessage.GetInvocationList()) {

                    var action = (Action<EndPoint, byte[]>)_action;

                    actions.Add(action);

                    this.OnMessage -= action;
                }
            }

            //----------------------------------------------------------------
            // resolve stun endpoint.
            //----------------------------------------------------------------

            Reactor.Net.Dns.GetHostAddresses(Host, (exception0, addresses) => {

                if (exception0 != null)
                {
                    callback(exception0, null);

                    return;
                }

                var remoteEP     = new IPEndPoint(addresses[0], Port);

                StunPacket test1 = new StunPacket();

                test1.Type       = PacketType.BindingRequest;

                this.StunRequest(remoteEP, test1, (test1response) =>
                {
                    if (test1response == null)
                    {
                        foreach(var action in actions) {

                            this.OnMessage += action;
                        }

                        callback(null, new StunResponse(NatType.UdpBlocked, null));
                    }
                    else
                    {
                        if (this.LocalEndPoint.Equals(test1response.MappedAddress))
                        {
                            StunPacket test2    = new StunPacket();

                            test2.Type          = PacketType.BindingRequest;

                            test2.ChangeRequest = new ChangeRequest(true, true);

                            this.StunRequest(remoteEP, test2, (test2response) =>
                            {
                                if (test2response == null)
                                {
                                    foreach(var action in actions) {

                                        this.OnMessage += action;
                                    }

                                    callback(null, new StunResponse(NatType.SymmetricUdpFirewall, test1response.MappedAddress));

                                }
                                else
                                {
                                    foreach(var action in actions) {

                                        this.OnMessage += action;
                                    }

                                    callback(null, new StunResponse(NatType.OpenInternet, test1response.MappedAddress));
                                }
                            });
                        }
                        else
                        {
                            StunPacket test2 = new StunPacket();

                            test2.Type = PacketType.BindingRequest;

                            test2.ChangeRequest = new ChangeRequest(true, true);

                            this.StunRequest(remoteEP, test2, (test2response) =>
                            {
                                if (test2response != null)
                                {
                                    foreach(var action in actions) {

                                        this.OnMessage += action;
                                    }

                                    callback(null, new StunResponse(NatType.FullCone, test1response.MappedAddress));
                                }
                                else
                                {
                                    // Test I(II)
                                    StunPacket test12 = new StunPacket();

                                    test12.Type = PacketType.BindingRequest;

                                    this.StunRequest(remoteEP, test12, (test12response) =>
                                    {
                                        if (test12response == null)
                                        {
                                            foreach(var action in actions) {

                                                this.OnMessage += action;
                                            }

                                            callback(null, new StunResponse(NatType.UdpBlocked, null));
                                        }
                                        else
                                        {
                                            StunPacket test3 = new StunPacket();

                                            test3.Type = PacketType.BindingRequest;

                                            test3.ChangeRequest = new ChangeRequest(false, true);

                                            this.StunRequest(remoteEP, test3, (test3response) =>
                                            {
                                                if (test3response == null)
                                                {
                                                    foreach(var action in actions) {

                                                        this.OnMessage += action;
                                                    }

                                                    callback(null, new StunResponse(NatType.PortRestrictedCone, test1response.MappedAddress));
                                                }
                                                else
                                                {
                                                    foreach(var action in actions) {

                                                        this.OnMessage += action;
                                                    }

                                                    callback(null, new StunResponse(NatType.RestrictedCone, test1response.MappedAddress));
                                                }
                                            });
                                        }
                                    });
                                }
                            });
                        }
                    }
                });
            });
        }