private IReadOnlyList <DnsResourceRecord> GetAdditionalRecords(IReadOnlyList <DnsResourceRecord> nsRecords) { IReadOnlyList <DnsResourceRecord> glueRecords = nsRecords.GetGlueRecords(); if (glueRecords.Count > 0) { return(glueRecords); } List <DnsResourceRecord> additionalRecords = new List <DnsResourceRecord>(); foreach (DnsResourceRecord nsRecord in nsRecords) { if (nsRecord.Type != DnsResourceRecordType.NS) { continue; } AuthZone authZone = _root.FindZone((nsRecord.RDATA as DnsNSRecord).NameServer, out _, out _, out _); if ((authZone != null) && authZone.IsActive) { { IReadOnlyList <DnsResourceRecord> records = authZone.QueryRecords(DnsResourceRecordType.A); if ((records.Count > 0) && (records[0].RDATA is DnsARecord)) { additionalRecords.AddRange(records); } } { IReadOnlyList <DnsResourceRecord> records = authZone.QueryRecords(DnsResourceRecordType.AAAA); if ((records.Count > 0) && (records[0].RDATA is DnsAAAARecord)) { additionalRecords.AddRange(records); } } } } return(additionalRecords); }
private void ResolveAdditionalRecords(string domain, List <DnsResourceRecord> additionalRecords) { AuthZone authZone = _root.FindZone(domain, out _, out _, out _); if ((authZone != null) && authZone.IsActive) { { IReadOnlyList <DnsResourceRecord> records = authZone.QueryRecords(DnsResourceRecordType.A); if ((records.Count > 0) && (records[0].RDATA is DnsARecord)) { additionalRecords.AddRange(records); } } { IReadOnlyList <DnsResourceRecord> records = authZone.QueryRecords(DnsResourceRecordType.AAAA); if ((records.Count > 0) && (records[0].RDATA is DnsAAAARecord)) { additionalRecords.AddRange(records); } } } }
private static DnsDatagram GetForwarderResponse(DnsDatagram request, AuthZone zone, AuthZone forwarderZone, bool isRecursionAllowed) { IReadOnlyList <DnsResourceRecord> authority = null; if (zone != null) { authority = zone.QueryRecords(DnsResourceRecordType.FWD); } if ((authority == null) || (authority.Count == 0)) { authority = forwarderZone.QueryRecords(DnsResourceRecordType.FWD); } return(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, null, authority)); }
private DnsDatagram GetReferralResponse(DnsDatagram request, AuthZone delegationZone, bool isRecursionAllowed) { IReadOnlyList <DnsResourceRecord> authority; if (delegationZone is StubZone) { authority = delegationZone.GetRecords(DnsResourceRecordType.NS); //stub zone has no authority so cant query } else { authority = delegationZone.QueryRecords(DnsResourceRecordType.NS); } IReadOnlyList <DnsResourceRecord> additional = GetAdditionalRecords(authority); return(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, null, authority, additional)); }
public DnsDatagram Query(DnsDatagram request, bool isRecursionAllowed) { AuthZone zone = _root.FindZone(request.Question[0].Name, out AuthZone delegation, out AuthZone authZone, out bool hasSubDomains); if ((authZone == null) || !authZone.IsActive) //no authority for requested zone { return(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.Refused, request.Question)); } if ((delegation != null) && delegation.IsActive) { return(GetReferralResponse(request, delegation, isRecursionAllowed)); } if ((zone == null) || !zone.IsActive) { //zone not found if (authZone is StubZone) { return(GetReferralResponse(request, authZone, isRecursionAllowed)); } else if (authZone is ForwarderZone) { return(GetForwarderResponse(request, null, authZone, isRecursionAllowed)); } DnsResponseCode rCode = DnsResponseCode.NoError; IReadOnlyList <DnsResourceRecord> authority = authZone.QueryRecords(DnsResourceRecordType.APP); if (authority.Count == 0) { if (!hasSubDomains) { rCode = DnsResponseCode.NxDomain; } authority = authZone.GetRecords(DnsResourceRecordType.SOA); } return(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, true, false, request.RecursionDesired, isRecursionAllowed, false, false, rCode, request.Question, null, authority)); } else { //zone found IReadOnlyList <DnsResourceRecord> authority; IReadOnlyList <DnsResourceRecord> additional; IReadOnlyList <DnsResourceRecord> answers = zone.QueryRecords(request.Question[0].Type); if (answers.Count == 0) { //record type not found if (authZone is StubZone) { return(GetReferralResponse(request, authZone, isRecursionAllowed)); } else if (authZone is ForwarderZone) { return(GetForwarderResponse(request, zone, authZone, isRecursionAllowed)); } authority = zone.QueryRecords(DnsResourceRecordType.APP); if (authority.Count == 0) { authority = authZone.QueryRecords(DnsResourceRecordType.APP); if (authority.Count == 0) { authority = authZone.GetRecords(DnsResourceRecordType.SOA); } } additional = null; } else { //record type found if (zone.Name.Contains("*")) { //wildcard zone; generate new answer records DnsResourceRecord[] wildcardAnswers = new DnsResourceRecord[answers.Count]; for (int i = 0; i < answers.Count; i++) { wildcardAnswers[i] = new DnsResourceRecord(request.Question[0].Name, answers[i].Type, answers[i].Class, answers[i].TtlValue, answers[i].RDATA) { Tag = answers[i].Tag } } ; answers = wildcardAnswers; } switch (request.Question[0].Type) { case DnsResourceRecordType.NS: case DnsResourceRecordType.MX: case DnsResourceRecordType.SRV: authority = null; additional = GetAdditionalRecords(answers); break; case DnsResourceRecordType.ANY: authority = null; additional = null; break; default: authority = authZone.QueryRecords(DnsResourceRecordType.NS); additional = GetAdditionalRecords(authority); break; } } return(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers, authority, additional)); } }