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