Support IP dualstack speed perference
This commit is contained in:
@@ -36,9 +36,14 @@ cache-size 512
|
||||
# List of IPs that will be filtered when nameserver is configured -blacklist-ip parameter
|
||||
# blacklist-ip [ip/subnet]
|
||||
|
||||
# force AAAA query return SO
|
||||
# force AAAA query return SOA
|
||||
# force-AAAA-SOA [yes|no]
|
||||
|
||||
# enabel ipv4 and ipv6 preference
|
||||
# dualstack-preference-threshold [num] (100~10000)
|
||||
# dualstack-preference [yes|no]
|
||||
# dualstack-preference yes
|
||||
|
||||
# ttl for all resource record
|
||||
# rr-ttl: ttl for all record
|
||||
# rr-ttl-min: minimum ttl for resource record
|
||||
|
||||
@@ -36,6 +36,9 @@ int dns_conf_audit_num = 2;
|
||||
art_tree dns_conf_domain_rule;
|
||||
radix_tree_t *dns_conf_address_rule;
|
||||
|
||||
int dns_conf_dualstack_preference;
|
||||
int dns_conf_dualstack_threshold = 1000; // cent usecond
|
||||
|
||||
int dns_conf_rr_ttl;
|
||||
int dns_conf_rr_ttl_min;
|
||||
int dns_conf_rr_ttl_max;
|
||||
@@ -514,6 +517,8 @@ struct config_item config_item[] = {
|
||||
CONF_INT("tcp-idle-time", &dns_conf_tcp_idle_time, 0, 3600),
|
||||
CONF_INT("cache-size", &dns_conf_cachesize, 0, CONF_INT_MAX),
|
||||
CONF_YESNO("prefetch-domain", &dns_conf_prefetch),
|
||||
CONF_YESNO("dualstack-preference", &dns_conf_dualstack_preference),
|
||||
CONF_INT("dualstack-preference-threshold", &dns_conf_dualstack_threshold, 100, 10000),
|
||||
CONF_CUSTOM("log-level", config_log_level, NULL),
|
||||
CONF_STRING("log-file", (char *)dns_conf_log_file, DNS_MAX_PATH),
|
||||
CONF_SIZE("log-size", &dns_conf_log_size, 0, 1024 * 1024 * 1024),
|
||||
|
||||
@@ -99,6 +99,9 @@ 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 int dns_conf_dualstack_preference;
|
||||
extern int dns_conf_dualstack_threshold;
|
||||
|
||||
extern int dns_conf_rr_ttl;
|
||||
extern int dns_conf_rr_ttl_min;
|
||||
extern int dns_conf_rr_ttl_max;
|
||||
|
||||
@@ -148,7 +148,7 @@ struct dns_request {
|
||||
|
||||
/* send original raw packet to server/client like proxy */
|
||||
int passthrough;
|
||||
|
||||
int request_wait;
|
||||
int prefetch;
|
||||
|
||||
pthread_mutex_t ip_map_lock;
|
||||
@@ -419,6 +419,30 @@ static int _dns_reply(struct dns_request *request)
|
||||
return _dns_reply_inpacket(request, inpacket, encode_len);
|
||||
}
|
||||
|
||||
static int _dns_server_reply_SOA(int rcode, struct dns_request *request, struct dns_packet *packet)
|
||||
{
|
||||
struct dns_soa *soa;
|
||||
|
||||
request->rcode = rcode;
|
||||
request->has_soa = 1;
|
||||
request->has_ipv4 = 0;
|
||||
request->has_ipv6 = 0;
|
||||
request->has_ptr = 0;
|
||||
|
||||
soa = &request->soa;
|
||||
|
||||
strcpy(soa->mname, "a.gtld-servers.net");
|
||||
strcpy(soa->rname, "nstld.verisign-grs.com");
|
||||
soa->serial = 1800;
|
||||
soa->refresh = 1800;
|
||||
soa->retry = 900;
|
||||
soa->expire = 604800;
|
||||
soa->minimum = 86400;
|
||||
_dns_reply(request);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_setup_ipset(struct dns_request *request)
|
||||
{
|
||||
struct dns_ipset_rule *ipset_rule = NULL;
|
||||
@@ -489,6 +513,15 @@ int _dns_server_request_complete(struct dns_request *request)
|
||||
request->ipv6_addr[6], request->ipv6_addr[7], request->ipv6_addr[8], request->ipv6_addr[9], request->ipv6_addr[10], request->ipv6_addr[11],
|
||||
request->ipv6_addr[12], request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]);
|
||||
|
||||
if (request->has_ipv4) {
|
||||
dns_cache_insert(request->domain, cname, cname_ttl, request->ttl_v4, DNS_T_AAAA, request->ipv4_addr, DNS_RR_A_LEN);
|
||||
|
||||
if ((request->ping_ttl_v4 - dns_conf_dualstack_threshold < request->ping_ttl_v6 ) && (request->ping_ttl_v4 > 0)) {
|
||||
tlog(TLOG_DEBUG, "Force IPV4 perfered.");
|
||||
return _dns_server_reply_SOA(DNS_RC_NOERROR, request, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (request->has_ipv6) {
|
||||
if (request->has_ping_result == 0 && request->ttl_v6 > DNS_SERVER_TMOUT_TTL) {
|
||||
request->ttl_v6 = DNS_SERVER_TMOUT_TTL;
|
||||
@@ -566,6 +599,7 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
|
||||
{
|
||||
struct dns_request *request = userptr;
|
||||
int may_complete = 0;
|
||||
int threshold = 100;
|
||||
|
||||
if (request == NULL) {
|
||||
return;
|
||||
@@ -579,6 +613,7 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
|
||||
|
||||
unsigned int rtt = tv->tv_sec * 10000 + tv->tv_usec / 100;
|
||||
|
||||
|
||||
switch (addr->sa_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in;
|
||||
@@ -588,6 +623,10 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
|
||||
request->has_ipv4 = 1;
|
||||
memcpy(request->ipv4_addr, &addr_in->sin_addr.s_addr, 4);
|
||||
}
|
||||
|
||||
if (dns_conf_dualstack_preference == 1 && request->qtype == DNS_T_AAAA) {
|
||||
threshold = dns_conf_dualstack_threshold;
|
||||
}
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6;
|
||||
@@ -616,7 +655,7 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
|
||||
tlog(TLOG_DEBUG, "from %15s: seq=%d timeout\n", host, seqno);
|
||||
}
|
||||
|
||||
if (rtt < 100) {
|
||||
if (rtt < threshold) {
|
||||
may_complete = 1;
|
||||
} else if (rtt < (get_tick_count() - request->send_tick) * 10) {
|
||||
may_complete = 1;
|
||||
@@ -763,7 +802,9 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
|
||||
unsigned char addr[4];
|
||||
if (request->qtype != DNS_T_A) {
|
||||
/* ignore non-matched query type */
|
||||
break;
|
||||
if (dns_conf_dualstack_preference == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_dns_server_request_get(request);
|
||||
dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
|
||||
@@ -905,6 +946,7 @@ static int dns_server_resolve_callback(char *domain, dns_result_type rtype, unsi
|
||||
{
|
||||
struct dns_request *request = user_ptr;
|
||||
int ip_num = 0;
|
||||
int request_wait = 0;
|
||||
|
||||
if (request == NULL) {
|
||||
return -1;
|
||||
@@ -925,10 +967,12 @@ static int dns_server_resolve_callback(char *domain, dns_result_type rtype, unsi
|
||||
} else {
|
||||
pthread_mutex_lock(&request->ip_map_lock);
|
||||
ip_num = request->ip_map_num;
|
||||
request_wait = request->request_wait;
|
||||
request->request_wait--;
|
||||
pthread_mutex_unlock(&request->ip_map_lock);
|
||||
|
||||
/* Not need to wait check result if only has one ip address */
|
||||
if (ip_num == 1) {
|
||||
if (ip_num == 1 && request_wait == 1) {
|
||||
_dns_server_request_complete(request);
|
||||
}
|
||||
|
||||
@@ -1014,27 +1058,6 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _dns_server_reply_SOA(int rcode, struct dns_request *request, struct dns_packet *packet)
|
||||
{
|
||||
struct dns_soa *soa;
|
||||
|
||||
request->rcode = rcode;
|
||||
request->has_soa = 1;
|
||||
|
||||
soa = &request->soa;
|
||||
|
||||
strcpy(soa->mname, "a.gtld-servers.net");
|
||||
strcpy(soa->rname, "nstld.verisign-grs.com");
|
||||
soa->serial = 1800;
|
||||
soa->refresh = 1800;
|
||||
soa->retry = 900;
|
||||
soa->expire = 604800;
|
||||
soa->minimum = 86400;
|
||||
_dns_reply(request);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _dns_server_log_rule(char *domain, unsigned char *rule_key, int rule_key_len)
|
||||
{
|
||||
char rule_name[DNS_MAX_CNAME_LEN];
|
||||
@@ -1278,7 +1301,14 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac
|
||||
|
||||
_dns_server_request_get(request);
|
||||
request->send_tick = get_tick_count();
|
||||
|
||||
dns_client_query(request->domain, qtype, dns_server_resolve_callback, request);
|
||||
request->request_wait++;
|
||||
if (qtype == DNS_T_AAAA && dns_conf_dualstack_preference) {
|
||||
_dns_server_request_get(request);
|
||||
dns_client_query(request->domain, DNS_T_A, dns_server_resolve_callback, request);
|
||||
request->request_wait++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
clean_exit:
|
||||
|
||||
@@ -285,7 +285,7 @@ void sig_error_exit(int signo, siginfo_t *siginfo, void *context)
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
int sig_list[] = {SIGSEGV, SIGABRT, SIGPIPE, SIGBUS, SIGILL, SIGFPE};
|
||||
int sig_list[] = {SIGSEGV, SIGABRT, SIGBUS, SIGILL, SIGFPE};
|
||||
|
||||
int sig_num = sizeof(sig_list) / sizeof(int);
|
||||
|
||||
@@ -362,11 +362,12 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
signal(SIGINT, sig_exit);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
atexit(smartdns_exit);
|
||||
|
||||
return smartdns_run();
|
||||
|
||||
|
||||
errout:
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user