dns_conf: ip-alias support ip-set input
This commit is contained in:
@@ -348,3 +348,4 @@ log-level info
|
||||
# ip-set -name ip-list -file /etc/smartdns/ip-list.conf
|
||||
# bogus-nxdomain ip-set:ip-list
|
||||
# ip-alias ip-set:ip-list 1.2.3.4
|
||||
# ip-alias ip-set:ip-list ip-set:ip-map-list
|
||||
|
||||
@@ -296,6 +296,7 @@ load_domain_rules()
|
||||
|
||||
config_get forwarding_domain_set_file "$section" "forwarding_domain_set_file" ""
|
||||
[ ! -z "$forwarding_domain_set_file" ] && {
|
||||
[ ! -e "$forwarding_domain_set_file" ] && touch $forwarding_domain_set_file
|
||||
conf_append "domain-set" "-name ${domain_set_name}-forwarding-file -file '$forwarding_domain_set_file'"
|
||||
conf_append "domain-rules" "/domain-set:${domain_set_name}-forwarding-file/ $domain_set_args"
|
||||
}
|
||||
@@ -307,6 +308,7 @@ load_domain_rules()
|
||||
|
||||
config_get block_domain_set_file "$section" "block_domain_set_file"
|
||||
[ ! -z "$block_domain_set_file" ] && {
|
||||
[ ! -e "$block_domain_set_file" ] && touch $block_domain_set_file
|
||||
conf_append "domain-set" "-name ${domain_set_name}-block-file -file '$block_domain_set_file'"
|
||||
conf_append "domain-rules" "/domain-set:${domain_set_name}-block-file/ --address #"
|
||||
}
|
||||
@@ -355,6 +357,7 @@ load_domain_rule_list()
|
||||
[ ! -z "$addition_flag" ] && domain_set_args="$domain_set_args $addition_flag"
|
||||
[ -z "$domain_set_args" ] && return
|
||||
|
||||
[ ! -e "$domain_list_file" ] && touch $domain_list_file
|
||||
conf_append "domain-set" "-name domain-rule-list-${domain_set_name} -file '$domain_list_file'"
|
||||
conf_append "domain-rules" "/domain-set:domain-rule-list-${domain_set_name}/ $domain_set_args"
|
||||
}
|
||||
|
||||
112
src/dns_conf.c
112
src/dns_conf.c
@@ -794,8 +794,8 @@ static int _config_set_rule_each_from_list(const char *file, set_rule_add_func c
|
||||
|
||||
fp = fopen(file, "r");
|
||||
if (fp == NULL) {
|
||||
tlog(TLOG_WARN, "open file %s error, %s", file, strerror(errno));
|
||||
return 0;
|
||||
tlog(TLOG_ERROR, "open file %s error, %s", file, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
line_no = 0;
|
||||
@@ -845,7 +845,9 @@ static int _config_domain_rule_set_each(const char *domain_set, set_rule_add_fun
|
||||
{
|
||||
switch (set_name_item->type) {
|
||||
case DNS_DOMAIN_SET_LIST:
|
||||
_config_set_rule_each_from_list(set_name_item->file, callback, priv);
|
||||
if (_config_set_rule_each_from_list(set_name_item->file, callback, priv) != 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case DNS_DOMAIN_SET_GEOSITE:
|
||||
break;
|
||||
@@ -2858,7 +2860,9 @@ static int _config_ip_rule_set_each(const char *ip_set, set_rule_add_func callba
|
||||
{
|
||||
switch (set_name_item->type) {
|
||||
case DNS_IP_SET_LIST:
|
||||
_config_set_rule_each_from_list(set_name_item->file, callback, priv);
|
||||
if (_config_set_rule_each_from_list(set_name_item->file, callback, priv) != 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
tlog(TLOG_WARN, "ip set %s type %d not support.", set_name_list->name, set_name_item->type);
|
||||
@@ -3020,10 +3024,58 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _config_ip_rule_alias_add_ip(const char *ip, struct ip_rule_alias *ip_alias)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
unsigned char *paddr = NULL;
|
||||
int ret = 0;
|
||||
|
||||
ret = getaddr_by_host(ip, (struct sockaddr *)&addr, &addr_len);
|
||||
if (ret != 0) {
|
||||
tlog(TLOG_ERROR, "ip is invalid: %s", ip);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
switch (addr.ss_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
addr_in = (struct sockaddr_in *)&addr;
|
||||
paddr = (unsigned char *)&(addr_in->sin_addr.s_addr);
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_A_LEN);
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
paddr = addr_in6->sin6_addr.s6_addr + 12;
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_A_LEN);
|
||||
} else {
|
||||
paddr = addr_in6->sin6_addr.s6_addr;
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_AAAA_LEN);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
goto errout;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _config_ip_alias_add_ip_callback(const char *ip_cidr, void *priv)
|
||||
{
|
||||
return _config_ip_rule_alias_add_ip(ip_cidr, (struct ip_rule_alias *)priv);
|
||||
}
|
||||
|
||||
static int _config_ip_alias(const char *ip_cidr, const char *ips)
|
||||
{
|
||||
struct ip_rule_alias *ip_alias = NULL;
|
||||
char *target_ips = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (ip_cidr == NULL || ips == NULL) {
|
||||
goto errout;
|
||||
@@ -3034,43 +3086,21 @@ static int _config_ip_alias(const char *ip_cidr, const char *ips)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
target_ips = strdup(ips);
|
||||
if (target_ips == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
for (char *tok = strtok(target_ips, ","); tok != NULL; tok = strtok(NULL, ",")) {
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
unsigned char *paddr = NULL;
|
||||
int ret = 0;
|
||||
|
||||
ret = getaddr_by_host(tok, (struct sockaddr *)&addr, &addr_len);
|
||||
if (ret != 0) {
|
||||
if (strncmp(ips, "ip-set:", sizeof("ip-set:") - 1) == 0) {
|
||||
if (_config_ip_rule_set_each(ips + sizeof("ip-set:") - 1, _config_ip_alias_add_ip_callback, ip_alias) != 0) {
|
||||
goto errout;
|
||||
}
|
||||
} else {
|
||||
target_ips = strdup(ips);
|
||||
if (target_ips == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
switch (addr.ss_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
addr_in = (struct sockaddr_in *)&addr;
|
||||
paddr = (unsigned char *)&(addr_in->sin_addr.s_addr);
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_A_LEN);
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
paddr = addr_in6->sin6_addr.s6_addr + 12;
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_A_LEN);
|
||||
} else {
|
||||
paddr = addr_in6->sin6_addr.s6_addr;
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_AAAA_LEN);
|
||||
for (char *tok = strtok(target_ips, ","); tok != NULL; tok = strtok(NULL, ",")) {
|
||||
ret = _config_ip_rule_alias_add_ip(tok, ip_alias);
|
||||
if (ret != 0) {
|
||||
goto errout;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
goto errout;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3079,7 +3109,9 @@ static int _config_ip_alias(const char *ip_cidr, const char *ips)
|
||||
}
|
||||
|
||||
_dns_ip_rule_put(&ip_alias->head);
|
||||
free(target_ips);
|
||||
if (target_ips) {
|
||||
free(target_ips);
|
||||
}
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
@@ -3302,6 +3334,10 @@ errout:
|
||||
if (ip_set) {
|
||||
free(ip_set);
|
||||
}
|
||||
|
||||
if (ip_set_name_list != NULL) {
|
||||
free(ip_set_name_list);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -210,3 +210,72 @@ cache-persist no)""");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "7.8.9.10");
|
||||
}
|
||||
|
||||
TEST_F(IPRule, ip_alias_ip_set)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::MockServer server_upstream2;
|
||||
smartdns::Server server;
|
||||
std::string file = "/tmp/smartdns_test_ip_set.list" + smartdns::GenerateRandomString(5);
|
||||
std::string file_ip = "/tmp/smartdns_test_ip_set_ip.list" + smartdns::GenerateRandomString(5);
|
||||
std::ofstream ofs(file);
|
||||
std::ofstream ofs_ip(file_ip);
|
||||
ASSERT_TRUE(ofs.is_open());
|
||||
ASSERT_TRUE(ofs_ip.is_open());
|
||||
Defer
|
||||
{
|
||||
ofs.close();
|
||||
unlink(file.c_str());
|
||||
ofs_ip.close();
|
||||
unlink(file_ip.c_str());
|
||||
};
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_A) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 611);
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "4.5.6.7", 611);
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "7.8.9.10", 611);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server.MockPing(PING_TYPE_ICMP, "1.2.3.4", 60, 10);
|
||||
server.MockPing(PING_TYPE_ICMP, "4.5.6.7", 60, 90);
|
||||
server.MockPing(PING_TYPE_ICMP, "7.8.9.10", 60, 40);
|
||||
|
||||
std::string ipset_list = R"""(
|
||||
1.2.3.0/24
|
||||
4.5.6.0/24
|
||||
7.8.9.0/24
|
||||
)""";
|
||||
ofs.write(ipset_list.c_str(), ipset_list.length());
|
||||
ofs.flush();
|
||||
|
||||
std::string ipset_list_ip = R"""(
|
||||
1.1.1.1
|
||||
)""";
|
||||
ofs_ip.write(ipset_list_ip.c_str(), ipset_list_ip.length());
|
||||
ofs_ip.flush();
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server udp://127.0.0.1:61053 -blacklist-ip
|
||||
ip-set -name ip-list -file )""" +
|
||||
file + R"""(
|
||||
ip-set -name ip-list-ip -file )""" +
|
||||
file_ip + R"""(
|
||||
ip-alias ip-set:ip-list ip-set:ip-list-ip
|
||||
log-num 0
|
||||
speed-check-mode none
|
||||
log-console yes
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("a.com", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.1.1.1");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user