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