예제 #1
0
        public void Cache_GetOrAdd()
        {
            var cache    = new ResponseCache(true);
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 100, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0);

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));
            var item = cache.Get("key");

            Assert.Equal(item, response.AsQueryResponse(new NameServer(IPAddress.Any)));
        }
예제 #2
0
        public void Cache_DoesCacheWithMinimumDefined()
        {
            var cache    = new ResponseCache(true, TimeSpan.FromMilliseconds(100));
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 0, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0);

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));
            var item = cache.Get("key");

            // should not be null although TTL is zero, mimimum timeout is set to 100ms
            Assert.Equal(item, response.AsQueryResponse(new NameServer(IPAddress.Any)));
        }
예제 #3
0
        public void Cache_SupportsInfinite()
        {
            var cache    = new ResponseCache(true, Timeout.InfiniteTimeSpan);
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 0, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0);

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any), null));
            var item = cache.Get("key", out double?effectiveTtl);

            // should not be null although TTL is zero, minimum timeout is set to infinite
            Assert.Equal(item, response.AsQueryResponse(new NameServer(IPAddress.Any), null));
            Assert.Equal(int.MaxValue, effectiveTtl);
        }
예제 #4
0
        public async Task MockLookup()
        {
            // arrange
            var lookupMock = new Mock <IDnsQuery>();

            var aRecord = new ARecord(new ResourceRecordInfo("query", ResourceRecordType.A, QueryClass.IN, 0, 0), IPAddress.Any);

            var responseMsg = new DnsResponseMessage(new DnsResponseHeader(123, 256, 1, 1, 0, 1), 123);

            responseMsg.Answers.Add(aRecord);
            IDnsQueryResponse dnsResponse = responseMsg.AsQueryResponse(new NameServer(NameServer.GooglePublicDns));

            //// or mock response
            //var dnsResponseMock = new Mock<IDnsQueryResponse>();
            //dnsResponseMock
            //    .Setup(p => p.Answers)
            //        .Returns(new DnsResourceRecord[] { aRecord });

            Task <IDnsQueryResponse> response = Task.FromResult(dnsResponse);

            lookupMock.Setup(f => f.QueryAsync(It.IsAny <string>(), QueryType.A)).Returns(response);
            var lookup = lookupMock.Object;

            // act
            var result = await lookup.QueryAsync("query", QueryType.A);

            // assert
            Assert.Equal(1, result.Header.AnswerCount);
            Assert.Equal("query.", result.Answers.First().DomainName.Value);
            Assert.Equal(IPAddress.Any, result.Answers.ARecords().First().Address);
        }
예제 #5
0
        public async Task Cache_EntriesLowestTT_Expires()
        {
            var cache    = new ResponseCache(true);
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 1000, 100));
            var recordB  = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 100, 100));
            var recordC  = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 1, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0);

            response.AddAnswer(record);
            response.AddAdditional(recordB);
            response.AddAuthority(recordC);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any), null));

            await Task.Delay(200);

            var item = cache.Get("key", out double?effectiveTtl);

            Assert.NotNull(item);
            Assert.Equal(1 * 1000, effectiveTtl);

            await Task.Delay(1100);

            var item3 = cache.Get("key", out double?effectiveTtl2);

            Assert.Null(item3);
        }
예제 #6
0
        public void DnsRecordFactory_ResolveARecord()
        {
            var header          = new DnsResponseHeader(42, 256, 0, 1, 0, 0);
            var responseMessage = new DnsResponseMessage(header, 0);

            var info   = new ResourceRecordInfo("query", ResourceRecordType.A, QueryClass.IN, 100, 4);
            var ip     = IPAddress.Parse("123.45.67.9");
            var answer = new ARecord(info, ip);

            responseMessage.AddAnswer(answer);
            var response = responseMessage.AsQueryResponse(new NameServer(ip));

            var answerBytes = ip.GetAddressBytes();

            var raw = GetResponseBytes(response, answerBytes);

            var handle = new DnsUdpMessageHandler(true);
            var result = handle.GetResponseMessage(new System.ArraySegment <byte>(raw)).AsQueryResponse(new NameServer(ip));

            Assert.Equal(result.Answers.Count, 1);
            var resultAnswer = result.Answers.OfType <ARecord>().First();

            Assert.Equal(resultAnswer.Address.ToString(), ip.ToString());
            Assert.Equal(resultAnswer.DomainName.Value, "query.");
            Assert.Equal(resultAnswer.RawDataLength, 4);
            Assert.Equal(resultAnswer.RecordClass, QueryClass.IN);
            Assert.Equal(resultAnswer.RecordType, ResourceRecordType.A);
            Assert.True(resultAnswer.TimeToLive == 100);
            Assert.True(result.Header.Id == 42);
            Assert.True(result.Header.AnswerCount == 1);
        }
예제 #7
0
        public async Task Cache_EntriesLowestTT_Expires()
        {
            var cache    = new ResponseCache();
            var record   = new EmptyRecord(new ResourceRecord(DnsString.Parse("a"), ARecord.ResourceRecordType, QueryClass.In, 1000, 100));
            var recordB  = new EmptyRecord(new ResourceRecord(DnsString.Parse("a"), ARecord.ResourceRecordType, QueryClass.In, 100, 100));
            var recordC  = new EmptyRecord(new ResourceRecord(DnsString.Parse("a"), ARecord.ResourceRecordType, QueryClass.In, 1, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0)
            {
                Audit = new LookupClientAudit()
            };

            response.AddAnswer(record);
            response.AddAdditional(recordB);
            response.AddAuthority(recordC);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));

            await Task.Delay(200);

            var item = cache.Get("key", out var effectiveTtl);

            Assert.NotNull(item);
            Assert.Equal(1 * 1000, effectiveTtl);

            await Task.Delay(1100);

            var item3 = cache.Get("key", out _);

            Assert.Null(item3);
        }
예제 #8
0
        public void Cache_GetOrAddExists()
        {
            var cache    = new ResponseCache(true);
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 100, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0);

            response.AddAnswer(record);

            var success = cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));

            Assert.True(success);

            response.AddAnswer(new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 100, 100)));
            var fail = cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));

            Assert.False(fail);
        }
예제 #9
0
        public void Cache_GetOrAdd()
        {
            var cache    = new ResponseCache(true);
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 100, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0)
            {
                Audit = new LookupClientAudit()
            };

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));
            var item = cache.Get("key", out double?effectiveTtl);

            Assert.Equal(item, response.AsQueryResponse(new NameServer(IPAddress.Any)));
            Assert.Equal(100 * 1000, effectiveTtl);
        }
예제 #10
0
        public void Cache_SupportsInfinite()
        {
            var cache    = new ResponseCache(true, Timeout.InfiniteTimeSpan);
            var record   = new EmptyRecord(new ResourceRecord(DnsString.Parse("a"), ARecord.ResourceRecordType, QueryClass.In, 0, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0)
            {
                Audit = new LookupClientAudit()
            };

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));
            var item = cache.Get("key", out var effectiveTtl);

            // should not be null although TTL is zero, mimimum timeout is set to infinite
            Assert.Equal(item, response.AsQueryResponse(new NameServer(IPAddress.Any)));
            Assert.Equal(int.MaxValue, effectiveTtl);
        }
예제 #11
0
        public void Cache_GetOrAddExists()
        {
            var cache    = new ResponseCache();
            var record   = new EmptyRecord(new ResourceRecord(DnsString.Parse("a"), ARecord.ResourceRecordType, QueryClass.In, 100, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0)
            {
                Audit = new LookupClientAudit()
            };

            response.AddAnswer(record);

            var success = cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));

            Assert.True(success);

            response.AddAnswer(new EmptyRecord(new ResourceRecord(DnsString.Parse("a"), ARecord.ResourceRecordType, QueryClass.In, 100, 100)));
            var fail = cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));

            Assert.False(fail);
        }
예제 #12
0
        public void Cache_DoesCacheFailureIfEnabled()
        {
            var cache         = new ResponseCache(true);
            var failureStatus = DnsResponseCode.NotExistentDomain;
            var response      = new DnsResponseMessage(new DnsResponseHeader(1, (ushort)failureStatus, 0, 0, 0, 0), 0);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any), null), true);
            var item = cache.Get("key", out _);

            Assert.NotNull(item);
        }
예제 #13
0
        public void Cache_DoesNotCacheFailureIfDisabled()
        {
            var cache         = new ResponseCache(true);
            var failureStatus = DnsResponseCode.NotExistentDomain;
            var response      = new DnsResponseMessage(new DnsResponseHeader(1, (ushort)failureStatus, 0, 0, 0, 0), 0);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any), null));
            var item = cache.Get("key", out _);

            // Should be null because cache does not accept failure responses by default.
            Assert.Null(item);
        }
예제 #14
0
        public void Cache_DoesNotCacheIfZeroTTL()
        {
            var cache    = new ResponseCache(true);
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 0, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0);

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));
            var item = cache.Get("key");

            // should be null because ttl of the record is 0 which disables caching for this record
            Assert.Null(item);
        }
예제 #15
0
        public void Cache_DoesNotCacheIfDisabled()
        {
            var cache    = new ResponseCache(false);
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 100, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0);

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));
            var item = cache.Get("key");

            // should be null because cache is disabled and we create null in the second call of GetOrAdd
            Assert.Null(item);
        }
예제 #16
0
        public async Task Cache_DoesCacheFailureExpire()
        {
            var cache         = new ResponseCache(true, null, null, TimeSpan.FromMilliseconds(1));
            var failureStatus = DnsResponseCode.NotExistentDomain;
            var response      = new DnsResponseMessage(new DnsResponseHeader(1, (ushort)failureStatus, 0, 0, 0, 0), 0);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any), null), true);

            await Task.Delay(10);

            var item = cache.Get("key", out _);

            // Should be null because failed response expires after 1 millisecond.
            Assert.Null(item);
        }
예제 #17
0
        public void Cache_DoesCacheWithMinimumDefined()
        {
            var minTtl   = 2000;
            var cache    = new ResponseCache(true, TimeSpan.FromMilliseconds(minTtl));
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 0, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0);

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any), null));

            var item = cache.Get("key", out double?effectiveTtl);

            Assert.NotNull(item);
            Assert.Equal(0, item.Answers.First().TimeToLive);
            Assert.Equal(minTtl, effectiveTtl);
        }
            public IDnsQueryResponse GetResponse()
            {
                var elapsed = Elapsed();

                if (elapsed <= 0)
                {
                    return(_response);
                }

                var response = new DnsResponseMessage(
                    _response.Header,
                    _response.MessageSize)
                {
                    Audit = (_response as DnsQueryResponse)?.Audit ?? new LookupClientAudit()
                };

                foreach (var record in _response.Questions)
                {
                    response.AddQuestion(record);
                }

                foreach (var record in _response.Answers)
                {
                    var clone = record.Clone();
                    clone.TimeToLive = clone.TimeToLive - elapsed;
                    response.AddAnswer(clone);
                }

                foreach (var record in _response.Additionals)
                {
                    var clone = record.Clone();
                    clone.TimeToLive = clone.TimeToLive - elapsed;
                    response.AddAnswer(clone);
                }

                foreach (var record in _response.Authorities)
                {
                    var clone = record.Clone();
                    clone.TimeToLive = clone.TimeToLive - elapsed;
                    response.AddAnswer(clone);
                }

                var qr = response.AsQueryResponse(_response.NameServer);

                return(qr);
            }
예제 #19
0
        public async Task ResolveService_WithCnameRef()
        {
            var    ns          = new NameServer(IPAddress.Loopback, 8600);
            var    serviceName = "myservice";
            var    baseName    = "service.consul";
            var    fullQuery   = $"{serviceName}.{baseName}";
            ushort prio        = 99;
            ushort weight      = 69;
            ushort port        = 88;

            var response = new DnsResponseMessage(new DnsResponseHeader(1234, (int)DnsResponseCode.NoError, 0, 0, 0, 0), 0);

            response.AddAnswer(
                new SrvRecord(
                    new ResourceRecordInfo(fullQuery, ResourceRecordType.SRV, QueryClass.IN, 1000, 0),
                    prio,
                    weight,
                    port,
                    DnsString.Parse(serviceName)));

            var targetHost = DnsString.Parse("myservice.localhost.net");

            response.AddAdditional(
                new CNameRecord(
                    new ResourceRecordInfo(serviceName, ResourceRecordType.CNAME, QueryClass.IN, 1000, 0),
                    targetHost));

            var client = new LookupClient(ns);

            var mock = new Mock <IDnsQuery>();

            mock.Setup(p => p.QueryAsync(It.IsAny <string>(), It.IsAny <QueryType>(), It.IsAny <QueryClass>(), It.IsAny <CancellationToken>()))
            .Returns(() => Task.FromResult <IDnsQueryResponse>(response.AsQueryResponse(ns, client.Settings)));

            var mockClient = mock.Object;

            var result = await mockClient.ResolveServiceAsync(baseName, serviceName);

            Assert.Single(result);
            var first = result.First();

            Assert.Equal(targetHost.ToString(), first.HostName);
            Assert.Equal((int)port, first.Port);
            Assert.Equal((int)prio, first.Priority);
            Assert.Equal((int)weight, first.Weight);
        }
예제 #20
0
        public void Cache_DoesNotCacheIfZeroTTLWithZeroMinTtl()
        {
            var cache    = new ResponseCache(true, TimeSpan.Zero);
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 0, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0)
            {
                Audit = new LookupClientAudit()
            };

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));
            var item = cache.Get("key", out double?effectiveTtl);

            // should be null because ttl of the record is 0 which disables caching for this record
            Assert.Null(item);
            Assert.Null(effectiveTtl);
        }
예제 #21
0
        public void Cache_RespectsMaximumTtl()
        {
            var maxTtl   = 2000;
            var cache    = new ResponseCache(true, maximumTimeout: TimeSpan.FromMilliseconds(maxTtl));
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 60 * 60 * 24, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0);

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any), null));

            var item = cache.Get("key", out double?effectiveTtl);

            Assert.NotNull(item);
            Assert.Equal(1, cache.Count);
            Assert.Equal(60 * 60 * 24, item.Answers.First().TimeToLive);
            Assert.Equal(maxTtl, effectiveTtl);
        }
예제 #22
0
        public void Cache_DoesNotCacheIfDisabled()
        {
            var cache    = new ResponseCache(false);
            var record   = new EmptyRecord(new ResourceRecord(DnsString.Parse("a"), ARecord.ResourceRecordType, QueryClass.In, 100, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0)
            {
                Audit = new LookupClientAudit()
            };

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));
            var item = cache.Get("key", out var effectiveTtl);

            // should be null because cache is disabled and we create null in the second call of GetOrAdd
            Assert.Null(item);
            Assert.Null(effectiveTtl);
        }
예제 #23
0
        public void Cache_DoesNotCacheIfZeroTTL()
        {
            var cache    = new ResponseCache();
            var record   = new EmptyRecord(new ResourceRecord(DnsString.Parse("a"), ARecord.ResourceRecordType, QueryClass.In, 0, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0)
            {
                Audit = new LookupClientAudit()
            };

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));
            var item = cache.Get("key", out var effectiveTtl);

            // should be null because ttl of the record is 0 which disables caching for this record
            Assert.Null(item);
            Assert.Null(effectiveTtl);
        }
예제 #24
0
        public void Cache_EntriesLowestTTLWins()
        {
            var cache    = new ResponseCache(true);
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 1000, 100));
            var recordB  = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 100, 100));
            var recordC  = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 0, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0);

            response.AddAnswer(record);
            response.AddAdditional(recordB);
            response.AddAuthority(recordC);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));
            var item = cache.Get("key");

            // should be null because recordC has zero TTL which wins
            Assert.Null(item);
        }
예제 #25
0
        public void Cache_EntriesLowestTTLWins()
        {
            var cache    = new ResponseCache();
            var record   = new EmptyRecord(new ResourceRecord(DnsString.Parse("a"), ARecord.ResourceRecordType, QueryClass.In, 1000, 100));
            var recordB  = new EmptyRecord(new ResourceRecord(DnsString.Parse("a"), ARecord.ResourceRecordType, QueryClass.In, 100, 100));
            var recordC  = new EmptyRecord(new ResourceRecord(DnsString.Parse("a"), ARecord.ResourceRecordType, QueryClass.In, 0, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0)
            {
                Audit = new LookupClientAudit()
            };

            response.AddAnswer(record);
            response.AddAdditional(recordB);
            response.AddAuthority(recordC);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));
            var item = cache.Get("key", out var effectiveTtl);

            // should be null because recordC has zero TTL which wins
            Assert.Null(item);
            Assert.Null(effectiveTtl);
        }
예제 #26
0
        public async Task Cache_DoesCacheWithMinimumDefined()
        {
            var minTtl   = 2000;
            var cache    = new ResponseCache(true, TimeSpan.FromMilliseconds(minTtl));
            var record   = new EmptyRecord(new ResourceRecordInfo("a", ResourceRecordType.A, QueryClass.IN, 1, 100));
            var response = new DnsResponseMessage(new DnsResponseHeader(1, 256, 1, 1, 0, 0), 0)
            {
                Audit = new LookupClientAudit()
            };

            response.AddAnswer(record);

            cache.Add("key", response.AsQueryResponse(new NameServer(IPAddress.Any)));

            await Task.Delay(1200);

            var item = cache.Get("key", out double?effectiveTtl);

            // should not be null although TTL is zero, mimimum timeout is set to 2000ms
            // TTL of the record should be zero because the initial TTL is 100
            Assert.Equal(0, item.Answers.First().TimeToLive);
            Assert.Equal(minTtl, effectiveTtl);
        }