Check ip before ping
This commit is contained in:
12
dns_client.c
12
dns_client.c
@@ -174,9 +174,9 @@ 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);
|
||||||
|
|
||||||
if (fast_ping_start(server_ip, 0, 60000, NULL, server_info) == NULL) {
|
// if (fast_ping_start(server_ip, 0, 60000, NULL, server_info) == NULL) {
|
||||||
goto errout;
|
// goto errout;
|
||||||
}
|
// }
|
||||||
|
|
||||||
pthread_mutex_lock(&client.server_list_lock);
|
pthread_mutex_lock(&client.server_list_lock);
|
||||||
list_add(&server_info->list, &client.dns_server_list);
|
list_add(&server_info->list, &client.dns_server_list);
|
||||||
@@ -205,9 +205,9 @@ int _dns_client_server_remove(char *server_ip, struct addrinfo *gai, dns_server_
|
|||||||
}
|
}
|
||||||
list_del(&server_info->list);
|
list_del(&server_info->list);
|
||||||
pthread_mutex_unlock(&client.server_list_lock);
|
pthread_mutex_unlock(&client.server_list_lock);
|
||||||
if (fast_ping_stop(server_info->ping_host) != 0) {
|
// if (fast_ping_stop(server_info->ping_host) != 0) {
|
||||||
tlog(TLOG_ERROR, "stop ping failed.\n");
|
// tlog(TLOG_ERROR, "stop ping failed.\n");
|
||||||
}
|
// }
|
||||||
free(server_info);
|
free(server_info);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,14 +10,6 @@ typedef enum {
|
|||||||
DNS_SERVER_TYPE_END,
|
DNS_SERVER_TYPE_END,
|
||||||
} dns_server_type_t;
|
} dns_server_type_t;
|
||||||
|
|
||||||
struct dns_result {
|
|
||||||
char alias[DNS_MAX_CNAME_LEN];
|
|
||||||
unsigned long ttl_v4;
|
|
||||||
unsigned char addr_ipv4[4];
|
|
||||||
unsigned long ttl_v6;
|
|
||||||
unsigned char addr_ipv6[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum dns_result_type {
|
typedef enum dns_result_type {
|
||||||
DNS_QUERY_ERR,
|
DNS_QUERY_ERR,
|
||||||
DNS_QUERY_RESULT = 1,
|
DNS_QUERY_RESULT = 1,
|
||||||
|
|||||||
75
dns_server.c
75
dns_server.c
@@ -58,6 +58,16 @@ struct dns_server {
|
|||||||
DECLARE_HASHTABLE(hostmap, 6);
|
DECLARE_HASHTABLE(hostmap, 6);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dns_ip_address {
|
||||||
|
struct hlist_node node;
|
||||||
|
dns_type_t addr_type;
|
||||||
|
union {
|
||||||
|
unsigned char ipv4_addr[DNS_RR_A_LEN];
|
||||||
|
unsigned char ipv6_addr[DNS_RR_AAAA_LEN];
|
||||||
|
unsigned char addr[0];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
struct dns_request {
|
struct dns_request {
|
||||||
atomic_t refcnt;
|
atomic_t refcnt;
|
||||||
struct hlist_node map;
|
struct hlist_node map;
|
||||||
@@ -94,6 +104,8 @@ struct dns_request {
|
|||||||
atomic_t notified;
|
atomic_t notified;
|
||||||
|
|
||||||
int passthrough;
|
int passthrough;
|
||||||
|
|
||||||
|
DECLARE_HASHTABLE(ip_map, 4);
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dns_server server;
|
static struct dns_server server;
|
||||||
@@ -255,6 +267,10 @@ int _dns_server_request_complete(struct dns_request *request)
|
|||||||
|
|
||||||
void _dns_server_request_release(struct dns_request *request)
|
void _dns_server_request_release(struct dns_request *request)
|
||||||
{
|
{
|
||||||
|
struct dns_ip_address *addr_map;
|
||||||
|
struct hlist_node *tmp;
|
||||||
|
int bucket = 0;
|
||||||
|
|
||||||
int refcnt = atomic_dec_return(&request->refcnt);
|
int refcnt = atomic_dec_return(&request->refcnt);
|
||||||
if (refcnt) {
|
if (refcnt) {
|
||||||
if (refcnt < 0) {
|
if (refcnt < 0) {
|
||||||
@@ -265,6 +281,10 @@ void _dns_server_request_release(struct dns_request *request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_dns_server_request_complete(request);
|
_dns_server_request_complete(request);
|
||||||
|
hash_for_each_safe(request->ip_map, bucket, tmp, addr_map, node) {
|
||||||
|
hash_del(&addr_map->node);
|
||||||
|
free(addr_map);
|
||||||
|
}
|
||||||
memset(request, 0, sizeof(*request));
|
memset(request, 0, sizeof(*request));
|
||||||
free(request);
|
free(request);
|
||||||
}
|
}
|
||||||
@@ -337,6 +357,47 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _dns_ip_address_check_add(struct dns_request *request, unsigned char *addr, dns_type_t addr_type)
|
||||||
|
{
|
||||||
|
int key = 0;
|
||||||
|
struct dns_ip_address *addr_map = NULL;
|
||||||
|
int addr_len = 0;
|
||||||
|
|
||||||
|
if (addr_type == DNS_T_A) {
|
||||||
|
addr_len = DNS_RR_A_LEN;
|
||||||
|
} else if (addr_type == DNS_T_AAAA) {
|
||||||
|
addr_len = DNS_RR_AAAA_LEN;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = jhash(addr, addr_len, 0);
|
||||||
|
hash_for_each_possible(request->ip_map, addr_map, node, key)
|
||||||
|
{
|
||||||
|
if (addr_type == DNS_T_A) {
|
||||||
|
if (memcmp(addr_map->ipv4_addr, addr, addr_len) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (addr_type == DNS_T_AAAA) {
|
||||||
|
if (memcmp(addr_map->ipv6_addr, addr, addr_len) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_map = malloc(sizeof(*addr_map));
|
||||||
|
if (addr_map == NULL) {
|
||||||
|
tlog(TLOG_ERROR, "malloc failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_map->addr_type = addr_type;
|
||||||
|
memcpy(addr_map->addr, addr, addr_len);
|
||||||
|
hash_add(request->ip_map, &addr_map->node, key);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int _dns_client_process_answer(struct dns_request *request, char *domain, struct dns_packet *packet)
|
static int _dns_client_process_answer(struct dns_request *request, char *domain, struct dns_packet *packet)
|
||||||
{
|
{
|
||||||
int ttl;
|
int ttl;
|
||||||
@@ -363,12 +424,16 @@ static int _dns_client_process_answer(struct dns_request *request, char *domain,
|
|||||||
switch (rrs->type) {
|
switch (rrs->type) {
|
||||||
case DNS_T_A: {
|
case DNS_T_A: {
|
||||||
unsigned char addr[4];
|
unsigned char addr[4];
|
||||||
|
_dns_server_request_get(request);
|
||||||
dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
|
dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
|
||||||
|
if (_dns_ip_address_check_add(request, addr, DNS_T_A) != 0) {
|
||||||
|
_dns_server_request_release(request);
|
||||||
|
break;
|
||||||
|
}
|
||||||
tlog(TLOG_INFO, "%s %d : %d.%d.%d.%d", name, ttl, addr[0], addr[1], addr[2], addr[3]);
|
tlog(TLOG_INFO, "%s %d : %d.%d.%d.%d", name, ttl, addr[0], addr[1], addr[2], addr[3]);
|
||||||
sprintf(ip, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
|
sprintf(ip, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
|
||||||
|
|
||||||
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) == 0 || strncmp(request->alias, name, DNS_MAX_CNAME_LEN) == 0) {
|
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) == 0 || strncmp(request->alias, name, DNS_MAX_CNAME_LEN) == 0) {
|
||||||
_dns_server_request_get(request);
|
|
||||||
if (fast_ping_start(ip, 1, 1000, _dns_server_ping_result, request) == NULL) {
|
if (fast_ping_start(ip, 1, 1000, _dns_server_ping_result, request) == NULL) {
|
||||||
_dns_server_request_release(request);
|
_dns_server_request_release(request);
|
||||||
}
|
}
|
||||||
@@ -376,10 +441,15 @@ static int _dns_client_process_answer(struct dns_request *request, char *domain,
|
|||||||
} break;
|
} break;
|
||||||
case DNS_T_AAAA: {
|
case DNS_T_AAAA: {
|
||||||
unsigned char addr[16];
|
unsigned char addr[16];
|
||||||
|
_dns_server_request_get(request);
|
||||||
dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
|
dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
|
||||||
|
if (_dns_ip_address_check_add(request, addr, DNS_T_AAAA) != 0) {
|
||||||
|
_dns_server_request_release(request);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(name, "%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8],
|
sprintf(name, "%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8],
|
||||||
addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]);
|
addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]);
|
||||||
_dns_server_request_get(request);
|
|
||||||
if (fast_ping_start(name, 1, 1000, _dns_server_ping_result, request) == NULL) {
|
if (fast_ping_start(name, 1, 1000, _dns_server_ping_result, request) == NULL) {
|
||||||
_dns_server_request_release(request);
|
_dns_server_request_release(request);
|
||||||
}
|
}
|
||||||
@@ -547,6 +617,7 @@ static int _dns_server_recv(unsigned char *inpacket, int inpacket_len, struct so
|
|||||||
|
|
||||||
request->id = packet->head.id;
|
request->id = packet->head.id;
|
||||||
memcpy(&request->head, &packet->head, sizeof(struct dns_head));
|
memcpy(&request->head, &packet->head, sizeof(struct dns_head));
|
||||||
|
hash_init(request->ip_map);
|
||||||
|
|
||||||
rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &rr_count);
|
rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &rr_count);
|
||||||
if (rr_count > 1) {
|
if (rr_count > 1) {
|
||||||
|
|||||||
@@ -298,7 +298,8 @@ static int _fast_ping_sendping_v6(struct ping_host_struct *ping_host)
|
|||||||
|
|
||||||
len = sendto(ping_host->fd, &ping_host->packet, sizeof(struct fast_ping_packet), 0, (struct sockaddr *)&ping_host->addr, ping_host->addr_len);
|
len = sendto(ping_host->fd, &ping_host->packet, sizeof(struct fast_ping_packet), 0, (struct sockaddr *)&ping_host->addr, ping_host->addr_len);
|
||||||
if (len < 0 || len != sizeof(struct fast_ping_packet)) {
|
if (len < 0 || len != sizeof(struct fast_ping_packet)) {
|
||||||
tlog(TLOG_ERROR, "sendto %s\n", strerror(errno));
|
char ping_host_name[PING_MAX_HOSTLEN];
|
||||||
|
tlog(TLOG_ERROR, "sendto %s %s\n", gethost_by_addr(ping_host_name, (struct sockaddr *)&ping_host->addr, ping_host->addr_len), strerror(errno));
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//Source: http://golubenco.org/atomic-operations.html
|
|
||||||
#ifndef _GENERIC_ATOMIC_H
|
#ifndef _GENERIC_ATOMIC_H
|
||||||
#define _GENERIC_ATOMIC_H
|
#define _GENERIC_ATOMIC_H
|
||||||
|
|
||||||
|
|||||||
22
include/cache.h
Normal file
22
include/cache.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef _GENERIC_CACHE_H
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
#include "hashtable.h"
|
||||||
|
|
||||||
|
struct cache_node {
|
||||||
|
struct hlist_node list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cache_head;
|
||||||
|
|
||||||
|
struct cache_head *cache_new(int hashsize, void (*item_free)(struct cache_head *head, struct cache_node *node));
|
||||||
|
|
||||||
|
int cache_add(struct cache_head *head, struct cache_node *node, void *key, int key_len);
|
||||||
|
|
||||||
|
struct cache_node *cache_lookup(struct cache_head *head, void *key, int key_len);
|
||||||
|
|
||||||
|
int cache_update(struct cache_head *head, void *key, int key_len);
|
||||||
|
|
||||||
|
void cache_free(struct cache_head *head);
|
||||||
|
|
||||||
|
#endif // !_GENERIC_CACHE_H
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
|
#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
|
||||||
#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
|
#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef _TOOLS_LINUX_COMPILER_H_
|
#ifndef _TOOLS_LINUX_COMPILER_H_
|
||||||
#define _TOOLS_LINUX_COMPILER_H_
|
#define _TOOLS_LINUX_COMPILER_H_
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
/*
|
||||||
* Statically sized hash table implementation
|
* Statically sized hash table implementation
|
||||||
* (C) 2012 Sasha Levin <levinsasha928@gmail.com>
|
* (C) 2012 Sasha Levin <levinsasha928@gmail.com>
|
||||||
|
|||||||
8
lib/cache.c
Normal file
8
lib/cache.c
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include "cache.h"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
struct cache_head {
|
||||||
|
struct hlist_head hash_head;
|
||||||
|
int hash_size;
|
||||||
|
pthread_rwlock_t *rwlock;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user