kapetan / dns Goto Github PK
View Code? Open in Web Editor NEWA DNS library written in C#
License: MIT License
A DNS library written in C#
License: MIT License
hi , thanks for this code.
I need to ipaddress in the Requested event (dns service).
please help me.
how can I get the autodiscover domain from the srv record?
"_autodiscover._tcp." ?
Hey,
Any idea how to implement some cache on the DNS server part?
Thank you
PS: awesome library
Dear kapetan,
Is there any option to sends update to root-hints ?
https://www.iana.org/domains/root/servers
I'm wanna test it on public, but there is no root-hints option !
Hi, I'm kinda new to this whole DNS server thing so please excuse the newbie question - how do I add an NXDOMAIN answer to Response.AnswerRecords?
Good Evening Kapetan,
Forgive, I don't believe this qualifies as an issue per se, however it is an issue for me (: Is there no way to delete a record from or clear the Masterfile?
Thank you for your hard work on the proejct and help with my issue!
Is there any chance of supporting .NET Core with this library?
If it possible to add Support for EDNS, http://en.wikipedia.org/wiki/EDNS
Even if a response is available and passed to the exception's constructor. The Response property is always null.
I'm doing a very basic implementation of the DNS server:
// Resolve these domain to localhost
server.MasterFile.AddIPAddressResourceRecord("test.local", "192.168.1.100");
server.MasterFile.AddIPAddressResourceRecord("*.extrasub.local", "192.168.1.100");
server.MasterFile.AddIPAddressResourceRecord("*.local", "192.168.1.100");
On my Windows machine hosting the DNS server all three records are resolving correctly. However on my Android phone (setup via WiFi on the same network, using the specified DNS), only resolves test.local
and doesn't work for the wildcards.
Any ideas wether this is some DNS protocol thingy or something wrong with the library?
Is there any plans? Or will accept any PRs?
please add a more complex example like register a subdomain
The following is my code -
DnsClient client = new DnsClient(PrimeDns.Config.DnsResolver_1);
ClientRequest request = client.Create();
try
{
mapRow.IpAddressList = await client.Lookup(pDomain);
Console.WriteLine(mapRow.GetStringOfIpAddressList());
mapRow.LastCheckedTime = DateTime.Now;
mapRow.LastUpdatedTime = DateTime.Now;
PrimeDns.Log._LogInformation("Dns Resolved successfully for Domain - " + pDomain, Logger.Logger.CDnsResolver, null);
}
catch(Exception e)
{
PrimeDns.Log._LogError("Error occured while Dns resolution of Domain - " + pDomain, Logger.Logger.CDnsResolver, e);
}
It is giving raise to System.OperationCanceledException.
I am unable to make requests for the root servers. This is what I do in nslookup (on Windows):
> nslookup - 8.8.8.8
Default Server: google-public-dns-a.google.com
Address: 8.8.8.8
> set type=ns
> .
Server: google-public-dns-a.google.com
Address: 8.8.8.8
Non-authoritative answer:
(root) nameserver = c.root-servers.net
(root) nameserver = g.root-servers.net
(root) nameserver = d.root-servers.net
(root) nameserver = b.root-servers.net
(root) nameserver = a.root-servers.net
(root) nameserver = f.root-servers.net
(root) nameserver = l.root-servers.net
(root) nameserver = j.root-servers.net
(root) nameserver = m.root-servers.net
(root) nameserver = e.root-servers.net
(root) nameserver = i.root-servers.net
(root) nameserver = k.root-servers.net
(root) nameserver = h.root-servers.net
However, when I do the following using this library, an incorrect request is sent (when inspected via Wireshark):
var client = new DnsClient("8.8.8.8");
var rootServers = client.Resolve(".", RecordType.NS);
Is there a way to query for the root records? Essentially, what I want to achieve is the equivalent of:
dig +trace example.com
I'm not a .NET guru at all so rather than browser the code I just thought I'd ask for direction.
If I wanted to try to get this to work in .NET 3.5 (or rather Unity3D) can you point me in the direction of the things I'd have to take a look at and what you think might be entailed?
Thank you
How can I create a question for the requester for a reverse lookup? I cannot see how I can pass any argument(s) into the question for it to use for a PTR request?
ClientRequest request = new ClientRequest("192.168.4.0");
request.Questions.Add(new Question(Domain.FromString("192.168.4.1"), RecordType.PTR, RecordClass.ANY));
request.RecursionDesired = true;
ClientResponse response = (ClientResponse)await request.Resolve();
Not a bug, This might be something that was overlooked or unimplemented.
IResourceRecord in IResponse.AnswerRecords is missing IPAddress.
example:
response.AnswerRecords[0].IPAddress
https://github.com/kapetan/dns/blob/master/Examples/Server/ServerExample.cs#L29
await server.Listen();
should be actually returning right? it actually blocks the caller.
Hi @kapetan
I checked your [dns] repository and I need more info about this library. Also I've question.
Can I use this library [Server|Client] for Nat traversal or as UDP tunnel or expose local port to public network?
Thank you for more description and help me.
I have upgraded to V3, it is great having TXT fields abstraction. But in some domains, it is throwing an ArgumentException: "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection."
I found that it is happening when CharacterString.GetAllFromArray()
is called
dns/DNS/Protocol/ResourceRecords/TextResourceRecord.cs
Lines 43 to 46 in 8ae198c
For example, for makingsense.com.
, of message
in base64 is IA+BgAABAAIAAAAAC21ha2luZ3NlbnNlA2NvbQAAEAABwAwAEAABAAADnQBFRGdvb2dsZS1zaXRlLXZlcmlmaWNhdGlvbj1mUTZtaEFzOWlZTEZOWklZSFhJX28yMXNuVUtZbGE5TGgtMDZxOUJWNUpVwAwAEAABAAADnQBAP3Y9c3BmMSBpbmNsdWRlOnNwZi5mcm9tZG9wcGxlci5jb20gaW5jbHVkZTpfc3BmLmdvb2dsZS5jb20gfmFsbA==
and offset
is 45
.
Going deeper, in the 2nd iteration of CharacterString.FromArray()
dns/DNS/Protocol/CharacterString.cs
Lines 38 to 48 in 8ae198c
len
take value of 192
, but offset
is 115
and message.Length
is 190
, so Buffer.BlockCopy(message, offset, data, 0, len);
throws the ArgumentException.
There are a lot of DNS that are throwing that error, I am not sure if DNS data is fine or not, but other tools are reading it fine, for example in this case with MXToolbox.
I would be glad to create a PR with a fix, but my knowledge about DNS standards ir limited.
Do you think that it is possible to apply a workaround to fix or mitigate it?
I created a server and it returns this:
{Id=1814, QuestionCount=1, AnswerRecordCount=0, AuthorityRecordCount=0, AdditionalRecordCount=0, Response=False, OperationCode=Query, AuthorativeServer=False, Truncated=False, RecursionDesired=True, RecursionAvailable=False, ResponseCode=NoError}
System.Collections.Generic.List`1[DNS.Protocol.Question]
0
0
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
at System.Collections.Generic.List`1.get_Item(Int32 index)
at DNS.Protocol.Request.FromArray(Byte[] message)
at DNS.Server.DnsServer.<>c__DisplayClass5.<Listen>b__0()
Any chance of you converting this to a Portable Class Library?
I needed a far more dynamic answer for my DNS server so I modified the code so that DnsServer takes a IQuestionAnswerer
(horrible name - suggest a new one). MasterFile
is then an implementor of IQuestionAnswerer
.
This has a few advantages
IQuestionAnswerer
.MasterFile
on DnsServer
.Any interest in this? Should I turn it into a PR?
Source of the problem is in the Request.FromArray method
The header.AdditionalRecordCount is always larger than one and therefore an exception is thrown.
Hi, very nice project!
I ran into the following behavior:
Request.FromArray(udpPacket.PayloadData)
throws an exception for the following payload
[0]: 0x71
[1]: 0x2e
[2]: 0x28
[3]: 0x00
[4]: 0x00
[5]: 0x01
[6]: 0x00
[7]: 0x01
[8]: 0x00
[9]: 0x03
[10]: 0x00
[11]: 0x00
[12]: 0x05
[13]: 0x67
[14]: 0x64
[15]: 0x61
[16]: 0x74
[17]: 0x61
[18]: 0x02
[19]: 0x64
[20]: 0x65
[21]: 0x00
[22]: 0x00
[23]: 0x06
[24]: 0x00
[25]: 0x01
[26]: 0x0a
[27]: 0x49
[28]: 0x44
[29]: 0x2d
[30]: 0x43
[31]: 0x48
[32]: 0x2d
[33]: 0x30
[34]: 0x33
[35]: 0x30
[36]: 0x34
[37]: 0x05
[38]: 0x67
[39]: 0x64
[40]: 0x61
[41]: 0x74
[42]: 0x61
[43]: 0x02
[44]: 0x64
[45]: 0x65
[46]: 0x00
[47]: 0x00
[48]: 0x05
[49]: 0x00
[50]: 0xfe
[51]: 0x00
[52]: 0x00
[53]: 0x00
[54]: 0x00
[55]: 0x00
[56]: 0x00
[57]: 0xc0
[58]: 0x1a
[59]: 0x00
[60]: 0x1c
[61]: 0x00
[62]: 0xff
[63]: 0x00
[64]: 0x00
[65]: 0x00
[66]: 0x00
[67]: 0x00
[68]: 0x00
[69]: 0xc0
[70]: 0x1a
[71]: 0x00
[72]: 0x01
[73]: 0x00
[74]: 0xff
[75]: 0x00
[76]: 0x00
[77]: 0x00
[78]: 0x00
[79]: 0x00
[80]: 0x00
[81]: 0xc0
[82]: 0x1a
[83]: 0x00
[84]: 0x01
[85]: 0x00
[86]: 0x01
[87]: 0x00
[88]: 0x00
[89]: 0x04
[90]: 0xb0
[91]: 0x00
[92]: 0x04
[93]: 0x0a
[94]: 0x32
[95]: 0x04
[96]: 0x1f
The UDPPacket itself has the following information attached:
{[UDPPacket: SourcePort=51027, DestinationPort=53]}
Bytes: {byte[0x00000069]}
BytesHighPerformance: {[ByteArraySegment: Length=105, Bytes.Length=139, BytesLength=139, Offset=34, NeedsCopyForActualBytes=True]}
Checksum: 0x1939
Color: "\u001b[1;32m"
DestinationPort: 0x0035
Header: {[ByteArraySegment: Length=8, Bytes.Length=139, BytesLength=139, Offset=34, NeedsCopyForActualBytes=True]}
HeaderData: {byte[0x00000008]}
Length: 0x00000069
ParentPacket: {[IPv4Packet: SourceAddress=10.50.4.31, DestinationAddress=10.10.0.100, HeaderLength=5, Protocol=UDP, TimeToLive=128][UDPPacket: SourcePort=51027, DestinationPort=53]}
PayloadData: {byte[0x00000061]}
PayloadPacket: null
PayloadPacketOrData: ThreadSafetyMode=null, IsValueCreated=true, IsValueFaulted=false, Value={PacketDotNet.PacketOrByteArraySegment}
SharesMemoryWithSubPackets: true
SourcePort: 0xc753
TotalPacketLength: 0x00000069
ValidChecksum: false
ValidUDPChecksum: false
I'm not sure if the payload is really just invalid and I have to "try-catch" that, or that the parser runs into an error for a valid UDP DNS packet.
Regards secana
Hello!
Can I add a resource record to the server while it's running?
Thanks for the answer.
I have set up the LocalRequestResolver similar to the demo. How do I create the DNS server to listen to a specific IP Address instead of ANY with the Local Request Resolver?
Thank you for this very nice library!
While working with the library I discovered the following bug.
If you try parsing from a byte array a DNS response containing CNAME records with label pointers in the data section, the resulting array from Response.ToArray(), is invalid ( Got bad packet: bad label type with nslookup).
The problem resides from the fact ResourceRecordFactory.FromArray(byte[] message, int offset, out int endOffest) blindly copies the data section while parsing the input array, therefore keeping a pointer to an invalid location if you try converting the response back to an array.
A simple fix would be to change
case RecordType.CNAME:
return new CanonicalNameResourceRecord(record, message, dataOffset);
to
case RecordType.CNAME:
return new CanonicalNameResourceRecord(record.Name, Domain.FromArray(message, dataOffset), record.TimeToLive);
in ResourceRecordFactory.FromArray(byte[] message, int offset, out int endOffest) to get rid of the pointer.
Please find attached to this issue, two dump files.
originalResponse.txt contains the raw DNS Reponse from Cloudlfare's DNS.
generatedResponse.txt contains the reponse generated from first parsing Cloudflare's response, then immediately converting back to an array
var originalResponse = Response.FromArray(payload);
var generatedResponse = originalResponse.ToArray();
As you can see in generatedResponse.txt at offset 0h171, instead of having the label ".net", there is the original pointer (C0 D5) as found in the compressed Response from Cloudlfare.
Hope this can help,
Message Compression i can also not found
http://www.ietf.org/rfc/rfc1035.txt
4.1.4. Message compression
hi, can you add an event: onlookup
Cant the library be compat with NetStandard 1.X?
hi
have an issue: I using local resolver (Not master file) and I need to have a name server [like Microsoft DNS Server config] for an external app like haproxy can calibrate with my DNS server.
how can I do that in this scenario?
am I missing something?
hi, ive tried to redirect my own name record to googles ip.
but the browser dont accept it and googles the name record.
how can i fix it?
thanks
Hi,
I keep getting the below error on running >ServerExample.exe foo.com google.com
Redirecting foo.com to localhost
Redirecting google.com to localhost
Errored: System.Net.Sockets.SocketException (0x80004005): Only one usage of each socket address (protocol/network address/port) is normally permitted
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at System.Net.Sockets.UdpClient..ctor(IPEndPoint localEP)
at DNS.Server.DnsServer.d__26.MoveNext()
Can you tell me why I am getting this error?
Please add support for SRV Record.
Originally posted by @AlexLaroche in #22 (comment)
I need this support as well, i don't mind implementing it my self, would you mind just giving me a brief description on how to do this, or any docs on dns that i might need, then il fork the project and make pr once i get it working ?
Here's my code fragment:
var networkInterface = NetworkInterface
.GetAllNetworkInterfaces()?
.FirstOrDefault(i => i.OperationalStatus == OperationalStatus.Up && i.NetworkInterfaceType != NetworkInterfaceType.Loopback);
if (networkInterface is null) return;
var dns = networkInterface
.GetIPProperties()
.DnsAddresses
.FirstOrDefault(i => i.AddressFamily == AddressFamily.InterNetwork)
?? new IPAddress(new byte[] { 8, 8, 8, 8 });
Client = new DnsClient(dns);
I had to filter my network interface addresses to IPv4 only, because I got following exception on lookup:
An address incompatible with the requested protocol was used
Stack trace:
at System.Net.Sockets.Socket.DoBeginSendTo(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, EndPoint endPointSnapshot, SocketAddress socketAddress, OverlappedAsyncResult asyncResult)
at System.Net.Sockets.Socket.BeginSendTo(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, EndPoint remoteEP, AsyncCallback callback, Object state)
at System.Net.Sockets.UdpClient.BeginSend(Byte[] datagram, Int32 bytes, IPEndPoint endPoint, AsyncCallback requestCallback, Object state)
at System.Threading.Tasks.TaskFactory1.FromAsyncImpl[TArg1,TArg2,TArg3](Func
6 beginMethod, Func2 endFunction, Action
1 endAction, TArg1 arg1, TArg2 arg2, TArg3 arg3, Object state, TaskCreationOptions creationOptions)
at System.Net.Sockets.UdpClient.SendAsync(Byte[] datagram, Int32 bytes, IPEndPoint endPoint)
at DNS.Client.RequestResolver.UdpRequestResolver.d__5.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at DNS.Client.ClientRequest.<Resolve>d__24.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()
at DNS.Client.DnsClient.d__9.MoveNext()
Hi !
Just to note this (subject).
I am using Windows Server 2008 R2,en, Net 4.
It should not happen, that a request keeps pending unlimited.
Regards,
Manfred
Hi. I love this project, it's exactly what I was looking for. Only one thing is missing though, and that is wildcard support when adding new records. This feature would allow me to complete my own project.
Please do consider adding it!
Sincerely, Rottweiler.
I'm writing a custom DNS server that will resolve host-running Docker containers. This DNS server will be added to the list of DNS servers. There is no need for the endpoint server because if I can't resolve the request, I don't want to forward it on, I want the next DNS server configured to try and resolve it.
Apologies if I'm simply just not fluent enough with .NET async to know this myself, but I can't figure out a nice way to make the server stop listening asynchronously besides just terminating the app. In my application I want the server running in another thread but that allows no way to stop the server.
What i've tried:
I'm using the ServerExample (mostly, it's insignificantly modified) in an async function.
I've messed around with GetAwaiter()s and Task.Run() and researched CancellationTokens but the former just doesnt seem to allow cancelling the task and the latter requires I edit the source code of the library.
What's the recommended (if any) way to do this?
File: Request.cs (Line 17)
If I test this DNS server code using "dig @127.0.0.1 google.com", then "header.AdditionalRecordCount" is > 0. It means not a valid request, then exception.
But if I test it using "nslookup google.com 127.0.0.1", "header.AdditionalRecordCount" is == 0. Your code works.
I'm going to set up a geoLocation service using the DNS you have developed. so that I need to get the IP address of the requesting user. please kindly help me how to do so.
Latest code has cancellation token support while NuGet package doesn't.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.