Skip to content

Commit

Permalink
dns_server: retry when dns packet is truncated.
Browse files Browse the repository at this point in the history
  • Loading branch information
pymumu committed Jan 14, 2024
1 parent d00f012 commit 9df7eaf
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/dns.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extern "C" {
#define DNS_RR_AAAA_LEN 16
#define DNS_MAX_CNAME_LEN 256
#define DNS_MAX_OPT_LEN 256
#define DNS_IN_PACKSIZE (512 * 8)
#define DNS_IN_PACKSIZE (512 * 16)
#define DNS_PACKSIZE (512 * 16)
#define DNS_DEFAULT_PACKET_SIZE 512
#define DNS_MAX_ALPN_LEN 32
Expand Down
29 changes: 19 additions & 10 deletions src/dns_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ static LIST_HEAD(pending_servers);
static pthread_mutex_t pending_server_mutex = PTHREAD_MUTEX_INITIALIZER;
static int dns_client_has_bootstrap_dns = 0;

static void _dns_client_retry_dns_query(struct dns_query_struct *query);
static int _dns_client_send_udp(struct dns_server_info *server_info, void *packet, int len);
static void _dns_client_clear_wakeup_event(void);
static void _dns_client_do_wakeup_event(void);
Expand Down Expand Up @@ -1856,6 +1857,10 @@ static int _dns_client_recv(struct dns_server_info *server_info, unsigned char *
/* remove this result */
_dns_replied_check_remove(query, from, from_len);
atomic_inc(&query->dns_request_sent);
if (ret == DNS_CLIENT_RETRY) {
/* retry immdiately */
_dns_client_retry_dns_query(query);
}
}
}

Expand Down Expand Up @@ -4036,6 +4041,19 @@ static int _dns_client_query_parser_options(struct dns_query_struct *query, stru
return 0;
}

static void _dns_client_retry_dns_query(struct dns_query_struct *query)
{
if (atomic_dec_and_test(&query->retry_count) || (query->has_result != 0)) {
_dns_client_query_remove(query);
if (query->has_result == 0) {
tlog(TLOG_DEBUG, "retry query %s, type: %d, id: %d failed", query->domain, query->qtype, query->sid);
}
} else {
tlog(TLOG_DEBUG, "retry query %s, type: %d, id: %d", query->domain, query->qtype, query->sid);
_dns_client_send_query(query);
}
}

static int _dns_client_add_hashmap(struct dns_query_struct *query)
{
uint32_t key = 0;
Expand Down Expand Up @@ -4439,16 +4457,7 @@ static void _dns_client_period_run(unsigned int msec)
if (atomic_read(&query->retry_count) == 1) {
_dns_client_check_udp_nat(query);
}

if (atomic_dec_and_test(&query->retry_count) || (query->has_result != 0)) {
_dns_client_query_remove(query);
if (query->has_result == 0) {
tlog(TLOG_DEBUG, "retry query %s, type: %d, id: %d failed", query->domain, query->qtype, query->sid);
}
} else {
tlog(TLOG_DEBUG, "retry query %s, type: %d, id: %d", query->domain, query->qtype, query->sid);
_dns_client_send_query(query);
}
_dns_client_retry_dns_query(query);
_dns_client_query_release(query);
}

Expand Down
1 change: 1 addition & 0 deletions src/dns_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ int dns_client_set_ecs(char *ip, int subnet);

struct dns_server_info;
/* query result notify function */
#define DNS_CLIENT_RETRY (-2)
typedef int (*dns_client_callback)(const char *domain, dns_result_type rtype, struct dns_server_info *server_info,
struct dns_packet *packet, unsigned char *inpacket, int inpacket_len,
void *user_ptr);
Expand Down
10 changes: 3 additions & 7 deletions src/dns_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -3745,14 +3745,10 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d
request->rcode = packet->head.rcode;
}

if (has_result == 0 && request->rcode == DNS_RC_NOERROR) {
/* When queries A and AAAA from CloudFlare DNS at the same time and there is a retry,
* CloudFlare DNS may return the sent request packet. I don’t know the reason.
* Maybe retry should be considered?
*/
tlog(TLOG_DEBUG, "no result, %s qtype: %d, rcode: %d, id: %d", domain, request->qtype,
if (has_result == 0 && request->rcode == DNS_RC_NOERROR && packet->head.tc == 1) {
tlog(TLOG_DEBUG, "result is truncated, %s qtype: %d, rcode: %d, id: %d, retry.", domain, request->qtype,
packet->head.rcode, packet->head.id);
return 0;
return DNS_CLIENT_RETRY;
}

return 0;
Expand Down

0 comments on commit 9df7eaf

Please sign in to comment.