client: retry upstream when network restart
This commit is contained in:
125
src/dns_client.c
125
src/dns_client.c
@@ -902,13 +902,14 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
|
||||
return 0;
|
||||
errout:
|
||||
if (server_info) {
|
||||
if (server_info->ping_host) {
|
||||
fast_ping_stop(server_info->ping_host);
|
||||
}
|
||||
|
||||
if (server_info->ssl_ctx) {
|
||||
SSL_CTX_free(server_info->ssl_ctx);
|
||||
server_info->ssl_ctx = NULL;
|
||||
}
|
||||
if (server_info->ping_host) {
|
||||
fast_ping_stop(server_info->ping_host);
|
||||
}
|
||||
|
||||
free(server_info);
|
||||
}
|
||||
@@ -1509,7 +1510,7 @@ static int _DNS_client_create_socket_tcp(struct dns_server_info *server_info)
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&server_info->addr, server_info->ai_addrlen) != 0) {
|
||||
if (errno != EINPROGRESS) {
|
||||
tlog(TLOG_ERROR, "connect failed.");
|
||||
tlog(TLOG_ERROR, "connect %s failed, %s", server_info->ip, strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
@@ -1518,7 +1519,7 @@ static int _DNS_client_create_socket_tcp(struct dns_server_info *server_info)
|
||||
event.events = EPOLLIN | EPOLLOUT;
|
||||
event.data.ptr = server_info;
|
||||
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_ADD, fd, &event) != 0) {
|
||||
tlog(TLOG_ERROR, "epoll ctl failed.");
|
||||
tlog(TLOG_ERROR, "epoll ctl failed, %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1575,7 +1576,7 @@ static int _DNS_client_create_socket_tls(struct dns_server_info *server_info, ch
|
||||
// setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes));
|
||||
// setsockopt(fd, IPPROTO_TCP, TCP_THIN_DUPACK, &yes, sizeof(yes));
|
||||
// setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, &yes, sizeof(yes));
|
||||
// set_sock_keepalive(fd, 15, 3, 4);
|
||||
set_sock_keepalive(fd, 15, 3, 4);
|
||||
setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority));
|
||||
setsockopt(fd, IPPROTO_IP, IP_TOS, &ip_tos, sizeof(ip_tos));
|
||||
|
||||
@@ -2352,7 +2353,7 @@ static int _dns_client_send_data_to_buffer(struct dns_server_info *server_info,
|
||||
event.events = EPOLLIN | EPOLLOUT;
|
||||
event.data.ptr = server_info;
|
||||
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_MOD, server_info->fd, &event) != 0) {
|
||||
tlog(TLOG_ERROR, "epoll ctl failed.");
|
||||
tlog(TLOG_ERROR, "epoll ctl failed, %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2506,59 +2507,79 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
|
||||
query->send_tick = get_tick_count();
|
||||
|
||||
/* send query to all dns servers */
|
||||
pthread_mutex_lock(&client.server_list_lock);
|
||||
list_for_each_entry_safe(group_member, tmp, &query->server_group->head, list)
|
||||
{
|
||||
server_info = group_member->server;
|
||||
if (server_info->fd <= 0) {
|
||||
ret = _dns_client_create_socket(server_info);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
pthread_mutex_lock(&client.server_list_lock);
|
||||
list_for_each_entry_safe(group_member, tmp, &query->server_group->head, list)
|
||||
{
|
||||
server_info = group_member->server;
|
||||
if (server_info->fd <= 0) {
|
||||
ret = _dns_client_create_socket(server_info);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
atomic_inc(&query->dns_request_sent);
|
||||
switch (server_info->type) {
|
||||
case DNS_SERVER_UDP:
|
||||
/* udp query */
|
||||
ret = _dns_client_send_udp(server_info, packet, len);
|
||||
send_err = errno;
|
||||
break;
|
||||
case DNS_SERVER_TCP:
|
||||
/* tcp query */
|
||||
ret = _dns_client_send_tcp(server_info, packet, len);
|
||||
send_err = errno;
|
||||
break;
|
||||
case DNS_SERVER_TLS:
|
||||
/* tls query */
|
||||
ret = _dns_client_send_tls(server_info, packet, len);
|
||||
send_err = errno;
|
||||
break;
|
||||
case DNS_SERVER_HTTPS:
|
||||
/* https query */
|
||||
ret = _dns_client_send_https(server_info, packet, len);
|
||||
send_err = errno;
|
||||
break;
|
||||
default:
|
||||
/* unsupport query type */
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
if (send_err != ENOMEM) {
|
||||
tlog(TLOG_ERROR, "send query to %s failed, %s, type: %d", server_info->ip, strerror(send_err),
|
||||
server_info->type);
|
||||
} else {
|
||||
tlog(TLOG_DEBUG, "send query to %s failed, %s, type: %d", server_info->ip, strerror(send_err),
|
||||
server_info->type);
|
||||
time_t now;
|
||||
time(&now);
|
||||
if (now - 5 > server_info->last_recv) {
|
||||
server_info->recv_buff.len = 0;
|
||||
server_info->send_buff.len = 0;
|
||||
tlog(TLOG_DEBUG, "server %s not response, retry.", server_info->ip);
|
||||
_dns_client_close_socket(server_info);
|
||||
}
|
||||
}
|
||||
atomic_dec(&query->dns_request_sent);
|
||||
continue;
|
||||
}
|
||||
time(&server_info->last_send);
|
||||
}
|
||||
pthread_mutex_unlock(&client.server_list_lock);
|
||||
|
||||
atomic_inc(&query->dns_request_sent);
|
||||
switch (server_info->type) {
|
||||
case DNS_SERVER_UDP:
|
||||
/* udp query */
|
||||
ret = _dns_client_send_udp(server_info, packet, len);
|
||||
send_err = errno;
|
||||
break;
|
||||
case DNS_SERVER_TCP:
|
||||
/* tcp query */
|
||||
ret = _dns_client_send_tcp(server_info, packet, len);
|
||||
send_err = errno;
|
||||
break;
|
||||
case DNS_SERVER_TLS:
|
||||
/* tls query */
|
||||
ret = _dns_client_send_tls(server_info, packet, len);
|
||||
send_err = errno;
|
||||
break;
|
||||
case DNS_SERVER_HTTPS:
|
||||
/* https query */
|
||||
ret = _dns_client_send_https(server_info, packet, len);
|
||||
send_err = errno;
|
||||
break;
|
||||
default:
|
||||
/* unsupport query type */
|
||||
ret = -1;
|
||||
if (atomic_read(&query->dns_request_sent) > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
if (send_err != ENOMEM) {
|
||||
tlog(TLOG_ERROR, "send query to %s failed, %s, type: %d", server_info->ip, strerror(send_err),
|
||||
server_info->type);
|
||||
} else {
|
||||
tlog(TLOG_DEBUG, "send query to %s failed, %s, type: %d", server_info->ip, strerror(send_err),
|
||||
server_info->type);
|
||||
}
|
||||
atomic_dec(&query->dns_request_sent);
|
||||
continue;
|
||||
}
|
||||
time(&server_info->last_send);
|
||||
}
|
||||
pthread_mutex_unlock(&client.server_list_lock);
|
||||
|
||||
if (atomic_read(&query->dns_request_sent) <= 0) {
|
||||
tlog(TLOG_ERROR, "Send query to upstream server failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -339,24 +339,30 @@ static void _sig_error_exit(int signo, siginfo_t *siginfo, void *ct)
|
||||
{
|
||||
unsigned long PC = 0;
|
||||
ucontext_t *context = ct;
|
||||
const char *arch = NULL;
|
||||
#if defined(__i386__)
|
||||
int *pgregs = (int *)(&(context->uc_mcontext.gregs));
|
||||
PC = pgregs[REG_EIP];
|
||||
arch = "i386";
|
||||
#elif defined(__x86_64__)
|
||||
int *pgregs = (int *)(&(context->uc_mcontext.gregs));
|
||||
PC = pgregs[REG_RIP];
|
||||
arch = "x86_64";
|
||||
#elif defined(__arm__)
|
||||
PC = context->uc_mcontext.arm_pc;
|
||||
arch = "arm";
|
||||
#elif defined(__aarch64__)
|
||||
PC = context->uc_mcontext.pc;
|
||||
arch = "arm64";
|
||||
#elif defined(__mips__)
|
||||
PC = context->uc_mcontext.pc;
|
||||
arch = "mips";
|
||||
#endif
|
||||
tlog(TLOG_FATAL,
|
||||
"process exit with signal %d, code = %d, errno = %d, pid = %d, self = %d, pc = %#lx, addr = %#lx, build(%s "
|
||||
"%s)\n",
|
||||
"%s %s)\n",
|
||||
signo, siginfo->si_code, siginfo->si_errno, siginfo->si_pid, getpid(), PC, (unsigned long)siginfo->si_addr,
|
||||
__DATE__, __TIME__);
|
||||
__DATE__, __TIME__, arch);
|
||||
|
||||
sleep(1);
|
||||
_exit(0);
|
||||
|
||||
Reference in New Issue
Block a user