code lint and optimize code style
This commit is contained in:
250
src/dns.c
250
src/dns.c
@@ -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
|
||||
|
||||
14
src/dns.h
14
src/dns.h
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
127
src/dns_client.c
127
src/dns_client.c
@@ -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;
|
||||
|
||||
200
src/dns_conf.c
200
src/dns_conf.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
199
src/dns_server.c
199
src/dns_server.c
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -237,4 +237,4 @@ int art_iter_prefix(art_tree *t, const unsigned char *prefix, int prefix_len, ar
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -197,4 +197,4 @@ static inline uint32_t rol32(uint32_t word, unsigned int shift)
|
||||
return (word << shift) | (word >> ((-shift) & 31));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -210,4 +210,4 @@ hash_string(const char *str)
|
||||
return(v);
|
||||
}
|
||||
|
||||
#endif /* _GENERIC_HASH_H */
|
||||
#endif /* _GENERIC_HASH_H */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -285,3 +285,4 @@ rb_erase_augmented(struct rb_node *node, struct rb_root *root,
|
||||
}
|
||||
|
||||
#endif /* _GENERIC_RBTREE_H */
|
||||
|
||||
|
||||
120
src/smartdns.c
120
src/smartdns.c
@@ -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:
|
||||
|
||||
|
||||
26
src/tlog.c
26
src/tlog.c
@@ -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);
|
||||
|
||||
@@ -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)));
|
||||
|
||||
165
src/util.c
165
src/util.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user