Initial commit
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
using Backend.Helper;
|
||||
using MessagePack;
|
||||
using Models.Handler;
|
||||
using Models.Model.Backend;
|
||||
using Models.Model.External;
|
||||
using NetMQ;
|
||||
using NetMQ.Sockets;
|
||||
|
||||
namespace Backend.Handler;
|
||||
|
||||
public class Communication
|
||||
{
|
||||
private readonly NetMQPoller _poller;
|
||||
private readonly DbHandler _dbHandler;
|
||||
private readonly ThreadHandler _threadHandler;
|
||||
|
||||
public Communication(DbHandler dbHandler, ThreadHandler threadHandler)
|
||||
{
|
||||
_dbHandler = dbHandler;
|
||||
_threadHandler = threadHandler;
|
||||
_poller = new();
|
||||
}
|
||||
|
||||
public WaitHandle[] Start()
|
||||
{
|
||||
WaitHandle[] waitHandles = new WaitHandle[1];
|
||||
EventWaitHandle handle = new(false, EventResetMode.ManualReset);
|
||||
waitHandles[0] = handle;
|
||||
|
||||
Thread thread = new(Server!);
|
||||
thread.Start(handle);
|
||||
|
||||
return waitHandles;
|
||||
}
|
||||
|
||||
private void Server(object obj)
|
||||
{
|
||||
using ResponseSocket server = new();
|
||||
server.Bind("tcp://*:5556");
|
||||
|
||||
server.ReceiveReady += OnServerOnReceiveReady;
|
||||
|
||||
_poller.Add(server);
|
||||
|
||||
Console.WriteLine("Server is running and waiting for client requests...");
|
||||
|
||||
_poller.Run();
|
||||
|
||||
Console.WriteLine("Communication stopped.");
|
||||
|
||||
((EventWaitHandle) obj).Set();
|
||||
}
|
||||
|
||||
[RequiresDynamicCode("Calls System.Text.Json.JsonSerializer.Serialize<TValue>(TValue, JsonSerializerOptions)")]
|
||||
[RequiresUnreferencedCode("Calls System.Text.Json.JsonSerializer.Serialize<TValue>(TValue, JsonSerializerOptions)")]
|
||||
private void OnServerOnReceiveReady(object? _, NetMQSocketEventArgs e)
|
||||
{
|
||||
byte[] message = e.Socket.ReceiveFrameBytes();
|
||||
|
||||
CommunicationObject communicationObject = MessagePackSerializer.Deserialize<CommunicationObject>(message);
|
||||
|
||||
switch (communicationObject.Command)
|
||||
{
|
||||
case CommunicationCommand.GetScanningProgress:
|
||||
{
|
||||
DatabaseSizes databaseSizes = FilesystemHelper.GetDatabaseSizes();
|
||||
|
||||
long discardedIndexes = _dbHandler.GetDiscardedIndexes();
|
||||
|
||||
ScanningStatus status = new();
|
||||
// 4294967296 is all Ipv4 addresses.
|
||||
|
||||
if (discardedIndexes != 0)
|
||||
{
|
||||
status.PercentageOfIpv4Scanned = (float)discardedIndexes / 4294967296 * 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
status.PercentageOfIpv4Scanned = 0.0000000001f;
|
||||
}
|
||||
|
||||
status.AmountOfIpv4Left = 4294967296 - discardedIndexes;
|
||||
status.TotalFiltered = DbHandler.GetFilteredIndexes();
|
||||
status.TotalDiscarded = discardedIndexes;
|
||||
status.MyDbSize = databaseSizes.MyDbSize;
|
||||
status.FilteredDbSize = databaseSizes.FilteredDbSize;
|
||||
status.DiscardedDbSize = databaseSizes.DiscardedDbSize;
|
||||
|
||||
|
||||
byte[] serializedResult = MessagePackSerializer.Serialize(status, MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray));
|
||||
|
||||
e.Socket.SendFrame(serializedResult);
|
||||
break;
|
||||
}
|
||||
case CommunicationCommand.StopScanning:
|
||||
SendStringResponse(e, "Server is stopping.");
|
||||
|
||||
_threadHandler.Stop();
|
||||
break;
|
||||
|
||||
case CommunicationCommand.GarbageCollect:
|
||||
ThreadHandler.ManualGc();
|
||||
|
||||
SendStringResponse(e, "Server has garbage collected.");
|
||||
|
||||
_threadHandler.Stop();
|
||||
break;
|
||||
|
||||
case CommunicationCommand.DbReindex:
|
||||
_dbHandler.ReIndex();
|
||||
|
||||
SendStringResponse(e, "All Dbs have been reindexed.");
|
||||
break;
|
||||
|
||||
case CommunicationCommand.DbVacuum:
|
||||
_dbHandler.Vacuum();
|
||||
|
||||
SendStringResponse(e, "All Dbs have been vacuumed.");
|
||||
break;
|
||||
|
||||
case CommunicationCommand.GetSearches:
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(communicationObject.SearchTerm))
|
||||
{
|
||||
SendSearchResponse(e, communicationObject.SearchTerm);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SendStringResponse(NetMQSocketEventArgs e, string response)
|
||||
{
|
||||
MessagePackSerializerOptions withCompression = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray);
|
||||
byte[] serializedResult = MessagePackSerializer.Serialize(response, withCompression);
|
||||
|
||||
e.Socket.SendFrame(serializedResult);
|
||||
}
|
||||
|
||||
private static void SendSearchResponse(NetMQSocketEventArgs e, string searchTerm)
|
||||
{
|
||||
//SearchResults result = SearchHelper.Search(communicationObject.SearchTerm!, _dbHandler);
|
||||
SearchResults result = new()
|
||||
{
|
||||
Results = []
|
||||
};
|
||||
SearchResult lol = new()
|
||||
{
|
||||
Url = "Remember to use an actual search tearm. Like 'dotnet 9.0'",
|
||||
Title = "Remember to use an actual search tearm. Like 'dotnet 9.0'",
|
||||
};
|
||||
|
||||
result.Results.Add(lol);
|
||||
|
||||
string serializedResult = JsonSerializer.Serialize(result);
|
||||
|
||||
e.Socket.SendFrame(serializedResult);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_poller.Stop();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using Backend.Helper;
|
||||
using Models.Handler;
|
||||
using Models.Model.Backend;
|
||||
|
||||
namespace Backend.Handler;
|
||||
|
||||
public class ContentFilter
|
||||
{
|
||||
private readonly ConcurrentQueue<QueueItem> _queue;
|
||||
private readonly DbHandler _dbHandler;
|
||||
private const string GetDomainPort80 = "/home/skingging/Documents/Projects/CSharp/RSE/Backend/GetDomainNamePort80.sh";
|
||||
private const string GetDomainPort443 = "/home/skingging/Documents/Projects/CSharp/RSE/Backend/GetDomainNamePort443.sh";
|
||||
private bool _stop;
|
||||
|
||||
public ContentFilter(ConcurrentQueue<QueueItem> queue, DbHandler dbHandler)
|
||||
{
|
||||
_queue = queue;
|
||||
_dbHandler = dbHandler;
|
||||
}
|
||||
|
||||
public WaitHandle[] Start()
|
||||
{
|
||||
WaitHandle[] waitHandles = new WaitHandle[1];
|
||||
EventWaitHandle handle = new(false, EventResetMode.ManualReset);
|
||||
waitHandles[0] = handle;
|
||||
Thread f = new (Filter!);
|
||||
f.Start(handle);
|
||||
|
||||
return waitHandles;
|
||||
}
|
||||
|
||||
private void Filter(object obj)
|
||||
{
|
||||
long indexes = DbHandler.GetUnfilteredIndexes();
|
||||
|
||||
for (long i = 0; i < indexes; i++)
|
||||
{
|
||||
if (_stop) break;
|
||||
|
||||
Unfiltered? unfiltered = DbHandler.ReadUnfilteredWithId(i);
|
||||
|
||||
if (unfiltered is null || unfiltered.Filtered == 1) continue;
|
||||
|
||||
unfiltered.Filtered = 1;
|
||||
|
||||
QueueItem superUnfilteredObject = new()
|
||||
{
|
||||
Unfiltered = unfiltered,
|
||||
Operations = Operations.Update
|
||||
};
|
||||
|
||||
_queue.Enqueue(superUnfilteredObject);
|
||||
|
||||
Filtered filtered = GetSiteData(unfiltered.Ip);
|
||||
|
||||
filtered.Port1 = unfiltered.Port1;
|
||||
filtered.Port2 = unfiltered.Port2;
|
||||
|
||||
QueueItem superFilteredObject = new()
|
||||
{
|
||||
Filtered = filtered,
|
||||
Operations = Operations.Insert
|
||||
};
|
||||
|
||||
_queue.Enqueue(superFilteredObject);
|
||||
}
|
||||
|
||||
((EventWaitHandle) obj).Set();
|
||||
}
|
||||
|
||||
private static Filtered GetSiteData(string ip)
|
||||
{
|
||||
StartProcess(ip, 80);
|
||||
StartProcess(ip, 443);
|
||||
|
||||
string url1 = "";
|
||||
string url2 = "";
|
||||
string title1 = "";
|
||||
string title2 = "";
|
||||
string description1 = "";
|
||||
string description2 = "";
|
||||
bool robotsTxt1 = false;
|
||||
bool robotsTxt2 = false;
|
||||
string serverType1 = "";
|
||||
string serverType2 = "";
|
||||
string httpVersion1 = "";
|
||||
string httpVersion2 = "";
|
||||
string alpn = "";
|
||||
string certificateIssuerCountry = "";
|
||||
string certificateOrganizationName = "";
|
||||
string ipV6 = "";
|
||||
string tlsVersion = "";
|
||||
string cipherSuite = "";
|
||||
string keyExchangeAlgorithm = "";
|
||||
string publicKeyType1 = "";
|
||||
string publicKeyType2 = "";
|
||||
string publicKeyType3 = "";
|
||||
string acceptEncoding1 = "";
|
||||
string acceptEncoding2 = "";
|
||||
string connection1 = "";
|
||||
string connection2 = "";
|
||||
|
||||
int[] ports = [80, 443];
|
||||
|
||||
for (int i = 0; i < ports.Length; i++)
|
||||
{
|
||||
using StreamReader streamReader = new($"{ports[i]}Header.txt");
|
||||
|
||||
while (streamReader.Peek() != -1)
|
||||
{
|
||||
string? line = streamReader.ReadLine();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(line)) continue;
|
||||
|
||||
if (ports[i] == 80 && string.IsNullOrWhiteSpace(url1)) { FilterHelper.GetDomain(line, out url1); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(url2)) { FilterHelper.GetDomain(line, out url2); }
|
||||
if (ports[i] == 80 && string.IsNullOrWhiteSpace(serverType1)) { FilterHelper.GetServerType(line, out serverType1); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(serverType2)) { FilterHelper.GetServerType(line, out serverType2); }
|
||||
if (ports[i] == 80 && string.IsNullOrWhiteSpace(httpVersion1)) { FilterHelper.GetHttpVersion(line, out httpVersion1); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(httpVersion2)) { FilterHelper.GetHttpVersion(line, out httpVersion2); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(alpn)) { FilterHelper.GetALPN(line, out alpn); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(certificateIssuerCountry)) { FilterHelper.GetCertificateIssuerCountry(line, out certificateIssuerCountry); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(certificateOrganizationName)) { FilterHelper.GetCertificateOrganizationName(line, out certificateOrganizationName); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(ipV6)) { FilterHelper.GetIpV6(line, out ipV6); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(tlsVersion)) { FilterHelper.GetTlsVersion(line, out tlsVersion); }
|
||||
if (ports[i] == 80 && string.IsNullOrWhiteSpace(connection1)) { FilterHelper.GetConnection(line, out connection1); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(connection2)) { FilterHelper.GetConnection(line, out connection2); }
|
||||
if (ports[i] == 80 && string.IsNullOrWhiteSpace(acceptEncoding1)) { FilterHelper.GetEncoding(line, out acceptEncoding1); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(acceptEncoding2)) { FilterHelper.GetEncoding(line, out acceptEncoding2); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(publicKeyType1)) { FilterHelper.GetPublicKeyType(line, out publicKeyType1, "Certificate level 0: Public key type "); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(publicKeyType2)) { FilterHelper.GetPublicKeyType(line, out publicKeyType2, "Certificate level 1: Public key type "); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(publicKeyType3)) { FilterHelper.GetPublicKeyType(line, out publicKeyType3, "Certificate level 2: Public key type "); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(cipherSuite)) { FilterHelper.GetCipherSuite(line, out cipherSuite); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(keyExchangeAlgorithm)) { FilterHelper.GetKeyExchangeAlgorithm(line, out keyExchangeAlgorithm); }
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ports.Length; i++)
|
||||
{
|
||||
string? html;
|
||||
|
||||
if (ports[i] == 80)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url1)) continue;
|
||||
|
||||
html = Task.Run(() => HttpClientHelper.GetHtml(url1, 80).Result).Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url2)) continue;
|
||||
|
||||
html = Task.Run(() => HttpClientHelper.GetHtml(url2, 443).Result).Result;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(html)) continue;
|
||||
|
||||
if (ports[i] == 80 && string.IsNullOrWhiteSpace(title1)) { FilterHelper.GetTitle(html, out title1); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(title2)) { FilterHelper.GetTitle(html ,out title2); }
|
||||
if (ports[i] == 80 && string.IsNullOrWhiteSpace(description1)) { FilterHelper.GetDescription(html, out description1); }
|
||||
if (ports[i] == 443 && string.IsNullOrWhiteSpace(description2)) { FilterHelper.GetDescription(html, out description2); }
|
||||
if (ports[i] == 80 && !robotsTxt1) { robotsTxt1 = Task.Run(() => HttpClientHelper.HasRobotsTxt(url1, 80).Result).Result; }
|
||||
if (ports[i] == 443 && !robotsTxt2) { robotsTxt2 = Task.Run(() => HttpClientHelper.HasRobotsTxt(url2, 443).Result).Result; }
|
||||
}
|
||||
|
||||
Filtered siteData = new()
|
||||
{
|
||||
Ip = ip,
|
||||
Url1 = url1,
|
||||
Url2 = url2,
|
||||
Title1 = title1,
|
||||
Title2 = title2,
|
||||
Description1 = description1,
|
||||
Description2 = description2,
|
||||
ServerType1 = serverType1,
|
||||
ServerType2 = serverType2,
|
||||
RobotsTXT1 = robotsTxt1,
|
||||
RobotsTXT2 = robotsTxt2,
|
||||
HttpVersion1 = httpVersion1,
|
||||
HttpVersion2 = httpVersion2,
|
||||
ALPN = alpn,
|
||||
CertificateIssuerCountry = certificateIssuerCountry,
|
||||
CertificateOrganizationName = certificateOrganizationName,
|
||||
IpV6 = ipV6,
|
||||
TlsVersion = tlsVersion,
|
||||
CipherSuite = cipherSuite,
|
||||
KeyExchangeAlgorithm = keyExchangeAlgorithm,
|
||||
PublicKeyType1 = publicKeyType1,
|
||||
PublicKeyType2 = publicKeyType2,
|
||||
PublicKeyType3 = publicKeyType3,
|
||||
AcceptEncoding1 = acceptEncoding1,
|
||||
AcceptEncoding2 = acceptEncoding2,
|
||||
Connection1 = connection1,
|
||||
Connection2 = connection2,
|
||||
};
|
||||
|
||||
return siteData;
|
||||
}
|
||||
|
||||
private static void StartProcess(string ip, int port)
|
||||
{
|
||||
string fileName = port == 80 ? GetDomainPort80 : GetDomainPort443;
|
||||
|
||||
Process proc = new();
|
||||
proc.StartInfo = new()
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = $"{ip}",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = false,
|
||||
RedirectStandardError = false,
|
||||
RedirectStandardInput = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
proc.Start();
|
||||
proc.WaitForExit();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
proc.Close();
|
||||
proc.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_stop = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using Backend.Helper;
|
||||
using Models.Handler;
|
||||
using Models.Model.Backend;
|
||||
|
||||
namespace Backend.Handler;
|
||||
|
||||
public class ScanSettings
|
||||
{
|
||||
public int Start;
|
||||
public int End;
|
||||
public int ThreadNumber;
|
||||
public EventWaitHandle? Handle;
|
||||
}
|
||||
|
||||
public class IpScanner
|
||||
{
|
||||
private readonly ConcurrentQueue<QueueItem> _queue;
|
||||
private readonly ConcurrentQueue<Discarded> _discardedQueue;
|
||||
private readonly DbHandler _dbHandler;
|
||||
private bool _stop;
|
||||
|
||||
public IpScanner(ConcurrentQueue<QueueItem> queue, DbHandler dbHandler, ConcurrentQueue<Discarded> discardedQueue)
|
||||
{
|
||||
_queue = queue;
|
||||
_dbHandler = dbHandler;
|
||||
_discardedQueue = discardedQueue;
|
||||
}
|
||||
|
||||
public WaitHandle[] Start(int threads)
|
||||
{
|
||||
int threadsAmount = 0;
|
||||
if (threads % 2 == 0)
|
||||
{
|
||||
threadsAmount = 256 / threads;
|
||||
}
|
||||
|
||||
WaitHandle[] waitHandles = new WaitHandle[threads];
|
||||
|
||||
for (int i = 0; i < threads; i++)
|
||||
{
|
||||
EventWaitHandle handle = new(false, EventResetMode.ManualReset);
|
||||
|
||||
ScanSettings scanSettings = new()
|
||||
{
|
||||
Start = threadsAmount * i,
|
||||
End = threadsAmount * i + threadsAmount,
|
||||
ThreadNumber = i,
|
||||
Handle = handle
|
||||
};
|
||||
|
||||
waitHandles[i] = handle;
|
||||
|
||||
Thread f = new (Scan!);
|
||||
f.Start(scanSettings);
|
||||
|
||||
Console.WriteLine($"Scanner thread ({i}) started");
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
return waitHandles;
|
||||
}
|
||||
|
||||
private void Scan(object obj)
|
||||
{
|
||||
ScanSettings scanSettings = (ScanSettings)obj;
|
||||
|
||||
ScannerResumeObject resumeObject = new();
|
||||
resumeObject.ThreadNumber = scanSettings.ThreadNumber;
|
||||
resumeObject.StartRange = scanSettings.Start;
|
||||
resumeObject.EndRange = scanSettings.End;
|
||||
|
||||
ScannerResumeObject? resumeNow = _dbHandler.GetResumeObject(scanSettings.ThreadNumber);
|
||||
|
||||
int secondByte = 0;
|
||||
int thirdByte = 0;
|
||||
int fourthByte = 0;
|
||||
|
||||
if (resumeNow is not null)
|
||||
{
|
||||
scanSettings.Start = resumeNow.FirstByte;
|
||||
scanSettings.End = resumeNow.EndRange;
|
||||
secondByte = resumeNow.SecondByte;
|
||||
thirdByte = resumeNow.ThirdByte;
|
||||
fourthByte = resumeNow.FourthByte;
|
||||
}
|
||||
|
||||
byte[] buf = [];
|
||||
using Ping ping = new();
|
||||
|
||||
for (int i = scanSettings.Start; i < scanSettings.End; i++)
|
||||
{
|
||||
if (i is 0 or 10 or 127 or 256) continue;
|
||||
if (i is >= 224 and <= 239) continue;
|
||||
|
||||
for (int j = secondByte; j < 256; j++)
|
||||
{
|
||||
if (i == 169 && j == 254) continue;
|
||||
if (i == 192 && j == 168) continue;
|
||||
if (i == 198 && j == 18 || j == 19) continue;
|
||||
if (i == 172 && j is >= 16 and <= 31) continue;
|
||||
|
||||
for (int k = thirdByte; k < 256; k++)
|
||||
{
|
||||
if (i == 192 && k == 2) continue;
|
||||
if (i == 192 && j == 88 && k == 99) continue;
|
||||
|
||||
if (_discardedQueue.Count >= 2000)
|
||||
{
|
||||
Console.WriteLine("loooooooooooooooooooooooooooool");
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
for (int l = fourthByte; l < 256; l++)
|
||||
{
|
||||
if (_stop)
|
||||
{
|
||||
resumeObject.FourthByte = l;
|
||||
break;
|
||||
}
|
||||
|
||||
string ip = $"{i}.{j}.{k}.{l}";
|
||||
|
||||
IPStatus responseCode = IPStatus.Unknown;
|
||||
|
||||
try
|
||||
{
|
||||
// Sometimes, if the pinger gets a Destination Unreachable Communication administratively prohibited response, the pinger will throw an exception.
|
||||
// https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol?useskin=vector#Control_messages
|
||||
_ = IPAddress.TryParse(ip, out IPAddress? address);
|
||||
if (address is not null)
|
||||
{
|
||||
responseCode = ping.Send(address, 512, buf, null).Status;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
|
||||
if (responseCode != IPStatus.Success)
|
||||
{
|
||||
_discardedQueue.Enqueue(CreateDiscardedQueueItem(ip, (int)responseCode));
|
||||
continue;
|
||||
}
|
||||
|
||||
(int, int) ports = TcpClientHelper.CheckPort(ip, 80, 443);
|
||||
|
||||
if (ports is { Item1: 0, Item2: 0 })
|
||||
{
|
||||
_discardedQueue.Enqueue(CreateDiscardedQueueItem(ip, (int)responseCode));
|
||||
continue;
|
||||
}
|
||||
|
||||
_queue.Enqueue(CreateUnfilteredQueueItem(ip, (int)responseCode, ports));
|
||||
}
|
||||
|
||||
if (_stop)
|
||||
{
|
||||
resumeObject.ThirdByte = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_stop)
|
||||
{
|
||||
resumeObject.SecondByte = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_stop)
|
||||
{
|
||||
resumeObject.FirstByte = i;
|
||||
break;
|
||||
}
|
||||
//Console.WriteLine($"Thread ({scanSettings.ThreadNumber}) is at index ({i}) out of ({scanSettings.End}). Remaining ({scanSettings.End - i})");
|
||||
}
|
||||
|
||||
QueueItem resume = new()
|
||||
{
|
||||
ResumeObject = resumeObject,
|
||||
Operations = Operations.Insert
|
||||
};
|
||||
|
||||
_queue.Enqueue(resume);
|
||||
|
||||
scanSettings.Handle!.Set();
|
||||
}
|
||||
|
||||
private static Discarded CreateDiscardedQueueItem(string ip, int responseCode)
|
||||
{
|
||||
Discarded discarded = new()
|
||||
{
|
||||
Ip = ip,
|
||||
ResponseCode = responseCode
|
||||
};
|
||||
|
||||
return discarded;
|
||||
}
|
||||
|
||||
private static QueueItem CreateUnfilteredQueueItem(string ip, int responseCode, (int, int) ports)
|
||||
{
|
||||
Unfiltered unfiltered = new()
|
||||
{
|
||||
Ip = ip,
|
||||
ResponseCode = responseCode,
|
||||
Port1 = ports.Item1,
|
||||
Port2 = ports.Item2,
|
||||
Filtered = 0
|
||||
};
|
||||
|
||||
QueueItem superUnfilteredObject = new()
|
||||
{
|
||||
Unfiltered = unfiltered,
|
||||
Operations = Operations.Insert
|
||||
};
|
||||
|
||||
return superUnfilteredObject;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_stop = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Models.Handler;
|
||||
using Models.Model.Backend;
|
||||
|
||||
namespace Backend.Handler;
|
||||
|
||||
public class ThreadHandler
|
||||
{
|
||||
private readonly DbHandler _dbHandler;
|
||||
private readonly Communication _communication;
|
||||
private readonly IpScanner _ipScanner;
|
||||
private readonly ContentFilter _contentFilter;
|
||||
|
||||
private bool _communicationStopped;
|
||||
private bool _ipScannerStopped;
|
||||
private bool _contentFilterStopped;
|
||||
private bool _stopSignal;
|
||||
|
||||
public ThreadHandler()
|
||||
{
|
||||
ConcurrentQueue<QueueItem> contentQueue = new();
|
||||
ConcurrentQueue<Discarded> discardedQueue = new();
|
||||
|
||||
_dbHandler = new(contentQueue, discardedQueue);
|
||||
_communication = new(_dbHandler, this);
|
||||
_ipScanner = new(contentQueue, _dbHandler, discardedQueue);
|
||||
_contentFilter = new(contentQueue, _dbHandler);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
//Thread scanner = new(StartScanner);
|
||||
//Thread indexer = new(StartIndexer);
|
||||
Thread database = new(StartDbHandler);
|
||||
Thread discarded = new(StartDiscardedDbHandler);
|
||||
Thread communication = new(StartCommunicationHandler);
|
||||
|
||||
//scanner.Start();
|
||||
//indexer.Start();
|
||||
database.Start();
|
||||
discarded.Start();
|
||||
communication.Start();
|
||||
|
||||
//scanner.Join();
|
||||
//indexer.Join();
|
||||
database.Join();
|
||||
discarded.Join();
|
||||
communication.Join();
|
||||
}
|
||||
|
||||
public static void ManualGc()
|
||||
{
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
private void StartScanner()
|
||||
{
|
||||
Thread.Sleep(10000); // Let the database handler instantiate and warm up first.
|
||||
|
||||
WaitHandle[] wait = _ipScanner.Start(4);
|
||||
|
||||
WaitHandle.WaitAll(wait);
|
||||
|
||||
Console.WriteLine("Scanner finished");
|
||||
|
||||
_ipScannerStopped = true;
|
||||
}
|
||||
|
||||
private void StartIndexer()
|
||||
{
|
||||
while (!_stopSignal)
|
||||
{
|
||||
WaitHandle[] wait = _contentFilter.Start();
|
||||
|
||||
WaitHandle.WaitAll(wait);
|
||||
|
||||
Thread.Sleep(300000); // 5 minutes
|
||||
}
|
||||
|
||||
Console.WriteLine("Indexer finished");
|
||||
|
||||
_contentFilterStopped = true;
|
||||
}
|
||||
|
||||
private void StartDbHandler()
|
||||
{
|
||||
_dbHandler.StartContent();
|
||||
}
|
||||
|
||||
private void StartDiscardedDbHandler()
|
||||
{
|
||||
WaitHandle[] wait = _dbHandler.Start(2);
|
||||
|
||||
WaitHandle.WaitAll(wait);
|
||||
|
||||
Console.WriteLine("Discarded DbHandler finished");
|
||||
}
|
||||
|
||||
private void StartCommunicationHandler()
|
||||
{
|
||||
WaitHandle[] wait = _communication.Start();
|
||||
|
||||
WaitHandle.WaitAll(wait);
|
||||
|
||||
Console.WriteLine("Communicator finished");
|
||||
|
||||
_communicationStopped = true;
|
||||
}
|
||||
|
||||
private void StopCommunicator()
|
||||
{
|
||||
Thread t = new(_communication.Stop);
|
||||
t.Start();
|
||||
t.Join();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_stopSignal = true;
|
||||
_ipScanner.Stop();
|
||||
_contentFilter.Stop();
|
||||
StopCommunicator();
|
||||
|
||||
bool stopping = true;
|
||||
|
||||
while (stopping)
|
||||
{
|
||||
if (_communicationStopped && _ipScannerStopped && _contentFilterStopped)
|
||||
{
|
||||
_dbHandler.Stop();
|
||||
stopping = false;
|
||||
}
|
||||
|
||||
Thread.Sleep(3000);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user