using System.Collections.Concurrent; using Backend.Helper; using Models.Model.Backend; namespace Backend.Handler; public class IpFilterHandler { private readonly ConcurrentQueue _discardedQueue; private readonly ConcurrentQueue _unfilteredQueue; private readonly ConcurrentQueue _preFilteredQueue; private bool _stop; private int _timeout; public IpFilterHandler(ConcurrentQueue discardedQueue, ConcurrentQueue unfilteredQueue, ConcurrentQueue filteredQueue) { _discardedQueue = discardedQueue; _unfilteredQueue = unfilteredQueue; _preFilteredQueue = filteredQueue; _timeout = 16; } public List Start(int threadCount) { WaitHandle[] waitHandle = new WaitHandle[64]; int counter = 0; List waitHandles = []; for (int i = 0; i < threadCount; i++) { EventWaitHandle handle = new(false, EventResetMode.ManualReset); if (counter < 64) { waitHandle[counter] = handle; counter++; Thread f = new (Filter!); f.Start(handle); Console.WriteLine($"Filter thread ({i}) started"); Thread.Sleep(25); continue; } counter = 0; waitHandles.Add(waitHandle); waitHandle = new WaitHandle[64]; } return waitHandles; } private void Filter(object obj) { while (!_stop) { if (_preFilteredQueue.IsEmpty) { Thread.Sleep(_timeout); continue; } _preFilteredQueue.TryDequeue(out FilterQueueItem item); (int, int) ports = TcpClientHelper.CheckPort(item.Ip, 80, 443); if (ports is { Item1: 0, Item2: 0 }) { _discardedQueue.Enqueue(CreateDiscardedQueueItem(item.Ip, item.ResponseCode)); continue; } _unfilteredQueue.Enqueue(CreateUnfilteredQueueItem(item.Ip, ports)); } ((EventWaitHandle) obj).Set(); } private static Discarded CreateDiscardedQueueItem(Ip ip, int responseCode) { return new() { Ip = ip, ResponseCode = responseCode }; } private static UnfilteredQueueItem CreateUnfilteredQueueItem(Ip ip, (int, int) ports) { Unfiltered unfiltered = new() { Ip = ip, Port1 = ports.Item1, Port2 = ports.Item2, Filtered = false }; return new() { Unfiltered = unfiltered, Operations = Operations.Insert }; } public void Stop() { _stop = true; } }