/// <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); }
public void ReadRecordInfo_should_return_BaseResourceRecordInfo_from_responseMessage() { // Arrange. const string query = "www.msn.com"; const string queryRoot = query + "."; const ushort recordType = 1; // A - Host Address. const ushort queryClass = 1; // IN const int timeToLive = 1000; const int rawDataLen = 10; ArraySegment <byte> responseData = GetSampleData(ResponseDataSampleFile.QuestionAndAnswerQuery); mockReader.Setup(r => r.ReadQuestionQueryString(responseData)) .Returns(new DnsString(query, queryRoot)); mockReader.SetupSequence(r => r.ReadUInt16NetworkOrder(responseData)) .Returns(recordType) .Returns(queryClass) .Returns(rawDataLen); mockReader.Setup(r => r.ReadUInt32NetworkOrder(responseData)) .Returns(timeToLive); IDnsRecordFactory factory = new DnsRecordFactory(mockReader.Object); // Act. BaseResourceRecordInfo recordInfo = factory.ReadRecordInfo(responseData); // Assert. // no need to check id recordInfo is null because we are already asserting on its properties. Assert.AreEqual(queryRoot, recordInfo.DomainName.ToString()); Assert.AreEqual(recordType, (int)recordInfo.RecordType); Assert.AreEqual(queryClass, (int)recordInfo.RecordClass); Assert.AreEqual(rawDataLen, recordInfo.RawDataLength); Assert.AreEqual(timeToLive, recordInfo.TimeToLive); }