code lint and optimize code style

This commit is contained in:
Nick Peng
2019-02-22 23:14:42 +08:00
parent c0c6fde39d
commit 7828f0ec27
28 changed files with 705 additions and 513 deletions

250
src/dns.c
View File

@@ -25,6 +25,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#define QR_MASK 0x8000
#define OPCODE_MASK 0x7800
@@ -35,10 +36,13 @@
#define RCODE_MASK 0x000F
#define DNS_RR_END (0XFFFF)
#define UNUSED(expr) do { (void)(expr); } while (0)
#define UNUSED(expr) \
do { \
(void)(expr); \
} while (0)
/* read short and move pointer */
short dns_read_short(unsigned char **buffer)
static short _dns_read_short(unsigned char **buffer)
{
unsigned short value;
@@ -48,14 +52,14 @@ short dns_read_short(unsigned char **buffer)
}
/* write char and move pointer */
void dns_write_char(unsigned char **buffer, unsigned char value)
static __attribute__((unused)) void _dns_write_char(unsigned char **buffer, unsigned char value)
{
**buffer = value;
*buffer += 1;
}
/* read char and move pointer */
unsigned char dns_read_char(unsigned char **buffer)
static unsigned char _dns_read_char(unsigned char **buffer)
{
unsigned char value = **buffer;
*buffer += 1;
@@ -63,7 +67,7 @@ unsigned char dns_read_char(unsigned char **buffer)
}
/* write short and move pointer */
void dns_write_short(unsigned char **buffer, unsigned short value)
static void _dns_write_short(unsigned char **buffer, unsigned short value)
{
value = htons(value);
*((unsigned short *)(*buffer)) = value;
@@ -71,7 +75,7 @@ void dns_write_short(unsigned char **buffer, unsigned short value)
}
/* write int and move pointer */
void dns_write_int(unsigned char **buffer, unsigned int value)
static void _dns_write_int(unsigned char **buffer, unsigned int value)
{
value = htonl(value);
*((unsigned int *)(*buffer)) = value;
@@ -79,7 +83,7 @@ void dns_write_int(unsigned char **buffer, unsigned int value)
}
/* read int and move pointer */
unsigned int dns_read_int(unsigned char **buffer)
static unsigned int _dns_read_int(unsigned char **buffer)
{
unsigned int value;
@@ -138,7 +142,7 @@ struct dns_rrs *dns_get_rrs_next(struct dns_packet *packet, struct dns_rrs *rrs)
}
/* iterator add rrs begin */
unsigned char *_dns_add_rrs_start(struct dns_packet *packet, int *maxlen)
static unsigned char *_dns_add_rrs_start(struct dns_packet *packet, int *maxlen)
{
struct dns_rrs *rrs;
unsigned char *end = packet->data + packet->len;
@@ -153,7 +157,7 @@ unsigned char *_dns_add_rrs_start(struct dns_packet *packet, int *maxlen)
}
/* iterator add rrs end */
int dns_rr_add_end(struct dns_packet *packet, int type, dns_type_t rtype, int len)
static int _dns_rr_add_end(struct dns_packet *packet, int type, dns_type_t rtype, int len)
{
struct dns_rrs *rrs;
struct dns_rrs *rrs_next;
@@ -221,7 +225,7 @@ static inline int _dns_data_left_len(struct dns_data_context *data_context)
return data_context->maxsize - (data_context->ptr - data_context->data);
}
int _dns_add_qr_head(struct dns_data_context *data_context, char *domain, int qtype, int qclass)
static int _dns_add_qr_head(struct dns_data_context *data_context, char *domain, int qtype, int qclass)
{
/* question head */
/* |domain |
@@ -253,7 +257,7 @@ int _dns_add_qr_head(struct dns_data_context *data_context, char *domain, int qt
return 0;
}
int _dns_get_qr_head(struct dns_data_context *data_context, char *domain, int maxsize, int *qtype, int *qclass)
static int _dns_get_qr_head(struct dns_data_context *data_context, char *domain, int maxsize, int *qtype, int *qclass)
{
int i;
/* question head */
@@ -291,7 +295,7 @@ int _dns_get_qr_head(struct dns_data_context *data_context, char *domain, int ma
return 0;
}
int _dns_add_rr_head(struct dns_data_context *data_context, char *domain, int qtype, int qclass, int ttl, int rr_len)
static int _dns_add_rr_head(struct dns_data_context *data_context, char *domain, int qtype, int qclass, int ttl, int rr_len)
{
int len = 0;
@@ -319,7 +323,7 @@ int _dns_add_rr_head(struct dns_data_context *data_context, char *domain, int qt
return 0;
}
int _dns_get_rr_head(struct dns_data_context *data_context, char *domain, int maxsize, int *qtype, int *qclass, int *ttl, int *rr_len)
static int _dns_get_rr_head(struct dns_data_context *data_context, char *domain, int maxsize, int *qtype, int *qclass, int *ttl, int *rr_len)
{
int len = 0;
@@ -344,7 +348,7 @@ int _dns_get_rr_head(struct dns_data_context *data_context, char *domain, int ma
return len;
}
int dns_add_RAW(struct dns_packet *packet, dns_rr_type rrtype, dns_type_t rtype, char *domain, int ttl, void *raw, int raw_len)
static int _dns_add_RAW(struct dns_packet *packet, dns_rr_type rrtype, dns_type_t rtype, char *domain, int ttl, void *raw, int raw_len)
{
int maxlen = 0;
int len = 0;
@@ -380,10 +384,10 @@ int dns_add_RAW(struct dns_packet *packet, dns_rr_type rrtype, dns_type_t rtype,
data_context.ptr += raw_len;
len = data_context.ptr - data_context.data;
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)
static int _dns_get_RAW(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, void *raw, int *raw_len)
{
int qtype = 0;
int qclass = 0;
@@ -421,10 +425,10 @@ int dns_get_RAW(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, void *
return 0;
}
int dns_add_OPT(struct dns_packet *packet, dns_rr_type type, unsigned short opt_code, unsigned short opt_len, struct dns_opt *opt)
static int __attribute__((unused)) _dns_add_OPT(struct dns_packet *packet, dns_rr_type type, unsigned short opt_code, unsigned short opt_len, struct dns_opt *opt)
{
// TODO
int maxlen = 0;
int len = 0;
struct dns_data_context data_context;
@@ -432,15 +436,15 @@ int dns_add_OPT(struct dns_packet *packet, dns_rr_type type, unsigned short opt_
int ttl = 0;
/*
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0: | OPTION-CODE |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
2: | OPTION-LENGTH |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
4: | |
/ OPTION-DATA /
/ /
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
/ OPTION-DATA /
/ /
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
*/
unsigned char *data = _dns_add_rrs_start(packet, &maxlen);
if (data == NULL) {
@@ -468,10 +472,10 @@ int dns_add_OPT(struct dns_packet *packet, dns_rr_type type, unsigned short opt_
data_context.ptr += total_len;
len = data_context.ptr - data_context.data;
return dns_rr_add_end(packet, type, DNS_T_OPT, len);
return _dns_rr_add_end(packet, type, DNS_T_OPT, len);
}
int dns_get_OPT(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt *opt, int *opt_maxlen)
static int __attribute__((unused)) _dns_get_OPT(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt *opt, int *opt_maxlen)
{
// TODO
@@ -509,63 +513,62 @@ int dns_get_OPT(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *o
return 0;
}
int dns_add_CNAME(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname)
{
int rr_len = strnlen(cname, DNS_MAX_CNAME_LEN) + 1;
return dns_add_RAW(packet, type, DNS_T_CNAME, domain, ttl, cname, rr_len);
return _dns_add_RAW(packet, type, DNS_T_CNAME, domain, ttl, cname, rr_len);
}
int dns_get_CNAME(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size)
{
int len = cname_size;
return dns_get_RAW(rrs, domain, maxsize, ttl, cname, &len);
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])
{
return dns_add_RAW(packet, type, DNS_T_A, domain, ttl, addr, DNS_RR_A_LEN);
return _dns_add_RAW(packet, type, DNS_T_A, domain, ttl, 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])
{
int len = DNS_RR_A_LEN;
return dns_get_RAW(rrs, domain, maxsize, ttl, addr, &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 rr_len = strnlen(cname, DNS_MAX_CNAME_LEN) + 1;
return dns_add_RAW(packet, type, DNS_T_PTR, domain, ttl, cname, rr_len);
return _dns_add_RAW(packet, type, DNS_T_PTR, domain, ttl, cname, rr_len);
}
int dns_get_PTR(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size)
{
int len = cname_size;
return dns_get_RAW(rrs, domain, maxsize, ttl, cname, &len);
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 rr_len = strnlen(cname, DNS_MAX_CNAME_LEN) + 1;
return dns_add_RAW(packet, type, DNS_T_NS, domain, ttl, cname, rr_len);
return _dns_add_RAW(packet, type, DNS_T_NS, domain, ttl, cname, rr_len);
}
int dns_get_NS(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size)
{
int len = cname_size;
return dns_get_RAW(rrs, domain, maxsize, ttl, cname, &len);
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])
{
return dns_add_RAW(packet, type, DNS_T_AAAA, domain, ttl, addr, DNS_RR_AAAA_LEN);
return _dns_add_RAW(packet, type, DNS_T_AAAA, domain, ttl, 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 len = DNS_RR_AAAA_LEN;
return dns_get_RAW(rrs, domain, maxsize, ttl, addr, &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)
@@ -598,7 +601,7 @@ int dns_add_SOA(struct dns_packet *packet, dns_rr_type type, char *domain, int t
ptr += 4;
len = ptr - data;
return dns_add_RAW(packet, type, DNS_T_SOA, domain, ttl, data, len);
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)
@@ -616,7 +619,7 @@ int dns_get_SOA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, struct
*| expire |
*| minimum |
*/
if (dns_get_RAW(rrs, domain, maxsize, ttl, data, &len) != 0) {
if (_dns_get_RAW(rrs, domain, maxsize, ttl, data, &len) != 0) {
return -1;
}
@@ -674,7 +677,7 @@ int dns_add_OPT_ECS(struct dns_packet *packet, struct dns_opt_ecs *ecs)
len += (ecs->source_prefix / 8);
len += (ecs->source_prefix % 8 > 0) ? 1 : 0;
return dns_add_RAW(packet, DNS_RRS_OPT, DNS_OPT_T_ECS, "", 0, opt_data, len);
return _dns_add_RAW(packet, DNS_RRS_OPT, DNS_OPT_T_ECS, "", 0, opt_data, len);
}
int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt_ecs *ecs)
@@ -684,7 +687,7 @@ int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned shor
int len = DNS_MAX_OPT_LEN;
int ttl = 0;
if (dns_get_RAW(rrs, 0, 0, &ttl, opt_data, &len) != 0) {
if (_dns_get_RAW(rrs, NULL, 0, &ttl, opt_data, &len) != 0) {
return -1;
}
@@ -727,7 +730,7 @@ int dns_add_domain(struct dns_packet *packet, char *domain, int qtype, int qclas
len = data_context.ptr - data_context.data;
return dns_rr_add_end(packet, DNS_RRS_QD, DNS_T_CNAME, len);
return _dns_rr_add_end(packet, DNS_RRS_QD, DNS_T_CNAME, len);
}
int dns_get_domain(struct dns_rrs *rrs, char *domain, int maxsize, int *qtype, int *qclass)
@@ -778,8 +781,8 @@ static int _dns_decode_head(struct dns_context *context)
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
head->id = dns_read_short(&context->ptr);
fields = dns_read_short(&context->ptr);
head->id = _dns_read_short(&context->ptr);
fields = _dns_read_short(&context->ptr);
head->qr = (fields & QR_MASK) >> 15;
head->opcode = (fields & OPCODE_MASK) >> 11;
head->aa = (fields & AA_MASK) >> 10;
@@ -787,10 +790,10 @@ static int _dns_decode_head(struct dns_context *context)
head->rd = (fields & RD_MASK) >> 8;
head->ra = (fields & RA_MASK) >> 7;
head->rcode = (fields & RCODE_MASK) >> 0;
head->qdcount = dns_read_short(&context->ptr);
head->ancount = dns_read_short(&context->ptr);
head->nscount = dns_read_short(&context->ptr);
head->nrcount = dns_read_short(&context->ptr);
head->qdcount = _dns_read_short(&context->ptr);
head->ancount = _dns_read_short(&context->ptr);
head->nscount = _dns_read_short(&context->ptr);
head->nrcount = _dns_read_short(&context->ptr);
return 0;
}
@@ -804,7 +807,7 @@ static int _dns_encode_head(struct dns_context *context)
return -1;
}
dns_write_short(&context->ptr, head->id);
_dns_write_short(&context->ptr, head->id);
int fields = 0;
fields |= (head->qr << 15) & QR_MASK;
@@ -814,12 +817,12 @@ static int _dns_encode_head(struct dns_context *context)
fields |= (head->rd << 8) & RD_MASK;
fields |= (head->ra << 7) & RA_MASK;
fields |= (head->rcode << 0) & RCODE_MASK;
dns_write_short(&context->ptr, fields);
_dns_write_short(&context->ptr, fields);
dns_write_short(&context->ptr, head->qdcount);
dns_write_short(&context->ptr, head->ancount);
dns_write_short(&context->ptr, head->nscount);
dns_write_short(&context->ptr, head->nrcount);
_dns_write_short(&context->ptr, head->qdcount);
_dns_write_short(&context->ptr, head->ancount);
_dns_write_short(&context->ptr, head->nscount);
_dns_write_short(&context->ptr, head->nrcount);
return len;
}
@@ -830,10 +833,10 @@ static int _dns_encode_head_count(struct dns_context *context)
unsigned char *ptr = context->data;
ptr += 4;
dns_write_short(&ptr, head->qdcount);
dns_write_short(&ptr, head->ancount);
dns_write_short(&ptr, head->nscount);
dns_write_short(&ptr, head->nrcount);
_dns_write_short(&ptr, head->qdcount);
_dns_write_short(&ptr, head->ancount);
_dns_write_short(&ptr, head->nscount);
_dns_write_short(&ptr, head->nrcount);
return len;
}
@@ -851,7 +854,7 @@ static int _dns_decode_domain(struct dns_context *context, char *output, int siz
if (ptr > context->data + context->maxsize || ptr < context->data || output_len >= size - 1 || ptr_jump > 4) {
return -1;
}
len = *ptr;
if (len == 0) {
*output = 0;
@@ -871,7 +874,7 @@ static int _dns_decode_domain(struct dns_context *context, char *output, int siz
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
/* read offset */
len = dns_read_short(&ptr) & 0x3FFF;
len = _dns_read_short(&ptr) & 0x3FFF;
if (is_compressed == 0) {
context->ptr = ptr;
}
@@ -958,7 +961,7 @@ static int _dns_decode_qr_head(struct dns_context *context, char *domain, int do
{
int ret = 0;
/*
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 1 2 3 4 5 6 7 8 9 A B C D E F
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
@@ -981,8 +984,8 @@ static int _dns_decode_qr_head(struct dns_context *context, char *domain, int do
return -1;
}
*qtype = dns_read_short(&context->ptr);
*qclass = dns_read_short(&context->ptr);
*qtype = _dns_read_short(&context->ptr);
*qclass = _dns_read_short(&context->ptr);
return 0;
}
@@ -999,8 +1002,8 @@ static int _dns_encode_qr_head(struct dns_context *context, char *domain, int qt
return -1;
}
dns_write_short(&context->ptr, qtype);
dns_write_short(&context->ptr, qclass);
_dns_write_short(&context->ptr, qtype);
_dns_write_short(&context->ptr, qclass);
return 0;
}
@@ -1020,8 +1023,8 @@ static int _dns_decode_rr_head(struct dns_context *context, char *domain, int do
return -1;
}
*ttl = dns_read_int(&context->ptr);
*rr_len = dns_read_short(&context->ptr);
*ttl = _dns_read_int(&context->ptr);
*rr_len = _dns_read_short(&context->ptr);
return 0;
}
@@ -1038,8 +1041,8 @@ static int _dns_encode_rr_head(struct dns_context *context, char *domain, int qt
return -1;
}
dns_write_int(&context->ptr, ttl);
dns_write_short(&context->ptr, rr_len);
_dns_write_int(&context->ptr, ttl);
_dns_write_short(&context->ptr, rr_len);
return 0;
}
@@ -1054,7 +1057,7 @@ static int _dns_encode_raw(struct dns_context *context, struct dns_rrs *rrs)
int rr_len;
struct dns_data_context data_context;
/*
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 1 2 3 4 5 6 7 8 9 A B C D E F
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
@@ -1111,7 +1114,7 @@ static int _dns_decode_raw(struct dns_context *context, unsigned char *raw, int
return 0;
}
int _dns_decode_CNAME(struct dns_context *context, char *cname, int cname_size)
static int _dns_decode_CNAME(struct dns_context *context, char *cname, int cname_size)
{
int ret = 0;
ret = _dns_decode_domain(context, cname, cname_size);
@@ -1122,7 +1125,7 @@ int _dns_decode_CNAME(struct dns_context *context, char *cname, int cname_size)
return 0;
}
int _dns_encode_CNAME(struct dns_context *context, struct dns_rrs *rrs)
static int _dns_encode_CNAME(struct dns_context *context, struct dns_rrs *rrs)
{
int ret;
int qtype = 0;
@@ -1162,7 +1165,7 @@ int _dns_encode_CNAME(struct dns_context *context, struct dns_rrs *rrs)
return 0;
}
int _dns_decode_SOA(struct dns_context *context, struct dns_soa *soa)
static 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);
@@ -1179,16 +1182,16 @@ int _dns_decode_SOA(struct dns_context *context, struct dns_soa *soa)
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);
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)
static int _dns_encode_SOA(struct dns_context *context, struct dns_rrs *rrs)
{
int ret;
int qtype = 0;
@@ -1238,33 +1241,32 @@ int _dns_encode_SOA(struct dns_context *context, struct dns_rrs *rrs)
return -1;
}
dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
_dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
data_context.ptr += 4;
dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
_dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
data_context.ptr += 4;
dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
_dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
data_context.ptr += 4;
dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
_dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
data_context.ptr += 4;
dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
_dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr);
data_context.ptr += 4;
return 0;
}
static int _dns_decode_opt_ecs(struct dns_context *context, struct dns_opt_ecs *ecs)
{
// TODO
int len = 0;
if (_dns_left_len(context) < 4) {
return -1;
}
ecs->family = dns_read_short(&context->ptr);
ecs->source_prefix = dns_read_char(&context->ptr);
ecs->scope_prefix = dns_read_char(&context->ptr);
ecs->family = _dns_read_short(&context->ptr);
ecs->source_prefix = _dns_read_char(&context->ptr);
ecs->scope_prefix = _dns_read_char(&context->ptr);
len = (ecs->source_prefix / 8);
len += (ecs->source_prefix % 8 > 0) ? 1 : 0;
@@ -1281,7 +1283,7 @@ static int _dns_decode_opt_ecs(struct dns_context *context, struct dns_opt_ecs *
return 0;
}
int _dns_encode_OPT(struct dns_context *context, struct dns_rrs *rrs)
static int _dns_encode_OPT(struct dns_context *context, struct dns_rrs *rrs)
{
int ret;
int opt_code = 0;
@@ -1304,15 +1306,15 @@ int _dns_encode_OPT(struct dns_context *context, struct dns_rrs *rrs)
return -1;
}
dns_write_short(&context->ptr, opt_code);
dns_write_short(&context->ptr, rr_len);
_dns_write_short(&context->ptr, opt_code);
_dns_write_short(&context->ptr, rr_len);
memcpy(context->ptr, data_context.ptr, rr_len);
context->ptr += rr_len;
return 0;
}
int _dns_get_opts_data_len(struct dns_packet *packet, struct dns_rrs *rrs, int count)
static int _dns_get_opts_data_len(struct dns_packet *packet, struct dns_rrs *rrs, int count)
{
int i = 0;
int len = 0;
@@ -1340,7 +1342,7 @@ int _dns_get_opts_data_len(struct dns_packet *packet, struct dns_rrs *rrs, int c
return len;
}
int _dns_encode_opts(struct dns_packet *packet, struct dns_context *context, struct dns_rrs *rrs, int count)
static int _dns_encode_opts(struct dns_packet *packet, struct dns_context *context, struct dns_rrs *rrs, int count)
{
int i = 0;
int len = 0;
@@ -1382,7 +1384,7 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
unsigned short opt_code;
unsigned short opt_len;
unsigned short ercode = (ttl >> 16) & 0xFFFF;
unsigned short ever = (ttl) & 0xFFFF;
unsigned short ever = (ttl)&0xFFFF;
unsigned char *start = context->ptr;
struct dns_packet *packet = context->packet;
int ret = 0;
@@ -1390,46 +1392,46 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
UNUSED(ever);
/*
Field Name Field Type Description
------------------------------------------------------
NAME domain name empty (root domain)
TYPE u_int16_t OPT
CLASS u_int16_t sender's UDP payload size
TTL u_int32_t extended RCODE and flags
RDLEN u_int16_t describes RDATA
RDATA octet stream {attribute,value} pairs
Field Name Field Type Description
------------------------------------------------------
NAME domain name empty (root domain)
TYPE u_int16_t OPT
CLASS u_int16_t sender's UDP payload size
TTL u_int32_t extended RCODE and flags
RDLEN u_int16_t describes RDATA
RDATA octet stream {attribute,value} pairs
+0 (MSB) +1 (LSB)
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+0 (MSB) +1 (LSB)
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0: | OPTION-CODE |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
2: | OPTION-LENGTH |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
4: | |
/ OPTION-DATA /
/ /
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
/ OPTION-DATA /
/ /
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
TTL
+0 (MSB) +1 (LSB)
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+0 (MSB) +1 (LSB)
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0: | EXTENDED-RCODE | VERSION |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
2: | Z |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
*/
if (ercode != 0) {
tlog(TLOG_ERROR, "extend rcode invalid.");
return -1;
}
while (context->ptr - start < rr_len) {
if (_dns_left_len(context) < 4) {
return -1;
}
opt_code = dns_read_short(&context->ptr);
opt_len = dns_read_short(&context->ptr);
opt_code = _dns_read_short(&context->ptr);
opt_len = _dns_read_short(&context->ptr);
if (_dns_left_len(context) < opt_len) {
tlog(TLOG_ERROR, "read opt data failed, opt_code = %d, opt_le = %d", opt_code, opt_len);
@@ -1441,13 +1443,13 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
case DNS_OPT_T_ECS: {
struct dns_opt_ecs ecs;
ret = _dns_decode_opt_ecs(context, &ecs);
if (ret != 0 ) {
if (ret != 0) {
tlog(TLOG_ERROR, "decode ecs failed.");
return -1;
}
ret = dns_add_OPT_ECS(packet, &ecs);
if (ret != 0 ) {
if (ret != 0) {
tlog(TLOG_ERROR, "add ecs failed.");
return -1;
}
@@ -1456,7 +1458,7 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
context->ptr += opt_len;
tlog(TLOG_DEBUG, "DNS opt type = %d not supported", opt_code);
break;
}
}
}
return 0;
@@ -1589,7 +1591,7 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
}
} break;
case DNS_T_OPT: {
unsigned char *opt_start = context->ptr;
unsigned char *opt_start = context->ptr;
ret = _dns_decode_opt(context, type, ttl, rr_len);
if (ret < 0) {
tlog(TLOG_ERROR, "decode opt failed, %s", domain);
@@ -1875,7 +1877,8 @@ int dns_encode(unsigned char *data, int size, struct dns_packet *packet)
return context.ptr - context.data;
}
void dns_debug(void)
#if 0
static void dns_debug(void)
{
unsigned char data[1024];
int len;
@@ -1899,10 +1902,11 @@ void dns_debug(void)
memset(data, 0, sizeof(data));
len = dns_encode(data, 1024, packet);
if (len < 0) {
tlog(TLOG_ERROR, "encode failed.\n");
tlog(TLOG_ERROR, "encode failed.");
}
fd = open("dns-cmp.bin", O_CREAT | O_TRUNC | O_RDWR);
write(fd, data, len);
close(fd);
}
#endif

View File

@@ -1,11 +1,6 @@
#ifndef _DNS_HEAD_H
#define _DNS_HEAD_H
#include <arpa/inet.h>
#include <linux/filter.h>
#include <netdb.h>
#include <stdint.h>
#define DNS_RR_A_LEN 4
#define DNS_RR_AAAA_LEN 16
#define DNS_MAX_CNAME_LEN 256
@@ -50,9 +45,9 @@ typedef enum dns_type {
DNS_T_ALL = 255
} dns_type_t;
typedef enum dns_opt_code {
DNS_OPT_T_ECS = 8,
DNS_OPT_T_ALL = 255
typedef enum dns_opt_code {
DNS_OPT_T_ECS = 8,
DNS_OPT_T_ALL = 255
} dns_opt_code_t;
typedef enum dns_opcode {
@@ -188,6 +183,9 @@ int dns_get_AAAA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsig
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);
int dns_add_NS(struct dns_packet *packet, dns_rr_type type, char *domain, int ttl, char *cname);
int dns_get_NS(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size);
int dns_set_OPT_payload_size(struct dns_packet *packet, int payload_size);
int dns_get_OPT_payload_size(struct dns_packet *packet);

View File

@@ -10,7 +10,7 @@ struct dns_cache_head {
pthread_mutex_t lock;
};
struct dns_cache_head dns_cache_head;
static struct dns_cache_head dns_cache_head;
int dns_cache_init(int size)
{
@@ -19,22 +19,22 @@ int dns_cache_init(int size)
dns_cache_head.num = 0;
dns_cache_head.size = size;
pthread_mutex_init(&dns_cache_head.lock, 0);
pthread_mutex_init(&dns_cache_head.lock, NULL);
return 0;
}
struct dns_cache *_dns_cache_last(void)
static __attribute__((unused)) struct dns_cache *_dns_cache_last(void)
{
return list_last_entry(&dns_cache_head.cache_list, struct dns_cache, list);
}
struct dns_cache *_dns_cache_first(void)
static struct dns_cache *_dns_cache_first(void)
{
return list_first_entry_or_null(&dns_cache_head.cache_list, struct dns_cache, list);
}
void _dns_cache_delete(struct dns_cache *dns_cache)
static void _dns_cache_delete(struct dns_cache *dns_cache)
{
hash_del(&dns_cache->node);
list_del_init(&dns_cache->list);
@@ -59,7 +59,7 @@ void dns_cache_release(struct dns_cache *dns_cache)
_dns_cache_delete(dns_cache);
}
void _dns_cache_remove(struct dns_cache *dns_cache)
static void _dns_cache_remove(struct dns_cache *dns_cache)
{
hash_del(&dns_cache->node);
list_del_init(&dns_cache->list);
@@ -74,6 +74,7 @@ int dns_cache_replace(char *domain, char *cname, int cname_ttl, int ttl, dns_typ
return 0;
}
/* lookup existing cache */
dns_cache = dns_cache_lookup(domain, qtype);
if (dns_cache == NULL) {
return 0;
@@ -83,6 +84,7 @@ int dns_cache_replace(char *domain, char *cname, int cname_ttl, int ttl, dns_typ
ttl = DNS_CACHE_TTL_MIN;
}
/* update cache data */
pthread_mutex_lock(&dns_cache_head.lock);
dns_cache->ttl = ttl;
dns_cache->qtype = qtype;
@@ -128,6 +130,7 @@ int dns_cache_insert(char *domain, char *cname, int cname_ttl, int ttl, dns_type
return 0;
}
/* if cache already exists, free */
dns_cache = dns_cache_lookup(domain, qtype);
if (dns_cache) {
dns_cache_delete(dns_cache);
@@ -179,6 +182,7 @@ int dns_cache_insert(char *domain, char *cname, int cname_ttl, int ttl, dns_type
INIT_LIST_HEAD(&dns_cache->check_list);
dns_cache_head.num++;
/* Release extra cache, remove oldest cache record */
if (dns_cache_head.num > dns_cache_head.size) {
struct dns_cache *del_cache;
del_cache = _dns_cache_first();
@@ -212,6 +216,7 @@ struct dns_cache *dns_cache_lookup(char *domain, dns_type_t qtype)
key = jhash(&qtype, sizeof(qtype), key);
time(&now);
/* find cache */
pthread_mutex_lock(&dns_cache_head.lock);
hash_for_each_possible(dns_cache_head.cache_hash, dns_cache, node, key)
{
@@ -228,6 +233,7 @@ struct dns_cache *dns_cache_lookup(char *domain, dns_type_t qtype)
}
if (dns_cache_ret) {
/* Return NULL if the cache times out */
if (now - dns_cache_ret->insert_time > dns_cache_ret->ttl) {
_dns_cache_remove(dns_cache_ret);
dns_cache_ret = NULL;
@@ -291,6 +297,7 @@ void dns_cache_invalidate(dns_cache_preinvalid_callback callback, int ttl_pre)
{
ttl = dns_cache->insert_time + dns_cache->ttl - now;
if (ttl > 0 && ttl < ttl_pre) {
/* If the TTL time is in the pre-timeout range, call callback function */
if (callback && dns_cache->del_pending == 0) {
list_add_tail(&dns_cache->check_list, &checklist);
dns_cache_get(dns_cache);
@@ -307,6 +314,7 @@ void dns_cache_invalidate(dns_cache_preinvalid_callback callback, int ttl_pre)
list_for_each_entry_safe(dns_cache, tmp, &checklist, check_list)
{
/* run callback */
if (callback) {
callback(dns_cache);
}
@@ -326,4 +334,4 @@ void dns_cache_destroy(void)
pthread_mutex_unlock(&dns_cache_head.lock);
pthread_mutex_destroy(&dns_cache_head.lock);
}
}

View File

@@ -6,6 +6,7 @@
#include "hash.h"
#include "hashtable.h"
#include "list.h"
#include <stdlib.h>
#include <time.h>
#define DNS_CACHE_TTL_MIN 30
@@ -54,4 +55,4 @@ int dns_cache_get_ttl(struct dns_cache *dns_cache);
void dns_cache_destroy(void);
#endif // !_SMARTDNS_CACHE_H
#endif // !_SMARTDNS_CACHE_H

View File

@@ -19,12 +19,12 @@
#include "dns_client.h"
#include "atomic.h"
#include "dns.h"
#include "dns_conf.h"
#include "fast_ping.h"
#include "hashtable.h"
#include "list.h"
#include "tlog.h"
#include "util.h"
#include "dns_conf.h"
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
@@ -59,6 +59,7 @@
#define TCP_FASTOPEN_CONNECT 30
#endif
/* ECS info */
struct dns_client_ecs {
int enable;
unsigned int family;
@@ -70,6 +71,7 @@ struct dns_client_ecs {
};
};
/* TCP/TLS buffer */
struct dns_server_buff {
unsigned char data[DNS_TCP_BUFFER];
unsigned short len;
@@ -123,11 +125,13 @@ struct dns_server_info {
};
};
/* upstream server group member */
struct dns_server_group_member {
struct list_head list;
struct dns_server_info *server;
};
/* upstream server groups */
struct dns_server_group {
char group_name[DNS_GROUP_NAME_LEN];
struct hlist_node node;
@@ -230,7 +234,7 @@ errout:
}
/* check whether server exists */
int _dns_client_server_exist(struct addrinfo *gai, dns_server_type_t server_type)
static int _dns_client_server_exist(struct addrinfo *gai, dns_server_type_t server_type)
{
struct dns_server_info *server_info, *tmp;
pthread_mutex_lock(&client.server_list_lock);
@@ -256,7 +260,7 @@ int _dns_client_server_exist(struct addrinfo *gai, dns_server_type_t server_type
return -1;
}
void _dns_client_server_update_ttl(struct ping_host_struct *ping_host, const char *host, FAST_PING_RESULT result, struct sockaddr *addr, socklen_t addr_len,
static void _dns_client_server_update_ttl(struct ping_host_struct *ping_host, const char *host, FAST_PING_RESULT result, struct sockaddr *addr, socklen_t addr_len,
int seqno, int ttl, struct timeval *tv, void *userptr)
{
struct dns_server_info *server_info = userptr;
@@ -270,7 +274,7 @@ void _dns_client_server_update_ttl(struct ping_host_struct *ping_host, const cha
}
/* get server control block by ip and port, type */
struct dns_server_info *_dns_client_get_server(char *server_ip, int port, dns_server_type_t server_type)
static struct dns_server_info *_dns_client_get_server(char *server_ip, int port, dns_server_type_t server_type)
{
struct dns_server_info *server_info, *tmp;
struct dns_server_info *server_info_return = NULL;
@@ -335,7 +339,8 @@ errout:
return NULL;
}
struct dns_server_group *_dns_client_get_group(const char *group_name)
/* get server group by name */
static struct dns_server_group *_dns_client_get_group(const char *group_name)
{
unsigned long key;
struct dns_server_group *group = NULL;
@@ -358,7 +363,8 @@ struct dns_server_group *_dns_client_get_group(const char *group_name)
return NULL;
}
int _dns_client_add_to_group(char *group_name, struct dns_server_info *server_info)
/* add server to group */
static int _dns_client_add_to_group(char *group_name, struct dns_server_info *server_info)
{
struct dns_server_group *group = NULL;
struct dns_server_group_member *group_member = NULL;
@@ -388,6 +394,7 @@ errout:
return -1;
}
/* add server to group */
int dns_client_add_to_group(char *group_name, char *server_ip, int port, dns_server_type_t server_type)
{
struct dns_server_info *server_info = NULL;
@@ -400,7 +407,8 @@ int dns_client_add_to_group(char *group_name, char *server_ip, int port, dns_ser
return _dns_client_add_to_group(group_name, server_info);
}
int _dns_client_remove_member(struct dns_server_group_member *group_member)
/* free group member */
static int _dns_client_remove_member(struct dns_server_group_member *group_member)
{
list_del_init(&group_member->list);
free(group_member);
@@ -408,7 +416,7 @@ int _dns_client_remove_member(struct dns_server_group_member *group_member)
return 0;
}
int _dns_client_remove_from_group(struct dns_server_group *group, struct dns_server_info *server_info)
static int _dns_client_remove_from_group(struct dns_server_group *group, struct dns_server_info *server_info)
{
struct dns_server_group_member *group_member;
struct dns_server_group_member *tmp;
@@ -425,7 +433,7 @@ int _dns_client_remove_from_group(struct dns_server_group *group, struct dns_ser
return 0;
}
int _dns_client_remove_server_from_groups(struct dns_server_info *server_info)
static int _dns_client_remove_server_from_groups(struct dns_server_info *server_info)
{
struct dns_server_group *group;
struct hlist_node *tmp = NULL;
@@ -488,7 +496,7 @@ errout:
return -1;
}
int _dns_client_remove_group(struct dns_server_group *group)
static int _dns_client_remove_group(struct dns_server_group *group)
{
struct dns_server_group_member *group_member;
struct dns_server_group_member *tmp;
@@ -504,7 +512,7 @@ int _dns_client_remove_group(struct dns_server_group *group)
return 0;
}
int dns_remove_group(char *group_name)
int dns_client_remove_group(char *group_name)
{
unsigned long key;
struct dns_server_group *group = NULL;
@@ -525,7 +533,7 @@ int dns_remove_group(char *group_name)
return 0;
}
void _dns_client_group_remove_all(void)
static void _dns_client_group_remove_all(void)
{
struct dns_server_group *group;
struct hlist_node *tmp = NULL;
@@ -538,13 +546,14 @@ void _dns_client_group_remove_all(void)
}
/* add dns server information */
int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag, int ttl, char *spki)
static int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag, int ttl,
char *spki)
{
struct dns_server_info *server_info = NULL;
unsigned char *spki_data = NULL;
int spki_data_len = 0;
/* read SPKI */
/* read SPKI value, base64 sha256 value */
if (spki && (strlen(spki) < DNS_MAX_SPKI_LEN)) {
spki_data = malloc(DNS_MAX_SPKI_LEN);
if (spki_data) {
@@ -558,6 +567,7 @@ int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_typ
}
}
/* if server exist, return */
if (_dns_client_server_exist(gai, server_type) == 0) {
return 0;
}
@@ -584,6 +594,7 @@ int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_typ
server_info->spki = spki_data;
server_info->spki_len = spki_data_len;
/* exclude this server from default group */
if ((server_flag & SERVER_FLAG_EXCLUDE_DEFAULT) == 0) {
if (_dns_client_add_to_group(DNS_SERVER_GROUP_DEFAULT, server_info) != 0) {
tlog(TLOG_ERROR, "add server to default group failed.");
@@ -591,6 +602,7 @@ int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_typ
}
}
/* if server type is TLS, create ssl context */
if (server_type == DNS_SERVER_TLS) {
server_info->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
if (server_info->ssl_ctx == NULL) {
@@ -599,6 +611,7 @@ int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_typ
}
}
/* safe address info */
if (gai->ai_addrlen > sizeof(server_info->in6)) {
tlog(TLOG_ERROR, "addr len invalid, %d, %zd, %d", gai->ai_addrlen, sizeof(server_info->addr), server_info->ai_family);
goto errout;
@@ -652,16 +665,19 @@ static void _dns_client_close_socket(struct dns_server_info *server_info)
}
if (server_info->ssl) {
/* Shutdown ssl */
SSL_shutdown(server_info->ssl);
SSL_free(server_info->ssl);
server_info->ssl = NULL;
}
/* remove fd from epoll */
epoll_ctl(client.epoll_fd, EPOLL_CTL_DEL, server_info->fd, NULL);
close(server_info->fd);
server_info->fd = -1;
server_info->status = DNS_SERVER_STATUS_DISCONNECTED;
/* update send recv time */
time(&server_info->last_send);
time(&server_info->last_recv);
tlog(TLOG_DEBUG, "server %s closed.", server_info->ip);
@@ -686,11 +702,11 @@ static void _dns_client_server_close(struct dns_server_info *server_info)
if (server_info->ssl_ctx) {
SSL_CTX_free(server_info->ssl_ctx);
server_info->ssl_ctx = NULL;
}
}
}
/* remove all servers information */
void _dns_client_server_remove_all(void)
static void _dns_client_server_remove_all(void)
{
struct dns_server_info *server_info, *tmp;
pthread_mutex_lock(&client.server_list_lock);
@@ -708,7 +724,7 @@ void _dns_client_server_remove_all(void)
}
/* remove single server */
int _dns_client_server_remove(char *server_ip, struct addrinfo *gai, dns_server_type_t server_type)
static int _dns_client_server_remove(char *server_ip, struct addrinfo *gai, dns_server_type_t server_type)
{
struct dns_server_info *server_info, *tmp;
@@ -736,7 +752,8 @@ int _dns_client_server_remove(char *server_ip, struct addrinfo *gai, dns_server_
return -1;
}
int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag, int ttl, char *spki, int operate)
static int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag, int ttl,
char *spki, int operate)
{
char port_s[8];
int sock_type;
@@ -770,11 +787,13 @@ int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t serv
}
if (operate == 0) {
/* add server */
ret = _dns_client_server_add(server_ip, gai, server_type, server_flag, result_flag, ttl, spki);
if (ret != 0) {
goto errout;
}
} else {
/* remove server */
ret = _dns_client_server_remove(server_ip, gai, server_type);
if (ret != 0) {
goto errout;
@@ -804,7 +823,7 @@ int dns_server_num(void)
return atomic_read(&client.dns_server_num);
}
void _dns_client_query_get(struct dns_query_struct *query)
static void _dns_client_query_get(struct dns_query_struct *query)
{
if (atomic_inc_return(&query->refcnt) <= 0) {
tlog(TLOG_ERROR, "BUG: query ref is invalid, domain: %s", query->domain);
@@ -812,7 +831,7 @@ void _dns_client_query_get(struct dns_query_struct *query)
}
}
void _dns_client_query_release(struct dns_query_struct *query)
static void _dns_client_query_release(struct dns_query_struct *query)
{
int refcnt = atomic_dec_return(&query->refcnt);
int bucket = 0;
@@ -847,7 +866,7 @@ void _dns_client_query_release(struct dns_query_struct *query)
free(query);
}
void _dns_client_query_remove(struct dns_query_struct *query)
static void _dns_client_query_remove(struct dns_query_struct *query)
{
/* remove query from period check list, and release reference*/
pthread_mutex_lock(&client.domain_map_lock);
@@ -862,7 +881,7 @@ void _dns_client_query_remove(struct dns_query_struct *query)
_dns_client_query_release(query);
}
void _dns_client_query_remove_all(void)
static void _dns_client_query_remove_all(void)
{
struct dns_query_struct *query, *tmp;
LIST_HEAD(check_list);
@@ -883,7 +902,7 @@ void _dns_client_query_remove_all(void)
return;
}
void _dns_client_check_udp_nat(struct dns_query_struct *query)
static void _dns_client_check_udp_nat(struct dns_query_struct *query)
{
struct dns_server_info *server_info = NULL;
struct dns_server_group_member *group_member = NULL;
@@ -911,7 +930,7 @@ void _dns_client_check_udp_nat(struct dns_query_struct *query)
pthread_mutex_unlock(&client.server_list_lock);
}
void _dns_client_check_tcp(void)
static void _dns_client_check_tcp(void)
{
struct dns_server_info *server_info;
time_t now;
@@ -922,6 +941,7 @@ void _dns_client_check_tcp(void)
list_for_each_entry(server_info, &client.dns_server_list, list)
{
if (server_info->type == DNS_SERVER_UDP) {
/* no need to check udp server */
continue;
}
@@ -932,21 +952,22 @@ void _dns_client_check_tcp(void)
}
} else if (server_info->status == DNS_SERVER_STATUS_CONNECTED) {
if (server_info->last_recv + DNS_TCP_IDLE_TIMEOUT < now) {
/*disconnect if the server is not responding */
server_info->recv_buff.len = 0;
server_info->send_buff.len = 0;
_dns_client_close_socket(server_info);
}
}
}
pthread_mutex_unlock(&client.server_list_lock);
pthread_mutex_unlock(&client.server_list_lock);
}
void _dns_client_period_run_second(void)
static void _dns_client_period_run_second(void)
{
_dns_client_check_tcp();
}
void _dns_client_period_run(void)
static void _dns_client_period_run(void)
{
struct dns_query_struct *query, *tmp;
static unsigned int msec = 0;
@@ -974,10 +995,8 @@ void _dns_client_period_run(void)
_dns_client_check_udp_nat(query);
_dns_client_query_remove(query);
_dns_client_query_release(query);
}
if (msec % 10 == 0) {
_dns_client_period_run_second();
}
@@ -1015,7 +1034,7 @@ static struct dns_query_struct *_dns_client_get_request(unsigned short sid, char
return query_result;
}
int _dns_replied_check_add(struct dns_query_struct *dns_query, struct sockaddr *addr, socklen_t addr_len)
static int _dns_replied_check_add(struct dns_query_struct *dns_query, struct sockaddr *addr, socklen_t addr_len)
{
uint32_t key = 0;
struct dns_query_replied *replied_map = NULL;
@@ -1156,6 +1175,7 @@ static int _dns_client_create_socket_udp(struct dns_server_info *server_info)
setsockopt(server_info->fd, IPPROTO_IP, IP_RECVTTL, &on, sizeof(on));
setsockopt(server_info->fd, SOL_IP, IP_TTL, &val, sizeof(val));
if (server_info->ai_family == AF_INET6) {
/* for recving ip ttl value */
setsockopt(server_info->fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on));
setsockopt(server_info->fd, IPPROTO_IPV6, IPV6_2292HOPLIMIT, &on, sizeof(on));
setsockopt(server_info->fd, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on));
@@ -1187,6 +1207,7 @@ static int _DNS_client_create_socket_tcp(struct dns_server_info *server_info)
goto errout;
}
/* enable tcp fast open */
if (setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT, &yes, sizeof(yes)) != 0) {
tlog(TLOG_DEBUG, "enable TCP fast open failed.");
}
@@ -1257,7 +1278,7 @@ static int _DNS_client_create_socket_tls(struct dns_server_info *server_info)
// ? this cause ssl crash ?
// setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes));
if (connect(fd, (struct sockaddr *)&server_info->addr, server_info->ai_addrlen) != 0) {
if (errno != EINPROGRESS) {
tlog(TLOG_ERROR, "connect failed.");
@@ -1270,6 +1291,7 @@ static int _DNS_client_create_socket_tls(struct dns_server_info *server_info)
goto errout;
}
/* reuse ssl session */
if (server_info->ssl_session) {
SSL_set_session(ssl, server_info->ssl_session);
}
@@ -1354,6 +1376,7 @@ static int _dns_client_process_udp(struct dns_server_info *server_info, struct e
}
from_len = msg.msg_namelen;
/* Get the TTL of the IP header */
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) {
if (cmsg->cmsg_len >= sizeof(int)) {
@@ -1371,13 +1394,17 @@ static int _dns_client_process_udp(struct dns_server_info *server_info, struct e
tlog(TLOG_DEBUG, "recv udp packet from %s, len: %d, ttl: %d", gethost_by_addr(from_host, sizeof(from_host), (struct sockaddr *)&from), len, ttl);
if ((ttl != server_info->ttl) && (server_info->ttl > 0) && (server_info->result_flag & DNSSERVER_FLAG_CHECK_TTL)) {
/* If TTL check is enabled but the TTL is inconsistent, it is considered to be a fake dns packet */
if ((ttl < server_info->ttl - server_info->ttl_range) || (ttl > server_info->ttl + server_info->ttl_range)) {
/* tlog(TLOG_DEBUG, "TTL mismatch, from:%d, local %d, discard result", ttl, server_info->ttl); */
return 0;
}
}
/* update recv time */
time(&server_info->last_recv);
/* processing dns packet */
if (_dns_client_recv(server_info, inpacket, len, (struct sockaddr *)&from, from_len) != 0) {
return -1;
}
@@ -1519,7 +1546,8 @@ static int _dns_client_socket_recv(struct dns_server_info *server_info)
} else if (server_info->type == DNS_SERVER_TCP) {
return recv(server_info->fd, server_info->recv_buff.data + server_info->recv_buff.len, DNS_TCP_BUFFER - server_info->recv_buff.len, 0);
} else if (server_info->type == DNS_SERVER_TLS) {
return _dns_client_socket_ssl_recv(server_info->ssl, server_info->recv_buff.data + server_info->recv_buff.len, DNS_TCP_BUFFER - server_info->recv_buff.len);
return _dns_client_socket_ssl_recv(server_info->ssl, server_info->recv_buff.data + server_info->recv_buff.len,
DNS_TCP_BUFFER - server_info->recv_buff.len);
} else {
return -1;
}
@@ -1622,7 +1650,7 @@ static int _dns_client_process_tcp(struct dns_server_info *server_info, struct e
}
pthread_mutex_lock(&client.server_list_lock);
if (server_info->send_buff.len > 0) {
/* send data in send_buffer */
/* send existing send_buffer data */
len = _dns_client_socket_send(server_info);
if (len < 0) {
if (errno == EAGAIN) {
@@ -1700,7 +1728,7 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
/* get spki pin */
key_len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
if (key_len <= 0 ) {
if (key_len <= 0) {
tlog(TLOG_ERROR, "get x509 public key failed.");
goto errout;
}
@@ -1714,7 +1742,8 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &key_data_tmp);
key_sha256 = SSL_SHA256(key_data, key_len, 0);
/* Get the SHA256 value of SPKI */
key_sha256 = SSL_SHA256(key_data, key_len, NULL);
if (key_sha256 == NULL) {
tlog(TLOG_ERROR, "get sha256 failed.");
goto errout;
@@ -1734,6 +1763,7 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
tlog(TLOG_DEBUG, "cert SPKI pin(%s): %s", "sha256", cert_fingerprint);
if (server_info->spki) {
/* check SPKI */
if (memcmp(server_info->spki, key_sha256, server_info->spki_len) != 0) {
tlog(TLOG_INFO, "server %s cert spki is invalid", server_info->ip);
goto errout;
@@ -1765,6 +1795,7 @@ static int _dns_client_process_tls(struct dns_server_info *server_info, struct e
int ssl_ret;
if (server_info->status == DNS_SERVER_STATUS_CONNECTING) {
/* do SSL hand shake */
ret = SSL_connect(server_info->ssl);
if (ret == 0) {
goto errout;
@@ -1790,11 +1821,12 @@ static int _dns_client_process_tls(struct dns_server_info *server_info, struct e
tlog(TLOG_DEBUG, "tls server %s connected.\n", server_info->ip);
/* Was the stored session reused? */
if (SSL_session_reused(server_info->ssl)) {
tlog(TLOG_DEBUG, "reused session");
} else {
tlog(TLOG_DEBUG, "new session");
if (SSL_session_reused(server_info->ssl)) {
tlog(TLOG_DEBUG, "reused session");
} else {
tlog(TLOG_DEBUG, "new session");
if (server_info->ssl_session) {
/* free session */
SSL_SESSION_free(server_info->ssl_session);
server_info->ssl_session = NULL;
}
@@ -1804,8 +1836,9 @@ static int _dns_client_process_tls(struct dns_server_info *server_info, struct e
goto errout;
}
/* save ssl session for next request */
server_info->ssl_session = SSL_get1_session(server_info->ssl);
}
}
server_info->status = DNS_SERVER_STATUS_CONNECTED;
memset(&fd_event, 0, sizeof(fd_event));
@@ -1939,7 +1972,7 @@ static int _dns_client_send_tcp(struct dns_server_info *server_info, void *packe
unsigned char inpacket_data[DNS_IN_PACKSIZE];
unsigned char *inpacket = inpacket_data;
if (len > sizeof(inpacket_data) -2 ) {
if (len > sizeof(inpacket_data) - 2) {
tlog(TLOG_ERROR, "packet size is invalid.");
return -1;
}
@@ -1982,7 +2015,7 @@ static int _dns_client_send_tls(struct dns_server_info *server_info, void *packe
unsigned char inpacket_data[DNS_IN_PACKSIZE];
unsigned char *inpacket = inpacket_data;
if (len > sizeof(inpacket_data) -2 ) {
if (len > sizeof(inpacket_data) - 2) {
tlog(TLOG_ERROR, "packet size is invalid.");
return -1;
}
@@ -2117,7 +2150,7 @@ static int _dns_client_send_query(struct dns_query_struct *query, char *doamin)
head.ra = 0;
head.rcode = 0;
if(dns_packet_init(packet, DNS_PACKSIZE, &head) != 0) {
if (dns_packet_init(packet, DNS_PACKSIZE, &head) != 0) {
tlog(TLOG_ERROR, "init packet failed.");
return -1;
}
@@ -2224,7 +2257,7 @@ int dns_client_set_ecs(char *ip, int subnet)
return 0;
}
int dns_client_init()
int dns_client_init(void)
{
pthread_attr_t attr;
int epollfd = -1;
@@ -2244,10 +2277,10 @@ int dns_client_init()
goto errout;
}
pthread_mutex_init(&client.server_list_lock, 0);
pthread_mutex_init(&client.server_list_lock, NULL);
INIT_LIST_HEAD(&client.dns_server_list);
pthread_mutex_init(&client.domain_map_lock, 0);
pthread_mutex_init(&client.domain_map_lock, NULL);
hash_init(client.domain_map);
hash_init(client.group);
INIT_LIST_HEAD(&client.dns_request_list);
@@ -2286,7 +2319,7 @@ errout:
return -1;
}
void dns_client_exit()
void dns_client_exit(void)
{
if (client.tid > 0) {
void *ret = NULL;

View File

@@ -7,40 +7,55 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <syslog.h>
#define DEFAULT_DNS_CACHE_SIZE 512
/* ipset */
struct dns_ipset_table {
DECLARE_HASHTABLE(ipset, 8);
};
struct dns_ipset_table dns_ipset_table;
static struct dns_ipset_table dns_ipset_table;
/* dns groups */
struct dns_group_table dns_group_table;
/* server ip/port */
char dns_conf_server_ip[DNS_MAX_IPLEN];
char dns_conf_server_tcp_ip[DNS_MAX_IPLEN];
int dns_conf_tcp_idle_time = 120;
/* cache */
int dns_conf_cachesize = DEFAULT_DNS_CACHE_SIZE;
int dns_conf_prefetch = 0;
/* upstream servers */
struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
char dns_conf_server_name[DNS_MAX_CONF_CNAME_LEN];
int dns_conf_server_num;
/* logging */
int dns_conf_log_level = TLOG_ERROR;
char dns_conf_log_file[DNS_MAX_PATH];
size_t dns_conf_log_size = 1024 * 1024;
int dns_conf_log_num = 8;
/* auditing */
int dns_conf_audit_enable = 0;
char dns_conf_audit_file[DNS_MAX_PATH];
size_t dns_conf_audit_size = 1024 * 1024;
int dns_conf_audit_num = 2;
/* address rules */
art_tree dns_conf_domain_rule;
struct dns_conf_address_rule dns_conf_address_rule;
/* dual-stack selection */
int dns_conf_dualstack_ip_selection;
int dns_conf_dualstack_ip_selection_threshold = 30;
/* TTL */
int dns_conf_rr_ttl;
int dns_conf_rr_ttl_min;
int dns_conf_rr_ttl_max;
@@ -48,10 +63,12 @@ int dns_conf_force_AAAA_SOA;
int dns_conf_ipset_timeout_enable;
/* ECS */
struct dns_edns_client_subnet dns_conf_ipv4_ecs;
struct dns_edns_client_subnet dns_conf_ipv6_ecs;
struct dns_server_groups *dns_conf_get_group(const char *group_name)
/* create and get dns server group */
static struct dns_server_groups *_dns_conf_get_group(const char *group_name)
{
uint32_t key = 0;
struct dns_server_groups *group = NULL;
@@ -82,12 +99,12 @@ errout:
return NULL;
}
int dns_conf_get_group_set(const char *group_name, struct dns_servers *server)
static int _dns_conf_get_group_set(const char *group_name, struct dns_servers *server)
{
struct dns_server_groups *group = NULL;
int i = 0;
group = dns_conf_get_group(group_name);
group = _dns_conf_get_group(group_name);
if (group == NULL) {
return -1;
}
@@ -108,11 +125,11 @@ int dns_conf_get_group_set(const char *group_name, struct dns_servers *server)
return 0;
}
const char *dns_conf_get_group_name(const char *group_name)
static const char *_dns_conf_get_group_name(const char *group_name)
{
struct dns_server_groups *group = NULL;
group = dns_conf_get_group(group_name);
group = _dns_conf_get_group(group_name);
if (group == NULL) {
return NULL;
}
@@ -120,7 +137,7 @@ const char *dns_conf_get_group_name(const char *group_name)
return group->group_name;
}
void config_group_table_destroy(void)
static void _config_group_table_destroy(void)
{
struct dns_server_groups *group = NULL;
struct hlist_node *tmp = NULL;
@@ -133,7 +150,7 @@ void config_group_table_destroy(void)
}
}
int config_server(int argc, char *argv[], dns_server_type_t type, int default_port)
static int _config_server(int argc, char *argv[], dns_server_type_t type, int default_port)
{
int index = dns_conf_server_num;
struct dns_servers *server;
@@ -147,13 +164,13 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
int ttl = 0;
/* clang-format off */
static struct option long_options[] = {
{"blacklist-ip", 0, 0, 'b'},
{"check-edns", 0, 0, 'e'},
{"spki-pin", required_argument, 0, 'p'},
{"check-ttl", required_argument, 0, 't'},
{"group", required_argument, 0, 'g'},
{"exclude-default-group", 0, 0, 'E'},
{0, 0, 0, 0}
{"blacklist-ip", no_argument, NULL, 'b'}, /* filtering with blacklist-ip */
{"check-edns", no_argument, NULL, 'e'}, /* check edns */
{"spki-pin", required_argument, NULL, 'p'}, /* check SPKI pin */
{"check-ttl", required_argument, NULL, 't'}, /* check ttl */
{"group", required_argument, NULL, 'g'}, /* add to group */
{"exclude-default-group", no_argument, NULL, 'E'}, /* ecluse this from default group */
{NULL, no_argument, NULL, 0}
};
/* clang-format on */
if (argc <= 1) {
@@ -180,6 +197,7 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
port = default_port;
}
/* process extra options */
optind = 1;
while (1) {
opt = getopt_long_only(argc, argv, "", long_options, NULL);
@@ -202,6 +220,10 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
}
ttl = atoi(optarg);
/* Greater than 0, exact match
Equal to 0, match after check
Less than 0, match in the -N range after inspection
*/
if (ttl < -255 || ttl > 255) {
tlog(TLOG_ERROR, "ttl value is invalid.");
goto errout;
@@ -214,7 +236,7 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
break;
}
case 'g': {
if (dns_conf_get_group_set(optarg, server) != 0) {
if (_dns_conf_get_group_set(optarg, server) != 0) {
tlog(TLOG_ERROR, "add group failed.");
goto errout;
}
@@ -229,6 +251,7 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
}
}
/* add new server */
server->type = type;
server->port = port;
server->result_flag = result_flag;
@@ -247,7 +270,7 @@ errout:
return -1;
}
int config_domain_iter_cb(void *data, const unsigned char *key, uint32_t key_len, void *value)
static int _config_domain_iter_free(void *data, const unsigned char *key, uint32_t key_len, void *value)
{
struct dns_domain_rule *domain_rule = value;
int i = 0;
@@ -268,13 +291,13 @@ int config_domain_iter_cb(void *data, const unsigned char *key, uint32_t key_len
return 0;
}
void config_domain_destroy(void)
static void _config_domain_destroy(void)
{
art_iter(&dns_conf_domain_rule, config_domain_iter_cb, 0);
art_iter(&dns_conf_domain_rule, _config_domain_iter_free, NULL);
art_tree_destroy(&dns_conf_domain_rule);
}
void config_address_destroy(radix_node_t *node, void *cbctx)
static void _config_address_destroy(radix_node_t *node, void *cbctx)
{
if (node == NULL) {
return;
@@ -288,7 +311,7 @@ void config_address_destroy(radix_node_t *node, void *cbctx)
node->data = NULL;
}
int config_domain_rule_add(char *domain, enum domain_rule type, void *rule)
static int _config_domain_rule_add(char *domain, enum domain_rule type, void *rule)
{
struct dns_domain_rule *domain_rule = NULL;
struct dns_domain_rule *old_domain_rule = NULL;
@@ -297,6 +320,7 @@ int config_domain_rule_add(char *domain, enum domain_rule type, void *rule)
char domain_key[DNS_MAX_CONF_CNAME_LEN];
int len = 0;
/* Reverse string, for suffix match */
len = strlen(domain);
reverse_string(domain_key, domain, len);
domain_key[len] = '.';
@@ -307,6 +331,7 @@ int config_domain_rule_add(char *domain, enum domain_rule type, void *rule)
goto errout;
}
/* Get existing or create domain rule */
domain_rule = art_search(&dns_conf_domain_rule, (unsigned char *)domain_key, len);
if (domain_rule == NULL) {
add_domain_rule = malloc(sizeof(*add_domain_rule));
@@ -317,6 +342,7 @@ int config_domain_rule_add(char *domain, enum domain_rule type, void *rule)
domain_rule = add_domain_rule;
}
/* add new rule to domain */
if (domain_rule->rules[type]) {
free(domain_rule->rules[type]);
domain_rule->rules[type] = NULL;
@@ -324,6 +350,7 @@ int config_domain_rule_add(char *domain, enum domain_rule type, void *rule)
domain_rule->rules[type] = rule;
/* update domain rule */
if (add_domain_rule) {
old_domain_rule = art_insert(&dns_conf_domain_rule, (unsigned char *)domain_key, len, add_domain_rule);
if (old_domain_rule) {
@@ -341,7 +368,7 @@ errout:
return -1;
}
int config_domain_rule_flag_set(char *domain, unsigned int flag)
static int _config_domain_rule_flag_set(char *domain, unsigned int flag)
{
struct dns_domain_rule *domain_rule = NULL;
struct dns_domain_rule *old_domain_rule = NULL;
@@ -357,6 +384,7 @@ int config_domain_rule_flag_set(char *domain, unsigned int flag)
len++;
domain_key[len] = 0;
/* Get existing or create domain rule */
domain_rule = art_search(&dns_conf_domain_rule, (unsigned char *)domain_key, len);
if (domain_rule == NULL) {
add_domain_rule = malloc(sizeof(*add_domain_rule));
@@ -367,6 +395,7 @@ int config_domain_rule_flag_set(char *domain, unsigned int flag)
domain_rule = add_domain_rule;
}
/* add new rule to domain */
if (domain_rule->rules[DOMAIN_RULE_FLAGS] == NULL) {
rule_flags = malloc(sizeof(*rule_flags));
rule_flags->flags = 0;
@@ -376,6 +405,7 @@ int config_domain_rule_flag_set(char *domain, unsigned int flag)
rule_flags = domain_rule->rules[DOMAIN_RULE_FLAGS];
rule_flags->flags |= flag;
/* update domain rule */
if (add_domain_rule) {
old_domain_rule = art_insert(&dns_conf_domain_rule, (unsigned char *)domain_key, len, add_domain_rule);
if (old_domain_rule) {
@@ -393,7 +423,7 @@ errout:
return 0;
}
void config_ipset_table_destroy(void)
static void _config_ipset_table_destroy(void)
{
struct dns_ipset_name *ipset_name = NULL;
struct hlist_node *tmp = NULL;
@@ -406,7 +436,7 @@ void config_ipset_table_destroy(void)
}
}
const char *dns_conf_get_ipset(const char *ipsetname)
static const char *_dns_conf_get_ipset(const char *ipsetname)
{
uint32_t key = 0;
struct dns_ipset_name *ipset_name = NULL;
@@ -437,7 +467,7 @@ errout:
return NULL;
}
int config_ipset(void *data, int argc, char *argv[])
static int _config_ipset(void *data, int argc, char *argv[])
{
struct dns_ipset_rule *ipset_rule = NULL;
char domain[DNS_MAX_CONF_CNAME_LEN];
@@ -452,11 +482,13 @@ int config_ipset(void *data, int argc, char *argv[])
goto errout;
}
/* first field */
begin = strstr(value, "/");
if (begin == NULL) {
goto errout;
}
/* second field */
begin++;
end = strstr(begin, "/");
if (end == NULL) {
@@ -468,6 +500,7 @@ int config_ipset(void *data, int argc, char *argv[])
begin++;
}
/* Get domain */
len = end - begin;
memcpy(domain, begin, len);
domain[len] = '\0';
@@ -477,9 +510,11 @@ int config_ipset(void *data, int argc, char *argv[])
goto errout;
}
/* Process domain option */
if (strncmp(end + 1, "-", sizeof("-")) != 0) {
/* new ipset domain */
strncpy(ipsetname, end + 1, DNS_MAX_IPSET_NAMELEN);
ipset = dns_conf_get_ipset(ipsetname);
ipset = _dns_conf_get_ipset(ipsetname);
if (ipset == NULL) {
goto errout;
}
@@ -491,14 +526,15 @@ int config_ipset(void *data, int argc, char *argv[])
ipset_rule->ipsetname = ipset;
} else {
if (config_domain_rule_flag_set(domain, DOMAIN_FLAG_IPSET_IGNORE) != 0 ) {
/* ignore this domain */
if (_config_domain_rule_flag_set(domain, DOMAIN_FLAG_IPSET_IGNORE) != 0) {
goto errout;
}
return 0;
}
if (config_domain_rule_add(domain, DOMAIN_RULE_IPSET, ipset_rule) != 0) {
if (_config_domain_rule_add(domain, DOMAIN_RULE_IPSET, ipset_rule) != 0) {
goto errout;
}
@@ -512,7 +548,7 @@ errout:
return 0;
}
int config_address(void *data, int argc, char *argv[])
static int _config_address(void *data, int argc, char *argv[])
{
struct dns_address_IPV4 *address_ipv4 = NULL;
struct dns_address_IPV6 *address_ipv6 = NULL;
@@ -533,11 +569,13 @@ int config_address(void *data, int argc, char *argv[])
goto errout;
}
/* first field */
begin = strstr(value, "/");
if (begin == NULL) {
goto errout;
}
/* second field */
begin++;
end = strstr(begin, "/");
if (end == NULL) {
@@ -549,6 +587,7 @@ int config_address(void *data, int argc, char *argv[])
begin++;
}
/* get domain */
len = end - begin;
memcpy(domain, begin, len);
domain[len] = 0;
@@ -564,7 +603,8 @@ int config_address(void *data, int argc, char *argv[])
goto errout;
}
if (config_domain_rule_flag_set(domain, flag) != 0 ) {
/* add SOA rule */
if (_config_domain_rule_flag_set(domain, flag) != 0) {
goto errout;
}
@@ -580,12 +620,14 @@ int config_address(void *data, int argc, char *argv[])
goto errout;
}
if (config_domain_rule_flag_set(domain, flag) != 0 ) {
/* ignore rule */
if (_config_domain_rule_flag_set(domain, flag) != 0) {
goto errout;
}
return 0;
} else {
/* set address to domain */
if (parse_ip(end + 1, ip, &port) != 0) {
goto errout;
}
@@ -631,9 +673,10 @@ int config_address(void *data, int argc, char *argv[])
default:
goto errout;
}
}
}
if (config_domain_rule_add(domain, type, address) != 0) {
/* add domain to ART-tree */
if (_config_domain_rule_add(domain, type, address) != 0) {
goto errout;
}
@@ -647,22 +690,22 @@ errout:
return 0;
}
int config_server_udp(void *data, int argc, char *argv[])
static int _config_server_udp(void *data, int argc, char *argv[])
{
return config_server(argc, argv, DNS_SERVER_UDP, DEFAULT_DNS_PORT);
return _config_server(argc, argv, DNS_SERVER_UDP, DEFAULT_DNS_PORT);
}
int config_server_tcp(void *data, int argc, char *argv[])
static int _config_server_tcp(void *data, int argc, char *argv[])
{
return config_server(argc, argv, DNS_SERVER_TCP, DEFAULT_DNS_PORT);
return _config_server(argc, argv, DNS_SERVER_TCP, DEFAULT_DNS_PORT);
}
int config_server_tls(void *data, int argc, char *argv[])
static int _config_server_tls(void *data, int argc, char *argv[])
{
return config_server(argc, argv, DNS_SERVER_TLS, DEFAULT_DNS_TLS_PORT);
return _config_server(argc, argv, DNS_SERVER_TLS, DEFAULT_DNS_TLS_PORT);
}
int config_nameserver(void *data, int argc, char *argv[])
static int _config_nameserver(void *data, int argc, char *argv[])
{
struct dns_nameserver_rule *nameserver_rule = NULL;
char domain[DNS_MAX_CONF_CNAME_LEN];
@@ -677,11 +720,13 @@ int config_nameserver(void *data, int argc, char *argv[])
goto errout;
}
/* first field */
begin = strstr(value, "/");
if (begin == NULL) {
goto errout;
}
/* second field */
begin++;
end = strstr(begin, "/");
if (end == NULL) {
@@ -704,7 +749,7 @@ int config_nameserver(void *data, int argc, char *argv[])
if (strncmp(end + 1, "-", sizeof("-")) != 0) {
strncpy(group_name, end + 1, DNS_GROUP_NAME_LEN);
group = dns_conf_get_group_name(group_name);
group = _dns_conf_get_group_name(group_name);
if (group == NULL) {
goto errout;
}
@@ -716,14 +761,15 @@ int config_nameserver(void *data, int argc, char *argv[])
nameserver_rule->group_name = group;
} else {
if (config_domain_rule_flag_set(domain, DOMAIN_FLAG_NAMESERVER_IGNORE) != 0 ) {
/* ignore this domain */
if (_config_domain_rule_flag_set(domain, DOMAIN_FLAG_NAMESERVER_IGNORE) != 0) {
goto errout;
}
return 0;
}
if (config_domain_rule_add(domain, DOMAIN_RULE_NAMESERVER, nameserver_rule) != 0) {
if (_config_domain_rule_add(domain, DOMAIN_RULE_NAMESERVER, nameserver_rule) != 0) {
goto errout;
}
@@ -737,7 +783,7 @@ errout:
return 0;
}
radix_node_t *create_addr_node(char *addr)
static radix_node_t *_create_addr_node(char *addr)
{
radix_node_t *node;
void *p;
@@ -763,12 +809,12 @@ radix_node_t *create_addr_node(char *addr)
return node;
}
int config_iplist_rule(char *subnet, enum address_rule rule)
static int _config_iplist_rule(char *subnet, enum address_rule rule)
{
radix_node_t *node = NULL;
struct dns_ip_address_rule *ip_rule = NULL;
node = create_addr_node(subnet);
node = _create_addr_node(subnet);
if (node == NULL) {
return -1;
}
@@ -799,34 +845,34 @@ int config_iplist_rule(char *subnet, enum address_rule rule)
return 0;
}
int config_blacklist_ip(void *data, int argc, char *argv[])
static int _config_blacklist_ip(void *data, int argc, char *argv[])
{
if (argc <= 1) {
return -1;
}
return config_iplist_rule(argv[1], ADDRESS_RULE_BLACKLIST);
return _config_iplist_rule(argv[1], ADDRESS_RULE_BLACKLIST);
}
int conf_bogus_nxdomain(void *data, int argc, char *argv[])
static int _conf_bogus_nxdomain(void *data, int argc, char *argv[])
{
if (argc <= 1) {
return -1;
}
return config_iplist_rule(argv[1], ADDRESS_RULE_BOGUS);
return _config_iplist_rule(argv[1], ADDRESS_RULE_BOGUS);
}
int conf_ip_ignore(void *data, int argc, char *argv[])
static int _conf_ip_ignore(void *data, int argc, char *argv[])
{
if (argc <= 1) {
return -1;
}
return config_iplist_rule(argv[1], ADDRESS_RULE_IP_IGNORE);
return _config_iplist_rule(argv[1], ADDRESS_RULE_IP_IGNORE);
}
int conf_edns_client_subnet(void *data, int argc, char *argv[])
static int _conf_edns_client_subnet(void *data, int argc, char *argv[])
{
char *slash = NULL;
char *value = NULL;
@@ -876,7 +922,7 @@ errout:
return -1;
}
int config_log_level(void *data, int argc, char *argv[])
static int _config_log_level(void *data, int argc, char *argv[])
{
/* read log level and set */
char *value = argv[1];
@@ -896,23 +942,23 @@ int config_log_level(void *data, int argc, char *argv[])
return 0;
}
struct config_item config_item[] = {
static struct config_item _config_item[] = {
CONF_STRING("server-name", (char *)dns_conf_server_name, DNS_MAX_CONF_CNAME_LEN),
CONF_STRING("bind", dns_conf_server_ip, DNS_MAX_IPLEN),
CONF_STRING("bind-tcp", dns_conf_server_tcp_ip, DNS_MAX_IPLEN),
CONF_CUSTOM("server", config_server_udp, NULL),
CONF_CUSTOM("server-tcp", config_server_tcp, NULL),
CONF_CUSTOM("server-tls", config_server_tls, NULL),
CONF_CUSTOM("nameserver", config_nameserver, NULL),
CONF_CUSTOM("address", config_address, NULL),
CONF_CUSTOM("server", _config_server_udp, NULL),
CONF_CUSTOM("server-tcp", _config_server_tcp, NULL),
CONF_CUSTOM("server-tls", _config_server_tls, NULL),
CONF_CUSTOM("nameserver", _config_nameserver, NULL),
CONF_CUSTOM("address", _config_address, NULL),
CONF_YESNO("ipset-timeout", &dns_conf_ipset_timeout_enable),
CONF_CUSTOM("ipset", config_ipset, NULL),
CONF_CUSTOM("ipset", _config_ipset, NULL),
CONF_INT("tcp-idle-time", &dns_conf_tcp_idle_time, 0, 3600),
CONF_INT("cache-size", &dns_conf_cachesize, 0, CONF_INT_MAX),
CONF_YESNO("prefetch-domain", &dns_conf_prefetch),
CONF_YESNO("dualstack-ip-selection", &dns_conf_dualstack_ip_selection),
CONF_INT("dualstack-ip-selection-threshold", &dns_conf_dualstack_ip_selection_threshold, 0, 1000),
CONF_CUSTOM("log-level", config_log_level, NULL),
CONF_CUSTOM("log-level", _config_log_level, NULL),
CONF_STRING("log-file", (char *)dns_conf_log_file, DNS_MAX_PATH),
CONF_SIZE("log-size", &dns_conf_log_size, 0, 1024 * 1024 * 1024),
CONF_INT("log-num", &dns_conf_log_num, 0, 1024),
@@ -924,15 +970,15 @@ struct config_item config_item[] = {
CONF_INT("rr-ttl-min", &dns_conf_rr_ttl_min, 0, CONF_INT_MAX),
CONF_INT("rr-ttl-max", &dns_conf_rr_ttl_max, 0, CONF_INT_MAX),
CONF_YESNO("force-AAAA-SOA", &dns_conf_force_AAAA_SOA),
CONF_CUSTOM("blacklist-ip", config_blacklist_ip, NULL),
CONF_CUSTOM("bogus-nxdomain", conf_bogus_nxdomain, NULL),
CONF_CUSTOM("ignore-ip", conf_ip_ignore, NULL),
CONF_CUSTOM("edns-client-subnet", conf_edns_client_subnet, NULL),
CONF_CUSTOM("blacklist-ip", _config_blacklist_ip, NULL),
CONF_CUSTOM("bogus-nxdomain", _conf_bogus_nxdomain, NULL),
CONF_CUSTOM("ignore-ip", _conf_ip_ignore, NULL),
CONF_CUSTOM("edns-client-subnet", _conf_edns_client_subnet, NULL),
CONF_CUSTOM("conf-file", config_addtional_file, NULL),
CONF_END(),
};
int conf_printf(const char *file, int lineno, int ret)
static int _conf_printf(const char *file, int lineno, int ret)
{
if (ret == CONF_RET_ERR) {
tlog(TLOG_ERROR, "process config file '%s' failed at line %d.", file, lineno);
@@ -956,10 +1002,10 @@ int config_addtional_file(void *data, int argc, char *argv[])
return 0;
}
return load_conf(file_path, config_item, conf_printf);
return load_conf(file_path, _config_item, _conf_printf);
}
int _dns_server_load_conf_init(void)
static int _dns_server_load_conf_init(void)
{
dns_conf_address_rule.ipv4 = New_Radix();
dns_conf_address_rule.ipv6 = New_Radix();
@@ -978,19 +1024,19 @@ int _dns_server_load_conf_init(void)
void dns_server_load_exit(void)
{
config_domain_destroy();
Destroy_Radix(dns_conf_address_rule.ipv4, config_address_destroy, NULL);
Destroy_Radix(dns_conf_address_rule.ipv6, config_address_destroy, NULL);
config_ipset_table_destroy();
config_group_table_destroy();
_config_domain_destroy();
Destroy_Radix(dns_conf_address_rule.ipv4, _config_address_destroy, NULL);
Destroy_Radix(dns_conf_address_rule.ipv6, _config_address_destroy, NULL);
_config_ipset_table_destroy();
_config_group_table_destroy();
}
int dns_server_load_conf(const char *file)
{
int ret = 0;
_dns_server_load_conf_init();
openlog ("smartdns", LOG_CONS | LOG_NDELAY, LOG_LOCAL1);
ret = load_conf(file, config_item, conf_printf);
openlog("smartdns", LOG_CONS | LOG_NDELAY, LOG_LOCAL1);
ret = load_conf(file, _config_item, _conf_printf);
closelog();
return ret;
}

View File

@@ -33,13 +33,13 @@ enum domain_rule {
DOMAIN_RULE_MAX,
};
#define DOMAIN_FLAG_ADDR_SOA (1 << 0)
#define DOMAIN_FLAG_ADDR_SOA (1 << 0)
#define DOMAIN_FLAG_ADDR_IPV4_SOA (1 << 1)
#define DOMAIN_FLAG_ADDR_IPV6_SOA (1 << 2)
#define DOMAIN_FLAG_ADDR_IGN (1 << 3)
#define DOMAIN_FLAG_ADDR_IGN (1 << 3)
#define DOMAIN_FLAG_ADDR_IPV4_IGN (1 << 4)
#define DOMAIN_FLAG_ADDR_IPV6_IGN (1 << 5)
#define DOMAIN_FLAG_IPSET_IGNORE (1 << 6)
#define DOMAIN_FLAG_IPSET_IGNORE (1 << 6)
#define DOMAIN_FLAG_NAMESERVER_IGNORE (1 << 7)
#define SERVER_FLAG_EXCLUDE_DEFAULT (1 << 0)
@@ -172,4 +172,4 @@ int dns_server_load_conf(const char *file);
extern int config_addtional_file(void *data, int argc, char *argv[]);
#endif // !_DNS_CONF
#endif // !_DNS_CONF

View File

@@ -15,7 +15,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "dns_server.h"
#include "atomic.h"
#include "dns.h"
@@ -27,26 +29,16 @@
#include "list.h"
#include "tlog.h"
#include "util.h"
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <ifaddrs.h>
#include <linux/filter.h>
#include <netdb.h>
#include <netinet/icmp6.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/ip_icmp.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#define DNS_MAX_EVENTS 256
#define DNS_SERVER_TMOUT_TTL (5 * 60)
@@ -230,39 +222,47 @@ static int _dns_add_rrs(struct dns_packet *packet, struct dns_request *request)
int ret = 0;
char *domain = request->domain;
if (request->has_ptr) {
/* add PTR record */
char hostname[DNS_MAX_CNAME_LEN];
if (dns_conf_server_name[0] == 0) {
/* get local host name */
if (getdomainname(hostname, DNS_MAX_CNAME_LEN) != 0) {
if (gethostname(hostname, DNS_MAX_CNAME_LEN) != 0) {
return -1;
}
}
/* get host name again */
if (strncmp(hostname, "(none)", DNS_MAX_CNAME_LEN) == 0) {
if (gethostname(hostname, DNS_MAX_CNAME_LEN) != 0) {
return -1;
}
}
/* if hostname is (none), return smartdns */
if (strncmp(hostname, "(none)", DNS_MAX_CNAME_LEN) == 0) {
strncpy(hostname, "smartdns", DNS_MAX_CNAME_LEN);
}
} else {
/* return configured server name */
strncpy(hostname, dns_conf_server_name, DNS_MAX_CNAME_LEN);
}
ret = dns_add_PTR(packet, DNS_RRS_AN, request->domain, 30, hostname);
}
/* add CNAME record */
if (request->has_cname) {
ret |= dns_add_CNAME(packet, DNS_RRS_AN, request->domain, request->ttl_cname, request->cname);
domain = request->cname;
}
/* add A record */
if (request->has_ipv4 && request->qtype == DNS_T_A) {
ret |= dns_add_A(packet, DNS_RRS_AN, domain, request->ttl_v4, request->ipv4_addr);
}
/* add AAAA record */
if (request->has_ipv6 && request->qtype == DNS_T_AAAA) {
if (request->has_ipv4) {
ret |= dns_add_A(packet, DNS_RRS_AN, domain, request->ttl_v4, request->ipv4_addr);
@@ -270,6 +270,7 @@ static int _dns_add_rrs(struct dns_packet *packet, struct dns_request *request)
ret |= dns_add_AAAA(packet, DNS_RRS_AN, domain, request->ttl_v6, request->ipv6_addr);
}
/* add SOA record */
if (request->has_soa) {
ret |= dns_add_SOA(packet, DNS_RRS_NS, domain, 0, &request->soa);
}
@@ -307,7 +308,7 @@ static void _dns_server_client_get(struct dns_server_conn *client)
if (client == NULL) {
return;
}
if (atomic_inc_return(&client->refcnt) <= 0) {
tlog(TLOG_ERROR, "BUG: client ref is invalid.");
abort();
@@ -367,7 +368,7 @@ static int _dns_server_reply_tcp(struct dns_server_conn *client, void *packet, u
static int _dns_server_reply_udp(struct dns_request *request, struct dns_server_conn *client, unsigned char *inpacket, int inpacket_len)
{
int send_len = 0;
send_len = sendto(client->fd, inpacket, inpacket_len, 0, &request->addr, request->addr_len);
send_len = sendto(client->fd, inpacket, inpacket_len, 0, (struct sockaddr *)&request->addr, request->addr_len);
if (send_len != inpacket_len) {
tlog(TLOG_ERROR, "send failed.");
return -1;
@@ -424,26 +425,31 @@ static int _dns_reply(struct dns_request *request)
head.tc = 0;
head.rcode = request->rcode;
/* init a new DNS packet */
ret = dns_packet_init(packet, DNS_PACKSIZE, &head);
if (ret != 0) {
return -1;
}
/* add request domain */
ret = dns_add_domain(packet, request->domain, request->qtype, DNS_C_IN);
if (ret != 0) {
return -1;
}
/* add RECORDs */
ret = _dns_add_rrs(packet, request);
if (ret != 0) {
return -1;
}
/* encode to binary data */
encode_len = dns_encode(inpacket, DNS_IN_PACKSIZE, packet);
if (encode_len <= 0) {
return -1;
}
/* send request */
return _dns_reply_inpacket(request, inpacket, encode_len);
}
@@ -451,6 +457,7 @@ static int _dns_server_reply_SOA(int rcode, struct dns_request *request, struct
{
struct dns_soa *soa;
/* return SOA record */
request->rcode = rcode;
request->has_soa = 1;
request->has_ipv4 = 0;
@@ -471,6 +478,7 @@ static int _dns_server_reply_SOA(int rcode, struct dns_request *request, struct
return 0;
}
/* add ip to specific ipset */
static int _dns_setup_ipset(struct dns_request *request)
{
struct dns_ipset_rule *ipset_rule = NULL;
@@ -481,6 +489,7 @@ static int _dns_setup_ipset(struct dns_request *request)
return 0;
}
/* check ipset rule */
rule_flags = request->domain_rule->rules[DOMAIN_RULE_FLAGS];
if (rule_flags) {
if (rule_flags->flags & DOMAIN_FLAG_IPSET_IGNORE) {
@@ -493,10 +502,12 @@ static int _dns_setup_ipset(struct dns_request *request)
return 0;
}
/* add IPV4 to ipset */
if (request->has_ipv4 && request->qtype == DNS_T_A) {
ret |= ipset_add(ipset_rule->ipsetname, request->ipv4_addr, DNS_RR_A_LEN, request->ttl_v4 * 2);
}
/* add IPV6 to ipset */
if (request->has_ipv6 && request->qtype == DNS_T_AAAA) {
if (request->has_ipv4) {
ret |= ipset_add(ipset_rule->ipsetname, request->ipv4_addr, DNS_RR_A_LEN, request->ttl_v4 * 2);
@@ -509,7 +520,7 @@ static int _dns_setup_ipset(struct dns_request *request)
return ret;
}
int _dns_server_request_complete(struct dns_request *request)
static int _dns_server_request_complete(struct dns_request *request)
{
char *cname = NULL;
int cname_ttl = 0;
@@ -518,6 +529,7 @@ int _dns_server_request_complete(struct dns_request *request)
return 0;
}
/* if passthrouth, return */
if (request->passthrough) {
return 0;
}
@@ -530,15 +542,17 @@ int _dns_server_request_complete(struct dns_request *request)
if (request->qtype == DNS_T_A) {
if (request->has_ipv4) {
tlog(TLOG_INFO, "result: %s, rcode: %d, %d.%d.%d.%d\n", request->domain, request->rcode, request->ipv4_addr[0], request->ipv4_addr[1],
request->ipv4_addr[2], request->ipv4_addr[3]);
request->ipv4_addr[2], request->ipv4_addr[3]);
if (request->has_ping_result == 0 && request->ttl_v4 > DNS_SERVER_TMOUT_TTL) {
request->ttl_v4 = DNS_SERVER_TMOUT_TTL;
}
/* if doing prefetch, update cache only */
if (request->prefetch) {
dns_cache_replace(request->domain, cname, cname_ttl, request->ttl_v4, DNS_T_A, request->ipv4_addr, DNS_RR_A_LEN);
} else {
/* insert result to cache */
dns_cache_insert(request->domain, cname, cname_ttl, request->ttl_v4, DNS_T_A, request->ipv4_addr, DNS_RR_A_LEN);
}
@@ -548,8 +562,9 @@ int _dns_server_request_complete(struct dns_request *request)
} else if (request->qtype == DNS_T_AAAA) {
if (request->has_ipv4 && request->ping_ttl_v4 > 0) {
tlog(TLOG_INFO, "result: %s, rcode: %d, %d.%d.%d.%d\n", request->domain, request->rcode, request->ipv4_addr[0], request->ipv4_addr[1],
request->ipv4_addr[2], request->ipv4_addr[3]);
request->ipv4_addr[2], request->ipv4_addr[3]);
/* if ipv4 is fasting than ipv6, add ipv4 to cache, and return SOA for AAAA request */
if ((request->ping_ttl_v4 + (dns_conf_dualstack_ip_selection_threshold * 10)) < request->ping_ttl_v6 || request->ping_ttl_v6 < 0) {
tlog(TLOG_DEBUG, "Force IPV4 perfered.");
if (request->prefetch) {
@@ -560,22 +575,23 @@ int _dns_server_request_complete(struct dns_request *request)
return _dns_server_reply_SOA(DNS_RC_NOERROR, request, NULL);
}
}
if (request->has_ipv6) {
tlog(TLOG_INFO, "result: %s, rcode: %d, %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", request->domain, request->rcode,
request->ipv6_addr[0], request->ipv6_addr[1], request->ipv6_addr[2], request->ipv6_addr[3], request->ipv6_addr[4], request->ipv6_addr[5],
request->ipv6_addr[6], request->ipv6_addr[7], request->ipv6_addr[8], request->ipv6_addr[9], request->ipv6_addr[10], request->ipv6_addr[11],
request->ipv6_addr[12], request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]);
request->ipv6_addr[0], request->ipv6_addr[1], request->ipv6_addr[2], request->ipv6_addr[3], request->ipv6_addr[4], request->ipv6_addr[5],
request->ipv6_addr[6], request->ipv6_addr[7], request->ipv6_addr[8], request->ipv6_addr[9], request->ipv6_addr[10], request->ipv6_addr[11],
request->ipv6_addr[12], request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]);
if (request->has_ping_result == 0 && request->ttl_v6 > DNS_SERVER_TMOUT_TTL) {
request->ttl_v6 = DNS_SERVER_TMOUT_TTL;
}
/* if doing prefetch, update cache only */
if (request->prefetch) {
dns_cache_replace(request->domain, cname, cname_ttl, request->ttl_v6, DNS_T_AAAA, request->ipv6_addr, DNS_RR_AAAA_LEN);
} else {
/* insert result to cache */
dns_cache_insert(request->domain, cname, cname_ttl, request->ttl_v6, DNS_T_AAAA, request->ipv6_addr, DNS_RR_AAAA_LEN);
}
@@ -588,19 +604,21 @@ int _dns_server_request_complete(struct dns_request *request)
tlog(TLOG_INFO, "result: %s, qtype: %d, SOA", request->domain, request->qtype);
}
/* update ipset */
_dns_setup_ipset(request);
if (request->prefetch) {
return 0;
}
/* return result to client */
_dns_reply(request);
return 0;
}
void _dns_server_request_release(struct dns_request *request);
void _dns_server_request_remove(struct dns_request *request)
static void _dns_server_request_release(struct dns_request *request);
static void _dns_server_request_remove(struct dns_request *request)
{
pthread_mutex_lock(&server.request_list_lock);
if (list_empty(&request->list)) {
@@ -612,7 +630,7 @@ void _dns_server_request_remove(struct dns_request *request)
_dns_server_request_release(request);
}
void _dns_server_select_possible_ipaddress(struct dns_request *request)
static void _dns_server_select_possible_ipaddress(struct dns_request *request)
{
int maxhit = 0;
int bucket = 0;
@@ -627,6 +645,8 @@ void _dns_server_select_possible_ipaddress(struct dns_request *request)
return;
}
/* Return the most likely correct IP address */
/* Returns the IP with the most hits, or the last returned record is considered to be the most likely correct. */
hash_for_each_safe(request->ip_map, bucket, tmp, addr_map, node)
{
if (addr_map->addr_type != request->qtype) {
@@ -660,22 +680,22 @@ void _dns_server_select_possible_ipaddress(struct dns_request *request)
memcpy(request->ipv4_addr, selected_addr_map->ipv4_addr, DNS_RR_A_LEN);
request->ttl_v4 = DNS_SERVER_TMOUT_TTL;
tlog(TLOG_DEBUG, "possible result: %s, rcode: %d, %d.%d.%d.%d\n", request->domain, request->rcode, request->ipv4_addr[0], request->ipv4_addr[1],
request->ipv4_addr[2], request->ipv4_addr[3]);
request->ipv4_addr[2], request->ipv4_addr[3]);
} break;
case DNS_T_AAAA: {
memcpy(request->ipv6_addr, selected_addr_map->ipv6_addr, DNS_RR_AAAA_LEN);
request->ttl_v6 = DNS_SERVER_TMOUT_TTL;
tlog(TLOG_DEBUG, "possible result: %s, rcode: %d, %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", request->domain, request->rcode,
request->ipv6_addr[0], request->ipv6_addr[1], request->ipv6_addr[2], request->ipv6_addr[3], request->ipv6_addr[4], request->ipv6_addr[5],
request->ipv6_addr[6], request->ipv6_addr[7], request->ipv6_addr[8], request->ipv6_addr[9], request->ipv6_addr[10], request->ipv6_addr[11],
request->ipv6_addr[12], request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]);
tlog(TLOG_DEBUG, "possible result: %s, rcode: %d, %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", request->domain,
request->rcode, request->ipv6_addr[0], request->ipv6_addr[1], request->ipv6_addr[2], request->ipv6_addr[3], request->ipv6_addr[4],
request->ipv6_addr[5], request->ipv6_addr[6], request->ipv6_addr[7], request->ipv6_addr[8], request->ipv6_addr[9], request->ipv6_addr[10],
request->ipv6_addr[11], request->ipv6_addr[12], request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]);
} break;
default:
break;
}
}
void _dns_server_request_release(struct dns_request *request)
static void _dns_server_request_release(struct dns_request *request)
{
struct dns_ip_address *addr_map;
struct hlist_node *tmp;
@@ -709,7 +729,7 @@ void _dns_server_request_release(struct dns_request *request)
free(request);
}
void _dns_server_request_get(struct dns_request *request)
static void _dns_server_request_get(struct dns_request *request)
{
if (atomic_inc_return(&request->refcnt) <= 0) {
tlog(TLOG_ERROR, "BUG: request ref is invalid, %s", request->domain);
@@ -717,8 +737,8 @@ void _dns_server_request_get(struct dns_request *request)
}
}
void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *host, FAST_PING_RESULT result, struct sockaddr *addr, socklen_t addr_len,
int seqno, int ttl, struct timeval *tv, void *userptr)
static void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *host, FAST_PING_RESULT result, struct sockaddr *addr, socklen_t addr_len,
int seqno, int ttl, struct timeval *tv, void *userptr)
{
struct dns_request *request = userptr;
int may_complete = 0;
@@ -781,19 +801,20 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
tlog(TLOG_DEBUG, "from %s: seq=%d timeout\n", host, seqno);
}
/* If the ping delay is less than the threshold, the result is returned */
if (rtt < threshold) {
may_complete = 1;
} else if (rtt < (get_tick_count() - request->send_tick) * 10) {
may_complete = 1;
}
if (may_complete && request->has_ping_result == 1) {
_dns_server_request_complete(request);
_dns_server_request_remove(request);
}
}
int _dns_server_ping(struct dns_request *request, PING_TYPE type, char *ip, int timeout)
static int _dns_server_ping(struct dns_request *request, PING_TYPE type, char *ip, int timeout)
{
if (fast_ping_start(type, ip, 1, 0, timeout, _dns_server_ping_result, request) == NULL) {
return -1;
@@ -802,7 +823,7 @@ int _dns_server_ping(struct dns_request *request, PING_TYPE type, char *ip, int
return 0;
}
int _dns_ip_address_check_add(struct dns_request *request, unsigned char *addr, dns_type_t addr_type)
static int _dns_ip_address_check_add(struct dns_request *request, unsigned char *addr, dns_type_t addr_type)
{
uint32_t key = 0;
struct dns_ip_address *addr_map = NULL;
@@ -816,6 +837,7 @@ int _dns_ip_address_check_add(struct dns_request *request, unsigned char *addr,
return -1;
}
/* store the ip address and the number of hits */
key = jhash(addr, addr_len, 0);
pthread_mutex_lock(&request->ip_map_lock);
hash_for_each_possible(request->ip_map, addr_map, node, key)
@@ -875,6 +897,7 @@ static int _dns_server_ip_rule_check(struct dns_request *request, unsigned char
radix_node_t *node = NULL;
struct dns_ip_address_rule *rule = NULL;
/* Match IP address rules */
if (prefix_from_blob(addr, addr_len, addr_len * 8, &prefix) == NULL) {
return -1;
}
@@ -889,7 +912,7 @@ static int _dns_server_ip_rule_check(struct dns_request *request, unsigned char
default:
break;
}
if (node == NULL) {
return -1;
}
@@ -898,17 +921,20 @@ static int _dns_server_ip_rule_check(struct dns_request *request, unsigned char
return -1;
}
/* bogux-nxdomain */
rule = node->data;
if (rule->bogus) {
goto match;
}
/* blacklist-ip */
if (rule->blacklist) {
if (result_flag & DNSSERVER_FLAG_BLACKLIST_IP) {
goto match;
}
}
/* ignore-ip */
if (rule->ip_ignore) {
goto skip;
}
@@ -945,7 +971,6 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
return -1;
}
ping_timeout = ping_timeout - (now - request->send_tick);
if (ping_timeout > DNS_PING_TIMEOUT) {
ping_timeout = DNS_PING_TIMEOUT;
@@ -966,6 +991,7 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
}
}
_dns_server_request_get(request);
/* get A result */
dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
tlog(TLOG_DEBUG, "domain: %s TTL:%d IP: %d.%d.%d.%d", name, ttl, addr[0], addr[1], addr[2], addr[3]);
@@ -973,13 +999,16 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
/* ip rule check */
ip_check_result = _dns_server_ip_rule_check(request, addr, 4, DNS_T_A, result_flag);
if (ip_check_result == 0) {
/* match */
_dns_server_request_release(request);
break;
} else if (ip_check_result == -2) {
/* skip */
_dns_server_request_release(request);
continue;
}
/* if domain is not match */
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(request->cname, name, DNS_MAX_CNAME_LEN) != 0) {
_dns_server_request_release(request);
break;
@@ -995,13 +1024,16 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
}
}
/* Ad blocking result */
if (addr[0] == 0 || addr[0] == 127) {
/* If half of the servers return the same result, then the domain name result is the IP address. */
if (atomic_inc_return(&request->adblock) <= dns_server_num() / 2) {
_dns_server_request_release(request);
break;
}
}
/* add this ip to reqeust */
if (_dns_ip_address_check_add(request, addr, DNS_T_A) != 0) {
_dns_server_request_release(request);
break;
@@ -1010,6 +1042,7 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
request->rcode = packet->head.rcode;
sprintf(ip, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
/* start ping */
if (_dns_server_ping(request, PING_TYPE_ICMP, ip, ping_timeout) != 0) {
_dns_server_request_release(request);
}
@@ -1028,13 +1061,16 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
ip_check_result = _dns_server_ip_rule_check(request, addr, 16, DNS_T_AAAA, result_flag);
if (ip_check_result == 0) {
/* match */
_dns_server_request_release(request);
break;
} else if (ip_check_result == -2) {
/* skip */
_dns_server_request_release(request);
continue;
}
/* if domain is not match */
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(request->cname, name, DNS_MAX_CNAME_LEN) != 0) {
_dns_server_request_release(request);
break;
@@ -1050,6 +1086,7 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
}
}
/* add this ip to reqeust */
if (_dns_ip_address_check_add(request, addr, DNS_T_AAAA) != 0) {
_dns_server_request_release(request);
break;
@@ -1060,6 +1097,7 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
sprintf(ip, "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]);
/* start ping */
if (_dns_server_ping(request, PING_TYPE_ICMP, ip, ping_timeout) != 0) {
_dns_server_request_release(request);
}
@@ -1081,8 +1119,9 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
request->has_soa = 1;
request->rcode = packet->head.rcode;
dns_get_SOA(rrs, name, 128, &ttl, &request->soa);
tlog(TLOG_DEBUG, "domain: %s, qtype: %d, SOA: mname: %s, rname: %s, serial: %d, refresh: %d, retry: %d, expire: %d, minimum: %d", domain, request->qtype,
request->soa.mname, request->soa.rname, request->soa.serial, request->soa.refresh, request->soa.retry, request->soa.expire, request->soa.minimum);
tlog(TLOG_DEBUG, "domain: %s, qtype: %d, SOA: mname: %s, rname: %s, serial: %d, refresh: %d, retry: %d, expire: %d, minimum: %d", domain,
request->qtype, request->soa.mname, request->soa.rname, request->soa.serial, request->soa.refresh, request->soa.retry, request->soa.expire,
request->soa.minimum);
} break;
default:
tlog(TLOG_DEBUG, "%s, qtype: %d", name, rrs->type);
@@ -1116,6 +1155,7 @@ static int _dns_server_reply_passthrouth(struct dns_request *request, struct dns
return 0;
}
/* When passthrough, modify the id to be the id of the client request. */
dns_server_update_reply_packet_id(request, inpacket, inpacket_len);
ret = _dns_reply_inpacket(request, inpacket, inpacket_len);
@@ -1177,6 +1217,7 @@ static int _dns_server_process_ptr(struct dns_request *request, struct dns_packe
return -1;
}
/* Get the NIC IP and match it. If the match is successful, return the host name. */
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL) {
continue;
@@ -1217,6 +1258,7 @@ static int _dns_server_process_ptr(struct dns_request *request, struct dns_packe
}
}
/* Determine if the smartdns service is in effect. */
if (strstr(request->domain, "0.0.0.0.in-addr.arpa") != NULL) {
found = 1;
}
@@ -1259,12 +1301,14 @@ static struct dns_domain_rule *_dns_server_get_domain_rule(char *domain)
unsigned char matched_key[DNS_MAX_CNAME_LEN];
struct dns_domain_rule *domain_rule = NULL;
/* reverse domain string */
domain_len = strlen(domain);
reverse_string(domain_key, domain, domain_len);
domain_key[domain_len] = '.';
domain_len++;
domain_key[domain_len] = 0;
/* find domain rule */
if (likely(dns_conf_log_level > TLOG_INFO)) {
return art_substring(&dns_conf_domain_rule, (unsigned char *)domain_key, domain_len, NULL, NULL);
}
@@ -1293,6 +1337,7 @@ static int _dns_server_pre_process_rule_flags(struct dns_request *request, struc
goto errout;
}
/* get domain rule flag */
rule_flag = request->domain_rule->rules[DOMAIN_RULE_FLAGS];
if (rule_flag == NULL) {
goto errout;
@@ -1300,31 +1345,38 @@ static int _dns_server_pre_process_rule_flags(struct dns_request *request, struc
flags = rule_flag->flags;
if (flags & DOMAIN_FLAG_ADDR_IGN) {
/* ignore this domain */
goto errout;
}
if (flags & DOMAIN_FLAG_ADDR_SOA) {
/* return SOA */
_dns_server_reply_SOA(DNS_RC_NOERROR, request, packet);
return 0;
}
/* return specific type of address */
switch (request->qtype) {
case DNS_T_A:
if (flags & DOMAIN_FLAG_ADDR_IPV4_IGN) {
/* ignore this domain for A reqeust */
goto errout;
}
if (flags & DOMAIN_FLAG_ADDR_IPV4_SOA) {
/* return SOA for A request */
_dns_server_reply_SOA(DNS_RC_NOERROR, request, packet);
return 0;
}
break;
case DNS_T_AAAA:
if (flags & DOMAIN_FLAG_ADDR_IPV6_IGN) {
/* ignore this domain for A reqeust */
goto errout;
}
if (flags & DOMAIN_FLAG_ADDR_IPV6_SOA) {
/* return SOA for A request */
_dns_server_reply_SOA(DNS_RC_NOERROR, request, packet);
return 0;
}
@@ -1347,6 +1399,7 @@ static int _dns_server_process_address(struct dns_request *request, struct dns_p
goto errout;
}
/* address /domain/ rule */
switch (request->qtype) {
case DNS_T_A:
if (request->domain_rule->rules[DOMAIN_RULE_ADDRESS_IPV4] == NULL) {
@@ -1392,6 +1445,7 @@ static int _dns_server_process_cache(struct dns_request *request, struct dns_pac
goto errout;
}
/* Cache hits, returning results in the cache */
switch (request->qtype) {
case DNS_T_A:
memcpy(request->ipv4_addr, dns_cache->ipv4_addr, DNS_RR_A_LEN);
@@ -1444,6 +1498,7 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac
_dns_server_client_get(client);
/* decode packet */
tlog(TLOG_DEBUG, "recv query packet from %s, len = %d", gethost_by_addr(name, sizeof(name), (struct sockaddr *)from), inpacket_len);
decode_len = dns_decode(packet, DNS_PACKSIZE, inpacket, inpacket_len);
if (decode_len < 0) {
@@ -1466,7 +1521,7 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac
}
memset(request, 0, sizeof(*request));
pthread_mutex_init(&request->ip_map_lock, 0);
pthread_mutex_init(&request->ip_map_lock, NULL);
atomic_set(&request->adblock, 0);
atomic_set(&request->refcnt, 0);
request->ping_ttl_v4 = -1;
@@ -1476,6 +1531,7 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac
request->client = client;
INIT_LIST_HEAD(&request->list);
/* get client request address type */
if (_dns_recv_addr(request, from, from_len) != 0) {
goto errout;
}
@@ -1484,6 +1540,7 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac
memcpy(&request->head, &packet->head, sizeof(struct dns_head));
hash_init(request->ip_map);
/* get request domain and request qtype */
rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &rr_count);
if (rr_count > 1) {
goto errout;
@@ -1498,45 +1555,54 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac
request->qtype = qtype;
}
/* lookup domain rule */
request->domain_rule = _dns_server_get_domain_rule(request->domain);
switch (qtype) {
case DNS_T_PTR:
/* return PTR record */
ret = _dns_server_process_ptr(request, packet);
if (ret == 0) {
goto clean_exit;
} else {
/* pass to upstream server */
request->passthrough = 1;
}
break;
case DNS_T_A:
break;
case DNS_T_AAAA:
/* force return SOA */
if (dns_conf_force_AAAA_SOA == 1) {
_dns_server_reply_SOA(DNS_RC_NOERROR, request, packet);
goto clean_exit;
}
break;
default:
tlog(TLOG_DEBUG, "unsupport qtype: %d, domain: %s", qtype, request->domain);
request->passthrough = 1;
/* pass request to upstream server */
break;
}
/* process domain flag */
if (_dns_server_pre_process_rule_flags(request, packet) == 0) {
goto clean_exit;
}
/* process domain address */
if (_dns_server_process_address(request, packet) == 0) {
goto clean_exit;
}
/* process cache */
if (_dns_server_process_cache(request, packet) == 0) {
goto clean_exit;
}
if (request->domain_rule) {
/* Get the nameserver rule */
if (request->domain_rule->rules[DOMAIN_RULE_NAMESERVER]) {
struct dns_nameserver_rule *nameserver_rule = request->domain_rule->rules[DOMAIN_RULE_NAMESERVER];
group_name = nameserver_rule->group_name;
@@ -1553,6 +1619,7 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac
_dns_server_request_get(request);
request->send_tick = get_tick_count();
/* When the dual stack ip preference is enabled, both A and AAAA records are requested. */
if (qtype == DNS_T_AAAA && dns_conf_dualstack_ip_selection) {
_dns_server_request_get(request);
request->request_wait++;
@@ -1601,7 +1668,7 @@ static int _dns_server_prefetch_request(char *domain, dns_type_t qtype)
goto errout;
}
memset(request, 0, sizeof(*request));
pthread_mutex_init(&request->ip_map_lock, 0);
pthread_mutex_init(&request->ip_map_lock, NULL);
atomic_set(&request->adblock, 0);
request->ping_ttl_v4 = -1;
request->ping_ttl_v6 = -1;
@@ -1613,6 +1680,7 @@ static int _dns_server_prefetch_request(char *domain, dns_type_t qtype)
hash_init(request->ip_map);
strncpy(request->domain, domain, DNS_MAX_CNAME_LEN);
/* lookup domain rule */
request->domain_rule = _dns_server_get_domain_rule(request->domain);
tlog(TLOG_INFO, "prefetch domain %s, qtype = %d\n", request->domain, qtype);
@@ -1627,11 +1695,14 @@ static int _dns_server_prefetch_request(char *domain, dns_type_t qtype)
request->request_wait++;
if (request->domain_rule) {
/* get nameserver rule */
if (request->domain_rule->rules[DOMAIN_RULE_NAMESERVER]) {
struct dns_nameserver_rule *nameserver_rule = request->domain_rule->rules[DOMAIN_RULE_NAMESERVER];
group_name = nameserver_rule->group_name;
}
}
/* send request */
dns_client_query(request->domain, qtype, dns_server_resolve_callback, request, group_name);
return 0;
@@ -1724,10 +1795,11 @@ errout:
return -1;
}
int _dns_server_tcp_recv(struct dns_server_conn *dnsserver)
static int _dns_server_tcp_recv(struct dns_server_conn *dnsserver)
{
int len = 0;
/* Receive data */
while (dnsserver->recvbuff.size < sizeof(dnsserver->recvbuff.buf)) {
if (dnsserver->recvbuff.size == sizeof(dnsserver->recvbuff.buf)) {
return 0;
@@ -1750,7 +1822,7 @@ int _dns_server_tcp_recv(struct dns_server_conn *dnsserver)
return 0;
}
int _dns_server_tcp_process_one_request(struct dns_server_conn *dnsserver)
static int _dns_server_tcp_process_one_request(struct dns_server_conn *dnsserver)
{
int request_len = 0;
int total_len = dnsserver->recvbuff.size;
@@ -1758,12 +1830,14 @@ int _dns_server_tcp_process_one_request(struct dns_server_conn *dnsserver)
unsigned char *request_data = NULL;
int ret = 0;
/* Handling multiple requests */
for (;;) {
if ((total_len - proceed_len) <= sizeof(unsigned short)) {
ret = 1;
break;
}
/* Get record length */
request_data = (unsigned char *)(dnsserver->recvbuff.buf + proceed_len);
request_len = ntohs(*((unsigned short *)(request_data)));
@@ -1779,6 +1853,7 @@ int _dns_server_tcp_process_one_request(struct dns_server_conn *dnsserver)
request_data = (unsigned char *)(dnsserver->recvbuff.buf + proceed_len + sizeof(unsigned short));
/* process one record */
if (_dns_server_recv(dnsserver, request_data, request_len, &dnsserver->addr, dnsserver->addr_len) != 0) {
tlog(TLOG_ERROR, "process tcp request failed.");
return -1;
@@ -1796,7 +1871,7 @@ int _dns_server_tcp_process_one_request(struct dns_server_conn *dnsserver)
return ret;
}
int _dns_server_tcp_process_requests(struct dns_server_conn *client)
static int _dns_server_tcp_process_requests(struct dns_server_conn *client)
{
int recv_ret = 0;
int request_ret = 0;
@@ -1814,14 +1889,17 @@ int _dns_server_tcp_process_requests(struct dns_server_conn *client)
request_ret = _dns_server_tcp_process_one_request(client);
if (request_ret < 0) {
/* failed */
return -1;
}
if (request_ret == 1 && is_eof == 1) {
/* failed or remote shutdown */
return -1;
}
if (recv_ret == 1 && request_ret == 1) {
/* process complete */
return 0;
}
}
@@ -1829,7 +1907,7 @@ int _dns_server_tcp_process_requests(struct dns_server_conn *client)
return 0;
}
int _dns_server_tcp_send(struct dns_server_conn *client)
static int _dns_server_tcp_send(struct dns_server_conn *client)
{
int len;
while (client->sndbuff.size > 0) {
@@ -1894,7 +1972,7 @@ static int _dns_server_process(struct dns_server_conn *dnsserver, struct epoll_e
}
}
void _dns_server_tcp_ping_check(struct dns_request *request)
static void _dns_server_tcp_ping_check(struct dns_request *request)
{
struct dns_ip_address *addr_map;
int bucket = 0;
@@ -1908,6 +1986,7 @@ void _dns_server_tcp_ping_check(struct dns_request *request)
return;
}
/* start tcping */
pthread_mutex_lock(&request->ip_map_lock);
hash_for_each(request->ip_map, bucket, addr_map, node)
{
@@ -1939,21 +2018,23 @@ void _dns_server_tcp_ping_check(struct dns_request *request)
request->has_ping_tcp = 1;
}
void _dns_server_prefetch_domain(struct dns_cache *dns_cache)
static void _dns_server_prefetch_domain(struct dns_cache *dns_cache)
{
/* If there are still hits, continue pre-fetching */
if (dns_cache->hitnum <= 0) {
return;
}
dns_cache->hitnum--;
/* start prefetch domain */
tlog(TLOG_DEBUG, "prefetch by cache %s, qtype %d, ttl %d, hitnum %d", dns_cache->domain, dns_cache->qtype, dns_cache->ttl, dns_cache->hitnum);
if (_dns_server_prefetch_request(dns_cache->domain, dns_cache->qtype) != 0) {
tlog(TLOG_ERROR, "prefetch domain %s, qtype %d, failed.", dns_cache->domain, dns_cache->qtype);
}
}
void _dns_server_tcp_idle_check(void)
static void _dns_server_tcp_idle_check(void)
{
struct dns_server_conn *client, *tmp;
time_t now;
@@ -1973,13 +2054,14 @@ void _dns_server_tcp_idle_check(void)
}
}
void _dns_server_period_run_second(void)
static void _dns_server_period_run_second(void)
{
static unsigned int sec = 0;
sec++;
if (sec % 2 == 0) {
if (dns_conf_prefetch) {
/* do pre-fetching */
dns_cache_invalidate(_dns_server_prefetch_domain, 3);
} else {
dns_cache_invalidate(NULL, 0);
@@ -1989,7 +2071,7 @@ void _dns_server_period_run_second(void)
_dns_server_tcp_idle_check();
}
void _dns_server_period_run(void)
static void _dns_server_period_run(void)
{
struct dns_request *request, *tmp;
static unsigned int msec = 0;
@@ -2005,6 +2087,7 @@ void _dns_server_period_run(void)
pthread_mutex_lock(&server.request_list_lock);
list_for_each_entry_safe(request, tmp, &server.request_list, list)
{
/* Need to use tcping detection speed */
if (request->send_tick < now - DNS_TCPPING_START && request->has_ping_tcp == 0) {
_dns_server_request_get(request);
list_add_tail(&request->check_list, &check_list);
@@ -2099,7 +2182,7 @@ errout:
return NULL;
}
int _dns_server_start_udp(void)
static int _dns_server_start_udp(void)
{
struct epoll_event event;
@@ -2118,7 +2201,7 @@ int _dns_server_start_udp(void)
return 0;
}
int _dns_server_start_tcp(void)
static int _dns_server_start_tcp(void)
{
struct epoll_event event;
@@ -2151,7 +2234,7 @@ int dns_server_start(void)
return 0;
}
int _dns_create_socket(const char *host_ip, int type)
static int _dns_create_socket(const char *host_ip, int type)
{
int fd = -1;
struct addrinfo *gai = NULL;
@@ -2213,7 +2296,7 @@ errout:
return -1;
}
int _dns_server_socket(void)
static int _dns_server_socket(void)
{
int fd_udp = -1;
int fd_tcp = -1;
@@ -2253,7 +2336,7 @@ errout:
return -1;
}
void _dns_server_close_socket(void)
static void _dns_server_close_socket(void)
{
struct dns_server_conn *client, *tmp;
@@ -2273,7 +2356,7 @@ void _dns_server_close_socket(void)
}
}
int _dns_server_audit_init(void)
static int _dns_server_audit_init(void)
{
char *audit_file = SMARTDNS_AUDIT_FILE;
if (dns_conf_audit_enable == 0) {
@@ -2328,7 +2411,7 @@ int dns_server_init(void)
goto errout;
}
pthread_mutex_init(&server.request_list_lock, 0);
pthread_mutex_init(&server.request_list_lock, NULL);
INIT_LIST_HEAD(&server.request_list);
server.epoll_fd = epollfd;
server.run = 1;

View File

@@ -1,12 +1,21 @@
#ifndef _SMART_DNS_SERVER_H
#define _SMART_DNS_SERVER_H
#ifdef __cpluscplus
extern "C" {
#endif
int dns_server_init(void);
int dns_server_run(void);
int dns_server_start(void);
void dns_server_stop(void);
void dns_server_exit(void);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -45,9 +45,9 @@
#define ICMP_INPACKET_SIZE 1024
#ifndef ICMP_FILTER
#define ICMP_FILTER 1
#define ICMP_FILTER 1
struct icmp_filter {
uint32_t data;
uint32_t data;
};
#endif
@@ -142,7 +142,7 @@ static struct fast_ping_struct ping;
static atomic_t ping_sid = ATOMIC_INIT(0);
static int bool_print_log = 1;
uint16_t _fast_ping_checksum(uint16_t *header, size_t len)
static uint16_t _fast_ping_checksum(uint16_t *header, size_t len)
{
uint32_t sum = 0;
int i;
@@ -154,7 +154,7 @@ uint16_t _fast_ping_checksum(uint16_t *header, size_t len)
return htons(~((sum >> 16) + (sum & 0xffff)));
}
void _fast_ping_install_filter_v6(int sock)
static void _fast_ping_install_filter_v6(int sock)
{
struct icmp6_filter icmp6_filter;
ICMP6_FILTER_SETBLOCKALL(&icmp6_filter);
@@ -186,7 +186,7 @@ void _fast_ping_install_filter_v6(int sock)
}
}
void _fast_ping_install_filter_v4(int sock)
static void _fast_ping_install_filter_v4(int sock)
{
static int once;
static struct sock_filter insns[] = {
@@ -350,8 +350,8 @@ static int _fast_ping_sendping_v6(struct ping_host_struct *ping_host)
icmp6->icmp6_id = ping.ident;
icmp6->icmp6_seq = htons(ping_host->seq);
gettimeofday(&packet->msg.tv, 0);
gettimeofday(&ping_host->last, 0);
gettimeofday(&packet->msg.tv, NULL);
gettimeofday(&ping_host->last, NULL);
packet->msg.sid = ping_host->sid;
packet->msg.cookie = ping_host->cookie;
packet->msg.seq = ping_host->seq;
@@ -397,8 +397,8 @@ static int _fast_ping_sendping_v4(struct ping_host_struct *ping_host)
icmp->icmp_id = ping.ident;
icmp->icmp_seq = htons(ping_host->seq);
gettimeofday(&packet->msg.tv, 0);
gettimeofday(&ping_host->last, 0);
gettimeofday(&packet->msg.tv, NULL);
gettimeofday(&ping_host->last, NULL);
packet->msg.sid = ping_host->sid;
packet->msg.seq = ping_host->seq;
packet->msg.cookie = ping_host->cookie;
@@ -449,7 +449,7 @@ static int _fast_ping_sendping_udp(struct ping_host_struct *ping_host)
memset(&dns_head, 0, sizeof(dns_head));
dns_head.id = htons(ping_host->sid);
dns_head.flag = flag;
gettimeofday(&ping_host->last, 0);
gettimeofday(&ping_host->last, NULL);
len = sendto(fd, &dns_head, sizeof(dns_head), 0, (struct sockaddr *)&ping_host->addr, ping_host->addr_len);
if (len < 0 || len != sizeof(dns_head)) {
int err = errno;
@@ -499,13 +499,13 @@ static int _fast_ping_sendping_tcp(struct ping_host_struct *ping_host)
bool_print_log = 0;
}
tlog(TLOG_ERROR, "connect %s, id %d, %s", gethost_by_addr(ping_host_name, sizeof(ping_host_name), (struct sockaddr *)&ping_host->addr), ping_host->sid,
strerror(errno));
tlog(TLOG_ERROR, "connect %s, id %d, %s", gethost_by_addr(ping_host_name, sizeof(ping_host_name), (struct sockaddr *)&ping_host->addr),
ping_host->sid, strerror(errno));
goto errout;
}
}
gettimeofday(&ping_host->last, 0);
gettimeofday(&ping_host->last, NULL);
ping_host->fd = fd;
memset(&event, 0, sizeof(event));
event.events = EPOLLIN | EPOLLOUT | EPOLLERR;
@@ -528,7 +528,7 @@ errout:
static int _fast_ping_sendping(struct ping_host_struct *ping_host)
{
int ret = -1;
gettimeofday(&ping_host->last, 0);
gettimeofday(&ping_host->last, NULL);
if (ping_host->type == FAST_PING_ICMP) {
ret = _fast_ping_sendping_v4(ping_host);
@@ -741,7 +741,7 @@ errout:
return -1;
}
void fast_ping_print_result(struct ping_host_struct *ping_host, const char *host, FAST_PING_RESULT result, struct sockaddr *addr, socklen_t addr_len, int seqno,
static void _fast_ping_print_result(struct ping_host_struct *ping_host, const char *host, FAST_PING_RESULT result, struct sockaddr *addr, socklen_t addr_len, int seqno,
int ttl, struct timeval *tv, void *userptr)
{
if (result == PING_RESULT_RESPONSE) {
@@ -882,7 +882,7 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
if (ping_callback) {
ping_host->ping_callback = ping_callback;
} else {
ping_host->ping_callback = fast_ping_print_result;
ping_host->ping_callback = _fast_ping_print_result;
}
ping_host->interval = (timeout > interval) ? timeout : interval;
ping_host->addr_len = gai->ai_addrlen;
@@ -1028,7 +1028,7 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *
return packet;
}
struct fast_ping_packet *_fast_ping_recv_packet(struct ping_host_struct *ping_host, struct msghdr *msg, u_char *inpacket, int len, struct timeval *tvrecv)
static struct fast_ping_packet *_fast_ping_recv_packet(struct ping_host_struct *ping_host, struct msghdr *msg, u_char *inpacket, int len, struct timeval *tvrecv)
{
struct fast_ping_packet *packet = NULL;
@@ -1325,7 +1325,7 @@ static void _fast_ping_period_run(void)
struct timeval now;
struct timeval interval;
int64_t millisecond;
gettimeofday(&now, 0);
gettimeofday(&now, NULL);
LIST_HEAD(action);
pthread_mutex_lock(&ping.map_lock);
@@ -1422,7 +1422,7 @@ static void *_fast_ping_work(void *arg)
continue;
}
gettimeofday(&tvnow, 0);
gettimeofday(&tvnow, NULL);
for (i = 0; i < num; i++) {
struct epoll_event *event = &events[i];
struct ping_host_struct *ping_host = (struct ping_host_struct *)event->data.ptr;
@@ -1456,8 +1456,8 @@ int fast_ping_init(void)
goto errout;
}
pthread_mutex_init(&ping.map_lock, 0);
pthread_mutex_init(&ping.lock, 0);
pthread_mutex_init(&ping.map_lock, NULL);
pthread_mutex_init(&ping.lock, NULL);
hash_init(ping.addrmap);
ping.epoll_fd = epollfd;
ping.ident = (getpid() & 0XFFFF);

View File

@@ -237,4 +237,4 @@ int art_iter_prefix(art_tree *t, const unsigned char *prefix, int prefix_len, ar
}
#endif
#endif
#endif

View File

@@ -11,7 +11,7 @@
* Atomic type.
*/
typedef struct {
volatile int counter;
int counter;
} atomic_t;
#define ATOMIC_INIT(i) { (i) }
@@ -154,3 +154,4 @@ static inline int atomic_add_negative( int i, atomic_t *v )
}
#endif

View File

@@ -130,4 +130,4 @@ static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
return __bitmap_and(dst, src1, src2, nbits);
}
#endif /* _PERF_BITOPS_H */
#endif /* _PERF_BITOPS_H */

View File

@@ -197,4 +197,4 @@ static inline uint32_t rol32(uint32_t word, unsigned int shift)
return (word << shift) | (word >> ((-shift) & 31));
}
#endif
#endif

View File

@@ -86,7 +86,7 @@ struct config_item_size {
#define CONF_END() \
{ \
0, 0, 0 \
NULL, NULL, NULL \
}
extern int conf_custom(const char *item, void *data, int argc, char *argv[]);
@@ -118,4 +118,4 @@ int load_conf(const char *file, struct config_item items[], conf_error_handler h
void load_exit(void);
#endif // !_GENERIC_CONF_H
#endif // !_GENERIC_CONF_H

View File

@@ -74,4 +74,4 @@ extern unsigned long find_first_bit(const unsigned long *addr,
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size);
#endif
#endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */
#endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */

View File

@@ -114,4 +114,4 @@
#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
#define round_down(x, y) ((x) & ~__round_mask(x, y))
#endif /* _TOOLS_LINUX_COMPILER_H */
#endif /* _TOOLS_LINUX_COMPILER_H */

View File

@@ -210,4 +210,4 @@ hash_string(const char *str)
return(v);
}
#endif /* _GENERIC_HASH_H */
#endif /* _GENERIC_HASH_H */

View File

@@ -147,4 +147,4 @@ static inline void hash_del(struct hlist_node *node)
hlist_for_each_entry_safe(obj, tmp,\
&name[hash_min(key, HASH_BITS(name))], member)
#endif
#endif

View File

@@ -181,4 +181,4 @@ static inline uint32_t jhash_1word(uint32_t a, uint32_t initval)
return __jhash_nwords(a, 0, 0, initval + JHASH_INITVAL + (1 << 2));
}
#endif /* _JHASH_H */
#endif /* _JHASH_H */

View File

@@ -789,4 +789,4 @@ static inline void list_del_range(struct list_head *begin,
#define list_for_each_from(pos, head) \
for (; pos != (head); pos = pos->next)
#endif /* _GENERIC_LIST_H */
#endif /* _GENERIC_LIST_H */

View File

@@ -159,3 +159,4 @@ const char *prefix_addr_ntop(prefix_t *prefix, char *buf, size_t len);
const char *prefix_ntop(prefix_t *prefix, char *buf, size_t len);
#endif /* _RADIX_H */

View File

@@ -285,3 +285,4 @@ rb_erase_augmented(struct rb_node *node, struct rb_root *root,
}
#endif /* _GENERIC_RBTREE_H */

View File

@@ -49,7 +49,7 @@
static int verbose_screen;
void help(void)
static void _help(void)
{
/* clang-format off */
char *help = ""
@@ -69,7 +69,7 @@ void help(void)
printf("%s", help);
}
int smartdns_load_from_resolv(void)
static int _smartdns_load_from_resolv(void)
{
FILE *fp = NULL;
char line[MAX_LINE_LEN];
@@ -120,7 +120,7 @@ int smartdns_load_from_resolv(void)
return ret;
}
int smartdns_add_servers(void)
static int _smartdns_add_servers(void)
{
int i = 0;
int j = 0;
@@ -129,8 +129,8 @@ int smartdns_add_servers(void)
struct dns_servers *server = NULL;
for (i = 0; i < dns_conf_server_num; i++) {
ret = dns_client_add_server(dns_conf_servers[i].server, dns_conf_servers[i].port, dns_conf_servers[i].type, dns_conf_servers[i].server_flag, dns_conf_servers[i].result_flag,
dns_conf_servers[i].ttl, dns_conf_servers[i].spki);
ret = dns_client_add_server(dns_conf_servers[i].server, dns_conf_servers[i].port, dns_conf_servers[i].type, dns_conf_servers[i].server_flag,
dns_conf_servers[i].result_flag, dns_conf_servers[i].ttl, dns_conf_servers[i].spki);
if (ret != 0) {
tlog(TLOG_ERROR, "add server failed, %s:%d", dns_conf_servers[i].server, dns_conf_servers[i].port);
return -1;
@@ -158,11 +158,10 @@ int smartdns_add_servers(void)
}
}
return 0;
}
int smartdns_set_ecs_ip(void)
static int _smartdns_set_ecs_ip(void)
{
int ret = 0;
if (dns_conf_ipv4_ecs.enable) {
@@ -176,52 +175,7 @@ int smartdns_set_ecs_ip(void)
return ret;
}
int create_pid_file(const char *pid_file)
{
int fd;
int flags;
char buff[TMP_BUFF_LEN_32];
/* create pid file, and lock this file */
fd = open(pid_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
if (fd == -1) {
fprintf(stderr, "create pid file failed, %s\n", strerror(errno));
return -1;
}
flags = fcntl(fd, F_GETFD);
if (flags < 0) {
fprintf(stderr, "Could not get flags for PID file %s\n", pid_file);
goto errout;
}
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1) {
fprintf(stderr, "Could not set flags for PID file %s\n", pid_file);
goto errout;
}
if (lockf(fd, F_TLOCK, 0) < 0) {
fprintf(stderr, "Server is already running.\n");
goto errout;
}
snprintf(buff, TMP_BUFF_LEN_32, "%d\n", getpid());
if (write(fd, buff, strnlen(buff, TMP_BUFF_LEN_32)) < 0) {
fprintf(stderr, "write pid to file failed, %s.\n", strerror(errno));
goto errout;
}
return 0;
errout:
if (fd > 0) {
close(fd);
}
return -1;
}
int smartdns_init_ssl(void)
static int _smartdns_init_ssl(void)
{
SSL_load_error_strings();
SSL_library_init();
@@ -231,7 +185,7 @@ int smartdns_init_ssl(void)
return 0;
}
int smartdns_destroy_ssl(void)
static int _smartdns_destroy_ssl(void)
{
SSL_CRYPTO_thread_cleanup();
ERR_free_strings();
@@ -240,7 +194,7 @@ int smartdns_destroy_ssl(void)
return 0;
}
int smartdns_init(void)
static int _smartdns_init(void)
{
int ret;
char *logfile = SMARTDNS_LOG_FILE;
@@ -260,13 +214,13 @@ int smartdns_init(void)
tlog(TLOG_NOTICE, "smartdns starting...(Copyright (C) Nick Peng <pymumu@gmail.com>, build:%s %s)", __DATE__, __TIME__);
if (smartdns_init_ssl() != 0) {
if (_smartdns_init_ssl() != 0) {
tlog(TLOG_ERROR, "init ssl failed.");
goto errout;
}
if (dns_conf_server_num <= 0) {
if (smartdns_load_from_resolv() != 0) {
if (_smartdns_load_from_resolv() != 0) {
tlog(TLOG_ERROR, "load dns from resolv failed.");
goto errout;
}
@@ -289,13 +243,13 @@ int smartdns_init(void)
tlog(TLOG_ERROR, "start dns client failed.\n");
goto errout;
}
ret = smartdns_add_servers();
ret = _smartdns_add_servers();
if (ret != 0) {
tlog(TLOG_ERROR, "add servers failed.");
goto errout;
}
ret = smartdns_set_ecs_ip();
ret = _smartdns_set_ecs_ip();
if (ret != 0) {
tlog(TLOG_WARN, "set ecs ip address failed.");
}
@@ -306,57 +260,57 @@ errout:
return -1;
}
int smartdns_run(void)
static int _smartdns_run(void)
{
return dns_server_run();
}
void smartdns_exit(void)
static void _smartdns_exit(void)
{
dns_server_exit();
dns_client_exit();
fast_ping_exit();
smartdns_destroy_ssl();
_smartdns_destroy_ssl();
tlog_exit();
dns_server_load_exit();
}
void sig_exit(int signo)
static void _sig_exit(int signo)
{
dns_server_stop();
}
void sig_error_exit(int signo, siginfo_t *siginfo, void *ct)
static void _sig_error_exit(int signo, siginfo_t *siginfo, void *ct)
{
unsigned long PC = 0;
ucontext_t *context = ct;
#if defined(__i386__)
int *pgregs = (int*)(&(context->uc_mcontext.gregs));
PC = pgregs[REG_EIP];
#elif defined(__x86_64__)
int *pgregs = (int*)(&(context->uc_mcontext.gregs));
PC = pgregs[REG_RIP];
int *pgregs = (int *)(&(context->uc_mcontext.gregs));
PC = pgregs[REG_EIP];
#elif defined(__x86_64__)
int *pgregs = (int *)(&(context->uc_mcontext.gregs));
PC = pgregs[REG_RIP];
#elif defined(__aarch64__) || defined(__arm__)
PC = context->uc_mcontext.arm_pc;
PC = context->uc_mcontext.arm_pc;
#elif defined(__mips__)
PC = context->uc_mcontext.pc;
PC = context->uc_mcontext.pc;
#endif
tlog(TLOG_ERROR, "process exit with signal %d, code = %d, errno = %d, pid = %d, self = %d, pc = %#lx, addr = %#lx, build(%s %s)\n", signo, siginfo->si_code, siginfo->si_errno,
siginfo->si_pid, getpid(), PC, (unsigned long)siginfo->si_addr, __DATE__, __TIME__);
tlog(TLOG_ERROR, "process exit with signal %d, code = %d, errno = %d, pid = %d, self = %d, pc = %#lx, addr = %#lx, build(%s %s)\n", signo, siginfo->si_code,
siginfo->si_errno, siginfo->si_pid, getpid(), PC, (unsigned long)siginfo->si_addr, __DATE__, __TIME__);
sleep(1);
_exit(0);
}
int sig_list[] = {SIGSEGV, SIGABRT, SIGBUS, SIGILL, SIGFPE};
static int sig_list[] = {SIGSEGV, SIGABRT, SIGBUS, SIGILL, SIGFPE};
int sig_num = sizeof(sig_list) / sizeof(int);
static int sig_num = sizeof(sig_list) / sizeof(int);
void reg_signal(void)
static void _reg_signal(void)
{
struct sigaction act, old;
int i = 0;
act.sa_sigaction = sig_error_exit;
act.sa_sigaction = _sig_error_exit;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART | SA_SIGINFO;
@@ -395,7 +349,7 @@ int main(int argc, char *argv[])
verbose_screen = 1;
break;
case 'h':
help();
_help();
return 1;
}
}
@@ -408,7 +362,7 @@ int main(int argc, char *argv[])
}
if (signal_ignore == 0) {
reg_signal();
_reg_signal();
}
if (dns_server_load_conf(config_file) != 0) {
@@ -420,17 +374,17 @@ int main(int argc, char *argv[])
goto errout;
}
ret = smartdns_init();
ret = _smartdns_init();
if (ret != 0) {
usleep(100000);
goto errout;
}
signal(SIGINT, sig_exit);
signal(SIGINT, _sig_exit);
signal(SIGPIPE, SIG_IGN);
atexit(smartdns_exit);
atexit(_smartdns_exit);
return smartdns_run();
return _smartdns_run();
errout:

View File

@@ -97,10 +97,10 @@ struct tlog_info_inter {
typedef int (*list_callback)(const char *name, struct dirent *entry, void *user);
typedef int (*vprint_callback)(char *buff, int maxlen, void *userptr, const char *format, va_list ap);
struct tlog tlog;
static struct tlog tlog;
static int tlog_disable_early_print = 0;
static tlog_level tlog_set_level = TLOG_INFO;
tlog_format_func tlog_format;
static tlog_format_func tlog_format;
static unsigned int tlog_localtime_lock = 0;
static const char *tlog_level_str[] = {
@@ -332,7 +332,7 @@ static int _tlog_print_buffer(char *buff, int maxlen, void *userptr, const char
return total_len;
}
int _tlog_vprintf(struct tlog_log *log, vprint_callback print_callback, void *userptr, const char *format, va_list ap)
static int _tlog_vprintf(struct tlog_log *log, vprint_callback print_callback, void *userptr, const char *format, va_list ap)
{
int len;
int maxlen = 0;
@@ -406,7 +406,7 @@ int _tlog_vprintf(struct tlog_log *log, vprint_callback print_callback, void *us
int tlog_vprintf(struct tlog_log *log, const char *format, va_list ap)
{
return _tlog_vprintf(log, _tlog_print_buffer, 0, format, ap);
return _tlog_vprintf(log, _tlog_print_buffer, NULL, format, ap);
}
int tlog_printf(struct tlog_log *log, const char *format, ...)
@@ -421,7 +421,7 @@ int tlog_printf(struct tlog_log *log, const char *format, ...)
return len;
}
int _tlog_early_print(const char *format, va_list ap)
static int _tlog_early_print(const char *format, va_list ap)
{
char log_buf[TLOG_MAX_LINE_LEN];
int len = 0;
@@ -901,7 +901,7 @@ static int _tlog_write_log(struct tlog_log *log, char *buff, int bufflen)
return len;
}
int _tlog_has_data(void)
static int _tlog_has_data(void)
{
struct tlog_log *next = NULL;
@@ -919,7 +919,7 @@ int _tlog_has_data(void)
return 0;
}
int _tlog_wait_pids(void)
static int _tlog_wait_pids(void)
{
static time_t last = -1;
time_t now = 0;
@@ -931,7 +931,7 @@ int _tlog_wait_pids(void)
while (next) {
if (next->zip_pid > 0) {
if (now == 0) {
now = time(0);
now = time(NULL);
}
if (now != last) {
@@ -953,7 +953,7 @@ int _tlog_wait_pids(void)
return 0;
}
int _tlog_close(struct tlog_log *log, int wait_hang)
static int _tlog_close(struct tlog_log *log, int wait_hang)
{
struct tlog_log *next = tlog.log;
@@ -1126,7 +1126,7 @@ void tlog_set_early_printf(int enable)
tlog_disable_early_print = (enable == 0) ? 1 : 0;
}
void _tlog_log_setlogscreen(struct tlog_log *log, int enable)
static void _tlog_log_setlogscreen(struct tlog_log *log, int enable)
{
if (log == NULL) {
return;
@@ -1260,9 +1260,9 @@ int tlog_init(const char *logfile, int maxlogsize, int maxlogcount, int block, i
tlog.is_wait = 0;
pthread_attr_init(&attr);
pthread_mutex_init(&tlog.lock, 0);
pthread_cond_init(&tlog.cond, 0);
pthread_cond_init(&tlog.client_cond, 0);
pthread_mutex_init(&tlog.lock, NULL);
pthread_cond_init(&tlog.cond, NULL);
pthread_cond_init(&tlog.client_cond, NULL);
tlog.run = 1;
log = tlog_open(logfile, maxlogsize, maxlogcount, block, buffsize, multiwrite);

View File

@@ -48,7 +48,7 @@ format: Log formats
#ifndef BASE_FILE_NAME
#define BASE_FILE_NAME __FILE__
#endif
#define tlog(level, format, ...) tlog_ext(level, BASE_FILE_NAME, __LINE__, __func__, 0, format, ##__VA_ARGS__)
#define tlog(level, format, ...) tlog_ext(level, BASE_FILE_NAME, __LINE__, __func__, NULL, format, ##__VA_ARGS__)
extern int tlog_ext(tlog_level level, const char *file, int line, const char *func, void *userptr, const char *format, ...)
__attribute__((format(printf, 6, 7)));

View File

@@ -1,16 +1,23 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "util.h"
#include "dns_conf.h"
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/netlink.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#define TMP_BUFF_LEN_32 32
#define NFNL_SUBSYS_IPSET 6
@@ -248,12 +255,12 @@ static int _ipset_socket_init(void)
return 0;
}
static int _ipset_support_timeout(const char *ipsetname)
static int _ipset_support_timeout(const char *ipsetname)
{
if (dns_conf_ipset_timeout_enable) {
return 0;
}
return -1;
}
@@ -369,82 +376,126 @@ unsigned char *SSL_SHA256(const unsigned char *d, size_t n, unsigned char *md)
int SSL_base64_decode(const char *in, unsigned char *out)
{
size_t inlen = strlen(in);
int outlen;
size_t inlen = strlen(in);
int outlen;
if (inlen == 0) {
return 0;
}
if (inlen == 0) {
return 0;
}
outlen = EVP_DecodeBlock(out, (unsigned char *)in, inlen);
if (outlen < 0) {
goto errout;
}
outlen = EVP_DecodeBlock(out, (unsigned char *)in, inlen);
if (outlen < 0) {
goto errout;
}
/* Subtract padding bytes from |outlen| */
while (in[--inlen] == '=') {
--outlen;
}
/* Subtract padding bytes from |outlen| */
while (in[--inlen] == '=') {
--outlen;
}
return outlen;
return outlen;
errout:
return -1;
return -1;
}
#define THREAD_STACK_SIZE (16*1024)
int create_pid_file(const char *pid_file)
{
int fd;
int flags;
char buff[TMP_BUFF_LEN_32];
/* create pid file, and lock this file */
fd = open(pid_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
if (fd == -1) {
fprintf(stderr, "create pid file failed, %s\n", strerror(errno));
return -1;
}
flags = fcntl(fd, F_GETFD);
if (flags < 0) {
fprintf(stderr, "Could not get flags for PID file %s\n", pid_file);
goto errout;
}
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1) {
fprintf(stderr, "Could not set flags for PID file %s\n", pid_file);
goto errout;
}
if (lockf(fd, F_TLOCK, 0) < 0) {
fprintf(stderr, "Server is already running.\n");
goto errout;
}
snprintf(buff, TMP_BUFF_LEN_32, "%d\n", getpid());
if (write(fd, buff, strnlen(buff, TMP_BUFF_LEN_32)) < 0) {
fprintf(stderr, "write pid to file failed, %s.\n", strerror(errno));
goto errout;
}
return 0;
errout:
if (fd > 0) {
close(fd);
}
return -1;
}
#define THREAD_STACK_SIZE (16 * 1024)
static pthread_mutex_t *lock_cs;
static long *lock_count;
void pthreads_locking_callback(int mode, int type, const char *file, int line)
static __attribute__((unused)) void _pthreads_locking_callback(int mode, int type, const char *file, int line)
{
if (mode & CRYPTO_LOCK) {
pthread_mutex_lock(&(lock_cs[type]));
lock_count[type]++;
} else {
pthread_mutex_unlock(&(lock_cs[type]));
}
if (mode & CRYPTO_LOCK) {
pthread_mutex_lock(&(lock_cs[type]));
lock_count[type]++;
} else {
pthread_mutex_unlock(&(lock_cs[type]));
}
}
unsigned long pthreads_thread_id(void)
static __attribute__((unused)) unsigned long _pthreads_thread_id(void)
{
unsigned long ret;
unsigned long ret;
ret = (unsigned long)pthread_self();
return (ret);
ret = (unsigned long)pthread_self();
return (ret);
}
void SSL_CRYPTO_thread_setup(void)
{
int i;
int i;
lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
if (!lock_cs || !lock_count) {
/* Nothing we can do about this...void function! */
if (lock_cs)
OPENSSL_free(lock_cs);
if (lock_count)
OPENSSL_free(lock_count);
return;
}
for (i = 0; i < CRYPTO_num_locks(); i++) {
lock_count[i] = 0;
pthread_mutex_init(&(lock_cs[i]), NULL);
}
lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
if (!lock_cs || !lock_count) {
/* Nothing we can do about this...void function! */
if (lock_cs)
OPENSSL_free(lock_cs);
if (lock_count)
OPENSSL_free(lock_count);
return;
}
for (i = 0; i < CRYPTO_num_locks(); i++) {
lock_count[i] = 0;
pthread_mutex_init(&(lock_cs[i]), NULL);
}
CRYPTO_set_id_callback(pthreads_thread_id);
CRYPTO_set_locking_callback(pthreads_locking_callback);
CRYPTO_set_id_callback(_pthreads_thread_id);
CRYPTO_set_locking_callback(_pthreads_locking_callback);
}
void SSL_CRYPTO_thread_cleanup(void)
{
int i;
int i;
CRYPTO_set_locking_callback(NULL);
for (i = 0; i < CRYPTO_num_locks(); i++) {
pthread_mutex_destroy(&(lock_cs[i]));
}
OPENSSL_free(lock_cs);
OPENSSL_free(lock_count);
CRYPTO_set_locking_callback(NULL);
for (i = 0; i < CRYPTO_num_locks(); i++) {
pthread_mutex_destroy(&(lock_cs[i]));
}
OPENSSL_free(lock_cs);
OPENSSL_free(lock_count);
}

View File

@@ -34,4 +34,6 @@ unsigned char *SSL_SHA256(const unsigned char *d, size_t n, unsigned char *md);
int SSL_base64_decode(const char *in, unsigned char *out);
#endif
int create_pid_file(const char *pid_file);
#endif