*** empty log message ***
authorMatthew Mondor <mmondor@pulsar-zone.net>
Wed, 22 Oct 2003 19:32:12 +0000 (19:32 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Wed, 22 Oct 2003 19:32:12 +0000 (19:32 +0000)
mmsoftware/mmlib/Makefile
mmsoftware/mmlib/makepart.sh
mmsoftware/mmlib/mmlimitrate.3
mmsoftware/mmlib/mmlimitrate.h
mmsoftware/mmlib/mmserver.c
mmsoftware/mmlib/mmserver.h

index fb7da31..ec24328 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.9 2003/08/03 05:27:03 mmondor Exp $
+# $Id: Makefile,v 1.10 2003/10/22 19:32:12 mmondor Exp $
 
 CC = gcc
 MAKE = make
@@ -15,7 +15,7 @@ MYSQL != $(ECHO) `mysql_config --cflags`
 OPENSSL = -I/usr/pkg/include -I/usr/local/include -I/usr/include
 INCDIR = -I/usr/include -I/usr/local/include -I. $(PTH) $(MYSQL) $(OPENSSL)
 
-OBJS = mmpool.o mmfd.o mmrc4.o mmserver.o mmpath.o mmlog.o mmstr.o mmsql.o mmreadcfg.o mmstring.o mmloadarray.o mmstat.o mmbstring.o mmhash.o mmalarm.o mmheap.o mmrc4util.o
+OBJS = mmpool.o mmfd.o mmrc4.o mmserver.o mmpath.o mmlog.o mmstr.o mmsql.o mmreadcfg.o mmstring.o mmloadarray.o mmstat.o mmbstring.o mmhash.o mmalarm.o mmheap.o mmrc4util.o mmlimitrate.o
 
 CCOBJ = $(CC) $(CFLAGS) -c $(INCDIR)
 
@@ -83,3 +83,6 @@ mmheap.o:
 
 mmrc4util.o:
        $(CCOBJ) mmrc4util.c
+
+mmlimitrate.o:
+       $(CCOBJ) mmlimitrate.c
index fcb2e8a..06e95cf 100755 (executable)
@@ -1,11 +1,11 @@
 #!/bin/sh
-# $Id: makepart.sh,v 1.8 2003/08/03 05:27:03 mmondor Exp $
+# $Id: makepart.sh,v 1.9 2003/10/22 19:32:12 mmondor Exp $
 
 . ./makedefs.sh
 
 OBJS="mmpool.o mmfd.o mmrc4.o mmserver.o mmpath.o mmlog.o mmstr.o \
 mmsql.o mmreadcfg.o mmstring.o mmloadarray.o mmstat.o mmbstring.o mmhash.o \
-mmalarm.o mmheap.o mmrc4util.o"
+mmalarm.o mmheap.o mmrc4util.o mmlimitrate.o"
 
 if [ "$1" = "clean" ]; then
        show $RM $OBJS libmmondor.a
index 9d12cef..6291892 100644 (file)
@@ -1,4 +1,4 @@
-.\" $Id: mmlimitrate.3,v 1.1 2003/10/22 18:17:33 mmondor Exp $
+.\" $Id: mmlimitrate.3,v 1.2 2003/10/22 19:32:12 mmondor Exp $
 .\"
 .\" Copyright (C) 2001-2003, Matthew Mondor
 .\" All rights reserved.
@@ -122,6 +122,11 @@ TRUE is returned on success (the posts were allowed), or FALSE if the maximum
 allowed number of posts within a period is exceeded. Note that unless this
 period is specifically reset, subsequent requests will also be refused with
 FALSE in this case.
+Note that the
+.Fa now
+parameter is ignored if
+.Fa expire
+is FALSE. Otherwise,
 .Fa now
 specifies the current time as returned by
 .Xr time 3 .
index bb57d7c..4e1fa46 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmlimitrate.h,v 1.3 2003/10/22 18:17:33 mmondor Exp $ */
+/* $Id: mmlimitrate.h,v 1.4 2003/10/22 19:32:12 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2003, Matthew Mondor
 
 
 
+#ifndef MMLIMITRATE_H
+#define MMLIMITRATE_H
+
+
+
 #include <sys/types.h>
 
 #include <mmtypes.h>
@@ -48,9 +53,9 @@ struct limitrate {
 
 
 /* Permits to initialize a limitrate structure */
-#define LR_INIT(f, max, secs, now) do { \
+#define LR_INIT(f, rmax, secs, now) do { \
     (f)->posts = 0; \
-    (f)->max = (max); \
+    (f)->max = (rmax); \
     (f)->seconds = (secs); \
     (f)->expires = (now) + (secs); \
 } while (FALSE);
