diff --git a/CHANGES b/CHANGES index 4baa0b628a..a6e643e5ca 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3138. [bug] Address memory leaks and out-of-order operations when + shutting named down. [RT #25210] + 3137. [func] Improve hardware scalability by allowing multiple worker threads to process incoming UDP packets. This can significantly increase query throughput diff --git a/bin/named/client.c b/bin/named/client.c index 0e26afa7c2..4202e26707 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.c,v 1.274 2011/07/28 04:04:36 each Exp $ */ +/* $Id: client.c,v 1.275 2011/07/28 04:27:26 marka Exp $ */ #include @@ -1313,6 +1313,12 @@ ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, UNUSED(arg); + /* + * ns_g_server->interfacemgr is task exclusive locked. + */ + if (ns_g_server->interfacemgr == NULL) + return (ISC_TRUE); + if (!ns_interfacemgr_listeningon(ns_g_server->interfacemgr, dstaddr)) return (ISC_FALSE); diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c index 4fd918989e..dc9e69c949 100644 --- a/bin/named/xfrout.c +++ b/bin/named/xfrout.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrout.c,v 1.141 2011/03/10 23:47:49 tbox Exp $ */ +/* $Id: xfrout.c,v 1.142 2011/07/28 04:27:26 marka Exp $ */ #include @@ -1064,9 +1064,9 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) { CHECK(xfr->stream->methods->first(xfr->stream)); - if (xfr->tsigkey != NULL) { + if (xfr->tsigkey != NULL) dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname)); - } else + else keyname[0] = '\0'; if (is_poll) xfrout_log1(client, question_name, question_class, @@ -1136,7 +1136,8 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id, xfr = isc_mem_get(mctx, sizeof(*xfr)); if (xfr == NULL) return (ISC_R_NOMEMORY); - xfr->mctx = mctx; + xfr->mctx = NULL; + isc_mem_attach(mctx, &xfr->mctx); xfr->client = NULL; ns_client_attach(client, &xfr->client); xfr->id = id; @@ -1510,6 +1511,7 @@ sendstream(xfrout_ctx_t *xfr) { static void xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { xfrout_ctx_t *xfr = *xfrp; + ns_client_t *client = NULL; INSIST(xfr->sends == 0); @@ -1533,9 +1535,14 @@ xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { if (xfr->db != NULL) dns_db_detach(&xfr->db); + /* + * We want to detch the client after we have released the memory + * context as ns_client_detach checks the memory reference count. + */ + ns_client_attach(xfr->client, &client); ns_client_detach(&xfr->client); - - isc_mem_put(xfr->mctx, xfr, sizeof(*xfr)); + isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); + ns_client_detach(&client); *xfrp = NULL; } diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index 796044d5b2..c35b4fd965 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.c,v 1.341 2011/07/28 04:04:37 each Exp $ */ +/* $Id: socket.c,v 1.342 2011/07/28 04:27:26 marka Exp $ */ /*! \file */ @@ -4538,9 +4538,8 @@ isc__socket_recvv(isc_socket_t *sock0, isc_bufferlist_t *buflist, INSIST(sock->bound); dev = allocate_socketevent(sock, ISC_SOCKEVENT_RECVDONE, action, arg); - if (dev == NULL) { + if (dev == NULL) return (ISC_R_NOMEMORY); - } /* * UDP sockets are always partial read @@ -4744,9 +4743,8 @@ isc__socket_sendto(isc_socket_t *sock0, isc_region_t *region, INSIST(sock->bound); dev = allocate_socketevent(sock, ISC_SOCKEVENT_SENDDONE, action, arg); - if (dev == NULL) { + if (dev == NULL) return (ISC_R_NOMEMORY); - } dev->region = *region; @@ -4785,9 +4783,8 @@ isc__socket_sendtov(isc_socket_t *sock0, isc_bufferlist_t *buflist, REQUIRE(iocount > 0); dev = allocate_socketevent(sock, ISC_SOCKEVENT_SENDDONE, action, arg); - if (dev == NULL) { + if (dev == NULL) return (ISC_R_NOMEMORY); - } /* * Move each buffer from the passed in list to our internal one. @@ -5205,6 +5202,7 @@ isc__socket_accept(isc_socket_t *sock0, */ isc_task_attach(task, &ntask); if (isc_task_exiting(ntask)) { + free_socket(&nsock); isc_task_detach(&ntask); isc_event_free(ISC_EVENT_PTR(&dev)); UNLOCK(&sock->lock); diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index 4343454a44..1c5935878c 100644 --- a/lib/isc/win32/socket.c +++ b/lib/isc/win32/socket.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.c,v 1.88 2011/07/28 04:04:37 each Exp $ */ +/* $Id: socket.c,v 1.89 2011/07/28 04:27:27 marka Exp $ */ /* This code uses functions which are only available on Server 2003 and * higher, and Windows XP and higher. @@ -3346,6 +3346,7 @@ isc__socket_accept(isc_socket_t *sock, */ isc_task_attach(task, &ntask); if (isc_task_exiting(ntask)) { + free_socket(&nsock, __LINE__); isc_task_detach(&ntask); isc_event_free(ISC_EVENT_PTR(&adev)); UNLOCK(&sock->lock);