1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 *
4 * Copyright 1998-2021 The OpenLDAP Foundation.
5 * Portions Copyright 2007 by Howard Chu, Symas Corporation.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
10 * Public License.
11 *
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
15 */
16 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms are permitted
20 * provided that this notice is preserved and that due credit is given
21 * to the University of Michigan at Ann Arbor. The name of the University
22 * may not be used to endorse or promote products derived from this
23 * software without specific prior written permission. This software
24 * is provided ``as is'' without express or implied warranty.
25 */
26
27 #include "portable.h"
28
29 #include <stdio.h>
30
31 #include <ac/ctype.h>
32 #include <ac/errno.h>
33 #include <ac/socket.h>
34 #include <ac/string.h>
35 #include <ac/time.h>
36 #include <ac/unistd.h>
37
38 #include "slap.h"
39 #include "ldap_pvt_thread.h"
40 #include "lutil.h"
41
42 #include "ldap_rq.h"
43
44 #ifdef HAVE_SYSTEMD_SD_DAEMON_H
45 #include <systemd/sd-daemon.h>
46 #endif
47
48 #ifdef HAVE_POLL
49 #include <poll.h>
50 #endif
51
52 #ifdef HAVE_KQUEUE
53 # include <sys/types.h>
54 # include <sys/event.h>
55 # include <sys/time.h>
56 #elif defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL)
57 # include <sys/epoll.h>
58 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_SYS_DEVPOLL_H) && defined(HAVE_DEVPOLL)
59 # include <sys/types.h>
60 # include <sys/stat.h>
61 # include <fcntl.h>
62 # include <sys/devpoll.h>
63 #endif /* ! kqueue && ! epoll && ! /dev/poll */
64
65 #ifdef HAVE_TCPD
66 int allow_severity = LOG_INFO;
67 int deny_severity = LOG_NOTICE;
68 #endif /* TCP Wrappers */
69
70 #ifdef LDAP_PF_LOCAL
71 # include <sys/stat.h>
72 /* this should go in <ldap.h> as soon as it is accepted */
73 # define LDAPI_MOD_URLEXT "x-mod"
74 #endif /* LDAP_PF_LOCAL */
75
76 #ifdef LDAP_PF_INET6
77 int slap_inet4or6 = AF_UNSPEC;
78 #else /* ! INETv6 */
79 int slap_inet4or6 = AF_INET;
80 #endif /* ! INETv6 */
81
82 /* globals */
83 time_t starttime;
84 ber_socket_t dtblsize;
85 slap_ssf_t local_ssf = LDAP_PVT_SASL_LOCAL_SSF;
86 struct runqueue_s slapd_rq;
87
88 int slapd_daemon_threads = 1;
89 int slapd_daemon_mask;
90
91 #ifdef LDAP_TCP_BUFFER
92 int slapd_tcp_rmem;
93 int slapd_tcp_wmem;
94 #endif /* LDAP_TCP_BUFFER */
95
96 Listener **slap_listeners = NULL;
97 static volatile sig_atomic_t listening = 1; /* 0 when slap_listeners closed */
98
99 #ifndef SLAPD_LISTEN_BACKLOG
100 #define SLAPD_LISTEN_BACKLOG 2048
101 #endif /* ! SLAPD_LISTEN_BACKLOG */
102
103 #define DAEMON_ID(fd) (fd & slapd_daemon_mask)
104
105 typedef ber_socket_t sdpair[2];
106
107 static sdpair *wake_sds;
108 static ldap_pvt_thread_mutex_t emfile_mutex;
109 static int emfile;
110
111 static volatile int waking;
112 #define WAKE_LISTENER(l,w) do { \
113 if (w) { \
114 (void)!tcp_write( SLAP_FD2SOCK(wake_sds[l][1]), "0", 1 ); \
115 } \
116 } while (0)
117
118 ldap_pvt_thread_mutex_t slapd_init_mutex;
119 ldap_pvt_thread_cond_t slapd_init_cond;
120 int slapd_ready = 0;
121
122 volatile sig_atomic_t slapd_shutdown = 0;
123 volatile sig_atomic_t slapd_gentle_shutdown = 0;
124 volatile sig_atomic_t slapd_abrupt_shutdown = 0;
125
126 #ifdef HAVE_WINSOCK
127 ldap_pvt_thread_mutex_t slapd_ws_mutex;
128 SOCKET *slapd_ws_sockets;
129 #define SD_READ 1
130 #define SD_WRITE 2
131 #define SD_ACTIVE 4
132 #define SD_LISTENER 8
133 #endif
134
135 #ifdef HAVE_TCPD
136 static ldap_pvt_thread_mutex_t sd_tcpd_mutex;
137 #endif /* TCP Wrappers */
138
139 typedef struct slap_daemon_st {
140 ldap_pvt_thread_mutex_t sd_mutex;
141
142 ber_socket_t sd_nactives;
143 int sd_nwriters;
144 int sd_nfds;
145 ldap_pvt_thread_t sd_tid;
146
147 #if defined(HAVE_KQUEUE)
148 uint8_t* sd_fdmodes; /* indexed by fd */
149 Listener** sd_l; /* indexed by fd */
150 /* Double buffer the kqueue changes to avoid holding the sd_mutex \
151 * during a kevent() call. \
152 */
153 struct kq_change {
154 struct kevent* sd_changes;
155 int sd_nchanges;
156 int sd_maxchanges;
157 } sd_kqc[2];
158 int sd_changeidx; /* index to current change buffer */
159 int sd_kq;
160 #elif defined(HAVE_EPOLL)
161
162 struct epoll_event *sd_epolls;
163 int *sd_index;
164 int sd_epfd;
165 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_DEVPOLL)
166 /* eXperimental */
167 struct pollfd *sd_pollfd;
168 int *sd_index;
169 Listener **sd_l;
170 int sd_dpfd;
171 #else /* ! kqueue && ! epoll && ! /dev/poll */
172 #ifdef HAVE_WINSOCK
173 char *sd_flags;
174 char *sd_rflags;
175 #else /* ! HAVE_WINSOCK */
176 fd_set sd_actives;
177 fd_set sd_readers;
178 fd_set sd_writers;
179 #endif /* ! HAVE_WINSOCK */
180 #endif /* ! kqueue && ! epoll && ! /dev/poll */
181 } slap_daemon_st;
182
183 static slap_daemon_st *slap_daemon;
184
185 /*
186 * NOTE: naming convention for macros:
187 *
188 * - SLAP_SOCK_* and SLAP_EVENT_* for public interface that deals
189 * with file descriptors and events respectively
190 *
191 * - SLAP_<type>_* for private interface; type by now is one of
192 * EPOLL, DEVPOLL, SELECT, KQUEUE
193 *
194 * private interface should not be used in the code.
195 */
196 #ifdef HAVE_KQUEUE
197 # define SLAP_EVENT_FNAME "kqueue"
198 # define SLAP_EVENTS_ARE_INDEXED 0
199 # define SLAP_EVENT_MAX(t) (2 * dtblsize) /* each fd can have a read & a write event */
200
201 # define SLAP_EVENT_DECL \
202 static struct kevent* events = NULL
203
204 # define SLAP_EVENT_INIT(t) do {\
205 if (!events) { \
206 events = ch_malloc(sizeof(*events) * SLAP_EVENT_MAX(t)); \
207 } \
208 } while (0)
209
210 # define SLAP_SOCK_INIT(t) do { \
211 int kq_i; \
212 size_t kq_nbytes; \
213 Debug(LDAP_DEBUG_ANY, "daemon: SLAP_SOCK_INIT: dtblsize=%d\n", dtblsize); \
214 slap_daemon[t].sd_nfds = 0; \
215 slap_daemon[t].sd_changeidx = 0; \
216 for (kq_i = 0; kq_i < 2; kq_i++) { \
217 struct kq_change* kqc = &slap_daemon[t].sd_kqc[kq_i]; \
218 kqc->sd_nchanges = 0; \
219 kqc->sd_maxchanges = 256; /* will grow as needed */ \
220 kq_nbytes = sizeof(*kqc->sd_changes) * kqc->sd_maxchanges; \
221 kqc->sd_changes = ch_calloc(1, kq_nbytes); \
222 } \
223 kq_nbytes = sizeof(*slap_daemon[t].sd_fdmodes) * dtblsize; \
224 slap_daemon[t].sd_fdmodes = ch_calloc(1, kq_nbytes); \
225 kq_nbytes = sizeof(*slap_daemon[t].sd_l) * dtblsize; \
226 slap_daemon[t].sd_l = ch_calloc(1, kq_nbytes); \
227 slap_daemon[t].sd_kq = kqueue(); \
228 } while (0)
229
230 /* a kqueue fd obtained before a fork can't be used in child process.
231 * reacquire it.
232 */
233 # define SLAP_SOCK_INIT2() do { \
234 slap_daemon[0].sd_kq = kqueue(); \
235 } while (0)
236
237 # define SLAP_SOCK_DESTROY(t) do { \
238 int kq_i; \
239 if (slap_daemon[t].sd_kq > 0) { \
240 close(slap_daemon[t].sd_kq); \
241 slap_daemon[t].sd_kq = -1; \
242 } \
243 for (kq_i = 0; kq_i < 2; kq_i++) { \
244 if (slap_daemon[t].sd_kqc[kq_i].sd_changes != NULL) { \
245 ch_free(slap_daemon[t].sd_kqc[kq_i].sd_changes); \
246 slap_daemon[t].sd_kqc[kq_i].sd_changes = NULL; \
247 } \
248 slap_daemon[t].sd_kqc[kq_i].sd_nchanges = 0; \
249 slap_daemon[t].sd_kqc[kq_i].sd_maxchanges = 0; \
250 } \
251 if (slap_daemon[t].sd_l != NULL) { \
252 ch_free(slap_daemon[t].sd_l); \
253 slap_daemon[t].sd_l = NULL; \
254 } \
255 if (slap_daemon[t].sd_fdmodes != NULL) { \
256 ch_free(slap_daemon[t].sd_fdmodes); \
257 slap_daemon[t].sd_fdmodes = NULL; \
258 } \
259 slap_daemon[t].sd_nfds = 0; \
260 } while (0)
261
262 # define SLAP_KQUEUE_SOCK_ACTIVE 0x01
263 # define SLAP_KQUEUE_SOCK_READ_ENABLED 0x02
264 # define SLAP_KQUEUE_SOCK_WRITE_ENABLED 0x04
265
266 # define SLAP_SOCK_IS_ACTIVE(t,s) (slap_daemon[t].sd_fdmodes[(s)] != 0)
267 # define SLAP_SOCK_NOT_ACTIVE(t,s) (slap_daemon[t].sd_fdmodes[(s)] == 0)
268 # define SLAP_SOCK_IS_READ(t,s) (slap_daemon[t].sd_fdmodes[(s)] & SLAP_KQUEUE_SOCK_READ_ENABLED)
269 # define SLAP_SOCK_IS_WRITE(t,s) (slap_daemon[t].sd_fdmodes[(s)] & SLAP_KQUEUE_SOCK_WRITE_ENABLED)
270
271 /*
272 * SLAP_SOCK_SET_* & SLAP_SOCK_CLR_* get called a _lot_. Since kevent()
273 * processes changes before it looks for events, batch up the changes which
274 * will get submitted the next time kevent() is called for events.
275 */
276
277 # define SLAP_KQUEUE_CHANGE(t, s, filter, flag) do { \
278 /* If maxchanges is reached, have to realloc to make room for more. \
279 * Ideally we'd call kevent(), but the daemon thread could be sitting \
280 * in kevent() waiting for events. \
281 */ \
282 struct kq_change* kqc = &slap_daemon[t].sd_kqc[slap_daemon[t].sd_changeidx]; \
283 if (kqc->sd_nchanges == kqc->sd_maxchanges) { \
284 /* Don't want to do this very often. Double the size. */ \
285 size_t kq_nbytes; \
286 Debug(LDAP_DEBUG_CONNS, \
287 "daemon: SLAP_KQUEUE_CHANGE: increasing slap_daemon.sd_kqc[%d].maxchanges from %d to %d\n", \
288 slap_daemon[t].sd_changeidx, kqc->sd_maxchanges, 2*kqc->sd_maxchanges); \
289 kqc->sd_maxchanges += kqc->sd_maxchanges; \
290 kq_nbytes = sizeof(*kqc->sd_changes) * kqc->sd_maxchanges; \
291 kqc->sd_changes = ch_realloc(kqc->sd_changes, kq_nbytes); \
292 } \
293 EV_SET(&kqc->sd_changes[kqc->sd_nchanges++], \
294 (s), (filter), (flag), 0, 0, slap_daemon[t].sd_l[(s)]); \
295 } while (0)
296
297 # define SLAP_KQUEUE_SOCK_SET(t, s, filter, mode) do { \
298 if ((slap_daemon[t].sd_fdmodes[(s)] & (mode)) != (mode)) { \
299 slap_daemon[t].sd_fdmodes[(s)] |= (mode); \
300 SLAP_KQUEUE_CHANGE(t, (s), (filter), EV_ENABLE); \
301 } \
302 } while (0)
303
304 # define SLAP_KQUEUE_SOCK_CLR(t, s, filter, mode) do { \
305 if (slap_daemon[t].sd_fdmodes[(s)] & (mode)) { \
306 slap_daemon[t].sd_fdmodes[(s)] &= ~(mode); \
307 SLAP_KQUEUE_CHANGE(t, (s), (filter), EV_DISABLE); \
308 } \
309 } while (0)
310
311 # define SLAP_SOCK_SET_READ(t, s) SLAP_KQUEUE_SOCK_SET(t, (s), EVFILT_READ, SLAP_KQUEUE_SOCK_READ_ENABLED)
312 # define SLAP_SOCK_SET_WRITE(t, s) SLAP_KQUEUE_SOCK_SET(t, (s), EVFILT_WRITE, SLAP_KQUEUE_SOCK_WRITE_ENABLED)
313 # define SLAP_SOCK_CLR_READ(t, s) SLAP_KQUEUE_SOCK_CLR(t, (s), EVFILT_READ, SLAP_KQUEUE_SOCK_READ_ENABLED)
314 # define SLAP_SOCK_CLR_WRITE(t, s) SLAP_KQUEUE_SOCK_CLR(t, (s), EVFILT_WRITE, SLAP_KQUEUE_SOCK_WRITE_ENABLED)
315
316 /* kqueue doesn't need to do anything to clear the event. */
317 # define SLAP_EVENT_CLR_READ(i) do {} while (0)
318 # define SLAP_EVENT_CLR_WRITE(i) do {} while (0)
319
320 # define SLAP_SOCK_ADD(t, s, l) do { \
321 assert( s < dtblsize ); \
322 slap_daemon[t].sd_l[(s)] = (l); \
323 slap_daemon[t].sd_fdmodes[(s)] = SLAP_KQUEUE_SOCK_ACTIVE | SLAP_KQUEUE_SOCK_READ_ENABLED; \
324 ++slap_daemon[t].sd_nfds; \
325 SLAP_KQUEUE_CHANGE(t, (s), EVFILT_READ, EV_ADD); \
326 SLAP_KQUEUE_CHANGE(t, (s), EVFILT_WRITE, EV_ADD | EV_DISABLE); \
327 } while (0)
328
329 # define SLAP_SOCK_DEL(t, s) do { \
330 SLAP_KQUEUE_CHANGE(t, (s), EVFILT_READ, EV_DELETE); \
331 SLAP_KQUEUE_CHANGE(t, (s), EVFILT_WRITE, EV_DELETE); \
332 slap_daemon[t].sd_l[(s)] = NULL; \
333 slap_daemon[t].sd_fdmodes[(s)] = 0; \
334 --slap_daemon[t].sd_nfds; \
335 } while (0)
336
337 # define SLAP_EVENT_FD(t, i) (events[(i)].ident)
338
339 # define SLAP_EVENT_IS_READ(t, i) \
340 (events[(i)].filter == EVFILT_READ && SLAP_SOCK_IS_READ(t, SLAP_EVENT_FD(0, i)))
341
342 # define SLAP_EVENT_IS_WRITE(t, i) \
343 (events[(i)].filter == EVFILT_WRITE && SLAP_SOCK_IS_WRITE(t, SLAP_EVENT_FD(0, i)))
344
345 # define SLAP_EVENT_IS_LISTENER(t, i) \
346 (events[(i)].udata && SLAP_SOCK_IS_READ(t, SLAP_EVENT_FD(t, i)))
347
348 # define SLAP_EVENT_LISTENER(t, i) ((Listener*)(events[(i)].udata))
349
350 # define SLAP_EVENT_WAIT(t, tvp, nsp) do { \
351 struct timespec kq_ts; \
352 struct timespec* kq_tsp; \
353 int kq_idx; \
354 if (tvp) { \
355 TIMEVAL_TO_TIMESPEC((tvp), &kq_ts); \
356 kq_tsp = &kq_ts; \
357 } else { \
358 kq_tsp = NULL; \
359 } \
360 /* Save the change buffer index for use when the mutex is unlocked, \
361 * then switch the index so new changes go to the other buffer. \
362 */ \
363 ldap_pvt_thread_mutex_lock( &slap_daemon[t].sd_mutex ); \
364 kq_idx = slap_daemon[t].sd_changeidx; \
365 slap_daemon[t].sd_changeidx ^= 1; \
366 ldap_pvt_thread_mutex_unlock( &slap_daemon[t].sd_mutex ); \
367 *(nsp) = kevent(slap_daemon[t].sd_kq, \
368 slap_daemon[t].sd_kqc[kq_idx].sd_nchanges \
369 ? slap_daemon[t].sd_kqc[kq_idx].sd_changes : NULL, \
370 slap_daemon[t].sd_kqc[kq_idx].sd_nchanges, \
371 events, SLAP_EVENT_MAX(t), kq_tsp); \
372 slap_daemon[t].sd_kqc[kq_idx].sd_nchanges = 0; \
373 } while(0)
374
375 /*-------------------------------------------------------------------------------*/
376
377 #elif defined(HAVE_EPOLL)
378 /***************************************
379 * Use epoll infrastructure - epoll(4) *
380 ***************************************/
381 # define SLAP_EVENT_FNAME "epoll"
382 # define SLAP_EVENTS_ARE_INDEXED 0
383 # define SLAP_EPOLL_SOCK_IX(t,s) (slap_daemon[t].sd_index[(s)])
384 # define SLAP_EPOLL_SOCK_EP(t,s) (slap_daemon[t].sd_epolls[SLAP_EPOLL_SOCK_IX(t,s)])
385 # define SLAP_EPOLL_SOCK_EV(t,s) (SLAP_EPOLL_SOCK_EP(t,s).events)
386 # define SLAP_SOCK_IS_ACTIVE(t,s) (SLAP_EPOLL_SOCK_IX(t,s) != -1)
387 # define SLAP_SOCK_NOT_ACTIVE(t,s) (SLAP_EPOLL_SOCK_IX(t,s) == -1)
388 # define SLAP_EPOLL_SOCK_IS_SET(t,s, mode) (SLAP_EPOLL_SOCK_EV(t,s) & (mode))
389
390 # define SLAP_SOCK_IS_READ(t,s) SLAP_EPOLL_SOCK_IS_SET(t,(s), EPOLLIN)
391 # define SLAP_SOCK_IS_WRITE(t,s) SLAP_EPOLL_SOCK_IS_SET(t,(s), EPOLLOUT)
392
393 # define SLAP_EPOLL_SOCK_SET(t,s, mode) do { \
394 if ( (SLAP_EPOLL_SOCK_EV(t,s) & (mode)) != (mode) ) { \
395 SLAP_EPOLL_SOCK_EV(t,s) |= (mode); \
396 epoll_ctl( slap_daemon[t].sd_epfd, EPOLL_CTL_MOD, (s), \
397 &SLAP_EPOLL_SOCK_EP(t,s) ); \
398 } \
399 } while (0)
400
401 # define SLAP_EPOLL_SOCK_CLR(t,s, mode) do { \
402 if ( (SLAP_EPOLL_SOCK_EV(t,s) & (mode)) ) { \
403 SLAP_EPOLL_SOCK_EV(t,s) &= ~(mode); \
404 epoll_ctl( slap_daemon[t].sd_epfd, EPOLL_CTL_MOD, s, \
405 &SLAP_EPOLL_SOCK_EP(t,s) ); \
406 } \
407 } while (0)
408
409 # define SLAP_SOCK_SET_READ(t,s) SLAP_EPOLL_SOCK_SET(t,s, EPOLLIN)
410 # define SLAP_SOCK_SET_WRITE(t,s) SLAP_EPOLL_SOCK_SET(t,s, EPOLLOUT)
411
412 # define SLAP_SOCK_CLR_READ(t,s) SLAP_EPOLL_SOCK_CLR(t,(s), EPOLLIN)
413 # define SLAP_SOCK_CLR_WRITE(t,s) SLAP_EPOLL_SOCK_CLR(t,(s), EPOLLOUT)
414
415 # define SLAP_SOCK_SET_SUSPEND(t,s) \
416 ( slap_daemon[t].sd_suspend[SLAP_EPOLL_SOCK_IX(t,s)] = 1 )
417 # define SLAP_SOCK_CLR_SUSPEND(t,s) \
418 ( slap_daemon[t].sd_suspend[SLAP_EPOLL_SOCK_IX(t,s)] = 0 )
419 # define SLAP_SOCK_IS_SUSPEND(t,s) \
420 ( slap_daemon[t].sd_suspend[SLAP_EPOLL_SOCK_IX(t,s)] == 1 )
421
422 # define SLAP_EPOLL_EVENT_CLR(i, mode) (revents[(i)].events &= ~(mode))
423
424 # define SLAP_EVENT_MAX(t) slap_daemon[t].sd_nfds
425
426 /* If a Listener address is provided, store that as the epoll data.
427 * Otherwise, store the address of this socket's slot in the
428 * index array. If we can't do this add, the system is out of
429 * resources and we need to shutdown.
430 */
431 # define SLAP_SOCK_ADD(t, s, l) do { \
432 int rc; \
433 SLAP_EPOLL_SOCK_IX(t,(s)) = slap_daemon[t].sd_nfds; \
434 SLAP_EPOLL_SOCK_EP(t,(s)).data.ptr = (l) ? (l) : (void *)(&SLAP_EPOLL_SOCK_IX(t,s)); \
435 SLAP_EPOLL_SOCK_EV(t,(s)) = EPOLLIN; \
436 rc = epoll_ctl(slap_daemon[t].sd_epfd, EPOLL_CTL_ADD, \
437 (s), &SLAP_EPOLL_SOCK_EP(t,(s))); \
438 if ( rc == 0 ) { \
439 slap_daemon[t].sd_nfds++; \
440 } else { \
441 int saved_errno = errno; \
442 Debug( LDAP_DEBUG_ANY, \
443 "daemon: epoll_ctl(ADD,fd=%d) failed, errno=%d, shutting down\n", \
444 s, saved_errno ); \
445 slapd_shutdown = 2; \
446 } \
447 } while (0)
448
449 # define SLAP_EPOLL_EV_LISTENER(t,ptr) \
450 (((int *)(ptr) >= slap_daemon[t].sd_index && \
451 (int *)(ptr) <= &slap_daemon[t].sd_index[dtblsize]) ? 0 : 1 )
452
453 # define SLAP_EPOLL_EV_PTRFD(t,ptr) (SLAP_EPOLL_EV_LISTENER(t,ptr) ? \
454 ((Listener *)ptr)->sl_sd : \
455 (ber_socket_t) ((int *)(ptr) - slap_daemon[t].sd_index))
456
457 # define SLAP_SOCK_DEL(t,s) do { \
458 int fd, rc, index = SLAP_EPOLL_SOCK_IX(t,(s)); \
459 if ( index < 0 ) break; \
460 rc = epoll_ctl(slap_daemon[t].sd_epfd, EPOLL_CTL_DEL, \
461 (s), &SLAP_EPOLL_SOCK_EP(t,(s))); \
462 slap_daemon[t].sd_epolls[index] = \
463 slap_daemon[t].sd_epolls[slap_daemon[t].sd_nfds-1]; \
464 fd = SLAP_EPOLL_EV_PTRFD(t,slap_daemon[t].sd_epolls[index].data.ptr); \
465 slap_daemon[t].sd_index[fd] = index; \
466 slap_daemon[t].sd_index[(s)] = -1; \
467 slap_daemon[t].sd_nfds--; \
468 } while (0)
469
470 # define SLAP_EVENT_CLR_READ(i) SLAP_EPOLL_EVENT_CLR((i), EPOLLIN)
471 # define SLAP_EVENT_CLR_WRITE(i) SLAP_EPOLL_EVENT_CLR((i), EPOLLOUT)
472
473 # define SLAP_EPOLL_EVENT_CHK(i, mode) (revents[(i)].events & mode)
474
475 # define SLAP_EVENT_IS_READ(i) SLAP_EPOLL_EVENT_CHK((i), EPOLLIN)
476 # define SLAP_EVENT_IS_WRITE(i) SLAP_EPOLL_EVENT_CHK((i), EPOLLOUT)
477 # define SLAP_EVENT_IS_LISTENER(t,i) SLAP_EPOLL_EV_LISTENER(t,revents[(i)].data.ptr)
478 # define SLAP_EVENT_LISTENER(t,i) ((Listener *)(revents[(i)].data.ptr))
479
480 # define SLAP_EVENT_FD(t,i) SLAP_EPOLL_EV_PTRFD(t,revents[(i)].data.ptr)
481
482 # define SLAP_SOCK_INIT(t) do { \
483 int j; \
484 slap_daemon[t].sd_epolls = ch_calloc(1, \
485 ( sizeof(struct epoll_event) * 2 \
486 + sizeof(int) ) * dtblsize * 2); \
487 slap_daemon[t].sd_index = (int *)&slap_daemon[t].sd_epolls[ 2 * dtblsize ]; \
488 slap_daemon[t].sd_epfd = epoll_create( dtblsize / slapd_daemon_threads ); \
489 for ( j = 0; j < dtblsize; j++ ) slap_daemon[t].sd_index[j] = -1; \
490 } while (0)
491
492 # define SLAP_SOCK_INIT2()
493
494 # define SLAP_SOCK_DESTROY(t) do { \
495 if ( slap_daemon[t].sd_epolls != NULL ) { \
496 ch_free( slap_daemon[t].sd_epolls ); \
497 slap_daemon[t].sd_epolls = NULL; \
498 slap_daemon[t].sd_index = NULL; \
499 close( slap_daemon[t].sd_epfd ); \
500 } \
501 } while ( 0 )
502
503 # define SLAP_EVENT_DECL struct epoll_event *revents
504
505 # define SLAP_EVENT_INIT(t) do { \
506 revents = slap_daemon[t].sd_epolls + dtblsize; \
507 } while (0)
508
509 # define SLAP_EVENT_WAIT(t, tvp, nsp) do { \
510 *(nsp) = epoll_wait( slap_daemon[t].sd_epfd, revents, \
511 dtblsize, (tvp) ? ((tvp)->tv_sec * 1000 + (tvp)->tv_usec / 1000) : -1 ); \
512 } while (0)
513
514 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_DEVPOLL)
515
516 /*************************************************************
517 * Use Solaris' (>= 2.7) /dev/poll infrastructure - poll(7d) *
518 *************************************************************/
519 # define SLAP_EVENT_FNAME "/dev/poll"
520 # define SLAP_EVENTS_ARE_INDEXED 0
521 /*
522 * - sd_index is used much like with epoll()
523 * - sd_l is maintained as an array containing the address
524 * of the listener; the index is the fd itself
525 * - sd_pollfd is used to keep track of what data has been
526 * registered in /dev/poll
527 */
528 # define SLAP_DEVPOLL_SOCK_IX(t,s) (slap_daemon[t].sd_index[(s)])
529 # define SLAP_DEVPOLL_SOCK_LX(t,s) (slap_daemon[t].sd_l[(s)])
530 # define SLAP_DEVPOLL_SOCK_EP(t,s) (slap_daemon[t].sd_pollfd[SLAP_DEVPOLL_SOCK_IX(t,(s))])
531 # define SLAP_DEVPOLL_SOCK_FD(t,s) (SLAP_DEVPOLL_SOCK_EP(t,(s)).fd)
532 # define SLAP_DEVPOLL_SOCK_EV(t,s) (SLAP_DEVPOLL_SOCK_EP(t,(s)).events)
533 # define SLAP_SOCK_IS_ACTIVE(t,s) (SLAP_DEVPOLL_SOCK_IX(t,(s)) != -1)
534 # define SLAP_SOCK_NOT_ACTIVE(t,s) (SLAP_DEVPOLL_SOCK_IX(t,(s)) == -1)
535 # define SLAP_SOCK_IS_SET(t,s, mode) (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode))
536
537 # define SLAP_SOCK_IS_READ(t,s) SLAP_SOCK_IS_SET(t,(s), POLLIN)
538 # define SLAP_SOCK_IS_WRITE(t,s) SLAP_SOCK_IS_SET(t,(s), POLLOUT)
539
540 /* as far as I understand, any time we need to communicate with the kernel
541 * about the number and/or properties of a file descriptor we need it to
542 * wait for, we have to rewrite the whole set */
543 # define SLAP_DEVPOLL_WRITE_POLLFD(t,s, pfd, n, what, shdn) do { \
544 int rc; \
545 size_t size = (n) * sizeof( struct pollfd ); \
546 /* FIXME: use pwrite? */ \
547 rc = write( slap_daemon[t].sd_dpfd, (pfd), size ); \
548 if ( rc != size ) { \
549 int saved_errno = errno; \
550 Debug( LDAP_DEBUG_ANY, "daemon: " SLAP_EVENT_FNAME ": " \
551 "%s fd=%d failed errno=%d\n", \
552 (what), (s), saved_errno ); \
553 if ( (shdn) ) { \
554 slapd_shutdown = 2; \
555 } \
556 } \
557 } while (0)
558
559 # define SLAP_DEVPOLL_SOCK_SET(t,s, mode) do { \
560 Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_SET_%s(%d)=%d\n", \
561 (mode) == POLLIN ? "READ" : "WRITE", (s), \
562 ( (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) != (mode) ) ); \
563 if ( (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) != (mode) ) { \
564 struct pollfd pfd; \
565 SLAP_DEVPOLL_SOCK_EV(t,(s)) |= (mode); \
566 pfd.fd = SLAP_DEVPOLL_SOCK_FD(t,(s)); \
567 pfd.events = /* (mode) */ SLAP_DEVPOLL_SOCK_EV(t,(s)); \
568 SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &pfd, 1, "SET", 0); \
569 } \
570 } while (0)
571
572 # define SLAP_DEVPOLL_SOCK_CLR(t,s, mode) do { \
573 Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_CLR_%s(%d)=%d\n", \
574 (mode) == POLLIN ? "READ" : "WRITE", (s), \
575 ( (SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) == (mode) ) ); \
576 if ((SLAP_DEVPOLL_SOCK_EV(t,(s)) & (mode)) == (mode) ) { \
577 struct pollfd pfd[2]; \
578 SLAP_DEVPOLL_SOCK_EV(t,(s)) &= ~(mode); \
579 pfd[0].fd = SLAP_DEVPOLL_SOCK_FD(t,(s)); \
580 pfd[0].events = POLLREMOVE; \
581 pfd[1] = SLAP_DEVPOLL_SOCK_EP(t,(s)); \
582 SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &pfd[0], 2, "CLR", 0); \
583 } \
584 } while (0)
585
586 # define SLAP_SOCK_SET_READ(t,s) SLAP_DEVPOLL_SOCK_SET(t,s, POLLIN)
587 # define SLAP_SOCK_SET_WRITE(t,s) SLAP_DEVPOLL_SOCK_SET(t,s, POLLOUT)
588
589 # define SLAP_SOCK_CLR_READ(t,s) SLAP_DEVPOLL_SOCK_CLR(t,(s), POLLIN)
590 # define SLAP_SOCK_CLR_WRITE(t,s) SLAP_DEVPOLL_SOCK_CLR(t,(s), POLLOUT)
591
592 # define SLAP_SOCK_SET_SUSPEND(t,s) \
593 ( slap_daemon[t].sd_suspend[SLAP_DEVPOLL_SOCK_IX(t,(s))] = 1 )
594 # define SLAP_SOCK_CLR_SUSPEND(t,s) \
595 ( slap_daemon[t].sd_suspend[SLAP_DEVPOLL_SOCK_IX(t,(s))] = 0 )
596 # define SLAP_SOCK_IS_SUSPEND(t,s) \
597 ( slap_daemon[t].sd_suspend[SLAP_DEVPOLL_SOCK_IX(t,(s))] == 1 )
598
599 # define SLAP_DEVPOLL_EVENT_CLR(i, mode) (revents[(i)].events &= ~(mode))
600
601 # define SLAP_EVENT_MAX(t) slap_daemon[t].sd_nfds
602
603 /* If a Listener address is provided, store that in the sd_l array.
604 * If we can't do this add, the system is out of resources and we
605 * need to shutdown.
606 */
607 # define SLAP_SOCK_ADD(t, s, l) do { \
608 Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_ADD(%d, %p)\n", (s), (l) ); \
609 SLAP_DEVPOLL_SOCK_IX(t,(s)) = slap_daemon[t].sd_nfds; \
610 SLAP_DEVPOLL_SOCK_LX(t,(s)) = (l); \
611 SLAP_DEVPOLL_SOCK_FD(t,(s)) = (s); \
612 SLAP_DEVPOLL_SOCK_EV(t,(s)) = POLLIN; \
613 SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &SLAP_DEVPOLL_SOCK_EP(t, (s)), 1, "ADD", 1); \
614 slap_daemon[t].sd_nfds++; \
615 } while (0)
616
617 # define SLAP_DEVPOLL_EV_LISTENER(ptr) ((ptr) != NULL)
618
619 # define SLAP_SOCK_DEL(t,s) do { \
620 int fd, index = SLAP_DEVPOLL_SOCK_IX(t,(s)); \
621 Debug( LDAP_DEBUG_CONNS, "SLAP_SOCK_DEL(%d)\n", (s) ); \
622 if ( index < 0 ) break; \
623 if ( index < slap_daemon[t].sd_nfds - 1 ) { \
624 struct pollfd pfd = slap_daemon[t].sd_pollfd[index]; \
625 fd = slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1].fd; \
626 slap_daemon[t].sd_pollfd[index] = slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1]; \
627 slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1] = pfd; \
628 slap_daemon[t].sd_index[fd] = index; \
629 } \
630 slap_daemon[t].sd_index[(s)] = -1; \
631 slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1].events = POLLREMOVE; \
632 SLAP_DEVPOLL_WRITE_POLLFD(t,(s), &slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1], 1, "DEL", 0); \
633 slap_daemon[t].sd_pollfd[slap_daemon[t].sd_nfds - 1].events = 0; \
634 slap_daemon[t].sd_nfds--; \
635 } while (0)
636
637 # define SLAP_EVENT_CLR_READ(i) SLAP_DEVPOLL_EVENT_CLR((i), POLLIN)
638 # define SLAP_EVENT_CLR_WRITE(i) SLAP_DEVPOLL_EVENT_CLR((i), POLLOUT)
639
640 # define SLAP_DEVPOLL_EVENT_CHK(i, mode) (revents[(i)].events & (mode))
641
642 # define SLAP_EVENT_FD(t,i) (revents[(i)].fd)
643
644 # define SLAP_EVENT_IS_READ(i) SLAP_DEVPOLL_EVENT_CHK((i), POLLIN)
645 # define SLAP_EVENT_IS_WRITE(i) SLAP_DEVPOLL_EVENT_CHK((i), POLLOUT)
646 # define SLAP_EVENT_IS_LISTENER(t,i) SLAP_DEVPOLL_EV_LISTENER(SLAP_DEVPOLL_SOCK_LX(t, SLAP_EVENT_FD(t,(i))))
647 # define SLAP_EVENT_LISTENER(t,i) SLAP_DEVPOLL_SOCK_LX(t, SLAP_EVENT_FD(t,(i)))
648
649 # define SLAP_SOCK_DESTROY(t) do { \
650 if ( slap_daemon[t].sd_pollfd != NULL ) { \
651 ch_free( slap_daemon[t].sd_pollfd ); \
652 slap_daemon[t].sd_pollfd = NULL; \
653 slap_daemon[t].sd_index = NULL; \
654 slap_daemon[t].sd_l = NULL; \
655 close( slap_daemon[t].sd_dpfd ); \
656 } \
657 } while ( 0 )
658
659 # define SLAP_SOCK_INIT(t) do { \
660 slap_daemon[t].sd_pollfd = ch_calloc( 1, \
661 ( sizeof(struct pollfd) * 2 \
662 + sizeof( int ) \
663 + sizeof( Listener * ) ) * dtblsize ); \
664 slap_daemon[t].sd_index = (int *)&slap_daemon[t].sd_pollfd[ 2 * dtblsize ]; \
665 slap_daemon[t].sd_l = (Listener **)&slap_daemon[t].sd_index[ dtblsize ]; \
666 slap_daemon[t].sd_dpfd = open( SLAP_EVENT_FNAME, O_RDWR ); \
667 if ( slap_daemon[t].sd_dpfd == -1 ) { \
668 int saved_errno = errno; \
669 Debug( LDAP_DEBUG_ANY, "daemon: " SLAP_EVENT_FNAME ": " \
670 "open(\"" SLAP_EVENT_FNAME "\") failed errno=%d\n", \
671 saved_errno ); \
672 SLAP_SOCK_DESTROY(t); \
673 return -1; \
674 } \
675 for ( i = 0; i < dtblsize; i++ ) { \
676 slap_daemon[t].sd_pollfd[i].fd = -1; \
677 slap_daemon[t].sd_index[i] = -1; \
678 } \
679 } while (0)
680
681 # define SLAP_SOCK_INIT2()
682
683 # define SLAP_EVENT_DECL struct pollfd *revents
684
685 # define SLAP_EVENT_INIT(t) do { \
686 revents = &slap_daemon[t].sd_pollfd[ dtblsize ]; \
687 } while (0)
688
689 # define SLAP_EVENT_WAIT(t, tvp, nsp) do { \
690 struct dvpoll sd_dvpoll; \
691 sd_dvpoll.dp_timeout = (tvp) ? ((tvp)->tv_sec * 1000 + (tvp)->tv_usec / 1000) : -1; \
692 sd_dvpoll.dp_nfds = dtblsize; \
693 sd_dvpoll.dp_fds = revents; \
694 *(nsp) = ioctl( slap_daemon[t].sd_dpfd, DP_POLL, &sd_dvpoll ); \
695 } while (0)
696
697 #else /* ! kqueue && ! epoll && ! /dev/poll */
698 # ifdef HAVE_WINSOCK
699 # define SLAP_EVENT_FNAME "WSselect"
700 /* Winsock provides a "select" function but its fd_sets are
701 * actually arrays of sockets. Since these sockets are handles
702 * and not a contiguous range of small integers, we manage our
703 * own "fd" table of socket handles and use their indices as
704 * descriptors.
705 *
706 * All of our listener/connection structures use fds; the actual
707 * I/O functions use sockets. The SLAP_FD2SOCK macro in proto-slap.h
708 * handles the mapping.
709 *
710 * Despite the mapping overhead, this is about 45% more efficient
711 * than just using Winsock's select and FD_ISSET directly.
712 *
713 * Unfortunately Winsock's select implementation doesn't scale well
714 * as the number of connections increases. This probably needs to be
715 * rewritten to use the Winsock overlapped/asynchronous I/O functions.
716 */
717 # define SLAP_EVENTS_ARE_INDEXED 1
718 # define SLAP_EVENT_DECL fd_set readfds, writefds; char *rflags
719 # define SLAP_EVENT_INIT(t) do { \
720 int i; \
721 FD_ZERO( &readfds ); \
722 FD_ZERO( &writefds ); \
723 rflags = slap_daemon[t].sd_rflags; \
724 memset( rflags, 0, slap_daemon[t].sd_nfds ); \
725 for ( i=0; i<slap_daemon[t].sd_nfds; i++ ) { \
726 if ( slap_daemon[t].sd_flags[i] & SD_READ ) \
727 FD_SET( slapd_ws_sockets[i], &readfds );\
728 if ( slap_daemon[t].sd_flags[i] & SD_WRITE ) \
729 FD_SET( slapd_ws_sockets[i], &writefds ); \
730 } } while ( 0 )
731
732 # define SLAP_EVENT_MAX(t) slap_daemon[t].sd_nfds
733
734 # define SLAP_EVENT_WAIT(t, tvp, nsp) do { \
735 int i; \
736 *(nsp) = select( SLAP_EVENT_MAX(t), &readfds, \
737 nwriters > 0 ? &writefds : NULL, NULL, (tvp) ); \
738 for ( i=0; i<readfds.fd_count; i++) { \
739 int fd = slapd_sock2fd(readfds.fd_array[i]); \
740 if ( fd >= 0 ) { \
741 slap_daemon[t].sd_rflags[fd] = SD_READ; \
742 if ( fd >= *(nsp)) *(nsp) = fd+1; \
743 } \
744 } \
745 for ( i=0; i<writefds.fd_count; i++) { \
746 int fd = slapd_sock2fd(writefds.fd_array[i]); \
747 if ( fd >= 0 ) { \
748 slap_daemon[t].sd_rflags[fd] = SD_WRITE; \
749 if ( fd >= *(nsp)) *(nsp) = fd+1; \
750 } \
751 } \
752 } while (0)
753
754 # define SLAP_EVENT_IS_READ(fd) (rflags[fd] & SD_READ)
755 # define SLAP_EVENT_IS_WRITE(fd) (rflags[fd] & SD_WRITE)
756
757 # define SLAP_EVENT_CLR_READ(fd) rflags[fd] &= ~SD_READ
758 # define SLAP_EVENT_CLR_WRITE(fd) rflags[fd] &= ~SD_WRITE
759
760 # define SLAP_SOCK_INIT(t) do { \
761 if (!t) { \
762 ldap_pvt_thread_mutex_init( &slapd_ws_mutex ); \
763 slapd_ws_sockets = ch_malloc( dtblsize * ( sizeof(SOCKET) + 2)); \
764 memset( slapd_ws_sockets, -1, dtblsize * sizeof(SOCKET) ); \
765 } \
766 slap_daemon[t].sd_flags = (char *)(slapd_ws_sockets + dtblsize); \
767 slap_daemon[t].sd_rflags = slap_daemon[t].sd_flags + dtblsize; \
768 memset( slap_daemon[t].sd_flags, 0, dtblsize ); \
769 slapd_ws_sockets[t*2] = wake_sds[t][0]; \
770 slapd_ws_sockets[t*2+1] = wake_sds[t][1]; \
771 wake_sds[t][0] = t*2; \
772 wake_sds[t][1] = t*2+1; \
773 slap_daemon[t].sd_nfds = t*2 + 2; \
774 } while ( 0 )
775
776 # define SLAP_SOCK_INIT2()
777
778 # define SLAP_SOCK_DESTROY(t) do { \
779 ch_free( slapd_ws_sockets ); slapd_ws_sockets = NULL; \
780 slap_daemon[t].sd_flags = NULL; \
781 slap_daemon[t].sd_rflags = NULL; \
782 ldap_pvt_thread_mutex_destroy( &slapd_ws_mutex ); \
783 } while ( 0 )
784
785 # define SLAP_SOCK_IS_ACTIVE(t,fd) ( slap_daemon[t].sd_flags[fd] & SD_ACTIVE )
786 # define SLAP_SOCK_IS_READ(t,fd) ( slap_daemon[t].sd_flags[fd] & SD_READ )
787 # define SLAP_SOCK_IS_WRITE(t,fd) ( slap_daemon[t].sd_flags[fd] & SD_WRITE )
788 # define SLAP_SOCK_NOT_ACTIVE(t,fd) (!slap_daemon[t].sd_flags[fd])
789
790 # define SLAP_SOCK_SET_READ(t,fd) ( slap_daemon[t].sd_flags[fd] |= SD_READ )
791 # define SLAP_SOCK_SET_WRITE(t,fd) ( slap_daemon[t].sd_flags[fd] |= SD_WRITE )
792
793 # define SLAP_SELECT_ADDTEST(t,s) do { \
794 if ((s) >= slap_daemon[t].sd_nfds) slap_daemon[t].sd_nfds = (s)+1; \
795 } while (0)
796
797 # define SLAP_SOCK_CLR_READ(t,fd) ( slap_daemon[t].sd_flags[fd] &= ~SD_READ )
798 # define SLAP_SOCK_CLR_WRITE(t,fd) ( slap_daemon[t].sd_flags[fd] &= ~SD_WRITE )
799
800 # define SLAP_SOCK_ADD(t,s, l) do { \
801 SLAP_SELECT_ADDTEST(t,(s)); \
802 slap_daemon[t].sd_flags[s] = SD_ACTIVE|SD_READ; \
803 } while ( 0 )
804
805 # define SLAP_SOCK_DEL(t,s) do { \
806 slap_daemon[t].sd_flags[s] = 0; \
807 slapd_sockdel( s ); \
808 } while ( 0 )
809
810 # else /* !HAVE_WINSOCK */
811
812 /**************************************
813 * Use select system call - select(2) *
814 **************************************/
815 # define SLAP_EVENT_FNAME "select"
816 /* select */
817 # define SLAP_EVENTS_ARE_INDEXED 1
818 # define SLAP_EVENT_DECL fd_set readfds, writefds
819
820 # define SLAP_EVENT_INIT(t) do { \
821 AC_MEMCPY( &readfds, &slap_daemon[t].sd_readers, sizeof(fd_set) ); \
822 if ( nwriters ) { \
823 AC_MEMCPY( &writefds, &slap_daemon[t].sd_writers, sizeof(fd_set) ); \
824 } else { \
825 FD_ZERO( &writefds ); \
826 } \
827 } while (0)
828
829 # ifdef FD_SETSIZE
830 # define SLAP_SELECT_CHK_SETSIZE do { \
831 if (dtblsize > FD_SETSIZE) dtblsize = FD_SETSIZE; \
832 } while (0)
833 # else /* ! FD_SETSIZE */
834 # define SLAP_SELECT_CHK_SETSIZE do { ; } while (0)
835 # endif /* ! FD_SETSIZE */
836
837 # define SLAP_SOCK_INIT(t) do { \
838 SLAP_SELECT_CHK_SETSIZE; \
839 FD_ZERO(&slap_daemon[t].sd_actives); \
840 FD_ZERO(&slap_daemon[t].sd_readers); \
841 FD_ZERO(&slap_daemon[t].sd_writers); \
842 } while (0)
843
844 # define SLAP_SOCK_INIT2()
845
846 # define SLAP_SOCK_DESTROY(t)
847
848 # define SLAP_SOCK_IS_ACTIVE(t,fd) FD_ISSET((fd), &slap_daemon[t].sd_actives)
849 # define SLAP_SOCK_IS_READ(t,fd) FD_ISSET((fd), &slap_daemon[t].sd_readers)
850 # define SLAP_SOCK_IS_WRITE(t,fd) FD_ISSET((fd), &slap_daemon[t].sd_writers)
851
852 # define SLAP_SOCK_NOT_ACTIVE(t,fd) (!SLAP_SOCK_IS_ACTIVE(t,fd) && \
853 !SLAP_SOCK_IS_READ(t,fd) && !SLAP_SOCK_IS_WRITE(t,fd))
854
855 # define SLAP_SOCK_SET_READ(t,fd) FD_SET((fd), &slap_daemon[t].sd_readers)
856 # define SLAP_SOCK_SET_WRITE(t,fd) FD_SET((fd), &slap_daemon[t].sd_writers)
857
858 # define SLAP_EVENT_MAX(t) slap_daemon[t].sd_nfds
859 # define SLAP_SELECT_ADDTEST(t,s) do { \
860 if ((s) >= slap_daemon[t].sd_nfds) slap_daemon[t].sd_nfds = (s)+1; \
861 } while (0)
862
863 # define SLAP_SOCK_CLR_READ(t,fd) FD_CLR((fd), &slap_daemon[t].sd_readers)
864 # define SLAP_SOCK_CLR_WRITE(t,fd) FD_CLR((fd), &slap_daemon[t].sd_writers)
865
866 # define SLAP_SOCK_ADD(t,s, l) do { \
867 SLAP_SELECT_ADDTEST(t,(s)); \
868 FD_SET((s), &slap_daemon[t].sd_actives); \
869 FD_SET((s), &slap_daemon[t].sd_readers); \
870 } while (0)
871
872 # define SLAP_SOCK_DEL(t,s) do { \
873 FD_CLR((s), &slap_daemon[t].sd_actives); \
874 FD_CLR((s), &slap_daemon[t].sd_readers); \
875 FD_CLR((s), &slap_daemon[t].sd_writers); \
876 } while (0)
877
878 # define SLAP_EVENT_IS_READ(fd) FD_ISSET((fd), &readfds)
879 # define SLAP_EVENT_IS_WRITE(fd) FD_ISSET((fd), &writefds)
880
881 # define SLAP_EVENT_CLR_READ(fd) FD_CLR((fd), &readfds)
882 # define SLAP_EVENT_CLR_WRITE(fd) FD_CLR((fd), &writefds)
883
884 # define SLAP_EVENT_WAIT(t, tvp, nsp) do { \
885 *(nsp) = select( SLAP_EVENT_MAX(t), &readfds, \
886 nwriters > 0 ? &writefds : NULL, NULL, (tvp) ); \
887 } while (0)
888 # endif /* !HAVE_WINSOCK */
889 #endif /* ! kqueue && ! epoll && ! /dev/poll */
890
891 #ifdef HAVE_SLP
892 /*
893 * SLP related functions
894 */
895 #include <slp.h>
896
897 #define LDAP_SRVTYPE_PREFIX "service:ldap://"
898 #define LDAPS_SRVTYPE_PREFIX "service:ldaps://"
899 static char** slapd_srvurls = NULL;
900 static SLPHandle slapd_hslp = 0;
901 int slapd_register_slp = 0;
902 const char *slapd_slp_attrs = NULL;
903
904 static SLPError slapd_slp_cookie;
905
906 static void
slapd_slp_init(const char * urls)907 slapd_slp_init( const char* urls )
908 {
909 int i;
910 SLPError err;
911
912 slapd_srvurls = ldap_str2charray( urls, " " );
913
914 if ( slapd_srvurls == NULL ) return;
915
916 /* find and expand INADDR_ANY URLs */
917 for ( i = 0; slapd_srvurls[i] != NULL; i++ ) {
918 if ( strcmp( slapd_srvurls[i], "ldap:///" ) == 0 ) {
919 slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
920 global_host_bv.bv_len +
921 sizeof( LDAP_SRVTYPE_PREFIX ) );
922 strcpy( lutil_strcopy(slapd_srvurls[i],
923 LDAP_SRVTYPE_PREFIX ), global_host_bv.bv_val );
924 } else if ( strcmp( slapd_srvurls[i], "ldaps:///" ) == 0 ) {
925 slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
926 global_host_bv.bv_len +
927 sizeof( LDAPS_SRVTYPE_PREFIX ) );
928 strcpy( lutil_strcopy(slapd_srvurls[i],
929 LDAPS_SRVTYPE_PREFIX ), global_host_bv.bv_val );
930 }
931 }
932
933 /* open the SLP handle */
934 err = SLPOpen( "en", 0, &slapd_hslp );
935
936 if ( err != SLP_OK ) {
937 Debug( LDAP_DEBUG_CONNS, "daemon: SLPOpen() failed with %ld\n",
938 (long)err );
939 }
940 }
941
942 static void
slapd_slp_deinit(void)943 slapd_slp_deinit( void )
944 {
945 if ( slapd_srvurls == NULL ) return;
946
947 ldap_charray_free( slapd_srvurls );
948 slapd_srvurls = NULL;
949
950 /* close the SLP handle */
951 SLPClose( slapd_hslp );
952 }
953
954 static void
slapd_slp_regreport(SLPHandle hslp,SLPError errcode,void * cookie)955 slapd_slp_regreport(
956 SLPHandle hslp,
957 SLPError errcode,
958 void *cookie )
959 {
960 /* return the error code in the cookie */
961 *(SLPError*)cookie = errcode;
962 }
963
964 static void
slapd_slp_reg()965 slapd_slp_reg()
966 {
967 int i;
968 SLPError err;
969
970 if ( slapd_srvurls == NULL ) return;
971
972 for ( i = 0; slapd_srvurls[i] != NULL; i++ ) {
973 if ( strncmp( slapd_srvurls[i], LDAP_SRVTYPE_PREFIX,
974 sizeof( LDAP_SRVTYPE_PREFIX ) - 1 ) == 0 ||
975 strncmp( slapd_srvurls[i], LDAPS_SRVTYPE_PREFIX,
976 sizeof( LDAPS_SRVTYPE_PREFIX ) - 1 ) == 0 )
977 {
978 err = SLPReg( slapd_hslp,
979 slapd_srvurls[i],
980 SLP_LIFETIME_MAXIMUM,
981 "ldap",
982 (slapd_slp_attrs) ? slapd_slp_attrs : "",
983 SLP_TRUE,
984 slapd_slp_regreport,
985 &slapd_slp_cookie );
986
987 if ( err != SLP_OK || slapd_slp_cookie != SLP_OK ) {
988 Debug( LDAP_DEBUG_CONNS,
989 "daemon: SLPReg(%s) failed with %ld, cookie = %ld\n",
990 slapd_srvurls[i], (long)err, (long)slapd_slp_cookie );
991 }
992 }
993 }
994 }
995
996 static void
slapd_slp_dereg(void)997 slapd_slp_dereg( void )
998 {
999 int i;
1000 SLPError err;
1001
1002 if ( slapd_srvurls == NULL ) return;
1003
1004 for ( i = 0; slapd_srvurls[i] != NULL; i++ ) {
1005 err = SLPDereg( slapd_hslp,
1006 slapd_srvurls[i],
1007 slapd_slp_regreport,
1008 &slapd_slp_cookie );
1009
1010 if ( err != SLP_OK || slapd_slp_cookie != SLP_OK ) {
1011 Debug( LDAP_DEBUG_CONNS,
1012 "daemon: SLPDereg(%s) failed with %ld, cookie = %ld\n",
1013 slapd_srvurls[i], (long)err, (long)slapd_slp_cookie );
1014 }
1015 }
1016 }
1017 #endif /* HAVE_SLP */
1018
1019 #ifdef HAVE_WINSOCK
1020 /* Manage the descriptor to socket table */
1021 ber_socket_t
slapd_socknew(ber_socket_t s)1022 slapd_socknew( ber_socket_t s )
1023 {
1024 ber_socket_t i;
1025 ldap_pvt_thread_mutex_lock( &slapd_ws_mutex );
1026 for ( i = 0; i < dtblsize && slapd_ws_sockets[i] != INVALID_SOCKET; i++ );
1027 if ( i == dtblsize ) {
1028 WSASetLastError( WSAEMFILE );
1029 } else {
1030 slapd_ws_sockets[i] = s;
1031 }
1032 ldap_pvt_thread_mutex_unlock( &slapd_ws_mutex );
1033 return i;
1034 }
1035
1036 void
slapd_sockdel(ber_socket_t s)1037 slapd_sockdel( ber_socket_t s )
1038 {
1039 ldap_pvt_thread_mutex_lock( &slapd_ws_mutex );
1040 slapd_ws_sockets[s] = INVALID_SOCKET;
1041 ldap_pvt_thread_mutex_unlock( &slapd_ws_mutex );
1042 }
1043
1044 ber_socket_t
slapd_sock2fd(ber_socket_t s)1045 slapd_sock2fd( ber_socket_t s )
1046 {
1047 ber_socket_t i;
1048 for ( i=0; i<dtblsize && slapd_ws_sockets[i] != s; i++);
1049 if ( i == dtblsize )
1050 i = -1;
1051 return i;
1052 }
1053 #endif
1054
1055 #ifdef DEBUG_CLOSE
1056 /* Was used to find a bug causing slapd's descriptors to be closed
1057 * out from under it. Tracked it down to a long-standing (from 2009)
1058 * bug in Heimdal https://github.com/heimdal/heimdal/issues/431 .
1059 * Leaving this here for future use, if necessary.
1060 */
1061 #include <dlfcn.h>
1062 #ifndef RTLD_NEXT
1063 #define RTLD_NEXT (void *)-1L
1064 #endif
1065 static char *newconns;
1066 typedef int (closefunc)(int fd);
1067 static closefunc *close_ptr;
close(int s)1068 int close( int s )
1069 {
1070 if (newconns) {
1071 Debug( LDAP_DEBUG_CONNS,
1072 "daemon: close(%d)\n", s );
1073 if (s >= 0 && s < dtblsize && newconns[s])
1074 assert(newconns[s] == 2);
1075 }
1076 return close_ptr ? close_ptr(s) : -1;
1077 }
1078
slapd_debug_close()1079 void slapd_debug_close()
1080 {
1081 if (dtblsize)
1082 newconns = ch_calloc(1, dtblsize);
1083 close_ptr = dlsym(RTLD_NEXT, "close");
1084 }
1085
slapd_set_close(int fd)1086 void slapd_set_close(int fd)
1087 {
1088 newconns[fd] = 3;
1089 }
1090 #define SETUP_CLOSE() slapd_debug_close()
1091 #define SET_CLOSE(fd) slapd_set_close(fd)
1092 #define CLR_CLOSE(fd) if (newconns[fd]) newconns[fd]--
1093 #else
1094 #define SETUP_CLOSE(fd)
1095 #define SET_CLOSE(fd)
1096 #define CLR_CLOSE(fd)
1097 #endif
1098
1099 /*
1100 * Add a descriptor to daemon control
1101 *
1102 * If isactive, the descriptor is a live server session and is subject
1103 * to idletimeout control. Otherwise, the descriptor is a passive
1104 * listener or an outbound client session, and not subject to
1105 * idletimeout. The underlying event handler may record the Listener
1106 * argument to differentiate Listener's from real sessions.
1107 */
1108 static void
slapd_add(ber_socket_t s,int isactive,Listener * sl,int id)1109 slapd_add( ber_socket_t s, int isactive, Listener *sl, int id )
1110 {
1111 if (id < 0)
1112 id = DAEMON_ID(s);
1113 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1114
1115 assert( SLAP_SOCK_NOT_ACTIVE(id, s) );
1116
1117 if ( isactive ) slap_daemon[id].sd_nactives++;
1118
1119 SLAP_SOCK_ADD(id, s, sl);
1120
1121 Debug( LDAP_DEBUG_CONNS, "daemon: added %ldr%s listener=%p\n",
1122 (long) s, isactive ? " (active)" : "", (void *)sl );
1123
1124 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1125
1126 WAKE_LISTENER(id,1);
1127 }
1128
1129 /*
1130 * Remove the descriptor from daemon control
1131 */
1132 void
slapd_remove(ber_socket_t s,Sockbuf * sb,int wasactive,int wake,int locked)1133 slapd_remove(
1134 ber_socket_t s,
1135 Sockbuf *sb,
1136 int wasactive,
1137 int wake,
1138 int locked )
1139 {
1140 int waswriter;
1141 int wasreader;
1142 int id = DAEMON_ID(s);
1143
1144 if ( !locked )
1145 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1146
1147 assert( SLAP_SOCK_IS_ACTIVE( id, s ));
1148
1149 if ( wasactive ) slap_daemon[id].sd_nactives--;
1150
1151 waswriter = SLAP_SOCK_IS_WRITE(id, s);
1152 wasreader = SLAP_SOCK_IS_READ(id, s);
1153
1154 Debug( LDAP_DEBUG_CONNS, "daemon: removing %ld%s%s\n",
1155 (long) s,
1156 wasreader ? "r" : "",
1157 waswriter ? "w" : "" );
1158
1159 if ( waswriter ) slap_daemon[id].sd_nwriters--;
1160
1161 SLAP_SOCK_DEL(id, s);
1162 CLR_CLOSE(s);
1163
1164 if ( sb )
1165 ber_sockbuf_free(sb);
1166
1167 /* If we ran out of file descriptors, we dropped a listener from
1168 * the select() loop. Now that we're removing a session from our
1169 * control, we can try to resume a dropped listener to use.
1170 */
1171 ldap_pvt_thread_mutex_lock( &emfile_mutex );
1172 if ( emfile && listening ) {
1173 int i;
1174 for ( i = 0; slap_listeners[i] != NULL; i++ ) {
1175 Listener *lr = slap_listeners[i];
1176
1177 if ( lr->sl_sd == AC_SOCKET_INVALID ) continue;
1178 if ( lr->sl_sd == s ) continue;
1179 if ( lr->sl_mute ) {
1180 lr->sl_mute = 0;
1181 emfile--;
1182 if ( DAEMON_ID(lr->sl_sd) != id )
1183 WAKE_LISTENER(DAEMON_ID(lr->sl_sd), wake);
1184 break;
1185 }
1186 }
1187 /* Walked the entire list without enabling anything; emfile
1188 * counter is stale. Reset it.
1189 */
1190 if ( slap_listeners[i] == NULL ) emfile = 0;
1191 }
1192 ldap_pvt_thread_mutex_unlock( &emfile_mutex );
1193 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1194 WAKE_LISTENER(id, wake || slapd_gentle_shutdown == 2);
1195 }
1196
1197 void
slapd_clr_write(ber_socket_t s,int wake)1198 slapd_clr_write( ber_socket_t s, int wake )
1199 {
1200 int id = DAEMON_ID(s);
1201 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1202
1203 if ( SLAP_SOCK_IS_WRITE( id, s )) {
1204 assert( SLAP_SOCK_IS_ACTIVE( id, s ));
1205
1206 SLAP_SOCK_CLR_WRITE( id, s );
1207 slap_daemon[id].sd_nwriters--;
1208 }
1209
1210 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1211 WAKE_LISTENER(id,wake);
1212 }
1213
1214 void
slapd_set_write(ber_socket_t s,int wake)1215 slapd_set_write( ber_socket_t s, int wake )
1216 {
1217 int id = DAEMON_ID(s);
1218 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1219
1220 assert( SLAP_SOCK_IS_ACTIVE( id, s ));
1221
1222 if ( !SLAP_SOCK_IS_WRITE( id, s )) {
1223 SLAP_SOCK_SET_WRITE( id, s );
1224 slap_daemon[id].sd_nwriters++;
1225 }
1226
1227 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1228 WAKE_LISTENER(id,wake);
1229 }
1230
1231 int
slapd_clr_read(ber_socket_t s,int wake)1232 slapd_clr_read( ber_socket_t s, int wake )
1233 {
1234 int rc = 1;
1235 int id = DAEMON_ID(s);
1236 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1237
1238 if ( SLAP_SOCK_IS_ACTIVE( id, s )) {
1239 SLAP_SOCK_CLR_READ( id, s );
1240 rc = 0;
1241 }
1242 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1243 if ( !rc )
1244 WAKE_LISTENER(id,wake);
1245 return rc;
1246 }
1247
1248 void
slapd_set_read(ber_socket_t s,int wake)1249 slapd_set_read( ber_socket_t s, int wake )
1250 {
1251 int do_wake = 1;
1252 int id = DAEMON_ID(s);
1253 ldap_pvt_thread_mutex_lock( &slap_daemon[id].sd_mutex );
1254
1255 if( SLAP_SOCK_IS_ACTIVE( id, s ) && !SLAP_SOCK_IS_READ( id, s )) {
1256 SLAP_SOCK_SET_READ( id, s );
1257 } else {
1258 do_wake = 0;
1259 }
1260 ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex );
1261 if ( do_wake )
1262 WAKE_LISTENER(id,wake);
1263 }
1264
1265 static void
slapd_close(ber_socket_t s)1266 slapd_close( ber_socket_t s )
1267 {
1268 Debug( LDAP_DEBUG_CONNS, "daemon: closing %ld\n",
1269 (long) s );
1270 CLR_CLOSE( SLAP_FD2SOCK(s) );
1271 tcp_close( SLAP_FD2SOCK(s) );
1272 #ifdef HAVE_WINSOCK
1273 slapd_sockdel( s );
1274 #endif
1275 }
1276
1277 void
slapd_shutsock(ber_socket_t s)1278 slapd_shutsock( ber_socket_t s )
1279 {
1280 Debug( LDAP_DEBUG_CONNS, "daemon: shutdown socket %ld\n",
1281 (long) s );
1282 shutdown( SLAP_FD2SOCK(s), 2 );
1283 }
1284
1285 static void
slap_free_listener_addresses(struct sockaddr ** sal)1286 slap_free_listener_addresses( struct sockaddr **sal )
1287 {
1288 struct sockaddr **sap;
1289 if (sal == NULL) return;
1290 for (sap = sal; *sap != NULL; sap++) ch_free(*sap);
1291 ch_free(sal);
1292 }
1293
1294 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
1295 static int
get_url_perms(char ** exts,mode_t * perms,int * crit)1296 get_url_perms(
1297 char **exts,
1298 mode_t *perms,
1299 int *crit )
1300 {
1301 int i;
1302
1303 assert( exts != NULL );
1304 assert( perms != NULL );
1305 assert( crit != NULL );
1306
1307 *crit = 0;
1308 for ( i = 0; exts[ i ]; i++ ) {
1309 char *type = exts[ i ];
1310 int c = 0;
1311
1312 if ( type[ 0 ] == '!' ) {
1313 c = 1;
1314 type++;
1315 }
1316
1317 if ( strncasecmp( type, LDAPI_MOD_URLEXT "=",
1318 sizeof(LDAPI_MOD_URLEXT "=") - 1 ) == 0 )
1319 {
1320 char *value = type + ( sizeof(LDAPI_MOD_URLEXT "=") - 1 );
1321 mode_t p = 0;
1322 int j;
1323
1324 switch (strlen(value)) {
1325 case 4:
1326 /* skip leading '0' */
1327 if ( value[ 0 ] != '0' ) return LDAP_OTHER;
1328 value++;
1329
1330 case 3:
1331 for ( j = 0; j < 3; j++) {
1332 int v;
1333
1334 v = value[ j ] - '0';
1335
1336 if ( v < 0 || v > 7 ) return LDAP_OTHER;
1337
1338 p |= v << 3*(2-j);
1339 }
1340 break;
1341
1342 case 10:
1343 for ( j = 1; j < 10; j++ ) {
1344 static mode_t m[] = { 0,
1345 S_IRUSR, S_IWUSR, S_IXUSR,
1346 S_IRGRP, S_IWGRP, S_IXGRP,
1347 S_IROTH, S_IWOTH, S_IXOTH
1348 };
1349 static const char c[] = "-rwxrwxrwx";
1350
1351 if ( value[ j ] == c[ j ] ) {
1352 p |= m[ j ];
1353
1354 } else if ( value[ j ] != '-' ) {
1355 return LDAP_OTHER;
1356 }
1357 }
1358 break;
1359
1360 default:
1361 return LDAP_OTHER;
1362 }
1363
1364 *crit = c;
1365 *perms = p;
1366
1367 return LDAP_SUCCESS;
1368 }
1369 }
1370
1371 return LDAP_OTHER;
1372 }
1373 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
1374
1375 /* port = 0 indicates AF_LOCAL */
1376 static int
slap_get_listener_addresses(const char * host,unsigned short port,struct sockaddr *** sal)1377 slap_get_listener_addresses(
1378 const char *host,
1379 unsigned short port,
1380 struct sockaddr ***sal )
1381 {
1382 struct sockaddr **sap;
1383
1384 #ifdef LDAP_PF_LOCAL
1385 if ( port == 0 ) {
1386 sap = *sal = ch_malloc(2 * sizeof(void *));
1387
1388 *sap = ch_malloc(sizeof(struct sockaddr_un));
1389 sap[1] = NULL;
1390
1391 if ( strlen(host) >
1392 (sizeof(((struct sockaddr_un *)*sap)->sun_path) - 1) )
1393 {
1394 Debug( LDAP_DEBUG_ANY,
1395 "daemon: domain socket path (%s) too long in URL",
1396 host );
1397 goto errexit;
1398 }
1399
1400 (void)memset( (void *)*sap, '\0', sizeof(struct sockaddr_un) );
1401 (*sap)->sa_family = AF_LOCAL;
1402 strcpy( ((struct sockaddr_un *)*sap)->sun_path, host );
1403 } else
1404 #endif /* LDAP_PF_LOCAL */
1405 {
1406 #ifdef HAVE_GETADDRINFO
1407 struct addrinfo hints, *res, *sai;
1408 int n, err;
1409 char serv[7];
1410
1411 memset( &hints, '\0', sizeof(hints) );
1412 hints.ai_flags = AI_PASSIVE;
1413 hints.ai_socktype = SOCK_STREAM;
1414 hints.ai_family = slap_inet4or6;
1415 snprintf(serv, sizeof serv, "%d", port);
1416
1417 if ( (err = getaddrinfo(host, serv, &hints, &res)) ) {
1418 Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo() failed: %s\n",
1419 AC_GAI_STRERROR(err) );
1420 return -1;
1421 }
1422
1423 sai = res;
1424 for (n=2; (sai = sai->ai_next) != NULL; n++) {
1425 /* EMPTY */ ;
1426 }
1427 sap = *sal = ch_calloc(n, sizeof(void *));
1428 *sap = NULL;
1429
1430 for ( sai=res; sai; sai=sai->ai_next ) {
1431 if( sai->ai_addr == NULL ) {
1432 Debug( LDAP_DEBUG_ANY, "slap_get_listener_addresses: "
1433 "getaddrinfo ai_addr is NULL?\n" );
1434 freeaddrinfo(res);
1435 goto errexit;
1436 }
1437
1438 switch (sai->ai_family) {
1439 # ifdef LDAP_PF_INET6
1440 case AF_INET6:
1441 *sap = ch_malloc(sizeof(struct sockaddr_in6));
1442 *(struct sockaddr_in6 *)*sap =
1443 *((struct sockaddr_in6 *)sai->ai_addr);
1444 break;
1445 # endif /* LDAP_PF_INET6 */
1446 case AF_INET:
1447 *sap = ch_malloc(sizeof(struct sockaddr_in));
1448 *(struct sockaddr_in *)*sap =
1449 *((struct sockaddr_in *)sai->ai_addr);
1450 break;
1451 default:
1452 *sap = NULL;
1453 break;
1454 }
1455
1456 if (*sap != NULL) {
1457 (*sap)->sa_family = sai->ai_family;
1458 sap++;
1459 *sap = NULL;
1460 }
1461 }
1462
1463 freeaddrinfo(res);
1464
1465 #else /* ! HAVE_GETADDRINFO */
1466 int i, n = 1;
1467 struct in_addr in;
1468 struct hostent *he = NULL;
1469
1470 if ( host == NULL ) {
1471 in.s_addr = htonl(INADDR_ANY);
1472
1473 } else if ( !inet_aton( host, &in ) ) {
1474 he = gethostbyname( host );
1475 if( he == NULL ) {
1476 Debug( LDAP_DEBUG_ANY,
1477 "daemon: invalid host %s", host );
1478 return -1;
1479 }
1480 for (n = 0; he->h_addr_list[n]; n++) /* empty */;
1481 }
1482
1483 sap = *sal = ch_malloc((n+1) * sizeof(void *));
1484
1485 for ( i = 0; i<n; i++ ) {
1486 sap[i] = ch_calloc(1, sizeof(struct sockaddr_in));
1487 sap[i]->sa_family = AF_INET;
1488 ((struct sockaddr_in *)sap[i])->sin_port = htons(port);
1489 AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr,
1490 he ? (struct in_addr *)he->h_addr_list[i] : &in,
1491 sizeof(struct in_addr) );
1492 }
1493 sap[i] = NULL;
1494 #endif /* ! HAVE_GETADDRINFO */
1495 }
1496
1497 return 0;
1498
1499 errexit:
1500 slap_free_listener_addresses(*sal);
1501 return -1;
1502 }
1503
1504 static int
slap_open_listener(const char * url,int * listeners,int * cur)1505 slap_open_listener(
1506 const char* url,
1507 int *listeners,
1508 int *cur )
1509 {
1510 int num, tmp, rc;
1511 Listener l;
1512 Listener *li;
1513 LDAPURLDesc *lud;
1514 unsigned short port;
1515 int err, addrlen = 0;
1516 struct sockaddr **sal = NULL, **psal;
1517 int socktype = SOCK_STREAM; /* default to COTS */
1518 ber_socket_t s;
1519 char ebuf[128];
1520
1521 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
1522 /*
1523 * use safe defaults
1524 */
1525 int crit = 1;
1526 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
1527
1528 rc = ldap_url_parse( url, &lud );
1529
1530 if( rc != LDAP_URL_SUCCESS ) {
1531 Debug( LDAP_DEBUG_ANY,
1532 "daemon: listen URL \"%s\" parse error=%d\n",
1533 url, rc );
1534 return rc;
1535 }
1536
1537 l.sl_url.bv_val = NULL;
1538 l.sl_mute = 0;
1539 l.sl_busy = 0;
1540
1541 #ifndef HAVE_TLS
1542 if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) {
1543 Debug( LDAP_DEBUG_ANY, "daemon: TLS not supported (%s)\n",
1544 url );
1545 ldap_free_urldesc( lud );
1546 return -1;
1547 }
1548
1549 if(! lud->lud_port ) lud->lud_port = LDAP_PORT;
1550
1551 #else /* HAVE_TLS */
1552 l.sl_is_tls = ldap_pvt_url_scheme2tls( lud->lud_scheme );
1553
1554 if(! lud->lud_port ) {
1555 lud->lud_port = l.sl_is_tls ? LDAPS_PORT : LDAP_PORT;
1556 }
1557 #endif /* HAVE_TLS */
1558
1559 l.sl_is_proxied = ldap_pvt_url_scheme2proxied( lud->lud_scheme );
1560
1561 #ifdef LDAP_TCP_BUFFER
1562 l.sl_tcp_rmem = 0;
1563 l.sl_tcp_wmem = 0;
1564 #endif /* LDAP_TCP_BUFFER */
1565
1566 port = (unsigned short) lud->lud_port;
1567
1568 tmp = ldap_pvt_url_scheme2proto(lud->lud_scheme);
1569 if ( tmp == LDAP_PROTO_IPC ) {
1570 #ifdef LDAP_PF_LOCAL
1571 if ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) {
1572 err = slap_get_listener_addresses(LDAPI_SOCK, 0, &sal);
1573 } else {
1574 err = slap_get_listener_addresses(lud->lud_host, 0, &sal);
1575 }
1576 #else /* ! LDAP_PF_LOCAL */
1577
1578 Debug( LDAP_DEBUG_ANY, "daemon: URL scheme not supported: %s",
1579 url );
1580 ldap_free_urldesc( lud );
1581 return -1;
1582 #endif /* ! LDAP_PF_LOCAL */
1583 } else {
1584 if( lud->lud_host == NULL || lud->lud_host[0] == '\0'
1585 || strcmp(lud->lud_host, "*") == 0 )
1586 {
1587 err = slap_get_listener_addresses(NULL, port, &sal);
1588 } else {
1589 err = slap_get_listener_addresses(lud->lud_host, port, &sal);
1590 }
1591 }
1592
1593 #ifdef LDAP_CONNECTIONLESS
1594 l.sl_is_udp = ( tmp == LDAP_PROTO_UDP );
1595 #endif /* LDAP_CONNECTIONLESS */
1596
1597 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
1598 if ( lud->lud_exts ) {
1599 err = get_url_perms( lud->lud_exts, &l.sl_perms, &crit );
1600 } else {
1601 l.sl_perms = S_IRWXU | S_IRWXO;
1602 }
1603 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
1604
1605 if ( lud->lud_dn && lud->lud_dn[0] ) {
1606 sprintf( (char *)url, "%s://%s/", lud->lud_scheme, lud->lud_host );
1607 Debug( LDAP_DEBUG_ANY, "daemon: listener URL %s<junk> DN must be absent (%s)\n",
1608 url, lud->lud_dn );
1609 ldap_free_urldesc( lud );
1610 return -1;
1611 }
1612
1613 ldap_free_urldesc( lud );
1614 if ( err ) {
1615 slap_free_listener_addresses(sal);
1616 return -1;
1617 }
1618
1619 /* If we got more than one address returned, we need to make space
1620 * for it in the slap_listeners array.
1621 */
1622 for ( num=0; sal[num]; num++ ) /* empty */;
1623 if ( num > 1 ) {
1624 *listeners += num-1;
1625 slap_listeners = ch_realloc( slap_listeners,
1626 (*listeners + 1) * sizeof(Listener *) );
1627 }
1628
1629 psal = sal;
1630 while ( *sal != NULL ) {
1631 char *af;
1632 switch( (*sal)->sa_family ) {
1633 case AF_INET:
1634 af = "IPv4";
1635 break;
1636 #ifdef LDAP_PF_INET6
1637 case AF_INET6:
1638 af = "IPv6";
1639 break;
1640 #endif /* LDAP_PF_INET6 */
1641 #ifdef LDAP_PF_LOCAL
1642 case AF_LOCAL:
1643 af = "Local";
1644 break;
1645 #endif /* LDAP_PF_LOCAL */
1646 default:
1647 sal++;
1648 continue;
1649 }
1650
1651 #ifdef LDAP_CONNECTIONLESS
1652 if( l.sl_is_udp ) socktype = SOCK_DGRAM;
1653 #endif /* LDAP_CONNECTIONLESS */
1654
1655 s = socket( (*sal)->sa_family, socktype, 0);
1656 if ( s == AC_SOCKET_INVALID ) {
1657 int err = sock_errno();
1658 Debug( LDAP_DEBUG_ANY,
1659 "daemon: %s socket() failed errno=%d (%s)\n",
1660 af, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
1661 sal++;
1662 continue;
1663 }
1664 l.sl_sd = SLAP_SOCKNEW( s );
1665
1666 if ( l.sl_sd >= dtblsize ) {
1667 Debug( LDAP_DEBUG_ANY,
1668 "daemon: listener descriptor %ld is too great %ld\n",
1669 (long) l.sl_sd, (long) dtblsize );
1670 tcp_close( s );
1671 sal++;
1672 continue;
1673 }
1674
1675 #ifdef LDAP_PF_LOCAL
1676 if ( (*sal)->sa_family == AF_LOCAL ) {
1677 unlink( ((struct sockaddr_un *)*sal)->sun_path );
1678 } else
1679 #endif /* LDAP_PF_LOCAL */
1680 {
1681 #ifdef SO_REUSEADDR
1682 /* enable address reuse */
1683 tmp = 1;
1684 rc = setsockopt( s, SOL_SOCKET, SO_REUSEADDR,
1685 (char *) &tmp, sizeof(tmp) );
1686 if ( rc == AC_SOCKET_ERROR ) {
1687 int err = sock_errno();
1688 Debug( LDAP_DEBUG_ANY, "slapd(%ld): "
1689 "setsockopt(SO_REUSEADDR) failed errno=%d (%s)\n",
1690 (long) l.sl_sd, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
1691 }
1692 #endif /* SO_REUSEADDR */
1693 }
1694
1695 switch( (*sal)->sa_family ) {
1696 case AF_INET:
1697 addrlen = sizeof(struct sockaddr_in);
1698 break;
1699 #ifdef LDAP_PF_INET6
1700 case AF_INET6:
1701 #ifdef IPV6_V6ONLY
1702 /* Try to use IPv6 sockets for IPv6 only */
1703 tmp = 1;
1704 rc = setsockopt( s , IPPROTO_IPV6, IPV6_V6ONLY,
1705 (char *) &tmp, sizeof(tmp) );
1706 if ( rc == AC_SOCKET_ERROR ) {
1707 int err = sock_errno();
1708 Debug( LDAP_DEBUG_ANY, "slapd(%ld): "
1709 "setsockopt(IPV6_V6ONLY) failed errno=%d (%s)\n",
1710 (long) l.sl_sd, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
1711 }
1712 #endif /* IPV6_V6ONLY */
1713 addrlen = sizeof(struct sockaddr_in6);
1714 break;
1715 #endif /* LDAP_PF_INET6 */
1716
1717 #ifdef LDAP_PF_LOCAL
1718 case AF_LOCAL:
1719 #ifdef LOCAL_CREDS
1720 {
1721 int one = 1;
1722 setsockopt( s, 0, LOCAL_CREDS, &one, sizeof( one ) );
1723 }
1724 #endif /* LOCAL_CREDS */
1725
1726 addrlen = sizeof( struct sockaddr_un );
1727 break;
1728 #endif /* LDAP_PF_LOCAL */
1729 }
1730
1731 #ifdef LDAP_PF_LOCAL
1732 /* create socket with all permissions set for those systems
1733 * that honor permissions on sockets (e.g. Linux); typically,
1734 * only write is required. To exploit filesystem permissions,
1735 * place the socket in a directory and use directory's
1736 * permissions. Need write perms to the directory to
1737 * create/unlink the socket; likely need exec perms to access
1738 * the socket (ITS#4709) */
1739 {
1740 mode_t old_umask = 0;
1741
1742 if ( (*sal)->sa_family == AF_LOCAL ) {
1743 old_umask = umask( 0 );
1744 }
1745 #endif /* LDAP_PF_LOCAL */
1746 rc = bind( s, *sal, addrlen );
1747 #ifdef LDAP_PF_LOCAL
1748 if ( old_umask != 0 ) {
1749 umask( old_umask );
1750 }
1751 }
1752 #endif /* LDAP_PF_LOCAL */
1753 if ( rc ) {
1754 err = sock_errno();
1755 Debug( LDAP_DEBUG_ANY,
1756 "daemon: bind(%ld) failed errno=%d (%s)\n",
1757 (long)l.sl_sd, err, sock_errstr( err, ebuf, sizeof(ebuf) ) );
1758 tcp_close( s );
1759 sal++;
1760 continue;
1761 }
1762
1763 switch ( (*sal)->sa_family ) {
1764 #ifdef LDAP_PF_LOCAL
1765 case AF_LOCAL: {
1766 char *path = ((struct sockaddr_un *)*sal)->sun_path;
1767 l.sl_name.bv_len = strlen(path) + STRLENOF("PATH=");
1768 l.sl_name.bv_val = ch_malloc( l.sl_name.bv_len + 1 );
1769 snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1,
1770 "PATH=%s", path );
1771 } break;
1772 #endif /* LDAP_PF_LOCAL */
1773
1774 case AF_INET: {
1775 char addr[INET_ADDRSTRLEN];
1776 const char *s;
1777 #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
1778 s = inet_ntop( AF_INET, &((struct sockaddr_in *)*sal)->sin_addr,
1779 addr, sizeof(addr) );
1780 #else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
1781 s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr );
1782 #endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
1783 if (!s) s = SLAP_STRING_UNKNOWN;
1784 port = ntohs( ((struct sockaddr_in *)*sal) ->sin_port );
1785 l.sl_name.bv_val =
1786 ch_malloc( sizeof("IP=255.255.255.255:65535") );
1787 snprintf( l.sl_name.bv_val, sizeof("IP=255.255.255.255:65535"),
1788 "IP=%s:%d", s, port );
1789 l.sl_name.bv_len = strlen( l.sl_name.bv_val );
1790 } break;
1791
1792 #ifdef LDAP_PF_INET6
1793 case AF_INET6: {
1794 char addr[INET6_ADDRSTRLEN];
1795 const char *s;
1796 s = inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr,
1797 addr, sizeof addr);
1798 if (!s) s = SLAP_STRING_UNKNOWN;
1799 port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
1800 l.sl_name.bv_len = strlen(s) + sizeof("IP=[]:65535");
1801 l.sl_name.bv_val = ch_malloc( l.sl_name.bv_len );
1802 snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=[%s]:%d",
1803 s, port );
1804 l.sl_name.bv_len = strlen( l.sl_name.bv_val );
1805 } break;
1806 #endif /* LDAP_PF_INET6 */
1807
1808 default:
1809 Debug( LDAP_DEBUG_ANY, "daemon: unsupported address family (%d)\n",
1810 (int) (*sal)->sa_family );
1811 break;
1812 }
1813
1814 AC_MEMCPY(&l.sl_sa, *sal, addrlen);
1815 ber_str2bv( url, 0, 1, &l.sl_url);
1816 li = ch_malloc( sizeof( Listener ) );
1817 *li = l;
1818 slap_listeners[*cur] = li;
1819 (*cur)++;
1820 sal++;
1821 }
1822
1823 slap_free_listener_addresses(psal);
1824
1825 if ( l.sl_url.bv_val == NULL ) {
1826 Debug( LDAP_DEBUG_TRACE,
1827 "slap_open_listener: failed on %s\n", url );
1828 return -1;
1829 }
1830
1831 Debug( LDAP_DEBUG_TRACE, "daemon: listener initialized %s\n",
1832 l.sl_url.bv_val );
1833 return 0;
1834 }
1835
1836 static int sockinit(void);
1837 static int sockdestroy(void);
1838
1839 static int daemon_inited = 0;
1840
1841 int
slapd_daemon_init(const char * urls)1842 slapd_daemon_init( const char *urls )
1843 {
1844 int i, j, n, rc;
1845 char **u;
1846
1847 Debug( LDAP_DEBUG_ARGS, "daemon_init: %s\n",
1848 urls ? urls : "<null>" );
1849
1850 wake_sds = ch_malloc( slapd_daemon_threads * sizeof( sdpair ));
1851 for ( i=0; i<slapd_daemon_threads; i++ ) {
1852 wake_sds[i][0] = AC_SOCKET_INVALID;
1853 wake_sds[i][1] = AC_SOCKET_INVALID;
1854 }
1855
1856 slap_daemon = ch_calloc( slapd_daemon_threads, sizeof( slap_daemon_st ));
1857 ldap_pvt_thread_mutex_init( &slap_daemon[0].sd_mutex );
1858 #ifdef HAVE_TCPD
1859 ldap_pvt_thread_mutex_init( &sd_tcpd_mutex );
1860 #endif /* TCP Wrappers */
1861 ldap_pvt_thread_mutex_init( &emfile_mutex );
1862
1863 daemon_inited = 1;
1864
1865 if( (rc = sockinit()) != 0 ) return rc;
1866
1867 #ifdef HAVE_SYSCONF
1868 dtblsize = sysconf( _SC_OPEN_MAX );
1869 #elif defined(HAVE_GETDTABLESIZE)
1870 dtblsize = getdtablesize();
1871 #else /* ! HAVE_SYSCONF && ! HAVE_GETDTABLESIZE */
1872 dtblsize = FD_SETSIZE;
1873 #endif /* ! HAVE_SYSCONF && ! HAVE_GETDTABLESIZE */
1874
1875 SETUP_CLOSE();
1876
1877 /* open a pipe (or something equivalent connected to itself).
1878 * we write a byte on this fd whenever we catch a signal. The main
1879 * loop will be select'ing on this socket, and will wake up when
1880 * this byte arrives.
1881 */
1882 if( (rc = lutil_pair( wake_sds[0] )) < 0 ) {
1883 Debug( LDAP_DEBUG_ANY,
1884 "daemon: lutil_pair() failed rc=%d\n", rc );
1885 return rc;
1886 }
1887 ber_pvt_socket_set_nonblock( wake_sds[0][1], 1 );
1888
1889 SLAP_SOCK_INIT(0);
1890
1891 if( urls == NULL ) urls = "ldap:///";
1892
1893 u = ldap_str2charray( urls, " " );
1894
1895 if( u == NULL || u[0] == NULL ) {
1896 Debug( LDAP_DEBUG_ANY, "daemon_init: no urls (%s) provided.\n",
1897 urls );
1898 if ( u )
1899 ldap_charray_free( u );
1900 return -1;
1901 }
1902
1903 for( i=0; u[i] != NULL; i++ ) {
1904 Debug( LDAP_DEBUG_TRACE, "daemon_init: listen on %s\n",
1905 u[i] );
1906 }
1907
1908 if( i == 0 ) {
1909 Debug( LDAP_DEBUG_ANY, "daemon_init: no listeners to open (%s)\n",
1910 urls );
1911 ldap_charray_free( u );
1912 return -1;
1913 }
1914
1915 Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners to open...\n",
1916 i );
1917 slap_listeners = ch_malloc( (i+1)*sizeof(Listener *) );
1918
1919 for(n = 0, j = 0; u[n]; n++ ) {
1920 if ( slap_open_listener( u[n], &i, &j ) ) {
1921 ldap_charray_free( u );
1922 return -1;
1923 }
1924 }
1925 slap_listeners[j] = NULL;
1926
1927 Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners opened\n",
1928 i );
1929
1930
1931 #ifdef HAVE_SLP
1932 if( slapd_register_slp ) {
1933 slapd_slp_init( urls );
1934 slapd_slp_reg();
1935 }
1936 #endif /* HAVE_SLP */
1937
1938 ldap_charray_free( u );
1939
1940 return !i;
1941 }
1942
1943 /* transfer control of active sockets from old to new listener threads */
1944 static void
slapd_socket_realloc(int newnum)1945 slapd_socket_realloc( int newnum )
1946 {
1947 int i, j, oldid, newid;
1948 int newmask = newnum - 1;
1949 Listener *sl;
1950 int num_listeners;
1951
1952 for ( i=0; slap_listeners[i] != NULL; i++ ) ;
1953 num_listeners = i;
1954
1955 for ( i=0; i<dtblsize; i++ ) {
1956 int skip = 0;
1957
1958 /* don't bother with wake_sds, they're assigned independent of mask */
1959 for (j=0; j<slapd_daemon_threads; j++) {
1960 if ( i == wake_sds[j][0] || i == wake_sds[j][1] ) {
1961 skip = 1;
1962 break;
1963 }
1964 }
1965 if ( skip ) continue;
1966
1967 oldid = DAEMON_ID(i);
1968 newid = i & newmask;
1969 if ( oldid == newid ) continue;
1970 if ( !SLAP_SOCK_IS_ACTIVE( oldid, i )) continue;
1971 sl = NULL;
1972 if ( num_listeners ) {
1973 for ( j=0; slap_listeners[j] != NULL; j++ ) {
1974 if ( slap_listeners[j]->sl_sd == i ) {
1975 sl = slap_listeners[j];
1976 num_listeners--;
1977 break;
1978 }
1979 }
1980 }
1981 SLAP_SOCK_ADD( newid, i, sl );
1982 if ( SLAP_SOCK_IS_READ( oldid, i )) {
1983 SLAP_SOCK_SET_READ( newid, i );
1984 }
1985 if ( SLAP_SOCK_IS_WRITE( oldid, i )) {
1986 SLAP_SOCK_SET_WRITE( newid, i );
1987 slap_daemon[oldid].sd_nwriters--;
1988 slap_daemon[newid].sd_nwriters++;
1989 }
1990 if ( connection_is_active( i )) {
1991 slap_daemon[oldid].sd_nactives--;
1992 slap_daemon[newid].sd_nactives++;
1993 }
1994 SLAP_SOCK_DEL( oldid, i );
1995 }
1996 }
1997
1998
1999 int
slapd_daemon_destroy(void)2000 slapd_daemon_destroy( void )
2001 {
2002 connections_destroy();
2003 if ( daemon_inited ) {
2004 int i;
2005
2006 for ( i=0; i<slapd_daemon_threads; i++ ) {
2007 #ifdef HAVE_WINSOCK
2008 if ( wake_sds[i][1] != INVALID_SOCKET &&
2009 SLAP_FD2SOCK( wake_sds[i][1] ) != SLAP_FD2SOCK( wake_sds[i][0] ))
2010 #endif /* HAVE_WINSOCK */
2011 tcp_close( SLAP_FD2SOCK(wake_sds[i][1]) );
2012 #ifdef HAVE_WINSOCK
2013 if ( wake_sds[i][0] != INVALID_SOCKET )
2014 #endif /* HAVE_WINSOCK */
2015 tcp_close( SLAP_FD2SOCK(wake_sds[i][0]) );
2016 ldap_pvt_thread_mutex_destroy( &slap_daemon[i].sd_mutex );
2017 SLAP_SOCK_DESTROY(i);
2018 }
2019 daemon_inited = 0;
2020 ldap_pvt_thread_mutex_destroy( &emfile_mutex );
2021 #ifdef HAVE_TCPD
2022 ldap_pvt_thread_mutex_destroy( &sd_tcpd_mutex );
2023 #endif /* TCP Wrappers */
2024 }
2025 sockdestroy();
2026
2027 #ifdef HAVE_SLP
2028 if( slapd_register_slp ) {
2029 slapd_slp_dereg();
2030 slapd_slp_deinit();
2031 }
2032 #endif /* HAVE_SLP */
2033
2034 return 0;
2035 }
2036
2037
2038 static void
close_listeners(int remove)2039 close_listeners(
2040 int remove )
2041 {
2042 int l;
2043
2044 if ( !listening )
2045 return;
2046 listening = 0;
2047
2048 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
2049 Listener *lr = slap_listeners[l];
2050
2051 if ( lr->sl_sd != AC_SOCKET_INVALID ) {
2052 int s = lr->sl_sd;
2053 lr->sl_sd = AC_SOCKET_INVALID;
2054 if ( remove ) slapd_remove( s, NULL, 0, 0, 0 );
2055
2056 #ifdef LDAP_PF_LOCAL
2057 if ( lr->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
2058 unlink( lr->sl_sa.sa_un_addr.sun_path );
2059 }
2060 #endif /* LDAP_PF_LOCAL */
2061
2062 slapd_close( s );
2063 }
2064 }
2065 }
2066
2067 static void
destroy_listeners(void)2068 destroy_listeners( void )
2069 {
2070 Listener *lr, **ll = slap_listeners;
2071
2072 if ( ll == NULL )
2073 return;
2074
2075 while ( (lr = *ll++) != NULL ) {
2076 if ( lr->sl_url.bv_val ) {
2077 ber_memfree( lr->sl_url.bv_val );
2078 }
2079
2080 if ( lr->sl_name.bv_val ) {
2081 ber_memfree( lr->sl_name.bv_val );
2082 }
2083
2084 free( lr );
2085 }
2086
2087 free( slap_listeners );
2088 slap_listeners = NULL;
2089 }
2090
2091 static int
slap_listener(Listener * sl)2092 slap_listener(
2093 Listener *sl )
2094 {
2095 Sockaddr from;
2096
2097 ber_socket_t s, sfd;
2098 ber_socklen_t len = sizeof(from);
2099 Connection *c;
2100 slap_ssf_t ssf = 0;
2101 struct berval authid = BER_BVNULL;
2102 #ifdef SLAPD_RLOOKUPS
2103 char hbuf[NI_MAXHOST];
2104 #endif /* SLAPD_RLOOKUPS */
2105
2106 char *dnsname = NULL;
2107 /* we assume INET6_ADDRSTRLEN > INET_ADDRSTRLEN */
2108 char peername[LDAP_IPADDRLEN];
2109 struct berval peerbv = BER_BVC(peername);
2110 #ifdef LDAP_PF_LOCAL_SENDMSG
2111 char peerbuf[8];
2112 #endif
2113 int cflag;
2114 int tid;
2115 char ebuf[128];
2116
2117 Debug( LDAP_DEBUG_TRACE,
2118 ">>> slap_listener(%s)\n",
2119 sl->sl_url.bv_val );
2120
2121 peername[0] = '\0';
2122
2123 #ifdef LDAP_CONNECTIONLESS
2124 if ( sl->sl_is_udp ) return 1;
2125 #endif /* LDAP_CONNECTIONLESS */
2126
2127 # ifdef LDAP_PF_LOCAL
2128 /* FIXME: apparently accept doesn't fill
2129 * the sun_path sun_path member */
2130 from.sa_un_addr.sun_path[0] = '\0';
2131 # endif /* LDAP_PF_LOCAL */
2132
2133 s = accept( SLAP_FD2SOCK( sl->sl_sd ), (struct sockaddr *) &from, &len );
2134 if ( s != AC_SOCKET_INVALID ) {
2135 SET_CLOSE(s);
2136 }
2137 Debug( LDAP_DEBUG_CONNS,
2138 "daemon: accept() = %d\n", s );
2139
2140 /* Resume the listener FD to allow concurrent-processing of
2141 * additional incoming connections.
2142 */
2143 sl->sl_busy = 0;
2144 WAKE_LISTENER(DAEMON_ID(sl->sl_sd),1);
2145
2146 if ( s == AC_SOCKET_INVALID ) {
2147 int err = sock_errno();
2148
2149 if(
2150 #ifdef EMFILE
2151 err == EMFILE ||
2152 #endif /* EMFILE */
2153 #ifdef ENFILE
2154 err == ENFILE ||
2155 #endif /* ENFILE */
2156 0 )
2157 {
2158 ldap_pvt_thread_mutex_lock( &emfile_mutex );
2159 emfile++;
2160 /* Stop listening until an existing session closes */
2161 sl->sl_mute = 1;
2162 ldap_pvt_thread_mutex_unlock( &emfile_mutex );
2163 }
2164
2165 Debug( LDAP_DEBUG_ANY,
2166 "daemon: accept(%ld) failed errno=%d (%s)\n",
2167 (long) sl->sl_sd, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2168 ldap_pvt_thread_yield();
2169 return 0;
2170 }
2171 sfd = SLAP_SOCKNEW( s );
2172
2173 /* make sure descriptor number isn't too great */
2174 if ( sfd >= dtblsize ) {
2175 Debug( LDAP_DEBUG_ANY,
2176 "daemon: %ld beyond descriptor table size %ld\n",
2177 (long) sfd, (long) dtblsize );
2178
2179 tcp_close(s);
2180 ldap_pvt_thread_yield();
2181 return 0;
2182 }
2183 tid = DAEMON_ID(sfd);
2184
2185 #ifdef LDAP_DEBUG
2186 ldap_pvt_thread_mutex_lock( &slap_daemon[tid].sd_mutex );
2187 /* newly accepted stream should not be in any of the FD SETS */
2188 assert( SLAP_SOCK_NOT_ACTIVE( tid, sfd ));
2189 ldap_pvt_thread_mutex_unlock( &slap_daemon[tid].sd_mutex );
2190 #endif /* LDAP_DEBUG */
2191
2192 #if defined( SO_KEEPALIVE ) || defined( TCP_NODELAY )
2193 #ifdef LDAP_PF_LOCAL
2194 /* for IPv4 and IPv6 sockets only */
2195 if ( from.sa_addr.sa_family != AF_LOCAL )
2196 #endif /* LDAP_PF_LOCAL */
2197 {
2198 int rc;
2199 int tmp;
2200 #ifdef SO_KEEPALIVE
2201 /* enable keep alives */
2202 tmp = 1;
2203 rc = setsockopt( s, SOL_SOCKET, SO_KEEPALIVE,
2204 (char *) &tmp, sizeof(tmp) );
2205 if ( rc == AC_SOCKET_ERROR ) {
2206 int err = sock_errno();
2207 Debug( LDAP_DEBUG_ANY,
2208 "slapd(%ld): setsockopt(SO_KEEPALIVE) failed "
2209 "errno=%d (%s)\n", (long) sfd, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2210 slapd_close(sfd);
2211 return 0;
2212 }
2213 #endif /* SO_KEEPALIVE */
2214 #ifdef TCP_NODELAY
2215 /* enable no delay */
2216 tmp = 1;
2217 rc = setsockopt( s, IPPROTO_TCP, TCP_NODELAY,
2218 (char *)&tmp, sizeof(tmp) );
2219 if ( rc == AC_SOCKET_ERROR ) {
2220 int err = sock_errno();
2221 Debug( LDAP_DEBUG_ANY,
2222 "slapd(%ld): setsockopt(TCP_NODELAY) failed "
2223 "errno=%d (%s)\n", (long) sfd, err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2224 slapd_close(sfd);
2225 return 0;
2226 }
2227 #endif /* TCP_NODELAY */
2228 }
2229 #endif /* SO_KEEPALIVE || TCP_NODELAY */
2230
2231 Debug( LDAP_DEBUG_CONNS,
2232 "daemon: listen=%ld, new connection on %ld\n",
2233 (long) sl->sl_sd, (long) sfd );
2234
2235 cflag = 0;
2236 switch ( from.sa_addr.sa_family ) {
2237 # ifdef LDAP_PF_LOCAL
2238 case AF_LOCAL:
2239 cflag |= CONN_IS_IPC;
2240
2241 /* FIXME: apparently accept doesn't fill
2242 * the sun_path sun_path member */
2243 if ( from.sa_un_addr.sun_path[0] == '\0' ) {
2244 AC_MEMCPY( from.sa_un_addr.sun_path,
2245 sl->sl_sa.sa_un_addr.sun_path,
2246 sizeof( from.sa_un_addr.sun_path ) );
2247 }
2248
2249 sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
2250 ssf = local_ssf;
2251 {
2252 uid_t uid;
2253 gid_t gid;
2254
2255 #ifdef LDAP_PF_LOCAL_SENDMSG
2256 peerbv.bv_val = peerbuf;
2257 peerbv.bv_len = sizeof( peerbuf );
2258 #endif
2259 if( LUTIL_GETPEEREID( s, &uid, &gid, &peerbv ) == 0 ) {
2260 authid.bv_val = ch_malloc(
2261 STRLENOF( "gidNumber=4294967295+uidNumber=4294967295,"
2262 "cn=peercred,cn=external,cn=auth" ) + 1 );
2263 authid.bv_len = sprintf( authid.bv_val,
2264 "gidNumber=%d+uidNumber=%d,"
2265 "cn=peercred,cn=external,cn=auth",
2266 (int) gid, (int) uid );
2267 assert( authid.bv_len <=
2268 STRLENOF( "gidNumber=4294967295+uidNumber=4294967295,"
2269 "cn=peercred,cn=external,cn=auth" ) );
2270 }
2271 }
2272 dnsname = "local";
2273 break;
2274 #endif /* LDAP_PF_LOCAL */
2275
2276 # ifdef LDAP_PF_INET6
2277 case AF_INET6:
2278 # endif /* LDAP_PF_INET6 */
2279 case AF_INET:
2280 if ( sl->sl_is_proxied ) {
2281 if ( !proxyp( sfd, &from ) ) {
2282 Debug( LDAP_DEBUG_ANY, "slapd(%ld): proxyp failed\n", (long)sfd );
2283 slapd_close( sfd );
2284 return 0;
2285 }
2286 }
2287 ldap_pvt_sockaddrstr( &from, &peerbv );
2288 break;
2289
2290 default:
2291 slapd_close(sfd);
2292 return 0;
2293 }
2294
2295 if ( ( from.sa_addr.sa_family == AF_INET )
2296 #ifdef LDAP_PF_INET6
2297 || ( from.sa_addr.sa_family == AF_INET6 )
2298 #endif /* LDAP_PF_INET6 */
2299 )
2300 {
2301 dnsname = NULL;
2302 #ifdef SLAPD_RLOOKUPS
2303 if ( use_reverse_lookup ) {
2304 char *herr;
2305 if (ldap_pvt_get_hname( (const struct sockaddr *)&from, len, hbuf,
2306 sizeof(hbuf), &herr ) == 0) {
2307 ldap_pvt_str2lower( hbuf );
2308 dnsname = hbuf;
2309 }
2310 }
2311 #endif /* SLAPD_RLOOKUPS */
2312
2313 #ifdef HAVE_TCPD
2314 {
2315 int rc;
2316 char *peeraddr, *paend;
2317 peeraddr = peerbv.bv_val + 3;
2318 if ( *peeraddr == '[' ) {
2319 peeraddr++;
2320 paend = strrchr( peeraddr, ']' );
2321 } else {
2322 paend = strrchr( peeraddr, ':' );
2323 }
2324 if ( paend )
2325 *paend = '\0';
2326 ldap_pvt_thread_mutex_lock( &sd_tcpd_mutex );
2327 rc = hosts_ctl("slapd",
2328 dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
2329 peeraddr,
2330 SLAP_STRING_UNKNOWN );
2331 ldap_pvt_thread_mutex_unlock( &sd_tcpd_mutex );
2332 if ( !rc ) {
2333 /* DENY ACCESS */
2334 Debug( LDAP_DEBUG_STATS,
2335 "fd=%ld DENIED from %s (%s)\n",
2336 (long) sfd,
2337 dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
2338 peeraddr );
2339 slapd_close(sfd);
2340 return 0;
2341 }
2342 if ( paend ) {
2343 if ( peeraddr[-1] == '[' )
2344 *paend = ']';
2345 else
2346 *paend = ':';
2347 }
2348 }
2349 #endif /* HAVE_TCPD */
2350 }
2351
2352 #ifdef HAVE_TLS
2353 if ( sl->sl_is_tls ) cflag |= CONN_IS_TLS;
2354 #endif
2355 c = connection_init(sfd, sl,
2356 dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
2357 peername, cflag, ssf,
2358 authid.bv_val ? &authid : NULL
2359 LDAP_PF_LOCAL_SENDMSG_ARG(&peerbv));
2360
2361 if( authid.bv_val ) ch_free(authid.bv_val);
2362
2363 if( !c ) {
2364 Debug( LDAP_DEBUG_ANY,
2365 "daemon: connection_init(%ld, %s, %s) failed.\n",
2366 (long) sfd, peername, sl->sl_name.bv_val );
2367 slapd_close(sfd);
2368 }
2369
2370 return 0;
2371 }
2372
2373 static void*
slap_listener_thread(void * ctx,void * ptr)2374 slap_listener_thread(
2375 void* ctx,
2376 void* ptr )
2377 {
2378 int rc;
2379 Listener *sl = (Listener *)ptr;
2380
2381 rc = slap_listener( sl );
2382
2383 if( rc != LDAP_SUCCESS ) {
2384 Debug( LDAP_DEBUG_ANY,
2385 "slap_listener_thread(%s): failed err=%d",
2386 sl->sl_url.bv_val, rc );
2387 }
2388
2389 return (void*)NULL;
2390 }
2391
2392 static int
slap_listener_activate(Listener * sl)2393 slap_listener_activate(
2394 Listener* sl )
2395 {
2396 int rc;
2397
2398 Debug( LDAP_DEBUG_TRACE, "slap_listener_activate(%d): %s\n",
2399 sl->sl_sd, sl->sl_busy ? "busy" : "" );
2400
2401 sl->sl_busy = 1;
2402
2403 rc = ldap_pvt_thread_pool_submit( &connection_pool,
2404 slap_listener_thread, (void *) sl );
2405
2406 if( rc != 0 ) {
2407 Debug( LDAP_DEBUG_ANY,
2408 "slap_listener_activate(%d): submit failed (%d)\n",
2409 sl->sl_sd, rc );
2410 }
2411 return rc;
2412 }
2413
2414 static void *
slapd_daemon_task(void * ptr)2415 slapd_daemon_task(
2416 void *ptr )
2417 {
2418 int l;
2419 time_t last_idle_check = 0;
2420 int ebadf = 0;
2421 int tid = (slap_daemon_st *) ptr - slap_daemon;
2422 char ebuf[128];
2423
2424 #define SLAPD_IDLE_CHECK_LIMIT 4
2425
2426 slapd_add( wake_sds[tid][0], 0, NULL, tid );
2427 if ( tid )
2428 goto loop;
2429
2430 /* Init stuff done only by thread 0 */
2431
2432 last_idle_check = slap_get_time();
2433
2434 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
2435 if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue;
2436
2437 #ifdef LDAP_CONNECTIONLESS
2438 /* Since this is connectionless, the data port is the
2439 * listening port. The listen() and accept() calls
2440 * are unnecessary.
2441 */
2442 if ( slap_listeners[l]->sl_is_udp )
2443 continue;
2444 #endif /* LDAP_CONNECTIONLESS */
2445
2446 /* FIXME: TCP-only! */
2447 #ifdef LDAP_TCP_BUFFER
2448 if ( 1 ) {
2449 int origsize, size, realsize, rc;
2450 socklen_t optlen;
2451
2452 size = 0;
2453 if ( slap_listeners[l]->sl_tcp_rmem > 0 ) {
2454 size = slap_listeners[l]->sl_tcp_rmem;
2455 } else if ( slapd_tcp_rmem > 0 ) {
2456 size = slapd_tcp_rmem;
2457 }
2458
2459 if ( size > 0 ) {
2460 optlen = sizeof( origsize );
2461 rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2462 SOL_SOCKET,
2463 SO_RCVBUF,
2464 (void *)&origsize,
2465 &optlen );
2466
2467 if ( rc ) {
2468 int err = sock_errno();
2469 Debug( LDAP_DEBUG_ANY,
2470 "slapd_daemon_task: getsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
2471 err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2472 }
2473
2474 optlen = sizeof( size );
2475 rc = setsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2476 SOL_SOCKET,
2477 SO_RCVBUF,
2478 (const void *)&size,
2479 optlen );
2480
2481 if ( rc ) {
2482 int err = sock_errno();
2483 Debug( LDAP_DEBUG_ANY,
2484 "slapd_daemon_task: setsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
2485 err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2486 }
2487
2488 optlen = sizeof( realsize );
2489 rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2490 SOL_SOCKET,
2491 SO_RCVBUF,
2492 (void *)&realsize,
2493 &optlen );
2494
2495 if ( rc ) {
2496 int err = sock_errno();
2497 Debug( LDAP_DEBUG_ANY,
2498 "slapd_daemon_task: getsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
2499 err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2500 }
2501
2502 Debug(LDAP_DEBUG_ANY,
2503 "slapd_daemon_task: url=%s (#%d) RCVBUF original size=%d requested size=%d real size=%d\n",
2504 slap_listeners[l]->sl_url.bv_val, l,
2505 origsize, size, realsize );
2506 }
2507
2508 size = 0;
2509 if ( slap_listeners[l]->sl_tcp_wmem > 0 ) {
2510 size = slap_listeners[l]->sl_tcp_wmem;
2511 } else if ( slapd_tcp_wmem > 0 ) {
2512 size = slapd_tcp_wmem;
2513 }
2514
2515 if ( size > 0 ) {
2516 optlen = sizeof( origsize );
2517 rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2518 SOL_SOCKET,
2519 SO_SNDBUF,
2520 (void *)&origsize,
2521 &optlen );
2522
2523 if ( rc ) {
2524 int err = sock_errno();
2525 Debug( LDAP_DEBUG_ANY,
2526 "slapd_daemon_task: getsockopt(SO_SNDBUF) failed errno=%d (%s)\n",
2527 err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2528 }
2529
2530 optlen = sizeof( size );
2531 rc = setsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2532 SOL_SOCKET,
2533 SO_SNDBUF,
2534 (const void *)&size,
2535 optlen );
2536
2537 if ( rc ) {
2538 int err = sock_errno();
2539 Debug( LDAP_DEBUG_ANY,
2540 "slapd_daemon_task: setsockopt(SO_SNDBUF) failed errno=%d (%s)",
2541 err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2542 }
2543
2544 optlen = sizeof( realsize );
2545 rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
2546 SOL_SOCKET,
2547 SO_SNDBUF,
2548 (void *)&realsize,
2549 &optlen );
2550
2551 if ( rc ) {
2552 int err = sock_errno();
2553 Debug( LDAP_DEBUG_ANY,
2554 "slapd_daemon_task: getsockopt(SO_SNDBUF) failed errno=%d (%s)\n",
2555 err, sock_errstr(err, ebuf, sizeof(ebuf)) );
2556 }
2557
2558 Debug(LDAP_DEBUG_ANY,
2559 "slapd_daemon_task: url=%s (#%d) SNDBUF original size=%d requested size=%d real size=%d\n",
2560 slap_listeners[l]->sl_url.bv_val, l,
2561 origsize, size, realsize );
2562 }
2563 }
2564 #endif /* LDAP_TCP_BUFFER */
2565
2566 if ( listen( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), SLAPD_LISTEN_BACKLOG ) == -1 ) {
2567 int err = sock_errno();
2568
2569 #ifdef LDAP_PF_INET6
2570 /* If error is EADDRINUSE, we are trying to listen to INADDR_ANY and
2571 * we are already listening to in6addr_any, then we want to ignore
2572 * this and continue.
2573 */
2574 if ( err == EADDRINUSE ) {
2575 int i;
2576 struct sockaddr_in sa = slap_listeners[l]->sl_sa.sa_in_addr;
2577 struct sockaddr_in6 sa6;
2578
2579 if ( sa.sin_family == AF_INET &&
2580 sa.sin_addr.s_addr == htonl(INADDR_ANY) ) {
2581 for ( i = 0 ; i < l; i++ ) {
2582 sa6 = slap_listeners[i]->sl_sa.sa_in6_addr;
2583 if ( sa6.sin6_family == AF_INET6 &&
2584 !memcmp( &sa6.sin6_addr, &in6addr_any,
2585 sizeof(struct in6_addr) ) )
2586 {
2587 break;
2588 }
2589 }
2590
2591 if ( i < l ) {
2592 /* We are already listening to in6addr_any */
2593 Debug( LDAP_DEBUG_CONNS,
2594 "daemon: Attempt to listen to 0.0.0.0 failed, "
2595 "already listening on ::, assuming IPv4 included\n" );
2596 slapd_close( slap_listeners[l]->sl_sd );
2597 slap_listeners[l]->sl_sd = AC_SOCKET_INVALID;
2598 continue;
2599 }
2600 }
2601 }
2602 #endif /* LDAP_PF_INET6 */
2603 Debug( LDAP_DEBUG_ANY,
2604 "daemon: listen(%s, 5) failed errno=%d (%s)\n",
2605 slap_listeners[l]->sl_url.bv_val, err,
2606 sock_errstr(err, ebuf, sizeof(ebuf)) );
2607 ldap_pvt_thread_mutex_lock( &slapd_init_mutex );
2608 slapd_shutdown = 2;
2609 ldap_pvt_thread_cond_signal( &slapd_init_cond );
2610 ldap_pvt_thread_mutex_unlock( &slapd_init_mutex );
2611 return (void*)-1;
2612 }
2613
2614 /* make the listening socket non-blocking */
2615 if ( ber_pvt_socket_set_nonblock( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), 1 ) < 0 ) {
2616 Debug( LDAP_DEBUG_ANY, "slapd_daemon_task: "
2617 "set nonblocking on a listening socket failed\n" );
2618 ldap_pvt_thread_mutex_lock( &slapd_init_mutex );
2619 slapd_shutdown = 2;
2620 ldap_pvt_thread_cond_signal( &slapd_init_cond );
2621 ldap_pvt_thread_mutex_unlock( &slapd_init_mutex );
2622 return (void*)-1;
2623 }
2624
2625 slapd_add( slap_listeners[l]->sl_sd, 0, slap_listeners[l], -1 );
2626 }
2627
2628 ldap_pvt_thread_mutex_lock( &slapd_init_mutex );
2629 slapd_ready = 1;
2630 ldap_pvt_thread_cond_signal( &slapd_init_cond );
2631 ldap_pvt_thread_mutex_unlock( &slapd_init_mutex );
2632
2633 #ifdef HAVE_NT_SERVICE_MANAGER
2634 if ( started_event != NULL ) {
2635 ldap_pvt_thread_cond_signal( &started_event );
2636 }
2637 #endif /* HAVE_NT_SERVICE_MANAGER */
2638
2639 loop:
2640
2641 /* initialization complete. Here comes the loop. */
2642
2643 while ( !slapd_shutdown ) {
2644 ber_socket_t i;
2645 int ns, nwriters;
2646 int at;
2647 ber_socket_t nfds;
2648 #if SLAP_EVENTS_ARE_INDEXED
2649 ber_socket_t nrfds, nwfds;
2650 #endif /* SLAP_EVENTS_ARE_INDEXED */
2651 #define SLAPD_EBADF_LIMIT 16
2652
2653 time_t now;
2654
2655 SLAP_EVENT_DECL;
2656
2657 struct timeval tv;
2658 struct timeval *tvp;
2659
2660 struct timeval cat;
2661 time_t tdelta = 1;
2662 struct re_s* rtask;
2663
2664 now = slap_get_time();
2665
2666 if ( !tid && ( global_idletimeout > 0 )) {
2667 int check = 0;
2668 /* Set the select timeout.
2669 * Don't just truncate, preserve the fractions of
2670 * seconds to prevent sleeping for zero time.
2671 */
2672 {
2673 tv.tv_sec = global_idletimeout / SLAPD_IDLE_CHECK_LIMIT;
2674 tv.tv_usec = global_idletimeout - \
2675 ( tv.tv_sec * SLAPD_IDLE_CHECK_LIMIT );
2676 tv.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT;
2677 if ( difftime( last_idle_check +
2678 global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 )
2679 check = 1;
2680 }
2681 if ( check ) {
2682 connections_timeout_idle( now );
2683 last_idle_check = now;
2684 }
2685 } else {
2686 tv.tv_sec = 0;
2687 tv.tv_usec = 0;
2688 }
2689
2690 #ifdef SIGHUP
2691 if ( slapd_gentle_shutdown ) {
2692 ber_socket_t active;
2693
2694 if ( !tid && slapd_gentle_shutdown == 1 ) {
2695 BackendDB *be;
2696 Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n" );
2697 close_listeners( 1 );
2698 frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
2699 LDAP_STAILQ_FOREACH(be, &backendDB, be_next) {
2700 be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
2701 }
2702 slapd_gentle_shutdown = 2;
2703 }
2704
2705 ldap_pvt_thread_mutex_lock( &slap_daemon[tid].sd_mutex );
2706 active = slap_daemon[tid].sd_nactives;
2707 ldap_pvt_thread_mutex_unlock( &slap_daemon[tid].sd_mutex );
2708
2709 if ( active == 0 ) {
2710 if ( !tid ) {
2711 for ( l=1; l<slapd_daemon_threads; l++ ) {
2712 ldap_pvt_thread_mutex_lock( &slap_daemon[l].sd_mutex );
2713 active += slap_daemon[l].sd_nactives;
2714 ldap_pvt_thread_mutex_unlock( &slap_daemon[l].sd_mutex );
2715 }
2716 if ( !active )
2717 slapd_shutdown = 1;
2718 }
2719 if ( !active )
2720 break;
2721 }
2722 }
2723 #endif /* SIGHUP */
2724 at = 0;
2725
2726 ldap_pvt_thread_mutex_lock( &slap_daemon[tid].sd_mutex );
2727
2728 nwriters = slap_daemon[tid].sd_nwriters;
2729
2730 if ( listening )
2731 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
2732 Listener *lr = slap_listeners[l];
2733
2734 if ( lr->sl_sd == AC_SOCKET_INVALID ) continue;
2735 if ( DAEMON_ID( lr->sl_sd ) != tid ) continue;
2736 if ( !SLAP_SOCK_IS_ACTIVE( tid, lr->sl_sd )) continue;
2737
2738 if ( lr->sl_mute || lr->sl_busy )
2739 {
2740 SLAP_SOCK_CLR_READ( tid, lr->sl_sd );
2741 } else {
2742 SLAP_SOCK_SET_READ( tid, lr->sl_sd );
2743 }
2744 }
2745
2746 SLAP_EVENT_INIT(tid);
2747
2748 nfds = SLAP_EVENT_MAX(tid);
2749
2750 if (( global_idletimeout ) && slap_daemon[tid].sd_nactives ) at = 1;
2751
2752 ldap_pvt_thread_mutex_unlock( &slap_daemon[tid].sd_mutex );
2753
2754 if ( at
2755 #if defined(HAVE_YIELDING_SELECT)
2756 && ( tv.tv_sec || tv.tv_usec )
2757 #endif /* HAVE_YIELDING_SELECT */
2758 )
2759 {
2760 tvp = &tv;
2761 } else {
2762 tvp = NULL;
2763 }
2764
2765 /* Only thread 0 handles runqueue */
2766 if ( !tid ) {
2767 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
2768 rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
2769 while ( rtask && cat.tv_sec && cat.tv_sec <= now ) {
2770 if ( ldap_pvt_runqueue_isrunning( &slapd_rq, rtask )) {
2771 ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
2772 } else {
2773 ldap_pvt_runqueue_runtask( &slapd_rq, rtask );
2774 ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
2775 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
2776 ldap_pvt_thread_pool_submit2( &connection_pool,
2777 rtask->routine, (void *) rtask, &rtask->pool_cookie );
2778 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
2779 }
2780 rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
2781 }
2782 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
2783
2784 if ( rtask && cat.tv_sec ) {
2785 /* NOTE: diff __should__ always be >= 0,
2786 * AFAI understand; however (ITS#4872),
2787 * time_t might be unsigned in some systems,
2788 * while difftime() returns a double */
2789 double diff = difftime( cat.tv_sec, now );
2790 if ( diff <= 0 ) {
2791 diff = tdelta;
2792 }
2793 if ( tvp == NULL || diff < tv.tv_sec ) {
2794 tv.tv_sec = diff;
2795 tv.tv_usec = 0;
2796 tvp = &tv;
2797 }
2798 }
2799 }
2800
2801 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
2802 Listener *lr = slap_listeners[l];
2803
2804 if ( lr->sl_sd == AC_SOCKET_INVALID ) {
2805 continue;
2806 }
2807
2808 if ( DAEMON_ID( lr->sl_sd ) != tid ) continue;
2809
2810 if ( lr->sl_mute ) {
2811 Debug( LDAP_DEBUG_CONNS,
2812 "daemon: " SLAP_EVENT_FNAME ": "
2813 "listen=%d muted\n",
2814 lr->sl_sd );
2815 continue;
2816 }
2817
2818 if ( lr->sl_busy ) {
2819 Debug( LDAP_DEBUG_CONNS,
2820 "daemon: " SLAP_EVENT_FNAME ": "
2821 "listen=%d busy\n",
2822 lr->sl_sd );
2823 continue;
2824 }
2825
2826 Debug( LDAP_DEBUG_CONNS,
2827 "daemon: " SLAP_EVENT_FNAME ": "
2828 "listen=%d active_threads=%d tvp=%s\n",
2829 lr->sl_sd, at, tvp == NULL ? "NULL" : "zero" );
2830 }
2831
2832 SLAP_EVENT_WAIT( tid, tvp, &ns );
2833 switch ( ns ) {
2834 case -1: { /* failure - try again */
2835 int err = sock_errno();
2836
2837 if ( err != EINTR ) {
2838 ebadf++;
2839
2840 /* Don't log unless we got it twice in a row */
2841 if ( !( ebadf & 1 ) ) {
2842 Debug( LDAP_DEBUG_ANY,
2843 "daemon: "
2844 SLAP_EVENT_FNAME
2845 " failed count %d "
2846 "err (%d): %s\n",
2847 ebadf, err,
2848 sock_errstr( err, ebuf, sizeof(ebuf) ) );
2849 }
2850 if ( ebadf >= SLAPD_EBADF_LIMIT ) {
2851 slapd_shutdown = 2;
2852 }
2853 }
2854 }
2855 continue;
2856
2857 case 0: /* timeout - let threads run */
2858 ebadf = 0;
2859 #ifndef HAVE_YIELDING_SELECT
2860 Debug( LDAP_DEBUG_CONNS, "daemon: " SLAP_EVENT_FNAME
2861 "timeout - yielding\n" );
2862
2863 ldap_pvt_thread_yield();
2864 #endif /* ! HAVE_YIELDING_SELECT */
2865 continue;
2866
2867 default: /* something happened - deal with it */
2868 if ( slapd_shutdown ) continue;
2869
2870 ebadf = 0;
2871 Debug( LDAP_DEBUG_CONNS,
2872 "daemon: activity on %d descriptor%s\n",
2873 ns, ns != 1 ? "s" : "" );
2874 /* FALL THRU */
2875 }
2876
2877 #if SLAP_EVENTS_ARE_INDEXED
2878 if ( SLAP_EVENT_IS_READ( wake_sds[tid][0] ) ) {
2879 char c[BUFSIZ];
2880 SLAP_EVENT_CLR_READ( wake_sds[tid][0] );
2881 waking = 0;
2882 tcp_read( SLAP_FD2SOCK(wake_sds[tid][0]), c, sizeof(c) );
2883 Debug( LDAP_DEBUG_CONNS, "daemon: waked\n" );
2884 continue;
2885 }
2886
2887 /* The event slot equals the descriptor number - this is
2888 * true for Unix select and poll. We treat Windows select
2889 * like this too, even though it's a kludge.
2890 */
2891 if ( listening )
2892 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
2893 int rc;
2894
2895 if ( ns <= 0 ) break;
2896 if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue;
2897 if ( DAEMON_ID( slap_listeners[l]->sl_sd ) != tid ) continue;
2898 #ifdef LDAP_CONNECTIONLESS
2899 if ( slap_listeners[l]->sl_is_udp ) continue;
2900 #endif /* LDAP_CONNECTIONLESS */
2901 if ( !SLAP_EVENT_IS_READ( slap_listeners[l]->sl_sd ) ) continue;
2902
2903 /* clear events */
2904 SLAP_EVENT_CLR_READ( slap_listeners[l]->sl_sd );
2905 SLAP_EVENT_CLR_WRITE( slap_listeners[l]->sl_sd );
2906 ns--;
2907
2908 rc = slap_listener_activate( slap_listeners[l] );
2909 }
2910
2911 /* bypass the following tests if no descriptors left */
2912 if ( ns <= 0 ) {
2913 #ifndef HAVE_YIELDING_SELECT
2914 ldap_pvt_thread_yield();
2915 #endif /* HAVE_YIELDING_SELECT */
2916 continue;
2917 }
2918
2919 Debug( LDAP_DEBUG_CONNS, "daemon: activity on:" );
2920 nrfds = 0;
2921 nwfds = 0;
2922 for ( i = 0; i < nfds; i++ ) {
2923 int r, w;
2924
2925 r = SLAP_EVENT_IS_READ( i );
2926 /* writefds was not initialized if nwriters was zero */
2927 w = nwriters ? SLAP_EVENT_IS_WRITE( i ) : 0;
2928 if ( r || w ) {
2929 Debug( LDAP_DEBUG_CONNS, " %d%s%s", i,
2930 r ? "r" : "", w ? "w" : "" );
2931 if ( r ) {
2932 nrfds++;
2933 ns--;
2934 }
2935 if ( w ) {
2936 nwfds++;
2937 ns--;
2938 }
2939 }
2940 if ( ns <= 0 ) break;
2941 }
2942 Debug( LDAP_DEBUG_CONNS, "\n" );
2943
2944 /* loop through the writers */
2945 for ( i = 0; nwfds > 0; i++ ) {
2946 ber_socket_t wd;
2947 if ( ! SLAP_EVENT_IS_WRITE( i ) ) continue;
2948 wd = i;
2949
2950 SLAP_EVENT_CLR_WRITE( wd );
2951 nwfds--;
2952
2953 Debug( LDAP_DEBUG_CONNS,
2954 "daemon: write active on %d\n",
2955 wd );
2956
2957 /*
2958 * NOTE: it is possible that the connection was closed
2959 * and that the stream is now inactive.
2960 * connection_write() must validate the stream is still
2961 * active.
2962 *
2963 * ITS#4338: if the stream is invalid, there is no need to
2964 * close it here. It has already been closed in connection.c.
2965 */
2966 if ( connection_write( wd ) < 0 ) {
2967 if ( SLAP_EVENT_IS_READ( wd ) ) {
2968 SLAP_EVENT_CLR_READ( (unsigned) wd );
2969 nrfds--;
2970 }
2971 }
2972 }
2973
2974 for ( i = 0; nrfds > 0; i++ ) {
2975 ber_socket_t rd;
2976 if ( ! SLAP_EVENT_IS_READ( i ) ) continue;
2977 rd = i;
2978 SLAP_EVENT_CLR_READ( rd );
2979 nrfds--;
2980
2981 Debug ( LDAP_DEBUG_CONNS,
2982 "daemon: read activity on %d\n", rd );
2983 /*
2984 * NOTE: it is possible that the connection was closed
2985 * and that the stream is now inactive.
2986 * connection_read() must valid the stream is still
2987 * active.
2988 */
2989
2990 connection_read_activate( rd );
2991 }
2992 #else /* !SLAP_EVENTS_ARE_INDEXED */
2993 /* FIXME */
2994 /* The events are returned in an arbitrary list. This is true
2995 * for /dev/poll, epoll and kqueue. In order to prioritize things
2996 * so that we can handle wake_sds first, listeners second, and then
2997 * all other connections last (as we do for select), we would need
2998 * to use multiple event handles and cascade them.
2999 *
3000 * That seems like a bit of hassle. So the wake_sds check has been
3001 * skipped. For epoll and kqueue we can associate arbitrary data with
3002 * an event, so we could use pointers to the listener structure
3003 * instead of just the file descriptor. For /dev/poll we have to
3004 * search the listeners array for a matching descriptor.
3005 *
3006 * We now handle wake events when we see them; they are not given
3007 * higher priority.
3008 */
3009 #ifdef LDAP_DEBUG
3010 Debug( LDAP_DEBUG_CONNS, "daemon: activity on:" );
3011
3012 for ( i = 0; i < ns; i++ ) {
3013 int r, w, fd;
3014
3015 /* Don't log listener events */
3016 if ( SLAP_EVENT_IS_LISTENER( tid, i )
3017 #ifdef LDAP_CONNECTIONLESS
3018 && !( (SLAP_EVENT_LISTENER( tid, i ))->sl_is_udp )
3019 #endif /* LDAP_CONNECTIONLESS */
3020 )
3021 {
3022 continue;
3023 }
3024
3025 fd = SLAP_EVENT_FD( tid, i );
3026 /* Don't log internal wake events */
3027 if ( fd == wake_sds[tid][0] ) continue;
3028
3029 #ifdef HAVE_KQUEUE
3030 r = SLAP_EVENT_IS_READ( tid, i );
3031 w = SLAP_EVENT_IS_WRITE( tid, i );
3032 #else
3033 r = SLAP_EVENT_IS_READ( i );
3034 w = SLAP_EVENT_IS_WRITE( i );
3035 #endif /* HAVE_KQUEUE */
3036 if ( r || w ) {
3037 Debug( LDAP_DEBUG_CONNS, " %d%s%s", fd,
3038 r ? "r" : "", w ? "w" : "" );
3039 }
3040 }
3041 Debug( LDAP_DEBUG_CONNS, "\n" );
3042 #endif /* LDAP_DEBUG */
3043
3044 for ( i = 0; i < ns; i++ ) {
3045 int rc = 1, fd, w = 0, r = 0;
3046
3047 if ( SLAP_EVENT_IS_LISTENER( tid, i ) ) {
3048 rc = slap_listener_activate( SLAP_EVENT_LISTENER( tid, i ) );
3049 }
3050
3051 /* If we found a regular listener, rc is now zero, and we
3052 * can skip the data portion. But if it was a UDP listener
3053 * then rc is still 1, and we want to handle the data.
3054 */
3055 if ( rc ) {
3056 fd = SLAP_EVENT_FD( tid, i );
3057
3058 /* Handle wake events */
3059 if ( fd == wake_sds[tid][0] ) {
3060 char c[BUFSIZ];
3061 waking = 0;
3062 (void)!tcp_read( SLAP_FD2SOCK(wake_sds[tid][0]), c, sizeof(c) );
3063 continue;
3064 }
3065
3066 #ifdef HAVE_KQUEUE
3067 if ( SLAP_EVENT_IS_WRITE( tid, i ) )
3068 #else
3069 if ( SLAP_EVENT_IS_WRITE( i ) )
3070 #endif /* HAVE_KQUEUE */
3071 {
3072 Debug( LDAP_DEBUG_CONNS,
3073 "daemon: write active on %d\n",
3074 fd );
3075
3076 SLAP_EVENT_CLR_WRITE( i );
3077 w = 1;
3078
3079 /*
3080 * NOTE: it is possible that the connection was closed
3081 * and that the stream is now inactive.
3082 * connection_write() must valid the stream is still
3083 * active.
3084 */
3085 if ( connection_write( fd ) < 0 ) {
3086 continue;
3087 }
3088 }
3089 /* If event is a read */
3090 #ifdef HAVE_KQUEUE
3091 if ( SLAP_EVENT_IS_READ( tid, i ))
3092 #else
3093 if ( SLAP_EVENT_IS_READ( i ))
3094 #endif /* HAVE_KQUEUE */
3095 {
3096 r = 1;
3097 Debug( LDAP_DEBUG_CONNS,
3098 "daemon: read active on %d\n",
3099 fd );
3100
3101 SLAP_EVENT_CLR_READ( i );
3102 connection_read_activate( fd );
3103 } else if ( !w ) {
3104 #ifdef HAVE_EPOLL
3105 /* Don't keep reporting the hangup
3106 */
3107 if ( SLAP_SOCK_IS_ACTIVE( tid, fd )) {
3108 SLAP_EPOLL_SOCK_SET( tid, fd, EPOLLET );
3109 }
3110 #endif
3111 }
3112 }
3113 }
3114 #endif /* SLAP_EVENTS_ARE_INDEXED */
3115
3116 /* Was number of listener threads decreased? */
3117 if ( ldap_pvt_thread_pool_pausecheck_native( &connection_pool )) {
3118 /* decreased, let this thread finish */
3119 if ( tid >= slapd_daemon_threads )
3120 break;
3121 }
3122
3123 #ifndef HAVE_YIELDING_SELECT
3124 ldap_pvt_thread_yield();
3125 #endif /* ! HAVE_YIELDING_SELECT */
3126 }
3127
3128 /* Only thread 0 handles shutdown */
3129 if ( tid )
3130 return NULL;
3131
3132 if ( slapd_shutdown == 1 ) {
3133 Debug( LDAP_DEBUG_ANY,
3134 "daemon: shutdown requested and initiated.\n" );
3135
3136 } else if ( slapd_shutdown == 2 ) {
3137 #ifdef HAVE_NT_SERVICE_MANAGER
3138 Debug( LDAP_DEBUG_ANY,
3139 "daemon: shutdown initiated by Service Manager.\n" );
3140 #else /* !HAVE_NT_SERVICE_MANAGER */
3141 Debug( LDAP_DEBUG_ANY,
3142 "daemon: abnormal condition, shutdown initiated.\n" );
3143 #endif /* !HAVE_NT_SERVICE_MANAGER */
3144 } else {
3145 Debug( LDAP_DEBUG_ANY,
3146 "daemon: no active streams, shutdown initiated.\n" );
3147 }
3148
3149 close_listeners( 1 );
3150
3151 if ( !slapd_gentle_shutdown ) {
3152 slapd_abrupt_shutdown = 1;
3153 connections_shutdown();
3154 }
3155
3156 #ifdef HAVE_KQUEUE
3157 close( slap_daemon[tid].sd_kq );
3158 #endif
3159
3160 if ( LogTest( LDAP_DEBUG_ANY )) {
3161 int t = ldap_pvt_thread_pool_backload( &connection_pool );
3162 Debug( LDAP_DEBUG_ANY,
3163 "slapd shutdown: waiting for %d operations/tasks to finish\n",
3164 t );
3165 }
3166 ldap_pvt_thread_pool_close( &connection_pool, 1 );
3167
3168 return NULL;
3169 }
3170
3171 typedef struct slap_tid_waiter {
3172 int num_tids;
3173 ldap_pvt_thread_t tids[0];
3174 } slap_tid_waiter;
3175
3176 static void *
slapd_daemon_tid_cleanup(void * ctx,void * ptr)3177 slapd_daemon_tid_cleanup(
3178 void *ctx,
3179 void *ptr )
3180 {
3181 slap_tid_waiter *tids = ptr;
3182 int i;
3183
3184 for ( i=0; i<tids->num_tids; i++ )
3185 ldap_pvt_thread_join( tids->tids[i], (void *)NULL );
3186 ch_free( ptr );
3187 return NULL;
3188 }
3189
3190 int
slapd_daemon_resize(int newnum)3191 slapd_daemon_resize( int newnum )
3192 {
3193 int i, rc;
3194
3195 if ( newnum == slapd_daemon_threads )
3196 return 0;
3197
3198 /* wake up all current listener threads */
3199 for ( i=0; i<slapd_daemon_threads; i++ )
3200 WAKE_LISTENER(i,1);
3201
3202 /* mutexes may not survive realloc, so destroy & recreate later */
3203 for ( i=0; i<slapd_daemon_threads; i++ )
3204 ldap_pvt_thread_mutex_destroy( &slap_daemon[i].sd_mutex );
3205
3206 if ( newnum > slapd_daemon_threads ) {
3207 wake_sds = ch_realloc( wake_sds, newnum * sizeof( sdpair ));
3208 slap_daemon = ch_realloc( slap_daemon, newnum * sizeof( slap_daemon_st ));
3209
3210 for ( i=slapd_daemon_threads; i<newnum; i++ )
3211 {
3212 memset( &slap_daemon[i], 0, sizeof( slap_daemon_st ));
3213 if( (rc = lutil_pair( wake_sds[i] )) < 0 ) {
3214 Debug( LDAP_DEBUG_ANY,
3215 "daemon: lutil_pair() failed rc=%d\n", rc );
3216 return rc;
3217 }
3218 ber_pvt_socket_set_nonblock( wake_sds[i][1], 1 );
3219
3220 SLAP_SOCK_INIT(i);
3221 }
3222
3223 for ( i=0; i<newnum; i++ )
3224 ldap_pvt_thread_mutex_init( &slap_daemon[i].sd_mutex );
3225
3226 slapd_socket_realloc( newnum );
3227
3228 for ( i=slapd_daemon_threads; i<newnum; i++ )
3229 {
3230 /* listener as a separate THREAD */
3231 rc = ldap_pvt_thread_create( &slap_daemon[i].sd_tid,
3232 0, slapd_daemon_task, &slap_daemon[i] );
3233
3234 if ( rc != 0 ) {
3235 Debug( LDAP_DEBUG_ANY,
3236 "listener ldap_pvt_thread_create failed (%d)\n", rc );
3237 return rc;
3238 }
3239 }
3240 } else {
3241 int j;
3242 slap_tid_waiter *tids = ch_malloc( sizeof(slap_tid_waiter) +
3243 ((slapd_daemon_threads - newnum) * sizeof(ldap_pvt_thread_t )));
3244 slapd_socket_realloc( newnum );
3245 tids->num_tids = slapd_daemon_threads - newnum;
3246 for ( i=newnum, j=0; i<slapd_daemon_threads; i++, j++ ) {
3247 tids->tids[j] = slap_daemon[i].sd_tid;
3248 #ifdef HAVE_WINSOCK
3249 if ( wake_sds[i][1] != INVALID_SOCKET &&
3250 SLAP_FD2SOCK( wake_sds[i][1] ) != SLAP_FD2SOCK( wake_sds[i][0] ))
3251 #endif /* HAVE_WINSOCK */
3252 tcp_close( SLAP_FD2SOCK(wake_sds[i][1]) );
3253 #ifdef HAVE_WINSOCK
3254 if ( wake_sds[i][0] != INVALID_SOCKET )
3255 #endif /* HAVE_WINSOCK */
3256 tcp_close( SLAP_FD2SOCK(wake_sds[i][0]) );
3257
3258 SLAP_SOCK_DESTROY( i );
3259 }
3260
3261 wake_sds = ch_realloc( wake_sds, newnum * sizeof( sdpair ));
3262 slap_daemon = ch_realloc( slap_daemon, newnum * sizeof( slap_daemon_st ));
3263 for ( i=0; i<newnum; i++ )
3264 ldap_pvt_thread_mutex_init( &slap_daemon[i].sd_mutex );
3265 ldap_pvt_thread_pool_submit( &connection_pool,
3266 slapd_daemon_tid_cleanup, (void *) tids );
3267 }
3268 slapd_daemon_threads = newnum;
3269 slapd_daemon_mask = newnum - 1;
3270 return 0;
3271 }
3272
3273 #ifdef LDAP_CONNECTIONLESS
3274 static int
connectionless_init(void)3275 connectionless_init( void )
3276 {
3277 int l;
3278
3279 for ( l = 0; slap_listeners[l] != NULL; l++ ) {
3280 Listener *lr = slap_listeners[l];
3281 Connection *c;
3282
3283 if ( !lr->sl_is_udp ) {
3284 continue;
3285 }
3286
3287 c = connection_init( lr->sl_sd, lr, "", "",
3288 CONN_IS_UDP, (slap_ssf_t) 0, NULL
3289 LDAP_PF_LOCAL_SENDMSG_ARG(NULL));
3290
3291 if ( !c ) {
3292 Debug( LDAP_DEBUG_TRACE,
3293 "connectionless_init: failed on %s (%d)\n",
3294 lr->sl_url.bv_val, lr->sl_sd );
3295 return -1;
3296 }
3297 lr->sl_is_udp++;
3298 }
3299
3300 return 0;
3301 }
3302 #endif /* LDAP_CONNECTIONLESS */
3303
3304 int
slapd_daemon(void)3305 slapd_daemon( void )
3306 {
3307 int i, rc;
3308
3309 #ifdef LDAP_CONNECTIONLESS
3310 connectionless_init();
3311 #endif /* LDAP_CONNECTIONLESS */
3312
3313 SLAP_SOCK_INIT2();
3314
3315 /* daemon_init only inits element 0 */
3316 for ( i=1; i<slapd_daemon_threads; i++ )
3317 {
3318 ldap_pvt_thread_mutex_init( &slap_daemon[i].sd_mutex );
3319
3320 if( (rc = lutil_pair( wake_sds[i] )) < 0 ) {
3321 Debug( LDAP_DEBUG_ANY,
3322 "daemon: lutil_pair() failed rc=%d\n", rc );
3323 return rc;
3324 }
3325 ber_pvt_socket_set_nonblock( wake_sds[i][1], 1 );
3326
3327 SLAP_SOCK_INIT(i);
3328 }
3329
3330 for ( i=0; i<slapd_daemon_threads; i++ )
3331 {
3332 /* listener as a separate THREAD */
3333 rc = ldap_pvt_thread_create( &slap_daemon[i].sd_tid,
3334 0, slapd_daemon_task, &slap_daemon[i] );
3335
3336 if ( rc != 0 ) {
3337 Debug( LDAP_DEBUG_ANY,
3338 "listener ldap_pvt_thread_create failed (%d)\n", rc );
3339 return rc;
3340 }
3341 }
3342
3343 ldap_pvt_thread_mutex_lock( &slapd_init_mutex );
3344 while ( !slapd_ready && !slapd_shutdown ) {
3345 ldap_pvt_thread_cond_wait( &slapd_init_cond, &slapd_init_mutex );
3346 }
3347 ldap_pvt_thread_mutex_unlock( &slapd_init_mutex );
3348
3349 if ( slapd_shutdown ) {
3350 Debug( LDAP_DEBUG_ANY,
3351 "listener initialization failed\n" );
3352 return 1;
3353 }
3354
3355 #ifdef HAVE_SYSTEMD
3356 rc = sd_notify( 1, "READY=1" );
3357 if ( rc < 0 ) {
3358 Debug( LDAP_DEBUG_ANY,
3359 "systemd sd_notify failed (%d)\n", rc );
3360 }
3361 #endif /* HAVE_SYSTEMD */
3362
3363 /* wait for the listener threads to complete */
3364 for ( i=0; i<slapd_daemon_threads; i++ )
3365 ldap_pvt_thread_join( slap_daemon[i].sd_tid, (void *)NULL );
3366
3367 destroy_listeners();
3368
3369 return 0;
3370 }
3371
3372 static int
sockinit(void)3373 sockinit( void )
3374 {
3375 #if defined( HAVE_WINSOCK2 )
3376 WORD wVersionRequested;
3377 WSADATA wsaData;
3378 int err;
3379
3380 wVersionRequested = MAKEWORD( 2, 0 );
3381
3382 err = WSAStartup( wVersionRequested, &wsaData );
3383 if ( err != 0 ) {
3384 /* Tell the user that we couldn't find a usable */
3385 /* WinSock DLL. */
3386 return -1;
3387 }
3388
3389 /* Confirm that the WinSock DLL supports 2.0.*/
3390 /* Note that if the DLL supports versions greater */
3391 /* than 2.0 in addition to 2.0, it will still return */
3392 /* 2.0 in wVersion since that is the version we */
3393 /* requested. */
3394
3395 if ( LOBYTE( wsaData.wVersion ) != 2 ||
3396 HIBYTE( wsaData.wVersion ) != 0 )
3397 {
3398 /* Tell the user that we couldn't find a usable */
3399 /* WinSock DLL. */
3400 WSACleanup();
3401 return -1;
3402 }
3403
3404 /* The WinSock DLL is acceptable. Proceed. */
3405 #elif defined( HAVE_WINSOCK )
3406 WSADATA wsaData;
3407 if ( WSAStartup( 0x0101, &wsaData ) != 0 ) return -1;
3408 #endif /* ! HAVE_WINSOCK2 && ! HAVE_WINSOCK */
3409
3410 return 0;
3411 }
3412
3413 static int
sockdestroy(void)3414 sockdestroy( void )
3415 {
3416 #if defined( HAVE_WINSOCK2 ) || defined( HAVE_WINSOCK )
3417 WSACleanup();
3418 #endif /* HAVE_WINSOCK2 || HAVE_WINSOCK */
3419
3420 return 0;
3421 }
3422
3423 RETSIGTYPE
slap_sig_shutdown(int sig)3424 slap_sig_shutdown( int sig )
3425 {
3426 int save_errno = errno;
3427 int i;
3428
3429 #if 0
3430 Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: signal %d\n", sig);
3431 #endif
3432
3433 /*
3434 * If the NT Service Manager is controlling the server, we don't
3435 * want SIGBREAK to kill the server. For some strange reason,
3436 * SIGBREAK is generated when a user logs out.
3437 */
3438
3439 #if defined(HAVE_NT_SERVICE_MANAGER) && defined(SIGBREAK)
3440 if (is_NT_Service && sig == SIGBREAK) {
3441 /* empty */;
3442 } else
3443 #endif /* HAVE_NT_SERVICE_MANAGER && SIGBREAK */
3444 #ifdef SIGHUP
3445 if (sig == SIGHUP && global_gentlehup && slapd_gentle_shutdown == 0) {
3446 slapd_gentle_shutdown = 1;
3447 } else
3448 #endif /* SIGHUP */
3449 {
3450 slapd_shutdown = 1;
3451 }
3452
3453 for (i=0; i<slapd_daemon_threads; i++) {
3454 WAKE_LISTENER(i,1);
3455 }
3456
3457 /* reinstall self */
3458 (void) SIGNAL_REINSTALL( sig, slap_sig_shutdown );
3459
3460 errno = save_errno;
3461 }
3462
3463 RETSIGTYPE
slap_sig_wake(int sig)3464 slap_sig_wake( int sig )
3465 {
3466 int save_errno = errno;
3467
3468 WAKE_LISTENER(0,1);
3469
3470 /* reinstall self */
3471 (void) SIGNAL_REINSTALL( sig, slap_sig_wake );
3472
3473 errno = save_errno;
3474 }
3475
3476 int
slap_pause_server(void)3477 slap_pause_server( void )
3478 {
3479 BackendInfo *bi;
3480 int rc = LDAP_SUCCESS;
3481
3482 rc = ldap_pvt_thread_pool_pause( &connection_pool );
3483
3484 LDAP_STAILQ_FOREACH(bi, &backendInfo, bi_next) {
3485 if ( bi->bi_pause ) {
3486 rc = bi->bi_pause( bi );
3487 if ( rc != LDAP_SUCCESS ) {
3488 Debug( LDAP_DEBUG_ANY, "slap_pause_server: "
3489 "bi_pause failed for backend %s\n",
3490 bi->bi_type );
3491 return rc;
3492 }
3493 }
3494 }
3495
3496 return rc;
3497 }
3498
3499 int
slap_unpause_server(void)3500 slap_unpause_server( void )
3501 {
3502 BackendInfo *bi;
3503 int rc = LDAP_SUCCESS;
3504
3505 LDAP_STAILQ_FOREACH(bi, &backendInfo, bi_next) {
3506 if ( bi->bi_unpause ) {
3507 rc = bi->bi_unpause( bi );
3508 if ( rc != LDAP_SUCCESS ) {
3509 Debug( LDAP_DEBUG_ANY, "slap_unpause_server: "
3510 "bi_unpause failed for backend %s\n",
3511 bi->bi_type );
3512 return rc;
3513 }
3514 }
3515 }
3516
3517 rc = ldap_pvt_thread_pool_resume( &connection_pool );
3518 return rc;
3519 }
3520
3521
3522 void
slapd_add_internal(ber_socket_t s,int isactive)3523 slapd_add_internal( ber_socket_t s, int isactive )
3524 {
3525 if (!isactive) {
3526 SET_CLOSE(s);
3527 }
3528 slapd_add( s, isactive, NULL, -1 );
3529 }
3530
3531 Listener **
slapd_get_listeners(void)3532 slapd_get_listeners( void )
3533 {
3534 /* Could return array with no listeners if !listening, but current
3535 * callers mostly look at the URLs. E.g. syncrepl uses this to
3536 * identify the server, which means it wants the startup arguments.
3537 */
3538 return slap_listeners;
3539 }
3540
3541 /* Reject all incoming requests */
3542 void
slap_suspend_listeners(void)3543 slap_suspend_listeners( void )
3544 {
3545 int i;
3546 for (i=0; slap_listeners[i]; i++) {
3547 slap_listeners[i]->sl_mute = 1;
3548 listen( slap_listeners[i]->sl_sd, 0 );
3549 }
3550 }
3551
3552 /* Resume after a suspend */
3553 void
slap_resume_listeners(void)3554 slap_resume_listeners( void )
3555 {
3556 int i;
3557 for (i=0; slap_listeners[i]; i++) {
3558 slap_listeners[i]->sl_mute = 0;
3559 listen( slap_listeners[i]->sl_sd, SLAPD_LISTEN_BACKLOG );
3560 }
3561 }
3562
3563 void
slap_wake_listener()3564 slap_wake_listener()
3565 {
3566 WAKE_LISTENER(0,1);
3567 }
3568
3569 /* return 0 on timeout, 1 on writer ready
3570 * -1 on general error
3571 */
3572 int
slapd_wait_writer(ber_socket_t sd)3573 slapd_wait_writer( ber_socket_t sd )
3574 {
3575 #ifdef HAVE_WINSOCK
3576 fd_set writefds;
3577 struct timeval tv, *tvp;
3578
3579 FD_ZERO( &writefds );
3580 FD_SET( slapd_ws_sockets[sd], &writefds );
3581 if ( global_writetimeout ) {
3582 tv.tv_sec = global_writetimeout;
3583 tv.tv_usec = 0;
3584 tvp = &tv;
3585 } else {
3586 tvp = NULL;
3587 }
3588 return select( 0, NULL, &writefds, NULL, tvp );
3589 #else
3590 struct pollfd fds;
3591 int timeout = global_writetimeout ? global_writetimeout * 1000 : -1;
3592
3593 fds.fd = sd;
3594 fds.events = POLLOUT;
3595
3596 return poll( &fds, 1, timeout );
3597 #endif
3598 }
3599