Пример #1
0
        public static STUN_Result Detect(int portNumber)
        {
            fLogger.WriteInfo("STUN detecting started");

            using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
                socket.Bind(new IPEndPoint(IPAddress.Any, portNumber));

                fLogger.WriteInfo("Local Endpoint: " + socket.LocalEndPoint);

                STUN_Result result = STUN_Client.Query("stun1.l.google.com", 19302, socket);
                if (result.NetType == STUN_NetType.UdpBlocked)
                {
                    foreach (var item in STUNProviders)
                    {
                        var res = STUN_Client.Query(item.Address, item.Port, socket);
                        if (res.NetType != STUN_NetType.UdpBlocked)
                        {
                            result = res;
                            break;
                        }
                    }
                }

                fLogger.WriteInfo("NAT Type: " + result.NetType);
                if (result.NetType != STUN_NetType.UdpBlocked)
                {
                    fLogger.WriteInfo("Public Endpoint: " + result.PublicEndPoint);
                }

                fLogger.WriteInfo("STUN detecting finished");

                return(result);
            }
        }
Пример #2
0
        private void DetectSTUN(string stunServer, Socket socket)
        {
            if (string.IsNullOrEmpty(stunServer))
            {
                throw new Exception("Not specified STUN server");
            }

            STUN_Result result = null;

            try {
                result = STUN_Client.Query(stunServer, 3478, socket);

                fLogger.WriteInfo("STUN Info:");
                fLogger.WriteInfo("NetType: {0}", result.NetType.ToString());
                fLogger.WriteInfo("LocalEndPoint: {0}", socket.LocalEndPoint.ToString());
                if (result.NetType != STUN_NetType.UdpBlocked)
                {
                    fPublicEndPoint = new IPEndPoint(result.PublicEndPoint.Address, ProtocolHelper.PublicTCPPort);
                    fLogger.WriteInfo("PublicEndPoint: {0}", result.PublicEndPoint.ToString());
                }
                else
                {
                    fPublicEndPoint = null;
                    fLogger.WriteInfo("PublicEndPoint: -");
                }
            } catch (Exception ex) {
                fLogger.WriteError("DetectSTUN() error", ex);
            }

            fSTUNInfo = result;
        }
Пример #3
0
        private void DetectSTUN(string stunServer, Socket socket)
        {
            if (string.IsNullOrEmpty(stunServer))
            {
                throw new ArgumentException("Not specified STUN server");
            }

            STUN_Result result = null;

            try {
                result = STUN_Client.Query(stunServer, 3478, socket);

                fLogger.WriteInfo("STUN Info:");
                fLogger.WriteInfo("NetType: {0}", result.NetType);
                fLogger.WriteInfo("LocalEndPoint: {0}", socket.LocalEndPoint);
                if (result.NetType != STUN_NetType.UdpBlocked)
                {
                    fPublicEndPoint = result.PublicEndPoint;
                }
                else
                {
                    fPublicEndPoint = null;
                }
                fLogger.WriteInfo("PublicEndPoint: {0}", fPublicEndPoint);
            } catch (Exception ex) {
                fLogger.WriteError("DetectSTUN() error", ex);
            }

            fSTUNInfo = result;
            fDHTClient.PublicEndPoint = fPublicEndPoint;
        }
Пример #4
0
        static void ReceiveSTUN()
        {
            var         strHostName    = Dns.GetHostName();
            IPHostEntry ipEntry        = Dns.GetHostEntry(strHostName);
            var         localIPAddress = ipEntry.AddressList.First();

            Console.WriteLine($"Local IP: {localIPAddress}");

            var localEndPoint = new IPEndPoint(localIPAddress, 4711);

            // Create new socket for STUN client.
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            socket.Bind(localEndPoint);

            Console.WriteLine("Querying STUN server...");
            STUN_Result result = STUN_Client.Query("stun.sipgate.net", 3478, socket);

            if (result.NetType == STUN_NetType.UdpBlocked)
            {
                Console.WriteLine("Error: UDP blocked or bad STUN server");
            }
            else
            {
                Console.WriteLine($"Success: Public Endpoint is {result.PublicEndPoint.ToString()} Type: {result.NetType}");

                Listen(new IPEndPoint(localIPAddress, result.PublicEndPoint.Port));
            }
        }
Пример #5
0
        public static (string, string, string) NatTypeTestCore(string local, string server, int port)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(server))
                {
                    MessageBox.Show(@"Please specify STUN server !", @"Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return(string.Empty, DefaultLocalEnd, string.Empty);
                }

                using (var socketV4 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
                {
                    var ipe = ParseEndpoint(local) ?? new IPEndPoint(IPAddress.Any, 0);
                    socketV4.Bind(ipe);
                    var result = STUN_Client.Query(server, port, socketV4);

                    return(
                        result.NetType.ToString(),
                        socketV4.LocalEndPoint.ToString(),
                        result.NetType != STUN_NetType.UdpBlocked ? result.PublicEndPoint.ToString() : string.Empty
                        );
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($@"Error: {ex}", @"Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return(string.Empty, DefaultLocalEnd, string.Empty);
            }
        }
Пример #6
0
        private static STUN_Result StunUDP(UdpClient socket)
        {
            socket.AllowNatTraversal(true);
            var servers = new[] { "stun.l.google.com:19302", "stun.services.mozilla.com", "stunserver.org" };

            foreach (var server in servers)
            {
                var host = server.Split(':').FirstOrDefault();
                try
                {
                    int port;
                    if (!int.TryParse(server.Split(':').LastOrDefault(), out port) || (port == 0))
                    {
                        port = 3478;
                    }

                    return(STUN_Client.Query(host, port, socket.Client));
                }
                catch (Exception ex)
                {
                    Trace.TraceWarning("STUN request to {0} failed : {1}", host, ex);
                }
            }
            return(null);
        }
Пример #7
0
 public static string GetPublicIpAdress(IPAddress ip, int port)
 {
     socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
     //сюда вставить локальный ip адрес
     socket.Bind(new IPEndPoint(ip, port));
     STUN = STUN_Client.Query(stunServer, stunPort, socket);
     return(string.Format("{0}:{1}", STUN.PublicEndPoint.Address.ToString(), STUN.PublicEndPoint.Port));
 }
Пример #8
0
        public void Publish()
        {
            RemoteSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            RemoteSocket.Bind(new IPEndPoint(IPAddress.Any, 0));

            var result = STUN_Client.Query(StunServer, StunPort, RemoteSocket);

            PublicEndPoint = result.PublicEndPoint;
        }
Пример #9
0
        public static IPEndPoint GetStunnedIpEndPoint(int port, string stunIp, int stunPort)
        {
            var result = STUN_Client.Query(stunIp, stunPort, new IPEndPoint(IPAddress.Any, port));

            if (result.NetType == STUN_NetType.RestrictedCone || result.NetType == STUN_NetType.PortRestrictedCone || result.NetType == STUN_NetType.UdpBlocked)
            {
                return(null);
            }
            return(result.PublicEndPoint);
        }
Пример #10
0
        private static STUN_Result StartStun(string stunaddress, int stunport, UdpClient udp = null)
        {
            if (udp == null)
            {
                udp = new UdpClient(new IPEndPoint(IPAddress.Any, 8787));
            }

            // GoogleのSTUNサーバーに問い合わせる
            Console.WriteLine("Connecting... " + stunaddress + ":" + stunport);

            STUN_Result result = STUN_Client.Query(stunaddress, stunport, udp);

            Console.WriteLine("[STUN] EndPoint:" + result.PublicEndPoint.ToString());
            Console.WriteLine("[STUN] NetType:" + result.NetType.ToString());

            if (result.NetType == STUN_NetType.UdpBlocked)
            {
                // UDPがブロックされる
                Console.WriteLine("[STUN] UDP is always blocked.");
            }
            else if (result.NetType == STUN_NetType.SymmetricUdpFirewall)
            {
                Console.WriteLine("[STUN] SymmetricUdpFirewall");
            }
            else if (result.NetType == STUN_NetType.Symmetric)
            {
                Console.WriteLine("[STUN] Symmetric NAT");
            }
            else if (result.NetType == STUN_NetType.PortRestrictedCone)
            {
                // 相手がシンメトリックだった場合に通信できないので、ホスト対応から外す
                Console.WriteLine("[STUN] PortRestrictedCone");
            }
            else if (result.NetType == STUN_NetType.RestrictedCone)
            {
                // Clientのエフェメラルポートがわかれば対応できるが、netcodeの実装上使うポートが不明なので一旦非対応
                Console.WriteLine("[STUN] RestrictedCone");
            }
            else
            {
                Console.WriteLine("[STUN] Host Ready");
            }

            // 上記以外のNATはUDPホールパンチング対応

            return(result);
        }
Пример #11
0
 private void button1_Click(object sender, EventArgs e)
 {
     this.Cursor             = Cursors.WaitCursor;
     connectToServer.Visible = false;
     startServer.Visible     = false;
     chatInput.Visible       = false;
     chatOutput.Visible      = false;
     try
     {
         Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
         socket.Bind(new IPEndPoint(IPAddress.Any, portNumber));
         STUN_Result result = STUN_Client.Query("stun1.l.google.com", 19302, socket);
         if (result.NetType == STUN_NetType.UdpBlocked)
         {
             PrintOutput("Did not manage to contact STUN server, trying alternatives");
             foreach (var item in STUN_PROVIDERS)
             {
                 var res = STUN_Client.Query(item.Item1, item.Item2, socket);
                 if (res.NetType != STUN_NetType.UdpBlocked)
                 {
                     result = res;
                     break;
                 }
             }
         }
         PrintOutput("NAT Type: " + result.NetType.ToString());
         PrintOutput("Local Endpoint: " + socket.LocalEndPoint.ToString());
         if (result.NetType != STUN_NetType.UdpBlocked)
         {
             PrintOutput("Public Endpoint: " + result.PublicEndPoint.ToString());
             var id = Base64Encode(result.PublicEndPoint.ToString());
             //Clipboard.SetText(id);
             idText.Text = id;
         }
         PrintOutput("=================");
         socket.Close();
     }
     catch (Exception x)
     {
         MessageBox.Show(this, "Error: " + x.ToString(), "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
     finally
     {
         this.Cursor = Cursors.Default;
     }
 }
Пример #12
0
        IPEndPoint getEndpoint()
        {
            // Query STUN server
            STUN_Result result = STUN_Client.Query("stun.l.google.com", 19302, udpClient.Client);

            if (result.NetType == STUN_NetType.UdpBlocked)
            {
                // UDP blocked or !!!! bad STUN server
                return(null);
            }
            else
            {
                IPEndPoint publicEP = result.PublicEndPoint;
                // Do your stuff
                return(publicEP);
            }
        }
Пример #13
0
        private void SysInfoWin_Load(object sender, EventArgs e)
        {
            var peerInfo = new PeerProfile();

            peerInfo.ResetSystem();

            textBox1.Text += "UserName: "******"\r\n";
            textBox1.Text += "UserCountry: " + peerInfo.Country + "\r\n";
            textBox1.Text += "TimeZone: " + peerInfo.TimeZone + "\r\n";
            textBox1.Text += "Languages: " + peerInfo.Languages + "\r\n\r\n\r\n";

            string server = "stun.ekiga.net";

            this.Cursor = Cursors.WaitCursor;
            try {
                if (string.IsNullOrEmpty(server))
                {
                    MessageBox.Show(this, "Please specify STUN server!", "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                socket.Bind(new IPEndPoint(IPAddress.Any, 0));

                STUN_Result result = STUN_Client.Query(server, 3478, socket);
                textBox1.Text += "NET type: " + result.NetType.ToString() + "\r\n";
                textBox1.Text += "Local end point: " + socket.LocalEndPoint.ToString() + "\r\n";
                if (result.NetType != STUN_NetType.UdpBlocked)
                {
                    textBox1.Text += "Public end point: " + result.PublicEndPoint.ToString() + "\r\n";
                }
                else
                {
                    textBox1.Text += "Public end point: -\r\n";
                }
            } catch (Exception x) {
                MessageBox.Show(this, "Error: " + x.ToString(), "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error);
            } finally {
                this.Cursor = Cursors.Default;
            }
        }
Пример #14
0
        private static string[] Core(string local, string server, int port)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(server))
                {
                    MessageBox.Show(@"Please specify STUN server !", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(null);
                }

                using (var socketv4 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
                {
                    if (local != string.Empty)
                    {
                        var ip_port = local.Split(':');
                        socketv4.Bind(new IPEndPoint(IPAddress.Parse(ip_port[0]), Convert.ToInt32(ip_port[1])));
                    }
                    else
                    {
                        socketv4.Bind(new IPEndPoint(IPAddress.Any, 0));
                    }

                    var result = STUN_Client.Query(server, port, socketv4);

                    return(new[]
                    {
                        result.NetType.ToString(),
                        socketv4.LocalEndPoint.ToString(),
                        result.NetType != STUN_NetType.UdpBlocked ? result.PublicEndPoint.ToString() : string.Empty
                    });
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($@"Error: {ex}", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(null);
            }
            finally
            {
            }
        }
Пример #15
0
        static void Main(string[] args)
        {
            Socket socket = new Socket
                                (AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            socket.Bind(new IPEndPoint(IPAddress.Any, 0));

            // Query STUN server
            STUN_Result result = STUN_Client.Query("stun.sipgate.net", 3478, socket);

            if (result.NetType != STUN_NetType.UdpBlocked)
            {
                // UDP blocked or !!!! bad STUN server
            }
            else
            {
                IPEndPoint publicEP = result.PublicEndPoint;
                // Do your stuff
            }
            Console.ReadLine();
        }
Пример #16
0
 private static Task <IPAddress> CreateGetPublicIpTask(string stunAddress, int port, IPAddress localIPaddress)
 {
     return(Task.WhenAny(Task.Run(() =>
     {
         try
         {
             var stopWatch = Stopwatch.StartNew();
             var ip = STUN_Client.GetPublicIP(stunAddress, port, localIPaddress);
             Logger.Debug($"Get public ip from stun server [{stunAddress}] with time: [{stopWatch.ElapsedMilliseconds}]");
             return ip;
         }
         catch
         {
             return null;
         }
     }), Task.Run(async() =>
     {
         await Task.Delay(TimeSpan.FromMilliseconds(StunTimeOutInMs));
         return (IPAddress)null;
     })).Unwrap());
 }
Пример #17
0
 public void STUN()
 {
     if (UniP2PManager.AdvancedSettings.isSTUN)
     {
         STUN_Result result = STUN_Client.Query(UniP2PManager.AdvancedSettings.STUNURL, UniP2PManager.AdvancedSettings.STUNPort, UdpSocket);
         Debugger.Log("[STUN] NetType:" + result.NetType.ToString());
         if (result.NetType == STUN_NetType.UdpBlocked)
         {
             Debugger.Error("[STUN] UDP blocked");
             HLAPI.NetworkErrorCanvas.isError = true;
         }
         else if (result.NetType == STUN_NetType.Symmetric || result.NetType == STUN_NetType.SymmetricUdpFirewall)
         {
             Debugger.Log("[STUN] Symmetric NAT");
             HLAPI.NetworkErrorCanvas.isError = true;
         }
         else
         {
             IPEndPoint publicEP = result.PublicEndPoint;
             Debugger.Log("[STUN] IPEndPoint:" + publicEP.Address + ":" + publicEP.Port);
             STUNIPEndPoint = publicEP;
         }
     }
 }
Пример #18
0
        public async Task launch()
        {
            SystemLog.addEntry("Beginning network setup...");
            SystemLog.addEntry("Deleting old UPnP mappings...");
            if (App.settings.getBool("Use UPnP", true))
            {
                bool done = false;
                System.Threading.Semaphore s = new System.Threading.Semaphore(0, 1);
                System.Threading.Thread t = new System.Threading.Thread(async delegate()
                {
                    await unMapPorts();
                    done = true;
                    s.Release();
                });
                t.IsBackground = true;
                t.Name         = "UPnP test thread";
                t.Start();

                if (!done)
                {
                    s.WaitOne(10000);
                }
                if (!done)
                {
                    SystemLog.addEntry("Failed to find UPnP router in a timely fashion. Disabling UPnP...");
                    UPnPActive = false;
                }
            }
            SystemLog.addEntry("Binding UDP sockets.");
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);


            listener = new TcpListener(IPAddress.Any, App.settings.getInt("Default Data Port", 0));

            listener.Start();
            internalDataPort = ((IPEndPoint)listener.Server.LocalEndPoint).Port;
            SystemLog.addEntry("Binding to TCP port " + internalDataPort.ToString());
            int control = App.settings.getInt("Default Control Port", 0);

            if (control == Dimension.Model.NetConstants.controlPort)
            {
                control = 0;
            }
            unreliableClient    = new UdpClient(control);
            internalControlPort = ((IPEndPoint)unreliableClient.Client.LocalEndPoint).Port;
            if (control == 0)
            {
                App.settings.setInt("Default Control Port", internalControlPort);
            }
            SystemLog.addEntry("Successfully bound to UDP control port " + internalControlPort);

            publicControlEndPoint = (IPEndPoint)unreliableClient.Client.LocalEndPoint;
            publicDataEndPoint    = (IPEndPoint)listener.Server.LocalEndPoint;

tryAgain:

            if (App.settings.getBool("Use UPnP", true) == false || LANMode || !UPnPActive || behindDoubleNAT)
            {
                SystemLog.addEntry("STUNning NAT");
                try
                {
                    string      stunUrl = "stun.l.google.com";
                    STUN_Result result  = STUN_Client.Query(stunUrl, 19302, unreliableClient.Client);
                    SystemLog.addEntry("Attempting to STUN control port to " + stunUrl + ".");

                    if (result.NetType == STUN_NetType.UdpBlocked)
                    {
                        SystemLog.addEntry("STUN failed. Assuming network is LAN-only.");
                        LANMode    = true;
                        UPnPActive = false;
                    }
                    else
                    {
                        publicControlEndPoint = new IPEndPoint(result.PublicEndPoint.Address, result.PublicEndPoint.Port);
                        publicDataEndPoint    = new IPEndPoint(result.PublicEndPoint.Address, internalDataPort);
                        SystemLog.addEntry("STUN successful. External control endpoint: " + result.PublicEndPoint.ToString());
                        SystemLog.addEntry("External data endpoint: " + publicDataEndPoint.ToString());
                    }
                }
                catch (Exception) //STUN can throw generic exceptions :(
                {
                    SystemLog.addEntry("Failed to STUN. Working in LAN mode.");
                    //Stun failed, offline mode
                    LANMode = true;
                }
            }



            Random r = new Random();

            internalDHTPort = App.settings.getInt("Default DHT Port", 0);
            if (internalDHTPort == 0)
            {
                internalDHTPort = r.Next(short.MaxValue - 1000) + 1000;
            }
            publicDHTPort = internalDHTPort;
            if (App.settings.getBool("Use UPnP", true) && !LANMode && UPnPActive && !behindDoubleNAT)
            {
                SystemLog.addEntry("UPnP enabled. Attempting to map UPnP ports...");

                publicControlEndPoint = new IPEndPoint(publicControlEndPoint.Address, r.Next(short.MaxValue - 1000) + 1000);
                publicDataEndPoint    = new IPEndPoint(publicControlEndPoint.Address, r.Next(short.MaxValue - 1000) + 1000);
                publicDHTPort         = r.Next(short.MaxValue - 1000) + 1000;

                SystemLog.addEntry("Creating control UPnP mapping (random external port)...");
                await mapPorts(((IPEndPoint)unreliableClient.Client.LocalEndPoint).Port, publicControlEndPoint.Port, false);

                SystemLog.addEntry("Creating data UPnP mapping (random external port)...");
                await mapPorts(((IPEndPoint)listener.Server.LocalEndPoint).Port, publicDataEndPoint.Port, true);

                SystemLog.addEntry("Creating DHT UPnP mapping (random external port)...");
                await mapPorts(internalDHTPort, publicDHTPort, false);

                publicControlEndPoint = new IPEndPoint(externalIPFromUPnP, publicControlEndPoint.Port);
                publicDataEndPoint    = new IPEndPoint(externalIPFromUPnP, publicDataEndPoint.Port);

                if (externalIPFromUPnP.ToString().StartsWith("10.") || externalIPFromUPnP.ToString().StartsWith("192."))
                {
                    behindDoubleNAT = true;
                    SystemLog.addEntry("WARNING! Your router provided a local IP address as the external endpoint.");
                    SystemLog.addEntry("This probably means you're running more than one router in a row (double NAT).");
                    SystemLog.addEntry("Dimension is going to disable UPnP and try STUNning again to get through this.");
                    SystemLog.addEntry("If this is your home network, please talk to a network engineer -- having UPnP with double NAT is a very bad idea.");
                    goto tryAgain;
                }
            }
            SystemLog.addEntry("Network setup complete.");
        }