Esempio n. 1
0
        private void HandleReceive(IAsyncResult ar)
        {
            UdpClient receiveClient = (UdpClient)ar.AsyncState;

            try
            {
                IPEndPoint receiveAddr  = null;
                byte[]     receiveBytes = receiveClient.EndReceive(ar, ref receiveAddr);
                if (receiveBytes.Length >= 24)
                {
                    UdpMeshCommon.ProcessBytes(receiveBytes, receiveAddr, callbacks);
                }
            }
            catch (Exception e)
            {
                if (!shutdown)
                {
                    Console.WriteLine("Error receiving: " + e);
                }
            }
            if (!shutdown)
            {
                try
                {
                    receiveClient.BeginReceive(HandleReceive, receiveClient);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error restarting receive: " + e);
                    error = true;
                }
            }
        }
Esempio n. 2
0
 public static Guid[] RequestRemoteIPv6(UdpClient client)
 {
     byte[] header = GetRequestBytes();
     Guid[] retVal = new Guid[2];
     retVal[0] = Guid.Empty;
     retVal[1] = Guid.Empty;
     if (stunServer1v4 == null)
     {
         SetStunServer();
     }
     if (stunServer1v6 == null)
     {
         return(retVal);
     }
     try
     {
         retVal[0] = WriteGuid(header);
         UdpMeshCommon.Send(client, header, stunServer1v6);
     }
     catch
     {
         //Don't care
     }
     try
     {
         retVal[1] = WriteGuid(header);
         UdpMeshCommon.Send(client, header, stunServer2v6);
     }
     catch
     {
         //Don't care
     }
     return(retVal);
 }
Esempio n. 3
0
 private void SendClientsHello()
 {
     byte[] timeBytes = BitConverter.GetBytes(DateTime.UtcNow.Ticks);
     UdpMeshCommon.FlipEndian(ref timeBytes);
     byte[] sendBytes = UdpMeshCommon.GetPayload(-201, timeBytes);
     lock (clients)
     {
         foreach (UdpPeer peer in clients.Values)
         {
             if (peer.guid == UdpMeshCommon.GetMeshAddress())
             {
                 continue;
             }
             //Send to ipv4
             if (peer.usev4)
             {
                 UdpMeshCommon.Send(clientSocketv4, sendBytes, peer.contactV4);
             }
             else
             {
                 foreach (IPEndPoint iPEndPoint in peer.remoteEndpoints)
                 {
                     if (UdpMeshCommon.IsIPv4(iPEndPoint.Address))
                     {
                         string newContactString = iPEndPoint.ToString();
                         if (!contactedIPs.Contains(newContactString))
                         {
                             contactedIPs.Add(newContactString);
                             DebugLog("Attempting new contact v4: " + newContactString);
                         }
                         UdpMeshCommon.Send(clientSocketv4, sendBytes, iPEndPoint);
                     }
                 }
             }
             //Send to ipv6
             if (peer.usev6)
             {
                 UdpMeshCommon.Send(clientSocketv6, sendBytes, peer.contactV6);
             }
             else
             {
                 foreach (IPEndPoint iPEndPoint in peer.remoteEndpoints)
                 {
                     if (UdpMeshCommon.IsIPv6(iPEndPoint.Address))
                     {
                         string newContactString = iPEndPoint.ToString();
                         if (!contactedIPs.Contains(newContactString))
                         {
                             contactedIPs.Add(newContactString);
                             DebugLog("Attempting new contact v6: " + newContactString);
                         }
                         UdpMeshCommon.Send(clientSocketv6, sendBytes, iPEndPoint);
                     }
                 }
             }
         }
     }
 }
Esempio n. 4
0
 private void HandleRelayMessage(byte[] inputData, Guid serverGuid, IPEndPoint endPoint)
 {
     if (inputData.Length < 64)
     {
         return;
     }
     byte[] cropMessage = new byte[inputData.Length - 40];
     Array.Copy(inputData, 40, cropMessage, 0, cropMessage.Length);
     UdpMeshCommon.ProcessBytes(cropMessage, null, callbacks);
 }
Esempio n. 5
0
        public void SendMessageToClient(Guid clientGuid, int type, byte[] data)
        {
            if (type < 0)
            {
                throw new IndexOutOfRangeException("Implementers must use positive ID's");
            }
            UdpPeer peer = GetPeer(clientGuid);

            if (peer == null)
            {
                return;
            }
            byte[] sendBytes = UdpMeshCommon.GetPayload(type, data);
            if (peer.usev4 && peer.usev6 && clientSocketv4 != null && clientSocketv6 != null)
            {
                if (peer.latency4 < peer.latency6)
                {
                    UdpMeshCommon.Send(clientSocketv4, sendBytes, peer.contactV4);
                }
                else
                {
                    UdpMeshCommon.Send(clientSocketv6, sendBytes, peer.contactV6);
                }
                return;
            }
            if (peer.usev6 && clientSocketv6 != null)
            {
                UdpMeshCommon.Send(clientSocketv6, sendBytes, peer.contactV6);
                return;
            }
            if (peer.usev4 && clientSocketv4 != null)
            {
                UdpMeshCommon.Send(clientSocketv4, sendBytes, peer.contactV4);
                return;
            }
            byte[] relayBytes = new byte[40 + sendBytes.Length];
            Array.Copy(relayHeader, 0, relayBytes, 0, relayHeader.Length);
            byte[] destination = clientGuid.ToByteArray();
            Array.Copy(destination, 0, relayBytes, 24, 16);
            Array.Copy(sendBytes, 0, relayBytes, 40, sendBytes.Length);
            if (connectedv6 && clientSocketv6 != null)
            {
                UdpMeshCommon.Send(clientSocketv6, relayBytes, serverEndpointv6);
                return;
            }
            if (connectedv4 && clientSocketv4 != null)
            {
                UdpMeshCommon.Send(clientSocketv4, relayBytes, serverEndpointv4);
                return;
            }
        }
