internal void ProcessReceivedNat1TestRequest(SocketWithReceiver socket, byte[] udpData, IPEndPoint remoteEndpoint) // receiver thread { // todo put some limits here per endpoint? or we don't care? var request = NatTest1RequestPacket.Decode(udpData); var response = new NatTest1ResponsePacket { RequesterEndpoint = remoteEndpoint, Token32 = request.Token32 }; var responseData = response.Encode(); socket.UdpSocket.Send(responseData, responseData.Length, remoteEndpoint); }
async void TestNat1Async(DrpPeerEngine drpPeerEngine) { _visionChannel.Emit("NATtest1", "NATtest1", AttentionLevel.guiActivity, $"running NAT#1 test...."); for (int loop = 0; ; loop++) { if (!Nat1TestStarted) { break; } if (drpPeerEngine.IsDisposed) { break; } await drpPeerEngine.EngineThreadQueue.WaitAsync(TimeSpan.FromMilliseconds(20), "nattest1 528"); short?ttl = null; if (short.TryParse(Nat1TestTTL, out var ttl2)) { ttl = ttl2; } var rnd = new Random(); var epLines = Nat1TestRemoteEPs.Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (var epLine in epLines) { var i0 = epLine.IndexOf(':'); if (i0 == -1) { continue; } var ipStr = epLine.Substring(0, i0); if (!IPAddress.TryParse(ipStr, out var epIP)) { continue; } var portsStr = epLine.Substring(i0 + 1); int portsRangeStart, portsRangeEnd; // inclusive var i1 = portsStr.IndexOf('-'); if (i1 == -1) { if (!Int32.TryParse(portsStr, out var port1)) { continue; } portsRangeStart = portsRangeEnd = port1; } else { if (!Int32.TryParse(portsStr.Substring(0, i1), out portsRangeStart)) { continue; } if (!Int32.TryParse(portsStr.Substring(i1 + 1), out portsRangeEnd)) { continue; } if (portsRangeEnd <= portsRangeStart) { continue; } } var port = portsRangeStart + loop % (portsRangeEnd - portsRangeStart + 1); var responderEp = new IPEndPoint(epIP, port); var req = new NatTest1RequestPacket { Token32 = (uint)rnd.Next() }; var sw = Stopwatch.StartNew(); var nateTest1responseData = await drpPeerEngine.SendUdpRequestAsync_Retransmit(new PendingLowLevelUdpRequest("nattest1 23", responderEp , NatTest1ResponsePacket.GetScanner(req.Token32), drpPeerEngine.DateTimeNowUtc, 1.0, req.Encode(), 0.3, 1.2 ) { TTL = ttl }); if (nateTest1responseData != null) { var nateTest1response = NatTest1ResponsePacket.Decode(nateTest1responseData); _visionChannel.Emit("NATtest1", "NATtest1", AttentionLevel.guiActivity, $"response from {responderEp}: {nateTest1response.RequesterEndpoint} {(int)sw.Elapsed.TotalMilliseconds}ms"); } else { _visionChannel.Emit("NATtest1", "NATtest1", AttentionLevel.guiActivity, $"no response from {responderEp}"); } } if (int.TryParse(Nat1TestWaitTimeMs, out var sleepTimeMs)) { await drpPeerEngine.EngineThreadQueue.WaitAsync(TimeSpan.FromMilliseconds(sleepTimeMs), "nattest1 247"); } } }