summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2007-08-03 22:14:41 +0000
committerNoriko Hosoi <nhosoi@redhat.com>2007-08-03 22:14:41 +0000
commit0073de611b08f6027dfcdde79335db149020a4a9 (patch)
tree045e3735701a46c69f01856a4a8339f4c7db5fed
parentd7531c68d34d83c17c0d1996fec6d6a0ebfc0e4b (diff)
downloadds-0073de611b08f6027dfcdde79335db149020a4a9.tar.gz
ds-0073de611b08f6027dfcdde79335db149020a4a9.tar.xz
ds-0073de611b08f6027dfcdde79335db149020a4a9.zip
Resolves: #250702
Summary: not all the addresses associated with listenhost are bound to listen sockets (comment #10)
-rw-r--r--ldap/servers/slapd/daemon.c599
-rw-r--r--ldap/servers/slapd/fe.h12
-rw-r--r--ldap/servers/slapd/main.c27
-rw-r--r--ldap/servers/slapd/slap.h15
4 files changed, 416 insertions, 237 deletions
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
index 3ad3d82c..667cf05c 100644
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -127,9 +127,6 @@ static int writesignalpipe = SLAPD_INVALID_SOCKET;
static int readsignalpipe = SLAPD_INVALID_SOCKET;
#define FDS_SIGNAL_PIPE 0
-#define FDS_N_TCPS 1
-#define FDS_S_TCPS 2
-#define FDS_I_UNIX 3
static int get_configured_connection_table_size();
#ifdef RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS
@@ -139,12 +136,12 @@ static void get_loopback_by_addr( void );
#ifdef XP_WIN32
static int createlistensocket(unsigned short port, const PRNetAddr *listenaddr);
#endif
-static PRFileDesc *createprlistensocket(unsigned short port,
- const PRNetAddr *listenaddr, int secure, int local);
+static PRFileDesc **createprlistensockets(unsigned short port,
+ PRNetAddr **listenaddr, int secure, int local);
static const char *netaddr2string(const PRNetAddr *addr, char *addrbuf,
size_t addrbuflen);
static void set_shutdown (int);
-static void setup_pr_read_pds(Connection_Table *ct, PRFileDesc *n_tcps, PRFileDesc *s_tcps, PRFileDesc *i_unix, PRIntn *num_to_read);
+static void setup_pr_read_pds(Connection_Table *ct, PRFileDesc **n_tcps, PRFileDesc **s_tcps, PRFileDesc **i_unix, PRIntn *num_to_read);
#ifdef HPUX10
static void* catch_signals();
@@ -373,7 +370,7 @@ static int handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_
#ifdef _WIN32
static void unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, int n_tcps, PRFileDesc *s_tcps);
#else
-static void unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, PRFileDesc *n_tcps, PRFileDesc *s_tcps, PRFileDesc *i_unix);
+static void unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, PRFileDesc **n_tcps, PRFileDesc **s_tcps, PRFileDesc **i_unix);
#endif
static int write_pid_file();
static int init_shutdown_detect();
@@ -396,14 +393,14 @@ int daemon_pre_setuid_init(daemon_ports_t *ports)
ports->n_socket = createlistensocket((unsigned short)ports->n_port,
&ports->n_listenaddr);
#else
- ports->n_socket = createprlistensocket(ports->n_port,
- &ports->n_listenaddr, 0, 0);
+ ports->n_socket = createprlistensockets(ports->n_port,
+ ports->n_listenaddr, 0, 0);
#endif
}
if ( config_get_security() && (0 != ports->s_port) ) {
- ports->s_socket = createprlistensocket((unsigned short)ports->s_port,
- &ports->s_listenaddr, 1, 0);
+ ports->s_socket = createprlistensockets((unsigned short)ports->s_port,
+ ports->s_listenaddr, 1, 0);
#ifdef XP_WIN32
ports->s_socket_native = PR_FileDesc2NativeHandle(ports->s_socket);
#endif
@@ -418,7 +415,7 @@ int daemon_pre_setuid_init(daemon_ports_t *ports)
#if defined(ENABLE_LDAPI)
/* ldapi */
if(0 != ports->i_port) {
- ports->i_socket = createprlistensocket(1, &ports->i_listenaddr, 0, 1);
+ ports->i_socket = createprlistensockets(1, ports->i_listenaddr, 0, 1);
}
#endif /* ENABLE_LDAPI */
#endif
@@ -486,12 +483,14 @@ void slapd_daemon( daemon_ports_t *ports )
#if defined( XP_WIN32 )
int n_tcps = 0;
int s_tcps_native = 0;
+ PRFileDesc *s_tcps = NULL;
#else
- PRFileDesc *n_tcps = NULL;
PRFileDesc *tcps = 0;
- PRFileDesc *i_unix = 0;
+ PRFileDesc **n_tcps = NULL;
+ PRFileDesc **s_tcps = NULL;
+ PRFileDesc **i_unix = NULL;
+ PRFileDesc **fdesp = NULL;
#endif
- PRFileDesc *s_tcps = NULL;
PRIntn num_poll = 0;
PRIntervalTime pr_timeout = PR_MillisecondsToInterval(slapd_wakeup_timer);
PRThread *time_thread_p;
@@ -576,44 +575,59 @@ void slapd_daemon( daemon_ports_t *ports )
g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
}
#else
- if ( n_tcps != NULL
- && PR_Listen( n_tcps, DAEMON_LISTEN_SIZE ) == PR_FAILURE) {
- PRErrorCode prerr = PR_GetError();
- char addrbuf[ 256 ];
-
- slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
- "PR_Listen() on %s port %d failed: %s error %d (%s)\n",
- netaddr2string(&ports->n_listenaddr, addrbuf, sizeof(addrbuf)),
- ports->n_port, SLAPI_COMPONENT_NAME_NSPR, prerr,
- slapd_pr_strerror( prerr ));
- g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
+ if ( n_tcps != NULL ) {
+ PRFileDesc **fdesp;
+ PRNetAddr **nap = ports->n_listenaddr;
+ for (fdesp = n_tcps; fdesp && *fdesp; fdesp++, nap++) {
+ if ( PR_Listen( *fdesp, DAEMON_LISTEN_SIZE ) == PR_FAILURE ) {
+ PRErrorCode prerr = PR_GetError();
+ char addrbuf[ 256 ];
+
+ slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
+ "PR_Listen() on %s port %d failed: %s error %d (%s)\n",
+ netaddr2string(*nap, addrbuf, sizeof(addrbuf)),
+ ports->n_port, SLAPI_COMPONENT_NAME_NSPR, prerr,
+ slapd_pr_strerror( prerr ));
+ g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
+ }
+ }
}
#endif
- if ( s_tcps != NULL
- && PR_Listen( s_tcps, DAEMON_LISTEN_SIZE ) == PR_FAILURE ) {
- PRErrorCode prerr = PR_GetError();
- char addrbuf[ 256 ];
-
- slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
- "PR_Listen() on %s port %d failed: %s error %d (%s)\n",
- netaddr2string(&ports->s_listenaddr, addrbuf, sizeof(addrbuf)),
- ports->s_port, SLAPI_COMPONENT_NAME_NSPR, prerr,
- slapd_pr_strerror( prerr ));
- g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
+ if ( s_tcps != NULL ) {
+ PRFileDesc **fdesp;
+ PRNetAddr **sap = ports->s_listenaddr;
+ for (fdesp = s_tcps; fdesp && *fdesp; fdesp++, sap++) {
+ if ( PR_Listen( *fdesp, DAEMON_LISTEN_SIZE ) == PR_FAILURE ) {
+ PRErrorCode prerr = PR_GetError();
+ char addrbuf[ 256 ];
+
+ slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
+ "PR_Listen() on %s port %d failed: %s error %d (%s)\n",
+ netaddr2string(*sap, addrbuf, sizeof(addrbuf)),
+ ports->s_port, SLAPI_COMPONENT_NAME_NSPR, prerr,
+ slapd_pr_strerror( prerr ));
+ g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
+ }
+ }
}
#if !defined( XP_WIN32 )
#if defined(ENABLE_LDAPI)
- if( i_unix != NULL &&
- PR_Listen(i_unix, DAEMON_LISTEN_SIZE) == PR_FAILURE) {
- PRErrorCode prerr = PR_GetError();
- slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
- "listen() on %s failed: error %d (%s)\n",
- ports->i_listenaddr.local.path,
- prerr,
- slapd_pr_strerror( prerr ));
- g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
+ if( i_unix != NULL ) {
+ PRFileDesc **fdesp;
+ PRNetAddr **iap = ports->i_listenaddr;
+ for (fdesp = i_unix; fdesp && *fdesp; fdesp++, iap++) {
+ if ( PR_Listen(*fdesp, DAEMON_LISTEN_SIZE) == PR_FAILURE) {
+ PRErrorCode prerr = PR_GetError();
+ slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
+ "listen() on %s failed: error %d (%s)\n",
+ (*iap)->local.path,
+ prerr,
+ slapd_pr_strerror( prerr ));
+ g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
+ }
+ }
}
#endif /* ENABLE_LDAPI */
#endif
@@ -632,6 +646,7 @@ void slapd_daemon( daemon_ports_t *ports )
int select_return = 0;
int secure = 0; /* is a new connection an SSL one ? */
int local = 0; /* is new connection an ldapi one? */
+ int i;
#ifndef _WIN32
PRErrorCode prerr;
@@ -680,21 +695,44 @@ void slapd_daemon( daemon_ports_t *ports )
clear_signal(&readfds);
#else
tcps = NULL;
- /* info for n_tcps is always in fd[FDS_N_TCPS] and info for s_tcps is always
- * in fd[FDS_S_TCPS] */
- if( n_tcps != NULL &&
- the_connection_table->fd[FDS_N_TCPS].out_flags & SLAPD_POLL_FLAGS ) {
- tcps = n_tcps;
- } else if ( s_tcps != NULL &&
- the_connection_table->fd[FDS_S_TCPS].out_flags & SLAPD_POLL_FLAGS ) {
- tcps = s_tcps;
- secure = 1;
+ /* info for n_tcps is always in fd[n_tcps ~ n_tcpe] */
+ if( NULL != n_tcps ) {
+ for (i = the_connection_table->n_tcps;
+ i < the_connection_table->n_tcpe; i++) {
+ if (the_connection_table->fd[i].out_flags &
+ SLAPD_POLL_FLAGS ) {
+ /* tcps = n_tcps[i - the_connection_table->n_tcps]; */
+ tcps = the_connection_table->fd[i].fd;
+ break;
+ }
+ }
+ }
+ /* info for s_tcps is always in fd[s_tcps ~ s_tcpe] */
+ if ( NULL == tcps && NULL != s_tcps ) {
+ for (i = the_connection_table->s_tcps;
+ i < the_connection_table->s_tcpe; i++) {
+ if (the_connection_table->fd[i].out_flags &
+ SLAPD_POLL_FLAGS ) {
+ /* tcps = s_tcps[i - the_connection_table->s_tcps]; */
+ tcps = the_connection_table->fd[i].fd;
+ secure = 1;
+ break;
+ }
+ }
}
#if defined(ENABLE_LDAPI)
- else if ( i_unix != 0 &&
- the_connection_table->fd[FDS_I_UNIX].out_flags & SLAPD_POLL_FLAGS ) {
- tcps = i_unix;
- local = 1;
+ /* info for i_unix is always in fd[i_unixs ~ i_unixe] */
+ if ( NULL == tcps && NULL != i_unix ) {
+ for (i = the_connection_table->i_unixs;
+ i < the_connection_table->i_unixe; i++) {
+ if (the_connection_table->fd[i].out_flags &
+ SLAPD_POLL_FLAGS ) {
+ /* tcps = i_unix[i - the_connection_table->i_unixs]; */
+ tcps = the_connection_table->fd[i].fd;
+ local = 1;
+ break;
+ }
+ }
}
#endif /* ENABLE_LDAPI */
@@ -723,20 +761,45 @@ void slapd_daemon( daemon_ports_t *ports )
if ( n_tcps != SLAPD_INVALID_SOCKET ) {
closesocket( n_tcps );
}
+ if ( s_tcps != NULL ) {
+ PR_Close( s_tcps );
+ }
#else
- if ( n_tcps != NULL ) {
- PR_Close( n_tcps );
+ for (fdesp = n_tcps; fdesp && *fdesp; fdesp++) {
+ PR_Close( *fdesp );
}
+ slapi_ch_free ((void**)&n_tcps);
- if ( i_unix != NULL ) {
- PR_Close( i_unix );
+ for (fdesp = i_unix; fdesp && *fdesp; fdesp++) {
+ PR_Close( *fdesp );
}
+ slapi_ch_free ((void**)&i_unix);
-#endif
+ for (fdesp = s_tcps; fdesp && *fdesp; fdesp++) {
+ PR_Close( *fdesp );
+ }
+ slapi_ch_free ((void**)&s_tcps);
- if ( s_tcps != NULL ) {
- PR_Close( s_tcps );
+ /* freeing NetAddrs */
+ {
+ PRNetAddr **nap;
+ for (nap = ports->n_listenaddr; nap && *nap; nap++) {
+ slapi_ch_free ((void**)nap);
+ }
+ slapi_ch_free ((void**)&ports->n_listenaddr);
+
+ for (nap = ports->s_listenaddr; nap && *nap; nap++) {
+ slapi_ch_free ((void**)nap);
+ }
+ slapi_ch_free ((void**)&ports->s_listenaddr);
+#if defined(ENABLE_LDAPI)
+ for (nap = ports->i_listenaddr; nap && *nap; nap++) {
+ slapi_ch_free ((void**)nap);
+ }
+ slapi_ch_free ((void**)&ports->i_listenaddr);
+#endif
}
+#endif
/* Might compete with housecleaning thread, but so far so good */
be_flushall();
@@ -988,8 +1051,9 @@ static void setup_read_fds(Connection_Table *ct, fd_set *readfds, int n_tcps, in
#endif /* _WIN32 */
static int first_time_setup_pr_read_pds = 1;
+static int listen_addr_count = 0;
static void
-setup_pr_read_pds(Connection_Table *ct, PRFileDesc *n_tcps, PRFileDesc *s_tcps, PRFileDesc *i_unix, PRIntn *num_to_read)
+setup_pr_read_pds(Connection_Table *ct, PRFileDesc **n_tcps, PRFileDesc **s_tcps, PRFileDesc **i_unix, PRIntn *num_to_read)
{
Connection *c= NULL;
Connection *next= NULL;
@@ -1001,19 +1065,19 @@ setup_pr_read_pds(Connection_Table *ct, PRFileDesc *n_tcps, PRFileDesc *s_tcps,
int max_threads_per_conn = config_get_maxthreadsperconn();
accept_new_connections = ((ct->size - g_get_current_conn_count())
- > slapdFrontendConfig->reservedescriptors);
+ > slapdFrontendConfig->reservedescriptors);
if ( ! accept_new_connections ) {
if ( last_accept_new_connections ) {
LDAPDebug( LDAP_DEBUG_ANY, "Not listening for new "
- "connections - too many fds open\n", 0, 0, 0 );
+ "connections - too many fds open\n", 0, 0, 0 );
/* reinitialize n_tcps and s_tcps to the pds */
first_time_setup_pr_read_pds = 1;
}
} else {
if ( ! last_accept_new_connections &&
- last_accept_new_connections != -1 ) {
+ last_accept_new_connections != -1 ) {
LDAPDebug( LDAP_DEBUG_ANY, "Listening for new "
- "connections again\n", 0, 0, 0 );
+ "connections again\n", 0, 0, 0 );
/* reinitialize n_tcps and s_tcps to the pds */
first_time_setup_pr_read_pds = 1;
}
@@ -1021,91 +1085,116 @@ setup_pr_read_pds(Connection_Table *ct, PRFileDesc *n_tcps, PRFileDesc *s_tcps,
last_accept_new_connections = accept_new_connections;
- /* initialize the mapping from connection table entries to fds entries */
+ /* initialize the mapping from connection table entries to fds entries */
if (first_time_setup_pr_read_pds)
{
int i;
- for (i = 0; i < ct->size; i++)
- {
- ct->c[i].c_fdi = SLAPD_INVALID_SOCKET_INDEX;
- }
+ for (i = 0; i < ct->size; i++)
+ {
+ ct->c[i].c_fdi = SLAPD_INVALID_SOCKET_INDEX;
+ }
- /* The fds entry for n_tcps is always FDS_N_TCPS */
- if (n_tcps != NULL && accept_new_connections)
- {
- ct->fd[FDS_N_TCPS].fd = n_tcps;
- ct->fd[FDS_N_TCPS].in_flags = SLAPD_POLL_FLAGS;
- ct->fd[FDS_N_TCPS].out_flags = 0;
- LDAPDebug( LDAP_DEBUG_HOUSE,
- "listening for connections on %d\n", socketdesc, 0, 0 );
- } else {
- ct->fd[FDS_N_TCPS].fd = NULL;
- }
+ /* The fds entry for the signalpipe is always FDS_SIGNAL_PIPE (== 0) */
+ count = FDS_SIGNAL_PIPE;
+#if !defined(_WIN32)
+ ct->fd[count].fd = signalpipe[0];
+ ct->fd[count].in_flags = SLAPD_POLL_FLAGS;
+ ct->fd[count].out_flags = 0;
+#else
+ ct->fd[count].fd = NULL;
+#endif
+ count++;
+
+ /* The fds entry for n_tcps starts with n_tcps and less than n_tcpe */
+ ct->n_tcps = count;
+ if (n_tcps != NULL && accept_new_connections)
+ {
+ PRFileDesc **fdesc = NULL;
+ for (fdesc = n_tcps; fdesc && *fdesc; fdesc++, count++) {
+ ct->fd[count].fd = *fdesc;
+ ct->fd[count].in_flags = SLAPD_POLL_FLAGS;
+ ct->fd[count].out_flags = 0;
+ LDAPDebug( LDAP_DEBUG_HOUSE,
+ "listening for connections on %d\n", socketdesc, 0, 0 );
+ }
+ } else {
+ ct->fd[count].fd = NULL;
+ count++;
+ }
+ ct->n_tcpe = count;
+
+ ct->s_tcps = count;
+ /* The fds entry for s_tcps starts with s_tcps and less than s_tcpe */
+ if (s_tcps != NULL && accept_new_connections)
+ {
+ PRFileDesc **fdesc = NULL;
+ for (fdesc = s_tcps; fdesc && *fdesc; fdesc++, count++) {
+ ct->fd[count].fd = *fdesc;
+ ct->fd[count].in_flags = SLAPD_POLL_FLAGS;
+ ct->fd[count].out_flags = 0;
+ LDAPDebug( LDAP_DEBUG_HOUSE,
+ "listening for SSL connections on %d\n", socketdesc, 0, 0 );
+ }
+ } else {
+ ct->fd[count].fd = NULL;
+ count++;
+ }
+ ct->s_tcpe = count;
- /* The fds entry for s_tcps is always FDS_S_TCPS */
- if (s_tcps != NULL && accept_new_connections)
- {
- ct->fd[FDS_S_TCPS].fd = s_tcps;
- ct->fd[FDS_S_TCPS].in_flags = SLAPD_POLL_FLAGS;
- ct->fd[FDS_S_TCPS].out_flags = 0;
- LDAPDebug( LDAP_DEBUG_HOUSE,
- "listening for SSL connections on %d\n", socketdesc, 0, 0 );
- } else {
- ct->fd[FDS_S_TCPS].fd = NULL;
- }
#if !defined(_WIN32)
- /* The fds entry for i_unix is always FDS_I_UNIX */
- if (i_unix != NULL && accept_new_connections)
- {
- ct->fd[FDS_I_UNIX].fd = i_unix;
- ct->fd[FDS_I_UNIX].in_flags = SLAPD_POLL_FLAGS;
- ct->fd[FDS_I_UNIX].out_flags = 0;
- LDAPDebug( LDAP_DEBUG_HOUSE,
- "listening for LDAPI connections on %d\n", socketdesc, 0, 0 );
- } else {
- ct->fd[FDS_I_UNIX].fd = NULL;
- }
-
- /* The fds entry for the signalpipe is always FDS_SIGNAL_PIPE */
- ct->fd[FDS_SIGNAL_PIPE].fd = signalpipe[0];
- ct->fd[FDS_SIGNAL_PIPE].in_flags = SLAPD_POLL_FLAGS;
- ct->fd[FDS_SIGNAL_PIPE].out_flags = 0;
-#else
- ct->fd[FDS_SIGNAL_PIPE].fd = NULL;
+#if defined(ENABLE_LDAPI)
+ ct->i_unixs = count;
+ /* The fds entry for i_unix starts with i_unixs and less than i_unixe */
+ if (i_unix != NULL && accept_new_connections)
+ {
+ PRFileDesc **fdesc = NULL;
+ for (fdesc = i_unix; fdesc && *fdesc; fdesc++, count++) {
+ ct->fd[count].fd = *fdesc;
+ ct->fd[count].in_flags = SLAPD_POLL_FLAGS;
+ ct->fd[count].out_flags = 0;
+ LDAPDebug( LDAP_DEBUG_HOUSE,
+ "listening for LDAPI connections on %d\n", socketdesc, 0, 0 );
+ }
+ } else {
+ ct->fd[count].fd = NULL;
+ count++;
+ }
+ ct->i_unixe = count;
#endif
- first_time_setup_pr_read_pds = 0;
+#endif
+
+ first_time_setup_pr_read_pds = 0;
+ listen_addr_count = count;
}
- /* count is the number of entries we've place in the fds array.
- * we always put n_tcps in slot FDS_N_TCPS, s_tcps in slot
- * FDS_S_TCPS and the signal pipe in slot FDS_SIGNAL_PIPE
- * and i_unix in FDS_I_UNIX
- * so we now set count to 4 */
- count = 4;
-
- /* Walk down the list of active connections to find
+ /* count is the number of entries we've place in the fds array.
+ * listen_addr_count is counted up when
+ * first_time_setup_pr_read_pds is TURE. */
+ count = listen_addr_count;
+
+ /* Walk down the list of active connections to find
* out which connections we should poll over. If a connection
* is no longer in use, we should remove it from the linked
* list. */
c = connection_table_get_first_active_connection (ct);
while (c)
- {
- next = connection_table_get_next_active_connection (ct, c);
- if ( c->c_mutex == NULL )
- {
- connection_table_move_connection_out_of_active_list(ct,c);
- }
- else
- {
- PR_Lock( c->c_mutex );
+ {
+ next = connection_table_get_next_active_connection (ct, c);
+ if ( c->c_mutex == NULL )
+ {
+ connection_table_move_connection_out_of_active_list(ct,c);
+ }
+ else
+ {
+ PR_Lock( c->c_mutex );
if (c->c_flags & CONN_FLAG_CLOSING)
{
- /* A worker thread has marked that this connection
- * should be closed by calling disconnect_server.
+ /* A worker thread has marked that this connection
+ * should be closed by calling disconnect_server.
* move this connection out of the active list
* the last thread to use the connection will close it
- */
+ */
connection_table_move_connection_out_of_active_list(ct,c);
}
else if ( c->c_sd == SLAPD_INVALID_SOCKET )
@@ -1119,18 +1208,18 @@ setup_pr_read_pds(Connection_Table *ct, PRFileDesc *n_tcps, PRFileDesc *s_tcps,
{
ct->fd[count].fd = c->c_prfd;
ct->fd[count].in_flags = SLAPD_POLL_FLAGS;
- /* slot i of the connection table is mapped to slot
- * count of the fds array */
- c->c_fdi = count;
- count++;
+ /* slot i of the connection table is mapped to slot
+ * count of the fds array */
+ c->c_fdi = count;
+ count++;
}
- else
+ else
{
- c->c_fdi = SLAPD_INVALID_SOCKET_INDEX;
- }
+ c->c_fdi = SLAPD_INVALID_SOCKET_INDEX;
+ }
}
PR_Unlock( c->c_mutex );
- }
+ }
c = next;
}
@@ -2021,8 +2110,8 @@ entry_map_free:
slapi_pblock_destroy(search_pb);
slapi_ch_free_string(&filter);
slapi_ch_free_string(&utype);
- slapi_ch_free_string(&gtype);
- slapi_ch_free_string(&base_dn);
+ slapi_ch_free_string(&gtype);
+ slapi_ch_free_string(&base_dn);
}
if(ret && 0 == uid)
@@ -2363,7 +2452,7 @@ static void
unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, int n_tcps, PRFileDesc *s_tcps)
#else
static void
-unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, PRFileDesc *n_tcps, PRFileDesc *s_tcps, PRFileDesc *i_unix)
+unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, PRFileDesc **n_tcps, PRFileDesc **s_tcps, PRFileDesc **i_unix)
#endif
{
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -2407,30 +2496,57 @@ unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, PRFileDesc *n_tcps, P
*/
#if !defined( XP_WIN32 )
if ( n_tcps != NULL ) { /* standard LDAP */
-#else
- if ( n_tcps != SLAPD_INVALID_SOCKET ) { /* standard LDAP */
-#endif
+ PRNetAddr **nap = NULL;
+ int isfirsttime = 1;
+
+ for (nap = ports->n_listenaddr; nap && *nap; nap++) {
+ if (isfirsttime) {
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "slapd started. Listening on %s port %d for LDAP requests\n",
+ netaddr2string(*nap, addrbuf, sizeof(addrbuf)),
+ ports->n_port, 0 );
+ isfirsttime = 0;
+ } else {
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "Listening on %s port %d for LDAP requests\n",
+ netaddr2string(*nap, addrbuf, sizeof(addrbuf)),
+ ports->n_port, 0 );
+ }
+ }
+ }
+
+ if ( s_tcps != NULL ) { /* LDAP over SSL; separate port */
+ PRNetAddr **sap = NULL;
+ for (sap = ports->s_listenaddr; sap && *sap; sap++) {
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "Listening on %s port %d for LDAPS requests\n",
+ netaddr2string(*sap, addrbuf, sizeof(addrbuf)),
+ ports->s_port, 0 );
+ }
+ }
+#else
+ if ( n_tcps != SLAPD_INVALID_SOCKET ) { /* standard LDAP; XP_WIN32 */
LDAPDebug( LDAP_DEBUG_ANY,
- "slapd started. Listening on %s port %d for LDAP requests\n",
+ "slapd started. Listening on %s port %d for LDAP requests\n",
netaddr2string(&ports->n_listenaddr, addrbuf, sizeof(addrbuf)),
ports->n_port, 0 );
}
if ( s_tcps != NULL ) { /* LDAP over SSL; separate port */
LDAPDebug( LDAP_DEBUG_ANY,
- "Listening on %s port %d for LDAPS requests\n",
+ "Listening on %s port %d for LDAPS requests\n",
netaddr2string(&ports->s_listenaddr, addrbuf, sizeof(addrbuf)),
ports->s_port, 0 );
}
+#endif
#if !defined( XP_WIN32 )
#if defined(ENABLE_LDAPI)
if ( i_unix != NULL ) { /* LDAPI */
+ PRNetAddr **iap = ports->i_listenaddr;
LDAPDebug( LDAP_DEBUG_ANY,
- "Listening on %s for LDAPI requests\n",
- ports->i_listenaddr.local.path,
- 0, 0 );
+ "Listening on %s for LDAPI requests\n", (*iap)->local.path, 0, 0 );
}
#endif /* ENABLE_LDAPI */
#endif
@@ -2619,26 +2735,29 @@ createlistensocket(unsigned short port, const PRNetAddr *listenaddr)
return tcps;
failed:
- WSACleanup();
- exit( 1 );
+ WSACleanup();
+ exit( 1 );
suppressed:
- return -1;
+ return -1;
} /* createlistensocket */
#endif /* XP_WIN32 */
-static PRFileDesc *
-createprlistensocket(PRUint16 port, const PRNetAddr *listenaddr,
+static PRFileDesc **
+createprlistensockets(PRUint16 port, PRNetAddr **listenaddr,
int secure, int local)
{
- PRFileDesc *sock;
+ PRFileDesc **sock;
PRNetAddr sa_server;
PRErrorCode prerr = 0;
PRSocketOptionData pr_socketoption;
char addrbuf[ 256 ];
- char *logname = "createprlistensocket";
- int socktype = PR_AF_INET6;
- char *socktype_s = "PR_AF_INET";
+ char *logname = "createprlistensockets";
+ int sockcnt = 0;
+ int socktype;
+ char *socktype_s = NULL;
+ PRNetAddr **lap;
+ int i;
if (!port) goto suppressed;
@@ -2649,61 +2768,79 @@ createprlistensocket(PRUint16 port, const PRNetAddr *listenaddr,
socktype = PR_AF_LOCAL;
socktype_s = "PR_AF_LOCAL";
}
-#endif /* ENABLE_LDAPI */
+#endif
- /* create TCP socket */
- if ((sock = PR_OpenTCPSocket(socktype)) == SLAPD_INVALID_SOCKET) {
- prerr = PR_GetError();
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "PR_OpenTCPSocket(%s) failed: %s error %d (%s)\n",
- socktype_s,
- SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
- goto failed;
+ /* need to know the count */
+ sockcnt = 0;
+ for (lap = listenaddr; lap && *lap; lap++) {
+ sockcnt++;
}
- pr_socketoption.option = PR_SockOpt_Reuseaddr;
- pr_socketoption.value.reuse_addr = 1;
- if ( PR_SetSocketOption(sock, &pr_socketoption ) == PR_FAILURE) {
- prerr = PR_GetError();
+ if (0 == sockcnt) {
slapi_log_error(SLAPI_LOG_FATAL, logname,
- "PR_SetSocketOption(PR_SockOpt_Reuseaddr) failed: %s error %d (%s)\n",
- SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror( prerr ));
+ "There is no address to listen\n");
goto failed;
}
+ sock = (PRFileDesc **)slapi_ch_calloc(sockcnt + 1, sizeof(PRFileDesc *));
+ pr_socketoption.option = PR_SockOpt_Reuseaddr;
+ pr_socketoption.value.reuse_addr = 1;
+ for (i = 0, lap = listenaddr; lap && *lap && i < sockcnt; i++, lap++) {
+ /* create TCP socket */
+ socktype = PR_NetAddrFamily(*lap);
+ if (PR_AF_INET6 == socktype) {
+ socktype_s = "PR_AF_INET6";
+ } else {
+ socktype_s = "PR_AF_INET";
+ }
+ if ((sock[i] = PR_OpenTCPSocket(socktype)) == SLAPD_INVALID_SOCKET) {
+ prerr = PR_GetError();
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "PR_OpenTCPSocket(%s) failed: %s error %d (%s)\n",
+ socktype_s,
+ SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
+ goto failed;
+ }
- /* set up listener address, including port */
- memcpy(&sa_server, listenaddr, sizeof(sa_server));
+ if ( PR_SetSocketOption(sock[i], &pr_socketoption ) == PR_FAILURE) {
+ prerr = PR_GetError();
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "PR_SetSocketOption(PR_SockOpt_Reuseaddr) failed: %s error %d (%s)\n",
+ SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror( prerr ));
+ goto failed;
+ }
- if(!local)
- PRLDAP_SET_PORT( &sa_server, port );
+ /* set up listener address, including port */
+ memcpy(&sa_server, *lap, sizeof(sa_server));
- if ( PR_Bind(sock, &sa_server) == PR_FAILURE) {
- prerr = PR_GetError();
if(!local)
- {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "PR_Bind() on %s port %d failed: %s error %d (%s)\n",
- netaddr2string(&sa_server, addrbuf, sizeof(addrbuf)), port,
- SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
- }
+ PRLDAP_SET_PORT( &sa_server, port );
+
+ if ( PR_Bind(sock[i], &sa_server) == PR_FAILURE) {
+ prerr = PR_GetError();
+ if(!local)
+ {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "PR_Bind() on %s port %d failed: %s error %d (%s)\n",
+ netaddr2string(&sa_server, addrbuf, sizeof(addrbuf)), port,
+ SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
+ }
#if defined(ENABLE_LDAPI)
- else
- {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "PR_Bind() on %s file %s failed: %s error %d (%s)\n",
- netaddr2string(&sa_server, addrbuf, sizeof(addrbuf)),
- sa_server.local.path,
- SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
- }
+ else
+ {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "PR_Bind() on %s file %s failed: %s error %d (%s)\n",
+ netaddr2string(&sa_server, addrbuf, sizeof(addrbuf)),
+ sa_server.local.path,
+ SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
+ }
#endif /* ENABLE_LDAPI */
-
- goto failed;
+ goto failed;
+ }
}
#if defined(ENABLE_LDAPI)
- if(local)
- {
- if(chmod(listenaddr->local.path,
+ if(local) { /* ldapi */
+ if(chmod((*listenaddr)->local.path,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH))
{
slapi_log_error(SLAPI_LOG_FATAL, logname, "err: %d", errno);
@@ -2721,7 +2858,7 @@ failed:
suppressed:
return (PRFileDesc *)-1;
-} /* createprlistensocket */
+} /* createprlistensockets */
/*
@@ -2729,36 +2866,63 @@ suppressed:
* Returns: 0 if successful and -1 if not (after logging an error message).
*/
int
-slapd_listenhost2addr(const char *listenhost, PRNetAddr *addr)
+slapd_listenhost2addr(const char *listenhost, PRNetAddr ***addr)
{
- char *logname = "slapd_listenhost2addr";
- PRErrorCode prerr = 0;
- int rval = 0;
+ char *logname = "slapd_listenhost2addr";
+ PRErrorCode prerr = 0;
+ int rval = 0;
+ PRNetAddr *netaddr = (PRNetAddr *)slapi_ch_calloc(1, sizeof(PRNetAddr));
PR_ASSERT( addr != NULL );
+ *addr = NULL;
if (NULL == listenhost) {
/* listen on all interfaces */
- if ( PR_SUCCESS != PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, addr)) {
+ if ( PR_SUCCESS != PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, netaddr)) {
prerr = PR_GetError();
slapi_log_error( SLAPI_LOG_FATAL, logname,
"PR_SetNetAddr(PR_IpAddrAny) failed - %s error %d (%s)\n",
SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
rval = -1;
+ slapi_ch_free ((void**)&netaddr);
}
- } else if (PR_SUCCESS == PR_StringToNetAddr(listenhost, addr)) {
+ *addr = (PRNetAddr **)slapi_ch_calloc(2, sizeof (PRNetAddr *));
+ *addr[0] = netaddr;
+ } else if (PR_SUCCESS == PR_StringToNetAddr(listenhost, netaddr)) {
/* PR_StringNetAddr newer than NSPR v4.6.2 supports both IPv4&v6 */;
+ *addr = (PRNetAddr **)slapi_ch_calloc(2, sizeof (PRNetAddr *));
+ *addr[0] = netaddr;
} else {
PRAddrInfo *infop = PR_GetAddrInfoByName( listenhost,
PR_AF_UNSPEC, (PR_AI_ADDRCONFIG|PR_AI_NOCANONNAME) );
if ( NULL != infop ) {
- memset( addr, 0, sizeof( PRNetAddr ));
- if ( NULL == PR_EnumerateAddrInfo( NULL, infop, 0, addr )) {
+ void *iter = NULL;
+ int addrcnt = 0;
+ int i = 0;
+ memset( netaddr, 0, sizeof( PRNetAddr ));
+ /* need to count the address, first */
+ while ( (iter = PR_EnumerateAddrInfo( iter, infop, 0, netaddr ))
+ != NULL ) {
+ addrcnt++;
+ }
+ if ( 0 == addrcnt ) {
slapi_log_error( SLAPI_LOG_FATAL, logname,
"PR_EnumerateAddrInfo for %s failed - %s error %d (%s)\n",
listenhost, SLAPI_COMPONENT_NAME_NSPR, prerr,
slapd_pr_strerror(prerr));
rval = -1;
+ } else {
+ *addr = (PRNetAddr **)slapi_ch_calloc(addrcnt + 1, sizeof (PRNetAddr *));
+ iter = NULL; /* from the beginning */
+ memset( netaddr, 0, sizeof( PRNetAddr ));
+ for ( i = 0; i < addrcnt; i++ ) {
+ iter = PR_EnumerateAddrInfo( iter, infop, 0, netaddr );
+ if ( NULL == iter ) {
+ break;
+ }
+ *addr[i] = netaddr;
+ netaddr = (PRNetAddr *)slapi_ch_calloc(1, sizeof(PRNetAddr));
+ }
}
PR_FreeAddrInfo( infop );
} else {
@@ -2915,20 +3079,15 @@ get_configured_connection_table_size()
return size;
}
-
-
-
PRFileDesc * get_ssl_listener_fd()
{
PRFileDesc * listener;
- listener = the_connection_table->fd[FDS_S_TCPS].fd;
+ listener = the_connection_table->fd[the_connection_table->s_tcps].fd;
return listener;
}
-
-
int configure_pr_socket( PRFileDesc **pr_socket, int secure, int local )
{
int ns = 0;
diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h
index a92327c8..7ded15ef 100644
--- a/ldap/servers/slapd/fe.h
+++ b/ldap/servers/slapd/fe.h
@@ -134,6 +134,16 @@ struct connection_table
/* An array of connections, file descriptors, and a mapping between them. */
Connection *c;
struct POLL_STRUCT *fd;
+ int n_tcps; /* standard socket start index in fd */
+ int n_tcpe; /* standard socket last ( +1 ) index in fd */
+ int s_tcps; /* ssl socket start index in fd */
+ int s_tcpe; /* ssl socket last ( +1 ) in fd */
+#ifndef XP_WIN32
+#if defined(ENABLE_LDAPI)
+ int i_unixs; /* unix socket start index in fd */
+ int i_unixe; /* unix socket last ( +1 ) in fd */
+#endif /* ENABLE_LDAPI */
+#endif
PRLock *table_mutex;
};
typedef struct connection_table Connection_Table;
@@ -166,7 +176,7 @@ int signal_listner();
int daemon_pre_setuid_init(daemon_ports_t *ports);
void slapd_daemon( daemon_ports_t *ports );
void daemon_register_connection();
-int slapd_listenhost2addr( const char *listenhost, PRNetAddr *addr );
+int slapd_listenhost2addr( const char *listenhost, PRNetAddr ***addr );
int daemon_register_reslimits( void );
int secure_read_function( int ignore , void *buffer, int count, struct lextiof_socket_private *handle );
int secure_write_function( int ignore, const void *buffer, int count, struct lextiof_socket_private *handle );
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index d735261e..9a5987dc 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -846,13 +846,15 @@ main( int argc, char **argv)
(slapd_exemode == SLAPD_EXEMODE_REFERRAL)) {
ports_info.n_port = (unsigned short)n_port;
if ( slapd_listenhost2addr( config_get_listenhost(),
- &ports_info.n_listenaddr ) != 0 ) {
+ &ports_info.n_listenaddr ) != 0 ||
+ ports_info.n_listenaddr == NULL ) {
return(1);
}
ports_info.s_port = (unsigned short)s_port;
if ( slapd_listenhost2addr( config_get_securelistenhost(),
- &ports_info.s_listenaddr ) != 0 ) {
+ &ports_info.s_listenaddr ) != 0 ||
+ ports_info.s_listenaddr == NULL ) {
return(1);
}
@@ -861,11 +863,13 @@ main( int argc, char **argv)
config_get_ldapi_filename() != 0)
{
i_port = ports_info.i_port = 1; /* flag ldapi as on */
- ports_info.i_listenaddr.local.family = PR_AF_LOCAL;
- PL_strncpyz(ports_info.i_listenaddr.local.path,
+ ports_info.i_listenaddr = (PRNetAddr **)slapi_ch_calloc(2, sizeof(PRNetAddr *));
+ *ports_info.i_listenaddr = (PRNetAddr *)slapi_ch_calloc(1, sizeof(PRNetAddr));
+ (*ports_info.i_listenaddr)->local.family = PR_AF_LOCAL;
+ PL_strncpyz((*ports_info.i_listenaddr)->local.path,
config_get_ldapi_filename(),
- sizeof(ports_info.i_listenaddr.local.path));
- unlink(ports_info.i_listenaddr.local.path);
+ sizeof((*ports_info.i_listenaddr)->local.path));
+ unlink((*ports_info.i_listenaddr)->local.path);
}
#endif /* ENABLE_LDAPI */
@@ -919,10 +923,15 @@ main( int argc, char **argv)
if ((slapd_exemode == SLAPD_EXEMODE_SLAPD) ||
(slapd_exemode == SLAPD_EXEMODE_REFERRAL)) {
- if ( init_ssl && ( 0 != slapd_ssl_init2(&ports_info.s_socket, 0) ) ) {
- LDAPDebug(LDAP_DEBUG_ANY,
+ if ( init_ssl ) {
+ PRFileDesc **sock;
+ for (sock = ports_info.s_socket; sock && *sock; sock++) {
+ if ( 0 != slapd_ssl_init2(sock, 0) ) {
+ LDAPDebug(LDAP_DEBUG_ANY,
"ERROR: SSL Initialization phase 2 Failed.\n", 0, 0, 0 );
- exit( 1 );
+ exit( 1 );
+ }
+ }
}
}
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 1be6c20e..4f9c91ac 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1456,20 +1456,21 @@ typedef struct ref_array {
typedef struct daemon_ports_s {
int n_port;
int s_port;
- PRNetAddr n_listenaddr;
- PRNetAddr s_listenaddr;
+ PRNetAddr **n_listenaddr;
+ PRNetAddr **s_listenaddr;
#if defined( XP_WIN32 )
int n_socket;
int s_socket_native;
#else
- PRFileDesc *n_socket;
+ PRFileDesc **n_socket;
+#if defined(ENABLE_LDAPI)
/* ldapi */
- PRNetAddr i_listenaddr;
+ PRNetAddr **i_listenaddr;
int i_port; /* used as a flag only */
- PRFileDesc *i_socket;
-
+ PRFileDesc **i_socket;
+#endif
#endif
- PRFileDesc *s_socket;
+ PRFileDesc **s_socket;
} daemon_ports_t;