Example #1
0
        // Funktionen

        private static STUNMessage SendOverUDP(String IP, int Port, STUNMessage StunMessage)
        {
            IPEndPoint remoteEndpoint = new IPEndPoint(IPAddress.Parse(IP), Port);
            IPEndPoint localEndpoint = new IPEndPoint(IPAddress.Any, 0);

            UdpClient udpClient = null;

            // IPv4 oder IPv6 Adresse?
            if (remoteEndpoint.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                udpClient = new UdpClient();
            else if (remoteEndpoint.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                udpClient = new UdpClient(System.Net.Sockets.AddressFamily.InterNetworkV6);

            // Nachricht in Byte Array wandeln
            Byte[] message_buffer = StunMessage.ToByteArray();



            // initialen TimeOut Wert festlegen
            udpClient.Client.ReceiveTimeout = RTO;

            // Buffer für Empfang der Antwort
            Byte[] response_buffer = null;

            //Stopwatch stopwatch = new Stopwatch();
            //stopwatch.Start();

            // MessageType
            int type = (int)StunMessage.StunMessageType;

            // Indication?
            // 8.Bit(Maske 0x100) gelöscht? und 4.Bit(Maske 0x10) gesetzt?
            if (((type & 0x100) == 0) && ((type & 0x10) != 0))
            {
                // Indication nur ein Sendeversuch
                //Console.WriteLine("Indication");

                try
                {
                    // Versuchen zu senden
                    udpClient.Send(message_buffer, message_buffer.Length, remoteEndpoint);

                    // auf Antwort warten   => AUF INDICATION KOMMT KEINE ANTWORT !!!
                    //response_buffer = udpClient.Receive(ref localEndpoint);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    throw e;
                }

            }
            else
            {
                // Request oder Response
                //Console.WriteLine("Request oder Response");

                // RC Versuche
                for (int versuch = 1; versuch <= RC; versuch++)
                {
                    try
                    {
                        // Versuchen zu senden
                        //Console.WriteLine("Sende bei ({0} ms)", stopwatch.ElapsedMilliseconds);
                        udpClient.Send(message_buffer, message_buffer.Length, remoteEndpoint);

                        // auf Antwort warten
                        response_buffer = udpClient.Receive(ref localEndpoint);

                        // wenn Antwort erhalten springe aus Sende-Schleife
                        break;
                    }
                    catch (SocketException e)
                    {
                        //stopwatch.Stop();
                        if (e.SocketErrorCode == SocketError.TimedOut)
                        {
                            // welcher Versuch ist gescheitert?
                            if (versuch < RC - 1)
                                udpClient.Client.ReceiveTimeout *= 2;
                            // wenn vorletzter Versuch gescheitert ist => letzten Versuch mit ReceiveTimeOut = RM * RTO
                            else if (versuch == RC - 1)
                                udpClient.Client.ReceiveTimeout = RM * RTO;
                            // letzter Versuch ebenfalls gescheitert
                            else if (versuch == RC)
                            {
                                //stopwatch.Stop();
                                //Console.WriteLine("Sendevorgang nach {0} Versuchen und {1} ms abgebrochen!", RC, stopwatch.ElapsedMilliseconds);
                            }
                        }

                        /*
                        if (e.SocketErrorCode == SocketError.NetworkUnreachable)       // trifft nicht ein
                        {
                            Console.WriteLine("unreachable");
                        }
                        */

                        else
                        {
                            Console.WriteLine(e.Message);
                            throw e;
                        }

                    }

                }

            }


            // UdpClient schließen
            udpClient.Close();

            // Nachricht erhalten?
            if (response_buffer != null)
            {
                STUNMessage response = STUNMessage.Parse(response_buffer);
                return response;
            }
            else
                return null;

        }
Example #2
0
        private static STUNMessage SendOverTCP(String IP, int Port, STUNMessage StunMessage, IPEndPoint localEndpoint)
        {

            try
            {
                TcpClient tcpClient = new TcpClient(localEndpoint);
                tcpClient.Connect(IP, Port);

                // TimeOut Wert festlegen
                tcpClient.Client.ReceiveTimeout = TI;

                // Nachricht in Byte Array wandeln
                Byte[] message_buffer = StunMessage.ToByteArray();

                // Netzwerkstream holen
                NetworkStream stream = tcpClient.GetStream();

                // Message senden 
                stream.Write(message_buffer, 0, message_buffer.Length);


                // zuerst Header (20 Byte) empfangen um Länge der Nachricht zu ermitteln
                Byte[] header = new Byte[20];
                stream.Read(header, 0, 20);

                // Länge parsen (3. und 4. Byte im Header)
                Int16 msg_length = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(header, 2));

                // Byte Array für Response
                Byte[] response = new Byte[20 + msg_length];

                // Header in Response kopieren
                Array.Copy(header, 0, response, 0, header.Length);

                // Rest der Nachricht empfangen
                int bytesRead = stream.Read(response, 20, msg_length);

                // alles eingetroffen?
                if (bytesRead != msg_length)
                    Console.WriteLine("Fehler beim empfangen!");

                // parsen
                STUNMessage stunResponse = STUNMessage.Parse(response);

                // aufräumen
                //Thread.Sleep(2000);
                stream.Close();
                tcpClient.Close();

                return stunResponse;


            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw e;

            }

        }
Example #3
0
        private static IPEndPoint GetPublicMapping(Socket stunSocket)
        {
            STUNMessage stunBindingRequest = new STUNMessage(StunMessageType.BindingRequest);
            stunBindingRequest.Create();

            stunSocket.Send(stunBindingRequest.ToByteArray());

            // STUN Header 20 Byte
            byte[] stunHeader = new byte[20];
            stunSocket.Receive(stunHeader, 20, SocketFlags.None);

            ushort stunBodyLength = NetworkByteArray.ReadUInt16(stunHeader, 2);
            byte[] stunBody = new byte[stunBodyLength];
            stunSocket.Receive(stunBody, stunBodyLength, SocketFlags.None);

            byte[] stunBindResp = new byte[20 + stunBodyLength];
            Array.Copy(stunHeader, 0, stunBindResp, 0, 20);
            Array.Copy(stunBody, 0, stunBindResp, 20, stunBodyLength);

            STUNMessage stunBindingResponse = STUNMessage.Parse(stunBindResp);

            // contains XOR Mapped Address?
            for (int i = 0; i < stunBindingResponse.AttributeList.Count; i++)
            {
                if (stunBindingResponse.AttributeList[i].Type == STUNAttribute.StunAttributeType.XorMappedAddress)
                {
                    XorMappedAddressAttribute xmaa = (XorMappedAddressAttribute)stunBindingResponse.AttributeList[i];
                    return xmaa.XorMappedAddress;

                }
            }

            // contains Mapped Address
            for (int i = 0; i < stunBindingResponse.AttributeList.Count; i++)
            {
                if (stunBindingResponse.AttributeList[i].Type == STUNAttribute.StunAttributeType.MappedAddress)
                {
                    MappedAddressAttribute maa = (MappedAddressAttribute)stunBindingResponse.AttributeList[i];
                    return maa.MappedAddress;
                }
            }

            // no attribute
            return null;
        }