1*12094SStacey.Marshall@Sun.COM /* 2*12094SStacey.Marshall@Sun.COM * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3*12094SStacey.Marshall@Sun.COM */ 4*12094SStacey.Marshall@Sun.COM 50Sstevel@tonic-gate /* 611038SRao.Shoaib@Sun.COM * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 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 * 1311038SRao.Shoaib@Sun.COM * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 1411038SRao.Shoaib@Sun.COM * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1511038SRao.Shoaib@Sun.COM * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 1611038SRao.Shoaib@Sun.COM * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1711038SRao.Shoaib@Sun.COM * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1811038SRao.Shoaib@Sun.COM * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 1911038SRao.Shoaib@Sun.COM * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate 220Sstevel@tonic-gate #if !defined(LINT) && !defined(CODECENTER) 2311038SRao.Shoaib@Sun.COM static const char rcsid[] = "$Id: irs_data.c,v 1.12 2007/08/27 03:32:26 marka Exp $"; 240Sstevel@tonic-gate #endif 250Sstevel@tonic-gate 260Sstevel@tonic-gate #include "port_before.h" 270Sstevel@tonic-gate 280Sstevel@tonic-gate #ifndef __BIND_NOSTATIC 290Sstevel@tonic-gate 300Sstevel@tonic-gate #include <sys/types.h> 310Sstevel@tonic-gate 320Sstevel@tonic-gate #include <netinet/in.h> 330Sstevel@tonic-gate #include <arpa/nameser.h> 340Sstevel@tonic-gate 350Sstevel@tonic-gate #include <resolv.h> 360Sstevel@tonic-gate #include <stdio.h> 370Sstevel@tonic-gate #include <string.h> 380Sstevel@tonic-gate #include <isc/memcluster.h> 390Sstevel@tonic-gate 400Sstevel@tonic-gate #ifdef DO_PTHREADS 410Sstevel@tonic-gate #include <pthread.h> 420Sstevel@tonic-gate #endif 430Sstevel@tonic-gate 440Sstevel@tonic-gate #include <irs.h> 4511038SRao.Shoaib@Sun.COM #include <stdlib.h> 460Sstevel@tonic-gate 470Sstevel@tonic-gate #include "port_after.h" 480Sstevel@tonic-gate 490Sstevel@tonic-gate #include "irs_data.h" 500Sstevel@tonic-gate #undef _res 5111038SRao.Shoaib@Sun.COM #if !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) 520Sstevel@tonic-gate #undef h_errno 5311038SRao.Shoaib@Sun.COM extern int h_errno; 5411038SRao.Shoaib@Sun.COM #endif 550Sstevel@tonic-gate 560Sstevel@tonic-gate extern struct __res_state _res; 570Sstevel@tonic-gate 580Sstevel@tonic-gate #ifdef DO_PTHREADS 5911038SRao.Shoaib@Sun.COM static pthread_key_t key; 6011038SRao.Shoaib@Sun.COM static int once = 0; 610Sstevel@tonic-gate #else 6211038SRao.Shoaib@Sun.COM static struct net_data *net_data; 630Sstevel@tonic-gate #endif 640Sstevel@tonic-gate 650Sstevel@tonic-gate void 660Sstevel@tonic-gate irs_destroy(void) { 670Sstevel@tonic-gate #ifndef DO_PTHREADS 680Sstevel@tonic-gate if (net_data != NULL) 690Sstevel@tonic-gate net_data_destroy(net_data); 700Sstevel@tonic-gate net_data = NULL; 710Sstevel@tonic-gate #endif 720Sstevel@tonic-gate } 730Sstevel@tonic-gate 740Sstevel@tonic-gate void 750Sstevel@tonic-gate net_data_destroy(void *p) { 760Sstevel@tonic-gate struct net_data *net_data = p; 770Sstevel@tonic-gate 780Sstevel@tonic-gate res_ndestroy(net_data->res); 790Sstevel@tonic-gate if (net_data->gr != NULL) { 800Sstevel@tonic-gate (*net_data->gr->close)(net_data->gr); 810Sstevel@tonic-gate net_data->gr = NULL; 820Sstevel@tonic-gate } 830Sstevel@tonic-gate if (net_data->pw != NULL) { 840Sstevel@tonic-gate (*net_data->pw->close)(net_data->pw); 850Sstevel@tonic-gate net_data->pw = NULL; 860Sstevel@tonic-gate } 870Sstevel@tonic-gate if (net_data->sv != NULL) { 880Sstevel@tonic-gate (*net_data->sv->close)(net_data->sv); 890Sstevel@tonic-gate net_data->sv = NULL; 900Sstevel@tonic-gate } 910Sstevel@tonic-gate if (net_data->pr != NULL) { 920Sstevel@tonic-gate (*net_data->pr->close)(net_data->pr); 930Sstevel@tonic-gate net_data->pr = NULL; 940Sstevel@tonic-gate } 950Sstevel@tonic-gate if (net_data->ho != NULL) { 960Sstevel@tonic-gate (*net_data->ho->close)(net_data->ho); 970Sstevel@tonic-gate net_data->ho = NULL; 980Sstevel@tonic-gate } 990Sstevel@tonic-gate if (net_data->nw != NULL) { 1000Sstevel@tonic-gate (*net_data->nw->close)(net_data->nw); 1010Sstevel@tonic-gate net_data->nw = NULL; 1020Sstevel@tonic-gate } 1030Sstevel@tonic-gate if (net_data->ng != NULL) { 1040Sstevel@tonic-gate (*net_data->ng->close)(net_data->ng); 1050Sstevel@tonic-gate net_data->ng = NULL; 1060Sstevel@tonic-gate } 1070Sstevel@tonic-gate if (net_data->ho_data != NULL) { 1080Sstevel@tonic-gate free(net_data->ho_data); 1090Sstevel@tonic-gate net_data->ho_data = NULL; 1100Sstevel@tonic-gate } 1110Sstevel@tonic-gate if (net_data->nw_data != NULL) { 1120Sstevel@tonic-gate free(net_data->nw_data); 1130Sstevel@tonic-gate net_data->nw_data = NULL; 1140Sstevel@tonic-gate } 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1170Sstevel@tonic-gate memput(net_data, sizeof *net_data); 1180Sstevel@tonic-gate } 1190Sstevel@tonic-gate 12011038SRao.Shoaib@Sun.COM /*% 12111038SRao.Shoaib@Sun.COM * 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 12911038SRao.Shoaib@Sun.COM #ifndef LIBBIND_MUTEX_INITIALIZER 13011038SRao.Shoaib@Sun.COM #define LIBBIND_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 13111038SRao.Shoaib@Sun.COM #endif 13211038SRao.Shoaib@Sun.COM static pthread_mutex_t keylock = LIBBIND_MUTEX_INITIALIZER; 1330Sstevel@tonic-gate struct net_data *net_data; 1340Sstevel@tonic-gate 13511038SRao.Shoaib@Sun.COM if (!once) { 13611038SRao.Shoaib@Sun.COM if (pthread_mutex_lock(&keylock) != 0) 13711038SRao.Shoaib@Sun.COM return (NULL); 13811038SRao.Shoaib@Sun.COM if (!once) { 13911038SRao.Shoaib@Sun.COM if (pthread_key_create(&key, net_data_destroy) != 0) { 14011038SRao.Shoaib@Sun.COM (void)pthread_mutex_unlock(&keylock); 14111038SRao.Shoaib@Sun.COM return (NULL); 14211038SRao.Shoaib@Sun.COM } 14311038SRao.Shoaib@Sun.COM once = 1; 14411038SRao.Shoaib@Sun.COM } 14511038SRao.Shoaib@Sun.COM if (pthread_mutex_unlock(&keylock) != 0) 14611038SRao.Shoaib@Sun.COM return (NULL); 14711038SRao.Shoaib@Sun.COM } 1480Sstevel@tonic-gate net_data = pthread_getspecific(key); 1490Sstevel@tonic-gate #endif 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate if (net_data == NULL) { 1520Sstevel@tonic-gate net_data = net_data_create(conf_file); 1530Sstevel@tonic-gate if (net_data == NULL) 1540Sstevel@tonic-gate return (NULL); 1550Sstevel@tonic-gate #ifdef DO_PTHREADS 1563822Sjs198686 if (pthread_setspecific(key, net_data) != 0) { 1573822Sjs198686 net_data_destroy(net_data); 1583822Sjs198686 return (NULL); 1593822Sjs198686 } 1600Sstevel@tonic-gate #endif 1610Sstevel@tonic-gate } 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate return (net_data); 1640Sstevel@tonic-gate } 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate struct net_data * 1670Sstevel@tonic-gate net_data_create(const char *conf_file) { 1680Sstevel@tonic-gate struct net_data *net_data; 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate net_data = memget(sizeof (struct net_data)); 1710Sstevel@tonic-gate if (net_data == NULL) 1720Sstevel@tonic-gate return (NULL); 1730Sstevel@tonic-gate memset(net_data, 0, sizeof (struct net_data)); 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate if ((net_data->irs = irs_gen_acc("", conf_file)) == NULL) { 1760Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1770Sstevel@tonic-gate return (NULL); 1780Sstevel@tonic-gate } 1790Sstevel@tonic-gate #ifndef DO_PTHREADS 1800Sstevel@tonic-gate (*net_data->irs->res_set)(net_data->irs, &_res, NULL); 1810Sstevel@tonic-gate #endif 1820Sstevel@tonic-gate 1830Sstevel@tonic-gate net_data->res = (*net_data->irs->res_get)(net_data->irs); 1840Sstevel@tonic-gate if (net_data->res == NULL) { 1850Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1860Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1870Sstevel@tonic-gate return (NULL); 1880Sstevel@tonic-gate } 1890Sstevel@tonic-gate 19011038SRao.Shoaib@Sun.COM if ((net_data->res->options & RES_INIT) == 0U && 1910Sstevel@tonic-gate res_ninit(net_data->res) == -1) { 1920Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1930Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1940Sstevel@tonic-gate return (NULL); 1950Sstevel@tonic-gate } 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate return (net_data); 1980Sstevel@tonic-gate } 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate void 2010Sstevel@tonic-gate net_data_minimize(struct net_data *net_data) { 2020Sstevel@tonic-gate res_nclose(net_data->res); 2030Sstevel@tonic-gate } 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate #ifdef _REENTRANT 2060Sstevel@tonic-gate struct __res_state * 2070Sstevel@tonic-gate __res_state(void) { 2080Sstevel@tonic-gate /* NULL param here means use the default config file. */ 2090Sstevel@tonic-gate struct net_data *net_data = net_data_init(NULL); 2100Sstevel@tonic-gate if (net_data && net_data->res) 2110Sstevel@tonic-gate return (net_data->res); 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate return (&_res); 2140Sstevel@tonic-gate } 21511038SRao.Shoaib@Sun.COM #else 21611038SRao.Shoaib@Sun.COM #ifdef __linux 21711038SRao.Shoaib@Sun.COM struct __res_state * 21811038SRao.Shoaib@Sun.COM __res_state(void) { 21911038SRao.Shoaib@Sun.COM return (&_res); 22011038SRao.Shoaib@Sun.COM } 22111038SRao.Shoaib@Sun.COM #endif 2220Sstevel@tonic-gate #endif 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate int * 2250Sstevel@tonic-gate __h_errno(void) { 2260Sstevel@tonic-gate /* NULL param here means use the default config file. */ 2270Sstevel@tonic-gate struct net_data *net_data = net_data_init(NULL); 2280Sstevel@tonic-gate if (net_data && net_data->res) 2290Sstevel@tonic-gate return (&net_data->res->res_h_errno); 230*12094SStacey.Marshall@Sun.COM #ifdef ORIGINAL_ISC_CODE 23111038SRao.Shoaib@Sun.COM #if !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) 23211038SRao.Shoaib@Sun.COM return(&_res.res_h_errno); 23311038SRao.Shoaib@Sun.COM #else 2340Sstevel@tonic-gate return (&h_errno); 23511038SRao.Shoaib@Sun.COM #endif 236*12094SStacey.Marshall@Sun.COM #else 237*12094SStacey.Marshall@Sun.COM return (&h_errno); 238*12094SStacey.Marshall@Sun.COM #endif /* ORIGINAL_ISC_CODE */ 2390Sstevel@tonic-gate } 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate void 2420Sstevel@tonic-gate __h_errno_set(struct __res_state *res, int err) { 2430Sstevel@tonic-gate 24411038SRao.Shoaib@Sun.COM 24511038SRao.Shoaib@Sun.COM #if (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) 24611038SRao.Shoaib@Sun.COM res->res_h_errno = err; 24711038SRao.Shoaib@Sun.COM #else 2480Sstevel@tonic-gate h_errno = res->res_h_errno = err; 24911038SRao.Shoaib@Sun.COM #endif 2500Sstevel@tonic-gate } 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate #endif /*__BIND_NOSTATIC*/ 25311038SRao.Shoaib@Sun.COM 25411038SRao.Shoaib@Sun.COM /*! \file */ 255