diff --git a/src/dns_conf.h b/src/dns_conf.h index 7fbc190..980cc76 100644 --- a/src/dns_conf.h +++ b/src/dns_conf.h @@ -159,6 +159,7 @@ struct dns_nftset_rule { struct dns_domain_rule { struct dns_rule head; struct dns_rule *rules[DOMAIN_RULE_MAX]; + int is_sub_rule[DOMAIN_RULE_MAX]; }; struct dns_nameserver_rule { diff --git a/src/dns_server.c b/src/dns_server.c index c2afae5..e4a7ab7 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -334,6 +334,15 @@ static void *_dns_server_get_dns_rule(struct dns_request *request, enum domain_r return request->domain_rule.rules[rule]; } +static int _dns_server_is_dns_rule_extact_match(struct dns_request *request, enum domain_rule rule) +{ + if (rule >= DOMAIN_RULE_MAX || request == NULL) { + return 0; + } + + return request->domain_rule.is_sub_rule[rule] == 0; +} + static void _dns_server_set_dualstack_selection(struct dns_request *request) { struct dns_rule_flags *rule_flag = NULL; @@ -3365,7 +3374,7 @@ static void _dns_server_update_rule_by_flags(struct dns_request *request) } } -static int _dns_server_get_rules(unsigned char *key, uint32_t key_len, void *value, void *arg) +static int _dns_server_get_rules(unsigned char *key, uint32_t key_len, int is_subkey, void *value, void *arg) { struct rule_walk_args *walk_args = arg; struct dns_request *request = walk_args->args; @@ -3381,6 +3390,7 @@ static int _dns_server_get_rules(unsigned char *key, uint32_t key_len, void *val } request->domain_rule.rules[i] = domain_rule->rules[i]; + request->domain_rule.is_sub_rule[i] = is_subkey; walk_args->key[i] = key; walk_args->key_len[i] = key_len; } @@ -3920,6 +3930,10 @@ static int _dns_server_process_smartdns_domain(struct dns_request *request) return -1; } + if (_dns_server_is_dns_rule_extact_match(request, DOMAIN_RULE_FLAGS) == 0) { + return -1; + } + flags = rule_flag->flags; if (!(flags & DOMAIN_FLAG_SMARTDNS_DOMAIN)) { return -1; diff --git a/src/include/art.h b/src/include/art.h index fbdf307..4bcbeb0 100644 --- a/src/include/art.h +++ b/src/include/art.h @@ -200,10 +200,11 @@ void *art_substring(const art_tree *t, const unsigned char *str, int str_len, un * @arg t The tree * @arg str The key * @arg str_len The length of the key + * @arg is_subkey is sub key or not * @return NULL if the item was not found, otherwise * the value pointer is returned. */ -typedef int (*walk_func)(unsigned char *key, uint32_t key_len, void *value, void *arg); +typedef int (*walk_func)(unsigned char *key, uint32_t key_len, int is_subkey, void *value, void *arg); void art_substring_walk(const art_tree *t, const unsigned char *str, int str_len, walk_func func, void *arg); /** diff --git a/src/lib/art.c b/src/lib/art.c index de296c3..597ee29 100644 --- a/src/lib/art.c +++ b/src/lib/art.c @@ -1090,7 +1090,7 @@ void art_substring_walk(const art_tree *t, const unsigned char *str, int str_len // Check if the expanded path matches if (!str_prefix_matches((art_leaf*)n, str, str_len)) { found = (art_leaf*)n; - stop_search = func(found->key, found->key_len, found->value, arg); + stop_search = func(found->key, found->key_len, found->key_len != (uint32_t)str_len, found->value, arg); } break; } @@ -1103,7 +1103,7 @@ void art_substring_walk(const art_tree *t, const unsigned char *str, int str_len // Check if the expanded path matches if (!str_prefix_matches((art_leaf*)m, str, str_len)) { found = (art_leaf*)m; - stop_search = func(found->key, found->key_len, found->value, arg); + stop_search = func(found->key, found->key_len, found->key_len != (uint32_t)str_len, found->value, arg); } }