lload.h 13.9 KB
Newer Older
1
/* lload.h - load balancer include file */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 *
 * Copyright 1998-2015 The OpenLDAP Foundation.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
 */
/* Portions Copyright (c) 1995 Regents of the University of Michigan.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that this notice is preserved and that due credit is given
 * to the University of Michigan at Ann Arbor. The name of the University
 * may not be used to endorse or promote products derived from this
 * software without specific prior written permission. This software
 * is provided ``as is'' without express or implied warranty.
 */

27
28
#ifndef _LLOAD_H_
#define _LLOAD_H_
Ondřej Kuzník's avatar
Ondřej Kuzník committed
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

#include "ldap_defaults.h"

#include <stdio.h>
#include <ac/stdlib.h>

#include <sys/types.h>
#include <ac/syslog.h>
#include <ac/regex.h>
#include <ac/signal.h>
#include <ac/socket.h>
#include <ac/time.h>
#include <ac/param.h>

#include "avl.h"

45
#include "../servers/slapd/slap.h"
46
#include "../slapd/back-monitor/back-monitor.h"
47

Ondřej Kuzník's avatar
Ondřej Kuzník committed
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#ifndef ldap_debug
#define ldap_debug slap_debug
#endif

#include "ldap_log.h"

#include <ldap.h>
#include <ldap_schema.h>

#include "lber_pvt.h"
#include "ldap_pvt.h"
#include "ldap_pvt_thread.h"
#include "ldap_queue.h"

#include <event2/event.h>

64
65
66
67
68
69
70
71
#ifdef HAVE_CYRUS_SASL
#ifdef HAVE_SASL_SASL_H
#include <sasl/sasl.h>
#else
#include <sasl.h>
#endif
#endif /* HAVE_CYRUS_SASL */

Ondřej Kuzník's avatar
Ondřej Kuzník committed
72
73
LDAP_BEGIN_DECL

74
75
76
#ifdef SERVICE_NAME
#undef SERVICE_NAME
#endif
Ondřej Kuzník's avatar
Ondřej Kuzník committed
77

78
#define SERVICE_NAME OPENLDAP_PACKAGE "-lloadd"
Ondřej Kuzník's avatar
Ondřej Kuzník committed
79

80
#define LLOAD_SB_MAX_INCOMING_CLIENT ( ( 1 << 24 ) - 1 )
81
#define LLOAD_SB_MAX_INCOMING_UPSTREAM ( ( 1 << 24 ) - 1 )
Ondřej Kuzník's avatar
Ondřej Kuzník committed
82

83
#define LLOAD_CONN_MAX_PDUS_PER_CYCLE_DEFAULT 10
Ondřej Kuzník's avatar
Ondřej Kuzník committed
84

85
86
#define BER_BV_OPTIONAL( bv ) ( BER_BVISNULL( bv ) ? NULL : ( bv ) )

87
88
89
90
typedef struct LloadBackend LloadBackend;
typedef struct LloadPendingConnection LloadPendingConnection;
typedef struct LloadConnection LloadConnection;
typedef struct LloadOperation LloadOperation;
91
typedef struct LloadChange LloadChange;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
92
93
/* end of forward declarations */

94
95
typedef LDAP_CIRCLEQ_HEAD(BeSt, LloadBackend) lload_b_head;
typedef LDAP_CIRCLEQ_HEAD(ConnSt, LloadConnection) lload_c_head;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
96

97
98
LDAP_SLAPD_V (lload_b_head) backend;
LDAP_SLAPD_V (lload_c_head) clients;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
99
LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) backend_mutex;
100
LDAP_SLAPD_V (LloadBackend *) current_backend;
101
LDAP_SLAPD_V (struct slap_bindconf) bindconf;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
102
LDAP_SLAPD_V (struct berval) lloadd_identity;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
103

Ondřej Kuzník's avatar
Ondřej Kuzník committed
104
105
106
107
108
/* Used to coordinate server (un)pause, shutdown */
LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) lload_wait_mutex;
LDAP_SLAPD_V (ldap_pvt_thread_cond_t) lload_pause_cond;
LDAP_SLAPD_V (ldap_pvt_thread_cond_t) lload_wait_cond;

109
typedef int lload_cf_aux_table_parse_x( struct berval *val,
Ondřej Kuzník's avatar
Ondřej Kuzník committed
110
111
112
113
114
        void *bc,
        slap_cf_aux_table *tab0,
        const char *tabmsg,
        int unparse );

115
typedef struct LloadListener LloadListener;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
116

