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