ber_len_t sockbuf_max_incoming = SLAP_SB_MAX_INCOMING_DEFAULT;
ber_len_t sockbuf_max_incoming_auth= SLAP_SB_MAX_INCOMING_AUTH;
+int slap_conn_max_pending = SLAP_CONN_MAX_PENDING_DEFAULT;
+int slap_conn_max_pending_auth = SLAP_CONN_MAX_PENDING_AUTH;
+
char *slapd_pid_file = NULL;
char *slapd_args_file = NULL;
sockbuf_max_incoming_auth = max;
+ /* set conn pending max */
+ } else if ( strcasecmp( cargv[0], "conn_max_pending" ) == 0 ) {
+ long max;
+ if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: missing max in \"conn_max_pending "
+ "<requests>\" line\n", fname, lineno, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing max in \"conn_max_pending <requests>\" line\n",
+ fname, lineno, 0 );
+#endif
+
+ return( 1 );
+ }
+
+ max = atol( cargv[1] );
+
+ if( max < 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: invalid max value (%ld) in "
+ "\"conn_max_pending <requests>\" line.\n",
+ fname, lineno, max );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: invalid max value (%ld) in "
+ "\"conn_max_pending <requests>\" line.\n",
+ fname, lineno, max );
+#endif
+
+ return( 1 );
+ }
+
+ slap_conn_max_pending = max;
+
+ /* set conn pending max authenticated */
+ } else if ( strcasecmp( cargv[0], "conn_max_pending_auth" ) == 0 ) {
+ long max;
+ if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: missing max in \"conn_max_pending_auth "
+ "<requests>\" line\n", fname, lineno, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing max in \"conn_max_pending_auth <requests>\" line\n",
+ fname, lineno, 0 );
+#endif
+
+ return( 1 );
+ }
+
+ max = atol( cargv[1] );
+
+ if( max < 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: invalid max value (%ld) in "
+ "\"conn_max_pending_auth <requests>\" line.\n",
+ fname, lineno, max );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: invalid max value (%ld) in "
+ "\"conn_max_pending_auth <requests>\" line.\n",
+ fname, lineno, max );
+#endif
+
+ return( 1 );
+ }
+
+ slap_conn_max_pending_auth = max;
+
/* default search base */
} else if ( strcasecmp( cargv[0], "defaultSearchBase" ) == 0 ) {
if ( cargc < 2 ) {
ber_len_t len;
ber_int_t msgid;
BerElement *ber;
+ int rc;
#ifdef LDAP_CONNECTIONLESS
Sockaddr peeraddr;
char *cdn = NULL;
#endif
#ifdef LDAP_CONNECTIONLESS
if (conn->c_is_udp) {
- int rc;
if ( cdn ) {
ber_str2bv( cdn, 0, 1, &op->o_dn );
}
#endif /* LDAP_CONNECTIONLESS */
+ rc = 0;
+
+ /* Don't process requests when the conn is in the middle of a
+ * Bind, or if it's closing. Also, don't let any single conn
+ * use up all the available threads, and don't execute if we're
+ * currently blocked on output. And don't execute if there are
+ * already pending ops, let them go first.
+ */
if ( conn->c_conn_state == SLAP_C_BINDING
- || conn->c_conn_state == SLAP_C_CLOSING )
+ || conn->c_conn_state == SLAP_C_CLOSING
+ || conn->c_n_ops_executing >= connection_pool_max/2
+ || conn->c_n_ops_pending
+ || conn->c_writewaiter)
{
+ int max = conn->c_dn.bv_len ? slap_conn_max_pending_auth
+ : slap_conn_max_pending;
#ifdef NEW_LOGGING
LDAP_LOG( CONNECTION, INFO,
"connection_input: conn %lu deferring operation\n",
#endif
conn->c_n_ops_pending++;
LDAP_STAILQ_INSERT_TAIL( &conn->c_pending_ops, op, o_next );
-
+ if ( conn->c_n_ops_pending > max ) {
+ rc = -1;
+ } else {
+ rc = 1;
+ }
} else {
conn->c_n_ops_executing++;
- /* Don't allow any single conn to soak up all of the
- * available threads
- */
- if (conn->c_n_ops_executing > connection_pool_max/2) {
- ber_socket_t sd;
-
- ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
- slapd_clr_read( sd, 0 );
- }
connection_op_activate( op );
}
#endif
assert( conn->c_struct_state == SLAP_C_USED );
- return 0;
+ return rc;
}
static int
return 0;
}
- if( conn->c_conn_state != SLAP_C_ACTIVE ) {
+ if( conn->c_conn_state != SLAP_C_ACTIVE || conn->c_writewaiter ) {
/* other states need different handling */
return 0;
}
while ((op = LDAP_STAILQ_FIRST( &conn->c_pending_ops )) != NULL) {
+ if ( conn->c_n_ops_executing > connection_pool_max/2 ) {
+ break;
+ }
LDAP_STAILQ_REMOVE_HEAD( &conn->c_pending_ops, o_next );
LDAP_STAILQ_NEXT(op, o_next) = NULL;
/* pending operations should not be marked for abandonment */
op->o_protocol = op->o_conn->c_protocol
? op->o_conn->c_protocol : LDAP_VERSION3;
}
+ if (op->o_conn->c_conn_state == SLAP_C_INACTIVE
+ && op->o_protocol > LDAP_VERSION2) {
+ op->o_conn->c_conn_state = SLAP_C_ACTIVE;
+ }
+
op->o_connid = op->o_conn->c_connid;
LDAP_STAILQ_INSERT_TAIL( &op->o_conn->c_ops, op, o_next );
LDAP_SLAPD_V (ber_len_t) sockbuf_max_incoming;
LDAP_SLAPD_V (ber_len_t) sockbuf_max_incoming_auth;
+LDAP_SLAPD_V (int) slap_conn_max_pending;
+LDAP_SLAPD_V (int) slap_conn_max_pending_auth;
LDAP_SLAPD_V (slap_mask_t) global_restrictops;
LDAP_SLAPD_V (slap_mask_t) global_allows;
#define SLAP_SB_MAX_INCOMING_DEFAULT ((1<<18) - 1)
#define SLAP_SB_MAX_INCOMING_AUTH ((1<<24) - 1)
+#define SLAP_CONN_MAX_PENDING_DEFAULT 100
+#define SLAP_CONN_MAX_PENDING_AUTH 1000
+
#define SLAP_TEXT_BUFLEN (256)
/* psuedo error code indicating abandoned operation */