diff --git a/src/dns.c b/src/dns.c index 58c6a39..187a554 100644 --- a/src/dns.c +++ b/src/dns.c @@ -25,6 +25,7 @@ #include #include #include +#include #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 diff --git a/src/dns.h b/src/dns.h index 436cfff..3aadc1a 100644 --- a/src/dns.h +++ b/src/dns.h @@ -1,11 +1,6 @@ #ifndef _DNS_HEAD_H #define _DNS_HEAD_H -#include -#include -#include -#include - #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); diff --git a/src/dns_cache.c b/src/dns_cache.c index 64c287e..04b9cfe 100644 --- a/src/dns_cache.c +++ b/src/dns_cache.c @@ -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); -} \ No newline at end of file +} diff --git a/src/dns_cache.h b/src/dns_cache.h index 961d5a2..dad5a39 100644 --- a/src/dns_cache.h +++ b/src/dns_cache.h @@ -6,6 +6,7 @@ #include "hash.h" #include "hashtable.h" #include "list.h" +#include #include #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 \ No newline at end of file +#endif // !_SMARTDNS_CACHE_H diff --git a/src/dns_client.c b/src/dns_client.c index 3b0c7b7..9eb4bff 100644 --- a/src/dns_client.c +++ b/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 #include #include @@ -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; diff --git a/src/dns_conf.c b/src/dns_conf.c index 80a5be9..c024fe7 100644 --- a/src/dns_conf.c +++ b/src/dns_conf.c @@ -7,40 +7,55 @@ #include #include #include +#include #include - #include #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; } diff --git a/src/dns_conf.h b/src/dns_conf.h index 4d17e85..7c65797 100644 --- a/src/dns_conf.h +++ b/src/dns_conf.h @@ -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 \ No newline at end of file +#endif // !_DNS_CONF diff --git a/src/dns_server.c b/src/dns_server.c index 17948f3..5bfa745 100644 --- a/src/dns_server.c +++ b/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 . */ +#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 #include #include #include -#include -#include -#include -#include -#include -#include #include #include #include #include #include #include -#include -#include -#include -#include +#include /* 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; diff --git a/src/dns_server.h b/src/dns_server.h index 48d63e8..1075b1a 100644 --- a/src/dns_server.h +++ b/src/dns_server.h @@ -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 diff --git a/src/fast_ping.c b/src/fast_ping.c index acd8f9b..3689114 100644 --- a/src/fast_ping.c +++ b/src/fast_ping.c @@ -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); diff --git a/src/include/art.h b/src/include/art.h index e327b00..e39745f 100644 --- a/src/include/art.h +++ b/src/include/art.h @@ -237,4 +237,4 @@ int art_iter_prefix(art_tree *t, const unsigned char *prefix, int prefix_len, ar } #endif -#endif \ No newline at end of file +#endif diff --git a/src/include/atomic.h b/src/include/atomic.h index a5564fe..e94ed4d 100644 --- a/src/include/atomic.h +++ b/src/include/atomic.h @@ -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 + diff --git a/src/include/bitmap.h b/src/include/bitmap.h index fec0961..584e57d 100644 --- a/src/include/bitmap.h +++ b/src/include/bitmap.h @@ -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 */ \ No newline at end of file +#endif /* _PERF_BITOPS_H */ diff --git a/src/include/bitops.h b/src/include/bitops.h index b2c6526..7f8a6c8 100644 --- a/src/include/bitops.h +++ b/src/include/bitops.h @@ -197,4 +197,4 @@ static inline uint32_t rol32(uint32_t word, unsigned int shift) return (word << shift) | (word >> ((-shift) & 31)); } -#endif \ No newline at end of file +#endif diff --git a/src/include/conf.h b/src/include/conf.h index c9ac0fa..0236134 100644 --- a/src/include/conf.h +++ b/src/include/conf.h @@ -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 \ No newline at end of file +#endif // !_GENERIC_CONF_H diff --git a/src/include/findbit.h b/src/include/findbit.h index 0a6feb9..435c7d0 100644 --- a/src/include/findbit.h +++ b/src/include/findbit.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_ */ \ No newline at end of file +#endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */ diff --git a/src/include/gcc_builtin.h b/src/include/gcc_builtin.h index 0d34b2c..e5ae72d 100644 --- a/src/include/gcc_builtin.h +++ b/src/include/gcc_builtin.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 */ \ No newline at end of file +#endif /* _TOOLS_LINUX_COMPILER_H */ diff --git a/src/include/hash.h b/src/include/hash.h index 85ff038..27de4da 100644 --- a/src/include/hash.h +++ b/src/include/hash.h @@ -210,4 +210,4 @@ hash_string(const char *str) return(v); } -#endif /* _GENERIC_HASH_H */ \ No newline at end of file +#endif /* _GENERIC_HASH_H */ diff --git a/src/include/hashtable.h b/src/include/hashtable.h index f21b2c1..23bd279 100644 --- a/src/include/hashtable.h +++ b/src/include/hashtable.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 \ No newline at end of file +#endif diff --git a/src/include/jhash.h b/src/include/jhash.h index 3dfcc6e..6bbdfea 100644 --- a/src/include/jhash.h +++ b/src/include/jhash.h @@ -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 */ \ No newline at end of file +#endif /* _JHASH_H */ diff --git a/src/include/list.h b/src/include/list.h index f122411..081b463 100644 --- a/src/include/list.h +++ b/src/include/list.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 */ \ No newline at end of file +#endif /* _GENERIC_LIST_H */ diff --git a/src/include/radix.h b/src/include/radix.h index b93b657..adb5ab1 100644 --- a/src/include/radix.h +++ b/src/include/radix.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 */ + diff --git a/src/include/rbtree.h b/src/include/rbtree.h index 5bea0bf..13a97e0 100644 --- a/src/include/rbtree.h +++ b/src/include/rbtree.h @@ -285,3 +285,4 @@ rb_erase_augmented(struct rb_node *node, struct rb_root *root, } #endif /* _GENERIC_RBTREE_H */ + diff --git a/src/smartdns.c b/src/smartdns.c index ba9d94c..fc3ff32 100644 --- a/src/smartdns.c +++ b/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 , 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: diff --git a/src/tlog.c b/src/tlog.c index ef90237..4f4bb37 100644 --- a/src/tlog.c +++ b/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); diff --git a/src/tlog.h b/src/tlog.h index 896b360..504dd2c 100644 --- a/src/tlog.h +++ b/src/tlog.h @@ -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))); diff --git a/src/util.c b/src/util.c index b4def9b..07bb9ac 100644 --- a/src/util.c +++ b/src/util.c @@ -1,16 +1,23 @@ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include "util.h" #include "dns_conf.h" #include #include #include #include +#include +#include +#include #include #include #include #include -#include -#include -#include +#include +#include + +#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); } - diff --git a/src/util.h b/src/util.h index 76d5893..0842577 100644 --- a/src/util.h +++ b/src/util.h @@ -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 \ No newline at end of file +int create_pid_file(const char *pid_file); + +#endif