Updated UI

This commit is contained in:
EonaCat 2023-07-19 16:35:30 +02:00
parent 16c642dd20
commit 6ae0e0b779
7 changed files with 380 additions and 273 deletions

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
@ -11,12 +10,10 @@ namespace EonaCat.DnsTester.Helpers
class DnsHelper class DnsHelper
{ {
public static event EventHandler<string> OnLog; public static event EventHandler<string> OnLog;
public static async Task<DnsResponse> SendDnsQueryPacketAsync(string dnsId, string server, int port, byte[] queryBytes)
private static readonly Random random = new Random();
public static async Task<DnsResponse> SendDnsQueryPacket(string dnsId, string server, int port, byte[] queryBytes)
{ {
var stopwatch = System.Diagnostics.Stopwatch.StartNew(); // Start the clock
var startTime = DateTime.Now.Ticks;
var endPoint = new IPEndPoint(IPAddress.Parse(server), port); var endPoint = new IPEndPoint(IPAddress.Parse(server), port);
using (var client = new UdpClient(endPoint.AddressFamily)) using (var client = new UdpClient(endPoint.AddressFamily))
@ -25,68 +22,106 @@ namespace EonaCat.DnsTester.Helpers
client.EnableBroadcast = false; client.EnableBroadcast = false;
client.Client.SendTimeout = DnsSendTimeout; client.Client.SendTimeout = DnsSendTimeout;
client.Client.ReceiveTimeout = DnsReceiveTimeout; client.Client.ReceiveTimeout = DnsReceiveTimeout;
byte[] responseBytes = null;
byte[] responseBytes;
if (FakeResponse) if (FakeResponse)
{ {
responseBytes = GetExampleResponse(); responseBytes = DnsHelper.GetExampleResponse();
} }
else else
{ {
await client.SendAsync(queryBytes, queryBytes.Length, endPoint); await client.SendAsync(queryBytes, queryBytes.Length, endPoint).ConfigureAwait(false);
var responseResult = await client.ReceiveAsync(); var responseResult = await client.ReceiveAsync().ConfigureAwait(false);
responseBytes = responseResult.Buffer; responseBytes = responseResult.Buffer;
} }
var response = ParseDnsResponsePacket(dnsId, stopwatch.ElapsedTicks, server, responseBytes); var response = ParseDnsResponsePacket(dnsId, startTime, server, responseBytes);
return response; return response;
} }
} }
// For testing purposes // For testing purposes
public static bool FakeResponse { get; set; } public static bool FakeResponse { get; set; }
public static int DnsSendTimeout { get; set; } = 5; public static int DnsSendTimeout { get; set; } = 5;
public static int DnsReceiveTimeout { get; set; } = 5; public static int DnsReceiveTimeout { get; set; } = 5;
public static byte[] CreateDnsQueryPacket(string domainName, DnsRecordType recordType) public static byte[] CreateDnsQueryPacket(string domainName, DnsRecordType recordType)
{ {
var random = new Random();
// DNS header
var id = (ushort)random.Next(0, 65536); var id = (ushort)random.Next(0, 65536);
var flags = (ushort)0x0100; // recursion desired var flags = (ushort)0x0100; // recursion desired
var qdcount = (ushort)1; ushort qdcount = 1;
var ancount = (ushort)0; ushort ancount = 0;
var nscount = (ushort)0; ushort nscount = 0;
var arcount = (ushort)0; ushort arcount = 0;
var headerBytes = new byte[]
using (var stream = new MemoryStream())
using (var writer = new BinaryWriter(stream))
{ {
writer.Write(id); (byte)(id >> 8), (byte)(id & 0xff),
writer.Write(flags); (byte)(flags >> 8), (byte)(flags & 0xff),
writer.Write(qdcount); (byte)(qdcount >> 8), (byte)(qdcount & 0xff),
writer.Write(ancount); (byte)(ancount >> 8), (byte)(ancount & 0xff),
writer.Write(nscount); (byte)(nscount >> 8), (byte)(nscount & 0xff),
writer.Write(arcount); (byte)(arcount >> 8), (byte)(arcount & 0xff),
};
var labels = domainName.Split('.'); // DNS question
foreach (var label in labels) var labels = domainName.Split('.');
var qnameBytes = new byte[domainName.Length + 2];
var qnameIndex = 0;
foreach (var label in labels)
{
qnameBytes[qnameIndex++] = (byte)label.Length;
foreach (var c in label)
{ {
writer.Write((byte)label.Length); qnameBytes[qnameIndex++] = (byte)c;
writer.Write(Encoding.ASCII.GetBytes(label));
} }
writer.Write((byte)0); // Null terminator
writer.Write((ushort)recordType);
writer.Write((ushort)1); // Record class: IN (Internet)
return stream.ToArray();
} }
qnameBytes[qnameIndex++] = 0;
var qtypeBytes = new byte[] { (byte)((ushort)recordType >> 8), (byte)((ushort)recordType & 0xff) };
var qclassBytes = new byte[] { 0, 1 }; // internet class
var questionBytes = new byte[qnameBytes.Length + qtypeBytes.Length + qclassBytes.Length];
qnameBytes.CopyTo(questionBytes, 0);
qtypeBytes.CopyTo(questionBytes, qnameBytes.Length);
qclassBytes.CopyTo(questionBytes, qnameBytes.Length + qtypeBytes.Length);
// Combine the header and question to form the DNS query packet
var queryBytes = new byte[headerBytes.Length + questionBytes.Length];
headerBytes.CopyTo(queryBytes, 0);
questionBytes.CopyTo(queryBytes, headerBytes.Length);
return queryBytes;
}
static DnsQuestion ParseDnsQuestionRecord(byte[] queryBytes, ref int offset)
{
// Parse the DNS name
var name = DnsNameParser.ParseName(queryBytes, ref offset);
if (name == null)
{
return null;
}
// Parse the DNS type and class
var type = (ushort)((queryBytes[offset] << 8) | queryBytes[offset + 1]);
var qclass = (ushort)((queryBytes[offset + 2] << 8) | queryBytes[offset + 3]);
offset += 4;
return new DnsQuestion
{
Name = name,
Type = (DnsRecordType)type,
Class = (DnsRecordClass)qclass,
};
} }
public static byte[] GetExampleResponse() public static byte[] GetExampleResponse()
{ {
// Example response bytes for the A record of google.com // Example response bytes for the A record of google.com
return new byte[] byte[] response = {
{
0x9d, 0xa9, // Query ID 0x9d, 0xa9, // Query ID
0x81, 0x80, // Flags 0x81, 0x80, // Flags
0x00, 0x01, // Questions: 1 0x00, 0x01, // Questions: 1
@ -105,31 +140,43 @@ namespace EonaCat.DnsTester.Helpers
0x00, 0x04, // Data length: 4 bytes 0x00, 0x04, // Data length: 4 bytes
0xac, 0xd9, 0x03, 0x3d // Data: 172.217.3.61 0xac, 0xd9, 0x03, 0x3d // Data: 172.217.3.61
}; };
return response;
} }
private static DnsResponse ParseDnsResponsePacket(string dnsId, long startTime, string server, byte[] responseBytes) static DnsResponse ParseDnsResponsePacket(string dnsId, long startTime, string server, byte[] responseBytes)
{ {
Console.WriteLine("new byte[] { " + responseBytes + " }");
// Check if response is valid
if (responseBytes.Length < 12) if (responseBytes.Length < 12)
{ {
throw new Exception("Invalid DNS response"); throw new Exception("Invalid DNS response");
} }
// Set the offset to the start
var offset = 0; var offset = 0;
var id = (ushort)((responseBytes[offset++] << 8) | responseBytes[offset++]);
var flags = (ushort)((responseBytes[offset++] << 8) | responseBytes[offset++]); // Parse the DNS header
var id = (ushort)((responseBytes[0] << 8) | responseBytes[1]);
var flags = (ushort)((responseBytes[2] << 8) | responseBytes[3]);
var isResponse = (flags & 0x8000) != 0; var isResponse = (flags & 0x8000) != 0;
var qdcount = (ushort)((responseBytes[offset++] << 8) | responseBytes[offset++]); var qdcount = (ushort)((responseBytes[4] << 8) | responseBytes[5]);
var ancount = (ushort)((responseBytes[6] << 8) | responseBytes[7]);
if (!isResponse) if (!isResponse)
{ {
throw new Exception("Invalid DNS response"); throw new Exception("Invalid DNS response");
} }
var nscount = (ushort)((responseBytes[offset++] << 8) | responseBytes[offset++]); var nscount = (ushort)((responseBytes[8] << 8) | responseBytes[9]);
var arcount = (ushort)((responseBytes[offset++] << 8) | responseBytes[offset++]); var arcount = (ushort)((responseBytes[10] << 8) | responseBytes[11]);
// We parsed the header set the offset past the header
offset = 12;
var questions = new List<DnsQuestion>(); var questions = new List<DnsQuestion>();
for (int i = 0; i < qdcount; i++)
for (var i = 0; i < qdcount; i++)
{ {
var question = ParseDnsQuestionRecord(responseBytes, ref offset); var question = ParseDnsQuestionRecord(responseBytes, ref offset);
if (question != null) if (question != null)
@ -138,8 +185,9 @@ namespace EonaCat.DnsTester.Helpers
} }
} }
// Parse the DNS answer records
var answers = new List<ResourceRecord>(); var answers = new List<ResourceRecord>();
for (int i = 0; i < qdcount; i++) for (var i = 0; i < ancount; i++)
{ {
try try
{ {
@ -151,13 +199,13 @@ namespace EonaCat.DnsTester.Helpers
} }
catch (Exception exception) catch (Exception exception)
{ {
OnLog?.Invoke(null, $"Answer exception: {exception.Message}"); OnLog?.Invoke(null, $"Answer exception: " + exception.Message);
} }
} }
// Parse the DNS authority records // Parse the DNS authority records
var authorities = new List<ResourceRecord>(); var authorities = new List<ResourceRecord>();
for (int i = 0; i < nscount; i++) for (var i = 0; i < nscount; i++)
{ {
try try
{ {
@ -169,13 +217,13 @@ namespace EonaCat.DnsTester.Helpers
} }
catch (Exception exception) catch (Exception exception)
{ {
OnLog?.Invoke(null, $"Authority answer exception: {exception.Message}"); OnLog?.Invoke(null, $"Authority answer exception: " + exception.Message);
} }
} }
// Parse the DNS additional records // Parse the DNS additional records
var additionals = new List<ResourceRecord>(); var additionals = new List<ResourceRecord>();
for (int i = 0; i < arcount; i++) for (var i = 0; i < arcount; i++)
{ {
try try
{ {
@ -187,7 +235,7 @@ namespace EonaCat.DnsTester.Helpers
} }
catch (Exception exception) catch (Exception exception)
{ {
OnLog?.Invoke(null, $"Additional answer exception: {exception.Message}"); OnLog?.Invoke(null, $"Additional answer exception: " + exception.Message);
} }
} }
@ -206,61 +254,53 @@ namespace EonaCat.DnsTester.Helpers
}; };
} }
private static DnsQuestion ParseDnsQuestionRecord(byte[] queryBytes, ref int offset) static ResourceRecord ParseDnsAnswerRecord(byte[] responseBytes, ref int offset)
{
var name = DnsNameParser.ParseName(queryBytes, ref offset);
if (name == null)
{
return null;
}
var type = (DnsRecordType)((queryBytes[offset++] << 8) | queryBytes[offset++]);
var qclass = (DnsRecordClass)((queryBytes[offset++] << 8) | queryBytes[offset++]);
return new DnsQuestion
{
Name = name,
Type = type,
Class = qclass,
};
}
private static ResourceRecord ParseDnsAnswerRecord(byte[] responseBytes, ref int offset)
{ {
// Parse the DNS name
var name = DnsNameParser.ExtractDomainName(responseBytes, ref offset); var name = DnsNameParser.ExtractDomainName(responseBytes, ref offset);
if (name == null) if (name == null)
{ {
return null; return null;
} }
// Parse the DNS type, class, ttl, and data length
var type = (DnsRecordType)((responseBytes[offset++] << 8) + responseBytes[offset++]); var type = (DnsRecordType)((responseBytes[offset++] << 8) + responseBytes[offset++]);
var klass = (DnsRecordClass)((responseBytes[offset++] << 8) + responseBytes[offset++]); var klass = (DnsRecordClass)((responseBytes[offset++] << 8) + responseBytes[offset++]);
var ttl = (responseBytes[offset++] << 24) + (responseBytes[offset++] << 16) + (responseBytes[offset++] << 8) + responseBytes[offset++]; var ttl = (responseBytes[offset++] << 24) + (responseBytes[offset++] << 16) + (responseBytes[offset++] << 8) + responseBytes[offset++];
var dataLength = (responseBytes[offset++] << 8) + responseBytes[offset++];
string dataAsString = null; // Extract record data length
switch (type) var dataLength = (responseBytes[offset] << 8) + responseBytes[offset + 1];
offset += 2;
// Extract record data
var recordData = new byte[dataLength];
Buffer.BlockCopy(responseBytes, offset, recordData, 0, dataLength);
string recordDataAsString = null;
switch ((DnsRecordType)type)
{ {
case DnsRecordType.A: case DnsRecordType.A:
if (dataLength != 4) if (dataLength != 4)
{ {
return null; return null;
} }
dataAsString = new IPAddress(responseBytes, offset).ToString(); recordDataAsString = new IPAddress(recordData).ToString();
offset += dataLength; offset += recordData.Length;
break; break;
case DnsRecordType.CNAME: case DnsRecordType.CNAME:
recordDataAsString = DnsNameParser.ExtractDomainName(responseBytes, ref offset);
break;
case DnsRecordType.NS: case DnsRecordType.NS:
dataAsString = DnsNameParser.ExtractDomainName(responseBytes, ref offset); recordDataAsString = DnsNameParser.ExtractDomainName(responseBytes, ref offset);
break; break;
case DnsRecordType.MX: case DnsRecordType.MX:
var preference = (responseBytes[offset++] << 8) + responseBytes[offset++]; var preference = (responseBytes[0] << 8) + responseBytes[1];
offset += 2;
var exchange = DnsNameParser.ExtractDomainName(responseBytes, ref offset); var exchange = DnsNameParser.ExtractDomainName(responseBytes, ref offset);
dataAsString = $"{preference} {exchange}"; recordDataAsString = $"{preference} {exchange}";
break; break;
case DnsRecordType.TXT: case DnsRecordType.TXT:
dataAsString = Encoding.ASCII.GetString(responseBytes, offset, dataLength); recordDataAsString = Encoding.ASCII.GetString(recordData);
offset += dataLength;
break; break;
default: default:
offset += dataLength; offset += dataLength;
@ -273,10 +313,19 @@ namespace EonaCat.DnsTester.Helpers
Type = type, Type = type,
Class = klass, Class = klass,
Ttl = TimeSpan.FromSeconds(ttl), Ttl = TimeSpan.FromSeconds(ttl),
Data = dataAsString, Data = recordDataAsString,
DataLength = (ushort)dataLength,
}; };
} }
static string GetString(byte[] bytes, ref int index, int length)
{
var str = "";
for (var i = 0; i < length; i++)
{
str += (char)bytes[index++];
}
return str;
}
} }
public class DnsQuestion public class DnsQuestion
@ -322,11 +371,35 @@ namespace EonaCat.DnsTester.Helpers
public enum DnsRecordClass : ushort public enum DnsRecordClass : ushort
{ {
/// <summary>
/// The Internet.
/// </summary>
Internet = 1, Internet = 1,
/// <summary>
/// The CSNET class (Obsolete - used only for examples insome obsolete RFCs).
/// </summary>
CS = 2, CS = 2,
/// <summary>
/// The CHAOS class.
/// </summary>
CH = 3, CH = 3,
/// <summary>
/// Hesiod[Dyer 87].
/// </summary>
HS = 4, HS = 4,
/// <summary>
/// Used in UPDATE message to signify no class.
/// </summary>
None = 254, None = 254,
/// <summary>
/// Only used in QCLASS.
/// </summary>
/// <seealso cref="Question.Class"/>
ANY = 255 ANY = 255
} }
} }

View File

@ -7,7 +7,7 @@ namespace EonaCat.DnsTester.Helpers
{ {
public static string ParseName(byte[] responseBytes, ref int offset) public static string ParseName(byte[] responseBytes, ref int offset)
{ {
List<string> labels = new List<string>(); var labels = new List<string>();
int length; int length;
while ((length = responseBytes[offset++]) != 0) while ((length = responseBytes[offset++]) != 0)
@ -15,8 +15,8 @@ namespace EonaCat.DnsTester.Helpers
if ((length & 0xC0) == 0xC0) if ((length & 0xC0) == 0xC0)
{ {
// The name is compressed // The name is compressed
int pointer = ((length & 0x3F) << 8) | responseBytes[offset++]; var pointer = ((length & 0x3F) << 8) | responseBytes[offset++];
int savedOffset = offset; var savedOffset = offset;
offset = pointer; offset = pointer;
labels.AddRange(ParseName(responseBytes, ref offset).Split('.')); labels.AddRange(ParseName(responseBytes, ref offset).Split('.'));
offset = savedOffset; offset = savedOffset;
@ -24,7 +24,7 @@ namespace EonaCat.DnsTester.Helpers
} }
// The name is not compressed // The name is not compressed
labels.Add(System.Text.Encoding.ASCII.GetString(responseBytes, offset, length)); labels.Add(Encoding.ASCII.GetString(responseBytes, offset, length));
offset += length; offset += length;
} }
@ -33,11 +33,11 @@ namespace EonaCat.DnsTester.Helpers
public static string ExtractDomainName(byte[] buffer, ref int offset) public static string ExtractDomainName(byte[] buffer, ref int offset)
{ {
List<string> labels = new List<string>(); var labels = new List<string>();
while (true) while (true)
{ {
byte labelLength = buffer[offset++]; var labelLength = buffer[offset++];
if (labelLength == 0) if (labelLength == 0)
{ {
@ -47,12 +47,12 @@ namespace EonaCat.DnsTester.Helpers
if ((labelLength & 0xC0) == 0xC0) if ((labelLength & 0xC0) == 0xC0)
{ {
// Compressed domain name // Compressed domain name
int pointer = (int)(((labelLength & 0x3F) << 8) + buffer[offset++]); var pointer = (int)(((labelLength & 0x3F) << 8) + buffer[offset++]);
labels.Add(ExtractDomainName(buffer, ref pointer)); labels.Add(ExtractDomainName(buffer, ref pointer));
break; break;
} }
string label = Encoding.ASCII.GetString(buffer, offset, labelLength); var label = Encoding.ASCII.GetString(buffer, offset, labelLength);
labels.Add(label); labels.Add(label);
offset += labelLength; offset += labelLength;
} }

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net.Http;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -10,84 +10,95 @@ namespace EonaCat.DnsTester.Helpers
{ {
internal class UrlHelper internal class UrlHelper
{ {
private static readonly RandomNumberGenerator _randomNumberGenerator = RandomNumberGenerator.Create(); private static readonly RandomNumberGenerator RandomNumberGenerator = RandomNumberGenerator.Create();
public static event EventHandler<string> Log; public static event EventHandler<string> Log;
public static bool UseSearchEngineYahoo { get; set; } public static bool UseSearchEngineYahoo { get; set; }
public static bool UseSearchEngineBing { get; set; } public static bool UseSearchEngineBing { get; set; }
public static bool UseSearchEngineGoogle { get; set; } public static bool UseSearchEngineGoogle { get; set; }
public static bool UseSearchEngineQwant { get; set; } public static bool UseSearchEngineQwant { get; set; }
public static bool UseSearchEngineAsk { get; set; }
public static bool UseSearchEngineWolfram { get; set; } public static bool UseSearchEngineWolfram { get; set; }
public static bool UseSearchEngineStartPage { get; set; } public static bool UseSearchEngineStartPage { get; set; }
public static bool UseSearchEngineYandex { get; set; } public static bool UseSearchEngineYandex { get; set; }
private static List<string> GetRandomUrls(int totalUrls) private static async Task<List<string>> GetRandomUrlsAsync(int totalUrls)
{ {
var letters = GetRandomLetters(); var letters = GetRandomLetters();
var searchEngineUrls = GetSearchEngines(); var searchEngineUrls = GetSearchEngines();
var rand = new Random();
var urls = new List<string>();
List<string> urls = new List<string>(); while (urls.Count < totalUrls)
Parallel.ForEach(searchEngineUrls, searchEngine =>
{ {
if (urls.Count >= totalUrls) var index = rand.Next(searchEngineUrls.Count);
return; var searchEngine = searchEngineUrls.ElementAt(index);
var url = searchEngine.Value + letters;
string url = searchEngine.Value + letters; using (var httpClient = new HttpClient())
using (var client = new WebClient())
{ {
string responseString = null;
try try
{ {
responseString = client.DownloadString(url); var response = await httpClient.GetAsync(url).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
// find all .xxx.com addresses
var hostNames = Regex.Matches(responseString, @"[.](\w+[.]com)");
// Loop through the match collection to retrieve all matches and delete the leading "."
var uniqueNames = new HashSet<string>();
foreach (Match match in hostNames)
{
var name = match.Groups[1].Value;
if (name != $"{searchEngine.Key.ToLower()}.com")
{
uniqueNames.Add(name);
}
}
// Add the names to the list
foreach (var name in uniqueNames)
{
if (urls.Count >= totalUrls)
{
break;
}
if (!urls.Contains(name))
{
urls.Add(name);
}
}
}
else
{
// Handle non-successful status codes (optional)
searchEngineUrls.Remove(searchEngine.Key);
SetStatus($"{searchEngine.Key}: {response.StatusCode}");
}
} }
catch (Exception ex) catch (Exception ex)
{ {
// Handle exceptions (optional)
searchEngineUrls.Remove(searchEngine.Key); searchEngineUrls.Remove(searchEngine.Key);
SetStatus($"{searchEngine.Key}: {ex.Message}"); SetStatus($"{searchEngine.Key}: {ex.Message}");
} }
if (responseString == null)
return;
// find all .xxx.com addresses
MatchCollection hostNames = Regex.Matches(responseString, @"[.](\w+[.]com)");
// Loop through the match collection to retrieve all matches and delete the leading "."
HashSet<string> uniqueNames = new HashSet<string>();
foreach (Match match in hostNames)
{
string name = match.Groups[1].Value;
if (name != $"{searchEngine.Key.ToLower()}.com")
{
uniqueNames.Add(name);
}
}
lock (urls)
{
// Add the names to the list
foreach (string name in uniqueNames)
{
if (urls.Count >= totalUrls)
break;
if (!urls.Contains(name))
urls.Add(name);
}
}
} }
});
letters = GetRandomLetters();
await Task.Delay(100).ConfigureAwait(false);
}
var urlText = "url" + (urls.Count > 1 ? "'s" : string.Empty); var urlText = "url" + (urls.Count > 1 ? "'s" : string.Empty);
SetStatus($"{urls.Count} random {urlText} found"); SetStatus($"{urls.Count} random {urlText} found");
return urls; return urls;
} }
private static Dictionary<string, string> GetSearchEngines() private static Dictionary<string, string> GetSearchEngines()
{ {
Dictionary<string, string> searchEngineUrls = new Dictionary<string, string>(); var searchEngineUrls = new Dictionary<string, string>();
if (UseSearchEngineYahoo) if (UseSearchEngineYahoo)
{ {
searchEngineUrls.Add("Yahoo", "https://search.yahoo.com/search?p="); searchEngineUrls.Add("Yahoo", "https://search.yahoo.com/search?p=");
@ -108,11 +119,6 @@ namespace EonaCat.DnsTester.Helpers
searchEngineUrls.Add("Qwant", "https://www.qwant.com/?q="); searchEngineUrls.Add("Qwant", "https://www.qwant.com/?q=");
} }
if (UseSearchEngineAsk)
{
searchEngineUrls.Add("Ask", "https://www.ask.com/web?q=");
}
if (UseSearchEngineWolfram) if (UseSearchEngineWolfram)
{ {
searchEngineUrls.Add("WolframAlpha", "https://www.wolframalpha.com/input/?i="); searchEngineUrls.Add("WolframAlpha", "https://www.wolframalpha.com/input/?i=");
@ -131,18 +137,20 @@ namespace EonaCat.DnsTester.Helpers
return searchEngineUrls; return searchEngineUrls;
} }
public static List<string> RetrieveUrls(int numThreads, int numUrlsPerThread) public static async Task<List<string>> RetrieveUrlsAsync(int numThreads, int numUrlsPerThread)
{ {
List<string> urlList = new List<string>(); var tasks = new Task[numThreads];
Parallel.For(0, numThreads, _ => var urlList = new List<string>();
// start each thread to retrieve a subset of unique URLs
for (var i = 0; i < numThreads; i++)
{ {
var threadUrls = GetRandomUrls(numUrlsPerThread); tasks[i] = Task.Run(async () => urlList.AddRange(await GetRandomUrlsAsync(numUrlsPerThread).ConfigureAwait(false)));
lock (urlList) }
{
urlList.AddRange(threadUrls); // wait for all threads to complete
} await Task.WhenAll(tasks).ConfigureAwait(false);
});
return urlList; return urlList;
} }
@ -150,8 +158,8 @@ namespace EonaCat.DnsTester.Helpers
private static string GetRandomLetters() private static string GetRandomLetters()
{ {
// Generate a cryptographically strong random string // Generate a cryptographically strong random string
byte[] randomBytes = new byte[32]; var randomBytes = new byte[32];
_randomNumberGenerator.GetBytes(randomBytes); RandomNumberGenerator.GetBytes(randomBytes);
return Convert.ToBase64String(randomBytes); return Convert.ToBase64String(randomBytes);
} }

View File

@ -37,7 +37,6 @@
checkBox7 = new System.Windows.Forms.CheckBox(); checkBox7 = new System.Windows.Forms.CheckBox();
checkBox6 = new System.Windows.Forms.CheckBox(); checkBox6 = new System.Windows.Forms.CheckBox();
checkBox5 = new System.Windows.Forms.CheckBox(); checkBox5 = new System.Windows.Forms.CheckBox();
checkBox4 = new System.Windows.Forms.CheckBox();
checkBox3 = new System.Windows.Forms.CheckBox(); checkBox3 = new System.Windows.Forms.CheckBox();
checkBox2 = new System.Windows.Forms.CheckBox(); checkBox2 = new System.Windows.Forms.CheckBox();
checkBox1 = new System.Windows.Forms.CheckBox(); checkBox1 = new System.Windows.Forms.CheckBox();
@ -108,6 +107,7 @@
// //
// tabPage1 // tabPage1
// //
tabPage1.BackColor = System.Drawing.Color.LightGray;
tabPage1.Controls.Add(panel2); tabPage1.Controls.Add(panel2);
tabPage1.Controls.Add(panel1); tabPage1.Controls.Add(panel1);
tabPage1.Location = new System.Drawing.Point(10, 58); tabPage1.Location = new System.Drawing.Point(10, 58);
@ -116,16 +116,14 @@
tabPage1.Size = new System.Drawing.Size(2239, 1449); tabPage1.Size = new System.Drawing.Size(2239, 1449);
tabPage1.TabIndex = 0; tabPage1.TabIndex = 0;
tabPage1.Text = "Dns tester"; tabPage1.Text = "Dns tester";
tabPage1.UseVisualStyleBackColor = true;
// //
// panel2 // panel2
// //
panel2.BackColor = System.Drawing.SystemColors.ControlLight; panel2.BackColor = System.Drawing.Color.Gold;
panel2.Controls.Add(checkBox8); panel2.Controls.Add(checkBox8);
panel2.Controls.Add(checkBox7); panel2.Controls.Add(checkBox7);
panel2.Controls.Add(checkBox6); panel2.Controls.Add(checkBox6);
panel2.Controls.Add(checkBox5); panel2.Controls.Add(checkBox5);
panel2.Controls.Add(checkBox4);
panel2.Controls.Add(checkBox3); panel2.Controls.Add(checkBox3);
panel2.Controls.Add(checkBox2); panel2.Controls.Add(checkBox2);
panel2.Controls.Add(checkBox1); panel2.Controls.Add(checkBox1);
@ -142,7 +140,7 @@
checkBox8.AutoSize = true; checkBox8.AutoSize = true;
checkBox8.Checked = true; checkBox8.Checked = true;
checkBox8.CheckState = System.Windows.Forms.CheckState.Checked; checkBox8.CheckState = System.Windows.Forms.CheckState.Checked;
checkBox8.Location = new System.Drawing.Point(1301, 42); checkBox8.Location = new System.Drawing.Point(1172, 38);
checkBox8.Name = "checkBox8"; checkBox8.Name = "checkBox8";
checkBox8.Size = new System.Drawing.Size(143, 45); checkBox8.Size = new System.Drawing.Size(143, 45);
checkBox8.TabIndex = 70; checkBox8.TabIndex = 70;
@ -154,7 +152,7 @@
checkBox7.AutoSize = true; checkBox7.AutoSize = true;
checkBox7.Checked = true; checkBox7.Checked = true;
checkBox7.CheckState = System.Windows.Forms.CheckState.Checked; checkBox7.CheckState = System.Windows.Forms.CheckState.Checked;
checkBox7.Location = new System.Drawing.Point(1301, 135); checkBox7.Location = new System.Drawing.Point(1172, 135);
checkBox7.Name = "checkBox7"; checkBox7.Name = "checkBox7";
checkBox7.Size = new System.Drawing.Size(150, 45); checkBox7.Size = new System.Drawing.Size(150, 45);
checkBox7.TabIndex = 69; checkBox7.TabIndex = 69;
@ -166,7 +164,7 @@
checkBox6.AutoSize = true; checkBox6.AutoSize = true;
checkBox6.Checked = true; checkBox6.Checked = true;
checkBox6.CheckState = System.Windows.Forms.CheckState.Checked; checkBox6.CheckState = System.Windows.Forms.CheckState.Checked;
checkBox6.Location = new System.Drawing.Point(1109, 135); checkBox6.Location = new System.Drawing.Point(959, 135);
checkBox6.Name = "checkBox6"; checkBox6.Name = "checkBox6";
checkBox6.Size = new System.Drawing.Size(181, 45); checkBox6.Size = new System.Drawing.Size(181, 45);
checkBox6.TabIndex = 68; checkBox6.TabIndex = 68;
@ -178,31 +176,19 @@
checkBox5.AutoSize = true; checkBox5.AutoSize = true;
checkBox5.Checked = true; checkBox5.Checked = true;
checkBox5.CheckState = System.Windows.Forms.CheckState.Checked; checkBox5.CheckState = System.Windows.Forms.CheckState.Checked;
checkBox5.Location = new System.Drawing.Point(824, 135); checkBox5.Location = new System.Drawing.Point(659, 135);
checkBox5.Name = "checkBox5"; checkBox5.Name = "checkBox5";
checkBox5.Size = new System.Drawing.Size(244, 45); checkBox5.Size = new System.Drawing.Size(244, 45);
checkBox5.TabIndex = 67; checkBox5.TabIndex = 67;
checkBox5.Text = "WolframAlpha"; checkBox5.Text = "WolframAlpha";
checkBox5.UseVisualStyleBackColor = true; checkBox5.UseVisualStyleBackColor = true;
// //
// checkBox4
//
checkBox4.AutoSize = true;
checkBox4.Checked = true;
checkBox4.CheckState = System.Windows.Forms.CheckState.Checked;
checkBox4.Location = new System.Drawing.Point(654, 135);
checkBox4.Name = "checkBox4";
checkBox4.Size = new System.Drawing.Size(103, 45);
checkBox4.TabIndex = 66;
checkBox4.Text = "Ask";
checkBox4.UseVisualStyleBackColor = true;
//
// checkBox3 // checkBox3
// //
checkBox3.AutoSize = true; checkBox3.AutoSize = true;
checkBox3.Checked = true; checkBox3.Checked = true;
checkBox3.CheckState = System.Windows.Forms.CheckState.Checked; checkBox3.CheckState = System.Windows.Forms.CheckState.Checked;
checkBox3.Location = new System.Drawing.Point(1109, 42); checkBox3.Location = new System.Drawing.Point(959, 42);
checkBox3.Name = "checkBox3"; checkBox3.Name = "checkBox3";
checkBox3.Size = new System.Drawing.Size(154, 45); checkBox3.Size = new System.Drawing.Size(154, 45);
checkBox3.TabIndex = 65; checkBox3.TabIndex = 65;
@ -214,7 +200,7 @@
checkBox2.AutoSize = true; checkBox2.AutoSize = true;
checkBox2.Checked = true; checkBox2.Checked = true;
checkBox2.CheckState = System.Windows.Forms.CheckState.Checked; checkBox2.CheckState = System.Windows.Forms.CheckState.Checked;
checkBox2.Location = new System.Drawing.Point(824, 41); checkBox2.Location = new System.Drawing.Point(819, 41);
checkBox2.Name = "checkBox2"; checkBox2.Name = "checkBox2";
checkBox2.Size = new System.Drawing.Size(115, 45); checkBox2.Size = new System.Drawing.Size(115, 45);
checkBox2.TabIndex = 64; checkBox2.TabIndex = 64;
@ -226,7 +212,7 @@
checkBox1.AutoSize = true; checkBox1.AutoSize = true;
checkBox1.Checked = true; checkBox1.Checked = true;
checkBox1.CheckState = System.Windows.Forms.CheckState.Checked; checkBox1.CheckState = System.Windows.Forms.CheckState.Checked;
checkBox1.Location = new System.Drawing.Point(654, 42); checkBox1.Location = new System.Drawing.Point(659, 42);
checkBox1.Name = "checkBox1"; checkBox1.Name = "checkBox1";
checkBox1.Size = new System.Drawing.Size(138, 45); checkBox1.Size = new System.Drawing.Size(138, 45);
checkBox1.TabIndex = 63; checkBox1.TabIndex = 63;
@ -246,6 +232,7 @@
// //
// StatusBox // StatusBox
// //
StatusBox.BackColor = System.Drawing.Color.OldLace;
StatusBox.FormattingEnabled = true; StatusBox.FormattingEnabled = true;
StatusBox.HorizontalScrollbar = true; StatusBox.HorizontalScrollbar = true;
StatusBox.ItemHeight = 41; StatusBox.ItemHeight = 41;
@ -257,6 +244,7 @@
// //
// ResultView // ResultView
// //
ResultView.BackColor = System.Drawing.Color.OldLace;
ResultView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { Url, DNS1DATA, DNS1Performance, DNS2DATA, DNS2Performance }); ResultView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { Url, DNS1DATA, DNS1Performance, DNS2DATA, DNS2Performance });
ResultView.GridLines = true; ResultView.GridLines = true;
ResultView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; ResultView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
@ -300,7 +288,7 @@
// //
// panel1 // panel1
// //
panel1.BackColor = System.Drawing.SystemColors.ControlLight; panel1.BackColor = System.Drawing.Color.Gold;
panel1.Controls.Add(numericUpDown2); panel1.Controls.Add(numericUpDown2);
panel1.Controls.Add(label2); panel1.Controls.Add(label2);
panel1.Controls.Add(comboBox1); panel1.Controls.Add(comboBox1);
@ -578,6 +566,7 @@
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
AutoSize = true; AutoSize = true;
AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
BackColor = System.Drawing.SystemColors.MenuHighlight;
ClientSize = new System.Drawing.Size(2517, 1693); ClientSize = new System.Drawing.Size(2517, 1693);
Controls.Add(tabControl1); Controls.Add(tabControl1);
Controls.Add(RunTest); Controls.Add(RunTest);
@ -647,7 +636,6 @@
private System.Windows.Forms.CheckBox checkBox7; private System.Windows.Forms.CheckBox checkBox7;
private System.Windows.Forms.CheckBox checkBox6; private System.Windows.Forms.CheckBox checkBox6;
private System.Windows.Forms.CheckBox checkBox5; private System.Windows.Forms.CheckBox checkBox5;
private System.Windows.Forms.CheckBox checkBox4;
} }
} }

View File

@ -6,7 +6,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using EonaCat.DnsTester.Helpers; using EonaCat.DnsTester.Helpers;
@ -44,13 +43,13 @@ namespace EonaCat.DnsTester
return; return;
} }
List<string> urls = new List<string>(); var urls = new List<string>();
SetupView(); SetupView();
int numThreads = (int)numericUpDown2.Value; // number of concurrent threads to use var numThreads = (int)numericUpDown2.Value; // number of concurrent threads to use
int maxUrls = (int)numericUpDown1.Value; // maximum number of unique URLs to retrieve var maxUrls = (int)numericUpDown1.Value; // maximum number of unique URLs to retrieve
int numUrlsPerThread = maxUrls / numThreads; var numUrlsPerThread = maxUrls / numThreads;
if (numUrlsPerThread == 0) if (numUrlsPerThread == 0)
{ {
numUrlsPerThread = maxUrls; numUrlsPerThread = maxUrls;
@ -58,11 +57,11 @@ namespace EonaCat.DnsTester
} }
SetSearchEngines(); SetSearchEngines();
urls = UrlHelper.RetrieveUrls(numThreads, numUrlsPerThread); urls = await UrlHelper.RetrieveUrlsAsync(numThreads, numUrlsPerThread).ConfigureAwait(false);
AddUrlToView(urls); AddUrlToView(urls);
IsRunning = true; IsRunning = true;
await Process(_recordType, urls.ToArray(), _dnsServer1, _dnsServer2).ConfigureAwait(false); await ProcessAsync(_recordType, urls.ToArray(), _dnsServer1, _dnsServer2).ConfigureAwait(false);
IsRunning = false; IsRunning = false;
} }
@ -72,7 +71,6 @@ namespace EonaCat.DnsTester
UrlHelper.UseSearchEngineBing = checkBox2.Checked; UrlHelper.UseSearchEngineBing = checkBox2.Checked;
UrlHelper.UseSearchEngineGoogle = checkBox3.Checked; UrlHelper.UseSearchEngineGoogle = checkBox3.Checked;
UrlHelper.UseSearchEngineQwant = checkBox8.Checked; UrlHelper.UseSearchEngineQwant = checkBox8.Checked;
UrlHelper.UseSearchEngineAsk = checkBox4.Checked;
UrlHelper.UseSearchEngineWolfram = checkBox5.Checked; UrlHelper.UseSearchEngineWolfram = checkBox5.Checked;
UrlHelper.UseSearchEngineStartPage = checkBox6.Checked; UrlHelper.UseSearchEngineStartPage = checkBox6.Checked;
UrlHelper.UseSearchEngineYandex = checkBox7.Checked; UrlHelper.UseSearchEngineYandex = checkBox7.Checked;
@ -127,23 +125,26 @@ namespace EonaCat.DnsTester
private void AddUrlToView(List<string> urls) private void AddUrlToView(List<string> urls)
{ {
foreach (var currentUrl in urls) ResultView.Invoke(() =>
{ {
ListViewItem listURL = new ListViewItem(currentUrl); foreach (var currentUrl in urls)
listURL.SubItems.Add(" "); {
listURL.SubItems.Add(" "); var listUrl = new ListViewItem(currentUrl);
listURL.SubItems.Add(" "); listUrl.SubItems.Add(" ");
listURL.SubItems.Add(" "); listUrl.SubItems.Add(" ");
listUrl.SubItems.Add(" ");
listUrl.SubItems.Add(" ");
ResultView.Items.Add(listURL); ResultView.Items.Add(listUrl);
} }
if (ResultView.Items.Count > 1) if (ResultView.Items.Count > 1)
{ {
ResultView.EnsureVisible(ResultView.Items.Count - 1); ResultView.EnsureVisible(ResultView.Items.Count - 1);
} }
ResultView.Update(); ResultView.Update();
});
Application.DoEvents(); Application.DoEvents();
} }
@ -162,13 +163,13 @@ namespace EonaCat.DnsTester
dnsList2.DisplayMember = "name"; dnsList2.DisplayMember = "name";
var serverList = Path.Combine(Application.StartupPath, "Servers.xml"); var serverList = Path.Combine(Application.StartupPath, "Servers.xml");
DataSet servers1 = new DataSet(); var servers1 = new DataSet();
DataSet servers2 = new DataSet(); var servers2 = new DataSet();
servers1.ReadXml(serverList); servers1.ReadXml(serverList);
servers2.ReadXml(serverList); servers2.ReadXml(serverList);
DataTable dataTable1 = servers1.Tables[0]; var dataTable1 = servers1.Tables[0];
DataTable dataTable2 = servers2.Tables[0]; var dataTable2 = servers2.Tables[0];
dnsList1.DataSource = dataTable1; dnsList1.DataSource = dataTable1;
dnsList2.DataSource = dataTable2; dnsList2.DataSource = dataTable2;
} }
@ -195,46 +196,46 @@ namespace EonaCat.DnsTester
} }
private async Task Process(DnsRecordType recordType, string[] urls, string dnsAddress1, string dnsAddress2) private async Task ProcessAsync(DnsRecordType recordType, string[] urls, string dnsAddress1, string dnsAddress2)
{ {
if (recordType == 0) if (recordType == 0)
{ {
recordType = DnsRecordType.A; recordType = DnsRecordType.A;
} }
int urlsTotal = urls.Length; var urlsTotal = urls.Length;
const string dnsId1 = "Dns1"; const string dnsId1 = "Dns1";
const string dnsId2 = "Dns2"; const string dnsId2 = "Dns2";
DnsHelper.OnLog -= DnsHelper_OnLog; DnsHelper.OnLog -= DnsHelper_OnLog;
DnsHelper.OnLog += DnsHelper_OnLog; DnsHelper.OnLog += DnsHelper_OnLog;
for (int i = 0; i < urlsTotal; i++) for (var i = 0; i < urlsTotal; i++)
{ {
var currentUrl = urls[i]; var currentUrl = urls[i];
await ExecuteDns1(recordType, dnsAddress1, currentUrl, dnsId1, i); await ExecuteDns1Async(recordType, dnsAddress1, currentUrl, dnsId1, i).ConfigureAwait(false);
if (chkDns2.Checked) if (chkDns2.Checked)
{ {
await ExecuteDns2(recordType, dnsAddress2, currentUrl, dnsId2, i); await ExecuteDns2Async(recordType, dnsAddress2, currentUrl, dnsId2, i).ConfigureAwait(false);
} }
await Task.Delay(100); await Task.Delay(100).ConfigureAwait(false);
} }
} }
private async Task ExecuteDns2(DnsRecordType recordType, string dnsAddress2, string currentUrl, string dnsId2, private async Task ExecuteDns2Async(DnsRecordType recordType, string dnsAddress2, string currentUrl, string dnsId2,
int i) int i)
{ {
try try
{ {
DnsResponse response2 = null; DnsResponse response2 = null;
byte[] queryBytes2 = DnsHelper.CreateDnsQueryPacket(currentUrl, recordType); var queryBytes2 = DnsHelper.CreateDnsQueryPacket(currentUrl, recordType);
response2 = await DnsHelper.SendDnsQueryPacket(dnsId2, dnsAddress2, 53, queryBytes2); response2 = await DnsHelper.SendDnsQueryPacketAsync(dnsId2, dnsAddress2, 53, queryBytes2).ConfigureAwait(false);
ProcessResponse(response2); ProcessResponse(response2);
} }
catch (SocketException socketException) catch (SocketException socketException)
{ {
SetStatus( SetStatus(
Convert.ToString(socketException).IndexOf("time", StringComparison.Ordinal) > 0 Convert.ToString(socketException)!.IndexOf("time", StringComparison.Ordinal) > 0
? $"DNS1 Timeout - No response received for {Convert.ToString(DnsHelper.DnsReceiveTimeout / 1000)} seconds" ? $"DNS1 Timeout - No response received for {Convert.ToString(DnsHelper.DnsReceiveTimeout / 1000)} seconds"
: Convert.ToString(socketException)); : Convert.ToString(socketException));
} }
@ -245,7 +246,7 @@ namespace EonaCat.DnsTester
} }
} }
private async Task ExecuteDns1(DnsRecordType recordType, string dnsAddress1, string currentUrl, string dnsId1, private async Task ExecuteDns1Async(DnsRecordType recordType, string dnsAddress1, string currentUrl, string dnsId1,
int i) int i)
{ {
if (chkDns1.Checked) if (chkDns1.Checked)
@ -253,14 +254,14 @@ namespace EonaCat.DnsTester
try try
{ {
DnsResponse response1 = null; DnsResponse response1 = null;
byte[] queryBytes1 = DnsHelper.CreateDnsQueryPacket(currentUrl, recordType); var queryBytes1 = DnsHelper.CreateDnsQueryPacket(currentUrl, recordType);
response1 = await DnsHelper.SendDnsQueryPacket(dnsId1, dnsAddress1, 53, queryBytes1); response1 = await DnsHelper.SendDnsQueryPacketAsync(dnsId1, dnsAddress1, 53, queryBytes1).ConfigureAwait(false);
ProcessResponse(response1); ProcessResponse(response1);
} }
catch (SocketException socketException) catch (SocketException socketException)
{ {
SetStatus( SetStatus(
Convert.ToString(socketException).IndexOf("time", StringComparison.Ordinal) > 0 Convert.ToString(socketException)!.IndexOf("time", StringComparison.Ordinal) > 0
? $"DNS1 Timeout - No response received for {Convert.ToString(DnsHelper.DnsReceiveTimeout / 1000)} seconds" ? $"DNS1 Timeout - No response received for {Convert.ToString(DnsHelper.DnsReceiveTimeout / 1000)} seconds"
: Convert.ToString(socketException)); : Convert.ToString(socketException));
} }
@ -279,7 +280,7 @@ namespace EonaCat.DnsTester
private void ProcessResponse(DnsResponse dnsResponse) private void ProcessResponse(DnsResponse dnsResponse)
{ {
if (dnsResponse?.Answers == null || !dnsResponse.Answers.Any()) if (dnsResponse == null || dnsResponse?.Answers == null || !dnsResponse.Answers.Any())
{ {
return; return;
} }
@ -296,7 +297,7 @@ namespace EonaCat.DnsTester
ResultView.Invoke(() => ResultView.Invoke(() =>
{ {
for (int i = 0; i < ResultView.Items.Count; i++) for (var i = 0; i < ResultView.Items.Count; i++)
{ {
foreach (var answer in dnsResponse.Answers) foreach (var answer in dnsResponse.Answers)
{ {
@ -308,7 +309,7 @@ namespace EonaCat.DnsTester
{ {
case "Dns1": case "Dns1":
ResultView.Items[i].SubItems[1].Text = ResultView.Items[i].SubItems[1].Text =
Convert.ToString(answer.Data); Convert.ToString(answer.Data) ?? string.Empty;
sDeltaTime = Convert.ToString(deltaTime); sDeltaTime = Convert.ToString(deltaTime);
ResultView.Items[i].SubItems[2].Text = ResultView.Items[i].SubItems[2].Text =
sDeltaTime.Length > 5 ? sDeltaTime.Substring(0, 5) : sDeltaTime; sDeltaTime.Length > 5 ? sDeltaTime.Substring(0, 5) : sDeltaTime;
@ -321,7 +322,7 @@ namespace EonaCat.DnsTester
case "Dns2": case "Dns2":
ResultView.Items[i].SubItems[3].Text = ResultView.Items[i].SubItems[3].Text =
Convert.ToString(answer.Data); Convert.ToString(answer.Data) ?? string.Empty;
sDeltaTime = Convert.ToString(deltaTime); sDeltaTime = Convert.ToString(deltaTime);
ResultView.Items[i].SubItems[4].Text = ResultView.Items[i].SubItems[4].Text =
sDeltaTime.Length > 5 ? sDeltaTime.Substring(0, 5) : sDeltaTime; sDeltaTime.Length > 5 ? sDeltaTime.Substring(0, 5) : sDeltaTime;
@ -345,13 +346,27 @@ namespace EonaCat.DnsTester
return; return;
} }
if (!IPAddress.TryParse(txtResolveIP.Text, out IPAddress iPAddress)) if (!IPAddress.TryParse(txtResolveIP.Text, out var iPAddress))
{ {
MessageBox.Show("Please enter a valid IP address"); MessageBox.Show("Please enter a valid IP address");
return; return;
} }
await ResolveIP().ConfigureAwait(false); 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);
} }
private async void btnResolveHost_Click(object sender, EventArgs e) private async void btnResolveHost_Click(object sender, EventArgs e)
@ -361,75 +376,38 @@ namespace EonaCat.DnsTester
MessageBox.Show("Please enter a hostname to resolve"); MessageBox.Show("Please enter a hostname to resolve");
return; return;
} }
await ResolveHost().ConfigureAwait(false);
}
private async Task ResolveIP()
{
if (string.IsNullOrWhiteSpace(txtResolveIP.Text))
{
MessageBox.Show("Please enter an IP address to resolve");
return;
}
if (!IPAddress.TryParse(txtResolveIP.Text, out IPAddress iPAddress)) await Task.Run(() =>
{ {
MessageBox.Show("Please enter a valid IP address"); try
return;
}
try
{
var dnsEntry = await Dns.GetHostEntryAsync(iPAddress);
txtResolveHost.Text = dnsEntry.HostName;
}
catch (Exception)
{
MessageBox.Show($"Could not get hostname for IP address '{txtResolveIP.Text}'");
}
}
private async Task ResolveHost()
{
if (string.IsNullOrWhiteSpace(txtResolveHost.Text))
{
MessageBox.Show("Please enter a hostname to resolve");
return;
}
try
{
var dnsEntry = await Dns.GetHostEntryAsync(txtResolveHost.Text);
var ipAddress = dnsEntry.AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork);
if (ipAddress != null)
{ {
txtResolveIP.Text = ipAddress.ToString(); var dnsEntry = Dns.GetHostEntry(txtResolveHost.Text);
txtResolveHost.Invoke(() =>
{
txtResolveIP.Text = dnsEntry.AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault().Address.ToString();
});
} }
else catch (Exception)
{ {
MessageBox.Show($"Could not get IP address for hostname '{txtResolveHost.Text}'"); MessageBox.Show($"Could not get IP address for hostname '{txtResolveHost.Text}'");
} }
} }).ConfigureAwait(false);
catch (Exception)
{
MessageBox.Show($"Could not get IP address for hostname '{txtResolveHost.Text}'");
}
} }
private void SetStatus(string text) private void SetStatus(string text)
{ {
StringBuilder sb = new StringBuilder(StatusBox.Items.Count + 1);
sb.AppendLine($"{DateTime.Now} {text}");
StatusBox.Invoke(() => StatusBox.Invoke(() =>
{ {
StatusBox.Items.Add(sb.ToString()); StatusBox.Items.Add($"{DateTime.Now} {text}");
StatusBox.TopIndex = StatusBox.Items.Count - 1; StatusBox.TopIndex = StatusBox.Items.Count - 1;
if (StatusBox.Items.Count > STATUS_BAR_SIZE) if (StatusBox.Items.Count > STATUS_BAR_SIZE)
{ {
StatusBox.Items.RemoveAt(0); StatusBox.Items.RemoveAt(0);
} }
StatusBox.Update();
}); });
} }

View File

@ -1,4 +1,64 @@
<root> <?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 KiB

After

Width:  |  Height:  |  Size: 538 KiB