using System.Collections.Concurrent; using System.Diagnostics; using Backend.Helper; using Models.Handler; using Models.Model.Backend; namespace Backend.Handler; public class IpFilterHandler { private readonly ConcurrentQueue _discardedQueue; private readonly ConcurrentQueue _unfilteredQueue; private readonly ConcurrentQueue _preFilteredQueue; private DbHandler _dbHandler; private ThreadHandler _threadHandler; private bool _stop; private bool _fillerStop; private bool _stopAutoscaledThreads; private int _timeout; public IpFilterHandler(ConcurrentQueue discardedQueue, ConcurrentQueue unfilteredQueue, ConcurrentQueue preFilteredQueue, DbHandler dbHandler, ThreadHandler threadHandler) { _discardedQueue = discardedQueue; _unfilteredQueue = unfilteredQueue; _preFilteredQueue = preFilteredQueue; _dbHandler = dbHandler; _threadHandler = threadHandler; _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(16); continue; } counter = 0; waitHandles.Add(waitHandle); waitHandle = new WaitHandle[64]; } return waitHandles; } public void AutoScaler() { int i = 0; int j = 0; while (!_stop) { if (_preFilteredQueue.Count >= 2000) { if (i == 10) { _stopAutoscaledThreads = false; Console.WriteLine("Autoscaler started"); while (!_stopAutoscaledThreads) { if (_preFilteredQueue.Count <= 2000) { if (j == 1000) { _stopAutoscaledThreads = true; } j++; Thread.Sleep(128); } else { EventWaitHandle handle = new(false, EventResetMode.ManualReset); Thread f = new (Filter_AutoScaler!); f.Start(handle); Thread.Sleep(16); } } } i++; } else { i = 0; j = 0; } Thread.Sleep(128); } } private void Filter(object obj) { int counter = 0; while (!_stop) { if (_preFilteredQueue.IsEmpty && _fillerStop) { if (counter == 100) { _threadHandler.Stop(); _stop = true; } counter++; Thread.Sleep(128); } _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(); } public void FillFilterQueue() { Console.WriteLine("Fill FilterQueue started."); while (!_stop) { if (_preFilteredQueue.Count > 500) continue; if (_dbHandler.GetPreFilterQueueItem(out FilterQueueItem item)) { _preFilteredQueue.Enqueue(item); } else { _fillerStop = true; } } } private void Filter_AutoScaler(object obj) { while (!_stopAutoscaledThreads) { 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; } }