From 8f37ebb9b50f2aae7a146effb53fe1b076dd5cf3 Mon Sep 17 00:00:00 2001
From: Rich Megginson <rmeggins@redhat.com>
Date: Tue, 16 Apr 2013 08:26:03 -0600
Subject: [PATCH] Ticket #47377 - make listen backlog size configurable

https://fedorahosted.org/389/ticket/47377
Reviewed by: ???
Branch: master
Fix Description: Add the attribute nsslapd-listen-backlog-size - this controls
the listening socket connection backlog maximum size.  This corresponds to
the backlog parameter of the listen() system call.  The default value is 128.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: yes - need to doc the new attribute
---
 ldap/servers/slapd/daemon.c     |   16 ++++------------
 ldap/servers/slapd/libglobs.c   |   34 +++++++++++++++++++++++++++++++++-
 ldap/servers/slapd/proto-slap.h |    3 ++-
 ldap/servers/slapd/slap.h       |   10 ++++++++++
 4 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
index 7791f81..9ff2da3 100644
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -101,14 +101,6 @@
 #include "getsocketpeer.h"
 #endif /* ENABLE_LDAPI */
 
-/*
- * Define the backlog number for use in listen() call.
- * We use the same definition as in ldapserver/include/base/systems.h
- */
-#ifndef DAEMON_LISTEN_SIZE
-#define DAEMON_LISTEN_SIZE 128
-#endif
-
 #if defined (LDAP_IOCP)
 #define	SLAPD_WAKEUP_TIMER	250
 #else
