Fix period run timer issue

This commit is contained in:
Nick Peng
2018-06-03 02:42:53 +08:00
parent 9f727cdec8
commit 2a5f821f64
6 changed files with 287 additions and 60 deletions

216
dns.c
View File

@@ -325,7 +325,7 @@ int dns_add_RAW(struct dns_packet *packet, dns_rr_type rrtype, dns_type_t rtype,
return dns_rr_add_end(packet, rrtype, rtype, len); return dns_rr_add_end(packet, rrtype, rtype, len);
} }
int dns_get_RAW(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, void *raw, int raw_len) int dns_get_RAW(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, void *raw, int *raw_len)
{ {
int qtype = 0; int qtype = 0;
int qclass = 0; int qclass = 0;
@@ -344,12 +344,13 @@ int dns_get_RAW(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, void *
return -1; return -1;
} }
if (qtype != rrs->type || rr_len > raw_len) { if (qtype != rrs->type || rr_len > *raw_len) {
return -1; return -1;
} }
memcpy(raw, data_context.ptr, rr_len); memcpy(raw, data_context.ptr, rr_len);
data_context.ptr += rr_len; data_context.ptr += rr_len;
*raw_len = rr_len;
return 0; return 0;
} }
@@ -362,7 +363,8 @@ int dns_add_CNAME(struct dns_packet *packet, dns_rr_type type, char *domain, int
int dns_get_CNAME(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size) int dns_get_CNAME(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size)
{ {
return dns_get_RAW(rrs, domain, maxsize, ttl, cname, cname_size); int len = cname_size;
return dns_get_RAW(rrs, domain, maxsize, ttl, cname, &len);
} }
int dns_add_A(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, unsigned char addr[DNS_RR_A_LEN]) int dns_add_A(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, unsigned char addr[DNS_RR_A_LEN])
@@ -372,7 +374,8 @@ int dns_add_A(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl
int dns_get_A(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[DNS_RR_A_LEN]) int dns_get_A(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[DNS_RR_A_LEN])
{ {
return dns_get_RAW(rrs, domain, maxsize, ttl, addr, DNS_RR_A_LEN); int len = DNS_RR_A_LEN;
return dns_get_RAW(rrs, domain, maxsize, ttl, addr, &len);
} }
int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname) int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname)
@@ -383,7 +386,8 @@ int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, char *domain, int t
int dns_get_PTR(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size) int dns_get_PTR(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size)
{ {
return dns_get_RAW(rrs, domain, maxsize, ttl, cname, cname_size); int len = cname_size;
return dns_get_RAW(rrs, domain, maxsize, ttl, cname, &len);
} }
int dns_add_NS(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname) int dns_add_NS(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname)
@@ -394,7 +398,8 @@ int dns_add_NS(struct dns_packet *packet, dns_rr_type type, char *domain, int tt
int dns_get_NS(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size) int dns_get_NS(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size)
{ {
return dns_get_RAW(rrs, domain, maxsize, ttl, cname, cname_size); int len = cname_size;
return dns_get_RAW(rrs, domain, maxsize, ttl, cname, &len);
} }
int dns_add_AAAA(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, unsigned char addr[DNS_RR_AAAA_LEN]) int dns_add_AAAA(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, unsigned char addr[DNS_RR_AAAA_LEN])
@@ -404,7 +409,56 @@ int dns_add_AAAA(struct dns_packet *packet, dns_rr_type type, char *domain, int
int dns_get_AAAA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[DNS_RR_AAAA_LEN]) int dns_get_AAAA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[DNS_RR_AAAA_LEN])
{ {
return dns_get_RAW(rrs, domain, maxsize, ttl, addr, DNS_RR_AAAA_LEN); int len = DNS_RR_AAAA_LEN;
return dns_get_RAW(rrs, domain, maxsize, ttl, addr, &len);
}
int dns_add_SOA(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, struct dns_soa *soa)
{
unsigned char data[sizeof(*soa)];
unsigned char *ptr = data;
int len = 0;
strncpy((char *)ptr, soa->mname, DNS_MAX_CNAME_LEN - 1);
ptr += strnlen(soa->mname, DNS_MAX_CNAME_LEN - 1) + 1;
strncpy((char *)ptr, soa->rname, DNS_MAX_CNAME_LEN - 1);
ptr += strnlen(soa->rname, DNS_MAX_CNAME_LEN - 1) + 1;
dns_write_int(&ptr, soa->serial);
dns_write_int(&ptr, soa->refresh);
dns_write_int(&ptr, soa->retry);
dns_write_int(&ptr, soa->expire);
dns_write_int(&ptr, soa->minimum);
len = ptr - data;
return dns_add_RAW(packet, type, DNS_T_SOA, domain, ttl, data, len);
}
int dns_get_SOA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, struct dns_soa *soa)
{
unsigned char data[sizeof(*soa)];
unsigned char *ptr = data;
int len = sizeof(data);
if (dns_get_RAW(rrs, domain, maxsize, ttl, data, &len) != 0) {
return -1;
}
strncpy(soa->mname, (char *)ptr, DNS_MAX_CNAME_LEN - 1);
ptr += strnlen(soa->mname, DNS_MAX_CNAME_LEN - 1) + 1;
if (ptr - data >= len) {
return -1;
}
strncpy(soa->rname, (char *)ptr, DNS_MAX_CNAME_LEN - 1);
ptr += strnlen(soa->rname, DNS_MAX_CNAME_LEN - 1) + 1;
if (ptr - data + 20 > len) {
return -1;
}
soa->serial = dns_read_int(&ptr);
soa->refresh = dns_read_int(&ptr);
soa->retry = dns_read_int(&ptr);
soa->expire = dns_read_int(&ptr);
soa->minimum = dns_read_int(&ptr);
return 0;
} }
/* /*
@@ -538,8 +592,7 @@ static int _dns_decode_domain(struct dns_context *context, char *output, int siz
} }
ptr = context->data + len; ptr = context->data + len;
if (context->maxsize - (ptr - context->data) < 0) { if (context->maxsize - (ptr - context->data) < 0) {
tlog(TLOG_ERROR, "length is not enouth %d:%d, %p, %p", context->maxsize, ptr-context->data, tlog(TLOG_ERROR, "length is not enouth %d:%d, %p, %p", context->maxsize, ptr - context->data, context->ptr, context->data);
context->ptr, context->data);
return -1; return -1;
} }
is_compressed = 1; is_compressed = 1;
@@ -547,8 +600,7 @@ static int _dns_decode_domain(struct dns_context *context, char *output, int siz
} }
if (context->maxsize - (ptr - context->data) < 0) { if (context->maxsize - (ptr - context->data) < 0) {
tlog(TLOG_ERROR, "length is not enouth %d:%d, %p, %p", context->maxsize, ptr-context->data, tlog(TLOG_ERROR, "length is not enouth %d:%d, %p, %p", context->maxsize, ptr - context->data, context->ptr, context->data);
context->ptr, context->data);
return -1; return -1;
} }
@@ -556,8 +608,7 @@ static int _dns_decode_domain(struct dns_context *context, char *output, int siz
if (output_len < size - 1) { if (output_len < size - 1) {
copy_len = (len < size - output_len) ? len : size - 1 - output_len; copy_len = (len < size - output_len) ? len : size - 1 - output_len;
if (context->maxsize - (ptr - context->data) < 0) { if (context->maxsize - (ptr - context->data) < 0) {
tlog(TLOG_ERROR, "length is not enouth %d:%d, %p, %p", context->maxsize, ptr-context->data, tlog(TLOG_ERROR, "length is not enouth %d:%d, %p, %p", context->maxsize, ptr - context->data, context->ptr, context->data);
context->ptr, context->data);
return -1; return -1;
} }
memcpy(output, ptr, copy_len); memcpy(output, ptr, copy_len);
@@ -713,7 +764,7 @@ static int _dns_encode_raw(struct dns_context *context, struct dns_rrs *rrs)
context->ptr += rr_len; context->ptr += rr_len;
data_context.ptr += rr_len; data_context.ptr += rr_len;
return 0; return 0;
} }
static int _dns_decode_raw(struct dns_context *context, unsigned char *raw, int len) static int _dns_decode_raw(struct dns_context *context, unsigned char *raw, int len)
@@ -727,7 +778,6 @@ static int _dns_decode_raw(struct dns_context *context, unsigned char *raw, int
return 0; return 0;
} }
int _dns_decode_CNAME(struct dns_context *context, char *cname, int cname_size) int _dns_decode_CNAME(struct dns_context *context, char *cname, int cname_size)
{ {
int ret = 0; int ret = 0;
@@ -774,7 +824,97 @@ int _dns_encode_CNAME(struct dns_context *context, struct dns_rrs *rrs)
return -1; return -1;
} }
data_context.ptr += strnlen((char*)(data_context.ptr), DNS_MAX_CNAME_LEN) + 1; data_context.ptr += strnlen((char *)(data_context.ptr), DNS_MAX_CNAME_LEN) + 1;
return 0;
}
int _dns_decode_SOA(struct dns_context *context, struct dns_soa *soa)
{
int ret = 0;
ret = _dns_decode_domain(context, soa->mname, DNS_MAX_CNAME_LEN - 1);
if (ret < 0) {
return -1;
}
ret = _dns_decode_domain(context, soa->rname, DNS_MAX_CNAME_LEN - 1);
if (ret < 0) {
return -1;
}
if (_dns_left_len(context) < 20) {
return -1;
}
soa->serial = dns_read_int(&context->ptr);
soa->refresh = dns_read_int(&context->ptr);
soa->retry = dns_read_int(&context->ptr);
soa->expire = dns_read_int(&context->ptr);
soa->minimum = dns_read_int(&context->ptr);
return 0;
}
int _dns_encode_SOA(struct dns_context *context, struct dns_rrs *rrs)
{
int ret;
int qtype = 0;
int qclass = 0;
int ttl = 0;
char domain[DNS_MAX_CNAME_LEN];
int rr_len;
struct dns_data_context data_context;
data_context.data = rrs->data;
data_context.ptr = rrs->data;
data_context.maxsize = rrs->len;
ret = _dns_get_rr_head(&data_context, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
if (ret < 0) {
return -1;
}
/* when code two domain, len must plus 2, because of length at the begining */
rr_len += 2;
if (rr_len > rrs->len) {
return -1;
}
ret = _dns_encode_rr_head(context, domain, qtype, qclass, ttl, rr_len);
if (ret < 0) {
return -1;
}
/* mname */
ret = _dns_encode_domain(context, (char *)data_context.ptr);
if (ret < 0) {
return -1;
}
data_context.ptr += strnlen((char *)(data_context.ptr), DNS_MAX_CNAME_LEN) + 1;
/* rname */
ret = _dns_encode_domain(context, (char *)data_context.ptr);
if (ret < 0) {
return -1;
}
data_context.ptr += strnlen((char *)(data_context.ptr), DNS_MAX_CNAME_LEN) + 1;
if (_dns_left_len(context) < 20) {
return -1;
}
dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
data_context.ptr += 4;
dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
data_context.ptr += 4;
dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
data_context.ptr += 4;
dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
data_context.ptr += 4;
dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
data_context.ptr += 4;
return 0; return 0;
} }
@@ -847,6 +987,20 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
return -1; return -1;
} }
} break; } break;
case DNS_T_SOA: {
struct dns_soa soa;
ret = _dns_decode_SOA(context, &soa);
if (ret < 0) {
tlog(TLOG_ERROR, "decode CNAME failed, %s", domain);
return -1;
}
ret = dns_add_SOA(packet, type, domain, ttl, &soa);
if (ret < 0) {
tlog(TLOG_ERROR, "add CNAME failed, %s", domain);
return -1;
}
} break;
case DNS_T_NS: { case DNS_T_NS: {
char ns[DNS_MAX_CNAME_LEN]; char ns[DNS_MAX_CNAME_LEN];
ret = _dns_decode_CNAME(context, ns, DNS_MAX_CNAME_LEN); ret = _dns_decode_CNAME(context, ns, DNS_MAX_CNAME_LEN);
@@ -891,12 +1045,12 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
} break; } break;
default: default:
context->ptr += rr_len; context->ptr += rr_len;
tlog(TLOG_DEBUG, "type = %d", qtype);
break; break;
} }
if (context->ptr - start != rr_len) { if (context->ptr - start != rr_len) {
tlog(TLOG_ERROR, "length mitchmatch , %s, %d:%d", domain, tlog(TLOG_ERROR, "length mitchmatch , %s, %d:%d", domain, context->ptr - start, rr_len);
context->ptr - start, rr_len);
return -1; return -1;
} }
@@ -932,20 +1086,22 @@ static int _dns_encode_an(struct dns_context *context, struct dns_rrs *rrs)
{ {
int ret; int ret;
switch (rrs->type) { switch (rrs->type) {
case DNS_T_A: { case DNS_T_A:
case DNS_T_AAAA: {
ret = _dns_encode_raw(context, rrs); ret = _dns_encode_raw(context, rrs);
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
} break; } break;
case DNS_T_CNAME:
case DNS_T_PTR: case DNS_T_PTR:
ret = _dns_encode_CNAME(context, rrs); ret = _dns_encode_CNAME(context, rrs);
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
break; break;
case DNS_T_AAAA: case DNS_T_SOA:
ret = _dns_encode_raw(context, rrs); ret = _dns_encode_SOA(context, rrs);
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
@@ -1030,6 +1186,24 @@ static int _dns_encode_body(struct dns_context *context)
} }
} }
rrs = dns_get_rrs_start(packet, DNS_RRS_NS, &count);
head->nscount = count;
for (i = 0; i < count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
len = _dns_encode_an(context, rrs);
if (len < 0) {
return -1;
}
}
rrs = dns_get_rrs_start(packet, DNS_RRS_NR, &count);
head->nrcount = count;
for (i = 0; i < count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
len = _dns_encode_an(context, rrs);
if (len < 0) {
return -1;
}
}
return 0; return 0;
} }