Esempio n. 6
0
        private void ClientExternalReport(byte[] inputBytes, Guid guid, IPEndPoint iPEndPoint)
        {
            if (inputBytes.Length != 47 && inputBytes.Length != 59)
            {
                return;
            }
            byte type = inputBytes[40];
            Guid onBehalfOf;

            lock (tempGuid)
            {
                Array.Copy(inputBytes, 24, tempGuid, 0, 16);
                onBehalfOf = new Guid(tempGuid);
            }
            lock (clients)
            {
                UdpPeer peer;
                if (clients.TryGetValue(onBehalfOf, out peer))
                {
                    IPAddress addr;
                    int       port;
                    if (inputBytes.Length == 47 && type == 4)
                    {
                        lock (tempClientPort)
                        {
                            Array.Copy(inputBytes, 41, tempClientAddress4, 0, 4);
                            addr = new IPAddress(tempClientAddress4);
                            Array.Copy(inputBytes, 45, tempClientPort, 0, 2);
                            UdpMeshCommon.FlipEndian(ref tempClientPort);
                            port = BitConverter.ToUInt16(tempClientPort, 0);
                        }
                        IPEndPoint endPoint = new IPEndPoint(addr, port);
                        peer.AddRemoteEndpoint(endPoint);
                    }
                    if (inputBytes.Length == 59 && type == 6)
                    {
                        lock (tempClientPort)
                        {
                            Array.Copy(inputBytes, 41, tempClientAddress6, 0, 16);
                            addr = new IPAddress(tempClientAddress6);
                            Array.Copy(inputBytes, 57, tempClientPort, 0, 2);
                            UdpMeshCommon.FlipEndian(ref tempClientPort);
                            port = BitConverter.ToUInt16(tempClientPort, 0);
                        }
                        IPEndPoint endPoint = new IPEndPoint(addr, port);
                        peer.AddRemoteEndpoint(endPoint);
                    }
                }
            }
        }
Esempio n. 7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:UDPMeshLib.UdpMeshClient"/> class.
 /// </summary>
 /// <param name="serverEndpointv4">Mesh servers IPv4 address to connect to.</param>
 /// <param name="serverEndpointv6">Mesh servers IPv6 address to connect to.</param>
 /// <param name="myAddresses">List of local addresses to inform the server about for in-network meshing</param>
 /// <param name="debugLog">Debug logging callback, leave <see langword="null"/> to disable</param>
 public UdpMeshClient(IPEndPoint serverEndpointv4, IPEndPoint serverEndpointv6, IPAddress[] myAddresses, Action <string> debugLog)
 {
     this.me               = new UdpPeer(UdpMeshCommon.GetMeshAddress());
     this.myAddresses      = myAddresses;
     this.serverEndpointv4 = serverEndpointv4;
     this.serverEndpointv6 = serverEndpointv6;
     this.debugLog         = debugLog;
     callbacks[-1]         = HandleServerReport;
     callbacks[-2]         = HandleClientInfo;
     callbacks[-3]         = HandleRelayMessage;
     callbacks[-201]       = HandleHeartBeat;
     callbacks[-202]       = HandleHeartBeatReply;
     UdpStun.callback      = HandleStun;
 }
Esempio n. 8
0
 private void HandleClientInfo(byte[] inputData, int inputDataLength, Guid serverGuid, IPEndPoint serverEndpoint)
 {
     lock (guidData)
     {
         int readPos = 24;
         if (inputDataLength - readPos < 17)
         {
             return;
         }
         Array.Copy(inputData, readPos, guidData, 0, 16);
         Guid receiveID = new Guid(guidData);
         if (!clients.ContainsKey(receiveID))
         {
             clients.Add(receiveID, new UdpPeer(receiveID));
         }
         UdpPeer client = clients[receiveID];
         readPos += 16;
         int v4Num = inputData[readPos];
         readPos++;
         for (int i = 0; i < v4Num; i++)
         {
             Array.Copy(inputData, readPos, tempClientAddress4, 0, 4);
             IPAddress ip = new IPAddress(tempClientAddress4);
             readPos += 4;
             Array.Copy(inputData, readPos, tempClientPort, 0, 2);
             UdpMeshCommon.FlipEndian(ref tempClientPort);
             int port = BitConverter.ToUInt16(tempClientPort, 0);
             client.AddRemoteEndpoint(new IPEndPoint(ip, port));
             readPos += 2;
         }
         if (inputDataLength - readPos < 1)
         {
             return;
         }
         int v6Num = inputData[readPos];
         readPos++;
         for (int i = 0; i < v6Num; i++)
         {
             Array.Copy(inputData, readPos, tempClientAddress6, 0, 16);
             IPAddress ip = new IPAddress(tempClientAddress6);
             readPos += 16;
             Array.Copy(inputData, readPos, tempClientPort, 0, 2);
             UdpMeshCommon.FlipEndian(ref tempClientPort);
             int port = BitConverter.ToUInt16(tempClientPort, 0);
             client.AddRemoteEndpoint(new IPEndPoint(ip, port));
             readPos += 2;
         }
     }
 }
Esempio n. 9
0
        private void RelayMessage(byte[] inputBytes, int inputBytesLength, Guid client, IPEndPoint endPoint)
        {
            //A valid message must contain 2 headers (24 bytes) and a destination GUID (16 bytes)
            if (inputBytesLength < 64)
            {
                return;
            }

            //Make sure client isn't relaying control messages
            lock (tempType)
            {
                Array.Copy(inputBytes, 60, tempType, 0, 4);
                UdpMeshCommon.FlipEndian(ref tempType);
                int relayType = BitConverter.ToInt32(tempType, 0);
                if (relayType < 0)
                {
                    return;
                }
            }
            UdpPeer peer;

            lock (tempGuid)
            {
                Array.Copy(inputBytes, 24, tempGuid, 0, 16);
                Guid destinationGuid = new Guid(tempGuid);
                clients.TryGetValue(destinationGuid, out peer);
            }
            //Make sure client is connected
            if (peer == null)
            {
                return;
            }
            if (relayHeader == null)
            {
                relayHeader = new byte[24];
                UdpMeshCommon.GetPayload(-3, null, 0, relayHeader);
            }
            Array.Copy(relayHeader, 0, inputBytes, 0, 24);
            if (peer.usev6)
            {
                UdpMeshCommon.Send(serverSocketv6, inputBytes, peer.contactV6);
                return;
            }
            if (peer.usev4)
            {
                UdpMeshCommon.Send(serverSocketv4, inputBytes, peer.contactV4);
                return;
            }
        }
