summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/bin/named/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/bin/named/client.c')
-rw-r--r--contrib/bind9/bin/named/client.c105
1 files changed, 101 insertions, 4 deletions
diff --git a/contrib/bind9/bin/named/client.c b/contrib/bind9/bin/named/client.c
index baecc23..b0ce793 100644
--- a/contrib/bind9/bin/named/client.c
+++ b/contrib/bind9/bin/named/client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: client.c,v 1.176.2.13.4.26 2005/07/27 02:53:14 marka Exp $ */
+/* $Id: client.c,v 1.176.2.13.4.31 2006/07/22 01:09:38 marka Exp $ */
#include <config.h>
@@ -164,6 +164,12 @@ struct ns_clientmgr {
* Must be greater than any valid state.
*/
+/*
+ * Enable ns_client_dropport() by default.
+ */
+#ifndef NS_CLIENT_DROPPORT
+#define NS_CLIENT_DROPPORT 1
+#endif
static void client_read(ns_client_t *client);
static void client_accept(ns_client_t *client);
@@ -285,8 +291,17 @@ exit_check(ns_client_t *client) {
}
/*
* I/O cancel is complete. Burn down all state
- * related to the current request.
+ * related to the current request. Ensure that
+ * the client is on the active list and not the
+ * recursing list.
*/
+ LOCK(&client->manager->lock);
+ if (client->list == &client->manager->recursing) {
+ ISC_LIST_UNLINK(*client->list, client, link);
+ ISC_LIST_APPEND(client->manager->active, client, link);
+ client->list = &client->manager->active;
+ }
+ UNLOCK(&client->manager->lock);
ns_client_endrequest(client);
client->state = NS_CLIENTSTATE_READING;
@@ -972,6 +987,34 @@ ns_client_send(ns_client_t *client) {
ns_client_next(client, result);
}
+#if NS_CLIENT_DROPPORT
+#define DROPPORT_NO 0
+#define DROPPORT_REQUEST 1
+#define DROPPORT_RESPONSE 2
+/*%
+ * ns_client_dropport determines if certain requests / responses
+ * should be dropped based on the port number.
+ *
+ * Returns:
+ * \li 0: Don't drop.
+ * \li 1: Drop request.
+ * \li 2: Drop (error) response.
+ */
+static int
+ns_client_dropport(in_port_t port) {
+ switch (port) {
+ case 7: /* echo */
+ case 13: /* daytime */
+ case 19: /* chargen */
+ case 37: /* time */
+ return (DROPPORT_REQUEST);
+ case 464: /* kpasswd */
+ return (DROPPORT_RESPONSE);
+ }
+ return (DROPPORT_NO);
+}
+#endif
+
void
ns_client_error(ns_client_t *client, isc_result_t result) {
dns_rcode_t rcode;
@@ -984,6 +1027,28 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
message = client->message;
rcode = dns_result_torcode(result);
+#if NS_CLIENT_DROPPORT
+ /*
+ * Don't send FORMERR to ports on the drop port list.
+ */
+ if (rcode == dns_rcode_formerr &&
+ ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) !=
+ DROPPORT_NO) {
+ char buf[64];
+ isc_buffer_t b;
+
+ isc_buffer_init(&b, buf, sizeof(buf) - 1);
+ if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS)
+ isc_buffer_putstr(&b, "UNKNOWN RCODE");
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
+ NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
+ "dropped error (%.*s) response: suspicious port",
+ (int)isc_buffer_usedlength(&b), buf);
+ ns_client_next(client, ISC_R_SUCCESS);
+ return;
+ }
+#endif
+
/*
* Message may be an in-progress reply that we had trouble
* with, in which case QR will be set. We need to clear QR before
@@ -1208,6 +1273,17 @@ client_request(isc_task_t *task, isc_event_t *event) {
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+#if NS_CLIENT_DROPPORT
+ if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) ==
+ DROPPORT_REQUEST) {
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
+ NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
+ "dropped request: suspicious port");
+ ns_client_next(client, ISC_R_SUCCESS);
+ goto cleanup;
+ }
+#endif
+
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
"%s request",
@@ -1242,6 +1318,7 @@ client_request(isc_task_t *task, isc_event_t *event) {
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
"dropping multicast request");
ns_client_next(client, DNS_R_REFUSED);
+ goto cleanup;
}
result = dns_message_peekheader(buffer, &id, &flags);
@@ -1532,12 +1609,15 @@ client_request(isc_task_t *task, isc_event_t *event) {
* Decide whether recursive service is available to this client.
* We do this here rather than in the query code so that we can
* set the RA bit correctly on all kinds of responses, not just
- * responses to ordinary queries.
+ * responses to ordinary queries. Note if you can't query the
+ * cache there is no point in setting RA.
*/
ra = ISC_FALSE;
if (client->view->resolver != NULL &&
client->view->recursion == ISC_TRUE &&
ns_client_checkaclsilent(client, client->view->recursionacl,
+ ISC_TRUE) == ISC_R_SUCCESS &&
+ ns_client_checkaclsilent(client, client->view->queryacl,
ISC_TRUE) == ISC_R_SUCCESS)
ra = ISC_TRUE;
@@ -2364,3 +2444,20 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) {
}
UNLOCK(&manager->lock);
}
+
+void
+ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) {
+
+ if (client->manager != NULL)
+ LOCK(&client->manager->lock);
+ if (client->query.restarts > 0) {
+ /*
+ * client->query.qname was dynamically allocated.
+ */
+ dns_message_puttempname(client->message,
+ &client->query.qname);
+ }
+ client->query.qname = name;
+ if (client->manager != NULL)
+ UNLOCK(&client->manager->lock);
+}
OpenPOWER on IntegriCloud