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; unsigned short value;
value = *((unsigned short *)(*buffer)); value = ntohs(*((unsigned short *)(*buffer)));
*buffer += 2; *buffer += 2;
return ntohs(value); return value;
} }
void dns_write_char(unsigned char **buffer, unsigned char 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) void dns_write_int(unsigned char **buffer, unsigned int value)
{ {
value = htons(value); value = htonl(value);
*((unsigned int *)(*buffer)) = value; *((unsigned int *)(*buffer)) = value;
*buffer += 4; *buffer += 4;
} }
@@ -72,10 +72,10 @@ unsigned int dns_read_int(unsigned char **buffer)
{ {
unsigned int value; unsigned int value;
value = *((unsigned int *)(*buffer)); value = ntohl(*((unsigned int *)(*buffer)));
*buffer += 4; *buffer += 4;
return ntohs(value); return value;
} }
struct dns_rrs *dns_get_rrs_start(struct dns_packet *packet, dns_rr_type type, int *count) 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 { struct dns_query_struct {
atomic_t refcnt; atomic_t refcnt;
unsigned short sid; unsigned short sid;
@@ -98,6 +108,8 @@ struct dns_query_struct {
void *user_ptr; void *user_ptr;
unsigned long send_tick; unsigned long send_tick;
dns_client_callback callback; dns_client_callback callback;
DECLARE_HASHTABLE(replied_map, 4);
}; };
static struct dns_client client; 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) void _dns_client_query_release(struct dns_query_struct *query)
{ {
int refcnt = atomic_dec_return(&query->refcnt); int refcnt = atomic_dec_return(&query->refcnt);
int bucket = 0;
struct dns_query_replied *replied_map;
struct hlist_node *tmp;
if (refcnt) { if (refcnt) {
if (refcnt < 0) { if (refcnt < 0) {
tlog(TLOG_ERROR, "BUG: refcnt is %d", refcnt); 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); 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)); memset(query, 0, sizeof(*query));
free(query); free(query);
} }
@@ -346,6 +367,36 @@ static struct dns_query_struct *_dns_client_get_request(unsigned short sid, char
return query; 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) static int _dns_client_recv(unsigned char *inpacket, int inpacket_len, struct sockaddr_storage *from, socklen_t from_len)
{ {
int len; int len;
@@ -373,8 +424,8 @@ static int _dns_client_recv(unsigned char *inpacket, int inpacket_len, struct so
return -1; 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, 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.rd, packet->head.ra, packet->head.rcode); 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); 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)) { 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; 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); request_num = atomic_dec_return(&query->dns_request_sent);
if (request_num < 0) { if (request_num < 0) {
tlog(TLOG_ERROR, "send count is invalid, %d", request_num); tlog(TLOG_ERROR, "send count is invalid, %d", request_num);
@@ -526,9 +581,9 @@ static int _dns_client_send_query(struct dns_query_struct *query, char *doamin)
head.id = query->sid; head.id = query->sid;
head.qr = DNS_QR_QUERY; head.qr = DNS_QR_QUERY;
head.opcode = DNS_OP_QUERY; head.opcode = DNS_OP_QUERY;
head.aa = 1; head.aa = 0;
head.rd = 1; head.rd = 1;
head.ra = 1; head.ra = 0;
head.rcode = 0; head.rcode = 0;
dns_packet_init(packet, DNS_PACKSIZE, &head); 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); INIT_LIST_HEAD(&query->dns_request_list);
atomic_set(&query->refcnt, 0); atomic_set(&query->refcnt, 0);
atomic_set(&query->dns_request_sent, 0); atomic_set(&query->dns_request_sent, 0);
hash_init(query->replied_map);
strncpy(query->domain, domain, DNS_MAX_CNAME_LEN); strncpy(query->domain, domain, DNS_MAX_CNAME_LEN);
query->user_ptr = user_ptr; query->user_ptr = user_ptr;
query->callback = callback; query->callback = callback;

View File

@@ -211,7 +211,7 @@ static int _dns_reply(struct dns_request *request)
head.id = request->id; head.id = request->id;
head.qr = DNS_QR_ANSWER; head.qr = DNS_QR_ANSWER;
head.opcode = DNS_OP_QUERY; head.opcode = DNS_OP_QUERY;
head.rd = 0; head.rd = 1;
head.ra = 0; head.ra = 0;
head.aa = 0; head.aa = 0;
head.tc = 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; struct dns_rrs *rrs = NULL;
if (packet->head.rcode != DNS_RC_NOERROR) { if (packet->head.rcode != DNS_RC_NOERROR) {
if (request->rcode == (unsigned short)-1) { if (request->rcode == DNS_RC_SERVFAIL) {
request->rcode = packet->head.rcode; request->rcode = packet->head.rcode;
} }
tlog(TLOG_ERROR, "inquery failed, %s, rcode = %d, id = %d\n", domain, packet->head.rcode, packet->head.id); tlog(TLOG_ERROR, "inquery failed, %s, rcode = %d, id = %d\n", domain, packet->head.rcode, packet->head.id);
return -1; return -1;
} }
request->rcode = packet->head.rcode; request->rcode = packet->head.rcode;
for (j = 1; j < DNS_RRS_END; j++) { for (j = 1; j < DNS_RRS_END; j++) {

View File

@@ -116,7 +116,7 @@ int smartdns_init()
} }
tlog_setlogscreen(1); tlog_setlogscreen(1);
tlog_setlevel(TLOG_DEBUG); tlog_setlevel(TLOG_INFO);
if (dns_conf_server_num <= 0) { if (dns_conf_server_num <= 0) {
if (smartdns_load_from_resolv() != 0) { if (smartdns_load_from_resolv() != 0) {

View File

@@ -5,12 +5,13 @@ port 53
cache-size 1024 cache-size 1024
loglevel info loglevel info
#server 192.168.1.1
server 114.114.114.114 server 114.114.114.114
server 123.207.137.88 server 123.207.137.88
server 119.29.29.29 server 119.29.29.29
server 223.5.5.5 server 223.5.5.5
server 208.67.222.222:5353 server 208.67.222.222:5353
server 202.141.178.13: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 202.141.162.123:53
server 101.132.183.99:53 server 101.132.183.99:53