Commit 93c787c7 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Change "client" to "srcaddr", it's more descriptive.

Add srcaddr management and start charging bytes to the srcaddr.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@469 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 9ecc0302
......@@ -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 */
......
......@@ -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);
}
......
......@@ -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) \
......
/*
* $Id$
*
* XXX: charge bytes to srcaddr
*/
#include <stdio.h>
......
/*
* $Id$
*
* XXX: charge bytes to srcaddr
*/
#include <stdio.h>
......
......@@ -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));
}
......@@ -11,6 +11,7 @@
SLTM(Debug)
SLTM(Error)
SLTM(CLI)
SLTM(SrcAddr)
SLTM(SessionOpen)
SLTM(SessionReuse)
SLTM(SessionClose)
......
......@@ -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")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment