Update code
This commit is contained in:
10
dns.c
10
dns.c
@@ -35,10 +35,10 @@ short dns_read_short(unsigned char **buffer)
|
||||
{
|
||||
unsigned short value;
|
||||
|
||||
value = *((unsigned short *)(*buffer));
|
||||
value = ntohs(*((unsigned short *)(*buffer)));
|
||||
*buffer += 2;
|
||||
|
||||
return ntohs(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void dns_write_char(unsigned char **buffer, unsigned char value)
|
||||
@@ -63,7 +63,7 @@ void dns_write_short(unsigned char **buffer, unsigned short value)
|
||||
|
||||
void dns_write_int(unsigned char **buffer, unsigned int value)
|
||||
{
|
||||
value = htons(value);
|
||||
value = htonl(value);
|
||||
*((unsigned int *)(*buffer)) = value;
|
||||
*buffer += 4;
|
||||
}
|
||||
@@ -72,10 +72,10 @@ unsigned int dns_read_int(unsigned char **buffer)
|
||||
{
|
||||
unsigned int value;
|
||||
|
||||
value = *((unsigned int *)(*buffer));
|
||||
value = ntohl(*((unsigned int *)(*buffer)));
|
||||
*buffer += 4;
|
||||
|
||||
return ntohs(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
struct dns_rrs *dns_get_rrs_start(struct dns_packet *packet, dns_rr_type type, int *count)
|
||||
|
||||
66
dns_client.c
66
dns_client.c
@@ -87,6 +87,16 @@ struct dns_server_info {
|
||||
};
|
||||
};
|
||||
|
||||
struct dns_query_replied {
|
||||
struct hlist_node node;
|
||||
socklen_t addr_len;
|
||||
union {
|
||||
struct sockaddr_in in;
|
||||
struct sockaddr_in6 in6;
|
||||
struct sockaddr addr;
|
||||
};
|
||||
};
|
||||
|
||||
struct dns_query_struct {
|
||||
atomic_t refcnt;
|
||||
unsigned short sid;
|
||||
@@ -98,6 +108,8 @@ struct dns_query_struct {
|
||||
void *user_ptr;
|
||||
unsigned long send_tick;
|
||||
dns_client_callback callback;
|
||||
|
||||
DECLARE_HASHTABLE(replied_map, 4);
|
||||
};
|
||||
|
||||
static struct dns_client client;
|
||||
@@ -273,6 +285,10 @@ int dns_remove_server(char *server_ip, int port, dns_server_type_t server_type)
|
||||
void _dns_client_query_release(struct dns_query_struct *query)
|
||||
{
|
||||
int refcnt = atomic_dec_return(&query->refcnt);
|
||||
int bucket = 0;
|
||||
struct dns_query_replied *replied_map;
|
||||
struct hlist_node *tmp;
|
||||
|
||||
if (refcnt) {
|
||||
if (refcnt < 0) {
|
||||
tlog(TLOG_ERROR, "BUG: refcnt is %d", refcnt);
|
||||
@@ -285,6 +301,11 @@ void _dns_client_query_release(struct dns_query_struct *query)
|
||||
query->callback(query->domain, DNS_QUERY_END, NULL, NULL, 0, query->user_ptr);
|
||||
}
|
||||
|
||||
hash_for_each_safe(query->replied_map, bucket, tmp, replied_map, node)
|
||||
{
|
||||
hash_del(&replied_map->node);
|
||||
free(replied_map);
|
||||
}
|
||||
memset(query, 0, sizeof(*query));
|
||||
free(query);
|
||||
}
|
||||
@@ -346,6 +367,36 @@ static struct dns_query_struct *_dns_client_get_request(unsigned short sid, char
|
||||
return query;
|
||||
}
|
||||
|
||||
int _dns_replied_check_add(struct dns_query_struct *dns_query, struct sockaddr *addr, socklen_t addr_len)
|
||||
{
|
||||
int key = 0;
|
||||
struct dns_query_replied *replied_map = NULL;
|
||||
|
||||
if (addr_len > sizeof(struct sockaddr_in6)) {
|
||||
tlog(TLOG_ERROR, "addr length is invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
key = jhash(addr, addr_len, 0);
|
||||
hash_for_each_possible(dns_query->replied_map, replied_map, node, key)
|
||||
{
|
||||
if (memcmp(&replied_map->addr, addr, addr_len) == 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
replied_map = malloc(sizeof(*replied_map));
|
||||
if (replied_map == NULL) {
|
||||
tlog(TLOG_ERROR, "malloc failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(&replied_map->addr, addr, addr_len);
|
||||
hash_add(dns_query->replied_map, &replied_map->node, key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _dns_client_recv(unsigned char *inpacket, int inpacket_len, struct sockaddr_storage *from, socklen_t from_len)
|
||||
{
|
||||
int len;
|
||||
@@ -373,8 +424,8 @@ static int _dns_client_recv(unsigned char *inpacket, int inpacket_len, struct so
|
||||
return -1;
|
||||
}
|
||||
|
||||
tlog(TLOG_DEBUG, "qdcount = %d, ancount = %d, nscount = %d, nrcount = %d, len = %d, id = %d, rd = %d, ra = %d, rcode = %d\n", packet->head.qdcount,
|
||||
packet->head.ancount, packet->head.nscount, packet->head.nrcount, inpacket_len, packet->head.id, packet->head.rd, packet->head.ra, packet->head.rcode);
|
||||
tlog(TLOG_DEBUG, "qdcount = %d, ancount = %d, nscount = %d, nrcount = %d, len = %d, id = %d, tc = %d, rd = %d, ra = %d, rcode = %d\n", packet->head.qdcount,
|
||||
packet->head.ancount, packet->head.nscount, packet->head.nrcount, inpacket_len, packet->head.id, packet->head.tc, packet->head.rd, packet->head.ra, packet->head.rcode);
|
||||
|
||||
rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &rr_count);
|
||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
||||
@@ -387,6 +438,10 @@ static int _dns_client_recv(unsigned char *inpacket, int inpacket_len, struct so
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_dns_replied_check_add(query, (struct sockaddr *)from, from_len) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
request_num = atomic_dec_return(&query->dns_request_sent);
|
||||
if (request_num < 0) {
|
||||
tlog(TLOG_ERROR, "send count is invalid, %d", request_num);
|
||||
@@ -435,7 +490,7 @@ static void *_dns_client_work(void *arg)
|
||||
struct epoll_event events[DNS_MAX_EVENTS + 1];
|
||||
int num;
|
||||
int i;
|
||||
unsigned long now = {0};
|
||||
unsigned long now = { 0 };
|
||||
unsigned int sleep = 100;
|
||||
int sleep_time;
|
||||
unsigned int expect_time = 0;
|
||||
@@ -526,9 +581,9 @@ static int _dns_client_send_query(struct dns_query_struct *query, char *doamin)
|
||||
head.id = query->sid;
|
||||
head.qr = DNS_QR_QUERY;
|
||||
head.opcode = DNS_OP_QUERY;
|
||||
head.aa = 1;
|
||||
head.aa = 0;
|
||||
head.rd = 1;
|
||||
head.ra = 1;
|
||||
head.ra = 0;
|
||||
head.rcode = 0;
|
||||
|
||||
dns_packet_init(packet, DNS_PACKSIZE, &head);
|
||||
@@ -557,6 +612,7 @@ int dns_client_query(char *domain, int qtype, dns_client_callback callback, void
|
||||
INIT_LIST_HEAD(&query->dns_request_list);
|
||||
atomic_set(&query->refcnt, 0);
|
||||
atomic_set(&query->dns_request_sent, 0);
|
||||
hash_init(query->replied_map);
|
||||
strncpy(query->domain, domain, DNS_MAX_CNAME_LEN);
|
||||
query->user_ptr = user_ptr;
|
||||
query->callback = callback;
|
||||
|
||||
@@ -211,7 +211,7 @@ static int _dns_reply(struct dns_request *request)
|
||||
head.id = request->id;
|
||||
head.qr = DNS_QR_ANSWER;
|
||||
head.opcode = DNS_OP_QUERY;
|
||||
head.rd = 0;
|
||||
head.rd = 1;
|
||||
head.ra = 0;
|
||||
head.aa = 0;
|
||||
head.tc = 0;
|
||||
@@ -411,13 +411,14 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
|
||||
struct dns_rrs *rrs = NULL;
|
||||
|
||||
if (packet->head.rcode != DNS_RC_NOERROR) {
|
||||
if (request->rcode == (unsigned short)-1) {
|
||||
if (request->rcode == DNS_RC_SERVFAIL) {
|
||||
request->rcode = packet->head.rcode;
|
||||
}
|
||||
tlog(TLOG_ERROR, "inquery failed, %s, rcode = %d, id = %d\n", domain, packet->head.rcode, packet->head.id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
request->rcode = packet->head.rcode;
|
||||
|
||||
for (j = 1; j < DNS_RRS_END; j++) {
|
||||
|
||||
@@ -116,7 +116,7 @@ int smartdns_init()
|
||||
}
|
||||
|
||||
tlog_setlogscreen(1);
|
||||
tlog_setlevel(TLOG_DEBUG);
|
||||
tlog_setlevel(TLOG_INFO);
|
||||
|
||||
if (dns_conf_server_num <= 0) {
|
||||
if (smartdns_load_from_resolv() != 0) {
|
||||
|
||||
@@ -5,12 +5,13 @@ port 53
|
||||
cache-size 1024
|
||||
loglevel info
|
||||
|
||||
#server 192.168.1.1
|
||||
server 114.114.114.114
|
||||
server 123.207.137.88
|
||||
server 119.29.29.29
|
||||
server 223.5.5.5
|
||||
server 208.67.222.222:5353
|
||||
server 202.141.178.13:5353
|
||||
#server 77.88.8.8:53
|
||||
server 77.88.8.8:53
|
||||
server 202.141.162.123:53
|
||||
server 101.132.183.99:53
|
||||
Reference in New Issue
Block a user