2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 23:25:38 +00:00

781. [func] Avoid error packet loops by dropping duplicate FORMERR

responses. [RT #1006]
This commit is contained in:
Andreas Gustafsson
2001-03-19 20:52:21 +00:00
parent 484deb5c3e
commit 4c03e69ab8
3 changed files with 51 additions and 2 deletions

View File

@@ -1,3 +1,7 @@
781. [func] Avoid error packet loops by dropping duplicate FORMERR
responses. [RT #1006]
780. [bug] Error handling code dealing with out of memory or 780. [bug] Error handling code dealing with out of memory or
other rare errors could lead to assertion failures other rare errors could lead to assertion failures
when calling functions on unitialized names. [RT #1065] when calling functions on unitialized names. [RT #1065]

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: client.c,v 1.159 2001/03/12 22:27:14 bwelling Exp $ */ /* $Id: client.c,v 1.160 2001/03/19 20:52:19 gson Exp $ */
#include <config.h> #include <config.h>
@@ -950,6 +950,33 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
} }
} }
message->rcode = rcode; message->rcode = rcode;
/*
* FORMERR loop avoidance: If we sent a FORMERR message
* with the same ID to the same client less than two
* seconds ago, assume that we are in an infinite error
* packet dialog with a server for some protocol whose
* error responses look enough like DNS queries to
* elicit a FORMERR response. Drop a packet to break
* the loop.
*/
if (rcode == dns_rcode_formerr) {
if (isc_sockaddr_equal(&client->peeraddr,
&client->formerrcache.addr) &&
message->id == client->formerrcache.id &&
client->requesttime - client->formerrcache.time < 2) {
/* Drop packet. */
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
"possible error packet loop, "
"FORMERR dropped");
ns_client_next(client, result);
return;
}
client->formerrcache.addr = client->peeraddr;
client->formerrcache.time = client->requesttime;
client->formerrcache.id = message->id;
}
ns_client_send(client); ns_client_send(client);
} }
@@ -1618,6 +1645,13 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp)
ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL, ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL,
NS_EVENT_CLIENTCONTROL, client_start, client, client, NS_EVENT_CLIENTCONTROL, client_start, client, client,
NULL, NULL); NULL, NULL);
/*
* Initialize FORMERR cache to sentinel value that will not match
* any actual FORMERR response.
*/
isc_sockaddr_any(&client->formerrcache.addr);
client->formerrcache.time = 0;
client->formerrcache.id = 0;
ISC_LINK_INIT(client, link); ISC_LINK_INIT(client, link);
client->list = NULL; client->list = NULL;

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: client.h,v 1.56 2001/03/11 06:19:39 marka Exp $ */ /* $Id: client.h,v 1.57 2001/03/19 20:52:21 gson Exp $ */
#ifndef NAMED_CLIENT_H #ifndef NAMED_CLIENT_H
#define NAMED_CLIENT_H 1 #define NAMED_CLIENT_H 1
@@ -133,6 +133,17 @@ struct ns_client {
isc_boolean_t peeraddr_valid; isc_boolean_t peeraddr_valid;
struct in6_pktinfo pktinfo; struct in6_pktinfo pktinfo;
isc_event_t ctlevent; isc_event_t ctlevent;
/*
* Information about recent FORMERR response(s), for
* FORMERR loop avoidance. This is separate for each
* client object rather than global only to avoid
* the need for locking.
*/
struct {
isc_sockaddr_t addr;
isc_stdtime_t time;
dns_messageid_t id;
} formerrcache;
ISC_LINK(ns_client_t) link; ISC_LINK(ns_client_t) link;
/* /*
* The list 'link' is part of, or NULL if not on any list. * The list 'link' is part of, or NULL if not on any list.