update code
This commit is contained in:
38
dns.c
38
dns.c
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "dns.h"
|
||||
#include "tlog.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -515,6 +516,9 @@ int _dns_decode_domain(struct dns_context *context, char *output, int size)
|
||||
int is_compressed = 0;
|
||||
|
||||
while (1) {
|
||||
if (ptr > context->data + context->maxsize || ptr < context->data) {
|
||||
return -1;
|
||||
}
|
||||
len = *ptr;
|
||||
if (len == 0) {
|
||||
*(output - 1) = 0;
|
||||
@@ -528,21 +532,27 @@ int _dns_decode_domain(struct dns_context *context, char *output, int size)
|
||||
context->ptr = ptr;
|
||||
}
|
||||
ptr = context->data + len;
|
||||
if (context->maxsize - (ptr - context->data) < 1) {
|
||||
if (context->maxsize - (ptr - context->data) < 0) {
|
||||
tlog(TLOG_ERROR, "length is not enouth %d:%d, %p, %p", context->maxsize, ptr-context->data,
|
||||
context->ptr, context->data);
|
||||
return -1;
|
||||
}
|
||||
is_compressed = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (context->maxsize - (ptr - context->data) < 1) {
|
||||
if (context->maxsize - (ptr - context->data) < 0) {
|
||||
tlog(TLOG_ERROR, "length is not enouth %d:%d, %p, %p", context->maxsize, ptr-context->data,
|
||||
context->ptr, context->data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
if (output_len < size - 1) {
|
||||
copy_len = (len < size - output_len) ? len : size - 1 - output_len;
|
||||
if (context->maxsize - (ptr - context->data) < 1) {
|
||||
if (context->maxsize - (ptr - context->data) < 0) {
|
||||
tlog(TLOG_ERROR, "length is not enouth %d:%d, %p, %p", context->maxsize, ptr-context->data,
|
||||
context->ptr, context->data);
|
||||
return -1;
|
||||
}
|
||||
memcpy(output, ptr, copy_len);
|
||||
@@ -594,10 +604,12 @@ int _dns_decode_qr_head(struct dns_context *context, char *domain, int domain_si
|
||||
|
||||
ret = _dns_decode_domain(context, domain, domain_size);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode domain failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_dns_left_len(context) < 4) {
|
||||
tlog(TLOG_ERROR, "left length is not enough, %s.", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -631,10 +643,12 @@ int _dns_decode_rr_head(struct dns_context *context, char *domain, int domain_si
|
||||
|
||||
len = _dns_decode_qr_head(context, domain, domain_size, qtype, qclass);
|
||||
if (len < 0) {
|
||||
tlog(TLOG_ERROR, "decode qr head failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_dns_left_len(context) < 6) {
|
||||
tlog(TLOG_ERROR, "left length is not enough.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -873,6 +887,7 @@ int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
|
||||
ret = _dns_decode_rr_head(context, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode head failed.");
|
||||
return -1;
|
||||
}
|
||||
start = context->ptr;
|
||||
@@ -882,11 +897,13 @@ int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
unsigned char addr[DNS_RR_A_LEN];
|
||||
ret = _dns_decode_A(context, addr);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode A failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dns_add_A(packet, type, domain, ttl, addr);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "add A failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
@@ -894,11 +911,13 @@ int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
char cname[DNS_MAX_CNAME_LEN];
|
||||
ret = _dns_decode_CNAME(context, cname, DNS_MAX_CNAME_LEN);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode CNAME failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dns_add_CNAME(packet, type, domain, ttl, cname);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "add CNAME failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
@@ -906,11 +925,13 @@ int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
char ns[DNS_MAX_CNAME_LEN];
|
||||
ret = _dns_decode_CNAME(context, ns, DNS_MAX_CNAME_LEN);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode NS failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dns_add_NS(packet, type, domain, ttl, ns);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "add NS failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
@@ -918,11 +939,13 @@ int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
char name[DNS_MAX_CNAME_LEN];
|
||||
ret = _dns_decode_PTR(context, name, DNS_MAX_CNAME_LEN);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode PTR failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dns_add_PTR(packet, type, domain, ttl, name);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "add PTR failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
@@ -930,11 +953,13 @@ int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
unsigned char addr[DNS_RR_AAAA_LEN];
|
||||
ret = _dns_decode_AAAA(context, addr);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode AAAA failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dns_add_AAAA(packet, type, domain, ttl, addr);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "add AAAA failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
@@ -944,6 +969,8 @@ int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
}
|
||||
|
||||
if (context->ptr - start != rr_len) {
|
||||
tlog(TLOG_ERROR, "length mitchmatch , %s, %d:%d", domain,
|
||||
context->ptr - start, rr_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1014,6 +1041,7 @@ int _dns_decode_body(struct dns_context *context)
|
||||
for (i = 0; i < head->qdcount; i++) {
|
||||
ret = _dns_decode_qd(context);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode qd failed.");
|
||||
return -1;
|
||||
}
|
||||
head->qdcount--;
|
||||
@@ -1022,6 +1050,7 @@ int _dns_decode_body(struct dns_context *context)
|
||||
for (i = 0; i < head->ancount; i++) {
|
||||
ret = _dns_decode_an(context, DNS_RRS_AN);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode an failed.");
|
||||
return -1;
|
||||
}
|
||||
head->ancount--;
|
||||
@@ -1030,6 +1059,7 @@ int _dns_decode_body(struct dns_context *context)
|
||||
for (i = 0; i < head->nscount; i++) {
|
||||
ret = _dns_decode_an(context, DNS_RRS_NS);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode ns failed.");
|
||||
return -1;
|
||||
}
|
||||
head->nscount--;
|
||||
@@ -1038,6 +1068,7 @@ int _dns_decode_body(struct dns_context *context)
|
||||
for (i = 0; i < head->nrcount; i++) {
|
||||
ret = _dns_decode_an(context, DNS_RRS_NR);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode nr failed.");
|
||||
return -1;
|
||||
}
|
||||
head->nrcount--;
|
||||
@@ -1119,6 +1150,7 @@ int dns_decode(struct dns_packet *packet, int maxsize, unsigned char *data, int
|
||||
|
||||
ret = _dns_decode_body(&context);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_ERROR, "decode body failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
2
dns.h
2
dns.h
@@ -9,7 +9,7 @@
|
||||
#define DNS_RR_A_LEN 4
|
||||
#define DNS_RR_AAAA_LEN 16
|
||||
#define DNS_MAX_CNAME_LEN 256
|
||||
#define DNS_IN_PACKSIZE 512
|
||||
#define DNS_IN_PACKSIZE (512 * 2)
|
||||
#define DNS_PACKSIZE (512 * 4)
|
||||
|
||||
typedef enum dns_rr_type {
|
||||
|
||||
75
dns_client.c
75
dns_client.c
@@ -40,6 +40,11 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
|
||||
#define DNS_MAX_HOSTNAME 256
|
||||
|
||||
@@ -378,12 +383,13 @@ static int _dns_client_process_answer(char *domain, struct dns_packet *packet)
|
||||
struct dns_query_struct *query;
|
||||
int ttl;
|
||||
char name[DNS_MAX_CNAME_LEN];
|
||||
char alias[DNS_MAX_CNAME_LEN] = {0};
|
||||
char ip[DNS_MAX_CNAME_LEN] = {0};
|
||||
int rr_count;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
struct dns_rrs *rrs = NULL;
|
||||
int ret = -1;
|
||||
int A_num = 0;
|
||||
|
||||
query = _dns_client_get_request(packet->head.id, domain);
|
||||
if (query == NULL) {
|
||||
@@ -398,12 +404,14 @@ static int _dns_client_process_answer(char *domain, struct dns_packet *packet)
|
||||
unsigned char addr[4];
|
||||
dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
|
||||
printf("%s %d : %d.%d.%d.%d\n", name, ttl, addr[0], addr[1], addr[2], addr[3]);
|
||||
sprintf(name, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
|
||||
_dns_client_query_get(query);
|
||||
if (fast_ping_start(name, 1, 700, dns_client_ping_result, query) == NULL) {
|
||||
_dns_client_query_release(query);
|
||||
sprintf(ip, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
|
||||
|
||||
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) == 0 || strncmp(alias, name, DNS_MAX_CNAME_LEN) == 0) {
|
||||
_dns_client_query_get(query);
|
||||
if (fast_ping_start(ip, 1, 700, dns_client_ping_result, query) == NULL) {
|
||||
_dns_client_query_release(query);
|
||||
}
|
||||
}
|
||||
A_num++;
|
||||
} break;
|
||||
case DNS_T_AAAA: {
|
||||
unsigned char addr[16];
|
||||
@@ -424,6 +432,7 @@ static int _dns_client_process_answer(char *domain, struct dns_packet *packet)
|
||||
char cname[128];
|
||||
dns_get_CNAME(rrs, name, 128, &ttl, cname, 128);
|
||||
printf("%s %d : %s\n", name, ttl, cname);
|
||||
strncpy(alias, cname, DNS_MAX_CNAME_LEN);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
@@ -431,10 +440,12 @@ static int _dns_client_process_answer(char *domain, struct dns_packet *packet)
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&client.server_list_lock);
|
||||
query->dns_request_sent--;
|
||||
if (query->dns_request_sent <= 0) {
|
||||
if (query->dns_request_sent < 0) {
|
||||
_dns_client_query_release(query);
|
||||
}
|
||||
pthread_mutex_unlock(&client.server_list_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -451,9 +462,14 @@ static int _dns_client_recv(unsigned char *inpacket, int inpacket_len, struct so
|
||||
unsigned char packet_buff[DNS_PACKSIZE];
|
||||
struct dns_packet *packet = (struct dns_packet *)packet_buff;
|
||||
|
||||
packet->head.tc = 0;
|
||||
len = dns_decode(packet, DNS_PACKSIZE, inpacket, inpacket_len);
|
||||
if (len != 0) {
|
||||
printf("decode failed, packet len = %d\n", inpacket_len);
|
||||
tlog(TLOG_ERROR, "decode failed, packet len = %d, tc=%d, %d\n", inpacket_len,
|
||||
packet->head.tc, packet->head.id);
|
||||
int fd = open("dns.bin", O_CREAT | O_TRUNC | O_RDWR);
|
||||
write(fd, inpacket, inpacket_len);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -462,8 +478,9 @@ static int _dns_client_recv(unsigned char *inpacket, int inpacket_len, struct so
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("qdcount = %d, ancount = %d, nscount = %d, nrcount = %d, len = %d, id = %d\n", packet->head.qdcount, packet->head.ancount, packet->head.nscount,
|
||||
packet->head.nrcount, inpacket_len, packet->head.id);
|
||||
printf("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);
|
||||
|
||||
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)) {
|
||||
@@ -471,6 +488,12 @@ static int _dns_client_recv(unsigned char *inpacket, int inpacket_len, struct so
|
||||
printf("domain: %s qtype: %d qclass: %d\n", name, qtype, qclass);
|
||||
}
|
||||
|
||||
if (packet->head.rcode != DNS_RC_NOERROR) {
|
||||
tlog(TLOG_ERROR, "inquery failed, %s, rcode = %d\n", name, packet->head.rcode);
|
||||
//TODO set response to dns_server.c
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _dns_client_process_answer(name, packet);
|
||||
}
|
||||
|
||||
@@ -480,6 +503,7 @@ static int _dns_client_process(struct dns_query_struct *dns_query, unsigned long
|
||||
unsigned char inpacket[DNS_IN_PACKSIZE];
|
||||
struct sockaddr_storage from;
|
||||
socklen_t from_len = sizeof(from);
|
||||
char from_host[DNS_MAX_CNAME_LEN];
|
||||
|
||||
len = recvfrom(client.udp, inpacket, sizeof(inpacket), 0, (struct sockaddr *)&from, (socklen_t *)&from_len);
|
||||
if (len < 0) {
|
||||
@@ -487,6 +511,8 @@ static int _dns_client_process(struct dns_query_struct *dns_query, unsigned long
|
||||
return -1;
|
||||
}
|
||||
|
||||
tlog(TLOG_INFO, "recv from %s", gethost_by_addr(from_host, (struct sockaddr *)&from, from_len));
|
||||
|
||||
return _dns_client_recv(inpacket, len, &from, from_len);
|
||||
}
|
||||
|
||||
@@ -625,6 +651,8 @@ int dns_client_query(char *domain, dns_client_callback callback, void *user_ptr)
|
||||
goto errout_del_list;
|
||||
}
|
||||
|
||||
tlog(TLOG_ERROR, "send request %s, id %d\n", domain, query->sid);
|
||||
|
||||
key = hash_string(domain);
|
||||
key = jhash(&query->sid, sizeof(query->sid), key);
|
||||
pthread_mutex_lock(&client.domain_map_lock);
|
||||
@@ -719,6 +747,28 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void dns_debug(void)
|
||||
{
|
||||
char data[1024];
|
||||
int len;
|
||||
char buff[4096];
|
||||
|
||||
int fd = open("dns.bin", O_RDWR);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
len = read(fd, data, 1024);
|
||||
close(fd);
|
||||
if (len < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct dns_packet *packet = buff;
|
||||
if (dns_decode(packet, 4096, data, len) != 0) {
|
||||
printf("decode failed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
int dns_client_init()
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
@@ -726,7 +776,10 @@ int dns_client_init()
|
||||
int ret;
|
||||
int fd = 1;
|
||||
|
||||
if (client.epoll_fd > 0) {
|
||||
//dns_debug();
|
||||
|
||||
if (client.epoll_fd > 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ struct dns_request {
|
||||
atomic_t refcnt;
|
||||
struct hlist_node map;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
char alias[DNS_MAX_CNAME_LEN];
|
||||
unsigned short qtype;
|
||||
unsigned short id;
|
||||
unsigned short ss_family;
|
||||
@@ -169,6 +170,7 @@ static int _dns_add_rrs(struct dns_packet *packet, struct dns_request *request)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -226,7 +228,8 @@ static int dns_server_resolve_callback(char *domain, struct dns_result *result,
|
||||
}
|
||||
|
||||
memcpy(request->ipv4_addr, result->addr_ipv4, 4);
|
||||
//memcpy(request->ipv6_addr, result->addr_ipv6, 16);
|
||||
strncpy(request->alias, result->alias, DNS_MAX_CNAME_LEN);
|
||||
// memcpy(request->ipv6_addr, result->addr_ipv6, 16);
|
||||
request->qtype = DNS_T_A;
|
||||
|
||||
printf("----------------%s--%d.%d.%d.%d-\n", domain,
|
||||
|
||||
@@ -559,15 +559,18 @@ static struct fast_ping_packet *_fast_ping_icmp6_packet(struct ping_host_struct
|
||||
struct icmp6_hdr *icmp6 = &packet->icmp6;
|
||||
|
||||
if (icmp6->icmp6_type != ICMP6_ECHO_REPLY) {
|
||||
tlog(TLOG_ERROR, "icmp6 type faild, %d:%d", icmp6->icmp6_type, ICMP6_ECHO_REPLY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
icmp_len = data_len;
|
||||
if (icmp_len < 16) {
|
||||
tlog(TLOG_ERROR, "length is invalid, %d", icmp_len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (icmp6->icmp6_id != ping.ident) {
|
||||
tlog(TLOG_ERROR, "ident failed, %d:%d", icmp6->icmp6_id, ping.ident);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -583,6 +586,7 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *
|
||||
int icmp_len;
|
||||
|
||||
if (ip->ip_p != IPPROTO_ICMP) {
|
||||
tlog(TLOG_ERROR, "ip type faild, %d:%d", ip->ip_p, IPPROTO_ICMP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -592,14 +596,17 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *
|
||||
icmp_len = data_len - hlen;
|
||||
|
||||
if (icmp_len < 16) {
|
||||
tlog(TLOG_ERROR, "length is invalid, %d", icmp_len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (icmp->icmp_type != ICMP_ECHOREPLY) {
|
||||
tlog(TLOG_ERROR, "icmp type faild, %d:%d", icmp->icmp_type, ICMP_ECHOREPLY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (icmp->icmp_id != ping.ident) {
|
||||
tlog(TLOG_ERROR, "ident failed, %d:%d", icmp->icmp_id, ping.ident);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -621,6 +628,7 @@ struct fast_ping_packet *_fast_ping_recv_packet(struct ping_host_struct *ping_ho
|
||||
goto errout;
|
||||
}
|
||||
} else {
|
||||
tlog(TLOG_ERROR, "ping host type is invalid, %d", ping_host->type);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ int smartdns_init()
|
||||
goto errout;
|
||||
}
|
||||
|
||||
tlog_setlogscreen(1);
|
||||
|
||||
ret = fast_ping_init();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "start ping failed.\n");
|
||||
@@ -53,10 +55,11 @@ int smartdns_init()
|
||||
goto errout;
|
||||
}
|
||||
|
||||
dns_add_server("192.168.1.1", 53, DNS_SERVER_UDP);
|
||||
//dns_add_server("192.168.1.1", 53, DNS_SERVER_UDP);
|
||||
dns_add_server("114.114.114.114", 53, DNS_SERVER_UDP);
|
||||
dns_add_server("123.207.137.88", 53, DNS_SERVER_UDP);
|
||||
fast_ping_start("192.168.1.1", 10, 1000, 0, 0);
|
||||
dns_add_server("193.112.15.186", 53, DNS_SERVER_UDP);
|
||||
//dns_add_server("202.141.178.13", 5353, DNS_SERVER_UDP);
|
||||
return 0;
|
||||
errout:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user