~ruther/NosSmooth

1d2c2cdd28a3d1dd8f29246113cc8c5513a35a12 — Rutherther 2 years ago a99f4d6
feat(pcap): add options, replace magic numbers with options
M Pcap/NosSmooth.Pcap/PcapNostaleClient.cs => Pcap/NosSmooth.Pcap/PcapNostaleClient.cs +9 -6
@@ 8,6 8,7 @@ using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Microsoft.Extensions.Options;
using NosSmooth.Core.Client;
using NosSmooth.Core.Commands;
using NosSmooth.Core.Packets;


@@ 35,11 36,11 @@ public class PcapNostaleClient : BaseNostaleClient
    private readonly PcapNostaleManager _pcapManager;
    private readonly ProcessTcpManager _processTcpManager;
    private readonly IPacketHandler _handler;
    private readonly PcapNostaleOptions _options;
    private CryptographyManager _crypto;
    private int _localPort;
    private long _localAddr;
    private CancellationToken? _stoppingToken;
    private bool _running;
    private TcpConnection _connection;

    /// <summary>
    /// Initializes a new instance of the <see cref="PcapNostaleClient"/> class.


@@ 51,6 52,7 @@ public class PcapNostaleClient : BaseNostaleClient
    /// <param name="processTcpManager">The process manager.</param>
    /// <param name="handler">The packet handler.</param>
    /// <param name="commandProcessor">The command processor.</param>
    /// <param name="options">The options.</param>
    public PcapNostaleClient
    (
        Process process,


@@ 59,7 61,8 @@ public class PcapNostaleClient : BaseNostaleClient
        PcapNostaleManager pcapManager,
        ProcessTcpManager processTcpManager,
        IPacketHandler handler,
        CommandProcessor commandProcessor
        CommandProcessor commandProcessor,
        IOptions<PcapNostaleOptions> options
    )
        : base(commandProcessor)
    {


@@ 68,6 71,7 @@ public class PcapNostaleClient : BaseNostaleClient
        _pcapManager = pcapManager;
        _processTcpManager = processTcpManager;
        _handler = handler;
        _options = options.Value;
        _crypto = new CryptographyManager();
        _crypto.EncryptionKey = encryptionKey;
    }


@@ 118,8 122,7 @@ public class PcapNostaleClient : BaseNostaleClient
                        var reverseConn = new TcpConnection
                            (conn.RemoteAddr, conn.RemotePort, conn.LocalAddr, conn.LocalPort);

                        _localAddr = conn.LocalAddr;
                        _localPort = conn.LocalPort;
                        _connection = conn;

                        _pcapManager.RegisterConnection(conn, this);
                        _pcapManager.RegisterConnection(reverseConn, this);


@@ 134,7 137,7 @@ public class PcapNostaleClient : BaseNostaleClient
                    }
                }

                await Task.Delay(TimeSpan.FromMilliseconds(10), stopRequested);
                await Task.Delay(TimeSpan.FromMilliseconds(_options.ProcessRefreshInterval), stopRequested);
            }
        }
        catch (OperationCanceledException)

M Pcap/NosSmooth.Pcap/PcapNostaleManager.cs => Pcap/NosSmooth.Pcap/PcapNostaleManager.cs +13 -9
@@ 8,6 8,8 @@ using System.Collections.Concurrent;
using System.Diagnostics;
using System.Net;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using PacketDotNet;
using SharpPcap;
using SharpPcap.LibPcap;



@@ 19,6 21,7 @@ namespace NosSmooth.Pcap;
public class PcapNostaleManager
{
    private readonly ILogger<PcapNostaleManager> _logger;
    private readonly PcapNostaleOptions _options;
    private readonly ConcurrentDictionary<TcpConnection, ConnectionData> _connections;
    private readonly ConcurrentDictionary<TcpConnection, PcapNostaleClient> _clients;
    private Task? _deletionTask;


@@ 30,9 33,11 @@ public class PcapNostaleManager
    /// Initializes a new instance of the <see cref="PcapNostaleManager"/> class.
    /// </summary>
    /// <param name="logger">The logger.</param>
    public PcapNostaleManager(ILogger<PcapNostaleManager> logger)
    /// <param name="options">The options.</param>
    public PcapNostaleManager(ILogger<PcapNostaleManager> logger, IOptions<PcapNostaleOptions> options)
    {
        _logger = logger;
        _options = options.Value;
        _connections = new ConcurrentDictionary<TcpConnection, ConnectionData>();
        _clients = new ConcurrentDictionary<TcpConnection, PcapNostaleClient>();
    }


@@ 79,7 84,7 @@ public class PcapNostaleManager
        {
            foreach (var sniffedPacket in data.SniffedData)
            {
                client.OnPacketArrival(connection, sniffedPacket);
                client.OnPacketArrival(null, connection, sniffedPacket);
            }
        }
    }


