portlist.c revision 70e5a7403f0e0a3bd292b8287c5fed5772c15270
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*
2728d0618e15ee3a2ecc5f6d15acd7898e6de85aTinderbox User * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * Copyright (C) 2003 Internet Software Consortium.
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Permission to use, copy, modify, and/or distribute this software for any
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * purpose with or without fee is hereby granted, provided that the above
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * copyright notice and this permission notice appear in all copies.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Hunt * PERFORMANCE OF THIS SOFTWARE.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/* $Id: portlist.c,v 1.13 2007/06/19 23:47:16 tbox Exp $ */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*! \file */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <config.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <stdlib.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/magic.h>
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt#include <isc/mem.h>
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt#include <isc/mutex.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/net.h>
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt#include <isc/refcount.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/result.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/string.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/types.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/util.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <dns/types.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <dns/portlist.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define DNS_PORTLIST_MAGIC ISC_MAGIC('P','L','S','T')
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define DNS_VALID_PORTLIST(p) ISC_MAGIC_VALID(p, DNS_PORTLIST_MAGIC)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunttypedef struct dns_element {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt in_port_t port;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_uint16_t flags;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt} dns_element_t;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
e20788e1216ed720aefa84f3295f7899d9f28c22Mark Andrewsstruct dns_portlist {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int magic;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_t *mctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_refcount_t refcount;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mutex_t lock;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dns_element_t *list;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int allocated;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int active;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt};
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define DNS_PL_INET 0x0001
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define DNS_PL_INET6 0x0002
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define DNS_PL_ALLOCATE 16
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic int
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntcompare(const void *arg1, const void *arg2) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt const dns_element_t *e1 = (const dns_element_t *)arg1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt const dns_element_t *e2 = (const dns_element_t *)arg2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (e1->port < e2->port)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (-1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (e1->port > e2->port)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (0);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Huntisc_result_t
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Huntdns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dns_portlist_t *portlist;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t result;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(portlistp != NULL && *portlistp == NULL);
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist = isc_mem_get(mctx, sizeof(*portlist));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (portlist == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = isc_mutex_init(&portlist->lock);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (result != ISC_R_SUCCESS) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(mctx, portlist, sizeof(*portlist));
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt return (result);
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = isc_refcount_init(&portlist->refcount, 1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (result != ISC_R_SUCCESS) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DESTROYLOCK(&portlist->lock);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(mctx, portlist, sizeof(*portlist));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (result);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->list = NULL;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt portlist->allocated = 0;
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt portlist->active = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->mctx = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_attach(mctx, &portlist->mctx);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->magic = DNS_PORTLIST_MAGIC;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *portlistp = portlist;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic dns_element_t *
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntfind_port(dns_element_t *list, unsigned int len, in_port_t port) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int xtry = len / 2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int min = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int max = len - 1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int last = len;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (;;) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (list[xtry].port == port)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (&list[xtry]);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (port > list[xtry].port) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (xtry == max)
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt min = xtry;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt xtry = xtry + (max - xtry + 1) / 2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(xtry <= max);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (xtry == last)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt last = min;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt } else {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (xtry == min)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt max = xtry;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt xtry = xtry - (xtry - min + 1) / 2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(xtry >= min);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (xtry == last)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt last = max;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt return (NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntdns_portlist_add(dns_portlist_t *portlist, int af, in_port_t port) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dns_element_t *el;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t result;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(DNS_VALID_PORTLIST(portlist));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(af == AF_INET || af == AF_INET6);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt LOCK(&portlist->lock);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (portlist->active != 0) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt el = find_port(portlist->list, portlist->active, port);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (el != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (af == AF_INET)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt el->flags |= DNS_PL_INET;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt el->flags |= DNS_PL_INET6;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = ISC_R_SUCCESS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto unlock;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (portlist->allocated <= portlist->active) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int allocated;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt allocated = portlist->allocated + DNS_PL_ALLOCATE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt el = isc_mem_get(portlist->mctx, sizeof(*el) * allocated);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (el == NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = ISC_R_NOMEMORY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto unlock;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (portlist->list != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memcpy(el, portlist->list,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->allocated * sizeof(*el));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(portlist->mctx, portlist->list,
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt portlist->allocated * sizeof(*el));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt portlist->list = el;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->allocated = allocated;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->list[portlist->active].port = port;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (af == AF_INET)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->list[portlist->active].flags = DNS_PL_INET;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->list[portlist->active].flags = DNS_PL_INET6;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->active++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt qsort(portlist->list, portlist->active, sizeof(*el), compare);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = ISC_R_SUCCESS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unlock:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt UNLOCK(&portlist->lock);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (result);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntvoid
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntdns_portlist_remove(dns_portlist_t *portlist, int af, in_port_t port) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dns_element_t *el;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(DNS_VALID_PORTLIST(portlist));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(af == AF_INET || af == AF_INET6);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt LOCK(&portlist->lock);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (portlist->active != 0) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt el = find_port(portlist->list, portlist->active, port);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (el != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (af == AF_INET)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt el->flags &= ~DNS_PL_INET;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt el->flags &= ~DNS_PL_INET6;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (el->flags == 0) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *el = portlist->list[portlist->active];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->active--;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt qsort(portlist->list, portlist->active,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt sizeof(*el), compare);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt UNLOCK(&portlist->lock);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Huntisc_boolean_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntdns_portlist_match(dns_portlist_t *portlist, int af, in_port_t port) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dns_element_t *el;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_boolean_t result = ISC_FALSE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(DNS_VALID_PORTLIST(portlist));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(af == AF_INET || af == AF_INET6);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt LOCK(&portlist->lock);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (portlist->active != 0) {
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt el = find_port(portlist->list, portlist->active, port);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt if (el != NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (af == AF_INET && (el->flags & DNS_PL_INET) != 0)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = ISC_TRUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (af == AF_INET6 && (el->flags & DNS_PL_INET6) != 0)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = ISC_TRUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt UNLOCK(&portlist->lock);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (result);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntvoid
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntdns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(DNS_VALID_PORTLIST(portlist));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(portlistp != NULL && *portlistp == NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_refcount_increment(&portlist->refcount, NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *portlistp = portlist;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntvoid
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntdns_portlist_detach(dns_portlist_t **portlistp) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dns_portlist_t *portlist;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int count;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(portlistp != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist = *portlistp;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(DNS_VALID_PORTLIST(portlist));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *portlistp = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_refcount_decrement(&portlist->refcount, &count);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (count == 0) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->magic = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_refcount_destroy(&portlist->refcount);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (portlist->list != NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(portlist->mctx, portlist->list,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt portlist->allocated *
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt sizeof(*portlist->list));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DESTROYLOCK(&portlist->lock);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_putanddetach(&portlist->mctx, portlist,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt sizeof(*portlist));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt