feature: auto detect ipv6 features.
This commit is contained in:
@@ -420,7 +420,7 @@ static int _dns_client_server_exist(const char *server_ip, int port, dns_server_
|
||||
|
||||
static void _dns_client_server_update_ttl(struct ping_host_struct *ping_host, const char *host, FAST_PING_RESULT result,
|
||||
struct sockaddr *addr, socklen_t addr_len, int seqno, int ttl,
|
||||
struct timeval *tv, void *userptr)
|
||||
struct timeval *tv, int error, void *userptr)
|
||||
{
|
||||
struct dns_server_info *server_info = userptr;
|
||||
if (result != PING_RESULT_RESPONSE || server_info == NULL) {
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#define DNS_MAX_EVENTS 256
|
||||
#define IPV6_READY_CHECK_TIME 180
|
||||
#define DNS_SERVER_TMOUT_TTL (5 * 60)
|
||||
#define DNS_CONN_BUFF_SIZE 4096
|
||||
#define DNS_REQUEST_MAX_TIMEOUT 850
|
||||
@@ -248,6 +249,8 @@ static struct dns_server server;
|
||||
|
||||
static tlog_log *dns_audit;
|
||||
|
||||
static int is_ipv6_ready;
|
||||
|
||||
static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, uint32_t server_flags);
|
||||
|
||||
static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len)
|
||||
@@ -1675,7 +1678,7 @@ errout:
|
||||
|
||||
static void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *host, FAST_PING_RESULT result,
|
||||
struct sockaddr *addr, socklen_t addr_len, int seqno, int ttl, struct timeval *tv,
|
||||
void *userptr)
|
||||
int error, void *userptr)
|
||||
{
|
||||
struct dns_request *request = userptr;
|
||||
int may_complete = 0;
|
||||
@@ -1692,6 +1695,18 @@ static void _dns_server_ping_result(struct ping_host_struct *ping_host, const ch
|
||||
return;
|
||||
} else if (result == PING_RESULT_TIMEOUT) {
|
||||
return;
|
||||
} else if (result == PING_RESULT_ERROR) {
|
||||
if (addr->sa_family != AF_INET6) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_ipv6_ready) {
|
||||
if (error == EADDRNOTAVAIL || errno == EACCES) {
|
||||
is_ipv6_ready = 0;
|
||||
tlog(TLOG_ERROR, "IPV6 is not ready, disable all ipv6 feature, recheck after %ds", IPV6_READY_CHECK_TIME);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int rtt = tv->tv_sec * 10000 + tv->tv_usec / 100;
|
||||
@@ -3011,6 +3026,60 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void _dns_server_check_ipv6_ready(void)
|
||||
{
|
||||
static int do_get_conf = 0;
|
||||
static int is_icmp_check_set;
|
||||
static int is_tcp_check_set;
|
||||
int i = 0;
|
||||
|
||||
if (do_get_conf == 0) {
|
||||
for (i = 0; i < DOMAIN_CHECK_NUM; i++) {
|
||||
if (dns_conf_check_order.order[i] == DOMAIN_CHECK_ICMP) {
|
||||
is_icmp_check_set = 1;
|
||||
}
|
||||
|
||||
if (dns_conf_check_order.order[i] == DOMAIN_CHECK_TCP) {
|
||||
is_tcp_check_set = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_icmp_check_set == 0) {
|
||||
tlog(TLOG_INFO, "ICMP ping is disabled, no ipv6 icmp check feature");
|
||||
}
|
||||
|
||||
do_get_conf = 1;
|
||||
}
|
||||
|
||||
if (is_icmp_check_set) {
|
||||
struct ping_host_struct *check_ping = fast_ping_start(PING_TYPE_ICMP, "2001::", 1, 0, 100, 0, 0);
|
||||
if (check_ping) {
|
||||
fast_ping_stop(check_ping);
|
||||
is_ipv6_ready = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (errno == EADDRNOTAVAIL) {
|
||||
is_ipv6_ready = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_tcp_check_set) {
|
||||
struct ping_host_struct *check_ping = fast_ping_start(PING_TYPE_TCP, "2001::", 1, 0, 100, 0, 0);
|
||||
if (check_ping) {
|
||||
fast_ping_stop(check_ping);
|
||||
is_ipv6_ready = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (errno == EADDRNOTAVAIL) {
|
||||
is_ipv6_ready = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _dns_server_request_set_client(struct dns_request *request, struct dns_server_conn_head *conn)
|
||||
{
|
||||
request->conn = conn;
|
||||
@@ -3116,6 +3185,10 @@ static void _dns_server_check_set_passthrough(struct dns_request *request)
|
||||
request->passthrough = 1;
|
||||
}
|
||||
|
||||
if (is_ipv6_ready == 0 && request->qtype == DNS_T_AAAA) {
|
||||
request->passthrough = 1;
|
||||
}
|
||||
|
||||
if (request->passthrough == 1) {
|
||||
request->dualstack_selection = 0;
|
||||
}
|
||||
@@ -3791,6 +3864,10 @@ static void _dns_server_period_run_second(void)
|
||||
}
|
||||
|
||||
_dns_server_tcp_idle_check();
|
||||
|
||||
if (sec % IPV6_READY_CHECK_TIME == 0 && is_ipv6_ready == 0) {
|
||||
_dns_server_check_ipv6_ready();
|
||||
}
|
||||
}
|
||||
|
||||
static void _dns_server_period_run(void)
|
||||
@@ -4240,6 +4317,9 @@ int dns_server_init(void)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
_dns_server_check_ipv6_ready();
|
||||
tlog(TLOG_INFO, "%s", (is_ipv6_ready) ? "IPV6 is ready, enable IPV6 features" : "IPV6 is not ready, disable IPV6 features");
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
server.run = 0;
|
||||
|
||||
@@ -97,6 +97,7 @@ struct ping_host_struct {
|
||||
FAST_PING_TYPE type;
|
||||
|
||||
void *userptr;
|
||||
int error;
|
||||
fast_ping_result ping_callback;
|
||||
char host[PING_MAX_HOSTLEN];
|
||||
|
||||
@@ -386,7 +387,7 @@ static void _fast_ping_host_put(struct ping_host_struct *ping_host)
|
||||
tv.tv_usec = 0;
|
||||
|
||||
ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_END, &ping_host->addr, ping_host->addr_len,
|
||||
ping_host->seq, ping_host->ttl, &tv, ping_host->userptr);
|
||||
ping_host->seq, ping_host->ttl, &tv, ping_host->error, ping_host->userptr);
|
||||
}
|
||||
|
||||
tlog(TLOG_DEBUG, "ping end, id %d", ping_host->sid);
|
||||
@@ -414,7 +415,7 @@ static void _fast_ping_host_remove(struct ping_host_struct *ping_host)
|
||||
tv.tv_usec = 0;
|
||||
|
||||
ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_END, &ping_host->addr, ping_host->addr_len,
|
||||
ping_host->seq, ping_host->ttl, &tv, ping_host->userptr);
|
||||
ping_host->seq, ping_host->ttl, &tv, ping_host->error, ping_host->userptr);
|
||||
}
|
||||
|
||||
_fast_ping_host_put(ping_host);
|
||||
@@ -445,7 +446,7 @@ static int _fast_ping_sendping_v6(struct ping_host_struct *ping_host)
|
||||
(struct sockaddr *)&ping_host->addr, ping_host->addr_len);
|
||||
if (len < 0 || len != sizeof(struct fast_ping_packet)) {
|
||||
int err = errno;
|
||||
if (errno == ENETUNREACH || errno == EINVAL) {
|
||||
if (errno == ENETUNREACH || errno == EINVAL || errno == EADDRNOTAVAIL) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@@ -644,6 +645,7 @@ static int _fast_ping_sendping(struct ping_host_struct *ping_host)
|
||||
ping_host->send = 1;
|
||||
|
||||
if (ret != 0) {
|
||||
ping_host->error = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -848,13 +850,15 @@ errout:
|
||||
|
||||
static void _fast_ping_print_result(struct ping_host_struct *ping_host, const char *host, FAST_PING_RESULT result,
|
||||
struct sockaddr *addr, socklen_t addr_len, int seqno, int ttl, struct timeval *tv,
|
||||
void *userptr)
|
||||
int error, void *userptr)
|
||||
{
|
||||
if (result == PING_RESULT_RESPONSE) {
|
||||
double rtt = tv->tv_sec * 1000.0 + tv->tv_usec / 1000.0;
|
||||
tlog(TLOG_INFO, "from %15s: seq=%d ttl=%d time=%.3f\n", host, seqno, ttl, rtt);
|
||||
} else if (result == PING_RESULT_TIMEOUT) {
|
||||
tlog(TLOG_INFO, "from %15s: seq=%d timeout\n", host, seqno);
|
||||
} else if (result == PING_RESULT_ERROR) {
|
||||
tlog(TLOG_DEBUG, "from %15s: error is %s\n", host, strerror(error));
|
||||
} else if (result == PING_RESULT_END) {
|
||||
fast_ping_stop(ping_host);
|
||||
}
|
||||
@@ -1041,7 +1045,6 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
|
||||
|
||||
ret = _fast_ping_get_addr_by_type(type, ip_str, port, &gai, &ping_type);
|
||||
if (ret != 0) {
|
||||
tlog(TLOG_ERROR, "get addr by type failed, host: %s", host);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@@ -1097,6 +1100,9 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
|
||||
_fast_ping_host_put(ping_host);
|
||||
return ping_host;
|
||||
errout_remove:
|
||||
ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_ERROR, &ping_host->addr,
|
||||
ping_host->addr_len, ping_host->seq, ping_host->ttl, 0,
|
||||
ping_host->error, ping_host->userptr);
|
||||
fast_ping_stop(ping_host);
|
||||
_fast_ping_host_put(ping_host);
|
||||
ping_host = NULL;
|
||||
@@ -1315,7 +1321,7 @@ static int _fast_ping_process_icmp(struct ping_host_struct *ping_host, struct ti
|
||||
if (recv_ping_host->ping_callback) {
|
||||
recv_ping_host->ping_callback(recv_ping_host, recv_ping_host->host, PING_RESULT_RESPONSE, &recv_ping_host->addr,
|
||||
recv_ping_host->addr_len, recv_ping_host->seq, recv_ping_host->ttl, &tvresult,
|
||||
recv_ping_host->userptr);
|
||||
ping_host->error, recv_ping_host->userptr);
|
||||
}
|
||||
|
||||
recv_ping_host->send = 0;
|
||||
@@ -1349,7 +1355,8 @@ static int _fast_ping_process_tcp(struct ping_host_struct *ping_host, struct epo
|
||||
tv_sub(&tvresult, tvsend);
|
||||
if (ping_host->ping_callback) {
|
||||
ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_RESPONSE, &ping_host->addr,
|
||||
ping_host->addr_len, ping_host->seq, ping_host->ttl, &tvresult, ping_host->userptr);
|
||||
ping_host->addr_len, ping_host->seq, ping_host->ttl, &tvresult, ping_host->error,
|
||||
ping_host->userptr);
|
||||
}
|
||||
|
||||
ping_host->send = 0;
|
||||
@@ -1445,7 +1452,7 @@ static int _fast_ping_process_udp(struct ping_host_struct *ping_host, struct tim
|
||||
if (recv_ping_host->ping_callback) {
|
||||
recv_ping_host->ping_callback(recv_ping_host, recv_ping_host->host, PING_RESULT_RESPONSE, &recv_ping_host->addr,
|
||||
recv_ping_host->addr_len, recv_ping_host->seq, recv_ping_host->ttl, &tvresult,
|
||||
recv_ping_host->userptr);
|
||||
ping_host->error, recv_ping_host->userptr);
|
||||
}
|
||||
|
||||
recv_ping_host->send = 0;
|
||||
@@ -1554,7 +1561,7 @@ static void _fast_ping_period_run(void)
|
||||
if (millisecond >= ping_host->timeout && ping_host->send == 1) {
|
||||
ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_TIMEOUT, &ping_host->addr,
|
||||
ping_host->addr_len, ping_host->seq, ping_host->ttl, &interval,
|
||||
ping_host->userptr);
|
||||
ping_host->error, ping_host->userptr);
|
||||
ping_host->send = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,13 +34,14 @@ typedef enum {
|
||||
typedef enum {
|
||||
PING_RESULT_RESPONSE = 1,
|
||||
PING_RESULT_TIMEOUT = 2,
|
||||
PING_RESULT_END = 3,
|
||||
PING_RESULT_ERROR = 3,
|
||||
PING_RESULT_END = 4,
|
||||
} FAST_PING_RESULT;
|
||||
|
||||
struct ping_host_struct;
|
||||
typedef void (*fast_ping_result)(struct ping_host_struct *ping_host, const char *host, FAST_PING_RESULT result,
|
||||
struct sockaddr *addr, socklen_t addr_len, int seqno, int ttl, struct timeval *tv,
|
||||
void *userptr);
|
||||
int error, void *userptr);
|
||||
|
||||
/* start ping */
|
||||
struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int count, int interval, int timeout,
|
||||
|
||||
Reference in New Issue
Block a user