@@ 147,7 152,6 @@ public class PcapNostaleManager
    private void DeviceOnOnPacketArrival(object sender, PacketCapture e)
    {
        var rawPacket = e.GetPacket();

        var packet = PacketDotNet.Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data);

        var tcpPacket = packet.Extract<PacketDotNet.TcpPacket>();


@@ 188,14 192,14 @@ public class PcapNostaleManager

        var data = _connections[tcpConnection];
        if (data.SniffedData.Count < 5 && tcpPacket.PayloadData.Length < 500
            && data.FirstObservedAt.AddSeconds(10) > DateTimeOffset.Now)
            && data.FirstObservedAt.AddMilliseconds(_options.CleanSniffedDataInterval) > DateTimeOffset.Now)
        {
            data.SniffedData.Add(tcpPacket.PayloadData);
        }

        if (_clients.TryGetValue(tcpConnection, out var client))
        {
            client.OnPacketArrival(tcpConnection, tcpPacket.PayloadData);
            client.OnPacketArrival((LibPcapLiveDevice)e.Device, tcpConnection, tcpPacket.PayloadData);
        }
    }



@@ 207,19 211,19 @@ public class PcapNostaleManager
            {
                foreach (var connectionData in _connections)
                {
                    if (connectionData.Value.FirstObservedAt.AddMinutes(10) < DateTimeOffset.Now)
                    if (connectionData.Value.FirstObservedAt.AddMilliseconds(_options.ForgetConnectionInterval) < DateTimeOffset.Now)
                    {
                        _connections.TryRemove(connectionData);
                    }

                    if (connectionData.Value.SniffedData.Count > 0 && connectionData.Value.FirstObservedAt.AddSeconds
                            (10) < DateTimeOffset.Now)
                    if (connectionData.Value.SniffedData.Count > 0 && connectionData.Value.FirstObservedAt.AddMilliseconds
                            (_options.CleanSniffedDataInterval) < DateTimeOffset.Now)
                    {
                        connectionData.Value.SniffedData.Clear();
                    }
                }

                await Task.Delay(TimeSpan.FromSeconds(30), ct);
                await Task.Delay(TimeSpan.FromSeconds(_options.CleanSniffedDataInterval * 3), ct);
            }
            catch (OperationCanceledException)
            {

A Pcap/NosSmooth.Pcap/PcapNostaleOptions.cs => Pcap/NosSmooth.Pcap/PcapNostaleOptions.cs +28 -0
@@ 0,0 1,28 @@
//
//  PcapNostaleOptions.cs
//
//  Copyright (c) František Boháček. All rights reserved.
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace NosSmooth.Pcap;

/// <summary>
/// Options for <see cref="PcapNostaleManager"/> and <see cref="PcapNostaleClient"/>.
/// </summary>
public class PcapNostaleOptions
{
    /// <summary>
    /// Gets or sets the refresh interval of connections of NosTale processes in milliseconds. Default 10 milliseconds.
    /// </summary>
    public long ProcessRefreshInterval { get; set; } = 10;

    /// <summary>
    /// Gets or sets the time data from a connection should be kept in milliseconds. Default 10 seconds.
    /// </summary>
    public long CleanSniffedDataInterval { get; set; } = 10 * 1000;

    /// <summary>
    /// Gets or sets the time tcp connection should be forgotten in milliseconds. Default 10 minutes.
    /// </summary>
    public long ForgetConnectionInterval { get; set; } = 10 * 60 * 1000;
}
\ No newline at end of file

M Pcap/NosSmooth.Pcap/ProcessTcpManager.cs => Pcap/NosSmooth.Pcap/ProcessTcpManager.cs +6 -3
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Diagnostics;
using Microsoft.Extensions.Options;

namespace NosSmooth.Pcap;



@@ 14,7 15,7 @@ namespace NosSmooth.Pcap;
/// </summary>
public class ProcessTcpManager
{
    private static TimeSpan RefreshInterval = TimeSpan.FromMilliseconds(9.99);
    private readonly PcapNostaleOptions _options;

    private readonly SemaphoreSlim _semaphore;
    private readonly List<int> _processes;


@@ 24,8 25,10 @@ public class ProcessTcpManager
    /// <summary>
    /// Initializes a new instance of the <see cref="ProcessTcpManager"/> class.
    /// </summary>
    public ProcessTcpManager()
    /// <param name="options">The options.</param>
    public ProcessTcpManager(IOptions<PcapNostaleOptions> options)
    {
        _options = options.Value;
        _lastRefresh = DateTimeOffset.MinValue;
        _semaphore = new SemaphoreSlim(1, 1);
        _processes = new List<int>();


@@ 92,7 95,7 @@ public class ProcessTcpManager

    private async Task Refresh()
    {
        if (_lastRefresh.Add(RefreshInterval) >= DateTimeOffset.Now)
        if (_lastRefresh.AddMilliseconds(_options.ProcessRefreshInterval) >= DateTimeOffset.Now)
        {
            return;
        }

Do not follow this link