Home | History | Annotate | Line # | Download | only in lloadd
      1 /*	$NetBSD: daemon.c,v 1.3 2025/09/05 21:16:24 christos Exp $	*/
      2 
      3 /* $OpenLDAP$ */
      4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      5  *
      6  * Copyright 1998-2024 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.3 2025/09/05 21:16:24 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 <event2/event.h>
     44 #include <event2/dns.h>
     45 #include <event2/listener.h>
     46 
     47 #include "lload.h"
     48 #include "ldap_pvt_thread.h"
     49 #include "lutil.h"
     50 
     51 #include "ldap_rq.h"
     52 
     53 #ifdef HAVE_SYSTEMD
     54 #include "sd-notify.h"
     55 #endif
     56 
     57 #ifdef LDAP_PF_LOCAL
     58 #include <sys/stat.h>
     59 /* this should go in <ldap.h> as soon as it is accepted */
     60 #define LDAPI_MOD_URLEXT "x-mod"
     61 #endif /* LDAP_PF_LOCAL */
     62 
     63 #ifndef BALANCER_MODULE
     64 #ifdef LDAP_PF_INET6
     65 int slap_inet4or6 = AF_UNSPEC;
     66 #else /* ! INETv6 */
     67 int slap_inet4or6 = AF_INET;
     68 #endif /* ! INETv6 */
     69 
     70 /* globals */
     71 time_t starttime;
     72 struct runqueue_s slapd_rq;
     73 
     74 #ifdef LDAP_TCP_BUFFER
     75 int slapd_tcp_rmem;
     76 int slapd_tcp_wmem;
     77 #endif /* LDAP_TCP_BUFFER */
     78 
     79 volatile sig_atomic_t slapd_shutdown = 0;
     80 volatile sig_atomic_t slapd_gentle_shutdown = 0;
     81 volatile sig_atomic_t slapd_abrupt_shutdown = 0;
     82 #endif /* !BALANCER_MODULE */
     83 
     84 static int emfile;
     85 
     86 ldap_pvt_thread_mutex_t lload_wait_mutex;
     87 ldap_pvt_thread_cond_t lload_wait_cond;
     88 ldap_pvt_thread_cond_t lload_pause_cond;
     89 
     90 #ifndef SLAPD_MAX_DAEMON_THREADS
     91 #define SLAPD_MAX_DAEMON_THREADS 16
     92 #endif
     93 int lload_daemon_threads = 1;
     94 int lload_daemon_mask;
     95 
     96 struct event_base *listener_base = NULL;
     97 LloadListener **lload_listeners = NULL;
     98 static ldap_pvt_thread_t listener_tid, *daemon_tid;
     99 
    100 #ifndef RESOLV_CONF_PATH
    101 #define RESOLV_CONF_PATH "/etc/resolv.conf"
    102 #endif
    103 char *lload_resolvconf_path = RESOLV_CONF_PATH;
    104 
    105 struct event_base *daemon_base = NULL;
    106 struct evdns_base *dnsbase;
    107 
    108 struct event *lload_timeout_event;
    109 struct event *lload_stats_event;
    110 
    111 /*
    112  * global lload statistics. Not mutex protected to preserve performance -
    113  * increment is atomic, at most we risk a bit of inconsistency
    114  */
    115 lload_global_stats_t lload_stats = {};
    116 
    117 #ifndef SLAPD_LISTEN_BACKLOG
    118 #define SLAPD_LISTEN_BACKLOG 1024
    119 #endif /* ! SLAPD_LISTEN_BACKLOG */
    120 
    121 #define DAEMON_ID(fd) ( fd & lload_daemon_mask )
    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 listener_item {
    137     struct evconnlistener *listener;
    138     ber_socket_t fd;
    139 } listener_item;
    140 
    141 typedef struct lload_daemon_st {
    142     ldap_pvt_thread_mutex_t sd_mutex;
    143 
    144     struct event_base *base;
    145     struct event *wakeup_event;
    146 } lload_daemon_st;
    147 
    148 static lload_daemon_st lload_daemon[SLAPD_MAX_DAEMON_THREADS];
    149 
    150 static void daemon_wakeup_cb( evutil_socket_t sig, short what, void *arg );
    151 
    152 static void
    153 lloadd_close( ber_socket_t s )
    154 {
    155     Debug( LDAP_DEBUG_CONNS, "lloadd_close: "
    156             "closing fd=%ld\n",
    157             (long)s );
    158     tcp_close( s );
    159 }
    160 
    161 static void
    162 lload_free_listener_addresses( struct sockaddr **sal )
    163 {
    164     struct sockaddr **sap;
    165     if ( sal == NULL ) return;
    166     for ( sap = sal; *sap != NULL; sap++ )
    167         ch_free(*sap);
    168     ch_free( sal );
    169 }
    170 
    171 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
    172 static int
    173 get_url_perms( char **exts, mode_t *perms, int *crit )
    174 {
    175     int i;
    176 
    177     assert( exts != NULL );
    178     assert( perms != NULL );
    179     assert( crit != NULL );
    180 
    181     *crit = 0;
    182     for ( i = 0; exts[i]; i++ ) {
    183         char *type = exts[i];
    184         int c = 0;
    185 
    186         if ( type[0] == '!' ) {
    187             c = 1;
    188             type++;
    189         }
    190 
    191         if ( strncasecmp( type, LDAPI_MOD_URLEXT "=",
    192                      sizeof(LDAPI_MOD_URLEXT "=") - 1 ) == 0 ) {
    193             char *value = type + ( sizeof(LDAPI_MOD_URLEXT "=") - 1 );
    194             mode_t p = 0;
    195             int j;
    196 
    197             switch ( strlen( value ) ) {
    198                 case 4:
    199                     /* skip leading '0' */
    200                     if ( value[0] != '0' ) return LDAP_OTHER;
    201                     value++;
    202 
    203                 case 3:
    204                     for ( j = 0; j < 3; j++ ) {
    205                         int v;
    206 
    207                         v = value[j] - '0';
    208 
    209                         if ( v < 0 || v > 7 ) return LDAP_OTHER;
    210 
    211                         p |= v << 3 * ( 2 - j );
    212                     }
    213                     break;
    214 
    215                 case 10:
    216                     for ( j = 1; j < 10; j++ ) {
    217                         static mode_t m[] = { 0, S_IRUSR, S_IWUSR, S_IXUSR,
    218                                 S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH,
    219                                 S_IXOTH };
    220                         static const char c[] = "-rwxrwxrwx";
    221 
    222                         if ( value[j] == c[j] ) {
    223                             p |= m[j];
    224 
    225                         } else if ( value[j] != '-' ) {
    226                             return LDAP_OTHER;
    227                         }
    228                     }
    229                     break;
    230 
    231                 default:
    232                     return LDAP_OTHER;
    233             }
    234 
    235             *crit = c;
    236             *perms = p;
    237 
    238             return LDAP_SUCCESS;
    239         }
    240     }
    241 
    242     return LDAP_OTHER;
    243 }
    244 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
    245 
    246 /* port = 0 indicates AF_LOCAL */
    247 static int
    248 lload_get_listener_addresses(
    249         const char *host,
    250         unsigned short port,
    251         struct sockaddr ***sal )
    252 {
    253     struct sockaddr **sap;
    254 
    255 #ifdef LDAP_PF_LOCAL
    256     if ( port == 0 ) {
    257         sap = *sal = ch_malloc( 2 * sizeof(void *) );
    258 
    259         *sap = ch_calloc( 1, sizeof(struct sockaddr_un) );
    260         sap[1] = NULL;
    261 
    262         if ( strlen( host ) >
    263                 ( sizeof( ((struct sockaddr_un *)*sap)->sun_path ) - 1 ) ) {
    264             Debug( LDAP_DEBUG_ANY, "lload_get_listener_addresses: "
    265                     "domain socket path (%s) too long in URL\n",
    266                     host );
    267             goto errexit;
    268         }
    269 
    270         (*sap)->sa_family = AF_LOCAL;
    271         strcpy( ((struct sockaddr_un *)*sap)->sun_path, host );
    272     } else
    273 #endif /* LDAP_PF_LOCAL */
    274     {
    275 #ifdef HAVE_GETADDRINFO
    276         struct addrinfo hints, *res, *sai;
    277         int n, err;
    278         char serv[7];
    279 
    280         memset( &hints, '\0', sizeof(hints) );
    281         hints.ai_flags = AI_PASSIVE;
    282         hints.ai_socktype = SOCK_STREAM;
    283         hints.ai_family = slap_inet4or6;
    284         snprintf( serv, sizeof(serv), "%d", port );
    285 
    286         if ( (err = getaddrinfo( host, serv, &hints, &res )) ) {
    287             Debug( LDAP_DEBUG_ANY, "lload_get_listener_addresses: "
    288                     "getaddrinfo() failed: %s\n",
    289                     AC_GAI_STRERROR(err) );
    290             return -1;
    291         }
    292 
    293         sai = res;
    294         for ( n = 2; ( sai = sai->ai_next ) != NULL; n++ ) {
    295             /* EMPTY */;
    296         }
    297         sap = *sal = ch_calloc( n, sizeof(void *) );
    298 
    299         *sap = NULL;
    300 
    301         for ( sai = res; sai; sai = sai->ai_next ) {
    302             if ( sai->ai_addr == NULL ) {
    303                 Debug( LDAP_DEBUG_ANY, "lload_get_listener_addresses: "
    304                         "getaddrinfo ai_addr is NULL?\n" );
    305                 freeaddrinfo( res );
    306                 goto errexit;
    307             }
    308 
    309             switch ( sai->ai_family ) {
    310 #ifdef LDAP_PF_INET6
    311                 case AF_INET6:
    312                     *sap = ch_malloc( sizeof(struct sockaddr_in6) );
    313                     *(struct sockaddr_in6 *)*sap =
    314                             *((struct sockaddr_in6 *)sai->ai_addr);
    315                     break;
    316 #endif /* LDAP_PF_INET6 */
    317                 case AF_INET:
    318                     *sap = ch_malloc( sizeof(struct sockaddr_in) );
    319                     *(struct sockaddr_in *)*sap =
    320                             *((struct sockaddr_in *)sai->ai_addr);
    321                     break;
    322                 default:
    323                     *sap = NULL;
    324                     break;
    325             }
    326 
    327             if ( *sap != NULL ) {
    328                 (*sap)->sa_family = sai->ai_family;
    329                 sap++;
    330                 *sap = NULL;
    331             }
    332         }
    333 
    334         freeaddrinfo( res );
    335 
    336 #else /* ! HAVE_GETADDRINFO */
    337         int i, n = 1;
    338         struct in_addr in;
    339         struct hostent *he = NULL;
    340 
    341         if ( host == NULL ) {
    342             in.s_addr = htonl( INADDR_ANY );
    343 
    344         } else if ( !inet_aton( host, &in ) ) {
    345             he = gethostbyname( host );
    346             if ( he == NULL ) {
    347                 Debug( LDAP_DEBUG_ANY, "lload_get_listener_addresses: "
    348                         "invalid host %s\n",
    349                         host );
    350                 return -1;
    351             }
    352             for ( n = 0; he->h_addr_list[n]; n++ ) /* empty */;
    353         }
    354 
    355         sap = *sal = ch_malloc( ( n + 1 ) * sizeof(void *) );
    356 
    357         for ( i = 0; i < n; i++ ) {
    358             sap[i] = ch_calloc( 1, sizeof(struct sockaddr_in) );
    359             sap[i]->sa_family = AF_INET;
    360             ((struct sockaddr_in *)sap[i])->sin_port = htons( port );
    361             AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr,
    362                     he ? (struct in_addr *)he->h_addr_list[i] : &in,
    363                     sizeof(struct in_addr) );
    364         }
    365         sap[i] = NULL;
    366 #endif /* ! HAVE_GETADDRINFO */
    367     }
    368 
    369     return 0;
    370 
    371 errexit:
    372     lload_free_listener_addresses(*sal);
    373     return -1;
    374 }
    375 
    376 static int
    377 lload_open_listener(
    378         const char *url,
    379         LDAPURLDesc *lud,
    380         int *listeners,
    381         int *cur )
    382 {
    383     int num, tmp, rc;
    384     LloadListener l;
    385     LloadListener *li;
    386     unsigned short port;
    387     int err, addrlen = 0;
    388     struct sockaddr **sal = NULL, **psal;
    389     int socktype = SOCK_STREAM; /* default to COTS */
    390     ber_socket_t s;
    391     char ebuf[128];
    392 
    393 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
    394     /*
    395      * use safe defaults
    396      */
    397     int crit = 1;
    398 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
    399 
    400     assert( url );
    401     assert( lud );
    402 
    403     l.sl_url.bv_val = NULL;
    404     l.sl_mute = 0;
    405     l.sl_busy = 0;
    406 
    407 #ifndef HAVE_TLS
    408     if ( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) {
    409         Debug( LDAP_DEBUG_ANY, "lload_open_listener: "
    410                 "TLS not supported (%s)\n",
    411                 url );
    412         ldap_free_urldesc( lud );
    413         return -1;
    414     }
    415 
    416     if ( !lud->lud_port ) lud->lud_port = LDAP_PORT;
    417 
    418 #else /* HAVE_TLS */
    419     l.sl_is_tls = ldap_pvt_url_scheme2tls( lud->lud_scheme );
    420 #endif /* HAVE_TLS */
    421 
    422     l.sl_is_proxied = ldap_pvt_url_scheme2proxied( lud->lud_scheme );
    423 
    424 #ifdef LDAP_TCP_BUFFER
    425     l.sl_tcp_rmem = 0;
    426     l.sl_tcp_wmem = 0;
    427 #endif /* LDAP_TCP_BUFFER */
    428 
    429     port = (unsigned short)lud->lud_port;
    430 
    431     tmp = ldap_pvt_url_scheme2proto( lud->lud_scheme );
    432     if ( tmp == LDAP_PROTO_IPC ) {
    433 #ifdef LDAP_PF_LOCAL
    434         if ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) {
    435             err = lload_get_listener_addresses( LDAPI_SOCK, 0, &sal );
    436         } else {
    437             err = lload_get_listener_addresses( lud->lud_host, 0, &sal );
    438         }
    439 #else /* ! LDAP_PF_LOCAL */
    440 
    441         Debug( LDAP_DEBUG_ANY, "lload_open_listener: "
    442                 "URL scheme not supported: %s\n",
    443                 url );
    444         ldap_free_urldesc( lud );
    445         return -1;
    446 #endif /* ! LDAP_PF_LOCAL */
    447     } else {
    448         if ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ||
    449                 strcmp( lud->lud_host, "*" ) == 0 ) {
    450             err = lload_get_listener_addresses( NULL, port, &sal );
    451         } else {
    452             err = lload_get_listener_addresses( lud->lud_host, port, &sal );
    453         }
    454     }
    455 
    456 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
    457     if ( lud->lud_exts ) {
    458         err = get_url_perms( lud->lud_exts, &l.sl_perms, &crit );
    459     } else {
    460         l.sl_perms = S_IRWXU | S_IRWXO;
    461     }
    462 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
    463 
    464     ldap_free_urldesc( lud );
    465     if ( err ) {
    466         lload_free_listener_addresses( sal );
    467         return -1;
    468     }
    469 
    470     /* If we got more than one address returned, we need to make space
    471      * for it in the lload_listeners array.
    472      */
    473     for ( num = 0; sal[num]; num++ ) /* empty */;
    474     if ( num > 1 ) {
    475         *listeners += num - 1;
    476         lload_listeners = ch_realloc( lload_listeners,
    477                 ( *listeners + 1 ) * sizeof(LloadListener *) );
    478     }
    479 
    480     psal = sal;
    481     while ( *sal != NULL ) {
    482         char *af;
    483         switch ( (*sal)->sa_family ) {
    484             case AF_INET:
    485                 af = "IPv4";
    486                 break;
    487 #ifdef LDAP_PF_INET6
    488             case AF_INET6:
    489                 af = "IPv6";
    490                 break;
    491 #endif /* LDAP_PF_INET6 */
    492 #ifdef LDAP_PF_LOCAL
    493             case AF_LOCAL:
    494                 af = "Local";
    495                 break;
    496 #endif /* LDAP_PF_LOCAL */
    497             default:
    498                 sal++;
    499                 continue;
    500         }
    501 
    502         s = socket( (*sal)->sa_family, socktype, 0 );
    503         if ( s == AC_SOCKET_INVALID ) {
    504             int err = sock_errno();
    505             Debug( LDAP_DEBUG_ANY, "lload_open_listener: "
    506                     "%s socket() failed errno=%d (%s)\n",
    507                     af, err, sock_errstr( err, ebuf, sizeof(ebuf) ) );
    508             sal++;
    509             continue;
    510         }
    511         ber_pvt_socket_set_nonblock( s, 1 );
    512         l.sl_sd = s;
    513 
    514 #ifdef LDAP_PF_LOCAL
    515         if ( (*sal)->sa_family == AF_LOCAL ) {
    516             unlink( ((struct sockaddr_un *)*sal)->sun_path );
    517         } else
    518 #endif /* LDAP_PF_LOCAL */
    519         {
    520 #ifdef SO_REUSEADDR
    521             /* enable address reuse */
    522             tmp = 1;
    523             rc = setsockopt(
    524                     s, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp) );
    525             if ( rc == AC_SOCKET_ERROR ) {
    526                 int err = sock_errno();
    527                 Debug( LDAP_DEBUG_ANY, "lload_open_listener(%ld): "
    528                         "setsockopt(SO_REUSEADDR) failed errno=%d (%s)\n",
    529                         (long)l.sl_sd, err,
    530                         sock_errstr( err, ebuf, sizeof(ebuf) ) );
    531             }
    532 #endif /* SO_REUSEADDR */
    533         }
    534 
    535         switch ( (*sal)->sa_family ) {
    536             case AF_INET:
    537                 addrlen = sizeof(struct sockaddr_in);
    538                 break;
    539 #ifdef LDAP_PF_INET6
    540             case AF_INET6:
    541 #ifdef IPV6_V6ONLY
    542                 /* Try to use IPv6 sockets for IPv6 only */
    543                 tmp = 1;
    544                 rc = setsockopt( s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&tmp,
    545                         sizeof(tmp) );
    546                 if ( rc == AC_SOCKET_ERROR ) {
    547                     int err = sock_errno();
    548                     Debug( LDAP_DEBUG_ANY, "lload_open_listener(%ld): "
    549                             "setsockopt(IPV6_V6ONLY) failed errno=%d (%s)\n",
    550                             (long)l.sl_sd, err,
    551                             sock_errstr( err, ebuf, sizeof(ebuf) ) );
    552                 }
    553 #endif /* IPV6_V6ONLY */
    554                 addrlen = sizeof(struct sockaddr_in6);
    555                 break;
    556 #endif /* LDAP_PF_INET6 */
    557 
    558 #ifdef LDAP_PF_LOCAL
    559             case AF_LOCAL:
    560 #ifdef LOCAL_CREDS
    561             {
    562                 int one = 1;
    563                 setsockopt( s, 0, LOCAL_CREDS, &one, sizeof(one) );
    564             }
    565 #endif /* LOCAL_CREDS */
    566 
    567                 addrlen = sizeof(struct sockaddr_un);
    568                 break;
    569 #endif /* LDAP_PF_LOCAL */
    570         }
    571 
    572 #ifdef LDAP_PF_LOCAL
    573         /* create socket with all permissions set for those systems
    574          * that honor permissions on sockets (e.g. Linux); typically,
    575          * only write is required.  To exploit filesystem permissions,
    576          * place the socket in a directory and use directory's
    577          * permissions.  Need write perms to the directory to
    578          * create/unlink the socket; likely need exec perms to access
    579          * the socket (ITS#4709) */
    580         {
    581             mode_t old_umask = 0;
    582 
    583             if ( (*sal)->sa_family == AF_LOCAL ) {
    584                 old_umask = umask( 0 );
    585             }
    586 #endif /* LDAP_PF_LOCAL */
    587             rc = bind( s, *sal, addrlen );
    588 #ifdef LDAP_PF_LOCAL
    589             if ( old_umask != 0 ) {
    590                 umask( old_umask );
    591             }
    592         }
    593 #endif /* LDAP_PF_LOCAL */
    594         if ( rc ) {
    595             err = sock_errno();
    596             Debug( LDAP_DEBUG_ANY, "lload_open_listener: "
    597                     "bind(%ld) failed errno=%d (%s)\n",
    598                     (long)l.sl_sd, err,
    599                     sock_errstr( err, ebuf, sizeof(ebuf) ) );
    600             tcp_close( s );
    601             sal++;
    602             continue;
    603         }
    604 
    605         switch ( (*sal)->sa_family ) {
    606 #ifdef LDAP_PF_LOCAL
    607             case AF_LOCAL: {
    608                 char *path = ((struct sockaddr_un *)*sal)->sun_path;
    609                 l.sl_name.bv_len = strlen( path ) + STRLENOF("PATH=");
    610                 l.sl_name.bv_val = ch_malloc( l.sl_name.bv_len + 1 );
    611                 snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1, "PATH=%s",
    612                         path );
    613             } break;
    614 #endif /* LDAP_PF_LOCAL */
    615 
    616             case AF_INET: {
    617                 char addr[INET_ADDRSTRLEN];
    618                 const char *s;
    619 #if defined(HAVE_GETADDRINFO) && defined(HAVE_INET_NTOP)
    620                 s = inet_ntop( AF_INET,
    621                         &((struct sockaddr_in *)*sal)->sin_addr, addr,
    622                         sizeof(addr) );
    623 #else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
    624                 s = inet_ntoa( ((struct sockaddr_in *)*sal)->sin_addr );
    625 #endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
    626                 if ( !s ) s = SLAP_STRING_UNKNOWN;
    627                 port = ntohs( ((struct sockaddr_in *)*sal)->sin_port );
    628                 l.sl_name.bv_val =
    629                         ch_malloc( sizeof("IP=255.255.255.255:65535") );
    630                 snprintf( l.sl_name.bv_val,
    631                         sizeof("IP=255.255.255.255:65535"), "IP=%s:%d", s,
    632                         port );
    633                 l.sl_name.bv_len = strlen( l.sl_name.bv_val );
    634             } break;
    635 
    636 #ifdef LDAP_PF_INET6
    637             case AF_INET6: {
    638                 char addr[INET6_ADDRSTRLEN];
    639                 const char *s;
    640                 s = inet_ntop( AF_INET6,
    641                         &((struct sockaddr_in6 *)*sal)->sin6_addr, addr,
    642                         sizeof(addr) );
    643                 if ( !s ) s = SLAP_STRING_UNKNOWN;
    644                 port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
    645                 l.sl_name.bv_len = strlen( s ) + sizeof("IP=[]:65535");
    646                 l.sl_name.bv_val = ch_malloc( l.sl_name.bv_len );
    647                 snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=[%s]:%d", s,
    648                         port );
    649                 l.sl_name.bv_len = strlen( l.sl_name.bv_val );
    650             } break;
    651 #endif /* LDAP_PF_INET6 */
    652 
    653             default:
    654                 Debug( LDAP_DEBUG_ANY, "lload_open_listener: "
    655                         "unsupported address family (%d)\n",
    656                         (int)(*sal)->sa_family );
    657                 break;
    658         }
    659 
    660         AC_MEMCPY( &l.sl_sa, *sal, addrlen );
    661         ber_str2bv( url, 0, 1, &l.sl_url );
    662         li = ch_malloc( sizeof(LloadListener) );
    663         *li = l;
    664         lload_listeners[*cur] = li;
    665         (*cur)++;
    666         sal++;
    667     }
    668 
    669     lload_free_listener_addresses( psal );
    670 
    671     if ( l.sl_url.bv_val == NULL ) {
    672         Debug( LDAP_DEBUG_ANY, "lload_open_listener: "
    673                 "failed on %s\n",
    674                 url );
    675         return -1;
    676     }
    677 
    678     Debug( LDAP_DEBUG_TRACE, "lload_open_listener: "
    679             "listener initialized %s\n",
    680             l.sl_url.bv_val );
    681 
    682     return 0;
    683 }
    684 
    685 int
    686 lload_open_new_listener( const char *url, LDAPURLDesc *lud )
    687 {
    688     int rc, i, j = 0;
    689 
    690     for ( i = 0; lload_listeners && lload_listeners[i] != NULL;
    691             i++ ) /* count */
    692         ;
    693     j = i;
    694 
    695     i++;
    696     lload_listeners = ch_realloc(
    697             lload_listeners, ( i + 1 ) * sizeof(LloadListener *) );
    698 
    699     rc = lload_open_listener( url, lud, &i, &j );
    700     lload_listeners[j] = NULL;
    701     return rc;
    702 }
    703 
    704 int lloadd_inited = 0;
    705 
    706 int
    707 lloadd_listeners_init( const char *urls )
    708 {
    709     int i, j, n;
    710     char **u;
    711     LDAPURLDesc *lud;
    712 
    713     Debug( LDAP_DEBUG_ARGS, "lloadd_listeners_init: %s\n",
    714             urls ? urls : "<null>" );
    715 
    716 #ifdef HAVE_TCPD
    717     ldap_pvt_thread_mutex_init( &sd_tcpd_mutex );
    718 #endif /* TCP Wrappers */
    719 
    720     if ( urls == NULL ) urls = "ldap:///";
    721 
    722     u = ldap_str2charray( urls, " " );
    723 
    724     if ( u == NULL || u[0] == NULL ) {
    725         Debug( LDAP_DEBUG_ANY, "lloadd_listeners_init: "
    726                 "no urls (%s) provided\n",
    727                 urls );
    728         if ( u ) ldap_charray_free( u );
    729         return -1;
    730     }
    731 
    732     for ( i = 0; u[i] != NULL; i++ ) {
    733         Debug( LDAP_DEBUG_TRACE, "lloadd_listeners_init: "
    734                 "listen on %s\n",
    735                 u[i] );
    736     }
    737 
    738     if ( i == 0 ) {
    739         Debug( LDAP_DEBUG_ANY, "lloadd_listeners_init: "
    740                 "no listeners to open (%s)\n",
    741                 urls );
    742         ldap_charray_free( u );
    743         return -1;
    744     }
    745 
    746     Debug( LDAP_DEBUG_TRACE, "lloadd_listeners_init: "
    747             "%d listeners to open...\n",
    748             i );
    749     lload_listeners = ch_malloc( ( i + 1 ) * sizeof(LloadListener *) );
    750 
    751     for ( n = 0, j = 0; u[n]; n++ ) {
    752         if ( ldap_url_parse_ext( u[n], &lud, LDAP_PVT_URL_PARSE_DEF_PORT ) ) {
    753             Debug( LDAP_DEBUG_ANY, "lloadd_listeners_init: "
    754                     "could not parse url %s\n",
    755                     u[n] );
    756             ldap_charray_free( u );
    757             return -1;
    758         }
    759 
    760         if ( lload_open_listener( u[n], lud, &i, &j ) ) {
    761             ldap_charray_free( u );
    762             return -1;
    763         }
    764     }
    765     lload_listeners[j] = NULL;
    766 
    767     Debug( LDAP_DEBUG_TRACE, "lloadd_listeners_init: "
    768             "%d listeners opened\n",
    769             i );
    770 
    771     ldap_charray_free( u );
    772 
    773     return !i;
    774 }
    775 
    776 int
    777 lloadd_daemon_destroy( void )
    778 {
    779     epoch_shutdown();
    780     if ( lloadd_inited ) {
    781         int i;
    782 
    783         for ( i = 0; i < lload_daemon_threads; i++ ) {
    784             ldap_pvt_thread_mutex_destroy( &lload_daemon[i].sd_mutex );
    785             if ( lload_daemon[i].wakeup_event ) {
    786                 event_free( lload_daemon[i].wakeup_event );
    787             }
    788             if ( lload_daemon[i].base ) {
    789                 event_base_free( lload_daemon[i].base );
    790             }
    791         }
    792 
    793         event_free( lload_stats_event );
    794         event_free( lload_timeout_event );
    795 
    796         event_base_free( daemon_base );
    797         daemon_base = NULL;
    798 
    799         lloadd_inited = 0;
    800 #ifdef HAVE_TCPD
    801         ldap_pvt_thread_mutex_destroy( &sd_tcpd_mutex );
    802 #endif /* TCP Wrappers */
    803     }
    804 
    805     return 0;
    806 }
    807 
    808 static void
    809 destroy_listeners( void )
    810 {
    811     LloadListener *lr, **ll = lload_listeners;
    812 
    813     if ( ll == NULL ) return;
    814 
    815     ldap_pvt_thread_join( listener_tid, (void *)NULL );
    816 
    817     while ( (lr = *ll++) != NULL ) {
    818         if ( lr->sl_url.bv_val ) {
    819             ber_memfree( lr->sl_url.bv_val );
    820         }
    821 
    822         if ( lr->sl_name.bv_val ) {
    823             ber_memfree( lr->sl_name.bv_val );
    824         }
    825 
    826 #ifdef LDAP_PF_LOCAL
    827         if ( lr->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
    828             unlink( lr->sl_sa.sa_un_addr.sun_path );
    829         }
    830 #endif /* LDAP_PF_LOCAL */
    831 
    832         evconnlistener_free( lr->listener );
    833 
    834         free( lr );
    835     }
    836 
    837     free( lload_listeners );
    838     lload_listeners = NULL;
    839 
    840     if ( listener_base ) {
    841         event_base_free( listener_base );
    842     }
    843 }
    844 
    845 static void
    846 lload_listener(
    847         struct evconnlistener *listener,
    848         ber_socket_t s,
    849         struct sockaddr *a,
    850         int len,
    851         void *arg )
    852 {
    853     LloadListener *sl = arg;
    854     LloadConnection *c;
    855     Sockaddr *from = (Sockaddr *)a;
    856     char peername[LDAP_IPADDRLEN];
    857     struct berval peerbv = BER_BVC(peername);
    858     int cflag;
    859     int tid;
    860     char ebuf[128];
    861 
    862     Debug( LDAP_DEBUG_TRACE, ">>> lload_listener(%s)\n", sl->sl_url.bv_val );
    863 
    864     peername[0] = '\0';
    865 
    866     /* Resume the listener FD to allow concurrent-processing of
    867      * additional incoming connections.
    868      */
    869     sl->sl_busy = 0;
    870 
    871     tid = DAEMON_ID(s);
    872 
    873     Debug( LDAP_DEBUG_CONNS, "lload_listener: "
    874             "listen=%ld, new connection fd=%ld\n",
    875             (long)sl->sl_sd, (long)s );
    876 
    877 #if defined(SO_KEEPALIVE) || defined(TCP_NODELAY)
    878 #ifdef LDAP_PF_LOCAL
    879     /* for IPv4 and IPv6 sockets only */
    880     if ( from->sa_addr.sa_family != AF_LOCAL )
    881 #endif /* LDAP_PF_LOCAL */
    882     {
    883         int rc;
    884         int tmp;
    885 #ifdef SO_KEEPALIVE
    886         /* enable keep alives */
    887         tmp = 1;
    888         rc = setsockopt(
    889                 s, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp) );
    890         if ( rc == AC_SOCKET_ERROR ) {
    891             int err = sock_errno();
    892             Debug( LDAP_DEBUG_ANY, "lload_listener(%ld): "
    893                     "setsockopt(SO_KEEPALIVE) failed errno=%d (%s)\n",
    894                     (long)s, err, sock_errstr( err, ebuf, sizeof(ebuf) ) );
    895         }
    896 #endif /* SO_KEEPALIVE */
    897 #ifdef TCP_NODELAY
    898         /* enable no delay */
    899         tmp = 1;
    900         rc = setsockopt(
    901                 s, IPPROTO_TCP, TCP_NODELAY, (char *)&tmp, sizeof(tmp) );
    902         if ( rc == AC_SOCKET_ERROR ) {
    903             int err = sock_errno();
    904             Debug( LDAP_DEBUG_ANY, "lload_listener(%ld): "
    905                     "setsockopt(TCP_NODELAY) failed errno=%d (%s)\n",
    906                     (long)s, err, sock_errstr( err, ebuf, sizeof(ebuf) ) );
    907         }
    908 #endif /* TCP_NODELAY */
    909     }
    910 #endif /* SO_KEEPALIVE || TCP_NODELAY */
    911 
    912     if ( sl->sl_is_proxied ) {
    913         if ( !proxyp( s, from ) ) {
    914             Debug( LDAP_DEBUG_ANY, "lload_listener: "
    915                     "proxyp(%ld) failed\n",
    916                     (long)s );
    917             lloadd_close( s );
    918             return;
    919         }
    920     }
    921 
    922     cflag = 0;
    923     switch ( from->sa_addr.sa_family ) {
    924 #ifdef LDAP_PF_LOCAL
    925         case AF_LOCAL:
    926             cflag |= CONN_IS_IPC;
    927 
    928             /* FIXME: apparently accept doesn't fill the sun_path member */
    929             sprintf( peername, "PATH=%s", sl->sl_sa.sa_un_addr.sun_path );
    930             break;
    931 #endif /* LDAP_PF_LOCAL */
    932 
    933 #ifdef LDAP_PF_INET6
    934         case AF_INET6:
    935 #endif /* LDAP_PF_INET6 */
    936         case AF_INET:
    937             ldap_pvt_sockaddrstr( from, &peerbv );
    938             break;
    939 
    940         default:
    941             lloadd_close( s );
    942             return;
    943     }
    944 
    945 #ifdef HAVE_TLS
    946     if ( sl->sl_is_tls ) cflag |= CONN_IS_TLS;
    947 #endif
    948     c = client_init( s, peername, lload_daemon[tid].base, cflag );
    949 
    950     if ( !c ) {
    951         Debug( LDAP_DEBUG_ANY, "lload_listener: "
    952                 "client_init(%ld, %s, %s) failed\n",
    953                 (long)s, peername, sl->sl_name.bv_val );
    954         lloadd_close( s );
    955     }
    956 
    957     return;
    958 }
    959 
    960 static void *
    961 lload_listener_thread( void *ctx )
    962 {
    963     /* ITS#9984 Survive the listeners being paused if we run out of fds */
    964     int rc = event_base_loop( listener_base, EVLOOP_NO_EXIT_ON_EMPTY );
    965     Debug( LDAP_DEBUG_ANY, "lload_listener_thread: "
    966             "event loop finished: rc=%d\n",
    967             rc );
    968 
    969     return (void *)NULL;
    970 }
    971 
    972 static void
    973 listener_error_cb( struct evconnlistener *lev, void *arg )
    974 {
    975     LloadListener *l = arg;
    976     int err = EVUTIL_SOCKET_ERROR();
    977 
    978     assert( l->listener == lev );
    979     if (
    980 #ifdef EMFILE
    981             err == EMFILE ||
    982 #endif /* EMFILE */
    983 #ifdef ENFILE
    984             err == ENFILE ||
    985 #endif /* ENFILE */
    986             0 ) {
    987         ldap_pvt_thread_mutex_lock( &lload_daemon[0].sd_mutex );
    988         emfile++;
    989         /* Stop listening until an existing session closes */
    990         l->sl_mute = 1;
    991         evconnlistener_disable( lev );
    992         ldap_pvt_thread_mutex_unlock( &lload_daemon[0].sd_mutex );
    993         Debug( LDAP_DEBUG_ANY, "listener_error_cb: "
    994                 "too many open files, cannot accept new connections on "
    995                 "url=%s\n",
    996                 l->sl_url.bv_val );
    997     } else {
    998         char ebuf[128];
    999         Debug( LDAP_DEBUG_ANY, "listener_error_cb: "
   1000                 "received an error on a listener, shutting down: '%s'\n",
   1001                 sock_errstr( err, ebuf, sizeof(ebuf) ) );
   1002         event_base_loopexit( l->base, NULL );
   1003     }
   1004 }
   1005 
   1006 void
   1007 listeners_reactivate( void )
   1008 {
   1009     int i;
   1010 
   1011     ldap_pvt_thread_mutex_lock( &lload_daemon[0].sd_mutex );
   1012     for ( i = 0; emfile && lload_listeners[i] != NULL; i++ ) {
   1013         LloadListener *lr = lload_listeners[i];
   1014 
   1015         if ( lr->sl_sd == AC_SOCKET_INVALID ) continue;
   1016         if ( lr->sl_mute ) {
   1017             emfile--;
   1018             evconnlistener_enable( lr->listener );
   1019             lr->sl_mute = 0;
   1020             Debug( LDAP_DEBUG_CONNS, "listeners_reactivate: "
   1021                     "reactivated listener url=%s\n",
   1022                     lr->sl_url.bv_val );
   1023         }
   1024     }
   1025     if ( emfile && lload_listeners[i] == NULL ) {
   1026         /* Walked the entire list without enabling anything; emfile
   1027          * counter is stale. Reset it. */
   1028         emfile = 0;
   1029     }
   1030     ldap_pvt_thread_mutex_unlock( &lload_daemon[0].sd_mutex );
   1031 }
   1032 
   1033 static int
   1034 lload_listener_activate( void )
   1035 {
   1036     struct evconnlistener *listener;
   1037     int l, rc;
   1038     char ebuf[128];
   1039 
   1040     listener_base = event_base_new();
   1041     if ( !listener_base ) return -1;
   1042 
   1043     for ( l = 0; lload_listeners[l] != NULL; l++ ) {
   1044         if ( lload_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue;
   1045 
   1046             /* FIXME: TCP-only! */
   1047 #ifdef LDAP_TCP_BUFFER
   1048         if ( 1 ) {
   1049             int origsize, size, realsize, rc;
   1050             socklen_t optlen;
   1051 
   1052             size = 0;
   1053             if ( lload_listeners[l]->sl_tcp_rmem > 0 ) {
   1054                 size = lload_listeners[l]->sl_tcp_rmem;
   1055             } else if ( slapd_tcp_rmem > 0 ) {
   1056                 size = slapd_tcp_rmem;
   1057             }
   1058 
   1059             if ( size > 0 ) {
   1060                 optlen = sizeof(origsize);
   1061                 rc = getsockopt( lload_listeners[l]->sl_sd, SOL_SOCKET,
   1062                         SO_RCVBUF, (void *)&origsize, &optlen );
   1063 
   1064                 if ( rc ) {
   1065                     int err = sock_errno();
   1066                     Debug( LDAP_DEBUG_ANY, "lload_listener_activate: "
   1067                             "getsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
   1068                             err, AC_STRERROR_R( err, ebuf, sizeof(ebuf) ) );
   1069                 }
   1070 
   1071                 optlen = sizeof(size);
   1072                 rc = setsockopt( lload_listeners[l]->sl_sd, SOL_SOCKET,
   1073                         SO_RCVBUF, (const void *)&size, optlen );
   1074 
   1075                 if ( rc ) {
   1076                     int err = sock_errno();
   1077                     Debug( LDAP_DEBUG_ANY, "lload_listener_activate: "
   1078                             "setsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
   1079                             err, sock_errstr( err, ebuf, sizeof(ebuf) ) );
   1080                 }
   1081 
   1082                 optlen = sizeof(realsize);
   1083                 rc = getsockopt( lload_listeners[l]->sl_sd, SOL_SOCKET,
   1084                         SO_RCVBUF, (void *)&realsize, &optlen );
   1085 
   1086                 if ( rc ) {
   1087                     int err = sock_errno();
   1088                     Debug( LDAP_DEBUG_ANY, "lload_listener_activate: "
   1089                             "getsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
   1090                             err, sock_errstr( err, ebuf, sizeof(ebuf) ) );
   1091                 }
   1092 
   1093                 Debug( LDAP_DEBUG_ANY, "lload_listener_activate: "
   1094                         "url=%s (#%d) RCVBUF original size=%d requested "
   1095                         "size=%d real size=%d\n",
   1096                         lload_listeners[l]->sl_url.bv_val, l, origsize, size,
   1097                         realsize );
   1098             }
   1099 
   1100             size = 0;
   1101             if ( lload_listeners[l]->sl_tcp_wmem > 0 ) {
   1102                 size = lload_listeners[l]->sl_tcp_wmem;
   1103             } else if ( slapd_tcp_wmem > 0 ) {
   1104                 size = slapd_tcp_wmem;
   1105             }
   1106 
   1107             if ( size > 0 ) {
   1108                 optlen = sizeof(origsize);
   1109                 rc = getsockopt( lload_listeners[l]->sl_sd, SOL_SOCKET,
   1110                         SO_SNDBUF, (void *)&origsize, &optlen );
   1111 
   1112                 if ( rc ) {
   1113                     int err = sock_errno();
   1114                     Debug( LDAP_DEBUG_ANY, "lload_listener_activate: "
   1115                             "getsockopt(SO_SNDBUF) failed errno=%d (%s)\n",
   1116                             err, sock_errstr( err, ebuf, sizeof(ebuf) ) );
   1117                 }
   1118 
   1119                 optlen = sizeof(size);
   1120                 rc = setsockopt( lload_listeners[l]->sl_sd, SOL_SOCKET,
   1121                         SO_SNDBUF, (const void *)&size, optlen );
   1122 
   1123                 if ( rc ) {
   1124                     int err = sock_errno();
   1125                     Debug( LDAP_DEBUG_ANY, "lload_listener_activate: "
   1126                             "setsockopt(SO_SNDBUF) failed errno=%d (%s)\n",
   1127                             err, sock_errstr( err, ebuf, sizeof(ebuf) ) );
   1128                 }
   1129 
   1130                 optlen = sizeof(realsize);
   1131                 rc = getsockopt( lload_listeners[l]->sl_sd, SOL_SOCKET,
   1132                         SO_SNDBUF, (void *)&realsize, &optlen );
   1133 
   1134                 if ( rc ) {
   1135                     int err = sock_errno();
   1136                     Debug( LDAP_DEBUG_ANY, "lload_listener_activate: "
   1137                             "getsockopt(SO_SNDBUF) failed errno=%d (%s)\n",
   1138                             err, sock_errstr( err, ebuf, sizeof(ebuf) ) );
   1139                 }
   1140 
   1141                 Debug( LDAP_DEBUG_ANY, "lload_listener_activate: "
   1142                         "url=%s (#%d) SNDBUF original size=%d requested "
   1143                         "size=%d real size=%d\n",
   1144                         lload_listeners[l]->sl_url.bv_val, l, origsize, size,
   1145                         realsize );
   1146             }
   1147         }
   1148 #endif /* LDAP_TCP_BUFFER */
   1149 
   1150         lload_listeners[l]->sl_busy = 1;
   1151         listener = evconnlistener_new( listener_base, lload_listener,
   1152                 lload_listeners[l],
   1153                 LEV_OPT_THREADSAFE|LEV_OPT_DEFERRED_ACCEPT,
   1154                 SLAPD_LISTEN_BACKLOG, lload_listeners[l]->sl_sd );
   1155         if ( !listener ) {
   1156             int err = sock_errno();
   1157 
   1158 #ifdef LDAP_PF_INET6
   1159             /* If error is EADDRINUSE, we are trying to listen to INADDR_ANY and
   1160              * we are already listening to in6addr_any, then we want to ignore
   1161              * this and continue.
   1162              */
   1163             if ( err == EADDRINUSE ) {
   1164                 int i;
   1165                 struct sockaddr_in sa = lload_listeners[l]->sl_sa.sa_in_addr;
   1166                 struct sockaddr_in6 sa6;
   1167 
   1168                 if ( sa.sin_family == AF_INET &&
   1169                         sa.sin_addr.s_addr == htonl( INADDR_ANY ) ) {
   1170                     for ( i = 0; i < l; i++ ) {
   1171                         sa6 = lload_listeners[i]->sl_sa.sa_in6_addr;
   1172                         if ( sa6.sin6_family == AF_INET6 &&
   1173                                 !memcmp( &sa6.sin6_addr, &in6addr_any,
   1174                                         sizeof(struct in6_addr) ) ) {
   1175                             break;
   1176                         }
   1177                     }
   1178 
   1179                     if ( i < l ) {
   1180                         /* We are already listening to in6addr_any */
   1181                         Debug( LDAP_DEBUG_CONNS, "lload_listener_activate: "
   1182                                 "Attempt to listen to 0.0.0.0 failed, "
   1183                                 "already listening on ::, assuming IPv4 "
   1184                                 "included\n" );
   1185                         lloadd_close( lload_listeners[l]->sl_sd );
   1186                         lload_listeners[l]->sl_sd = AC_SOCKET_INVALID;
   1187                         continue;
   1188                     }
   1189                 }
   1190             }
   1191 #endif /* LDAP_PF_INET6 */
   1192             Debug( LDAP_DEBUG_ANY, "lload_listener_activate: "
   1193                     "listen(%s, 5) failed errno=%d (%s)\n",
   1194                     lload_listeners[l]->sl_url.bv_val, err,
   1195                     sock_errstr( err, ebuf, sizeof(ebuf) ) );
   1196             return -1;
   1197         }
   1198 
   1199         lload_listeners[l]->base = listener_base;
   1200         lload_listeners[l]->listener = listener;
   1201         evconnlistener_set_error_cb( listener, listener_error_cb );
   1202     }
   1203 
   1204     rc = ldap_pvt_thread_create(
   1205             &listener_tid, 0, lload_listener_thread, lload_listeners[l] );
   1206 
   1207     if ( rc != 0 ) {
   1208         Debug( LDAP_DEBUG_ANY, "lload_listener_activate(%d): "
   1209                 "submit failed (%d)\n",
   1210                 lload_listeners[l]->sl_sd, rc );
   1211     }
   1212     return rc;
   1213 }
   1214 
   1215 static void *
   1216 lloadd_io_task( void *ptr )
   1217 {
   1218     int rc;
   1219     int tid = (ldap_pvt_thread_t *)ptr - daemon_tid;
   1220     struct event_base *base = lload_daemon[tid].base;
   1221     struct event *event;
   1222 
   1223     event = event_new( base, -1, EV_WRITE, daemon_wakeup_cb, ptr );
   1224     if ( !event ) {
   1225         Debug( LDAP_DEBUG_ANY, "lloadd_io_task: "
   1226                 "failed to set up the wakeup event\n" );
   1227         return (void *)-1;
   1228     }
   1229     event_add( event, NULL );
   1230     lload_daemon[tid].wakeup_event = event;
   1231 
   1232     /* run */
   1233     rc = event_base_dispatch( base );
   1234     Debug( LDAP_DEBUG_ANY, "lloadd_io_task: "
   1235             "Daemon %d, event loop finished: rc=%d\n",
   1236             tid, rc );
   1237 
   1238     if ( !slapd_gentle_shutdown ) {
   1239         slapd_abrupt_shutdown = 1;
   1240     }
   1241 
   1242     return NULL;
   1243 }
   1244 
   1245 int
   1246 lloadd_daemon( struct event_base *daemon_base )
   1247 {
   1248     int i, rc;
   1249     LloadTier *tier;
   1250     struct event_base *base;
   1251     struct event *event;
   1252     struct timeval second = { 1, 0 };
   1253 
   1254     assert( daemon_base != NULL );
   1255 
   1256     dnsbase = evdns_base_new( daemon_base, 0 );
   1257     if ( !dnsbase ) {
   1258         Debug( LDAP_DEBUG_ANY, "lloadd startup: "
   1259                 "failed to set up for async name resolution\n" );
   1260         return -1;
   1261     }
   1262 
   1263     /*
   1264      * ITS#10070: Allow both operation without working DNS (test environments)
   1265      * and e.g. containers that don't have a /etc/resolv.conf but do have a
   1266      * server listening on 127.0.0.1 which is the default.
   1267      */
   1268     (void)evdns_base_resolv_conf_parse( dnsbase,
   1269             DNS_OPTION_NAMESERVERS|DNS_OPTION_HOSTSFILE,
   1270             lload_resolvconf_path );
   1271 
   1272     if ( lload_daemon_threads > SLAPD_MAX_DAEMON_THREADS )
   1273         lload_daemon_threads = SLAPD_MAX_DAEMON_THREADS;
   1274 
   1275     daemon_tid =
   1276             ch_malloc( lload_daemon_threads * sizeof(ldap_pvt_thread_t) );
   1277 
   1278     for ( i = 0; i < lload_daemon_threads; i++ ) {
   1279         base = event_base_new();
   1280         if ( !base ) {
   1281             Debug( LDAP_DEBUG_ANY, "lloadd startup: "
   1282                     "failed to acquire event base for an I/O thread\n" );
   1283             return -1;
   1284         }
   1285         lload_daemon[i].base = base;
   1286 
   1287         ldap_pvt_thread_mutex_init( &lload_daemon[i].sd_mutex );
   1288         /* threads that handle client and upstream sockets */
   1289         rc = ldap_pvt_thread_create(
   1290                 &daemon_tid[i], 0, lloadd_io_task, &daemon_tid[i] );
   1291 
   1292         if ( rc != 0 ) {
   1293             Debug( LDAP_DEBUG_ANY, "lloadd startup: "
   1294                     "listener ldap_pvt_thread_create failed (%d)\n",
   1295                     rc );
   1296             return rc;
   1297         }
   1298     }
   1299 
   1300     if ( (rc = lload_listener_activate()) != 0 ) {
   1301         return rc;
   1302     }
   1303 
   1304     LDAP_STAILQ_FOREACH ( tier, &tiers, t_next ) {
   1305         if ( tier->t_type.tier_startup( tier ) ) {
   1306             return -1;
   1307         }
   1308     }
   1309 
   1310     event = event_new( daemon_base, -1, EV_TIMEOUT|EV_PERSIST,
   1311             lload_tiers_update, NULL );
   1312     if ( !event ) {
   1313         Debug( LDAP_DEBUG_ANY, "lloadd: "
   1314                 "failed to allocate stats update event\n" );
   1315         return -1;
   1316     }
   1317     lload_stats_event = event;
   1318     event_add( event, &second );
   1319 
   1320     event = evtimer_new( daemon_base, operations_timeout, event_self_cbarg() );
   1321     if ( !event ) {
   1322         Debug( LDAP_DEBUG_ANY, "lloadd: "
   1323                 "failed to allocate timeout event\n" );
   1324         return -1;
   1325     }
   1326     lload_timeout_event = event;
   1327 
   1328     /* TODO: should we just add it with any timeout and re-add when the timeout
   1329      * changes? */
   1330     if ( lload_timeout_api ) {
   1331         event_add( event, lload_timeout_api );
   1332     }
   1333 
   1334     checked_lock( &lload_wait_mutex );
   1335     lloadd_inited = 1;
   1336     ldap_pvt_thread_cond_signal( &lload_wait_cond );
   1337     checked_unlock( &lload_wait_mutex );
   1338 #if !defined(BALANCER_MODULE) && defined(HAVE_SYSTEMD)
   1339     rc = sd_notify( 1, "READY=1" );
   1340     if ( rc < 0 ) {
   1341         Debug( LDAP_DEBUG_ANY, "lloadd startup: "
   1342             "systemd sd_notify failed (%d)\n", rc );
   1343     }
   1344 #endif /* !BALANCER_MODULE && HAVE_SYSTEMD */
   1345 
   1346     rc = event_base_dispatch( daemon_base );
   1347     Debug( LDAP_DEBUG_ANY, "lloadd shutdown: "
   1348             "Main event loop finished: rc=%d\n",
   1349             rc );
   1350 
   1351     /* shutdown */
   1352     event_base_loopexit( listener_base, 0 );
   1353 
   1354     /* wait for the listener threads to complete */
   1355     destroy_listeners();
   1356 
   1357     /* Mark upstream connections closing and prevent from opening new ones */
   1358     lload_tiers_shutdown();
   1359 
   1360     /* Do the same for clients */
   1361     clients_destroy( 1 );
   1362 
   1363     for ( i = 0; i < lload_daemon_threads; i++ ) {
   1364         /*
   1365          * https://github.com/libevent/libevent/issues/623
   1366          * deleting the event doesn't notify the base, just activate it and
   1367          * let it delete itself
   1368          */
   1369         event_active( lload_daemon[i].wakeup_event, EV_READ, 0 );
   1370     }
   1371 
   1372     for ( i = 0; i < lload_daemon_threads; i++ ) {
   1373         ldap_pvt_thread_join( daemon_tid[i], (void *)NULL );
   1374     }
   1375 
   1376 #ifndef BALANCER_MODULE
   1377     if ( LogTest( LDAP_DEBUG_ANY ) ) {
   1378         int t = ldap_pvt_thread_pool_backload( &connection_pool );
   1379         Debug( LDAP_DEBUG_ANY, "lloadd shutdown: "
   1380                 "waiting for %d operations/tasks to finish\n",
   1381                 t );
   1382     }
   1383     ldap_pvt_thread_pool_close( &connection_pool, 1 );
   1384 #endif
   1385 
   1386     lload_tiers_destroy();
   1387     clients_destroy( 0 );
   1388     lload_bindconf_free( &bindconf );
   1389     evdns_base_free( dnsbase, 0 );
   1390 
   1391     ch_free( daemon_tid );
   1392     daemon_tid = NULL;
   1393 
   1394     lloadd_daemon_destroy();
   1395 
   1396     /* If we're a slapd module, let the thread that initiated the shut down
   1397      * know we've finished */
   1398     checked_lock( &lload_wait_mutex );
   1399     ldap_pvt_thread_cond_signal( &lload_wait_cond );
   1400     checked_unlock( &lload_wait_mutex );
   1401 
   1402     return 0;
   1403 }
   1404 
   1405 static void
   1406 daemon_wakeup_cb( evutil_socket_t sig, short what, void *arg )
   1407 {
   1408     int tid = (ldap_pvt_thread_t *)arg - daemon_tid;
   1409 
   1410     Debug( LDAP_DEBUG_TRACE, "daemon_wakeup_cb: "
   1411             "Daemon thread %d woken up\n",
   1412             tid );
   1413     event_del( lload_daemon[tid].wakeup_event );
   1414 }
   1415 
   1416 LloadChange lload_change = { .type = LLOAD_CHANGE_UNDEFINED };
   1417 
   1418 #ifdef BALANCER_MODULE
   1419 int
   1420 backend_conn_cb( ldap_pvt_thread_start_t *start, void *startarg, void *arg )
   1421 {
   1422     LloadConnection *c = startarg;
   1423     LloadBackend *b = arg;
   1424 
   1425     if ( b == NULL || c->c_backend == b ) {
   1426         CONNECTION_LOCK_DESTROY(c);
   1427         return 1;
   1428     }
   1429     return 0;
   1430 }
   1431 
   1432 #ifdef HAVE_TLS
   1433 int
   1434 client_tls_cb( ldap_pvt_thread_start_t *start, void *startarg, void *arg )
   1435 {
   1436     LloadConnection *c = startarg;
   1437 
   1438     if ( c->c_destroy == client_destroy &&
   1439             c->c_is_tls == LLOAD_TLS_ESTABLISHED ) {
   1440         CONNECTION_LOCK_DESTROY(c);
   1441         return 1;
   1442     }
   1443     return 0;
   1444 }
   1445 #endif /* HAVE_TLS */
   1446 
   1447 static int
   1448 detach_linked_backend_cb( LloadConnection *client, LloadBackend *b )
   1449 {
   1450     int rc = LDAP_SUCCESS;
   1451 
   1452     if ( client->c_backend != b ) {
   1453         return rc;
   1454     }
   1455 
   1456     Debug( LDAP_DEBUG_CONNS, "detach_linked_backend_cb: "
   1457             "detaching backend '%s' from connid=%lu%s\n",
   1458             b->b_name.bv_val, client->c_connid,
   1459             client->c_restricted == LLOAD_OP_RESTRICTED_BACKEND ?
   1460                 " and closing the connection" :
   1461                 "" );
   1462 
   1463     /* We were approached from the connection list */
   1464     assert( IS_ALIVE( client, c_refcnt ) );
   1465 
   1466     assert( client->c_restricted == LLOAD_OP_RESTRICTED_WRITE ||
   1467             client->c_restricted == LLOAD_OP_RESTRICTED_BACKEND );
   1468     if ( client->c_restricted == LLOAD_OP_RESTRICTED_BACKEND ) {
   1469         int gentle = 1;
   1470         CONNECTION_LOCK(client);
   1471         rc = lload_connection_close( client, &gentle );
   1472         CONNECTION_UNLOCK(client);
   1473     }
   1474 
   1475     client->c_restricted = LLOAD_OP_NOT_RESTRICTED;
   1476     client->c_restricted_at = 0;
   1477     client->c_restricted_inflight = 0;
   1478 
   1479     return rc;
   1480 }
   1481 
   1482 void
   1483 lload_handle_backend_invalidation( LloadChange *change )
   1484 {
   1485     LloadBackend *b = change->target;
   1486     LloadTier *tier = b->b_tier;
   1487 
   1488     assert( change->object == LLOAD_BACKEND );
   1489 
   1490     if ( change->type == LLOAD_CHANGE_ADD ) {
   1491         BackendInfo *mi = backend_info( "monitor" );
   1492 
   1493         if ( mi ) {
   1494             monitor_extra_t *mbe = mi->bi_extra;
   1495             if ( mbe->is_configured() ) {
   1496                 lload_monitor_backend_init( mi, tier->t_monitor, b );
   1497             }
   1498         }
   1499 
   1500         if ( tier->t_type.tier_change ) {
   1501             tier->t_type.tier_change( tier, change );
   1502         }
   1503 
   1504         checked_lock( &b->b_mutex );
   1505         backend_retry( b );
   1506         checked_unlock( &b->b_mutex );
   1507         return;
   1508     } else if ( change->type == LLOAD_CHANGE_DEL ) {
   1509         ldap_pvt_thread_pool_walk(
   1510                 &connection_pool, handle_pdus, backend_conn_cb, b );
   1511         ldap_pvt_thread_pool_walk(
   1512                 &connection_pool, upstream_bind, backend_conn_cb, b );
   1513 
   1514         checked_lock( &clients_mutex );
   1515         connections_walk(
   1516                 &clients_mutex, &clients,
   1517                 (CONNCB)detach_linked_backend_cb, b );
   1518         checked_unlock( &clients_mutex );
   1519 
   1520         if ( tier->t_type.tier_change ) {
   1521             tier->t_type.tier_change( tier, change );
   1522         }
   1523         lload_backend_destroy( b );
   1524         return;
   1525     }
   1526     assert( change->type == LLOAD_CHANGE_MODIFY );
   1527 
   1528     /*
   1529      * A change that can't be handled gracefully, terminate all connections and
   1530      * start over.
   1531      */
   1532     if ( change->flags.backend & LLOAD_BACKEND_MOD_OTHER ) {
   1533         ldap_pvt_thread_pool_walk(
   1534                 &connection_pool, handle_pdus, backend_conn_cb, b );
   1535         ldap_pvt_thread_pool_walk(
   1536                 &connection_pool, upstream_bind, backend_conn_cb, b );
   1537         checked_lock( &b->b_mutex );
   1538         backend_reset( b, 0 );
   1539         backend_retry( b );
   1540         checked_unlock( &b->b_mutex );
   1541         return;
   1542     }
   1543 
   1544     /*
   1545      * Handle changes to number of connections:
   1546      * - a change might get the connection limit above the pool size:
   1547      *   - consider closing (in order of priority?):
   1548      *     - connections awaiting connect() completion
   1549      *     - connections currently preparing
   1550      *     - bind connections over limit (which is 0 if 'feature vc' is on
   1551      *     - regular connections over limit
   1552      * - below pool size
   1553      *   - call backend_retry if there are no opening connections
   1554      * - one pool size above and one below the configured size
   1555      *   - still close the ones above limit, it should sort itself out
   1556      *     the only issue is if a closing connection isn't guaranteed to do
   1557      *     that at some point
   1558      */
   1559     if ( change->flags.backend & LLOAD_BACKEND_MOD_CONNS ) {
   1560         int bind_requested = 0, need_close = 0, need_open = 0;
   1561         LloadConnection *c;
   1562 
   1563         bind_requested =
   1564 #ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS
   1565                 (lload_features & LLOAD_FEATURE_VC) ? 0 :
   1566 #endif /* LDAP_API_FEATURE_VERIFY_CREDENTIALS */
   1567                 b->b_numbindconns;
   1568 
   1569         if ( b->b_bindavail > bind_requested ) {
   1570             need_close += b->b_bindavail - bind_requested;
   1571         } else if ( b->b_bindavail < bind_requested ) {
   1572             need_open = 1;
   1573         }
   1574 
   1575         if ( b->b_active > b->b_numconns ) {
   1576             need_close += b->b_active - b->b_numconns;
   1577         } else if ( b->b_active < b->b_numconns ) {
   1578             need_open = 1;
   1579         }
   1580 
   1581         if ( !need_open ) {
   1582             need_close += b->b_opening;
   1583 
   1584             while ( !LDAP_LIST_EMPTY( &b->b_connecting ) ) {
   1585                 LloadPendingConnection *p = LDAP_LIST_FIRST( &b->b_connecting );
   1586 
   1587                 LDAP_LIST_REMOVE( p, next );
   1588                 event_free( p->event );
   1589                 evutil_closesocket( p->fd );
   1590                 ch_free( p );
   1591                 b->b_opening--;
   1592                 need_close--;
   1593             }
   1594         }
   1595 
   1596         if ( need_close || !need_open ) {
   1597             /* It might be too late to repurpose a preparing connection, just
   1598              * close them all */
   1599             while ( !LDAP_CIRCLEQ_EMPTY( &b->b_preparing ) ) {
   1600                 c = LDAP_CIRCLEQ_FIRST( &b->b_preparing );
   1601 
   1602                 event_del( c->c_read_event );
   1603                 CONNECTION_LOCK_DESTROY(c);
   1604                 assert( c == NULL );
   1605                 b->b_opening--;
   1606                 need_close--;
   1607             }
   1608             if ( event_pending( b->b_retry_event, EV_TIMEOUT, NULL ) ) {
   1609                 event_del( b->b_retry_event );
   1610                 b->b_opening--;
   1611             }
   1612             assert( b->b_opening == 0 );
   1613         }
   1614 
   1615         if ( b->b_bindavail > bind_requested ) {
   1616             int diff = b->b_bindavail - bind_requested;
   1617 
   1618             assert( need_close >= diff );
   1619 
   1620             LDAP_CIRCLEQ_FOREACH ( c, &b->b_bindconns, c_next ) {
   1621                 int gentle = 1;
   1622 
   1623                 lload_connection_close( c, &gentle );
   1624                 need_close--;
   1625                 diff--;
   1626                 if ( !diff ) {
   1627                     break;
   1628                 }
   1629             }
   1630             assert( diff == 0 );
   1631         }
   1632 
   1633         if ( b->b_active > b->b_numconns ) {
   1634             int diff = b->b_active - b->b_numconns;
   1635 
   1636             assert( need_close >= diff );
   1637 
   1638             LDAP_CIRCLEQ_FOREACH ( c, &b->b_conns, c_next ) {
   1639                 int gentle = 1;
   1640 
   1641                 lload_connection_close( c, &gentle );
   1642                 need_close--;
   1643                 diff--;
   1644                 if ( !diff ) {
   1645                     break;
   1646                 }
   1647             }
   1648             assert( diff == 0 );
   1649         }
   1650         assert( need_close == 0 );
   1651 
   1652         if ( need_open ) {
   1653             checked_lock( &b->b_mutex );
   1654             backend_retry( b );
   1655             checked_unlock( &b->b_mutex );
   1656         }
   1657     }
   1658 }
   1659 
   1660 void
   1661 lload_handle_tier_invalidation( LloadChange *change )
   1662 {
   1663     LloadTier *tier;
   1664 
   1665     assert( change->object == LLOAD_TIER );
   1666     tier = change->target;
   1667 
   1668     if ( change->type == LLOAD_CHANGE_ADD ) {
   1669         BackendInfo *mi = backend_info( "monitor" );
   1670 
   1671         if ( mi ) {
   1672             monitor_extra_t *mbe = mi->bi_extra;
   1673             if ( mbe->is_configured() ) {
   1674                 lload_monitor_tier_init( mi, tier );
   1675             }
   1676         }
   1677 
   1678         tier->t_type.tier_startup( tier );
   1679         if ( LDAP_STAILQ_EMPTY( &tiers ) ) {
   1680             LDAP_STAILQ_INSERT_HEAD( &tiers, tier, t_next );
   1681         } else {
   1682             LDAP_STAILQ_INSERT_TAIL( &tiers, tier, t_next );
   1683         }
   1684         return;
   1685     } else if ( change->type == LLOAD_CHANGE_DEL ) {
   1686         LDAP_STAILQ_REMOVE( &tiers, tier, LloadTier, t_next );
   1687         tier->t_type.tier_reset( tier, 1 );
   1688         tier->t_type.tier_destroy( tier );
   1689         return;
   1690     }
   1691     assert( change->type == LLOAD_CHANGE_MODIFY );
   1692 
   1693     if ( tier->t_type.tier_change ) {
   1694         tier->t_type.tier_change( tier, change );
   1695     }
   1696 }
   1697 
   1698 void
   1699 lload_handle_global_invalidation( LloadChange *change )
   1700 {
   1701     assert( change->type == LLOAD_CHANGE_MODIFY );
   1702     assert( change->object == LLOAD_DAEMON );
   1703 
   1704     if ( change->flags.daemon & LLOAD_DAEMON_MOD_THREADS ) {
   1705         /* walk the task queue to remove any tasks belonging to us. */
   1706         /* TODO: initiate a full module restart, everything will fall into
   1707          * place at that point */
   1708         ldap_pvt_thread_pool_walk(
   1709                 &connection_pool, handle_pdus, backend_conn_cb, NULL );
   1710         ldap_pvt_thread_pool_walk(
   1711                 &connection_pool, upstream_bind, backend_conn_cb, NULL );
   1712         assert(0);
   1713         return;
   1714     }
   1715 
   1716     if ( change->flags.daemon & LLOAD_DAEMON_MOD_FEATURES ) {
   1717         lload_features_t feature_diff =
   1718                 lload_features ^ ( ~(uintptr_t)change->target );
   1719         /* Feature change handling:
   1720          * - VC (TODO):
   1721          *   - on: terminate all bind connections
   1722          *   - off: cancel all bind operations in progress, reopen bind connections
   1723          * - ProxyAuthz:
   1724          *   - on: nothing needed
   1725          *   - off: clear c_auth/privileged on each client
   1726          * - read pause (WIP):
   1727          *   - nothing needed?
   1728          */
   1729 
   1730         assert( change->target );
   1731         if ( feature_diff & LLOAD_FEATURE_VC ) {
   1732             assert(0);
   1733             feature_diff &= ~LLOAD_FEATURE_VC;
   1734         }
   1735         if ( feature_diff & LLOAD_FEATURE_PAUSE ) {
   1736             feature_diff &= ~LLOAD_FEATURE_PAUSE;
   1737         }
   1738         if ( feature_diff & LLOAD_FEATURE_PROXYAUTHZ ) {
   1739             if ( !(lload_features & LLOAD_FEATURE_PROXYAUTHZ) ) {
   1740                 LloadConnection *c;
   1741                 /* We switched proxyauthz off */
   1742                 LDAP_CIRCLEQ_FOREACH ( c, &clients, c_next ) {
   1743                     if ( !BER_BVISNULL( &c->c_auth ) ) {
   1744                         ber_memfree( c->c_auth.bv_val );
   1745                         BER_BVZERO( &c->c_auth );
   1746                     }
   1747                     if ( c->c_type == LLOAD_C_PRIVILEGED ) {
   1748                         c->c_type = LLOAD_C_OPEN;
   1749                     }
   1750                 }
   1751             }
   1752             feature_diff &= ~LLOAD_FEATURE_PROXYAUTHZ;
   1753         }
   1754         assert( !feature_diff );
   1755     }
   1756 
   1757 #ifdef HAVE_TLS
   1758     if ( change->flags.daemon & LLOAD_DAEMON_MOD_TLS ) {
   1759         /* terminate all clients with TLS set up */
   1760         ldap_pvt_thread_pool_walk(
   1761                 &connection_pool, handle_pdus, client_tls_cb, NULL );
   1762         if ( !LDAP_CIRCLEQ_EMPTY( &clients ) ) {
   1763             LloadConnection *c = LDAP_CIRCLEQ_FIRST( &clients );
   1764             unsigned long first_connid = c->c_connid;
   1765 
   1766             while ( c ) {
   1767                 LloadConnection *next =
   1768                         LDAP_CIRCLEQ_LOOP_NEXT( &clients, c, c_next );
   1769                 if ( c->c_is_tls ) {
   1770                     CONNECTION_LOCK_DESTROY(c);
   1771                     assert( c == NULL );
   1772                 }
   1773                 c = next;
   1774                 if ( c->c_connid <= first_connid ) {
   1775                     c = NULL;
   1776                 }
   1777             }
   1778         }
   1779     }
   1780 #endif /* HAVE_TLS */
   1781 
   1782     if ( change->flags.daemon & LLOAD_DAEMON_MOD_BINDCONF ) {
   1783         LloadConnection *c;
   1784 
   1785         /*
   1786          * Only timeout changes can be handled gracefully, terminate all
   1787          * connections and start over.
   1788          */
   1789         ldap_pvt_thread_pool_walk(
   1790                 &connection_pool, handle_pdus, backend_conn_cb, NULL );
   1791         ldap_pvt_thread_pool_walk(
   1792                 &connection_pool, upstream_bind, backend_conn_cb, NULL );
   1793 
   1794         lload_tiers_reset( 0 );
   1795 
   1796         /* Reconsider the PRIVILEGED flag on all clients */
   1797         LDAP_CIRCLEQ_FOREACH ( c, &clients, c_next ) {
   1798             int privileged = ber_bvstrcasecmp( &c->c_auth, &lloadd_identity );
   1799 
   1800             /* We have just terminated all pending operations (even pins), there
   1801              * should be no connections still binding/closing */
   1802             assert( c->c_state == LLOAD_C_READY );
   1803 
   1804             c->c_type = privileged ? LLOAD_C_PRIVILEGED : LLOAD_C_OPEN;
   1805         }
   1806     }
   1807 }
   1808 
   1809 int
   1810 lload_handle_invalidation( LloadChange *change )
   1811 {
   1812     if ( (change->type == LLOAD_CHANGE_MODIFY) &&
   1813             change->flags.generic == 0 ) {
   1814         Debug( LDAP_DEBUG_ANY, "lload_handle_invalidation: "
   1815                 "a modify where apparently nothing changed\n" );
   1816     }
   1817 
   1818     switch ( change->object ) {
   1819         case LLOAD_BACKEND:
   1820             lload_handle_backend_invalidation( change );
   1821             break;
   1822         case LLOAD_TIER:
   1823             lload_handle_tier_invalidation( change );
   1824             break;
   1825         case LLOAD_DAEMON:
   1826             lload_handle_global_invalidation( change );
   1827             break;
   1828         default:
   1829             Debug( LDAP_DEBUG_ANY, "lload_handle_invalidation: "
   1830                     "unrecognised change\n" );
   1831             assert(0);
   1832     }
   1833 
   1834     return LDAP_SUCCESS;
   1835 }
   1836 
   1837 static void
   1838 lload_pause_event_cb( evutil_socket_t s, short what, void *arg )
   1839 {
   1840     /*
   1841      * We are pausing, signal the pausing thread we've finished and
   1842      * wait until the thread pool resumes operation.
   1843      *
   1844      * Do this in lockstep with the pausing thread.
   1845      */
   1846     checked_lock( &lload_wait_mutex );
   1847     ldap_pvt_thread_cond_signal( &lload_wait_cond );
   1848 
   1849     /* Now wait until we unpause, then we can resume operation */
   1850     ldap_pvt_thread_cond_wait( &lload_pause_cond, &lload_wait_mutex );
   1851     checked_unlock( &lload_wait_mutex );
   1852 }
   1853 
   1854 /*
   1855  * Signal the event base to terminate processing as soon as it can and wait for
   1856  * lload_pause_event_cb to notify us this has happened.
   1857  */
   1858 static int
   1859 lload_pause_base( struct event_base *base )
   1860 {
   1861     int rc;
   1862 
   1863     checked_lock( &lload_wait_mutex );
   1864     event_base_once( base, -1, EV_TIMEOUT, lload_pause_event_cb, base, NULL );
   1865     rc = ldap_pvt_thread_cond_wait( &lload_wait_cond, &lload_wait_mutex );
   1866     checked_unlock( &lload_wait_mutex );
   1867 
   1868     return rc;
   1869 }
   1870 
   1871 void
   1872 lload_pause_server( void )
   1873 {
   1874     LloadChange ch = { .type = LLOAD_CHANGE_UNDEFINED };
   1875     int i;
   1876 
   1877     lload_pause_base( listener_base );
   1878     lload_pause_base( daemon_base );
   1879 
   1880     for ( i = 0; i < lload_daemon_threads; i++ ) {
   1881         lload_pause_base( lload_daemon[i].base );
   1882     }
   1883 
   1884     lload_change = ch;
   1885 }
   1886 
   1887 void
   1888 lload_unpause_server( void )
   1889 {
   1890     if ( lload_change.type != LLOAD_CHANGE_UNDEFINED ) {
   1891         lload_handle_invalidation( &lload_change );
   1892     }
   1893 
   1894     /*
   1895      * Make sure lloadd is completely ready to unpause by now:
   1896      *
   1897      * After the broadcast, we handle I/O and begin filling the thread pool, in
   1898      * high load conditions, we might hit the pool limits and start processing
   1899      * operations in the I/O threads (one PDU per socket at a time for fairness
   1900      * sake) even before a pause has finished from slapd's point of view!
   1901      *
   1902      * When (max_pdus_per_cycle == 0) we don't use the pool for these at all and
   1903      * most lload processing starts immediately making this even more prominent.
   1904      */
   1905     ldap_pvt_thread_cond_broadcast( &lload_pause_cond );
   1906 }
   1907 #endif /* BALANCER_MODULE */
   1908 
   1909 void
   1910 lload_sig_shutdown( evutil_socket_t sig, short what, void *arg )
   1911 {
   1912     struct event_base *daemon_base = arg;
   1913     int save_errno = errno;
   1914     int i;
   1915 
   1916     /*
   1917      * If the NT Service Manager is controlling the server, we don't
   1918      * want SIGBREAK to kill the server. For some strange reason,
   1919      * SIGBREAK is generated when a user logs out.
   1920      */
   1921 
   1922 #if defined(HAVE_NT_SERVICE_MANAGER) && defined(SIGBREAK)
   1923     if ( is_NT_Service && sig == SIGBREAK ) {
   1924         /* empty */;
   1925     } else
   1926 #endif /* HAVE_NT_SERVICE_MANAGER && SIGBREAK */
   1927 #ifdef SIGHUP
   1928     if ( sig == SIGHUP && global_gentlehup && slapd_gentle_shutdown == 0 ) {
   1929         slapd_gentle_shutdown = 1;
   1930     } else
   1931 #endif /* SIGHUP */
   1932     {
   1933         slapd_shutdown = 1;
   1934     }
   1935 
   1936     for ( i = 0; i < lload_daemon_threads; i++ ) {
   1937         event_base_loopexit( lload_daemon[i].base, NULL );
   1938     }
   1939     event_base_loopexit( daemon_base, NULL );
   1940 
   1941     errno = save_errno;
   1942 }
   1943 
   1944 struct event_base *
   1945 lload_get_base( ber_socket_t s )
   1946 {
   1947     int tid = DAEMON_ID(s);
   1948     return lload_daemon[tid].base;
   1949 }
   1950 
   1951 LloadListener **
   1952 lloadd_get_listeners( void )
   1953 {
   1954     /* Could return array with no listeners if !listening, but current
   1955      * callers mostly look at the URLs.  E.g. syncrepl uses this to
   1956      * identify the server, which means it wants the startup arguments.
   1957      */
   1958     return lload_listeners;
   1959 }
   1960 
   1961 /* Reject all incoming requests */
   1962 void
   1963 lload_suspend_listeners( void )
   1964 {
   1965     int i;
   1966     for ( i = 0; lload_listeners[i]; i++ ) {
   1967         lload_listeners[i]->sl_mute = 1;
   1968         evconnlistener_disable( lload_listeners[i]->listener );
   1969         listen( lload_listeners[i]->sl_sd, 0 );
   1970     }
   1971 }
   1972 
   1973 /* Resume after a suspend */
   1974 void
   1975 lload_resume_listeners( void )
   1976 {
   1977     int i;
   1978     for ( i = 0; lload_listeners[i]; i++ ) {
   1979         lload_listeners[i]->sl_mute = 0;
   1980         listen( lload_listeners[i]->sl_sd, SLAPD_LISTEN_BACKLOG );
   1981         evconnlistener_enable( lload_listeners[i]->listener );
   1982     }
   1983 }
   1984