16
dns.h
View File

@@ -15,7 +15,7 @@
typedef enum dns_qr { typedef enum dns_qr {
DNS_QR_QUERY = 0, DNS_QR_QUERY = 0,
DNS_QR_ANSWER = 1, DNS_QR_ANSWER = 1,
}dns_qr; } dns_qr;
typedef enum dns_rr_type { typedef enum dns_rr_type {
DNS_RRS_QD = 0, DNS_RRS_QD = 0,
@@ -114,6 +114,16 @@ struct dns_context {
unsigned char *ptr; unsigned char *ptr;
}; };
struct dns_soa {
char mname[DNS_MAX_CNAME_LEN];
char rname[DNS_MAX_CNAME_LEN];
unsigned int serial;
unsigned int refresh;
unsigned int retry;
unsigned int expire;
unsigned int minimum;
} __attribute__((packed));;
struct dns_rrs *dns_get_rrs_next(struct dns_packet *packet, struct dns_rrs *rrs); struct dns_rrs *dns_get_rrs_next(struct dns_packet *packet, struct dns_rrs *rrs);
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);
@@ -144,8 +154,10 @@ int dns_add_AAAA(struct dns_packet *packet, dns_rr_type type, char *domain, int
int dns_get_AAAA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[DNS_RR_AAAA_LEN]); int dns_get_AAAA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[DNS_RR_AAAA_LEN]);
int dns_add_SOA(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, struct dns_soa *soa);
/* int dns_get_SOA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, struct dns_soa *soa);
/*
* Packet operation * Packet operation
*/ */
int dns_decode(struct dns_packet *packet, int maxsize, unsigned char *data, int size); int dns_decode(struct dns_packet *packet, int maxsize, unsigned char *data, int size);

