From 5057a8e45dce759c256c63622c41421f95b91974 Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Sat, 26 Jan 2019 23:39:54 +0800 Subject: [PATCH] Fix ipsub net issue: ipv4 matching ipv6 rule --- src/dns_conf.c | 28 +++++++++++++++++++++------- src/dns_conf.h | 7 ++++++- src/dns_server.c | 12 +++++++++++- src/lib/radix.c | 3 +++ 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/dns_conf.c b/src/dns_conf.c index 0319e10..b0a496d 100644 --- a/src/dns_conf.c +++ b/src/dns_conf.c @@ -35,7 +35,7 @@ size_t dns_conf_audit_size = 1024 * 1024; int dns_conf_audit_num = 2; art_tree dns_conf_domain_rule; -radix_tree_t *dns_conf_address_rule; +struct dns_conf_address_rule dns_conf_address_rule; int dns_conf_dualstack_ip_selection; int dns_conf_dualstack_ip_selection_threshold = 30; @@ -535,18 +535,28 @@ int config_server_tls(void *data, int argc, char *argv[]) return config_server(argc, argv, DNS_SERVER_TLS, DEFAULT_DNS_TLS_PORT); } -radix_node_t *create_addr_node(radix_tree_t *tree, char *addr) +radix_node_t *create_addr_node(char *addr) { radix_node_t *node; void *p; prefix_t prefix; const char *errmsg = NULL; + radix_tree_t *tree = NULL; p = prefix_pton(addr, -1, &prefix, &errmsg); if (p == NULL) { return NULL; } + switch (prefix.family) { + case AF_INET: + tree = dns_conf_address_rule.ipv4; + break; + case AF_INET6: + tree = dns_conf_address_rule.ipv6; + break; + } + node = radix_lookup(tree, &prefix); return node; } @@ -556,7 +566,7 @@ int config_iplist_rule(char *subnet, enum address_rule rule) radix_node_t *node = NULL; struct dns_ip_address_rule *ip_rule = NULL; - node = create_addr_node(dns_conf_address_rule, subnet); + node = create_addr_node(subnet); if (node == NULL) { return -1; } @@ -737,12 +747,15 @@ int config_addtional_file(void *data, int argc, char *argv[]) int _dns_server_load_conf_init(void) { - dns_conf_address_rule = New_Radix(); - art_tree_init(&dns_conf_domain_rule); - if (dns_conf_address_rule == NULL) { + dns_conf_address_rule.ipv4 = New_Radix(); + dns_conf_address_rule.ipv6 = New_Radix(); + if (dns_conf_address_rule.ipv4 == NULL || dns_conf_address_rule.ipv6 == NULL) { + tlog(TLOG_WARN, "init radix tree failed."); return -1; } + art_tree_init(&dns_conf_domain_rule); + hash_init(dns_ipset_table.ipset); return 0; @@ -751,7 +764,8 @@ int _dns_server_load_conf_init(void) void dns_server_load_exit(void) { config_domain_destroy(); - Destroy_Radix(dns_conf_address_rule, config_address_destroy, NULL); + Destroy_Radix(dns_conf_address_rule.ipv4, config_address_destroy, NULL); + Destroy_Radix(dns_conf_address_rule.ipv6, config_address_destroy, NULL); config_ipset_table_destroy(); } diff --git a/src/dns_conf.h b/src/dns_conf.h index ef5b69f..cadacc6 100644 --- a/src/dns_conf.h +++ b/src/dns_conf.h @@ -99,6 +99,11 @@ struct dns_edns_client_subnet { int subnet; }; +struct dns_conf_address_rule { + radix_tree_t *ipv4; + radix_tree_t *ipv6; +}; + extern char dns_conf_server_ip[DNS_MAX_IPLEN]; extern char dns_conf_server_tcp_ip[DNS_MAX_IPLEN]; extern int dns_conf_tcp_idle_time; @@ -119,7 +124,7 @@ extern int dns_conf_audit_num; extern char dns_conf_server_name[DNS_MAX_CONF_CNAME_LEN]; extern art_tree dns_conf_domain_rule; -extern radix_tree_t *dns_conf_address_rule; +extern struct dns_conf_address_rule dns_conf_address_rule; extern int dns_conf_dualstack_ip_selection; extern int dns_conf_dualstack_ip_selection_threshold; diff --git a/src/dns_server.c b/src/dns_server.c index 27fef02..c6a6200 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -864,7 +864,17 @@ static int _dns_server_ip_rule_check(struct dns_request *request, unsigned char return -1; } - node = radix_search_best(dns_conf_address_rule, &prefix); + switch (prefix.family) { + case AF_INET: + node = radix_search_best(dns_conf_address_rule.ipv4, &prefix); + break; + case AF_INET6: + node = radix_search_best(dns_conf_address_rule.ipv6, &prefix); + break; + default: + break; + } + if (node == NULL) { return -1; } diff --git a/src/lib/radix.c b/src/lib/radix.c index e01fa9d..5ec0830 100644 --- a/src/lib/radix.c +++ b/src/lib/radix.c @@ -221,6 +221,9 @@ Clear_Radix(radix_tree_t *radix, rdx_cb_t func, void *cbctx) void Destroy_Radix(radix_tree_t *radix, rdx_cb_t func, void *cbctx) { + if (radix == NULL) { + return; + } Clear_Radix(radix, func, cbctx); free(radix); }