Exemplo n.º 1
0
        public void ReadQuery1Packet()
        {
            var header = DnsByteExtensions.FromBytes <DnsHeader>(SampleDnsPackets.Query1);

            Assert.Equal(DnsQueryClass.IN, header.QueryClass);
            Assert.Equal(DnsQueryType.A, header.QueryType);
            Assert.Equal("cognito-identity.us-east-1.amazonaws.com", header.Host);
            Assert.Equal(0, header.AnswerRecordCount);
            Assert.Equal(0, header.AdditionalRecordCount);
            Assert.Equal(1, header.QuestionCount);
            Assert.Equal(0, header.NameServerRecordCount);
            Assert.False(header.IsQueryResponse);
            Assert.False(header.Truncation);
            Assert.False(header.RecursionAvailable);
            Assert.True(header.RecusionDesired);
            Assert.Equal(DnsResponseCode.NoError, header.ResponseCode);

            var header2 = new DnsHeader
            {
                Id              = header.Id,
                QueryClass      = DnsQueryClass.IN,
                QueryType       = DnsQueryType.A,
                RecusionDesired = true,
                Labels          = header.Labels,
                QuestionCount   = 1,
            };

            var bytes = DnsByteExtensions.ToBytes(header2).ToArray();

            Assert.Equal(SampleDnsPackets.Query1, bytes);
        }
Exemplo n.º 2
0
        public async Task InvokeAsync(HttpContext context)
        {
            if (context.Request.Path != _middlewareConfig.Path)
            {
                await _next(context);

                return;
            }

            if (context.Request.GetTypedHeaders().Accept.All(x => x.MediaType != DnsMessageType))
            {
                context.Response.StatusCode = (int)HttpStatusCode.UnprocessableEntity;
                return;
            }

            var ms = await context.Request.BodyReader.ReadAsync(context.RequestAborted);

            var buffer = ms.Buffer.ToArray();

            var header = DnsByteExtensions.FromBytes <DnsHeader>(buffer);

            var answer = await _dnsClient.Query(header, context.RequestAborted);

            context.Response.Headers.Add("Content-Type", new StringValues(DnsMessageType));

            await context.Response.BodyWriter.WriteAsync(DnsByteExtensions.ToBytes(answer), context.RequestAborted);
        }
Exemplo n.º 3
0
        public async Task <DnsAnswer> Query(DnsHeader query, CancellationToken token)
        {
            var raw = DnsByteExtensions.ToBytes(query).ToArray();

            var payload = DnsByteExtensions.ToBytes((ushort)raw.Length).Concat(raw).ToArray();
            var stream  = _socket.GetStream();

            await stream.WriteAsync(payload, 0, payload.Length, token);

            var buffer  = new byte[4096];
            var receive = await stream.ReadAsync(buffer, 0, buffer.Length, token);

            stream.Close();

            var offset         = 0;
            var responseLength = DnsByteExtensions.ReadUInt16(buffer, ref offset);

            var response = DnsByteExtensions.ReadBytes(buffer, responseLength, ref offset);

            if (response.Length != responseLength)
            {
                throw new InvalidOperationException();
            }

            return(DnsByteExtensions.FromBytes <DnsAnswer>(response));
        }
Exemplo n.º 4
0
 /// <inheritdoc/>
 public void ReadBytes(byte[] bytes, ref int offset, int length)
 {
     MName   = string.Join(".", DnsByteExtensions.ReadString(bytes, ref offset));
     RName   = string.Join(".", DnsByteExtensions.ReadString(bytes, ref offset));
     Serial  = DnsByteExtensions.ReadUInt32(bytes, ref offset);
     Refresh = TimeSpan.FromSeconds(DnsByteExtensions.ReadInt32(bytes, ref offset));
     Retry   = TimeSpan.FromSeconds(DnsByteExtensions.ReadInt32(bytes, ref offset));
     Expire  = TimeSpan.FromSeconds(DnsByteExtensions.ReadInt32(bytes, ref offset));
     Minimum = TimeSpan.FromSeconds(DnsByteExtensions.ReadUInt32(bytes, ref offset));
 }
