Update code

This commit is contained in:
Nick Peng
2018-06-08 21:57:33 +08:00
parent 4ee70e3eac
commit 4a6b0baddd
5 changed files with 595 additions and 537 deletions

10
dns.c
View File

@@ -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)

View File

@@ -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;

View File

@@ -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++) {

View File

@@ -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) {

View File

@@ -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