From 994887921b673b3b94cc395ebe16811ee0a5347d Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sat, 11 Feb 2023 18:13:23 +0100 Subject: [PATCH] feat(pcap): add mechanism to remove sniffed packets and remove hanging connections --- Pcap/NosSmooth.Pcap/PcapNostaleManager.cs | 57 +++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/Pcap/NosSmooth.Pcap/PcapNostaleManager.cs b/Pcap/NosSmooth.Pcap/PcapNostaleManager.cs index def3ac1..997180d 100644 --- a/Pcap/NosSmooth.Pcap/PcapNostaleManager.cs +++ b/Pcap/NosSmooth.Pcap/PcapNostaleManager.cs @@ -7,6 +7,7 @@ using System.Collections.Concurrent; using System.Diagnostics; using System.Net; +using Microsoft.Extensions.Logging; using SharpPcap; using SharpPcap.LibPcap; @@ -17,16 +18,21 @@ namespace NosSmooth.Pcap; /// public class PcapNostaleManager { + private readonly ILogger _logger; private readonly ConcurrentDictionary _connections; private readonly ConcurrentDictionary _clients; + private Task? _deletionTask; + private CancellationTokenSource? _deletionTaskCancellationSource; private int _clientsCount; private bool _started; /// /// Initializes a new instance of the class. /// - public PcapNostaleManager() + /// The logger. + public PcapNostaleManager(ILogger logger) { + _logger = logger; _connections = new ConcurrentDictionary(); _clients = new ConcurrentDictionary(); } @@ -99,6 +105,16 @@ public class PcapNostaleManager { device.StopCapture(); } + + var task = _deletionTask; + _deletionTask = null; + + _deletionTaskCancellationSource?.Cancel(); + _deletionTaskCancellationSource?.Dispose(); + _deletionTaskCancellationSource = null; + + task?.GetAwaiter().GetResult(); + task?.Dispose(); } /// @@ -112,6 +128,8 @@ public class PcapNostaleManager } _started = true; + _deletionTaskCancellationSource = new CancellationTokenSource(); + _deletionTask = Task.Run(() => DeletionTask(_deletionTaskCancellationSource.Token)); foreach (var device in LibPcapLiveDeviceList.Instance) { @@ -169,14 +187,47 @@ public class PcapNostaleManager } var data = _connections[tcpConnection]; - if (data.SniffedData.Count < 5) + if (data.SniffedData.Count < 5 && data.FirstObservedAt.AddSeconds(10) > DateTimeOffset.Now) { data.SniffedData.Add(tcpPacket.PayloadData); - } // TODO: clean up the sniffed data in case they are not needed. + } if (_clients.TryGetValue(tcpConnection, out var client)) { client.OnPacketArrival(tcpConnection, tcpPacket.PayloadData); } } + + private async Task DeletionTask(CancellationToken ct) + { + while (!ct.IsCancellationRequested) + { + try + { + foreach (var connectionData in _connections) + { + if (connectionData.Value.FirstObservedAt.AddMinutes(10) < DateTimeOffset.Now) + { + _connections.TryRemove(connectionData); + } + + if (connectionData.Value.SniffedData.Count > 0 && connectionData.Value.FirstObservedAt.AddSeconds + (10) < DateTimeOffset.Now) + { + connectionData.Value.SniffedData.Clear(); + } + } + + await Task.Delay(TimeSpan.FromSeconds(30), ct); + } + catch (OperationCanceledException) + { + // ignored + } + catch (Exception e) + { + _logger.LogError(e, "The pcap manager deletion task has thrown an exception"); + } + } + } } \ No newline at end of file -- 2.49.0