// // ProcessTcpManager.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. using System.Diagnostics; namespace NosSmooth.Pcap; /// /// A manager containing tcp connections, allowing notifications /// to to know about any new connections. /// public class ProcessTcpManager { private static TimeSpan RefreshInterval = TimeSpan.FromMilliseconds(9.99); private readonly SemaphoreSlim _semaphore; private readonly List _processes; private DateTimeOffset _lastRefresh; private IReadOnlyDictionary> _connections; /// /// Initializes a new instance of the class. /// public ProcessTcpManager() { _lastRefresh = DateTimeOffset.MinValue; _semaphore = new SemaphoreSlim(1, 1); _processes = new List(); _connections = new Dictionary>(); } /// /// Register the given process to refreshing list to allow calling /// with that process. /// /// The id of the process to register. /// A representing the asynchronous operation. public async Task RegisterProcess(int processId) { await _semaphore.WaitAsync(); try { _processes.Add(processId); } finally { _semaphore.Release(); } } /// /// Unregister the given process from refreshing list, won't /// work for that process anymore. /// /// The process to unregister. /// A representing the asynchronous operation. public async Task UnregisterProcess(int processId) { await _semaphore.WaitAsync(); try { _processes.Remove(processId); } finally { _semaphore.Release(); } } /// /// Get connections established by the given process. /// /// /// Works only for processes registered using . /// /// The id of process to retrieve connections for. /// The list of process connections. public async Task> GetConnectionsAsync(int processId) { await Refresh(); if (!_connections.ContainsKey(processId)) { return Array.Empty(); } return _connections[processId]; } private async Task Refresh() { if (_lastRefresh.Add(RefreshInterval) >= DateTimeOffset.Now) { return; } _lastRefresh = DateTimeOffset.Now; if (_processes.Count == 0) { if (_connections.Count > 0) { _connections = new Dictionary>(); } } await _semaphore.WaitAsync(); _connections = TcpConnectionHelper.GetConnections(_processes); _semaphore.Release(); } }