Esempio n. 10
0
 private void HandleHeartBeatReply(byte[] inputData, int inputDataLength, Guid clientGuid, IPEndPoint iPEndPoint)
 {
     lock (tempTime)
     {
         if (inputDataLength != 40)
         {
             return;
         }
         UdpPeer peer = GetPeer(clientGuid);
         if (peer == null)
         {
             return;
         }
         lock (tempTime)
         {
             Array.Copy(inputData, 24, tempTime, 0, 8);
             UdpMeshCommon.FlipEndian(ref tempTime);
             long sendTime = BitConverter.ToInt64(tempTime, 0);
             Array.Copy(inputData, 32, tempTime, 0, 8);
             UdpMeshCommon.FlipEndian(ref tempTime);
             long remoteTime  = BitConverter.ToInt64(tempTime, 0);
             long receiveTime = DateTime.UtcNow.Ticks;
             peer.lastReceiveTime = receiveTime;
             if (UdpMeshCommon.IsIPv4(iPEndPoint.Address))
             {
                 peer.latency4 = receiveTime - sendTime;
                 long expectedReceive = (peer.latency4 / 2) + sendTime;
                 peer.offset = expectedReceive - remoteTime;
             }
             if (UdpMeshCommon.IsIPv6(iPEndPoint.Address))
             {
                 peer.latency6 = receiveTime - sendTime;
                 long expectedReceive = (peer.latency6 / 2) + sendTime;
                 peer.offset = expectedReceive - remoteTime;
             }
         }
         peer.AddRemoteEndpoint(iPEndPoint);
         if (UdpMeshCommon.IsIPv4(iPEndPoint.Address) && !peer.usev4)
         {
             peer.contactV4 = iPEndPoint;
             peer.usev4     = true;
         }
         if (UdpMeshCommon.IsIPv6(iPEndPoint.Address) && !peer.usev6)
         {
             peer.contactV6 = iPEndPoint;
             peer.usev6     = true;
         }
     }
 }
Esempio n. 11
0
 /// <summary>
 /// Send FROM the server
 /// </summary>
 internal byte[] GetClientEndpointMessage()
 {
     if (!cacheOK)
     {
         cacheOK = true;
         List <IPEndPoint> v4end = new List <IPEndPoint>();
         List <IPEndPoint> v6end = new List <IPEndPoint>();
         foreach (IPEndPoint endPoint in remoteEndpoints)
         {
             if (endPoint.AddressFamily == AddressFamily.InterNetwork)
             {
                 v4end.Add(endPoint);
             }
             if (endPoint.AddressFamily == AddressFamily.InterNetworkV6)
             {
                 v6end.Add(endPoint);
             }
         }
         int cachedDataBuildLength = 18 + 6 * v4end.Count + 18 * v6end.Count;
         Array.Copy(guid.ToByteArray(), cachedDataBuild, 16);
         cachedDataBuild[16] = (Byte)v4end.Count;
         int writepos = 17;
         foreach (IPEndPoint endPoint in v4end)
         {
             byte[] addrBytes = endPoint.Address.GetAddressBytes();
             Array.Copy(addrBytes, 0, cachedDataBuild, writepos, 4);
             writepos += 4;
             byte[] portBytes = BitConverter.GetBytes((ushort)endPoint.Port);
             UdpMeshCommon.FlipEndian(ref portBytes);
             Array.Copy(portBytes, 0, cachedDataBuild, writepos, 2);
             writepos += 2;
         }
         cachedDataBuild[writepos] = (Byte)v6end.Count;
         writepos++;
         foreach (IPEndPoint endPoint in v6end)
         {
             byte[] addrBytes = endPoint.Address.GetAddressBytes();
             Array.Copy(addrBytes, 0, cachedDataBuild, writepos, 16);
             writepos += 16;
             byte[] portBytes = BitConverter.GetBytes((ushort)endPoint.Port);
             UdpMeshCommon.FlipEndian(ref portBytes);
             Array.Copy(portBytes, 0, cachedDataBuild, writepos, 2);
             writepos += 2;
         }
         cachedDataLength = UdpMeshCommon.GetPayload(-2, cachedDataBuild, cachedDataBuildLength, cachedData);
     }
     return(cachedData);
 }
Esempio n. 12
0
 private void HandleReceive(UdpClient receiveClient, bool isv6)
 {
     try
     {
         if (receiveClient.Client.Available == 0)
         {
             return;
         }
         byte[]   buffer = v4buffer;
         EndPoint receiveAddrEndpoint = (EndPoint)anyV4;
         if (isv6)
         {
             buffer = v6buffer;
             receiveAddrEndpoint = (EndPoint)anyV6;
         }
         byte[]     processBytes = buffer;
         int        bytesRead    = receiveClient.Client.ReceiveFrom(buffer, ref receiveAddrEndpoint);
         IPEndPoint receiveAddr  = (IPEndPoint)receiveAddrEndpoint;
         bool       process      = true;
         if (bytesRead >= 24)
         {
             if (process)
             {
                 try
                 {
                     if (!UdpMeshCommon.USE_BUFFERS)
                     {
                         processBytes = new byte[bytesRead];
                         Array.Copy(buffer, 0, processBytes, 0, bytesRead);
                     }
                     UdpMeshCommon.ProcessBytes(processBytes, bytesRead, receiveAddr, callbacks);
                 }
                 catch (Exception e)
                 {
                     DebugLog("Error processing message: " + e);
                 }
             }
         }
     }
     catch (Exception e)
     {
         if (!shutdown)
         {
             Console.WriteLine("Error receiving: " + e);
         }
     }
 }
