[BACK]Return to forward.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / mpl / bind / dist / lib / dns

Annotation of src/external/mpl/bind/dist/lib/dns/forward.c, Revision 1.3

1.2       christos    1: /*     $NetBSD: forward.c,v 1.1.1.8 2016/05/26 15:45:49 christos Exp $ */
1.1       christos    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.3     ! 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.3     ! 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>