17c478bd9Sstevel@tonic-gate /* 2*4e567b44SStacey Marshall * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3*4e567b44SStacey Marshall */ 4*4e567b44SStacey Marshall 5*4e567b44SStacey Marshall /* 69525b14bSRao Shoaib * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 77c478bd9Sstevel@tonic-gate * Copyright (c) 1996,1999 by Internet Software Consortium. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 107c478bd9Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 117c478bd9Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 127c478bd9Sstevel@tonic-gate * 139525b14bSRao Shoaib * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 149525b14bSRao Shoaib * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 159525b14bSRao Shoaib * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 169525b14bSRao Shoaib * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 179525b14bSRao Shoaib * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 189525b14bSRao Shoaib * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 199525b14bSRao Shoaib * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate 227c478bd9Sstevel@tonic-gate #if !defined(LINT) && !defined(CODECENTER) 239525b14bSRao Shoaib static const char rcsid[] = "$Id: irs_data.c,v 1.12 2007/08/27 03:32:26 marka Exp $"; 247c478bd9Sstevel@tonic-gate #endif 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include "port_before.h" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #ifndef __BIND_NOSTATIC 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #include <sys/types.h> 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <netinet/in.h> 337c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include <resolv.h> 367c478bd9Sstevel@tonic-gate #include <stdio.h> 377c478bd9Sstevel@tonic-gate #include <string.h> 387c478bd9Sstevel@tonic-gate #include <isc/memcluster.h> 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #ifdef DO_PTHREADS 417c478bd9Sstevel@tonic-gate #include <pthread.h> 427c478bd9Sstevel@tonic-gate #endif 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #include <irs.h> 459525b14bSRao Shoaib #include <stdlib.h> 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate #include "port_after.h" 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #include "irs_data.h" 507c478bd9Sstevel@tonic-gate #undef _res 519525b14bSRao Shoaib #if !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) 527c478bd9Sstevel@tonic-gate #undef h_errno 539525b14bSRao Shoaib extern int h_errno; 549525b14bSRao Shoaib #endif 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate extern struct __res_state _res; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate #ifdef DO_PTHREADS 599525b14bSRao Shoaib static pthread_key_t key; 609525b14bSRao Shoaib static int once = 0; 617c478bd9Sstevel@tonic-gate #else 629525b14bSRao Shoaib static struct net_data *net_data; 637c478bd9Sstevel@tonic-gate #endif 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate void 667c478bd9Sstevel@tonic-gate irs_destroy(void) { 677c478bd9Sstevel@tonic-gate #ifndef DO_PTHREADS 687c478bd9Sstevel@tonic-gate if (net_data != NULL) 697c478bd9Sstevel@tonic-gate net_data_destroy(net_data); 707c478bd9Sstevel@tonic-gate net_data = NULL; 717c478bd9Sstevel@tonic-gate #endif 727c478bd9Sstevel@tonic-gate } 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate void 757c478bd9Sstevel@tonic-gate net_data_destroy(void *p) { 767c478bd9Sstevel@tonic-gate struct net_data *net_data = p; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate res_ndestroy(net_data->res); 797c478bd9Sstevel@tonic-gate if (net_data->gr != NULL) { 807c478bd9Sstevel@tonic-gate (*net_data->gr->close)(net_data->gr); 817c478bd9Sstevel@tonic-gate net_data->gr = NULL; 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate if (net_data->pw != NULL) { 847c478bd9Sstevel@tonic-gate (*net_data->pw->close)(net_data->pw); 857c478bd9Sstevel@tonic-gate net_data->pw = NULL; 867c478bd9Sstevel@tonic-gate } 877c478bd9Sstevel@tonic-gate if (net_data->sv != NULL) { 887c478bd9Sstevel@tonic-gate (*net_data->sv->close)(net_data->sv); 897c478bd9Sstevel@tonic-gate net_data->sv = NULL; 907c478bd9Sstevel@tonic-gate } 917c478bd9Sstevel@tonic-gate if (net_data->pr != NULL) { 927c478bd9Sstevel@tonic-gate (*net_data->pr->close)(net_data->pr); 937c478bd9Sstevel@tonic-gate net_data->pr = NULL; 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate if (net_data->ho != NULL) { 967c478bd9Sstevel@tonic-gate (*net_data->ho->close)(net_data->ho); 977c478bd9Sstevel@tonic-gate net_data->ho = NULL; 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate if (net_data->nw != NULL) { 1007c478bd9Sstevel@tonic-gate (*net_data->nw->close)(net_data->nw); 1017c478bd9Sstevel@tonic-gate net_data->nw = NULL; 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate if (net_data->ng != NULL) { 1047c478bd9Sstevel@tonic-gate (*net_data->ng->close)(net_data->ng); 1057c478bd9Sstevel@tonic-gate net_data->ng = NULL; 1067c478bd9Sstevel@tonic-gate } 1077c478bd9Sstevel@tonic-gate if (net_data->ho_data != NULL) { 1087c478bd9Sstevel@tonic-gate free(net_data->ho_data); 1097c478bd9Sstevel@tonic-gate net_data->ho_data = NULL; 1107c478bd9Sstevel@tonic-gate } 1117c478bd9Sstevel@tonic-gate if (net_data->nw_data != NULL) { 1127c478bd9Sstevel@tonic-gate free(net_data->nw_data); 1137c478bd9Sstevel@tonic-gate net_data->nw_data = NULL; 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1177c478bd9Sstevel@tonic-gate memput(net_data, sizeof *net_data); 1187c478bd9Sstevel@tonic-gate } 1197c478bd9Sstevel@tonic-gate 1209525b14bSRao Shoaib /*% 1219525b14bSRao Shoaib * applications that need a specific config file other than 1227c478bd9Sstevel@tonic-gate * _PATH_IRS_CONF should call net_data_init directly rather than letting 1237c478bd9Sstevel@tonic-gate * the various wrapper functions make the first call. - brister 1247c478bd9Sstevel@tonic-gate */ 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate struct net_data * 1277c478bd9Sstevel@tonic-gate net_data_init(const char *conf_file) { 1287c478bd9Sstevel@tonic-gate #ifdef DO_PTHREADS 1299525b14bSRao Shoaib #ifndef LIBBIND_MUTEX_INITIALIZER 1309525b14bSRao Shoaib #define LIBBIND_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 1319525b14bSRao Shoaib #endif 1329525b14bSRao Shoaib static pthread_mutex_t keylock = LIBBIND_MUTEX_INITIALIZER; 1337c478bd9Sstevel@tonic-gate struct net_data *net_data; 1347c478bd9Sstevel@tonic-gate 1359525b14bSRao Shoaib if (!once) { 1369525b14bSRao Shoaib if (pthread_mutex_lock(&keylock) != 0) 137168c2130Sjs198686 return (NULL); 1389525b14bSRao Shoaib if (!once) { 1399525b14bSRao Shoaib if (pthread_key_create(&key, net_data_destroy) != 0) { 1409525b14bSRao Shoaib (void)pthread_mutex_unlock(&keylock); 1419525b14bSRao Shoaib return (NULL); 1429525b14bSRao Shoaib } 1439525b14bSRao Shoaib once = 1; 1449525b14bSRao Shoaib } 1459525b14bSRao Shoaib if (pthread_mutex_unlock(&keylock) != 0) 1469525b14bSRao Shoaib return (NULL); 1479525b14bSRao Shoaib } 1487c478bd9Sstevel@tonic-gate net_data = pthread_getspecific(key); 1497c478bd9Sstevel@tonic-gate #endif 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate if (net_data == NULL) { 1527c478bd9Sstevel@tonic-gate net_data = net_data_create(conf_file); 1537c478bd9Sstevel@tonic-gate if (net_data == NULL) 1547c478bd9Sstevel@tonic-gate return (NULL); 1557c478bd9Sstevel@tonic-gate #ifdef DO_PTHREADS 156168c2130Sjs198686 if (pthread_setspecific(key, net_data) != 0) { 157168c2130Sjs198686 net_data_destroy(net_data); 158168c2130Sjs198686 return (NULL); 159168c2130Sjs198686 } 1607c478bd9Sstevel@tonic-gate #endif 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate return (net_data); 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate struct net_data * 1677c478bd9Sstevel@tonic-gate net_data_create(const char *conf_file) { 1687c478bd9Sstevel@tonic-gate struct net_data *net_data; 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate net_data = memget(sizeof (struct net_data)); 1717c478bd9Sstevel@tonic-gate if (net_data == NULL) 1727c478bd9Sstevel@tonic-gate return (NULL); 1737c478bd9Sstevel@tonic-gate memset(net_data, 0, sizeof (struct net_data)); 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate if ((net_data->irs = irs_gen_acc("", conf_file)) == NULL) { 1767c478bd9Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1777c478bd9Sstevel@tonic-gate return (NULL); 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate #ifndef DO_PTHREADS 1807c478bd9Sstevel@tonic-gate (*net_data->irs->res_set)(net_data->irs, &_res, NULL); 1817c478bd9Sstevel@tonic-gate #endif 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate net_data->res = (*net_data->irs->res_get)(net_data->irs); 1847c478bd9Sstevel@tonic-gate if (net_data->res == NULL) { 1857c478bd9Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1867c478bd9Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1877c478bd9Sstevel@tonic-gate return (NULL); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate 1909525b14bSRao Shoaib if ((net_data->res->options & RES_INIT) == 0U && 1917c478bd9Sstevel@tonic-gate res_ninit(net_data->res) == -1) { 1927c478bd9Sstevel@tonic-gate (*net_data->irs->close)(net_data->irs); 1937c478bd9Sstevel@tonic-gate memput(net_data, sizeof (struct net_data)); 1947c478bd9Sstevel@tonic-gate return (NULL); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate return (net_data); 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate void 2017c478bd9Sstevel@tonic-gate net_data_minimize(struct net_data *net_data) { 2027c478bd9Sstevel@tonic-gate res_nclose(net_data->res); 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate #ifdef _REENTRANT 2067c478bd9Sstevel@tonic-gate struct __res_state * 2077c478bd9Sstevel@tonic-gate __res_state(void) { 2087c478bd9Sstevel@tonic-gate /* NULL param here means use the default config file. */ 2097c478bd9Sstevel@tonic-gate struct net_data *net_data = net_data_init(NULL); 2107c478bd9Sstevel@tonic-gate if (net_data && net_data->res) 2117c478bd9Sstevel@tonic-gate return (net_data->res); 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate return (&_res); 2147c478bd9Sstevel@tonic-gate } 2159525b14bSRao Shoaib #else 2169525b14bSRao Shoaib #ifdef __linux 2179525b14bSRao Shoaib struct __res_state * 2189525b14bSRao Shoaib __res_state(void) { 2199525b14bSRao Shoaib return (&_res); 2209525b14bSRao Shoaib } 2219525b14bSRao Shoaib #endif 2227c478bd9Sstevel@tonic-gate #endif 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate int * 2257c478bd9Sstevel@tonic-gate __h_errno(void) { 2267c478bd9Sstevel@tonic-gate /* NULL param here means use the default config file. */ 2277c478bd9Sstevel@tonic-gate struct net_data *net_data = net_data_init(NULL); 2287c478bd9Sstevel@tonic-gate if (net_data && net_data->res) 2297c478bd9Sstevel@tonic-gate return (&net_data->res->res_h_errno); 230*4e567b44SStacey Marshall #ifdef ORIGINAL_ISC_CODE 2319525b14bSRao Shoaib #if !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) 2329525b14bSRao Shoaib return(&_res.res_h_errno); 2339525b14bSRao Shoaib #else 2347c478bd9Sstevel@tonic-gate return (&h_errno); 2359525b14bSRao Shoaib #endif 236*4e567b44SStacey Marshall #else 237*4e567b44SStacey Marshall return (&h_errno); 238*4e567b44SStacey Marshall #endif /* ORIGINAL_ISC_CODE */ 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate void 2427c478bd9Sstevel@tonic-gate __h_errno_set(struct __res_state *res, int err) { 2437c478bd9Sstevel@tonic-gate 2449525b14bSRao Shoaib 2459525b14bSRao Shoaib #if (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) 2469525b14bSRao Shoaib res->res_h_errno = err; 2479525b14bSRao Shoaib #else 2487c478bd9Sstevel@tonic-gate h_errno = res->res_h_errno = err; 2499525b14bSRao Shoaib #endif 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate #endif /*__BIND_NOSTATIC*/ 2539525b14bSRao Shoaib 2549525b14bSRao Shoaib /*! \file */ 255