Пример #1
0
        public QueryResult Resolve(Query query)
        {
            // Find potential matches
            var matches =
                _dnsRuleGroups
                    .Select(group => new
                                         {
                                             Group = group,
                                             RuleMatchResult = GetRuleMatch(query,
                                                                            group)
                                         })
                    .Where(match => match.RuleMatchResult.Match)
                    .OrderByDescending(match => match.RuleMatchResult.HostnameSimilarity)
                    .ToArray();

            if (!matches.Any())
            {
                return new QueryResult() { Result = false };
            }

            var bestMatch = matches.First();
            var rule = bestMatch.RuleMatchResult.Rule;

            string ruleValue;
            if (!string.IsNullOrWhiteSpace(rule.ValueAlias))
            {
                var result = _dnsValueAliases
                    .Where(alias =>
                           alias != null
                           &&
                           rule.ValueAlias != null
                           &&
                           string.Compare(alias.Name,
                                          rule.ValueAlias,
                                          StringComparison.InvariantCultureIgnoreCase)
                                          == 0)
                    .FirstOrDefault();

                if (result == null)
                {
                    throw new WranglerConfigurationException(
                        string.Format("Alias {0} is specified in Rule {1} but wasn't found", rule.ValueAlias,
                                      rule.ToString()));
                }

                ruleValue = result.Value;
            }
            else
            {
                ruleValue = rule.Value;
            }

            return new QueryResult()
                       {
                           Result = true,
                           RecordType = rule.RecordType,
                           RecordValue = ruleValue,
                           RuleResult = rule.RuleType
                       };
        }
Пример #2
0
        private double FindHostnameSimilarity(Query query, DnsRule rule)
        {
            var hostnames = rule.Hostnames;
            if (query.QueryType != DnsRecordType.CNAME && query.QueryType != DnsRecordType.A)
            {
                if (hostnames.Any(hostname => hostname.HostnameType == HostnameType.Exact && hostname.HostnameEntry == query.Question))
                {
                    return 1;
                }
                return 0;
            }

            if (hostnames.Any(hostname => hostname.HostnameType == HostnameType.Exact && hostname.HostnameEntry == query.Question))
            {
                return 1;
            }

            if (hostnames.Any(hostname => hostname.HostnameType == HostnameType.Wildcard && query.Question.EndsWith(hostname.HostnameEntry)))
            {
                return 0.9;
            }

            return 0;
        }
Пример #3
0
        private double SimilarRuleTypes(Query query, DnsRule rule)
        {
            if (rule.RuleType.HasValue && (rule.RuleType.Value == DnsRuleType.NXDomain || rule.RuleType.Value == DnsRuleType.ResolveUpstream))
            {
                return 0.1;
            }

            if (rule.RecordType == query.QueryType)
            {
                return 1;
            }

            if (query.QueryType == DnsRecordType.A && rule.RecordType == DnsRecordType.CNAME)
            {
                return 0.9;
            }

            return 0;
        }
Пример #4
0
        private RuleMatchResult GetRuleMatch(Query query, DnsRuleGroup group)
        {
            // Examine the group's rules and give a result.

            var similarRules = group.Rules
                .Select(rule => new
                                    {
                                        HostnameSimilarity = FindHostnameSimilarity(query, rule),
                                        TypeSimilarity = SimilarRuleTypes(query, rule),
                                        Rule = rule
                                    })
                .Where(result => result.HostnameSimilarity > 0 && result.TypeSimilarity > 0)
                .OrderByDescending(rule => rule.HostnameSimilarity)
                .ThenByDescending(rule => rule.TypeSimilarity)
                .ToArray();

            if (!similarRules.Any())
            {
                return new RuleMatchResult { Match = false };
            }

            return
                similarRules
                    .Select(
                        rule =>
                        new RuleMatchResult
                            {
                                HostnameSimilarity = rule.HostnameSimilarity,
                                Match = true,
                                Rule = rule.Rule
                            })
                    .FirstOrDefault();
        }