/// <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);
        }
Пример #2
0
        public void GetRecord_should_throw_InvalidOperationException_when_Record_reader_index_becomes_out_of_sync()
        {
            // Arrange.
            const string             query      = "www.msn.com";
            const string             queryRoot  = query + ".";
            const ResourceRecordType recordType = ResourceRecordType.A;
            const QueryClass         queryClass = QueryClass.IN; // IN
            const int timeToLive = 1000;
            const int rawDataLen = 10;
            IPAddress ipaddress  = IPAddress.Parse("10.1.1.100");

            IDnsString dnsString = new DnsString(query, queryRoot);

            BaseResourceRecordInfo info         = new BaseResourceRecordInfo(recordType, queryClass, timeToLive, rawDataLen, dnsString);
            ArraySegment <byte>    responseData = GetSampleData(ResponseDataSampleFile.QuestionAndAnswerQuery);

            mockReader.Setup(r => r.Index).Returns(100);
            mockReader.Setup(r => r.ReadIPAddress(responseData)).Returns(ipaddress);

            IDnsRecordFactory factory = new DnsRecordFactory(mockReader.Object);

            // Act.

            Assert.Throws <InvalidOperationException>(() => factory.GetRecord(info, responseData), "Record reader index out of sync.");
        }
Пример #3
0
        public void GetRecord_should_return_EmptyRecord_type_when_unknown_recordType_is_found()
        {
            // Arrange.
            const string             query      = "www.msn.com";
            const string             queryRoot  = query + ".";
            const ResourceRecordType recordType = ResourceRecordType.OPT; // possibly make it to default case in the switch statement.
            const QueryClass         queryClass = QueryClass.IN;          // IN
            const int timeToLive = 1000;
            const int rawDataLen = 10;
            IPAddress ipaddress  = IPAddress.Parse("10.1.1.100");

            IDnsString dnsString = new DnsString(query, queryRoot);

            BaseResourceRecordInfo info         = new BaseResourceRecordInfo(recordType, queryClass, timeToLive, rawDataLen, dnsString);
            ArraySegment <byte>    responseData = GetSampleData(ResponseDataSampleFile.QuestionAndAnswerQuery);

            mockReader.SetupSequence(r => r.Index).Returns(100).Returns(100 + rawDataLen);
            mockReader.Setup(r => r.ReadIPAddress(responseData)).Returns(ipaddress);

            IDnsRecordFactory factory = new DnsRecordFactory(mockReader.Object);

            // Act.
            DnsResourceRecord result = factory.GetRecord(info, responseData);

            // Assert.

            Assert.IsInstanceOf(typeof(EmptyRecord), result);
            EmptyRecord record = (EmptyRecord)result;
        }
Пример #4
0
        public void GetRecord_should_return_RecordTypeA()
        {
            // Arrange.
            const string             query      = "www.msn.com";
            const string             queryRoot  = query + ".";
            const ResourceRecordType recordType = ResourceRecordType.A; // A - Host Address.
            const QueryClass         queryClass = QueryClass.IN;        // IN
            const int timeToLive = 1000;
            const int rawDataLen = 10;
            IPAddress ipaddress  = IPAddress.Parse("10.1.1.100");

            IDnsString dnsString = new DnsString(query, queryRoot);

            BaseResourceRecordInfo info         = new BaseResourceRecordInfo(recordType, queryClass, timeToLive, rawDataLen, dnsString);
            ArraySegment <byte>    responseData = GetSampleData(ResponseDataSampleFile.QuestionAndAnswerQuery);

            mockReader.SetupSequence(r => r.Index).Returns(100).Returns(100 + rawDataLen);
            mockReader.Setup(r => r.ReadIPAddress(responseData)).Returns(ipaddress);

            IDnsRecordFactory factory = new DnsRecordFactory(mockReader.Object);

            // Act.

            DnsResourceRecord result = factory.GetRecord(info, responseData);

            // Assert.

            Assert.IsInstanceOf(typeof(ARecord), result);
            ARecord record = (ARecord)result;

            Assert.AreEqual(queryRoot, record.DomainName.ToString());
            Assert.AreEqual(ipaddress.ToString(), record.Address.ToString());
            Assert.AreEqual(recordType, record.RecordType);
            Assert.AreEqual(queryClass, record.RecordClass);
            Assert.AreEqual(timeToLive, record.TimeToLive);
            Assert.AreEqual(rawDataLen, record.RawDataLength);
        }