Bugfix
This commit is contained in:
14
src/conf.c
14
src/conf.c
@@ -72,11 +72,13 @@ void config_address_destroy(void)
|
||||
int config_address(char *value)
|
||||
{
|
||||
struct dns_address *address = NULL;
|
||||
struct dns_address *oldaddress;
|
||||
char ip[MAX_IP_LEN];
|
||||
char domain_key[DNS_MAX_CONF_CNAME_LEN];
|
||||
char *begin = NULL;
|
||||
char *end = NULL;
|
||||
int len = 0;
|
||||
int port;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
char type = '4';
|
||||
@@ -101,9 +103,12 @@ int config_address(char *value)
|
||||
len = end - begin;
|
||||
memcpy(address->domain, begin, len);
|
||||
address->domain[len] = 0;
|
||||
strncpy(ip, end + 1, MAX_IP_LEN);
|
||||
reverse_string(domain_key + 1, address->domain, len);
|
||||
|
||||
if (parse_ip(end + 1, ip, &port) != 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (getaddr_by_host(ip, (struct sockaddr *)&addr, &addr_len) != 0) {
|
||||
goto errout;
|
||||
}
|
||||
@@ -135,7 +140,10 @@ int config_address(char *value)
|
||||
|
||||
domain_key[0] = type;
|
||||
len++;
|
||||
art_insert(&dns_conf_address, (unsigned char *)domain_key, len, address);
|
||||
oldaddress = art_insert(&dns_conf_address, (unsigned char *)domain_key, len, address);
|
||||
if (oldaddress) {
|
||||
free(oldaddress);
|
||||
}
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
@@ -277,4 +285,4 @@ errout:
|
||||
fclose(fp);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
251
src/dns.c
251
src/dns.c
@@ -412,6 +412,95 @@ 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)
|
||||
{
|
||||
// TODO
|
||||
|
||||
int maxlen = 0;
|
||||
int len = 0;
|
||||
struct dns_data_context data_context;
|
||||
int total_len = sizeof(*opt) + opt->length;
|
||||
int ttl = 0;
|
||||
|
||||
/*
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
0: | OPTION-CODE |
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
2: | OPTION-LENGTH |
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
4: | |
|
||||
/ OPTION-DATA /
|
||||
/ /
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*/
|
||||
unsigned char *data = _dns_add_rrs_start(packet, &maxlen);
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (total_len > maxlen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data_context.data = data;
|
||||
data_context.ptr = data;
|
||||
data_context.maxsize = maxlen;
|
||||
|
||||
ttl = (opt_code << 16) | opt_len;
|
||||
|
||||
/* add rr head */
|
||||
len = _dns_add_rr_head(&data_context, "", type, DNS_C_IN, ttl, total_len);
|
||||
if (len < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* add rr data */
|
||||
memcpy(data_context.ptr, opt, total_len);
|
||||
data_context.ptr += total_len;
|
||||
len = data_context.ptr - data_context.data;
|
||||
|
||||
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)
|
||||
{
|
||||
// TODO
|
||||
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
int rr_len = 0;
|
||||
int ret = 0;
|
||||
struct dns_data_context data_context;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
int maxsize = DNS_MAX_CNAME_LEN;
|
||||
int ttl = 0;
|
||||
unsigned char *data = rrs->data;
|
||||
|
||||
data_context.data = data;
|
||||
data_context.ptr = data;
|
||||
data_context.maxsize = rrs->len;
|
||||
|
||||
/* get rr head */
|
||||
ret = _dns_get_rr_head(&data_context, domain, maxsize, &qtype, &qclass, &ttl, &rr_len);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (qtype != rrs->type || rr_len > *opt_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get rr data */
|
||||
*opt_code = ttl >> 16;
|
||||
*opt_len = ttl & 0xFFFF;
|
||||
memcpy(opt, data_context.ptr, rr_len);
|
||||
data_context.ptr += rr_len;
|
||||
*opt_maxlen = rr_len;
|
||||
|
||||
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;
|
||||
@@ -546,6 +635,47 @@ int dns_get_SOA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_add_OPT_ECS(struct dns_packet *packet, dns_rr_type type, struct dns_opt_ecs *ecs)
|
||||
{
|
||||
// TODO
|
||||
|
||||
unsigned char opt_data[DNS_MAX_OPT_LEN];
|
||||
struct dns_opt *opt = (struct dns_opt *)opt_data;
|
||||
int len = 0;
|
||||
|
||||
opt->code = DNS_OPT_T_ECS;
|
||||
opt->length = sizeof(*ecs);
|
||||
memcpy(opt->data, ecs, sizeof(*ecs));
|
||||
|
||||
/* ecs size 4 + bit of address*/
|
||||
len = sizeof(*opt) + 4;
|
||||
len += (ecs->source_prefix / 8);
|
||||
len += (ecs->source_prefix % 8 > 0) ? 1 : 0;
|
||||
|
||||
return dns_add_OPT(packet, type, DNS_OPT_T_ECS, len, opt);
|
||||
}
|
||||
|
||||
int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt_ecs *ecs)
|
||||
{
|
||||
// TODO
|
||||
|
||||
unsigned char opt_data[DNS_MAX_OPT_LEN];
|
||||
struct dns_opt *opt = (struct dns_opt *)opt_data;
|
||||
int len = sizeof(opt_data);
|
||||
|
||||
if (dns_get_OPT(rrs, opt_code, opt_len, opt, &len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (opt->code != DNS_OPT_T_ECS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(ecs, opt->data, opt->length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Format:
|
||||
* |DNS_NAME\0(string)|qtype(short)|qclass(short)|
|
||||
@@ -1074,6 +1204,108 @@ int _dns_encode_SOA(struct dns_context *context, struct dns_rrs *rrs)
|
||||
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);
|
||||
len = (ecs->source_prefix / 8);
|
||||
len += (ecs->source_prefix % 8 > 0) ? 1 : 0;
|
||||
|
||||
if (_dns_left_len(context) < len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(ecs->addr, context->ptr, len);
|
||||
context->ptr += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _dns_encode_OPT(struct dns_context *context, struct dns_rrs *rrs)
|
||||
{
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsigned int ttl, int rr_len)
|
||||
{
|
||||
unsigned short opt_code;
|
||||
unsigned short opt_len;
|
||||
unsigned short ercode = (ttl >> 16) & 0xFFFF;
|
||||
unsigned short ever = (ttl) & 0xFFFF;
|
||||
unsigned char *start = context->ptr;
|
||||
struct dns_packet *packet = context->packet;
|
||||
int ret = 0;
|
||||
/*
|
||||
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: | OPTION-CODE |
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
2: | OPTION-LENGTH |
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
4: | |
|
||||
/ OPTION-DATA /
|
||||
/ /
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
|
||||
TTL
|
||||
+0 (MSB) +1 (LSB)
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
0: | EXTENDED-RCODE | VERSION |
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
2: | Z |
|
||||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*/
|
||||
|
||||
if (ercode != 0) {
|
||||
tlog(TLOG_ERROR, "extend rcode invalid.");
|
||||
return -1;
|
||||
}
|
||||
ever = ever;
|
||||
|
||||
while (context->ptr - start < rr_len) {
|
||||
opt_code = dns_read_short(&context->ptr);
|
||||
opt_len = dns_read_short(&context->ptr);
|
||||
switch (opt_code) {
|
||||
case DNS_OPT_T_ECS: {
|
||||
struct dns_opt_ecs ecs;
|
||||
ret = _dns_decode_opt_ecs(context, &ecs);
|
||||
if (ret != 0 ) {
|
||||
tlog(TLOG_ERROR, "decode ecs failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dns_add_OPT_ECS(packet, type, &ecs);
|
||||
} break;
|
||||
default:
|
||||
context->ptr += opt_len;
|
||||
tlog(TLOG_DEBUG, "DNS opt type = %d not supported", opt_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_decode_qd(struct dns_context *context)
|
||||
{
|
||||
struct dns_packet *packet = context->packet;
|
||||
@@ -1200,6 +1432,19 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
case DNS_T_OPT: {
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (context->ptr - opt_start != rr_len) {
|
||||
tlog(TLOG_ERROR, "opt length mitchmatch, %s\n", domain);
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
context->ptr += rr_len;
|
||||
tlog(TLOG_DEBUG, "DNS type = %d not supported", qtype);
|
||||
@@ -1263,6 +1508,12 @@ static int _dns_encode_an(struct dns_context *context, struct dns_rrs *rrs)
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case DNS_T_OPT:
|
||||
ret = _dns_encode_OPT(context, rrs);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
31
src/dns.h
31
src/dns.h
@@ -9,6 +9,7 @@
|
||||
#define DNS_RR_A_LEN 4
|
||||
#define DNS_RR_AAAA_LEN 16
|
||||
#define DNS_MAX_CNAME_LEN 256
|
||||
#define DNS_MAX_OPT_LEN 256
|
||||
#define DNS_IN_PACKSIZE (512 * 4)
|
||||
#define DNS_PACKSIZE (512 * 8)
|
||||
|
||||
@@ -44,6 +45,11 @@ 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
|
||||
} dns_opt_code_t;
|
||||
|
||||
typedef enum dns_opcode {
|
||||
DNS_OP_QUERY = 0,
|
||||
DNS_OP_IQUERY = 1,
|
||||
@@ -128,7 +134,24 @@ struct dns_soa {
|
||||
unsigned int expire;
|
||||
unsigned int minimum;
|
||||
} __attribute__((packed));
|
||||
;
|
||||
|
||||
#define DNS_OPT_ECS_FAMILY_IPV4 1
|
||||
#define DNS_OPT_ECS_FAMILY_IPV6 2
|
||||
|
||||
/* OPT ECS */
|
||||
struct dns_opt_ecs {
|
||||
unsigned short family;
|
||||
unsigned char source_prefix;
|
||||
unsigned char scope_prefix;
|
||||
unsigned char addr[DNS_RR_AAAA_LEN];
|
||||
};
|
||||
|
||||
/* OPT */
|
||||
struct dns_opt {
|
||||
unsigned short code;
|
||||
unsigned short length;
|
||||
unsigned char data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct dns_rrs *dns_get_rrs_next(struct dns_packet *packet, struct dns_rrs *rrs);
|
||||
struct dns_rrs *dns_get_rrs_start(struct dns_packet *packet, dns_rr_type type, int *count);
|
||||
@@ -156,6 +179,12 @@ 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_OPT(struct dns_packet *packet, dns_rr_type type, unsigned short opt_code, unsigned short opt_len, struct dns_opt *opt);
|
||||
int dns_get_OPT(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt *opt, int *opt_maxlen);
|
||||
|
||||
int dns_add_OPT_ECS(struct dns_packet *packet, dns_rr_type type, struct dns_opt_ecs *ecs);
|
||||
int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt_ecs *ecs);
|
||||
/*
|
||||
* Packet operation
|
||||
*/
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#define DNS_MAX_EVENTS 256
|
||||
#define DNS_SERVER_TMOUT_TTL (3 * 60)
|
||||
|
||||
/* dns server data */
|
||||
struct dns_server {
|
||||
@@ -268,11 +269,25 @@ int _dns_server_request_complete(struct dns_request *request)
|
||||
if (request->qtype == DNS_T_A) {
|
||||
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]);
|
||||
|
||||
if (request->has_ipv4) {
|
||||
if (request->has_ping_result == 0 && request->ttl_v4 > DNS_SERVER_TMOUT_TTL) {
|
||||
request->ttl_v4 = DNS_SERVER_TMOUT_TTL;
|
||||
}
|
||||
}
|
||||
dns_cache_insert(request->domain, request->ttl_v4, DNS_T_A, request->ipv4_addr, DNS_RR_A_LEN);
|
||||
} else if (request->qtype == DNS_T_AAAA) {
|
||||
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]);
|
||||
|
||||
if (request->has_ipv6) {
|
||||
if (request->has_ping_result == 0 && request->ttl_v6 > DNS_SERVER_TMOUT_TTL) {
|
||||
request->ttl_v6 = DNS_SERVER_TMOUT_TTL;
|
||||
}
|
||||
dns_cache_insert(request->domain, request->ttl_v6, DNS_T_AAAA, request->ipv6_addr, DNS_RR_AAAA_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
_dns_reply(request);
|
||||
@@ -333,7 +348,6 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
|
||||
{
|
||||
struct dns_request *request = userptr;
|
||||
int may_complete = 0;
|
||||
int addr_type = 0;
|
||||
|
||||
if (request == NULL) {
|
||||
return;
|
||||
@@ -355,7 +369,6 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
|
||||
request->ping_ttl_v4 = rtt;
|
||||
request->has_ipv4 = 1;
|
||||
memcpy(request->ipv4_addr, &addr_in->sin_addr.s_addr, 4);
|
||||
addr_type = 4;
|
||||
}
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
@@ -366,14 +379,12 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
|
||||
request->ping_ttl_v4 = rtt;
|
||||
request->has_ipv4 = 1;
|
||||
memcpy(request->ipv4_addr, addr_in6->sin6_addr.s6_addr + 12, 4);
|
||||
addr_type = 4;
|
||||
}
|
||||
} else {
|
||||
if (request->ping_ttl_v6 > rtt) {
|
||||
request->ping_ttl_v6 = rtt;
|
||||
request->has_ipv6 = 1;
|
||||
memcpy(request->ipv6_addr, addr_in6->sin6_addr.s6_addr, 16);
|
||||
addr_type = 6;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
@@ -396,11 +407,6 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos
|
||||
if (may_complete) {
|
||||
_dns_server_request_complete(request);
|
||||
_dns_server_request_remove(request);
|
||||
if (addr_type == 4) {
|
||||
dns_cache_insert(request->domain, request->ttl_v4, DNS_T_A, request->ipv4_addr, DNS_RR_A_LEN);
|
||||
} else if (addr_type == 6) {
|
||||
dns_cache_insert(request->domain, request->ttl_v6, DNS_T_AAAA, request->ipv6_addr, DNS_RR_AAAA_LEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,6 +514,10 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
|
||||
memcpy(request->ipv4_addr, addr, DNS_RR_A_LEN);
|
||||
request->ttl_v4 = ttl;
|
||||
request->has_ipv4 = 1;
|
||||
} else {
|
||||
if (ttl < request->ttl_v4) {
|
||||
request->ttl_v4 = ttl;
|
||||
}
|
||||
}
|
||||
if (_dns_ip_address_check_add(request, addr, DNS_T_A) != 0) {
|
||||
_dns_server_request_release(request);
|
||||
@@ -539,6 +549,10 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
|
||||
memcpy(request->ipv6_addr, addr, DNS_RR_AAAA_LEN);
|
||||
request->ttl_v6 = ttl;
|
||||
request->has_ipv6 = 1;
|
||||
} else {
|
||||
if (ttl < request->ttl_v6) {
|
||||
request->ttl_v6 = ttl;
|
||||
}
|
||||
}
|
||||
|
||||
if (_dns_ip_address_check_add(request, addr, DNS_T_AAAA) != 0) {
|
||||
@@ -546,7 +560,7 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(name, "%.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],
|
||||
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]);
|
||||
|
||||
if (_dns_server_ping(request, ip) != 0) {
|
||||
@@ -702,7 +716,7 @@ static struct dns_address *_dns_server_get_address_by_domain(char *domain, int q
|
||||
domain_key[0] = type;
|
||||
domain_len++;
|
||||
|
||||
return art_substring(&dns_conf_address, (unsigned char *)domain_key, domain_len);;
|
||||
return art_substring(&dns_conf_address, (unsigned char *)domain_key, domain_len);
|
||||
}
|
||||
|
||||
static int _dns_server_process_address(struct dns_request *request, struct dns_packet *packet)
|
||||
@@ -745,7 +759,7 @@ errout:
|
||||
static int _dns_server_process_cache(struct dns_request *request, struct dns_packet *packet)
|
||||
{
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
|
||||
|
||||
dns_cache = dns_cache_get(request->domain, request->qtype);
|
||||
if (dns_cache == NULL) {
|
||||
goto errout;
|
||||
|
||||
@@ -170,9 +170,9 @@ static art_node** find_child(art_node *n, unsigned char c) {
|
||||
case NODE4:
|
||||
p.p1 = (art_node4*)n;
|
||||
for (i=0 ; i < n->num_children; i++) {
|
||||
/* this cast works around a bug in gcc 5.1 when unrolling loops
|
||||
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124
|
||||
*/
|
||||
/* this cast works around a bug in gcc 5.1 when unrolling loops
|
||||
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124
|
||||
*/
|
||||
if (((unsigned char*)p.p1->keys)[i] == c)
|
||||
return &p.p1->children[i];
|
||||
}
|
||||
@@ -421,8 +421,8 @@ static void add_child48(art_node48 *n, art_node **ref, unsigned char c, void *ch
|
||||
n->n.num_children++;
|
||||
} else {
|
||||
art_node256 *new_node = (art_node256*)alloc_node(NODE256);
|
||||
int i;
|
||||
for (i=0;i<256;i++) {
|
||||
int i;
|
||||
for (i=0;i<256;i++) {
|
||||
if (n->keys[i]) {
|
||||
new_node->children[i] = n->children[n->keys[i] - 1];
|
||||
}
|
||||
@@ -461,8 +461,8 @@ static void add_child16(art_node16 *n, art_node **ref, unsigned char c, void *ch
|
||||
#else
|
||||
// Compare the key to all 16 stored keys
|
||||
unsigned bitfield = 0;
|
||||
int i;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
int i;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
if (c < n->keys[i])
|
||||
bitfield |= (1 << i);
|
||||
}
|
||||
@@ -489,9 +489,9 @@ static void add_child16(art_node16 *n, art_node **ref, unsigned char c, void *ch
|
||||
|
||||
} else {
|
||||
art_node48 *new_node = (art_node48*)alloc_node(NODE48);
|
||||
int i;
|
||||
int i;
|
||||
|
||||
// Copy the child pointers and populate the key map
|
||||
// Copy the child pointers and populate the key map
|
||||
memcpy(new_node->children, n->children,
|
||||
sizeof(void*)*n->n.num_children);
|
||||
for (i=0;i<n->n.num_children;i++) {
|
||||
@@ -688,8 +688,8 @@ static void remove_child256(art_node256 *n, art_node **ref, unsigned char c) {
|
||||
copy_header((art_node*)new_node, (art_node*)n);
|
||||
|
||||
int pos = 0;
|
||||
int i;
|
||||
for (i=0;i<256;i++) {
|
||||
int i;
|
||||
for (i=0;i<256;i++) {
|
||||
if (n->children[i]) {
|
||||
new_node->children[pos] = n->children[i];
|
||||
new_node->keys[i] = pos + 1;
|
||||
@@ -712,8 +712,8 @@ static void remove_child48(art_node48 *n, art_node **ref, unsigned char c) {
|
||||
copy_header((art_node*)new_node, (art_node*)n);
|
||||
|
||||
int child = 0;
|
||||
int i;
|
||||
for (i=0;i<256;i++) {
|
||||
int i;
|
||||
for (i=0;i<256;i++) {
|
||||
pos = n->keys[i];
|
||||
if (pos) {
|
||||
new_node->keys[child] = i;
|
||||
@@ -858,8 +858,8 @@ static int recursive_iter(art_node *n, art_callback cb, void *data) {
|
||||
}
|
||||
|
||||
int idx, res;
|
||||
int i;
|
||||
switch (n->type) {
|
||||
int i;
|
||||
switch (n->type) {
|
||||
case NODE4:
|
||||
for (i=0; i < n->num_children; i++) {
|
||||
res = recursive_iter(((art_node4*)n)->children[i], cb, data);
|
||||
@@ -941,12 +941,6 @@ int art_iter_prefix(art_tree *t, const unsigned char *key, int key_len, art_call
|
||||
art_node *n = t->root;
|
||||
int prefix_len, depth = 0;
|
||||
while (n) {
|
||||
|
||||
if (IS_LEAF(n)) {
|
||||
n = (art_node*)LEAF_RAW(n);
|
||||
art_leaf *l = (art_leaf*)n;
|
||||
printf("LEAF: %s\n", l->key);
|
||||
}
|
||||
// Might be a leaf
|
||||
if (IS_LEAF(n)) {
|
||||
n = (art_node*)LEAF_RAW(n);
|
||||
@@ -998,7 +992,7 @@ int art_iter_prefix(art_tree *t, const unsigned char *key, int key_len, art_call
|
||||
|
||||
static int str_prefix_matches(const art_leaf *n, const unsigned char *str, int str_len) {
|
||||
// Fail if the key length is too short
|
||||
if (n->key_len > (uint32_t)str_len) return 1;
|
||||
if (n->key_len > (uint32_t)str_len) return 1;
|
||||
|
||||
// Compare the keys
|
||||
return memcmp(str, n->key, n->key_len);
|
||||
@@ -1008,33 +1002,40 @@ void *art_substring(const art_tree *t, const unsigned char *str, int str_len)
|
||||
{
|
||||
art_node **child;
|
||||
art_node *n = t->root;
|
||||
art_leaf *found = NULL;
|
||||
art_node *m;
|
||||
art_leaf *found = NULL;
|
||||
int prefix_len, depth = 0;
|
||||
|
||||
int prefix_len, depth = 0;
|
||||
while (n) {
|
||||
// Might be a leaf
|
||||
if (IS_LEAF(n)) {
|
||||
n = (art_node*)LEAF_RAW(n);
|
||||
// Check if the expanded path matches
|
||||
if (!str_prefix_matches((art_leaf*)n, str, str_len)) {
|
||||
found = (art_leaf*)n;
|
||||
found = (art_leaf*)n;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if current is leaf
|
||||
child = find_child(n, 0);
|
||||
m = (child) ? *child : NULL;
|
||||
if (m && IS_LEAF(m)) {
|
||||
m = (art_node*)LEAF_RAW(m);
|
||||
// Check if the expanded path matches
|
||||
if (!str_prefix_matches((art_leaf*)m, str, str_len)) {
|
||||
found = (art_leaf*)m;
|
||||
}
|
||||
}
|
||||
|
||||
// Bail if the prefix does not match
|
||||
if (n->partial_len) {
|
||||
prefix_len = check_prefix(n, str, str_len, depth);
|
||||
if (prefix_len != min(MAX_PREFIX_LEN, n->partial_len))
|
||||
break;
|
||||
depth = depth + n->partial_len;
|
||||
break;
|
||||
depth = depth + n->partial_len;
|
||||
}
|
||||
|
||||
art_leaf *l = maximum(n);
|
||||
if (!str_prefix_matches(l, str, str_len)) {
|
||||
found = l;
|
||||
}
|
||||
|
||||
// Recursively search
|
||||
child = find_child(n, str[depth]);
|
||||
n = (child) ? *child : NULL;
|
||||
@@ -1042,8 +1043,8 @@ void *art_substring(const art_tree *t, const unsigned char *str, int str_len)
|
||||
}
|
||||
|
||||
if (found == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return found->value;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user