portlist.c revision 12040a4f5c29f430cc3e0ced6b912b8cf7f5d301
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley/*
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater * Copyright (C) 2003 Internet Software Consortium.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Permission to use, copy, modify, and distribute this software for any
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * purpose with or without fee is hereby granted, provided that the above
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * copyright notice and this permission notice appear in all copies.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley */
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews/* $Id: portlist.c,v 1.4 2003/10/01 00:58:07 marka Exp $ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#include <stdlib.h>
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
110d1702731f42dd620879c1d765ebe91f3920ceMichael Graff#include <isc/magic.h>
110d1702731f42dd620879c1d765ebe91f3920ceMichael Graff#include <isc/mem.h>
c3b708aaf1bb0a118e0e11befa1b732acfb1d079Bob Halley#include <isc/mutex.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <isc/net.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/refcount.h>
c569a0e4d518bf30be1b2ba9cc3592fe470e9822Mark Andrews#include <isc/result.h>
def8e47c688e2480a4539d69c3d1a0a28a7c0550Mark Andrews#include <isc/string.h>
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <isc/types.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <isc/util.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
8dfa9caeec8e68db0c937e347a3d6629e7627d54Bob Halley#include <dns/types.h>
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley#include <dns/portlist.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews#define DNS_PORTLIST_MAGIC ISC_MAGIC('P','L','S','T')
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#define DNS_VALID_PORTLIST(p) ISC_MAGIC_VALID(p, DNS_PORTLIST_MAGIC)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleytypedef struct dns_element {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley in_port_t port;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley isc_uint16_t flags;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley} dns_element_t;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleystruct dns_portlist {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned int magic;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley isc_mem_t *mctx;
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley isc_refcount_t refcount;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley isc_mutex_t lock;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_element_t *list;
904a5734375869ffb504ed8cde6b68cafadb6d64Bob Halley unsigned int allocated;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned int active;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley};
ca67883a666bdf314d3da958d5195e7215b1f797Bob Halley
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley#define DNS_PL_INET 0x0001
b12f0228b32775ee688ed21ddbf3a116c1adfb43Michael Graff#define DNS_PL_INET6 0x0002
61fb42c4ef45d88e115bd769c30c4f36b461870bMark Andrews#define DNS_PL_ALLOCATE 16
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleystatic int
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleycompare(const void *arg1, const void *arg2) {
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews const dns_element_t *e1 = (const dns_element_t *)arg1;
e496615043400500492fa7b891c515c8e7cb7d08Bob Halley const dns_element_t *e2 = (const dns_element_t *)arg2;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews if (e1->port < e2->port)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley return (-1);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (e1->port > e2->port)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley return (1);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley return (0);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley}
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleyisc_result_t
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleydns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_portlist_t *portlist;
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley isc_result_t result;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence REQUIRE(portlistp != NULL && *portlistp == NULL);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley portlist = isc_mem_get(mctx, sizeof(*portlist));
904a5734375869ffb504ed8cde6b68cafadb6d64Bob Halley if (portlist == NULL)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley return (ISC_R_NOMEMORY);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley result = isc_mutex_init(&portlist->lock);
ca67883a666bdf314d3da958d5195e7215b1f797Bob Halley if (result != ISC_R_SUCCESS) {
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley isc_mem_put(mctx, portlist, sizeof(*portlist));
b12f0228b32775ee688ed21ddbf3a116c1adfb43Michael Graff UNEXPECTED_ERROR(__FILE__, __LINE__,
61fb42c4ef45d88e115bd769c30c4f36b461870bMark Andrews "isc_mutex_init() failed: %s",
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley isc_result_totext(result));
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley return (ISC_R_UNEXPECTED);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley }
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews isc_refcount_init(&portlist->refcount, 1);
e496615043400500492fa7b891c515c8e7cb7d08Bob Halley portlist->list = NULL;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley portlist->allocated = 0;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley portlist->active = 0;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley portlist->mctx = NULL;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley isc_mem_attach(mctx, &portlist->mctx);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley portlist->magic = DNS_PORTLIST_MAGIC;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley *portlistp = portlist;
2cd0c38115b1efb043ed3104c0d08e51ceade0d7Bob Halley return (ISC_R_SUCCESS);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley}
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
078d49b63324f01d98301ee21671abee0c41fcdeBob Halleystatic dns_element_t *
0180ccf72c79b98eb8ee5abbb7331aec6951dd9fBob Halleyfind_port(dns_element_t *list, unsigned int len, in_port_t port) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned int xtry = len / 2;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned int min = 0;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned int max = len - 1;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned int last = len;
904a5734375869ffb504ed8cde6b68cafadb6d64Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley while (1) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (list[xtry].port == port)
ca67883a666bdf314d3da958d5195e7215b1f797Bob Halley return (&list[xtry]);
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley if (port > list[xtry].port) {
b12f0228b32775ee688ed21ddbf3a116c1adfb43Michael Graff if (xtry == max)
61fb42c4ef45d88e115bd769c30c4f36b461870bMark Andrews return (NULL);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley min = xtry;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley xtry = xtry + (max - xtry + 1) / 2;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley INSIST(xtry <= max);
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews if (xtry == last)
e496615043400500492fa7b891c515c8e7cb7d08Bob Halley return (NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews last = min;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley } else {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (xtry == min)
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halley return (NULL);
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halley max = xtry;
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halley xtry = xtry - (xtry - min + 1) / 2;
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halley INSIST(xtry >= min);
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halley if (xtry == last)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence return (NULL);
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halley last = max;
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halley }
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halley }
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halley}
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halley
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halleyisc_result_t
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halleydns_portlist_add(dns_portlist_t *portlist, int af, in_port_t port) {
28640d1da26d561f4137122fe64e9e8cc08bf11eBob Halley dns_element_t *el;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley isc_result_t result;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley
e02884167b7c969b56413f76c48c3802c4dca14dAndreas Gustafsson REQUIRE(DNS_VALID_PORTLIST(portlist));
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley REQUIRE(af == AF_INET || af == AF_INET6);
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff LOCK(&portlist->lock);
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley if (portlist->active != 0) {
e02884167b7c969b56413f76c48c3802c4dca14dAndreas Gustafsson el = find_port(portlist->list, portlist->active, port);
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater if (el != NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (af == AF_INET)
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley el->flags |= DNS_PL_INET;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley else
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley el->flags |= DNS_PL_INET6;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley result = ISC_R_SUCCESS;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley goto unlock;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley }
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley }
e02884167b7c969b56413f76c48c3802c4dca14dAndreas Gustafsson
e02884167b7c969b56413f76c48c3802c4dca14dAndreas Gustafsson if (portlist->allocated <= portlist->active) {
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater unsigned int allocated;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley allocated = portlist->allocated + DNS_PL_ALLOCATE;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley el = isc_mem_get(portlist->mctx, sizeof(*el) * allocated);
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley if (el == NULL) {
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley result = ISC_R_NOMEMORY;
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley goto unlock;
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley }
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley if (portlist->list != NULL) {
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley memcpy(el, portlist->list,
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley portlist->allocated * sizeof(*el));
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley isc_mem_put(portlist->mctx, portlist->list,
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley portlist->allocated * sizeof(*el));
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley }
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley portlist->list = el;
e02884167b7c969b56413f76c48c3802c4dca14dAndreas Gustafsson portlist->allocated = allocated;
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley }
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley portlist->list[portlist->active].port = port;
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley if (af == AF_INET)
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley portlist->list[portlist->active].flags = DNS_PL_INET;
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley else
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley portlist->list[portlist->active].flags = DNS_PL_INET6;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley portlist->active++;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley qsort(portlist->list, portlist->active, sizeof(*el), compare);
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley result = ISC_R_SUCCESS;
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley unlock:
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley UNLOCK(&portlist->lock);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (result);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews}
d0eb2cc33c5db3366a16b1cb0abcca6ec7c8ee3cTatuya JINMEI 神明達哉
d0eb2cc33c5db3366a16b1cb0abcca6ec7c8ee3cTatuya JINMEI 神明達哉void
d0eb2cc33c5db3366a16b1cb0abcca6ec7c8ee3cTatuya JINMEI 神明達哉dns_portlist_remove(dns_portlist_t *portlist, int af, in_port_t port) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_element_t *el;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(DNS_VALID_PORTLIST(portlist));
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley REQUIRE(af == AF_INET || af == AF_INET6);
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley LOCK(&portlist->lock);
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley if (portlist->active != 0) {
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley el = find_port(portlist->list, portlist->active, port);
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley if (el != NULL) {
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley if (af == AF_INET)
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley el->flags &= ~DNS_PL_INET;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley else
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley el->flags &= ~DNS_PL_INET6;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley if (el->flags == 0) {
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley *el = portlist->list[portlist->active];
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley portlist->active--;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley qsort(portlist->list, portlist->active,
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley sizeof(*el), compare);
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley }
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley }
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley }
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley UNLOCK(&portlist->lock);
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley}
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halleyisc_boolean_t
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halleydns_portlist_match(dns_portlist_t *portlist, int af, in_port_t port) {
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley dns_element_t *el;
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley isc_boolean_t result = ISC_FALSE;
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley REQUIRE(DNS_VALID_PORTLIST(portlist));
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley REQUIRE(af == AF_INET || af == AF_INET6);
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley LOCK(&portlist->lock);
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley if (portlist->active != 0) {
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley el = find_port(portlist->list, portlist->active, port);
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley if (el != NULL) {
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley if (af == AF_INET && (el->flags & DNS_PL_INET) != 0)
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley result = ISC_TRUE;
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley if (af == AF_INET6 && (el->flags & DNS_PL_INET6) != 0)
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley result = ISC_TRUE;
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley }
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley }
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley UNLOCK(&portlist->lock);
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley return (result);
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley}
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halleyvoid
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halleydns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp) {
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence REQUIRE(DNS_VALID_PORTLIST(portlist));
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley REQUIRE(portlistp != NULL && *portlistp == NULL);
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley isc_refcount_increment(&portlist->refcount, NULL);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff *portlistp = portlist;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley}
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleyvoid
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleydns_portlist_detach(dns_portlist_t **portlistp) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_portlist_t *portlist;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned int count;
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley
0180ccf72c79b98eb8ee5abbb7331aec6951dd9fBob Halley REQUIRE(portlistp != NULL);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley portlist = *portlistp;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley REQUIRE(DNS_VALID_PORTLIST(portlist));
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley *portlistp = NULL;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley isc_refcount_decrement(&portlist->refcount, &count);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff if (count == 0) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley portlist->magic = 0;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley isc_refcount_destroy(&portlist->refcount);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (portlist->list != NULL)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley isc_mem_put(portlist->mctx, portlist->list,
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley portlist->allocated *
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley sizeof(*portlist->list));
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley DESTROYLOCK(&portlist->lock);
0180ccf72c79b98eb8ee5abbb7331aec6951dd9fBob Halley isc_mem_putanddetach(&portlist->mctx, portlist,
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley sizeof(*portlist));
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley }
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley}
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley