Updated UI
This commit is contained in:
parent
16c642dd20
commit
6ae0e0b779
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
@ -11,12 +10,10 @@ namespace EonaCat.DnsTester.Helpers
|
|||
class DnsHelper
|
||||
{
|
||||
public static event EventHandler<string> OnLog;
|
||||
|
||||
private static readonly Random random = new Random();
|
||||
|
||||
public static async Task<DnsResponse> SendDnsQueryPacket(string dnsId, string server, int port, byte[] queryBytes)
|
||||
public static async Task<DnsResponse> SendDnsQueryPacketAsync(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);
|
||||
using (var client = new UdpClient(endPoint.AddressFamily))
|
||||
|
@ -25,68 +22,106 @@ namespace EonaCat.DnsTester.Helpers
|
|||
client.EnableBroadcast = false;
|
||||
client.Client.SendTimeout = DnsSendTimeout;
|
||||
client.Client.ReceiveTimeout = DnsReceiveTimeout;
|
||||
|
||||
byte[] responseBytes;
|
||||
byte[] responseBytes = null;
|
||||
if (FakeResponse)
|
||||
{
|
||||
responseBytes = GetExampleResponse();
|
||||
responseBytes = DnsHelper.GetExampleResponse();
|
||||
}
|
||||
else
|
||||
{
|
||||
await client.SendAsync(queryBytes, queryBytes.Length, endPoint);
|
||||
var responseResult = await client.ReceiveAsync();
|
||||
await client.SendAsync(queryBytes, queryBytes.Length, endPoint).ConfigureAwait(false);
|
||||
var responseResult = await client.ReceiveAsync().ConfigureAwait(false);
|
||||
responseBytes = responseResult.Buffer;
|
||||
}
|
||||
|
||||
var response = ParseDnsResponsePacket(dnsId, stopwatch.ElapsedTicks, server, responseBytes);
|
||||
var response = ParseDnsResponsePacket(dnsId, startTime, server, responseBytes);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
// For testing purposes
|
||||
public static bool FakeResponse { get; set; }
|
||||
|
||||
public static int DnsSendTimeout { get; set; } = 5;
|
||||
public static int DnsReceiveTimeout { get; set; } = 5;
|
||||
|
||||
|
||||
public static byte[] CreateDnsQueryPacket(string domainName, DnsRecordType recordType)
|
||||
{
|
||||
var random = new Random();
|
||||
|
||||
// DNS header
|
||||
var id = (ushort)random.Next(0, 65536);
|
||||
var flags = (ushort)0x0100; // recursion desired
|
||||
var qdcount = (ushort)1;
|
||||
var ancount = (ushort)0;
|
||||
var nscount = (ushort)0;
|
||||
var arcount = (ushort)0;
|
||||
|
||||
using (var stream = new MemoryStream())
|
||||
using (var writer = new BinaryWriter(stream))
|
||||
ushort qdcount = 1;
|
||||
ushort ancount = 0;
|
||||
ushort nscount = 0;
|
||||
ushort arcount = 0;
|
||||
var headerBytes = new byte[]
|
||||
{
|
||||
writer.Write(id);
|
||||
writer.Write(flags);
|
||||
writer.Write(qdcount);
|
||||
writer.Write(ancount);
|
||||
writer.Write(nscount);
|
||||
writer.Write(arcount);
|
||||
(byte)(id >> 8), (byte)(id & 0xff),
|
||||
(byte)(flags >> 8), (byte)(flags & 0xff),
|
||||
(byte)(qdcount >> 8), (byte)(qdcount & 0xff),
|
||||
(byte)(ancount >> 8), (byte)(ancount & 0xff),
|
||||
(byte)(nscount >> 8), (byte)(nscount & 0xff),
|
||||
(byte)(arcount >> 8), (byte)(arcount & 0xff),
|
||||
};
|
||||
|
||||
var labels = domainName.Split('.');
|
||||
foreach (var label in labels)
|
||||
// DNS question
|
||||
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);
|
||||
writer.Write(Encoding.ASCII.GetBytes(label));
|
||||
qnameBytes[qnameIndex++] = (byte)c;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
// Example response bytes for the A record of google.com
|
||||
return new byte[]
|
||||
{
|
||||
byte[] response = {
|
||||
0x9d, 0xa9, // Query ID
|
||||
0x81, 0x80, // Flags
|
||||
0x00, 0x01, // Questions: 1
|
||||
|
@ -105,31 +140,43 @@ namespace EonaCat.DnsTester.Helpers
|
|||
0x00, 0x04, // Data length: 4 bytes
|
||||
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)
|
||||
{
|
||||
throw new Exception("Invalid DNS response");
|
||||
}
|
||||
|
||||
// Set the offset to the start
|
||||
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 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)
|
||||
{
|
||||
throw new Exception("Invalid DNS response");
|
||||
}
|
||||
|
||||
var nscount = (ushort)((responseBytes[offset++] << 8) | responseBytes[offset++]);
|
||||
var arcount = (ushort)((responseBytes[offset++] << 8) | responseBytes[offset++]);
|
||||
var nscount = (ushort)((responseBytes[8] << 8) | responseBytes[9]);
|
||||
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>();
|
||||
for (int i = 0; i < qdcount; i++)
|
||||
|
||||
for (var i = 0; i < qdcount; i++)
|
||||
{
|
||||
var question = ParseDnsQuestionRecord(responseBytes, ref offset);
|
||||
if (question != null)
|
||||
|
@ -138,8 +185,9 @@ namespace EonaCat.DnsTester.Helpers
|
|||
}
|
||||
}
|
||||
|
||||
// Parse the DNS answer records
|
||||
var answers = new List<ResourceRecord>();
|
||||
for (int i = 0; i < qdcount; i++)
|
||||
for (var i = 0; i < ancount; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -151,13 +199,13 @@ namespace EonaCat.DnsTester.Helpers
|
|||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
OnLog?.Invoke(null, $"Answer exception: {exception.Message}");
|
||||
OnLog?.Invoke(null, $"Answer exception: " + exception.Message);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the DNS authority records
|
||||
var authorities = new List<ResourceRecord>();
|
||||
for (int i = 0; i < nscount; i++)
|
||||
for (var i = 0; i < nscount; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -169,13 +217,13 @@ namespace EonaCat.DnsTester.Helpers
|
|||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
OnLog?.Invoke(null, $"Authority answer exception: {exception.Message}");
|
||||
OnLog?.Invoke(null, $"Authority answer exception: " + exception.Message);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the DNS additional records
|
||||
var additionals = new List<ResourceRecord>();
|
||||
for (int i = 0; i < arcount; i++)
|
||||
for (var i = 0; i < arcount; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -187,7 +235,7 @@ namespace EonaCat.DnsTester.Helpers
|
|||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
static ResourceRecord ParseDnsAnswerRecord(byte[] responseBytes, ref int offset)
|
||||
{
|
||||
// Parse the DNS name
|
||||
var name = DnsNameParser.ExtractDomainName(responseBytes, ref offset);
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Parse the DNS type, class, ttl, and data length
|
||||
var type = (DnsRecordType)((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 dataLength = (responseBytes[offset++] << 8) + responseBytes[offset++];
|
||||
|
||||
string dataAsString = null;
|
||||
switch (type)
|
||||
// Extract record data length
|
||||
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:
|
||||
if (dataLength != 4)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
dataAsString = new IPAddress(responseBytes, offset).ToString();
|
||||
offset += dataLength;
|
||||
recordDataAsString = new IPAddress(recordData).ToString();
|
||||
offset += recordData.Length;
|
||||
break;
|
||||
case DnsRecordType.CNAME:
|
||||
recordDataAsString = DnsNameParser.ExtractDomainName(responseBytes, ref offset);
|
||||
break;
|
||||
case DnsRecordType.NS:
|
||||
dataAsString = DnsNameParser.ExtractDomainName(responseBytes, ref offset);
|
||||
recordDataAsString = DnsNameParser.ExtractDomainName(responseBytes, ref offset);
|
||||
break;
|
||||
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);
|
||||
dataAsString = $"{preference} {exchange}";
|
||||
recordDataAsString = $"{preference} {exchange}";
|
||||
break;
|
||||
case DnsRecordType.TXT:
|
||||
dataAsString = Encoding.ASCII.GetString(responseBytes, offset, dataLength);
|
||||
offset += dataLength;
|
||||
recordDataAsString = Encoding.ASCII.GetString(recordData);
|
||||
break;
|
||||
default:
|
||||
offset += dataLength;
|
||||
|
@ -273,10 +313,19 @@ namespace EonaCat.DnsTester.Helpers
|
|||
Type = type,
|
||||
Class = klass,
|
||||
Ttl = TimeSpan.FromSeconds(ttl),
|
||||
Data = dataAsString,
|
||||
DataLength = (ushort)dataLength,
|
||||
Data = recordDataAsString,
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -322,11 +371,35 @@ namespace EonaCat.DnsTester.Helpers
|
|||
|
||||
public enum DnsRecordClass : ushort
|
||||
{
|
||||
/// <summary>
|
||||
/// The Internet.
|
||||
/// </summary>
|
||||
Internet = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The CSNET class (Obsolete - used only for examples insome obsolete RFCs).
|
||||
/// </summary>
|
||||
CS = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The CHAOS class.
|
||||
/// </summary>
|
||||
CH = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Hesiod[Dyer 87].
|
||||
/// </summary>
|
||||
HS = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Used in UPDATE message to signify no class.
|
||||
/// </summary>
|
||||
None = 254,
|
||||
|
||||
/// <summary>
|
||||
/// Only used in QCLASS.
|
||||
/// </summary>
|
||||
/// <seealso cref="Question.Class"/>
|
||||
ANY = 255
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace EonaCat.DnsTester.Helpers
|
|||
{
|
||||
public static string ParseName(byte[] responseBytes, ref int offset)
|
||||
{
|
||||
List<string> labels = new List<string>();
|
||||
var labels = new List<string>();
|
||||
int length;
|
||||
|
||||
while ((length = responseBytes[offset++]) != 0)
|
||||
|
@ -15,8 +15,8 @@ namespace EonaCat.DnsTester.Helpers
|
|||
if ((length & 0xC0) == 0xC0)
|
||||
{
|
||||
// The name is compressed
|
||||
int pointer = ((length & 0x3F) << 8) | responseBytes[offset++];
|
||||
int savedOffset = offset;
|
||||
var pointer = ((length & 0x3F) << 8) | responseBytes[offset++];
|
||||
var savedOffset = offset;
|
||||
offset = pointer;
|
||||
labels.AddRange(ParseName(responseBytes, ref offset).Split('.'));
|
||||
offset = savedOffset;
|
||||
|
@ -24,7 +24,7 @@ namespace EonaCat.DnsTester.Helpers
|
|||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -33,11 +33,11 @@ namespace EonaCat.DnsTester.Helpers
|
|||
|
||||
public static string ExtractDomainName(byte[] buffer, ref int offset)
|
||||
{
|
||||
List<string> labels = new List<string>();
|
||||
var labels = new List<string>();
|
||||
|
||||
while (true)
|
||||
{
|
||||
byte labelLength = buffer[offset++];
|
||||
var labelLength = buffer[offset++];
|
||||
|
||||
if (labelLength == 0)
|
||||
{
|
||||
|
@ -47,12 +47,12 @@ namespace EonaCat.DnsTester.Helpers
|
|||
if ((labelLength & 0xC0) == 0xC0)
|
||||
{
|
||||
// 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));
|
||||
break;
|
||||
}
|
||||
|
||||
string label = Encoding.ASCII.GetString(buffer, offset, labelLength);
|
||||
var label = Encoding.ASCII.GetString(buffer, offset, labelLength);
|
||||
labels.Add(label);
|
||||
offset += labelLength;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -10,84 +10,95 @@ namespace EonaCat.DnsTester.Helpers
|
|||
{
|
||||
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 bool UseSearchEngineYahoo { get; set; }
|
||||
public static bool UseSearchEngineBing { get; set; }
|
||||
public static bool UseSearchEngineGoogle { get; set; }
|
||||
public static bool UseSearchEngineQwant { get; set; }
|
||||
public static bool UseSearchEngineAsk { get; set; }
|
||||
public static bool UseSearchEngineWolfram { get; set; }
|
||||
public static bool UseSearchEngineStartPage { 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 searchEngineUrls = GetSearchEngines();
|
||||
var rand = new Random();
|
||||
var urls = new List<string>();
|
||||
|
||||
List<string> urls = new List<string>();
|
||||
|
||||
Parallel.ForEach(searchEngineUrls, searchEngine =>
|
||||
while (urls.Count < totalUrls)
|
||||
{
|
||||
if (urls.Count >= totalUrls)
|
||||
return;
|
||||
var index = rand.Next(searchEngineUrls.Count);
|
||||
var searchEngine = searchEngineUrls.ElementAt(index);
|
||||
var url = searchEngine.Value + letters;
|
||||
|
||||
string url = searchEngine.Value + letters;
|
||||
|
||||
using (var client = new WebClient())
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
string responseString = null;
|
||||
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)
|
||||
{
|
||||
// Handle exceptions (optional)
|
||||
searchEngineUrls.Remove(searchEngine.Key);
|
||||
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);
|
||||
SetStatus($"{urls.Count} random {urlText} found");
|
||||
return urls;
|
||||
}
|
||||
|
||||
|
||||
private static Dictionary<string, string> GetSearchEngines()
|
||||
{
|
||||
Dictionary<string, string> searchEngineUrls = new Dictionary<string, string>();
|
||||
var searchEngineUrls = new Dictionary<string, string>();
|
||||
if (UseSearchEngineYahoo)
|
||||
{
|
||||
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=");
|
||||
}
|
||||
|
||||
if (UseSearchEngineAsk)
|
||||
{
|
||||
searchEngineUrls.Add("Ask", "https://www.ask.com/web?q=");
|
||||
}
|
||||
|
||||
if (UseSearchEngineWolfram)
|
||||
{
|
||||
searchEngineUrls.Add("WolframAlpha", "https://www.wolframalpha.com/input/?i=");
|
||||
|
@ -131,18 +137,20 @@ namespace EonaCat.DnsTester.Helpers
|
|||
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);
|
||||
lock (urlList)
|
||||
{
|
||||
urlList.AddRange(threadUrls);
|
||||
}
|
||||
});
|
||||
tasks[i] = Task.Run(async () => urlList.AddRange(await GetRandomUrlsAsync(numUrlsPerThread).ConfigureAwait(false)));
|
||||
}
|
||||
|
||||
// wait for all threads to complete
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
|
||||
return urlList;
|
||||
}
|
||||
|
@ -150,8 +158,8 @@ namespace EonaCat.DnsTester.Helpers
|
|||
private static string GetRandomLetters()
|
||||
{
|
||||
// Generate a cryptographically strong random string
|
||||
byte[] randomBytes = new byte[32];
|
||||
_randomNumberGenerator.GetBytes(randomBytes);
|
||||
var randomBytes = new byte[32];
|
||||
RandomNumberGenerator.GetBytes(randomBytes);
|
||||
return Convert.ToBase64String(randomBytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
checkBox7 = new System.Windows.Forms.CheckBox();
|
||||
checkBox6 = new System.Windows.Forms.CheckBox();
|
||||
checkBox5 = new System.Windows.Forms.CheckBox();
|
||||
checkBox4 = new System.Windows.Forms.CheckBox();
|
||||
checkBox3 = new System.Windows.Forms.CheckBox();
|
||||
checkBox2 = new System.Windows.Forms.CheckBox();
|
||||
checkBox1 = new System.Windows.Forms.CheckBox();
|
||||
|
@ -108,6 +107,7 @@
|
|||
//
|
||||
// tabPage1
|
||||
//
|
||||
tabPage1.BackColor = System.Drawing.Color.LightGray;
|
||||
tabPage1.Controls.Add(panel2);
|
||||
tabPage1.Controls.Add(panel1);
|
||||
tabPage1.Location = new System.Drawing.Point(10, 58);
|
||||
|
@ -116,16 +116,14 @@
|
|||
tabPage1.Size = new System.Drawing.Size(2239, 1449);
|
||||
tabPage1.TabIndex = 0;
|
||||
tabPage1.Text = "Dns tester";
|
||||
tabPage1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
panel2.BackColor = System.Drawing.SystemColors.ControlLight;
|
||||
panel2.BackColor = System.Drawing.Color.Gold;
|
||||
panel2.Controls.Add(checkBox8);
|
||||
panel2.Controls.Add(checkBox7);
|
||||
panel2.Controls.Add(checkBox6);
|
||||
panel2.Controls.Add(checkBox5);
|
||||
panel2.Controls.Add(checkBox4);
|
||||
panel2.Controls.Add(checkBox3);
|
||||
panel2.Controls.Add(checkBox2);
|
||||
panel2.Controls.Add(checkBox1);
|
||||
|
@ -142,7 +140,7 @@
|
|||
checkBox8.AutoSize = true;
|
||||
checkBox8.Checked = true;
|
||||
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.Size = new System.Drawing.Size(143, 45);
|
||||
checkBox8.TabIndex = 70;
|
||||
|
@ -154,7 +152,7 @@
|
|||
checkBox7.AutoSize = true;
|
||||
checkBox7.Checked = true;
|
||||
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.Size = new System.Drawing.Size(150, 45);
|
||||
checkBox7.TabIndex = 69;
|
||||
|
@ -166,7 +164,7 @@
|
|||
checkBox6.AutoSize = true;
|
||||
checkBox6.Checked = true;
|
||||
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.Size = new System.Drawing.Size(181, 45);
|
||||
checkBox6.TabIndex = 68;
|
||||
|
@ -178,31 +176,19 @@
|
|||
checkBox5.AutoSize = true;
|
||||
checkBox5.Checked = true;
|
||||
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.Size = new System.Drawing.Size(244, 45);
|
||||
checkBox5.TabIndex = 67;
|
||||
checkBox5.Text = "WolframAlpha";
|
||||
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.AutoSize = true;
|
||||
checkBox3.Checked = true;
|
||||
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.Size = new System.Drawing.Size(154, 45);
|
||||
checkBox3.TabIndex = 65;
|
||||
|
@ -214,7 +200,7 @@
|
|||
checkBox2.AutoSize = true;
|
||||
checkBox2.Checked = true;
|
||||
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.Size = new System.Drawing.Size(115, 45);
|
||||
checkBox2.TabIndex = 64;
|
||||
|
@ -226,7 +212,7 @@
|
|||
checkBox1.AutoSize = true;
|
||||
checkBox1.Checked = true;
|
||||
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.Size = new System.Drawing.Size(138, 45);
|
||||
checkBox1.TabIndex = 63;
|
||||
|
@ -246,6 +232,7 @@
|
|||
//
|
||||
// StatusBox
|
||||
//
|
||||
StatusBox.BackColor = System.Drawing.Color.OldLace;
|
||||
StatusBox.FormattingEnabled = true;
|
||||
StatusBox.HorizontalScrollbar = true;
|
||||
StatusBox.ItemHeight = 41;
|
||||
|
@ -257,6 +244,7 @@
|
|||
//
|
||||
// ResultView
|
||||
//
|
||||
ResultView.BackColor = System.Drawing.Color.OldLace;
|
||||
ResultView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { Url, DNS1DATA, DNS1Performance, DNS2DATA, DNS2Performance });
|
||||
ResultView.GridLines = true;
|
||||
ResultView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
|
||||
|
@ -300,7 +288,7 @@
|
|||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.BackColor = System.Drawing.SystemColors.ControlLight;
|
||||
panel1.BackColor = System.Drawing.Color.Gold;
|
||||
panel1.Controls.Add(numericUpDown2);
|
||||
panel1.Controls.Add(label2);
|
||||
panel1.Controls.Add(comboBox1);
|
||||
|
@ -578,6 +566,7 @@
|
|||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
|
||||
AutoSize = true;
|
||||
AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
BackColor = System.Drawing.SystemColors.MenuHighlight;
|
||||
ClientSize = new System.Drawing.Size(2517, 1693);
|
||||
Controls.Add(tabControl1);
|
||||
Controls.Add(RunTest);
|
||||
|
@ -647,7 +636,6 @@
|
|||
private System.Windows.Forms.CheckBox checkBox7;
|
||||
private System.Windows.Forms.CheckBox checkBox6;
|
||||
private System.Windows.Forms.CheckBox checkBox5;
|
||||
private System.Windows.Forms.CheckBox checkBox4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using EonaCat.DnsTester.Helpers;
|
||||
|
@ -44,13 +43,13 @@ namespace EonaCat.DnsTester
|
|||
return;
|
||||
}
|
||||
|
||||
List<string> urls = new List<string>();
|
||||
var urls = new List<string>();
|
||||
SetupView();
|
||||
|
||||
|
||||
int numThreads = (int)numericUpDown2.Value; // number of concurrent threads to use
|
||||
int maxUrls = (int)numericUpDown1.Value; // maximum number of unique URLs to retrieve
|
||||
int numUrlsPerThread = maxUrls / numThreads;
|
||||
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;
|
||||
if (numUrlsPerThread == 0)
|
||||
{
|
||||
numUrlsPerThread = maxUrls;
|
||||
|
@ -58,11 +57,11 @@ namespace EonaCat.DnsTester
|
|||
}
|
||||
|
||||
SetSearchEngines();
|
||||
urls = UrlHelper.RetrieveUrls(numThreads, numUrlsPerThread);
|
||||
urls = await UrlHelper.RetrieveUrlsAsync(numThreads, numUrlsPerThread).ConfigureAwait(false);
|
||||
AddUrlToView(urls);
|
||||
|
||||
IsRunning = true;
|
||||
await Process(_recordType, urls.ToArray(), _dnsServer1, _dnsServer2).ConfigureAwait(false);
|
||||
await ProcessAsync(_recordType, urls.ToArray(), _dnsServer1, _dnsServer2).ConfigureAwait(false);
|
||||
IsRunning = false;
|
||||
}
|
||||
|
||||
|
@ -72,7 +71,6 @@ namespace EonaCat.DnsTester
|
|||
UrlHelper.UseSearchEngineBing = checkBox2.Checked;
|
||||
UrlHelper.UseSearchEngineGoogle = checkBox3.Checked;
|
||||
UrlHelper.UseSearchEngineQwant = checkBox8.Checked;
|
||||
UrlHelper.UseSearchEngineAsk = checkBox4.Checked;
|
||||
UrlHelper.UseSearchEngineWolfram = checkBox5.Checked;
|
||||
UrlHelper.UseSearchEngineStartPage = checkBox6.Checked;
|
||||
UrlHelper.UseSearchEngineYandex = checkBox7.Checked;
|
||||
|
@ -127,23 +125,26 @@ namespace EonaCat.DnsTester
|
|||
|
||||
private void AddUrlToView(List<string> urls)
|
||||
{
|
||||
foreach (var currentUrl in urls)
|
||||
ResultView.Invoke(() =>
|
||||
{
|
||||
ListViewItem listURL = new ListViewItem(currentUrl);
|
||||
listURL.SubItems.Add(" ");
|
||||
listURL.SubItems.Add(" ");
|
||||
listURL.SubItems.Add(" ");
|
||||
listURL.SubItems.Add(" ");
|
||||
foreach (var currentUrl in urls)
|
||||
{
|
||||
var listUrl = new ListViewItem(currentUrl);
|
||||
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)
|
||||
{
|
||||
ResultView.EnsureVisible(ResultView.Items.Count - 1);
|
||||
}
|
||||
if (ResultView.Items.Count > 1)
|
||||
{
|
||||
ResultView.EnsureVisible(ResultView.Items.Count - 1);
|
||||
}
|
||||
|
||||
ResultView.Update();
|
||||
ResultView.Update();
|
||||
});
|
||||
Application.DoEvents();
|
||||
}
|
||||
|
||||
|
@ -162,13 +163,13 @@ namespace EonaCat.DnsTester
|
|||
dnsList2.DisplayMember = "name";
|
||||
|
||||
var serverList = Path.Combine(Application.StartupPath, "Servers.xml");
|
||||
DataSet servers1 = new DataSet();
|
||||
DataSet servers2 = new DataSet();
|
||||
var servers1 = new DataSet();
|
||||
var servers2 = new DataSet();
|
||||
servers1.ReadXml(serverList);
|
||||
servers2.ReadXml(serverList);
|
||||
|
||||
DataTable dataTable1 = servers1.Tables[0];
|
||||
DataTable dataTable2 = servers2.Tables[0];
|
||||
var dataTable1 = servers1.Tables[0];
|
||||
var dataTable2 = servers2.Tables[0];
|
||||
dnsList1.DataSource = dataTable1;
|
||||
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)
|
||||
{
|
||||
recordType = DnsRecordType.A;
|
||||
}
|
||||
|
||||
int urlsTotal = urls.Length;
|
||||
var urlsTotal = urls.Length;
|
||||
const string dnsId1 = "Dns1";
|
||||
const string dnsId2 = "Dns2";
|
||||
|
||||
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];
|
||||
await ExecuteDns1(recordType, dnsAddress1, currentUrl, dnsId1, i);
|
||||
await ExecuteDns1Async(recordType, dnsAddress1, currentUrl, dnsId1, i).ConfigureAwait(false);
|
||||
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)
|
||||
{
|
||||
try
|
||||
{
|
||||
DnsResponse response2 = null;
|
||||
byte[] queryBytes2 = DnsHelper.CreateDnsQueryPacket(currentUrl, recordType);
|
||||
response2 = await DnsHelper.SendDnsQueryPacket(dnsId2, dnsAddress2, 53, queryBytes2);
|
||||
var queryBytes2 = DnsHelper.CreateDnsQueryPacket(currentUrl, recordType);
|
||||
response2 = await DnsHelper.SendDnsQueryPacketAsync(dnsId2, dnsAddress2, 53, queryBytes2).ConfigureAwait(false);
|
||||
ProcessResponse(response2);
|
||||
}
|
||||
catch (SocketException socketException)
|
||||
{
|
||||
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"
|
||||
: 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)
|
||||
{
|
||||
if (chkDns1.Checked)
|
||||
|
@ -253,14 +254,14 @@ namespace EonaCat.DnsTester
|
|||
try
|
||||
{
|
||||
DnsResponse response1 = null;
|
||||
byte[] queryBytes1 = DnsHelper.CreateDnsQueryPacket(currentUrl, recordType);
|
||||
response1 = await DnsHelper.SendDnsQueryPacket(dnsId1, dnsAddress1, 53, queryBytes1);
|
||||
var queryBytes1 = DnsHelper.CreateDnsQueryPacket(currentUrl, recordType);
|
||||
response1 = await DnsHelper.SendDnsQueryPacketAsync(dnsId1, dnsAddress1, 53, queryBytes1).ConfigureAwait(false);
|
||||
ProcessResponse(response1);
|
||||
}
|
||||
catch (SocketException socketException)
|
||||
{
|
||||
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"
|
||||
: Convert.ToString(socketException));
|
||||
}
|
||||
|
@ -279,7 +280,7 @@ namespace EonaCat.DnsTester
|
|||
|
||||
private void ProcessResponse(DnsResponse dnsResponse)
|
||||
{
|
||||
if (dnsResponse?.Answers == null || !dnsResponse.Answers.Any())
|
||||
if (dnsResponse == null || dnsResponse?.Answers == null || !dnsResponse.Answers.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -296,7 +297,7 @@ namespace EonaCat.DnsTester
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -308,7 +309,7 @@ namespace EonaCat.DnsTester
|
|||
{
|
||||
case "Dns1":
|
||||
ResultView.Items[i].SubItems[1].Text =
|
||||
Convert.ToString(answer.Data);
|
||||
Convert.ToString(answer.Data) ?? string.Empty;
|
||||
sDeltaTime = Convert.ToString(deltaTime);
|
||||
ResultView.Items[i].SubItems[2].Text =
|
||||
sDeltaTime.Length > 5 ? sDeltaTime.Substring(0, 5) : sDeltaTime;
|
||||
|
@ -321,7 +322,7 @@ namespace EonaCat.DnsTester
|
|||
|
||||
case "Dns2":
|
||||
ResultView.Items[i].SubItems[3].Text =
|
||||
Convert.ToString(answer.Data);
|
||||
Convert.ToString(answer.Data) ?? string.Empty;
|
||||
sDeltaTime = Convert.ToString(deltaTime);
|
||||
ResultView.Items[i].SubItems[4].Text =
|
||||
sDeltaTime.Length > 5 ? sDeltaTime.Substring(0, 5) : sDeltaTime;
|
||||
|
@ -345,13 +346,27 @@ namespace EonaCat.DnsTester
|
|||
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");
|
||||
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)
|
||||
|
@ -361,75 +376,38 @@ namespace EonaCat.DnsTester
|
|||
MessageBox.Show("Please enter a hostname to resolve");
|
||||
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");
|
||||
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)
|
||||
try
|
||||
{
|
||||
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}'");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
MessageBox.Show($"Could not get IP address for hostname '{txtResolveHost.Text}'");
|
||||
}
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void SetStatus(string text)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(StatusBox.Items.Count + 1);
|
||||
sb.AppendLine($"{DateTime.Now} {text}");
|
||||
|
||||
StatusBox.Invoke(() =>
|
||||
{
|
||||
StatusBox.Items.Add(sb.ToString());
|
||||
StatusBox.Items.Add($"{DateTime.Now} {text}");
|
||||
StatusBox.TopIndex = StatusBox.Items.Count - 1;
|
||||
|
||||
if (StatusBox.Items.Count > STATUS_BAR_SIZE)
|
||||
{
|
||||
StatusBox.Items.RemoveAt(0);
|
||||
}
|
||||
|
||||
StatusBox.Update();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 257 KiB After Width: | Height: | Size: 538 KiB |
Loading…
Reference in New Issue