Exemple #1
0
        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));
            }
        }