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;
|
return 0;
|
||||||
errout:
|
errout:
|
||||||
if (server_info) {
|
if (server_info) {
|
||||||
|
if (server_info->ping_host) {
|
||||||
|
fast_ping_stop(server_info->ping_host);
|
||||||
|
}
|
||||||
|
|
||||||
if (server_info->ssl_ctx) {
|
if (server_info->ssl_ctx) {
|
||||||
SSL_CTX_free(server_info->ssl_ctx);
|
SSL_CTX_free(server_info->ssl_ctx);
|
||||||
server_info->ssl_ctx = NULL;
|
server_info->ssl_ctx = NULL;
|
||||||
}
|
}
|
||||||
if (server_info->ping_host) {
|
|
||||||
fast_ping_stop(server_info->ping_host);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(server_info);
|
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 (connect(fd, (struct sockaddr *)&server_info->addr, server_info->ai_addrlen) != 0) {
|
||||||
if (errno != EINPROGRESS) {
|
if (errno != EINPROGRESS) {
|
||||||
tlog(TLOG_ERROR, "connect failed.");
|
tlog(TLOG_ERROR, "connect %s failed, %s", server_info->ip, strerror(errno));
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1518,7 +1519,7 @@ static int _DNS_client_create_socket_tcp(struct dns_server_info *server_info)
|
|||||||
event.events = EPOLLIN | EPOLLOUT;
|
event.events = EPOLLIN | EPOLLOUT;
|
||||||
event.data.ptr = server_info;
|
event.data.ptr = server_info;
|
||||||
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_ADD, fd, &event) != 0) {
|
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;
|
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_NODELAY, &yes, sizeof(yes));
|
||||||
// setsockopt(fd, IPPROTO_TCP, TCP_THIN_DUPACK, &yes, sizeof(yes));
|
// setsockopt(fd, IPPROTO_TCP, TCP_THIN_DUPACK, &yes, sizeof(yes));
|
||||||
// setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, &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, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority));
|
||||||
setsockopt(fd, IPPROTO_IP, IP_TOS, &ip_tos, sizeof(ip_tos));
|
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.events = EPOLLIN | EPOLLOUT;
|
||||||
event.data.ptr = server_info;
|
event.data.ptr = server_info;
|
||||||
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_MOD, server_info->fd, &event) != 0) {
|
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;
|
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();
|
query->send_tick = get_tick_count();
|
||||||
|
|
||||||
/* send query to all dns servers */
|
/* send query to all dns servers */
|
||||||
pthread_mutex_lock(&client.server_list_lock);
|
for (int i = 0; i < 2; i++) {
|
||||||
list_for_each_entry_safe(group_member, tmp, &query->server_group->head, list)
|
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) {
|
server_info = group_member->server;
|
||||||
ret = _dns_client_create_socket(server_info);
|
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 (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;
|
continue;
|
||||||
}
|
}
|
||||||
|
time(&server_info->last_send);
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&client.server_list_lock);
|
||||||
|
|
||||||
atomic_inc(&query->dns_request_sent);
|
if (atomic_read(&query->dns_request_sent) > 0) {
|
||||||
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;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -339,24 +339,30 @@ static void _sig_error_exit(int signo, siginfo_t *siginfo, void *ct)
|
|||||||
{
|
{
|
||||||
unsigned long PC = 0;
|
unsigned long PC = 0;
|
||||||
ucontext_t *context = ct;
|
ucontext_t *context = ct;
|
||||||
|
const char *arch = NULL;
|
||||||
#if defined(__i386__)
|
#if defined(__i386__)
|
||||||
int *pgregs = (int *)(&(context->uc_mcontext.gregs));
|
int *pgregs = (int *)(&(context->uc_mcontext.gregs));
|
||||||
PC = pgregs[REG_EIP];
|
PC = pgregs[REG_EIP];
|
||||||
|
arch = "i386";
|
||||||
#elif defined(__x86_64__)
|
#elif defined(__x86_64__)
|
||||||
int *pgregs = (int *)(&(context->uc_mcontext.gregs));
|
int *pgregs = (int *)(&(context->uc_mcontext.gregs));
|
||||||
PC = pgregs[REG_RIP];
|
PC = pgregs[REG_RIP];
|
||||||
|
arch = "x86_64";
|
||||||
#elif defined(__arm__)
|
#elif defined(__arm__)
|
||||||
PC = context->uc_mcontext.arm_pc;
|
PC = context->uc_mcontext.arm_pc;
|
||||||
|
arch = "arm";
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
PC = context->uc_mcontext.pc;
|
PC = context->uc_mcontext.pc;
|
||||||
|
arch = "arm64";
|
||||||
#elif defined(__mips__)
|
#elif defined(__mips__)
|
||||||
PC = context->uc_mcontext.pc;
|
PC = context->uc_mcontext.pc;
|
||||||
|
arch = "mips";
|
||||||
#endif
|
#endif
|
||||||
tlog(TLOG_FATAL,
|
tlog(TLOG_FATAL,
|
||||||
"process exit with signal %d, code = %d, errno = %d, pid = %d, self = %d, pc = %#lx, addr = %#lx, build(%s "
|
"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,
|
signo, siginfo->si_code, siginfo->si_errno, siginfo->si_pid, getpid(), PC, (unsigned long)siginfo->si_addr,
|
||||||
__DATE__, __TIME__);
|
__DATE__, __TIME__, arch);
|
||||||
|
|
||||||
sleep(1);
|
sleep(1);
|
||||||
_exit(0);
|
_exit(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user