Compare commits
5 Commits
Release37
...
Release37.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96d3deb595 | ||
|
|
584480dda1 | ||
|
|
2848aa0ac7 | ||
|
|
c156595f61 | ||
|
|
9dfe51c5ed |
@@ -563,6 +563,7 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
|
||||
| rr-ttl-min | 允许的最小 TTL 值 | 远程查询结果 | 大于 0 的数字 | rr-ttl-min 60 |
|
||||
| rr-ttl-max | 允许的最大 TTL 值 | 远程查询结果 | 大于 0 的数字 | rr-ttl-max 600 |
|
||||
| rr-ttl-reply-max | 允许返回给客户端的最大 TTL 值 | 远程查询结果 | 大于 0 的数字 | rr-ttl-reply-max 60 |
|
||||
| local-ttl | 本地HOST,address的TTL值 | rr-ttl-min | 大于 0 的数字 | local-ttl 60 |
|
||||
| max-reply-ip-num | 允许返回给客户的最大IP数量 | IP数量 | 大于 0 的数字 | max-reply-ip-num 1 |
|
||||
| log-level | 设置日志级别 | error | fatal、error、warn、notice、info 或 debug | log-level error |
|
||||
| log-file | 日志文件路径 | /var/log/smartdns/smartdns.log | 合法路径字符串 | log-file /var/log/smartdns/smartdns.log |
|
||||
|
||||
@@ -497,6 +497,7 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|
||||
|tcp-idle-time|TCP connection idle timeout|120|integer|tcp-idle-time 120
|
||||
|rr-ttl|Domain name TTL|Remote query result|number greater than 0|rr-ttl 600
|
||||
|rr-ttl-min|Domain name Minimum TTL|Remote query result|number greater than 0|rr-ttl-min 60
|
||||
|local-ttl|ttl for address and host|rr-ttl-min|number greater than 0|local-ttl 600
|
||||
|rr-ttl-reply-max|Domain name Minimum Reply TTL|Remote query result|number greater than 0|rr-ttl-reply-max 60
|
||||
|rr-ttl-max|Domain name Maximum TTL|Remote query result|number greater than 0|rr-ttl-max 600
|
||||
|max-reply-ip-num|Maximum number of IPs returned to the client|8|number of IPs, 1~16 |max-reply-ip-num 1
|
||||
|
||||
@@ -187,7 +187,7 @@ init_dir()
|
||||
which systemctl >/dev/null 2>&1
|
||||
ISSYSTEMD="$?"
|
||||
# Running under WSL (Windows Subsystem for Linux)?
|
||||
cat /proc/version | grep Microsoft >/dev/null 2>&1;
|
||||
cat /proc/version | grep -E '[Mm]icrosoft' >/dev/null 2>&1;
|
||||
if [ $? -eq 0 ]; then
|
||||
ISSYSTEMD=1
|
||||
ISWSL=0
|
||||
|
||||
@@ -22,6 +22,7 @@ SMARTDNS_PID=/var/run/smartdns.pid
|
||||
SMARTDNS_PORT=535
|
||||
SMARTDNS_OPT=/opt/etc/smartdns/smartdns-opt.conf
|
||||
# workmode
|
||||
# DO NOT CHANGE THIS, CHANGE MODE IN smartdns-opt.conf
|
||||
# 0: run as port only
|
||||
# 1: redirect port
|
||||
# 2: replace
|
||||
@@ -232,11 +233,11 @@ set_smartdns_port()
|
||||
if [ "$SMARTDNS_WORKMODE" = "0" ]; then
|
||||
return 0
|
||||
elif [ "$SMARTDNS_WORKMODE" = "1" ]; then
|
||||
sed -i "s/^\\(bind .*\\):53 *\\(.*\\)\$/\\1:$SMARTDNS_PORT \\2/g" $SMARTDNS_CONF
|
||||
sed -i "s/^\\(bind-tcp .*\\):53 *\\(.*\\)\$/\\1:$SMARTDNS_PORT \\2/g" $SMARTDNS_CONF
|
||||
sed -i "s/^\(bind .*\):53\( .*\)\?$/\1:$SMARTDNS_PORT \2/g" $SMARTDNS_CONF
|
||||
sed -i "s/^\(bind-tcp .*\):53\( .*\)\?$/\1:$SMARTDNS_PORT \2/g" $SMARTDNS_CONF
|
||||
elif [ "$SMARTDNS_WORKMODE" = "2" ]; then
|
||||
sed -i "s/^\\(bind .*\\):$SMARTDNS_PORT *\\(.*\\)\$/\\1:53 \\2/g" $SMARTDNS_CONF
|
||||
sed -i "s/^\\(bind-tcp .*\\):$SMARTDNS_PORT *\\(.*\\)\$/\\1:53 \\2/g" $SMARTDNS_CONF
|
||||
sed -i "s/^\(bind .*\):$SMARTDNS_PORT\( .*\)\?$/\1:53 \2/g" $SMARTDNS_CONF
|
||||
sed -i "s/^\(bind-tcp .*\):$SMARTDNS_PORT\( .*\)\?$/\1:53 \2/g" $SMARTDNS_CONF
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
20
src/dns.c
20
src/dns.c
@@ -43,7 +43,7 @@
|
||||
} while (0)
|
||||
|
||||
/* read short and move pointer */
|
||||
static short _dns_read_short(unsigned char **buffer)
|
||||
static unsigned short _dns_read_short(unsigned char **buffer)
|
||||
{
|
||||
unsigned short value = 0;
|
||||
|
||||
@@ -549,6 +549,10 @@ static int _dns_add_RAW(struct dns_packet *packet, dns_rr_type rrtype, dns_type_
|
||||
struct dns_context context;
|
||||
int ret = 0;
|
||||
|
||||
if (raw_len < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* resource record */
|
||||
/* |domain |
|
||||
* |qtype | qclass |
|
||||
@@ -1153,6 +1157,11 @@ static int _dns_decode_rr_head(struct dns_context *context, char *domain, int do
|
||||
*ttl = _dns_read_int(&context->ptr);
|
||||
*rr_len = _dns_read_short(&context->ptr);
|
||||
|
||||
if (*rr_len < 0 || *ttl < 0) {
|
||||
tlog(TLOG_DEBUG, "rr len or ttl is invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1233,7 +1242,7 @@ static int _dns_encode_raw(struct dns_context *context, struct dns_rrs *rrs)
|
||||
|
||||
static int _dns_decode_raw(struct dns_context *context, unsigned char *raw, int len)
|
||||
{
|
||||
if (_dns_left_len(context) < len) {
|
||||
if (_dns_left_len(context) < len || len < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1595,6 +1604,11 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*/
|
||||
|
||||
if (rr_len < 0) {
|
||||
tlog(TLOG_DEBUG, "opt len is invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ercode != 0) {
|
||||
tlog(TLOG_ERROR, "extend rcode invalid.");
|
||||
return -1;
|
||||
@@ -1682,7 +1696,7 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
|
||||
/* decode rr head */
|
||||
ret = _dns_decode_rr_head(context, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
|
||||
if (ret < 0) {
|
||||
if (ret < 0 || qclass < 0) {
|
||||
tlog(TLOG_DEBUG, "decode head failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -128,9 +128,14 @@ enum CACHE_TYPE dns_cache_data_type(struct dns_cache_data *cache_data)
|
||||
return cache_data->head.cache_type;
|
||||
}
|
||||
|
||||
uint32_t dns_cache_get_cache_flag(struct dns_cache_data *cache_data)
|
||||
uint32_t dns_cache_get_query_flag(struct dns_cache_data *cache_data)
|
||||
{
|
||||
return cache_data->head.cache_flag;
|
||||
return cache_data->head.query_flag;
|
||||
}
|
||||
|
||||
const char *dns_cache_get_dns_group_name(struct dns_cache_data *cache_data)
|
||||
{
|
||||
return cache_data->head.dns_group_name;
|
||||
}
|
||||
|
||||
void dns_cache_data_free(struct dns_cache_data *data)
|
||||
@@ -156,7 +161,8 @@ struct dns_cache_data *dns_cache_new_data(void)
|
||||
return (struct dns_cache_data *)cache_addr;
|
||||
}
|
||||
|
||||
void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, int32_t cache_flag, char *cname, int cname_ttl)
|
||||
void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, struct dns_cache_query_option *query_option, char *cname,
|
||||
int cname_ttl)
|
||||
{
|
||||
if (dns_cache == NULL) {
|
||||
goto errout;
|
||||
@@ -179,7 +185,13 @@ void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, int32_t cache_flag
|
||||
cache_addr->addr_data.cname_ttl = cname_ttl;
|
||||
}
|
||||
|
||||
cache_addr->head.cache_flag = cache_flag;
|
||||
if (query_option) {
|
||||
cache_addr->head.query_flag = query_option->query_flag;
|
||||
if (query_option->dns_group_name) {
|
||||
safe_strncpy(cache_addr->head.dns_group_name, query_option->dns_group_name, DNS_CACHE_GROUP_NAME_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
cache_addr->addr_data.soa = 1;
|
||||
cache_addr->head.cache_type = CACHE_TYPE_ADDR;
|
||||
cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head);
|
||||
@@ -187,8 +199,8 @@ errout:
|
||||
return;
|
||||
}
|
||||
|
||||
void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, uint32_t cache_flag, char *cname, int cname_ttl,
|
||||
unsigned char *addr, int addr_len)
|
||||
void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, struct dns_cache_query_option *query_option, char *cname,
|
||||
int cname_ttl, unsigned char *addr, int addr_len)
|
||||
{
|
||||
if (dns_cache == NULL) {
|
||||
goto errout;
|
||||
@@ -212,14 +224,21 @@ void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, uint32_t cache_fl
|
||||
cache_addr->addr_data.cname_ttl = cname_ttl;
|
||||
}
|
||||
|
||||
cache_addr->head.cache_flag = cache_flag;
|
||||
if (query_option) {
|
||||
cache_addr->head.query_flag = query_option->query_flag;
|
||||
if (query_option->dns_group_name) {
|
||||
safe_strncpy(cache_addr->head.dns_group_name, query_option->dns_group_name, DNS_CACHE_GROUP_NAME_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
cache_addr->head.cache_type = CACHE_TYPE_ADDR;
|
||||
cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head);
|
||||
errout:
|
||||
return;
|
||||
}
|
||||
|
||||
struct dns_cache_data *dns_cache_new_data_packet(uint32_t cache_flag, void *packet, size_t packet_len)
|
||||
struct dns_cache_data *dns_cache_new_data_packet(struct dns_cache_query_option *query_option, void *packet,
|
||||
size_t packet_len)
|
||||
{
|
||||
struct dns_cache_packet *cache_packet = NULL;
|
||||
size_t data_size = 0;
|
||||
@@ -236,7 +255,12 @@ struct dns_cache_data *dns_cache_new_data_packet(uint32_t cache_flag, void *pack
|
||||
memcpy(cache_packet->data, packet, packet_len);
|
||||
memset(&cache_packet->head, 0, sizeof(cache_packet->head));
|
||||
|
||||
cache_packet->head.cache_flag = cache_flag;
|
||||
if (query_option) {
|
||||
cache_packet->head.query_flag = query_option->query_flag;
|
||||
if (query_option->dns_group_name) {
|
||||
strncpy(cache_packet->head.dns_group_name, query_option->dns_group_name, DNS_CACHE_GROUP_NAME_LEN - 1);
|
||||
}
|
||||
}
|
||||
cache_packet->head.cache_type = CACHE_TYPE_PACKET;
|
||||
cache_packet->head.size = packet_len;
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ extern "C" {
|
||||
|
||||
#define DNS_CACHE_TTL_MIN 1
|
||||
#define DNS_CACHE_VERSION_LEN 32
|
||||
#define DNS_CACHE_GROUP_NAME_LEN 32
|
||||
#define MAGIC_NUMBER 0x6548634163536e44
|
||||
#define MAGIC_CACHE_DATA 0x44615461
|
||||
|
||||
@@ -47,9 +48,15 @@ enum CACHE_RECORD_TYPE {
|
||||
CACHE_RECORD_TYPE_INACTIVE,
|
||||
};
|
||||
|
||||
struct dns_cache_query_option {
|
||||
uint32_t query_flag;
|
||||
const char *dns_group_name;
|
||||
};
|
||||
|
||||
struct dns_cache_data_head {
|
||||
uint32_t cache_flag;
|
||||
enum CACHE_TYPE cache_type;
|
||||
uint32_t query_flag;
|
||||
char dns_group_name[DNS_CACHE_GROUP_NAME_LEN];
|
||||
int is_soa;
|
||||
ssize_t size;
|
||||
};
|
||||
@@ -115,11 +122,14 @@ struct dns_cache_file {
|
||||
|
||||
enum CACHE_TYPE dns_cache_data_type(struct dns_cache_data *cache_data);
|
||||
|
||||
uint32_t dns_cache_get_cache_flag(struct dns_cache_data *cache_data);
|
||||
uint32_t dns_cache_get_query_flag(struct dns_cache_data *cache_data);
|
||||
|
||||
const char *dns_cache_get_dns_group_name(struct dns_cache_data *cache_data);
|
||||
|
||||
void dns_cache_data_free(struct dns_cache_data *data);
|
||||
|
||||
struct dns_cache_data *dns_cache_new_data_packet(uint32_t cache_flag, void *packet, size_t packet_len);
|
||||
struct dns_cache_data *dns_cache_new_data_packet(struct dns_cache_query_option *query_option, void *packet,
|
||||
size_t packet_len);
|
||||
|
||||
int dns_cache_init(int size, int enable_inactive, int inactive_list_expired);
|
||||
|
||||
@@ -156,10 +166,11 @@ struct dns_cache_data *dns_cache_new_data(void);
|
||||
|
||||
struct dns_cache_data *dns_cache_get_data(struct dns_cache *dns_cache);
|
||||
|
||||
void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, uint32_t cache_flag, char *cname, int cname_ttl,
|
||||
unsigned char *addr, int addr_len);
|
||||
void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, struct dns_cache_query_option *query_option, char *cname,
|
||||
int cname_ttl, unsigned char *addr, int addr_len);
|
||||
|
||||
void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, int32_t cache_flag, char *cname, int cname_ttl);
|
||||
void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, struct dns_cache_query_option *query_option, char *cname,
|
||||
int cname_ttl);
|
||||
|
||||
void dns_cache_destroy(void);
|
||||
|
||||
|
||||
@@ -1416,10 +1416,6 @@ static void _dns_client_query_remove(struct dns_query_struct *query)
|
||||
{
|
||||
/* remove query from period check list, and release reference*/
|
||||
pthread_mutex_lock(&client.domain_map_lock);
|
||||
if (list_empty(&query->dns_request_list)) {
|
||||
pthread_mutex_unlock(&client.domain_map_lock);
|
||||
return;
|
||||
}
|
||||
list_del_init(&query->dns_request_list);
|
||||
hash_del(&query->domain_node);
|
||||
pthread_mutex_unlock(&client.domain_map_lock);
|
||||
|
||||
@@ -124,6 +124,7 @@ int dns_conf_rr_ttl;
|
||||
int dns_conf_rr_ttl_reply_max;
|
||||
int dns_conf_rr_ttl_min = 600;
|
||||
int dns_conf_rr_ttl_max;
|
||||
int dns_conf_local_ttl;
|
||||
int dns_conf_force_AAAA_SOA;
|
||||
int dns_conf_force_no_cname;
|
||||
int dns_conf_ipset_timeout_enable;
|
||||
@@ -1907,6 +1908,7 @@ static struct config_item _config_item[] = {
|
||||
CONF_INT("rr-ttl-min", &dns_conf_rr_ttl_min, 0, CONF_INT_MAX),
|
||||
CONF_INT("rr-ttl-max", &dns_conf_rr_ttl_max, 0, CONF_INT_MAX),
|
||||
CONF_INT("rr-ttl-reply-max", &dns_conf_rr_ttl_reply_max, 0, CONF_INT_MAX),
|
||||
CONF_INT("local-ttl", &dns_conf_local_ttl, 0, CONF_INT_MAX),
|
||||
CONF_INT("max-reply-ip-num", &dns_conf_max_reply_ip_num, 1, CONF_INT_MAX),
|
||||
CONF_ENUM("response-mode", &dns_conf_response_mode, &dns_conf_response_mode_enum),
|
||||
CONF_YESNO("force-AAAA-SOA", &dns_conf_force_AAAA_SOA),
|
||||
@@ -2091,6 +2093,10 @@ static int _dns_conf_load_post(void)
|
||||
dns_conf_response_mode_enum[dns_conf_response_mode].name);
|
||||
}
|
||||
|
||||
if (dns_conf_local_ttl == 0) {
|
||||
dns_conf_local_ttl = dns_conf_rr_ttl_min;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -312,6 +312,7 @@ extern int dns_conf_rr_ttl_min;
|
||||
extern int dns_conf_rr_ttl_max;
|
||||
extern int dns_conf_force_AAAA_SOA;
|
||||
extern int dns_conf_ipset_timeout_enable;
|
||||
extern int dns_conf_local_ttl;
|
||||
|
||||
extern int dns_conf_force_no_cname;
|
||||
|
||||
|
||||
114
src/dns_server.c
114
src/dns_server.c
@@ -163,6 +163,7 @@ struct dns_request {
|
||||
|
||||
struct dns_server_conn_head *conn;
|
||||
uint32_t server_flags;
|
||||
char dns_group_name[DNS_GROUP_NAME_LEN];
|
||||
|
||||
/* dns request list */
|
||||
struct list_head list;
|
||||
@@ -261,8 +262,8 @@ static tlog_log *dns_audit;
|
||||
|
||||
static int is_ipv6_ready;
|
||||
|
||||
static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, int expired_domain, uint32_t server_flags,
|
||||
struct dns_query_options *options);
|
||||
static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, int expired_domain,
|
||||
struct dns_server_query_option *server_query_option);
|
||||
static int _dns_server_get_answer(struct dns_server_post_context *context);
|
||||
static void _dns_server_request_get(struct dns_request *request);
|
||||
static void _dns_server_request_release(struct dns_request *request);
|
||||
@@ -940,6 +941,8 @@ static int _dns_server_request_update_cache(struct dns_request *request, dns_typ
|
||||
speed = request->ping_time;
|
||||
|
||||
if (has_soa) {
|
||||
struct dns_cache_query_option cache_option;
|
||||
|
||||
if (request->dualstack_selection && request->has_ip && request->qtype == DNS_T_AAAA) {
|
||||
ttl = _dns_server_get_conf_ttl(request->ip_ttl);
|
||||
} else {
|
||||
@@ -948,7 +951,10 @@ static int _dns_server_request_update_cache(struct dns_request *request, dns_typ
|
||||
ttl = DNS_SERVER_TMOUT_TTL;
|
||||
}
|
||||
}
|
||||
dns_cache_set_data_soa(cache_data, request->server_flags, request->cname, request->ttl_cname);
|
||||
|
||||
cache_option.query_flag = request->server_flags;
|
||||
cache_option.dns_group_name = 0;
|
||||
dns_cache_set_data_soa(cache_data, &cache_option, request->cname, request->ttl_cname);
|
||||
}
|
||||
|
||||
tlog(TLOG_DEBUG, "cache %s qtype: %d ttl: %d\n", request->domain, qtype, ttl);
|
||||
@@ -983,6 +989,7 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context)
|
||||
{
|
||||
struct dns_packet *packet = context->packet;
|
||||
struct dns_packet *cname_packet = NULL;
|
||||
struct dns_cache_query_option cache_option;
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
@@ -1080,7 +1087,10 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context)
|
||||
if (inpacket_len <= 0) {
|
||||
return -1;
|
||||
}
|
||||
cache_packet = dns_cache_new_data_packet(request->server_flags, inpacket_buff, inpacket_len);
|
||||
|
||||
cache_option.query_flag = request->server_flags;
|
||||
cache_option.dns_group_name = request->dns_group_name;
|
||||
cache_packet = dns_cache_new_data_packet(&cache_option, inpacket_buff, inpacket_len);
|
||||
if (cache_packet == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1123,9 +1133,13 @@ errout:
|
||||
|
||||
static int _dns_cache_packet(struct dns_server_post_context *context)
|
||||
{
|
||||
struct dns_cache_query_option cache_option;
|
||||
struct dns_request *request = context->request;
|
||||
|
||||
cache_option.query_flag = request->server_flags;
|
||||
cache_option.dns_group_name = request->dns_group_name;
|
||||
struct dns_cache_data *cache_packet =
|
||||
dns_cache_new_data_packet(request->server_flags, context->inpacket, context->inpacket_len);
|
||||
dns_cache_new_data_packet(&cache_option, context->inpacket, context->inpacket_len);
|
||||
if (cache_packet == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1249,8 +1263,11 @@ static int _dns_cache_reply_packet(struct dns_server_post_context *context)
|
||||
return _dns_cache_specify_packet(context);
|
||||
}
|
||||
|
||||
struct dns_cache_query_option cache_option;
|
||||
cache_option.query_flag = request->server_flags;
|
||||
cache_option.dns_group_name = request->dns_group_name;
|
||||
struct dns_cache_data *cache_packet =
|
||||
dns_cache_new_data_packet(request->server_flags, context->inpacket, context->inpacket_len);
|
||||
dns_cache_new_data_packet(&cache_option, context->inpacket, context->inpacket_len);
|
||||
if (cache_packet == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1788,10 +1805,6 @@ static void _dns_server_complete_with_multi_ipaddress(struct dns_request *reques
|
||||
struct dns_server_post_context context;
|
||||
int do_reply = 0;
|
||||
|
||||
if (request->passthrough) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (atomic_read(&request->ip_map_num) > 0) {
|
||||
request->has_soa = 0;
|
||||
}
|
||||
@@ -3400,7 +3413,7 @@ static int _dns_server_process_address(struct dns_request *request)
|
||||
}
|
||||
|
||||
request->rcode = DNS_RC_NOERROR;
|
||||
request->ip_ttl = 600;
|
||||
request->ip_ttl = dns_conf_local_ttl;
|
||||
request->has_ip = 1;
|
||||
|
||||
struct dns_server_post_context context;
|
||||
@@ -3647,18 +3660,21 @@ reply_cache:
|
||||
|
||||
out_update_cache:
|
||||
if (dns_cache_get_ttl(dns_cache) == 0) {
|
||||
uint32_t server_flags = request->server_flags;
|
||||
struct dns_query_options options;
|
||||
struct dns_server_query_option dns_query_options;
|
||||
dns_query_options.server_flags = request->server_flags;
|
||||
dns_query_options.dns_group_name = request->dns_group_name;
|
||||
if (request->conn == NULL) {
|
||||
server_flags = dns_cache_get_cache_flag(dns_cache->cache_data);
|
||||
dns_query_options.server_flags = dns_cache_get_query_flag(dns_cache->cache_data);
|
||||
dns_query_options.dns_group_name = dns_cache_get_dns_group_name(dns_cache->cache_data);
|
||||
}
|
||||
|
||||
options.enable_flag = 0;
|
||||
dns_query_options.ecs_enable_flag = 0;
|
||||
if (request->has_ecs) {
|
||||
options.enable_flag |= DNS_QUEY_OPTION_ECS_DNS;
|
||||
memcpy(&options.ecs_dns, &request->ecs, sizeof(options.ecs_dns));
|
||||
dns_query_options.ecs_enable_flag |= DNS_QUEY_OPTION_ECS_DNS;
|
||||
memcpy(&dns_query_options.ecs_dns, &request->ecs, sizeof(dns_query_options.ecs_dns));
|
||||
}
|
||||
_dns_server_prefetch_request(request->domain, request->qtype, 0, server_flags, &options);
|
||||
|
||||
_dns_server_prefetch_request(request->domain, request->qtype, 0, &dns_query_options);
|
||||
} else {
|
||||
dns_cache_update(dns_cache);
|
||||
}
|
||||
@@ -3918,7 +3934,7 @@ static int _dns_server_process_host(struct dns_request *request)
|
||||
}
|
||||
|
||||
request->rcode = DNS_RC_NOERROR;
|
||||
request->ip_ttl = 600;
|
||||
request->ip_ttl = dns_conf_local_ttl;
|
||||
request->has_ip = 1;
|
||||
|
||||
struct dns_server_post_context context;
|
||||
@@ -3969,6 +3985,7 @@ static int _dns_server_query_dualstack(struct dns_request *request)
|
||||
}
|
||||
|
||||
request_dualstack->server_flags = request->server_flags;
|
||||
safe_strncpy(request_dualstack->dns_group_name, request->dns_group_name, sizeof(request->dns_group_name));
|
||||
safe_strncpy(request_dualstack->domain, request->domain, sizeof(request->domain));
|
||||
request_dualstack->qtype = qtype;
|
||||
request_dualstack->dualstack_selection_query = 1;
|
||||
@@ -4013,14 +4030,16 @@ static int _dns_server_do_query(struct dns_request *request)
|
||||
|
||||
/* lookup domain rule */
|
||||
_dns_server_get_domain_rule(request);
|
||||
group_name = _dns_server_get_request_groupname(request);
|
||||
if (group_name == NULL) {
|
||||
group_name = dns_group;
|
||||
|
||||
group_name = request->dns_group_name;
|
||||
if (request->dns_group_name[0] == '\0') {
|
||||
group_name = _dns_server_get_request_groupname(request);
|
||||
if (group_name == NULL) {
|
||||
group_name = dns_group;
|
||||
}
|
||||
safe_strncpy(request->dns_group_name, group_name, DNS_GROUP_NAME_LEN);
|
||||
}
|
||||
|
||||
if (_dns_server_process_host(request) == 0) {
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
_dns_server_set_dualstack_selection(request);
|
||||
|
||||
@@ -4038,6 +4057,10 @@ static int _dns_server_do_query(struct dns_request *request)
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
if (_dns_server_process_host(request) == 0) {
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
/* process qtype soa */
|
||||
if (_dns_server_qtype_soa(request) == 0) {
|
||||
goto clean_exit;
|
||||
@@ -4206,22 +4229,28 @@ errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _dns_server_prefetch_setup_options(struct dns_request *request, struct dns_query_options *options)
|
||||
static int _dns_server_setup_server_query_options(struct dns_request *request,
|
||||
struct dns_server_query_option *server_query_option)
|
||||
{
|
||||
if (options == NULL) {
|
||||
if (server_query_option == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (options->enable_flag & DNS_QUEY_OPTION_ECS_DNS) {
|
||||
request->server_flags = server_query_option->server_flags;
|
||||
if (server_query_option->dns_group_name) {
|
||||
safe_strncpy(request->dns_group_name, server_query_option->dns_group_name, DNS_GROUP_NAME_LEN);
|
||||
}
|
||||
|
||||
if (server_query_option->ecs_enable_flag & DNS_QUEY_OPTION_ECS_DNS) {
|
||||
request->has_ecs = 1;
|
||||
memcpy(&request->ecs, &options->ecs_dns, sizeof(request->ecs));
|
||||
memcpy(&request->ecs, &server_query_option->ecs_dns, sizeof(request->ecs));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, int expired_domain, uint32_t server_flags,
|
||||
struct dns_query_options *options)
|
||||
static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, int expired_domain,
|
||||
struct dns_server_query_option *server_query_option)
|
||||
{
|
||||
int ret = -1;
|
||||
struct dns_request *request = NULL;
|
||||
@@ -4234,8 +4263,7 @@ static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, int expi
|
||||
|
||||
safe_strncpy(request->domain, domain, sizeof(request->domain));
|
||||
request->qtype = qtype;
|
||||
request->server_flags = server_flags;
|
||||
_dns_server_prefetch_setup_options(request, options);
|
||||
_dns_server_setup_server_query_options(request, server_query_option);
|
||||
_dns_server_request_set_enable_prefetch(request, expired_domain);
|
||||
ret = _dns_server_do_query(request);
|
||||
if (ret != 0) {
|
||||
@@ -4253,7 +4281,8 @@ errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dns_server_query(const char *domain, int qtype, uint32_t server_flags, dns_result_callback callback, void *user_ptr)
|
||||
int dns_server_query(const char *domain, int qtype, struct dns_server_query_option *server_query_option,
|
||||
dns_result_callback callback, void *user_ptr)
|
||||
{
|
||||
int ret = -1;
|
||||
struct dns_request *request = NULL;
|
||||
@@ -4264,9 +4293,9 @@ int dns_server_query(const char *domain, int qtype, uint32_t server_flags, dns_r
|
||||
goto errout;
|
||||
}
|
||||
|
||||
request->server_flags = server_flags;
|
||||
safe_strncpy(request->domain, domain, sizeof(request->domain));
|
||||
request->qtype = qtype;
|
||||
_dns_server_setup_server_query_options(request, server_query_option);
|
||||
_dns_server_request_set_callback(request, callback, user_ptr);
|
||||
ret = _dns_server_do_query(request);
|
||||
if (ret != 0) {
|
||||
@@ -4662,6 +4691,7 @@ static int _dns_server_second_ping_check(struct dns_request *request)
|
||||
static void _dns_server_prefetch_domain(struct dns_cache *dns_cache)
|
||||
{
|
||||
/* If there are still hits, continue pre-fetching */
|
||||
struct dns_server_query_option server_query_option;
|
||||
int hitnum = dns_cache_hitnum_dec_get(dns_cache);
|
||||
if (hitnum <= 0) {
|
||||
return;
|
||||
@@ -4670,8 +4700,10 @@ static void _dns_server_prefetch_domain(struct dns_cache *dns_cache)
|
||||
/* start prefetch domain */
|
||||
tlog(TLOG_DEBUG, "prefetch by cache %s, qtype %d, ttl %d, hitnum %d", dns_cache->info.domain, dns_cache->info.qtype,
|
||||
dns_cache->info.ttl, hitnum);
|
||||
if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype, 0,
|
||||
dns_cache_get_cache_flag(dns_cache->cache_data), NULL) != 0) {
|
||||
server_query_option.dns_group_name = dns_cache_get_dns_group_name(dns_cache->cache_data);
|
||||
server_query_option.server_flags = dns_cache_get_query_flag(dns_cache->cache_data);
|
||||
server_query_option.ecs_enable_flag = 0;
|
||||
if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype, 0, &server_query_option) != 0) {
|
||||
tlog(TLOG_ERROR, "prefetch domain %s, qtype %d, failed.", dns_cache->info.domain, dns_cache->info.qtype);
|
||||
}
|
||||
}
|
||||
@@ -4682,8 +4714,12 @@ static void _dns_server_prefetch_expired_domain(struct dns_cache *dns_cache)
|
||||
tlog(TLOG_DEBUG, "expired domain, prefetch by cache %s, qtype %d, ttl %d", dns_cache->info.domain,
|
||||
dns_cache->info.qtype, dns_cache->info.ttl);
|
||||
|
||||
if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype, 1,
|
||||
dns_cache_get_cache_flag(dns_cache->cache_data), NULL) != 0) {
|
||||
struct dns_server_query_option server_query_option;
|
||||
server_query_option.dns_group_name = dns_cache_get_dns_group_name(dns_cache->cache_data);
|
||||
server_query_option.server_flags = dns_cache_get_query_flag(dns_cache->cache_data);
|
||||
server_query_option.ecs_enable_flag = 0;
|
||||
|
||||
if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype, 1, &server_query_option) != 0) {
|
||||
tlog(TLOG_ERROR, "prefetch domain %s, qtype %d, failed.", dns_cache->info.domain, dns_cache->info.qtype);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,20 @@
|
||||
|
||||
#include "dns.h"
|
||||
#include <stdint.h>
|
||||
#include "dns_client.h"
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dns_server_query_option {
|
||||
uint32_t server_flags;
|
||||
const char *dns_group_name;
|
||||
unsigned long ecs_enable_flag;
|
||||
struct dns_opt_ecs ecs_dns;
|
||||
struct dns_query_ecs_ip ecs_ip;
|
||||
};
|
||||
|
||||
int dns_server_init(void);
|
||||
|
||||
int dns_server_run(void);
|
||||
@@ -41,7 +50,8 @@ typedef int (*dns_result_callback)(const char *domain, dns_rtcode_t rtcode, dns_
|
||||
unsigned int ping_time, void *user_ptr);
|
||||
|
||||
/* query domain */
|
||||
int dns_server_query(const char *domain, int qtype, uint32_t server_flags, dns_result_callback callback, void *user_ptr);
|
||||
int dns_server_query(const char *domain, int qtype, struct dns_server_query_option *server_query_option,
|
||||
dns_result_callback callback, void *user_ptr);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
@@ -24,6 +24,15 @@
|
||||
|
||||
static inline char *safe_strncpy(char *dest, const char *src, size_t n)
|
||||
{
|
||||
if (src == NULL) {
|
||||
dest[0] = '\0';
|
||||
return dest;
|
||||
}
|
||||
|
||||
if (n <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if __GNUC__ > 7
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
||||
|
||||
Reference in New Issue
Block a user