117
118
119
120
121
122
123
enum lc_type {
    LLOAD_CHANGE_UNDEFINED = 0,
    LLOAD_CHANGE_MODIFY,
    LLOAD_CHANGE_ADD,
    LLOAD_CHANGE_DEL,
};

124
125
126
enum lc_object {
    LLOAD_UNDEFINED = 0,
    LLOAD_DAEMON,
127
    /*
128
    LLOAD_BINDCONF,
129
    */
130
131
132
133
134
135
136
    LLOAD_BACKEND,
};

enum lcf_daemon {
    LLOAD_DAEMON_MOD_THREADS = 1 << 0,
    LLOAD_DAEMON_MOD_FEATURES = 1 << 1,
    LLOAD_DAEMON_MOD_TLS = 1 << 2,
137
138
    LLOAD_DAEMON_MOD_LISTENER_ADD = 1 << 3,
    LLOAD_DAEMON_MOD_LISTENER_REPLACE = 1 << 4,
139
    LLOAD_DAEMON_MOD_BINDCONF = 1 << 5,
140
141
142
143
144
145
146
147
};

enum lcf_backend {
    LLOAD_BACKEND_MOD_OTHER = 1 << 0,
    LLOAD_BACKEND_MOD_CONNS = 1 << 1,
};

struct LloadChange {
148
    enum lc_type type;
149
150
151
152
153
154
155
    enum lc_object object;
    union {
        int generic;
        enum lcf_daemon daemon;
        enum lcf_backend backend;
    } flags;
    void *target;
156
} lload_change;
157

Ondřej Kuzník's avatar
Ondřej Kuzník committed
158
typedef enum {
159
#ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS
Ondřej Kuzník's avatar
Ondřej Kuzník committed
160
    LLOAD_FEATURE_VC = 1 << 0,
161
#endif /* LDAP_API_FEATURE_VERIFY_CREDENTIALS */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
162
163
164
    LLOAD_FEATURE_PROXYAUTHZ = 1 << 1,
} lload_features_t;

165
166
167
168
169
170
#ifdef BALANCER_MODULE
#define LLOAD_TLS_CTX ( lload_use_slap_tls_ctx ? slap_tls_ctx : lload_tls_ctx )
#else
#define LLOAD_TLS_CTX ( lload_tls_ctx )
#endif

Ondřej Kuzník's avatar
Ondřej Kuzník committed
171
172
173
enum lload_tls_type {
    LLOAD_CLEARTEXT = 0,
    LLOAD_LDAPS,
Ondřej Kuzník's avatar
Ondřej Kuzník committed
174
    LLOAD_STARTTLS_OPTIONAL,
Ondřej Kuzník's avatar
Ondřej Kuzník committed
175
    LLOAD_STARTTLS,
Ondřej Kuzník's avatar
Ondřej Kuzník committed
176
    LLOAD_TLS_ESTABLISHED,
Ondřej Kuzník's avatar
Ondřej Kuzník committed
177
178
};

179
180
struct LloadPendingConnection {
    LloadBackend *backend;
181
182
183
184

    struct event *event;
    ber_socket_t fd;

185
    LDAP_LIST_ENTRY(LloadPendingConnection) next;
186
187
};

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
typedef struct lload_counters_t {
    ldap_pvt_mp_t lc_ops_completed;
    ldap_pvt_mp_t lc_ops_received;
    ldap_pvt_mp_t lc_ops_forwarded;
    ldap_pvt_mp_t lc_ops_rejected;
    ldap_pvt_mp_t lc_ops_failed;
} lload_counters_t;

enum {
    LLOAD_STATS_OPS_BIND = 0,
    LLOAD_STATS_OPS_OTHER,
    LLOAD_STATS_OPS_LAST
};

typedef struct lload_global_stats_t {
    ldap_pvt_mp_t global_incoming;
    ldap_pvt_mp_t global_outgoing;
    lload_counters_t counters[LLOAD_STATS_OPS_LAST];
} lload_global_stats_t;