Esempio n. 13
0
 /// <summary>
 /// Sent TO the server
 /// </summary>
 internal byte[] GetServerEndpointMessage()
 {
     if (cachedData == null)
     {
         List <IPEndPoint> v4end = new List <IPEndPoint>();
         List <IPEndPoint> v6end = new List <IPEndPoint>();
         foreach (IPEndPoint endPoint in remoteEndpoints)
         {
             if (endPoint.AddressFamily == AddressFamily.InterNetwork)
             {
                 v4end.Add(endPoint);
             }
             if (endPoint.AddressFamily == AddressFamily.InterNetworkV6)
             {
                 v6end.Add(endPoint);
             }
         }
         cachedData    = new byte[2 + 6 * v4end.Count + 18 * v6end.Count];
         cachedData[0] = (Byte)v4end.Count;
         int writepos = 1;
         foreach (IPEndPoint endPoint in v4end)
         {
             byte[] addrBytes = endPoint.Address.GetAddressBytes();
             Array.Copy(addrBytes, 0, cachedData, writepos, 4);
             writepos += 4;
             byte[] portBytes = BitConverter.GetBytes((ushort)endPoint.Port);
             UdpMeshCommon.FlipEndian(ref portBytes);
             Array.Copy(portBytes, 0, cachedData, writepos, 2);
             writepos += 2;
         }
         cachedData[writepos] = (Byte)v6end.Count;
         writepos++;
         foreach (IPEndPoint endPoint in v6end)
         {
             byte[] addrBytes = endPoint.Address.GetAddressBytes();
             Array.Copy(addrBytes, 0, cachedData, writepos, 16);
             writepos += 16;
             byte[] portBytes = BitConverter.GetBytes((ushort)endPoint.Port);
             UdpMeshCommon.FlipEndian(ref portBytes);
             Array.Copy(portBytes, 0, cachedData, writepos, 2);
             writepos += 2;
         }
         cachedData = UdpMeshCommon.GetPayload(-101, cachedData);
     }
     return(cachedData);
 }
Esempio n. 14
0
 private void HandleRelayMessage(byte[] inputData, int inputDataLength, Guid serverGuid, IPEndPoint endPoint)
 {
     lock (relayBuffer)
     {
         if (inputDataLength < 64)
         {
             return;
         }
         byte[] relayData = relayBuffer;
         if (!UdpMeshCommon.USE_BUFFERS)
         {
             relayData = new byte[inputDataLength - 40];
         }
         Array.Copy(inputData, 0, relayData, 0, inputDataLength - 40);
         UdpMeshCommon.ProcessBytes(relayData, inputDataLength - 40, null, callbacks);
     }
 }
Esempio n. 15
0
 private void SendServerInfo()
 {
     byte[] serverData = me.GetServerEndpointMessage();
     if (serverEndpointv4 != null)
     {
         if (serverEndpointv4.Address != IPAddress.None)
         {
             UdpMeshCommon.Send(clientSocketv4, serverData, serverEndpointv4);
         }
     }
     if (serverEndpointv6 != null)
     {
         if (serverEndpointv6.Address != IPAddress.None)
         {
             UdpMeshCommon.Send(clientSocketv6, serverData, serverEndpointv6);
         }
     }
 }
Esempio n. 16
0
 private byte[] GetConnectedGuidBytes()
 {
     if (connectedGuidBytes == null)
     {
         lock (clients)
         {
             connectedGuidBytes = new byte[16 * clients.Count];
             int writepos = 0;
             foreach (Guid guid in clients.Keys)
             {
                 Array.Copy(guid.ToByteArray(), 0, connectedGuidBytes, writepos, 16);
                 writepos = writepos + 16;
             }
             connectedGuidBytes = UdpMeshCommon.GetPayload(-1, connectedGuidBytes);
         }
     }
     return(connectedGuidBytes);
 }
Esempio n. 17
0
 private void SendClientsMeshState()
 {
     lock (clients)
     {
         byte[] sendGuidBytes = GetConnectedGuidBytes();
         clientBytes.Clear();
         foreach (UdpPeer client in clients.Values)
         {
             clientBytes.Add(client.GetClientEndpointMessage());
         }
         foreach (KeyValuePair <Guid, UdpPeer> client in clients)
         {
             if ((client.Value.lastReceiveTime + CLIENT_TIMEOUT) < DateTime.UtcNow.Ticks)
             {
                 removeList.Add(client.Key);
                 continue;
             }
             if (serverSocketv4 != null && client.Value.usev4)
             {
                 UdpMeshCommon.Send(serverSocketv4, sendGuidBytes, client.Value.contactV4);
                 foreach (byte[] clientByte in clientBytes)
                 {
                     UdpMeshCommon.Send(serverSocketv4, clientByte, client.Value.contactV4);
                 }
             }
             if (serverSocketv6 != null && client.Value.usev6)
             {
                 UdpMeshCommon.Send(serverSocketv6, sendGuidBytes, client.Value.contactV6);
                 foreach (byte[] clientByte in clientBytes)
                 {
                     UdpMeshCommon.Send(serverSocketv6, clientByte, client.Value.contactV6);
                 }
             }
         }
         foreach (Guid client in removeList)
         {
             clients.Remove(client);
             connectedGuidBytes = null;
         }
         removeList.Clear();
     }
 }
Esempio n. 18
0
 private void HandleServerReport(byte[] inputData, int inputDataLength, Guid serverGuid, IPEndPoint serverEndpoint)
 {
     lock (guidData)
     {
         if (UdpMeshCommon.IsIPv4(serverEndpoint.Address))
         {
             connectedv4 = true;
         }
         if (UdpMeshCommon.IsIPv6(serverEndpoint.Address))
         {
             connectedv6 = true;
         }
         int readPos = 24;
         lock (clients)
         {
             removeGuids.AddRange(clients.Keys);
             while (inputDataLength - readPos >= 16)
             {
                 Array.Copy(inputData, readPos, guidData, 0, 16);
                 readPos += 16;
                 Guid newGuid = new Guid(guidData);
                 if (!clients.ContainsKey(newGuid))
                 {
                     clients.Add(newGuid, new UdpPeer(newGuid));
                 }
                 if (removeGuids.Contains(newGuid))
                 {
                     removeGuids.Remove(newGuid);
                 }
             }
             foreach (Guid guid in removeGuids)
             {
                 clients.Remove(guid);
             }
             removeGuids.Clear();
         }
     }
 }