@@ -1083,7 +1075,7 @@ void slapd_daemon( daemon_ports_t *ports )
 	/* We are now ready to accept incoming connections */
 #if defined( XP_WIN32 )
 	if ( n_tcps != SLAPD_INVALID_SOCKET
-				&& listen( n_tcps, DAEMON_LISTEN_SIZE ) == -1 ) {
+				&& listen( n_tcps, config_get_listen_backlog_size() ) == -1 ) {
 		int		oserr = errno;
 		char	addrbuf[ 256 ];
 
@@ -1099,7 +1091,7 @@ void slapd_daemon( daemon_ports_t *ports )
 		PRFileDesc **fdesp;
 		PRNetAddr  **nap = ports->n_listenaddr;
 		for (fdesp = n_tcps; fdesp && *fdesp; fdesp++, nap++) {
-			if ( PR_Listen( *fdesp, DAEMON_LISTEN_SIZE ) == PR_FAILURE ) {
+			if ( PR_Listen( *fdesp, config_get_listen_backlog_size() ) == PR_FAILURE ) {
 				PRErrorCode prerr = PR_GetError();
 				char		addrbuf[ 256 ];
 
@@ -1119,7 +1111,7 @@ void slapd_daemon( daemon_ports_t *ports )
 		PRFileDesc **fdesp;
 		PRNetAddr  **sap = ports->s_listenaddr;
 		for (fdesp = s_tcps; fdesp && *fdesp; fdesp++, sap++) {
-			if ( PR_Listen( *fdesp, DAEMON_LISTEN_SIZE ) == PR_FAILURE ) {
+			if ( PR_Listen( *fdesp, config_get_listen_backlog_size() ) == PR_FAILURE ) {
 				PRErrorCode prerr = PR_GetError();
 				char		addrbuf[ 256 ];
 
@@ -1140,7 +1132,7 @@ void slapd_daemon( daemon_ports_t *ports )
 		PRFileDesc **fdesp;
 		PRNetAddr  **iap = ports->i_listenaddr;
 		for (fdesp = i_unix; fdesp && *fdesp; fdesp++, iap++) {
-			if ( PR_Listen(*fdesp, DAEMON_LISTEN_SIZE) == PR_FAILURE) {
+			if ( PR_Listen(*fdesp, config_get_listen_backlog_size()) == PR_FAILURE) {
 				PRErrorCode prerr = PR_GetError();
 				slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
 					"listen() on %s failed: error %d (%s)\n",
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index cfb8856..8095d85 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -260,6 +260,7 @@ slapi_onoff_t init_return_orig_type;
 slapi_onoff_t init_enable_turbo_mode;
 slapi_onoff_t init_connection_nocanon;
 slapi_int_t init_connection_buffer;
+slapi_int_t init_listen_backlog_size;
 #ifdef MEMPOOL_EXPERIMENTAL
 slapi_onoff_t init_mempool_switch;
 #endif
@@ -1063,7 +1064,11 @@ static struct config_get_and_set {
 	{CONFIG_CONNECTION_NOCANON, config_set_connection_nocanon,
 	        NULL, 0,
 	        (void**)&global_slapdFrontendConfig.connection_nocanon,
-	        CONFIG_ON_OFF, (ConfigGetFunc)config_get_connection_nocanon, &init_connection_nocanon}
+	        CONFIG_ON_OFF, (ConfigGetFunc)config_get_connection_nocanon, &init_connection_nocanon},
+	{CONFIG_LISTEN_BACKLOG_SIZE, config_set_listen_backlog_size,
+		NULL, 0,
+		(void**)&global_slapdFrontendConfig.listen_backlog_size, CONFIG_INT,
+		(ConfigGetFunc)config_get_listen_backlog_size, &init_listen_backlog_size}
 #ifdef MEMPOOL_EXPERIMENTAL
 	,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch,
 		NULL, 0,
@@ -1506,6 +1511,7 @@ FrontendConfig_init () {
   init_connection_buffer = cfg->connection_buffer = CONNECTION_BUFFER_ON;
   init_connection_nocanon = cfg->connection_nocanon = LDAP_ON;
 
+  init_listen_backlog_size = cfg->listen_backlog_size = DAEMON_LISTEN_SIZE;
 #ifdef MEMPOOL_EXPERIMENTAL
   init_mempool_switch = cfg->mempool_switch = LDAP_ON;
   cfg->mempool_maxfreelist = 1024;
@@ -7054,6 +7060,32 @@ config_set_connection_buffer( const char *attrname, char *value,
     return retVal;
 }
 
+int
+config_set_listen_backlog_size( const char *attrname, char *value,
+		char *errorbuf, int apply )
+{
+	slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+	
+	if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+		return LDAP_OPERATIONS_ERROR;
+	}
+
+	if ( apply ) {
+    		PR_AtomicSet(&slapdFrontendConfig->listen_backlog_size, atoi(value));
+	}
+	return LDAP_SUCCESS;
+}
+
+int
+config_get_listen_backlog_size()
+{
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  int retVal;
+
+  retVal = slapdFrontendConfig->listen_backlog_size;
+  return retVal; 
+}
+
 /*
  * This function is intended to be used from the dse code modify callback.  It
  * is "optimized" for that case because it takes a berval** of values, which is
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 9fe26ff..64d3777 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -403,6 +403,7 @@ int config_set_ndn_cache_max_size(const char *attrname, char *value, char *error
 int config_set_unhashed_pw_switch(const char *attrname, char *value, char *errorbuf, int apply); 
 int config_set_return_orig_type_switch(const char *attrname, char *value, char *errorbuf, int apply);
 int config_set_sasl_maxbufsize(const char *attrname, char *value, char *errorbuf, int apply );
+int config_set_listen_backlog_size(const char *attrname, char *value, char *errorbuf, int apply);
 
 #if !defined(_WIN32) && !defined(AIX)
 int config_set_maxdescriptors( const char *attrname, char *value, char *errorbuf, int apply );
@@ -577,7 +578,7 @@ int config_get_connection_buffer();
 int config_set_connection_buffer(const char *attrname, char *value, char *errorbuf, int apply);
 int config_get_connection_nocanon();
 int config_set_connection_nocanon(const char *attrname, char *value, char *errorbuf, int apply);
-
+int config_get_listen_backlog_size(void);
 
 PLHashNumber hashNocaseString(const void *key);
 PRIntn hashNocaseCompare(const void *v1, const void *v2);
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 1039b0a..af69ebb 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -2090,6 +2090,15 @@ typedef struct _slapdEntryPoints {
 #define CONFIG_ENABLE_TURBO_MODE "nsslapd-enable-turbo-mode"
 #define CONFIG_CONNECTION_BUFFER "nsslapd-connection-buffer"
 #define CONFIG_CONNECTION_NOCANON "nsslapd-connection-nocanon"
+#define CONFIG_LISTEN_BACKLOG_SIZE	"nsslapd-listen-backlog-size"
+
+/*
+ * Define the backlog number for use in listen() call.
+ * We use the same definition as in ldapserver/include/base/systems.h
+ */
+#ifndef DAEMON_LISTEN_SIZE
+#define DAEMON_LISTEN_SIZE 128
+#endif
 
 #ifdef MEMPOOL_EXPERIMENTAL
 #define CONFIG_MEMPOOL_SWITCH_ATTRIBUTE "nsslapd-mempool"
@@ -2298,6 +2307,7 @@ typedef struct _slapdFrontendConfig {
   slapi_onoff_t minssf_exclude_rootdse; /* ON: minssf is ignored when searching rootdse */
   size_t maxsasliosize;         /* limit incoming SASL IO packet size */
   char *anon_limits_dn;		/* template entry for anonymous resource limits */
+  slapi_int_t listen_backlog_size;      /* size of backlog parameter to PR_Listen */
 #ifndef _WIN32
   struct passwd *localuserinfo; /* userinfo of localuser */
 #endif /* _WIN32 */
-- 
1.7.1

