void TestOneOutboundTunnel() { OutboundTunnel outtunnel; lock ( OutboundTunnels ) { if (OutboundTunnels.Count == 0) { return; } outtunnel = OutboundTunnels.First.Value; OutboundTunnels.RemoveFirst(); if (outtunnel.NeedsRecreation) { return; } OutboundTunnels.AddLast(outtunnel); } var run = OutstandingTests.Get(outtunnel); if (run != null) { // Run has finished? if (run.TestedPartners.Count >= RunsPerTest) { if (run.LastRun.DeltaToNow < TimeBetweenTests) { return; } run.OutstandingProbes.Clear(); run.SuccessPartners.Clear(); run.TestedPartners.Clear(); } } else { run = new TestRun2(outtunnel); OutstandingTests[outtunnel] = run; } var test = TestResults.Get(outtunnel, () => new TunnelTestResult(outtunnel)); var intunnels = TunnelProvider.Inst.GetInboundTunnels().Shuffle().Take(RunsPerTest * 2).ToArray(); if (!intunnels.Any()) { //DebugUtils.LogDebug( "TunnelTester: Failed to get a established inbound tunnel." ); return; } run.LastRun.SetNow(); string tunneldbginfo = ""; foreach (var intunnel in intunnels) { if (run.FailurePartners.Contains(intunnel) || run.SuccessPartners.Contains(intunnel) || run.TestedPartners.Contains(intunnel)) { continue; } run.TestedPartners.Add(intunnel); var probe = new ProbesSent() { Tunnel = outtunnel, Partner = intunnel, MessageId = I2NPHeader.GenerateMessageId(), TotalHops = outtunnel.Config.Info.Hops.Count + intunnel.Config.Info.Hops.Count }; tunneldbginfo += $"({intunnel.TunnelDebugTrace}:{probe.MessageId})"; run.OutstandingProbes.Add(probe); OutstandingProbeIds[probe.MessageId] = probe; outtunnel.Send(new TunnelMessageTunnel((new DeliveryStatusMessage(probe.MessageId)).Header16, intunnel)); } if (tunneldbginfo.Length > 0) { DebugUtils.LogDebug( $"TunnelTester: Starting outbound tunnel {outtunnel.TunnelDebugTrace} test with tunnels: {tunneldbginfo}"); } }
private void HandleTunnelTestResult(TestRun2 run) { if (run.OutstandingProbes.Count > 0) { return; } var testresult = TestResults.Get(run.TunnelUnderTest, () => new TunnelTestResult(run.TunnelUnderTest)); if (run.SuccessPartners.Count > 0) { ++testresult.Pass; } else { ++testresult.Fail; } if (run.TestedPartners.Count < RunsPerTest) { return; } if (testresult.Pass > 0 && testresult.Pass * 2 >= testresult.Fail) { DebugUtils.LogDebug(string.Format("TunnelTester: Run result: Tunnel {0} passed tests. Successes: {1}, Failures {2}.", run.TunnelUnderTest, testresult.Pass, testresult.Fail)); foreach (var onehop in run.TunnelUnderTest.TunnelMembers) { NetDb.Inst.Statistics.SuccessfulTunnelTest(onehop.IdentHash); } foreach (var onepartner in run.SuccessPartners) { foreach (var onehop in onepartner.TunnelMembers) { NetDb.Inst.Statistics.SuccessfulTunnelTest(onehop.IdentHash); } var partnertestresult = TestResults.Get(onepartner, () => new TunnelTestResult(onepartner)); ++partnertestresult.Pass; } foreach (var onepartner in run.FailurePartners) { foreach (var onehop in onepartner.TunnelMembers) { NetDb.Inst.Statistics.FailedTunnelTest(onehop.IdentHash); } var partnertestresult = TestResults.Get(onepartner, () => new TunnelTestResult(onepartner)); ++partnertestresult.Fail; } return; } // Fail and remove foreach (var onehop in run.TunnelUnderTest.TunnelMembers) { NetDb.Inst.Statistics.FailedTunnelTest(onehop.IdentHash); } foreach (var onepartner in run.FailurePartners) { foreach (var onehop in onepartner.TunnelMembers) { NetDb.Inst.Statistics.FailedTunnelTest(onehop.IdentHash); } } if (run.TunnelUnderTest is InboundTunnel) { lock ( InboundTunnels ) { InboundTunnels.RemoveAll(t => t == run.TunnelUnderTest); } } else { lock ( OutboundTunnels ) { OutboundTunnels.RemoveAll(t => t == run.TunnelUnderTest); } } DebugUtils.LogDebug(string.Format("TunnelTester: Run result: Tunnel {0} failed tests and is removed. Successes: {1}, Failures {2}.", run.TunnelUnderTest, testresult.Pass, testresult.Fail)); TunnelProvider.Inst.TunnelTestFailed(run.TunnelUnderTest); run.TunnelUnderTest.Shutdown(); }
void TestOneOutboundTunnel() { if (OutboundTunnels.IsEmpty) { return; } if (!OutboundTunnels.TryDequeue(out var outtunnel)) { return; } if (!outtunnel.Active || outtunnel.Metrics.PassedTunnelTest) { return; } OutboundTunnels.Enqueue(outtunnel); var run = OutstandingTests.Get(outtunnel); if (run != null) { // Run has finished? if (run.TestedPartners.Count >= RunsPerTest) { if (run.LastRun.DeltaToNow < TimeBetweenTests) { return; } run.OutstandingProbes.Clear(); run.SuccessPartners.Clear(); run.TestedPartners.Clear(); } } else { run = new TestRun2(outtunnel); OutstandingTests[outtunnel] = run; } var test = TestResults.Get(outtunnel, () => new TunnelTestResult(outtunnel)); var intunnels = TunnelProvider.Inst.GetInboundTunnels() .Where(t => t.Active) .Shuffle() .Take(RunsPerTest * 2) .ToArray(); if (!intunnels.Any()) { //Logging.LogDebug( "TunnelTester: Failed to get a established inbound tunnel." ); return; } run.LastRun.SetNow(); string tunneldbginfo = ""; foreach (var intunnel in intunnels) { if (run.FailurePartners.Contains(intunnel) || run.SuccessPartners.Contains(intunnel) || run.TestedPartners.Contains(intunnel)) { continue; } run.TestedPartners.Add(intunnel); var probe = new ProbesSent() { Tunnel = outtunnel, Partner = intunnel, MessageId = I2NPMessage.GenerateMessageId(), TotalHops = outtunnel.Config.Info.Hops.Count + intunnel.Config.Info.Hops.Count }; tunneldbginfo += $"({intunnel.TunnelDebugTrace}:{probe.MessageId})"; run.OutstandingProbes.Add(probe); OutstandingProbeIds[probe.MessageId] = probe; outtunnel.Send(new TunnelMessageTunnel(new DeliveryStatusMessage(probe.MessageId), intunnel)); } if (tunneldbginfo.Length > 0) { Logging.LogDebug( $"TunnelTester: Starting outbound tunnel {outtunnel.TunnelDebugTrace} test with tunnels: {tunneldbginfo}"); } }