Esempio n. 19
0
 private byte[] GetConnectedGuidBytes()
 {
     lock (sendBuffer)
     {
         if (connectedGuidBytes == null)
         {
             lock (clients)
             {
                 byte[] connectedGuidBytesBuild = new byte[16 * clients.Count];
                 int    writepos = 0;
                 foreach (Guid guid in clients.Keys)
                 {
                     Array.Copy(guid.ToByteArray(), 0, connectedGuidBytesBuild, writepos, 16);
                     writepos = writepos + 16;
                 }
                 int connectedGuidBytesLength = UdpMeshCommon.GetPayload(-1, connectedGuidBytesBuild, connectedGuidBytesBuild.Length, sendBuffer);
                 connectedGuidBytes = new byte[connectedGuidBytesLength];
                 Array.Copy(sendBuffer, 0, connectedGuidBytes, 0, connectedGuidBytesLength);
             }
         }
         return(connectedGuidBytes);
     }
 }
Esempio n. 20
0
 private static void SetStunServer()
 {
     IPAddress[] addrs1 = Dns.GetHostAddresses("stun1.l.google.com");
     IPAddress[] addrs2 = Dns.GetHostAddresses("stun2.l.google.com");
     foreach (IPAddress addr1 in addrs1)
     {
         if (UdpMeshCommon.IsIPv4(addr1))
         {
             stunServer1v4 = new IPEndPoint(addr1, 19302);
             break;
         }
     }
     foreach (IPAddress addr2 in addrs2)
     {
         if (UdpMeshCommon.IsIPv4(addr2))
         {
             stunServer2v4 = new IPEndPoint(addr2, 19302);
             break;
         }
     }
     foreach (IPAddress addr1 in addrs1)
     {
         if (UdpMeshCommon.IsIPv6(addr1))
         {
             stunServer1v6 = new IPEndPoint(addr1, 19302);
             break;
         }
     }
     foreach (IPAddress addr2 in addrs2)
     {
         if (UdpMeshCommon.IsIPv6(addr2))
         {
             stunServer2v6 = new IPEndPoint(addr2, 19302);
             break;
         }
     }
 }
Esempio n. 21
0
        /// <summary>
        /// Processes a received stun message.
        /// </summary>
        /// <returns>Stun result</returns>
        /// <param name="inputData">Input raw stun message</param>
        public static StunResult ProcessStun(byte[] inputData, int inputDataLength)
        {
            StunResult retVal = new StunResult();

            if (inputDataLength < 20)
            {
                return(retVal);
            }
            byte[] messageShortBytes = new byte[2];
            Array.Copy(inputData, 0, messageShortBytes, 0, 2);
            UdpMeshCommon.FlipEndian(ref messageShortBytes);
            int messageTypeCombined = BitConverter.ToInt16(messageShortBytes, 0);

            Array.Copy(inputData, 2, messageShortBytes, 0, 2);
            UdpMeshCommon.FlipEndian(ref messageShortBytes);
            int messageLength = BitConverter.ToInt16(messageShortBytes, 0);

            byte[] messageGuidBytes = new byte[16];
            Array.Copy(inputData, 4, messageGuidBytes, 0, 16);
            retVal.messageGuid = new Guid(messageGuidBytes);
            int bytesToRead = messageLength;

            while (bytesToRead > 0)
            {
                if (bytesToRead < 4)
                {
                    return(retVal);
                }
                Array.Copy(inputData, inputData.Length - bytesToRead, messageShortBytes, 0, 2);
                UdpMeshCommon.FlipEndian(ref messageShortBytes);
                int attrType = BitConverter.ToUInt16(messageShortBytes, 0);
                bytesToRead -= 2;
                Array.Copy(inputData, inputData.Length - bytesToRead, messageShortBytes, 0, 2);
                UdpMeshCommon.FlipEndian(ref messageShortBytes);
                int attrLength = BitConverter.ToUInt16(messageShortBytes, 0);
                bytesToRead -= 2;
                if (attrLength > 0)
                {
                    byte[] attrBytes = new byte[attrLength];
                    Array.Copy(inputData, inputData.Length - bytesToRead, attrBytes, 0, attrLength);
                    bytesToRead -= attrLength;
                    if (attrType == 1 && attrBytes[1] == 1 && attrLength == 8)
                    {
                        Array.Copy(attrBytes, 2, messageShortBytes, 0, 2);
                        UdpMeshCommon.FlipEndian(ref messageShortBytes);
                        retVal.port = BitConverter.ToUInt16(messageShortBytes, 0);
                        byte[] ipBytes = new byte[4];
                        Array.Copy(attrBytes, 4, ipBytes, 0, 4);
                        retVal.remoteAddr = new IPAddress(ipBytes);
                        retVal.success    = true;
                    }
                    if (attrType == 1 && attrBytes[1] == 2 && attrLength == 20)
                    {
                        Array.Copy(attrBytes, 2, messageShortBytes, 0, 2);
                        UdpMeshCommon.FlipEndian(ref messageShortBytes);
                        retVal.port = BitConverter.ToUInt16(messageShortBytes, 0);
                        byte[] ipBytes = new byte[16];
                        Array.Copy(attrBytes, 4, ipBytes, 0, 16);
                        retVal.remoteAddr = new IPAddress(ipBytes);
                        retVal.success    = true;
                    }
                    if (attrType == 32 && attrBytes[1] == 1 && attrLength == 8)
                    {
                        Array.Copy(attrBytes, 2, messageShortBytes, 0, 2);
                        //Xor with magic cookie
                        XorBytes(messageShortBytes, messageGuidBytes);
                        UdpMeshCommon.FlipEndian(ref messageShortBytes);
                        retVal.port = BitConverter.ToUInt16(messageShortBytes, 0);
                        byte[] ipBytes = new byte[4];
                        Array.Copy(attrBytes, 4, ipBytes, 0, 4);
                        //Xor with magic cookie
                        XorBytes(ipBytes, messageGuidBytes);
                        retVal.remoteAddr = new IPAddress(ipBytes);
                        retVal.success    = true;
                    }
                    if (attrType == 32 && attrBytes[1] == 2 && attrLength == 20)
                    {
                        Array.Copy(attrBytes, 2, messageShortBytes, 0, 2);
                        //Xor with magic cookie
                        XorBytes(messageShortBytes, messageGuidBytes);
                        UdpMeshCommon.FlipEndian(ref messageShortBytes);
                        retVal.port = BitConverter.ToUInt16(messageShortBytes, 0);
                        byte[] ipBytes = new byte[16];
                        Array.Copy(attrBytes, 4, ipBytes, 0, 16);
                        //Xor with magic cookie
                        XorBytes(ipBytes, messageGuidBytes);
                        retVal.remoteAddr = new IPAddress(ipBytes);
                        retVal.success    = true;
                    }
                }
            }
            if (callback != null)
            {
                callback(retVal);
            }
            return(retVal);
        }
