mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-04 16:45:24 +00:00
snapshot; dispatch list stuff
This commit is contained in:
218
lib/dns/dispatchlist.c
Normal file
218
lib/dns/dispatchlist.c
Normal file
@@ -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 <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <isc/mem.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/dispatch.h>
|
||||
#include <dns/dispatchlist.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
}
|
173
lib/dns/include/dns/dispatchlist.h
Normal file
173
lib/dns/include/dns/dispatchlist.h
Normal file
@@ -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 <isc/lang.h>
|
||||
|
||||
#include <dns/types.h>
|
||||
|
||||
/*
|
||||
* 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 */
|
Reference in New Issue
Block a user