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