Ondřej Kuzník's avatar
Ondřej Kuzník committed
208
/* Can hold mutex when locking a linked connection */
209
struct LloadBackend {
Ondřej Kuzník's avatar
Ondřej Kuzník committed
210
    ldap_pvt_thread_mutex_t b_mutex;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
211

Ondřej Kuzník's avatar
Ondřej Kuzník committed
212
    struct berval b_name, b_uri;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
213
    int b_proto, b_port;
214
    enum lload_tls_type b_tls, b_tls_conf;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
215
216
    char *b_host;

217
218
219
220
    int b_retry_timeout, b_failed;
    struct event *b_retry_event;
    struct timeval b_retry_tv;

Ondřej Kuzník's avatar
Ondřej Kuzník committed
221
    int b_numconns, b_numbindconns;
222
    int b_bindavail, b_active, b_opening;
223
224
225
    lload_c_head b_conns, b_bindconns, b_preparing;
    LDAP_LIST_HEAD(ConnectingSt, LloadPendingConnection) b_connecting;
    LloadConnection *b_last_conn, *b_last_bindconn;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
226

227
228
229
    long b_max_pending, b_max_conn_pending;
    long b_n_ops_executing;

230
231
    lload_counters_t b_counters[LLOAD_STATS_OPS_LAST];

232
233
234
235
#ifdef BALANCER_MODULE
    monitor_subsys_t *b_monitor;
#endif /* BALANCER_MODULE */

236
    struct evdns_getaddrinfo_request *b_dns_req;
237
    void *b_cookie;
238

239
    LDAP_CIRCLEQ_ENTRY(LloadBackend) b_next;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
240
241
};

242
243
244
typedef int (*LloadOperationHandler)( LloadConnection *client,
        LloadOperation *op,
        BerElement *ber );
245
typedef int (*RequestHandler)( LloadConnection *c, LloadOperation *op );
Ondřej Kuzník's avatar
Ondřej Kuzník committed
246
247
248
249
typedef struct lload_exop_handlers_t {
    struct berval oid;
    RequestHandler func;
} ExopHandler;
250

251
252
typedef int (*CONNECTION_PDU_CB)( LloadConnection *c );
typedef void (*CONNECTION_DESTROY_CB)( LloadConnection *c );
Ondřej Kuzník's avatar
Ondřej Kuzník committed
253

Ondřej Kuzník's avatar
Ondřej Kuzník committed
254
/* connection state (protected by c_mutex) */
255
enum sc_state {
256
257
258
259
260
    LLOAD_C_INVALID = 0, /* MUST BE ZERO (0) */
    LLOAD_C_READY,       /* ready */
    LLOAD_C_CLOSING,     /* closing */
    LLOAD_C_ACTIVE,      /* exclusive operation (tls setup, ...) in progress */
    LLOAD_C_BINDING,     /* binding */
261
    LLOAD_C_DYING, /* part-processed dead but someone still holds a reference */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
262
};
263
enum sc_type {
264
265
266
267
    LLOAD_C_OPEN = 0,  /* regular connection */
    LLOAD_C_PREPARING, /* upstream connection not assigned yet */
    LLOAD_C_BIND, /* connection used to handle bind client requests if VC not enabled */
    LLOAD_C_PRIVILEGED, /* connection can override proxyauthz control */
268
};
269
270
271
/*
 * represents a connection from an ldap client/to ldap server
 */
