diff options
author | Doug Barton <dougb@FreeBSD.org> | 2006-12-10 07:09:56 +0000 |
---|---|---|
committer | Doug Barton <dougb@FreeBSD.org> | 2006-12-10 07:09:56 +0000 |
commit | e99fbbb680307fe016c8db7d6611f1a3249761fb (patch) | |
tree | d7fa0e61cadfdb3b3752a55401049f2294a7cfaf /contrib/bind9/bin/named/client.c | |
parent | a02f92e875d0d48c46103eef0fbea835048a278b (diff) |
Vendor import of BIND 9.3.3
Notes
Notes:
svn path=/vendor/bind9/dist/; revision=165071
Diffstat (limited to 'contrib/bind9/bin/named/client.c')
-rw-r--r-- | contrib/bind9/bin/named/client.c | 105 |
1 files changed, 101 insertions, 4 deletions
diff --git a/contrib/bind9/bin/named/client.c b/contrib/bind9/bin/named/client.c index baecc2345cb9..b0ce793b98ea 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); +} |