10Sstevel@tonic-gate /* 2*3822Sjs198686 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 30Sstevel@tonic-gate * Use is subject to license terms. 40Sstevel@tonic-gate */ 50Sstevel@tonic-gate 60Sstevel@tonic-gate /* 70Sstevel@tonic-gate * Copyright (c) 1996,1999 by Internet Software Consortium. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 100Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 110Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 140Sstevel@tonic-gate * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 150Sstevel@tonic-gate * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 160Sstevel@tonic-gate * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 170Sstevel@tonic-gate * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 180Sstevel@tonic-gate * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 190Sstevel@tonic-gate * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 200Sstevel@tonic-gate * SOFTWARE. 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate 230Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 240Sstevel@tonic-gate 250Sstevel@tonic-gate #if !defined(LINT) && !defined(CODECENTER) 260Sstevel@tonic-gate static const char rcsid[] = "$Id: irs_data.c,v 1.22 2003/06/20 07:09:33 marka Exp $"; 270Sstevel@tonic-gate #endif 280Sstevel@tonic-gate 290Sstevel@tonic-gate #include "port_before.h" 300Sstevel@tonic-gate 310Sstevel@tonic-gate #ifndef __BIND_NOSTATIC 320Sstevel@tonic-gate 330Sstevel@tonic-gate #include <sys/types.h> 340Sstevel@tonic-gate 350Sstevel@tonic-gate #include <netinet/in.h> 360Sstevel@tonic-gate #include <arpa/nameser.h> 370Sstevel@tonic-gate 380Sstevel@tonic-gate #include <resolv.h> 390Sstevel@tonic-gate #include <stdio.h> 400Sstevel@tonic-gate #include <string.h> 410Sstevel@tonic-gate #include <isc/memcluster.h> 420Sstevel@tonic-gate #include <stdlib.h> 430Sstevel@tonic-gate 440Sstevel@tonic-gate #ifdef DO_PTHREADS 450Sstevel@tonic-gate #include <pthread.h> 460Sstevel@tonic-gate #endif 470Sstevel@tonic-gate 480Sstevel@tonic-gate #include <irs.h> 490Sstevel@tonic-gate 500Sstevel@tonic-gate #include "port_after.h" 510Sstevel@tonic-gate 520Sstevel@tonic-gate #include "irs_data.h" 530Sstevel@tonic-gate #undef _res 540Sstevel@tonic-gate #undef h_errno 550Sstevel@tonic-gate 560Sstevel@tonic-gate extern struct __res_state _res; 570Sstevel@tonic-gate extern int h_errno; 580Sstevel@tonic-gate 590Sstevel@tonic-gate #ifdef DO_PTHREADS 600Sstevel@tonic-gate static pthread_key_t key; 610Sstevel@tonic-gate static int once = 0; 620Sstevel@tonic-gate #else 630Sstevel@tonic-gate static struct net_data *net_data; 640Sstevel@tonic-gate #endif 650Sstevel@tonic-gate 660Sstevel@tonic-gate void 670Sstevel@tonic-gate irs_destroy(void) { 680Sstevel@tonic-gate #ifndef DO_PTHREADS 690Sstevel@tonic-gate if (net_data != NULL) 700Sstevel@tonic-gate net_data_destroy(net_data); 710Sstevel@tonic-gate net_data = NULL; 720Sstevel@tonic-gate #endif 730Sstevel@tonic-gate } 740Sstevel@tonic-gate 750Sstevel@tonic-gate void 760Sstevel@tonic-gate net_data_destroy(void *p) { 770Sstevel@tonic-gate struct net_data *net_data = p; 780Sstevel@tonic-gate 790Sstevel@tonic-gate res_ndestroy(net_data->res); 800Sstevel@tonic-gate if (net_data->gr != NULL) { 810Sstevel@tonic-gate (*net_data->gr->close)(net_data->gr); 820Sstevel@tonic-gate net_data->gr = NULL; 830Sstevel@tonic-gate } 840Sstevel@tonic-gate if (net_data->pw != NULL) { 850Sstevel@tonic-gate (*net_data->pw->close)(net_data->pw); 860Sstevel@tonic-gate net_data->pw = NULL; 870Sstevel@tonic-gate } 880Sstevel@tonic-gate if (net_data->sv != NULL) { 890Sstevel@tonic-gate (*net_data->sv->close)(net_data->sv); 900Sstevel@tonic-gate net_data->sv = NULL; 910Sstevel@tonic-gate } 920Sstevel@tonic-gate if (net_data->pr != NULL) { 930Sstevel@tonic-gate (*net_data->pr->close)(net_data->pr); 940Sstevel@tonic-gate net_data->pr = NULL; 950Sstevel@tonic-gate } 960Sstevel@tonic-gate if (net_data->ho != NULL) { 970Sstevel@tonic-gate (*net_data->ho->close)(net_data->ho); 980Sstevel@tonic-gate net_data->ho = NULL; 990Sstevel@tonic-gate } 1000Sstevel@tonic-gate if (net_data->nw != NULL) { 1010Sstevel@tonic-gate (*net_data->nw->close)(net_data->nw); 1020Sstevel@tonic-gate net_data->nw = NULL; 1030Sstevel@tonic-gate } 1040Sstevel@tonic-gate if (net_data->ng != NULL) { 1050Sstevel@tonic-gate (*net_data->ng->close)(net_data->ng); 1060Sstevel@tonic-gate net_data->ng = NULL; 1070Sstevel@tonic-gate } 1080Sstevel@tonic-gate if (net_data->ho_data != NULL) { 1090Sstevel@tonic-gate free(net_data->ho_data); 1100Sstevel@tonic-gate net_data->ho_data = NULL; 1110Sstevel@tonic-gate } 1120Sstevel@tonic-gate if (net_data->nw_data != NULL) { 1130Sstevel@tonic-gate free(net_data->nw_data); 1140Sstevel@tonic-gate net_data->nw_data = NULL; 1150Sstevel@tonic-gate } 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1180Sstevel@tonic-gate memput(net_data, sizeof *net_data); 1190Sstevel@tonic-gate } 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate /* applications that need a specific config file other than 1220Sstevel@tonic-gate * _PATH_IRS_CONF should call net_data_init directly rather than letting 1230Sstevel@tonic-gate * the various wrapper functions make the first call. - brister 1240Sstevel@tonic-gate */ 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate struct net_data * 1270Sstevel@tonic-gate net_data_init(const char *conf_file) { 1280Sstevel@tonic-gate #ifdef DO_PTHREADS 1290Sstevel@tonic-gate static pthread_mutex_t keylock = PTHREAD_MUTEX_INITIALIZER; 1300Sstevel@tonic-gate struct net_data *net_data; 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate if (!once) { 133*3822Sjs198686 if (pthread_mutex_lock(&keylock) != 0) 134*3822Sjs198686 return (NULL); 135*3822Sjs198686 if (!once) { 136*3822Sjs198686 if (pthread_key_create(&key, net_data_destroy) != 0) { 137*3822Sjs198686 pthread_mutex_unlock(&keylock); 138*3822Sjs198686 return (NULL); 139*3822Sjs198686 } 140*3822Sjs198686 once = 1; 141*3822Sjs198686 } 142*3822Sjs198686 if (pthread_mutex_unlock(&keylock) != 0) 143*3822Sjs198686 return (NULL); 1440Sstevel@tonic-gate } 1450Sstevel@tonic-gate net_data = pthread_getspecific(key); 1460Sstevel@tonic-gate #endif 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate if (net_data == NULL) { 1490Sstevel@tonic-gate net_data = net_data_create(conf_file); 1500Sstevel@tonic-gate if (net_data == NULL) 1510Sstevel@tonic-gate return (NULL); 1520Sstevel@tonic-gate #ifdef DO_PTHREADS 153*3822Sjs198686 if (pthread_setspecific(key, net_data) != 0) { 154*3822Sjs198686 net_data_destroy(net_data); 155*3822Sjs198686 return (NULL); 156*3822Sjs198686 } 1570Sstevel@tonic-gate #endif 1580Sstevel@tonic-gate } 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate return (net_data); 1610Sstevel@tonic-gate } 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate struct net_data * 1640Sstevel@tonic-gate net_data_create(const char *conf_file) { 1650Sstevel@tonic-gate struct net_data *net_data; 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate net_data = memget(sizeof (struct net_data)); 1680Sstevel@tonic-gate if (net_data == NULL) 1690Sstevel@tonic-gate return (NULL); 1700Sstevel@tonic-gate memset(net_data, 0, sizeof (struct net_data)); 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate if ((net_data->irs = irs_gen_acc("", conf_file)) == NULL) { 1730Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1740Sstevel@tonic-gate return (NULL); 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate #ifndef DO_PTHREADS 1770Sstevel@tonic-gate (*net_data->irs->res_set)(net_data->irs, &_res, NULL); 1780Sstevel@tonic-gate #endif 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate net_data->res = (*net_data->irs->res_get)(net_data->irs); 1810Sstevel@tonic-gate if (net_data->res == NULL) { 1820Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1830Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1840Sstevel@tonic-gate return (NULL); 1850Sstevel@tonic-gate } 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate if ((net_data->res->options & RES_INIT) == 0 && 1880Sstevel@tonic-gate res_ninit(net_data->res) == -1) { 1890Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1900Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1910Sstevel@tonic-gate return (NULL); 1920Sstevel@tonic-gate } 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate return (net_data); 1950Sstevel@tonic-gate } 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate void 2000Sstevel@tonic-gate net_data_minimize(struct net_data *net_data) { 2010Sstevel@tonic-gate res_nclose(net_data->res); 2020Sstevel@tonic-gate } 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate #ifdef _REENTRANT 2050Sstevel@tonic-gate struct __res_state * 2060Sstevel@tonic-gate __res_state(void) { 2070Sstevel@tonic-gate /* NULL param here means use the default config file. */ 2080Sstevel@tonic-gate struct net_data *net_data = net_data_init(NULL); 2090Sstevel@tonic-gate if (net_data && net_data->res) 2100Sstevel@tonic-gate return (net_data->res); 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate return (&_res); 2130Sstevel@tonic-gate } 2140Sstevel@tonic-gate #endif 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate int * 2170Sstevel@tonic-gate __h_errno(void) { 2180Sstevel@tonic-gate /* NULL param here means use the default config file. */ 2190Sstevel@tonic-gate struct net_data *net_data = net_data_init(NULL); 2200Sstevel@tonic-gate if (net_data && net_data->res) 2210Sstevel@tonic-gate return (&net_data->res->res_h_errno); 2220Sstevel@tonic-gate return (&h_errno); 2230Sstevel@tonic-gate } 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate void 2260Sstevel@tonic-gate __h_errno_set(struct __res_state *res, int err) { 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate h_errno = res->res_h_errno = err; 2290Sstevel@tonic-gate } 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate #endif /*__BIND_NOSTATIC*/ 232