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);
        }
Example #2
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);
        }
        /// <summary> Constructs the response object based upon the data received from the DNS server. </summary>
        /// <param name="responseData">The data (byte[]) from the DNS server.</param>
        /// <returns>Response message object.</returns>
        public DnsResponseMessage ProcessResponse(ArraySegment <byte> responseData)
        {
            IDnsRecordFactory factory = new DnsRecordFactory(reader);

            /*
             * From index 0 till 11 bytes in the responseData array, we have the header items.
             */

            ushort id              = reader.ReadUInt16NetworkOrder(responseData);
            ushort flags           = reader.ReadUInt16NetworkOrder(responseData);
            ushort questionCount   = reader.ReadUInt16NetworkOrder(responseData);
            ushort answerCount     = reader.ReadUInt16NetworkOrder(responseData);
            ushort nameServerCount = reader.ReadUInt16NetworkOrder(responseData);
            ushort additionalCount = reader.ReadUInt16NetworkOrder(responseData);

            /*
             * We have got above data, now build the response header.
             */
            DnsResponseHeader  header   = new DnsResponseHeader(id, flags, questionCount, answerCount, additionalCount, nameServerCount);
            DnsResponseMessage response = new DnsResponseMessage(header, responseData.Count);

            /*
             * Next item in the response data is question that we sent to the DNS server which the server has copied onto the response message.
             */
            for (int questionIndex = 0; questionIndex < questionCount; questionIndex++)
            {
                IDnsString  questionString = reader.ReadQuestionQueryString(responseData);
                DnsQuestion question       = new DnsQuestion(questionString, (QueryType)reader.ReadUInt16NetworkOrder(responseData), (QueryClass)reader.ReadUInt16NetworkOrder(responseData));
                response.AddQuestion(question);
            }

            for (int answerIndex = 0; answerIndex < answerCount; answerIndex++)
            {
                BaseResourceRecordInfo info   = factory.ReadRecordInfo(responseData);
                DnsResourceRecord      record = factory.GetRecord(info, responseData);
                response.AddAnswer(record);
            }

            for (int serverIndex = 0; serverIndex < nameServerCount; serverIndex++)
            {
                BaseResourceRecordInfo info   = factory.ReadRecordInfo(responseData);
                DnsResourceRecord      record = factory.GetRecord(info, responseData);
                response.AddAuthority(record);
            }

            for (int additionalIndex = 0; additionalIndex < additionalCount; additionalIndex++)
            {
                BaseResourceRecordInfo info   = factory.ReadRecordInfo(responseData);
                DnsResourceRecord      record = factory.GetRecord(info, responseData);
                response.AddAdditional(record);
            }

            return(response);
        }
Example #4
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);
        }
Example #5
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);
        }
Example #6
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);
        }