Merge from vendor branch OPENSSH:
[dragonfly.git] / contrib / bind-9.2.4rc7 / bin / named / listenlist.c
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 2000, 2001  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: listenlist.c,v 1.9.2.1 2004/03/09 06:09:18 marka Exp $ */
19
20 #include <config.h>
21
22 #include <isc/mem.h>
23 #include <isc/util.h>
24
25 #include <dns/acl.h>
26
27 #include <named/listenlist.h>
28
29 static void
30 destroy(ns_listenlist_t *list);
31
32 isc_result_t
33 ns_listenelt_create(isc_mem_t *mctx, in_port_t port,
34                     dns_acl_t *acl, ns_listenelt_t **target)
35 {
36         ns_listenelt_t *elt = NULL;
37         REQUIRE(target != NULL && *target == NULL);
38         elt = isc_mem_get(mctx, sizeof(*elt));
39         if (elt == NULL)
40                 return (ISC_R_NOMEMORY);
41         elt->mctx = mctx;
42         ISC_LINK_INIT(elt, link);
43         elt->port = port;
44         elt->acl = acl;
45         *target = elt;
46         return (ISC_R_SUCCESS);
47 }
48
49 void
50 ns_listenelt_destroy(ns_listenelt_t *elt) {
51         if (elt->acl != NULL)
52                 dns_acl_detach(&elt->acl);
53         isc_mem_put(elt->mctx, elt, sizeof(*elt));
54 }
55
56 isc_result_t
57 ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target) {
58         ns_listenlist_t *list = NULL;
59         REQUIRE(target != NULL && *target == NULL);
60         list = isc_mem_get(mctx, sizeof(*list));
61         if (list == NULL)
62                 return (ISC_R_NOMEMORY);
63         list->mctx = mctx;
64         list->refcount = 1;
65         ISC_LIST_INIT(list->elts);
66         *target = list;
67         return (ISC_R_SUCCESS);
68 }
69
70 static void
71 destroy(ns_listenlist_t *list) {
72         ns_listenelt_t *elt, *next;
73         for (elt = ISC_LIST_HEAD(list->elts);
74              elt != NULL;
75              elt = next)
76         {
77                 next = ISC_LIST_NEXT(elt, link);
78                 ns_listenelt_destroy(elt);
79         }
80         isc_mem_put(list->mctx, list, sizeof(*list));
81 }
82
83 void
84 ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target) {
85         INSIST(source->refcount > 0);
86         source->refcount++;
87         *target = source;
88 }
89
90 void
91 ns_listenlist_detach(ns_listenlist_t **listp) {
92         ns_listenlist_t *list = *listp;
93         INSIST(list->refcount > 0);
94         list->refcount--;
95         if (list->refcount == 0)
96                 destroy(list);
97         *listp = NULL;
98 }
99
100 isc_result_t
101 ns_listenlist_default(isc_mem_t *mctx, in_port_t port,
102                       isc_boolean_t enabled, ns_listenlist_t **target)
103 {
104         isc_result_t result;
105         dns_acl_t *acl = NULL;
106         ns_listenelt_t *elt = NULL;
107         ns_listenlist_t *list = NULL;
108
109         REQUIRE(target != NULL && *target == NULL);
110         if (enabled)
111                 result = dns_acl_any(mctx, &acl);
112         else
113                 result = dns_acl_none(mctx, &acl);
114         if (result != ISC_R_SUCCESS)
115                 goto cleanup;
116
117         result = ns_listenelt_create(mctx, port, acl, &elt);
118         if (result != ISC_R_SUCCESS)
119                 goto cleanup_acl;
120
121         result = ns_listenlist_create(mctx, &list);
122         if (result != ISC_R_SUCCESS)
123                 goto cleanup_listenelt;
124
125         ISC_LIST_APPEND(list->elts, elt, link);
126
127         *target = list;
128         return (ISC_R_SUCCESS);
129
130  cleanup_listenelt:
131         ns_listenelt_destroy(elt);
132  cleanup_acl:
133         dns_acl_detach(&acl);
134  cleanup:
135         return (result);
136 }