From 1cf2ee1ef0e850d43e931b7dadf20de61559eb4c Mon Sep 17 00:00:00 2001 From: Michael Graff Date: Wed, 10 May 2000 07:28:33 +0000 Subject: [PATCH] snapshot; dispatch list stuff --- lib/dns/dispatchlist.c | 218 +++++++++++++++++++++++++++++ lib/dns/include/dns/dispatchlist.h | 173 +++++++++++++++++++++++ 2 files changed, 391 insertions(+) create mode 100644 lib/dns/dispatchlist.c create mode 100644 lib/dns/include/dns/dispatchlist.h diff --git a/lib/dns/dispatchlist.c b/lib/dns/dispatchlist.c new file mode 100644 index 0000000000..4cd7d2622e --- /dev/null +++ b/lib/dns/dispatchlist.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2000 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include + +#include + +#include +#include + +#include +#include +#include + +/* + * This module implements a dispatch list. The items on the list are + * dispatch objects. These dispatchers have attributes such as shared, + * TCP, UDP, IPv4, IPv6, etc. When searching for a usable shared + * dispatcher these flags are respected. + */ + +typedef struct dns__dle dns__dle_t; + +struct dns__dle { + dns_dispatch_t *disp; + unsigned int attributes; + ISC_LINK(dns__dle_t) link; +}; + +struct dns_dispatchlist { + /* Unlocked. */ + unsigned int magic; + isc_mem_t *mctx; + + /* Locked. */ + isc_mutex_t lock; + unsigned int state; + ISC_LIST(dns__dle_t) list; +}; + +#define SHUTTINGDOWN 0x00000001U +#define IS_SHUTTINGDOWN(l) (((l)->state & SHUTTINGDOWN) != 0) + +#define DNS_DISPATCHLIST_MAGIC ISC_MAGIC('D', 'l', 's', 't') +#define DNS_DISPATCHLIST_VALID(a) \ + ISC_MAGIC_VALID(a, DNS_DISPATCHLIST_MAGIC) + + +isc_result_t +dns_dispatchlist_create(isc_mem_t *mctx, dns_dispatchlist_t **listp) +{ + dns_dispatchlist_t *list; + isc_result_t result; + + REQUIRE(mctx != NULL); + REQUIRE(listp != NULL && *listp == NULL); + + list = isc_mem_get(mctx, sizeof(dns_dispatchlist_t)); + if (list == NULL) + return (ISC_R_NOMEMORY); + + result = isc_mutex_init(&list->lock); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, list, sizeof(dns_dispatchlist_t)); + return (result); + } + + list->magic = DNS_DISPATCHLIST_MAGIC; + list->state = 0; + list->mctx = NULL; + isc_mem_attach(mctx, &list->mctx); + ISC_LIST_INIT(list->list); + + *listp = list; + return (ISC_R_SUCCESS); +} + +/* + * List must be locked when calling this function. + */ +static isc_boolean_t +destroy_ok(dns_dispatchlist_t *list) +{ + if ((list->state & SHUTTINGDOWN) == 0) + return (ISC_FALSE); + if (!ISC_LIST_EMPTY(list->list)) + return (ISC_FALSE); + + return (ISC_TRUE); +} + +/* + * List must be unlocked when calling this function. + */ +static void +destroy(dns_dispatchlist_t **listp) +{ + isc_mem_t *mctx; + dns_dispatchlist_t *list; + + list = *listp; + *listp = NULL; + + mctx = list->mctx; + + list->magic = 0; + list->mctx = 0; + isc_mutex_destroy(&list->lock); + list->state = 0; + + isc_mem_put(mctx, list, sizeof(dns_dispatchlist_t)); + isc_mem_detach(&mctx); +} + +void +dns_dispatchlist_destroy(dns_dispatchlist_t **listp) +{ + dns_dispatchlist_t *list; + isc_boolean_t killit; + + REQUIRE(listp != NULL); + REQUIRE(DNS_DISPATCHLIST_VALID(*listp)); + RUNTIME_CHECK(destory_ok(*listp)); + + list = *listp; + *listp = NULL; + + LOCK(&list->lock); + list->state |= SHUTTINGDOWN; + killit = destroy_ok(list); + UNLOCK(&list->lock); + + if (killit) + destroy(&list); +} + +isc_result_t +dns_dispatchlist_add(dns_dispatchlist_t *list, dns_dispatch_t *disp, + unsigned int attributes) +{ + dns__dle_t *dle; + isc_result_t result; + + REQUIRE(DNS_DISPATCHLIST_VALID(list)); + REQUIRE(disp != NULL); + + LOCK(&list->lock); + if (IS_SHUTTINGDOWN(list)) { + result = ISC_R_SHUTTINGDOWN; + goto out; + } + + dle = isc_mem_get(list->mctx, sizeof(dns__dle_t)); + if (dle == NULL) { + result = ISC_R_NOMEMORY; + goto out; + } + + dle->disp = NULL; + dns_dispatch_attach(disp, &dle->disp); + dle->attributes = attributes; + ISC_LINK_INIT(dle, link); + ISC_LIST_APPEND(list->list, dle, link); + + result = ISC_R_SUCCESS; + + out: + UNLOCK(&list->lock); + return (result); +} + +isc_result_t +dns_dispatchlist_delete(dns_dispatchlist_t *list, dns_dispatch_t *disp) +{ + dns__dle_t *dle; + isc_result_t result; + + dle = ISC_LIST_HEAD(list->list); + while (dle != NULL) { + if (dle->disp == disp) + break; + dle = ISC_LIST_NEXT(dle, link); + } + + if (dle == NULL) { + result = ISC_R_NOTFOUND; + goto out; + } + + ISC_LIST_UNLINK(list->list, dle, link); + dns_dispatch_detach(&dle->disp); + result = ISC_R_SUCCESS; + + out: + killit = destroy_ok(list); + UNLOCK(&list->lock); + return (result); +} + +isc_result_t +dns_dispatchlist_find(dns_dispatchlist_t *list, unsigned int attributes, + unsigned int mask, dns_dispatch_t **dispp) +{ +} diff --git a/lib/dns/include/dns/dispatchlist.h b/lib/dns/include/dns/dispatchlist.h new file mode 100644 index 0000000000..bc78835a7f --- /dev/null +++ b/lib/dns/include/dns/dispatchlist.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2000 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifndef DNS_DISPATCHLIST_H +#define DNS_DISPATCHLIST_H 1 + +/***** + ***** Module Info + *****/ + +/* + * DNS Dispatch List Management + * + * Maintains a list of dispatchers to help various parts of the DNS + * library and applications keep track and share dispatchers. + * + * MP: + * + * All locking is performed internally to each list. + * + * dns_dispatchlist_find() will return dispatches which are + * attached. + * + * Reliability: + * + * Resources: + * + * Security: + * + * None. + * + * Standards: + * + * None. + */ + +/*** + *** Imports + ***/ + +#include + +#include + +/* + * Attributes for added dispatchers. + * + * Values with the mask 0xffff0000 are application defined. + * Values with the mask 0x0000ffff are library defined. + */ +#define DNS_DISPATCHLISTATTR_TCP 0x00000001U +#define DNS_DISPATCHLISTATTR_UDP 0x00000002U +#define DNS_DISPATCHLISTATTR_PRIVATE 0x00000004U + +ISC_LANG_BEGINDECLS + +isc_result_t +dns_dispatchlist_create(isc_mem_t *mctx, dns_dispatchlist_t **listp); +/* + * Creates a new dispatchlist object. + * + * Requires: + * "mctx" be a valid memory context. + * + * listp != NULL && *listp == NULL + * + * Returns: + * ISC_R_SUCCESS -- all ok + * + * anythign else -- failure + */ + + +void +dns_dispatchlist_destroy(dns_dispatchlist_t **listp); +/* + * Destroys the dispatchlist when it becomes empty. This could be + * immediately. + * + * Requires: + * listp != NULL && *listp is a valid dispatchlist. + */ + + +isc_result_t +dns_dispatchlist_add(dns_dispatchlist_t *list, dns_dispatch_t *disp, + unsigned int attributes); +/* + * Add a new dispatch object to the dispatch list with the attributes + * supplied. + * + * Requires: + * "list" be a valid dispatchlist. + * + * "disp" be a valid dispatcher that is not already present on "list" + * + * Ensures: + * On successful return, the dispatcher is attached, preventing it + * from being deleted while on the dispatchlist. + * + * Returns: + * ISC_R_SUCCESS -- added. + * + * anything else -- failure. + */ + + +isc_result_t +dns_dispatchlist_delete(dns_dispatchlist_t *list, dns_dispatch_t *disp); +/* + * Deletes the dispatcher from the list. + * + * Requires: + * "list" be a valid dispatchlist. + * + * "disp" be a valid dispatcher. + * + * Ensures: + * On successful return, the dispatcher is detached once, allowing it + * to be deleted. + * + * Returns: + * ISC_R_SUCCESS -- deleted. + * + * ISC_R_NOTFOUND -- dispatcher is not on the list. + * + * anything else -- failure. + */ + + +isc_result_t +dns_dispatchlist_find(dns_dispatchlist_t *list, unsigned int attributes, + unsigned int mask, dns_dispatch_t **dispp); +/* + * Search for a dispatcher that has the attributes specified by + * (attributes & mask) + * + * Requires: + * "list" be a valid dispatchlist. + * + * dispp != NULL && *dispp == NULL. + * + * Ensures: + * The dispatcher returned into *dispp is attached on behalf of the + * caller. It is required that the caller detach from it when it is + * no longer needed. + * + * Returns: + * ISC_R_SUCCESS -- found. + * + * ISC_R_NOTFOUND -- no dispatcher matching the requirements found. + * + * anything else -- failure. + */ + + +ISC_LANG_ENDDECLS + +#endif /* DNS_DISPATCHLIST_H */