10Sstevel@tonic-gate /* 2*11038SRao.Shoaib@Sun.COM * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 30Sstevel@tonic-gate * Copyright (c) 1996,1999 by Internet Software Consortium. 40Sstevel@tonic-gate * 50Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 60Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 70Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 80Sstevel@tonic-gate * 9*11038SRao.Shoaib@Sun.COM * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 10*11038SRao.Shoaib@Sun.COM * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*11038SRao.Shoaib@Sun.COM * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 12*11038SRao.Shoaib@Sun.COM * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*11038SRao.Shoaib@Sun.COM * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*11038SRao.Shoaib@Sun.COM * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15*11038SRao.Shoaib@Sun.COM * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 160Sstevel@tonic-gate */ 170Sstevel@tonic-gate 180Sstevel@tonic-gate #if !defined(LINT) && !defined(CODECENTER) 19*11038SRao.Shoaib@Sun.COM static const char rcsid[] = "$Id: irs_data.c,v 1.12 2007/08/27 03:32:26 marka Exp $"; 200Sstevel@tonic-gate #endif 210Sstevel@tonic-gate 220Sstevel@tonic-gate #include "port_before.h" 230Sstevel@tonic-gate 240Sstevel@tonic-gate #ifndef __BIND_NOSTATIC 250Sstevel@tonic-gate 260Sstevel@tonic-gate #include <sys/types.h> 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include <netinet/in.h> 290Sstevel@tonic-gate #include <arpa/nameser.h> 300Sstevel@tonic-gate 310Sstevel@tonic-gate #include <resolv.h> 320Sstevel@tonic-gate #include <stdio.h> 330Sstevel@tonic-gate #include <string.h> 340Sstevel@tonic-gate #include <isc/memcluster.h> 350Sstevel@tonic-gate 360Sstevel@tonic-gate #ifdef DO_PTHREADS 370Sstevel@tonic-gate #include <pthread.h> 380Sstevel@tonic-gate #endif 390Sstevel@tonic-gate 400Sstevel@tonic-gate #include <irs.h> 41*11038SRao.Shoaib@Sun.COM #include <stdlib.h> 420Sstevel@tonic-gate 430Sstevel@tonic-gate #include "port_after.h" 440Sstevel@tonic-gate 450Sstevel@tonic-gate #include "irs_data.h" 460Sstevel@tonic-gate #undef _res 47*11038SRao.Shoaib@Sun.COM #if !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) 480Sstevel@tonic-gate #undef h_errno 49*11038SRao.Shoaib@Sun.COM extern int h_errno; 50*11038SRao.Shoaib@Sun.COM #endif 510Sstevel@tonic-gate 520Sstevel@tonic-gate extern struct __res_state _res; 530Sstevel@tonic-gate 540Sstevel@tonic-gate #ifdef DO_PTHREADS 55*11038SRao.Shoaib@Sun.COM static pthread_key_t key; 56*11038SRao.Shoaib@Sun.COM static int once = 0; 570Sstevel@tonic-gate #else 58*11038SRao.Shoaib@Sun.COM static struct net_data *net_data; 590Sstevel@tonic-gate #endif 600Sstevel@tonic-gate 610Sstevel@tonic-gate void 620Sstevel@tonic-gate irs_destroy(void) { 630Sstevel@tonic-gate #ifndef DO_PTHREADS 640Sstevel@tonic-gate if (net_data != NULL) 650Sstevel@tonic-gate net_data_destroy(net_data); 660Sstevel@tonic-gate net_data = NULL; 670Sstevel@tonic-gate #endif 680Sstevel@tonic-gate } 690Sstevel@tonic-gate 700Sstevel@tonic-gate void 710Sstevel@tonic-gate net_data_destroy(void *p) { 720Sstevel@tonic-gate struct net_data *net_data = p; 730Sstevel@tonic-gate 740Sstevel@tonic-gate res_ndestroy(net_data->res); 750Sstevel@tonic-gate if (net_data->gr != NULL) { 760Sstevel@tonic-gate (*net_data->gr->close)(net_data->gr); 770Sstevel@tonic-gate net_data->gr = NULL; 780Sstevel@tonic-gate } 790Sstevel@tonic-gate if (net_data->pw != NULL) { 800Sstevel@tonic-gate (*net_data->pw->close)(net_data->pw); 810Sstevel@tonic-gate net_data->pw = NULL; 820Sstevel@tonic-gate } 830Sstevel@tonic-gate if (net_data->sv != NULL) { 840Sstevel@tonic-gate (*net_data->sv->close)(net_data->sv); 850Sstevel@tonic-gate net_data->sv = NULL; 860Sstevel@tonic-gate } 870Sstevel@tonic-gate if (net_data->pr != NULL) { 880Sstevel@tonic-gate (*net_data->pr->close)(net_data->pr); 890Sstevel@tonic-gate net_data->pr = NULL; 900Sstevel@tonic-gate } 910Sstevel@tonic-gate if (net_data->ho != NULL) { 920Sstevel@tonic-gate (*net_data->ho->close)(net_data->ho); 930Sstevel@tonic-gate net_data->ho = NULL; 940Sstevel@tonic-gate } 950Sstevel@tonic-gate if (net_data->nw != NULL) { 960Sstevel@tonic-gate (*net_data->nw->close)(net_data->nw); 970Sstevel@tonic-gate net_data->nw = NULL; 980Sstevel@tonic-gate } 990Sstevel@tonic-gate if (net_data->ng != NULL) { 1000Sstevel@tonic-gate (*net_data->ng->close)(net_data->ng); 1010Sstevel@tonic-gate net_data->ng = NULL; 1020Sstevel@tonic-gate } 1030Sstevel@tonic-gate if (net_data->ho_data != NULL) { 1040Sstevel@tonic-gate free(net_data->ho_data); 1050Sstevel@tonic-gate net_data->ho_data = NULL; 1060Sstevel@tonic-gate } 1070Sstevel@tonic-gate if (net_data->nw_data != NULL) { 1080Sstevel@tonic-gate free(net_data->nw_data); 1090Sstevel@tonic-gate net_data->nw_data = NULL; 1100Sstevel@tonic-gate } 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1130Sstevel@tonic-gate memput(net_data, sizeof *net_data); 1140Sstevel@tonic-gate } 1150Sstevel@tonic-gate 116*11038SRao.Shoaib@Sun.COM /*% 117*11038SRao.Shoaib@Sun.COM * applications that need a specific config file other than 1180Sstevel@tonic-gate * _PATH_IRS_CONF should call net_data_init directly rather than letting 1190Sstevel@tonic-gate * the various wrapper functions make the first call. - brister 1200Sstevel@tonic-gate */ 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate struct net_data * 1230Sstevel@tonic-gate net_data_init(const char *conf_file) { 1240Sstevel@tonic-gate #ifdef DO_PTHREADS 125*11038SRao.Shoaib@Sun.COM #ifndef LIBBIND_MUTEX_INITIALIZER 126*11038SRao.Shoaib@Sun.COM #define LIBBIND_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 127*11038SRao.Shoaib@Sun.COM #endif 128*11038SRao.Shoaib@Sun.COM static pthread_mutex_t keylock = LIBBIND_MUTEX_INITIALIZER; 1290Sstevel@tonic-gate struct net_data *net_data; 1300Sstevel@tonic-gate 131*11038SRao.Shoaib@Sun.COM if (!once) { 132*11038SRao.Shoaib@Sun.COM if (pthread_mutex_lock(&keylock) != 0) 133*11038SRao.Shoaib@Sun.COM return (NULL); 134*11038SRao.Shoaib@Sun.COM if (!once) { 135*11038SRao.Shoaib@Sun.COM if (pthread_key_create(&key, net_data_destroy) != 0) { 136*11038SRao.Shoaib@Sun.COM (void)pthread_mutex_unlock(&keylock); 137*11038SRao.Shoaib@Sun.COM return (NULL); 138*11038SRao.Shoaib@Sun.COM } 139*11038SRao.Shoaib@Sun.COM once = 1; 140*11038SRao.Shoaib@Sun.COM } 141*11038SRao.Shoaib@Sun.COM if (pthread_mutex_unlock(&keylock) != 0) 142*11038SRao.Shoaib@Sun.COM return (NULL); 143*11038SRao.Shoaib@Sun.COM } 1440Sstevel@tonic-gate net_data = pthread_getspecific(key); 1450Sstevel@tonic-gate #endif 1460Sstevel@tonic-gate 1470Sstevel@tonic-gate if (net_data == NULL) { 1480Sstevel@tonic-gate net_data = net_data_create(conf_file); 1490Sstevel@tonic-gate if (net_data == NULL) 1500Sstevel@tonic-gate return (NULL); 1510Sstevel@tonic-gate #ifdef DO_PTHREADS 1523822Sjs198686 if (pthread_setspecific(key, net_data) != 0) { 1533822Sjs198686 net_data_destroy(net_data); 1543822Sjs198686 return (NULL); 1553822Sjs198686 } 1560Sstevel@tonic-gate #endif 1570Sstevel@tonic-gate } 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate return (net_data); 1600Sstevel@tonic-gate } 1610Sstevel@tonic-gate 1620Sstevel@tonic-gate struct net_data * 1630Sstevel@tonic-gate net_data_create(const char *conf_file) { 1640Sstevel@tonic-gate struct net_data *net_data; 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate net_data = memget(sizeof (struct net_data)); 1670Sstevel@tonic-gate if (net_data == NULL) 1680Sstevel@tonic-gate return (NULL); 1690Sstevel@tonic-gate memset(net_data, 0, sizeof (struct net_data)); 1700Sstevel@tonic-gate 1710Sstevel@tonic-gate if ((net_data->irs = irs_gen_acc("", conf_file)) == NULL) { 1720Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1730Sstevel@tonic-gate return (NULL); 1740Sstevel@tonic-gate } 1750Sstevel@tonic-gate #ifndef DO_PTHREADS 1760Sstevel@tonic-gate (*net_data->irs->res_set)(net_data->irs, &_res, NULL); 1770Sstevel@tonic-gate #endif 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate net_data->res = (*net_data->irs->res_get)(net_data->irs); 1800Sstevel@tonic-gate if (net_data->res == NULL) { 1810Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1820Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1830Sstevel@tonic-gate return (NULL); 1840Sstevel@tonic-gate } 1850Sstevel@tonic-gate 186*11038SRao.Shoaib@Sun.COM if ((net_data->res->options & RES_INIT) == 0U && 1870Sstevel@tonic-gate res_ninit(net_data->res) == -1) { 1880Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1890Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1900Sstevel@tonic-gate return (NULL); 1910Sstevel@tonic-gate } 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate return (net_data); 1940Sstevel@tonic-gate } 1950Sstevel@tonic-gate 1960Sstevel@tonic-gate void 1970Sstevel@tonic-gate net_data_minimize(struct net_data *net_data) { 1980Sstevel@tonic-gate res_nclose(net_data->res); 1990Sstevel@tonic-gate } 2000Sstevel@tonic-gate 2010Sstevel@tonic-gate #ifdef _REENTRANT 2020Sstevel@tonic-gate struct __res_state * 2030Sstevel@tonic-gate __res_state(void) { 2040Sstevel@tonic-gate /* NULL param here means use the default config file. */ 2050Sstevel@tonic-gate struct net_data *net_data = net_data_init(NULL); 2060Sstevel@tonic-gate if (net_data && net_data->res) 2070Sstevel@tonic-gate return (net_data->res); 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate return (&_res); 2100Sstevel@tonic-gate } 211*11038SRao.Shoaib@Sun.COM #else 212*11038SRao.Shoaib@Sun.COM #ifdef __linux 213*11038SRao.Shoaib@Sun.COM struct __res_state * 214*11038SRao.Shoaib@Sun.COM __res_state(void) { 215*11038SRao.Shoaib@Sun.COM return (&_res); 216*11038SRao.Shoaib@Sun.COM } 217*11038SRao.Shoaib@Sun.COM #endif 2180Sstevel@tonic-gate #endif 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate int * 2210Sstevel@tonic-gate __h_errno(void) { 2220Sstevel@tonic-gate /* NULL param here means use the default config file. */ 2230Sstevel@tonic-gate struct net_data *net_data = net_data_init(NULL); 2240Sstevel@tonic-gate if (net_data && net_data->res) 2250Sstevel@tonic-gate return (&net_data->res->res_h_errno); 226*11038SRao.Shoaib@Sun.COM #if !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) 227*11038SRao.Shoaib@Sun.COM return(&_res.res_h_errno); 228*11038SRao.Shoaib@Sun.COM #else 2290Sstevel@tonic-gate return (&h_errno); 230*11038SRao.Shoaib@Sun.COM #endif 2310Sstevel@tonic-gate } 2320Sstevel@tonic-gate 2330Sstevel@tonic-gate void 2340Sstevel@tonic-gate __h_errno_set(struct __res_state *res, int err) { 2350Sstevel@tonic-gate 236*11038SRao.Shoaib@Sun.COM 237*11038SRao.Shoaib@Sun.COM #if (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) 238*11038SRao.Shoaib@Sun.COM res->res_h_errno = err; 239*11038SRao.Shoaib@Sun.COM #else 2400Sstevel@tonic-gate h_errno = res->res_h_errno = err; 241*11038SRao.Shoaib@Sun.COM #endif 2420Sstevel@tonic-gate } 2430Sstevel@tonic-gate 2440Sstevel@tonic-gate #endif /*__BIND_NOSTATIC*/ 245*11038SRao.Shoaib@Sun.COM 246*11038SRao.Shoaib@Sun.COM /*! \file */ 247