View File

@@ -206,7 +206,7 @@ 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) {
printf("stop ping failed.\n"); tlog(TLOG_ERROR, "stop ping failed.\n");
} }
free(server_info); free(server_info);
return 0; return 0;
@@ -367,7 +367,7 @@ static int _dns_client_recv(unsigned char *inpacket, int inpacket_len, struct so
} }
if (packet->head.qr != DNS_OP_IQUERY) { if (packet->head.qr != DNS_OP_IQUERY) {
printf("message type error.\n"); tlog(TLOG_ERROR, "message type error.\n");
return -1; return -1;
} }
@@ -442,7 +442,7 @@ static void *_dns_client_work(void *arg)
expect_time = now + sleep; expect_time = now + sleep;
while (client.run) { while (client.run) {
now = get_tick_count(); now = get_tick_count();
if (now - expect_time >= 0) { if (now >= expect_time) {
_dns_client_period_run(); _dns_client_period_run();
sleep_time = sleep - (now - expect_time); sleep_time = sleep - (now - expect_time);
if (sleep_time < 0) { if (sleep_time < 0) {
@@ -476,8 +476,7 @@ static int _dns_client_send_udp(struct dns_server_info *server_info, void *packe
int send_len = 0; int send_len = 0;
send_len = sendto(client.udp, packet, len, 0, (struct sockaddr *)&server_info->addr, server_info->addr_len); send_len = sendto(client.udp, packet, len, 0, (struct sockaddr *)&server_info->addr, server_info->addr_len);
if (send_len != len) { if (send_len != len) {
printf("send to server failed."); tlog(TLOG_ERROR, "send to server failed.");
abort();
return -1; return -1;
} }
@@ -559,6 +558,7 @@ int dns_client_query(char *domain, int qtype, dns_client_callback callback, void
query->user_ptr = user_ptr; query->user_ptr = user_ptr;
query->callback = callback; query->callback = callback;
query->qtype = qtype; query->qtype = qtype;
query->send_tick = 0;
query->sid = atomic_inc_return(&dns_client_sid); query->sid = atomic_inc_return(&dns_client_sid);
_dns_client_query_get(query); _dns_client_query_get(query);
@@ -569,7 +569,6 @@ int dns_client_query(char *domain, int qtype, dns_client_callback callback, void
hash_add(client.domain_map, &query->domain_node, key); hash_add(client.domain_map, &query->domain_node, key);
pthread_mutex_unlock(&client.domain_map_lock); pthread_mutex_unlock(&client.domain_map_lock);
ret = _dns_client_send_query(query, domain); ret = _dns_client_send_query(query, domain);
if (ret != 0) { if (ret != 0) {
goto errout_del_list; goto errout_del_list;
@@ -586,6 +585,7 @@ errout_del_list:
pthread_mutex_unlock(&client.domain_map_lock); pthread_mutex_unlock(&client.domain_map_lock);
errout: errout:
if (query) { if (query) {
tlog(TLOG_ERROR, "release %p", query);
free(query); free(query);
} }
return -1; return -1;
@@ -682,8 +682,18 @@ void dns_debug(void)
struct dns_packet *packet = (struct dns_packet *)buff; struct dns_packet *packet = (struct dns_packet *)buff;
if (dns_decode(packet, 4096, data, len) != 0) { if (dns_decode(packet, 4096, data, len) != 0) {
printf("decode failed.\n"); tlog(TLOG_ERROR, "decode failed.\n");
} }
memset(data, 0, sizeof(data));
len = dns_encode(data, 1024, packet);
if (len < 0) {
tlog(TLOG_ERROR, "encode failed.\n");
}
fd = open("dns-cmp.bin", O_CREAT | O_TRUNC | O_RDWR);
write(fd, data, len);
close(fd);
} }
int dns_client_init() int dns_client_init()
@@ -693,8 +703,6 @@ int dns_client_init()
int ret; int ret;
int fd = 1; int fd = 1;
// dns_debug();
if (client.epoll_fd > 0) { if (client.epoll_fd > 0) {
return -1; return -1;
} }

View File

@@ -62,7 +62,6 @@ struct dns_request {
atomic_t refcnt; atomic_t refcnt;
struct hlist_node map; struct hlist_node map;
char domain[DNS_MAX_CNAME_LEN]; char domain[DNS_MAX_CNAME_LEN];
char alias[DNS_MAX_CNAME_LEN];
struct dns_head head; struct dns_head head;
unsigned long send_tick; unsigned long send_tick;
unsigned short qtype; unsigned short qtype;
@@ -76,12 +75,22 @@ struct dns_request {
struct sockaddr addr; struct sockaddr addr;
}; };
int has_ptr;
int has_cname;
char alias[DNS_MAX_CNAME_LEN];
int has_ipv4;
int ttl_v4; int ttl_v4;
unsigned char ipv4_addr[DNS_RR_A_LEN]; unsigned char ipv4_addr[DNS_RR_A_LEN];
int has_ipv6;
int ttl_v6; int ttl_v6;
unsigned char ipv6_addr[DNS_RR_AAAA_LEN]; unsigned char ipv6_addr[DNS_RR_AAAA_LEN];
struct dns_soa soa;
int has_soa;
atomic_t notified; atomic_t notified;
int passthrough; int passthrough;
@@ -151,13 +160,9 @@ static int _dns_recv_addr(struct dns_request *request, struct sockaddr_storage *
static int _dns_add_rrs(struct dns_packet *packet, struct dns_request *request) static int _dns_add_rrs(struct dns_packet *packet, struct dns_request *request)
{ {
int qtype; int ret = 0;
int ret = -1; char *domain = request->domain;
if (request->has_ptr) {
qtype = request->qtype;
switch (qtype) {
case DNS_T_PTR: {
char hostname[DNS_MAX_CNAME_LEN]; char hostname[DNS_MAX_CNAME_LEN];
if (getdomainname(hostname, DNS_MAX_CNAME_LEN) != 0) { if (getdomainname(hostname, DNS_MAX_CNAME_LEN) != 0) {
if (gethostname(hostname, DNS_MAX_CNAME_LEN) != 0) { if (gethostname(hostname, DNS_MAX_CNAME_LEN) != 0) {
@@ -172,15 +177,26 @@ static int _dns_add_rrs(struct dns_packet *packet, struct dns_request *request)
} }
ret = dns_add_PTR(packet, DNS_RRS_AN, request->domain, 30, hostname); ret = dns_add_PTR(packet, DNS_RRS_AN, request->domain, 30, hostname);
} break; }
case DNS_T_A:
ret = dns_add_A(packet, DNS_RRS_AN, request->domain, 30, request->ipv4_addr); if (request->has_cname) {
break; ret |= dns_add_CNAME(packet, DNS_RRS_AN, request->domain, 30, request->alias);
case DNS_T_AAAA: domain = request->alias;
ret = dns_add_AAAA(packet, DNS_RRS_AN, request->domain, 30, request->ipv6_addr); }
break;
default: if (request->has_ipv4 && request->qtype == DNS_T_A) {
break; ret |= dns_add_A(packet, DNS_RRS_AN, domain, 30, request->ipv4_addr);
}
if (request->has_ipv6 && request->qtype == DNS_T_AAAA) {
if (request->has_ipv4) {
ret |= dns_add_A(packet, DNS_RRS_AN, domain, 30, request->ipv4_addr);
}
ret |= dns_add_AAAA(packet, DNS_RRS_AN, domain, 30, request->ipv6_addr);
}
if (request->has_soa) {
ret |= dns_add_SOA(packet, DNS_RRS_NS, domain, 0, &request->soa);
} }
return ret; return ret;
@@ -313,6 +329,7 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
addr_in = (struct sockaddr_in *)addr; addr_in = (struct sockaddr_in *)addr;
if (request->ttl_v4 > rtt) { if (request->ttl_v4 > rtt) {
request->ttl_v4 = rtt; request->ttl_v4 = rtt;
request->has_ipv4 = 1;
memcpy(request->ipv4_addr, &addr_in->sin_addr.s_addr, 4); memcpy(request->ipv4_addr, &addr_in->sin_addr.s_addr, 4);
} }
} break; } break;
@@ -322,11 +339,13 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) { if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
if (request->ttl_v4 > rtt) { if (request->ttl_v4 > rtt) {
request->ttl_v4 = rtt; request->ttl_v4 = rtt;
request->has_ipv4 = 1;
memcpy(request->ipv4_addr, addr_in6->sin6_addr.s6_addr + 12, 4); memcpy(request->ipv4_addr, addr_in6->sin6_addr.s6_addr + 12, 4);
} }
} else { } else {
if (request->ttl_v6 > rtt) { if (request->ttl_v6 > rtt) {
request->ttl_v6 = rtt; request->ttl_v6 = rtt;
request->has_ipv6 = 1;
memcpy(request->ipv6_addr, addr_in6->sin6_addr.s6_addr, 16); memcpy(request->ipv6_addr, addr_in6->sin6_addr.s6_addr, 16);
} }
} }
@@ -355,7 +374,6 @@ static int _dns_client_process_answer(struct dns_request *request, char *domain,
{ {
int ttl; int ttl;
char name[DNS_MAX_CNAME_LEN] = {0}; char name[DNS_MAX_CNAME_LEN] = {0};
char alias[DNS_MAX_CNAME_LEN] = {0};
char ip[DNS_MAX_CNAME_LEN] = {0}; char ip[DNS_MAX_CNAME_LEN] = {0};
int rr_count; int rr_count;
int i = 0; int i = 0;
@@ -382,7 +400,7 @@ static int _dns_client_process_answer(struct dns_request *request, char *domain,
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(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); _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);
@@ -408,9 +426,17 @@ static int _dns_client_process_answer(struct dns_request *request, char *domain,
char cname[128]; char cname[128];
dns_get_CNAME(rrs, name, 128, &ttl, cname, 128); dns_get_CNAME(rrs, name, 128, &ttl, cname, 128);
tlog(TLOG_DEBUG, "%s %d : %s\n", name, ttl, cname); tlog(TLOG_DEBUG, "%s %d : %s\n", name, ttl, cname);
strncpy(alias, cname, DNS_MAX_CNAME_LEN); strncpy(request->alias, cname, DNS_MAX_CNAME_LEN);
request->has_cname = 1;
} break; } break;
case DNS_T_SOA: {
request->has_soa = 1;
dns_get_SOA(rrs, name, 128, &ttl, &request->soa);
tlog(TLOG_INFO, "SOA: mname: %s, rname: %s, serial: %d, refresh: %d, retry: %d, expire: %d, minimum: %d", request->soa.mname,
request->soa.rname, request->soa.serial, request->soa.refresh, request->soa.retry, request->soa.expire, request->soa.minimum);
}
default: default:
tlog(TLOG_INFO, "%s, qtype: %d", name, rrs->type);
break; break;
} }
} }
@@ -477,15 +503,21 @@ static int _dns_server_process_ptr(struct dns_request *request, struct dns_packe
snprintf(reverse_addr, sizeof(reverse_addr), "%d.%d.%d.%d.in-addr.arpa", addr[3], addr[2], addr[1], addr[0]); snprintf(reverse_addr, sizeof(reverse_addr), "%d.%d.%d.%d.in-addr.arpa", addr[3], addr[2], addr[1], addr[0]);
} else { } else {
addr = addr_in6->sin6_addr.s6_addr; addr = addr_in6->sin6_addr.s6_addr;
snprintf(reverse_addr, sizeof(reverse_addr), "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x.in-addr.arpa", addr[15], snprintf(reverse_addr, sizeof(reverse_addr),
addr[14], addr[13], addr[12], addr[11], addr[10], addr[9], addr[8], addr[7], addr[6], addr[5], addr[4], addr[3], addr[2], addr[1], "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa", addr[15] & 0xF,
addr[0]); (addr[15] >> 4) & 0xF, addr[14] & 0xF, (addr[14] >> 4) & 0xF, addr[13] & 0xF, (addr[13] >> 4) & 0xF, addr[12] & 0xF,
(addr[12] >> 4) & 0xF, addr[11] & 0xF, (addr[11] >> 4) & 0xF, addr[10] & 0xF, (addr[10] >> 4) & 0xF, addr[9] & 0xF,
(addr[9] >> 4) & 0xF, addr[8] & 0xF, (addr[8] >> 4) & 0xF, addr[7] & 0xF, (addr[7] >> 4) & 0xF, addr[6] & 0xF, (addr[6] >> 4) & 0xF,
addr[5] & 0xF, (addr[5] >> 4) & 0xF, addr[4] & 0xF, (addr[4] >> 4) & 0xF, addr[3] & 0xF, (addr[3] >> 4) & 0xF, addr[2] & 0xF,
(addr[2] >> 4) & 0xF, addr[1] & 0xF, (addr[1] >> 4) & 0xF, addr[0] & 0xF, (addr[0] >> 4) & 0xF);
} }
} break; } break;
default: default:
continue;
break; break;
} }
if (strncmp(request->domain, reverse_addr, sizeof(reverse_addr)) == 0) {
if (strstr(request->domain, reverse_addr) != NULL) {
found = 1; found = 1;
break; break;
} }
@@ -496,6 +528,7 @@ static int _dns_server_process_ptr(struct dns_request *request, struct dns_packe
} }
request->rcode = DNS_RC_NOERROR; request->rcode = DNS_RC_NOERROR;
request->has_ptr = 1;
_dns_reply(request); _dns_reply(request);
freeifaddrs(ifaddr); freeifaddrs(ifaddr);
@@ -626,7 +659,7 @@ int dns_server_run(void)
expect_time = now + sleep; expect_time = now + sleep;
while (server.run) { while (server.run) {
now = get_tick_count(); now = get_tick_count();
if (now - expect_time >= 0) { if (now >= expect_time) {
_dns_server_period_run(); _dns_server_period_run();
sleep_time = sleep - (now - expect_time); sleep_time = sleep - (now - expect_time);
if (sleep_time < 0) { if (sleep_time < 0) {

View File

@@ -520,7 +520,7 @@ struct ping_host_struct *fast_ping_start(const char *host, int count, int timeou
memcpy(&ping_host->addr, gai->ai_addr, gai->ai_addrlen); memcpy(&ping_host->addr, gai->ai_addr, gai->ai_addrlen);
if (_fast_ping_sendping(ping_host) != 0) { if (_fast_ping_sendping(ping_host) != 0) {
goto errout1;
} }
hostkey = hash_string(ping_host->host); hostkey = hash_string(ping_host->host);
@@ -539,7 +539,7 @@ errout:
if (fd > 0) { if (fd > 0) {
close(fd); close(fd);
} }
errout1:
if (gai) { if (gai) {
freeaddrinfo(gai); freeaddrinfo(gai);
} }

View File

@@ -53,7 +53,7 @@ int smartdns_init()
} }
tlog_setlogscreen(1); tlog_setlogscreen(1);
//tlog_setlevel(TLOG_DEBUG); //tlog_setlevel(TLOG_ERROR);
ret = fast_ping_init(); ret = fast_ping_init();
if (ret != 0) { if (ret != 0) {