]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/daemon.c
Add missing semicolon.
[openldap] / servers / slapd / daemon.c
index be475f30f1da5238ad391e2888f44800086449e3..efa1b38c759e094f6978b8c947017162f3bff2a5 100644 (file)
@@ -26,6 +26,7 @@ ber_socket_t dtblsize;
 
 typedef struct slap_listener {
        char* sl_url;
+       char* sl_name;
 #ifdef HAVE_TLS
        int             sl_is_tls;
 #endif
@@ -33,7 +34,7 @@ typedef struct slap_listener {
        struct sockaddr_in      sl_addr;
 } Listener;
 
-Listener **slap_listeners;
+Listener **slap_listeners = NULL;
 
 #ifdef HAVE_WINSOCK2
 /* in nt_main.c */
@@ -196,7 +197,7 @@ static void slapd_close(ber_socket_t s) {
 
 Listener *
 open_listener(
-       char* url,
+       const char* url,
        int port,
        int tls_port )
 {
@@ -204,6 +205,7 @@ open_listener(
        Listener l;
        Listener *li;
        LDAPURLDesc *lud;
+       char *s;
 
        rc = ldap_url_parse( url, &lud );
 
@@ -228,11 +230,15 @@ open_listener(
        }
 
 #else
+       l.sl_is_tls = lud->lud_ldaps;
+
        if(! lud->lud_port ) {
                lud->lud_port = lud->lud_ldaps ? tls_port : port;
        }
 #endif
 
+       port = lud->lud_port;
+
        (void) memset( (void*) &l.sl_addr, '\0', sizeof(l.sl_addr) );
 
        l.sl_addr.sin_family = AF_INET;
@@ -246,20 +252,12 @@ open_listener(
        } else {
                /* host or address was specified */
 
-               if( isdigit( lud->lud_host[0] ) ) {
 #ifdef HAVE_WINSOCK
-                       if(!(l.sl_addr.sin_addr.S_un.S_addr = inet_addr(lud->lud_host)))
+               if((l.sl_addr.sin_addr.S_un.S_addr = inet_addr(lud->lud_host)) == INADDR_NONE)
 #else
-                       if(!inet_aton(lud->lud_host, &l.sl_addr.sin_addr))
+               if(!inet_aton(lud->lud_host, &l.sl_addr.sin_addr))
 #endif  
-                       {
-                               Debug( LDAP_DEBUG_ANY, "invalid address (%s) in URL: %s",
-                                       lud->lud_host, url, 0);
-                               ldap_free_urldesc( lud );
-                               return NULL;
-                       }
-
-               } else {
+               {
                        struct hostent *he = gethostbyname( lud->lud_host );
                        if( he == NULL ) {
                                Debug( LDAP_DEBUG_ANY, "invalid host (%s) in URL: %s",
@@ -269,16 +267,12 @@ open_listener(
                        }
 
 #ifdef HAVE_WINSOCK
-                       if(!(l.sl_addr.sin_addr.S_un.S_addr = inet_addr(he->h_addr)))
+                       memcpy( &l.sl_addr.sin_addr.S_un.S_addr, he->h_addr,
+                              sizeof( l.sl_addr.sin_addr.S_un.S_addr ) );
 #else
-                       if(!inet_aton(he->h_addr, &l.sl_addr.sin_addr))
+                       memcpy( &l.sl_addr.sin_addr, he->h_addr,
+                              sizeof( l.sl_addr.sin_addr ) );
 #endif  
-                       {
-                               Debug( LDAP_DEBUG_ANY, "%s has invalid address (%s) in URL: %s",
-                                       lud->lud_host, he->h_addr, url );
-                               ldap_free_urldesc( lud );
-                               return NULL;
-                       }
                }
        }
 
@@ -298,7 +292,7 @@ open_listener(
                        WSAGetLastError(),
                WSAGetLastErrorString(), 0 );
 #endif
-               return( AC_SOCKET_INVALID );
+               return NULL;
        }
 
 #ifndef HAVE_WINSOCK
@@ -307,7 +301,7 @@ open_listener(
                        "daemon: listener descriptor %ld is too great %ld\n",
                        (long) l.sl_sd, (long) dtblsize, 0 );
                tcp_close( l.sl_sd );
-               return( AC_SOCKET_INVALID );
+               return NULL;
        }
 #endif
 
@@ -318,7 +312,7 @@ open_listener(
        {
                int err = errno;
                Debug( LDAP_DEBUG_ANY,
-              "slapd(%ld): setsockopt() failed errno %d (%s)\n",
+              "slapd(%ld): setsockopt(SO_REUSEADDR) failed errno %d (%s)\n",
                (long) l.sl_sd, err,
                        err > -1 && err < sys_nerr
                                ? sys_errlist[err] : "unknown" );
@@ -331,7 +325,20 @@ open_listener(
        {
                int err = errno;
                Debug( LDAP_DEBUG_ANY,
-                       "slapd(%ld): setsockopt(KEEPALIVE) failed errno %d (%s)\n",
+                       "slapd(%ld): setsockopt(SO_KEEPALIVE) failed errno %d (%s)\n",
+               (long) l.sl_sd, err,
+                       err > -1 && err < sys_nerr
+                               ? sys_errlist[err] : "unknown" );
+       }
+#endif
+#ifdef TCP_NODELAY
+       tmp = 1;
+       if ( setsockopt( l.sl_sd, IPPROTO_TCP, TCP_NODELAY,
+               (char *)&tmp, sizeof(tmp) ) )
+       {
+               int err = errno;
+               Debug( LDAP_DEBUG_ANY,
+                       "slapd(%ld): setsockopt(TCP_NODELAY) failed errno %d (%s)\n",
                (long) l.sl_sd, err,
                        err > -1 && err < sys_nerr
                                ? sys_errlist[err] : "unknown" );
@@ -345,21 +352,29 @@ open_listener(
                        err > -1 && err < sys_nerr
                                ? sys_errlist[err] : "unknown" );
                tcp_close( l.sl_sd );
-               return AC_SOCKET_INVALID;
+               return NULL;
        }
 
        l.sl_url = ch_strdup( url );
 
+       l.sl_name = ch_malloc( sizeof("IP=255.255.255.255:65336") );
+       s = inet_ntoa( l.sl_addr.sin_addr );
+       sprintf( l.sl_name, "IP=%s:%d",
+               s != NULL ? s : "unknown" , port );
+
        li = ch_malloc( sizeof( Listener ) );
        *li = l;
 
+       Debug( LDAP_DEBUG_TRACE, "daemon: initialized %s\n",
+               l.sl_url, 0, 0 );
+
        return li;
 }
 
 static int sockinit(void);
 static int sockdestroy(void);
 
-slapd_daemon_init(char *urls, int port, int tls_port )
+int slapd_daemon_init(char *urls, int port, int tls_port )
 {
        int i, rc;
        char **u;
@@ -368,6 +383,9 @@ slapd_daemon_init(char *urls, int port, int tls_port )
        assert( tls_port == 0 );
 #endif
 
+       Debug( LDAP_DEBUG_ARGS, "daemon_init: %s (%d/%d)\n",
+               urls ? urls : "<null>", port, tls_port );
+
        if( rc = sockinit() ) {
                return rc;
        }
@@ -390,22 +408,35 @@ slapd_daemon_init(char *urls, int port, int tls_port )
        FD_ZERO( &slap_daemon.sd_writers );
 
        if( urls == NULL ) {
-               urls = ch_strdup("ldap://");
+               urls = "ldap:///";
        }
 
        u = str2charray( urls, " " );
 
-       if( u == NULL ) {
+       if( u == NULL || u[0] == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "daemon_init: no urls (%s) provided.\n",
+                       urls, 0, 0 );
+
                return -1;
        }
 
-       for(i = 0; u[i] == NULL; i++ ) {
-               /* EMPTY */ ;
+       for( i=0; u[i] != NULL; i++ ) {
+               Debug( LDAP_DEBUG_TRACE, "daemon_init: listen on %s\n",
+                       u[i], 0, 0 );
        }
 
+       if( i == 0 ) {
+               Debug( LDAP_DEBUG_ANY, "daemon_init: no listeners to open (%s)\n",
+                       urls, 0, 0 );
+               return -1;
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners to open...\n",
+               i, 0, 0 );
+
        slap_listeners = ch_malloc( (i+1)*sizeof(Listener *) );
 
-       for(i = 0; u[i] == NULL; i++ ) {
+       for(i = 0; u[i] != NULL; i++ ) {
                slap_listeners[i] = open_listener( u[i], port, tls_port );
 
                if( slap_listeners[i] == NULL ) {
@@ -414,12 +445,12 @@ slapd_daemon_init(char *urls, int port, int tls_port )
        }
        slap_listeners[i] = NULL;
 
+       Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners opened.\n",
+               i, 0, 0 );
 
        charray_free( u );
-
        ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex );
-
-       return 0;
+       return !i;
 }
 
 
@@ -488,9 +519,6 @@ slapd_daemon_task(
                struct timeval          zero;
                struct timeval          *tvp;
 
-               char    *client_name;
-               char    *client_addr;
-
                if( global_idletimeout > 0 && difftime(
                        last_idle_check+global_idletimeout/SLAPD_IDLE_CHECK_LIMIT,
                        now ) < 0 )
@@ -607,6 +635,11 @@ slapd_daemon_task(
                        socklen_t len = sizeof(from);
                        long id;
 
+                       char    *dnsname;
+                       char    *peeraddr;
+
+                       char    peername[sizeof("IP=255.255.255.255:65336")];
+
                        if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
                                continue;
 
@@ -652,47 +685,50 @@ slapd_daemon_task(
                                (long) s, 0, 0 );
 
                        len = sizeof(from);
-                       if ( getpeername( s, (struct sockaddr *) &from, &len ) == 0 ) {
-                               client_addr = inet_ntoa( from.sin_addr );
 
-#if defined(SLAPD_RLOOKUPS) || defined(HAVE_TCPD)
-                               hp = gethostbyaddr( (char *)
-                                   &(from.sin_addr.s_addr),
-                                   sizeof(from.sin_addr.s_addr), AF_INET );
+                       if ( getpeername( s, (struct sockaddr *) &from, &len ) != 0 ) {
+                               int err = errno;
+                               Debug( LDAP_DEBUG_ANY,
+                                       "daemon: getpeername( %ld ) failed: errno=%d (%s)\n",
+                                       (long) s, err,
+                                   err >= 0 && err < sys_nerr ?
+                                   sys_errlist[err] : "unknown" );
+                               slapd_close(s);
+                               continue;
+                       }
 
-                               if(hp) {
-                                       char *p;
-                                       client_name = hp->h_name;
+                       peeraddr = inet_ntoa( from.sin_addr );
+                       sprintf( peername, "IP=%s:%d",
+                               peeraddr != NULL ? peeraddr : "unknown",
+                               (unsigned) ntohs( from.sin_port ) );
 
-                                       /* normalize the domain */
-                                       for ( p = client_name; *p; p++ ) {
-                                               *p = TOLOWER( (unsigned char) *p );
-                                       }
+#if defined(SLAPD_RLOOKUPS) || defined(HAVE_TCPD)
+                       hp = gethostbyaddr( (char *)
+                           &(from.sin_addr.s_addr),
+                           sizeof(from.sin_addr.s_addr), AF_INET );
 
-                               } else {
-                                       client_name = NULL;
-                               }
-#else
-                               client_name = NULL;
-#endif
+                       if(hp) {
+                               dnsname = str2lower( hp->h_name );
 
                        } else {
-                               client_name = NULL;;
-                               client_addr = NULL;
+                               dnsname = NULL;
                        }
+#else
+                       dnsname = NULL;
+#endif
 
 #ifdef HAVE_TCPD
-                       if(!hosts_ctl("slapd",
-                               client_name != NULL ? client_name : STRING_UNKNOWN,
-                               client_addr != NULL ? client_addr : STRING_UNKNOWN,
-                               STRING_UNKNOWN))
+                       if( !hosts_ctl("slapd",
+                               dnsname != NULL ? dnsname : STRING_UNKNOWN,
+                               peeraddr != NULL ? peeraddr : STRING_UNKNOWN,
+                               STRING_UNKNOWN ))
                        {
                                /* DENY ACCESS */
                                Statslog( LDAP_DEBUG_ANY,
                                 "fd=%ld connection from %s (%s) denied.\n",
                                        (long) s,
-                                       client_name == NULL ? "unknown" : client_name,
-                                       client_addr == NULL ? "unknown" : client_addr,
+                                       dnsname != NULL ? dnsname : "unknown",
+                                       peeraddr != NULL ? peeraddr : "unknown",
                                  0, 0 );
 
                                slapd_close(s);
@@ -700,7 +736,10 @@ slapd_daemon_task(
                        }
 #endif /* HAVE_TCPD */
 
-                       if( (id = connection_init(s, client_name, client_addr,
+                       if( (id = connection_init(s,
+                               slap_listeners[l]->sl_url,
+                               dnsname, peername,
+                               slap_listeners[l]->sl_name,
 #ifdef HAVE_TLS
                                slap_listeners[l]->sl_is_tls
 #else
@@ -711,8 +750,8 @@ slapd_daemon_task(
                                Debug( LDAP_DEBUG_ANY,
                                        "daemon: connection_init(%ld, %s, %s) failed.\n",
                                        (long) s,
-                                       client_name == NULL ? "unknown" : client_name,
-                                       client_addr == NULL ? "unknown" : client_addr);
+                                       peername,
+                                       slap_listeners[l]->sl_name );
                                slapd_close(s);
                                continue;
                        }
@@ -720,8 +759,8 @@ slapd_daemon_task(
                        Statslog( LDAP_DEBUG_STATS,
                                "daemon: conn=%d fd=%ld connection from %s (%s) accepted.\n",
                                id, (long) s,
-                               client_name == NULL ? "unknown" : client_name,
-                               client_addr == NULL ? "unknown" : client_addr,
+                               peername,
+                               slap_listeners[l]->sl_name,
                                0 );
 
                        slapd_add( s );
@@ -828,7 +867,7 @@ slapd_daemon_task(
 #endif
 
                        for ( l = 0; slap_listeners[l] != NULL; l++ ) {
-                               if ( i == slap_listeners[l]->sl_sd ) {
+                               if ( rd == slap_listeners[l]->sl_sd ) {
                                        is_listener = 1;
                                        break;
                                }
@@ -847,9 +886,7 @@ slapd_daemon_task(
                         * active.
                         */
 
-                       while ( ( rc = connection_read( rd ) ) > 0 )
-                               ;
-                       if ( rc < 0 ) {
+                       if ( connection_read( rd ) < 0 ) {
                                slapd_close( rd );
                        }
                }
@@ -1027,7 +1064,6 @@ slap_set_shutdown( int sig )
                ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
        }
 #else
-       Debug( LDAP_DEBUG_TRACE, "Shutdown %d ordered", sig, 0, 0 );
        /* trying to "hit" the socket seems to always get a */
        /* EWOULDBLOCK error, so just close the listen socket to */
        /* break out of the select since we're shutting down anyway */