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