Annotation of src/external/mpl/bind/dist/lib/dns/forward.c, Revision 1.1.1.2
1.1 christos 1: /* $NetBSD$ */
2:
3: /*
4: * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5: *
6: * This Source Code Form is subject to the terms of the Mozilla Public
7: * License, v. 2.0. If a copy of the MPL was not distributed with this
8: * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9: *
10: * See the COPYRIGHT file distributed with this work for additional
11: * information regarding copyright ownership.
12: */
13:
14: /*! \file */
15:
16: #include <config.h>
17:
18: #include <isc/magic.h>
19: #include <isc/mem.h>
20: #include <isc/rwlock.h>
21: #include <isc/util.h>
22:
23: #include <dns/forward.h>
24: #include <dns/rbt.h>
25: #include <dns/result.h>
26: #include <dns/types.h>
27:
28: struct dns_fwdtable {
29: /* Unlocked. */
30: unsigned int magic;
31: isc_mem_t *mctx;
32: isc_rwlock_t rwlock;
33: /* Locked by lock. */
34: dns_rbt_t *table;
35: };
36:
37: #define FWDTABLEMAGIC ISC_MAGIC('F', 'w', 'd', 'T')
38: #define VALID_FWDTABLE(ft) ISC_MAGIC_VALID(ft, FWDTABLEMAGIC)
39:
40: static void
41: auto_detach(void *, void *);
42:
43: isc_result_t
44: dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep) {
45: dns_fwdtable_t *fwdtable;
46: isc_result_t result;
47:
48: REQUIRE(fwdtablep != NULL && *fwdtablep == NULL);
49:
50: fwdtable = isc_mem_get(mctx, sizeof(dns_fwdtable_t));
51: if (fwdtable == NULL)
52: return (ISC_R_NOMEMORY);
53:
54: fwdtable->table = NULL;
55: result = dns_rbt_create(mctx, auto_detach, fwdtable, &fwdtable->table);
56: if (result != ISC_R_SUCCESS)
57: goto cleanup_fwdtable;
58:
59: result = isc_rwlock_init(&fwdtable->rwlock, 0, 0);
60: if (result != ISC_R_SUCCESS)
61: goto cleanup_rbt;
62:
63: fwdtable->mctx = NULL;
64: isc_mem_attach(mctx, &fwdtable->mctx);
65: fwdtable->magic = FWDTABLEMAGIC;
66: *fwdtablep = fwdtable;
67:
68: return (ISC_R_SUCCESS);
69:
70: cleanup_rbt:
71: dns_rbt_destroy(&fwdtable->table);
72:
73: cleanup_fwdtable:
74: isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t));
75:
76: return (result);
77: }
78:
79: isc_result_t
80: dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, const dns_name_t *name,
81: dns_forwarderlist_t *fwdrs, dns_fwdpolicy_t fwdpolicy)
82: {
83: isc_result_t result;
84: dns_forwarders_t *forwarders;
85: dns_forwarder_t *fwd, *nfwd;
86:
87: REQUIRE(VALID_FWDTABLE(fwdtable));
88:
89: forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t));
90: if (forwarders == NULL)
91: return (ISC_R_NOMEMORY);
92:
93: ISC_LIST_INIT(forwarders->fwdrs);
94: for (fwd = ISC_LIST_HEAD(*fwdrs);
95: fwd != NULL;
96: fwd = ISC_LIST_NEXT(fwd, link))
97: {
98: nfwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t));
99: if (nfwd == NULL) {
100: result = ISC_R_NOMEMORY;
101: goto cleanup;
102: }
103: *nfwd = *fwd;
104: ISC_LINK_INIT(nfwd, link);
105: ISC_LIST_APPEND(forwarders->fwdrs, nfwd, link);
106: }
107: forwarders->fwdpolicy = fwdpolicy;
108:
109: RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
110: result = dns_rbt_addname(fwdtable->table, name, forwarders);
111: RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
112:
113: if (result != ISC_R_SUCCESS)
114: goto cleanup;
115:
116: return (ISC_R_SUCCESS);
117:
118: cleanup:
119: while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
120: fwd = ISC_LIST_HEAD(forwarders->fwdrs);
121: ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
122: isc_mem_put(fwdtable->mctx, fwd, sizeof(isc_sockaddr_t));
123: }
124: isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
125: return (result);
126: }
127:
128: isc_result_t
129: dns_fwdtable_add(dns_fwdtable_t *fwdtable, const dns_name_t *name,
130: isc_sockaddrlist_t *addrs, dns_fwdpolicy_t fwdpolicy)
131: {
132: isc_result_t result;
133: dns_forwarders_t *forwarders;
134: dns_forwarder_t *fwd;
135: isc_sockaddr_t *sa;
136:
137: REQUIRE(VALID_FWDTABLE(fwdtable));
138:
139: forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t));
140: if (forwarders == NULL)
141: return (ISC_R_NOMEMORY);
142:
143: ISC_LIST_INIT(forwarders->fwdrs);
144: for (sa = ISC_LIST_HEAD(*addrs);
145: sa != NULL;
146: sa = ISC_LIST_NEXT(sa, link))
147: {
148: fwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t));
149: if (fwd == NULL) {
150: result = ISC_R_NOMEMORY;
151: goto cleanup;
152: }
153: fwd->addr = *sa;
154: fwd->dscp = -1;
155: ISC_LINK_INIT(fwd, link);
156: ISC_LIST_APPEND(forwarders->fwdrs, fwd, link);
157: }
158: forwarders->fwdpolicy = fwdpolicy;
159:
160: RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
161: result = dns_rbt_addname(fwdtable->table, name, forwarders);
162: RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
163:
164: if (result != ISC_R_SUCCESS)
165: goto cleanup;
166:
167: return (ISC_R_SUCCESS);
168:
169: cleanup:
170: while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
171: fwd = ISC_LIST_HEAD(forwarders->fwdrs);
172: ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
173: isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t));
174: }
175: isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
176: return (result);
177: }
178:
179: isc_result_t
180: dns_fwdtable_delete(dns_fwdtable_t *fwdtable, const dns_name_t *name) {
181: isc_result_t result;
182:
183: REQUIRE(VALID_FWDTABLE(fwdtable));
184:
185: RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
1.1.1.2 ! christos 186: result = dns_rbt_deletename(fwdtable->table, name, false);
1.1 christos 187: RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
188:
189: if (result == DNS_R_PARTIALMATCH)
190: result = ISC_R_NOTFOUND;
191:
192: return (result);
193: }
194:
195: isc_result_t
196: dns_fwdtable_find(dns_fwdtable_t *fwdtable, const dns_name_t *name,
1.1.1.2 ! christos 197: dns_name_t *foundname, dns_forwarders_t **forwardersp)
1.1 christos 198: {
199: isc_result_t result;
200:
201: REQUIRE(VALID_FWDTABLE(fwdtable));
202:
203: RWLOCK(&fwdtable->rwlock, isc_rwlocktype_read);
204:
205: result = dns_rbt_findname(fwdtable->table, name, 0, foundname,
206: (void **)forwardersp);
207: if (result == DNS_R_PARTIALMATCH)
208: result = ISC_R_SUCCESS;
209:
210: RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_read);
211:
212: return (result);
213: }
214:
215: void
216: dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep) {
217: dns_fwdtable_t *fwdtable;
218: isc_mem_t *mctx;
219:
220: REQUIRE(fwdtablep != NULL && VALID_FWDTABLE(*fwdtablep));
221:
222: fwdtable = *fwdtablep;
223:
224: dns_rbt_destroy(&fwdtable->table);
225: isc_rwlock_destroy(&fwdtable->rwlock);
226: fwdtable->magic = 0;
227: mctx = fwdtable->mctx;
228: isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t));
229: isc_mem_detach(&mctx);
230:
231: *fwdtablep = NULL;
232: }
233:
234: /***
235: *** Private
236: ***/
237:
238: static void
239: auto_detach(void *data, void *arg) {
240: dns_forwarders_t *forwarders = data;
241: dns_fwdtable_t *fwdtable = arg;
242: dns_forwarder_t *fwd;
243:
244: UNUSED(arg);
245:
246: while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
247: fwd = ISC_LIST_HEAD(forwarders->fwdrs);
248: ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
249: isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t));
250: }
251: isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
252: }
CVSweb <webmaster@jp.NetBSD.org>