浏览代码

Ticket 47426 - move compute_idletimeout out of handle_pr_read_ready

Description:  Instead of calculating the idletimeout everytime new data is received,
              set the anonymous reslimit idletimeout and handle in the connection struct when the
              connection first comes in.  Then update idletimeout after each bind.

              I removed compute_idletimeout() because bind_credentials_set_nolock()
              basically does the same thing, so it was just extended to update
              the idletimeout.

https://fedorahosted.org/389/ticket/47426

Reviewed by: richm(Thanks!)
Mark Reynolds 12 年之前
父节点
当前提交
ed83a78388
共有 4 个文件被更改,包括 50 次插入65 次删除
  1. 21 0
      ldap/servers/slapd/connection.c
  2. 14 64
      ldap/servers/slapd/daemon.c
  3. 12 0
      ldap/servers/slapd/pblock.c
  4. 3 1
      ldap/servers/slapd/slap.h

+ 21 - 0
ldap/servers/slapd/connection.c

@@ -2326,6 +2326,27 @@ connection_threadmain()
 					   in connection_activity when the conn is added to the
 					   work queue, setup_pr_read_pds won't add the connection prfd
 					   to the poll list */
+					if(pb->pb_conn && pb->pb_conn->c_opscompleted == 0){
+						/*
+						 * We have a new connection, set the anonymous reslimit idletimeout
+						 * if applicable.
+						 */
+						char *anon_dn = config_get_anon_limits_dn();
+						int idletimeout;
+						/* If an anonymous limits dn is set, use it to set the limits. */
+						if (anon_dn && (strlen(anon_dn) > 0)) {
+							Slapi_DN *anon_sdn = slapi_sdn_new_normdn_byref( anon_dn );
+							reslimit_update_from_dn( pb->pb_conn, anon_sdn );
+							slapi_sdn_free( &anon_sdn );
+							if (slapi_reslimit_get_integer_limit(pb->pb_conn, pb->pb_conn->c_idletimeout_handle,
+									&idletimeout)
+								== SLAPI_RESLIMIT_STATUS_SUCCESS)
+							{
+								pb->pb_conn->c_idletimeout = idletimeout;
+							}
+						}
+						slapi_ch_free_string( &anon_dn );
+					}
 					if (connection_call_io_layer_callbacks(pb->pb_conn)) {
 						LDAPDebug0Args( LDAP_DEBUG_ANY, "Error: could not add/remove IO layers from connection\n" );
 					}

+ 14 - 64
ldap/servers/slapd/daemon.c

@@ -1785,59 +1785,6 @@ daemon_register_reslimits( void )
 			&idletimeout_reslimit_handle ));
 }
 
-
-/*
- * Compute the idle timeout for the connection.
- *
- * Note: this function must always be called with conn->c_mutex locked.
- */
-static int
-compute_idletimeout( slapdFrontendConfig_t *fecfg, Connection *conn )
-{
-	int		idletimeout = 0;
-
-	if ( slapi_reslimit_get_integer_limit( conn, idletimeout_reslimit_handle,
-            &idletimeout ) != SLAPI_RESLIMIT_STATUS_SUCCESS ) {
-		/*
-		 * No limit associated with binder/connection or some other error
-		 * occurred.  If the user is anonymous and anonymous limits are
-		 * set, attempt to set the bind based resource limits.  We do this
-		 * here since a BIND operation is not required prior to other
-		 * operations.  We want to set the anonymous limits early on so
-		 * that they are put into effect if a BIND is never sent.  If
-		 * this is not an anonymous user and no bind-based limits are set,
-		 * use the default idle timeout.
-	 	 */
-
-		if (conn->c_dn == NULL) {
-			char *anon_dn = config_get_anon_limits_dn();
-			if (anon_dn && (strlen(anon_dn) > 0)) {
-				Slapi_DN *anon_sdn = slapi_sdn_new_dn_byref(anon_dn);
-
-				reslimit_update_from_dn(conn, anon_sdn);
-
-				if (slapi_reslimit_get_integer_limit(conn, idletimeout_reslimit_handle,
-													 &idletimeout)
-					!= SLAPI_RESLIMIT_STATUS_SUCCESS) {
-					idletimeout = fecfg->idletimeout;
-				}
-
-				slapi_sdn_free(&anon_sdn);
-			} else {
-				idletimeout = fecfg->idletimeout;
-			}
-			slapi_ch_free_string(&anon_dn);
-		} else if ( conn->c_isroot ) {
-			idletimeout = 0;	/* no limit for Directory Manager */
-		} else {
-			idletimeout = fecfg->idletimeout;
-		}
-	}
-
-	return( idletimeout );
-}
-
-
 #ifdef _WIN32
 static void
 handle_read_ready(Connection_Table *ct, fd_set *readfds)
@@ -1881,9 +1828,8 @@ handle_read_ready(Connection_Table *ct, fd_set *readfds)
 
 					/* idle timeout */
 				}
