public DnsResourceRecord GetRecord(BaseResourceRecordInfo info, ArraySegment <byte> data) { if (info == null) { throw new ArgumentNullException(nameof(info)); } int oldIndex = _reader.Index; DnsResourceRecord result; switch (info.RecordType) { case ResourceRecordType.A: IPAddress ipaddress = _reader.ReadIPAddress(data); result = new ARecord(info, ipaddress); break; default: // update reader index because we don't read full data for the empty record _reader.Advance(info.RawDataLength); result = new EmptyRecord(info); break; } // sanity check if (_reader.Index != oldIndex + info.RawDataLength) { throw new InvalidOperationException("Record reader index out of sync."); } return(result); }
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); }
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."); }
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; }
/// <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 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); }
/// <summary> Initializes a new instance of the <see cref="EmptyRecord"/> class. </summary> /// <param name="info">The information.</param> /// <exception cref="System.ArgumentNullException">If <paramref name="info"/> is null.</exception> public EmptyRecord(BaseResourceRecordInfo info) : base(info) { }