xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-asyncmeta/back-asyncmeta.h (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1*549b59edSchristos /*	$NetBSD: back-asyncmeta.h,v 1.2 2021/08/14 16:14:59 christos Exp $	*/
2e670fd5cSchristos 
3e670fd5cSchristos /* back-asyncmeta.h - main header file for back-asyncmeta module */
4e670fd5cSchristos /* $OpenLDAP$ */
5e670fd5cSchristos /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6e670fd5cSchristos  *
7e670fd5cSchristos  * Copyright 2016-2021 The OpenLDAP Foundation.
8e670fd5cSchristos  * Portions Copyright 2016 Symas Corporation.
9e670fd5cSchristos  * All rights reserved.
10e670fd5cSchristos  *
11e670fd5cSchristos  * Redistribution and use in source and binary forms, with or without
12e670fd5cSchristos  * modification, are permitted only as authorized by the OpenLDAP
13e670fd5cSchristos  * Public License.
14e670fd5cSchristos  *
15e670fd5cSchristos  * A copy of this license is available in the file LICENSE in the
16e670fd5cSchristos  * top-level directory of the distribution or, alternatively, at
17e670fd5cSchristos  * <http://www.OpenLDAP.org/license.html>.
18e670fd5cSchristos  */
19e670fd5cSchristos 
20e670fd5cSchristos /* ACKNOWLEDGEMENTS:
21e670fd5cSchristos  * This work was developed by Symas Corporation
22e670fd5cSchristos  * based on back-meta module for inclusion in OpenLDAP Software.
23e670fd5cSchristos  * This work was sponsored by Ericsson. */
24e670fd5cSchristos 
25e670fd5cSchristos #ifndef SLAPD_LDAP_H
26e670fd5cSchristos #error "include servers/slapd/back-ldap/back-ldap.h before this file!"
27e670fd5cSchristos #endif /* SLAPD_LDAP_H */
28e670fd5cSchristos 
29e670fd5cSchristos #ifndef SLAPD_ASYNCMETA_H
30e670fd5cSchristos #define SLAPD_ASYNCMETA_H
31e670fd5cSchristos 
32e670fd5cSchristos #ifdef LDAP_DEVEL
33e670fd5cSchristos #define SLAPD_META_CLIENT_PR 1
34e670fd5cSchristos #endif /* LDAP_DEVEL */
35e670fd5cSchristos 
36e670fd5cSchristos #include "proto-asyncmeta.h"
37e670fd5cSchristos 
38e670fd5cSchristos #include "ldap_rq.h"
39e670fd5cSchristos 
40e670fd5cSchristos LDAP_BEGIN_DECL
41e670fd5cSchristos 
42e670fd5cSchristos /*
43e670fd5cSchristos  * Set META_BACK_PRINT_CONNTREE larger than 0 to dump the connection tree (debug only)
44e670fd5cSchristos  */
45e670fd5cSchristos #ifndef META_BACK_PRINT_CONNTREE
46e670fd5cSchristos #define META_BACK_PRINT_CONNTREE 0
47e670fd5cSchristos #endif /* !META_BACK_PRINT_CONNTREE */
48e670fd5cSchristos 
49e670fd5cSchristos /*
50e670fd5cSchristos  * A a_metasingleconn_t can be in the following, mutually exclusive states:
51e670fd5cSchristos  *
52e670fd5cSchristos  *	- none			(0x0U)
53e670fd5cSchristos  *	- creating		META_BACK_FCONN_CREATING
54e670fd5cSchristos  *	- initialized		META_BACK_FCONN_INITED
55e670fd5cSchristos  *	- binding		LDAP_BACK_FCONN_BINDING
56e670fd5cSchristos  *	- bound/anonymous	LDAP_BACK_FCONN_ISBOUND/LDAP_BACK_FCONN_ISANON
57e670fd5cSchristos  *
58e670fd5cSchristos  * possible modifiers are:
59e670fd5cSchristos  *
60e670fd5cSchristos  *	- privileged		LDAP_BACK_FCONN_ISPRIV
61e670fd5cSchristos  *	- privileged, TLS	LDAP_BACK_FCONN_ISTLS
62e670fd5cSchristos  *	- subjected to idassert	LDAP_BACK_FCONN_ISIDASR
63e670fd5cSchristos  *	- tainted		LDAP_BACK_FCONN_TAINTED
64e670fd5cSchristos  */
65e670fd5cSchristos 
66e670fd5cSchristos #define META_BACK_FCONN_INITED		(0x00100000U)
67e670fd5cSchristos #define META_BACK_FCONN_CREATING	(0x00200000U)
68e670fd5cSchristos #define META_BACK_FCONN_INVALID	        (0x00400000U)
69e670fd5cSchristos 
70e670fd5cSchristos #define	META_BACK_CONN_INITED(lc)		LDAP_BACK_CONN_ISSET((lc), META_BACK_FCONN_INITED)
71e670fd5cSchristos #define	META_BACK_CONN_INITED_SET(lc)		LDAP_BACK_CONN_SET((lc), META_BACK_FCONN_INITED)
72e670fd5cSchristos #define	META_BACK_CONN_INITED_CLEAR(lc)		LDAP_BACK_CONN_CLEAR((lc), META_BACK_FCONN_INITED)
73e670fd5cSchristos #define	META_BACK_CONN_INITED_CPY(lc, mlc)	LDAP_BACK_CONN_CPY((lc), META_BACK_FCONN_INITED, (mlc))
74e670fd5cSchristos #define	META_BACK_CONN_CREATING(lc)		LDAP_BACK_CONN_ISSET((lc), META_BACK_FCONN_CREATING)
75e670fd5cSchristos #define	META_BACK_CONN_CREATING_SET(lc)		LDAP_BACK_CONN_SET((lc), META_BACK_FCONN_CREATING)
76e670fd5cSchristos #define	META_BACK_CONN_CREATING_CLEAR(lc)	LDAP_BACK_CONN_CLEAR((lc), META_BACK_FCONN_CREATING)
77e670fd5cSchristos #define	META_BACK_CONN_CREATING_CPY(lc, mlc)	LDAP_BACK_CONN_CPY((lc), META_BACK_FCONN_CREATING, (mlc))
78e670fd5cSchristos #define	META_BACK_CONN_INVALID(lc)		LDAP_BACK_CONN_ISSET((lc), META_BACK_FCONN_INVALID)
79e670fd5cSchristos #define	META_BACK_CONN_INVALID_SET(lc)		LDAP_BACK_CONN_SET((lc), META_BACK_FCONN_INVALID)
80e670fd5cSchristos #define	META_BACK_CONN_INVALID_CLEAR(lc)	LDAP_BACK_CONN_CLEAR((lc), META_BACK_FCONN_INVALID)
81e670fd5cSchristos 
82e670fd5cSchristos struct a_metainfo_t;
83e670fd5cSchristos struct a_metaconn_t;
84e670fd5cSchristos struct a_metatarget_t;
85e670fd5cSchristos #define	META_NOT_CANDIDATE		((ber_tag_t)0x0)
86e670fd5cSchristos #define	META_CANDIDATE			((ber_tag_t)0x1)
87e670fd5cSchristos #define	META_BINDING			((ber_tag_t)0x2)
88e670fd5cSchristos #define	META_RETRYING			((ber_tag_t)0x4)
89e670fd5cSchristos 
90e670fd5cSchristos typedef struct bm_context_t {
91e670fd5cSchristos 	LDAP_STAILQ_ENTRY(bm_context_t) bc_next;
92e670fd5cSchristos 	struct a_metaconn_t *bc_mc;
93e670fd5cSchristos 	time_t			timeout;
94e670fd5cSchristos 	time_t                  stoptime;
95e670fd5cSchristos 	ldap_back_send_t	sendok;
96e670fd5cSchristos 	ldap_back_send_t	retrying;
97e670fd5cSchristos 	int candidate_match;
98e670fd5cSchristos 	volatile int bc_active;
99e670fd5cSchristos 	int searchtime;	/* stoptime is a search timelimit */
100e670fd5cSchristos 	int is_ok;
101e670fd5cSchristos 	int is_root;
102e670fd5cSchristos 	volatile sig_atomic_t bc_invalid;
103e670fd5cSchristos 	SlapReply		rs;
104e670fd5cSchristos 	Operation		*op;
105e670fd5cSchristos 	Operation               copy_op;
106e670fd5cSchristos 	LDAPControl	        **ctrls;
107e670fd5cSchristos 	int                     *msgids;
108e670fd5cSchristos 	int                     *nretries;  /* number of times to retry a failed send on an msc */
109e670fd5cSchristos 	struct berval	        c_peer_name; /* peer name of original op->o_conn*/
110e670fd5cSchristos 	SlapReply               *candidates;
111e670fd5cSchristos } bm_context_t;
112e670fd5cSchristos 
113e670fd5cSchristos typedef struct a_metasingleconn_t {
114e670fd5cSchristos #define META_CND_ISSET(rs,f)		( ( (rs)->sr_tag & (f) ) == (f) )
115e670fd5cSchristos #define META_CND_SET(rs,f)		( (rs)->sr_tag |= (f) )
116e670fd5cSchristos #define META_CND_CLEAR(rs,f)		( (rs)->sr_tag &= ~(f) )
117e670fd5cSchristos 
118e670fd5cSchristos #define META_CANDIDATE_RESET(rs)	( (rs)->sr_tag = 0 )
119e670fd5cSchristos #define META_IS_CANDIDATE(rs)		META_CND_ISSET( (rs), META_CANDIDATE )
120e670fd5cSchristos #define META_CANDIDATE_SET(rs)		META_CND_SET( (rs), META_CANDIDATE )
121e670fd5cSchristos #define META_CANDIDATE_CLEAR(rs)	META_CND_CLEAR( (rs), META_CANDIDATE )
122e670fd5cSchristos #define META_IS_BINDING(rs)		META_CND_ISSET( (rs), META_BINDING )
123e670fd5cSchristos #define META_BINDING_SET(rs)		META_CND_SET( (rs), META_BINDING )
124e670fd5cSchristos #define META_BINDING_CLEAR(rs)		META_CND_CLEAR( (rs), META_BINDING )
125e670fd5cSchristos #define META_IS_RETRYING(rs)		META_CND_ISSET( (rs), META_RETRYING )
126e670fd5cSchristos #define META_RETRYING_SET(rs)		META_CND_SET( (rs), META_RETRYING )
127e670fd5cSchristos #define META_RETRYING_CLEAR(rs)		META_CND_CLEAR( (rs), META_RETRYING )
128e670fd5cSchristos 
129e670fd5cSchristos 	LDAP            	*msc_ld;
130e670fd5cSchristos 	LDAP            	*msc_ldr;
131e670fd5cSchristos 	time_t			msc_time;
132e670fd5cSchristos 	time_t                  msc_binding_time;
133e670fd5cSchristos 	time_t                  msc_result_time;
134e670fd5cSchristos 	struct berval          	msc_bound_ndn;
135e670fd5cSchristos 	struct berval		msc_cred;
136e670fd5cSchristos 	unsigned		msc_mscflags;
137e670fd5cSchristos 
138e670fd5cSchristos 	/* NOTE: lc_lcflags is redefined to msc_mscflags to reuse the macros
139e670fd5cSchristos 	 * defined for back-ldap */
140e670fd5cSchristos #define	lc_lcflags		msc_mscflags
141e670fd5cSchristos 	volatile int msc_active;
142e670fd5cSchristos 		/* Connection for the select */
143e670fd5cSchristos 	Connection *conn;
144e670fd5cSchristos } a_metasingleconn_t;
145e670fd5cSchristos 
146e670fd5cSchristos typedef struct a_metaconn_t {
147e670fd5cSchristos 	ldapconn_base_t		lc_base;
148e670fd5cSchristos #define	mc_base			lc_base
149e670fd5cSchristos //#define	mc_conn			mc_base.lcb_conn
150e670fd5cSchristos //#define	mc_local_ndn		mc_base.lcb_local_ndn
151e670fd5cSchristos //#define	mc_refcnt		mc_base.lcb_refcnt
152e670fd5cSchristos //#define	mc_create_time		mc_base.lcb_create_time
153e670fd5cSchristos //#define	mc_time			mc_base.lcb_time
154e670fd5cSchristos 
155e670fd5cSchristos 	LDAP_TAILQ_ENTRY(a_metaconn_t)	mc_q;
156e670fd5cSchristos 
157e670fd5cSchristos 	/* NOTE: msc_mscflags is used to recycle the #define
158e670fd5cSchristos 	 * in metasingleconn_t */
159e670fd5cSchristos 	unsigned		msc_mscflags;
160e670fd5cSchristos 	int	mc_active;
161e670fd5cSchristos 
162e670fd5cSchristos 	/*
163e670fd5cSchristos 	 * means that the connection is bound;
164e670fd5cSchristos 	 * of course only one target actually is ...
165e670fd5cSchristos 	 */
166e670fd5cSchristos 	int             	mc_authz_target;
167e670fd5cSchristos #define META_BOUND_NONE		(-1)
168e670fd5cSchristos #define META_BOUND_ALL		(-2)
169e670fd5cSchristos 
170e670fd5cSchristos 	struct a_metainfo_t	*mc_info;
171e670fd5cSchristos 
172e670fd5cSchristos 	int pending_ops;
173e670fd5cSchristos 	ldap_pvt_thread_mutex_t	mc_om_mutex;
174e670fd5cSchristos 	/* queue for pending operations */
175e670fd5cSchristos 	LDAP_STAILQ_HEAD(BCList, bm_context_t) mc_om_list;
176e670fd5cSchristos 	/* supersedes the connection stuff */
177e670fd5cSchristos 	a_metasingleconn_t	*mc_conns;
178e670fd5cSchristos } a_metaconn_t;
179e670fd5cSchristos 
180e670fd5cSchristos typedef enum meta_st_t {
181e670fd5cSchristos #if 0 /* todo */
182e670fd5cSchristos 	META_ST_EXACT = LDAP_SCOPE_BASE,
183e670fd5cSchristos #endif
184e670fd5cSchristos 	META_ST_SUBTREE = LDAP_SCOPE_SUBTREE,
185e670fd5cSchristos 	META_ST_SUBORDINATE = LDAP_SCOPE_SUBORDINATE,
186e670fd5cSchristos 	META_ST_REGEX /* last + 1 */
187e670fd5cSchristos } meta_st_t;
188e670fd5cSchristos 
189e670fd5cSchristos typedef struct a_metasubtree_t {
190e670fd5cSchristos 	meta_st_t ms_type;
191e670fd5cSchristos 	union {
192e670fd5cSchristos 		struct berval msu_dn;
193e670fd5cSchristos 		struct {
194e670fd5cSchristos 			struct berval msr_regex_pattern;
195e670fd5cSchristos 			regex_t msr_regex;
196e670fd5cSchristos 		} msu_regex;
197e670fd5cSchristos 	} ms_un;
198e670fd5cSchristos #define ms_dn ms_un.msu_dn
199e670fd5cSchristos #define ms_regex ms_un.msu_regex.msr_regex
200e670fd5cSchristos #define ms_regex_pattern ms_un.msu_regex.msr_regex_pattern
201e670fd5cSchristos 
202e670fd5cSchristos 	struct a_metasubtree_t *ms_next;
203e670fd5cSchristos } a_metasubtree_t;
204e670fd5cSchristos 
205e670fd5cSchristos typedef struct metafilter_t {
206e670fd5cSchristos 	struct metafilter_t *mf_next;
207e670fd5cSchristos 	struct berval mf_regex_pattern;
208e670fd5cSchristos 	regex_t mf_regex;
209e670fd5cSchristos } metafilter_t;
210e670fd5cSchristos 
211e670fd5cSchristos typedef struct a_metacommon_t {
212e670fd5cSchristos 	int				mc_version;
213e670fd5cSchristos 	int				mc_nretries;
214e670fd5cSchristos #define META_RETRY_UNDEFINED	(-2)
215e670fd5cSchristos #define META_RETRY_FOREVER	(-1)
216e670fd5cSchristos #define META_RETRY_NEVER	(0)
217e670fd5cSchristos #define META_RETRY_DEFAULT	(2)
218e670fd5cSchristos 
219e670fd5cSchristos 	unsigned		mc_flags;
220e670fd5cSchristos #define	META_BACK_CMN_ISSET(mc,f)		( ( (mc)->mc_flags & (f) ) == (f) )
221e670fd5cSchristos #define	META_BACK_CMN_QUARANTINE(mc)		META_BACK_CMN_ISSET( (mc), LDAP_BACK_F_QUARANTINE )
222e670fd5cSchristos #define	META_BACK_CMN_CHASE_REFERRALS(mc)	META_BACK_CMN_ISSET( (mc), LDAP_BACK_F_CHASE_REFERRALS )
223e670fd5cSchristos #define	META_BACK_CMN_NOREFS(mc)		META_BACK_CMN_ISSET( (mc), LDAP_BACK_F_NOREFS )
224e670fd5cSchristos #define	META_BACK_CMN_NOUNDEFFILTER(mc)		META_BACK_CMN_ISSET( (mc), LDAP_BACK_F_NOUNDEFFILTER )
225e670fd5cSchristos #define	META_BACK_CMN_SAVECRED(mc)		META_BACK_CMN_ISSET( (mc), LDAP_BACK_F_SAVECRED )
226e670fd5cSchristos #define	META_BACK_CMN_ST_REQUEST(mc)		META_BACK_CMN_ISSET( (mc), LDAP_BACK_F_ST_REQUEST )
227e670fd5cSchristos 
228e670fd5cSchristos #ifdef SLAPD_META_CLIENT_PR
229e670fd5cSchristos 	/*
230e670fd5cSchristos 	 * client-side paged results:
231e670fd5cSchristos 	 * -1: accept unsolicited paged results responses
232e670fd5cSchristos 	 *  0: off
233e670fd5cSchristos 	 * >0: always request paged results with size == mt_ps
234e670fd5cSchristos 	 */
235e670fd5cSchristos #define META_CLIENT_PR_DISABLE			(0)
236e670fd5cSchristos #define META_CLIENT_PR_ACCEPT_UNSOLICITED	(-1)
237e670fd5cSchristos 	ber_int_t		mc_ps;
238e670fd5cSchristos #endif /* SLAPD_META_CLIENT_PR */
239e670fd5cSchristos 
240e670fd5cSchristos 	slap_retry_info_t	mc_quarantine;
241e670fd5cSchristos 	time_t			mc_network_timeout;
242e670fd5cSchristos 	struct timeval	mc_bind_timeout;
243e670fd5cSchristos #define META_BIND_TIMEOUT	LDAP_BACK_RESULT_UTIMEOUT
244e670fd5cSchristos 	time_t			mc_timeout[ SLAP_OP_LAST ];
245e670fd5cSchristos } a_metacommon_t;
246e670fd5cSchristos 
247e670fd5cSchristos typedef struct a_metatarget_t {
248e670fd5cSchristos 	char			*mt_uri;
249e670fd5cSchristos 	ldap_pvt_thread_mutex_t	mt_uri_mutex;
250e670fd5cSchristos 
251e670fd5cSchristos 	/* TODO: we might want to enable different strategies
252e670fd5cSchristos 	 * for different targets */
253e670fd5cSchristos 	LDAP_REBIND_PROC	*mt_rebind_f;
254e670fd5cSchristos 	LDAP_URLLIST_PROC	*mt_urllist_f;
255e670fd5cSchristos 	void			*mt_urllist_p;
256e670fd5cSchristos 
257e670fd5cSchristos 	metafilter_t	*mt_filter;
258e670fd5cSchristos 	a_metasubtree_t		*mt_subtree;
259e670fd5cSchristos 	/* F: subtree-include; T: subtree-exclude */
260e670fd5cSchristos 	int			mt_subtree_exclude;
261e670fd5cSchristos 
262e670fd5cSchristos 	int			mt_scope;
263e670fd5cSchristos 
264e670fd5cSchristos 	struct berval		mt_psuffix;		/* pretty suffix */
265e670fd5cSchristos 	struct berval		mt_nsuffix;		/* normalized suffix */
266e670fd5cSchristos 
267e670fd5cSchristos 	struct berval		mt_lsuffixm;	/* local suffix for massage */
268e670fd5cSchristos 	struct berval		mt_rsuffixm;	/* remote suffix for massage */
269e670fd5cSchristos 
270e670fd5cSchristos 	struct berval		mt_binddn;
271e670fd5cSchristos 	struct berval		mt_bindpw;
272e670fd5cSchristos 
273e670fd5cSchristos 	/* we only care about the TLS options here */
274e670fd5cSchristos 	slap_bindconf		mt_tls;
275e670fd5cSchristos 
276e670fd5cSchristos 	slap_idassert_t		mt_idassert;
277e670fd5cSchristos #define	mt_idassert_mode	mt_idassert.si_mode
278e670fd5cSchristos #define	mt_idassert_authcID	mt_idassert.si_bc.sb_authcId
279e670fd5cSchristos #define	mt_idassert_authcDN	mt_idassert.si_bc.sb_binddn
280e670fd5cSchristos #define	mt_idassert_passwd	mt_idassert.si_bc.sb_cred
281e670fd5cSchristos #define	mt_idassert_authzID	mt_idassert.si_bc.sb_authzId
282e670fd5cSchristos #define	mt_idassert_authmethod	mt_idassert.si_bc.sb_method
283e670fd5cSchristos #define	mt_idassert_sasl_mech	mt_idassert.si_bc.sb_saslmech
284e670fd5cSchristos #define	mt_idassert_sasl_realm	mt_idassert.si_bc.sb_realm
285e670fd5cSchristos #define	mt_idassert_secprops	mt_idassert.si_bc.sb_secprops
286e670fd5cSchristos #define	mt_idassert_tls		mt_idassert.si_bc.sb_tls
287e670fd5cSchristos #define	mt_idassert_flags	mt_idassert.si_flags
288e670fd5cSchristos #define	mt_idassert_authz	mt_idassert.si_authz
289e670fd5cSchristos 
290e670fd5cSchristos 	sig_atomic_t		mt_isquarantined;
291e670fd5cSchristos 	ldap_pvt_thread_mutex_t	mt_quarantine_mutex;
292e670fd5cSchristos 
293e670fd5cSchristos 	a_metacommon_t	mt_mc;
294e670fd5cSchristos #define	mt_nretries	mt_mc.mc_nretries
295e670fd5cSchristos #define	mt_flags	mt_mc.mc_flags
296e670fd5cSchristos #define	mt_version	mt_mc.mc_version
297e670fd5cSchristos #define	mt_ps		mt_mc.mc_ps
298e670fd5cSchristos #define	mt_network_timeout	mt_mc.mc_network_timeout
299e670fd5cSchristos #define	mt_bind_timeout	mt_mc.mc_bind_timeout
300e670fd5cSchristos #define	mt_timeout	mt_mc.mc_timeout
301e670fd5cSchristos #define	mt_quarantine	mt_mc.mc_quarantine
302e670fd5cSchristos 
303e670fd5cSchristos #define	META_BACK_TGT_ISSET(mt,f)		( ( (mt)->mt_flags & (f) ) == (f) )
304e670fd5cSchristos #define	META_BACK_TGT_ISMASK(mt,m,f)		( ( (mt)->mt_flags & (m) ) == (f) )
305e670fd5cSchristos 
306e670fd5cSchristos #define META_BACK_TGT_SAVECRED(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_SAVECRED )
307e670fd5cSchristos 
308e670fd5cSchristos #define META_BACK_TGT_USE_TLS(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_USE_TLS )
309e670fd5cSchristos #define META_BACK_TGT_PROPAGATE_TLS(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_PROPAGATE_TLS )
310e670fd5cSchristos #define META_BACK_TGT_TLS_CRITICAL(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_TLS_CRITICAL )
311e670fd5cSchristos 
312e670fd5cSchristos #define META_BACK_TGT_CHASE_REFERRALS(mt)	META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_CHASE_REFERRALS )
313e670fd5cSchristos 
314e670fd5cSchristos #define	META_BACK_TGT_T_F(mt)			META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_T_F_MASK, LDAP_BACK_F_T_F )
315e670fd5cSchristos #define	META_BACK_TGT_T_F_DISCOVER(mt)		META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_T_F_MASK2, LDAP_BACK_F_T_F_DISCOVER )
316e670fd5cSchristos 
317e670fd5cSchristos #define	META_BACK_TGT_ABANDON(mt)		META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_CANCEL_MASK, LDAP_BACK_F_CANCEL_ABANDON )
318e670fd5cSchristos #define	META_BACK_TGT_IGNORE(mt)		META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_CANCEL_MASK, LDAP_BACK_F_CANCEL_IGNORE )
319e670fd5cSchristos #define	META_BACK_TGT_CANCEL(mt)		META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_CANCEL_MASK, LDAP_BACK_F_CANCEL_EXOP )
320e670fd5cSchristos #define	META_BACK_TGT_CANCEL_DISCOVER(mt)	META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_CANCEL_MASK2, LDAP_BACK_F_CANCEL_EXOP_DISCOVER )
321e670fd5cSchristos #define	META_BACK_TGT_QUARANTINE(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_QUARANTINE )
322e670fd5cSchristos 
323e670fd5cSchristos #ifdef SLAP_CONTROL_X_SESSION_TRACKING
324e670fd5cSchristos #define	META_BACK_TGT_ST_REQUEST(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_ST_REQUEST )
325e670fd5cSchristos #define	META_BACK_TGT_ST_RESPONSE(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_ST_RESPONSE )
326e670fd5cSchristos #endif /* SLAP_CONTROL_X_SESSION_TRACKING */
327e670fd5cSchristos 
328e670fd5cSchristos #define	META_BACK_TGT_NOREFS(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_NOREFS )
329e670fd5cSchristos #define	META_BACK_TGT_NOUNDEFFILTER(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_NOUNDEFFILTER )
330e670fd5cSchristos 
331e670fd5cSchristos #define META_BACK_CFG_MAX_PENDING_OPS		0x80
332e670fd5cSchristos #define META_BACK_CFG_MAX_TARGET_CONNS		0xFF
333e670fd5cSchristos #define META_BACK_CFG_DEFAULT_OPS_TIMEOUT	0x02
334e670fd5cSchristos 
335e670fd5cSchristos /* the interval of the timeout checking loop in microseconds
336e670fd5cSchristos  * possibly make this configurable? */
337e670fd5cSchristos #define META_BACK_CFG_MAX_TIMEOUT_LOOP		0x70000
338e670fd5cSchristos 	slap_mask_t		mt_rep_flags;
339e670fd5cSchristos 	int			mt_timeout_ops;
340e670fd5cSchristos } a_metatarget_t;
341e670fd5cSchristos 
342e670fd5cSchristos typedef struct a_metadncache_t {
343e670fd5cSchristos 	ldap_pvt_thread_mutex_t mutex;
344e670fd5cSchristos 	Avlnode			*tree;
345e670fd5cSchristos 
346e670fd5cSchristos #define META_DNCACHE_DISABLED   (0)
347e670fd5cSchristos #define META_DNCACHE_FOREVER    ((time_t)(-1))
348e670fd5cSchristos 	time_t			ttl;  /* seconds; 0: no cache, -1: no expiry */
349e670fd5cSchristos } a_metadncache_t;
350e670fd5cSchristos 
351e670fd5cSchristos typedef struct a_metacandidates_t {
352e670fd5cSchristos 	int			mc_ntargets;
353e670fd5cSchristos 	SlapReply		*mc_candidates;
354e670fd5cSchristos } a_metacandidates_t;
355e670fd5cSchristos 
356e670fd5cSchristos /*
357e670fd5cSchristos  * Hook to allow mucking with a_metainfo_t/a_metatarget_t when quarantine is over
358e670fd5cSchristos  */
359e670fd5cSchristos typedef int (*asyncmeta_quarantine_f)( struct a_metainfo_t *, int target, void * );
360e670fd5cSchristos 
361e670fd5cSchristos struct meta_out_message_t;
362e670fd5cSchristos 
363e670fd5cSchristos typedef struct a_metainfo_t {
364e670fd5cSchristos 	int			mi_ntargets;
365e670fd5cSchristos 	int			mi_defaulttarget;
366e670fd5cSchristos #define META_DEFAULT_TARGET_NONE	(-1)
367e670fd5cSchristos 
368e670fd5cSchristos #define	mi_nretries	mi_mc.mc_nretries
369e670fd5cSchristos #define	mi_flags	mi_mc.mc_flags
370e670fd5cSchristos #define	mi_version	mi_mc.mc_version
371e670fd5cSchristos #define	mi_ps		mi_mc.mc_ps
372e670fd5cSchristos #define	mi_network_timeout	mi_mc.mc_network_timeout
373e670fd5cSchristos #define	mi_bind_timeout	mi_mc.mc_bind_timeout
374e670fd5cSchristos #define	mi_timeout	mi_mc.mc_timeout
375e670fd5cSchristos #define	mi_quarantine	mi_mc.mc_quarantine
376e670fd5cSchristos 
377e670fd5cSchristos 	a_metatarget_t		**mi_targets;
378e670fd5cSchristos 	a_metacandidates_t	*mi_candidates;
379e670fd5cSchristos 
380e670fd5cSchristos 	LDAP_REBIND_PROC	*mi_rebind_f;
381e670fd5cSchristos 	LDAP_URLLIST_PROC	*mi_urllist_f;
382e670fd5cSchristos 
383e670fd5cSchristos 	a_metadncache_t		mi_cache;
384e670fd5cSchristos 
385e670fd5cSchristos 	struct {
386e670fd5cSchristos 		int						mic_num;
387e670fd5cSchristos 		LDAP_TAILQ_HEAD(mc_conn_priv_q, a_metaconn_t)	mic_priv;
388e670fd5cSchristos 	}			mi_conn_priv[ LDAP_BACK_PCONN_LAST ];
389e670fd5cSchristos 	int			mi_conn_priv_max;
390e670fd5cSchristos 
391e670fd5cSchristos 	/* NOTE: quarantine uses the connection mutex */
392e670fd5cSchristos 	asyncmeta_quarantine_f	mi_quarantine_f;
393e670fd5cSchristos 	void			*mi_quarantine_p;
394e670fd5cSchristos 
395e670fd5cSchristos #define	li_flags		mi_flags
396e670fd5cSchristos /* uses flags as defined in <back-ldap/back-ldap.h> */
397e670fd5cSchristos #define	META_BACK_F_ONERR_STOP		LDAP_BACK_F_ONERR_STOP
398e670fd5cSchristos #define	META_BACK_F_ONERR_REPORT	(0x02000000U)
399e670fd5cSchristos #define	META_BACK_F_ONERR_MASK		(META_BACK_F_ONERR_STOP|META_BACK_F_ONERR_REPORT)
400e670fd5cSchristos #define	META_BACK_F_DEFER_ROOTDN_BIND	(0x04000000U)
401e670fd5cSchristos #define	META_BACK_F_PROXYAUTHZ_ALWAYS	(0x08000000U)	/* users always proxyauthz */
402e670fd5cSchristos #define	META_BACK_F_PROXYAUTHZ_ANON	(0x10000000U)	/* anonymous always proxyauthz */
403e670fd5cSchristos #define	META_BACK_F_PROXYAUTHZ_NOANON	(0x20000000U)	/* anonymous remains anonymous */
404e670fd5cSchristos 
405e670fd5cSchristos #define	META_BACK_ONERR_STOP(mi)	LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_STOP )
406e670fd5cSchristos #define	META_BACK_ONERR_REPORT(mi)	LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_REPORT )
407e670fd5cSchristos #define	META_BACK_ONERR_CONTINUE(mi)	( !LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_MASK ) )
408e670fd5cSchristos 
409e670fd5cSchristos #define META_BACK_DEFER_ROOTDN_BIND(mi)	LDAP_BACK_ISSET( (mi), META_BACK_F_DEFER_ROOTDN_BIND )
410e670fd5cSchristos #define META_BACK_PROXYAUTHZ_ALWAYS(mi)	LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_ALWAYS )
411e670fd5cSchristos #define META_BACK_PROXYAUTHZ_ANON(mi)	LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_ANON )
412e670fd5cSchristos #define META_BACK_PROXYAUTHZ_NOANON(mi)	LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_NOANON )
413e670fd5cSchristos 
414e670fd5cSchristos #define META_BACK_QUARANTINE(mi)	LDAP_BACK_ISSET( (mi), LDAP_BACK_F_QUARANTINE )
415e670fd5cSchristos 
416e670fd5cSchristos 	time_t			mi_idle_timeout;
417e670fd5cSchristos 	struct re_s *mi_task;
418e670fd5cSchristos 
419e670fd5cSchristos 	a_metacommon_t	mi_mc;
420e670fd5cSchristos 	ldap_extra_t	*mi_ldap_extra;
421e670fd5cSchristos 
422e670fd5cSchristos 	int                    mi_max_timeout_ops;
423e670fd5cSchristos 	int                    mi_max_pending_ops;
424e670fd5cSchristos 	int                    mi_max_target_conns;
425e670fd5cSchristos 	/* mutex for access to the connection structures */
426e670fd5cSchristos 	ldap_pvt_thread_mutex_t	mi_mc_mutex;
427e670fd5cSchristos 	int                    mi_num_conns;
428e670fd5cSchristos 	int                    mi_next_conn;
429e670fd5cSchristos 	a_metaconn_t          *mi_conns;
430e670fd5cSchristos 
431e670fd5cSchristos 	struct berval		mi_suffix;
432e670fd5cSchristos } a_metainfo_t;
433e670fd5cSchristos 
434e670fd5cSchristos typedef enum meta_op_type {
435e670fd5cSchristos 	META_OP_ALLOW_MULTIPLE = 0,
436e670fd5cSchristos 	META_OP_REQUIRE_SINGLE,
437e670fd5cSchristos 	META_OP_REQUIRE_ALL
438e670fd5cSchristos } meta_op_type;
439e670fd5cSchristos 
440e670fd5cSchristos /* Whatever context asyncmeta_dn_massage needs... */
441e670fd5cSchristos typedef struct a_dncookie {
442e670fd5cSchristos 	Operation		*op;
443e670fd5cSchristos 	struct a_metatarget_t	*target;
444e670fd5cSchristos 	void	*memctx;
445e670fd5cSchristos 	int	to_from;
446e670fd5cSchristos } a_dncookie;
447e670fd5cSchristos 
448e670fd5cSchristos 
449e670fd5cSchristos #define MASSAGE_REQ	0
450e670fd5cSchristos #define MASSAGE_REP	1
451e670fd5cSchristos 
452e670fd5cSchristos extern void
453e670fd5cSchristos asyncmeta_dn_massage(a_dncookie *dc, struct berval *dn,
454e670fd5cSchristos 	struct berval *res);
455e670fd5cSchristos 
456e670fd5cSchristos extern void
457e670fd5cSchristos asyncmeta_filter_map_rewrite(
458e670fd5cSchristos 	a_dncookie	*dc,
459e670fd5cSchristos 	Filter		*f,
460e670fd5cSchristos 	struct berval	*fstr );
461e670fd5cSchristos 
462e670fd5cSchristos extern void
463e670fd5cSchristos asyncmeta_back_referral_result_rewrite(
464e670fd5cSchristos 	a_dncookie	*dc,
465e670fd5cSchristos 	BerVarray	a_vals );
466e670fd5cSchristos 
467e670fd5cSchristos extern a_metaconn_t *
468e670fd5cSchristos asyncmeta_getconn(
469e670fd5cSchristos 	Operation		*op,
470e670fd5cSchristos 	SlapReply		*rs,
471e670fd5cSchristos 	SlapReply               *candidates,
472e670fd5cSchristos 	int			*candidate,
473e670fd5cSchristos 	ldap_back_send_t	sendok,
474e670fd5cSchristos 	int                     alloc_new);
475e670fd5cSchristos 
476e670fd5cSchristos 
477e670fd5cSchristos extern int
478e670fd5cSchristos asyncmeta_init_one_conn(
479e670fd5cSchristos 	Operation		*op,
480e670fd5cSchristos 	SlapReply		*rs,
481e670fd5cSchristos 	a_metaconn_t		*mc,
482e670fd5cSchristos 	int			candidate,
483e670fd5cSchristos 	int			ispriv,
484e670fd5cSchristos 	ldap_back_send_t	sendok,
485e670fd5cSchristos 	int			dolock );
486e670fd5cSchristos 
487e670fd5cSchristos extern void
488e670fd5cSchristos asyncmeta_quarantine(
489e670fd5cSchristos 	Operation		*op,
490e670fd5cSchristos 	a_metainfo_t            *mi,
491e670fd5cSchristos 	SlapReply		*rs,
492e670fd5cSchristos 	int			candidate );
493e670fd5cSchristos 
494e670fd5cSchristos extern int
495e670fd5cSchristos asyncmeta_proxy_authz_cred(
496e670fd5cSchristos 	a_metaconn_t		*mc,
497e670fd5cSchristos 	int			candidate,
498e670fd5cSchristos 	Operation		*op,
499e670fd5cSchristos 	SlapReply		*rs,
500e670fd5cSchristos 	ldap_back_send_t	sendok,
501e670fd5cSchristos 	struct berval		*binddn,
502e670fd5cSchristos 	struct berval		*bindcred,
503e670fd5cSchristos 	int			*method );
504e670fd5cSchristos 
505e670fd5cSchristos extern int
506e670fd5cSchristos asyncmeta_controls_add(
507e670fd5cSchristos 	Operation	*op,
508e670fd5cSchristos 	SlapReply	*rs,
509e670fd5cSchristos 	a_metaconn_t	*mc,
510e670fd5cSchristos 	int		candidate,
511e670fd5cSchristos 	int             isroot,
512e670fd5cSchristos 	LDAPControl	***pctrls );
513e670fd5cSchristos 
514e670fd5cSchristos extern int
515e670fd5cSchristos asyncmeta_LTX_init_module(
516e670fd5cSchristos 	int			argc,
517e670fd5cSchristos 	char			*argv[] );
518e670fd5cSchristos 
519e670fd5cSchristos /*
520e670fd5cSchristos  * Candidate stuff
521e670fd5cSchristos  */
522e670fd5cSchristos extern int
523e670fd5cSchristos asyncmeta_is_candidate(
524e670fd5cSchristos 	a_metatarget_t		*mt,
525e670fd5cSchristos 	struct berval		*ndn,
526e670fd5cSchristos 	int			scope );
527e670fd5cSchristos 
528e670fd5cSchristos extern int
529e670fd5cSchristos asyncmeta_select_unique_candidate(
530e670fd5cSchristos 	a_metainfo_t		*mi,
531e670fd5cSchristos 	struct berval		*ndn );
532e670fd5cSchristos 
533e670fd5cSchristos extern int
534e670fd5cSchristos asyncmeta_clear_unused_candidates(
535e670fd5cSchristos 	Operation		*op,
536e670fd5cSchristos 	int			candidate,
537e670fd5cSchristos 	a_metaconn_t            *mc,
538e670fd5cSchristos 	SlapReply	*candidates);
539e670fd5cSchristos 
540e670fd5cSchristos /*
541e670fd5cSchristos  * Dn cache stuff (experimental)
542e670fd5cSchristos  */
543e670fd5cSchristos extern int
544e670fd5cSchristos asyncmeta_dncache_cmp(
545e670fd5cSchristos 	const void		*c1,
546e670fd5cSchristos 	const void		*c2 );
547e670fd5cSchristos 
548e670fd5cSchristos extern int
549e670fd5cSchristos asyncmeta_dncache_dup(
550e670fd5cSchristos 	void			*c1,
551e670fd5cSchristos 	void			*c2 );
552e670fd5cSchristos 
553e670fd5cSchristos #define META_TARGET_NONE	(-1)
554e670fd5cSchristos #define META_TARGET_MULTIPLE	(-2)
555e670fd5cSchristos extern int
556e670fd5cSchristos asyncmeta_dncache_get_target(
557e670fd5cSchristos 	a_metadncache_t		*cache,
558e670fd5cSchristos 	struct berval		*ndn );
559e670fd5cSchristos 
560e670fd5cSchristos extern int
561e670fd5cSchristos meta_dncache_update_entry(
562e670fd5cSchristos 	a_metadncache_t		*cache,
563e670fd5cSchristos 	struct berval		*ndn,
564e670fd5cSchristos 	int			target );
565e670fd5cSchristos 
566e670fd5cSchristos extern int
567e670fd5cSchristos asyncmeta_dncache_delete_entry(
568e670fd5cSchristos 	a_metadncache_t		*cache,
569e670fd5cSchristos 	struct berval		*ndn );
570e670fd5cSchristos 
571e670fd5cSchristos extern void
572e670fd5cSchristos asyncmeta_dncache_free( void *entry );
573e670fd5cSchristos 
574e670fd5cSchristos extern int
575e670fd5cSchristos asyncmeta_subtree_destroy( a_metasubtree_t *ms );
576e670fd5cSchristos 
577e670fd5cSchristos extern void
578e670fd5cSchristos asyncmeta_filter_destroy( metafilter_t *mf );
579e670fd5cSchristos 
580e670fd5cSchristos extern int
581e670fd5cSchristos asyncmeta_target_finish( a_metainfo_t *mi, a_metatarget_t *mt,
582e670fd5cSchristos 	const char *log, char *msg, size_t msize
583e670fd5cSchristos );
584e670fd5cSchristos 
585e670fd5cSchristos 
586e670fd5cSchristos extern LDAP_REBIND_PROC		asyncmeta_back_default_rebind;
587e670fd5cSchristos extern LDAP_URLLIST_PROC	asyncmeta_back_default_urllist;
588e670fd5cSchristos 
589e670fd5cSchristos /* IGNORE means that target does not (no longer) participate
590e670fd5cSchristos  * in the search;
591e670fd5cSchristos  * NOTREADY means the search on that target has not been initialized yet
592e670fd5cSchristos  */
593e670fd5cSchristos #define	META_MSGID_IGNORE	(-1)
594e670fd5cSchristos #define	META_MSGID_NEED_BIND	(-2)
595e670fd5cSchristos #define	META_MSGID_CONNECTING	(-3)
596e670fd5cSchristos #define META_MSGID_UNDEFINED    (-4)
597e670fd5cSchristos #define META_MSGID_GOT_BIND     (-5)
598e670fd5cSchristos 
599e670fd5cSchristos typedef enum meta_search_candidate_t {
600e670fd5cSchristos 	META_SEARCH_UNDEFINED = -2,
601e670fd5cSchristos 	META_SEARCH_ERR = -1,
602e670fd5cSchristos 	META_SEARCH_NOT_CANDIDATE,
603e670fd5cSchristos 	META_SEARCH_CANDIDATE,
604e670fd5cSchristos 	META_SEARCH_BINDING,
605e670fd5cSchristos 	META_SEARCH_NEED_BIND,
606e670fd5cSchristos 	META_SEARCH_CONNECTING
607e670fd5cSchristos } meta_search_candidate_t;
608e670fd5cSchristos 
609e670fd5cSchristos Operation* asyncmeta_copy_op(Operation *op);
610e670fd5cSchristos void asyncmeta_clear_bm_context(bm_context_t *bc);
611e670fd5cSchristos 
612e670fd5cSchristos int asyncmeta_add_message_queue(a_metaconn_t *mc, bm_context_t *bc);
613e670fd5cSchristos void asyncmeta_drop_bc(a_metaconn_t *mc, bm_context_t *bc);
614e670fd5cSchristos void asyncmeta_drop_bc_from_fconn(bm_context_t *bc);
615e670fd5cSchristos 
616e670fd5cSchristos bm_context_t *
617e670fd5cSchristos asyncmeta_find_message(ber_int_t msgid, a_metaconn_t *mc, int candidate);
618e670fd5cSchristos 
619e670fd5cSchristos void* asyncmeta_op_handle_result(void *ctx, void *arg);
620e670fd5cSchristos int asyncmeta_back_cleanup( Operation *op, SlapReply *rs, bm_context_t *bm );
621e670fd5cSchristos 
622e670fd5cSchristos int
623e670fd5cSchristos asyncmeta_clear_one_msc(
624e670fd5cSchristos 	Operation	*op,
625e670fd5cSchristos 	a_metaconn_t	*msc,
626e670fd5cSchristos 	int		candidate,
627e670fd5cSchristos 	int             unbind,
628e670fd5cSchristos 	const char *          caller);
629e670fd5cSchristos 
630e670fd5cSchristos a_metaconn_t *
631e670fd5cSchristos asyncmeta_get_next_mc( a_metainfo_t *mi );
632e670fd5cSchristos 
633e670fd5cSchristos void* asyncmeta_timeout_loop(void *ctx, void *arg);
634e670fd5cSchristos 
635e670fd5cSchristos int
636e670fd5cSchristos asyncmeta_start_timeout_loop(a_metatarget_t *mt, a_metainfo_t *mi);
637e670fd5cSchristos 
638e670fd5cSchristos void asyncmeta_set_msc_time(a_metasingleconn_t *msc);
639e670fd5cSchristos 
640e670fd5cSchristos int asyncmeta_back_cancel(
641e670fd5cSchristos 	a_metaconn_t	*mc,
642e670fd5cSchristos 	Operation		*op,
643e670fd5cSchristos 	ber_int_t		msgid,
644e670fd5cSchristos 	int				candidate );
645e670fd5cSchristos 
646e670fd5cSchristos void
647e670fd5cSchristos asyncmeta_send_result(bm_context_t* bc, int error, char *text);
648e670fd5cSchristos 
649e670fd5cSchristos int asyncmeta_new_bm_context(Operation *op,
650e670fd5cSchristos 			     SlapReply *rs,
651e670fd5cSchristos 			     bm_context_t **new_bc,
652e670fd5cSchristos 			     int ntargets,
653e670fd5cSchristos 			     a_metainfo_t       *mi);
654e670fd5cSchristos 
655e670fd5cSchristos int asyncmeta_start_listeners(a_metaconn_t *mc, SlapReply *candidates,  bm_context_t *bc);
656e670fd5cSchristos int asyncmeta_start_one_listener(a_metaconn_t *mc, SlapReply *candidates,  bm_context_t *bc, int candidate);
657e670fd5cSchristos 
658e670fd5cSchristos meta_search_candidate_t
659e670fd5cSchristos asyncmeta_back_search_start(
660e670fd5cSchristos 	Operation             *op,
661e670fd5cSchristos 	SlapReply             *rs,
662e670fd5cSchristos 	a_metaconn_t          *mc,
663e670fd5cSchristos 	bm_context_t          *bc,
664e670fd5cSchristos 	int                   candidate,
665e670fd5cSchristos 	struct berval	      *prcookie,
666e670fd5cSchristos 	ber_int_t	      prsize,
667e670fd5cSchristos 	int do_lock);
668e670fd5cSchristos 
669e670fd5cSchristos meta_search_candidate_t
670e670fd5cSchristos asyncmeta_dobind_init(
671e670fd5cSchristos 	Operation            *op,
672e670fd5cSchristos 	SlapReply            *rs,
673e670fd5cSchristos 	bm_context_t         *bc,
674e670fd5cSchristos 	a_metaconn_t         *mc,
675e670fd5cSchristos 	int                  candidate);
676e670fd5cSchristos 
677e670fd5cSchristos meta_search_candidate_t
678e670fd5cSchristos asyncmeta_dobind_init_with_retry(
679e670fd5cSchristos 	Operation            *op,
680e670fd5cSchristos 	SlapReply            *rs,
681e670fd5cSchristos 	bm_context_t         *bc,
682e670fd5cSchristos 	a_metaconn_t         *mc,
683e670fd5cSchristos 	int                  candidate);
684e670fd5cSchristos 
685e670fd5cSchristos meta_search_candidate_t
686e670fd5cSchristos asyncmeta_back_add_start(Operation *op,
687e670fd5cSchristos 			 SlapReply *rs,
688e670fd5cSchristos 			 a_metaconn_t *mc,
689e670fd5cSchristos 			 bm_context_t *bc,
690e670fd5cSchristos 			 int candidate,
691e670fd5cSchristos 			 int do_lock);
692e670fd5cSchristos meta_search_candidate_t
693e670fd5cSchristos asyncmeta_back_modify_start(Operation *op,
694e670fd5cSchristos 			    SlapReply *rs,
695e670fd5cSchristos 			    a_metaconn_t *mc,
696e670fd5cSchristos 			    bm_context_t *bc,
697e670fd5cSchristos 			    int candidate,
698e670fd5cSchristos 			    int do_lock);
699e670fd5cSchristos 
700e670fd5cSchristos meta_search_candidate_t
701e670fd5cSchristos asyncmeta_back_modrdn_start(Operation *op,
702e670fd5cSchristos 			    SlapReply *rs,
703e670fd5cSchristos 			    a_metaconn_t *mc,
704e670fd5cSchristos 			    bm_context_t *bc,
705e670fd5cSchristos 			    int candidate,
706e670fd5cSchristos 			    int do_lock);
707e670fd5cSchristos meta_search_candidate_t
708e670fd5cSchristos asyncmeta_back_delete_start(Operation *op,
709e670fd5cSchristos 			    SlapReply *rs,
710e670fd5cSchristos 			    a_metaconn_t *mc,
711e670fd5cSchristos 			    bm_context_t *bc,
712e670fd5cSchristos 			    int candidate,
713e670fd5cSchristos 			    int do_lock);
714e670fd5cSchristos 
715e670fd5cSchristos meta_search_candidate_t
716e670fd5cSchristos asyncmeta_back_compare_start(Operation *op,
717e670fd5cSchristos 			     SlapReply *rs,
718e670fd5cSchristos 			     a_metaconn_t *mc,
719e670fd5cSchristos 			     bm_context_t *bc,
720e670fd5cSchristos 			     int candidate,
721e670fd5cSchristos 			     int do_lock);
722e670fd5cSchristos 
723e670fd5cSchristos bm_context_t *
724e670fd5cSchristos asyncmeta_bc_in_queue(a_metaconn_t *mc,
725e670fd5cSchristos 		      bm_context_t *bc);
726e670fd5cSchristos 
727e670fd5cSchristos int
728e670fd5cSchristos asyncmeta_error_cleanup(Operation *op,
729e670fd5cSchristos 			SlapReply *rs,
730e670fd5cSchristos 			bm_context_t *bc,
731e670fd5cSchristos 			a_metaconn_t *mc,
732e670fd5cSchristos 			int candidate);
733e670fd5cSchristos 
734e670fd5cSchristos int
735e670fd5cSchristos asyncmeta_reset_msc(Operation	*op,
736e670fd5cSchristos 		    a_metaconn_t	*mc,
737e670fd5cSchristos 		    int		candidate,
738e670fd5cSchristos 		    int             unbind,
739e670fd5cSchristos 		    const char *caller);
740e670fd5cSchristos 
741e670fd5cSchristos 
742e670fd5cSchristos void
743e670fd5cSchristos asyncmeta_back_conn_free(
744e670fd5cSchristos 	            void 		*v_mc );
745e670fd5cSchristos 
746e670fd5cSchristos void asyncmeta_log_msc(a_metasingleconn_t *msc);
747e670fd5cSchristos void asyncmeta_log_conns(a_metainfo_t *mi);
748e670fd5cSchristos 
749e670fd5cSchristos void asyncmeta_get_timestamp(char *buf);
750e670fd5cSchristos 
751e670fd5cSchristos int
752e670fd5cSchristos asyncmeta_dncache_update_entry(a_metadncache_t	*cache,
753e670fd5cSchristos 			       struct berval	*ndn,
754e670fd5cSchristos 			       int 		target );
755e670fd5cSchristos 
756e670fd5cSchristos void
757e670fd5cSchristos asyncmeta_dnattr_result_rewrite(a_dncookie		*dc,
758e670fd5cSchristos 				BerVarray		a_vals);
759e670fd5cSchristos 
760e670fd5cSchristos void
761e670fd5cSchristos asyncmeta_referral_result_rewrite(a_dncookie		*dc,
762e670fd5cSchristos 				  BerVarray		a_vals);
763e670fd5cSchristos 
764e670fd5cSchristos meta_search_candidate_t
765e670fd5cSchristos asyncmeta_send_all_pending_ops(a_metaconn_t *mc,
766e670fd5cSchristos 			       int          candidate,
767e670fd5cSchristos 			       void         *ctx,
768e670fd5cSchristos 			       int          dolock);
769e670fd5cSchristos meta_search_candidate_t
770e670fd5cSchristos asyncmeta_return_bind_errors(a_metaconn_t *mc,
771e670fd5cSchristos 			     int          candidate,
772e670fd5cSchristos 			     SlapReply    *bind_result,
773e670fd5cSchristos 			     void         *ctx,
774e670fd5cSchristos 			     int          dolock);
775e670fd5cSchristos 
776e670fd5cSchristos /* The the maximum time in seconds after a result has been received on a connection,
777e670fd5cSchristos  * after which it can be reset if a sender error occurs. Should this be configurable? */
778e670fd5cSchristos #define META_BACK_RESULT_INTERVAL (2)
779e670fd5cSchristos 
780e670fd5cSchristos extern int asyncmeta_debug;
781e670fd5cSchristos 
782e670fd5cSchristos LDAP_END_DECL
783e670fd5cSchristos 
784e670fd5cSchristos #endif /* SLAPD_ASYNCMETA_H */
785