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