-				else if (( idletimeout = compute_idletimeout(
-						slapdFrontendConfig, c )) > 0 &&
-						(curtime - c->c_idlesince) >= idletimeout &&
+				else if (( c->c_idletimeout > 0 &&
+						(curtime - c->c_idlesince) >= c->c_idletimeout &&
 						NULL == c->c_ops )
 				{
 					disconnect_server_nomutex( c, c->c_connid, -1,
@@ -1903,8 +1849,6 @@ handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll)
 {
 	Connection *c;
 	time_t curtime = current_time();
-	slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
-	int idletimeout;
 	int maxthreads = config_get_maxthreadsperconn();
 #if defined( XP_WIN32 )
 	int i;
@@ -1968,10 +1912,9 @@ handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll)
 				/* This is where the work happens ! */
 				connection_activity( c );
 			}
-			else if (( idletimeout = compute_idletimeout( slapdFrontendConfig,
-					c )) > 0 &&
+			else if (( c->c_ideltimeout > 0 &&
 					c->c_prfd == ct->fd[i].fd &&
-					(curtime - c->c_idlesince) >= idletimeout &&
+					(curtime - c->c_idlesince) >= c->c_ideltimeout &&
 					NULL == c->c_ops )
 			{
 				/* idle timeout */
@@ -2042,9 +1985,8 @@ handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll)
 									   SLAPD_DISCONNECT_POLL, EPIPE );
 					}
 				}
-				else if (( idletimeout = compute_idletimeout(
-						slapdFrontendConfig, c )) > 0 &&
-						(curtime - c->c_idlesince) >= idletimeout &&
+				else if (c->c_idletimeout > 0 &&
+						(curtime - c->c_idlesince) >= c->c_idletimeout &&
 						NULL == c->c_ops )
 				{
 					/* idle timeout */
@@ -2613,6 +2555,7 @@ handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd, i
 	PRNetAddr from;
 	PRFileDesc *pr_clonefd = NULL;
 	ber_len_t maxbersize;
+	slapdFrontendConfig_t *fecfg = getFrontendConfig();
 
 	memset(&from, 0, sizeof(from)); /* reset to nulls so we can see what was set */
 	if ( (ns = accept_and_configure( tcps, pr_acceptfd, &from,
@@ -2629,6 +2572,13 @@ handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd, i
 	}
 	PR_Lock( conn->c_mutex );
 
+	/*
+	 * Set the default idletimeout and the handle.  We'll update c_idletimeout
+	 * after each bind so we can correctly set the resource limit.
+	 */
+	conn->c_idletimeout = fecfg->idletimeout;
+	conn->c_idletimeout_handle = idletimeout_reslimit_handle;
+
 #if defined( XP_WIN32 )
 	if( !secure )
 		ber_sockbuf_set_option(conn->c_sb,LBER_SOCKBUF_OPT_DESC,&ns);

+ 12 - 0
ldap/servers/slapd/pblock.c

@@ -3659,6 +3659,9 @@ void
 bind_credentials_set_nolock( Connection *conn, char *authtype, char *normdn,
                 char *extauthtype, char *externaldn, CERTCertificate *clientcert, Slapi_Entry * bind_target_entry )
 {
+	slapdFrontendConfig_t *fecfg = getFrontendConfig();
+	int idletimeout = 0;
+
 	/* clear credentials */
 	bind_credentials_clear( conn, PR_FALSE /* conn is already locked */,
 		( extauthtype != NULL ) /* clear external creds. if requested */ );
@@ -3702,8 +3705,17 @@ bind_credentials_set_nolock( Connection *conn, char *authtype, char *normdn,
 
 			slapi_ch_free_string( &anon_dn );
 		}
+		if (slapi_reslimit_get_integer_limit(conn, conn->c_idletimeout_handle,
+											 &idletimeout)
+				!= SLAPI_RESLIMIT_STATUS_SUCCESS)
+		{
+			conn->c_idletimeout = fecfg->idletimeout;
+		} else {
+			conn->c_idletimeout = idletimeout;
+		}
 	} else {
 		/* For root dn clear about the resource limits */
 		reslimit_update_from_entry( conn, NULL );
+		conn->c_idletimeout = 0;
 	}
 }

+ 3 - 1
ldap/servers/slapd/slap.h

@@ -1441,7 +1441,7 @@ typedef struct conn {
 	char		*c_authtype;	/* auth method used to bind c_dn  */
 	char		*c_external_dn;	/* client DN of this SSL session  */
 	char		*c_external_authtype; /* used for c_external_dn   */
-        PRNetAddr	*cin_addr;	/* address of client on this conn */
+	PRNetAddr	*cin_addr;	/* address of client on this conn */
 	PRNetAddr	*cin_destaddr;	/* address client connected to    */
 	struct berval	**c_domain;	/* DNS names of client            */
 	Operation		*c_ops;		/* list of pending operations	  */
@@ -1458,6 +1458,8 @@ typedef struct conn {
 	PRLock			*c_mutex;	/* protect each conn structure    */
 	PRLock			*c_pdumutex;	/* only write one pdu at a time   */
 	time_t			c_idlesince;	/* last time of activity on conn  */
+	int			c_idletimeout;	/* local copy of idletimeout */
+	int			c_idletimeout_handle;	/* the resource limits handle */
 	Conn_private	*c_private;	/* data which is not shared outside*/
 								/* connection.c 		  */
 	int				c_flags;	/* Misc flags used only for SSL   */