Пример #1
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);
 }
Пример #2
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);
                     }
                 }
             }
         }
     }
 }
Пример #3
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;
            }
        }
Пример #4
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;
            }
        }
Пример #5
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);
         }
     }
 }
Пример #6
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();
     }
 }
Пример #7
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);
                }
            }
        }
Пример #8
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;
         }
     }
 }
Пример #9
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);
                 }
             }
         }
     }
 }