From 002213f9ffe45e3f92398992499d778b7a2d5f17 Mon Sep 17 00:00:00 2001 From: phk Date: Tue, 6 Mar 2007 22:40:06 +0000 Subject: [PATCH] Having thought long and hard about this, commit what I think is the new and simpler flow for version2. Pass is now handled like a miss where the object will not be cached. The main result of this is that we drag the entire object, header and body, from the backend before transmitting it to the client, thus isolating the backend from slow clients. From a software engineering point of view it is a big improvement, because it eliminates the need for all of cache_pass.c and we therefore end up with less HTTP protocol implementations. A side effect of this is that ticket #56 should be fixed now. If the object is pass'ed before vcl_fetch{} that is, in vcl_recv{}, vcl_hit{} or vcl_miss{}, no "pass this" object is inserted in the cache. The confusion between "pass", "insert" and "insert_pass" has been cleaned up, by the removal of the latter. Pipe and Pass calls vcl_pipe{} and vcl_pass{} respectively, before contacting the backend. I havn't quite decided if they should operate on the request header from the client or the one to the backend, or both. One possible use is to inject a "Connection: close" header to limit pipe to one transaction. A new vcl_hash{} has been added, it will allow customization of which fields we hash on, instead of the default "url + Host:" but this is not yet implemented. vcl_fetch{} is now called after both the headers and body have been picked up from the backend. This will allow us to do more comprehensive handling of backend errors later on. A disadvantage to this is that if the object ends up as a "pass this" object in the cache, we could possibly have released any queued requests already after the headers were received. If this is transpires as a real-world problem, we can add a vcl_fetchhdr{} which can do an early release (ie: "pass"). git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1277 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/Makefile.am | 1 - varnish-cache/bin/varnishd/cache.h | 9 +- varnish-cache/bin/varnishd/cache_center.c | 416 +++++++----------- varnish-cache/bin/varnishd/cache_fetch.c | 116 +++-- varnish-cache/bin/varnishd/cache_hash.c | 49 ++- varnish-cache/bin/varnishd/cache_pass.c | 269 ----------- varnish-cache/bin/varnishd/cache_vrt.c | 2 +- varnish-cache/bin/varnishd/mgt_vcc.c | 16 +- varnish-cache/bin/varnishd/steps.h | 2 - varnish-cache/include/vcl.h | 3 + varnish-cache/include/vcl_returns.h | 21 +- varnish-cache/lib/libvcl/vcc_fixed_token.c | 25 +- .../lib/libvcl/vcc_gen_fixed_token.tcl | 11 +- varnish-cache/lib/libvcl/vcc_token_defs.h | 6 +- 14 files changed, 304 insertions(+), 642 deletions(-) delete mode 100644 varnish-cache/bin/varnishd/cache_pass.c diff --git a/varnish-cache/bin/varnishd/Makefile.am b/varnish-cache/bin/varnishd/Makefile.am index 53ca4249..e11bbdc4 100644 --- a/varnish-cache/bin/varnishd/Makefile.am +++ b/varnish-cache/bin/varnishd/Makefile.am @@ -21,7 +21,6 @@ varnishd_SOURCES = \ cache_http.c \ cache_main.c \ cache_pool.c \ - cache_pass.c \ cache_pipe.c \ cache_response.c \ cache_session.c \ diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 112354dd..5090ecd2 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -279,7 +279,6 @@ struct sess { TAILQ_ENTRY(sess) list; - struct vbe_conn *vbc; struct backend *backend; struct object *obj; struct VCL_conf *vcl; @@ -348,10 +347,10 @@ void EXP_Init(void); void EXP_TTLchange(struct object *o); /* cache_fetch.c */ -int FetchBody(struct sess *sp); -int FetchHeaders(struct sess *sp); +int Fetch(struct sess *sp); /* cache_hash.c */ +void HSH_Prealloc(struct sess *sp); struct object *HSH_Lookup(struct sess *sp); void HSH_Unbusy(struct object *o); void HSH_Ref(struct object *o); @@ -390,10 +389,6 @@ void http_DoConnection(struct sess *sp); #include "http_headers.h" #undef HTTPH -/* cache_pass.c */ -int PassSession(struct sess *sp); -void PassBody(struct sess *sp); - /* cache_pipe.c */ void PipeSession(struct sess *sp); diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index 0714599f..2e0107d3 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -44,14 +44,24 @@ /* DOT digraph vcl_center { -DOT page="8.2,11.7" -DOT size="6.3,9.7" -DOT margin="1.0" +xDOT page="8.2,11.5" +DOT size="7.2,10.5" +DOT margin="0.5" +DOT center="1" DOT start [ DOT shape=hexagon -DOT label="Start" +DOT label="Request received" DOT ] -DOT start -> RECV +DOT RECV [shape=plaintext] +DOT PIPE [shape=plaintext] +DOT LOOKUP [shape=plaintext] +DOT HIT [shape=plaintext] +DOT MISS [shape=plaintext] +DOT PASS [shape=plaintext] +DOT FETCH [shape=plaintext] +DOT DELIVER [shape=plaintext] +DOT ERROR [shape=plaintext] +DOT start -> RECV [style=bold,color=green,weight=4] */ #include @@ -71,8 +81,13 @@ DOT start -> RECV static unsigned xids; /*-------------------------------------------------------------------- - * The very first request + * AGAIN + * We come here when we just completed a request and already have + * received (part of) the next one. Instead taking the detour + * around the acceptor and then back to a worker, just stay in this + * worker and do what it takes. */ + static int cnt_again(struct sess *sp) { @@ -101,19 +116,19 @@ cnt_again(struct sess *sp) /*-------------------------------------------------------------------- * We have a refcounted object on the session, now deliver it. * -DOT subgraph cluster_deliver { +DOT subgraph xcluster_deliver { DOT deliver [ DOT shape=ellipse DOT label="Build & send header" DOT ] -DOT DELIVER -> deliver [style=bold] +DOT DELIVER -> deliver [style=bold,color=green,weight=4] DOT deliver2 [ DOT shape=ellipse DOT label="Send object" DOT ] -DOT deliver -> deliver2 [style=bold] +DOT deliver -> deliver2 [style=bold,color=green,weight=4] DOT } -DOT deliver2 -> DONE [style=bold] +DOT deliver2 -> DONE [style=bold,color=green,weight=4] */ static int @@ -154,7 +169,6 @@ cnt_done(struct sess *sp) double dh, dp, da; AZ(sp->obj); - AZ(sp->vbc); sp->backend = NULL; if (sp->vcl != NULL) { if (sp->wrk->vcl != NULL) @@ -211,7 +225,7 @@ cnt_done(struct sess *sp) /*-------------------------------------------------------------------- * Emit an error * -DOT subgraph cluster_error { +DOT subgraph xcluster_error { DOT error [ DOT shape=ellipse DOT label="Issue HTTP error" @@ -237,99 +251,61 @@ cnt_error(struct sess *sp) * We have fetched the headers from the backend, ask the VCL code what * to do next, then head off in that direction. * -DOT subgraph cluster_fetch { +DOT subgraph xcluster_fetch { DOT fetch [ DOT shape=ellipse -DOT label="find obj.ttl\nobj.cacheable" +DOT label="fetch from backend\n(find obj.ttl)" DOT ] -DOT FETCH -> fetch [style=bold] +DOT FETCH -> fetch [style=bold,color=blue,weight=2] DOT vcl_fetch [ DOT shape=box DOT label="vcl_fetch()" DOT ] -DOT fetch -> vcl_fetch [style=bold] -DOT fetch_lookup [ -DOT shape=ellipse -DOT label="obj.cacheable=false\nunbusy obj\ndiscard body\n" -DOT ] -DOT vcl_fetch -> fetch_lookup [label="lookup", style=dotted, weight=0] +DOT fetch -> vcl_fetch [style=bold,color=blue,weight=2] DOT fetch_pass [ DOT shape=ellipse -DOT label="obj.cacheable=false\nunbusy obj" +DOT label="obj.pass=true" DOT ] DOT vcl_fetch -> fetch_pass [label="pass"] -DOT fetch_ipass [ -DOT shape=ellipse -DOT label="obj.cacheable=true\nobj.pass=true\nunbusy obj" -DOT ] -DOT vcl_fetch -> fetch_ipass [label="insert_pass"] -DOT fetch_insert [ -DOT shape=ellipse -DOT label="rcv body\nobj.cacheable=true\nunbusy" -DOT ] -DOT vcl_fetch -> fetch_insert [label="insert", style=bold] -DOT fetch_error [ -DOT shape=ellipse -DOT label="disc body\nobj.cacheable=false\nunbusy" -DOT ] -DOT vcl_fetch -> fetch_error [label="error"] DOT } -DOT fetch_lookup -> LOOKUP [style=dotted, weight=0] -DOT fetch_pass -> PASSBODY -DOT fetch_ipass -> PASSBODY -DOT fetch_insert -> DELIVER [style=bold] -DOT fetch_error -> ERROR +DOT fetch_pass -> DELIVER +DOT vcl_fetch -> DELIVER [label="insert",style=bold,color=blue,weight=2] +DOT vcl_fetch -> errfetch [label="error"] +DOT errfetch [label="ERROR",shape=plaintext] */ static int cnt_fetch(struct sess *sp) { - CHECK_OBJ_NOTNULL(sp->vbc, VBE_CONN_MAGIC); - RFC2616_cache_policy(sp, sp->vbc->http); - - VCL_fetch_method(sp); - if (sp->handling == VCL_RET_LOOKUP) - INCOMPL(); - if (sp->handling == VCL_RET_PASS) { + if (Fetch(sp)) { sp->obj->cacheable = 0; HSH_Unbusy(sp->obj); HSH_Deref(sp->obj); sp->obj = NULL; - sp->step = STP_PASSBODY; - return (0); - } - if (sp->handling == VCL_RET_INSERT_PASS) { - sp->obj->pass = 1; - sp->obj->cacheable = 1; - HSH_Unbusy(sp->obj); - /* Don't HSH_Deref(sp->obj); we need the ref for storage */ - sp->obj = NULL; - sp->step = STP_PASSBODY; - return (0); - } - if (sp->handling == VCL_RET_INSERT) { - if (FetchBody(sp)) { - sp->obj->cacheable = 0; - HSH_Unbusy(sp->obj); - HSH_Deref(sp->obj); - sp->obj = NULL; - RES_Error(sp, 503, NULL); - sp->step = STP_DONE; - return (0); - } - sp->obj->cacheable = 1; - AZ(sp->vbc); - HSH_Ref(sp->obj); /* get another, STP_DELIVER will deref */ - HSH_Unbusy(sp->obj); - sp->wrk->acct.fetch++; - sp->step = STP_DELIVER; + sp->step = STP_DONE; + RES_Error(sp, 503, NULL); return (0); } + + RFC2616_cache_policy(sp, &sp->obj->http); /* XXX -> VCL */ + + VCL_fetch_method(sp); + if (sp->handling == VCL_RET_ERROR) INCOMPL(); - INCOMPL(); + + if (sp->handling == VCL_RET_PASS) + sp->obj->pass = 1; + + sp->obj->cacheable = 1; + HSH_Ref(sp->obj); /* get another, STP_DELIVER will deref */ + if (sp->obj->objhead != NULL) + HSH_Unbusy(sp->obj); + sp->wrk->acct.fetch++; + sp->step = STP_DELIVER; + return (0); } /*-------------------------------------------------------------------- @@ -370,120 +346,96 @@ cnt_first(struct sess *sp) } /*-------------------------------------------------------------------- + * HIT * We had a cache hit. Ask VCL, then march off as instructed. * -DOT subgraph cluster_hit { +DOT subgraph xcluster_hit { DOT hit [ DOT shape=box DOT label="vcl_hit()" DOT ] -DOT HIT -> hit [style=bold] -DOT hit2 [ -DOT shape=diamond -DOT label="obj.pass ?" -DOT ] -DOT hit -> hit2 [label=deliver, style=bold] -DOT hit_lookup [ -DOT shape=ellipse -DOT label="unbusy" -DOT ] -DOT hit -> hit_lookup [label="lookup", style=dotted, weight=0] -DOT hit_error [ -DOT shape=ellipse -DOT label="unbusy" -DOT ] -DOT hit -> hit_error [label="error", weight=0] -DOT hit_pass [ -DOT shape=ellipse -DOT label="unbusy" -DOT ] -DOT hit -> hit_pass [label=pass] -DOT hit2 -> hit_pass +DOT HIT -> hit [style=bold,color=green,weight=4] DOT } -DOT hit_error -> ERROR -DOT hit_pass -> PASS -DOT hit_lookup -> LOOKUP [style=dotted, weight=0] -DOT hit2 -> DELIVER [style=bold] +DOT hit -> err_hit [label="error"] +DOT err_hit [label="ERROR",shape=plaintext] +DOT hit -> PASS [label=pass] +DOT hit -> DELIVER [label="deliver",style=bold,color=green,weight=4] */ static int cnt_hit(struct sess *sp) { - VCL_hit_method(sp); + assert(!sp->obj->pass); - if (sp->handling == VCL_RET_DELIVER && sp->obj->pass) - sp->handling = VCL_RET_PASS; + VCL_hit_method(sp); if (sp->handling == VCL_RET_DELIVER) { sp->step = STP_DELIVER; return (0); } + + /* Drop our object, we won't need it */ + HSH_Deref(sp->obj); + sp->obj = NULL; + if (sp->handling == VCL_RET_PASS) { - HSH_Deref(sp->obj); - sp->obj = NULL; sp->step = STP_PASS; return (0); } if (sp->handling == VCL_RET_ERROR) { - HSH_Deref(sp->obj); - sp->obj = NULL; sp->step = STP_ERROR; return (0); } - if (sp->handling == VCL_RET_LOOKUP) - INCOMPL(); INCOMPL(); } /*-------------------------------------------------------------------- - * Look up request in hash table + * LOOKUP + * Hash things together and look object up in hash-table. * * LOOKUP consists of two substates so that we can reenter if we * encounter a busy object. * -DOT subgraph cluster_lookup { +DOT subgraph xcluster_lookup { +DOT hash [ +DOT shape=box +DOT label="vcl_hash()" +DOT ] DOT lookup [ DOT shape=ellipse -DOT label="find obj in cache" +DOT label="obj in cache ?" DOT ] -DOT LOOKUP -> lookup [style=bold] -DOT lookup3 [ +DOT lookup2 [ DOT shape=ellipse -DOT label="Insert new busy object" +DOT label="obj.pass ?" DOT ] -DOT lookup -> lookup3 [style=bold] +DOT LOOKUP -> hash [style=bold,color=green,weight=4] +DOT hash -> lookup [label="hash",style=bold,color=green,weight=4] +DOT lookup -> lookup2 [label="yes",style=bold,color=green,weight=4] DOT } -DOT lookup -> HIT [label="hit", style=bold] -DOT lookup3 -> MISS [label="miss", style=bold] +DOT lookup2 -> HIT [label="no", style=bold,color=green,weight=4] +DOT lookup2 -> PASS [label="yes"] +DOT lookup -> MISS [label="no",style=bold,color=blue,weight=2] */ static int cnt_lookup(struct sess *sp) -{ - - AZ(sp->obj); - sp->step = STP_LOOKUP2; - return (0); -} - -static int -cnt_lookup2(struct sess *sp) { struct object *o; - /* - * We don't assign to sp->obj directly because it is used - * to cache state when we encounter a busy object. - */ - o = HSH_Lookup(sp); + VCL_hash_method(sp); /* XXX: no-op for now */ - /* If we encountered busy-object, disembark worker thread */ + o = HSH_Lookup(sp); if (o == NULL) { + /* + * We hit a busy object, disembark worker thread and expect + * hash code to restart us, still in STP_LOOKUP, later. + */ WSL(sp->wrk, SLT_Debug, sp->fd, "on waiting list on obj %u", sp->obj->xid); SES_Charge(sp); @@ -499,14 +451,17 @@ cnt_lookup2(struct sess *sp) return (0); } - /* Account separately for pass and cache objects */ if (sp->obj->pass) { VSL_stats->cache_hitpass++; WSL(sp->wrk, SLT_HitPass, sp->fd, "%u", sp->obj->xid); - } else { - VSL_stats->cache_hit++; - WSL(sp->wrk, SLT_Hit, sp->fd, "%u", sp->obj->xid); - } + HSH_Deref(sp->obj); + sp->obj = NULL; + sp->step = STP_PASS; + return (0); + } + + VSL_stats->cache_hit++; + WSL(sp->wrk, SLT_Hit, sp->fd, "%u", sp->obj->xid); sp->step = STP_HIT; return (0); } @@ -515,37 +470,21 @@ cnt_lookup2(struct sess *sp) /*-------------------------------------------------------------------- * We had a miss, ask VCL, proceed as instructed * -DOT subgraph cluster_miss { +DOT subgraph xcluster_miss { DOT miss [ DOT shape=box DOT label="vcl_miss()" DOT ] -DOT MISS -> miss [style=bold] -DOT miss_error [ -DOT shape=ellipse -DOT label="obj.cacheable=false\nunbusy" -DOT ] -DOT miss -> miss_error [label="error"] -DOT miss_pass [ -DOT shape=ellipse -DOT label="obj.cacheable=false\nunbusy" +DOT MISS -> miss [style=bold,color=blue,weight=2] +DOT miss_ins [ +DOT label="insert new object" DOT ] -DOT miss -> miss_pass [label="pass"] -DOT miss_lookup [ -DOT shape=ellipse -DOT label="obj.cacheable=false\nunbusy" -DOT ] -DOT miss -> miss_lookup [label="lookup", style=dotted, weight=0] -DOT miss_fetch [ -DOT shape=ellipse -DOT label="fetch obj headers\nfrom backend" -DOT ] -DOT miss -> miss_fetch [label="fetch", style=bold] +DOT miss -> miss_ins [label="fetch",style=bold,color=blue,weight=2] DOT } -DOT miss_error -> ERROR -DOT miss_pass -> PASS -DOT miss_fetch -> FETCH [style=bold] -DOT miss_lookup -> LOOKUP [style=dotted, weight=0] +DOT miss -> err_miss [label="error"] +DOT err_miss [label="ERROR",shape=plaintext] +DOT miss_ins -> FETCH [style=bold,color=blue,weight=2] +DOT miss -> PASS [label="pass"] DOT */ @@ -570,21 +509,8 @@ cnt_miss(struct sess *sp) sp->step = STP_PASS; return (0); } - if (sp->handling == VCL_RET_LOOKUP) - INCOMPL(); if (sp->handling == VCL_RET_FETCH) { - AZ(sp->vbc); - if (FetchHeaders(sp)) { - sp->obj->cacheable = 0; - HSH_Unbusy(sp->obj); - HSH_Deref(sp->obj); - sp->obj = NULL; - sp->step = STP_DONE; - RES_Error(sp, 503, NULL); - return (0); - } sp->step = STP_FETCH; - AN(sp->vbc); return (0); } INCOMPL(); @@ -595,69 +521,61 @@ cnt_miss(struct sess *sp) * Start pass processing by getting headers from backend, then * continue in passbody. * -DOT subgraph cluster_pass { +DOT subgraph xcluster_pass { DOT pass [ +DOT shape=box +DOT label="vcl_pass()" +DOT ] +DOT pass_do [ DOT shape=ellipse -DOT label="send to bke\nrx bkehdr" +DOT label="create new object\n" DOT ] DOT PASS -> pass +DOT pass -> pass_do [label="pass"] DOT } -DOT pass -> PASSBODY +DOT pass_do -> FETCH +DOT pass -> err_pass [label="error"] +DOT err_pass [label="ERROR",shape=plaintext] */ static int cnt_pass(struct sess *sp) { - AZ(sp->vbc); - if (!PassSession(sp)) { - AN(sp->vbc); - sp->step = STP_PASSBODY; - } else - sp->step = STP_DONE; - return (0); -} - - -/*-------------------------------------------------------------------- - * We get here when we have the backends headers, send them to client - * and pass any body the backend may have on as well. - * -DOT subgraph cluster_passbody { -DOT passbody [ -DOT shape=ellipse -DOT label="send hdrs\npass body\n" -DOT ] -DOT PASSBODY -> passbody -DOT } -DOT passbody -> DONE - */ - -static int -cnt_passbody(struct sess *sp) -{ + AZ(sp->obj); - sp->wrk->acct.pass++; - AN(sp->vbc); - PassBody(sp); - AZ(sp->vbc); - sp->step = STP_DONE; + VCL_pass_method(sp); + if (sp->handling == VCL_RET_ERROR) { + sp->step = STP_ERROR; + return (0); + } + HSH_Prealloc(sp); + sp->obj = sp->wrk->nobj; + sp->wrk->nobj = NULL; + sp->obj->busy = 1; + sp->step = STP_FETCH; return (0); } - /*-------------------------------------------------------------------- * Ship the request header to the backend unchanged, then pipe * until one of the ends close the connection. * -DOT subgraph cluster_pipe { +DOT subgraph xcluster_pipe { DOT pipe [ +DOT shape=box +DOT label="vcl_pipe()" +DOT ] +DOT pipe_do [ DOT shape=ellipse DOT label="build&send hdr\npipe until close" DOT ] DOT PIPE -> pipe +DOT pipe -> pipe_do [label="pipe"] DOT } -DOT pipe -> DONE +DOT pipe_do -> DONE +DOT pipe -> err_pipe [label="error"] +DOT err_pipe [label="ERROR",shape=plaintext] */ static int @@ -672,29 +590,22 @@ cnt_pipe(struct sess *sp) /*-------------------------------------------------------------------- - * Dispatch the request as instructed by VCL + * RECV + * We have a complete request, get a VCL reference and dispatch it + * as instructed by vcl_recv{} * -DOT subgraph cluster_recv { +DOT subgraph xcluster_recv { DOT recv [ DOT shape=box DOT label="vcl_recv()" DOT ] -DOT RECV -> recv -DOT recv_lookup [ -DOT shape=ellipse -DOT label="discard any body" -DOT ] -DOT recv -> recv_lookup [label="lookup"] -DOT recv_error [ -DOT shape=ellipse -DOT label="discard any body" -DOT ] -DOT recv -> recv_error [label="error"] +DOT RECV -> recv [style=bold,color=green,weight=4] DOT } DOT recv -> PIPE [label="pipe"] DOT recv -> PASS [label="pass"] -DOT recv_lookup -> LOOKUP -DOT recv_error -> ERROR +DOT recv -> err_recv [label="error"] +DOT err_recv [label="ERROR",shape=plaintext] +DOT recv -> LOOKUP [label="lookup",style=bold,color=green,weight=4] */ static int @@ -702,43 +613,45 @@ cnt_recv(struct sess *sp) { int done; - VSL_stats->client_req++; + AZ(sp->vcl); + AZ(sp->obj); + + /* Update stats of various sorts */ + VSL_stats->client_req++; /* XXX not locked */ clock_gettime(CLOCK_REALTIME, &sp->t_req); sp->wrk->idle = sp->t_req.tv_sec; - sp->xid = ++xids; + sp->wrk->acct.req++; + + /* Assign XID and log */ + sp->xid = ++xids; /* XXX not locked */ WSL(sp->wrk, SLT_ReqStart, sp->fd, "%s %s %u", sp->addr, sp->port, sp->xid); - AZ(sp->vcl); + /* Borrow VCL reference from worker thread */ VCL_Refresh(&sp->wrk->vcl); sp->vcl = sp->wrk->vcl; sp->wrk->vcl = NULL; - AZ(sp->obj); - AZ(sp->vbc); - - sp->wrk->acct.req++; done = http_DissectRequest(sp->wrk, sp->http, sp->fd); if (done != 0) { - RES_Error(sp, done, NULL); + RES_Error(sp, done, NULL); /* XXX: STP_ERROR ? */ sp->step = STP_DONE; return (0); } http_DoConnection(sp); + /* By default we use the first backend */ sp->backend = sp->vcl->backend[0]; /* XXX: Handle TRACE & OPTIONS of Max-Forwards = 0 */ - /* XXX: determine if request comes with body */ - VCL_recv_method(sp); + sp->wantbody = !strcmp(sp->http->hd[HTTP_HDR_REQ].b, "GET"); switch(sp->handling) { case VCL_RET_LOOKUP: /* XXX: discard req body, if any */ - sp->wantbody = !strcmp(sp->http->hd[HTTP_HDR_REQ].b, "GET"); sp->step = STP_LOOKUP; return (0); case VCL_RET_PIPE: @@ -760,8 +673,7 @@ cnt_recv(struct sess *sp) /*-------------------------------------------------------------------- * Central state engine dispatcher. * - * We grab a VCL reference, and keeps kicking the session around until - * it has had enough. + * Kick the session around until it has had enough. * */ @@ -776,6 +688,10 @@ CNT_Session(struct sess *sp) CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); for (done = 0; !done; ) { + /* + * This is a good place to be paranoid about the various + * pointers still pointing to the things we expect. + */ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); if (sp->obj != NULL) CHECK_OBJ(sp->obj, OBJECT_MAGIC); @@ -784,11 +700,9 @@ CNT_Session(struct sess *sp) CHECK_OBJ(w->nobj, OBJECT_MAGIC); if (w->nobjhead != NULL) CHECK_OBJ(w->nobjhead, OBJHEAD_MAGIC); + switch (sp->step) { -#define STEP(l,u) \ - case STP_##u: \ - done = cnt_##l(sp); \ - break; +#define STEP(l,u) case STP_##u: done = cnt_##l(sp); break; #include "steps.h" #undef STEP default: INCOMPL(); diff --git a/varnish-cache/bin/varnishd/cache_fetch.c b/varnish-cache/bin/varnishd/cache_fetch.c index 1a96b31a..15d913e3 100644 --- a/varnish-cache/bin/varnishd/cache_fetch.c +++ b/varnish-cache/bin/varnishd/cache_fetch.c @@ -243,11 +243,12 @@ fetch_eof(const struct sess *sp, int fd, struct http *hp) /*--------------------------------------------------------------------*/ int -FetchBody(struct sess *sp) +Fetch(struct sess *sp) { - int cls; struct vbe_conn *vc; + struct worker *w; char *b; + int cls; int body = 1; /* XXX */ struct http *hp; struct storage *st; @@ -256,9 +257,53 @@ FetchBody(struct sess *sp) CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); assert(sp->obj->busy != 0); + w = sp->wrk; + + sp->obj->xid = sp->xid; + + vc = VBE_GetFd(sp); + if (vc == NULL) + return (1); + + http_ClrHeader(vc->http); + vc->http->logtag = HTTP_Tx; + http_GetReq(w, vc->fd, vc->http, sp->http); + http_FilterHeader(w, vc->fd, vc->http, sp->http, HTTPH_R_FETCH); + http_PrintfHeader(w, vc->fd, vc->http, "X-Varnish: %u", sp->xid); + http_PrintfHeader(w, vc->fd, vc->http, + "X-Forwarded-for: %s", sp->addr); + if (!http_GetHdr(vc->http, H_Host, &b)) { + http_PrintfHeader(w, vc->fd, vc->http, "Host: %s", + sp->backend->hostname); + } - vc = sp->vbc; - sp->vbc = NULL; + WRK_Reset(w, &vc->fd); + http_Write(w, vc->http, 0); + if (WRK_Flush(w)) { + /* XXX: cleanup */ + return (1); + } + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); + + if (http_RecvHead(vc->http, vc->fd)) { + /* XXX: cleanup */ + return (1); + } + if (http_DissectResponse(sp->wrk, vc->http, vc->fd)) { + /* XXX: cleanup */ + return (1); + } + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); + + sp->obj->entered = time(NULL); + + + assert(sp->obj->busy != 0); if (http_GetHdr(vc->http, H_Last_Modified, &b)) sp->obj->last_modified = TIM_parse(b); @@ -314,66 +359,3 @@ FetchBody(struct sess *sp) return (0); } - -/*--------------------------------------------------------------------*/ - -int -FetchHeaders(struct sess *sp) -{ - struct vbe_conn *vc; - struct worker *w; - char *b; - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); - assert(sp->obj->busy != 0); - w = sp->wrk; - - sp->obj->xid = sp->xid; - - vc = VBE_GetFd(sp); - if (vc == NULL) - return (1); - - http_ClrHeader(vc->http); - vc->http->logtag = HTTP_Tx; - http_GetReq(w, vc->fd, vc->http, sp->http); - http_FilterHeader(w, vc->fd, vc->http, sp->http, HTTPH_R_FETCH); - http_PrintfHeader(w, vc->fd, vc->http, "X-Varnish: %u", sp->xid); - http_PrintfHeader(w, vc->fd, vc->http, - "X-Forwarded-for: %s", sp->addr); - if (!http_GetHdr(vc->http, H_Host, &b)) { - http_PrintfHeader(w, vc->fd, vc->http, "Host: %s", - sp->backend->hostname); - } - - WRK_Reset(w, &vc->fd); - http_Write(w, vc->http, 0); - if (WRK_Flush(w)) { - /* XXX: cleanup */ - return (1); - } - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); - - if (http_RecvHead(vc->http, vc->fd)) { - /* XXX: cleanup */ - return (1); - } - if (http_DissectResponse(sp->wrk, vc->http, vc->fd)) { - /* XXX: cleanup */ - return (1); - } - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); - AZ(sp->vbc); - sp->vbc = vc; - - sp->obj->entered = time(NULL); - - return (0); -} diff --git a/varnish-cache/bin/varnishd/cache_hash.c b/varnish-cache/bin/varnishd/cache_hash.c index 711a878a..d1947462 100644 --- a/varnish-cache/bin/varnishd/cache_hash.c +++ b/varnish-cache/bin/varnishd/cache_hash.c @@ -64,23 +64,15 @@ static struct hash_slinger *hash; -struct object * -HSH_Lookup(struct sess *sp) +/* Precreate an objhead and object for later use */ +void +HSH_Prealloc(struct sess *sp) { struct worker *w; - struct http *h; - struct objhead *oh; - struct object *o; - char *url, *host; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(sp->http, HTTP_MAGIC); - AN(hash); w = sp->wrk; - h = sp->http; - /* Precreate an objhead and object in case we need them */ if (w->nobjhead == NULL) { w->nobjhead = calloc(sizeof *w->nobjhead, 1); XXXAN(w->nobjhead); @@ -102,7 +94,25 @@ HSH_Lookup(struct sess *sp) VSL_stats->n_object++; } else CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC); +} + +struct object * +HSH_Lookup(struct sess *sp) +{ + struct worker *w; + struct http *h; + struct objhead *oh; + struct object *o; + char *url, *host; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(sp->http, HTTP_MAGIC); + AN(hash); + w = sp->wrk; + h = sp->http; + HSH_Prealloc(sp); url = h->hd[HTTP_HDR_URL].b; if (!http_GetHdr(h, H_Host, &host)) host = url; @@ -189,11 +199,14 @@ HSH_Ref(struct object *o) CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); oh = o->objhead; - CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); - LOCK(&oh->mtx); + if (oh != NULL) { + CHECK_OBJ(oh, OBJHEAD_MAGIC); + LOCK(&oh->mtx); + } assert(o->refcnt > 0); o->refcnt++; - UNLOCK(&oh->mtx); + if (oh != NULL) + UNLOCK(&oh->mtx); } void @@ -205,7 +218,13 @@ HSH_Deref(struct object *o) CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); oh = o->objhead; - CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); + if (oh == NULL) { + /* Pass object, not referenced anywhere */ + free(o); + return; + } + + CHECK_OBJ(oh, OBJHEAD_MAGIC); /* drop ref on object */ LOCK(&oh->mtx); diff --git a/varnish-cache/bin/varnishd/cache_pass.c b/varnish-cache/bin/varnishd/cache_pass.c deleted file mode 100644 index a7293b7f..00000000 --- a/varnish-cache/bin/varnishd/cache_pass.c +++ /dev/null @@ -1,269 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006 Linpro AS - * All rights reserved. - * - * Author: Poul-Henning Kamp - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id$ - * - * XXX: charge bytes to srcaddr - * XXX: buffer to relieve backed ASAP. - * XXX: Check if response has any body - * XXX: Don't pass chunked to HTTP/1.0 client - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef HAVE_CLOCK_GETTIME -#include "compat/clock_gettime.h" -#endif - -#include "shmlog.h" -#include "cache.h" - -#define PASS_BUFSIZ 8192 - -/*--------------------------------------------------------------------*/ - -static int -pass_straight(struct sess *sp, int fd, struct http *hp, char *bi) -{ - int i; - off_t cl; - unsigned c; - char buf[PASS_BUFSIZ]; - - if (bi != NULL) - cl = strtoumax(bi, NULL, 0); - else - cl = (1 << 30); - - i = fcntl(fd, F_GETFL); /* XXX ? */ - i &= ~O_NONBLOCK; - i = fcntl(fd, F_SETFL, i); - - while (cl != 0) { - c = cl; - if (c > sizeof buf) - c = sizeof buf; - i = http_Read(hp, fd, buf, c); - if (i == 0 && bi == NULL) - return (1); - if (i <= 0) { - vca_close_session(sp, "backend closed"); - return (1); - } - sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, buf, i); - if (WRK_Flush(sp->wrk)) - vca_close_session(sp, "remote closed"); - cl -= i; - } - return (0); -} - - -/*--------------------------------------------------------------------*/ - -static int -pass_chunked(struct sess *sp, int fd, struct http *hp) -{ - int i, j; - char *p, *q; - unsigned u; - char buf[PASS_BUFSIZ]; - char *bp, *be; - - i = fcntl(fd, F_GETFL); /* XXX ? */ - i &= ~O_NONBLOCK; - i = fcntl(fd, F_SETFL, i); - - bp = buf; - be = buf + sizeof buf; - p = buf; - while (1) { - i = http_Read(hp, fd, bp, be - bp); - xxxassert(i >= 0); - if (i == 0 && p == bp) - break; - bp += i; - /* buffer valid from p to bp */ - assert(bp >= p); - - /* chunk starts with f("%x\r\n", len) */ - u = strtoul(p, &q, 16); - while (q && q < bp && *q == ' ') - /* shouldn't happen - but sometimes it does */ - q++; - if (q == NULL || q > bp - 2 /* want \r\n in same buffer */) { - /* short - move to start of buffer and extend */ - memmove(buf, p, bp - p); - bp -= p - buf; - p = buf; - continue; - } - assert(*q == '\r'); - q++; - assert(*q == '\n'); - q++; - - /* we just received the final zero-length chunk */ - if (u == 0) { - sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, p, q - p); - break; - } - - /* include chunk header */ - u += q - p; - - /* include trailing \r\n with chunk */ - u += 2; - - for (;;) { - j = u; - if (bp - p < j) - j = bp - p; - sp->wrk->acct.bodybytes += WRK_Write(sp->wrk, p, j); - WRK_Flush(sp->wrk); - p += j; - assert(u >= j); - u -= j; - if (u == 0) - break; - p = bp = buf; - j = u; - if (j > be - bp) - j = be - bp; - i = http_Read(hp, fd, bp, j); - xxxassert(i > 0); - bp += i; - } - } - if (WRK_Flush(sp->wrk)) - vca_close_session(sp, "remote closed"); - return (0); -} - - -/*--------------------------------------------------------------------*/ - -void -PassBody(struct sess *sp) -{ - struct vbe_conn *vc; - char *b; - int cls; - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc, VBE_CONN_MAGIC); - vc = sp->vbc; - sp->vbc = NULL; - - clock_gettime(CLOCK_REALTIME, &sp->t_resp); - - http_ClrHeader(sp->http); - http_CopyResp(sp->wrk, sp->fd, sp->http, vc->http); - http_FilterHeader(sp->wrk, sp->fd, sp->http, vc->http, HTTPH_A_PASS); - http_PrintfHeader(sp->wrk, sp->fd, sp->http, "X-Varnish: %u", sp->xid); - http_PrintfHeader(sp->wrk, sp->fd, sp->http, - "X-Forwarded-for: %s", sp->addr); - /* XXX */ - if (http_HdrIs(vc->http, H_Transfer_Encoding, "chunked")) - http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Transfer-Encoding: chunked"); - WRK_Reset(sp->wrk, &sp->fd); - sp->wrk->acct.hdrbytes += http_Write(sp->wrk, sp->http, 1); - - if (http_GetHdr(vc->http, H_Content_Length, &b)) - cls = pass_straight(sp, vc->fd, vc->http, b); - else if (http_HdrIs(vc->http, H_Connection, "close")) - cls = pass_straight(sp, vc->fd, vc->http, NULL); - else if (http_HdrIs(vc->http, H_Transfer_Encoding, "chunked")) - cls = pass_chunked(sp, vc->fd, vc->http); - else if (http_IsBodyless(vc->http)) - cls = 0; - else { - cls = pass_straight(sp, vc->fd, vc->http, NULL); - } - - if (WRK_Flush(sp->wrk)) - vca_close_session(sp, "remote closed"); - - if (http_GetHdr(vc->http, H_Connection, &b) && !strcasecmp(b, "close")) - cls = 1; - - if (cls) - VBE_ClosedFd(sp->wrk, vc, 0); - else - VBE_RecycleFd(sp->wrk, vc); -} - - -/*--------------------------------------------------------------------*/ - -int -PassSession(struct sess *sp) -{ - int i; - struct vbe_conn *vc; - struct worker *w; - char *b; - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); - w = sp->wrk; - - vc = VBE_GetFd(sp); - if (vc == NULL) - return (1); - - http_CopyReq(w, vc->fd, vc->http, sp->http); - http_FilterHeader(w, vc->fd, vc->http, sp->http, HTTPH_R_PASS); - http_PrintfHeader(w, vc->fd, vc->http, "X-Varnish: %u", sp->xid); - if (!http_GetHdr(vc->http, H_Host, &b)) { - http_PrintfHeader(w, vc->fd, vc->http, "Host: %s", - sp->backend->hostname); - } - WRK_Reset(w, &vc->fd); - http_Write(w, vc->http, 0); - i = WRK_Flush(w); - xxxassert(i == 0); - - /* XXX: copy any contents */ - - i = http_RecvHead(vc->http, vc->fd); - xxxassert(i == 0); - http_DissectResponse(w, vc->http, vc->fd); - - assert(sp->vbc == NULL); - sp->vbc = vc; - return (0); -} diff --git a/varnish-cache/bin/varnishd/cache_vrt.c b/varnish-cache/bin/varnishd/cache_vrt.c index cc443256..5e52f421 100644 --- a/varnish-cache/bin/varnishd/cache_vrt.c +++ b/varnish-cache/bin/varnishd/cache_vrt.c @@ -82,7 +82,7 @@ VRT_GetHdr(struct sess *sp, int where, const char *n) hp = sp->http; break; case 2: - hp = sp->vbc->http; + hp = &sp->obj->http; break; default: INCOMPL(); diff --git a/varnish-cache/bin/varnishd/mgt_vcc.c b/varnish-cache/bin/varnishd/mgt_vcc.c index 324c6afa..301c0147 100644 --- a/varnish-cache/bin/varnishd/mgt_vcc.c +++ b/varnish-cache/bin/varnishd/mgt_vcc.c @@ -79,6 +79,18 @@ static const char *default_vcl = " lookup;\n" "}\n" "\n" + "sub default_vcl_pipe {\n" + " pipe;\n" + "}\n" + "\n" + "sub default_vcl_pass {\n" + " pass;\n" + "}\n" + "\n" + "sub default_vcl_hash {\n" + " hash;\n" + "}\n" + "\n" "sub default_vcl_hit {\n" " if (!obj.cacheable) {\n" " pass;\n" @@ -95,10 +107,10 @@ static const char *default_vcl = " error;\n" " }\n" " if (!obj.cacheable) {\n" - " insert_pass;\n" + " pass;\n" " }\n" " if (resp.http.Set-Cookie) {\n" - " insert_pass;\n" + " pass;\n" " }\n" " insert;\n" "}\n" diff --git a/varnish-cache/bin/varnishd/steps.h b/varnish-cache/bin/varnishd/steps.h index 5649cda2..d07febb8 100644 --- a/varnish-cache/bin/varnishd/steps.h +++ b/varnish-cache/bin/varnishd/steps.h @@ -34,9 +34,7 @@ STEP(first, FIRST) STEP(recv, RECV) STEP(pipe, PIPE) STEP(pass, PASS) -STEP(passbody, PASSBODY) STEP(lookup, LOOKUP) -STEP(lookup2, LOOKUP2) STEP(miss, MISS) STEP(hit, HIT) STEP(fetch, FETCH) diff --git a/varnish-cache/include/vcl.h b/varnish-cache/include/vcl.h index fa281c26..4bd7b70d 100644 --- a/varnish-cache/include/vcl.h +++ b/varnish-cache/include/vcl.h @@ -28,6 +28,9 @@ struct VCL_conf { vcl_fini_f *fini_func; vcl_func_f *recv_func; + vcl_func_f *pipe_func; + vcl_func_f *pass_func; + vcl_func_f *hash_func; vcl_func_f *miss_func; vcl_func_f *hit_func; vcl_func_f *fetch_func; diff --git a/varnish-cache/include/vcl_returns.h b/varnish-cache/include/vcl_returns.h index fa086117..59fcc657 100644 --- a/varnish-cache/include/vcl_returns.h +++ b/varnish-cache/include/vcl_returns.h @@ -11,9 +11,9 @@ VCL_RET_MAC_E(error, ERROR, (1 << 0), 0) #endif VCL_RET_MAC(lookup, LOOKUP, (1 << 1), 1) -VCL_RET_MAC(pipe, PIPE, (1 << 2), 2) -VCL_RET_MAC(pass, PASS, (1 << 3), 3) -VCL_RET_MAC(insert_pass, INSERT_PASS, (1 << 4), 4) +VCL_RET_MAC(hash, HASH, (1 << 2), 2) +VCL_RET_MAC(pipe, PIPE, (1 << 3), 3) +VCL_RET_MAC(pass, PASS, (1 << 4), 4) VCL_RET_MAC(fetch, FETCH, (1 << 5), 5) VCL_RET_MAC(insert, INSERT, (1 << 6), 6) VCL_RET_MAC(deliver, DELIVER, (1 << 7), 7) @@ -21,9 +21,9 @@ VCL_RET_MAC(discard, DISCARD, (1 << 8), 8) #else #define VCL_RET_ERROR (1 << 0) #define VCL_RET_LOOKUP (1 << 1) -#define VCL_RET_PIPE (1 << 2) -#define VCL_RET_PASS (1 << 3) -#define VCL_RET_INSERT_PASS (1 << 4) +#define VCL_RET_HASH (1 << 2) +#define VCL_RET_PIPE (1 << 3) +#define VCL_RET_PASS (1 << 4) #define VCL_RET_FETCH (1 << 5) #define VCL_RET_INSERT (1 << 6) #define VCL_RET_DELIVER (1 << 7) @@ -33,8 +33,11 @@ VCL_RET_MAC(discard, DISCARD, (1 << 8), 8) #ifdef VCL_MET_MAC VCL_MET_MAC(recv,RECV,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_PIPE|VCL_RET_LOOKUP)) -VCL_MET_MAC(miss,MISS,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_PIPE|VCL_RET_FETCH)) -VCL_MET_MAC(hit,HIT,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_PIPE|VCL_RET_DELIVER)) -VCL_MET_MAC(fetch,FETCH,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_PIPE|VCL_RET_INSERT|VCL_RET_INSERT_PASS)) +VCL_MET_MAC(pipe,PIPE,(VCL_RET_ERROR|VCL_RET_PIPE)) +VCL_MET_MAC(pass,PASS,(VCL_RET_ERROR|VCL_RET_PASS)) +VCL_MET_MAC(hash,HASH,(VCL_RET_HASH)) +VCL_MET_MAC(miss,MISS,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_FETCH)) +VCL_MET_MAC(hit,HIT,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_DELIVER)) +VCL_MET_MAC(fetch,FETCH,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_INSERT)) VCL_MET_MAC(timeout,TIMEOUT,(VCL_RET_FETCH|VCL_RET_DISCARD)) #endif diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c index d7fd8ed6..8701a0c5 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -228,14 +228,14 @@ vcl_fixed_token(const char *p, const char **q) return (T_FETCH); } return (0); - case 'i': - if (p[0] == 'i' && p[1] == 'n' && p[2] == 's' && - p[3] == 'e' && p[4] == 'r' && p[5] == 't' && - p[6] == '_' && p[7] == 'p' && p[8] == 'a' && - p[9] == 's' && p[10] == 's' && !isvar(p[11])) { - *q = p + 11; - return (T_INSERT_PASS); + case 'h': + if (p[0] == 'h' && p[1] == 'a' && p[2] == 's' && + p[3] == 'h' && !isvar(p[4])) { + *q = p + 4; + return (T_HASH); } + return (0); + case 'i': if (p[0] == 'i' && p[1] == 'n' && p[2] == 's' && p[3] == 'e' && p[4] == 'r' && p[5] == 't' && !isvar(p[6])) { @@ -396,11 +396,11 @@ vcl_init_tnames(void) vcl_tnames[T_FETCH] = "fetch"; vcl_tnames[T_FUNC] = "func"; vcl_tnames[T_GEQ] = ">="; + vcl_tnames[T_HASH] = "hash"; vcl_tnames[T_IF] = "if"; vcl_tnames[T_INC] = "++"; vcl_tnames[T_INCR] = "+="; vcl_tnames[T_INSERT] = "insert"; - vcl_tnames[T_INSERT_PASS] = "insert_pass"; vcl_tnames[T_LEQ] = "<="; vcl_tnames[T_LOOKUP] = "lookup"; vcl_tnames[T_MUL] = "*="; @@ -424,9 +424,9 @@ vcl_output_lang_h(FILE *f) { fputs("#define VCL_RET_ERROR (1 << 0)\n", f); fputs("#define VCL_RET_LOOKUP (1 << 1)\n", f); - fputs("#define VCL_RET_PIPE (1 << 2)\n", f); - fputs("#define VCL_RET_PASS (1 << 3)\n", f); - fputs("#define VCL_RET_INSERT_PASS (1 << 4)\n", f); + fputs("#define VCL_RET_HASH (1 << 2)\n", f); + fputs("#define VCL_RET_PIPE (1 << 3)\n", f); + fputs("#define VCL_RET_PASS (1 << 4)\n", f); fputs("#define VCL_RET_FETCH (1 << 5)\n", f); fputs("#define VCL_RET_INSERT (1 << 6)\n", f); fputs("#define VCL_RET_DELIVER (1 << 7)\n", f); @@ -461,6 +461,9 @@ vcl_output_lang_h(FILE *f) fputs(" vcl_fini_f *fini_func;\n", f); fputs("\n", f); fputs(" vcl_func_f *recv_func;\n", f); + fputs(" vcl_func_f *pipe_func;\n", f); + fputs(" vcl_func_f *pass_func;\n", f); + fputs(" vcl_func_f *hash_func;\n", f); fputs(" vcl_func_f *miss_func;\n", f); fputs(" vcl_func_f *hit_func;\n", f); fputs(" vcl_func_f *fetch_func;\n", f); diff --git a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl index 80618bc0..d081c7c9 100755 --- a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl +++ b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl @@ -35,9 +35,12 @@ # set methods { {recv {error pass pipe lookup}} - {miss {error pass pipe fetch}} - {hit {error pass pipe deliver}} - {fetch {error pass pipe insert insert_pass}} + {pipe {error pipe}} + {pass {error pass}} + {hash {hash}} + {miss {error pass fetch}} + {hit {error pass deliver}} + {fetch {error pass insert}} {timeout {fetch discard}} } @@ -46,9 +49,9 @@ set methods { set returns { error lookup + hash pipe pass - insert_pass fetch insert deliver diff --git a/varnish-cache/lib/libvcl/vcc_token_defs.h b/varnish-cache/lib/libvcl/vcc_token_defs.h index 93b77827..8d954761 100644 --- a/varnish-cache/lib/libvcl/vcc_token_defs.h +++ b/varnish-cache/lib/libvcl/vcc_token_defs.h @@ -24,9 +24,9 @@ #define T_SWITCH_CONFIG 142 #define T_ERROR 143 #define T_LOOKUP 144 -#define T_PIPE 145 -#define T_PASS 146 -#define T_INSERT_PASS 147 +#define T_HASH 145 +#define T_PIPE 146 +#define T_PASS 147 #define T_FETCH 148 #define T_INSERT 149 #define T_DELIVER 150 -- 2.39.5