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