227 lines
6.1 KiB
C#
227 lines
6.1 KiB
C#
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<Discarded> _discardedQueue;
|
|
private readonly ConcurrentQueue<UnfilteredQueueItem> _unfilteredQueue;
|
|
private readonly ConcurrentQueue<FilterQueueItem> _preFilteredQueue;
|
|
private DbHandler _dbHandler;
|
|
private ThreadHandler _threadHandler;
|
|
private bool _stop;
|
|
private bool _fillerStop;
|
|
private bool _stopAutoscaledThreads;
|
|
private int _timeout;
|
|
|
|
public IpFilterHandler(ConcurrentQueue<Discarded> discardedQueue,
|
|
ConcurrentQueue<UnfilteredQueueItem> unfilteredQueue,
|
|
ConcurrentQueue<FilterQueueItem> preFilteredQueue,
|
|
DbHandler dbHandler, ThreadHandler threadHandler)
|
|
{
|
|
_discardedQueue = discardedQueue;
|
|
_unfilteredQueue = unfilteredQueue;
|
|
_preFilteredQueue = preFilteredQueue;
|
|
_dbHandler = dbHandler;
|
|
_threadHandler = threadHandler;
|
|
|
|
_timeout = 16;
|
|
}
|
|
|
|
public List<WaitHandle[]> Start(int threadCount)
|
|
{
|
|
WaitHandle[] waitHandle = new WaitHandle[64];
|
|
|
|
int counter = 0;
|
|
|
|
List<WaitHandle[]> 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;
|
|
}
|
|
} |