@@ -88,3 +93,7 @@ struct limitrate {
 
 
 bool lr_allow(struct limitrate *, long, time_t, bool);
+
+
+
+#endif
index b72d889..84831b0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmserver.c,v 1.17 2003/10/09 04:43:36 mmondor Exp $ */
+/* $Id: mmserver.c,v 1.18 2003/10/22 19:32:12 mmondor Exp $ */
 
 /*
  * Copyright (C) 2000-2003, Matthew Mondor
@@ -69,6 +69,7 @@
 #include <mmhash.h>
 #include <mmserver.h>
 #include <mmreadcfg.h>
+#include <mmlimitrate.h>
 #include <mmlog.h>
 
 
@@ -76,7 +77,7 @@
 
 MMCOPYRIGHT("@(#) Copyright (c) 2002-2003\n\
 \tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmserver.c,v 1.17 2003/10/09 04:43:36 mmondor Exp $");
+MMRCSID("$Id: mmserver.c,v 1.18 2003/10/22 19:32:12 mmondor Exp $");
 
 
 
@@ -286,9 +287,12 @@ tcp_server(char *message, char *server_names, char *listen_ips, uid_t uid,
            pth_abort(clnode_thread);
            pth_join(clnode_thread, NULL);
        }
-       if (HASHTABLE_VALID(&ctable)) hashtable_destroy(&ctable, FALSE);
-       if (POOL_VALID(&ppool)) pool_destroy(&ppool);
-       if (POOL_VALID(&cpool)) pool_destroy(&cpool);
+       if (HASHTABLE_VALID(&ctable))
+           hashtable_destroy(&ctable, FALSE);
+       if (POOL_VALID(&ppool))
+           pool_destroy(&ppool);
+       if (POOL_VALID(&cpool))
+           pool_destroy(&cpool);
        exit(ret);
     }
 
@@ -319,8 +323,10 @@ tcp_server(char *message, char *server_names, char *listen_ips, uid_t uid,
                                if ((clnode = (clientlistnode *)pool_alloc(
                                                &cpool, FALSE)) != NULL) {
                                    clnode->hostname = NULL;
-                                   clnode->connections = clnode->rate = 0;
-                                   clnode->period = time(NULL) + rateper;
+                                   clnode->connections = 0;
+                                   if (ratemax != 0)
+                                       LR_INIT(&clnode->lr, ratemax,
+                                               (time_t)rateper, time(NULL));
                                    clnode->timeout = (timeout * 1000);
                                    clnode->client = addr;
                                    clnode->resolve = resolve;
@@ -340,10 +346,8 @@ tcp_server(char *message, char *server_names, char *listen_ips, uid_t uid,
                             */
                            if (clnode->connections < maxperip) {
                                if (ratemax != 0) {
-                                   if (clnode->rate < ratemax) {
-                                       clnode->rate++;
-                                       ok = TRUE;
-                                   } else
+                                   if (!(ok = lr_allow(&clnode->lr, 1, 0,
+                                                   FALSE)))
                                        reason = MMS_RATE_EXCEEDED;
                                } else
                                    ok = TRUE;
@@ -628,8 +632,10 @@ phandleclient(void *args)
                /* Lock the mutex for a very short moment */
                pth_mutex_acquire(&ctable_lock, FALSE, NULL);
                /* Verify again for NULL to avoid a potential memory leak */
-               if(clnode->hostname == NULL) clnode->hostname = tmp;
-               else tmp = mmstrfree(tmp);
+               if(clnode->hostname == NULL)
+                   clnode->hostname = tmp;
+               else
+                   tmp = mmstrfree(tmp);
                pth_mutex_release(&ctable_lock);
            }
        }
@@ -653,7 +659,8 @@ phandleclient(void *args)
      * decide if/when to uncache our node.
      */
     pth_mutex_acquire(&ctable_lock, FALSE, NULL);
-    if (clnode->connections > 0) clnode->connections--;
+    if (clnode->connections > 0)
+       clnode->connections--;
     pth_mutex_release(&ctable_lock);
 
     /* kthxbye :) */
@@ -1274,7 +1281,6 @@ clnode_expire_thread(void *args)
     /* Set initial timeout to maximum allowed */
     data.soonest = time(NULL) + period;
     data.cnt = 0;
-    data.period = period;
     for (;;) {
        /* Sleep until it is known that at least one node expired */
        pth_sleep(data.soonest - time(NULL));
@@ -1303,17 +1309,16 @@ clnode_expire_thread_iterator(hashnode_t *hnod, void *udata)
 {
     clientlistnode *clnode = (clientlistnode *)hnod;
     struct clnode_expire_thread_iterator_udata *data = udata;
+    time_t rem;
 
-    if (clnode->period <= data->current) {
-       /* This entry expired, reset it */
-       clnode->period = data->current + data->period;
-       clnode->rate = 0;
-    } else {
-       /* We must find and record the soonest expireing node */
-       if (data->soonest > clnode->period)
-           data->soonest = clnode->period;
-    }
-    if (clnode->connections == 0 && clnode->rate == 0) {
+    /* If the node expired, reset it. For nodes which do not, record the
+     * soonest to expire node.
+     */
+    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);
index 7ed5317..93b555e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmserver.h,v 1.5 2003/06/18 01:15:20 mmondor Exp $ */
+/* $Id: mmserver.h,v 1.6 2003/10/22 19:32:12 mmondor Exp $ */
 
 /*
  * Copyright (C) 2000-2003, Matthew Mondor
@@ -47,6 +47,7 @@
 #include <mmpool.h>
 #include <mmlist.h>
 #include <mmhash.h>
+#include <mmlimitrate.h>
 
 
 
@@ -86,8 +87,8 @@ enum mms {
 typedef struct clientlistnode {
     hashnode_t node;
     char *hostname;
-    long connections, rate;
-    time_t period;
+    long connections;
+    struct limitrate lr;
     int timeout;
     /* Key is ((struct sockaddr_in *)&clnode->client)->sin_addr.s_addr */
     struct sockaddr client;
@@ -97,7 +98,6 @@ typedef struct clientlistnode {
 struct clnode_expire_thread_iterator_udata {
     time_t current, soonest;
     int cnt;
-    long period;
 };
 
 /* This is passed to the client threads, which they return to the pool when