-
Notifications
You must be signed in to change notification settings - Fork 760
Managed implementation of DNS resolver #6104
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
Changes from 13 commits
2c217a3
704e33c
aff6d17
15db8a1
6bda235
6fc61e0
2b6d91e
2137954
c204b01
2fc7de4
9b4de29
3ad5a75
40f8f9b
e385605
3cf0a9d
6016e41
f8c189d
d929889
00e41d7
7267fb7
c1b76d3
86490cc
92b2905
fdf1904
61814e7
82a8108
fa627fd
4ec79ca
123375d
6311616
c57a8c5
83ca958
03e6a99
46418fe
4075e4f
56cd169
a19e8a2
5d5edae
3c387e9
c6e3d63
e66229a
da018f7
2697412
214cc9b
0d891cb
46cf262
35a5809
fcf18cf
df785d1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System.Buffers; | ||
| using System.Buffers.Binary; | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using System.Runtime.InteropServices; | ||
|
|
||
| namespace Microsoft.Extensions.ServiceDiscovery.Dns.Resolver; | ||
|
|
||
| internal struct DnsDataReader : IDisposable | ||
| { | ||
| public byte[]? RawData { get; private set; } | ||
| private ReadOnlyMemory<byte> _buffer; | ||
| private int _position; | ||
|
|
||
| public DnsDataReader(ReadOnlyMemory<byte> buffer, byte[]? returnToPool = null) | ||
| { | ||
| _buffer = buffer; | ||
| _position = 0; | ||
| RawData = returnToPool; | ||
| } | ||
|
|
||
| public bool TryReadHeader(out DnsMessageHeader header) | ||
| { | ||
| if (_buffer.Length - _position < DnsMessageHeader.HeaderLength) | ||
| { | ||
| header = default; | ||
| return false; | ||
| } | ||
|
|
||
| _position += DnsMessageHeader.HeaderLength; | ||
| header = MemoryMarshal.AsRef<DnsMessageHeader>(_buffer.Span); | ||
BrennanConroy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return true; | ||
| } | ||
|
|
||
| internal bool TryReadQuestion([NotNullWhen(true)] out string? name, out QueryType type, out QueryClass @class) | ||
| { | ||
| if (!TryReadDomainName(out name) || | ||
| !TryReadUInt16(out ushort typeAsInt) || | ||
| !TryReadUInt16(out ushort classAsInt)) | ||
| { | ||
| type = 0; | ||
| @class = 0; | ||
| return false; | ||
| } | ||
|
|
||
| type = (QueryType)typeAsInt; | ||
| @class = (QueryClass)classAsInt; | ||
| return true; | ||
| } | ||
|
|
||
| public bool TryReadUInt16(out ushort value) | ||
| { | ||
| if (_buffer.Length - _position < 2) | ||
| { | ||
| value = 0; | ||
| return false; | ||
| } | ||
|
|
||
| value = BinaryPrimitives.ReadUInt16BigEndian(_buffer.Span.Slice(_position)); | ||
| _position += 2; | ||
| return true; | ||
| } | ||
|
|
||
| public bool TryReadUInt32(out uint value) | ||
| { | ||
| if (_buffer.Length - _position < 4) | ||
| { | ||
| value = 0; | ||
| return false; | ||
| } | ||
|
|
||
| value = BinaryPrimitives.ReadUInt32BigEndian(_buffer.Span.Slice(_position)); | ||
| _position += 4; | ||
| return true; | ||
| } | ||
|
|
||
| public bool TryReadResourceRecord(out DnsResourceRecord record) | ||
| { | ||
| if (!TryReadDomainName(out string? name) || | ||
|
||
| !TryReadUInt16(out ushort type) || | ||
| !TryReadUInt16(out ushort @class) || | ||
| !TryReadUInt32(out uint ttl) || | ||
| !TryReadUInt16(out ushort dataLength) || | ||
| _buffer.Length - _position < dataLength) | ||
| { | ||
| record = default; | ||
| return false; | ||
| } | ||
|
|
||
| ReadOnlyMemory<byte> data = _buffer.Slice(_position, dataLength); | ||
| _position += dataLength; | ||
|
|
||
| record = new DnsResourceRecord(name, (QueryType)type, (QueryClass)@class, (int)ttl, data); | ||
| return true; | ||
| } | ||
|
|
||
| public bool TryReadDomainName([NotNullWhen(true)] out string? name) | ||
| { | ||
| if (DnsPrimitives.TryReadQName(_buffer.Span, _position, out name, out int bytesRead)) | ||
| { | ||
| _position += bytesRead; | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| public void Dispose() | ||
| { | ||
| if (RawData is not null) | ||
| { | ||
| ArrayPool<byte>.Shared.Return(RawData); | ||
| RawData = null!; | ||
rzikm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| _buffer = default; | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.