/* accept a connection on the socket */ static void *acceptconn(void *ctx, void *arg) { nssov_info *ni = arg; Connection conn = {0}; OperationBuffer opbuf; Operation *op; int csock; if ( slapd_shutdown ) return NULL; { struct sockaddr_storage addr; socklen_t alen; int j; /* accept a new connection */ alen=(socklen_t)sizeof(struct sockaddr_storage); csock=accept(ni->ni_socket,(struct sockaddr *)&addr,&alen); connection_client_enable(ni->ni_conn); if (csock<0) { if ((errno==EINTR)||(errno==EAGAIN)||(errno==EWOULDBLOCK)) { Debug( LDAP_DEBUG_TRACE,"nssov: accept() failed (ignored): %s",strerror(errno),0,0); return; } Debug( LDAP_DEBUG_ANY,"nssov: accept() failed: %s",strerror(errno),0,0); return; } /* make sure O_NONBLOCK is not inherited */ if ((j=fcntl(csock,F_GETFL,0))<0) { Debug( LDAP_DEBUG_ANY,"nssov: fcntl(F_GETFL) failed: %s",strerror(errno),0,0); if (close(csock)) Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0); return; } if (fcntl(csock,F_SETFL,j&~O_NONBLOCK)<0) { Debug( LDAP_DEBUG_ANY,"nssov: fcntl(F_SETFL,~O_NONBLOCK) failed: %s",strerror(errno),0,0); if (close(csock)) Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0); return; } } connection_fake_init( &conn, &opbuf, ctx ); op=&opbuf.ob_op; conn.c_ssf = conn.c_transport_ssf = local_ssf; op->o_bd = ni->ni_db; op->o_tag = LDAP_REQ_SEARCH; /* handle the connection */ handleconnection(ni,csock,op); }
static void *worker(void UNUSED(*arg)) { MYLDAP_SESSION *session; int csock; int j; struct sockaddr_storage addr; socklen_t alen; fd_set fds; struct timeval tv; /* create a new LDAP session */ session = myldap_create_session(); /* clean up the session if we're done */ pthread_cleanup_push(worker_cleanup, session); /* start waiting for incoming connections */ while (1) { /* time out connection to LDAP server if needed */ myldap_session_check(session); /* set up the set of fds to wait on */ FD_ZERO(&fds); FD_SET(nslcd_serversocket, &fds); /* set up our timeout value */ tv.tv_sec = nslcd_cfg->idle_timelimit; tv.tv_usec = 0; /* wait for a new connection */ j = select(nslcd_serversocket + 1, &fds, NULL, NULL, nslcd_cfg->idle_timelimit > 0 ? &tv : NULL); /* check result of select() */ if (j < 0) { if (errno == EINTR) log_log(LOG_DEBUG, "select() failed (ignored): %s", strerror(errno)); else log_log(LOG_ERR, "select() failed: %s", strerror(errno)); continue; } /* see if our file descriptor is actually ready */ if (!FD_ISSET(nslcd_serversocket, &fds)) continue; /* wait for a new connection */ alen = (socklen_t)sizeof(struct sockaddr_storage); csock = accept(nslcd_serversocket, (struct sockaddr *)&addr, &alen); if (csock < 0) { if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) log_log(LOG_DEBUG, "accept() failed (ignored): %s", strerror(errno)); else log_log(LOG_ERR, "accept() failed: %s", strerror(errno)); continue; } /* make sure O_NONBLOCK is not inherited */ if ((j = fcntl(csock, F_GETFL, 0)) < 0) { log_log(LOG_ERR, "fctnl(F_GETFL) failed: %s", strerror(errno)); if (close(csock)) log_log(LOG_WARNING, "problem closing socket: %s", strerror(errno)); continue; } if (fcntl(csock, F_SETFL, j & ~O_NONBLOCK) < 0) { log_log(LOG_ERR, "fctnl(F_SETFL,~O_NONBLOCK) failed: %s", strerror(errno)); if (close(csock)) log_log(LOG_WARNING, "problem closing socket: %s", strerror(errno)); continue; } /* indicate new connection to logging module (generates unique id) */ log_newsession(); /* handle the connection */ handleconnection(csock, session); /* indicate end of session in log messages */ log_clearsession(); } pthread_cleanup_pop(1); return NULL; }