xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/connection.c (revision c2f76ff004a2cb67efe5b12d97bd3ef7fe89e18d)
1 /*	$NetBSD: connection.c,v 1.1.1.3 2010/12/12 15:22:27 adam Exp $	*/
2 
3 /* OpenLDAP: pkg/ldap/servers/slapd/connection.c,v 1.358.2.40 2010/04/13 20:23:13 kurt Exp */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 1998-2010 The OpenLDAP Foundation.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
13  * A copy of this license is available in the file LICENSE in the
14  * top-level directory of the distribution or, alternatively, at
15  * <http://www.OpenLDAP.org/license.html>.
16  */
17 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
18  * All rights reserved.
19  *
20  * Redistribution and use in source and binary forms are permitted
21  * provided that this notice is preserved and that due credit is given
22  * to the University of Michigan at Ann Arbor. The name of the University
23  * may not be used to endorse or promote products derived from this
24  * software without specific prior written permission. This software
25  * is provided ``as is'' without express or implied warranty.
26  */
27 
28 #include "portable.h"
29 
30 #include <stdio.h>
31 #ifdef HAVE_LIMITS_H
32 #include <limits.h>
33 #endif
34 
35 #include <ac/socket.h>
36 #include <ac/errno.h>
37 #include <ac/string.h>
38 #include <ac/time.h>
39 #include <ac/unistd.h>
40 
41 #include "lutil.h"
42 #include "slap.h"
43 
44 #ifdef LDAP_SLAPI
45 #include "slapi/slapi.h"
46 #endif
47 
48 /* protected by connections_mutex */
49 static ldap_pvt_thread_mutex_t connections_mutex;
50 static Connection *connections = NULL;
51 
52 static ldap_pvt_thread_mutex_t conn_nextid_mutex;
53 static unsigned long conn_nextid = SLAPD_SYNC_SYNCCONN_OFFSET;
54 
55 static const char conn_lost_str[] = "connection lost";
56 
57 const char *
58 connection_state2str( int state )
59 {
60 	switch( state ) {
61 	case SLAP_C_INVALID:	return "!";
62 	case SLAP_C_INACTIVE:	return "|";
63 	case SLAP_C_CLOSING:	return "C";
64 	case SLAP_C_ACTIVE:		return "";
65 	case SLAP_C_BINDING:	return "B";
66 	case SLAP_C_CLIENT:		return "L";
67 	}
68 
69 	return "?";
70 }
71 
72 static Connection* connection_get( ber_socket_t s );
73 
74 typedef struct conn_readinfo {
75 	Operation *op;
76 	ldap_pvt_thread_start_t *func;
77 	void *arg;
78 	void *ctx;
79 	int nullop;
80 } conn_readinfo;
81 
82 static int connection_input( Connection *c, conn_readinfo *cri );
83 static void connection_close( Connection *c );
84 
85 static int connection_op_activate( Operation *op );
86 static void connection_op_queue( Operation *op );
87 static int connection_resched( Connection *conn );
88 static void connection_abandon( Connection *conn );
89 static void connection_destroy( Connection *c );
90 
91 static ldap_pvt_thread_start_t connection_operation;
92 
93 /*
94  * Initialize connection management infrastructure.
95  */
96 int connections_init(void)
97 {
98 	int i;
99 
100 	assert( connections == NULL );
101 
102 	if( connections != NULL) {
103 		Debug( LDAP_DEBUG_ANY, "connections_init: already initialized.\n",
104 			0, 0, 0 );
105 		return -1;
106 	}
107 
108 	/* should check return of every call */
109 	ldap_pvt_thread_mutex_init( &connections_mutex );
110 	ldap_pvt_thread_mutex_init( &conn_nextid_mutex );
111 
112 	connections = (Connection *) ch_calloc( dtblsize, sizeof(Connection) );
113 
114 	if( connections == NULL ) {
115 		Debug( LDAP_DEBUG_ANY, "connections_init: "
116 			"allocation (%d*%ld) of connection array failed\n",
117 			dtblsize, (long) sizeof(Connection), 0 );
118 		return -1;
119 	}
120 
121 	assert( connections[0].c_struct_state == SLAP_C_UNINITIALIZED );
122 	assert( connections[dtblsize-1].c_struct_state == SLAP_C_UNINITIALIZED );
123 
124 	for (i=0; i<dtblsize; i++) connections[i].c_conn_idx = i;
125 
126 	/*
127 	 * per entry initialization of the Connection array initialization
128 	 * will be done by connection_init()
129 	 */
130 
131 	return 0;
132 }
133 
134 /*
135  * Destroy connection management infrastructure.
136  */
137 
138 int connections_destroy(void)
139 {
140 	ber_socket_t i;
141 
142 	/* should check return of every call */
143 
144 	if( connections == NULL) {
145 		Debug( LDAP_DEBUG_ANY, "connections_destroy: nothing to destroy.\n",
146 			0, 0, 0 );
147 		return -1;
148 	}
149 
150 	for ( i = 0; i < dtblsize; i++ ) {
151 		if( connections[i].c_struct_state != SLAP_C_UNINITIALIZED ) {
152 			ber_sockbuf_free( connections[i].c_sb );
153 			ldap_pvt_thread_mutex_destroy( &connections[i].c_mutex );
154 			ldap_pvt_thread_mutex_destroy( &connections[i].c_write1_mutex );
155 			ldap_pvt_thread_mutex_destroy( &connections[i].c_write2_mutex );
156 			ldap_pvt_thread_cond_destroy( &connections[i].c_write1_cv );
157 			ldap_pvt_thread_cond_destroy( &connections[i].c_write2_cv );
158 #ifdef LDAP_SLAPI
159 			if ( slapi_plugins_used ) {
160 				slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION,
161 					&connections[i] );
162 			}
163 #endif
164 		}
165 	}
166 
167 	free( connections );
168 	connections = NULL;
169 
170 	ldap_pvt_thread_mutex_destroy( &connections_mutex );
171 	ldap_pvt_thread_mutex_destroy( &conn_nextid_mutex );
172 	return 0;
173 }
174 
175 /*
176  * shutdown all connections
177  */
178 int connections_shutdown(void)
179 {
180 	ber_socket_t i;
181 
182 	for ( i = 0; i < dtblsize; i++ ) {
183 		if( connections[i].c_struct_state != SLAP_C_UNINITIALIZED ) {
184 			ldap_pvt_thread_mutex_lock( &connections[i].c_mutex );
185 			if( connections[i].c_struct_state == SLAP_C_USED ) {
186 
187 				/* give persistent clients a chance to cleanup */
188 				if( connections[i].c_conn_state == SLAP_C_CLIENT ) {
189 					ldap_pvt_thread_pool_submit( &connection_pool,
190 					connections[i].c_clientfunc, connections[i].c_clientarg );
191 				} else {
192 					/* c_mutex is locked */
193 					connection_closing( &connections[i], "slapd shutdown" );
194 					connection_close( &connections[i] );
195 				}
196 			}
197 			ldap_pvt_thread_mutex_unlock( &connections[i].c_mutex );
198 		}
199 	}
200 
201 	return 0;
202 }
203 
204 /*
205  * Timeout idle connections.
206  */
207 int connections_timeout_idle(time_t now)
208 {
209 	int i = 0, writers = 0;
210 	int connindex;
211 	Connection* c;
212 	time_t old;
213 
214 	old = slapd_get_writetime();
215 
216 	for( c = connection_first( &connindex );
217 		c != NULL;
218 		c = connection_next( c, &connindex ) )
219 	{
220 		/* Don't timeout a slow-running request or a persistent
221 		 * outbound connection. But if it has a writewaiter, see
222 		 * if the waiter has been there too long.
223 		 */
224 		if(( c->c_n_ops_executing && !c->c_writewaiter)
225 			|| c->c_conn_state == SLAP_C_CLIENT ) {
226 			continue;
227 		}
228 
229 		if( global_idletimeout &&
230 			difftime( c->c_activitytime+global_idletimeout, now) < 0 ) {
231 			/* close it */
232 			connection_closing( c, "idletimeout" );
233 			connection_close( c );
234 			i++;
235 			continue;
236 		}
237 		if ( c->c_writewaiter && global_writetimeout ) {
238 			writers = 1;
239 			if( difftime( c->c_activitytime+global_writetimeout, now) < 0 ) {
240 				/* close it */
241 				connection_closing( c, "writetimeout" );
242 				connection_close( c );
243 				i++;
244 			}
245 		}
246 	}
247 	connection_done( c );
248 	if ( old && !writers )
249 		slapd_clr_writetime( old );
250 
251 	return i;
252 }
253 
254 static Connection* connection_get( ber_socket_t s )
255 {
256 	Connection *c;
257 
258 	Debug( LDAP_DEBUG_ARGS,
259 		"connection_get(%ld)\n",
260 		(long) s, 0, 0 );
261 
262 	assert( connections != NULL );
263 
264 	if(s == AC_SOCKET_INVALID) return NULL;
265 
266 	assert( s < dtblsize );
267 	c = &connections[s];
268 
269 	if( c != NULL ) {
270 		ldap_pvt_thread_mutex_lock( &c->c_mutex );
271 
272 		assert( c->c_struct_state != SLAP_C_UNINITIALIZED );
273 
274 		if( c->c_struct_state != SLAP_C_USED ) {
275 			/* connection must have been closed due to resched */
276 
277 			assert( c->c_conn_state == SLAP_C_INVALID );
278 			assert( c->c_sd == AC_SOCKET_INVALID );
279 
280 			Debug( LDAP_DEBUG_CONNS,
281 				"connection_get(%d): connection not used\n",
282 				s, 0, 0 );
283 
284 			ldap_pvt_thread_mutex_unlock( &c->c_mutex );
285 			return NULL;
286 		}
287 
288 		Debug( LDAP_DEBUG_TRACE,
289 			"connection_get(%d): got connid=%lu\n",
290 			s, c->c_connid, 0 );
291 
292 		c->c_n_get++;
293 
294 		assert( c->c_struct_state == SLAP_C_USED );
295 		assert( c->c_conn_state != SLAP_C_INVALID );
296 		assert( c->c_sd != AC_SOCKET_INVALID );
297 
298 #ifndef SLAPD_MONITOR
299 		if ( global_idletimeout > 0 )
300 #endif /* ! SLAPD_MONITOR */
301 		{
302 			c->c_activitytime = slap_get_time();
303 		}
304 	}
305 
306 	return c;
307 }
308 
309 static void connection_return( Connection *c )
310 {
311 	ldap_pvt_thread_mutex_unlock( &c->c_mutex );
312 }
313 
314 Connection * connection_init(
315 	ber_socket_t s,
316 	Listener *listener,
317 	const char* dnsname,
318 	const char* peername,
319 	int flags,
320 	slap_ssf_t ssf,
321 	struct berval *authid
322 	LDAP_PF_LOCAL_SENDMSG_ARG(struct berval *peerbv))
323 {
324 	unsigned long id;
325 	Connection *c;
326 	int doinit = 0;
327 	ber_socket_t sfd = SLAP_FD2SOCK(s);
328 
329 	assert( connections != NULL );
330 
331 	assert( listener != NULL );
332 	assert( dnsname != NULL );
333 	assert( peername != NULL );
334 
335 #ifndef HAVE_TLS
336 	assert( !( flags & CONN_IS_TLS ));
337 #endif
338 
339 	if( s == AC_SOCKET_INVALID ) {
340 		Debug( LDAP_DEBUG_ANY,
341 			"connection_init: init of socket %ld invalid.\n", (long)s, 0, 0 );
342 		return NULL;
343 	}
344 
345 	assert( s >= 0 );
346 	assert( s < dtblsize );
347 	c = &connections[s];
348 	if( c->c_struct_state == SLAP_C_UNINITIALIZED ) {
349 		doinit = 1;
350 	} else {
351 		assert( c->c_struct_state == SLAP_C_UNUSED );
352 	}
353 
354 	if( doinit ) {
355 		c->c_send_ldap_result = slap_send_ldap_result;
356 		c->c_send_search_entry = slap_send_search_entry;
357 		c->c_send_search_reference = slap_send_search_reference;
358 		c->c_send_ldap_extended = slap_send_ldap_extended;
359 		c->c_send_ldap_intermediate = slap_send_ldap_intermediate;
360 
361 		BER_BVZERO( &c->c_authmech );
362 		BER_BVZERO( &c->c_dn );
363 		BER_BVZERO( &c->c_ndn );
364 
365 		c->c_listener = NULL;
366 		BER_BVZERO( &c->c_peer_domain );
367 		BER_BVZERO( &c->c_peer_name );
368 
369 		LDAP_STAILQ_INIT(&c->c_ops);
370 		LDAP_STAILQ_INIT(&c->c_pending_ops);
371 
372 #ifdef LDAP_X_TXN
373 		c->c_txn = CONN_TXN_INACTIVE;
374 		c->c_txn_backend = NULL;
375 		LDAP_STAILQ_INIT(&c->c_txn_ops);
376 #endif
377 
378 		BER_BVZERO( &c->c_sasl_bind_mech );
379 		c->c_sasl_done = 0;
380 		c->c_sasl_authctx = NULL;
381 		c->c_sasl_sockctx = NULL;
382 		c->c_sasl_extra = NULL;
383 		c->c_sasl_bindop = NULL;
384 
385 		c->c_sb = ber_sockbuf_alloc( );
386 
387 		{
388 			ber_len_t max = sockbuf_max_incoming;
389 			ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
390 		}
391 
392 		c->c_currentber = NULL;
393 
394 		/* should check status of thread calls */
395 		ldap_pvt_thread_mutex_init( &c->c_mutex );
396 		ldap_pvt_thread_mutex_init( &c->c_write1_mutex );
397 		ldap_pvt_thread_mutex_init( &c->c_write2_mutex );
398 		ldap_pvt_thread_cond_init( &c->c_write1_cv );
399 		ldap_pvt_thread_cond_init( &c->c_write2_cv );
400 
401 #ifdef LDAP_SLAPI
402 		if ( slapi_plugins_used ) {
403 			slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, c );
404 		}
405 #endif
406 	}
407 
408 	ldap_pvt_thread_mutex_lock( &c->c_mutex );
409 
410 	assert( BER_BVISNULL( &c->c_authmech ) );
411 	assert( BER_BVISNULL( &c->c_dn ) );
412 	assert( BER_BVISNULL( &c->c_ndn ) );
413 	assert( c->c_listener == NULL );
414 	assert( BER_BVISNULL( &c->c_peer_domain ) );
415 	assert( BER_BVISNULL( &c->c_peer_name ) );
416 	assert( LDAP_STAILQ_EMPTY(&c->c_ops) );
417 	assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) );
418 #ifdef LDAP_X_TXN
419 	assert( c->c_txn == CONN_TXN_INACTIVE );
420 	assert( c->c_txn_backend == NULL );
421 	assert( LDAP_STAILQ_EMPTY(&c->c_txn_ops) );
422 #endif
423 	assert( BER_BVISNULL( &c->c_sasl_bind_mech ) );
424 	assert( c->c_sasl_done == 0 );
425 	assert( c->c_sasl_authctx == NULL );
426 	assert( c->c_sasl_sockctx == NULL );
427 	assert( c->c_sasl_extra == NULL );
428 	assert( c->c_sasl_bindop == NULL );
429 	assert( c->c_currentber == NULL );
430 	assert( c->c_writewaiter == 0);
431 	assert( c->c_writers == 0);
432 
433 	c->c_listener = listener;
434 	c->c_sd = s;
435 
436 	if ( flags & CONN_IS_CLIENT ) {
437 		c->c_connid = 0;
438 		ldap_pvt_thread_mutex_lock( &connections_mutex );
439 		c->c_conn_state = SLAP_C_CLIENT;
440 		c->c_struct_state = SLAP_C_USED;
441 		ldap_pvt_thread_mutex_unlock( &connections_mutex );
442 		c->c_close_reason = "?";			/* should never be needed */
443 		ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_FD, &sfd );
444 		ldap_pvt_thread_mutex_unlock( &c->c_mutex );
445 
446 		return c;
447 	}
448 
449 	ber_str2bv( dnsname, 0, 1, &c->c_peer_domain );
450 	ber_str2bv( peername, 0, 1, &c->c_peer_name );
451 
452 	c->c_n_ops_received = 0;
453 	c->c_n_ops_executing = 0;
454 	c->c_n_ops_pending = 0;
455 	c->c_n_ops_completed = 0;
456 
457 	c->c_n_get = 0;
458 	c->c_n_read = 0;
459 	c->c_n_write = 0;
460 
461 	/* set to zero until bind, implies LDAP_VERSION3 */
462 	c->c_protocol = 0;
463 
464 #ifndef SLAPD_MONITOR
465 	if ( global_idletimeout > 0 )
466 #endif /* ! SLAPD_MONITOR */
467 	{
468 		c->c_activitytime = c->c_starttime = slap_get_time();
469 	}
470 
471 #ifdef LDAP_CONNECTIONLESS
472 	c->c_is_udp = 0;
473 	if( flags & CONN_IS_UDP ) {
474 		c->c_is_udp = 1;
475 #ifdef LDAP_DEBUG
476 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug,
477 			LBER_SBIOD_LEVEL_PROVIDER, (void*)"udp_" );
478 #endif
479 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_udp,
480 			LBER_SBIOD_LEVEL_PROVIDER, (void *)&sfd );
481 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_readahead,
482 			LBER_SBIOD_LEVEL_PROVIDER, NULL );
483 	} else
484 #endif /* LDAP_CONNECTIONLESS */
485 #ifdef LDAP_PF_LOCAL
486 	if ( flags & CONN_IS_IPC ) {
487 #ifdef LDAP_DEBUG
488 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug,
489 			LBER_SBIOD_LEVEL_PROVIDER, (void*)"ipc_" );
490 #endif
491 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_fd,
492 			LBER_SBIOD_LEVEL_PROVIDER, (void *)&sfd );
493 #ifdef LDAP_PF_LOCAL_SENDMSG
494 		if ( !BER_BVISEMPTY( peerbv ))
495 			ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_UNGET_BUF, peerbv );
496 #endif
497 	} else
498 #endif /* LDAP_PF_LOCAL */
499 	{
500 #ifdef LDAP_DEBUG
501 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug,
502 			LBER_SBIOD_LEVEL_PROVIDER, (void*)"tcp_" );
503 #endif
504 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_tcp,
505 			LBER_SBIOD_LEVEL_PROVIDER, (void *)&sfd );
506 	}
507 
508 #ifdef LDAP_DEBUG
509 	ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug,
510 		INT_MAX, (void*)"ldap_" );
511 #endif
512 
513 	if( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_NONBLOCK,
514 		c /* non-NULL */ ) < 0 )
515 	{
516 		Debug( LDAP_DEBUG_ANY,
517 			"connection_init(%d, %s): set nonblocking failed\n",
518 			s, c->c_peer_name.bv_val, 0 );
519 	}
520 
521 	ldap_pvt_thread_mutex_lock( &conn_nextid_mutex );
522 	id = c->c_connid = conn_nextid++;
523 	ldap_pvt_thread_mutex_unlock( &conn_nextid_mutex );
524 
525 	ldap_pvt_thread_mutex_lock( &connections_mutex );
526 	c->c_conn_state = SLAP_C_INACTIVE;
527 	c->c_struct_state = SLAP_C_USED;
528 	ldap_pvt_thread_mutex_unlock( &connections_mutex );
529 	c->c_close_reason = "?";			/* should never be needed */
530 
531 	c->c_ssf = c->c_transport_ssf = ssf;
532 	c->c_tls_ssf = 0;
533 
534 #ifdef HAVE_TLS
535 	if ( flags & CONN_IS_TLS ) {
536 		c->c_is_tls = 1;
537 		c->c_needs_tls_accept = 1;
538 	} else {
539 		c->c_is_tls = 0;
540 		c->c_needs_tls_accept = 0;
541 	}
542 #endif
543 
544 	slap_sasl_open( c, 0 );
545 	slap_sasl_external( c, ssf, authid );
546 
547 	slapd_add_internal( s, 1 );
548 	ldap_pvt_thread_mutex_unlock( &c->c_mutex );
549 
550 	backend_connection_init(c);
551 
552 	return c;
553 }
554 
555 void connection2anonymous( Connection *c )
556 {
557 	assert( connections != NULL );
558 	assert( c != NULL );
559 
560 	{
561 		ber_len_t max = sockbuf_max_incoming;
562 		ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
563 	}
564 
565 	if ( !BER_BVISNULL( &c->c_authmech ) ) {
566 		ch_free(c->c_authmech.bv_val);
567 	}
568 	BER_BVZERO( &c->c_authmech );
569 
570 	if ( !BER_BVISNULL( &c->c_dn ) ) {
571 		ch_free(c->c_dn.bv_val);
572 	}
573 	BER_BVZERO( &c->c_dn );
574 
575 	if ( !BER_BVISNULL( &c->c_ndn ) ) {
576 		ch_free(c->c_ndn.bv_val);
577 	}
578 	BER_BVZERO( &c->c_ndn );
579 
580 	if ( !BER_BVISNULL( &c->c_sasl_authz_dn ) ) {
581 		ber_memfree_x( c->c_sasl_authz_dn.bv_val, NULL );
582 	}
583 	BER_BVZERO( &c->c_sasl_authz_dn );
584 
585 	c->c_authz_backend = NULL;
586 }
587 
588 static void
589 connection_destroy( Connection *c )
590 {
591 	unsigned long	connid;
592 	const char		*close_reason;
593 	Sockbuf			*sb;
594 	ber_socket_t	sd;
595 
596 	assert( connections != NULL );
597 	assert( c != NULL );
598 	assert( c->c_struct_state != SLAP_C_UNUSED );
599 	assert( c->c_conn_state != SLAP_C_INVALID );
600 	assert( LDAP_STAILQ_EMPTY(&c->c_ops) );
601 	assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) );
602 #ifdef LDAP_X_TXN
603 	assert( c->c_txn == CONN_TXN_INACTIVE );
604 	assert( c->c_txn_backend == NULL );
605 	assert( LDAP_STAILQ_EMPTY(&c->c_txn_ops) );
606 #endif
607 	assert( c->c_writewaiter == 0);
608 	assert( c->c_writers == 0);
609 
610 	/* only for stats (print -1 as "%lu" may give unexpected results ;) */
611 	connid = c->c_connid;
612 	close_reason = c->c_close_reason;
613 
614 	ldap_pvt_thread_mutex_lock( &connections_mutex );
615 	c->c_struct_state = SLAP_C_PENDING;
616 	ldap_pvt_thread_mutex_unlock( &connections_mutex );
617 
618 	backend_connection_destroy(c);
619 
620 	c->c_protocol = 0;
621 	c->c_connid = -1;
622 
623 	c->c_activitytime = c->c_starttime = 0;
624 
625 	connection2anonymous( c );
626 	c->c_listener = NULL;
627 
628 	if(c->c_peer_domain.bv_val != NULL) {
629 		free(c->c_peer_domain.bv_val);
630 	}
631 	BER_BVZERO( &c->c_peer_domain );
632 	if(c->c_peer_name.bv_val != NULL) {
633 		free(c->c_peer_name.bv_val);
634 	}
635 	BER_BVZERO( &c->c_peer_name );
636 
637 	c->c_sasl_bind_in_progress = 0;
638 	if(c->c_sasl_bind_mech.bv_val != NULL) {
639 		free(c->c_sasl_bind_mech.bv_val);
640 	}
641 	BER_BVZERO( &c->c_sasl_bind_mech );
642 
643 	slap_sasl_close( c );
644 
645 	if ( c->c_currentber != NULL ) {
646 		ber_free( c->c_currentber, 1 );
647 		c->c_currentber = NULL;
648 	}
649 
650 
651 #ifdef LDAP_SLAPI
652 	/* call destructors, then constructors; avoids unnecessary allocation */
653 	if ( slapi_plugins_used ) {
654 		slapi_int_clear_object_extensions( SLAPI_X_EXT_CONNECTION, c );
655 	}
656 #endif
657 
658 	sd = c->c_sd;
659 	c->c_sd = AC_SOCKET_INVALID;
660 	c->c_conn_state = SLAP_C_INVALID;
661 	c->c_struct_state = SLAP_C_UNUSED;
662 	c->c_close_reason = "?";			/* should never be needed */
663 
664 	sb = c->c_sb;
665 	c->c_sb = ber_sockbuf_alloc( );
666 	{
667 		ber_len_t max = sockbuf_max_incoming;
668 		ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
669 	}
670 
671 	/* c must be fully reset by this point; when we call slapd_remove
672 	 * it may get immediately reused by a new connection.
673 	 */
674 	if ( sd != AC_SOCKET_INVALID ) {
675 		slapd_remove( sd, sb, 1, 0, 0 );
676 
677 		if ( close_reason == NULL ) {
678 			Statslog( LDAP_DEBUG_STATS, "conn=%lu fd=%ld closed\n",
679 				connid, (long) sd, 0, 0, 0 );
680 		} else {
681 			Statslog( LDAP_DEBUG_STATS, "conn=%lu fd=%ld closed (%s)\n",
682 				connid, (long) sd, close_reason, 0, 0 );
683 		}
684 	}
685 }
686 
687 int connection_valid( Connection *c )
688 {
689 	/* c_mutex must be locked by caller */
690 
691 	assert( c != NULL );
692 
693 	return c->c_struct_state == SLAP_C_USED &&
694 		c->c_conn_state >= SLAP_C_ACTIVE &&
695 		c->c_conn_state <= SLAP_C_CLIENT;
696 }
697 
698 static void connection_abandon( Connection *c )
699 {
700 	/* c_mutex must be locked by caller */
701 
702 	Operation *o, *next, op = {0};
703 	Opheader ohdr = {0};
704 	SlapReply rs = {0};
705 
706 	op.o_hdr = &ohdr;
707 	op.o_conn = c;
708 	op.o_connid = c->c_connid;
709 	op.o_tag = LDAP_REQ_ABANDON;
710 
711 	for ( o = LDAP_STAILQ_FIRST( &c->c_ops ); o; o=next ) {
712 		next = LDAP_STAILQ_NEXT( o, o_next );
713 		op.orn_msgid = o->o_msgid;
714 		o->o_abandon = 1;
715 		op.o_bd = frontendDB;
716 		frontendDB->be_abandon( &op, &rs );
717 	}
718 
719 #ifdef LDAP_X_TXN
720 	/* remove operations in pending transaction */
721 	while ( (o = LDAP_STAILQ_FIRST( &c->c_txn_ops )) != NULL) {
722 		LDAP_STAILQ_REMOVE_HEAD( &c->c_txn_ops, o_next );
723 		LDAP_STAILQ_NEXT(o, o_next) = NULL;
724 		slap_op_free( o, NULL );
725 	}
726 
727 	/* clear transaction */
728 	c->c_txn_backend = NULL;
729 	c->c_txn = CONN_TXN_INACTIVE;
730 #endif
731 
732 	/* remove pending operations */
733 	while ( (o = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) {
734 		LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next );
735 		LDAP_STAILQ_NEXT(o, o_next) = NULL;
736 		slap_op_free( o, NULL );
737 	}
738 }
739 
740 static void
741 connection_wake_writers( Connection *c )
742 {
743 	/* wake write blocked operations */
744 	ldap_pvt_thread_mutex_lock( &c->c_write1_mutex );
745 	if ( c->c_writers > 0 ) {
746 		c->c_writers = -c->c_writers;
747 		ldap_pvt_thread_cond_broadcast( &c->c_write1_cv );
748 		ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
749 		if ( c->c_writewaiter ) {
750 			ldap_pvt_thread_mutex_lock( &c->c_write2_mutex );
751 			ldap_pvt_thread_cond_signal( &c->c_write2_cv );
752 			slapd_clr_write( c->c_sd, 1 );
753 			ldap_pvt_thread_mutex_unlock( &c->c_write2_mutex );
754 		}
755 		ldap_pvt_thread_mutex_lock( &c->c_write1_mutex );
756 		while ( c->c_writers ) {
757 			ldap_pvt_thread_cond_wait( &c->c_write1_cv, &c->c_write1_mutex );
758 		}
759 		ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
760 	} else {
761 		ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
762 		slapd_clr_write( c->c_sd, 1 );
763 	}
764 }
765 
766 void connection_closing( Connection *c, const char *why )
767 {
768 	assert( connections != NULL );
769 	assert( c != NULL );
770 
771 	if ( c->c_struct_state != SLAP_C_USED ) return;
772 
773 	assert( c->c_conn_state != SLAP_C_INVALID );
774 
775 	/* c_mutex must be locked by caller */
776 
777 	if( c->c_conn_state != SLAP_C_CLOSING ) {
778 		Debug( LDAP_DEBUG_CONNS,
779 			"connection_closing: readying conn=%lu sd=%d for close\n",
780 			c->c_connid, c->c_sd, 0 );
781 		/* update state to closing */
782 		c->c_conn_state = SLAP_C_CLOSING;
783 		c->c_close_reason = why;
784 
785 		/* don't listen on this port anymore */
786 		slapd_clr_read( c->c_sd, 0 );
787 
788 		/* abandon active operations */
789 		connection_abandon( c );
790 
791 		/* wake write blocked operations */
792 		connection_wake_writers( c );
793 
794 	} else if( why == NULL && c->c_close_reason == conn_lost_str ) {
795 		/* Client closed connection after doing Unbind. */
796 		c->c_close_reason = NULL;
797 	}
798 }
799 
800 static void
801 connection_close( Connection *c )
802 {
803 	assert( connections != NULL );
804 	assert( c != NULL );
805 
806 	if ( c->c_struct_state != SLAP_C_USED ) return;
807 
808 	assert( c->c_conn_state == SLAP_C_CLOSING );
809 
810 	/* NOTE: c_mutex should be locked by caller */
811 
812 	if ( !LDAP_STAILQ_EMPTY(&c->c_ops) ||
813 		!LDAP_STAILQ_EMPTY(&c->c_pending_ops) )
814 	{
815 		Debug( LDAP_DEBUG_CONNS,
816 			"connection_close: deferring conn=%lu sd=%d\n",
817 			c->c_connid, c->c_sd, 0 );
818 		return;
819 	}
820 
821 	Debug( LDAP_DEBUG_TRACE, "connection_close: conn=%lu sd=%d\n",
822 		c->c_connid, c->c_sd, 0 );
823 
824 	connection_destroy( c );
825 }
826 
827 unsigned long connections_nextid(void)
828 {
829 	unsigned long id;
830 	assert( connections != NULL );
831 
832 	ldap_pvt_thread_mutex_lock( &conn_nextid_mutex );
833 
834 	id = conn_nextid;
835 
836 	ldap_pvt_thread_mutex_unlock( &conn_nextid_mutex );
837 
838 	return id;
839 }
840 
841 Connection* connection_first( ber_socket_t *index )
842 {
843 	assert( connections != NULL );
844 	assert( index != NULL );
845 
846 	ldap_pvt_thread_mutex_lock( &connections_mutex );
847 	for( *index = 0; *index < dtblsize; (*index)++) {
848 		if( connections[*index].c_struct_state != SLAP_C_UNINITIALIZED ) {
849 			break;
850 		}
851 	}
852 	ldap_pvt_thread_mutex_unlock( &connections_mutex );
853 
854 	return connection_next(NULL, index);
855 }
856 
857 Connection* connection_next( Connection *c, ber_socket_t *index )
858 {
859 	assert( connections != NULL );
860 	assert( index != NULL );
861 	assert( *index <= dtblsize );
862 
863 	if( c != NULL ) ldap_pvt_thread_mutex_unlock( &c->c_mutex );
864 
865 	c = NULL;
866 
867 	ldap_pvt_thread_mutex_lock( &connections_mutex );
868 	for(; *index < dtblsize; (*index)++) {
869 		int c_struct;
870 		if( connections[*index].c_struct_state == SLAP_C_UNINITIALIZED ) {
871 			/* FIXME: accessing c_conn_state without locking c_mutex */
872 			assert( connections[*index].c_conn_state == SLAP_C_INVALID );
873 			continue;
874 		}
875 
876 		if( connections[*index].c_struct_state == SLAP_C_USED ) {
877 			c = &connections[(*index)++];
878 			if ( ldap_pvt_thread_mutex_trylock( &c->c_mutex )) {
879 				/* avoid deadlock */
880 				ldap_pvt_thread_mutex_unlock( &connections_mutex );
881 				ldap_pvt_thread_mutex_lock( &c->c_mutex );
882 				ldap_pvt_thread_mutex_lock( &connections_mutex );
883 				if ( c->c_struct_state != SLAP_C_USED ) {
884 					ldap_pvt_thread_mutex_unlock( &c->c_mutex );
885 					c = NULL;
886 					continue;
887 				}
888 			}
889 			assert( c->c_conn_state != SLAP_C_INVALID );
890 			break;
891 		}
892 
893 		c_struct = connections[*index].c_struct_state;
894 		if ( c_struct == SLAP_C_PENDING )
895 			continue;
896 		assert( c_struct == SLAP_C_UNUSED );
897 		/* FIXME: accessing c_conn_state without locking c_mutex */
898 		assert( connections[*index].c_conn_state == SLAP_C_INVALID );
899 	}
900 
901 	ldap_pvt_thread_mutex_unlock( &connections_mutex );
902 	return c;
903 }
904 
905 void connection_done( Connection *c )
906 {
907 	assert( connections != NULL );
908 
909 	if( c != NULL ) ldap_pvt_thread_mutex_unlock( &c->c_mutex );
910 }
911 
912 /*
913  * connection_activity - handle the request operation op on connection
914  * conn.  This routine figures out what kind of operation it is and
915  * calls the appropriate stub to handle it.
916  */
917 
918 #ifdef SLAPD_MONITOR
919 /* FIXME: returns 0 in case of failure */
920 #define INCR_OP_INITIATED(index) \
921 	do { \
922 		ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \
923 		ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_initiated_[(index)], 1); \
924 		ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \
925 	} while (0)
926 #define INCR_OP_COMPLETED(index) \
927 	do { \
928 		ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \
929 		ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed, 1); \
930 		ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed_[(index)], 1); \
931 		ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \
932 	} while (0)
933 #else /* !SLAPD_MONITOR */
934 #define INCR_OP_INITIATED(index) do { } while (0)
935 #define INCR_OP_COMPLETED(index) \
936 	do { \
937 		ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \
938 		ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed, 1); \
939 		ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \
940 	} while (0)
941 #endif /* !SLAPD_MONITOR */
942 
943 /*
944  * NOTE: keep in sync with enum in slapd.h
945  */
946 static BI_op_func *opfun[] = {
947 	do_bind,
948 	do_unbind,
949 	do_search,
950 	do_compare,
951 	do_modify,
952 	do_modrdn,
953 	do_add,
954 	do_delete,
955 	do_abandon,
956 	do_extended,
957 	NULL
958 };
959 
960 /* Counters are per-thread, not per-connection.
961  */
962 static void
963 conn_counter_destroy( void *key, void *data )
964 {
965 	slap_counters_t **prev, *sc;
966 
967 	ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
968 	for ( prev = &slap_counters.sc_next, sc = slap_counters.sc_next; sc;
969 		prev = &sc->sc_next, sc = sc->sc_next ) {
970 		if ( sc == data ) {
971 			int i;
972 
973 			*prev = sc->sc_next;
974 			/* Copy data to main counter */
975 			ldap_pvt_mp_add( slap_counters.sc_bytes, sc->sc_bytes );
976 			ldap_pvt_mp_add( slap_counters.sc_pdu, sc->sc_pdu );
977 			ldap_pvt_mp_add( slap_counters.sc_entries, sc->sc_entries );
978 			ldap_pvt_mp_add( slap_counters.sc_refs, sc->sc_refs );
979 			ldap_pvt_mp_add( slap_counters.sc_ops_initiated, sc->sc_ops_initiated );
980 			ldap_pvt_mp_add( slap_counters.sc_ops_completed, sc->sc_ops_completed );
981 #ifdef SLAPD_MONITOR
982 			for ( i = 0; i < SLAP_OP_LAST; i++ ) {
983 				ldap_pvt_mp_add( slap_counters.sc_ops_initiated_[ i ], sc->sc_ops_initiated_[ i ] );
984 				ldap_pvt_mp_add( slap_counters.sc_ops_initiated_[ i ], sc->sc_ops_completed_[ i ] );
985 			}
986 #endif /* SLAPD_MONITOR */
987 			slap_counters_destroy( sc );
988 			ber_memfree_x( data, NULL );
989 			break;
990 		}
991 	}
992 	ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
993 }
994 
995 static void
996 conn_counter_init( Operation *op, void *ctx )
997 {
998 	slap_counters_t *sc;
999 	void *vsc = NULL;
1000 
1001 	if ( ldap_pvt_thread_pool_getkey(
1002 			ctx, (void *)conn_counter_init, &vsc, NULL ) || !vsc ) {
1003 		vsc = ch_malloc( sizeof( slap_counters_t ));
1004 		sc = vsc;
1005 		slap_counters_init( sc );
1006 		ldap_pvt_thread_pool_setkey( ctx, (void*)conn_counter_init, vsc,
1007 			conn_counter_destroy, NULL, NULL );
1008 
1009 		ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
1010 		sc->sc_next = slap_counters.sc_next;
1011 		slap_counters.sc_next = sc;
1012 		ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
1013 	}
1014 	op->o_counters = vsc;
1015 }
1016 
1017 static void *
1018 connection_operation( void *ctx, void *arg_v )
1019 {
1020 	int rc = LDAP_OTHER, cancel;
1021 	Operation *op = arg_v;
1022 	SlapReply rs = {REP_RESULT};
1023 	ber_tag_t tag = op->o_tag;
1024 	slap_op_t opidx = SLAP_OP_LAST;
1025 	Connection *conn = op->o_conn;
1026 	void *memctx = NULL;
1027 	void *memctx_null = NULL;
1028 	ber_len_t memsiz;
1029 
1030 	conn_counter_init( op, ctx );
1031 	ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex );
1032 	/* FIXME: returns 0 in case of failure */
1033 	ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_initiated, 1);
1034 	ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex );
1035 
1036 	op->o_threadctx = ctx;
1037 	op->o_tid = ldap_pvt_thread_pool_tid( ctx );
1038 
1039 	switch ( tag ) {
1040 	case LDAP_REQ_BIND:
1041 	case LDAP_REQ_UNBIND:
1042 	case LDAP_REQ_ADD:
1043 	case LDAP_REQ_DELETE:
1044 	case LDAP_REQ_MODDN:
1045 	case LDAP_REQ_MODIFY:
1046 	case LDAP_REQ_COMPARE:
1047 	case LDAP_REQ_SEARCH:
1048 	case LDAP_REQ_ABANDON:
1049 	case LDAP_REQ_EXTENDED:
1050 		break;
1051 	default:
1052 		Debug( LDAP_DEBUG_ANY, "connection_operation: "
1053 			"conn %lu unknown LDAP request 0x%lx\n",
1054 			conn->c_connid, tag, 0 );
1055 		op->o_tag = LBER_ERROR;
1056 		rs.sr_err = LDAP_PROTOCOL_ERROR;
1057 		rs.sr_text = "unknown LDAP request";
1058 		send_ldap_disconnect( op, &rs );
1059 		rc = SLAPD_DISCONNECT;
1060 		goto operations_error;
1061 	}
1062 
1063 	if( conn->c_sasl_bind_in_progress && tag != LDAP_REQ_BIND ) {
1064 		Debug( LDAP_DEBUG_ANY, "connection_operation: "
1065 			"error: SASL bind in progress (tag=%ld).\n",
1066 			(long) tag, 0, 0 );
1067 		send_ldap_error( op, &rs, LDAP_OPERATIONS_ERROR,
1068 			"SASL bind in progress" );
1069 		rc = LDAP_OPERATIONS_ERROR;
1070 		goto operations_error;
1071 	}
1072 
1073 #ifdef LDAP_X_TXN
1074 	if (( conn->c_txn == CONN_TXN_SPECIFY ) && (
1075 		( tag == LDAP_REQ_ADD ) ||
1076 		( tag == LDAP_REQ_DELETE ) ||
1077 		( tag == LDAP_REQ_MODIFY ) ||
1078 		( tag == LDAP_REQ_MODRDN )))
1079 	{
1080 		/* Disable SLAB allocator for all update operations
1081 			issued inside of a transaction */
1082 		op->o_tmpmemctx = NULL;
1083 		op->o_tmpmfuncs = &ch_mfuncs;
1084 	} else
1085 #endif
1086 	{
1087 	/* We can use Thread-Local storage for most mallocs. We can
1088 	 * also use TL for ber parsing, but not on Add or Modify.
1089 	 */
1090 #if 0
1091 	memsiz = ber_len( op->o_ber ) * 64;
1092 	if ( SLAP_SLAB_SIZE > memsiz ) memsiz = SLAP_SLAB_SIZE;
1093 #endif
1094 	memsiz = SLAP_SLAB_SIZE;
1095 
1096 	memctx = slap_sl_mem_create( memsiz, SLAP_SLAB_STACK, ctx, 1 );
1097 	op->o_tmpmemctx = memctx;
1098 	op->o_tmpmfuncs = &slap_sl_mfuncs;
1099 	if ( tag != LDAP_REQ_ADD && tag != LDAP_REQ_MODIFY ) {
1100 		/* Note - the ber and its buffer are already allocated from
1101 		 * regular memory; this only affects subsequent mallocs that
1102 		 * ber_scanf may invoke.
1103 		 */
1104 		ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx );
1105 	}
1106 	}
1107 
1108 	opidx = slap_req2op( tag );
1109 	assert( opidx != SLAP_OP_LAST );
1110 	INCR_OP_INITIATED( opidx );
1111 	rc = (*(opfun[opidx]))( op, &rs );
1112 
1113 operations_error:
1114 	if ( rc == SLAPD_DISCONNECT ) {
1115 		tag = LBER_ERROR;
1116 
1117 	} else if ( opidx != SLAP_OP_LAST ) {
1118 		/* increment completed operations count
1119 		 * only if operation was initiated
1120 		 * and rc != SLAPD_DISCONNECT */
1121 		INCR_OP_COMPLETED( opidx );
1122 	}
1123 
1124 	ldap_pvt_thread_mutex_lock( &conn->c_mutex );
1125 
1126 	if ( opidx == SLAP_OP_BIND && conn->c_conn_state == SLAP_C_BINDING )
1127 		conn->c_conn_state = SLAP_C_ACTIVE;
1128 
1129 	cancel = op->o_cancel;
1130 	if ( cancel != SLAP_CANCEL_NONE && cancel != SLAP_CANCEL_DONE ) {
1131 		if ( cancel == SLAP_CANCEL_REQ ) {
1132 			op->o_cancel = rc == SLAPD_ABANDON
1133 				? SLAP_CANCEL_ACK : LDAP_TOO_LATE;
1134 		}
1135 
1136 		do {
1137 			/* Fake a cond_wait with thread_yield, then
1138 			 * verify the result properly mutex-protected.
1139 			 */
1140 			ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
1141 			do {
1142 				ldap_pvt_thread_yield();
1143 			} while ( (cancel = op->o_cancel) != SLAP_CANCEL_NONE
1144 					&& cancel != SLAP_CANCEL_DONE );
1145 			ldap_pvt_thread_mutex_lock( &conn->c_mutex );
1146 		} while ( (cancel = op->o_cancel) != SLAP_CANCEL_NONE
1147 				&& cancel != SLAP_CANCEL_DONE );
1148 	}
1149 
1150 	ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null );
1151 
1152 	LDAP_STAILQ_REMOVE( &conn->c_ops, op, Operation, o_next);
1153 	LDAP_STAILQ_NEXT(op, o_next) = NULL;
1154 	conn->c_n_ops_executing--;
1155 	conn->c_n_ops_completed++;
1156 
1157 	switch( tag ) {
1158 	case LBER_ERROR:
1159 	case LDAP_REQ_UNBIND:
1160 		/* c_mutex is locked */
1161 		connection_closing( conn,
1162 			tag == LDAP_REQ_UNBIND ? NULL : "operations error" );
1163 		break;
1164 	}
1165 
1166 	connection_resched( conn );
1167 	ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
1168 	slap_op_free( op, ctx );
1169 	return NULL;
1170 }
1171 
1172 static const Listener dummy_list = { BER_BVC(""), BER_BVC("") };
1173 
1174 Connection *connection_client_setup(
1175 	ber_socket_t s,
1176 	ldap_pvt_thread_start_t *func,
1177 	void *arg )
1178 {
1179 	Connection *c;
1180 	ber_socket_t sfd = SLAP_SOCKNEW( s );
1181 
1182 	c = connection_init( sfd, (Listener *)&dummy_list, "", "",
1183 		CONN_IS_CLIENT, 0, NULL
1184 		LDAP_PF_LOCAL_SENDMSG_ARG(NULL));
1185 	if ( c ) {
1186 		c->c_clientfunc = func;
1187 		c->c_clientarg = arg;
1188 
1189 		slapd_add_internal( sfd, 0 );
1190 	}
1191 	return c;
1192 }
1193 
1194 void connection_client_enable(
1195 	Connection *c )
1196 {
1197 	slapd_set_read( c->c_sd, 1 );
1198 }
1199 
1200 void connection_client_stop(
1201 	Connection *c )
1202 {
1203 	Sockbuf *sb;
1204 	ber_socket_t s = c->c_sd;
1205 
1206 	/* get (locked) connection */
1207 	c = connection_get( s );
1208 
1209 	assert( c->c_conn_state == SLAP_C_CLIENT );
1210 
1211 	c->c_listener = NULL;
1212 	c->c_conn_state = SLAP_C_INVALID;
1213 	c->c_struct_state = SLAP_C_UNUSED;
1214 	c->c_sd = AC_SOCKET_INVALID;
1215 	c->c_close_reason = "?";			/* should never be needed */
1216 	sb = c->c_sb;
1217 	c->c_sb = ber_sockbuf_alloc( );
1218 	{
1219 		ber_len_t max = sockbuf_max_incoming;
1220 		ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
1221 	}
1222 	slapd_remove( s, sb, 0, 1, 0 );
1223 
1224 	connection_return( c );
1225 }
1226 
1227 static int connection_read( ber_socket_t s, conn_readinfo *cri );
1228 
1229 static void* connection_read_thread( void* ctx, void* argv )
1230 {
1231 	int rc ;
1232 	conn_readinfo cri = { NULL, NULL, NULL, NULL, 0 };
1233 	ber_socket_t s = (long)argv;
1234 
1235 	/*
1236 	 * read incoming LDAP requests. If there is more than one,
1237 	 * the first one is returned with new_op
1238 	 */
1239 	cri.ctx = ctx;
1240 	if( ( rc = connection_read( s, &cri ) ) < 0 ) {
1241 		Debug( LDAP_DEBUG_CONNS, "connection_read(%d) error\n", s, 0, 0 );
1242 		return (void*)(long)rc;
1243 	}
1244 
1245 	/* execute a single queued request in the same thread */
1246 	if( cri.op && !cri.nullop ) {
1247 		rc = (long)connection_operation( ctx, cri.op );
1248 	} else if ( cri.func ) {
1249 		rc = (long)cri.func( ctx, cri.arg );
1250 	}
1251 
1252 	return (void*)(long)rc;
1253 }
1254 
1255 int connection_read_activate( ber_socket_t s )
1256 {
1257 	int rc;
1258 
1259 	/*
1260 	 * suspend reading on this file descriptor until a connection processing
1261 	 * thread reads data on it. Otherwise the listener thread will repeatedly
1262 	 * submit the same event on it to the pool.
1263 	 */
1264 	rc = slapd_clr_read( s, 0 );
1265 	if ( rc )
1266 		return rc;
1267 
1268 	/* Don't let blocked writers block a pause request */
1269 	if ( connections[s].c_writewaiter &&
1270 		ldap_pvt_thread_pool_pausing( &connection_pool ))
1271 		connection_wake_writers( &connections[s] );
1272 
1273 	rc = ldap_pvt_thread_pool_submit( &connection_pool,
1274 		connection_read_thread, (void *)(long)s );
1275 
1276 	if( rc != 0 ) {
1277 		Debug( LDAP_DEBUG_ANY,
1278 			"connection_read_activate(%d): submit failed (%d)\n",
1279 			s, rc, 0 );
1280 	}
1281 
1282 	return rc;
1283 }
1284 
1285 static int
1286 connection_read( ber_socket_t s, conn_readinfo *cri )
1287 {
1288 	int rc = 0;
1289 	Connection *c;
1290 
1291 	assert( connections != NULL );
1292 
1293 	/* get (locked) connection */
1294 	c = connection_get( s );
1295 
1296 	if( c == NULL ) {
1297 		Debug( LDAP_DEBUG_ANY,
1298 			"connection_read(%ld): no connection!\n",
1299 			(long) s, 0, 0 );
1300 
1301 		return -1;
1302 	}
1303 
1304 	c->c_n_read++;
1305 
1306 	if( c->c_conn_state == SLAP_C_CLOSING ) {
1307 		Debug( LDAP_DEBUG_CONNS,
1308 			"connection_read(%d): closing, ignoring input for id=%lu\n",
1309 			s, c->c_connid, 0 );
1310 		connection_return( c );
1311 		return 0;
1312 	}
1313 
1314 	if ( c->c_conn_state == SLAP_C_CLIENT ) {
1315 		cri->func = c->c_clientfunc;
1316 		cri->arg = c->c_clientarg;
1317 		/* read should already be cleared */
1318 		connection_return( c );
1319 		return 0;
1320 	}
1321 
1322 	Debug( LDAP_DEBUG_TRACE,
1323 		"connection_read(%d): checking for input on id=%lu\n",
1324 		s, c->c_connid, 0 );
1325 
1326 #ifdef HAVE_TLS
1327 	if ( c->c_is_tls && c->c_needs_tls_accept ) {
1328 		rc = ldap_pvt_tls_accept( c->c_sb, slap_tls_ctx );
1329 		if ( rc < 0 ) {
1330 			Debug( LDAP_DEBUG_TRACE,
1331 				"connection_read(%d): TLS accept failure "
1332 				"error=%d id=%lu, closing\n",
1333 				s, rc, c->c_connid );
1334 
1335 			c->c_needs_tls_accept = 0;
1336 			/* c_mutex is locked */
1337 			connection_closing( c, "TLS negotiation failure" );
1338 			connection_close( c );
1339 			connection_return( c );
1340 			return 0;
1341 
1342 		} else if ( rc == 0 ) {
1343 			void *ssl;
1344 			struct berval authid = BER_BVNULL;
1345 
1346 			c->c_needs_tls_accept = 0;
1347 
1348 			/* we need to let SASL know */
1349 			ssl = ldap_pvt_tls_sb_ctx( c->c_sb );
1350 
1351 			c->c_tls_ssf = (slap_ssf_t) ldap_pvt_tls_get_strength( ssl );
1352 			if( c->c_tls_ssf > c->c_ssf ) {
1353 				c->c_ssf = c->c_tls_ssf;
1354 			}
1355 
1356 			rc = dnX509peerNormalize( ssl, &authid );
1357 			if ( rc != LDAP_SUCCESS ) {
1358 				Debug( LDAP_DEBUG_TRACE, "connection_read(%d): "
1359 					"unable to get TLS client DN, error=%d id=%lu\n",
1360 					s, rc, c->c_connid );
1361 			}
1362 			Statslog( LDAP_DEBUG_STATS,
1363 				"conn=%lu fd=%d TLS established tls_ssf=%u ssf=%u\n",
1364 			    c->c_connid, (int) s, c->c_tls_ssf, c->c_ssf, 0 );
1365 			slap_sasl_external( c, c->c_tls_ssf, &authid );
1366 			if ( authid.bv_val ) free( authid.bv_val );
1367 		} else if ( rc == 1 && ber_sockbuf_ctrl( c->c_sb,
1368 			LBER_SB_OPT_NEEDS_WRITE, NULL )) {	/* need to retry */
1369 			slapd_set_write( s, 1 );
1370 			connection_return( c );
1371 			return 0;
1372 		}
1373 
1374 		/* if success and data is ready, fall thru to data input loop */
1375 		if( !ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL ) )
1376 		{
1377 			slapd_set_read( s, 1 );
1378 			connection_return( c );
1379 			return 0;
1380 		}
1381 	}
1382 #endif
1383 
1384 #ifdef HAVE_CYRUS_SASL
1385 	if ( c->c_sasl_layers ) {
1386 		/* If previous layer is not removed yet, give up for now */
1387 		if ( !c->c_sasl_sockctx ) {
1388 			slapd_set_read( s, 1 );
1389 			connection_return( c );
1390 			return 0;
1391 		}
1392 
1393 		c->c_sasl_layers = 0;
1394 
1395 		rc = ldap_pvt_sasl_install( c->c_sb, c->c_sasl_sockctx );
1396 		if( rc != LDAP_SUCCESS ) {
1397 			Debug( LDAP_DEBUG_TRACE,
1398 				"connection_read(%d): SASL install error "
1399 				"error=%d id=%lu, closing\n",
1400 				s, rc, c->c_connid );
1401 
1402 			/* c_mutex is locked */
1403 			connection_closing( c, "SASL layer install failure" );
1404 			connection_close( c );
1405 			connection_return( c );
1406 			return 0;
1407 		}
1408 	}
1409 #endif
1410 
1411 #define CONNECTION_INPUT_LOOP 1
1412 /* #define	DATA_READY_LOOP 1 */
1413 
1414 	do {
1415 		/* How do we do this without getting into a busy loop ? */
1416 		rc = connection_input( c, cri );
1417 	}
1418 #ifdef DATA_READY_LOOP
1419 	while( !rc && ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL ));
1420 #elif defined CONNECTION_INPUT_LOOP
1421 	while(!rc);
1422 #else
1423 	while(0);
1424 #endif
1425 
1426 	if( rc < 0 ) {
1427 		Debug( LDAP_DEBUG_CONNS,
1428 			"connection_read(%d): input error=%d id=%lu, closing.\n",
1429 			s, rc, c->c_connid );
1430 
1431 		/* c_mutex is locked */
1432 		connection_closing( c, conn_lost_str );
1433 		connection_close( c );
1434 		connection_return( c );
1435 		return 0;
1436 	}
1437 
1438 	if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
1439 		slapd_set_write( s, 0 );
1440 	}
1441 
1442 	slapd_set_read( s, 1 );
1443 	connection_return( c );
1444 
1445 	return 0;
1446 }
1447 
1448 static int
1449 connection_input( Connection *conn , conn_readinfo *cri )
1450 {
1451 	Operation *op;
1452 	ber_tag_t	tag;
1453 	ber_len_t	len;
1454 	ber_int_t	msgid;
1455 	BerElement	*ber;
1456 	int 		rc;
1457 #ifdef LDAP_CONNECTIONLESS
1458 	Sockaddr	peeraddr;
1459 	char 		*cdn = NULL;
1460 #endif
1461 	char *defer = NULL;
1462 	void *ctx;
1463 
1464 	if ( conn->c_currentber == NULL &&
1465 		( conn->c_currentber = ber_alloc()) == NULL )
1466 	{
1467 		Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
1468 		return -1;
1469 	}
1470 
1471 	sock_errset(0);
1472 
1473 #ifdef LDAP_CONNECTIONLESS
1474 	if ( conn->c_is_udp ) {
1475 		char peername[sizeof("IP=255.255.255.255:65336")];
1476 
1477 		len = ber_int_sb_read(conn->c_sb, &peeraddr, sizeof(struct sockaddr));
1478 		if (len != sizeof(struct sockaddr)) return 1;
1479 
1480 		sprintf( peername, "IP=%s:%d",
1481 			inet_ntoa( peeraddr.sa_in_addr.sin_addr ),
1482 			(unsigned) ntohs( peeraddr.sa_in_addr.sin_port ) );
1483 		Statslog( LDAP_DEBUG_STATS,
1484 			"conn=%lu UDP request from %s (%s) accepted.\n",
1485 			conn->c_connid, peername, conn->c_sock_name.bv_val, 0, 0 );
1486 	}
1487 #endif
1488 
1489 	tag = ber_get_next( conn->c_sb, &len, conn->c_currentber );
1490 	if ( tag != LDAP_TAG_MESSAGE ) {
1491 		int err = sock_errno();
1492 
1493 		if ( err != EWOULDBLOCK && err != EAGAIN ) {
1494 			/* log, close and send error */
1495 			Debug( LDAP_DEBUG_TRACE,
1496 				"ber_get_next on fd %d failed errno=%d (%s)\n",
1497 			conn->c_sd, err, sock_errstr(err) );
1498 			ber_free( conn->c_currentber, 1 );
1499 			conn->c_currentber = NULL;
1500 
1501 			return -2;
1502 		}
1503 		return 1;
1504 	}
1505 
1506 	ber = conn->c_currentber;
1507 	conn->c_currentber = NULL;
1508 
1509 	if ( (tag = ber_get_int( ber, &msgid )) != LDAP_TAG_MSGID ) {
1510 		/* log, close and send error */
1511 		Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n", tag, 0, 0 );
1512 		ber_free( ber, 1 );
1513 		return -1;
1514 	}
1515 
1516 	if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
1517 		/* log, close and send error */
1518 		Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%lx\n", tag, 0, 0 );
1519 		ber_free( ber, 1 );
1520 
1521 		return -1;
1522 	}
1523 
1524 #ifdef LDAP_CONNECTIONLESS
1525 	if( conn->c_is_udp ) {
1526 		if( tag == LBER_OCTETSTRING ) {
1527 			ber_get_stringa( ber, &cdn );
1528 			tag = ber_peek_tag(ber, &len);
1529 		}
1530 		if( tag != LDAP_REQ_ABANDON && tag != LDAP_REQ_SEARCH ) {
1531 			Debug( LDAP_DEBUG_ANY, "invalid req for UDP 0x%lx\n", tag, 0, 0 );
1532 			ber_free( ber, 1 );
1533 			return 0;
1534 		}
1535 	}
1536 #endif
1537 
1538 	if(tag == LDAP_REQ_BIND) {
1539 		/* immediately abandon all existing operations upon BIND */
1540 		connection_abandon( conn );
1541 	}
1542 
1543 	ctx = cri->ctx;
1544 	op = slap_op_alloc( ber, msgid, tag, conn->c_n_ops_received++, ctx );
1545 
1546 	Debug( LDAP_DEBUG_TRACE, "op tag 0x%lx, time %ld\n", tag,
1547 		(long) op->o_time, 0);
1548 
1549 	op->o_conn = conn;
1550 	/* clear state if the connection is being reused from inactive */
1551 	if ( conn->c_conn_state == SLAP_C_INACTIVE ) {
1552 		memset( &conn->c_pagedresults_state, 0,
1553 			sizeof( conn->c_pagedresults_state ) );
1554 	}
1555 
1556 	op->o_res_ber = NULL;
1557 
1558 #ifdef LDAP_CONNECTIONLESS
1559 	if (conn->c_is_udp) {
1560 		if ( cdn ) {
1561 			ber_str2bv( cdn, 0, 1, &op->o_dn );
1562 			op->o_protocol = LDAP_VERSION2;
1563 		}
1564 		op->o_res_ber = ber_alloc_t( LBER_USE_DER );
1565 		if (op->o_res_ber == NULL) return 1;
1566 
1567 		rc = ber_write( op->o_res_ber, (char *)&peeraddr,
1568 			sizeof(struct sockaddr), 0 );
1569 
1570 		if (rc != sizeof(struct sockaddr)) {
1571 			Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
1572 			return 1;
1573 		}
1574 
1575 		if (op->o_protocol == LDAP_VERSION2) {
1576 			rc = ber_printf(op->o_res_ber, "{is{" /*}}*/, op->o_msgid, "");
1577 			if (rc == -1) {
1578 				Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
1579 				return rc;
1580 			}
1581 		}
1582 	}
1583 #endif /* LDAP_CONNECTIONLESS */
1584 
1585 	rc = 0;
1586 
1587 	/* Don't process requests when the conn is in the middle of a
1588 	 * Bind, or if it's closing. Also, don't let any single conn
1589 	 * use up all the available threads, and don't execute if we're
1590 	 * currently blocked on output. And don't execute if there are
1591 	 * already pending ops, let them go first.  Abandon operations
1592 	 * get exceptions to some, but not all, cases.
1593 	 */
1594 	switch( tag ){
1595 	default:
1596 		/* Abandon and Unbind are exempt from these checks */
1597 		if (conn->c_conn_state == SLAP_C_CLOSING) {
1598 			defer = "closing";
1599 			break;
1600 		} else if (conn->c_writewaiter) {
1601 			defer = "awaiting write";
1602 			break;
1603 		} else if (conn->c_n_ops_pending) {
1604 			defer = "pending operations";
1605 			break;
1606 		}
1607 		/* FALLTHRU */
1608 	case LDAP_REQ_ABANDON:
1609 		/* Unbind is exempt from these checks */
1610 		if (conn->c_n_ops_executing >= connection_pool_max/2) {
1611 			defer = "too many executing";
1612 			break;
1613 		} else if (conn->c_conn_state == SLAP_C_BINDING) {
1614 			defer = "binding";
1615 			break;
1616 		}
1617 		/* FALLTHRU */
1618 	case LDAP_REQ_UNBIND:
1619 		break;
1620 	}
1621 
1622 	if( defer ) {
1623 		int max = conn->c_dn.bv_len
1624 			? slap_conn_max_pending_auth
1625 			: slap_conn_max_pending;
1626 
1627 		Debug( LDAP_DEBUG_ANY,
1628 			"connection_input: conn=%lu deferring operation: %s\n",
1629 			conn->c_connid, defer, 0 );
1630 		conn->c_n_ops_pending++;
1631 		LDAP_STAILQ_INSERT_TAIL( &conn->c_pending_ops, op, o_next );
1632 		rc = ( conn->c_n_ops_pending > max ) ? -1 : 0;
1633 
1634 	} else {
1635 		conn->c_n_ops_executing++;
1636 
1637 		/*
1638 		 * The first op will be processed in the same thread context,
1639 		 * as long as there is only one op total.
1640 		 * Subsequent ops will be submitted to the pool by
1641 		 * calling connection_op_activate()
1642 		 */
1643 		if ( cri->op == NULL ) {
1644 			/* the first incoming request */
1645 			connection_op_queue( op );
1646 			cri->op = op;
1647 		} else {
1648 			if ( !cri->nullop ) {
1649 				cri->nullop = 1;
1650 				rc = ldap_pvt_thread_pool_submit( &connection_pool,
1651 					connection_operation, (void *) cri->op );
1652 			}
1653 			connection_op_activate( op );
1654 		}
1655 	}
1656 
1657 #ifdef NO_THREADS
1658 	if ( conn->c_struct_state != SLAP_C_USED ) {
1659 		/* connection must have got closed underneath us */
1660 		return 1;
1661 	}
1662 #endif
1663 
1664 	assert( conn->c_struct_state == SLAP_C_USED );
1665 	return rc;
1666 }
1667 
1668 static int
1669 connection_resched( Connection *conn )
1670 {
1671 	Operation *op;
1672 
1673 	if( conn->c_writewaiter )
1674 		return 0;
1675 
1676 	if( conn->c_conn_state == SLAP_C_CLOSING ) {
1677 		Debug( LDAP_DEBUG_CONNS, "connection_resched: "
1678 			"attempting closing conn=%lu sd=%d\n",
1679 			conn->c_connid, conn->c_sd, 0 );
1680 		connection_close( conn );
1681 		return 0;
1682 	}
1683 
1684 	if( conn->c_conn_state != SLAP_C_ACTIVE ) {
1685 		/* other states need different handling */
1686 		return 0;
1687 	}
1688 
1689 	while ((op = LDAP_STAILQ_FIRST( &conn->c_pending_ops )) != NULL) {
1690 		if ( conn->c_n_ops_executing > connection_pool_max/2 ) break;
1691 
1692 		LDAP_STAILQ_REMOVE_HEAD( &conn->c_pending_ops, o_next );
1693 		LDAP_STAILQ_NEXT(op, o_next) = NULL;
1694 
1695 		/* pending operations should not be marked for abandonment */
1696 		assert(!op->o_abandon);
1697 
1698 		conn->c_n_ops_pending--;
1699 		conn->c_n_ops_executing++;
1700 
1701 		connection_op_activate( op );
1702 
1703 		if ( conn->c_conn_state == SLAP_C_BINDING ) break;
1704 	}
1705 	return 0;
1706 }
1707 
1708 static void
1709 connection_init_log_prefix( Operation *op )
1710 {
1711 	if ( op->o_connid == (unsigned long)(-1) ) {
1712 		snprintf( op->o_log_prefix, sizeof( op->o_log_prefix ),
1713 			"conn=-1 op=%lu", op->o_opid );
1714 
1715 	} else {
1716 		snprintf( op->o_log_prefix, sizeof( op->o_log_prefix ),
1717 			"conn=%lu op=%lu", op->o_connid, op->o_opid );
1718 	}
1719 }
1720 
1721 static int connection_bind_cleanup_cb( Operation *op, SlapReply *rs )
1722 {
1723 	op->o_conn->c_sasl_bindop = NULL;
1724 
1725 	ch_free( op->o_callback );
1726 	op->o_callback = NULL;
1727 
1728 	return SLAP_CB_CONTINUE;
1729 }
1730 
1731 static int connection_bind_cb( Operation *op, SlapReply *rs )
1732 {
1733 	ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
1734 	op->o_conn->c_sasl_bind_in_progress =
1735 		( rs->sr_err == LDAP_SASL_BIND_IN_PROGRESS );
1736 
1737 	/* Moved here from bind.c due to ITS#4158 */
1738 	op->o_conn->c_sasl_bindop = NULL;
1739 	if ( op->orb_method == LDAP_AUTH_SASL ) {
1740 		if( rs->sr_err == LDAP_SUCCESS ) {
1741 			ber_dupbv(&op->o_conn->c_dn, &op->orb_edn);
1742 			if( !BER_BVISEMPTY( &op->orb_edn ) ) {
1743 				/* edn is always normalized already */
1744 				ber_dupbv( &op->o_conn->c_ndn, &op->o_conn->c_dn );
1745 			}
1746 			op->o_tmpfree( op->orb_edn.bv_val, op->o_tmpmemctx );
1747 			BER_BVZERO( &op->orb_edn );
1748 			op->o_conn->c_authmech = op->o_conn->c_sasl_bind_mech;
1749 			BER_BVZERO( &op->o_conn->c_sasl_bind_mech );
1750 
1751 			op->o_conn->c_sasl_ssf = op->orb_ssf;
1752 			if( op->orb_ssf > op->o_conn->c_ssf ) {
1753 				op->o_conn->c_ssf = op->orb_ssf;
1754 			}
1755 
1756 			if( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
1757 				ber_len_t max = sockbuf_max_incoming_auth;
1758 				ber_sockbuf_ctrl( op->o_conn->c_sb,
1759 					LBER_SB_OPT_SET_MAX_INCOMING, &max );
1760 			}
1761 
1762 			/* log authorization identity */
1763 			Statslog( LDAP_DEBUG_STATS,
1764 				"%s BIND dn=\"%s\" mech=%s sasl_ssf=%d ssf=%d\n",
1765 				op->o_log_prefix,
1766 				BER_BVISNULL( &op->o_conn->c_dn ) ? "<empty>" : op->o_conn->c_dn.bv_val,
1767 				op->o_conn->c_authmech.bv_val,
1768 				op->orb_ssf, op->o_conn->c_ssf );
1769 
1770 			Debug( LDAP_DEBUG_TRACE,
1771 				"do_bind: SASL/%s bind: dn=\"%s\" sasl_ssf=%d\n",
1772 				op->o_conn->c_authmech.bv_val,
1773 				BER_BVISNULL( &op->o_conn->c_dn ) ? "<empty>" : op->o_conn->c_dn.bv_val,
1774 				op->orb_ssf );
1775 
1776 		} else if ( rs->sr_err != LDAP_SASL_BIND_IN_PROGRESS ) {
1777 			if ( !BER_BVISNULL( &op->o_conn->c_sasl_bind_mech ) ) {
1778 				free( op->o_conn->c_sasl_bind_mech.bv_val );
1779 				BER_BVZERO( &op->o_conn->c_sasl_bind_mech );
1780 			}
1781 		}
1782 	}
1783 	ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
1784 
1785 	ch_free( op->o_callback );
1786 	op->o_callback = NULL;
1787 
1788 	return SLAP_CB_CONTINUE;
1789 }
1790 
1791 static void connection_op_queue( Operation *op )
1792 {
1793 	ber_tag_t tag = op->o_tag;
1794 
1795 	if (tag == LDAP_REQ_BIND) {
1796 		slap_callback *sc = ch_calloc( 1, sizeof( slap_callback ));
1797 		sc->sc_response = connection_bind_cb;
1798 		sc->sc_cleanup = connection_bind_cleanup_cb;
1799 		sc->sc_next = op->o_callback;
1800 		op->o_callback = sc;
1801 		op->o_conn->c_conn_state = SLAP_C_BINDING;
1802 	}
1803 
1804 	if (!op->o_dn.bv_len) {
1805 		op->o_authz = op->o_conn->c_authz;
1806 		if ( BER_BVISNULL( &op->o_conn->c_sasl_authz_dn )) {
1807 			ber_dupbv( &op->o_dn, &op->o_conn->c_dn );
1808 			ber_dupbv( &op->o_ndn, &op->o_conn->c_ndn );
1809 		} else {
1810 			ber_dupbv( &op->o_dn, &op->o_conn->c_sasl_authz_dn );
1811 			ber_dupbv( &op->o_ndn, &op->o_conn->c_sasl_authz_dn );
1812 		}
1813 	}
1814 
1815 	op->o_authtype = op->o_conn->c_authtype;
1816 	ber_dupbv( &op->o_authmech, &op->o_conn->c_authmech );
1817 
1818 	if (!op->o_protocol) {
1819 		op->o_protocol = op->o_conn->c_protocol
1820 			? op->o_conn->c_protocol : LDAP_VERSION3;
1821 	}
1822 
1823 	if (op->o_conn->c_conn_state == SLAP_C_INACTIVE &&
1824 		op->o_protocol > LDAP_VERSION2)
1825 	{
1826 		op->o_conn->c_conn_state = SLAP_C_ACTIVE;
1827 	}
1828 
1829 	op->o_connid = op->o_conn->c_connid;
1830 	connection_init_log_prefix( op );
1831 
1832 	LDAP_STAILQ_INSERT_TAIL( &op->o_conn->c_ops, op, o_next );
1833 }
1834 
1835 static int connection_op_activate( Operation *op )
1836 {
1837 	int rc;
1838 
1839 	connection_op_queue( op );
1840 
1841 	rc = ldap_pvt_thread_pool_submit( &connection_pool,
1842 		connection_operation, (void *) op );
1843 
1844 	if ( rc != 0 ) {
1845 		Debug( LDAP_DEBUG_ANY,
1846 			"connection_op_activate: submit failed (%d) for conn=%lu\n",
1847 			rc, op->o_connid, 0 );
1848 		/* should move op to pending list */
1849 	}
1850 
1851 	return rc;
1852 }
1853 
1854 int connection_write(ber_socket_t s)
1855 {
1856 	Connection *c;
1857 	Operation *op;
1858 
1859 	assert( connections != NULL );
1860 
1861 	slapd_clr_write( s, 0 );
1862 
1863 	c = connection_get( s );
1864 	if( c == NULL ) {
1865 		Debug( LDAP_DEBUG_ANY,
1866 			"connection_write(%ld): no connection!\n",
1867 			(long)s, 0, 0 );
1868 		return -1;
1869 	}
1870 
1871 #ifdef HAVE_TLS
1872 	if ( c->c_is_tls && c->c_needs_tls_accept ) {
1873 		connection_return( c );
1874 		connection_read_activate( s );
1875 		return 0;
1876 	}
1877 #endif
1878 
1879 	c->c_n_write++;
1880 
1881 	Debug( LDAP_DEBUG_TRACE,
1882 		"connection_write(%d): waking output for id=%lu\n",
1883 		s, c->c_connid, 0 );
1884 	ldap_pvt_thread_mutex_lock( &c->c_write2_mutex );
1885 	ldap_pvt_thread_cond_signal( &c->c_write2_cv );
1886 	ldap_pvt_thread_mutex_unlock( &c->c_write2_mutex );
1887 
1888 	if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_READ, NULL ) ) {
1889 		slapd_set_read( s, 1 );
1890 	}
1891 	if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
1892 		slapd_set_write( s, 1 );
1893 	}
1894 
1895 	/* If there are ops pending because of a writewaiter,
1896 	 * start one up.
1897 	 */
1898 	while ((op = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) {
1899 		if ( !c->c_writewaiter ) break;
1900 		if ( c->c_n_ops_executing > connection_pool_max/2 ) break;
1901 
1902 		LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next );
1903 		LDAP_STAILQ_NEXT(op, o_next) = NULL;
1904 
1905 		/* pending operations should not be marked for abandonment */
1906 		assert(!op->o_abandon);
1907 
1908 		c->c_n_ops_pending--;
1909 		c->c_n_ops_executing++;
1910 
1911 		connection_op_activate( op );
1912 
1913 		break;
1914 	}
1915 
1916 	connection_return( c );
1917 	return 0;
1918 }
1919 
1920 #ifdef LDAP_SLAPI
1921 typedef struct conn_fake_extblock {
1922 	void *eb_conn;
1923 	void *eb_op;
1924 } conn_fake_extblock;
1925 
1926 static void
1927 connection_fake_destroy(
1928 	void *key,
1929 	void *data )
1930 {
1931 	Connection conn = {0};
1932 	Operation op = {0};
1933 	Opheader ohdr = {0};
1934 
1935 	conn_fake_extblock *eb = data;
1936 
1937 	op.o_hdr = &ohdr;
1938 	op.o_hdr->oh_extensions = eb->eb_op;
1939 	conn.c_extensions = eb->eb_conn;
1940 	op.o_conn = &conn;
1941 	conn.c_connid = -1;
1942 	op.o_connid = -1;
1943 
1944 	ber_memfree_x( eb, NULL );
1945 	slapi_int_free_object_extensions( SLAPI_X_EXT_OPERATION, &op );
1946 	slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, &conn );
1947 }
1948 #endif
1949 
1950 void
1951 connection_fake_init(
1952 	Connection *conn,
1953 	OperationBuffer *opbuf,
1954 	void *ctx )
1955 {
1956 	connection_fake_init2( conn, opbuf, ctx, 1 );
1957 }
1958 
1959 void
1960 operation_fake_init(
1961 	Connection *conn,
1962 	Operation *op,
1963 	void *ctx,
1964 	int newmem )
1965 {
1966 	/* set memory context */
1967 	op->o_tmpmemctx = slap_sl_mem_create(SLAP_SLAB_SIZE, SLAP_SLAB_STACK, ctx,
1968 		newmem );
1969 	op->o_tmpmfuncs = &slap_sl_mfuncs;
1970 	op->o_threadctx = ctx;
1971 	op->o_tid = ldap_pvt_thread_pool_tid( ctx );
1972 
1973 	op->o_counters = &slap_counters;
1974 	op->o_conn = conn;
1975 	op->o_connid = op->o_conn->c_connid;
1976 	connection_init_log_prefix( op );
1977 }
1978 
1979 
1980 void
1981 connection_fake_init2(
1982 	Connection *conn,
1983 	OperationBuffer *opbuf,
1984 	void *ctx,
1985 	int newmem )
1986 {
1987 	Operation *op = (Operation *) opbuf;
1988 
1989 	conn->c_connid = -1;
1990 	conn->c_conn_idx = -1;
1991 	conn->c_send_ldap_result = slap_send_ldap_result;
1992 	conn->c_send_search_entry = slap_send_search_entry;
1993 	conn->c_send_search_reference = slap_send_search_reference;
1994 	conn->c_send_ldap_extended = slap_send_ldap_extended;
1995 	conn->c_send_ldap_intermediate = slap_send_ldap_intermediate;
1996 	conn->c_listener = (Listener *)&dummy_list;
1997 	conn->c_peer_domain = slap_empty_bv;
1998 	conn->c_peer_name = slap_empty_bv;
1999 
2000 	memset( opbuf, 0, sizeof( *opbuf ));
2001 	op->o_hdr = &opbuf->ob_hdr;
2002 	op->o_controls = opbuf->ob_controls;
2003 
2004 	operation_fake_init( conn, op, ctx, newmem );
2005 
2006 #ifdef LDAP_SLAPI
2007 	if ( slapi_plugins_used ) {
2008 		conn_fake_extblock *eb;
2009 		void *ebx = NULL;
2010 
2011 		/* Use thread keys to make sure these eventually get cleaned up */
2012 		if ( ldap_pvt_thread_pool_getkey( ctx, (void *)connection_fake_init,
2013 				&ebx, NULL )) {
2014 			eb = ch_malloc( sizeof( *eb ));
2015 			slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, conn );
2016 			slapi_int_create_object_extensions( SLAPI_X_EXT_OPERATION, op );
2017 			eb->eb_conn = conn->c_extensions;
2018 			eb->eb_op = op->o_hdr->oh_extensions;
2019 			ldap_pvt_thread_pool_setkey( ctx, (void *)connection_fake_init,
2020 				eb, connection_fake_destroy, NULL, NULL );
2021 		} else {
2022 			eb = ebx;
2023 			conn->c_extensions = eb->eb_conn;
2024 			op->o_hdr->oh_extensions = eb->eb_op;
2025 		}
2026 	}
2027 #endif /* LDAP_SLAPI */
2028 
2029 	slap_op_time( &op->o_time, &op->o_tincr );
2030 }
2031 
2032 void
2033 connection_assign_nextid( Connection *conn )
2034 {
2035 	ldap_pvt_thread_mutex_lock( &conn_nextid_mutex );
2036 	conn->c_connid = conn_nextid++;
2037 	ldap_pvt_thread_mutex_unlock( &conn_nextid_mutex );
2038 }
2039