{"id":17454915,"url":"https://github.com/kapetan/dns","last_synced_at":"2025-05-15T11:04:26.267Z","repository":{"id":8024922,"uuid":"9434114","full_name":"kapetan/dns","owner":"kapetan","description":"A DNS library written in C#","archived":false,"fork":false,"pushed_at":"2024-06-06T18:58:21.000Z","size":381,"stargazers_count":422,"open_issues_count":21,"forks_count":129,"subscribers_count":35,"default_branch":"master","last_synced_at":"2025-04-14T18:07:22.046Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kapetan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-04-14T19:32:57.000Z","updated_at":"2025-04-09T18:53:00.000Z","dependencies_parsed_at":"2024-01-05T20:51:57.956Z","dependency_job_id":"fb1bf790-5341-4287-8c17-f5e46c8676a3","html_url":"https://github.com/kapetan/dns","commit_stats":{"total_commits":97,"total_committers":15,"mean_commits":6.466666666666667,"dds":0.1649484536082474,"last_synced_commit":"d8f973cb31040b4c1b013defab437a53eab95995"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapetan%2Fdns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapetan%2Fdns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapetan%2Fdns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapetan%2Fdns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kapetan","download_url":"https://codeload.github.com/kapetan/dns/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248933338,"owners_count":21185460,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-18T01:51:01.988Z","updated_at":"2025-04-14T18:07:26.461Z","avatar_url":"https://github.com/kapetan.png","language":"C#","readme":"﻿# DNS\n\nA DNS library written in C# targeting .NET Standard 2.0. Versions prior to version two (2.0.0) were written for .NET 4 using blocking network operations. Version two and above use asynchronous operations.\n\nAvailable through NuGet.\n\n\tInstall-Package DNS\n\n[![Test](https://github.com/kapetan/dns/actions/workflows/test.yml/badge.svg)](https://github.com/kapetan/dns/actions/workflows/test.yml)\n\n# Usage\n\nThe library exposes a `Request` and `Response` classes for parsing and creating DNS messages. These can be serialized to byte arrays.\n\n```C#\nRequest request = new Request();\n\nrequest.RecursionDesired = true;\nrequest.Id = 123;\n\nUdpClient udp = new UdpClient();\nIPEndPoint google = new IPEndPoint(IPAddress.Parse(\"8.8.8.8\"), 53);\n\n// Send to google's DNS server\nawait udp.SendAsync(request.ToArray(), request.Size, google);\n\nUdpReceiveResult result = await udp.ReceiveAsync();\nbyte[] buffer = result.Buffer;\nResponse response = Response.FromArray(buffer);\n\n// Outputs a human readable representation\nConsole.WriteLine(response);\n```\n\n### Client\n\nThe libray also includes a small client and a proxy server. Using the `ClientRequest` or the `DnsClient` class it is possible to send a request to a Domain Name Server. The request is first sent using UDP, if that fails (response is truncated), the request is sent again using TCP. This behaviour can be changed by supplying an `IRequestResolver` to the client constructor.\n\n```C#\nClientRequest request = new ClientRequest(\"8.8.8.8\");\n\n// Request an IPv6 record for the foo.com domain\nrequest.Questions.Add(new Question(Domain.FromString(\"foo.com\"), RecordType.AAAA));\nrequest.RecursionDesired = true;\n\nIResponse response = await request.Resolve();\n\n// Get all the IPs for the foo.com domain\nIList\u003cIPAddress\u003e ips = response.AnswerRecords\n\t.Where(r =\u003e r.Type == RecordType.AAAA)\n\t.Cast\u003cIPAddressResourceRecord\u003e()\n\t.Select(r =\u003e r.IPAddress)\n\t.ToList();\n```\n\nThe `DnsClient` class contains some conveniance methods for creating instances of `ClientRequest` and resolving domains.\n\n```C#\n// Bind to a Domain Name Server\nDnsClient client = new DnsClient(\"8.8.8.8\");\n\n// Create request bound to 8.8.8.8\nClientRequest request = client.Create();\n\n// Returns a list of IPs\nIList\u003cIPAddress\u003e ips = await client.Lookup(\"foo.com\");\n\n// Get the domain name belonging to the IP (google.com)\nstring domain = await client.Reverse(\"173.194.69.100\");\n```\n\n### Server\n\nThe `DnsServer` class exposes a proxy Domain Name Server (UDP only). You can intercept domain name resolution requests and route them to specified IPs. The server is asynchronous. It also emits an event on every request and every successful resolution.\n\n```C#\n// Proxy to google's DNS\nMasterFile masterFile = new MasterFile();\nDnsServer server = new DnsServer(masterFile, \"8.8.8.8\");\n\n// Resolve these domain to localhost\nmasterFile.AddIPAddressResourceRecord(\"google.com\", \"127.0.0.1\");\nmasterFile.AddIPAddressResourceRecord(\"github.com\", \"127.0.0.1\");\n\n// Log every request\nserver.Requested += (sender, e) =\u003e Console.WriteLine(e.Request);\n// On every successful request log the request and the response\nserver.Responded += (sender, e) =\u003e Console.WriteLine(\"{0} =\u003e {1}\", e.Request, e.Response);\n// Log errors\nserver.Errored += (sender, e) =\u003e Console.WriteLine(e.Exception.Message);\n\n// Start the server (by default it listens on port 53)\nawait server.Listen();\n```\n\nDepending on the application setup the events might be executed on a different thread than the calling thread.\n\nIt's also possible to modify the `request` instance in the `server.Requested` callback.\n\n### Request Resolver\n\nThe `DnsServer`, `DnsClient` and `ClientRequest` classes also accept an instance implementing the `IRequestResolver` interface, which they internally use to resolve DNS requests. Some of the default implementations are `UdpRequestResolver`, `TcpRequestResolver` and `MasterFile` classes. But it's also possible to provide a custom request resolver.\n\n```C#\n// A request resolver that resolves all dns queries to localhost\npublic class LocalRequestResolver : IRequestResolver {\n\tpublic Task\u003cIResponse\u003e Resolve(IRequest request) {\n\t\tIResponse response = Response.FromRequest(request);\n\n\t\tforeach (Question question in response.Questions) {\n\t\t\tif (question.Type == RecordType.A) {\n\t\t\t\tIResourceRecord record = new IPAddressResourceRecord(\n\t\t\t\t\tquestion.Name, IPAddress.Parse(\"127.0.0.1\"));\n\t\t\t\tresponse.AnswerRecords.Add(record);\n\t\t\t}\n\t\t}\n\n\t\treturn Task.FromResult(response);\n\t}\n}\n\n// All dns requests received will be handled by the localhost request resolver\nDnsServer server = new DnsServer(new LocalRequestResolver());\n\nawait server.Listen();\n```\n","funding_links":[],"categories":["Protocols","协议"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkapetan%2Fdns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkapetan%2Fdns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkapetan%2Fdns/lists"}