Bugfix: fix crash issue when has pending server
This commit is contained in:
@@ -136,6 +136,7 @@ struct dns_server_pending_group {
|
|||||||
|
|
||||||
struct dns_server_pending {
|
struct dns_server_pending {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
atomic_t refcnt;
|
||||||
|
|
||||||
char host[DNS_HOSTNAME_LEN];
|
char host[DNS_HOSTNAME_LEN];
|
||||||
char ipv4[DNS_HOSTNAME_LEN];
|
char ipv4[DNS_HOSTNAME_LEN];
|
||||||
@@ -960,6 +961,49 @@ static int _dns_client_server_remove(char *server_ip, int port, dns_server_type_
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _dns_client_server_pending_get(struct dns_server_pending *pending)
|
||||||
|
{
|
||||||
|
if (atomic_inc_return(&pending->refcnt) <= 0) {
|
||||||
|
tlog(TLOG_ERROR, "BUG: pending ref is invalid");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _dns_client_server_pending_release_lck(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_del_init(&pending->list);
|
||||||
|
free(pending);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _dns_client_server_pending_release(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);
|
||||||
|
}
|
||||||
|
|
||||||
static int _dns_client_server_pending(char *server_ip, int port, dns_server_type_t server_type, struct client_dns_server_flags *flags)
|
static int _dns_client_server_pending(char *server_ip, int port, dns_server_type_t server_type, struct client_dns_server_flags *flags)
|
||||||
{
|
{
|
||||||
struct dns_server_pending *pending = NULL;
|
struct dns_server_pending *pending = NULL;
|
||||||
@@ -980,6 +1024,7 @@ static int _dns_client_server_pending(char *server_ip, int port, dns_server_type
|
|||||||
pending->ipv6[0] = 0;
|
pending->ipv6[0] = 0;
|
||||||
pending->has_v4 = 0;
|
pending->has_v4 = 0;
|
||||||
pending->has_v6 = 0;
|
pending->has_v6 = 0;
|
||||||
|
_dns_client_server_pending_get(pending);
|
||||||
INIT_LIST_HEAD(&pending->group_list);
|
INIT_LIST_HEAD(&pending->group_list);
|
||||||
memcpy(&pending->flags, flags, sizeof(struct client_dns_server_flags));
|
memcpy(&pending->flags, flags, sizeof(struct client_dns_server_flags));
|
||||||
|
|
||||||
@@ -2613,6 +2658,7 @@ static void _dns_client_check_servers(void)
|
|||||||
static int _dns_client_pending_server_resolve(char *domain, dns_rtcode_t rtcode, dns_type_t addr_type, char *ip, unsigned int ping_time, void *user_ptr)
|
static int _dns_client_pending_server_resolve(char *domain, dns_rtcode_t rtcode, dns_type_t addr_type, char *ip, unsigned int ping_time, void *user_ptr)
|
||||||
{
|
{
|
||||||
struct dns_server_pending *pending = user_ptr;
|
struct dns_server_pending *pending = user_ptr;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (addr_type == DNS_T_A) {
|
if (addr_type == DNS_T_A) {
|
||||||
pending->has_v4 = 1;
|
pending->has_v4 = 1;
|
||||||
@@ -2629,10 +2675,11 @@ static int _dns_client_pending_server_resolve(char *domain, dns_rtcode_t rtcode,
|
|||||||
safe_strncpy(pending->ipv6, ip, DNS_HOSTNAME_LEN);
|
safe_strncpy(pending->ipv6, ip, DNS_HOSTNAME_LEN);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
_dns_client_server_pending_release(pending);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _dns_client_add_pendings(struct dns_server_pending *pending, char *ip)
|
static int _dns_client_add_pendings(struct dns_server_pending *pending, char *ip)
|
||||||
@@ -2672,11 +2719,15 @@ static void _dns_client_add_pending_servers(void)
|
|||||||
/* send dns type A, AAAA query to bootstrap DNS server */
|
/* send dns type A, AAAA query to bootstrap DNS server */
|
||||||
if (pending->query_v4 == 0) {
|
if (pending->query_v4 == 0) {
|
||||||
pending->query_v4 = 1;
|
pending->query_v4 = 1;
|
||||||
dns_server_query(pending->host, DNS_T_A, _dns_client_pending_server_resolve, pending);
|
_dns_client_server_pending_get(pending);
|
||||||
|
if (dns_server_query(pending->host, DNS_T_A, _dns_client_pending_server_resolve, pending) != 0) {
|
||||||
|
_dns_client_server_pending_release_lck(pending);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pending->query_v6 == 0) {
|
if (pending->query_v6 == 0) {
|
||||||
pending->query_v6 = 1;
|
pending->query_v6 = 1;
|
||||||
|
_dns_client_server_pending_get(pending);
|
||||||
dns_server_query(pending->host, DNS_T_AAAA, _dns_client_pending_server_resolve, pending);
|
dns_server_query(pending->host, DNS_T_AAAA, _dns_client_pending_server_resolve, pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2694,8 +2745,8 @@ static void _dns_client_add_pending_servers(void)
|
|||||||
tlog(TLOG_WARN, "add pending DNS server %s failed.", pending->host);
|
tlog(TLOG_WARN, "add pending DNS server %s failed.", pending->host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_del_init(&pending->list);
|
|
||||||
free(pending);
|
_dns_client_server_pending_release_lck(pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if has no bootstrap DNS, just call getaddrinfo to get address */
|
/* if has no bootstrap DNS, just call getaddrinfo to get address */
|
||||||
@@ -2706,8 +2757,8 @@ static void _dns_client_add_pending_servers(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
list_del_init(&pending->list);
|
|
||||||
free(pending);
|
_dns_client_server_pending_release_lck(pending);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&pending_server_mutex);
|
pthread_mutex_unlock(&pending_server_mutex);
|
||||||
|
|||||||
@@ -27,6 +27,10 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /*__cplusplus */
|
#endif /*__cplusplus */
|
||||||
|
|
||||||
|
#ifndef TCP_FASTOPEN
|
||||||
|
#define TCP_FASTOPEN 23
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef TCP_FASTOPEN_CONNECT
|
#ifndef TCP_FASTOPEN_CONNECT
|
||||||
#define TCP_FASTOPEN_CONNECT 30
|
#define TCP_FASTOPEN_CONNECT 30
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user