dns_server: refactoring dualstack selection code.
This commit is contained in:
@@ -30,6 +30,11 @@
|
|||||||
#define DNS_ADDR_FAMILY_IP 1
|
#define DNS_ADDR_FAMILY_IP 1
|
||||||
#define DNS_ADDR_FAMILY_IPV6 2
|
#define DNS_ADDR_FAMILY_IPV6 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
DNS parameters:
|
||||||
|
https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
|
||||||
|
*/
|
||||||
|
|
||||||
typedef enum dns_qr {
|
typedef enum dns_qr {
|
||||||
DNS_QR_QUERY = 0,
|
DNS_QR_QUERY = 0,
|
||||||
DNS_QR_ANSWER = 1,
|
DNS_QR_ANSWER = 1,
|
||||||
|
|||||||
@@ -341,6 +341,42 @@ SSL_SESSION *_ssl_get1_session(struct dns_server_info *server)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int dns_client_server_result_flag(struct dns_server_info *server_info)
|
||||||
|
{
|
||||||
|
if (server_info == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return server_info->flags.result_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *dns_client_get_server_ip(struct dns_server_info *server_info)
|
||||||
|
{
|
||||||
|
if (server_info == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return server_info->ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dns_client_get_server_port(struct dns_server_info *server_info)
|
||||||
|
{
|
||||||
|
if (server_info == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return server_info->port;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_server_type_t dns_client_get_server_type(struct dns_server_info *server_info)
|
||||||
|
{
|
||||||
|
if (server_info == NULL) {
|
||||||
|
return DNS_SERVER_TYPE_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
return server_info->type;
|
||||||
|
}
|
||||||
|
|
||||||
const char *_dns_server_get_type_string(dns_server_type_t type)
|
const char *_dns_server_get_type_string(dns_server_type_t type)
|
||||||
{
|
{
|
||||||
const char *type_str = "";
|
const char *type_str = "";
|
||||||
@@ -1210,6 +1246,8 @@ void _dns_client_server_pending_get(struct dns_server_pending *pending)
|
|||||||
|
|
||||||
void _dns_client_server_pending_release_lck(struct dns_server_pending *pending)
|
void _dns_client_server_pending_release_lck(struct dns_server_pending *pending)
|
||||||
{
|
{
|
||||||
|
struct dns_server_pending_group *group, *tmp;
|
||||||
|
|
||||||
int refcnt = atomic_dec_return(&pending->refcnt);
|
int refcnt = atomic_dec_return(&pending->refcnt);
|
||||||
|
|
||||||
if (refcnt) {
|
if (refcnt) {
|
||||||
@@ -1220,6 +1258,12 @@ void _dns_client_server_pending_release_lck(struct dns_server_pending *pending)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(group, tmp, &pending->group_list, list)
|
||||||
|
{
|
||||||
|
list_del_init(&group->list);
|
||||||
|
free(group);
|
||||||
|
}
|
||||||
|
|
||||||
list_del_init(&pending->list);
|
list_del_init(&pending->list);
|
||||||
free(pending);
|
free(pending);
|
||||||
}
|
}
|
||||||
@@ -1352,7 +1396,7 @@ static void _dns_client_query_release(struct dns_query_struct *query)
|
|||||||
|
|
||||||
/* notify caller query end */
|
/* notify caller query end */
|
||||||
if (query->callback) {
|
if (query->callback) {
|
||||||
tlog(TLOG_INFO, "result %s, qtype: %d, rcode: %d, id %d", query->domain, query->qtype, query->has_result,
|
tlog(TLOG_DEBUG, "result: %s, qtype: %d, hasresult: %d, id %d", query->domain, query->qtype, query->has_result,
|
||||||
query->sid);
|
query->sid);
|
||||||
query->callback(query->domain, DNS_QUERY_END, 0, NULL, NULL, 0, query->user_ptr);
|
query->callback(query->domain, DNS_QUERY_END, 0, NULL, NULL, 0, query->user_ptr);
|
||||||
}
|
}
|
||||||
@@ -1608,8 +1652,8 @@ static int _dns_client_recv(struct dns_server_info *server_info, unsigned char *
|
|||||||
|
|
||||||
/* notify caller dns query result */
|
/* notify caller dns query result */
|
||||||
if (query->callback) {
|
if (query->callback) {
|
||||||
ret = query->callback(query->domain, DNS_QUERY_RESULT, server_info->flags.result_flag, packet, inpacket,
|
ret = query->callback(query->domain, DNS_QUERY_RESULT, server_info, packet, inpacket, inpacket_len,
|
||||||
inpacket_len, query->user_ptr);
|
query->user_ptr);
|
||||||
if (request_num == 0 || ret) {
|
if (request_num == 0 || ret) {
|
||||||
/* if all server replied, or done, stop query, release resource */
|
/* if all server replied, or done, stop query, release resource */
|
||||||
_dns_client_query_remove(query);
|
_dns_client_query_remove(query);
|
||||||
@@ -2975,7 +3019,7 @@ int _dns_client_query_parser_options(struct dns_query_struct *query, struct dns_
|
|||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
socklen_t addr_len = sizeof(addr);
|
socklen_t addr_len = sizeof(addr);
|
||||||
struct dns_opt_ecs *ecs;
|
struct dns_opt_ecs *ecs;
|
||||||
|
|
||||||
ecs = &query->ecs.ecs;
|
ecs = &query->ecs.ecs;
|
||||||
getaddr_by_host(options->ecs_ip.ip, (struct sockaddr *)&addr, &addr_len);
|
getaddr_by_host(options->ecs_ip.ip, (struct sockaddr *)&addr, &addr_len);
|
||||||
|
|
||||||
@@ -3180,6 +3224,19 @@ static int _dns_client_add_pendings(struct dns_server_pending *pending, char *ip
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _dns_client_remove_all_pending_servers(void)
|
||||||
|
{
|
||||||
|
struct dns_server_pending *pending, *tmp;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&pending_server_mutex);
|
||||||
|
list_for_each_entry_safe(pending, tmp, &pending_servers, list)
|
||||||
|
{
|
||||||
|
list_del_init(&pending->list);
|
||||||
|
_dns_client_server_pending_release_lck(pending);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&pending_server_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
static void _dns_client_add_pending_servers(void)
|
static void _dns_client_add_pending_servers(void)
|
||||||
{
|
{
|
||||||
struct dns_server_pending *pending, *tmp;
|
struct dns_server_pending *pending, *tmp;
|
||||||
@@ -3296,7 +3353,9 @@ static void _dns_client_period_run(void)
|
|||||||
_dns_client_check_udp_nat(query);
|
_dns_client_check_udp_nat(query);
|
||||||
if (atomic_dec_and_test(&query->retry_count) || (query->has_result != 0)) {
|
if (atomic_dec_and_test(&query->retry_count) || (query->has_result != 0)) {
|
||||||
_dns_client_query_remove(query);
|
_dns_client_query_remove(query);
|
||||||
tlog(TLOG_INFO, "retry query %s, type: %d, id: %d failed", query->domain, query->qtype, query->sid);
|
if (query->has_result == 0) {
|
||||||
|
tlog(TLOG_INFO, "retry query %s, type: %d, id: %d failed", query->domain, query->qtype, query->sid);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tlog(TLOG_INFO, "retry query %s, type: %d, id: %d", query->domain, query->qtype, query->sid);
|
tlog(TLOG_INFO, "retry query %s, type: %d, id: %d", query->domain, query->qtype, query->sid);
|
||||||
_dns_client_send_query(query, query->domain);
|
_dns_client_send_query(query, query->domain);
|
||||||
@@ -3469,6 +3528,7 @@ void dns_client_exit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* free all resouces */
|
/* free all resouces */
|
||||||
|
_dns_client_remove_all_pending_servers();
|
||||||
_dns_client_server_remove_all();
|
_dns_client_server_remove_all();
|
||||||
_dns_client_query_remove_all();
|
_dns_client_query_remove_all();
|
||||||
_dns_client_group_remove_all();
|
_dns_client_group_remove_all();
|
||||||
|
|||||||
@@ -54,11 +54,20 @@ int dns_client_init(void);
|
|||||||
|
|
||||||
int dns_client_set_ecs(char *ip, int subnet);
|
int dns_client_set_ecs(char *ip, int subnet);
|
||||||
|
|
||||||
|
struct dns_server_info;
|
||||||
/* query result notify function */
|
/* query result notify function */
|
||||||
typedef int (*dns_client_callback)(char *domain, dns_result_type rtype, unsigned int result_flag,
|
typedef int (*dns_client_callback)(char *domain, dns_result_type rtype, struct dns_server_info *server_info,
|
||||||
struct dns_packet *packet, unsigned char *inpacket, int inpacket_len,
|
struct dns_packet *packet, unsigned char *inpacket, int inpacket_len,
|
||||||
void *user_ptr);
|
void *user_ptr);
|
||||||
|
|
||||||
|
unsigned int dns_client_server_result_flag(struct dns_server_info *server_info);
|
||||||
|
|
||||||
|
const char *dns_client_get_server_ip(struct dns_server_info *server_info);
|
||||||
|
|
||||||
|
int dns_client_get_server_port(struct dns_server_info *server_info);
|
||||||
|
|
||||||
|
dns_server_type_t dns_client_get_server_type(struct dns_server_info *server_info);
|
||||||
|
|
||||||
struct dns_query_ecs_ip {
|
struct dns_query_ecs_ip {
|
||||||
char ip[DNS_MAX_CNAME_LEN];
|
char ip[DNS_MAX_CNAME_LEN];
|
||||||
int subnet;
|
int subnet;
|
||||||
|
|||||||
@@ -1206,6 +1206,9 @@ static int _config_qtype_soa(void *data, int argc, char *argv[])
|
|||||||
|
|
||||||
memset(soa_list, 0, sizeof(*soa_list));
|
memset(soa_list, 0, sizeof(*soa_list));
|
||||||
soa_list->qtypeid = atol(argv[i]);
|
soa_list->qtypeid = atol(argv[i]);
|
||||||
|
if (soa_list->qtypeid == DNS_T_AAAA) {
|
||||||
|
dns_conf_force_AAAA_SOA = 1;
|
||||||
|
}
|
||||||
uint32_t key = hash_32_generic(soa_list->qtypeid, 32);
|
uint32_t key = hash_32_generic(soa_list->qtypeid, 32);
|
||||||
hash_add(dns_qtype_soa_table.qtype, &soa_list->node, key);
|
hash_add(dns_qtype_soa_table.qtype, &soa_list->node, key);
|
||||||
}
|
}
|
||||||
|
|||||||
832
src/dns_server.c
832
src/dns_server.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user