On Tue, Jan 01, 2019 at 09:56:42PM +0100, dspam-devel--- via Dspam-devel wrote:
> Hello Edgar,
> 
> 
> I am interested in this patch. Are you able to share this patch?
> 
> -- 
>  Kind Regards from Switzerland,
> 
>  Stevan Baji?
> 
> On 01/01/2019 07:14, Edgar Pettijohn wrote:
> > I have adapted the daemon to use kqueue instead of select. If anyone is 
> > interested in the patch.
> > 
> > Thanks,
> > 
> > Edgar
> 
> 
> 
> _______________________________________________
> Dspam-devel mailing list
> Dspam-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/dspam-devel

I haven't integrated into the build system yet. I'm still on the fence if I'm 
going to use dspam or not. 
So I will probably test it out a bit before putting more effort into it. So 
basically this patch just 
replaces daemon_listen() with a new daemon_listen() and includes the 
sys/event.h header unconditionally.
If it is of interest then I will gladly put forth the additional effort.

Edgar
--- daemon.c    2012-04-11 13:48:33.000000000 -0500
+++ /home/edgar/dspam/dspam-3.10.2/src/daemon.c 2019-01-01 15:55:39.119888537 
-0600
@@ -36,11 +36,13 @@
 
 #define RSET(A)        ( A && !strcmp(A, "RSET") )
 
+#include <err.h>
 #include <string.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <errno.h>
 #include <error.h>
+#include <sys/event.h> /* for kqueue */
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
@@ -86,18 +88,17 @@
  * RETURN VALUES
  *   returns 0 on success
  */
-
 int daemon_listen(DRIVER_CTX *DTX) {
   struct sockaddr_in local_addr, remote_addr;
   THREAD_CTX *TTX = NULL;
-  fd_set master, read_fds;
   pthread_attr_t attr;
-  struct timeval tv;
-  int fdmax, yes = 1;
+  struct timespec to = { 10, 0 };
+  struct kevent ev;
+  int yes = 1;
   int domain = 0;              /* listening on domain socket? */
   int listener;                        /* listener fd */
-  int i;
-  int port = 24, queue = 32;   /* default port and queue size */
+  int port = 2424, queue = 32; /* default port and queue size */
+  int kq, nev;
 
   signal(SIGPIPE, SIG_IGN);
   signal(SIGINT,  process_signal);
@@ -114,9 +115,10 @@
     domain = 1;
 
   /* initialize */
-
-  FD_ZERO(&master);
-  FD_ZERO(&read_fds);
+  if ((kq = kqueue()) == -1) {
+    LOG(LOG_CRIT, ERR_DAEMON_KQ, strerror(errno));
+    return(EFAILURE);
+  }
 
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
@@ -200,16 +202,12 @@
     return(EFAILURE);
   }
 
-  FD_SET(listener, &master);
-  fdmax = listener;
+  EV_SET(&ev, listener, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0);
+  kevent(kq, &ev, 1, NULL, 0, &to); 
 
   /* Process new connections (until death or reload) */
 
   for(;;) {
-    read_fds = master;
-    tv.tv_sec = 2;
-    tv.tv_usec = 0;
-
     if (__daemon_run == 0) {
       close(listener);
 
@@ -219,80 +217,80 @@
       return 0; 
     }
 
-    if (select(fdmax+1, &read_fds, NULL, NULL, &tv)>0) {
-
+    nev = kevent(kq, NULL, 0, &ev, 1, &to);
+    if (nev == -1)
+           err(1, "kevent");
+    if (nev == 0)
+           continue;
+    else {
       /* Process read-ready connections */
-
-      for(i=0;i<=fdmax;i++) {
-        if (FD_ISSET(i, &read_fds)) {
-
-          /* Accept new connections */
-
-          if (i == listener) {
-            int newfd;
-            int addrlen = sizeof(remote_addr);
-
-            if ((newfd = accept(listener, 
-                                (struct sockaddr *)&remote_addr, 
-                                (socklen_t *) &addrlen)) == -1)
-            {
+      if ((int)ev.ident == listener) {
+        /* Accept new connections */
+        int newfd;
+        int addrlen = sizeof(remote_addr);
+
+        if ((newfd = accept(listener, 
+                           (struct sockaddr *)&remote_addr, 
+                           (socklen_t *) &addrlen)) == -1)
+        {
               LOG(LOG_WARNING, ERR_DAEMON_ACCEPT, strerror(errno));
               continue;
 #ifdef DEBUG
-            } else if (!domain) {
-              char buff[32];
-              LOGDEBUG("connection id %d from %s.", newfd, 
+        } else if (!domain) {
+          char buff[32];
+          LOGDEBUG("connection id %d from %s.", newfd, 
 #ifdef HAVE_INET_NTOA_R_2
-                       inet_ntoa_r(remote_addr.sin_addr, buff)
+               inet_ntoa_r(remote_addr.sin_addr, buff)
 #else
-                       inet_ntoa_r(remote_addr.sin_addr, buff, sizeof(buff))
+               inet_ntoa_r(remote_addr.sin_addr, buff, sizeof(buff))
 #endif
-                      );
+                 );
 #endif
-            }
-            fcntl(newfd, F_SETFL, O_RDWR);
-            setsockopt(newfd,SOL_SOCKET,TCP_NODELAY,&yes,sizeof(int));
-
-            /* 
-             * Since processing time varies, each new connection gets its own 
-             * thread, so we create a new thread context and send it on its 
way 
-             *
-             */
+        }
+        fcntl(newfd, F_SETFL, O_RDWR);
+        setsockopt(newfd,SOL_SOCKET,TCP_NODELAY,&yes,sizeof(int));
 
-            TTX = calloc(1, sizeof(THREAD_CTX));
-            if (TTX == NULL) {
-              LOG(LOG_CRIT, ERR_MEM_ALLOC);
-              close(newfd);
-              continue;
-            } else {
-              TTX->sockfd = newfd;
-              TTX->DTX = DTX;
-              memcpy(&TTX->remote_addr, &remote_addr, sizeof(remote_addr));
-
-              increment_thread_count();
-              if (pthread_create(&TTX->thread, 
-                                 &attr, process_connection, (void *) TTX))
-              {
-                decrement_thread_count();
-                LOG(LOG_CRIT, ERR_DAEMON_THREAD, strerror(errno));
-                close(TTX->sockfd);
-                free(TTX);
-                continue;
-              }
-            }
-          } /* if i == listener */
-        } /* if FD_SET else */
-      } /* for(i.. */
-    }  /* if (select)... */
+        /* 
+         * Since processing time varies, each new connection gets its own 
+         * thread, so we create a new thread context and send it on its way 
+         *
+         */
+
+        TTX = calloc(1, sizeof(THREAD_CTX));
+        if (TTX == NULL) {
+          LOG(LOG_CRIT, ERR_MEM_ALLOC);
+          close(newfd);
+          /*continue? we are out of memory only bad things can happen*/
+          __daemon_run = 0;
+         break;
+        } else {
+          TTX->sockfd = newfd;
+          TTX->DTX = DTX;
+          memcpy(&TTX->remote_addr, &remote_addr, sizeof(remote_addr));
+
+          increment_thread_count();
+          if (pthread_create(&TTX->thread, 
+                             &attr, process_connection, (void *) TTX))
+          {
+            decrement_thread_count();
+            LOG(LOG_CRIT, ERR_DAEMON_THREAD, strerror(errno));
+            close(TTX->sockfd);
+           close(TTX->kq);
+            free(TTX);
+            continue;
+          }
+        } /* TTX != NULL */
+      } /* if ev.ident == listener */
+    } /* nev > 0 */
   } /* for(;;) */
 
   /* Shutdown - we should never get here, but who knows */
 
   close(listener);
+  close(kq);
   pthread_attr_destroy(&attr);
   return 0;
 }
-
 /*
  * process_connection(void *ptr)
  *
@@ -314,6 +312,7 @@
   char *server_ident = _ds_read_attribute(agent_config, "ServerIdent");
   THREAD_CTX *TTX = (THREAD_CTX *) ptr;
   AGENT_CTX *ATX = NULL;
+  struct kevent ev;
   char *input, *cmdline = NULL, *token, *ptrptr;
   buffer *message = NULL;
   char *parms=NULL, *p=NULL;
@@ -323,7 +322,8 @@
   char buf[1024];
   int tries = 0;
   int argc = 0;
-  FILE *fd = 0;
+  int nev;
+  FILE *fd = NULL;
 
   if (_ds_read_attribute(agent_config, "ServerMode") &&
       !strcasecmp(_ds_read_attribute(agent_config, "ServerMode"), "standard"))
@@ -336,9 +336,13 @@
   {
     server_mode = SSM_AUTO;
   }
+  /* Initialize this threads kqueue */
+  if ((TTX->kq = kqueue()) == -1) {
+    LOG(LOG_CRIT, ERR_DAEMON_KQ, strerror(errno));
+    goto CLOSE;
+  }
 
   /* Initialize a file descriptor hook for dspam to use as stdout */
-
   fd = fdopen(TTX->sockfd, "w");
   if (!fd) {
     close(TTX->sockfd);
@@ -521,11 +525,15 @@
          
           tries++;
           if (tries>=3) {
-            struct timeval tv;
-            tv.tv_sec = 5;
-            tv.tv_usec = 0;
-            select(0, NULL, NULL, NULL, &tv);
-            goto CLOSE;
+            /* is this some sort of sleep? */
+           EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE|EV_CLEAR, 0, 5000, 0);
+           for (;;) {
+             nev = kevent(TTX->kq, &ev, 1, NULL, 1, NULL);
+             if (nev > 0)
+                goto CLOSE;
+             else
+               continue; /* check for errors ? */
+           }
           }
         }
       }
@@ -850,6 +858,8 @@
     pthread_mutex_unlock(&TTX->DTX->connections[locked]->lock);
   if (fd)
     fclose(fd);
+  if (TTX->kq)
+    close(TTX->kq);
   buffer_destroy(TTX->packet_buffer);
   if (message) 
     buffer_destroy(message);
@@ -1114,41 +1124,45 @@
  */
 
 char *daemon_getline(THREAD_CTX *TTX, int timeout) {
-  struct timeval tv;
+  struct timespec to = { (time_t)timeout, 0 };
+  struct kevent ev;
   char *p, *q, *pop;
   char buf[1024];
   int total_wait = 0;
   long recv_len;
-  fd_set fds;
-  int i;
+  int i, nev;
+
+  EV_SET(&ev, TTX->sockfd, EVFILT_READ, EV_ADD|EV_ENABLE|EV_CLEAR, 0, 0, 0);
+  kevent(TTX->kq, &ev, 1, NULL, 0, &to);
 
   pop = pop_buffer(TTX);
   while(!pop && total_wait<timeout) {
     if (__daemon_run == 0) 
       return NULL;
     total_wait++;
-    tv.tv_sec = 1;
-    tv.tv_usec = 0;
-    FD_ZERO(&fds);
-    FD_SET(TTX->sockfd, &fds);
-    i = select(TTX->sockfd+1, &fds, NULL, NULL, &tv);
-    if (i<=0)
+
+    nev = kevent(TTX->kq, NULL, 0, &ev, 1, &to);
+    if (nev == -1)
+      err(1, "kevent");
+    if (nev == 0)
       continue;
+    else {
+      recv_len = recv(TTX->sockfd, buf, sizeof(buf)-1, 0);
+      buf[recv_len] = 0;
+      if (recv_len == 0)
+        return NULL;
 
-    recv_len = recv(TTX->sockfd, buf, sizeof(buf)-1, 0);
-    buf[recv_len] = 0;
-    if (recv_len == 0)
-      return NULL;
-    for(p=q=buf,i=0;i<recv_len;i++) {
-      if (*q) {
-        *p = *q;
-        p++;
+      for(p=q=buf,i=0;i<recv_len;i++) {
+        if (*q) {
+          *p = *q;
+          p++;
+        }
+        q++;
       }
-      q++;
+      *p = 0;
+      buffer_cat(TTX->packet_buffer, buf);
+      pop = pop_buffer(TTX);
     }
-    *p = 0;
-    buffer_cat(TTX->packet_buffer, buf);
-    pop = pop_buffer(TTX);
   }
 
 #ifdef VERBOSE
--- language.h  2012-04-11 13:48:33.000000000 -0500
+++ /home/edgar/dspam/dspam-3.10.2/src/language.h       2019-01-01 
15:49:00.517519528 -0600
@@ -130,6 +130,7 @@
 #define ERR_DAEMON_THREAD      "Thread creation failed: %s"
 #define ERR_DAEMON_FAIL         "Daemon mode failed to start"
 #define ERR_DAEMON_TERMINATE    "Daemon terminating on signal %d"
+#define ERR_DAEMON_KQ          "Could not create kqueue"
 
 /* LMTP (externally visible) info codes */
 
_______________________________________________
Dspam-devel mailing list
Dspam-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dspam-devel

Reply via email to