From 7d6222699556f4b23cd3165e3bbf25457dc36300 Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Tue, 5 Jul 2022 23:32:22 +0800 Subject: [PATCH] server: some minor fixes --- src/dns_client.c | 63 ++++++++++++++++++++++++++++++------------------ src/dns_server.c | 36 +++++++++++++++++++++------ src/fast_ping.c | 11 ++++----- src/smartdns.c | 4 +-- 4 files changed, 76 insertions(+), 38 deletions(-) diff --git a/src/dns_client.c b/src/dns_client.c index 118d34d..4c4339f 100644 --- a/src/dns_client.c +++ b/src/dns_client.c @@ -133,6 +133,7 @@ struct dns_server_pending_group { struct dns_server_pending { struct list_head list; + struct list_head retry_list; atomic_t refcnt; char host[DNS_HOSTNAME_LEN]; @@ -1244,7 +1245,7 @@ void _dns_client_server_pending_get(struct dns_server_pending *pending) } } -void _dns_client_server_pending_release_lck(struct dns_server_pending *pending) +void _dns_client_server_pending_release(struct dns_server_pending *pending) { struct dns_server_pending_group *group, *tmp; @@ -1258,6 +1259,7 @@ void _dns_client_server_pending_release_lck(struct dns_server_pending *pending) return; } + pthread_mutex_lock(&pending_server_mutex); list_for_each_entry_safe(group, tmp, &pending->group_list, list) { list_del_init(&group->list); @@ -1265,26 +1267,16 @@ void _dns_client_server_pending_release_lck(struct dns_server_pending *pending) } list_del_init(&pending->list); + pthread_mutex_unlock(&pending_server_mutex); free(pending); } -void _dns_client_server_pending_release(struct dns_server_pending *pending) +void _dns_client_server_pending_remove(struct dns_server_pending *pending) { - int refcnt = atomic_dec_return(&pending->refcnt); - - if (refcnt) { - if (refcnt < 0) { - tlog(TLOG_ERROR, "BUG: pending refcnt is %d", refcnt); - abort(); - } - return; - } - pthread_mutex_lock(&pending_server_mutex); list_del_init(&pending->list); pthread_mutex_unlock(&pending_server_mutex); - - free(pending); + _dns_client_server_pending_release(pending); } static int _dns_client_server_pending(char *server_ip, int port, dns_server_type_t server_type, @@ -1310,6 +1302,7 @@ static int _dns_client_server_pending(char *server_ip, int port, dns_server_type pending->has_v6 = 0; _dns_client_server_pending_get(pending); INIT_LIST_HEAD(&pending->group_list); + INIT_LIST_HEAD(&pending->retry_list); memcpy(&pending->flags, flags, sizeof(struct client_dns_server_flags)); pthread_mutex_lock(&pending_server_mutex); @@ -3227,20 +3220,30 @@ static int _dns_client_add_pendings(struct dns_server_pending *pending, char *ip static void _dns_client_remove_all_pending_servers(void) { struct dns_server_pending *pending, *tmp; + LIST_HEAD(remove_list); pthread_mutex_lock(&pending_server_mutex); list_for_each_entry_safe(pending, tmp, &pending_servers, list) { list_del_init(&pending->list); - _dns_client_server_pending_release_lck(pending); + list_add(&pending->retry_list, &remove_list); + _dns_client_server_pending_get(pending); } pthread_mutex_unlock(&pending_server_mutex); + + list_for_each_entry_safe(pending, tmp, &remove_list, retry_list) + { + list_del_init(&pending->retry_list); + _dns_client_server_pending_release(pending); + _dns_client_server_pending_remove(pending); + } } static void _dns_client_add_pending_servers(void) { struct dns_server_pending *pending, *tmp; static int dely = 0; + LIST_HEAD(retry_list); /* add pending server after 3 seconds */ if (++dely < 3) { @@ -3250,6 +3253,13 @@ static void _dns_client_add_pending_servers(void) pthread_mutex_lock(&pending_server_mutex); list_for_each_entry_safe(pending, tmp, &pending_servers, list) + { + list_add(&pending->retry_list, &retry_list); + _dns_client_server_pending_get(pending); + } + pthread_mutex_unlock(&pending_server_mutex); + + list_for_each_entry_safe(pending, tmp, &retry_list, retry_list) { /* send dns type A, AAAA query to bootstrap DNS server */ int add_success = 0; @@ -3259,7 +3269,8 @@ static void _dns_client_add_pending_servers(void) pending->query_v4 = 1; _dns_client_server_pending_get(pending); if (dns_server_query(pending->host, DNS_T_A, 0, _dns_client_pending_server_resolve, pending) != 0) { - _dns_client_server_pending_release_lck(pending); + _dns_client_server_pending_release(pending); + pending->query_v4 = 0; } } @@ -3267,10 +3278,14 @@ static void _dns_client_add_pending_servers(void) pending->query_v6 = 1; _dns_client_server_pending_get(pending); if (dns_server_query(pending->host, DNS_T_AAAA, 0, _dns_client_pending_server_resolve, pending) != 0) { - _dns_client_server_pending_release_lck(pending); + _dns_client_server_pending_release(pending); + pending->query_v4 = 0; } } + list_del_init(&pending->retry_list); + _dns_client_server_pending_release(pending); + /* if both A, AAAA has query result, select fastest IP address */ if (pending->has_v4 && pending->has_v6) { if (pending->ping_time_v4 <= pending->ping_time_v6 && pending->ipv4[0]) { @@ -3291,14 +3306,17 @@ static void _dns_client_add_pending_servers(void) } pending->retry_cnt++; - if (pending->retry_cnt >= DNS_PENDING_SERVER_RETRY || add_success) { + if (pending->retry_cnt == 1) { + continue; + } + + if (pending->retry_cnt - 1 > DNS_PENDING_SERVER_RETRY || add_success) { if (add_success == 0) { tlog(TLOG_WARN, "add pending DNS server %s failed.", pending->host); } - list_del_init(&pending->list); - _dns_client_server_pending_release_lck(pending); + _dns_client_server_pending_remove(pending); } else { - tlog(TLOG_INFO, "add pending DNS server %s failed, retry %d...", pending->host, pending->retry_cnt); + tlog(TLOG_INFO, "add pending DNS server %s failed, retry %d...", pending->host, pending->retry_cnt - 1); pending->query_v4 = 0; pending->query_v6 = 0; } @@ -3312,10 +3330,9 @@ static void _dns_client_add_pending_servers(void) return; } - _dns_client_server_pending_release_lck(pending); + _dns_client_server_pending_release(pending); } } - pthread_mutex_unlock(&pending_server_mutex); } static void _dns_client_period_run_second(void) diff --git a/src/dns_server.c b/src/dns_server.c index 1b79796..1c25f2a 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -732,7 +732,7 @@ static int _dns_add_rrs(struct dns_server_post_context *context) } if (request->rcode != DNS_RC_NOERROR) { - tlog(TLOG_INFO, "result %s, qtype: %d, rc-code: %d", domain, context->qtype, request->rcode); + tlog(TLOG_INFO, "result %s, qtype: %d, rccode: %d", domain, context->qtype, request->rcode); } return ret; @@ -2434,6 +2434,7 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char { int ttl = 0; char name[DNS_MAX_CNAME_LEN] = {0}; + char cname[DNS_MAX_CNAME_LEN]; int rr_count = 0; int i = 0; int j = 0; @@ -2457,6 +2458,7 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char switch (rrs->type) { case DNS_T_A: { unsigned char addr[4]; + int ttl_tmp; if (request->qtype != DNS_T_A) { /* ignore non-matched query type */ if (request->dualstack_selection == 0) { @@ -2465,9 +2467,15 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char } _dns_server_request_get(request); /* get A result */ - dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr); + dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl_tmp, addr); - tlog(TLOG_DEBUG, "domain: %s TTL:%d IP: %d.%d.%d.%d", name, ttl, addr[0], addr[1], addr[2], addr[3]); + /* if domain is not match */ + if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(cname, name, DNS_MAX_CNAME_LEN) != 0) { + _dns_server_request_release(request); + continue; + } + + tlog(TLOG_DEBUG, "domain: %s TTL:%d IP: %d.%d.%d.%d", name, ttl_tmp, addr[0], addr[1], addr[2], addr[3]); /* ip rule check */ ip_check_result = _dns_server_ip_rule_check(request, addr, 4, DNS_T_A, result_flag); @@ -2480,20 +2488,28 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char _dns_server_request_release(request); return 0; } + ttl = ttl_tmp; _dns_server_request_release(request); } break; case DNS_T_AAAA: { unsigned char addr[16]; + int ttl_tmp; if (request->qtype != DNS_T_AAAA) { /* ignore non-matched query type */ break; } _dns_server_request_get(request); - dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr); + dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl_tmp, addr); + + /* if domain is not match */ + if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(cname, name, DNS_MAX_CNAME_LEN) != 0) { + _dns_server_request_release(request); + continue; + } tlog(TLOG_DEBUG, "domain: %s TTL: %d IP: %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", - name, ttl, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], + name, ttl_tmp, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]); ip_check_result = _dns_server_ip_rule_check(request, addr, 16, DNS_T_AAAA, result_flag); @@ -2506,8 +2522,13 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char _dns_server_request_release(request); return 0; } + + ttl = ttl_tmp; _dns_server_request_release(request); } break; + case DNS_T_CNAME: { + dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN); + } break; default: break; } @@ -2570,7 +2591,7 @@ static int _dns_server_get_answer(struct dns_server_post_context *context) if (_dns_ip_address_check_add(request, name, addr, DNS_T_AAAA) != 0) { continue; } - + context->ip_num++; if (request->has_ip == 1) { continue; @@ -3412,6 +3433,7 @@ static int _dns_server_process_cache_packet(struct dns_request *request, struct _dns_server_post_context_init(&context, request); context.inpacket = cache_packet->data; context.inpacket_len = cache_packet->head.size; + request->ping_time = dns_cache->info.speed; if (dns_decode(context.packet, context.packet_maxlen, cache_packet->data, cache_packet->head.size) != 0) { return -1; @@ -4149,7 +4171,7 @@ int dns_server_query(char *domain, int qtype, uint32_t server_flags, dns_result_ goto errout; } - _dns_server_request_release(request); + _dns_server_request_release_complete(request, 0); return ret; errout: if (request) { diff --git a/src/fast_ping.c b/src/fast_ping.c index 61b0a0a..dce2bbd 100644 --- a/src/fast_ping.c +++ b/src/fast_ping.c @@ -1216,6 +1216,11 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct * return NULL; } + if (icmp->icmp_type != ICMP_ECHOREPLY) { + tlog(TLOG_DEBUG, "icmp type faild, %d:%d", icmp->icmp_type, ICMP_ECHOREPLY); + return NULL; + } + if (ping.no_unprivileged_ping) { if (ip->ip_p != IPPROTO_ICMP) { tlog(TLOG_ERROR, "ip type faild, %d:%d", ip->ip_p, IPPROTO_ICMP); @@ -1228,12 +1233,6 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct * } } - if (icmp->icmp_type != ICMP_ECHOREPLY) { - tlog(TLOG_DEBUG, "icmp type faild, %d:%d", icmp->icmp_type, ICMP_ECHOREPLY); - return NULL; - } - - return packet; } diff --git a/src/smartdns.c b/src/smartdns.c index 56f4a76..7a8b542 100644 --- a/src/smartdns.c +++ b/src/smartdns.c @@ -397,7 +397,7 @@ static int _smartdns_run(void) static void _smartdns_exit(void) { - tlog(TLOG_INFO, "smartdns starting exit..."); + tlog(TLOG_INFO, "smartdns exit..."); dns_server_exit(); dns_client_exit(); fast_ping_exit(); @@ -408,7 +408,7 @@ static void _smartdns_exit(void) static void _sig_exit(int signo) { - tlog(TLOG_INFO, "start stop smartdns"); + tlog(TLOG_INFO, "stop smartdns by signal %d", signo); dns_server_stop(); }