Exemplo n.º 5
0
        public void ReadQuery5Packet()
        {
            var header = DnsByteExtensions.FromBytes <DnsHeader>(SampleDnsPackets.Query5);

            Assert.Equal(DnsQueryClass.IN, header.QueryClass);
            Assert.Equal(DnsQueryType.A, header.QueryType);
            Assert.Equal("roaming.officeapps.live.com", header.Host);
            Assert.Equal(0, header.AnswerRecordCount);
            Assert.Equal(0, header.AdditionalRecordCount);
            Assert.Equal(1, header.QuestionCount);
            Assert.Equal(0, header.NameServerRecordCount);
        }
Exemplo n.º 6
0
        public void ReadQuery2Packet()
        {
            var header = DnsByteExtensions.FromBytes <DnsHeader>(SampleDnsPackets.Query2);

            Assert.Equal(DnsQueryClass.IN, header.QueryClass);
            Assert.Equal(DnsQueryType.A, header.QueryType);
            Assert.Equal("polling.bbc.co.uk", header.Host);
            Assert.Equal(0, header.AnswerRecordCount);
            Assert.Equal(0, header.AdditionalRecordCount);
            Assert.Equal(1, header.QuestionCount);
            Assert.Equal(0, header.NameServerRecordCount);
        }
Exemplo n.º 7
0
        public void ReadQuery4Packet()
        {
            var header = DnsByteExtensions.FromBytes <DnsHeader>(SampleDnsPackets.Query4);

            Assert.Equal(DnsQueryClass.IN, header.QueryClass);
            Assert.Equal(DnsQueryType.AAAA, header.QueryType);
            Assert.Equal("h3.shared.global.fastly.net", header.Host);
            Assert.Equal(0, header.AnswerRecordCount);
            Assert.Equal(0, header.AdditionalRecordCount);
            Assert.Equal(1, header.QuestionCount);
            Assert.Equal(0, header.NameServerRecordCount);
        }
Exemplo n.º 8
0
        public void ReadAnswer4()
        {
            var message = DnsByteExtensions.FromBytes <DnsAnswer>(SampleDnsPackets.Answer4);

            Assert.Equal(DnsQueryClass.IN, message.Header.QueryClass);
            Assert.Equal(DnsQueryType.A, message.Header.QueryType);
            Assert.Equal(5, message.Header.AnswerRecordCount);
            Assert.Equal(0, message.Header.AdditionalRecordCount);
            Assert.Equal(1, message.Header.QuestionCount);
            Assert.Equal(5, message.Answers.Count);

            var record1 = message.Answers[0];

            Assert.Equal(DnsQueryType.CNAME, record1.Type);
            Assert.Equal(DnsQueryClass.IN, record1.Class);
            Assert.Equal("alanedwardes.testing.alanedwardes.com", record1.Host);
            Assert.Equal("alanedwardes.com", ((DnsTextResource)record1.Resource).Text);
            Assert.Equal(TimeSpan.Parse("00:05:00"), record1.TimeToLive);

            var record2 = message.Answers[1];

            Assert.Equal(DnsQueryType.A, record2.Type);
            Assert.Equal(DnsQueryClass.IN, record2.Class);
            Assert.Equal(IPAddress.Parse("143.204.191.46"), ((DnsIpAddressResource)record2.Resource).IPAddress);
            Assert.Equal(TimeSpan.Parse("00:01:00"), record2.TimeToLive);

            var record3 = message.Answers[2];

            Assert.Equal(DnsQueryType.A, record3.Type);
            Assert.Equal(DnsQueryClass.IN, record3.Class);
            Assert.Equal("alanedwardes.com", record3.Host);
            Assert.Equal(IPAddress.Parse("143.204.191.37"), ((DnsIpAddressResource)record3.Resource).IPAddress);
            Assert.Equal(TimeSpan.Parse("00:01:00"), record3.TimeToLive);

            var record4 = message.Answers[3];

            Assert.Equal(DnsQueryType.A, record4.Type);
            Assert.Equal(DnsQueryClass.IN, record4.Class);
            Assert.Equal("alanedwardes.com", record4.Host);
            Assert.Equal(IPAddress.Parse("143.204.191.71"), ((DnsIpAddressResource)record4.Resource).IPAddress);
            Assert.Equal(TimeSpan.Parse("00:01:00"), record4.TimeToLive);

            var record5 = message.Answers[4];

            Assert.Equal(DnsQueryType.A, record5.Type);
            Assert.Equal(DnsQueryClass.IN, record5.Class);
            Assert.Equal("alanedwardes.com", record5.Host);
            Assert.Equal(IPAddress.Parse("143.204.191.110"), ((DnsIpAddressResource)record5.Resource).IPAddress);
            Assert.Equal(TimeSpan.Parse("00:01:00"), record5.TimeToLive);
        }
Exemplo n.º 9
0
        public void TestDnsHeaderIsQueryResponse()
        {
            foreach (var answer in SampleDnsPackets.Answers)
            {
                var header = DnsByteExtensions.FromBytes <DnsHeader>(answer);
                Assert.True(header.IsQueryResponse);
            }

            foreach (var query in SampleDnsPackets.Queries)
            {
                var header = DnsByteExtensions.FromBytes <DnsHeader>(query);
                Assert.False(header.IsQueryResponse);
            }
        }
Exemplo n.º 10
0
        /// <inheritdoc/>
        public async Task <DnsAnswer> Query(DnsHeader query, CancellationToken token)
        {
            string cacheKey = GetCacheKey(query);

            DnsAnswer answer;

            var cacheEntry = (DnsCacheEntry)_objectCache.Get(cacheKey);

            if (cacheEntry != null)
            {
                _logger.LogTrace("Returned cached DNS result for {Domain} (expires in: {ExpiryTime})", query.Host, cacheEntry.Expires);

                answer = DnsByteExtensions.FromBytes <DnsAnswer>(cacheEntry.Data);

                // Replace the ID
                answer.Header.Id = query.Id;

                // Adjust the TTLs to be correct
                foreach (var record in answer.Answers)
                {
                    record.TimeToLive -= cacheEntry.Age;
                }

                return(answer);
            }

            answer = await _dnsClient.Query(new DnsHeader
            {
                Id              = query.Id,
                Host            = query.Host,
                IsQueryResponse = false,
                RecusionDesired = query.RecusionDesired,
                QueryClass      = query.QueryClass,
                QueryType       = query.QueryType,
                QuestionCount   = query.QuestionCount
            }, token);

            _logger.LogTrace("Returned fresh DNS result for {Domain}", query.Host);

            if (answer.Answers.Count > 0)
            {
                cacheEntry = new DnsCacheEntry(answer);
                _objectCache.Add(cacheKey, cacheEntry, new CacheItemPolicy {
                    AbsoluteExpiration = cacheEntry.Expiry
                });
            }

            return(answer);
        }
Exemplo n.º 11
0
        /// <inheritdoc/>
        public async Task <DnsAnswer> Query(DnsHeader query, CancellationToken token)
        {
            var raw = DnsByteExtensions.ToBytes(query).ToArray();

            var completionSource = _pending.GetOrAdd(ToMessageId(query), key => SendQueryInternal(key, raw, token));

            var result = await completionSource.Task;

            var answer = DnsByteExtensions.FromBytes <DnsAnswer>(result);

            // Copy the same ID from the request
            answer.Header.Id = query.Id;

            return(answer);
        }
Exemplo n.º 12
0
        /// <inheritdoc/>
        public IEnumerable <IEnumerable <byte> > WriteBytes()
        {
            yield return(DnsByteExtensions.ToBytes(MName.Split('.')));

            yield return(DnsByteExtensions.ToBytes(RName.Split('.')));

            yield return(DnsByteExtensions.ToBytes(Serial));

            yield return(DnsByteExtensions.ToBytes((int)Refresh.TotalSeconds));

            yield return(DnsByteExtensions.ToBytes((int)Retry.TotalSeconds));

            yield return(DnsByteExtensions.ToBytes((int)Expire.TotalSeconds));

            yield return(DnsByteExtensions.ToBytes((uint)Minimum.TotalSeconds));
        }
Exemplo n.º 13
0
        public void ReadAnswer3()
        {
            var message = DnsByteExtensions.FromBytes <DnsAnswer>(SampleDnsPackets.Answer3);

            Assert.Equal(DnsQueryClass.IN, message.Header.QueryClass);
            Assert.Equal(DnsQueryType.A, message.Header.QueryType);
            Assert.Equal(1, message.Header.AnswerRecordCount);
            Assert.Equal(0, message.Header.AdditionalRecordCount);
            Assert.Equal(1, message.Header.QuestionCount);

            var record = Assert.Single(message.Answers);

            Assert.Equal(DnsQueryType.A, record.Type);
            Assert.Equal(DnsQueryClass.IN, record.Class);
            Assert.Equal("google.com", record.Host);
            Assert.Equal(IPAddress.Parse("216.58.210.206"), ((DnsIpAddressResource)record.Resource).IPAddress);
            Assert.Equal(TimeSpan.Parse("00:04:28"), record.TimeToLive);
        }
Exemplo n.º 14
0
        private void Receive(byte[] buffer)
        {
            DnsAnswer answer;

            try
            {
                answer = DnsByteExtensions.FromBytes <DnsAnswer>(buffer);
            }
            catch (Exception e)
            {
                _logger.LogCritical(e, "Received bad DNS response from {0}: {1}", _socket.Client.RemoteEndPoint.ToString(), buffer);
                return;
            }

            if (_pending.TryRemove(ToMessageId(answer.Header), out TaskCompletionSource <byte[]> completionSource))
            {
                completionSource.SetResult(buffer);
            }
        }
Exemplo n.º 15
0
        private async void Respond(UdpReceiveResult query, CancellationToken token)
        {
            var stopwatch = Stopwatch.StartNew();

            DnsHeader message;

            try
            {
                message = DnsByteExtensions.FromBytes <DnsHeader>(query.Buffer);
            }
            catch (Exception e)
            {
                _logger.LogCritical(e, "Unable to parse incoming packet: {0}", DnsByteExtensions.ToDebugString(query.Buffer));
                return;
            }

            DnsAnswer answer;

            try
            {
                answer = await _dnsClient.Query(message, token);
            }
            catch (Exception e)
            {
                _logger.LogCritical(e, "Unable to resolve {0}", message);
                return;
            }

            var answerBytes = DnsByteExtensions.ToBytes(answer).ToArray();

            try
            {
                await _listener.SendAsync(answerBytes, answerBytes.Length, query.RemoteEndPoint);
            }
            catch (Exception e)
            {
                _logger.LogCritical(e, "Unable to send back response to {0}", query.RemoteEndPoint);
                return;
            }

            _logger.LogTrace("Responded to DNS request for {Domain} in {ResponseTime}", message.Host, stopwatch.Elapsed.TotalSeconds);
        }
Exemplo n.º 16
0
        public void ReadAnswer1()
        {
            var message = DnsByteExtensions.FromBytes <DnsAnswer>(SampleDnsPackets.Answer1);

            Assert.Equal(DnsQueryClass.IN, message.Header.QueryClass);
            Assert.Equal(DnsQueryType.PTR, message.Header.QueryType);
            Assert.Equal("1.0.0.127.in-addr.arpa", message.Header.Host);
            Assert.Equal(0, message.Header.AnswerRecordCount);
            Assert.Equal(0, message.Header.AdditionalRecordCount);
            Assert.Equal(1, message.Header.QuestionCount);
            Assert.Equal(1, message.Header.NameServerRecordCount);

            var record = message.Answers.Single();

            Assert.Equal(DnsQueryType.SOA, record.Type);
            Assert.Equal(DnsQueryClass.IN, record.Class);
            Assert.Equal("in-addr.arpa", record.Host);

            var soaData = (DnsSoaResource)record.Resource;

            Assert.Equal("b.in-addr-servers.arpa", soaData.MName);
            Assert.Equal("nstld.iana.org", soaData.RName);
            Assert.Equal(TimeSpan.Parse("00:36:32"), record.TimeToLive);
        }
Exemplo n.º 17
0
        public void ReadARecordTests(int example, int offset, byte[] expected)
        {
            var value = DnsByteExtensions.ReadBytes(SampleDnsPackets.Answers[example - 1], 4, ref offset);

            Assert.Equal(expected, value);
        }
