From: phk Date: Fri, 14 Jul 2006 11:20:10 +0000 (+0000) Subject: Change "client" to "srcaddr", it's more descriptive. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c3bd6d39dcc0dd98b8b8cc21e5a2b3dda23140ec;p=varnish Change "client" to "srcaddr", it's more descriptive. 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 --- diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 796a4acf..3f9e90b1 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -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 */ diff --git a/varnish-cache/bin/varnishd/cache_acceptor.c b/varnish-cache/bin/varnishd/cache_acceptor.c index 5f0bc591..644446b7 100644 --- a/varnish-cache/bin/varnishd/cache_acceptor.c +++ b/varnish-cache/bin/varnishd/cache_acceptor.c @@ -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); } diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index adb3bc52..7480cfea 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -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) \ diff --git a/varnish-cache/bin/varnishd/cache_pass.c b/varnish-cache/bin/varnishd/cache_pass.c index 01b1b62b..d3e37e5c 100644 --- a/varnish-cache/bin/varnishd/cache_pass.c +++ b/varnish-cache/bin/varnishd/cache_pass.c @@ -1,5 +1,7 @@ /* * $Id$ + * + * XXX: charge bytes to srcaddr */ #include diff --git a/varnish-cache/bin/varnishd/cache_pipe.c b/varnish-cache/bin/varnishd/cache_pipe.c index f28652ca..3bbe5103 100644 --- a/varnish-cache/bin/varnishd/cache_pipe.c +++ b/varnish-cache/bin/varnishd/cache_pipe.c @@ -1,5 +1,7 @@ /* * $Id$ + * + * XXX: charge bytes to srcaddr */ #include diff --git a/varnish-cache/bin/varnishd/cache_session.c b/varnish-cache/bin/varnishd/cache_session.c index 37989ac8..721e13af 100644 --- a/varnish-cache/bin/varnishd/cache_session.c +++ b/varnish-cache/bin/varnishd/cache_session.c @@ -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 +#include #include +#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)); } diff --git a/varnish-cache/include/shmlog_tags.h b/varnish-cache/include/shmlog_tags.h index 62093488..c3d8b828 100644 --- a/varnish-cache/include/shmlog_tags.h +++ b/varnish-cache/include/shmlog_tags.h @@ -11,6 +11,7 @@ SLTM(Debug) SLTM(Error) SLTM(CLI) +SLTM(SrcAddr) SLTM(SessionOpen) SLTM(SessionReuse) SLTM(SessionClose) diff --git a/varnish-cache/include/stat_field.h b/varnish-cache/include/stat_field.h index df621252..77c7b2a8 100644 --- a/varnish-cache/include/stat_field.h +++ b/varnish-cache/include/stat_field.h @@ -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")