272
struct LloadConnection {
273
    enum sc_state c_state; /* connection state */
274
    enum sc_type c_type;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
275
    ber_socket_t c_fd;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
276

277
/*
278
 * LloadConnection reference counting:
279
280
 * - connection has a reference counter in c_refcnt
 * - also a liveness/validity token is added to c_refcnt during
281
 *   lload_connection_init, its existence is tracked in c_live and is usually the
282
283
284
285
286
 *   only one that prevents it from being destroyed
 * - anyone who needs to be able to lock the connection after unlocking it has
 *   to use CONNECTION_UNLOCK_INCREF, they are then responsible that
 *   CONNECTION_LOCK_DECREF+CONNECTION_UNLOCK_OR_DESTROY is used when they are
 *   done with it
287
288
289
290
291
292
 * - when a connection is considered dead, use CONNECTION_DESTROY on a locked
 *   connection, it might get disposed of or if anyone still holds a token, it
 *   just gets unlocked and it's the last token holder's responsibility to run
 *   CONNECTION_UNLOCK_OR_DESTROY
 * - CONNECTION_LOCK_DESTROY is a shorthand for locking, decreasing refcount
 *   and CONNECTION_DESTROY
293
 */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
294
    ldap_pvt_thread_mutex_t c_mutex; /* protect the connection */
295
    int c_refcnt, c_live;
296
297
    CONNECTION_DESTROY_CB c_destroy;
    CONNECTION_PDU_CB c_pdu_cb;
298
299
300
301
302
303
304
305
306
307
308
309
#define CONNECTION_LOCK(c) ldap_pvt_thread_mutex_lock( &(c)->c_mutex )
#define CONNECTION_UNLOCK(c) ldap_pvt_thread_mutex_unlock( &(c)->c_mutex )
#define CONNECTION_LOCK_DECREF(c) \
    do { \
        CONNECTION_LOCK(c); \
        (c)->c_refcnt--; \
    } while (0)
#define CONNECTION_UNLOCK_INCREF(c) \
    do { \
        (c)->c_refcnt++; \
        CONNECTION_UNLOCK(c); \
    } while (0)
310
#define CONNECTION_UNLOCK_OR_DESTROY(c) \
311
312
    do { \
        assert( (c)->c_refcnt >= 0 ); \
313
314
315
316
        if ( (c)->c_state == LLOAD_C_CLOSING && !( c )->c_ops ) { \
            (c)->c_refcnt -= (c)->c_live; \
            (c)->c_live = 0; \
        } \
317
        if ( !( c )->c_refcnt ) { \
318
            Debug( LDAP_DEBUG_TRACE, "%s: destroying connection connid=%lu\n", \
319
                    __func__, (c)->c_connid ); \
320
            (c)->c_destroy( (c) ); \
321
322
323
324
325
            (c) = NULL; \
        } else { \
            CONNECTION_UNLOCK(c); \
        } \
    } while (0)
326
#define CONNECTION_DESTROY(c) \
327
328
329
    do { \
        (c)->c_refcnt -= (c)->c_live; \
        (c)->c_live = 0; \
330
        CONNECTION_UNLOCK_OR_DESTROY(c); \
331
    } while (0)
332
#define CONNECTION_LOCK_DESTROY(c) \
333
334
    do { \
        CONNECTION_LOCK_DECREF(c); \
335
        CONNECTION_DESTROY(c); \
336
337
338
    } while (0);

    Sockbuf *c_sb; /* ber connection stuff */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
339
340
341
342
343
344

    /* set by connection_init */
    unsigned long c_connid;    /* unique id of this connection */
    struct berval c_peer_name; /* peer name (trans=addr:port) */
    time_t c_starttime;        /* when the connection was opened */

Ondřej Kuzník's avatar
Ondřej Kuzník committed
345
346
    time_t c_activitytime;  /* when the connection was last used */
    ber_int_t c_next_msgid; /* msgid of the next message */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
347

348
    /* must not be used while holding either mutex */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
349
    struct event *c_read_event, *c_write_event;
350
    struct timeval *c_read_timeout;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
351
352
353

    /* can only be changed by binding thread */
    struct berval c_sasl_bind_mech; /* mech in progress */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
354
355
    struct berval c_auth;           /* authcDN (possibly in progress) */

Ondřej Kuzník's avatar
Ondřej Kuzník committed
356
357
    unsigned long c_pin_id;

358
359
360
361
362
#ifdef HAVE_CYRUS_SASL
    sasl_conn_t *c_sasl_authctx;
    void *c_sasl_defaults;
#endif /* HAVE_CYRUS_SASL */

Ondřej Kuzník's avatar
Ondřej Kuzník committed
363
#ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS
Ondřej Kuzník's avatar
Ondřej Kuzník committed
364
    struct berval c_vc_cookie;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
365
#endif /* LDAP_API_FEATURE_VERIFY_CREDENTIALS */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
366

Ondřej Kuzník's avatar
Ondřej Kuzník committed
367
368
    /* Can be held while acquiring c_mutex to inject things into c_ops or
     * destroy the connection */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
369
370
    ldap_pvt_thread_mutex_t c_io_mutex; /* only one pdu written at a time */

Ondřej Kuzník's avatar
Ondřej Kuzník committed
371
372
    BerElement *c_currentber; /* ber we're attempting to read */
    BerElement *c_pendingber; /* ber we're attempting to write */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
373

Ondřej Kuzník's avatar
Ondřej Kuzník committed
374
375
    TAvlnode *c_ops; /* Operations pending on the connection */

Ondřej Kuzník's avatar
Ondřej Kuzník committed
376
#ifdef HAVE_TLS
Ondřej Kuzník's avatar
Ondřej Kuzník committed
377
    enum lload_tls_type c_is_tls; /* true if this LDAP over raw TLS */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
378
379
#endif

380
381
382
    long c_n_ops_executing;      /* num of ops currently executing */
    long c_n_ops_completed;      /* num of ops completed */
    lload_counters_t c_counters; /* per connection operation counters */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
383

384
385
386
387
388
    /*
     * Protected by the CIRCLEQ mutex:
     * - Client: clients_mutex
     * - Upstream: b->b_mutex
     */
389
    LDAP_CIRCLEQ_ENTRY(LloadConnection) c_next;
390

Ondřej Kuzník's avatar
Ondřej Kuzník committed
391
392
393
    void *c_private;
};

