-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DNS: Add POSIX DNS implementation #334
Draft
0x5ECF4ULT
wants to merge
14
commits into
dotnet:develop
Choose a base branch
from
0x5ECF4ULT:posix-dns-implementation-using-native-code
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
7ddab55
DNS: Add POSIX DNS implementation
0x5ECF4ULT 37d6cb1
DNS: Conform to language level
0x5ECF4ULT 54e6a36
DNS: Auto-detect DNS implementation
0x5ECF4ULT df5bed8
Core: Bump language version
0x5ECF4ULT 7600d67
DNS: Return from static constructor
0x5ECF4ULT 871508b
DNS: generalize the Debug parameter
0x5ECF4ULT 8cdc022
Bruce: add required debug flag to the cross-plat DNS client
0x5ECF4ULT ce750ea
Tests: add missing debug flag to the fake DNS impl
0x5ECF4ULT 1ae9709
Tests: honor case-sensitivity
0x5ECF4ULT 64a700c
Bruce: make it buildable on Linux
0x5ECF4ULT 688396d
KerbDumpCore: make it buildable on Linux
0x5ECF4ULT c3982f6
Tests: more cases of not honoring filesystem case-sensitivity
0x5ECF4ULT c731db1
Tests: disabling tests that use unsupported crypto for Linux
0x5ECF4ULT 7eedd69
Tests: conditionally disable tests that are supposed to run on a spec…
0x5ECF4ULT File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
// ----------------------------------------------------------------------- | ||
// Licensed to The .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// ----------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Buffers; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Net; | ||
using System.Net.NetworkInformation; | ||
using System.Runtime.InteropServices; | ||
using System.Text; | ||
|
||
namespace Kerberos.NET.Dns | ||
{ | ||
public unsafe class DnsQueryPOSIX | ||
{ | ||
private const int NS_PACKETSZ = 512; | ||
private const int NS_MAXDNAME = 1025; | ||
|
||
private const string LIBC = "libc.so"; | ||
|
||
[DllImport(LIBC, EntryPoint = "res_query")] | ||
private static extern short ResQuery( | ||
[MarshalAs(UnmanagedType.LPStr)] string dname, | ||
NsClass @class, | ||
DnsRecordType type, | ||
char[] answer, | ||
int anslen | ||
); | ||
|
||
[DllImport(LIBC, EntryPoint = "ns_initparse")] | ||
private static extern short NsInitParse( | ||
// [MarshalAs(UnmanagedType.LPStr)] string msg, | ||
char[] msg, | ||
short msglen, | ||
NsMsg* handle | ||
); | ||
|
||
[DllImport(LIBC, EntryPoint = "ns_msg_count")] | ||
private static extern ushort NsMsgCount( | ||
NsMsg handle, | ||
NsSect section | ||
); | ||
|
||
[DllImport(LIBC, EntryPoint = "ns_parserr")] | ||
private static extern short NsParserr( | ||
NsMsg* handle, | ||
NsSect section, | ||
short rrnum, | ||
NsRr* rr | ||
); | ||
|
||
[DllImport(LIBC, EntryPoint = "ns_rr_type")] | ||
private static extern DnsRecordType NsRrType( | ||
NsRr rr | ||
); | ||
|
||
[DllImport(LIBC, EntryPoint = "ns_msg_base")] | ||
private static extern string NsMsgBase( | ||
NsMsg handle | ||
); | ||
|
||
[DllImport(LIBC, EntryPoint = "ns_msg_end")] | ||
private static extern string NsMsgEnd( | ||
NsMsg handle | ||
); | ||
|
||
[DllImport(LIBC, EntryPoint = "ns_rr_rdata")] | ||
private static extern string NsRrRdata( | ||
NsRr rr | ||
); | ||
|
||
[DllImport(LIBC, EntryPoint = "dn_expand")] | ||
private static extern short DnExpand( | ||
[MarshalAs(UnmanagedType.LPStr)] string msg, | ||
[MarshalAs(UnmanagedType.LPStr)] string eomorig, | ||
[MarshalAs(UnmanagedType.LPStr)] string comp_dn, | ||
StringBuilder exp_dn, | ||
short length | ||
); | ||
|
||
[DllImport(LIBC, EntryPoint = "ns_rr_name")] | ||
private static extern string NsRrName( | ||
NsRr rr | ||
); | ||
|
||
[DllImport(LIBC, EntryPoint = "inet_ntoa")] | ||
private static extern string InetNToA( | ||
InAddr @in | ||
); | ||
|
||
public static IReadOnlyCollection<DnsRecord> QuerySrvRecord( | ||
string query, | ||
DnsRecordType type, | ||
DnsQueryOptions options = DnsQueryOptions.BypassCache) | ||
{ | ||
var list = new List<DnsRecord>(); | ||
var buffer = new char[NS_PACKETSZ]; | ||
|
||
short respLen = -1; | ||
if ((respLen = ResQuery(query, NsClass.NsCIn, type, buffer, NS_PACKETSZ)) < 0) | ||
throw new Exception($"Query for {query} failed!"); | ||
|
||
NsMsg handle; | ||
if (NsInitParse(buffer, respLen, &handle) < 0) | ||
throw new Exception("Failed to parse response buffer!"); | ||
|
||
var count = NsMsgCount(handle, NsSect.NsSAn); | ||
Debug.WriteLine($"{count} records returned in the answer section."); | ||
|
||
for (short i = 0; i < count; i++) | ||
{ | ||
NsRr rr; | ||
if (NsParserr(&handle, NsSect.NsSAn, i, &rr) < 0) | ||
throw new Exception("ns_parserr: TODO strerror"); | ||
|
||
if (NsRrType(rr) != DnsRecordType.SRV) continue; | ||
|
||
var name = new StringBuilder(1025); | ||
short ret; | ||
if ((ret = DnExpand(NsMsgBase(handle), | ||
NsMsgEnd(handle), | ||
NsRrRdata(rr) + 6, | ||
name, | ||
1025)) < 0) | ||
throw new Exception($"Failed to uncompress name ({ret})"); | ||
|
||
Debug.WriteLine(name); | ||
|
||
var p = NsRrRdata(rr); | ||
var ip = new InAddr | ||
{ | ||
s_addr = ((uint) p[3] << 24) | ((uint) p[2] << 16) | ((uint) p[1] << 8) | p[0] | ||
}; | ||
|
||
list.Add(new DnsRecord | ||
{ | ||
Target = InetNToA(ip), | ||
Name = rr.name.ToString(), | ||
//Port = | ||
//Priority = | ||
TimeToLive = (int) rr.ttl, | ||
Type = rr.type, | ||
//Weight = rr. | ||
}); | ||
} | ||
|
||
for (short i = 0; i < NsMsgCount(handle, NsSect.NsSAr); i++) | ||
{ | ||
NsRr rr; | ||
if (NsParserr(&handle, NsSect.NsSAr, i, &rr) < 0) | ||
throw new Exception("ns_parserr: TODO strerror"); | ||
|
||
if (NsRrType(rr) != DnsRecordType.A) continue; | ||
|
||
var p = NsRrRdata(rr); | ||
var ip = new InAddr | ||
{ | ||
s_addr = ((uint) p[3] << 24) | ((uint) p[2] << 16) | ((uint) p[1] << 8) | p[0] | ||
}; | ||
|
||
Debug.WriteLine($"{NsRrName(rr)} has address {InetNToA(ip)}"); | ||
|
||
list.Add(new DnsRecord | ||
{ | ||
Type = rr.type, | ||
Name = rr.name.ToString(), | ||
Target = InetNToA(ip) | ||
}); | ||
} | ||
|
||
return list; | ||
} | ||
|
||
private struct InAddr | ||
{ | ||
public uint s_addr; | ||
} | ||
|
||
private struct NsRr | ||
{ | ||
[MarshalAs(UnmanagedType.LPArray, SizeConst = NS_PACKETSZ)] | ||
public char[] name; | ||
public DnsRecordType type; | ||
public ushort rr_class; | ||
public uint ttl; | ||
public ushort rdlength; | ||
[MarshalAs(UnmanagedType.LPStr)] | ||
public string rdata; | ||
} | ||
|
||
private enum NsSect | ||
{ | ||
NsSQd = 0, /*%< Query: Question. */ | ||
NsSZn = 0, /*%< Update: Zone. */ | ||
NsSAn = 1, /*%< Query: Answer. */ | ||
NsSPr = 1, /*%< Update: Prerequisites. */ | ||
NsSNs = 2, /*%< Query: Name servers. */ | ||
NsSUd = 2, /*%< Update: Update. */ | ||
NsSAr = 3, /*%< Query|Update: Additional records. */ | ||
NsSMax = 4 | ||
} | ||
|
||
private struct NsMsg | ||
{ | ||
[MarshalAs(UnmanagedType.LPStr)] public string _msg, _eom; | ||
public ushort _id, _flags; | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NsSect.NsSMax)] | ||
public ushort[] _counts; | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = (int) NsSect.NsSMax)] | ||
public string[] _sections; | ||
public NsSect _sect; | ||
public short _rrnum; | ||
[MarshalAs(UnmanagedType.LPStr)] | ||
public string _msg_ptr; | ||
} | ||
|
||
private enum NsClass : ushort | ||
{ | ||
NsCInvalid, | ||
NsCIn, | ||
NsC2, | ||
NsCChaos, | ||
NsCHs, | ||
NsCNone = 254, | ||
NsCAny, | ||
NsCMax = 65535 | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// ----------------------------------------------------------------------- | ||
// Licensed to The .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// ----------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
|
||
namespace Kerberos.NET.Dns | ||
{ | ||
public class POSIXDnsQuery : IKerberosDnsQuery | ||
{ | ||
public bool Debug { get; set; } | ||
|
||
public bool IsSupported => OSPlatform.IsLinux; | ||
|
||
public Task<IReadOnlyCollection<DnsRecord>> Query(string query, DnsRecordType type) | ||
{ | ||
if (!IsSupported) | ||
{ | ||
throw new InvalidOperationException( | ||
"The POSIX DNS query implementation is not supported outside of POSIX-compliant systems"); | ||
} | ||
|
||
var result = DnsQueryWin32.QuerySrvRecord(query, type); | ||
|
||
return Task.FromResult(result); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: brackets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wrong about them?