public async Task TestQuery() { using var tokenSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(500)); var endpoint = GenerateEndPoint(); // Create a real upstream DNS client to serve the request (todo: mock this) using var upstream = new DnsUdpClient(IPAddress.Parse("1.1.1.1")); // Create a loopback server using var server = new DnsUdpServer(endpoint, upstream); // Start recieving using var receiveTask = server.Listen(tokenSource.Token); // Create a loopback DNS client to talk to the server using var client = new DnsUdpClient(endpoint); try { var query = DnsQueryFactory.CreateQuery("google.com"); // Send a DNS request to the server, verify the results var response = await client.Query(query, tokenSource.Token); Assert.Equal(query.Id, response.Header.Id); Assert.Equal(query.Host, response.Header.Host); Assert.True(response.Answers.Count > 0); } finally { tokenSource.Cancel(); await receiveTask; } }
private void buttonClientSend_Click(object sender, EventArgs e) { string errorMessage; IPAddress serverAddr; Cursor = Cursors.WaitCursor; buttonClientSend.Enabled = false; if (!ValidateServerText(textBoxClientServer.Text, out errorMessage)) { errorProvider1.SetError(textBoxClientServer, errorMessage); return; } try { // resolve server name by System.Net.Dns serverAddr = System.Net.Dns.GetHostAddresses(textBoxClientServer.Text.Trim()).First(); } catch (SocketException) { errorProvider1.SetError(textBoxClientServer, "Server name cannot be resolved."); return; } try { IDnsClient client; if (radioButtonClientTCP.Checked) { client = new DnsTcpClient(); } else { client = new DnsUdpClient(); } Request request = new Request( (ushort)DateTime.Now.Ticks, checkBoxClientRD.Checked, (OPCODE)Enum.Parse(typeof(OPCODE), comboBoxClientOPCODE.SelectedValue.ToString()), new Question( textBoxClientQNAME.Text.Trim(), (QTYPE)Enum.Parse(typeof(QTYPE), comboBoxClientQTYPE.SelectedValue.ToString()), (QCLASS)Enum.Parse(typeof(QCLASS), comboBoxClientQCLASS.SelectedValue.ToString()))); labelClientResponse.Text = String.Empty; textBoxClientResponse.Text = String.Empty; client.Connect(serverAddr); client.BeginProcess(request, new AsyncCallback(OnClientResponseReceived), new ClientAsyncState { Client = client, Request = request, Server = serverAddr }); //try //{ // client.Connect(serverAddr); // DnsClient.Response response = client.LookUp(request); // labelClientResponse.Text = String.Format("{0}: {1} from [{2}] in {3}ms", // (response.Header.AA ? "Authoritative Response" : "Non-Authoritative Response"), // response.Header.RCODE.ToString(), // serverAddr.ToString(), // response.Timestamp.Subtract(request.Timestamp).TotalMilliseconds); // StringBuilder result = new StringBuilder(); // RenderResponse(response, result); // textBoxClientResponse.Text = result.ToString(); //} //finally //{ // Cursor = Cursors.Default; // buttonClientSend.Enabled = true; //} } catch (Exception ex) { MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public void TestCleanup() { this.client?.Dispose(); this.client = null; }
public void TestInitialize() { this.client = new DnsUdpClient(); }
static void Main(string[] args) { try { File.Delete(filename); bool interactive = false; NameServer selected = null; while (true) { if (File.Exists(filename)) { using (DnsUdpClient client = new DnsUdpClient()) { client.Client.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket, System.Net.Sockets.SocketOptionName.ReceiveTimeout, 1000); client.LogMessageCreated += new LogMessageEventHandler(OnLogMessage); ResolutionIterator iterator = DeSerializeObject <ResolutionIterator>(filename); iterator.Resolver.Connect(client); if (iterator.MoveNext(selected)) { Console.WriteLine(); ResolutionResult result = iterator.Current; //Console.WriteLine("Response from {0} - chosen from {1} authorities", result.Authorities.Selected.Name, result.Authorities.ZoneName); //foreach (NameServer ns in result.Authorities) //{ // Console.WriteLine(" {0}", ns); //} Console.WriteLine("Took {0}ms:", result.Duration.TotalMilliseconds); RenderResponse(result.Response); if (interactive) { selected = null; if (result.NextAuthorities != null) { Console.WriteLine(); Console.WriteLine("Next authorities:"); int i = 1; foreach (NameServer ns in result.NextAuthorities) { Console.WriteLine(" ({0}) {1}", i, ns.ToString()); i++; } while (true) { Console.Write("Select next authority or ENTER for random: "); int s; string choice = Console.ReadLine(); if (!String.IsNullOrEmpty(choice)) { if (int.TryParse(choice, out s)) { if (s >= 1 && s <= result.NextAuthorities.Count) { selected = result.NextAuthorities[s - 1]; break; } } } else { break; } } } } SerializeObject <ResolutionIterator>(filename, iterator); Console.WriteLine("===================================="); } else { Console.WriteLine("finished."); File.Delete(filename); } } } else { DnsDomain domain = null; QTYPE question; try { Console.Write("enter name: "); domain = DnsDomain.Parse(Console.ReadLine().Trim()); } catch (Exception ex) { Console.WriteLine(ex.Message); goto next; } try { Console.Write("enter question: "); question = (QTYPE)Enum.Parse(typeof(QTYPE), Console.ReadLine().Trim(), true); } catch (Exception ex) { Console.WriteLine(ex.Message); goto next; } Console.WriteLine("OK: {0} IN {1}", domain, question.ToString()); DomainResolver resolver = new DomainResolver(Options.Default, domain); ResolutionIterator iterator = resolver.GetIterator(question); iterator.LogMessageCreated += new LogMessageEventHandler(OnLogMessage); SerializeObject <ResolutionIterator>(filename, iterator); } next: Console.WriteLine(); Console.WriteLine("type 'q' to quit, ENTER to continue."); ConsoleKeyInfo ck = Console.ReadKey(); if (ck.KeyChar == 'q') { break; } } } catch (Exception ex) { Console.WriteLine(ex); } }
public async Task TestLookupTimeout() { // Reserved - see https://en.wikipedia.org/wiki/Reserved_IP_addresses using var client = new DnsUdpClient(new NullLogger <DnsUdpClient>(), IPAddress.Parse("192.88.99.0")); await Assert.ThrowsAsync <DnsClientTimeoutException>(() => client.Query(DnsQueryFactory.CreateQuery("alanedwardes.com"), CancellationToken.None)); }
public async Task TestLookupWithGoogle(string domain, DnsQueryType type) { using var client = new DnsUdpClient(new NullLogger <DnsUdpClient>(), IPAddress.Parse("8.8.8.8")); await client.RunQuery(domain, type); }
public async Task TestLookupWithCloudFlare(string domain, DnsQueryType type) { using var client = new DnsUdpClient(new NullLogger <DnsUdpClient>(), IPAddress.Parse("1.1.1.1")); await client.RunQuery(domain, type, type == DnsQueryType.ANY?DnsResponseCode.NotImp : DnsResponseCode.NoError); }
/// <summary> /// Resolves a DNS name. /// </summary> /// <param name="Name">Domain Name to resolve</param> /// <param name="TYPE">Resource Record Type of interest.</param> /// <param name="ExceptionType">If no answer of type <paramref name="TYPE"/> is found, records of this type can also be accepted.</param> /// <param name="CLASS">Resource Record Class of interest.</param> /// <returns>Answer to the query</returns> /// <exception cref="IOException">If the domain name could not be resolved for the TYPE and CLASS provided.</exception> public static async Task <ResourceRecord[]> Resolve(string Name, QTYPE TYPE, TYPE?ExceptionType, QCLASS CLASS) { LinkedList <KeyValuePair <string, IPEndPoint> > Backup = null; TYPE? ExpectedType; IPEndPoint Destination = null; string LastName = null; int Timeout = 2000; // Local timeout if (Enum.TryParse <TYPE>(TYPE.ToString(), out TYPE T)) { ExpectedType = T; } else { ExpectedType = null; } lock (synchObject) { if (nestingDepth == 0 && networkChanged) { networkChanged = false; client?.Dispose(); client = null; } if (client is null) { client = new DnsUdpClient(); } nestingDepth++; } try { while (true) { DnsResponse Response = null; DnsMessage Message; if (LastName is null || LastName != Name) { LastName = Name; try { Response = await Database.FindFirstDeleteRest <DnsResponse>(new FilterAnd( new FilterFieldEqualTo("Name", Name), new FilterFieldEqualTo("Type", TYPE), new FilterFieldEqualTo("Class", CLASS))); if (!(Response is null) && Response.Expires <= DateTime.Now) { await Database.Delete(Response); Response = null; } } catch (Exception) { // Some inconsistency in database. Clear collection to get fresh set of DNS entries. await Database.Clear("DnsCache"); Response = null; } } if (Response is null) { try { Message = await client.SendRequestAsync(OpCode.Query, true, new Question[] { new Question(Name, TYPE, CLASS) }, Destination, Timeout); switch (Message.RCode) { case RCode.NXDomain: throw new ArgumentException("Domain name does not exist.", nameof(Name)); } } catch (TimeoutException) { Message = null; } if (Message is null || Message.RCode != RCode.NoError) { Destination = await NextDestination(Backup); if (Destination is null) { throw new IOException("Unable to resolve DNS query."); } continue; // Check an alternative } uint Ttl = 60 * 60 * 24 * 30; // Maximum TTL = 30 days Response = new DnsResponse() { Name = Name, Type = TYPE, Class = CLASS, Answer = CheckTtl(ref Ttl, Message.Answer), Authority = CheckTtl(ref Ttl, Message.Authority), Additional = CheckTtl(ref Ttl, Message.Additional) }; Response.Expires = DateTime.Now.AddSeconds(Ttl); await Database.Insert(Response); } string CName = null; if (!(Response.Answer is null)) { if (!ExpectedType.HasValue) { return(Response.Answer); } foreach (ResourceRecord RR in Response.Answer) { if (RR.Type == ExpectedType.Value) { return(Response.Answer); } if (CName is null && RR.Type == Enumerations.TYPE.CNAME && RR is CNAME CNAME) { CName = CNAME.Name2; } } if (ExceptionType.HasValue) { foreach (ResourceRecord RR in Response.Answer) { if (RR.Type == ExceptionType.Value) { return(Response.Answer); } } } if (!(CName is null)) { Name = CName; Backup = null; continue; } } if (!(Response.Authority is null)) { foreach (ResourceRecord RR in Response.Authority) { if (RR is NS NS) { string Authority = NS.Name2; IPAddress AuthorityAddress = null; if (!(Response.Additional is null)) { foreach (ResourceRecord RR2 in Response.Additional) { if (RR2 is A A) { AuthorityAddress = A.Address; break; } else if (RR2 is AAAA AAAA) { AuthorityAddress = AAAA.Address; break; } } } if (Backup is null) { Backup = new LinkedList <KeyValuePair <string, IPEndPoint> >(); } if (AuthorityAddress is null) { Backup.AddLast(new KeyValuePair <string, IPEndPoint>(Authority, null)); } else { Backup.AddLast(new KeyValuePair <string, IPEndPoint>(null, new IPEndPoint(AuthorityAddress, DefaultDnsPort))); } } } } Destination = await NextDestination(Backup); if (Destination is null) { throw new IOException("Unable to resolve DNS query."); } Timeout = 5000; } } finally { lock (synchObject) { nestingDepth--; } } }