diff --git a/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua b/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua index b6248e7a2b..dd65e316eb 100644 --- a/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua +++ b/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua @@ -135,7 +135,7 @@ o = s:taboption("advanced", Flag, "tls_server", translate("DOT Server"), transla o.rmempty = false o.default = o.disabled o.cfgvalue = function(...) - return Flag.cfgvalue(...) or "1" + return Flag.cfgvalue(...) or "0" end o = s:taboption("advanced", Value, "tls_server_port", translate("DOT Server Port"), translate("Smartdns DOT server port.")) @@ -150,7 +150,7 @@ o = s:taboption("advanced", Flag, "doh_server", translate("DOH Server"), transla o.rmempty = false o.default = o.disabled o.cfgvalue = function(...) - return Flag.cfgvalue(...) or "1" + return Flag.cfgvalue(...) or "0" end o = s:taboption("advanced", Value, "doh_server_port", translate("DOH Server Port"), translate("Smartdns DOH server port.")) diff --git a/src/dns_cache.c b/src/dns_cache.c index b9cc17d017..6a9a2dce1b 100644 --- a/src/dns_cache.c +++ b/src/dns_cache.c @@ -32,6 +32,7 @@ #define DNS_CACHE_HITNUM_STEP 3 #define DNS_CACHE_HITNUM_STEP_MAX 6 #define DNS_CACHE_READ_TIMEOUT 60 +#define DNS_CACHE_FAIL_TIMEOUT (60 * 5) #define EXPIRED_DOMAIN_PREFETCH_TIME (3600 * 8) struct dns_cache_head { @@ -168,9 +169,18 @@ static void dns_cache_expired(struct tw_base *base, struct tw_timer_list *timer, } if (dns_cache_head.timeout_callback) { - if (dns_cache_head.timeout_callback(dns_cache) != 0) { + dns_cache_tmout_action_t tmout_act = dns_cache_head.timeout_callback(dns_cache); + switch (tmout_act) { + case DNS_CACHE_TMOUT_ACTION_OK: + break; + case DNS_CACHE_TMOUT_ACTION_DEL: dns_cache_release(dns_cache); return; + case DNS_CACHE_TMOUT_ACTION_RETRY: + dns_timer_mod(&dns_cache->timer, DNS_CACHE_FAIL_TIMEOUT); + return; + default: + break; } } @@ -201,6 +211,7 @@ static int _dns_cache_replace(struct dns_cache_key *cache_key, int rcode, int tt /* update cache data */ pthread_mutex_lock(&dns_cache_head.lock); dns_cache->del_pending = 0; + dns_cache->info.rcode = rcode; dns_cache->info.qtype = cache_key->qtype; dns_cache->info.query_flag = cache_key->query_flag; dns_cache->info.ttl = ttl; @@ -364,6 +375,23 @@ int dns_cache_insert(struct dns_cache_key *cache_key, int rcode, int ttl, int sp return _dns_cache_insert(&info, cache_data, &dns_cache_head.cache_list, timeout); } +int dns_cache_update_timer(struct dns_cache_key *key, int timeout) +{ + struct dns_cache *dns_cache = dns_cache_lookup(key); + if (dns_cache == NULL) { + return -1; + } + + pthread_mutex_lock(&dns_cache_head.lock); + dns_timer_mod(&dns_cache->timer, timeout); + dns_cache->del_pending = 0; + pthread_mutex_unlock(&dns_cache_head.lock); + + dns_cache_release(dns_cache); + + return 0; +} + struct dns_cache *dns_cache_lookup(struct dns_cache_key *cache_key) { uint32_t key = 0; @@ -466,6 +494,11 @@ int dns_cache_is_visited(struct dns_cache *dns_cache) return dns_cache->info.is_visited; } +int dns_cache_total_num(void) +{ + return atomic_read(&dns_cache_head.num); +} + void dns_cache_delete(struct dns_cache *dns_cache) { pthread_mutex_lock(&dns_cache_head.lock); diff --git a/src/dns_cache.h b/src/dns_cache.h index 0b6cf07bb2..1ea711c819 100644 --- a/src/dns_cache.h +++ b/src/dns_cache.h @@ -124,7 +124,13 @@ const char *dns_cache_get_dns_group_name(struct dns_cache *dns_cache); struct dns_cache_data *dns_cache_new_data_packet(void *packet, size_t packet_len); -typedef int (*dns_cache_callback)(struct dns_cache *dns_cache); +typedef enum DNS_CACHE_TMOUT_ACTION { + DNS_CACHE_TMOUT_ACTION_OK = 0, + DNS_CACHE_TMOUT_ACTION_DEL = 1, + DNS_CACHE_TMOUT_ACTION_RETRY = 2, +} dns_cache_tmout_action_t; + +typedef dns_cache_tmout_action_t (*dns_cache_callback)(struct dns_cache *dns_cache); int dns_cache_init(int size, dns_cache_callback timeout_callback); @@ -136,6 +142,10 @@ int dns_cache_insert(struct dns_cache_key *key, int rcode, int ttl, int speed, i struct dns_cache *dns_cache_lookup(struct dns_cache_key *key); +int dns_cache_total_num(void); + +int dns_cache_update_timer(struct dns_cache_key *key, int timeout); + void dns_cache_delete(struct dns_cache *dns_cache); void dns_cache_get(struct dns_cache *dns_cache); diff --git a/src/dns_server.c b/src/dns_server.c index 11fecaa856..b0ee9e5d90 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -1012,7 +1012,8 @@ static int _dns_add_rrs(struct dns_server_post_context *context) } if (request->rcode != DNS_RC_NOERROR) { - tlog(TLOG_INFO, "result: %s, qtype: %d, rtcode: %d", domain, context->qtype, request->rcode); + tlog(TLOG_INFO, "result: %s, qtype: %d, rtcode: %d, id: %d", domain, context->qtype, request->rcode, + request->id); } return ret; @@ -1694,6 +1695,16 @@ static int _dns_cache_specify_packet(struct dns_server_post_context *context) return _dns_cache_packet(context); } +static int _dns_cache_try_keep_old_cache(struct dns_request *request) +{ + struct dns_cache_key cache_key; + cache_key.dns_group_name = request->dns_group_name; + cache_key.domain = request->domain; + cache_key.qtype = request->qtype; + cache_key.query_flag = request->server_flags; + return dns_cache_update_timer(&cache_key, DNS_SERVER_TMOUT_TTL); +} + static int _dns_cache_reply_packet(struct dns_server_post_context *context) { struct dns_request *request = context->request; @@ -1707,6 +1718,8 @@ static int _dns_cache_reply_packet(struct dns_server_post_context *context) context->reply_ttl = DNS_SERVER_FAIL_TTL; /* Do not cache record if cannot connect to remote */ if (request->remote_server_fail == 0 && context->packet->head.rcode == DNS_RC_SERVFAIL) { + /* Try keep old cache if server fail */ + _dns_cache_try_keep_old_cache(request); return 0; } @@ -3712,8 +3725,9 @@ static int dns_server_resolve_callback(const char *domain, dns_result_type rtype } if (rtype == DNS_QUERY_RESULT) { - tlog(TLOG_DEBUG, "query result from server %s:%d, type: %d", dns_client_get_server_ip(server_info), - dns_client_get_server_port(server_info), dns_client_get_server_type(server_info)); + tlog(TLOG_DEBUG, "query result from server %s:%d, type: %d, rcode: %d, id: %d", + dns_client_get_server_ip(server_info), dns_client_get_server_port(server_info), + dns_client_get_server_type(server_info), packet->head.rcode, request->id); if (request->passthrough == 1 && atomic_read(&request->notified) == 0) { struct dns_server_post_context context; @@ -6663,13 +6677,13 @@ static int _dns_server_second_ping_check(struct dns_request *request) return ret; } -static int _dns_server_prefetch_domain(struct dns_cache *dns_cache) +static dns_cache_tmout_action_t _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 -1; + return DNS_CACHE_TMOUT_ACTION_DEL; } /* start prefetch domain */ @@ -6681,23 +6695,26 @@ static int _dns_server_prefetch_domain(struct dns_cache *dns_cache) if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype, &server_query_option, PREFETCH_FLAGS_NO_DUALSTACK) != 0) { tlog(TLOG_ERROR, "prefetch domain %s, qtype %d, failed.", dns_cache->info.domain, dns_cache->info.qtype); - return -1; + return DNS_CACHE_TMOUT_ACTION_RETRY; } - return 0; + return DNS_CACHE_TMOUT_ACTION_OK; } -static int _dns_server_prefetch_expired_domain(struct dns_cache *dns_cache) +static dns_cache_tmout_action_t _dns_server_prefetch_expired_domain(struct dns_cache *dns_cache) { time_t ttl = _dns_server_expired_cache_ttl(dns_cache); if (ttl <= 1) { - return -1; + return DNS_CACHE_TMOUT_ACTION_DEL; } /* start prefetch domain */ - tlog(TLOG_DEBUG, "expired domain, prefetch by cache %s, qtype %d, ttl %llu, insert time %llu replace time %llu", - dns_cache->info.domain, dns_cache->info.qtype, (unsigned long long)ttl, - (unsigned long long)dns_cache->info.insert_time, (unsigned long long)dns_cache->info.replace_time); + tlog(TLOG_DEBUG, + "expired domain, total %d, prefetch by cache %s, qtype %d, ttl %llu, rcode %d, insert time %llu replace time " + "%llu", + dns_cache_total_num(), dns_cache->info.domain, dns_cache->info.qtype, (unsigned long long)ttl, + dns_cache->info.rcode, (unsigned long long)dns_cache->info.insert_time, + (unsigned long long)dns_cache->info.replace_time); struct dns_server_query_option server_query_option; server_query_option.dns_group_name = dns_cache_get_dns_group_name(dns_cache); @@ -6707,16 +6724,16 @@ static int _dns_server_prefetch_expired_domain(struct dns_cache *dns_cache) if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype, &server_query_option, PREFETCH_FLAGS_EXPIRED) != 0) { tlog(TLOG_DEBUG, "prefetch domain %s, qtype %d, failed.", dns_cache->info.domain, dns_cache->info.qtype); - return -1; + return DNS_CACHE_TMOUT_ACTION_RETRY; } - return 0; + return DNS_CACHE_TMOUT_ACTION_OK; } -static int _dns_server_cache_expired(struct dns_cache *dns_cache) +static dns_cache_tmout_action_t _dns_server_cache_expired(struct dns_cache *dns_cache) { if (dns_cache->info.rcode != DNS_RC_NOERROR) { - return -1; + return DNS_CACHE_TMOUT_ACTION_DEL; } if (dns_conf_prefetch == 1 && _dns_cache_is_specify_packet(dns_cache->info.qtype) != 0) { @@ -6727,7 +6744,7 @@ static int _dns_server_cache_expired(struct dns_cache *dns_cache) } } - return -1; + return DNS_CACHE_TMOUT_ACTION_DEL; } static void _dns_server_tcp_idle_check(void) diff --git a/src/lib/timer_wheel.c b/src/lib/timer_wheel.c index 09080a5c71..932894633c 100644 --- a/src/lib/timer_wheel.c +++ b/src/lib/timer_wheel.c @@ -158,7 +158,7 @@ void tw_add_timer(struct tw_base *base, struct tw_timer_list *timer) pthread_spin_lock(&base->lock); { - timer->expires += base->jiffies; + timer->expires += base->jiffies - 1; _tw_add_timer(base, timer); } pthread_spin_unlock(&base->lock); @@ -190,7 +190,7 @@ int tw_mod_timer_pending(struct tw_base *base, struct tw_timer_list *timer, unsi pthread_spin_lock(&base->lock); { - timer->expires = expires + base->jiffies; + timer->expires = expires + base->jiffies - 1; ret = __mod_timer(base, timer, 1); } pthread_spin_unlock(&base->lock); @@ -208,7 +208,7 @@ int tw_mod_timer(struct tw_base *base, struct tw_timer_list *timer, unsigned lon goto unblock; } - timer->expires = expires + base->jiffies; + timer->expires = expires + base->jiffies - 1; ret = __mod_timer(base, timer, 0); }