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:
4
CHANGES
4
CHANGES
@@ -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]
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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.
|
||||||
|
Reference in New Issue
Block a user