Esempio n. 22
0
 public void Run()
 {
     try
     {
         clientSocketv4 = new UdpClient(0, AddressFamily.InterNetwork);
     }
     catch (Exception e)
     {
         DebugLog("Error setting up v4 socket: " + e);
         clientSocketv4 = null;
     }
     try
     {
         clientSocketv6 = new UdpClient(0, AddressFamily.InterNetworkV6);
     }
     catch (Exception e)
     {
         DebugLog("Error setting up v6 socket: " + e);
         clientSocketv6 = null;
     }
     if (clientSocketv4 != null)
     {
         clientSocketv4.BeginReceive(HandleReceive, clientSocketv4);
     }
     if (clientSocketv6 != null)
     {
         clientSocketv6.BeginReceive(HandleReceive, clientSocketv6);
     }
     if (clientSocketv4 != null)
     {
         int v4portNumber = ((IPEndPoint)clientSocketv4.Client.LocalEndPoint).Port;
         DebugLog("Listening on port v4:" + v4portNumber);
         foreach (IPAddress addr in myAddresses)
         {
             if (UdpMeshCommon.IsIPv4(addr))
             {
                 me.AddRemoteEndpoint(new IPEndPoint(addr, v4portNumber));
             }
         }
     }
     if (clientSocketv6 != null)
     {
         int v6portNumber = ((IPEndPoint)clientSocketv6.Client.LocalEndPoint).Port;
         DebugLog("Listening on port v6:" + v6portNumber);
         foreach (IPAddress addr in myAddresses)
         {
             if (UdpMeshCommon.IsIPv6(addr))
             {
                 me.AddRemoteEndpoint(new IPEndPoint(addr, v6portNumber));
             }
         }
     }
     while (!shutdown && !error && clientSocketv4 != null && clientSocketv6 != null)
     {
         //Restun every 5 minutes
         if ((DateTime.UtcNow.Ticks - receivedStun) > (TimeSpan.TicksPerMinute * 5))
         {
             if (clientSocketv4 != null)
             {
                 UdpStun.RequestRemoteIPv4(clientSocketv4);
                 UdpStun.RequestRemoteIPv6(clientSocketv6);
             }
         }
         SendServerInfo();
         SendClientsHello();
         System.Threading.Thread.Sleep(10000);
     }
     Shutdown();
 }
Esempio n. 23
0
        private void HandleClientInfo(byte[] inputData, Guid serverGuid, IPEndPoint serverEndpoint)
        {
            int readPos = 24;

            if (inputData.Length - readPos < 17)
            {
                return;
            }
            byte[] guidData = new byte[16];
            Array.Copy(inputData, readPos, guidData, 0, 16);
            Guid receiveID = new Guid(guidData);

            if (!clients.ContainsKey(receiveID))
            {
                clients.Add(receiveID, new UdpPeer(receiveID));
            }
            UdpPeer client = clients[receiveID];

            readPos += 16;
            int v4Num = inputData[readPos];

            readPos++;
            for (int i = 0; i < v4Num; i++)
            {
                if (inputData.Length - readPos < 6)
                {
                    return;
                }
                Array.Copy(inputData, readPos, tempClientAddress4, 0, 4);
                IPAddress ip = new IPAddress(tempClientAddress4);
                readPos += 4;
                Array.Copy(inputData, readPos, tempClientPort, 0, 2);
                UdpMeshCommon.FlipEndian(ref tempClientPort);
                int port = BitConverter.ToUInt16(tempClientPort, 0);
                client.AddRemoteEndpoint(new IPEndPoint(ip, port));
                readPos += 2;
            }
            if (inputData.Length - readPos < 1)
            {
                return;
            }
            int v6Num = inputData[readPos];

            readPos++;
            for (int i = 0; i < v6Num; i++)
            {
                if (inputData.Length - readPos < 18)
                {
                    return;
                }
                Array.Copy(inputData, readPos, tempClientAddress6, 0, 16);
                IPAddress ip = new IPAddress(tempClientAddress6);
                readPos += 16;
                Array.Copy(inputData, readPos, tempClientPort, 0, 2);
                UdpMeshCommon.FlipEndian(ref tempClientPort);
                int port = BitConverter.ToUInt16(tempClientPort, 0);
                client.AddRemoteEndpoint(new IPEndPoint(ip, port));
                readPos += 2;
            }

            /*
             * DebugLog("Updated endpoints for " + receiveID);
             * foreach (IPEndPoint endPoint in client.remoteEndpoints)
             * {
             *  DebugLog(endPoint);
             * }1
             * DebugLog("===");
             */
        }
