From 48f1ac446b132a3dcc9bdbe58c33ec14b5bae0e5 Mon Sep 17 00:00:00 2001 From: phk Date: Fri, 14 Jul 2006 10:16:27 +0000 Subject: [PATCH] Move session management to new file (cache_session, SES prefix) in preparation of adding client tracking. Move the iovec's from the session to the worker and give the session a pointer to the worker so we can avoid passing it around as argument. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@467 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/Makefile.am | 1 + varnish-cache/bin/varnishd/cache.h | 25 +++++++ varnish-cache/bin/varnishd/cache_acceptor.c | 80 ++++++--------------- varnish-cache/bin/varnishd/cache_center.c | 2 + varnish-cache/bin/varnishd/cache_main.c | 2 + varnish-cache/bin/varnishd/cache_session.c | 80 +++++++++++++++++++++ 6 files changed, 130 insertions(+), 60 deletions(-) create mode 100644 varnish-cache/bin/varnishd/cache_session.c diff --git a/varnish-cache/bin/varnishd/Makefile.am b/varnish-cache/bin/varnishd/Makefile.am index 3e24cc31..489e3fbd 100644 --- a/varnish-cache/bin/varnishd/Makefile.am +++ b/varnish-cache/bin/varnishd/Makefile.am @@ -27,6 +27,7 @@ varnishd_SOURCES = \ cache_pass.c \ cache_pipe.c \ cache_response.c \ + cache_session.c \ cache_vcl.c \ cache_vrt.c \ cli_event.c \ diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 885e222f..44b71fb2 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -4,6 +4,7 @@ #include #include +#include #include #include "queue.h" @@ -13,6 +14,8 @@ #include "vcl_returns.h" #include "common.h" +#define MAX_IOVS 10 + struct event_base; struct cli; struct sbuf; @@ -66,6 +69,10 @@ struct worker { unsigned nbr; pthread_cond_t cv; TAILQ_ENTRY(worker) list; + + struct iovec iov[MAX_IOVS]; + unsigned niov; + size_t liov; }; struct workreq { @@ -147,12 +154,24 @@ struct objhead { TAILQ_HEAD(,object) objects; }; +/* -------------------------------------------------------------------*/ + +struct client { + TAILQ_ENTRY(client) list; + unsigned nsess; + char addr[TCP_ADDRBUFFSIZE]; + uint64_t bytes; +}; + struct sess { int fd; unsigned xid; + struct worker *wrk; + /* formatted ascii client address */ char addr[TCP_ADDRBUFFSIZE]; + struct client *client; /* HTTP request */ struct http *http; @@ -270,6 +289,12 @@ void PipeSession(struct worker *w, struct sess *sp); void WRK_Init(void); 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); + + /* cache_shmlog.c */ void VSL_Init(void); diff --git a/varnish-cache/bin/varnishd/cache_acceptor.c b/varnish-cache/bin/varnishd/cache_acceptor.c index 54695c0d..d7edc8f3 100644 --- a/varnish-cache/bin/varnishd/cache_acceptor.c +++ b/varnish-cache/bin/varnishd/cache_acceptor.c @@ -32,50 +32,9 @@ static struct timeval tick_rate; static pthread_t vca_thread; -#define SESS_IOVS 10 - static struct event accept_e[2 * HERITAGE_NSOCKS]; static TAILQ_HEAD(,sess) sesshead = TAILQ_HEAD_INITIALIZER(sesshead); -struct sessmem { - struct sess sess; - struct iovec iov[SESS_IOVS]; - int niov; - size_t liov; - struct http http; - char *http_hdr; -}; - -/*--------------------------------------------------------------------*/ - -static struct sess * -vca_new_sess(void) -{ - struct sessmem *sm; - - sm = calloc( - sizeof *sm + - heritage.mem_http_headers * sizeof sm->http_hdr + - heritage.mem_http_headerspace + - heritage.mem_workspace, - 1); - if (sm == NULL) - return (NULL); - VSL_stats->n_sess++; - sm->sess.mem = sm; - sm->sess.http = &sm->http; - http_Init(&sm->http, (void *)(sm + 1)); - return (&sm->sess); -} - -static void -vca_delete_sess(const struct sess *sp) -{ - - VSL_stats->n_sess--; - free(sp->mem); -} - /*-------------------------------------------------------------------- * Write data to client @@ -89,13 +48,13 @@ vca_flush(struct sess *sp) { int i; - if (sp->fd < 0 || sp->mem->niov == 0) + if (sp->fd < 0 || sp->wrk->niov == 0) return; - i = writev(sp->fd, sp->mem->iov, sp->mem->niov); - if (i != sp->mem->liov) + i = writev(sp->fd, sp->wrk->iov, sp->wrk->niov); + if (i != sp->wrk->liov) vca_close_session(sp, "remote closed"); - sp->mem->liov = 0; - sp->mem->niov = 0; + sp->wrk->liov = 0; + sp->wrk->niov = 0; } void @@ -104,13 +63,13 @@ vca_write(struct sess *sp, void *ptr, size_t len) if (sp->fd < 0 || len == 0) return; - if (sp->mem->niov == SESS_IOVS) + if (sp->wrk->niov == MAX_IOVS) vca_flush(sp); if (sp->fd < 0) return; - sp->mem->iov[sp->mem->niov].iov_base = ptr; - sp->mem->iov[sp->mem->niov++].iov_len = len; - sp->mem->liov += len; + sp->wrk->iov[sp->wrk->niov].iov_base = ptr; + sp->wrk->iov[sp->wrk->niov++].iov_len = len; + sp->wrk->liov += len; } void @@ -145,9 +104,9 @@ vca_write_obj(struct worker *w, struct sess *sp) continue; } st->stevedore->send(st, sp, - sp->mem->iov, sp->mem->niov, sp->mem->liov); - sp->mem->niov = 0; - sp->mem->liov = 0; + sp->wrk->iov, sp->wrk->niov, sp->wrk->liov); + sp->wrk->niov = 0; + sp->wrk->liov = 0; } assert(u == sp->obj->len); } @@ -221,16 +180,17 @@ accept_f(int fd, short event, void *arg) (void)arg; VSL_stats->client_conn++; - sp = vca_new_sess(); - assert(sp != NULL); /* XXX handle */ - l = sizeof addr; - sp->fd = accept(fd, addr, &l); - if (sp->fd < 0) { - vca_delete_sess(sp); + i = accept(fd, addr, &l); + if (i < 0) { return; } + sp = SES_New(addr, l); + assert(sp != NULL); /* XXX handle */ + + sp->fd = i; + #ifdef SO_NOSIGPIPE /* XXX Linux */ i = 1; AZ(setsockopt(sp->fd, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof i)); @@ -315,7 +275,7 @@ vca_return_session(struct sess *sp) VSL(SLT_SessionReuse, sp->fd, "%s", sp->addr); assert(sizeof sp == write(pipes[1], &sp, sizeof sp)); } else { - vca_delete_sess(sp); + SES_Delete(sp); } } diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index 67f66a9d..adb3bc52 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -521,6 +521,8 @@ CNT_Session(struct worker *w, struct sess *sp) sp->t0 = time(NULL); sp->vcl = VCL_Get(); + sp->wrk = w; + for (sp->step = STP_RECV; sp->step != STP_DONE; ) { switch (sp->step) { #define STEP(l,u) \ diff --git a/varnish-cache/bin/varnishd/cache_main.c b/varnish-cache/bin/varnishd/cache_main.c index 1f6fcb8c..4b97c48a 100644 --- a/varnish-cache/bin/varnishd/cache_main.c +++ b/varnish-cache/bin/varnishd/cache_main.c @@ -105,6 +105,8 @@ child_main(void) VCL_Init(); VCL_Load(heritage.vcl_file, "boot", NULL); + SES_Init(); + VBE_Init(); VSL_Init(); WRK_Init(); diff --git a/varnish-cache/bin/varnishd/cache_session.c b/varnish-cache/bin/varnishd/cache_session.c new file mode 100644 index 00000000..37989ac8 --- /dev/null +++ b/varnish-cache/bin/varnishd/cache_session.c @@ -0,0 +1,80 @@ +/* + * $Id$ + * + * Session and Client management. + * + * The client 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. + */ + +#include +#include + +#include "heritage.h" +#include "cache.h" +#include "shmlog.h" + +#define CLIENT_HASH 256 + +/*--------------------------------------------------------------------*/ + +struct sessmem { + struct sess sess; + struct http http; + char *http_hdr; +}; + +/*--------------------------------------------------------------------*/ + +TAILQ_HEAD(clienthead ,client); + +static struct clienthead client_hash[CLIENT_HASH]; + +/*--------------------------------------------------------------------*/ + +struct sess * +SES_New(struct sockaddr *addr, unsigned len) +{ + struct sessmem *sm; + + (void)addr; /* XXX */ + (void)len; /* XXX */ + sm = calloc( + sizeof *sm + + heritage.mem_http_headers * sizeof sm->http_hdr + + heritage.mem_http_headerspace + + heritage.mem_workspace, + 1); + if (sm == NULL) + return (NULL); + VSL_stats->n_sess++; + sm->sess.mem = sm; + sm->sess.http = &sm->http; + http_Init(&sm->http, (void *)(sm + 1)); + return (&sm->sess); +} + +void +SES_Delete(const struct sess *sp) +{ + + VSL_stats->n_sess--; + free(sp->mem); +} + +/*--------------------------------------------------------------------*/ + +void +SES_Init() +{ + int i; + + for (i = 0; i < CLIENT_HASH; i++) + TAILQ_INIT(&client_hash[i]); +} -- 2.39.5