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); } } } } } }
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; } }
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; } }
/// <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); }
/// <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); }
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); }
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); } }
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); } } }
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; } } }
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); } } } } }