Esempio n. 24
0
        private void ClientReport(byte[] inputData, Guid guid, IPEndPoint endpoint)
        {
            List <IPEndPoint> newEndpoints = new List <IPEndPoint>();

            lock (tempClientPort)
            {
                int readPos = 24;
                if (inputData.Length - readPos < 1)
                {
                    return;
                }
                int v4Num = inputData[readPos];
                readPos++;
                for (int i = 0; i < v4Num; i++)
                {
                    if (inputData.Length - readPos < 6)
                    {
                        return;
                    }
                    Array.Copy(inputData, readPos, tempClientAddress4, 0, 4);
                    IPAddress ip = new IPAddress(tempClientAddress4);
                    readPos += 4;
                    Array.Copy(inputData, readPos, tempClientPort, 0, 2);
                    UdpMeshCommon.FlipEndian(ref tempClientPort);
                    int port = BitConverter.ToUInt16(tempClientPort, 0);
                    newEndpoints.Add(new IPEndPoint(ip, port));
                    readPos += 2;
                }
                if (inputData.Length - readPos < 1)
                {
                    return;
                }
                int v6Num = inputData[readPos];
                readPos++;
                for (int i = 0; i < v6Num; i++)
                {
                    if (inputData.Length - readPos < 18)
                    {
                        return;
                    }
                    Array.Copy(inputData, readPos, tempClientAddress6, 0, 16);
                    IPAddress ip = new IPAddress(tempClientAddress6);
                    readPos += 16;
                    Array.Copy(inputData, readPos, tempClientPort, 0, 2);
                    UdpMeshCommon.FlipEndian(ref tempClientPort);
                    int port = BitConverter.ToUInt16(tempClientPort, 0);
                    newEndpoints.Add(new IPEndPoint(ip, port));
                    readPos += 2;
                }
                lock (clients)
                {
                    if (!clients.ContainsKey(guid))
                    {
                        clients.Add(guid, new UdpPeer(guid));
                        connectedGuidBytes = null;
                    }
                    UdpPeer client = clients[guid];
                    if (UdpMeshCommon.IsIPv4(endpoint.Address))
                    {
                        client.usev4     = true;
                        client.contactV4 = endpoint;
                    }
                    if (UdpMeshCommon.IsIPv6(endpoint.Address))
                    {
                        client.usev6     = true;
                        client.contactV6 = endpoint;
                    }
                    client.AddRemoteEndpoint(endpoint);
                    foreach (IPEndPoint tempEndPoint in newEndpoints)
                    {
                        client.AddRemoteEndpoint(tempEndPoint);
                    }
                    client.lastReceiveTime = DateTime.UtcNow.Ticks;
                }
            }
        }
Esempio n. 25
0
 public void SendMessageToClient(Guid clientGuid, int type, byte[] data, int length)
 {
     lock (sendBuffer)
     {
         if (type < 0)
         {
             throw new IndexOutOfRangeException("Implementers must use positive ID's");
         }
         UdpPeer peer = GetPeer(clientGuid);
         if (peer == null)
         {
             return;
         }
         int sendBufferLength = UdpMeshCommon.GetPayload(type, data, length, sendBuffer);
         //We can use v4 or v6, let's select the lowest latency
         if (peer.usev4 && peer.usev6 && clientSocketv4 != null && clientSocketv6 != null)
         {
             if (peer.latency4 < peer.latency6)
             {
                 UdpMeshCommon.Send(clientSocketv4, sendBuffer, sendBufferLength, peer.contactV4);
             }
             else
             {
                 UdpMeshCommon.Send(clientSocketv6, sendBuffer, sendBufferLength, peer.contactV6);
             }
             return;
         }
         //Have to use V6, only v6 contact
         if (peer.usev6 && !peer.usev4 && clientSocketv6 != null)
         {
             UdpMeshCommon.Send(clientSocketv6, sendBuffer, sendBufferLength, peer.contactV6);
             return;
         }
         //Have to use V6, only v4 contact
         if (peer.usev4 && !peer.usev6 && clientSocketv4 != null)
         {
             UdpMeshCommon.Send(clientSocketv4, sendBuffer, sendBufferLength, peer.contactV4);
             return;
         }
         //We currently have no contact and must send through the server to establish contact.
         int relayBufferLength = 40 + sendBufferLength;
         //Initialise header if this is the first run, we can use the relayBuffer as it is still free.
         if (relayHeader == null)
         {
             int relayHeaderLength = UdpMeshCommon.GetPayload(-102, null, 0, relayBuffer);
             relayHeader = new byte[relayHeaderLength];
             Array.Copy(relayBuffer, 0, relayHeader, 0, relayHeaderLength);
         }
         Array.Copy(relayHeader, 0, relayBuffer, 0, relayHeader.Length);
         byte[] destination = clientGuid.ToByteArray();
         Array.Copy(destination, 0, relayBuffer, 24, 16);
         Array.Copy(sendBuffer, 0, relayBuffer, 40, sendBufferLength);
         if (connectedv6 && clientSocketv6 != null)
         {
             UdpMeshCommon.Send(clientSocketv6, relayBuffer, relayBufferLength, serverEndpointv6);
             return;
         }
         if (connectedv4 && clientSocketv4 != null)
         {
             UdpMeshCommon.Send(clientSocketv4, relayBuffer, relayBufferLength, serverEndpointv4);
             return;
         }
     }
 }
