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