From 6d025001dadb2f6f3cb71105aabb766e3af2cb7b Mon Sep 17 00:00:00 2001 From: Stig Venaas Date: Thu, 27 Jun 2002 12:41:09 +0000 Subject: [PATCH] Ignore error if listen on socket bound to 0.0.0.0 fails and already listening on socket bound to :: --- servers/slapd/daemon.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index c34077e224..d60f875f3a 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -1006,9 +1006,9 @@ close_listeners( int l; for ( l = 0; slap_listeners[l] != NULL; l++ ) { - if ( remove ) - slapd_remove( slap_listeners[l]->sl_sd, 0 ); if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) { + if ( remove ) + slapd_remove( slap_listeners[l]->sl_sd, 0 ); #ifdef LDAP_PF_LOCAL if ( slap_listeners[l]->sl_sa.sa_addr.sa_family == AF_LOCAL ) { unlink( slap_listeners[l]->sl_sa.sa_un_addr.sun_path ); @@ -1055,6 +1055,43 @@ slapd_daemon_task( if ( listen( slap_listeners[l]->sl_sd, SLAPD_LISTEN ) == -1 ) { int err = sock_errno(); + +#ifdef LDAP_PF_INET6 + /* If error is EADDRINUSE, we are trying to listen to INADDR_ANY and + * we are already listening to in6addr_any, then we want to ignore + * this and continue. + */ + if ( err == EADDRINUSE ) { + int i; + struct sockaddr_in sa = slap_listeners[l]->sl_sa.sa_in_addr; + struct sockaddr_in6 sa6; + + if ( sa.sin_family == AF_INET && + sa.sin_addr.s_addr == htonl(INADDR_ANY) ) { + for ( i = 0 ; i < l; i++ ) { + sa6 = slap_listeners[i]->sl_sa.sa_in6_addr; + if ( sa6.sin6_family == AF_INET6 && + !memcmp( &sa6.sin6_addr, &in6addr_any, sizeof(struct in6_addr) ) ) + break; + } + + if ( i < l ) { + /* We are already listening to in6addr_any */ +#ifdef NEW_LOGGING + LDAP_LOG(( "connection", LDAP_LEVEL_WARNING, + "slapd_daemon_task: Attempt to listen to 0.0.0.0 failed, already listening on ::, assuming IPv4 included\n" )); +#else + Debug( LDAP_DEBUG_CONNS, + "daemon: Attempt to listen to 0.0.0.0 failed, already listening on ::, assuming IPv4 included\n", + 0, 0, 0 ); +#endif + slapd_close( slap_listeners[l]->sl_sd ); + slap_listeners[l]->sl_sd = AC_SOCKET_INVALID; + continue; + } + } + } +#endif #ifdef NEW_LOGGING LDAP_LOG(( "connection", LDAP_LEVEL_ERR, "slapd_daemon_task: listen( %s, 5 ) failed errno=%d (%s)\n", -- 2.39.5