Fix period run timer issue
This commit is contained in:
216
dns.c
216
dns.c
@@ -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
16
dns.h
@@ -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);
|
||||||
|
|||||||
26
dns_client.c
26
dns_client.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
83
dns_server.c
83
dns_server.c
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user