Exemplo n.º 18
0
 /// <inheritdoc/>
 public IEnumerable <IEnumerable <byte> > WriteBytes()
 {
     yield return(DnsByteExtensions.ToBytes(Text.Split('.')));
 }
Exemplo n.º 19
0
 /// <inheritdoc/>
 public void ReadBytes(byte[] bytes, ref int offset, int length) => IPAddress = new IPAddress(DnsByteExtensions.ReadBytes(bytes, length, ref offset));
Exemplo n.º 20
0
 public void TestReadQueries(byte[] queryBytes) => DnsByteExtensions.FromBytes <DnsHeader>(queryBytes);
Exemplo n.º 21
0
 public DnsCacheEntry(DnsAnswer answer)
 {
     LowestRecordTimeToLive = answer.Answers.Min(x => x.TimeToLive);
     Data = DnsByteExtensions.ToBytes(answer);
 }
Exemplo n.º 22
0
 /// <inheritdoc/>
 public void ReadBytes(byte[] bytes, ref int offset, int length)
 {
     Raw = DnsByteExtensions.ReadBytes(bytes, length, ref offset);
 }
Exemplo n.º 23
0
        public void TestDnsHeaderIsNxDomainResponse()
        {
            var header = DnsByteExtensions.FromBytes <DnsHeader>(SampleDnsPackets.Answer1);

            Assert.Equal(DnsResponseCode.NXDomain, header.ResponseCode);
        }
Exemplo n.º 24
0
        public void TestRoundTripQueries(byte[] queryBytes)
        {
            var query = DnsByteExtensions.FromBytes <DnsHeader>(queryBytes);

            Assert.Equal(query, DnsByteExtensions.FromBytes <DnsHeader>(DnsByteExtensions.ToBytes(query).ToArray()));
        }
Exemplo n.º 25
0
        public void TestRoundTripAnswers(byte[] answerBytes)
        {
            var answer = DnsByteExtensions.FromBytes <DnsAnswer>(answerBytes);

            Assert.Equal(answer, DnsByteExtensions.FromBytes <DnsAnswer>(DnsByteExtensions.ToBytes(answer).ToArray()));
        }
Exemplo n.º 26
0
 /// <inheritdoc/>
 public void ReadBytes(byte[] bytes, ref int offset, int length)
 {
     Preference = DnsByteExtensions.ReadUInt16(bytes, ref offset);
     Exchange   = string.Join(".", DnsByteExtensions.ReadString(bytes, ref offset));
 }
Exemplo n.º 27
0
        private async Task ReceiveTask()
        {
            while (!_cancel.IsCancellationRequested)
            {
                UdpReceiveResult recieve;

                try
                {
                    recieve = await _socket.ReceiveAsync();
                }
                catch (ObjectDisposedException)
                {
                    // Do nothing, client shutting down
                    return;
                }
                catch (Exception e)
                {
                    _logger.LogCritical(e, "Received bad network response from {0}: {1}", recieve.RemoteEndPoint.ToString(), DnsByteExtensions.ToDebugString(recieve.Buffer));
                    continue;
                }

                if (recieve.Buffer.Length > 0)
                {
                    _ = Task.Run(() => Receive(recieve.Buffer));
                }
            }
        }
Exemplo n.º 28
0
        /// <inheritdoc/>
        public IEnumerable <IEnumerable <byte> > WriteBytes()
        {
            yield return(DnsByteExtensions.ToBytes(Preference));

            yield return(DnsByteExtensions.ToBytes(Exchange.Split('.')));
        }
Exemplo n.º 29
0
 /// <inheritdoc/>
 public void ReadBytes(byte[] bytes, ref int offset, int length)
 {
     Text = string.Join(".", DnsByteExtensions.ReadString(bytes, ref offset, offset + length));
 }
Exemplo n.º 30
0
        public void ReadCnameRecordTests(int example, int offset, string[] expected)
        {
            var value = DnsByteExtensions.ReadString(SampleDnsPackets.Answers[example - 1], ref offset);

            Assert.Equal(expected, value);
        }