Esempio n. 26
0
 private void HandleHeartBeat(byte[] inputData, int inputDataLength, Guid clientGuid, IPEndPoint iPEndPoint)
 {
     lock (buildBuffer)
     {
         lock (sendBuffer)
         {
             if (inputDataLength != 32)
             {
                 return;
             }
             UdpPeer peer = GetPeer(clientGuid);
             if (peer == null)
             {
                 return;
             }
             peer.lastReceiveTime = DateTime.UtcNow.Ticks;
             byte[] currentTime = BitConverter.GetBytes(DateTime.UtcNow.Ticks);
             UdpMeshCommon.FlipEndian(ref currentTime);
             Array.Copy(inputData, 24, heartbeatReplyBytes, 0, 8);
             Array.Copy(currentTime, 0, heartbeatReplyBytes, 8, 8);
             int length = UdpMeshCommon.GetPayload(-202, heartbeatReplyBytes, heartbeatReplyBytes.Length, sendBuffer);
             if (UdpMeshCommon.IsIPv4(iPEndPoint.Address))
             {
                 UdpMeshCommon.Send(clientSocketv4, sendBuffer, length, iPEndPoint);
             }
             if (UdpMeshCommon.IsIPv6(iPEndPoint.Address))
             {
                 UdpMeshCommon.Send(clientSocketv6, sendBuffer, length, iPEndPoint);
             }
             if (UdpMeshCommon.IsIPv4(iPEndPoint.Address))
             {
                 if (!peer.usev4)
                 {
                     Array.Copy(clientGuid.ToByteArray(), 0, buildBuffer, 0, 16);
                     buildBuffer[16] = 4;
                     byte[] endpointBytes = iPEndPoint.Address.GetAddressBytes();
                     if (endpointBytes.Length == 4)
                     {
                         Array.Copy(endpointBytes, 0, buildBuffer, 17, 4);
                     }
                     if (endpointBytes.Length == 16)
                     {
                         Array.Copy(endpointBytes, 12, buildBuffer, 17, 4);
                     }
                     byte[] portBytes = BitConverter.GetBytes((UInt16)iPEndPoint.Port);
                     UdpMeshCommon.FlipEndian(ref portBytes);
                     Array.Copy(portBytes, 0, buildBuffer, 21, 2);
                     int sendLength = UdpMeshCommon.GetPayload(-103, buildBuffer, 25, sendBuffer);
                     UdpMeshCommon.Send(clientSocketv4, sendBuffer, sendLength, serverEndpointv4);
                 }
             }
             if (UdpMeshCommon.IsIPv6(iPEndPoint.Address))
             {
                 if (!peer.usev6)
                 {
                     Array.Copy(clientGuid.ToByteArray(), 0, buildBuffer, 0, 16);
                     buildBuffer[16] = 6;
                     byte[] endpointBytes = iPEndPoint.Address.GetAddressBytes();
                     Array.Copy(endpointBytes, 0, buildBuffer, 17, 16);
                     byte[] portBytes = BitConverter.GetBytes((UInt16)iPEndPoint.Port);
                     UdpMeshCommon.FlipEndian(ref portBytes);
                     Array.Copy(portBytes, 0, buildBuffer, 33, 2);
                     int sendLength = UdpMeshCommon.GetPayload(-103, buildBuffer, 35, sendBuffer);
                     UdpMeshCommon.Send(clientSocketv6, sendBuffer, sendLength, serverEndpointv6);
                 }
             }
         }
     }
 }
Esempio n. 27
0
        private void HandleHeartBeat(byte[] inputData, Guid clientGuid, IPEndPoint iPEndPoint)
        {
            if (inputData.Length != 32)
            {
                return;
            }
            UdpPeer peer = GetPeer(clientGuid);

            if (peer == null)
            {
                return;
            }
            peer.lastReceiveTime = DateTime.UtcNow.Ticks;
            byte[] replyBytes  = new byte[16];
            byte[] currentTime = BitConverter.GetBytes(DateTime.UtcNow.Ticks);
            UdpMeshCommon.FlipEndian(ref currentTime);
            Array.Copy(inputData, 24, replyBytes, 0, 8);
            Array.Copy(currentTime, 0, replyBytes, 8, 8);
            byte[] replyMessage = UdpMeshCommon.GetPayload(-202, replyBytes);
            if (UdpMeshCommon.IsIPv4(iPEndPoint.Address))
            {
                UdpMeshCommon.Send(clientSocketv4, replyMessage, iPEndPoint);
                if (!peer.usev4)
                {
                    byte[] notifyServerOfEndpoint = new byte[23];
                    Array.Copy(clientGuid.ToByteArray(), 0, notifyServerOfEndpoint, 0, 16);
                    notifyServerOfEndpoint[16] = 4;
                    byte[] endpointBytes = iPEndPoint.Address.GetAddressBytes();
                    if (endpointBytes.Length == 4)
                    {
                        Array.Copy(endpointBytes, 0, notifyServerOfEndpoint, 17, 4);
                    }
                    if (endpointBytes.Length == 16)
                    {
                        Array.Copy(endpointBytes, 12, notifyServerOfEndpoint, 17, 4);
                    }
                    byte[] portBytes = BitConverter.GetBytes((UInt16)iPEndPoint.Port);
                    UdpMeshCommon.FlipEndian(ref portBytes);
                    Array.Copy(portBytes, 0, notifyServerOfEndpoint, 21, 2);
                    byte[] notifyServerOfEndpointPayload = UdpMeshCommon.GetPayload(-103, notifyServerOfEndpoint);
                    UdpMeshCommon.Send(clientSocketv4, notifyServerOfEndpointPayload, serverEndpointv4);
                }
            }
            if (UdpMeshCommon.IsIPv6(iPEndPoint.Address))
            {
                UdpMeshCommon.Send(clientSocketv6, replyMessage, iPEndPoint);
                if (!peer.usev6)
                {
                    byte[] notifyServerOfEndpoint = new byte[35];
                    Array.Copy(clientGuid.ToByteArray(), 0, notifyServerOfEndpoint, 0, 16);
                    notifyServerOfEndpoint[16] = 6;
                    byte[] endpointBytes = iPEndPoint.Address.GetAddressBytes();
                    Array.Copy(endpointBytes, 0, notifyServerOfEndpoint, 17, 16);
                    byte[] portBytes = BitConverter.GetBytes((UInt16)iPEndPoint.Port);
                    UdpMeshCommon.FlipEndian(ref portBytes);
                    Array.Copy(portBytes, 0, notifyServerOfEndpoint, 33, 2);
                    byte[] notifyServerOfEndpointPayload = UdpMeshCommon.GetPayload(-103, notifyServerOfEndpoint);
                    UdpMeshCommon.Send(clientSocketv6, notifyServerOfEndpointPayload, serverEndpointv6);
                }
            }
        }