Ondřej Kuzník's avatar
Ondřej Kuzník committed
394
enum op_state {
395
396
397
398
399
    LLOAD_OP_NOT_FREEING = 0,
    LLOAD_OP_FREEING_UPSTREAM = 1 << 0,
    LLOAD_OP_FREEING_CLIENT = 1 << 1,
    LLOAD_OP_DETACHING_UPSTREAM = 1 << 2,
    LLOAD_OP_DETACHING_CLIENT = 1 << 3,
Ondřej Kuzník's avatar
Ondřej Kuzník committed
400
};
401
402
403
404
405
406
407
408

/* operation result for monitoring purposes */
enum op_result {
    LLOAD_OP_REJECTED,  /* operation was not forwarded */
    LLOAD_OP_COMPLETED, /* operation sent and response received */
    LLOAD_OP_FAILED, /* operation was forwarded, but no response was received */
};

409
410
411
412
#define LLOAD_OP_FREEING_MASK \
    ( LLOAD_OP_FREEING_UPSTREAM | LLOAD_OP_FREEING_CLIENT )
#define LLOAD_OP_DETACHING_MASK \
    ( LLOAD_OP_DETACHING_UPSTREAM | LLOAD_OP_DETACHING_CLIENT )
Ondřej Kuzník's avatar
Ondřej Kuzník committed
413

414
415
struct LloadOperation {
    LloadConnection *o_client;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
416
417
418
    unsigned long o_client_connid;
    int o_client_live, o_client_refcnt;
    ber_int_t o_client_msgid;
419
    ber_int_t o_saved_msgid;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
420

421
    LloadConnection *o_upstream;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
422
423
424
    unsigned long o_upstream_connid;
    int o_upstream_live, o_upstream_refcnt;
    ber_int_t o_upstream_msgid;
425
    time_t o_last_response;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
426

Ondřej Kuzník's avatar
Ondřej Kuzník committed
427
428
429
430
    /* Protects o_client, o_upstream pointers before we lock their c_mutex if
     * we don't know they are still alive */
    ldap_pvt_thread_mutex_t o_link_mutex;
    /* Protects o_freeing, can be locked while holding c_mutex */
431
    ldap_pvt_thread_mutex_t o_mutex;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
432
433
    /* Consistent w.r.t. o_mutex, only written to while holding
     * op->o_{client,upstream}->c_mutex */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
434
    enum op_state o_freeing;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
435
    ber_tag_t o_tag;
436
    time_t o_start;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
437
    unsigned long o_pin_id;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
438

439
    enum op_result o_res;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
440
441
442
443
    BerElement *o_ber;
    BerValue o_request, o_ctrls;
};

Ondřej Kuzník's avatar
Ondřej Kuzník committed
444
445
446
/*
 * listener; need to access it from monitor backend
 */
447
struct LloadListener {
Ondřej Kuzník's avatar
Ondřej Kuzník committed
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
    struct berval sl_url;
    struct berval sl_name;
    mode_t sl_perms;
#ifdef HAVE_TLS
    int sl_is_tls;
#endif
    struct event_base *base;
    struct evconnlistener *listener;
    int sl_mute; /* Listener is temporarily disabled due to emfile */
    int sl_busy; /* Listener is busy (accept thread activated) */
    ber_socket_t sl_sd;
    Sockaddr sl_sa;
#define sl_addr sl_sa.sa_in_addr
#define LDAP_TCP_BUFFER
#ifdef LDAP_TCP_BUFFER
    int sl_tcp_rmem; /* custom TCP read buffer size */
    int sl_tcp_wmem; /* custom TCP write buffer size */
#endif
};

Ondřej Kuzník's avatar
Ondřej Kuzník committed
468
typedef int (*CONNCB)( LloadConnection *c, void *arg );
469
470
471
472
473
474

struct lload_monitor_conn_arg {
    Operation *op;
    monitor_subsys_t *ms;
    Entry **ep;
};
475
476
477
478
479

/* config requires a bi_private with configuration data - dummy for now */
struct lload_conf_info {
    int dummy;
};
Ondřej Kuzník's avatar
Ondřej Kuzník committed
480
481
LDAP_END_DECL

482
483
#include "proto-lload.h"
#endif /* _LLOAD_H_ */