Receive DNS packet with IP-TTL.
This commit is contained in:
@@ -76,12 +76,15 @@ log-level info
|
|||||||
# audit-num 2
|
# audit-num 2
|
||||||
|
|
||||||
# remote udp dns server list
|
# remote udp dns server list
|
||||||
# server [IP]:[PORT] [-blacklist-ip] [-check-edns]
|
# server [IP]:[PORT] [-blacklist-ip] [-check-edns] [-check-ttl=[ttl]]
|
||||||
# default port is 53
|
# default port is 53
|
||||||
|
# -blacklist-ip: filter result with blacklist ip
|
||||||
|
# -check-edns: result must exist edns RR, or discard result.
|
||||||
|
# -check-ttl: Check whether TTL is the corresponding value, or discard result, -check-ttl=0 for auto check TTL.
|
||||||
# server 8.8.8.8 -blacklist-ip -check-edns
|
# server 8.8.8.8 -blacklist-ip -check-edns
|
||||||
|
|
||||||
# remote tcp dns server list
|
# remote tcp dns server list
|
||||||
# server-tcp [IP]:[PORT] [-blacklist-ip] [-check-edns]
|
# server-tcp [IP]:[PORT] [-blacklist-ip] [-check-edns]
|
||||||
# default port is 53
|
# default port is 53
|
||||||
# server-tcp 8.8.8.8
|
# server-tcp 8.8.8.8
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ struct dns_server_info {
|
|||||||
|
|
||||||
/* client socket */
|
/* client socket */
|
||||||
int fd;
|
int fd;
|
||||||
|
int ttl;
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
SSL_CTX *ssl_ctx;
|
SSL_CTX *ssl_ctx;
|
||||||
dns_server_status status;
|
dns_server_status status;
|
||||||
@@ -225,8 +226,21 @@ int _dns_client_server_exist(struct addrinfo *gai, dns_server_type_t server_type
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 dns_server_info *server_info = userptr;
|
||||||
|
if (result != PING_RESULT_RESPONSE || server_info == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
server_info->ttl = ttl;
|
||||||
|
}
|
||||||
|
|
||||||
/* add dns server information */
|
/* add dns server information */
|
||||||
int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_type_t server_type, int result_flag)
|
int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_type_t server_type, unsigned int result_flag, int ttl)
|
||||||
{
|
{
|
||||||
struct dns_server_info *server_info = NULL;
|
struct dns_server_info *server_info = NULL;
|
||||||
|
|
||||||
@@ -238,6 +252,11 @@ int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_typ
|
|||||||
if (server_info == NULL) {
|
if (server_info == NULL) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (server_type != DNS_SERVER_UDP) {
|
||||||
|
result_flag &= (~DNSSERVER_FLAG_CHECK_TTL);
|
||||||
|
}
|
||||||
|
|
||||||
memset(server_info, 0, sizeof(*server_info));
|
memset(server_info, 0, sizeof(*server_info));
|
||||||
server_info->ai_family = gai->ai_family;
|
server_info->ai_family = gai->ai_family;
|
||||||
server_info->ai_addrlen = gai->ai_addrlen;
|
server_info->ai_addrlen = gai->ai_addrlen;
|
||||||
@@ -245,6 +264,7 @@ int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_typ
|
|||||||
server_info->fd = 0;
|
server_info->fd = 0;
|
||||||
server_info->status = DNS_SERVER_STATUS_INIT;
|
server_info->status = DNS_SERVER_STATUS_INIT;
|
||||||
server_info->result_flag = result_flag;
|
server_info->result_flag = result_flag;
|
||||||
|
server_info->ttl = ttl;
|
||||||
|
|
||||||
if (gai->ai_addrlen > sizeof(server_info->in6)) {
|
if (gai->ai_addrlen > sizeof(server_info->in6)) {
|
||||||
tlog(TLOG_ERROR, "addr len invalid, %d, %zd, %d", gai->ai_addrlen, sizeof(server_info->addr), server_info->ai_family);
|
tlog(TLOG_ERROR, "addr len invalid, %d, %zd, %d", gai->ai_addrlen, sizeof(server_info->addr), server_info->ai_family);
|
||||||
@@ -253,13 +273,13 @@ int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_typ
|
|||||||
memcpy(&server_info->addr, gai->ai_addr, gai->ai_addrlen);
|
memcpy(&server_info->addr, gai->ai_addr, gai->ai_addrlen);
|
||||||
|
|
||||||
/* start ping task */
|
/* start ping task */
|
||||||
#if 0
|
if (ttl == 0 && (result_flag & DNSSERVER_FLAG_CHECK_TTL)) {
|
||||||
server_info->ping_host = fast_ping_start(server_ip, 0, 60000, 1000, NULL, server_info);
|
server_info->ping_host = fast_ping_start(server_ip, 0, 60000, 1000, _dns_client_server_update_ttl, server_info);
|
||||||
if (server_info->ping_host == NULL) {
|
if (server_info->ping_host == NULL) {
|
||||||
tlog(TLOG_ERROR, "start ping failed.");
|
tlog(TLOG_ERROR, "start ping failed.");
|
||||||
goto errout;
|
goto errout;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* add to list */
|
/* add to list */
|
||||||
pthread_mutex_lock(&client.server_list_lock);
|
pthread_mutex_lock(&client.server_list_lock);
|
||||||
@@ -352,7 +372,7 @@ int _dns_client_server_remove(char *server_ip, struct addrinfo *gai, dns_server_
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t server_type, int result_flag, int operate)
|
int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t server_type, int result_flag, int ttl, int operate)
|
||||||
{
|
{
|
||||||
char port_s[8];
|
char port_s[8];
|
||||||
int sock_type;
|
int sock_type;
|
||||||
@@ -386,7 +406,7 @@ int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t serv
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (operate == 0) {
|
if (operate == 0) {
|
||||||
ret = _dns_client_server_add(server_ip, gai, server_type, result_flag);
|
ret = _dns_client_server_add(server_ip, gai, server_type, result_flag, ttl);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
@@ -405,14 +425,14 @@ errout:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_add_server(char *server_ip, int port, dns_server_type_t server_type, int result_flag)
|
int dns_add_server(char *server_ip, int port, dns_server_type_t server_type, int result_flag, int ttl)
|
||||||
{
|
{
|
||||||
return _dns_client_server_operate(server_ip, port, server_type, result_flag, 0);
|
return _dns_client_server_operate(server_ip, port, server_type, result_flag, ttl, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_remove_server(char *server_ip, int port, dns_server_type_t server_type)
|
int dns_remove_server(char *server_ip, int port, dns_server_type_t server_type)
|
||||||
{
|
{
|
||||||
return _dns_client_server_operate(server_ip, port, server_type, 0, 1);
|
return _dns_client_server_operate(server_ip, port, server_type, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_server_num(void)
|
int dns_server_num(void)
|
||||||
@@ -684,6 +704,8 @@ static int _dns_client_create_socket_udp(struct dns_server_info *server_info)
|
|||||||
{
|
{
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
struct epoll_event event;
|
struct epoll_event event;
|
||||||
|
const int on = 1;
|
||||||
|
const int val=255;
|
||||||
|
|
||||||
fd = socket(server_info->ai_family, SOCK_DGRAM, 0);
|
fd = socket(server_info->ai_family, SOCK_DGRAM, 0);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@@ -701,6 +723,8 @@ static int _dns_client_create_socket_udp(struct dns_server_info *server_info)
|
|||||||
|
|
||||||
server_info->fd = fd;
|
server_info->fd = fd;
|
||||||
server_info->status = DNS_SERVER_STATUS_CONNECTIONLESS;
|
server_info->status = DNS_SERVER_STATUS_CONNECTIONLESS;
|
||||||
|
setsockopt(server_info->fd, IPPROTO_IP, IP_RECVTTL, &on, sizeof(on));
|
||||||
|
setsockopt(server_info->fd, SOL_IP, IP_TTL, &val, sizeof(val));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
errout:
|
errout:
|
||||||
@@ -857,15 +881,45 @@ static int _dns_client_process_udp(struct dns_server_info *server_info, struct e
|
|||||||
struct sockaddr_storage from;
|
struct sockaddr_storage from;
|
||||||
socklen_t from_len = sizeof(from);
|
socklen_t from_len = sizeof(from);
|
||||||
char from_host[DNS_MAX_CNAME_LEN];
|
char from_host[DNS_MAX_CNAME_LEN];
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec iov;
|
||||||
|
char ans_data[4096];
|
||||||
|
int ttl = 0;
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
|
||||||
/* receive from udp */
|
memset(&msg, 0, sizeof(msg));
|
||||||
len = recvfrom(server_info->fd, inpacket, sizeof(inpacket), 0, (struct sockaddr *)&from, (socklen_t *)&from_len);
|
iov.iov_base = (char *)inpacket;
|
||||||
|
iov.iov_len = sizeof(inpacket);
|
||||||
|
msg.msg_name = &from;
|
||||||
|
msg.msg_namelen = sizeof(from);
|
||||||
|
msg.msg_iov = &iov;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_control = ans_data;
|
||||||
|
msg.msg_controllen = sizeof(ans_data);
|
||||||
|
|
||||||
|
len = recvmsg(server_info->fd, &msg, MSG_DONTWAIT);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
tlog(TLOG_ERROR, "recvfrom failed, %s\n", strerror(errno));
|
tlog(TLOG_ERROR, "recvfrom failed, %s\n", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
from_len = msg.msg_namelen;
|
||||||
|
|
||||||
tlog(TLOG_DEBUG, "recv udp, from %s", gethost_by_addr(from_host, (struct sockaddr *)&from, from_len));
|
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||||
|
if (cmsg->cmsg_level == SOL_IP
|
||||||
|
&& cmsg->cmsg_type == IP_TTL
|
||||||
|
) {
|
||||||
|
uint8_t * ttlPtr = (uint8_t *)CMSG_DATA(cmsg);
|
||||||
|
ttl = *ttlPtr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tlog(TLOG_DEBUG, "recv udp, from %s, ttl: %d", gethost_by_addr(from_host, (struct sockaddr *)&from, from_len), ttl);
|
||||||
|
|
||||||
|
if ((ttl != server_info->ttl) && (server_info->result_flag & DNSSERVER_FLAG_CHECK_TTL)) {
|
||||||
|
tlog(TLOG_DEBUG, "TTL mismatch, from:%d, local %d, discard result", ttl, server_info->ttl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
time(&server_info->last_recv);
|
time(&server_info->last_recv);
|
||||||
if (_dns_client_recv(server_info, inpacket, len, (struct sockaddr *)&from, from_len) != 0) {
|
if (_dns_client_recv(server_info, inpacket, len, (struct sockaddr *)&from, from_len) != 0) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ typedef enum dns_result_type {
|
|||||||
|
|
||||||
#define DNSSERVER_FLAG_BLACKLIST_IP (0x1 << 0)
|
#define DNSSERVER_FLAG_BLACKLIST_IP (0x1 << 0)
|
||||||
#define DNSSERVER_FLAG_CHECK_EDNS (0x1 << 1)
|
#define DNSSERVER_FLAG_CHECK_EDNS (0x1 << 1)
|
||||||
|
#define DNSSERVER_FLAG_CHECK_TTL (0x1 << 2)
|
||||||
|
|
||||||
int dns_client_init(void);
|
int dns_client_init(void);
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ int dns_client_query(char *domain, int qtype, dns_client_callback callback, void
|
|||||||
void dns_client_exit(void);
|
void dns_client_exit(void);
|
||||||
|
|
||||||
/* add remote dns server */
|
/* add remote dns server */
|
||||||
int dns_add_server(char *server_ip, int port, dns_server_type_t server_type, int result_flag);
|
int dns_add_server(char *server_ip, int port, dns_server_type_t server_type, int result_flag, int ttl);
|
||||||
|
|
||||||
/* remove remote dns server */
|
/* remove remote dns server */
|
||||||
int dns_remove_server(char *server_ip, int port, dns_server_type_t server_type);
|
int dns_remove_server(char *server_ip, int port, dns_server_type_t server_type);
|
||||||
|
|||||||
@@ -55,10 +55,12 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
|
|||||||
char *ip = NULL;
|
char *ip = NULL;
|
||||||
int opt = 0;
|
int opt = 0;
|
||||||
int result_flag = 0;
|
int result_flag = 0;
|
||||||
|
int ttl = 0;
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"blacklist-ip", 0, 0, 'b'},
|
{"blacklist-ip", 0, 0, 'b'},
|
||||||
{"check-edns", 0, 0, 'e'},
|
{"check-edns", 0, 0, 'e'},
|
||||||
|
{"check-ttl", required_argument, 0, 't'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
@@ -84,6 +86,18 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
|
|||||||
result_flag |= DNSSERVER_FLAG_CHECK_EDNS;
|
result_flag |= DNSSERVER_FLAG_CHECK_EDNS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 't': {
|
||||||
|
if (DNS_SERVER_UDP != type) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ttl = atoi(optarg);
|
||||||
|
if (ttl < 0 || ttl > 255) {
|
||||||
|
tlog(TLOG_ERROR, "ttl value is invalid.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
result_flag |= DNSSERVER_FLAG_CHECK_TTL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,8 +120,9 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
|
|||||||
server->type = type;
|
server->type = type;
|
||||||
server->port = port;
|
server->port = port;
|
||||||
server->result_flag = result_flag;
|
server->result_flag = result_flag;
|
||||||
|
server->ttl = ttl;
|
||||||
dns_conf_server_num++;
|
dns_conf_server_num++;
|
||||||
tlog(TLOG_DEBUG, "add server %s, flag: %X", ip, result_flag);
|
tlog(TLOG_DEBUG, "add server %s, flag: %X, ttl: %d", ip, result_flag, ttl);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ struct dns_servers {
|
|||||||
char server[DNS_MAX_IPLEN];
|
char server[DNS_MAX_IPLEN];
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
unsigned int result_flag;
|
unsigned int result_flag;
|
||||||
|
int ttl;
|
||||||
dns_server_type_t type;
|
dns_server_type_t type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -650,7 +650,7 @@ void _dns_server_request_get(struct dns_request *request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
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, struct timeval *tv, void *userptr)
|
int seqno, int ttl, struct timeval *tv, void *userptr)
|
||||||
{
|
{
|
||||||
struct dns_request *request = userptr;
|
struct dns_request *request = userptr;
|
||||||
int may_complete = 0;
|
int may_complete = 0;
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ struct fast_ping_packet {
|
|||||||
struct icmp icmp;
|
struct icmp icmp;
|
||||||
struct icmp6_hdr icmp6;
|
struct icmp6_hdr icmp6;
|
||||||
};
|
};
|
||||||
|
unsigned int ttl;
|
||||||
struct fast_ping_packet_msg msg;
|
struct fast_ping_packet_msg msg;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -72,6 +73,7 @@ struct ping_host_struct {
|
|||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
unsigned int seq;
|
unsigned int seq;
|
||||||
|
int ttl;
|
||||||
struct timeval last;
|
struct timeval last;
|
||||||
int interval;
|
int interval;
|
||||||
int timeout;
|
int timeout;
|
||||||
@@ -267,7 +269,7 @@ static void _fast_ping_host_put(struct ping_host_struct *ping_host)
|
|||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 0;
|
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, &tv, ping_host->userptr);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
tlog(TLOG_DEBUG, "ping %p end", ping_host);
|
tlog(TLOG_DEBUG, "ping %p end", ping_host);
|
||||||
@@ -294,7 +296,7 @@ static void _fast_ping_host_remove(struct ping_host_struct *ping_host)
|
|||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 0;
|
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, &tv, ping_host->userptr);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
_fast_ping_host_put(ping_host);
|
_fast_ping_host_put(ping_host);
|
||||||
@@ -469,6 +471,8 @@ static int _fast_ping_create_icmp_sock(FAST_PING_TYPE type)
|
|||||||
struct epoll_event event;
|
struct epoll_event event;
|
||||||
int buffsize = 64 * 1024;
|
int buffsize = 64 * 1024;
|
||||||
socklen_t optlen = sizeof(buffsize);
|
socklen_t optlen = sizeof(buffsize);
|
||||||
|
const int val=255;
|
||||||
|
const int on = 1;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case FAST_PING_ICMP:
|
case FAST_PING_ICMP:
|
||||||
@@ -487,6 +491,9 @@ static int _fast_ping_create_icmp_sock(FAST_PING_TYPE type)
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
_fast_ping_install_filter_v6(fd);
|
_fast_ping_install_filter_v6(fd);
|
||||||
|
setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on));
|
||||||
|
setsockopt(fd, IPPROTO_IPV6, IPV6_2292HOPLIMIT, &on, sizeof(on));
|
||||||
|
setsockopt(fd, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on));
|
||||||
icmp_host = &ping.icmp6_host;
|
icmp_host = &ping.icmp6_host;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -495,6 +502,7 @@ static int _fast_ping_create_icmp_sock(FAST_PING_TYPE type)
|
|||||||
|
|
||||||
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const char *)&buffsize, optlen);
|
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const char *)&buffsize, optlen);
|
||||||
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const char *)&buffsize, optlen);
|
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const char *)&buffsize, optlen);
|
||||||
|
setsockopt(fd, SOL_IP, IP_TTL, &val, sizeof(val));
|
||||||
|
|
||||||
memset(&event, 0, sizeof(event));
|
memset(&event, 0, sizeof(event));
|
||||||
event.events = EPOLLIN;
|
event.events = EPOLLIN;
|
||||||
@@ -552,11 +560,11 @@ errout:
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
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,
|
||||||
struct timeval *tv, void *userptr)
|
int ttl, struct timeval *tv, void *userptr)
|
||||||
{
|
{
|
||||||
if (result == PING_RESULT_RESPONSE) {
|
if (result == PING_RESULT_RESPONSE) {
|
||||||
double rtt = tv->tv_sec * 1000.0 + tv->tv_usec / 1000.0;
|
double rtt = tv->tv_sec * 1000.0 + tv->tv_usec / 1000.0;
|
||||||
tlog(TLOG_INFO, "from %15s: seq=%d time=%.3f\n", host, seqno, rtt);
|
tlog(TLOG_INFO, "from %15s: seq=%d ttl=%d time=%.3f\n", host, seqno, ttl, rtt);
|
||||||
} else if (result == PING_RESULT_TIMEOUT) {
|
} else if (result == PING_RESULT_TIMEOUT) {
|
||||||
tlog(TLOG_INFO, "from %15s: seq=%d timeout\n", host, seqno);
|
tlog(TLOG_INFO, "from %15s: seq=%d timeout\n", host, seqno);
|
||||||
} else if (result == PING_RESULT_END) {
|
} else if (result == PING_RESULT_END) {
|
||||||
@@ -694,6 +702,10 @@ errout_remove:
|
|||||||
|
|
||||||
int fast_ping_stop(struct ping_host_struct *ping_host)
|
int fast_ping_stop(struct ping_host_struct *ping_host)
|
||||||
{
|
{
|
||||||
|
if (ping_host == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
atomic_inc_return(&ping_host->notified);
|
atomic_inc_return(&ping_host->notified);
|
||||||
_fast_ping_host_remove(ping_host);
|
_fast_ping_host_remove(ping_host);
|
||||||
_fast_ping_host_put(ping_host);
|
_fast_ping_host_put(ping_host);
|
||||||
@@ -709,12 +721,29 @@ static void tv_sub(struct timeval *out, struct timeval *in)
|
|||||||
out->tv_sec -= in->tv_sec;
|
out->tv_sec -= in->tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct fast_ping_packet *_fast_ping_icmp6_packet(struct ping_host_struct *ping_host, u_char *packet_data, int data_len)
|
static struct fast_ping_packet *_fast_ping_icmp6_packet(struct ping_host_struct *ping_host, struct msghdr *msg, u_char *packet_data, int data_len)
|
||||||
{
|
{
|
||||||
int icmp_len;
|
int icmp_len;
|
||||||
struct fast_ping_packet *packet = (struct fast_ping_packet *)packet_data;
|
struct fast_ping_packet *packet = (struct fast_ping_packet *)packet_data;
|
||||||
struct icmp6_hdr *icmp6 = &packet->icmp6;
|
struct icmp6_hdr *icmp6 = &packet->icmp6;
|
||||||
|
struct cmsghdr *c;
|
||||||
|
int hops = 0;
|
||||||
|
|
||||||
|
for (c = CMSG_FIRSTHDR(msg); c; c = CMSG_NXTHDR(msg, c)) {
|
||||||
|
if (c->cmsg_level != IPPROTO_IPV6)
|
||||||
|
continue;
|
||||||
|
switch(c->cmsg_type) {
|
||||||
|
case IPV6_HOPLIMIT:
|
||||||
|
#ifdef IPV6_2292HOPLIMIT
|
||||||
|
case IPV6_2292HOPLIMIT:
|
||||||
|
#endif
|
||||||
|
if (c->cmsg_len < CMSG_LEN(sizeof(int)))
|
||||||
|
continue;
|
||||||
|
memcpy(&hops, CMSG_DATA(c), sizeof(hops));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
packet->ttl = hops;
|
||||||
if (icmp6->icmp6_type != ICMP6_ECHO_REPLY) {
|
if (icmp6->icmp6_type != ICMP6_ECHO_REPLY) {
|
||||||
tlog(TLOG_DEBUG, "icmp6 type faild, %d:%d", icmp6->icmp6_type, ICMP6_ECHO_REPLY);
|
tlog(TLOG_DEBUG, "icmp6 type faild, %d:%d", icmp6->icmp6_type, ICMP6_ECHO_REPLY);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -734,7 +763,7 @@ static struct fast_ping_packet *_fast_ping_icmp6_packet(struct ping_host_struct
|
|||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *ping_host, u_char *packet_data, int data_len)
|
static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *ping_host, struct msghdr *msg, u_char *packet_data, int data_len)
|
||||||
{
|
{
|
||||||
struct ip *ip = (struct ip *)packet_data;
|
struct ip *ip = (struct ip *)packet_data;
|
||||||
struct fast_ping_packet *packet;
|
struct fast_ping_packet *packet;
|
||||||
@@ -751,6 +780,7 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *
|
|||||||
packet = (struct fast_ping_packet *)(packet_data + hlen);
|
packet = (struct fast_ping_packet *)(packet_data + hlen);
|
||||||
icmp = &packet->icmp;
|
icmp = &packet->icmp;
|
||||||
icmp_len = data_len - hlen;
|
icmp_len = data_len - hlen;
|
||||||
|
packet->ttl = ip->ip_ttl;
|
||||||
|
|
||||||
if (icmp_len < 16) {
|
if (icmp_len < 16) {
|
||||||
tlog(TLOG_ERROR, "length is invalid, %d", icmp_len);
|
tlog(TLOG_ERROR, "length is invalid, %d", icmp_len);
|
||||||
@@ -770,17 +800,17 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *
|
|||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fast_ping_packet *_fast_ping_recv_packet(struct ping_host_struct *ping_host, u_char *inpacket, int len, struct timeval *tvrecv)
|
struct fast_ping_packet *_fast_ping_recv_packet(struct ping_host_struct *ping_host, struct msghdr *msg, u_char *inpacket, int len, struct timeval *tvrecv)
|
||||||
{
|
{
|
||||||
struct fast_ping_packet *packet = NULL;
|
struct fast_ping_packet *packet = NULL;
|
||||||
|
|
||||||
if (ping_host->type == FAST_PING_ICMP6) {
|
if (ping_host->type == FAST_PING_ICMP6) {
|
||||||
packet = _fast_ping_icmp6_packet(ping_host, inpacket, len);
|
packet = _fast_ping_icmp6_packet(ping_host, msg, inpacket, len);
|
||||||
if (packet == NULL) {
|
if (packet == NULL) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
} else if (ping_host->type == FAST_PING_ICMP) {
|
} else if (ping_host->type == FAST_PING_ICMP) {
|
||||||
packet = _fast_ping_icmp_packet(ping_host, inpacket, len);
|
packet = _fast_ping_icmp_packet(ping_host, msg, inpacket, len);
|
||||||
if (packet == NULL) {
|
if (packet == NULL) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
@@ -808,14 +838,28 @@ static int _fast_ping_process_icmp(struct ping_host_struct *ping_host, struct ti
|
|||||||
unsigned int sid;
|
unsigned int sid;
|
||||||
unsigned int seq;
|
unsigned int seq;
|
||||||
unsigned int cookie;
|
unsigned int cookie;
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec iov;
|
||||||
|
char ans_data[4096];
|
||||||
|
|
||||||
len = recvfrom(ping_host->fd, inpacket, sizeof(inpacket), 0, (struct sockaddr *)&from, (socklen_t *)&from_len);
|
memset(&msg, 0, sizeof(msg));
|
||||||
|
iov.iov_base = (char *)inpacket;
|
||||||
|
iov.iov_len = sizeof(inpacket);
|
||||||
|
msg.msg_name = &from;
|
||||||
|
msg.msg_namelen = sizeof(from);
|
||||||
|
msg.msg_iov = &iov;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_control = ans_data;
|
||||||
|
msg.msg_controllen = sizeof(ans_data);
|
||||||
|
|
||||||
|
len = recvmsg(ping_host->fd, &msg, MSG_DONTWAIT);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
tlog(TLOG_ERROR, "recvfrom failed, %s\n", strerror(errno));
|
tlog(TLOG_ERROR, "recvfrom failed, %s\n", strerror(errno));
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet = _fast_ping_recv_packet(ping_host, inpacket, len, now);
|
from_len = msg.msg_namelen;
|
||||||
|
packet = _fast_ping_recv_packet(ping_host, &msg, inpacket, len, now);
|
||||||
if (packet == NULL) {
|
if (packet == NULL) {
|
||||||
char name[PING_MAX_HOSTLEN];
|
char name[PING_MAX_HOSTLEN];
|
||||||
tlog(TLOG_DEBUG, "recv ping packet from %s failed.", gethost_by_addr(name, (struct sockaddr *)&from, from_len));
|
tlog(TLOG_DEBUG, "recv ping packet from %s failed.", gethost_by_addr(name, (struct sockaddr *)&from, from_len));
|
||||||
@@ -848,10 +892,11 @@ static int _fast_ping_process_icmp(struct ping_host_struct *ping_host, struct ti
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recv_ping_host->ttl = packet->ttl;
|
||||||
tv_sub(&tvresult, tvsend);
|
tv_sub(&tvresult, tvsend);
|
||||||
if (recv_ping_host->ping_callback) {
|
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->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, &tvresult, recv_ping_host->userptr);
|
recv_ping_host->seq, recv_ping_host->ttl, &tvresult, recv_ping_host->userptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
recv_ping_host->send = 0;
|
recv_ping_host->send = 0;
|
||||||
@@ -882,8 +927,8 @@ static int _fast_ping_process_tcp(struct ping_host_struct *ping_host, struct epo
|
|||||||
}
|
}
|
||||||
tv_sub(&tvresult, tvsend);
|
tv_sub(&tvresult, tvsend);
|
||||||
if (ping_host->ping_callback) {
|
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, &tvresult,
|
ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_RESPONSE, &ping_host->addr, ping_host->addr_len, ping_host->seq,
|
||||||
ping_host->userptr);
|
ping_host->ttl, &tvresult, ping_host->userptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ping_host->send = 0;
|
ping_host->send = 0;
|
||||||
@@ -984,8 +1029,8 @@ static void _fast_ping_period_run(void)
|
|||||||
tv_sub(&interval, &ping_host->last);
|
tv_sub(&interval, &ping_host->last);
|
||||||
millisecond = interval.tv_sec * 1000 + interval.tv_usec / 1000;
|
millisecond = interval.tv_sec * 1000 + interval.tv_usec / 1000;
|
||||||
if (millisecond >= ping_host->timeout && ping_host->send == 1) {
|
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, &interval,
|
ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_TIMEOUT, &ping_host->addr, ping_host->addr_len, ping_host->seq,
|
||||||
ping_host->userptr);
|
ping_host->ttl, &interval, ping_host->userptr);
|
||||||
ping_host->send = 0;
|
ping_host->send = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ typedef enum {
|
|||||||
} FAST_PING_RESULT;
|
} FAST_PING_RESULT;
|
||||||
|
|
||||||
struct ping_host_struct;
|
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, struct timeval *tv, void *userptr);
|
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);
|
||||||
|
|
||||||
/* start ping */
|
/* start ping */
|
||||||
struct ping_host_struct *fast_ping_start(const char *host, int count, int interval, int timeout, fast_ping_result ping_callback, void *userptr);
|
struct ping_host_struct *fast_ping_start(const char *host, int count, int interval, int timeout, fast_ping_result ping_callback, void *userptr);
|
||||||
|
|||||||
@@ -124,7 +124,8 @@ int smartdns_add_servers(void)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
for (i = 0; i < dns_conf_server_num; i++) {
|
for (i = 0; i < dns_conf_server_num; i++) {
|
||||||
ret = dns_add_server(dns_conf_servers[i].server, dns_conf_servers[i].port, dns_conf_servers[i].type, dns_conf_servers[i].result_flag);
|
ret = dns_add_server(dns_conf_servers[i].server, dns_conf_servers[i].port, dns_conf_servers[i].type, dns_conf_servers[i].result_flag,
|
||||||
|
dns_conf_servers[i].ttl);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
tlog(TLOG_ERROR, "add server failed, %s:%d", dns_conf_servers[i].server, dns_conf_servers[i].port);
|
tlog(TLOG_ERROR, "add server failed, %s:%d", dns_conf_servers[i].server, dns_conf_servers[i].port);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user