]> err.no Git - varnish/commitdiff
Change "client" to "srcaddr", it's more descriptive.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 14 Jul 2006 11:20:10 +0000 (11:20 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 14 Jul 2006 11:20:10 +0000 (11:20 +0000)
Add srcaddr management and start charging bytes to the srcaddr.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@469 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_acceptor.c
varnish-cache/bin/varnishd/cache_center.c
varnish-cache/bin/varnishd/cache_pass.c
varnish-cache/bin/varnishd/cache_pipe.c
varnish-cache/bin/varnishd/cache_session.c
varnish-cache/include/shmlog_tags.h
varnish-cache/include/stat_field.h

index 796a4acf0a61fe52c880ca61c6574d27e5a1a792..3f9e90b1a03633f96524d118c0746d455286779d 100644 (file)
@@ -156,11 +156,15 @@ struct objhead {
 
 /* -------------------------------------------------------------------*/
 
-struct client {
-       TAILQ_ENTRY(client)     list;
+struct srcaddr {
+       TAILQ_ENTRY(srcaddr)    list;
        unsigned                nsess;
        char                    addr[TCP_ADDRBUFSIZE];
+       unsigned                sum;
+       time_t                  first;
+       time_t                  ttl;
        uint64_t                bytes;
+       struct srcaddrhead      *sah;
 };
 
 struct sess {
@@ -172,7 +176,7 @@ struct sess {
        /* formatted ascii client address */
        char                    addr[TCP_ADDRBUFSIZE];
        char                    port[TCP_PORTBUFSIZE];
-       struct client           *client;
+       struct srcaddr          *srcaddr;
 
        /* HTTP request */
        struct http             *http;
@@ -293,8 +297,10 @@ void WRK_QueueSession(struct sess *sp);
 /* cache_session.c [SES] */
 void SES_Init(void);
 struct sess *SES_New(struct sockaddr *addr, unsigned len);
-void SES_Delete(const struct sess *sp);
-
+void SES_Delete(struct sess *sp);
+void SES_RefSrcAddr(struct sess *sp);
+void SES_RelSrcAddr(struct sess *sp);
+void SES_ChargeBytes(struct sess *sp, uint64_t bytes);
 
 /* cache_shmlog.c */
 
index 5f0bc5911a7eb6828817af3bddc24b9bc547508a..644446b7d19c3f4ba28f68c52a19c44fa706a8a0 100644 (file)
@@ -79,6 +79,7 @@ vca_write_obj(struct worker *w, struct sess *sp)
        struct storage *st;
        unsigned u = 0;
        char *r;
+       uint64_t bytes = 0;
        
 
        VSL(SLT_Status, sp->fd, "%u", sp->obj->response);
@@ -96,6 +97,7 @@ vca_write_obj(struct worker *w, struct sess *sp)
        sbuf_printf(w->sb, "\r\n");
        sbuf_finish(w->sb);
        vca_write(sp, sbuf_data(w->sb), sbuf_len(w->sb));
+       bytes += sbuf_len(w->sb);
        assert(http_GetReq(sp->http, &r));
        if (!strcmp(r, "GET")) {
                TAILQ_FOREACH(st, &sp->obj->store, list) {
@@ -111,6 +113,7 @@ vca_write_obj(struct worker *w, struct sess *sp)
                }
                assert(u == sp->obj->len);
        }
+       SES_ChargeBytes(sp, bytes + u);
        vca_flush(sp);
 }
 
index adb3bc52f699ab7959c17e450f68fe678fd48550..7480cfea13aada4a17ca43ef04b877fbe21cb068 100644 (file)
@@ -523,6 +523,8 @@ CNT_Session(struct worker *w, struct sess *sp)
 
        sp->wrk = w;
 
+       SES_RefSrcAddr(sp);
+
        for (sp->step = STP_RECV; sp->step != STP_DONE; ) {
                switch (sp->step) {
 #define STEP(l,u) \
index 01b1b62bcfa89cfb0c19399010a10a24807f785a..d3e37e5cfc869cff2b4f8f142030ae127f475fad 100644 (file)
@@ -1,5 +1,7 @@
 /*
  * $Id$
+ *
+ * XXX: charge bytes to srcaddr
  */
 
 #include <stdio.h>
index f28652cad2b4924b2cafc3bb8ae3554b4242a7fb..3bbe51038cb8dd9afc8321f6d51f182c3d2e0784 100644 (file)
@@ -1,5 +1,7 @@
 /*
  * $Id$
+ *
+ * XXX: charge bytes to srcaddr
  */
 
 #include <stdio.h>
index 37989ac8dded51493175d8b85a6918c6696e2507..721e13af6e3c8c858280103017008a4c21f34bf4 100644 (file)
@@ -3,24 +3,26 @@
  *
  * Session and Client management.
  *
- * The client structures are kept around only as a convenience feature to
+ * The srcaddr structures are kept around only as a convenience feature to
  * make it possible to track down offenders and misconfigured caches.
  * As such it is pure overhead and we do not want to spend too much time
  * on maintaining it.
  *
- * We identify clients by their address only and disregard the port number,
- * because the desired level of granularity is "whois is abuse@ or tech-c@
- * in the RIPE database.
+ * We identify srcaddrs instead of full addr+port because the desired level
+ * of granularity is "whois is abuse@ or tech-c@ in the RIPE database.
  */
 
 #include <stdlib.h>
+#include <string.h>
 #include <sys/uio.h>
 
+#include "libvarnish.h"
 #include "heritage.h"
-#include "cache.h"
 #include "shmlog.h"
+#include "cache.h"
 
 #define CLIENT_HASH                    256
+#define CLIENT_TTL                     30
 
 /*--------------------------------------------------------------------*/
 
@@ -32,9 +34,113 @@ struct sessmem {
 
 /*--------------------------------------------------------------------*/
 
-TAILQ_HEAD(clienthead ,client);
+TAILQ_HEAD(srcaddrhead ,srcaddr);
+
+static struct srcaddrhead      srcaddr_hash[CLIENT_HASH];
+static pthread_mutex_t         ses_mtx;
+
+/*--------------------------------------------------------------------
+ * Assign a srcaddr to this session.
+ *
+ * We use a simple hash over the ascii representation of the address
+ * because it is nice and modular.  I'm not sure how much improvement
+ * using the binary address would be anyway.
+ *
+ * Each hash bucket is sorted in least recently used order and if we
+ * need to make a new entry we recycle the first expired entry we find.
+ * If we find more expired entries during our search, we delete them.
+ */
 
-static struct clienthead       client_hash[CLIENT_HASH];
+void
+SES_RefSrcAddr(struct sess *sp)
+{
+       unsigned u, v;
+       char *p;
+       struct srcaddr *c, *c2, *c3;
+       struct srcaddrhead *ch;
+       time_t now;
+
+       for (u = 0, p = sp->addr; *p; p++)
+               u += u + *p;
+       v = u % CLIENT_HASH;
+       ch = &srcaddr_hash[v];
+       now = time(NULL);
+
+       AZ(pthread_mutex_lock(&ses_mtx));
+       c3 = NULL;
+       TAILQ_FOREACH_SAFE(c, ch, list, c2) {
+               if (c->sum == u && !strcmp(c->addr, sp->addr)) {
+                       c->nsess++;
+                       c->ttl = now + CLIENT_TTL;
+                       sp->srcaddr = c;
+                       TAILQ_REMOVE(ch, c, list);
+                       TAILQ_INSERT_TAIL(ch, c, list);
+                       AZ(pthread_mutex_unlock(&ses_mtx));
+                       return;
+               }
+               if (c->nsess > 0 || c->ttl > now)
+                       continue;
+               if (c3 == NULL) {
+                       c3 = c;
+                       continue;
+               }
+               TAILQ_REMOVE(ch, c2, list);
+               free(c2);
+               VSL_stats->n_srcaddr--;
+       }
+       if (c3 == NULL) {
+               c3 = malloc(sizeof *c3);
+               if (c3 != NULL)
+                       VSL_stats->n_srcaddr++;
+       } else
+               TAILQ_REMOVE(ch, c3, list);
+       if (c3 != NULL) {
+               memset(c3, 0, sizeof *c3);
+               strcpy(c3->addr, sp->addr);
+               c3->sum = u;
+               c3->first = now;
+               c3->ttl = now + CLIENT_TTL;
+               c3->nsess = 1;
+               c3->sah = ch;
+               TAILQ_INSERT_TAIL(ch, c3, list);
+       }
+       sp->srcaddr = c3;
+       AZ(pthread_mutex_unlock(&ses_mtx));
+}
+
+void
+SES_ChargeBytes(struct sess *sp, uint64_t bytes)
+{
+       struct srcaddr *sa;
+       time_t now;
+
+       assert(sp->srcaddr != NULL);
+       sa = sp->srcaddr;
+       now = time(NULL);
+       AZ(pthread_mutex_lock(&ses_mtx));
+VSL(SLT_Debug, 0, "%ju", bytes);
+VSL(SLT_Debug, 0, "%ju", sa->bytes);
+       sa->bytes += bytes;
+VSL(SLT_Debug, 0, "%ju", sa->bytes);
+       sa->ttl = now + CLIENT_TTL;
+       TAILQ_REMOVE(sa->sah, sa, list);
+       TAILQ_INSERT_TAIL(sa->sah, sa, list);
+       bytes = sa->bytes;
+       AZ(pthread_mutex_unlock(&ses_mtx));
+       VSL(SLT_SrcAddr, sp->fd, "%s %jd %d",
+           sa->addr, (intmax_t)(bytes), now - sa->first);
+}
+
+void
+SES_RelSrcAddr(struct sess *sp)
+{
+
+       assert(sp->srcaddr != NULL);
+       AZ(pthread_mutex_lock(&ses_mtx));
+       sp->srcaddr->nsess--;
+       sp->srcaddr = NULL;
+       AZ(pthread_mutex_unlock(&ses_mtx));
+}
 
 /*--------------------------------------------------------------------*/
 
@@ -61,10 +167,11 @@ SES_New(struct sockaddr *addr, unsigned len)
 }
 
 void
-SES_Delete(const struct sess *sp)
+SES_Delete(struct sess *sp)
 {
 
        VSL_stats->n_sess--;
+       SES_RelSrcAddr(sp);
        free(sp->mem);
 }
 
@@ -76,5 +183,6 @@ SES_Init()
        int i;
 
        for (i = 0; i < CLIENT_HASH; i++)
-               TAILQ_INIT(&client_hash[i]);
+               TAILQ_INIT(&srcaddr_hash[i]);
+       AZ(pthread_mutex_init(&ses_mtx, NULL));
 }
index 62093488b37f61126036f02f829a46876225d60b..c3d8b828cc7fa05d161535958f56a0489bd4d2ed 100644 (file)
@@ -11,6 +11,7 @@
 SLTM(Debug)
 SLTM(Error)
 SLTM(CLI)
+SLTM(SrcAddr)
 SLTM(SessionOpen)
 SLTM(SessionReuse)
 SLTM(SessionClose)
index df6212529d5de9bbd3945d32ca505e681f0c8d43..77c7b2a87c7fea50962a4997b327b5ab7f9d76e9 100644 (file)
@@ -10,17 +10,18 @@ MAC_STAT(cache_miss,                uint64_t, "u", "Cache misses")
 MAC_STAT(backend_conn,         uint64_t, "u", "Backend connections initiated")
 MAC_STAT(backend_recycle,      uint64_t, "u", "Backend connections recyles")
 
-MAC_STAT(n_sess,               uint64_t, "u", "N struct sess");
-MAC_STAT(n_object,             uint64_t, "u", "N struct object");
-MAC_STAT(n_objecthead,         uint64_t, "u", "N struct objecthead");
-MAC_STAT(n_header,             uint64_t, "u", "N struct header");
-MAC_STAT(n_smf,                        uint64_t, "u", "N struct smf");
-MAC_STAT(n_vbe,                        uint64_t, "u", "N struct vbe");
-MAC_STAT(n_vbe_conn,           uint64_t, "u", "N struct vbe_conn");
-MAC_STAT(n_wrk,                        uint64_t, "u", "N worker threads");
-MAC_STAT(n_wrk_create,         uint64_t, "u", "N worker threads created");
-MAC_STAT(n_wrk_failed,         uint64_t, "u", "N worker threads not created");
-MAC_STAT(n_wrk_short,          uint64_t, "u", "N worker threads shortages");
-MAC_STAT(n_wrk_busy,           uint64_t, "u", "N busy worker threads");
+MAC_STAT(n_srcaddr,            uint64_t, "u", "N struct srcaddr")
+MAC_STAT(n_sess,               uint64_t, "u", "N struct sess")
+MAC_STAT(n_object,             uint64_t, "u", "N struct object")
+MAC_STAT(n_objecthead,         uint64_t, "u", "N struct objecthead")
+MAC_STAT(n_header,             uint64_t, "u", "N struct header")
+MAC_STAT(n_smf,                        uint64_t, "u", "N struct smf")
+MAC_STAT(n_vbe,                        uint64_t, "u", "N struct vbe")
+MAC_STAT(n_vbe_conn,           uint64_t, "u", "N struct vbe_conn")
+MAC_STAT(n_wrk,                        uint64_t, "u", "N worker threads")
+MAC_STAT(n_wrk_create,         uint64_t, "u", "N worker threads created")
+MAC_STAT(n_wrk_failed,         uint64_t, "u", "N worker threads not created")
+MAC_STAT(n_wrk_short,          uint64_t, "u", "N worker threads shortages")
+MAC_STAT(n_wrk_busy,           uint64_t, "u", "N busy worker threads")
 
-MAC_STAT(losthdr,              uint64_t, "u", "HTTP header overflows");
+MAC_STAT(losthdr,              uint64_t, "u", "HTTP header overflows")