5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 */
26
27 #include <stdlib.h>
28 #include <alloca.h>
29 #include <signal.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <pthread.h>
33 #include <time.h>
34 #include <errno.h>
35 #include <door.h>
36 #include <zone.h>
37 #include <resolv.h>
38 #include <sys/socket.h>
39 #include <net/route.h>
40 #include <string.h>
41 #include <net/if.h>
42 #include <sys/stat.h>
43 #include <fcntl.h>
44 #include "nscd_common.h"
72 extern mutex_t activity_lock;
73
74 static sema_t common_sema;
75
76 static thread_key_t lookup_state_key;
77 static mutex_t create_lock = DEFAULTMUTEX;
78 static int num_servers = 0;
79 static thread_key_t server_key;
80
81 /*
82 * Bind a TSD value to a server thread. This enables the destructor to
83 * be called if/when this thread exits. This would be a programming
84 * error, but better safe than sorry.
85 */
86 /*ARGSUSED*/
87 static void *
88 server_tsd_bind(void *arg)
89 {
90 static void *value = 0;
91
92 /* disable cancellation to avoid hangs if server threads disappear */
93 (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
94 (void) thr_setspecific(server_key, value);
95 (void) door_return(NULL, 0, NULL, 0);
96
97 /* make lint happy */
98 return (NULL);
99 }
100
101 /*
102 * Server threads are created here.
103 */
104 /*ARGSUSED*/
105 static void
106 server_create(door_info_t *dip)
107 {
108 (void) mutex_lock(&create_lock);
109 if (++num_servers > max_servers) {
110 num_servers--;
111 (void) mutex_unlock(&create_lock);
115 (void) thr_create(NULL, 0, server_tsd_bind, NULL,
116 THR_BOUND|THR_DETACHED, NULL);
117 }
118
119 /*
120 * Server thread are destroyed here
121 */
122 /*ARGSUSED*/
123 static void
124 server_destroy(void *arg)
125 {
126 (void) mutex_lock(&create_lock);
127 num_servers--;
128 (void) mutex_unlock(&create_lock);
129 }
130
131 /*
132 * get clearance
133 */
134 int
135 _nscd_get_clearance(sema_t *sema) {
136 if (sema_trywait(&common_sema) == 0) {
137 (void) thr_setspecific(lookup_state_key, NULL);
138 return (0);
139 }
140
141 if (sema_trywait(sema) == 0) {
142 (void) thr_setspecific(lookup_state_key, (void*)1);
143 return (0);
144 }
145
146 return (1);
147 }
148
149
150 /*
151 * release clearance
152 */
153 int
154 _nscd_release_clearance(sema_t *sema) {
155 int which;
156
157 (void) thr_getspecific(lookup_state_key, (void**)&which);
158 if (which == 0) /* from common pool */ {
159 (void) sema_post(&common_sema);
160 return (0);
161 }
162
163 (void) sema_post(sema);
164 return (1);
165 }
166
167 static void
168 dozip(void)
169 {
170 /* not much here */
171 }
172
173 /*
174 * _nscd_restart_if_cfgfile_changed()
1460 * cache are sorted based on destination address selection rules,
1461 * so when things change that could affect that sorting (interfaces
1462 * go up or down, flags change, etc.), we clear that cache so the
1463 * list will be re-ordered the next time the hostname is resolved.
1464 */
1465 static void
1466 rts_mon(void)
1467 {
1468 int rt_sock, rdlen, idx;
1469 union {
1470 struct {
1471 struct rt_msghdr rtm;
1472 struct sockaddr_storage addrs[RTA_NUMBITS];
1473 } r;
1474 struct if_msghdr ifm;
1475 struct ifa_msghdr ifam;
1476 } mbuf;
1477 struct ifa_msghdr *ifam = &mbuf.ifam;
1478 char *me = "rts_mon";
1479
1480 rt_sock = socket(PF_ROUTE, SOCK_RAW, 0);
1481 if (rt_sock < 0) {
1482 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
1483 (me, "Failed to open routing socket: %s\n", strerror(errno));
1484 thr_exit(0);
1485 }
1486
1487 for (;;) {
1488 rdlen = read(rt_sock, &mbuf, sizeof (mbuf));
1489 if (rdlen <= 0) {
1490 if (rdlen == 0 || (errno != EINTR && errno != EAGAIN)) {
1491 _NSCD_LOG(NSCD_LOG_FRONT_END,
1492 NSCD_LOG_LEVEL_ERROR)
1493 (me, "routing socket read: %s\n",
1494 strerror(errno));
1495 thr_exit(0);
1496 }
1497 continue;
1498 }
1499 if (ifam->ifam_version != RTM_VERSION) {
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 * Copyright 2018 Joyent, Inc.
26 */
27
28 #include <stdlib.h>
29 #include <alloca.h>
30 #include <signal.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <pthread.h>
34 #include <time.h>
35 #include <errno.h>
36 #include <door.h>
37 #include <zone.h>
38 #include <resolv.h>
39 #include <sys/socket.h>
40 #include <net/route.h>
41 #include <string.h>
42 #include <net/if.h>
43 #include <sys/stat.h>
44 #include <fcntl.h>
45 #include "nscd_common.h"
73 extern mutex_t activity_lock;
74
75 static sema_t common_sema;
76
77 static thread_key_t lookup_state_key;
78 static mutex_t create_lock = DEFAULTMUTEX;
79 static int num_servers = 0;
80 static thread_key_t server_key;
81
82 /*
83 * Bind a TSD value to a server thread. This enables the destructor to
84 * be called if/when this thread exits. This would be a programming
85 * error, but better safe than sorry.
86 */
87 /*ARGSUSED*/
88 static void *
89 server_tsd_bind(void *arg)
90 {
91 static void *value = 0;
92
93 (void) thr_setname(thr_self(), "server_tsd_bind");
94
95 /* disable cancellation to avoid hangs if server threads disappear */
96 (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
97 (void) thr_setspecific(server_key, value);
98 (void) door_return(NULL, 0, NULL, 0);
99
100 /* make lint happy */
101 return (NULL);
102 }
103
104 /*
105 * Server threads are created here.
106 */
107 /*ARGSUSED*/
108 static void
109 server_create(door_info_t *dip)
110 {
111 (void) mutex_lock(&create_lock);
112 if (++num_servers > max_servers) {
113 num_servers--;
114 (void) mutex_unlock(&create_lock);
118 (void) thr_create(NULL, 0, server_tsd_bind, NULL,
119 THR_BOUND|THR_DETACHED, NULL);
120 }
121
122 /*
123 * Server thread are destroyed here
124 */
125 /*ARGSUSED*/
126 static void
127 server_destroy(void *arg)
128 {
129 (void) mutex_lock(&create_lock);
130 num_servers--;
131 (void) mutex_unlock(&create_lock);
132 }
133
134 /*
135 * get clearance
136 */
137 int
138 _nscd_get_clearance(sema_t *sema)
139 {
140 if (sema_trywait(&common_sema) == 0) {
141 (void) thr_setspecific(lookup_state_key, NULL);
142 return (0);
143 }
144
145 if (sema_trywait(sema) == 0) {
146 (void) thr_setspecific(lookup_state_key, (void*)1);
147 return (0);
148 }
149
150 return (1);
151 }
152
153
154 /*
155 * release clearance
156 */
157 int
158 _nscd_release_clearance(sema_t *sema)
159 {
160 int which;
161
162 (void) thr_getspecific(lookup_state_key, (void**)&which);
163 if (which == 0) /* from common pool */ {
164 (void) sema_post(&common_sema);
165 return (0);
166 }
167
168 (void) sema_post(sema);
169 return (1);
170 }
171
172 static void
173 dozip(void)
174 {
175 /* not much here */
176 }
177
178 /*
179 * _nscd_restart_if_cfgfile_changed()
1465 * cache are sorted based on destination address selection rules,
1466 * so when things change that could affect that sorting (interfaces
1467 * go up or down, flags change, etc.), we clear that cache so the
1468 * list will be re-ordered the next time the hostname is resolved.
1469 */
1470 static void
1471 rts_mon(void)
1472 {
1473 int rt_sock, rdlen, idx;
1474 union {
1475 struct {
1476 struct rt_msghdr rtm;
1477 struct sockaddr_storage addrs[RTA_NUMBITS];
1478 } r;
1479 struct if_msghdr ifm;
1480 struct ifa_msghdr ifam;
1481 } mbuf;
1482 struct ifa_msghdr *ifam = &mbuf.ifam;
1483 char *me = "rts_mon";
1484
1485 (void) thr_setname(thr_self(), me);
1486
1487 rt_sock = socket(PF_ROUTE, SOCK_RAW, 0);
1488 if (rt_sock < 0) {
1489 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
1490 (me, "Failed to open routing socket: %s\n", strerror(errno));
1491 thr_exit(0);
1492 }
1493
1494 for (;;) {
1495 rdlen = read(rt_sock, &mbuf, sizeof (mbuf));
1496 if (rdlen <= 0) {
1497 if (rdlen == 0 || (errno != EINTR && errno != EAGAIN)) {
1498 _NSCD_LOG(NSCD_LOG_FRONT_END,
1499 NSCD_LOG_LEVEL_ERROR)
1500 (me, "routing socket read: %s\n",
1501 strerror(errno));
1502 thr_exit(0);
1503 }
1504 continue;
1505 }
1506 if (ifam->ifam_version != RTM_VERSION) {
|