Modifications to use the new mmlimitrate(3) API
authorMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 23 Oct 2003 01:01:34 +0000 (01:01 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 23 Oct 2003 01:01:34 +0000 (01:01 +0000)
mmsoftware/install.sh
mmsoftware/mmftpd/install.sh
mmsoftware/mmftpd/src/mmftpd.h
mmsoftware/mmlib/mmserver.c
mmsoftware/mmmail/ChangeLog
mmsoftware/mmmail/install.sh
mmsoftware/mmmail/src/mmsmtpd/mmsmtpd.c
mmsoftware/mmmail/src/mmsmtpd/mmsmtpd.h
mmsoftware/mmstatd/install.sh
mmsoftware/mmstatd/src/mmstatd.c

index f71cf95..410a986 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $Id: install.sh,v 1.8 2003/07/02 17:20:52 mmondor Exp $
+# $Id: install.sh,v 1.9 2003/10/23 01:01:15 mmondor Exp $
 
 if [ "$1" = "help" ]; then
        echo
@@ -117,6 +117,7 @@ instman mmpool.3 3
 instman mmpath.3 3
 instman mmstat.3 3
 instman mmhash.3 3
+instman mmlimitrate.3 3
 cd ../
 cd apache-mmstat/
 instman apache-mmstat.8 8
@@ -192,7 +193,7 @@ echo "mmftpd users: mmftpd(8), mmftpd.conf(5), mmftpdpasswd(5)"
 echo "mmmail users: mmmail(8), mmsmtpd(8), mmsmtpd.conf(5), mmpop3d(8),"
 echo "              mmpop3d.conf(5)"
 echo "source auditors: mmstat(3), mmfd(3), mmlist(3), mmpool(3), mmfifo(3),"
-echo "                 mmlifo(3), mmpath(3), mmhash(3)"
+echo "                 mmlifo(3), mmpath(3), mmhash(3), mmlimitrate(3)"
 echo
 echo "Thank you for using mmsoftware."
 echo
index b6c0543..05dc6e7 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $Id: install.sh,v 1.6 2003/06/18 01:15:20 mmondor Exp $
+# $Id: install.sh,v 1.7 2003/10/23 01:01:20 mmondor Exp $
 
 if [ "$1" = "help" ]; then
        echo
@@ -103,6 +103,7 @@ instman mmpool.3 3
 instman mmpath.3 3
 instman mmstat.3 3
 instman mmhash.3 3
+instman mmlimitrate.3 3
 cd ../
 
 cd mmpasswd/
@@ -147,7 +148,7 @@ echo
 echo "mmstat(8), mmstatd(8), mmstatd.conf(5) mmpasswd(8)"
 echo "mmftpd(8), mmftpd.conf(5), mmftpdpasswd(5)"
 echo "source auditors: mmstat(3), mmfd(3), mmlist(3), mmpool(3), mmfifo(3),"
-echo "                 mmpath(3), mmhash(3)"
+echo "                 mmpath(3), mmhash(3), mmlimitrate(3)"
 echo
 echo "Thank you for using mmsoftware."
 echo
index 17750ba..f3b61e5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmftpd.h,v 1.20 2003/10/11 09:46:01 mmondor Exp $ */
+/* $Id: mmftpd.h,v 1.21 2003/10/23 01:01:22 mmondor Exp $ */
 
 /*
  * Copyright (C) 2000-2003, Matthew Mondor
@@ -263,7 +263,8 @@ struct mutexnode {
     pth_mutex_t mutex;
 };
 
-/* Used to efficiently allocate FIFO buffers */
+/* Used to efficiently allocate FIFO buffers for recently visited directories
+*/
 struct fifonode {
     pnode_t node;
     u_int64_t buf[1];
index 84831b0..b6c252c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmserver.c,v 1.18 2003/10/22 19:32:12 mmondor Exp $ */
+/* $Id: mmserver.c,v 1.19 2003/10/23 01:01:25 mmondor Exp $ */
 
 /*
  * Copyright (C) 2000-2003, Matthew Mondor
@@ -77,7 +77,7 @@
 
 MMCOPYRIGHT("@(#) Copyright (c) 2002-2003\n\
 \tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmserver.c,v 1.18 2003/10/22 19:32:12 mmondor Exp $");
+MMRCSID("$Id: mmserver.c,v 1.19 2003/10/23 01:01:25 mmondor Exp $");
 
 
 
@@ -1279,16 +1279,16 @@ clnode_expire_thread(void *args)
     struct clnode_expire_thread_iterator_udata data;
 
     /* Set initial timeout to maximum allowed */
-    data.soonest = time(NULL) + period;
+    data.soonest = period;
     data.cnt = 0;
     for (;;) {
        /* Sleep until it is known that at least one node expired */
-       pth_sleep(data.soonest - time(NULL));
+       pth_sleep((unsigned int)data.soonest);
        /* Tell our iterator function the current time and the maximum
         * allowed time to wait to
         */
        data.current = time(NULL);
-       data.soonest = data.current + period;
+       data.soonest = period;
        /* Lock ctable, reset expired nodes, garbage collect, and set
         * data.soonest to the time of the soonest next expireing node.
         */
@@ -1312,17 +1312,23 @@ clnode_expire_thread_iterator(hashnode_t *hnod, void *udata)
     time_t rem;
 
     /* If the node expired, reset it. For nodes which do not, record the
-     * soonest to expire node.
+     * soonest to expire node. For nodes which expired and for which no
+     * connections exist anymore, expunge them.
      */
-    if ((rem = LR_REMAINS(&clnode->lr, data->current)) == 0)
-       LR_EXPIRE(&clnode->lr, data->current);
-    if (data->soonest > rem)
-       data->soonest = rem;
-    if (rem == 0 && clnode->connections == 0) {
-       /* Safe to expunge this node from the cache */
-       hashtable_unlink(&ctable, (hashnode_t *)clnode);
-       pool_free((pnode_t *)clnode);
+    if ((rem = LR_REMAINS(&clnode->lr, data->current)) == 0) {
+       /* This entry expired */
+       if (clnode->connections == 0) {
+           /* Safe to expunge this node from the cache */
+           hashtable_unlink(&ctable, (hashnode_t *)clnode);
+           pool_free((pnode_t *)clnode);
+       } else {
+           /* Reset it */
+           LR_EXPIRE(&clnode->lr, data->current);
+           rem = LR_REMAINS(&clnode->lr, data->current);
+       }
     }
+    if (rem != 0 && data->soonest > rem)
+       data->soonest = rem;
 
     /* If the cache is big, prevent from interfering with other threads */
     if ((data->cnt++) == 64) {
index 688cdbc..14bf9cc 100644 (file)
@@ -1,4 +1,4 @@
-$Id: ChangeLog,v 1.31 2003/10/11 11:20:11 mmondor Exp $
+$Id: ChangeLog,v 1.32 2003/10/23 01:01:27 mmondor Exp $
 
 
 
@@ -26,6 +26,9 @@ By     : Matthew Mondor
     speed improvement is always welcome when using userspace threads.
 * Bug fixes
   - mmstatd(8) and the mmstat(3) library had a bugfix.
+  - The message rate sanity checking host-based cache nodes expireing thread
+    would be awakened unnecessarily too fast, considering FLOOD_EXPIRES as a
+    number of seconds rather than as a number of minutes.
 * Other
   - A minor code cleanup was done
 
index 137249c..0cc2b08 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $Id: install.sh,v 1.5 2003/06/18 01:15:20 mmondor Exp $
+# $Id: install.sh,v 1.6 2003/10/23 01:01:27 mmondor Exp $
 
 if [ "$1" = "help" ]; then
        echo
@@ -100,6 +100,7 @@ instman mmlist.3 3
 instman mmpool.3 3
 instman mmstat.3 3
 instman mmhash.3 3
+instman mmlimitrate.3 3
 cd ../
 
 cd mmpasswd/
@@ -150,7 +151,8 @@ echo "*** Please read the following man pages ***"
 echo
 echo "mmstat(8), mmstatd(8), mmstatd.conf(5) mmpasswd(8)"
 echo "mmmail(8), mmsmtpd(8), mmsmtpd.conf(5), mmpop3d(8) mmpop3d.conf(5)"
-echo "source auditors: mmstat(3), mmfd(3), mmlist(3), mmpool(3), mmhash(3)"
+echo "source auditors: mmstat(3), mmfd(3), mmlist(3), mmpool(3), mmhash(3),"
+echo "                 mmlimitrate(3)"
 echo
 echo "Thank you for using mmsoftware."
 echo
index 5e76f79..cf6fe7b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmsmtpd.c,v 1.37 2003/10/11 11:20:23 mmondor Exp $ */
+/* $Id: mmsmtpd.c,v 1.38 2003/10/23 01:01:30 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2003, Matthew Mondor
@@ -69,6 +69,7 @@
 #include <mmstr.h>
 #include <mmstring.h>
 #include <mmstat.h>
+#include <mmlimitrate.h>
 
 #include "mmsmtpd.h"
 
@@ -77,7 +78,7 @@
 
 MMCOPYRIGHT("@(#) Copyright (c) 2002-2003\n\
 \tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmsmtpd.c,v 1.37 2003/10/11 11:20:23 mmondor Exp $");
+MMRCSID("$Id: mmsmtpd.c,v 1.38 2003/10/23 01:01:30 mmondor Exp $");
 
 
 
@@ -779,23 +780,12 @@ all_rcpt(clientenv *clenv)
        pth_mutex_acquire(&hosts_lock, FALSE, NULL);
        /* First acquire our hostnode, or create it if required */
        if ((hnod = (hostnode *)hashtable_lookup(&hosts_table, entry, len + 1))
-               != NULL) {
-           /* Found, check and update limits */
-           hnod->posts++;
-           if (hnod->posts > CONF.FLOOD_MESSAGES) {
-               valid = FALSE;
-               reason = RCPT_FLOOD;
-               mmsyslog(0, LOGLEVEL,
-                       "%08X Considered flood and rejected (%ld message(s) \
-within last %ld minute(s))", clenv->id, hnod->posts,
-                       CONF.FLOOD_EXPIRES);
-           }
-       } else {
+               == NULL) {
            /* Create a new entry */
            if ((hnod = (hostnode *)pool_alloc(&hosts_pool, FALSE)) != NULL) {
                mm_memcpy(hnod->host, entry, len + 1);
-               hnod->expires = time(NULL) + (CONF.FLOOD_EXPIRES * 60);
-               hnod->posts = 1;
+               LR_INIT(&hnod->lr, CONF.FLOOD_MESSAGES,
+                       CONF.FLOOD_EXPIRES * 60, time(NULL));
                hashtable_link(&hosts_table, (hashnode_t *)hnod, entry,
                        len + 1);
            } else {
@@ -804,6 +794,17 @@ within last %ld minute(s))", clenv->id, hnod->posts,
                mmsyslog(0, LOGLEVEL, "FLOOD_CACHE not large enough");
            }
        }
+       if (valid) {
+           /* Check and update limits */
+           if (!lr_allow(&hnod->lr, 1, 0, FALSE)) {
+               valid = FALSE;
+               reason = RCPT_FLOOD;
+               mmsyslog(0, LOGLEVEL,
+                       "%08X Considered flood and rejected (%ld message(s) \
+within last %ld minute(s))", clenv->id, LR_POSTS(&hnod->lr),
+                       CONF.FLOOD_EXPIRES);
+           }
+       }
        pth_mutex_release(&hosts_lock);
 
        if (!valid && CONF.STATFAIL_FLOOD)
@@ -819,7 +820,7 @@ within last %ld minute(s))", clenv->id, hnod->posts,
        pth_mutex_acquire(&rcpt_lock, FALSE, NULL);
        rnode = (rcptnode *)pool_alloc(&rcpt_pool, FALSE);
        pth_mutex_release(&rcpt_lock);
-       if (rnode) {
+       if (rnode != NULL) {
            mm_strcpy(rnode->address, addr);
            mm_strcpy(rnode->foraddress, foraddr);
            rnode->hash = ahash;
@@ -1881,16 +1882,16 @@ hosts_expire_thread(void *args)
     struct hosts_expire_thread_iterator_udata data;
 
     /* Set the initial timeout to the maximum allowed */
-    data.soonest = time(NULL) + CONF.FLOOD_EXPIRES;
+    data.soonest = CONF.FLOOD_EXPIRES * 60;
     data.cnt = 0;
     for (;;) {
        /* Sleep until it is known that at least one node expired */
-       pth_sleep(data.soonest - time(NULL));
+       pth_sleep((unsigned int)data.soonest);
        /* Tell our iterator function the current time and the maximum
         * allowed time to wait to
         */
        data.current = time(NULL);
-       data.soonest = data.current + CONF.FLOOD_EXPIRES;
+       data.soonest = CONF.FLOOD_EXPIRES * 60;
        /* Lock hosts_table, expunge expired nodes and set data.soonest to the
         * time of the soonest next expireing node
         */
@@ -1912,16 +1913,20 @@ hosts_expire_thread_iterator(hashnode_t *hnod, void *udata)
 {
     hostnode *nod = (hostnode *)hnod;
     struct hosts_expire_thread_iterator_udata *data = udata;
+    time_t rem;
 
-    if (nod->expires <= data->current) {
-       /* This entry expired, expunge it */
+    /* If the node expired, free it. For nodes which do not, record the
+     * soonest to expire node.
+     */
+    if ((rem = LR_REMAINS(&nod->lr, data->current)) == 0) {
+       /* Entry expired, free it */
        hashtable_unlink(&hosts_table, (hashnode_t *)nod);
        pool_free((pnode_t *)nod);
     } else {
-       /* We must find and record the soonest expireing node */
-       if (data->soonest > nod->expires)
-           data->soonest = nod->expires;
+       if (data->soonest > rem)
+           data->soonest = rem;
     }
+
     /* If the cache is big, prevent from interfering with other threads */
     if ((data->cnt++) == 64) {
        data->cnt = 0;
index 95c82e2..a373d90 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmsmtpd.h,v 1.18 2003/10/11 11:20:23 mmondor Exp $ */
+/* $Id: mmsmtpd.h,v 1.19 2003/10/23 01:01:30 mmondor Exp $ */
 
 /*
  * Copyright (C) 2000-2003, Matthew Mondor
@@ -54,6 +54,7 @@
 #include <mmserver.h>
 #include <mmfd.h>
 #include <mmstat.h>
+#include <mmlimitrate.h>
 
 
 
@@ -164,9 +165,8 @@ typedef struct rcptnode {
  */
 typedef struct hostnode {
     hashnode_t node;
-    char host[128];            /* Hostname */
-    time_t expires;            /* Time entry will expire */
-    long posts;                        /* How many posts since entry creation */
+    char host[128];            /* Hostname, key */
+    struct limitrate lr;
 } hostnode;
 
 struct hosts_expire_thread_iterator_udata {
index 38f8b02..cd5bc23 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $Id: install.sh,v 1.5 2003/07/02 17:20:57 mmondor Exp $
+# $Id: install.sh,v 1.6 2003/10/23 01:01:32 mmondor Exp $
 
 if [ "$1" = "help" ]; then
        echo
@@ -99,6 +99,10 @@ instbin mmstat 750 $MMADMINGROUP
 instman mmstat.8 8
 instman mmstatd.8 8
 instman mmstatd.conf.5 5
+instman mmlist.3 3
+instman mmpool.3 3
+instman mmhash.3 3
+instman mmlimitrate.3 3
 cd ../etc/
 instconf mmstatd.conf 640 $MMSTATDGROUP
 instdir $MMSTATDIR 750 $MMSTATDUSER $MMSTATDGROUP
@@ -113,7 +117,8 @@ echo
 echo "*** Please read the following man pages ***"
 echo
 echo "mmstat(8), mmstatd(8), mmstatd.conf(5), apache-mmstat(8)"
-echo "source auditors: mmstat(3), mmlist(3), mmpool(3), mmhash(3)"
+echo "source auditors: mmstat(3), mmlist(3), mmpool(3), mmhash(3),"
+echo "                 mmlimitrate(3)"
 echo
 echo "Thank you for using mmsoftware."
 echo
index c0bcb17..fd7635c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmstatd.c,v 1.25 2003/10/10 04:38:53 mmondor Exp $ */
+/* $Id: mmstatd.c,v 1.26 2003/10/23 01:01:34 mmondor Exp $ */
 
 /*
  * Copyright (C) 2002-2003, Matthew Mondor
 #include <mmstatd.h>
 #include <mmreadcfg.h>
 #include <mmlog.h>
+#include <mmlimitrate.h>
 
 
 
 
 MMCOPYRIGHT("@(#) Copyright (c) 2002-2003\n\
 \tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmstatd.c,v 1.25 2003/10/10 04:38:53 mmondor Exp $");
+MMRCSID("$Id: mmstatd.c,v 1.26 2003/10/23 01:01:34 mmondor Exp $");
 
 
 
@@ -1462,21 +1463,22 @@ librarian_init(void *args)
 static void
 librarian_main(int pfd, int ufd, int lfd, long *lognum, off_t *logpos)
 {
-    time_t otim, ttim;
-    long secs, cnt;
+    time_t otim;
     int len;
+    long secs;
     struct log_entry entries[MAX_TRANSACT + 1];
     struct pollfd fds[] = {
        {pfd, POLLIN, 0},
        {ufd, POLLIN, 0},
     };
+    struct limitrate lr;
 
 #ifndef __GLIBC__
     setproctitle("Librarian process");
 #endif
 
-    ttim = time(NULL);
-    secs = cnt = 0;
+    secs = 0;  /* Used to time delay between syncs */
+    LR_INIT(&lr, CONF.STATS_RATE, CONF.STATS_TIME, time(NULL));
     for (;;) {
        otim = time(NULL);
        if (poll(fds, 2, 60000) > 0) {
@@ -1491,7 +1493,6 @@ librarian_main(int pfd, int ufd, int lfd, long *lognum, off_t *logpos)
                socklen_t addrl;
                struct sockaddr addr;
                int sfd;
-               time_t t;
                char key[KEY_SIZE + 1], key2[KEY_SIZE + 1], c;
 
                /* Accept connection and send status report */
@@ -1505,14 +1506,8 @@ librarian_main(int pfd, int ufd, int lfd, long *lognum, off_t *logpos)
                    /* Make sure to drop connection immediately if rate
                     * was exceeded
                     */
-                   if (CONF.STATS_RATE != 0) {
-                       if ((t = time(NULL)) > ttim + CONF.STATS_TIME) {
-                           ttim = t;
-                           cnt = 0;
-                       }
-                   }
-                   if (CONF.STATS_RATE == 0 || cnt < CONF.STATS_RATE) {
-                       cnt++;
+                   if (CONF.STATS_RATE == 0 ||
+                           lr_allow(&lr, 1, time(NULL), TRUE)) {
                        if (pipesend) write(sfd, "+", 1);
                        if (poll(fds2, 1, 250) == 1) {
                            if (fds2[0].revents & POLLIN) {
@@ -1539,7 +1534,8 @@ librarian_main(int pfd, int ufd, int lfd, long *lognum, off_t *logpos)
                                    DPRINTF("librarian_main", "read(%d)", sfd);
                            }
                        }
-                   } else if (pipesend) write(sfd, "-", 1);
+                   } else if (pipesend)
+                       write(sfd, "-", 1);
                    close(sfd);
                }
            }