EonaCat.DnsTester/EonaCat.DnsTester/MainForm.cs

450 lines
16 KiB
C#
Raw Normal View History

2023-02-09 11:47:51 +01:00
using System;
2023-02-24 00:08:31 +01:00
using System.Collections.Generic;
2023-02-09 11:47:51 +01:00
using System.Data;
2023-03-01 21:15:40 +01:00
using System.Globalization;
2023-02-09 11:47:51 +01:00
using System.IO;
2023-02-13 19:49:03 +01:00
using System.Linq;
2023-02-09 11:47:51 +01:00
using System.Net;
using System.Net.Sockets;
2023-02-13 19:08:20 +01:00
using System.Threading.Tasks;
2023-02-09 11:47:51 +01:00
using System.Windows.Forms;
2023-02-24 13:25:01 +01:00
using EonaCat.DnsTester.Helpers;
2023-02-09 11:47:51 +01:00
namespace EonaCat.DnsTester
{
2023-02-24 13:25:01 +01:00
public partial class MainForm : Form
2023-02-09 11:47:51 +01:00
{
2023-03-01 21:15:40 +01:00
private bool _useCustomDnsServers;
2023-02-24 13:25:01 +01:00
private string _dnsServer1, _dnsServer2;
2023-02-27 22:15:41 +01:00
private DnsRecordType _recordType;
2023-02-24 13:25:01 +01:00
private int _dnsTotalChecked;
2023-02-09 11:47:51 +01:00
2023-02-13 19:08:20 +01:00
public bool IsRunning { get; private set; }
2023-02-09 11:47:51 +01:00
public MainForm()
{
InitializeComponent();
}
2023-02-27 22:15:41 +01:00
private async void RunTest_Click(object sender, EventArgs e)
2023-02-09 11:47:51 +01:00
{
2023-03-01 21:15:40 +01:00
if (!_useCustomDnsServers)
{
if (!chkDns1.Checked && !chkDns2.Checked)
{
MessageBox.Show("Please enable DNS 1 or 2 before starting");
return;
}
}
2023-03-02 19:06:28 +01:00
if (_useCustomDnsServers && (!chkDns1.Checked && !chkDns2.Checked))
2023-03-01 21:15:40 +01:00
{
MessageBox.Show("Please enable DNS 1 or 2 before using custom Dns");
return;
}
2023-02-27 22:15:41 +01:00
SetupView();
2023-07-19 16:35:30 +02:00
var numThreads = (int)numericUpDown2.Value; // number of concurrent threads to use
var maxUrls = (int)numericUpDown1.Value; // maximum number of unique URLs to retrieve
var numUrlsPerThread = maxUrls / numThreads;
2023-03-02 19:06:28 +01:00
if (numUrlsPerThread == 0)
{
numUrlsPerThread = maxUrls;
numThreads = 1;
}
2023-03-02 15:27:51 +01:00
2023-03-03 10:40:01 +01:00
SetSearchEngines();
2023-07-19 17:15:22 +02:00
var urls = await UrlHelper.RetrieveUrlsAsync(numThreads, numUrlsPerThread).ConfigureAwait(false);
2023-02-27 22:15:41 +01:00
AddUrlToView(urls);
2023-02-24 13:25:01 +01:00
IsRunning = true;
2023-07-19 17:15:22 +02:00
RunTest.Invoke(() => { RunTest.Enabled = false; });
2023-07-19 16:35:30 +02:00
await ProcessAsync(_recordType, urls.ToArray(), _dnsServer1, _dnsServer2).ConfigureAwait(false);
2023-02-24 13:25:01 +01:00
IsRunning = false;
2023-07-19 17:15:22 +02:00
RunTest.Invoke(() => { RunTest.Enabled = true; });
2023-02-24 13:25:01 +01:00
}
2023-02-09 11:47:51 +01:00
2023-03-03 10:40:01 +01:00
private void SetSearchEngines()
{
UrlHelper.UseSearchEngineYahoo = checkBox1.Checked;
UrlHelper.UseSearchEngineBing = checkBox2.Checked;
UrlHelper.UseSearchEngineGoogle = checkBox3.Checked;
UrlHelper.UseSearchEngineQwant = checkBox8.Checked;
UrlHelper.UseSearchEngineWolfram = checkBox5.Checked;
UrlHelper.UseSearchEngineStartPage = checkBox6.Checked;
UrlHelper.UseSearchEngineYandex = checkBox7.Checked;
}
2023-02-27 22:15:41 +01:00
private void SetupView()
2023-02-24 13:25:01 +01:00
{
2023-03-01 21:15:40 +01:00
if (_useCustomDnsServers)
2023-02-09 11:47:51 +01:00
{
2023-02-24 13:25:01 +01:00
_dnsTotalChecked = 0;
if (chkDns1.Checked)
{
_dnsTotalChecked++;
_dnsServer1 = CustomDns1.Text;
}
if (chkDns2.Checked)
{
_dnsTotalChecked++;
_dnsServer2 = CustomDns2.Text;
}
2023-02-09 11:47:51 +01:00
}
else
{
2023-02-24 13:25:01 +01:00
_dnsTotalChecked = 0;
if (chkDns1.Checked)
{
_dnsTotalChecked++;
_dnsServer1 = dnsList1.SelectedValue.ToString();
}
2023-02-13 19:08:20 +01:00
2023-02-24 13:25:01 +01:00
if (chkDns2.Checked)
{
_dnsTotalChecked++;
_dnsServer2 = dnsList2.SelectedValue.ToString();
}
2023-02-09 11:47:51 +01:00
}
2023-02-24 13:25:01 +01:00
ResultView.Items.Clear();
ResultView.Update();
Application.DoEvents();
2023-02-13 19:08:20 +01:00
2023-02-27 22:15:41 +01:00
UrlHelper.Log -= UrlHelper_Log;
2023-02-24 13:25:01 +01:00
UrlHelper.Log += UrlHelper_Log;
}
private void UrlHelper_Log(object sender, string e)
{
SetStatus(e);
}
private void AddUrlToView(List<string> urls)
{
2023-07-19 16:35:30 +02:00
ResultView.Invoke(() =>
2023-02-24 13:25:01 +01:00
{
2023-07-19 16:35:30 +02:00
foreach (var currentUrl in urls)
{
var listUrl = new ListViewItem(currentUrl);
listUrl.SubItems.Add(" ");
listUrl.SubItems.Add(" ");
listUrl.SubItems.Add(" ");
listUrl.SubItems.Add(" ");
2023-02-24 13:25:01 +01:00
2023-07-19 16:35:30 +02:00
ResultView.Items.Add(listUrl);
}
2023-02-24 13:25:01 +01:00
2023-07-19 16:35:30 +02:00
if (ResultView.Items.Count > 1)
{
ResultView.EnsureVisible(ResultView.Items.Count - 1);
}
2023-02-24 13:25:01 +01:00
2023-07-19 16:35:30 +02:00
ResultView.Update();
});
2023-02-24 13:25:01 +01:00
Application.DoEvents();
}
2023-02-09 11:47:51 +01:00
2023-02-24 13:25:01 +01:00
private void TesterUI_Load(object sender, EventArgs e)
2023-02-09 11:47:51 +01:00
{
2023-02-24 13:25:01 +01:00
PopulateDnsLists();
2023-02-09 11:47:51 +01:00
}
2023-02-24 13:25:01 +01:00
private void PopulateDnsLists()
2023-02-09 11:47:51 +01:00
{
2023-02-24 13:25:01 +01:00
dnsList1.ValueMember = "ip";
dnsList1.DisplayMember = "name";
2023-02-09 11:47:51 +01:00
2023-02-24 13:25:01 +01:00
dnsList2.ValueMember = "ip";
dnsList2.DisplayMember = "name";
2023-02-09 11:47:51 +01:00
2023-02-24 13:25:01 +01:00
var serverList = Path.Combine(Application.StartupPath, "Servers.xml");
2023-07-19 16:35:30 +02:00
var servers1 = new DataSet();
var servers2 = new DataSet();
2023-02-24 13:25:01 +01:00
servers1.ReadXml(serverList);
servers2.ReadXml(serverList);
2023-02-09 11:47:51 +01:00
2023-07-19 16:35:30 +02:00
var dataTable1 = servers1.Tables[0];
var dataTable2 = servers2.Tables[0];
2023-02-24 13:25:01 +01:00
dnsList1.DataSource = dataTable1;
dnsList2.DataSource = dataTable2;
2023-02-09 11:47:51 +01:00
}
private void UseCustomServers_CheckedChanged(object sender, EventArgs e)
{
2023-03-01 21:15:40 +01:00
_useCustomDnsServers = UseCustomServers.Checked;
2023-02-09 11:47:51 +01:00
SetUI();
}
private void SetUI()
{
2023-03-01 21:15:40 +01:00
dnsList1.Enabled = !_useCustomDnsServers && chkDns1.Checked;
dnsList2.Enabled = !_useCustomDnsServers && chkDns2.Checked;
2023-02-09 11:47:51 +01:00
2023-03-01 21:15:40 +01:00
CustomDns1.Enabled = _useCustomDnsServers && chkDns1.Checked;
CustomDns2.Enabled = _useCustomDnsServers && chkDns2.Checked;
2023-02-09 11:47:51 +01:00
2023-03-01 21:15:40 +01:00
CustomDns1.Visible = _useCustomDnsServers && chkDns1.Checked;
CustomDns2.Visible = _useCustomDnsServers && chkDns2.Checked;
lblCustom1.Visible = _useCustomDnsServers && chkDns1.Checked;
lblCustom2.Visible = _useCustomDnsServers && chkDns2.Checked;
2023-02-09 11:47:51 +01:00
}
2023-07-19 16:35:30 +02:00
private async Task ProcessAsync(DnsRecordType recordType, string[] urls, string dnsAddress1, string dnsAddress2)
2023-02-24 13:25:01 +01:00
{
2023-02-27 22:15:41 +01:00
if (recordType == 0)
{
recordType = DnsRecordType.A;
}
2023-07-19 16:35:30 +02:00
var urlsTotal = urls.Length;
2023-02-27 22:15:41 +01:00
const string dnsId1 = "Dns1";
const string dnsId2 = "Dns2";
DnsHelper.OnLog -= DnsHelper_OnLog;
DnsHelper.OnLog += DnsHelper_OnLog;
2023-07-19 16:35:30 +02:00
for (var i = 0; i < urlsTotal; i++)
2023-02-24 00:08:31 +01:00
{
2023-03-02 16:05:30 +01:00
var currentUrl = urls[i];
2023-07-19 16:35:30 +02:00
await ExecuteDns1Async(recordType, dnsAddress1, currentUrl, dnsId1, i).ConfigureAwait(false);
2023-03-02 19:20:08 +01:00
if (chkDns2.Checked)
{
2023-07-19 16:35:30 +02:00
await ExecuteDns2Async(recordType, dnsAddress2, currentUrl, dnsId2, i).ConfigureAwait(false);
2023-03-02 19:20:08 +01:00
}
2023-07-19 16:35:30 +02:00
await Task.Delay(100).ConfigureAwait(false);
2023-02-24 13:25:01 +01:00
}
2023-02-27 22:15:41 +01:00
}
2023-02-24 00:08:31 +01:00
2023-07-19 16:35:30 +02:00
private async Task ExecuteDns2Async(DnsRecordType recordType, string dnsAddress2, string currentUrl, string dnsId2,
2023-02-27 22:15:41 +01:00
int i)
{
2023-02-24 13:25:01 +01:00
try
{
2023-02-27 22:15:41 +01:00
DnsResponse response2 = null;
2023-07-19 16:35:30 +02:00
var queryBytes2 = DnsHelper.CreateDnsQueryPacket(currentUrl, recordType);
response2 = await DnsHelper.SendDnsQueryPacketAsync(dnsId2, dnsAddress2, 53, queryBytes2).ConfigureAwait(false);
2023-02-27 22:15:41 +01:00
ProcessResponse(response2);
2023-02-24 13:25:01 +01:00
}
catch (SocketException socketException)
{
SetStatus(
2023-07-19 16:35:30 +02:00
Convert.ToString(socketException)!.IndexOf("time", StringComparison.Ordinal) > 0
2023-02-27 22:15:41 +01:00
? $"DNS1 Timeout - No response received for {Convert.ToString(DnsHelper.DnsReceiveTimeout / 1000)} seconds"
2023-02-24 13:25:01 +01:00
: Convert.ToString(socketException));
}
2023-02-27 22:15:41 +01:00
catch (Exception exception)
{
SetStatus(exception.Message);
i--;
}
}
2023-07-19 16:35:30 +02:00
private async Task ExecuteDns1Async(DnsRecordType recordType, string dnsAddress1, string currentUrl, string dnsId1,
2023-02-27 22:15:41 +01:00
int i)
{
if (chkDns1.Checked)
2023-02-24 13:25:01 +01:00
{
2023-02-27 22:15:41 +01:00
try
{
DnsResponse response1 = null;
2023-07-19 16:35:30 +02:00
var queryBytes1 = DnsHelper.CreateDnsQueryPacket(currentUrl, recordType);
response1 = await DnsHelper.SendDnsQueryPacketAsync(dnsId1, dnsAddress1, 53, queryBytes1).ConfigureAwait(false);
2023-02-27 22:15:41 +01:00
ProcessResponse(response1);
}
catch (SocketException socketException)
{
SetStatus(
2023-07-19 16:35:30 +02:00
Convert.ToString(socketException)!.IndexOf("time", StringComparison.Ordinal) > 0
2023-02-27 22:15:41 +01:00
? $"DNS1 Timeout - No response received for {Convert.ToString(DnsHelper.DnsReceiveTimeout / 1000)} seconds"
: Convert.ToString(socketException));
}
catch (Exception exception)
{
SetStatus(exception.Message);
i--;
}
2023-02-24 13:25:01 +01:00
}
}
2023-02-24 00:08:31 +01:00
2023-02-27 22:15:41 +01:00
private void DnsHelper_OnLog(object sender, string e)
2023-02-24 13:25:01 +01:00
{
SetStatus(e);
}
2023-02-24 00:08:31 +01:00
2023-02-27 22:15:41 +01:00
private void ProcessResponse(DnsResponse dnsResponse)
2023-02-24 13:25:01 +01:00
{
2023-07-19 16:35:30 +02:00
if (dnsResponse == null || dnsResponse?.Answers == null || !dnsResponse.Answers.Any())
2023-02-24 13:25:01 +01:00
{
2023-02-27 22:15:41 +01:00
return;
2023-02-24 13:25:01 +01:00
}
2023-02-24 00:08:31 +01:00
2023-02-27 22:15:41 +01:00
// Retrieve stopTime
var stopTime = DateTime.Now.Ticks;
2023-03-01 21:15:40 +01:00
var deltaTime = Convert.ToString((double)(stopTime - dnsResponse.StartTime) / 10000000, CultureInfo.InvariantCulture);
2023-02-27 22:15:41 +01:00
2023-03-02 10:02:06 +01:00
foreach (var answer in dnsResponse.Answers)
{
SetStatus(
$"ResourceRecord: Name: {answer.Name} : Type : {answer.Type} : Data : {answer.Data}");
}
2023-03-02 15:27:51 +01:00
ResultView.Invoke(() =>
2023-02-24 13:25:01 +01:00
{
2023-07-19 16:35:30 +02:00
for (var i = 0; i < ResultView.Items.Count; i++)
2023-02-27 22:15:41 +01:00
{
2023-03-02 15:27:51 +01:00
foreach (var answer in dnsResponse.Answers)
2023-03-02 10:02:06 +01:00
{
2023-03-02 15:27:51 +01:00
if (ResultView.Items[i].Text != $"{answer.Name.TrimEnd('.')}")
continue;
string sDeltaTime;
switch (dnsResponse.DnsId)
{
case "Dns1":
ResultView.Items[i].SubItems[1].Text =
2023-07-19 16:35:30 +02:00
Convert.ToString(answer.Data) ?? string.Empty;
2023-03-02 15:27:51 +01:00
sDeltaTime = Convert.ToString(deltaTime);
ResultView.Items[i].SubItems[2].Text =
sDeltaTime.Length > 5 ? sDeltaTime.Substring(0, 5) : sDeltaTime;
ResultView.Items[i].ForeColor = System.Drawing.Color.Red;
ResultView.EnsureVisible(i);
ResultView.Update();
Application.DoEvents();
ResultView.Items[i].ForeColor = System.Drawing.Color.Black;
break;
case "Dns2":
ResultView.Items[i].SubItems[3].Text =
2023-07-19 16:35:30 +02:00
Convert.ToString(answer.Data) ?? string.Empty;
2023-03-02 15:27:51 +01:00
sDeltaTime = Convert.ToString(deltaTime);
ResultView.Items[i].SubItems[4].Text =
sDeltaTime.Length > 5 ? sDeltaTime.Substring(0, 5) : sDeltaTime;
ResultView.Items[i].ForeColor = System.Drawing.Color.Red;
ResultView.EnsureVisible(i);
ResultView.Update();
Application.DoEvents();
ResultView.Items[i].ForeColor = System.Drawing.Color.Black;
break;
}
2023-03-02 10:02:06 +01:00
}
2023-02-27 22:15:41 +01:00
}
2023-03-02 15:27:51 +01:00
});
2023-02-24 00:08:31 +01:00
}
2023-02-09 11:47:51 +01:00
2023-02-24 13:25:01 +01:00
private async void btnResolveIP_Click(object sender, EventArgs e)
2023-02-24 00:08:31 +01:00
{
2023-02-24 13:25:01 +01:00
if (string.IsNullOrWhiteSpace(txtResolveIP.Text))
2023-02-24 00:08:31 +01:00
{
2023-02-24 13:25:01 +01:00
MessageBox.Show("Please enter an IP address to resolve");
return;
2023-02-24 00:08:31 +01:00
}
2023-02-09 11:47:51 +01:00
2023-07-19 16:35:30 +02:00
if (!IPAddress.TryParse(txtResolveIP.Text, out var iPAddress))
2023-02-24 13:25:01 +01:00
{
MessageBox.Show("Please enter a valid IP address");
return;
}
2023-02-09 11:47:51 +01:00
2023-07-19 16:35:30 +02:00
await Task.Run(() =>
{
try
{
var dnsEntry = Dns.GetHostEntry(iPAddress);
txtResolveHost.Invoke(() =>
{
txtResolveHost.Text = dnsEntry.HostName;
});
}
catch (Exception)
{
MessageBox.Show($"Could not get hostname for IP address '{txtResolveIP.Text}'");
}
}).ConfigureAwait(false);
2023-02-13 19:49:03 +01:00
}
private async void btnResolveHost_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(txtResolveHost.Text))
{
2023-03-01 21:15:40 +01:00
MessageBox.Show("Please enter a hostname to resolve");
2023-02-13 19:49:03 +01:00
return;
}
2023-03-01 21:15:40 +01:00
2023-07-19 16:35:30 +02:00
await Task.Run(() =>
2023-02-13 19:49:03 +01:00
{
2023-07-19 16:35:30 +02:00
try
2023-07-17 12:53:25 +02:00
{
2023-07-19 16:35:30 +02:00
var dnsEntry = Dns.GetHostEntry(txtResolveHost.Text);
txtResolveHost.Invoke(() =>
{
txtResolveIP.Text = dnsEntry.AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault().Address.ToString();
});
2023-03-01 21:15:40 +01:00
}
2023-07-19 16:35:30 +02:00
catch (Exception)
2023-03-01 21:15:40 +01:00
{
MessageBox.Show($"Could not get IP address for hostname '{txtResolveHost.Text}'");
}
2023-07-19 16:35:30 +02:00
}).ConfigureAwait(false);
2023-02-13 19:49:03 +01:00
}
2023-02-24 13:25:01 +01:00
private void SetStatus(string text)
{
2023-02-27 22:15:41 +01:00
StatusBox.Invoke(() =>
2023-02-24 13:25:01 +01:00
{
2023-07-19 16:35:30 +02:00
StatusBox.Items.Add($"{DateTime.Now} {text}");
2023-02-27 22:15:41 +01:00
StatusBox.TopIndex = StatusBox.Items.Count - 1;
if (StatusBox.Items.Count > STATUS_BAR_SIZE)
{
StatusBox.Items.RemoveAt(0);
}
2023-07-19 16:35:30 +02:00
StatusBox.Update();
2023-02-27 22:15:41 +01:00
});
2023-02-24 13:25:01 +01:00
}
2023-02-09 11:47:51 +01:00
2023-02-24 13:25:01 +01:00
const int STATUS_BAR_SIZE = 5000;
2023-02-27 22:15:41 +01:00
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (Enum.TryParse(comboBox1.SelectedItem.ToString().ToUpper(), out DnsRecordType queryType))
{
_recordType = queryType;
}
}
2023-03-01 21:15:40 +01:00
private void chkDns2_CheckedChanged(object sender, EventArgs e)
{
SetUI();
}
private void chkDns1_CheckedChanged(object sender, EventArgs e)
{
SetUI();
}
2023-03-02 19:33:00 +01:00
private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;
}
2023-03-03 10:40:01 +01:00
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
UrlHelper.UseSearchEngineYahoo = checkBox1.Checked;
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
UrlHelper.UseSearchEngineBing = checkBox2.Checked;
}
2023-02-24 13:25:01 +01:00
}
2023-02-09 11:47:51 +01:00
}