2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 22:15:20 +00:00

[master] Prevent dig INSIST failures and hangs in some failure modes

4756.	[bug]		Interrupting dig could lead to an INSIST failure after
			certain errors were encountered while querying a host
			whose name resolved to more than one address.  Change
			4537 increased the odds of triggering this issue by
			causing dig to hang indefinitely when certain error
			paths were evaluated.  dig now also retries TCP queries
			(once) if the server gracefully closes the connection
			before sending a response. [RT #42832, #45159]
This commit is contained in:
Michał Kępień
2017-10-05 09:42:31 +02:00
parent d7ee3ed488
commit 14afc8425b
3 changed files with 34 additions and 3 deletions

View File

@@ -1,3 +1,12 @@
4756. [bug] Interrupting dig could lead to an INSIST failure after
certain errors were encountered while querying a host
whose name resolved to more than one address. Change
4537 increased the odds of triggering this issue by
causing dig to hang indefinitely when certain error
paths were evaluated. dig now also retries TCP queries
(once) if the server gracefully closes the connection
before sending a response. [RT #42832, #45159]
4755. [cleanup] Silence unnecessary log message when NZF file doesn't 4755. [cleanup] Silence unnecessary log message when NZF file doesn't
exist. [RT #46186] exist. [RT #46186]

View File

@@ -646,6 +646,7 @@ make_empty_lookup(void) {
looknew->mapped = ISC_TRUE; looknew->mapped = ISC_TRUE;
looknew->dscp = -1; looknew->dscp = -1;
looknew->rrcomments = 0; looknew->rrcomments = 0;
looknew->eoferr = 0;
dns_fixedname_init(&looknew->fdomain); dns_fixedname_init(&looknew->fdomain);
ISC_LINK_INIT(looknew, link); ISC_LINK_INIT(looknew, link);
ISC_LIST_INIT(looknew->q); ISC_LIST_INIT(looknew->q);
@@ -737,6 +738,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
looknew->done_as_is = lookold->done_as_is; looknew->done_as_is = lookold->done_as_is;
looknew->dscp = lookold->dscp; looknew->dscp = lookold->dscp;
looknew->rrcomments = lookold->rrcomments; looknew->rrcomments = lookold->rrcomments;
looknew->eoferr = lookold->eoferr;
if (lookold->ecs_addr != NULL) { if (lookold->ecs_addr != NULL) {
size_t len = sizeof(isc_sockaddr_t); size_t len = sizeof(isc_sockaddr_t);
@@ -2775,9 +2777,12 @@ send_udp(dig_query_t *query) {
next = ISC_LIST_NEXT(query, link); next = ISC_LIST_NEXT(query, link);
l = query->lookup; l = query->lookup;
clear_query(query); clear_query(query);
if (next == NULL) if (next == NULL) {
printf(";; No acceptable nameservers\n"); printf(";; No acceptable nameservers\n");
check_next_lookup(l); check_next_lookup(l);
} else {
send_udp(next);
}
return; return;
} }
@@ -2909,7 +2914,7 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
isc_buffer_t *b = NULL; isc_buffer_t *b = NULL;
isc_result_t result; isc_result_t result;
dig_query_t *query = NULL; dig_query_t *query = NULL;
dig_lookup_t *l; dig_lookup_t *l, *n;
isc_uint16_t length; isc_uint16_t length;
REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE);
@@ -2944,13 +2949,20 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
sizeof(sockstr)); sizeof(sockstr));
printf(";; communications error to %s: %s\n", printf(";; communications error to %s: %s\n",
sockstr, isc_result_totext(sevent->result)); sockstr, isc_result_totext(sevent->result));
if (keep != NULL)
isc_socket_detach(&keep);
l = query->lookup; l = query->lookup;
isc_socket_detach(&query->sock); isc_socket_detach(&query->sock);
sockcount--; sockcount--;
debug("sockcount=%d", sockcount); debug("sockcount=%d", sockcount);
INSIST(sockcount >= 0); INSIST(sockcount >= 0);
if (sevent->result == ISC_R_EOF && l->eoferr == 0U) {
n = requeue_lookup(l, ISC_TRUE);
n->eoferr++;
}
isc_event_free(&event); isc_event_free(&event);
clear_query(query); clear_query(query);
cancel_lookup(l);
check_next_lookup(l); check_next_lookup(l);
UNLOCK_LOOKUP; UNLOCK_LOOKUP;
return; return;
@@ -3443,13 +3455,20 @@ recv_done(isc_task_t *task, isc_event_t *event) {
} else { } else {
printf(";; communications error: %s\n", printf(";; communications error: %s\n",
isc_result_totext(sevent->result)); isc_result_totext(sevent->result));
if (keep != NULL)
isc_socket_detach(&keep);
isc_socket_detach(&query->sock); isc_socket_detach(&query->sock);
sockcount--; sockcount--;
debug("sockcount=%d", sockcount); debug("sockcount=%d", sockcount);
INSIST(sockcount >= 0); INSIST(sockcount >= 0);
} }
if (sevent->result == ISC_R_EOF && l->eoferr == 0U) {
n = requeue_lookup(l, ISC_TRUE);
n->eoferr++;
}
isc_event_free(&event); isc_event_free(&event);
clear_query(query); clear_query(query);
cancel_lookup(l);
check_next_lookup(l); check_next_lookup(l);
UNLOCK_LOOKUP; UNLOCK_LOOKUP;
return; return;
@@ -3511,6 +3530,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
if (fail) { if (fail) {
isc_event_free(&event); isc_event_free(&event);
clear_query(query); clear_query(query);
cancel_lookup(l);
check_next_lookup(l); check_next_lookup(l);
UNLOCK_LOOKUP; UNLOCK_LOOKUP;
return; return;
@@ -3614,6 +3634,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
if (l->tcp_mode) { if (l->tcp_mode) {
isc_event_free(&event); isc_event_free(&event);
clear_query(query); clear_query(query);
cancel_lookup(l);
check_next_lookup(l); check_next_lookup(l);
UNLOCK_LOOKUP; UNLOCK_LOOKUP;
return; return;

View File

@@ -168,6 +168,7 @@ struct dig_lookup {
unsigned int ednsflags; unsigned int ednsflags;
dns_opcode_t opcode; dns_opcode_t opcode;
int rrcomments; int rrcomments;
unsigned int eoferr;
}; };
/*% The dig_query structure */ /*% The dig_query structure */