~ruther/NosSmooth

994887921b673b3b94cc395ebe16811ee0a5347d — Rutherther 2 years ago 57fd7ba
feat(pcap): add mechanism to remove sniffed packets and remove hanging connections
1 files changed, 54 insertions(+), 3 deletions(-)

M Pcap/NosSmooth.Pcap/PcapNostaleManager.cs
M Pcap/NosSmooth.Pcap/PcapNostaleManager.cs => Pcap/NosSmooth.Pcap/PcapNostaleManager.cs +54 -3
@@ 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;
/// </summary>
public class PcapNostaleManager
{
    private readonly ILogger<PcapNostaleManager> _logger;
    private readonly ConcurrentDictionary<TcpConnection, ConnectionData> _connections;
    private readonly ConcurrentDictionary<TcpConnection, PcapNostaleClient> _clients;
    private Task? _deletionTask;
    private CancellationTokenSource? _deletionTaskCancellationSource;
    private int _clientsCount;
    private bool _started;

    /// <summary>
    /// Initializes a new instance of the <see cref="PcapNostaleManager"/> class.
    /// </summary>
    public PcapNostaleManager()
    /// <param name="logger">The logger.</param>
    public PcapNostaleManager(ILogger<PcapNostaleManager> logger)
    {
        _logger = logger;
        _connections = new ConcurrentDictionary<TcpConnection, ConnectionData>();
        _clients = new ConcurrentDictionary<TcpConnection, PcapNostaleClient>();
    }


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

    /// <summary>


@@ 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

Do not follow this link