From kristian at varnish-cache.org Sun Aug 1 14:45:22 2010 From: kristian at varnish-cache.org (kristian at varnish-cache.org) Date: Sun, 1 Aug 2010 16:45:22 +0200 Subject: r5062 - in trunk/varnish-cache: bin/varnishd doc/sphinx/reference include lib/libvcl Message-ID: Author: kristian Date: 2010-08-01 16:45:22 +0200 (Sun, 01 Aug 2010) New Revision: 5062 Added: trunk/varnish-cache/bin/varnishd/cache_dir_dns.c trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c Modified: trunk/varnish-cache/bin/varnishd/Makefile.am trunk/varnish-cache/bin/varnishd/cache_backend.c trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c trunk/varnish-cache/doc/sphinx/reference/vcl.rst trunk/varnish-cache/include/stat_field.h trunk/varnish-cache/include/vrt.h trunk/varnish-cache/include/vsc_fields.h trunk/varnish-cache/lib/libvcl/Makefile.am trunk/varnish-cache/lib/libvcl/vcc_backend.c trunk/varnish-cache/lib/libvcl/vcc_compile.h Log: Add a DNS director The DNS director allows Varnish to pick backend based on the Host header provided by the client, and how it resolves in DNS. A suffix can be added to make it "internal" (see vcl(7)). There's still some quirks that I want to work out, but this seems fairly commit-ready and non-intrusive. Modified: trunk/varnish-cache/bin/varnishd/Makefile.am =================================================================== --- trunk/varnish-cache/bin/varnishd/Makefile.am 2010-07-30 23:17:36 UTC (rev 5061) +++ trunk/varnish-cache/bin/varnishd/Makefile.am 2010-08-01 14:45:22 UTC (rev 5062) @@ -21,6 +21,7 @@ cache_center.c \ cache_cli.c \ cache_dir_random.c \ + cache_dir_dns.c \ cache_dir_round_robin.c \ cache_esi.c \ cache_expire.c \ Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-07-30 23:17:36 UTC (rev 5061) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-01 14:45:22 UTC (rev 5062) @@ -536,6 +536,24 @@ struct vsc_vbe *stats; }; +/* Returns the backend if and only if the this is a simple director. + * XXX: Needs a better name and possibly needs a better general approach. + * XXX: This is mainly used by the DNS director to fetch the actual backend + * XXX: so it can compare DNS lookups with the actual IP. + */ +struct backend * +vdi_get_backend_if_simple(const struct director *d) +{ + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + struct vdi_simple *vs, *vs2; + + vs2 = d->priv; + if (vs2->magic != VDI_SIMPLE_MAGIC) + return NULL; + CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); + return vs->backend; +} + static struct vbe_conn * vdi_simple_getfd(const struct director *d, struct sess *sp) { Modified: trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-07-30 23:17:36 UTC (rev 5061) +++ trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-01 14:45:22 UTC (rev 5062) @@ -272,6 +272,8 @@ VRT_init_dir_hash(cli, dir, idx, priv); else if (!strcmp(name, "random")) VRT_init_dir_random(cli, dir, idx, priv); + else if (!strcmp(name, "dns")) + VRT_init_dir_dns(cli, dir, idx, priv); else if (!strcmp(name, "round-robin")) VRT_init_dir_round_robin(cli, dir, idx, priv); else if (!strcmp(name, "client")) Added: trunk/varnish-cache/bin/varnishd/cache_dir_dns.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_dns.c (rev 0) +++ trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-01 14:45:22 UTC (rev 5062) @@ -0,0 +1,484 @@ +/*- + * Copyright (c) 2009 Redpill Linpro AS + * Copyright (c) 2010 Varnish Software AS + * All rights reserved. + * + * Author: Kristian Lyngstol + * + * 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 THE 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. + * + */ + +#include "config.h" + +#include "svnid.h" +SVNID("$Id$") + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include "cache.h" +#include "cache_backend.h" +#include "vrt.h" + +/*--------------------------------------------------------------------*/ + +/* FIXME: Should eventually be a configurable variable. */ +#define VDI_DNS_MAX_CACHE 1024 +#define VDI_DNS_GROUP_MAX_BACKENDS 1024 + +/* DNS Cache entry + */ +struct vdi_dns_hostgroup { + unsigned magic; +#define VDI_DNSDIR_MAGIC 0x1bacab21 + char *hostname; + struct director *hosts[VDI_DNS_GROUP_MAX_BACKENDS]; + unsigned nhosts; + unsigned next_host; /* Next to use...*/ + double ttl; + VTAILQ_ENTRY(vdi_dns_hostgroup) list; +}; + +struct vdi_dns { + unsigned magic; +#define VDI_DNS_MAGIC 0x1337a178 + struct director dir; + struct director **hosts; + unsigned nhosts; + VTAILQ_HEAD(_cachelist,vdi_dns_hostgroup) cachelist; + unsigned ncachelist; + pthread_rwlock_t rwlock; + const char *suffix; + double ttl; + const unsigned max_cache_size; +}; + + + +/* Compare an IPv4 backend to a IPv4 addr/len */ +static int +vdi_dns_comp_addrinfo4(struct backend *bp, + const struct sockaddr_in *addr, + const socklen_t len) +{ + uint32_t u, p; + struct sockaddr_in *bps = (struct sockaddr_in *) bp->ipv4; + + if (bp->ipv4len != len || len <= 0) + return 0; + + u = addr->sin_addr.s_addr; + p = bps->sin_addr.s_addr; + + return u == p; +} + +/* Compare an IPv6 backend to a IPv6 addr/len */ +static int +vdi_dns_comp_addrinfo6(struct backend *bp, + struct sockaddr_in6 *addr, + const socklen_t len) +{ + uint8_t *u, *p; + int i; + struct sockaddr_in6 *bps = (struct sockaddr_in6 *) bp->ipv6; + + if (bp->ipv6len != len || len <= 0) + return 0; + + u = addr->sin6_addr.s6_addr; + p = bps->sin6_addr.s6_addr; + + for (i=0; i < 16; i++) { + if (u[i] != p[i]) + return 0; + } + + return 1; +} + +struct backend * +vdi_get_backend_if_simple(const struct director *d); + +/* Check if a backends socket is the same as addr */ +static int +vdi_dns_comp_addrinfo(struct director *dir, + struct sockaddr *addr, + const socklen_t len) +{ + struct backend *bp; + bp = vdi_get_backend_if_simple(dir); + if (addr->sa_family == PF_INET && bp->ipv4) { + return (vdi_dns_comp_addrinfo4(bp, (struct sockaddr_in *) + addr, len)); + } else if (addr->sa_family == PF_INET6 && bp->ipv6) { + return (vdi_dns_comp_addrinfo6(bp, (struct sockaddr_in6 *) + addr, len)); + } + return 0; +} + +/* Pick a host from an existing hostgroup. + * Balance on round-robin if multiple backends are available and only pick + * healthy ones. + */ +static struct director * +vdi_dns_pick_host(const struct sess *sp, struct vdi_dns_hostgroup *group) { + int initial, i, nhosts, current; + if (group->nhosts == 0) + return (NULL); // In case of error. + if (group->next_host >= group->nhosts) + group->next_host = 0; + + /* Pick a healthy backend */ + initial = group->next_host; + nhosts = group->nhosts; + for (i=0; i < nhosts; i++) { + if (i + initial >= nhosts) + current = i + initial - nhosts; + else + current = i + initial; + if (VBE_Healthy_sp(sp, group->hosts[current])) { + group->next_host = current+1; + return group->hosts[current]; + } + } + + return NULL; +} + +/* Remove an item from the dns cache. + * If *group is NULL, the head is popped. + * Remember locking. + */ +static void +vdi_dns_pop_cache(struct vdi_dns *vs, + struct vdi_dns_hostgroup *group) +{ + if (group == NULL) + group = VTAILQ_LAST( &vs->cachelist, _cachelist ); + assert(group != NULL); + free(group->hostname); + VTAILQ_REMOVE(&vs->cachelist, group, list); + FREE_OBJ(group); + vs->ncachelist--; +} + +/* Dummy in case someone feels like optimizing it? meh... + */ +static inline int +vdi_dns_groupmatch(const struct vdi_dns_hostgroup *group, const char *hostname) +{ + return !strcmp(group->hostname, hostname); +} + +/* Search the cache for 'hostname' and put a backend-pointer as necessary, + * return true for cache hit. This could still be a NULL backend if we did + * a lookup earlier and didn't find a host (ie: cache failed too) + * + * if rwlock is true, the first timed out object found (if any) is popped + * and freed. + */ +static int +vdi_dns_cache_has(const struct sess *sp, + struct vdi_dns *vs, + const char *hostname, + struct director **backend, + int rwlock) +{ + struct director *ret; + struct vdi_dns_hostgroup *hostgr; + struct vdi_dns_hostgroup *hostgr2; + VTAILQ_FOREACH_SAFE(hostgr, &vs->cachelist, list, hostgr2) { + CHECK_OBJ_NOTNULL(hostgr, VDI_DNSDIR_MAGIC); + if (hostgr->ttl <= sp->t_req) { + if (rwlock) + vdi_dns_pop_cache(vs, hostgr); + return 0; + } + if (vdi_dns_groupmatch(hostgr, hostname)) { + ret = (vdi_dns_pick_host(sp, hostgr)); + *backend = ret; + if (*backend != NULL) + CHECK_OBJ_NOTNULL(*backend, DIRECTOR_MAGIC); + return 1; + } + } + return 0; +} + +/* Add a newly cached item to the dns cache list. + * (Sorry for the list_add/_add confusion...) + */ +static void +vdi_dns_cache_list_add(const struct sess *sp, + struct vdi_dns *vs, + struct vdi_dns_hostgroup *new) +{ + if (vs->ncachelist >= VDI_DNS_MAX_CACHE) { + VSC_main->dir_dns_cache_full++; + vdi_dns_pop_cache(vs, NULL); + } + CHECK_OBJ_NOTNULL(new, VDI_DNSDIR_MAGIC); + assert(new->hostname != 0); + new->ttl = sp->t_req + vs->ttl; + VTAILQ_INSERT_HEAD(&vs->cachelist, new, list); + vs->ncachelist++; +} + +/* Add an item to the dns cache. + * XXX: Might want to factor the getaddrinfo() out of the lock and do the + * cache_has() afterwards to do multiple dns lookups in parallel... + */ +static int +vdi_dns_cache_add(const struct sess *sp, + struct vdi_dns *vs, + const char *hostname, + struct director **backend) +{ + int error, i, host = 0; + struct addrinfo *res0, *res, hint; + struct vdi_dns_hostgroup *new; + /* Due to possible race while upgrading the lock, we have to + * recheck if the result is already looked up. The overhead for + * this is insignificant unless dns isn't cached properly (all + * unique names or something equally troublesome). + */ + + if (vdi_dns_cache_has(sp, vs, hostname, backend, 1)) + return 1; + + memset(&hint, 0, sizeof hint); + hint.ai_family = PF_UNSPEC; + hint.ai_socktype = SOCK_STREAM; + + ALLOC_OBJ(new, VDI_DNSDIR_MAGIC); + new->hostname = calloc(sizeof(char), strlen(hostname)+1); + assert(new->hostname != NULL); + strcpy(new->hostname, hostname); + + error = getaddrinfo(hostname, "80", &hint, &res0); + VSC_main->dir_dns_lookups++; + if (error) { + vdi_dns_cache_list_add(sp, vs, new); + VSC_main->dir_dns_failed++; + return 0; + } + + for (res = res0; res; res = res->ai_next) { + if (res->ai_family != PF_INET && + res->ai_family != PF_INET6) + continue; + + for (i = 0; i < vs->nhosts; i++) { + if (vdi_dns_comp_addrinfo(vs->hosts[i], + res->ai_addr, res->ai_addrlen)) { + new->hosts[host] = vs->hosts[i]; + CHECK_OBJ_NOTNULL(new->hosts[host], DIRECTOR_MAGIC); + host++; + } + } + } + freeaddrinfo(res0); + + new->nhosts = host; + vdi_dns_cache_list_add(sp, vs, new); + *backend = vdi_dns_pick_host(sp, new); + return 1; +} + +/* Walk through the cached lookups looking for the relevant host, add one + * if it isn't already cached. + * + * Returns a backend or NULL. + */ +static struct director * +vdi_dns_walk_cache(const struct sess *sp, + struct vdi_dns *vs, + const char *hostname) +{ + struct director *backend = NULL; + int ret; + AZ(pthread_rwlock_rdlock(&vs->rwlock)); + ret = vdi_dns_cache_has(sp, vs, hostname, &backend, 0); + pthread_rwlock_unlock(&vs->rwlock); + if (!ret) { + AZ(pthread_rwlock_wrlock(&vs->rwlock)); + ret = vdi_dns_cache_add(sp, vs, hostname, &backend); + pthread_rwlock_unlock(&vs->rwlock); + } else + VSC_main->dir_dns_hit++; + + /* Bank backend == cached a failure, so to speak */ + if (backend != NULL) + CHECK_OBJ_NOTNULL(backend, DIRECTOR_MAGIC); + return backend; +} + +/* Parses the Host:-header and heads out to find a backend. + */ +static struct director * +vdi_dns_find_backend(const struct sess *sp, struct vdi_dns *vs) +{ + struct director *ret; + struct http *hp; + char *p; + char hostname[NI_MAXHOST]; + int i; + + /* bereq is only present after recv et. al, otherwise use req (ie: + * use req for health checks in vcl_recv and such). + */ + if (sp->wrk->bereq) + hp = sp->wrk->bereq; + else + hp = sp->http; + + + CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); + if (http_GetHdr(hp, H_Host, &p) == 0) + return (NULL); + + /* We need a working copy since it's going to be modified */ + strncpy(hostname, p, sizeof(hostname)); + + /* remove port-portion of the Host-header, if present. */ + for (i = 0; i < strlen(hostname); i++) { + if (hostname[i] == ':') { + hostname[i] = '\0'; + break; + } + } + + if (vs->suffix) + strncat(hostname, vs->suffix, sizeof(hostname) - strlen(hostname)); + + ret = vdi_dns_walk_cache(sp, vs, hostname); + return ret; +} + +static struct vbe_conn * +vdi_dns_getfd(const struct director *director, struct sess *sp) +{ + int i; + struct vdi_dns *vs; + struct director *dir; + struct vbe_conn *vbe; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(director, DIRECTOR_MAGIC); + CAST_OBJ_NOTNULL(vs, director->priv, VDI_DNS_MAGIC); + + dir = vdi_dns_find_backend(sp, vs); + if (!dir || !VBE_Healthy_sp(sp, dir)) + return (NULL); + + vbe = VBE_GetFd(dir, sp); + return (vbe); +} + +static unsigned +vdi_dns_healthy(double now, const struct director *dir, uintptr_t target) +{ + return 1; + /* + struct vdi_dns *vs; + struct director *dir; + int i; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC); + CAST_OBJ_NOTNULL(vs, sp->director->priv, VDI_DNS_MAGIC); + + dir = vdi_dns_find_backend(sp, vs); + + if (dir) + return 1; + return 0; + */ +} + +/*lint -e{818} not const-able */ +static void +vdi_dns_fini(struct director *d) +{ + int i; + struct vdi_dns *vs; + struct director **vh; + + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + CAST_OBJ_NOTNULL(vs, d->priv, VDI_DNS_MAGIC); + + vh = vs->hosts; + free(vs->hosts); + free(vs->dir.vcl_name); + vs->dir.magic = 0; + /* FIXME: Free the cache */ + pthread_rwlock_destroy(&vs->rwlock); + FREE_OBJ(vs); +} + +void +VRT_init_dir_dns(struct cli *cli, struct director **bp, int idx, + const void *priv) +{ + const struct vrt_dir_dns *t; + struct vdi_dns *vs; + const struct vrt_dir_dns_entry *te; + int i; + + ASSERT_CLI(); + (void)cli; + t = priv; + ALLOC_OBJ(vs, VDI_DNS_MAGIC); + XXXAN(vs); + vs->hosts = calloc(sizeof(struct director *), t->nmember); + XXXAN(vs->hosts); + + vs->dir.magic = DIRECTOR_MAGIC; + vs->dir.priv = vs; + vs->dir.name = "dns"; + REPLACE(vs->dir.vcl_name, t->name); + vs->dir.getfd = vdi_dns_getfd; + vs->dir.fini = vdi_dns_fini; + vs->dir.healthy = vdi_dns_healthy; + + vs->suffix = t->suffix; + vs->ttl = t->ttl; + + te = t->members; + for (i = 0; i < t->nmember; i++, te++) + vs->hosts[i] = bp[te->host]; + vs->nhosts = t->nmember; + vs->ttl = t->ttl; + VTAILQ_INIT(&vs->cachelist); + pthread_rwlock_init(&vs->rwlock, NULL); + bp[idx] = &vs->dir; +} Modified: trunk/varnish-cache/doc/sphinx/reference/vcl.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/reference/vcl.rst 2010-07-30 23:17:36 UTC (rev 5061) +++ trunk/varnish-cache/doc/sphinx/reference/vcl.rst 2010-08-01 14:45:22 UTC (rev 5062) @@ -141,6 +141,34 @@ The round-robin does not take any options. +The DNS director +~~~~~~~~~~~~~~~~ + +The DNS director can use backends in three different ways. Either like the +random or round-robin director or using .list:: + + director directorname dns { + .list = { + .host_header = "www.example.com"; + .port = "80"; + .connection_timeout = 0.4; + "192.168.15.0"/24; + "192.168.16.128"/25; + } + .ttl = 5m; + .suffix = "internal.example.net"; + } + +This will specify 384 backends, all using port 80 and a connection timeout +of 0.4s. Options must come before the list of IPs in the .list statement. + +The .ttl defines the cache duration of the DNS lookups. + +The above example will append "internal.example.net" to the incoming Host +header supplied by the client, before looking it up. All settings are +optional. + + Backend probes -------------- Modified: trunk/varnish-cache/include/stat_field.h =================================================================== --- trunk/varnish-cache/include/stat_field.h 2010-07-30 23:17:36 UTC (rev 5061) +++ trunk/varnish-cache/include/stat_field.h 2010-08-01 14:45:22 UTC (rev 5062) @@ -153,6 +153,12 @@ MAC_STAT(client_drop_late, uint64_t, 0, 'a', "Connection dropped late") MAC_STAT(uptime, uint64_t, 0, 'a', "Client uptime") +MAC_STAT(dir_dns_lookups, uint64_t, 0, 'a', "DNS director lookups") +MAC_STAT(dir_dns_failed, uint64_t, 0, 'a', "DNS director failed lookups") +MAC_STAT(dir_dns_hit, uint64_t, 0, 'a', "DNS director cached lookups hit") +MAC_STAT(dir_dns_cache_full, uint64_t, 0, 'a', "DNS director full dnscache") + + MAC_STAT(critbit_cooler, uint64_t, 0, 'i', "Objhdr's on cool list") #ifdef __MAC_STAT Modified: trunk/varnish-cache/include/vrt.h =================================================================== --- trunk/varnish-cache/include/vrt.h 2010-07-30 23:17:36 UTC (rev 5061) +++ trunk/varnish-cache/include/vrt.h 2010-08-01 14:45:22 UTC (rev 5062) @@ -107,7 +107,22 @@ const struct vrt_dir_round_robin_entry *members; }; +/* + * A director with dns-based selection + */ +struct vrt_dir_dns_entry { + int host; +}; + +struct vrt_dir_dns { + const char *name; + const char *suffix; + const double ttl; + unsigned nmember; + const struct vrt_dir_dns_entry *members; +}; + /* * other stuff. * XXX: document when bored Modified: trunk/varnish-cache/include/vsc_fields.h =================================================================== --- trunk/varnish-cache/include/vsc_fields.h 2010-07-30 23:17:36 UTC (rev 5061) +++ trunk/varnish-cache/include/vsc_fields.h 2010-08-01 14:45:22 UTC (rev 5062) @@ -154,6 +154,12 @@ VSC_F_MAIN(client_drop_late, uint64_t, 0, 'a', "Connection dropped late") VSC_F_MAIN(uptime, uint64_t, 0, 'a', "Client uptime") +VSC_F_MAIN(dir_dns_lookups, uint64_t, 0, 'a', "DNS director lookups") +VSC_F_MAIN(dir_dns_failed, uint64_t, 0, 'a', "DNS director failed lookups") +VSC_F_MAIN(dir_dns_hit, uint64_t, 0, 'a', "DNS director cached lookups hit") +VSC_F_MAIN(dir_dns_cache_full, uint64_t, 0, 'a', "DNS director full dnscache") + + VSC_F_MAIN(critbit_cooler, uint64_t, 0, 'i', "Objhdr's on cool list") #ifdef __VSC_F_MAIN Modified: trunk/varnish-cache/lib/libvcl/Makefile.am =================================================================== --- trunk/varnish-cache/lib/libvcl/Makefile.am 2010-07-30 23:17:36 UTC (rev 5061) +++ trunk/varnish-cache/lib/libvcl/Makefile.am 2010-08-01 14:45:22 UTC (rev 5062) @@ -19,6 +19,7 @@ vcc_compile.c \ vcc_dir_random.c \ vcc_dir_round_robin.c \ + vcc_dir_dns.c \ vcc_expr.c \ vcc_parse.c \ $(builddir)/vcc_fixed_token.c \ Modified: trunk/varnish-cache/lib/libvcl/vcc_backend.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-07-30 23:17:36 UTC (rev 5061) +++ trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-08-01 14:45:22 UTC (rev 5062) @@ -96,7 +96,7 @@ * and put it in an official sockaddr when we load the VCL. */ -static void +void Emit_Sockaddr(struct vcc *tl, const struct token *t_host, const char *port) { @@ -189,7 +189,7 @@ * in that context. */ -static void +void vcc_EmitBeIdent(const struct vcc *tl, struct vsb *v, int serial, const struct token *first, const struct token *last) { @@ -696,6 +696,7 @@ { "random", vcc_ParseRandomDirector }, { "client", vcc_ParseRandomDirector }, { "round-robin", vcc_ParseRoundRobinDirector }, + { "dns", vcc_ParseDnsDirector }, { NULL, NULL } }; Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-07-30 23:17:36 UTC (rev 5061) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-01 14:45:22 UTC (rev 5062) @@ -222,6 +222,9 @@ double vcc_DoubleVal(struct vcc *tl); void vcc_Expr(struct vcc *tl, enum var_type fmt); +/* vcc_dir_dns.c */ +parsedirector_f vcc_ParseDnsDirector; + /* vcc_obj.c */ extern const struct var vcc_vars[]; Added: trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c (rev 0) +++ trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c 2010-08-01 14:45:22 UTC (rev 5062) @@ -0,0 +1,364 @@ +/*- + * Copyright (c) 2009 Redpill Linpro AS + * Copyright (c) 2010 Varnish Software AS + * All rights reserved. + * + * Author: Kristian Lyngstol + * + * 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 THE 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. + */ + +#include "config.h" + +#include "svnid.h" +SVNID("$Id$") + +#include +#include + +#include +#include +#include +#include +#include + +#include "vsb.h" + +#include "vcc_priv.h" +#include "vcc_compile.h" +#include "libvarnish.h" + +/*-------------------------------------------------------------------- + * Parse directors + */ + + +void +vcc_EmitBeIdent(const struct vcc *tl, struct vsb *v, + int serial, const struct token *first, const struct token *last); +void +Emit_Sockaddr(struct vcc *tl, const struct token *t_host, + const char *port); + +struct vcc_dir_backend_defaults { + char *port; + char *hostheader; + double connect_timeout; + double first_byte_timeout; + double between_bytes_timeout; + unsigned max_connections; + unsigned saint; +} b_defaults; + +void vcc_dir_initialize_defaults(void) +{ + b_defaults.port = NULL; + b_defaults.hostheader = NULL; + b_defaults.connect_timeout = -1.0; + b_defaults.first_byte_timeout = -1.0; + b_defaults.between_bytes_timeout = -1.0; + b_defaults.max_connections = UINT_MAX; + b_defaults.saint = UINT_MAX; +} + +struct token *dns_first; +void +print_backend(struct vcc *tl, + uint32_t serial, + uint8_t *ip) +{ + char vgcname[BUFSIZ]; + char strip[16]; + struct token tmptok; + struct vsb *vsb; + sprintf(strip, "%d.%d.%d.%d",ip[3],ip[2],ip[1],ip[0]); + tmptok.dec = strip; + sprintf(vgcname,"%.*s_%u",PF(tl->t_dir),serial); + vsb = vsb_newauto(); + AN(vsb); + tl->fb = vsb; + Fc(tl, 0, "\t{ .host = VGC_backend_%s },\n",vgcname); + Fh(tl, 1, "\n#define VGC_backend_%s %u\n", vgcname, serial); + + Fb(tl, 0, "\nstatic const struct vrt_backend vgc_dir_priv_%s = {\n", vgcname); + + Fb(tl, 0, "\t.vcl_name = \"%.*s", PF(tl->t_dir)); + if (serial >= 0) + Fb(tl, 0, "[%d]", serial); + Fb(tl, 0, "\",\n"); + Emit_Sockaddr(tl, &tmptok, b_defaults.port); + vcc_EmitBeIdent(tl, tl->fb, serial, dns_first , tl->t); + + Fb(tl, 0, "\t.hosthdr = \""); + if (b_defaults.hostheader != NULL) + Fb(tl,0, b_defaults.hostheader); + else + Fb(tl,0, strip); + Fb(tl, 0, "\",\n"); + + Fb(tl, 0, "\t.saintmode_threshold = %d,\n",b_defaults.saint); +#define FB_TIMEOUT(type) do { \ + if (b_defaults.type != -1.0) \ + Fb(tl, 0, "\t.%s = %g,\n",#type,b_defaults.type); \ + } while (0) + FB_TIMEOUT(connect_timeout); + FB_TIMEOUT(first_byte_timeout); + FB_TIMEOUT(between_bytes_timeout); + + Fb(tl, 0, "};\n"); + tl->fb = NULL; + vsb_finish(vsb); + Fh(tl, 0, "%s", vsb_data(vsb)); + vsb_delete(vsb); + Fi(tl, 0, "\tVRT_init_dir(cli, VCL_conf.director, \"simple\",\n" + "\t VGC_backend_%s, &vgc_dir_priv_%s);\n", vgcname, vgcname); + Ff(tl, 0, "\tVRT_fini_dir(cli, VGCDIR(%s));\n", vgcname); + tl->ndirector++; +} +/* + * Output backends for all IPs in the range supplied by + * "a[0].a[1].a[2].a[3]/inmask". + * + * XXX: + * This assumes that a uint32_t can be safely accessed as an array of 4 + * uint8_ts. + */ +void +vcc_dir_dns_makebackend(struct vcc *tl, + uint32_t *serial, + unsigned char a[], + int inmask) +{ + uint32_t ip4=0; + uint32_t ip4end; + uint32_t mask = UINT32_MAX << (32-inmask); + + ip4 |= a[0] << 24; + ip4 |= a[1] << 16; + ip4 |= a[2] << 8; + ip4 |= a[3] ; + + ip4end = ip4 | ~mask; + assert (ip4 == (ip4 & mask)); + +/* printf("uip4: \t0x%.8X\na: \t0x", ip4,ip4); + for (int i=0;i<4;i++) printf("%.2X",a[i]); + printf("\nmask:\t0x%.8X\nend:\t0x%.8X\n", mask, ip4end); +*/ + while (ip4 <= ip4end) { + uint8_t *b; + b=(uint8_t *)&ip4; + (*serial)++; + print_backend(tl, *serial, b); + ip4++; + } +} +void +vcc_dir_dns_parse_backend_options(struct vcc *tl) +{ + struct fld_spec *fs; + struct token *t_field; + double t; + unsigned u; + vcc_dir_initialize_defaults(); + fs = vcc_FldSpec(tl, + "?port", + "?host_header", + "?connect_timeout", + "?first_byte_timeout", + "?between_bytes_timeout", + "?max_connections", + "?saintmode_threshold", + NULL); + while (tl->t->tok != CSTR) { + + vcc_IsField(tl, &t_field, fs); + ERRCHK(tl); + if (vcc_IdIs(t_field, "port")) { + ExpectErr(tl, CSTR); + assert(tl->t->dec != NULL); + b_defaults.port = strdup(tl->t->dec); + assert(b_defaults.port); + vcc_NextToken(tl); + SkipToken(tl, ';'); + } else if (vcc_IdIs(t_field, "host_header")) { + ExpectErr(tl, CSTR); + assert(tl->t->dec != NULL); + b_defaults.hostheader = strdup(tl->t->dec); + assert(b_defaults.hostheader); + vcc_NextToken(tl); + SkipToken(tl, ';'); + } else if (vcc_IdIs(t_field, "connect_timeout")) { + vcc_TimeVal(tl, &t); + ERRCHK(tl); + b_defaults.connect_timeout = t; + SkipToken(tl, ';'); + } else if (vcc_IdIs(t_field, "first_byte_timeout")) { + vcc_TimeVal(tl, &t); + ERRCHK(tl); + b_defaults.first_byte_timeout = t; + SkipToken(tl, ';'); + } else if (vcc_IdIs(t_field, "between_bytes_timeout")) { + vcc_TimeVal(tl, &t); + ERRCHK(tl); + b_defaults.between_bytes_timeout = t; + SkipToken(tl, ';'); + } else if (vcc_IdIs(t_field, "max_connections")) { + u = vcc_UintVal(tl); + ERRCHK(tl); + SkipToken(tl, ';'); + b_defaults.max_connections = u; + } else if (vcc_IdIs(t_field, "saintmode_threshold")) { + u = vcc_UintVal(tl); + /* UINT_MAX == magic number to mark as unset, so + * not allowed here. + */ + if (u == UINT_MAX) { + vsb_printf(tl->sb, + "Value outside allowed range: "); + vcc_ErrToken(tl, tl->t); + vsb_printf(tl->sb, " at\n"); + vcc_ErrWhere(tl, tl->t); + } + ERRCHK(tl); + b_defaults.saint = u; + SkipToken(tl, ';'); + } else { + ErrInternal(tl); + return; + } + + } +} + +/* Parse a list of backends with optional /mask notation, then print out + * all relevant backends. + */ +void +vcc_dir_dns_parse_list(struct vcc *tl, int *serial) +{ + unsigned char a[4],mask; + int ret, nitem; + ERRCHK(tl); + SkipToken(tl, '{'); + if (tl->t->tok != CSTR) + vcc_dir_dns_parse_backend_options(tl); + while (tl->t->tok == CSTR) { + mask = 32; + ret = sscanf(tl->t->dec, "%d.%d.%d.%d",&a[0],&a[1],&a[2],&a[3],&a[4]); + assert(ret == 4); + vcc_NextToken(tl); + if (tl->t->tok == '/') { + vcc_NextToken(tl); + mask = vcc_UintVal(tl); + ERRCHK(tl); + } + vcc_dir_dns_makebackend(tl,serial,a,mask); + SkipToken(tl,';'); + } + ExpectErr(tl, '}'); +} + +void +vcc_ParseDnsDirector(struct vcc *tl) +{ + struct token *t_field, *t_be, *t_suffix = NULL; + double ttl = 60.0; + int nbh, nelem = 0; + struct fld_spec *fs; + const char *first; + char *p; + dns_first = tl->t; + tl->fb = tl->fc; + fs = vcc_FldSpec(tl, "!backend", "?ttl", "?suffix","?list", NULL); + + Fc(tl, 0, "\nstatic const struct vrt_dir_dns_entry " + "vddnse_%.*s[] = {\n", PF(tl->t_dir)); + + for (; tl->t->tok != '}'; ) { /* List of members */ + if (tl->t->tok == '{') { + nelem++; + first = ""; + t_be = tl->t; + vcc_ResetFldSpec(fs); + nbh = -1; + + ExpectErr(tl, '{'); + vcc_NextToken(tl); + Fc(tl, 0, "\t{"); + + while (tl->t->tok != '}') { /* Member fields */ + vcc_IsField(tl, &t_field, fs); + ERRCHK(tl); + if (vcc_IdIs(t_field, "backend")) { + vcc_ParseBackendHost(tl, nelem, &p); + ERRCHK(tl); + AN(p); + Fc(tl, 0, "%s .host = VGC_backend_%s", first, p); + } else { + ErrInternal(tl); + } + first = ", "; + } + vcc_FieldsOk(tl, fs); + if (tl->err) { + vsb_printf(tl->sb, + "\nIn member host specification starting at:\n"); + vcc_ErrWhere(tl, t_be); + return; + } + Fc(tl, 0, " },\n"); + } else { + vcc_IsField(tl, &t_field, fs); + ERRCHK(tl); + if (vcc_IdIs(t_field, "suffix")) { + ExpectErr(tl, CSTR); + t_suffix = tl->t; + vcc_NextToken(tl); + ExpectErr(tl, ';'); + } else if (vcc_IdIs(t_field, "ttl")) { + vcc_RTimeVal(tl, &ttl); + ExpectErr(tl, ';'); + } else if (vcc_IdIs(t_field, "list")) { + vcc_dir_dns_parse_list(tl,&nelem); + } + } + vcc_NextToken(tl); + } + Fc(tl, 0, "};\n"); + Fc(tl, 0, + "\nstatic const struct vrt_dir_dns vgc_dir_priv_%.*s = {\n", + PF(tl->t_dir)); + Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(tl->t_dir)); + Fc(tl, 0, "\t.nmember = %d,\n", nelem); + Fc(tl, 0, "\t.members = vddnse_%.*s,\n", PF(tl->t_dir)); + Fc(tl, 0, "\t.suffix = "); + if (t_suffix) + Fc(tl, 0, "%.*s", PF(t_suffix)); + else + Fc(tl, 0, "\"\""); + Fc(tl, 0, ",\n"); + Fc(tl, 0, "\t.ttl = %f", ttl); + Fc(tl, 0, ",\n"); + Fc(tl, 0, "};\n"); + Ff(tl, 0, "\tVRT_fini_dir(cli, VGCDIR(_%.*s));\n", PF(tl->t_dir)); +} From kristian at varnish-cache.org Mon Aug 2 10:40:36 2010 From: kristian at varnish-cache.org (kristian at varnish-cache.org) Date: Mon, 2 Aug 2010 12:40:36 +0200 Subject: r5063 - in trunk/varnish-cache: bin/varnishd lib/libvcl Message-ID: Author: kristian Date: 2010-08-02 12:40:35 +0200 (Mon, 02 Aug 2010) New Revision: 5063 Modified: trunk/varnish-cache/bin/varnishd/cache_backend.h trunk/varnish-cache/bin/varnishd/cache_dir_dns.c trunk/varnish-cache/lib/libvcl/vcc_compile.h trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c Log: Clean out some silly imprecisions, clearing the build Some minor nitpicking and some slightly ugly stuff. It currently fails a regression test (v00017.vtc). I'm on it. Modified: trunk/varnish-cache/bin/varnishd/cache_backend.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-08-01 14:45:22 UTC (rev 5062) +++ trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-08-02 10:40:35 UTC (rev 5063) @@ -143,6 +143,7 @@ /* cache_backend.c */ void VBE_ReleaseConn(struct vbe_conn *vc); +struct backend *vdi_get_backend_if_simple(const struct director *d); /* cache_backend_cfg.c */ extern struct lock VBE_mtx; @@ -158,6 +159,7 @@ /* Init functions for directors */ typedef void dir_init_f(struct cli *, struct director **, int , const void*); dir_init_f VRT_init_dir_simple; +dir_init_f VRT_init_dir_dns; dir_init_f VRT_init_dir_hash; dir_init_f VRT_init_dir_random; dir_init_f VRT_init_dir_round_robin; Modified: trunk/varnish-cache/bin/varnishd/cache_dir_dns.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-01 14:45:22 UTC (rev 5062) +++ trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-02 10:40:35 UTC (rev 5063) @@ -124,9 +124,6 @@ return 1; } -struct backend * -vdi_get_backend_if_simple(const struct director *d); - /* Check if a backends socket is the same as addr */ static int vdi_dns_comp_addrinfo(struct director *dir, @@ -387,7 +384,6 @@ static struct vbe_conn * vdi_dns_getfd(const struct director *director, struct sess *sp) { - int i; struct vdi_dns *vs; struct director *dir; struct vbe_conn *vbe; @@ -407,6 +403,12 @@ static unsigned vdi_dns_healthy(double now, const struct director *dir, uintptr_t target) { + /* XXX: Fooling -Werror for a bit until it's actually implemented. + */ + if (now || dir || target) + return 1; + else + return 1; return 1; /* struct vdi_dns *vs; @@ -429,7 +431,6 @@ static void vdi_dns_fini(struct director *d) { - int i; struct vdi_dns *vs; struct director **vh; Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-01 14:45:22 UTC (rev 5062) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-02 10:40:35 UTC (rev 5063) @@ -191,6 +191,10 @@ void vcc_IsField(struct vcc *tl, struct token **t, struct fld_spec *fs); void vcc_FieldsOk(struct vcc *tl, const struct fld_spec *fs); +void Emit_Sockaddr(struct vcc *tl, const struct token *t_host, const char *port); +void vcc_EmitBeIdent(const struct vcc *tl, struct vsb *v, + int serial, const struct token *first, const struct token *last); + /* vcc_compile.c */ extern struct method method_tab[]; /* Modified: trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c 2010-08-01 14:45:22 UTC (rev 5062) +++ trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c 2010-08-02 10:40:35 UTC (rev 5063) @@ -51,14 +51,6 @@ * Parse directors */ - -void -vcc_EmitBeIdent(const struct vcc *tl, struct vsb *v, - int serial, const struct token *first, const struct token *last); -void -Emit_Sockaddr(struct vcc *tl, const struct token *t_host, - const char *port); - struct vcc_dir_backend_defaults { char *port; char *hostheader; @@ -69,7 +61,7 @@ unsigned saint; } b_defaults; -void vcc_dir_initialize_defaults(void) +static void vcc_dir_initialize_defaults(void) { b_defaults.port = NULL; b_defaults.hostheader = NULL; @@ -80,10 +72,11 @@ b_defaults.saint = UINT_MAX; } -struct token *dns_first; -void +static struct token *dns_first; + +static void print_backend(struct vcc *tl, - uint32_t serial, + int serial, uint8_t *ip) { char vgcname[BUFSIZ]; @@ -92,12 +85,12 @@ struct vsb *vsb; sprintf(strip, "%d.%d.%d.%d",ip[3],ip[2],ip[1],ip[0]); tmptok.dec = strip; - sprintf(vgcname,"%.*s_%u",PF(tl->t_dir),serial); + sprintf(vgcname,"%.*s_%d",PF(tl->t_dir),serial); vsb = vsb_newauto(); AN(vsb); tl->fb = vsb; Fc(tl, 0, "\t{ .host = VGC_backend_%s },\n",vgcname); - Fh(tl, 1, "\n#define VGC_backend_%s %u\n", vgcname, serial); + Fh(tl, 1, "\n#define VGC_backend_%s %d\n", vgcname, serial); Fb(tl, 0, "\nstatic const struct vrt_backend vgc_dir_priv_%s = {\n", vgcname); @@ -142,9 +135,9 @@ * This assumes that a uint32_t can be safely accessed as an array of 4 * uint8_ts. */ -void +static void vcc_dir_dns_makebackend(struct vcc *tl, - uint32_t *serial, + int *serial, unsigned char a[], int inmask) { @@ -172,7 +165,8 @@ ip4++; } } -void + +static void vcc_dir_dns_parse_backend_options(struct vcc *tl) { struct fld_spec *fs; @@ -253,18 +247,18 @@ /* Parse a list of backends with optional /mask notation, then print out * all relevant backends. */ -void +static void vcc_dir_dns_parse_list(struct vcc *tl, int *serial) { unsigned char a[4],mask; - int ret, nitem; + int ret; ERRCHK(tl); SkipToken(tl, '{'); if (tl->t->tok != CSTR) vcc_dir_dns_parse_backend_options(tl); while (tl->t->tok == CSTR) { mask = 32; - ret = sscanf(tl->t->dec, "%d.%d.%d.%d",&a[0],&a[1],&a[2],&a[3],&a[4]); + ret = sscanf(tl->t->dec, "%hhu.%hhu.%hhu.%hhu",&a[0],&a[1],&a[2],&a[3]); assert(ret == 4); vcc_NextToken(tl); if (tl->t->tok == '/') { From kristian at varnish-cache.org Mon Aug 2 18:30:39 2010 From: kristian at varnish-cache.org (kristian at varnish-cache.org) Date: Mon, 2 Aug 2010 20:30:39 +0200 Subject: r5064 - trunk/varnish-cache/bin/varnishd Message-ID: Author: kristian Date: 2010-08-02 20:30:38 +0200 (Mon, 02 Aug 2010) New Revision: 5064 Modified: trunk/varnish-cache/bin/varnishd/cache_dir_dns.c Log: DNS Director: Include the necessary headers to build on FreeBSD too. Modified: trunk/varnish-cache/bin/varnishd/cache_dir_dns.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-02 10:40:35 UTC (rev 5063) +++ trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-02 18:30:38 UTC (rev 5064) @@ -43,6 +43,8 @@ #include #include +#include + #include "cache.h" #include "cache_backend.h" #include "vrt.h" From kristian at varnish-cache.org Mon Aug 2 19:14:15 2010 From: kristian at varnish-cache.org (kristian at varnish-cache.org) Date: Mon, 2 Aug 2010 21:14:15 +0200 Subject: r5065 - in trunk/varnish-cache: bin/varnishd doc/sphinx/reference lib/libvcl Message-ID: Author: kristian Date: 2010-08-02 21:14:15 +0200 (Mon, 02 Aug 2010) New Revision: 5065 Modified: trunk/varnish-cache/bin/varnishd/cache_center.c trunk/varnish-cache/bin/varnishd/cache_hash.c trunk/varnish-cache/bin/varnishd/steps.h trunk/varnish-cache/doc/sphinx/reference/vcl.rst trunk/varnish-cache/lib/libvcl/generate.py Log: Return(refresh) from VCL recv, allowing a controlled refresh of content (for example from a script). Does not deal with Vary in any particular fashion. Modified: trunk/varnish-cache/bin/varnishd/cache_center.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-02 18:30:38 UTC (rev 5064) +++ trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-02 19:14:15 UTC (rev 5065) @@ -830,6 +830,11 @@ return (0); } +static int +cnt_refresh(struct sess *sp) +{ + return cnt_lookup(sp); +} /*-------------------------------------------------------------------- * We had a miss, ask VCL, proceed as instructed * @@ -1063,6 +1068,9 @@ /* XXX: discard req body, if any */ sp->step = STP_LOOKUP; return (0); + case VCL_RET_REFRESH: + sp->step = STP_REFRESH; + return (0); case VCL_RET_PIPE: if (sp->esis > 0) { /* XXX: VSL something */ @@ -1207,6 +1215,7 @@ sp->step == STP_FIRST || sp->step == STP_START || sp->step == STP_LOOKUP || + sp->step == STP_REFRESH || sp->step == STP_RECV); /* Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_hash.c 2010-08-02 18:30:38 UTC (rev 5064) +++ trunk/varnish-cache/bin/varnishd/cache_hash.c 2010-08-02 19:14:15 UTC (rev 5065) @@ -402,7 +402,8 @@ if (oc == NULL /* We found no live object */ && grace_oc != NULL /* There is a grace candidate */ && (busy_oc != NULL /* Somebody else is already busy */ - || !VBE_Healthy(sp->t_req, sp->director, (uintptr_t)oh))) { + || !VBE_Healthy(sp->t_req, sp->director, (uintptr_t)oh)) + && sp->step != STP_REFRESH) { /* Or it is impossible to fetch: */ o = grace_oc->obj; CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); @@ -414,16 +415,24 @@ o = oc->obj; CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); assert(oc->objhead == oh); - - /* We found an object we like */ - oc->refcnt++; - if (o->hits < INT_MAX) - o->hits++; - assert(oh->refcnt > 1); - Lck_Unlock(&oh->mtx); - assert(hash->deref(oh)); - *poh = oh; - return (oc); + if (sp->step == STP_REFRESH) { + if (o->ttl >= sp->t_req) { + o->ttl = sp->t_req - 1; + o->grace = HSH_Grace(sp->grace); + EXP_Rearm(o); + } + o = NULL; + } else { + /* We found an object we like */ + oc->refcnt++; + if (o->hits < INT_MAX) + o->hits++; + assert(oh->refcnt > 1); + Lck_Unlock(&oh->mtx); + assert(hash->deref(oh)); + *poh = oh; + return (oc); + } } if (busy_oc != NULL) { Modified: trunk/varnish-cache/bin/varnishd/steps.h =================================================================== --- trunk/varnish-cache/bin/varnishd/steps.h 2010-08-02 18:30:38 UTC (rev 5064) +++ trunk/varnish-cache/bin/varnishd/steps.h 2010-08-02 19:14:15 UTC (rev 5065) @@ -36,6 +36,7 @@ STEP(pipe, PIPE) STEP(pass, PASS) STEP(lookup, LOOKUP) +STEP(refresh, REFRESH) STEP(miss, MISS) STEP(hit, HIT) STEP(fetch, FETCH) Modified: trunk/varnish-cache/doc/sphinx/reference/vcl.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/reference/vcl.rst 2010-08-02 18:30:38 UTC (rev 5064) +++ trunk/varnish-cache/doc/sphinx/reference/vcl.rst 2010-08-02 19:14:15 UTC (rev 5065) @@ -310,6 +310,11 @@ pipe Switch to pipe mode. Control will eventually pass to vcl_pipe. + refresh + Go through normal caching channels, but guarantee a cache miss even if + there is valid content in the cache, thereby performing a controlled + refresh of the content. + lookup Look up the requested object in the cache. Control will eventually pass to vcl_hit or vcl_miss, depending on whether the Modified: trunk/varnish-cache/lib/libvcl/generate.py =================================================================== --- trunk/varnish-cache/lib/libvcl/generate.py 2010-08-02 18:30:38 UTC (rev 5064) +++ trunk/varnish-cache/lib/libvcl/generate.py 2010-08-02 19:14:15 UTC (rev 5065) @@ -84,7 +84,7 @@ # Our methods and actions returns =( - ('recv', ('error', 'pass', 'pipe', 'lookup',)), + ('recv', ('error', 'pass', 'pipe', 'refresh','lookup',)), ('pipe', ('error', 'pipe',)), ('pass', ('error', 'restart', 'pass',)), ('hash', ('hash',)), From kristian at varnish-cache.org Mon Aug 2 19:29:50 2010 From: kristian at varnish-cache.org (kristian at varnish-cache.org) Date: Mon, 2 Aug 2010 21:29:50 +0200 Subject: r5066 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: Author: kristian Date: 2010-08-02 21:29:49 +0200 (Mon, 02 Aug 2010) New Revision: 5066 Added: trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc Log: Test-case for return(refresh) Added: trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc (rev 0) +++ trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc 2010-08-02 19:29:49 UTC (rev 5066) @@ -0,0 +1,38 @@ +# $Id: c00024.vtc 4651 2010-04-08 16:21:16Z phk $ + +test "Test return(refresh) in vcl_recv" + +server s1 { + rxreq + txresp -hdr "Inc: 1" + rxreq + txresp -hdr "Inc: 2" +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + if (req.http.x-refresh == "1") { + return(refresh); + } + } + } -start + +client c1 { + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.http.Inc == "1" + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.http.Inc == "1" + txreq -url "/" -hdr "x-refresh: 1" + rxresp + expect resp.status == 200 + expect resp.http.Inc == "2" + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.http.Inc == "2" +} -run + From kristian at varnish-cache.org Mon Aug 2 19:36:29 2010 From: kristian at varnish-cache.org (kristian at varnish-cache.org) Date: Mon, 2 Aug 2010 21:36:29 +0200 Subject: r5067 - trunk/varnish-cache/doc/sphinx/reference Message-ID: Author: kristian Date: 2010-08-02 21:36:28 +0200 (Mon, 02 Aug 2010) New Revision: 5067 Modified: trunk/varnish-cache/doc/sphinx/reference/vcl.rst Log: Update vcl(7) for 2.1: return(foo) is mandatory. Modified: trunk/varnish-cache/doc/sphinx/reference/vcl.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/reference/vcl.rst 2010-08-02 19:29:49 UTC (rev 5066) +++ trunk/varnish-cache/doc/sphinx/reference/vcl.rst 2010-08-02 19:36:28 UTC (rev 5067) @@ -229,7 +229,7 @@ To match an IP address against an ACL, simply use the match operator::: if (client.ip ~ local) { - pipe; + return (pipe); } Grace @@ -276,7 +276,7 @@ sub pipe_if_local { if (client.ip ~ local) { - pipe; + return (pipe); } } @@ -594,8 +594,8 @@ # Normalize the Host: header if (req.http.host ~ "^(www.)?example.com$") { set req.http.host = "www.example.com"; - } - } + } + } HTTP headers can be removed entirely using the remove keyword::: @@ -651,7 +651,7 @@ sub vcl_fetch { if (obj.ttl < 120s) { - set obj.ttl = 120s; + set obj.ttl = 120s; } } @@ -660,13 +660,13 @@ sub vcl_recv { if (req.request == "GET" && req.http.cookie) { - call(lookup); + return(lookup); } } sub vcl_fetch { if (beresp.http.Set-Cookie) { - deliver; + return(deliver); } } @@ -680,11 +680,11 @@ sub vcl_recv { if (req.request == "PURGE") { - if (!client.ip ~ purge) { - error 405 "Not allowed."; + if (!client.ip ~ purge) { + error 405 "Not allowed."; + } + return(lookup); } - lookup; - } } sub vcl_hit { From kristian at varnish-cache.org Mon Aug 2 19:46:49 2010 From: kristian at varnish-cache.org (kristian at varnish-cache.org) Date: Mon, 2 Aug 2010 21:46:49 +0200 Subject: r5068 - trunk/varnish-cache/doc/sphinx/reference Message-ID: Author: kristian Date: 2010-08-02 21:46:49 +0200 (Mon, 02 Aug 2010) New Revision: 5068 Modified: trunk/varnish-cache/doc/sphinx/reference/vcl.rst Log: Clean up obj/beresp left overs in vcl(7). Modified: trunk/varnish-cache/doc/sphinx/reference/vcl.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/reference/vcl.rst 2010-08-02 19:36:28 UTC (rev 5067) +++ trunk/varnish-cache/doc/sphinx/reference/vcl.rst 2010-08-02 19:46:49 UTC (rev 5068) @@ -537,11 +537,31 @@ The time in seconds to wait between each received byte from the backend. Not available in pipe mode. -XXX: Aren't these beresp now? - The following variables are available after the requested object has -been retrieved from cache or from the backend: +been retrieved from the backend, before it is entered into the cache. In +other words, they are available in vcl_fetch: +beresp.proto + The HTTP protocol version used when the object was retrieved. + +beresp.status + The HTTP status code returned by the server. + +beresp.response +The HTTP status message returned by the server. + +beresp.cacheable + True if the request resulted in a cacheable response. A response is + considered cacheable if it is valid (see above), and the HTTP status + code is 200, 203, 300, 301, 302, 404 or 410. + +beresp.ttl + The object's remaining time to live, in seconds. + +After the object is entered into the cache, the following (mostyl +read-only) variables are available when the object has been located in +cache: + obj.proto The HTTP protocol version used when the object was retrieved. @@ -601,7 +621,7 @@ sub vcl_fetch { # Don't cache cookies - remove obj.http.Set-Cookie; + remove beresp.http.Set-Cookie; } EXAMPLES @@ -650,8 +670,8 @@ which the backend did not specify a TTL::: sub vcl_fetch { - if (obj.ttl < 120s) { - set obj.ttl = 120s; + if (beresp.ttl < 120s) { + set beresp.ttl = 120s; } } From phk at varnish-cache.org Tue Aug 3 20:41:39 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Tue, 3 Aug 2010 22:41:39 +0200 Subject: r5069 - trunk/varnish-cache/doc/sphinx/phk Message-ID: Author: phk Date: 2010-08-03 22:41:39 +0200 (Tue, 03 Aug 2010) New Revision: 5069 Added: trunk/varnish-cache/doc/sphinx/phk/platforms.rst Modified: trunk/varnish-cache/doc/sphinx/phk/index.rst Log: Ramblings about why we do not support Zilog S-8000 Zeus as a platform. Modified: trunk/varnish-cache/doc/sphinx/phk/index.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/phk/index.rst 2010-08-02 19:46:49 UTC (rev 5068) +++ trunk/varnish-cache/doc/sphinx/phk/index.rst 2010-08-03 20:41:39 UTC (rev 5069) @@ -8,6 +8,7 @@ .. toctree:: + platforms.rst barriers.rst thoughts.rst autocrap.rst Added: trunk/varnish-cache/doc/sphinx/phk/platforms.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/phk/platforms.rst (rev 0) +++ trunk/varnish-cache/doc/sphinx/phk/platforms.rst 2010-08-03 20:41:39 UTC (rev 5069) @@ -0,0 +1,110 @@ +.. _phk_platforms: + +================= +Picking platforms +================= + +Whenever you write Open Source Software, you have to make a choice of +what platforms you are going to support. + +Generally you want to make your program as portable as possible and +cover as many platforms, distros and weird computers as possible. + +But making your program run on everything is hard work very hard work. + +For instance, did you know that: + + sizeof(void*) != sizeof(const void*) + +is legal in a ISO-C compliant environment ? + +Varnish `runs on a Nokia N900 `_ +but I am not going to go out of my way to make sure that is always +the case. + +To make sense for Varnish, a platform has to be able to deliver, +both in terms of performance, but also in terms of the APIs we +use to get that performance. + +In the FreeBSD project where I grew up, we ended up instituting +platform-tiers, in an effort to document which platforms we +cared about and which we did love quite as much. + +If we did the same for Varnish, the result would look something like: + +A - Platforms we care about +--------------------------- + +We care about these platforms because our users use them and +because they deliver a lot of bang for the buck with Varnish. + +These platforms are in our "tinderbox" tests, we use them ourselves +and they pass all regression tests all the time. +Platform specific bug reports gets acted on. + +*FreeBSD* + +*Linux* + +Obviously you can forget about running Varnish on your +`WRT54G `_ +but if you have a real computer, you can expect Varnish to work +"ok or better" on any distro that has a package available. + +B - Platforms we try not to break +--------------------------------- + +We try not to break these platforms, because they basically work, +possibly with some footnotes or minor limitations, and they have +an active userbase. + +We may or may not test on these platforms on a regular basis, +or we may rely on contributors to alert us to problems. +Platform specific bug reports without patches will likely live a quiet life. + +*Mac OS/X* + +*Solaris*. + +Yes, we'd like to bump Solaris to tier-A but I have to say that the +uncertainty about the future for OpenSolaris, and lack of time to +care and feed the somewhat altmodishe socket-API on Solaris, does +keep the enthusiasm bounded. + +NetBSD, AIX and HP-UX are conceivably candidates for this level, but +so far I have not heard much, if any, user interest. + +C - Platforms we tolerate +------------------------- + +We tolerate any other platform, as long as the burden of doing +so is proportional to the benefit to the Varnish community. + +Do not file bug reports specific to these platforms without attaching +a patch that solves the problem, we will just close it. + +For now, anything else goes here, certainly the N900 and the WRT54G. + +I'm afraid I have to put OpenBSD here for now, it is seriously +behind on socket APIs and working around those issues is just not +worth the effort. + +If people send us a small non-intrusive patches that makes Varnish +run on these platforms, we'll take it. + +If they send us patches that reorganizes everything, hurts code +readability, quality or just generally do not satisfy our taste, +they get told that thanks, but no thanks. + +Is that it ? Abandon all hope etc. ? +------------------------------------- + +These tiers are not static, if for some reason Varnish suddenly +becomes a mandatory accessory to some technically sensible platform, +(zOS anyone ?) that platform will get upgraded. If the pessimists +are right about Oracles intentions, Solaris may get demoted. + + +Until next time, + +Poul-Henning, 2010-08-03 From tfheen at varnish-cache.org Wed Aug 4 12:48:55 2010 From: tfheen at varnish-cache.org (tfheen at varnish-cache.org) Date: Wed, 4 Aug 2010 14:48:55 +0200 Subject: r5070 - trunk/varnish-cache/doc/sphinx/installation Message-ID: Author: tfheen Date: 2010-08-04 14:48:54 +0200 (Wed, 04 Aug 2010) New Revision: 5070 Modified: trunk/varnish-cache/doc/sphinx/installation/install.rst Log: Mention pkg-config in build requirements too Fixes #740 Modified: trunk/varnish-cache/doc/sphinx/installation/install.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/installation/install.rst 2010-08-03 20:41:39 UTC (rev 5069) +++ trunk/varnish-cache/doc/sphinx/installation/install.rst 2010-08-04 12:48:54 UTC (rev 5070) @@ -91,6 +91,7 @@ * xsltproc * groff-base * libpcre3-dev +* pkg-config To install all these just type ``sudo apt-get install autotools-dev automake1.9 libtool autoconf libncurses-dev xsltproc groff-base libpcre3-dev``. From perbu at varnish-cache.org Wed Aug 4 13:13:13 2010 From: perbu at varnish-cache.org (perbu at varnish-cache.org) Date: Wed, 4 Aug 2010 15:13:13 +0200 Subject: r5071 - in trunk/varnish-cache/doc/sphinx: installation tutorial Message-ID: Author: perbu Date: 2010-08-04 15:13:13 +0200 (Wed, 04 Aug 2010) New Revision: 5071 Modified: trunk/varnish-cache/doc/sphinx/installation/install.rst trunk/varnish-cache/doc/sphinx/tutorial/index.rst Log: Remove the command line. Incorrect and not really needed. Modified: trunk/varnish-cache/doc/sphinx/installation/install.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/installation/install.rst 2010-08-04 12:48:54 UTC (rev 5070) +++ trunk/varnish-cache/doc/sphinx/installation/install.rst 2010-08-04 13:13:13 UTC (rev 5071) @@ -93,8 +93,6 @@ * libpcre3-dev * pkg-config -To install all these just type ``sudo apt-get install autotools-dev automake1.9 libtool autoconf libncurses-dev xsltproc groff-base libpcre3-dev``. - Build dependencies on Red Hat / Centos ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Modified: trunk/varnish-cache/doc/sphinx/tutorial/index.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/tutorial/index.rst 2010-08-04 12:48:54 UTC (rev 5070) +++ trunk/varnish-cache/doc/sphinx/tutorial/index.rst 2010-08-04 13:13:13 UTC (rev 5071) @@ -1,25 +1,38 @@ .. _tutorial-index: -%%%%%%%%%%%%%%%% -Varnish Tutorial -%%%%%%%%%%%%%%%% +%%%%%%%%%%%%% +Using Varnish +%%%%%%%%%%%%% -Varnish is a web accelerator. It is installed in front of your web -application and it caches the reponses, making your web site run Varnish -is fast, flexible and easy to use. +This tutorial is intended for system administrators managing Varnish +cache. The reader should know how to configure her web- or application +server and have basic knowledge of the HTTP protocol. The reader +should have Varnish up and running with the default configuration. -This tutorial does not go through every bit of functionality Varnish -has. It will give you a good overview of what Varnish does and how it -is done. +Good luck. -We assume you have a web server and a web application up and running -and that you want to accelerate this application with Varnish. +TOC -Furthermore we assume you have read the :ref:`install-index` and that -it is installed with the default configuration. + Getting Varnish Running + backend_servers.rst + starting_varnish.rst + logging.rst + sizing_your_cache.rst + putting_varnish_on_port_80.rst + The Varnish Configuration Language + vcl.rst -Good luck. + Tuning Varnish + increasing_your_hitrate.rst + advanced_backend_servers.rst + handling_misbehaving_servers.rst + Advanced topics + advanced_topics.rst + +Troubleshooting and getting help + troubleshooting.rst + .. toctree:: backend_servers.rst From phk at varnish-cache.org Mon Aug 9 06:10:18 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 9 Aug 2010 08:10:18 +0200 Subject: r5072 - trunk/varnish-cache/bin/varnishtest Message-ID: Author: phk Date: 2010-08-09 08:10:17 +0200 (Mon, 09 Aug 2010) New Revision: 5072 Modified: trunk/varnish-cache/bin/varnishtest/vtc.c Log: Fix the error emitted if quotes on a line are not properly balanced. Modified: trunk/varnish-cache/bin/varnishtest/vtc.c =================================================================== --- trunk/varnish-cache/bin/varnishtest/vtc.c 2010-08-04 13:13:13 UTC (rev 5071) +++ trunk/varnish-cache/bin/varnishtest/vtc.c 2010-08-09 06:10:17 UTC (rev 5072) @@ -227,7 +227,7 @@ { char *token_s[MAX_TOKENS], *token_e[MAX_TOKENS]; struct vsb *token_exp[MAX_TOKENS]; - char *p, *q; + char *p, *q, *f; int nest_brace; int tn; const struct cmds *cp; @@ -249,6 +249,7 @@ /* First content on line, collect tokens */ tn = 0; + f = p; while (*p != '\0') { assert(tn < MAX_TOKENS); if (*p == '\n') { /* End on NL */ @@ -273,8 +274,9 @@ q++; } else { if (*p == '\n') - fprintf(stderr, - "Unterminated quoted string in line:\n%s", p); + vtc_log(vl, 0, + "Unterminated quoted string in line: %*.*s", + (int)(p - f), (int)(p - f), f); assert(*p != '\n'); *q++ = *p; } From phk at varnish-cache.org Mon Aug 9 06:22:27 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 9 Aug 2010 08:22:27 +0200 Subject: r5073 - in trunk/varnish-cache/bin: varnishd varnishtest/tests Message-ID: Author: phk Date: 2010-08-09 08:22:27 +0200 (Mon, 09 Aug 2010) New Revision: 5073 Added: trunk/varnish-cache/bin/varnishtest/tests/r00742.vtc Modified: trunk/varnish-cache/bin/varnishd/mgt_vcc.c trunk/varnish-cache/bin/varnishd/varnishd.c Log: Don't explode in vcl.show if VCL code contains a '%' sign. Fixes: 742 Modified: trunk/varnish-cache/bin/varnishd/mgt_vcc.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_vcc.c 2010-08-09 06:10:17 UTC (rev 5072) +++ trunk/varnish-cache/bin/varnishd/mgt_vcc.c 2010-08-09 06:22:27 UTC (rev 5073) @@ -671,6 +671,8 @@ /* * XXX: This should take an option argument to show all (include) files + * XXX: This violates the principle of not loading VCL's in the master + * XXX: process. */ void mcf_config_show(struct cli *cli, const char * const *av, void *priv) @@ -692,7 +694,7 @@ AZ(dlclose(dlh)); } else { src = sym; - cli_out(cli, src[0]); + cli_out(cli, "%s", src[0]); /* cli_out(cli, src[1]); */ AZ(dlclose(dlh)); } Modified: trunk/varnish-cache/bin/varnishd/varnishd.c =================================================================== --- trunk/varnish-cache/bin/varnishd/varnishd.c 2010-08-09 06:10:17 UTC (rev 5072) +++ trunk/varnish-cache/bin/varnishd/varnishd.c 2010-08-09 06:22:27 UTC (rev 5073) @@ -493,6 +493,7 @@ MCF_ParamSet(cli, "user", optarg); break; case 'V': + /* XXX: we should print the ident here */ varnish_version("varnishd"); exit(0); case 'x': Added: trunk/varnish-cache/bin/varnishtest/tests/r00742.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/r00742.vtc (rev 0) +++ trunk/varnish-cache/bin/varnishtest/tests/r00742.vtc 2010-08-09 06:22:27 UTC (rev 5073) @@ -0,0 +1,24 @@ +# $Id# + +test "% escapes in VCL source and vcl.show" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { + C{ + void foo(void) + { + printf("%s %s %s", "foo", "bar", "barf"); + } + }C +} -start + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok "vcl.show vcl1" From phk at varnish-cache.org Mon Aug 9 06:55:53 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 9 Aug 2010 08:55:53 +0200 Subject: r5074 - in trunk/varnish-cache/bin: varnishd varnishtest varnishtest/tests Message-ID: Author: phk Date: 2010-08-09 08:55:52 +0200 (Mon, 09 Aug 2010) New Revision: 5074 Added: trunk/varnish-cache/bin/varnishtest/tests/r00730.vtc Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_center.c trunk/varnish-cache/bin/varnishtest/vtc_varnish.c Log: Do not suppress the Content-Length:, Age:, Range: and Proxy-Auth headers from the backend on a pass operation. Fixes: #730 Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2010-08-09 06:22:27 UTC (rev 5073) +++ trunk/varnish-cache/bin/varnishd/cache.h 2010-08-09 06:55:52 UTC (rev 5074) @@ -416,6 +416,7 @@ enum step step; unsigned cur_method; unsigned handling; + unsigned char pass; unsigned char sendbody; unsigned char wantbody; int err_code; Modified: trunk/varnish-cache/bin/varnishd/cache_center.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-09 06:22:27 UTC (rev 5073) +++ trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-09 06:55:52 UTC (rev 5074) @@ -532,7 +532,7 @@ AZ(sp->objcore); } - l = http_EstimateWS(sp->wrk->beresp, HTTPH_A_INS, &nhttp); + l = http_EstimateWS(sp->wrk->beresp, sp->pass ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp); if (vary != NULL) l += varyl; @@ -584,7 +584,7 @@ hp2->logtag = HTTP_Obj; http_CopyResp(hp2, hp); - http_FilterFields(sp->wrk, sp->fd, hp2, hp, HTTPH_A_INS); + http_FilterFields(sp->wrk, sp->fd, hp2, hp, sp->pass ? HTTPH_R_PASS : HTTPH_A_INS); http_CopyHome(sp->wrk, sp->fd, hp2); if (http_GetHdr(hp, H_Last_Modified, &b)) @@ -954,6 +954,7 @@ sp->acct_tmp.pass++; sp->sendbody = 1; sp->step = STP_FETCH; + sp->pass = 1; return (0); } @@ -1041,6 +1042,7 @@ AN(sp->director); sp->disable_esi = 0; + sp->pass = 0; VCL_recv_method(sp); recv_handling = sp->handling; Added: trunk/varnish-cache/bin/varnishtest/tests/r00730.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/r00730.vtc (rev 0) +++ trunk/varnish-cache/bin/varnishtest/tests/r00730.vtc 2010-08-09 06:55:52 UTC (rev 5074) @@ -0,0 +1,33 @@ +# $Id$ + +test "Check that HEAD returns Content-Length: if backend provides" + +server s1 { + rxreq + txresp -bodylen 5 + rxreq + txresp -bodylen 6 +} -start + +varnish v1 -vcl+backend { +} -start + +client c1 { + txreq -req HEAD + rxresp -no_obj + expect resp.http.content-length == 5 +} -run + + +varnish v1 -vcl+backend { + sub vcl_recv { + return (pass); + } +} + +client c1 { + txreq -req HEAD + rxresp -no_obj + expect resp.http.content-length == 6 +} -run + Modified: trunk/varnish-cache/bin/varnishtest/vtc_varnish.c =================================================================== --- trunk/varnish-cache/bin/varnishtest/vtc_varnish.c 2010-08-09 06:22:27 UTC (rev 5073) +++ trunk/varnish-cache/bin/varnishtest/vtc_varnish.c 2010-08-09 06:55:52 UTC (rev 5074) @@ -198,7 +198,8 @@ vtc_logclose(v->vl); free(v->name); free(v->workdir); - VSM_Delete(v->vd); + if (v->vd != NULL) + VSM_Delete(v->vd); /* * We do not delete the workdir, it may contain stuff people From phk at varnish-cache.org Mon Aug 9 08:14:16 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 9 Aug 2010 10:14:16 +0200 Subject: r5075 - in trunk/varnish-cache/bin: varnishd varnishtest varnishtest/tests Message-ID: Author: phk Date: 2010-08-09 10:14:15 +0200 (Mon, 09 Aug 2010) New Revision: 5075 Added: trunk/varnish-cache/bin/varnishtest/tests/r00733.vtc Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c trunk/varnish-cache/bin/varnishtest/tests/b00011.vtc trunk/varnish-cache/bin/varnishtest/tests/b00027.vtc trunk/varnish-cache/bin/varnishtest/tests/e00007.vtc trunk/varnish-cache/bin/varnishtest/tests/e00014.vtc trunk/varnish-cache/bin/varnishtest/vtc_http.c Log: If we get a HTTP/1.1 response with no indicatation of length, assume EOF encoding, rather than zero length. This has implications for a number of testcases which were written using the previous assumption. Fixes: #733 Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-09 06:55:52 UTC (rev 5074) +++ trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-09 08:14:15 UTC (rev 5075) @@ -446,7 +446,10 @@ is_head = (strcasecmp(http_GetReq(sp->wrk->bereq), "head") == 0); - /* Determine if we have a body or not */ + /* + * Determine if we have a body or not + * XXX: Missing: RFC2616 sec. 4.4 in re 1xx, 204 & 304 responses + */ cls = 0; mklen = 0; if (is_head) { @@ -493,6 +496,7 @@ * Assume zero length * XXX: ??? */ + cls = fetch_eof(sp, sp->wrk->htc); mklen = 1; } Modified: trunk/varnish-cache/bin/varnishtest/tests/b00011.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/b00011.vtc 2010-08-09 06:55:52 UTC (rev 5074) +++ trunk/varnish-cache/bin/varnishtest/tests/b00011.vtc 2010-08-09 08:14:15 UTC (rev 5075) @@ -4,7 +4,9 @@ server s1 { rxreq - txresp -hdr "Connection: close" + send "HTTP/1.1 200 Ok\n" + send "Connection: close\n" + send "\n" send "Body line 1\n" send "Body line 2\n" send "Body line 3\n" Modified: trunk/varnish-cache/bin/varnishtest/tests/b00027.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/b00027.vtc 2010-08-09 06:55:52 UTC (rev 5074) +++ trunk/varnish-cache/bin/varnishtest/tests/b00027.vtc 2010-08-09 08:14:15 UTC (rev 5075) @@ -8,7 +8,9 @@ rxreq txresp -proto HTTP/1.0 -hdr "Connection: keep-alive" rxreq - txresp -hdr "Transfer-encoding: foobar" + send "HTTP/1.1 200 Ok\n" + send "Transfer-encoding: foobar\n" + send "\n" } -start varnish v1 -vcl+backend {} -start Modified: trunk/varnish-cache/bin/varnishtest/tests/e00007.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/e00007.vtc 2010-08-09 06:55:52 UTC (rev 5074) +++ trunk/varnish-cache/bin/varnishtest/tests/e00007.vtc 2010-08-09 08:14:15 UTC (rev 5075) @@ -18,7 +18,9 @@ server s1 { rxreq expect req.url == "/foo/bar" - txresp -hdr "Connection: close" + send "HTTP/1.1 200 Ok\n" + send "Connection: close\n" + send "\n" send { filler This is before the test Modified: trunk/varnish-cache/bin/varnishtest/tests/e00014.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/e00014.vtc 2010-08-09 06:55:52 UTC (rev 5074) +++ trunk/varnish-cache/bin/varnishtest/tests/e00014.vtc 2010-08-09 08:14:15 UTC (rev 5075) @@ -5,7 +5,9 @@ server s1 { rxreq expect req.url == "/foo" - txresp -hdr "Connection: close" + send "HTTP/1.1 200 Ok\n" + send "Connection: close\n" + send "\n" send { } } -start Added: trunk/varnish-cache/bin/varnishtest/tests/r00733.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/r00733.vtc (rev 0) +++ trunk/varnish-cache/bin/varnishtest/tests/r00733.vtc 2010-08-09 08:14:15 UTC (rev 5075) @@ -0,0 +1,18 @@ +# $Id$ + +test "HTTP/1.1 Backend sends no length hint" + +server s1 { + rxreq + send "HTTP/1.1 200 Ok\n" + send "\n" + send "12345" +} -start + +varnish v1 -vcl+backend {} -start + +client c1 { + txreq + rxresp + expect resp.bodylen == 5 +} -run Modified: trunk/varnish-cache/bin/varnishtest/vtc_http.c =================================================================== --- trunk/varnish-cache/bin/varnishtest/vtc_http.c 2010-08-09 06:55:52 UTC (rev 5074) +++ trunk/varnish-cache/bin/varnishtest/vtc_http.c 2010-08-09 08:14:15 UTC (rev 5075) @@ -507,7 +507,8 @@ const char *msg = "Ok"; int bodylen = 0; char *b, *c; - char *body = NULL; + char *body = NULL, *nullbody; + (void)cmd; (void)vl; @@ -518,6 +519,10 @@ vsb_clear(hp->vsb); + /* send a "Content-Length: 0" header unless something else happens */ + REPLACE(body, ""); + nullbody = body; + for(; *av != NULL; av++) { if (!strcmp(*av, "-proto")) { proto = av[1]; @@ -544,8 +549,9 @@ } for(; *av != NULL; av++) { if (!strcmp(*av, "-body")) { - AZ(body); + assert(body == nullbody); REPLACE(body, av[1]); + AN(body); av++; bodylen = strlen(body); @@ -560,7 +566,7 @@ } } } else if (!strcmp(*av, "-bodylen")) { - AZ(body); + assert(body == nullbody); body = synth_body(av[1]); bodylen = strlen(body); av++; From perbu at varnish-cache.org Mon Aug 9 12:11:19 2010 From: perbu at varnish-cache.org (perbu at varnish-cache.org) Date: Mon, 9 Aug 2010 14:11:19 +0200 Subject: r5076 - trunk/varnish-cache/doc/sphinx/tutorial Message-ID: Author: perbu Date: 2010-08-09 14:11:19 +0200 (Mon, 09 Aug 2010) New Revision: 5076 Modified: trunk/varnish-cache/doc/sphinx/tutorial/advanced_backend_servers.rst Log: add initial and duplcation of probes Modified: trunk/varnish-cache/doc/sphinx/tutorial/advanced_backend_servers.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/tutorial/advanced_backend_servers.rst 2010-08-09 08:14:15 UTC (rev 5075) +++ trunk/varnish-cache/doc/sphinx/tutorial/advanced_backend_servers.rst 2010-08-09 12:11:19 UTC (rev 5076) @@ -126,6 +126,10 @@ threshold How many of the .window last polls must be good for the backend to be declared healthy. +initial + How many of the of the probes a good when Varnish starts - defaults + to the same amount as the threshold. + Now we define the director.:: director example_director round-robin { @@ -144,3 +148,8 @@ unhealty. Varnish can also serve stale content if all the backends are down. See :ref:`tutorial-handling_misbehaving_servers` for more information on how to enable this. + +Please note that Varnish will keep probes active for all loaded +VCLs. Varnish will coalesce probes that seem identical - so be careful +not to change the probe config if you do a lot of VCL +loading. Unloading the VCL will discard the probes. From phk at varnish-cache.org Mon Aug 9 15:05:52 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 9 Aug 2010 17:05:52 +0200 Subject: r5077 - trunk/varnish-cache/doc/sphinx/phk Message-ID: Author: phk Date: 2010-08-09 17:05:52 +0200 (Mon, 09 Aug 2010) New Revision: 5077 Added: trunk/varnish-cache/doc/sphinx/phk/backends.rst Modified: trunk/varnish-cache/doc/sphinx/phk/index.rst Log: upd Added: trunk/varnish-cache/doc/sphinx/phk/backends.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/phk/backends.rst (rev 0) +++ trunk/varnish-cache/doc/sphinx/phk/backends.rst 2010-08-09 15:05:52 UTC (rev 5077) @@ -0,0 +1,121 @@ +.. _phk_backends: + +=============================== +What do you mean by 'backend' ? +=============================== + +Given that we are approaching Varnish 3.0, you would think I had this +question answered conclusively long time ago, but once you try to +be efficient, things get hairy fast. + +One of the features of Varnish we are very fundamental about, is the +ability to have multiple VCL's loaded at the same time, and to switch +between them instantly and seamlessly. + +So Imagine you have 1000 backends in your VCL, not an unreasonable +number, each configured with health-polling. + +Now you fiddle your vcl_recv{} a bit and load the VCL again, but +since you are not sure which is the best way to do it, you keep +both VCL's loaded so you can switch forth and back seamlessly. + +To switch seamlessly, the health status of each backend needs to +be up to date the instant we switch to the other VCL. + +This basically means that either all VCLs poll all their backends, +or they must share, somehow. + +We can dismiss the all VCL's poll all their backends scenario, +because it scales truly horribly, and would pummel backends with +probes if people forget to vcl.discard their old dusty VCLs. + +Share And Enjoy +=============== + +In addition to health-status (including the saint-list), we also +want to share cached open connections and stats counters. + +It would be truly stupid to close 100 ready and usable connections to +a backend, and open 100 other, just because we switch to a different +VCL that has an identical backend definition. + +But what is an identical backend definition in this context ? + +It is important to remember that we are not talking physical +backends: For instance, there is nothing preventing a VCL for +having the same physical backend declared as 4 different VCL +backends. + +The most obvious thing to do, is to use the VCL name of the backend +as identifier, but that is not enough. We can have two different +VCL's where backend "b1" points at two different physical machines, +for instance when we migrate or upgrade the backend. + +The identity of the state than can be shared is therefore the triplet: + {VCL-name, IPv4+port, IPv6+port} + +No Information without Representation +===================================== + +Since the health-status will be for each of these triplets, we will +need to find a way to represent them in CLI and statistics contexts. + +As long as we just print them out, that is not a big deal, but what +if you just want the health status for one of your 1000 backends, +how do you tell which one ? + +The syntax-nazi way of doing that, is forcing people to type it all +every time:: + + backend.health b1(127.0.0.1:8080,[::1]:8080) + +That will surely not be a hit with people who have just one backend. + +I think, but until I implement I will not commit to, that the solution +is a wildcard-ish scheme, where you can write things like:: + + b1 # The one and only backend b1 or error + + b1() # All backends named b1 + + b1(127.0.0.1) # All b1's on Ipv4 lookback + + b1(:8080) # All b1's on port 8080, (IPv4 or IPv6) + + b1(192.168.60.1,192.168.60.2) # All b1's on one of those addresses. + +(Input very much welcome) + +The final question is if we use shortcut notation for output from +varnishd, and the answer is no, because we do not want the stats-counters +to change name because we load another VCL and suddenly need disabiguation. + + +Sharing Health Status +===================== + +To avoid the over-polling, we define that maximum one VCL polls at +backend at any time, and the active VCL gets preference. It is not +important which particular VCL polls the backends not in the active +VCL, as long as one of them do. + +Implementation +============== + +The poll-policy can be implemented by updating a back-pointer to +the poll-specification for all backends on vcl.use execution. + +On vcl.discard, if this vcl was the active poller, it needs to walk +the list of vcls and substitute another. If the list is empty +the backend gets retired anyway. + +We should either park a thread on each backend, or have a poller thread +which throws jobs into the work-pool as the backends needs polled. + +The patternmatching is confined to CLI and possibly libvarnishapi + +I think this will work, + +Until next time, + +Poul-Henning, 2010-08-09 Modified: trunk/varnish-cache/doc/sphinx/phk/index.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/phk/index.rst 2010-08-09 12:11:19 UTC (rev 5076) +++ trunk/varnish-cache/doc/sphinx/phk/index.rst 2010-08-09 15:05:52 UTC (rev 5077) @@ -8,6 +8,7 @@ .. toctree:: + backends.rst platforms.rst barriers.rst thoughts.rst From kristian at varnish-cache.org Tue Aug 10 08:27:07 2010 From: kristian at varnish-cache.org (kristian at varnish-cache.org) Date: Tue, 10 Aug 2010 10:27:07 +0200 Subject: r5078 - in trunk/varnish-cache: bin/varnishd bin/varnishtest/tests doc/sphinx/reference lib/libvcl Message-ID: Author: kristian Date: 2010-08-10 10:27:07 +0200 (Tue, 10 Aug 2010) New Revision: 5078 Modified: trunk/varnish-cache/bin/varnishd/cache_center.c trunk/varnish-cache/bin/varnishd/cache_hash.c trunk/varnish-cache/bin/varnishd/steps.h trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc trunk/varnish-cache/doc/sphinx/reference/vcl.rst trunk/varnish-cache/lib/libvcl/generate.py Log: Revert the return(refresh) patches (better approach coming soon-ish) Modified: trunk/varnish-cache/bin/varnishd/cache_center.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-09 15:05:52 UTC (rev 5077) +++ trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-10 08:27:07 UTC (rev 5078) @@ -830,11 +830,6 @@ return (0); } -static int -cnt_refresh(struct sess *sp) -{ - return cnt_lookup(sp); -} /*-------------------------------------------------------------------- * We had a miss, ask VCL, proceed as instructed * @@ -1070,9 +1065,6 @@ /* XXX: discard req body, if any */ sp->step = STP_LOOKUP; return (0); - case VCL_RET_REFRESH: - sp->step = STP_REFRESH; - return (0); case VCL_RET_PIPE: if (sp->esis > 0) { /* XXX: VSL something */ @@ -1217,7 +1209,6 @@ sp->step == STP_FIRST || sp->step == STP_START || sp->step == STP_LOOKUP || - sp->step == STP_REFRESH || sp->step == STP_RECV); /* Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_hash.c 2010-08-09 15:05:52 UTC (rev 5077) +++ trunk/varnish-cache/bin/varnishd/cache_hash.c 2010-08-10 08:27:07 UTC (rev 5078) @@ -402,8 +402,7 @@ if (oc == NULL /* We found no live object */ && grace_oc != NULL /* There is a grace candidate */ && (busy_oc != NULL /* Somebody else is already busy */ - || !VBE_Healthy(sp->t_req, sp->director, (uintptr_t)oh)) - && sp->step != STP_REFRESH) { + || !VBE_Healthy(sp->t_req, sp->director, (uintptr_t)oh))) { /* Or it is impossible to fetch: */ o = grace_oc->obj; CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); @@ -415,24 +414,16 @@ o = oc->obj; CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); assert(oc->objhead == oh); - if (sp->step == STP_REFRESH) { - if (o->ttl >= sp->t_req) { - o->ttl = sp->t_req - 1; - o->grace = HSH_Grace(sp->grace); - EXP_Rearm(o); - } - o = NULL; - } else { - /* We found an object we like */ - oc->refcnt++; - if (o->hits < INT_MAX) - o->hits++; - assert(oh->refcnt > 1); - Lck_Unlock(&oh->mtx); - assert(hash->deref(oh)); - *poh = oh; - return (oc); - } + + /* We found an object we like */ + oc->refcnt++; + if (o->hits < INT_MAX) + o->hits++; + assert(oh->refcnt > 1); + Lck_Unlock(&oh->mtx); + assert(hash->deref(oh)); + *poh = oh; + return (oc); } if (busy_oc != NULL) { Modified: trunk/varnish-cache/bin/varnishd/steps.h =================================================================== --- trunk/varnish-cache/bin/varnishd/steps.h 2010-08-09 15:05:52 UTC (rev 5077) +++ trunk/varnish-cache/bin/varnishd/steps.h 2010-08-10 08:27:07 UTC (rev 5078) @@ -36,7 +36,6 @@ STEP(pipe, PIPE) STEP(pass, PASS) STEP(lookup, LOOKUP) -STEP(refresh, REFRESH) STEP(miss, MISS) STEP(hit, HIT) STEP(fetch, FETCH) Modified: trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc 2010-08-09 15:05:52 UTC (rev 5077) +++ trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc 2010-08-10 08:27:07 UTC (rev 5078) @@ -1,38 +0,0 @@ -# $Id: c00024.vtc 4651 2010-04-08 16:21:16Z phk $ - -test "Test return(refresh) in vcl_recv" - -server s1 { - rxreq - txresp -hdr "Inc: 1" - rxreq - txresp -hdr "Inc: 2" -} -start - -varnish v1 -vcl+backend { - sub vcl_recv { - if (req.http.x-refresh == "1") { - return(refresh); - } - } - } -start - -client c1 { - txreq -url "/" - rxresp - expect resp.status == 200 - expect resp.http.Inc == "1" - txreq -url "/" - rxresp - expect resp.status == 200 - expect resp.http.Inc == "1" - txreq -url "/" -hdr "x-refresh: 1" - rxresp - expect resp.status == 200 - expect resp.http.Inc == "2" - txreq -url "/" - rxresp - expect resp.status == 200 - expect resp.http.Inc == "2" -} -run - Modified: trunk/varnish-cache/doc/sphinx/reference/vcl.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/reference/vcl.rst 2010-08-09 15:05:52 UTC (rev 5077) +++ trunk/varnish-cache/doc/sphinx/reference/vcl.rst 2010-08-10 08:27:07 UTC (rev 5078) @@ -310,11 +310,6 @@ pipe Switch to pipe mode. Control will eventually pass to vcl_pipe. - refresh - Go through normal caching channels, but guarantee a cache miss even if - there is valid content in the cache, thereby performing a controlled - refresh of the content. - lookup Look up the requested object in the cache. Control will eventually pass to vcl_hit or vcl_miss, depending on whether the Modified: trunk/varnish-cache/lib/libvcl/generate.py =================================================================== --- trunk/varnish-cache/lib/libvcl/generate.py 2010-08-09 15:05:52 UTC (rev 5077) +++ trunk/varnish-cache/lib/libvcl/generate.py 2010-08-10 08:27:07 UTC (rev 5078) @@ -84,7 +84,7 @@ # Our methods and actions returns =( - ('recv', ('error', 'pass', 'pipe', 'refresh','lookup',)), + ('recv', ('error', 'pass', 'pipe', 'lookup',)), ('pipe', ('error', 'pipe',)), ('pass', ('error', 'restart', 'pass',)), ('hash', ('hash',)), From kristian at varnish-cache.org Tue Aug 10 08:29:02 2010 From: kristian at varnish-cache.org (kristian at varnish-cache.org) Date: Tue, 10 Aug 2010 10:29:02 +0200 Subject: r5079 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: Author: kristian Date: 2010-08-10 10:29:02 +0200 (Tue, 10 Aug 2010) New Revision: 5079 Removed: trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc Log: Remove empty return(refresh) test case Deleted: trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc =================================================================== From phk at varnish-cache.org Tue Aug 10 09:08:21 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Tue, 10 Aug 2010 11:08:21 +0200 Subject: r5080 - in trunk/varnish-cache: bin/varnishd bin/varnishtest/tests lib/libvcl Message-ID: Author: phk Date: 2010-08-10 11:08:21 +0200 (Tue, 10 Aug 2010) New Revision: 5080 Added: trunk/varnish-cache/bin/varnishtest/tests/v00028.vtc Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_center.c trunk/varnish-cache/bin/varnishd/cache_dir_random.c trunk/varnish-cache/bin/varnishd/cache_vrt.c trunk/varnish-cache/bin/varnishd/mgt_cli.c trunk/varnish-cache/lib/libvcl/generate.py Log: Add a new VCL variable "client.identity" which defaults to client.ip (without port number). This variable is used by the "client" director to distribute sessions across multiple backends. Having it be a separate variable from client.ip makes it possible to fill it from X-Forwarded-For: or Cookie headers. Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2010-08-10 08:29:02 UTC (rev 5079) +++ trunk/varnish-cache/bin/varnishd/cache.h 2010-08-10 09:08:21 UTC (rev 5080) @@ -390,6 +390,7 @@ /* formatted ascii client address */ char *addr; char *port; + char *client_identity; /* HTTP request */ const char *doclose; Modified: trunk/varnish-cache/bin/varnishd/cache_center.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-10 08:29:02 UTC (rev 5079) +++ trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-10 09:08:21 UTC (rev 5080) @@ -1038,6 +1038,7 @@ sp->disable_esi = 0; sp->pass = 0; + sp->client_identity = NULL; VCL_recv_method(sp); recv_handling = sp->handling; Modified: trunk/varnish-cache/bin/varnishd/cache_dir_random.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_random.c 2010-08-10 08:29:02 UTC (rev 5079) +++ trunk/varnish-cache/bin/varnishd/cache_dir_random.c 2010-08-10 09:08:21 UTC (rev 5080) @@ -106,7 +106,11 @@ */ SHA256_Init(&ctx); AN(sp->addr); - SHA256_Update(&ctx, sp->addr, strlen(sp->addr)); + if (sp->client_identity != NULL) + SHA256_Update(&ctx, sp->client_identity, + strlen(sp->client_identity)); + else + SHA256_Update(&ctx, sp->addr, strlen(sp->addr)); SHA256_Final(sign, &ctx); hp = sign; } Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-10 08:29:02 UTC (rev 5079) +++ trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-10 09:08:21 UTC (rev 5080) @@ -371,7 +371,7 @@ /*--------------------------------------------------------------------*/ -#define VBEREQ(dir, type,onm,field) \ +#define VBEREQ(dir, type, onm, field) \ void \ VRT_l_##dir##_##onm(const struct sess *sp, type a) \ { \ @@ -389,6 +389,30 @@ VBEREQ(beresp, unsigned, cacheable, cacheable) VBEREQ(beresp, double, grace, grace) +/*--------------------------------------------------------------------*/ + +const char * +VRT_r_client_identity(struct sess *sp) +{ + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + if (sp->client_identity != NULL) + return (sp->client_identity); + else + return (sp->addr); +} + +void +VRT_l_client_identity(struct sess *sp, const char *str, ...) +{ + va_list ap; + char *b; + + va_start(ap, str); + b = vrt_assemble_string(sp->http, NULL, str, ap); + va_end(ap); + sp->client_identity = b; +} + /*-------------------------------------------------------------------- * XXX: Working relative to t_req is maybe not the right thing, we could * XXX: have spent a long time talking to the backend since then. Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-10 08:29:02 UTC (rev 5079) +++ trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-10 09:08:21 UTC (rev 5080) @@ -187,8 +187,7 @@ } assert(i == 1 || errno == EPIPE); - (void)cli_readres(cli_i, - &u, &q, params->cli_timeout); + (void)cli_readres(cli_i, &u, &q, params->cli_timeout); cli_result(cli, u); cli_out(cli, "%s", q); free(q); Added: trunk/varnish-cache/bin/varnishtest/tests/v00028.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/v00028.vtc (rev 0) +++ trunk/varnish-cache/bin/varnishtest/tests/v00028.vtc 2010-08-10 09:08:21 UTC (rev 5080) @@ -0,0 +1,56 @@ +# $Id$ + +test "Client director" + +server s1 { + rxreq + txresp -hdr "be: s1" -bodylen 1 +} -start + +server s2 { + rxreq + txresp -hdr "be: s2" -bodylen 2 + rxreq + txresp -hdr "be: s2" -bodylen 4 +} -start + +varnish v1 -vcl+backend { + director d1 client { + { .backend = s1; .weight = 1; } + { .backend = s2; .weight = 1; } + } + + sub vcl_recv { + set req.backend = d1; + if (req.http.id) { + set client.identity = req.http.id; + } + return (pass); + } + sub vcl_deliver { + set resp.http.id = client.identity; + } +} -start + + +client c1 { + txreq + rxresp + expect resp.http.id == "127.0.0.1" + expect resp.http.be == s2 + expect resp.bodylen == 2 + + txreq -hdr "id: foo" + rxresp + expect resp.http.id == "foo" + expect resp.http.be == s1 + expect resp.bodylen == 1 + + txreq -hdr "id: baz" + rxresp + expect resp.http.id == "baz" + expect resp.http.be == s2 + expect resp.bodylen == 4 +} -run + + Modified: trunk/varnish-cache/lib/libvcl/generate.py =================================================================== --- trunk/varnish-cache/lib/libvcl/generate.py 2010-08-10 08:29:02 UTC (rev 5079) +++ trunk/varnish-cache/lib/libvcl/generate.py 2010-08-10 09:08:21 UTC (rev 5080) @@ -106,6 +106,12 @@ ( ), 'const struct sess *' ), + ('client.identity', + 'STRING', + ( 'all',), + ( 'all',), + 'struct sess *' + ), ('server.ip', 'IP', ( 'all',), From phk at varnish-cache.org Tue Aug 10 09:23:39 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Tue, 10 Aug 2010 11:23:39 +0200 Subject: r5081 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-10 11:23:39 +0200 (Tue, 10 Aug 2010) New Revision: 5081 Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_backend.c trunk/varnish-cache/bin/varnishd/cache_fetch.c trunk/varnish-cache/bin/varnishd/cache_pipe.c Log: VBE_ClosedFd() was badly named, loose the 'd' to indicate that it will close the Fd, rather than being an indication this already happened. Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2010-08-10 09:08:21 UTC (rev 5080) +++ trunk/varnish-cache/bin/varnishd/cache.h 2010-08-10 09:23:39 UTC (rev 5081) @@ -476,7 +476,7 @@ struct vbe_conn *VBE_GetFd(const struct director *, struct sess *sp); int VBE_Healthy(double now, const struct director *, uintptr_t target); int VBE_Healthy_sp(const struct sess *sp, const struct director *); -void VBE_ClosedFd(struct sess *sp); +void VBE_CloseFd(struct sess *sp); void VBE_RecycleFd(struct sess *sp); void VBE_AddHostHeader(const struct sess *sp); void VBE_Poll(void); Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-10 09:08:21 UTC (rev 5080) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-10 09:23:39 UTC (rev 5081) @@ -342,7 +342,7 @@ } VSC_main->backend_toolate++; sp->vbe = vc; - VBE_ClosedFd(sp); + VBE_CloseFd(sp); } if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, bp)) { @@ -374,7 +374,7 @@ /* Close a connection ------------------------------------------------*/ void -VBE_ClosedFd(struct sess *sp) +VBE_CloseFd(struct sess *sp) { struct backend *bp; Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-10 09:08:21 UTC (rev 5080) +++ trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-10 09:23:39 UTC (rev 5081) @@ -374,7 +374,7 @@ i = FetchReqBody(sp); if (WRW_FlushRelease(w) || i > 0) { WSP(sp, SLT_FetchError, "backend write error: %d", errno); - VBE_ClosedFd(sp); + VBE_CloseFd(sp); /* XXX: other cleanup ? */ return (__LINE__); } @@ -397,7 +397,7 @@ if (i < 0) { WSP(sp, SLT_FetchError, "http read error: %d", errno); - VBE_ClosedFd(sp); + VBE_CloseFd(sp); /* XXX: other cleanup ? */ return (__LINE__); } @@ -412,7 +412,7 @@ if (http_DissectResponse(sp->wrk, sp->wrk->htc, hp)) { WSP(sp, SLT_FetchError, "http format error"); - VBE_ClosedFd(sp); + VBE_CloseFd(sp); /* XXX: other cleanup ? */ return (__LINE__); } @@ -466,7 +466,7 @@ sp->wrk->stats.fetch_bad++; /* XXX: AUGH! */ WSL(sp->wrk, SLT_Debug, vc->fd, "Invalid Transfer-Encoding"); - VBE_ClosedFd(sp); + VBE_CloseFd(sp); return (__LINE__); } else if (http_HdrIs(hp, H_Connection, "keep-alive")) { /* @@ -515,7 +515,7 @@ VTAILQ_REMOVE(&sp->obj->store, st, list); STV_free(st); } - VBE_ClosedFd(sp); + VBE_CloseFd(sp); sp->obj->len = 0; return (__LINE__); } @@ -540,7 +540,7 @@ cls = 1; if (cls) - VBE_ClosedFd(sp); + VBE_CloseFd(sp); else VBE_RecycleFd(sp); Modified: trunk/varnish-cache/bin/varnishd/cache_pipe.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_pipe.c 2010-08-10 09:08:21 UTC (rev 5080) +++ trunk/varnish-cache/bin/varnishd/cache_pipe.c 2010-08-10 09:23:39 UTC (rev 5081) @@ -91,7 +91,7 @@ if (i) { vca_close_session(sp, "pipe"); - VBE_ClosedFd(sp); + VBE_CloseFd(sp); return; } @@ -135,5 +135,5 @@ (void)shutdown(vc->fd, SHUT_WR); } vca_close_session(sp, "pipe"); - VBE_ClosedFd(sp); + VBE_CloseFd(sp); } From phk at varnish-cache.org Tue Aug 10 09:40:18 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Tue, 10 Aug 2010 11:40:18 +0200 Subject: r5082 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-10 11:40:18 +0200 (Tue, 10 Aug 2010) New Revision: 5082 Modified: trunk/varnish-cache/bin/varnishd/cache_pipe.c Log: Fix a corner-case of pipe mode close-down processing, by simplifying the logic and letting vca_close_session() and VBE_CloseFd() carry out the last rites. Closes: #746 Modified: trunk/varnish-cache/bin/varnishd/cache_pipe.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_pipe.c 2010-08-10 09:23:39 UTC (rev 5081) +++ trunk/varnish-cache/bin/varnishd/cache_pipe.c 2010-08-10 09:40:18 UTC (rev 5082) @@ -114,26 +114,22 @@ if (i < 1) break; if (fds[0].revents && rdf(vc->fd, sp->fd)) { + if (fds[1].fd == -1) + break; (void)shutdown(vc->fd, SHUT_RD); (void)shutdown(sp->fd, SHUT_WR); fds[0].events = 0; fds[0].fd = -1; } if (fds[1].revents && rdf(sp->fd, vc->fd)) { + if (fds[0].fd == -1) + break; (void)shutdown(sp->fd, SHUT_RD); (void)shutdown(vc->fd, SHUT_WR); fds[1].events = 0; fds[1].fd = -1; } } - if (fds[0].fd >= 0) { - (void)shutdown(vc->fd, SHUT_RD); - (void)shutdown(sp->fd, SHUT_WR); - } - if (fds[1].fd >= 0) { - (void)shutdown(sp->fd, SHUT_RD); - (void)shutdown(vc->fd, SHUT_WR); - } vca_close_session(sp, "pipe"); VBE_CloseFd(sp); } From perbu at varnish-cache.org Tue Aug 10 15:21:42 2010 From: perbu at varnish-cache.org (perbu at varnish-cache.org) Date: Tue, 10 Aug 2010 17:21:42 +0200 Subject: r5083 - trunk/varnish-cache/doc/sphinx/tutorial Message-ID: Author: perbu Date: 2010-08-10 17:21:42 +0200 (Tue, 10 Aug 2010) New Revision: 5083 Modified: trunk/varnish-cache/doc/sphinx/tutorial/vcl.rst Log: missing set Modified: trunk/varnish-cache/doc/sphinx/tutorial/vcl.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/tutorial/vcl.rst 2010-08-10 09:40:18 UTC (rev 5082) +++ trunk/varnish-cache/doc/sphinx/tutorial/vcl.rst 2010-08-10 15:21:42 UTC (rev 5083) @@ -154,7 +154,7 @@ sub vcl_fetch { if (beresp.url ~ "\.(png|gif|jpg)$") { unset beresp.http.set-cookie; - beresp.ttl = 3600; + set beresp.ttl = 3600; } } From perbu at varnish-cache.org Tue Aug 10 15:38:20 2010 From: perbu at varnish-cache.org (perbu at varnish-cache.org) Date: Tue, 10 Aug 2010 17:38:20 +0200 Subject: r5084 - trunk/varnish-cache/doc/sphinx/tutorial Message-ID: Author: perbu Date: 2010-08-10 17:38:20 +0200 (Tue, 10 Aug 2010) New Revision: 5084 Modified: trunk/varnish-cache/doc/sphinx/tutorial/index.rst Log: cleaned up the index, must restructure the tutorial some day to balance out the chapters Modified: trunk/varnish-cache/doc/sphinx/tutorial/index.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/tutorial/index.rst 2010-08-10 15:21:42 UTC (rev 5083) +++ trunk/varnish-cache/doc/sphinx/tutorial/index.rst 2010-08-10 15:38:20 UTC (rev 5084) @@ -9,63 +9,21 @@ server and have basic knowledge of the HTTP protocol. The reader should have Varnish up and running with the default configuration. -Good luck. +The tutorial is split into short chapters, each chapter taking on a +separate topic. Good luck. -TOC +.. toctree:: :maxdepth: 1 - Getting Varnish Running - backend_servers.rst - starting_varnish.rst - logging.rst - sizing_your_cache.rst - putting_varnish_on_port_80.rst - The Varnish Configuration Language - vcl.rst + backend_servers + starting_varnish + logging + sizing_your_cache + putting_varnish_on_port_80 + vcl + statistics + increasing_your_hitrate + advanced_backend_servers + handling_misbehaving_servers + advanced_topics + troubleshooting - Tuning Varnish - increasing_your_hitrate.rst - advanced_backend_servers.rst - handling_misbehaving_servers.rst - - Advanced topics - advanced_topics.rst - -Troubleshooting and getting help - troubleshooting.rst - -.. toctree:: - - backend_servers.rst - starting_varnish.rst - logging.rst - sizing_your_cache.rst - putting_varnish_on_port_80.rst - vcl.rst - statistics.rst - increasing_your_hitrate.rst - advanced_backend_servers.rst - handling_misbehaving_servers.rst - advanced_topics.rst - troubleshooting.rst - -.. todo:: - starting varnish with -d, seeing a transaction go through - explain varnishlog output for a miss and a hit - a few simple VCL tricks, including switching VCL on the fly - The helpers: varnishstat, varnishhist, varnishtop varnishncsa - Now that you know how it works, lets talk planning: - - backend, directors and polling - - storage - - logging - - management CLI & security - - ESI - Real life examples: - - A real life varnish explained - - A more complex real life varnish explained - - Sky's Wikia Setup - Varnishtest - - What varnishtest does and why - - writing simple test-cases - - using varnishtest to test your VCL - - using varnishtest to reproduce bugs - From perbu at varnish-cache.org Tue Aug 10 15:39:37 2010 From: perbu at varnish-cache.org (perbu at varnish-cache.org) Date: Tue, 10 Aug 2010 17:39:37 +0200 Subject: r5085 - trunk/varnish-cache/doc/sphinx/tutorial Message-ID: Author: perbu Date: 2010-08-10 17:39:36 +0200 (Tue, 10 Aug 2010) New Revision: 5085 Modified: trunk/varnish-cache/doc/sphinx/tutorial/sizing_your_cache.rst Log: removed a rst warning Modified: trunk/varnish-cache/doc/sphinx/tutorial/sizing_your_cache.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/tutorial/sizing_your_cache.rst 2010-08-10 15:38:20 UTC (rev 5084) +++ trunk/varnish-cache/doc/sphinx/tutorial/sizing_your_cache.rst 2010-08-10 15:39:36 UTC (rev 5085) @@ -4,6 +4,7 @@ Picking how much memory you should give Varnish can be a tricky task. A few things to consider: + * How big is your *hot* data set. For a portal or news site that would be the size of the front page with all the stuff on it, and the size of all the pages and objects linked from the first page. From phk at varnish-cache.org Wed Aug 11 08:59:40 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 11 Aug 2010 10:59:40 +0200 Subject: r5086 - in trunk/varnish-cache: include lib/libvcl Message-ID: Author: phk Date: 2010-08-11 10:59:40 +0200 (Wed, 11 Aug 2010) New Revision: 5086 Modified: trunk/varnish-cache/include/vrt.h trunk/varnish-cache/lib/libvcl/vcc_backend.c Log: Add string representation of backend ipv4/ipv6 addresses to compiled VCL. Modified: trunk/varnish-cache/include/vrt.h =================================================================== --- trunk/varnish-cache/include/vrt.h 2010-08-10 15:39:36 UTC (rev 5085) +++ trunk/varnish-cache/include/vrt.h 2010-08-11 08:59:40 UTC (rev 5086) @@ -67,7 +67,10 @@ const char *hosthdr; const unsigned char *ipv4_sockaddr; + const char *ipv4_addr; const unsigned char *ipv6_sockaddr; + const char *ipv6_addr; + const char *port; double connect_timeout; double first_byte_timeout; Modified: trunk/varnish-cache/lib/libvcl/vcc_backend.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-08-10 15:39:36 UTC (rev 5085) +++ trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-08-11 08:59:40 UTC (rev 5086) @@ -90,6 +90,32 @@ return (NULL); } +static int +emit_sockaddr(struct vcc *tl, void *sa, unsigned sal) +{ + unsigned len; + uint8_t *u; + + AN(sa); + AN(sal); + assert(sal < 256); + Fh(tl, 0, "\nstatic const unsigned char sockaddr%u[%d] = {\n", + tl->nsockaddr, sal + 1); + Fh(tl, 0, " %3u, /* Length */\n", sal); + u = sa; + for (len = 0; len nsockaddr++); +} + /*-------------------------------------------------------------------- * Struct sockaddr is not really designed to be a compile time * initialized data structure, so we encode it as a byte-string @@ -101,9 +127,8 @@ const char *port) { struct addrinfo *res, *res0, *res1, hint; - int n4, n6, len, error, retval; + int n4, n6, error, retval, x; const char *emit, *multiple; - unsigned char *u; char hbuf[NI_MAXHOST]; AN(t_host->dec); @@ -115,16 +140,17 @@ AZ(error); n4 = n6 = 0; multiple = NULL; + for (res = res0; res; res = res->ai_next) { emit = NULL; if (res->ai_family == PF_INET) { if (n4++ == 0) - emit = "ipv4_sockaddr"; + emit = "ipv4"; else multiple = "IPv4"; } else if (res->ai_family == PF_INET6) { if (n6++ == 0) - emit = "ipv6_sockaddr"; + emit = "ipv6"; else multiple = "IPv6"; } else @@ -149,26 +175,22 @@ return; } AN(emit); - AN(res->ai_addr); - AN(res->ai_addrlen); - assert(res->ai_addrlen < 256); - Fh(tl, 0, "\nstatic const unsigned char sockaddr%u[%d] = {\n", - tl->nsockaddr, res->ai_addrlen + 1); - Fh(tl, 0, " %3u, /* Length */\n", res->ai_addrlen); - u = (void*)res->ai_addr; - for (len = 0; len < res->ai_addrlen; len++) { - if ((len % 8) == 0) - Fh(tl, 0, " "); - Fh(tl, 0, " %3u", u[len]); - if (len + 1 < res->ai_addrlen) - Fh(tl, 0, ","); - if ((len % 8) == 7) - Fh(tl, 0, "\n"); - } - Fh(tl, 0, "\n};\n"); - Fb(tl, 0, "\t.%s = sockaddr%u,\n", emit, tl->nsockaddr++); + x = emit_sockaddr(tl, res->ai_addr, res->ai_addrlen); + Fb(tl, 0, "\t.%s_sockaddr = sockaddr%u,\n", emit, x); + error = getnameinfo(res->ai_addr, + res->ai_addrlen, hbuf, sizeof hbuf, + NULL, 0, NI_NUMERICHOST); + AZ(error); + Fb(tl, 0, "\t.%s_addr = \"%s\",\n", emit, hbuf); retval++; } + if (res0 != NULL) { + error = getnameinfo(res0->ai_addr, + res0->ai_addrlen, NULL, 0, hbuf, sizeof hbuf, + NI_NUMERICSERV); + AZ(error); + Fb(tl, 0, "\t.port = \"%s\",\n", hbuf); + } freeaddrinfo(res0); if (retval == 0) { vsb_printf(tl->sb, From phk at varnish-cache.org Wed Aug 11 09:40:20 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 11 Aug 2010 11:40:20 +0200 Subject: r5087 - in trunk/varnish-cache: bin/varnishd include lib/libvcl Message-ID: Author: phk Date: 2010-08-11 11:40:20 +0200 (Wed, 11 Aug 2010) New Revision: 5087 Modified: trunk/varnish-cache/bin/varnishd/cache_backend.h trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c trunk/varnish-cache/include/vrt.h trunk/varnish-cache/lib/libvcl/vcc_backend.c Log: Identify backends using the (vcl_name, ipv4, ipv6) triplet and drop the "ident string". (see also: docs/sphinx/phk/backends.rst) Modified: trunk/varnish-cache/bin/varnishd/cache_backend.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-08-11 08:59:40 UTC (rev 5086) +++ trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-08-11 09:40:20 UTC (rev 5087) @@ -114,14 +114,14 @@ #define BACKEND_MAGIC 0x64c4c7c6 char *hosthdr; - char *ident; char *vcl_name; + char *ipv4_addr; + char *ipv6_addr; + char *port; double connect_timeout; double first_byte_timeout; double between_bytes_timeout; - uint32_t hash; - VTAILQ_ENTRY(backend) list; int refcount; struct lock mtx; Modified: trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 08:59:40 UTC (rev 5086) +++ trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 09:40:20 UTC (rev 5087) @@ -45,7 +45,6 @@ #include "cache.h" #include "vrt.h" -#include "vsha256.h" #include "cache_backend.h" #include "cli_priv.h" @@ -67,10 +66,12 @@ ASSERT_CLI(); VTAILQ_REMOVE(&backends, b, list); - free(b->ident); free(b->hosthdr); free(b->ipv4); + free(b->ipv4_addr); free(b->ipv6); + free(b->ipv6_addr); + free(b->port); FREE_OBJ(b); VSC_main->n_backend--; } @@ -148,7 +149,9 @@ VBE_DropRefLocked(b); } -/*--------------------------------------------------------------------*/ +/*-------------------------------------------------------------------- + * See lib/libvcl/vcc_backend.c::emit_sockaddr() + */ static void copy_sockaddr(struct sockaddr **sa, socklen_t *len, const unsigned char *src) @@ -156,7 +159,7 @@ assert(*src > 0); *sa = malloc(*src); - AN(*sa); + XXXAN(*sa); memcpy(*sa, src + 1, *src); *len = *src; } @@ -171,47 +174,25 @@ VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb) { struct backend *b; - uint32_t u; - struct SHA256Context ctx; - uint8_t hash[SHA256_LEN]; - AN(vb->ident); + AN(vb->vcl_name); assert(vb->ipv4_sockaddr != NULL || vb->ipv6_sockaddr != NULL); (void)cli; ASSERT_CLI(); - /* calculate a hash of (ident + ipv4_sockaddr + ipv6_sockaddr) */ - SHA256_Init(&ctx); - SHA256_Update(&ctx, vb->ident, strlen(vb->ident)); - if (vb->ipv4_sockaddr != NULL) - SHA256_Update(&ctx, - vb->ipv4_sockaddr + 1, vb->ipv4_sockaddr[0]); - if (vb->ipv6_sockaddr != NULL) - SHA256_Update(&ctx, - vb->ipv6_sockaddr + 1, vb->ipv6_sockaddr[0]); - - SHA256_Final(hash, &ctx); - memcpy(&u, hash, sizeof u); - /* Run through the list and see if we already have this backend */ VTAILQ_FOREACH(b, &backends, list) { CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); - if (u != b->hash) + if (strcmp(b->vcl_name, vb->vcl_name)) continue; - if (strcmp(b->ident, vb->ident)) + if (vb->ipv4_sockaddr != NULL && ( + b->ipv4len != vb->ipv4_sockaddr[0] || + memcmp(b->ipv4, vb->ipv4_sockaddr + 1, b->ipv4len))) continue; - if (vb->ipv4_sockaddr != NULL && - b->ipv4len != vb->ipv4_sockaddr[0]) + if (vb->ipv6_sockaddr != NULL && ( + b->ipv6len != vb->ipv6_sockaddr[0] || + memcmp(b->ipv6, vb->ipv6_sockaddr + 1, b->ipv6len))) continue; - if (vb->ipv6_sockaddr != NULL && - b->ipv6len != vb->ipv6_sockaddr[0]) - continue; - if (b->ipv4len != 0 && - memcmp(b->ipv4, vb->ipv4_sockaddr + 1, b->ipv4len)) - continue; - if (b->ipv6len != 0 && - memcmp(b->ipv6, vb->ipv6_sockaddr + 1, b->ipv6len)) - continue; b->refcount++; return (b); } @@ -223,7 +204,6 @@ b->refcount = 1; VTAILQ_INIT(&b->connlist); - b->hash = u; VTAILQ_INIT(&b->troublelist); @@ -231,8 +211,10 @@ * This backend may live longer than the VCL that instantiated it * so we cannot simply reference the VCL's copy of things. */ - REPLACE(b->ident, vb->ident); REPLACE(b->vcl_name, vb->vcl_name); + REPLACE(b->ipv4_addr, vb->ipv4_addr); + REPLACE(b->ipv6_addr, vb->ipv6_addr); + REPLACE(b->port, vb->port); REPLACE(b->hosthdr, vb->hosthdr); b->connect_timeout = vb->connect_timeout; @@ -304,8 +286,9 @@ ASSERT_CLI(); VTAILQ_FOREACH(b, &backends, list) { CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); - cli_out(cli, "%p %s %d %d/%d\n", - b, b->vcl_name, b->refcount, + cli_out(cli, "%p %s(%s,%s,:%s) %d %d/%d\n", + b, b->vcl_name, b->ipv4_addr, b->ipv6_addr, b->port, + b->refcount, b->n_conn, b->max_conn); } } Modified: trunk/varnish-cache/include/vrt.h =================================================================== --- trunk/varnish-cache/include/vrt.h 2010-08-11 08:59:40 UTC (rev 5086) +++ trunk/varnish-cache/include/vrt.h 2010-08-11 09:40:20 UTC (rev 5087) @@ -62,16 +62,15 @@ */ struct vrt_backend { const char *vcl_name; - const char *ident; - - const char *hosthdr; - - const unsigned char *ipv4_sockaddr; const char *ipv4_addr; - const unsigned char *ipv6_sockaddr; const char *ipv6_addr; const char *port; + const unsigned char *ipv4_sockaddr; + const unsigned char *ipv6_sockaddr; + + const char *hosthdr; + double connect_timeout; double first_byte_timeout; double between_bytes_timeout; Modified: trunk/varnish-cache/lib/libvcl/vcc_backend.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-08-11 08:59:40 UTC (rev 5086) +++ trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-08-11 09:40:20 UTC (rev 5087) @@ -592,7 +592,6 @@ ExpectErr(tl, '}'); /* We have parsed it all, emit the ident string */ - vcc_EmitBeIdent(tl, tl->fb, serial, t_first, tl->t); /* Emit the hosthdr field, fall back to .host if not specified */ Fb(tl, 0, "\t.hosthdr = "); From phk at varnish-cache.org Wed Aug 11 11:37:01 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 11 Aug 2010 13:37:01 +0200 Subject: r5088 - in trunk/varnish-cache: bin/varnishd include Message-ID: Author: phk Date: 2010-08-11 13:37:01 +0200 (Wed, 11 Aug 2010) New Revision: 5088 Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_backend.c trunk/varnish-cache/bin/varnishd/cache_backend.h trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c trunk/varnish-cache/bin/varnishd/cache_center.c trunk/varnish-cache/bin/varnishd/cache_cli.c trunk/varnish-cache/bin/varnishd/cache_dir_dns.c trunk/varnish-cache/bin/varnishd/cache_dir_random.c trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c trunk/varnish-cache/bin/varnishd/cache_fetch.c trunk/varnish-cache/bin/varnishd/cache_panic.c trunk/varnish-cache/bin/varnishd/cache_pipe.c trunk/varnish-cache/bin/varnishd/cache_vrt.c trunk/varnish-cache/bin/varnishd/heritage.h trunk/varnish-cache/bin/varnishd/mgt_param.c trunk/varnish-cache/include/stat_field.h trunk/varnish-cache/include/vsc_fields.h Log: Rename backend connections to the VTLA "VBC" Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache.h 2010-08-11 11:37:01 UTC (rev 5088) @@ -426,7 +426,7 @@ VTAILQ_ENTRY(sess) list; struct director *director; - struct vbe_conn *vbe; + struct vbc *vbc; struct object *obj; struct objcore *objcore; struct objhead *objhead; @@ -448,10 +448,10 @@ /* -------------------------------------------------------------------*/ /* Backend connection */ -struct vbe_conn { +struct vbc { unsigned magic; -#define VBE_CONN_MAGIC 0x0c5e6592 - VTAILQ_ENTRY(vbe_conn) list; +#define VBC_MAGIC 0x0c5e6592 + VTAILQ_ENTRY(vbc) list; struct backend *backend; int fd; @@ -473,7 +473,7 @@ /* cache_backend.c */ -struct vbe_conn *VBE_GetFd(const struct director *, struct sess *sp); +struct vbc *VBE_GetFd(const struct director *, struct sess *sp); int VBE_Healthy(double now, const struct director *, uintptr_t target); int VBE_Healthy_sp(const struct sess *sp, const struct director *); void VBE_CloseFd(struct sess *sp); Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -49,9 +49,9 @@ #include "vrt.h" /* - * List of cached vbe_conns, used if enabled in params/heritage + * List of cached vbcs, used if enabled in params/heritage */ -static VTAILQ_HEAD(,vbe_conn) vbe_conns = VTAILQ_HEAD_INITIALIZER(vbe_conns); +static VTAILQ_HEAD(,vbc) vbcs = VTAILQ_HEAD_INITIALIZER(vbcs); /*-------------------------------------------------------------------- * Create default Host: header for backend request @@ -62,29 +62,29 @@ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk->bereq, HTTP_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbe, VBE_CONN_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbe->backend, BACKEND_MAGIC); + CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); + CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->bereq, - "Host: %s", sp->vbe->backend->hosthdr); + "Host: %s", sp->vbc->backend->hosthdr); } /* Private interface from backend_cfg.c */ void -VBE_ReleaseConn(struct vbe_conn *vc) +VBE_ReleaseConn(struct vbc *vc) { - CHECK_OBJ_NOTNULL(vc, VBE_CONN_MAGIC); + CHECK_OBJ_NOTNULL(vc, VBC_MAGIC); assert(vc->backend == NULL); assert(vc->fd < 0); - if (params->cache_vbe_conns) { + if (params->cache_vbcs) { Lck_Lock(&VBE_mtx); - VTAILQ_INSERT_HEAD(&vbe_conns, vc, list); + VTAILQ_INSERT_HEAD(&vbcs, vc, list); VSC_main->backend_unused++; Lck_Unlock(&VBE_mtx); } else { Lck_Lock(&VBE_mtx); - VSC_main->n_vbe_conn--; + VSC_main->n_vbc--; Lck_Unlock(&VBE_mtx); free(vc); } @@ -197,23 +197,23 @@ } /*-------------------------------------------------------------------- - * Manage a pool of vbe_conn structures. + * Manage a pool of vbc structures. * XXX: as an experiment, make this caching controled by a parameter * XXX: so we can see if it has any effect. */ -static struct vbe_conn * +static struct vbc * vbe_NewConn(void) { - struct vbe_conn *vc; + struct vbc *vc; - vc = VTAILQ_FIRST(&vbe_conns); + vc = VTAILQ_FIRST(&vbcs); if (vc != NULL) { Lck_Lock(&VBE_mtx); - vc = VTAILQ_FIRST(&vbe_conns); + vc = VTAILQ_FIRST(&vbcs); if (vc != NULL) { VSC_main->backend_unused--; - VTAILQ_REMOVE(&vbe_conns, vc, list); + VTAILQ_REMOVE(&vbcs, vc, list); } Lck_Unlock(&VBE_mtx); } @@ -221,10 +221,10 @@ return (vc); vc = calloc(sizeof *vc, 1); XXXAN(vc); - vc->magic = VBE_CONN_MAGIC; + vc->magic = VBC_MAGIC; vc->fd = -1; Lck_Lock(&VBE_mtx); - VSC_main->n_vbe_conn++; + VSC_main->n_vbc++; Lck_Unlock(&VBE_mtx); return (vc); } @@ -312,15 +312,15 @@ * Get a connection to a particular backend. */ -static struct vbe_conn * +static struct vbc * vbe_GetVbe(struct sess *sp, struct backend *bp) { - struct vbe_conn *vc; + struct vbc *vc; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC); - /* first look for vbe_conn's we can recycle */ + /* first look for vbc's we can recycle */ while (1) { Lck_Lock(&bp->mtx); vc = VTAILQ_FIRST(&bp->connlist); @@ -341,7 +341,7 @@ return (vc); } VSC_main->backend_toolate++; - sp->vbe = vc; + sp->vbc = vc; VBE_CloseFd(sp); } @@ -378,18 +378,18 @@ { struct backend *bp; - CHECK_OBJ_NOTNULL(sp->vbe, VBE_CONN_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbe->backend, BACKEND_MAGIC); - assert(sp->vbe->fd >= 0); + CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); + CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); + assert(sp->vbc->fd >= 0); - bp = sp->vbe->backend; + bp = sp->vbc->backend; - WSL(sp->wrk, SLT_BackendClose, sp->vbe->fd, "%s", bp->vcl_name); - TCP_close(&sp->vbe->fd); + WSL(sp->wrk, SLT_BackendClose, sp->vbc->fd, "%s", bp->vcl_name); + TCP_close(&sp->vbc->fd); VBE_DropRefConn(bp); - sp->vbe->backend = NULL; - VBE_ReleaseConn(sp->vbe); - sp->vbe = NULL; + sp->vbc->backend = NULL; + VBE_ReleaseConn(sp->vbc); + sp->vbc = NULL; } /* Recycle a connection ----------------------------------------------*/ @@ -399,13 +399,13 @@ { struct backend *bp; - CHECK_OBJ_NOTNULL(sp->vbe, VBE_CONN_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbe->backend, BACKEND_MAGIC); - assert(sp->vbe->fd >= 0); + CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); + CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); + assert(sp->vbc->fd >= 0); - bp = sp->vbe->backend; + bp = sp->vbc->backend; - WSL(sp->wrk, SLT_BackendReuse, sp->vbe->fd, "%s", bp->vcl_name); + WSL(sp->wrk, SLT_BackendReuse, sp->vbc->fd, "%s", bp->vcl_name); /* * Flush the shmlog, so that another session reusing this backend * will log chronologically later than our use of it. @@ -413,14 +413,14 @@ WSL_Flush(sp->wrk, 0); Lck_Lock(&bp->mtx); VSC_main->backend_recycle++; - VTAILQ_INSERT_HEAD(&bp->connlist, sp->vbe, list); - sp->vbe = NULL; + VTAILQ_INSERT_HEAD(&bp->connlist, sp->vbc, list); + sp->vbc = NULL; VBE_DropRefLocked(bp); } /* Get a connection --------------------------------------------------*/ -struct vbe_conn * +struct vbc * VBE_GetFd(const struct director *d, struct sess *sp) { @@ -554,11 +554,11 @@ return vs->backend; } -static struct vbe_conn * +static struct vbc * vdi_simple_getfd(const struct director *d, struct sess *sp) { struct vdi_simple *vs; - struct vbe_conn *vc; + struct vbc *vc; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); Modified: trunk/varnish-cache/bin/varnishd/cache_backend.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-08-11 11:37:01 UTC (rev 5088) @@ -38,10 +38,10 @@ * A backend is a TCP destination, possibly multi-homed and it has a * number of associated properties and statistics. * - * A vbe_conn is an open TCP connection to a backend. + * A vbc is an open TCP connection to a backend. * * A bereq is a memory carrier for handling a HTTP transaction with - * a backend over a vbe_conn. + * a backend over a vbc. * * A director is a piece of code that selects which backend to use, * by whatever method or metric it chooses. @@ -53,7 +53,7 @@ * * When a VCL tries to instantiate a backend, any existing backend * with the same identity (== definition in VCL) will be used instead - * so that vbe_conn's can be reused across VCL changes. + * so that vbc's can be reused across VCL changes. * * Directors disapper with the VCL that created them. * @@ -69,7 +69,7 @@ */ struct vbp_target; -struct vbe_conn; +struct vbc; struct vrt_backend_probe; /*-------------------------------------------------------------------- @@ -77,7 +77,7 @@ * backends to use. */ -typedef struct vbe_conn *vdi_getfd_f(const struct director *, struct sess *sp); +typedef struct vbc *vdi_getfd_f(const struct director *, struct sess *sp); typedef void vdi_fini_f(struct director *); typedef unsigned vdi_healthy(double now, const struct director *, uintptr_t target); @@ -133,7 +133,7 @@ unsigned max_conn; unsigned n_conn; - VTAILQ_HEAD(, vbe_conn) connlist; + VTAILQ_HEAD(, vbc) connlist; struct vbp_target *probe; unsigned healthy; @@ -142,7 +142,7 @@ }; /* cache_backend.c */ -void VBE_ReleaseConn(struct vbe_conn *vc); +void VBE_ReleaseConn(struct vbc *vc); struct backend *vdi_get_backend_if_simple(const struct director *d); /* cache_backend_cfg.c */ Modified: trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -101,7 +101,7 @@ VBE_DropRefLocked(struct backend *b) { int i; - struct vbe_conn *vbe, *vbe2; + struct vbc *vbe, *vbe2; CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); assert(b->refcount > 0); Modified: trunk/varnish-cache/bin/varnishd/cache_center.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -229,7 +229,7 @@ CHECK_OBJ_ORNULL(sp->vcl, VCL_CONF_MAGIC); AZ(sp->obj); - AZ(sp->vbe); + AZ(sp->vbc); sp->director = NULL; sp->restarts = 0; @@ -432,7 +432,7 @@ CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC); AN(sp->director); - AZ(sp->vbe); + AZ(sp->vbc); /* sp->wrk->http[0] is (still) bereq */ sp->wrk->beresp = sp->wrk->http[1]; @@ -592,7 +592,7 @@ i = FetchBody(sp); AZ(sp->wrk->wfd); - AZ(sp->vbe); + AZ(sp->vbc); AN(sp->director); if (i) { Modified: trunk/varnish-cache/bin/varnishd/cache_cli.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_cli.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_cli.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -135,7 +135,7 @@ SZOF(struct objcore); SZOF(struct objhead); SZOF(struct sess); - SZOF(struct vbe_conn); + SZOF(struct vbc); SZOF(struct vsc_main); SZOF(struct lock); } Modified: trunk/varnish-cache/bin/varnishd/cache_dir_dns.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -383,12 +383,12 @@ return ret; } -static struct vbe_conn * +static struct vbc * vdi_dns_getfd(const struct director *director, struct sess *sp) { struct vdi_dns *vs; struct director *dir; - struct vbe_conn *vbe; + struct vbc *vbe; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(director, DIRECTOR_MAGIC); Modified: trunk/varnish-cache/bin/varnishd/cache_dir_random.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_random.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_dir_random.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -80,14 +80,14 @@ unsigned nhosts; }; -static struct vbe_conn * +static struct vbc * vdi_random_getfd(const struct director *d, struct sess *sp) { int i, k; struct vdi_random *vs; double r, s1; unsigned u = 0; - struct vbe_conn *vbe; + struct vbc *vbe; struct director *d2; struct SHA256Context ctx; uint8_t sign[SHA256_LEN], *hp; Modified: trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -59,13 +59,13 @@ unsigned next_host; }; -static struct vbe_conn * +static struct vbc * vdi_round_robin_getfd(const struct director *d, struct sess *sp) { int i; struct vdi_round_robin *vs; struct director *backend; - struct vbe_conn *vbe; + struct vbc *vbe; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -329,7 +329,7 @@ int FetchHdr(struct sess *sp) { - struct vbe_conn *vc; + struct vbc *vc; struct worker *w; char *b; struct http *hp; @@ -351,12 +351,12 @@ w = sp->wrk; hp = sp->wrk->bereq; - sp->vbe = VBE_GetFd(NULL, sp); - if (sp->vbe == NULL) { + sp->vbc = VBE_GetFd(NULL, sp); + if (sp->vbc == NULL) { WSP(sp, SLT_FetchError, "no backend connection"); return (__LINE__); } - vc = sp->vbe; + vc = sp->vbc; /* * Now that we know our backend, we can set a default Host: @@ -424,7 +424,7 @@ int FetchBody(struct sess *sp) { - struct vbe_conn *vc; + struct vbc *vc; char *b; int cls; struct http *hp; @@ -442,7 +442,7 @@ if (sp->obj->objcore != NULL) /* pass has no objcore */ AN(ObjIsBusy(sp->obj)); - vc = sp->vbe; + vc = sp->vbc; is_head = (strcasecmp(http_GetReq(sp->wrk->bereq), "head") == 0); @@ -520,7 +520,7 @@ return (__LINE__); } - WSL(sp->wrk, SLT_Length, sp->vbe->fd, "%u", sp->obj->len); + WSL(sp->wrk, SLT_Length, sp->vbc->fd, "%u", sp->obj->len); { /* Sanity check fetch methods accounting */ Modified: trunk/varnish-cache/bin/varnishd/cache_panic.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_panic.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_panic.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -89,14 +89,14 @@ /*--------------------------------------------------------------------*/ static void -pan_vbe(const struct vbe_conn *vbe) +pan_vbc(const struct vbc *vbc) { struct backend *be; - be = vbe->backend; + be = vbc->backend; - vsb_printf(vsp, " backend = %p fd = %d {\n", be, vbe->fd); + vsb_printf(vsp, " backend = %p fd = %d {\n", be, vbc->fd); vsb_printf(vsp, " vcl_name = \"%s\",\n", be->vcl_name); vsb_printf(vsp, " },\n"); } @@ -252,8 +252,8 @@ if (VALID_OBJ(sp->vcl, VCL_CONF_MAGIC)) pan_vcl(sp->vcl); - if (VALID_OBJ(sp->vbe, BACKEND_MAGIC)) - pan_vbe(sp->vbe); + if (VALID_OBJ(sp->vbc, BACKEND_MAGIC)) + pan_vbc(sp->vbc); if (VALID_OBJ(sp->obj, OBJECT_MAGIC)) pan_object(sp->obj); Modified: trunk/varnish-cache/bin/varnishd/cache_pipe.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_pipe.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_pipe.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -65,7 +65,7 @@ void PipeSession(struct sess *sp) { - struct vbe_conn *vc; + struct vbc *vc; struct worker *w; struct pollfd fds[2]; int i; @@ -74,10 +74,10 @@ CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); w = sp->wrk; - sp->vbe = VBE_GetFd(NULL, sp); - if (sp->vbe == NULL) + sp->vbc = VBE_GetFd(NULL, sp); + if (sp->vbc == NULL) return; - vc = sp->vbe; + vc = sp->vbc; (void)TCP_blocking(vc->fd); WRW_Reserve(w, &vc->fd); Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -293,12 +293,12 @@ struct trouble *tr2; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - if (!sp->vbe) + if (!sp->vbc) return; - CHECK_OBJ_NOTNULL(sp->vbe, VBE_CONN_MAGIC); - if (!sp->vbe->backend) + CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); + if (!sp->vbc->backend) return; - CHECK_OBJ_NOTNULL(sp->vbe->backend, BACKEND_MAGIC); + CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); if (!sp->objhead) return; CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC); @@ -317,8 +317,8 @@ * timeout at a later date (ie: sort by which entry will time out * from the list */ - Lck_Lock(&sp->vbe->backend->mtx); - VTAILQ_FOREACH_SAFE(tr, &sp->vbe->backend->troublelist, list, tr2) { + Lck_Lock(&sp->vbc->backend->mtx); + VTAILQ_FOREACH_SAFE(tr, &sp->vbc->backend->troublelist, list, tr2) { if (tr->timeout < new->timeout) { VTAILQ_INSERT_BEFORE(tr, new, list); new = NULL; @@ -330,9 +330,9 @@ * items have a longer timeout. */ if (new) - VTAILQ_INSERT_TAIL(&sp->vbe->backend->troublelist, new, list); + VTAILQ_INSERT_TAIL(&sp->vbc->backend->troublelist, new, list); - Lck_Unlock(&sp->vbe->backend->mtx); + Lck_Unlock(&sp->vbc->backend->mtx); } int Modified: trunk/varnish-cache/bin/varnishd/heritage.h =================================================================== --- trunk/varnish-cache/bin/varnishd/heritage.h 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/heritage.h 2010-08-11 11:37:01 UTC (rev 5088) @@ -144,8 +144,8 @@ /* Rush exponent */ unsigned rush_exponent; - /* Cache vbe_conns */ - unsigned cache_vbe_conns; + /* Cache vbcs */ + unsigned cache_vbcs; /* Default connection_timeout */ double connect_timeout; Modified: trunk/varnish-cache/bin/varnishd/mgt_param.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_param.c 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/bin/varnishd/mgt_param.c 2010-08-11 11:37:01 UTC (rev 5088) @@ -655,8 +655,8 @@ "Maximum depth of esi:include processing.\n", 0, "5", "includes" }, - { "cache_vbe_conns", tweak_bool, &master.cache_vbe_conns, 0, 0, - "Cache vbe_conn's or rely on malloc, that's the question.", + { "cache_vbcs", tweak_bool, &master.cache_vbcs, 0, 0, + "Cache vbc's or rely on malloc, that's the question.", EXPERIMENTAL, "off", "bool" }, { "connect_timeout", tweak_timeout_double, Modified: trunk/varnish-cache/include/stat_field.h =================================================================== --- trunk/varnish-cache/include/stat_field.h 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/include/stat_field.h 2010-08-11 11:37:01 UTC (rev 5088) @@ -75,7 +75,7 @@ MAC_STAT(n_smf, uint64_t, 0, 'i', "N struct smf") MAC_STAT(n_smf_frag, uint64_t, 0, 'i', "N small free smf") MAC_STAT(n_smf_large, uint64_t, 0, 'i', "N large free smf") -MAC_STAT(n_vbe_conn, uint64_t, 0, 'i', "N struct vbe_conn") +MAC_STAT(n_vbc, uint64_t, 0, 'i', "N struct vbc") MAC_STAT(n_wrk, uint64_t, 0, 'i', "N worker threads") MAC_STAT(n_wrk_create, uint64_t, 0, 'a', "N worker threads created") MAC_STAT(n_wrk_failed, uint64_t, 0, 'a', Modified: trunk/varnish-cache/include/vsc_fields.h =================================================================== --- trunk/varnish-cache/include/vsc_fields.h 2010-08-11 09:40:20 UTC (rev 5087) +++ trunk/varnish-cache/include/vsc_fields.h 2010-08-11 11:37:01 UTC (rev 5088) @@ -76,7 +76,7 @@ VSC_F_MAIN(n_smf, uint64_t, 0, 'i', "N struct smf") VSC_F_MAIN(n_smf_frag, uint64_t, 0, 'i', "N small free smf") VSC_F_MAIN(n_smf_large, uint64_t, 0, 'i', "N large free smf") -VSC_F_MAIN(n_vbe_conn, uint64_t, 0, 'i', "N struct vbe_conn") +VSC_F_MAIN(n_vbc, uint64_t, 0, 'i', "N struct vbc") VSC_F_MAIN(n_wrk, uint64_t, 0, 'i', "N worker threads") VSC_F_MAIN(n_wrk_create, uint64_t, 0, 'a', "N worker threads created") VSC_F_MAIN(n_wrk_failed, uint64_t, 0, 'a', From phk at varnish-cache.org Wed Aug 11 12:12:48 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 11 Aug 2010 14:12:48 +0200 Subject: r5089 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-11 14:12:47 +0200 (Wed, 11 Aug 2010) New Revision: 5089 Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c trunk/varnish-cache/bin/varnishd/cache_backend.h trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c Log: Move the per backend stats counters to "struct backend" Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 11:37:01 UTC (rev 5088) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 12:12:47 UTC (rev 5089) @@ -456,73 +456,6 @@ } /*-------------------------------------------------------------------- - * Backend VSC counters - * - * We use a private list, because we do not trust the content of the - * VSM (to hold our refcount). - * - * Backend stats are indexed purely by name, across all VCLs. - */ - -struct vbe_cnt { - unsigned magic; -#define CNT_PRIV_MAGIC 0x1acda1f5 - VTAILQ_ENTRY(vbe_cnt) list; - char *name; - int refcnt; - struct vsc_vbe *vsc_vbe; -}; - -static VTAILQ_HEAD(, vbe_cnt) vbe_cnt_head = - VTAILQ_HEAD_INITIALIZER(vbe_cnt_head); - -static struct vsc_vbe * -vbe_stat_ref(const char *name) -{ - struct vbe_cnt *vc; - - ASSERT_CLI(); - VTAILQ_FOREACH(vc, &vbe_cnt_head, list) { - if (!strcmp(vc->name, name)) { - vc->refcnt++; - vc->vsc_vbe->vcls = vc->refcnt; - return (vc->vsc_vbe); - } - } - ALLOC_OBJ(vc, CNT_PRIV_MAGIC); - AN(vc); - REPLACE(vc->name, name); - VTAILQ_INSERT_HEAD(&vbe_cnt_head, vc, list); - vc->vsc_vbe = VSM_Alloc(sizeof *vc->vsc_vbe, - VSC_CLASS, VSC_TYPE_VBE, name); - AN(vc->vsc_vbe); - vc->refcnt = 1; - vc->vsc_vbe->vcls = vc->refcnt; - return (vc->vsc_vbe); -} - -static void -vbe_stat_deref(const char *name) -{ - struct vbe_cnt *vc; - - ASSERT_CLI(); - VTAILQ_FOREACH(vc, &vbe_cnt_head, list) - if (!strcmp(vc->name, name)) - break; - AN(vc); - vc->refcnt--; - vc->vsc_vbe->vcls = vc->refcnt; - if (vc->refcnt > 0) - return; - AZ(vc->refcnt); - VTAILQ_REMOVE(&vbe_cnt_head, vc, list); - VSM_Free(vc->vsc_vbe); - FREE_OBJ(vc); -} - - -/*-------------------------------------------------------------------- * The "simple" director really isn't, since thats where all the actual * connections happen. Nontheless, pretend it is simple by sequestering * the directoricity of it under this line. @@ -533,7 +466,6 @@ #define VDI_SIMPLE_MAGIC 0x476d25b7 struct director dir; struct backend *backend; - struct vsc_vbe *stats; }; /* Returns the backend if and only if the this is a simple director. @@ -593,7 +525,7 @@ CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); VBE_DropRef(vs->backend); - vbe_stat_deref(vs->dir.vcl_name); + // vbe_stat_deref(vs->dir.vcl_name); free(vs->dir.vcl_name); vs->dir.magic = 0; FREE_OBJ(vs); @@ -621,7 +553,6 @@ vs->dir.healthy = vdi_simple_healthy; vs->backend = VBE_AddBackend(cli, t); - vs->stats = vbe_stat_ref(t->vcl_name); bp[idx] = &vs->dir; } Modified: trunk/varnish-cache/bin/varnishd/cache_backend.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-08-11 11:37:01 UTC (rev 5088) +++ trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-08-11 12:12:47 UTC (rev 5089) @@ -113,31 +113,34 @@ unsigned magic; #define BACKEND_MAGIC 0x64c4c7c6 + VTAILQ_ENTRY(backend) list; + int refcount; + struct lock mtx; + char *hosthdr; char *vcl_name; char *ipv4_addr; char *ipv6_addr; char *port; - double connect_timeout; - double first_byte_timeout; - double between_bytes_timeout; - VTAILQ_ENTRY(backend) list; - int refcount; - struct lock mtx; - struct sockaddr *ipv4; socklen_t ipv4len; struct sockaddr *ipv6; socklen_t ipv6len; - unsigned max_conn; unsigned n_conn; VTAILQ_HEAD(, vbc) connlist; struct vbp_target *probe; unsigned healthy; VTAILQ_HEAD(, trouble) troublelist; + + struct vsc_vbe *vsc; + + double connect_timeout; + double first_byte_timeout; + double between_bytes_timeout; + unsigned max_conn; unsigned saintmode_threshold; }; Modified: trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 11:37:01 UTC (rev 5088) +++ trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 12:12:47 UTC (rev 5089) @@ -72,6 +72,7 @@ free(b->ipv6); free(b->ipv6_addr); free(b->port); + VSM_Free(b->vsc); FREE_OBJ(b); VSC_main->n_backend--; } @@ -174,6 +175,7 @@ VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb) { struct backend *b; + char buf[128]; AN(vb->vcl_name); assert(vb->ipv4_sockaddr != NULL || vb->ipv6_sockaddr != NULL); @@ -203,6 +205,11 @@ Lck_New(&b->mtx); b->refcount = 1; + bprintf(buf, "%s(%s,%s,%s)", + vb->vcl_name, vb->ipv4_addr, vb->ipv6_addr, vb->port); + + b->vsc = VSM_Alloc(sizeof *b->vsc, VSC_CLASS, VSC_TYPE_VBE, buf); + VTAILQ_INIT(&b->connlist); VTAILQ_INIT(&b->troublelist); From phk at varnish-cache.org Wed Aug 11 12:27:45 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 11 Aug 2010 14:27:45 +0200 Subject: r5090 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-11 14:27:45 +0200 (Wed, 11 Aug 2010) New Revision: 5090 Added: trunk/varnish-cache/bin/varnishd/cache_dir.c Modified: trunk/varnish-cache/bin/varnishd/Makefile.am trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_backend.c trunk/varnish-cache/bin/varnishd/cache_dir_dns.c trunk/varnish-cache/bin/varnishd/cache_dir_random.c trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c trunk/varnish-cache/bin/varnishd/cache_fetch.c trunk/varnish-cache/bin/varnishd/cache_hash.c trunk/varnish-cache/bin/varnishd/cache_pipe.c trunk/varnish-cache/bin/varnishd/cache_vrt.c Log: Move the top-of-director APIs from cache_backend.c to cache_dir.c and give them the VTLA "VDI" Modified: trunk/varnish-cache/bin/varnishd/Makefile.am =================================================================== --- trunk/varnish-cache/bin/varnishd/Makefile.am 2010-08-11 12:12:47 UTC (rev 5089) +++ trunk/varnish-cache/bin/varnishd/Makefile.am 2010-08-11 12:27:45 UTC (rev 5090) @@ -20,6 +20,7 @@ cache_ban.c \ cache_center.c \ cache_cli.c \ + cache_dir.c \ cache_dir_random.c \ cache_dir_dns.c \ cache_dir_round_robin.c \ Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2010-08-11 12:12:47 UTC (rev 5089) +++ trunk/varnish-cache/bin/varnishd/cache.h 2010-08-11 12:27:45 UTC (rev 5090) @@ -473,12 +473,12 @@ /* cache_backend.c */ -struct vbc *VBE_GetFd(const struct director *, struct sess *sp); -int VBE_Healthy(double now, const struct director *, uintptr_t target); -int VBE_Healthy_sp(const struct sess *sp, const struct director *); -void VBE_CloseFd(struct sess *sp); -void VBE_RecycleFd(struct sess *sp); -void VBE_AddHostHeader(const struct sess *sp); +struct vbc *VDI_GetFd(const struct director *, struct sess *sp); +int VDI_Healthy(double now, const struct director *, uintptr_t target); +int VDI_Healthy_sp(const struct sess *sp, const struct director *); +void VDI_CloseFd(struct sess *sp); +void VDI_RecycleFd(struct sess *sp); +void VDI_AddHostHeader(const struct sess *sp); void VBE_Poll(void); /* cache_backend_cfg.c */ Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 12:12:47 UTC (rev 5089) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 12:27:45 UTC (rev 5090) @@ -53,21 +53,7 @@ */ static VTAILQ_HEAD(,vbc) vbcs = VTAILQ_HEAD_INITIALIZER(vbcs); -/*-------------------------------------------------------------------- - * Create default Host: header for backend request - */ -void -VBE_AddHostHeader(const struct sess *sp) -{ - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->wrk->bereq, HTTP_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); - http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->bereq, - "Host: %s", sp->vbc->backend->hosthdr); -} - /* Private interface from backend_cfg.c */ void VBE_ReleaseConn(struct vbc *vc) @@ -342,7 +328,7 @@ } VSC_main->backend_toolate++; sp->vbc = vc; - VBE_CloseFd(sp); + VDI_CloseFd(sp); } if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, bp)) { @@ -371,90 +357,6 @@ return (vc); } -/* Close a connection ------------------------------------------------*/ - -void -VBE_CloseFd(struct sess *sp) -{ - struct backend *bp; - - CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); - assert(sp->vbc->fd >= 0); - - bp = sp->vbc->backend; - - WSL(sp->wrk, SLT_BackendClose, sp->vbc->fd, "%s", bp->vcl_name); - TCP_close(&sp->vbc->fd); - VBE_DropRefConn(bp); - sp->vbc->backend = NULL; - VBE_ReleaseConn(sp->vbc); - sp->vbc = NULL; -} - -/* Recycle a connection ----------------------------------------------*/ - -void -VBE_RecycleFd(struct sess *sp) -{ - struct backend *bp; - - CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); - assert(sp->vbc->fd >= 0); - - bp = sp->vbc->backend; - - WSL(sp->wrk, SLT_BackendReuse, sp->vbc->fd, "%s", bp->vcl_name); - /* - * Flush the shmlog, so that another session reusing this backend - * will log chronologically later than our use of it. - */ - WSL_Flush(sp->wrk, 0); - Lck_Lock(&bp->mtx); - VSC_main->backend_recycle++; - VTAILQ_INSERT_HEAD(&bp->connlist, sp->vbc, list); - sp->vbc = NULL; - VBE_DropRefLocked(bp); -} - -/* Get a connection --------------------------------------------------*/ - -struct vbc * -VBE_GetFd(const struct director *d, struct sess *sp) -{ - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - if (d == NULL) - d = sp->director; - CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); - return (d->getfd(d, sp)); -} - -/* Check health ------------------------------------------------------ - * - * The target is really an objhead pointer, but since it can not be - * dereferenced during health-checks, we pass it as uintptr_t, which - * hopefully will make people investigate, before mucking about with it. - */ - -int -VBE_Healthy_sp(const struct sess *sp, const struct director *d) -{ - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); - return (d->healthy(sp->t_req, d, (uintptr_t)sp->objhead)); -} - -int -VBE_Healthy(double now, const struct director *d, uintptr_t target) -{ - - CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); - return (d->healthy(now, d, target)); -} - /*-------------------------------------------------------------------- * The "simple" director really isn't, since thats where all the actual * connections happen. Nontheless, pretend it is simple by sequestering Added: trunk/varnish-cache/bin/varnishd/cache_dir.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir.c (rev 0) +++ trunk/varnish-cache/bin/varnishd/cache_dir.c 2010-08-11 12:27:45 UTC (rev 5090) @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2010 Redpill 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 THE 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. + * + * Handle backend connections and backend request structures. + * + */ + +#include "config.h" + +#include "svnid.h" +SVNID("$Id: cache_backend.c 5089 2010-08-11 12:12:47Z phk $") + +#include "cache.h" +#include "cache_backend.h" + +/*-------------------------------------------------------------------- + * Create default Host: header for backend request + */ +void +VDI_AddHostHeader(const struct sess *sp) +{ + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sp->wrk->bereq, HTTP_MAGIC); + CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); + CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); + http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->bereq, + "Host: %s", sp->vbc->backend->hosthdr); +} + +/* Close a connection ------------------------------------------------*/ + +void +VDI_CloseFd(struct sess *sp) +{ + struct backend *bp; + + CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); + CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); + assert(sp->vbc->fd >= 0); + + bp = sp->vbc->backend; + + WSL(sp->wrk, SLT_BackendClose, sp->vbc->fd, "%s", bp->vcl_name); + TCP_close(&sp->vbc->fd); + VBE_DropRefConn(bp); + sp->vbc->backend = NULL; + VBE_ReleaseConn(sp->vbc); + sp->vbc = NULL; +} + +/* Recycle a connection ----------------------------------------------*/ + +void +VDI_RecycleFd(struct sess *sp) +{ + struct backend *bp; + + CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); + CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); + assert(sp->vbc->fd >= 0); + + bp = sp->vbc->backend; + + WSL(sp->wrk, SLT_BackendReuse, sp->vbc->fd, "%s", bp->vcl_name); + /* + * Flush the shmlog, so that another session reusing this backend + * will log chronologically later than our use of it. + */ + WSL_Flush(sp->wrk, 0); + Lck_Lock(&bp->mtx); + VSC_main->backend_recycle++; + VTAILQ_INSERT_HEAD(&bp->connlist, sp->vbc, list); + sp->vbc = NULL; + VBE_DropRefLocked(bp); +} + +/* Get a connection --------------------------------------------------*/ + +struct vbc * +VDI_GetFd(const struct director *d, struct sess *sp) +{ + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + if (d == NULL) + d = sp->director; + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + return (d->getfd(d, sp)); +} + +/* Check health ------------------------------------------------------ + * + * The target is really an objhead pointer, but since it can not be + * dereferenced during health-checks, we pass it as uintptr_t, which + * hopefully will make people investigate, before mucking about with it. + */ + +int +VDI_Healthy_sp(const struct sess *sp, const struct director *d) +{ + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + return (d->healthy(sp->t_req, d, (uintptr_t)sp->objhead)); +} + +int +VDI_Healthy(double now, const struct director *d, uintptr_t target) +{ + + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + return (d->healthy(now, d, target)); +} Modified: trunk/varnish-cache/bin/varnishd/cache_dir_dns.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-11 12:12:47 UTC (rev 5089) +++ trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-11 12:27:45 UTC (rev 5090) @@ -164,7 +164,7 @@ current = i + initial - nhosts; else current = i + initial; - if (VBE_Healthy_sp(sp, group->hosts[current])) { + if (VDI_Healthy_sp(sp, group->hosts[current])) { group->next_host = current+1; return group->hosts[current]; } @@ -395,10 +395,10 @@ CAST_OBJ_NOTNULL(vs, director->priv, VDI_DNS_MAGIC); dir = vdi_dns_find_backend(sp, vs); - if (!dir || !VBE_Healthy_sp(sp, dir)) + if (!dir || !VDI_Healthy_sp(sp, dir)) return (NULL); - vbe = VBE_GetFd(dir, sp); + vbe = VDI_GetFd(dir, sp); return (vbe); } Modified: trunk/varnish-cache/bin/varnishd/cache_dir_random.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_random.c 2010-08-11 12:12:47 UTC (rev 5089) +++ trunk/varnish-cache/bin/varnishd/cache_dir_random.c 2010-08-11 12:27:45 UTC (rev 5090) @@ -138,9 +138,9 @@ if (r >= s1) continue; d2 = vs->hosts[i].backend; - if (!VBE_Healthy_sp(sp, d2)) + if (!VDI_Healthy_sp(sp, d2)) break; - vbe = VBE_GetFd(d2, sp); + vbe = VDI_GetFd(d2, sp); if (vbe != NULL) return (vbe); break; @@ -153,7 +153,7 @@ for (i = 0; i < vs->nhosts; i++) { d2 = vs->hosts[i].backend; /* XXX: cache result of healty to avoid double work */ - if (VBE_Healthy_sp(sp, d2)) + if (VDI_Healthy_sp(sp, d2)) s1 += vs->hosts[i].weight; } @@ -172,12 +172,12 @@ s1 = 0.0; for (i = 0; i < vs->nhosts; i++) { d2 = vs->hosts[i].backend; - if (!VBE_Healthy_sp(sp, d2)) + if (!VDI_Healthy_sp(sp, d2)) continue; s1 += vs->hosts[i].weight; if (r >= s1) continue; - vbe = VBE_GetFd(d2, sp); + vbe = VDI_GetFd(d2, sp); if (vbe != NULL) return (vbe); break; @@ -197,7 +197,7 @@ CAST_OBJ_NOTNULL(vs, d->priv, VDI_RANDOM_MAGIC); for (i = 0; i < vs->nhosts; i++) { - if (VBE_Healthy(now, vs->hosts[i].backend, target)) + if (VDI_Healthy(now, vs->hosts[i].backend, target)) return 1; } return 0; Modified: trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c 2010-08-11 12:12:47 UTC (rev 5089) +++ trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c 2010-08-11 12:27:45 UTC (rev 5090) @@ -74,9 +74,9 @@ for (i = 0; i < vs->nhosts; i++) { backend = vs->hosts[vs->next_host].backend; vs->next_host = (vs->next_host + 1) % vs->nhosts; - if (!VBE_Healthy_sp(sp, backend)) + if (!VDI_Healthy_sp(sp, backend)) continue; - vbe = VBE_GetFd(backend, sp); + vbe = VDI_GetFd(backend, sp); if (vbe != NULL) return (vbe); } @@ -96,7 +96,7 @@ for (i = 0; i < vs->nhosts; i++) { backend = vs->hosts[i].backend; - if (VBE_Healthy(now, backend, target)) + if (VDI_Healthy(now, backend, target)) return 1; } return 0; Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-11 12:12:47 UTC (rev 5089) +++ trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-11 12:27:45 UTC (rev 5090) @@ -351,7 +351,7 @@ w = sp->wrk; hp = sp->wrk->bereq; - sp->vbc = VBE_GetFd(NULL, sp); + sp->vbc = VDI_GetFd(NULL, sp); if (sp->vbc == NULL) { WSP(sp, SLT_FetchError, "no backend connection"); return (__LINE__); @@ -364,7 +364,7 @@ * XXX: This possibly ought to go into the default VCL */ if (!http_GetHdr(hp, H_Host, &b)) - VBE_AddHostHeader(sp); + VDI_AddHostHeader(sp); (void)TCP_blocking(vc->fd); /* XXX: we should timeout instead */ WRW_Reserve(w, &vc->fd); @@ -374,7 +374,7 @@ i = FetchReqBody(sp); if (WRW_FlushRelease(w) || i > 0) { WSP(sp, SLT_FetchError, "backend write error: %d", errno); - VBE_CloseFd(sp); + VDI_CloseFd(sp); /* XXX: other cleanup ? */ return (__LINE__); } @@ -397,7 +397,7 @@ if (i < 0) { WSP(sp, SLT_FetchError, "http read error: %d", errno); - VBE_CloseFd(sp); + VDI_CloseFd(sp); /* XXX: other cleanup ? */ return (__LINE__); } @@ -412,7 +412,7 @@ if (http_DissectResponse(sp->wrk, sp->wrk->htc, hp)) { WSP(sp, SLT_FetchError, "http format error"); - VBE_CloseFd(sp); + VDI_CloseFd(sp); /* XXX: other cleanup ? */ return (__LINE__); } @@ -466,7 +466,7 @@ sp->wrk->stats.fetch_bad++; /* XXX: AUGH! */ WSL(sp->wrk, SLT_Debug, vc->fd, "Invalid Transfer-Encoding"); - VBE_CloseFd(sp); + VDI_CloseFd(sp); return (__LINE__); } else if (http_HdrIs(hp, H_Connection, "keep-alive")) { /* @@ -515,7 +515,7 @@ VTAILQ_REMOVE(&sp->obj->store, st, list); STV_free(st); } - VBE_CloseFd(sp); + VDI_CloseFd(sp); sp->obj->len = 0; return (__LINE__); } @@ -540,9 +540,9 @@ cls = 1; if (cls) - VBE_CloseFd(sp); + VDI_CloseFd(sp); else - VBE_RecycleFd(sp); + VDI_RecycleFd(sp); return (0); } Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_hash.c 2010-08-11 12:12:47 UTC (rev 5089) +++ trunk/varnish-cache/bin/varnishd/cache_hash.c 2010-08-11 12:27:45 UTC (rev 5090) @@ -402,7 +402,7 @@ if (oc == NULL /* We found no live object */ && grace_oc != NULL /* There is a grace candidate */ && (busy_oc != NULL /* Somebody else is already busy */ - || !VBE_Healthy(sp->t_req, sp->director, (uintptr_t)oh))) { + || !VDI_Healthy(sp->t_req, sp->director, (uintptr_t)oh))) { /* Or it is impossible to fetch: */ o = grace_oc->obj; CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); Modified: trunk/varnish-cache/bin/varnishd/cache_pipe.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_pipe.c 2010-08-11 12:12:47 UTC (rev 5089) +++ trunk/varnish-cache/bin/varnishd/cache_pipe.c 2010-08-11 12:27:45 UTC (rev 5090) @@ -74,7 +74,7 @@ CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); w = sp->wrk; - sp->vbc = VBE_GetFd(NULL, sp); + sp->vbc = VDI_GetFd(NULL, sp); if (sp->vbc == NULL) return; vc = sp->vbc; @@ -91,7 +91,7 @@ if (i) { vca_close_session(sp, "pipe"); - VBE_CloseFd(sp); + VDI_CloseFd(sp); return; } @@ -131,5 +131,5 @@ } } vca_close_session(sp, "pipe"); - VBE_CloseFd(sp); + VDI_CloseFd(sp); } Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-11 12:12:47 UTC (rev 5089) +++ trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-11 12:27:45 UTC (rev 5090) @@ -819,7 +819,7 @@ { CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC); - return (VBE_Healthy_sp(sp, sp->director)); + return (VDI_Healthy_sp(sp, sp->director)); } /*--------------------------------------------------------------------*/ From phk at varnish-cache.org Wed Aug 11 13:22:32 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 11 Aug 2010 15:22:32 +0200 Subject: r5091 - trunk/varnish-cache/include Message-ID: Author: phk Date: 2010-08-11 15:22:31 +0200 (Wed, 11 Aug 2010) New Revision: 5091 Modified: trunk/varnish-cache/include/vsm.h Log: Widen ident field to 64 byte. Modified: trunk/varnish-cache/include/vsm.h =================================================================== --- trunk/varnish-cache/include/vsm.h 2010-08-11 12:27:45 UTC (rev 5090) +++ trunk/varnish-cache/include/vsm.h 2010-08-11 13:22:31 UTC (rev 5091) @@ -52,7 +52,7 @@ unsigned state; char class[8]; char type[8]; - char ident[16]; + char ident[64]; }; #define VSM_NEXT(sha) ((void*)((uintptr_t)(sha) + (sha)->len)) From phk at varnish-cache.org Wed Aug 11 15:27:21 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 11 Aug 2010 17:27:21 +0200 Subject: r5092 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-11 17:27:21 +0200 (Wed, 11 Aug 2010) New Revision: 5092 Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_backend.c trunk/varnish-cache/bin/varnishd/cache_backend.h trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c trunk/varnish-cache/bin/varnishd/cache_backend_poll.c trunk/varnish-cache/bin/varnishd/cache_dir.c trunk/varnish-cache/bin/varnishd/cache_vcl.c Log: Continue the rototilling of the backend code to fit the finally decided naming/identity scheme. Now I just need to get probing working again, will say when it works, right now s00002.vtc plus likely others fail. Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2010-08-11 13:22:31 UTC (rev 5091) +++ trunk/varnish-cache/bin/varnishd/cache.h 2010-08-11 15:27:21 UTC (rev 5092) @@ -453,6 +453,7 @@ #define VBC_MAGIC 0x0c5e6592 VTAILQ_ENTRY(vbc) list; struct backend *backend; + struct vdi_simple *vdis; int fd; /* Timeouts */ @@ -472,6 +473,7 @@ extern pthread_t VCA_thread; /* cache_backend.c */ +void VBE_UseHealth(struct director *vdi); struct vbc *VDI_GetFd(const struct director *, struct sess *sp); int VDI_Healthy(double now, const struct director *, uintptr_t target); Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 13:22:31 UTC (rev 5091) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 15:27:21 UTC (rev 5092) @@ -48,12 +48,43 @@ #include "cache_backend.h" #include "vrt.h" +/*-------------------------------------------------------------------- + * The "simple" director really isn't, since thats where all the actual + * connections happen. Nontheless, pretend it is simple by sequestering + * the directoricity of it under this line. + */ + +struct vdi_simple { + unsigned magic; +#define VDI_SIMPLE_MAGIC 0x476d25b7 + struct director dir; + struct backend *backend; + const struct vrt_backend *vrt; +}; + + /* * List of cached vbcs, used if enabled in params/heritage */ static VTAILQ_HEAD(,vbc) vbcs = VTAILQ_HEAD_INITIALIZER(vbcs); +/*-------------------------------------------------------------------- + * Create default Host: header for backend request + */ +void +VDI_AddHostHeader(const struct sess *sp) +{ + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sp->wrk->bereq, HTTP_MAGIC); + CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); + CHECK_OBJ_NOTNULL(sp->vbc->vdis, VDI_SIMPLE_MAGIC); + http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->bereq, + "Host: %s", sp->vbc->vdis->vrt->hosthdr); +} + +/*--------------------------------------------------------------------*/ + /* Private interface from backend_cfg.c */ void VBE_ReleaseConn(struct vbc *vc) @@ -85,7 +116,6 @@ dst = params->tmx; \ } while (0) - /*-------------------------------------------------------------------- * Attempt to connect to a given addrinfo entry. * @@ -97,7 +127,7 @@ static int vbe_TryConnect(const struct sess *sp, int pf, const struct sockaddr *sa, - socklen_t salen, const struct backend *bp) + socklen_t salen, struct vdi_simple *vs) { int s, i, tmo; double tmod; @@ -105,12 +135,13 @@ char pbuf1[TCP_PORTBUFSIZE], pbuf2[TCP_PORTBUFSIZE]; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC); s = socket(pf, SOCK_STREAM, 0); if (s < 0) return (s); - FIND_TMO(connect_timeout, tmod, sp, bp); + FIND_TMO(connect_timeout, tmod, sp, vs->vrt); tmo = (int)(tmod * 1000.0); @@ -127,7 +158,7 @@ TCP_myname(s, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1); TCP_name(sa, salen, abuf2, sizeof abuf2, pbuf2, sizeof pbuf2); WSL(sp->wrk, SLT_BackendOpen, s, "%s %s %s %s %s", - bp->vcl_name, abuf1, pbuf1, abuf2, pbuf2); + vs->backend->vcl_name, abuf1, pbuf1, abuf2, pbuf2); return (s); } @@ -135,10 +166,13 @@ /*--------------------------------------------------------------------*/ static int -bes_conn_try(const struct sess *sp, struct backend *bp) +bes_conn_try(const struct sess *sp, struct vdi_simple *vs) { int s; + struct backend *bp = vs->backend; + CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC); + Lck_Lock(&bp->mtx); bp->refcount++; bp->n_conn++; /* It mostly works */ @@ -150,11 +184,11 @@ /* release lock during stuff that can take a long time */ if (params->prefer_ipv6 && bp->ipv6 != NULL) - s = vbe_TryConnect(sp, PF_INET6, bp->ipv6, bp->ipv6len, bp); + s = vbe_TryConnect(sp, PF_INET6, bp->ipv6, bp->ipv6len, vs); if (s == -1 && bp->ipv4 != NULL) - s = vbe_TryConnect(sp, PF_INET, bp->ipv4, bp->ipv4len, bp); + s = vbe_TryConnect(sp, PF_INET, bp->ipv4, bp->ipv4len, vs); if (s == -1 && !params->prefer_ipv6 && bp->ipv6 != NULL) - s = vbe_TryConnect(sp, PF_INET6, bp->ipv6, bp->ipv6len, bp); + s = vbe_TryConnect(sp, PF_INET6, bp->ipv6, bp->ipv6len, vs); if (s < 0) { Lck_Lock(&bp->mtx); @@ -215,7 +249,6 @@ return (vc); } - /*-------------------------------------------------------------------- * It evaluates if a backend is healthy _for_a_specific_object_. * That means that it relies on sp->objhead. This is mainly for saint-mode, @@ -228,7 +261,7 @@ */ static unsigned int -vbe_Healthy(double now, uintptr_t target, struct backend *backend) +vbe_Healthy(double now, uintptr_t target, struct vdi_simple *vs, struct backend *backend) { struct trouble *tr; struct trouble *tr2; @@ -236,6 +269,7 @@ unsigned i = 0, retval; unsigned int threshold; + CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC); CHECK_OBJ_NOTNULL(backend, BACKEND_MAGIC); if (!backend->healthy) @@ -244,10 +278,10 @@ /* VRT/VCC sets threshold to UINT_MAX to mark that it's not * specified by VCL (thus use param). */ - if (backend->saintmode_threshold == UINT_MAX) + if (vs->vrt->saintmode_threshold == UINT_MAX) threshold = params->saintmode_threshold; else - threshold = backend->saintmode_threshold; + threshold = vs->vrt->saintmode_threshold; /* Saintmode is disabled */ if (threshold == 0) @@ -299,11 +333,14 @@ */ static struct vbc * -vbe_GetVbe(struct sess *sp, struct backend *bp) +vbe_GetVbe(struct sess *sp, struct vdi_simple *vs) { struct vbc *vc; + struct backend *bp; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC); + bp = vs->backend; CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC); /* first look for vbc's we can recycle */ @@ -324,6 +361,7 @@ VSC_main->backend_reuse += 1; WSP(sp, SLT_Backend, "%d %s %s", vc->fd, sp->director->vcl_name, bp->vcl_name); + vc->vdis = vs; return (vc); } VSC_main->backend_toolate++; @@ -331,12 +369,13 @@ VDI_CloseFd(sp); } - if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, bp)) { + if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, vs, bp)) { VSC_main->backend_unhealthy++; return (NULL); } - if (bp->max_conn > 0 && bp->n_conn >= bp->max_conn) { + if (vs->vrt->max_connections > 0 && + bp->n_conn >= vs->vrt->max_connections) { VSC_main->backend_busy++; return (NULL); } @@ -344,7 +383,7 @@ vc = vbe_NewConn(); assert(vc->fd == -1); AZ(vc->backend); - vc->fd = bes_conn_try(sp, bp); + vc->fd = bes_conn_try(sp, vs); if (vc->fd < 0) { VBE_ReleaseConn(vc); VSC_main->backend_fail++; @@ -354,27 +393,17 @@ VSC_main->backend_conn++; WSP(sp, SLT_Backend, "%d %s %s", vc->fd, sp->director->vcl_name, bp->vcl_name); + vc->vdis = vs; return (vc); } /*-------------------------------------------------------------------- - * The "simple" director really isn't, since thats where all the actual - * connections happen. Nontheless, pretend it is simple by sequestering - * the directoricity of it under this line. - */ - -struct vdi_simple { - unsigned magic; -#define VDI_SIMPLE_MAGIC 0x476d25b7 - struct director dir; - struct backend *backend; -}; - -/* Returns the backend if and only if the this is a simple director. + * Returns the backend if and only if the this is a simple director. * XXX: Needs a better name and possibly needs a better general approach. * XXX: This is mainly used by the DNS director to fetch the actual backend * XXX: so it can compare DNS lookups with the actual IP. */ + struct backend * vdi_get_backend_if_simple(const struct director *d) { @@ -385,9 +414,33 @@ if (vs2->magic != VDI_SIMPLE_MAGIC) return NULL; CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); - return vs->backend; + return (vs->backend); } +/*-------------------------------------------------------------------- + * + */ + +void +VBE_UseHealth(struct director *vdi) +{ + struct vdi_simple *vs; + + ASSERT_CLI(); + + if (strcmp(vdi->name, "simple")) + return; + printf("USE HEALTH %p\n", vdi); + CAST_OBJ_NOTNULL(vs, vdi->priv, VDI_SIMPLE_MAGIC); + if (vs->vrt->probe == NULL) + return; + VBP_Start(vs->backend, vs->vrt->probe, vs->vrt->hosthdr); +} + +/*-------------------------------------------------------------------- + * + */ + static struct vbc * vdi_simple_getfd(const struct director *d, struct sess *sp) { @@ -397,12 +450,12 @@ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); - vc = vbe_GetVbe(sp, vs->backend); + vc = vbe_GetVbe(sp, vs); if (vc != NULL) { FIND_TMO(first_byte_timeout, - vc->first_byte_timeout, sp, vc->backend); + vc->first_byte_timeout, sp, vs->vrt); FIND_TMO(between_bytes_timeout, - vc->between_bytes_timeout, sp, vc->backend); + vc->between_bytes_timeout, sp, vs->vrt); } return (vc); } @@ -414,7 +467,7 @@ CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); - return (vbe_Healthy(now, target, vs->backend)); + return (vbe_Healthy(now, target, vs, vs->backend)); } /*lint -e{818} not const-able */ @@ -426,8 +479,8 @@ CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); + VBP_Stop(vs->backend, vs->vrt->probe); VBE_DropRef(vs->backend); - // vbe_stat_deref(vs->dir.vcl_name); free(vs->dir.vcl_name); vs->dir.magic = 0; FREE_OBJ(vs); @@ -454,7 +507,11 @@ vs->dir.fini = vdi_simple_fini; vs->dir.healthy = vdi_simple_healthy; + vs->vrt = t; + vs->backend = VBE_AddBackend(cli, t); + if (vs->backend->probe == NULL) + VBP_Start(vs->backend, vs->vrt->probe, vs->vrt->hosthdr); bp[idx] = &vs->dir; } Modified: trunk/varnish-cache/bin/varnishd/cache_backend.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-08-11 13:22:31 UTC (rev 5091) +++ trunk/varnish-cache/bin/varnishd/cache_backend.h 2010-08-11 15:27:21 UTC (rev 5092) @@ -117,7 +117,6 @@ int refcount; struct lock mtx; - char *hosthdr; char *vcl_name; char *ipv4_addr; char *ipv6_addr; @@ -136,12 +135,6 @@ VTAILQ_HEAD(, trouble) troublelist; struct vsc_vbe *vsc; - - double connect_timeout; - double first_byte_timeout; - double between_bytes_timeout; - unsigned max_conn; - unsigned saintmode_threshold; }; /* cache_backend.c */ @@ -155,10 +148,9 @@ void VBE_DropRefLocked(struct backend *b); /* cache_backend_poll.c */ -void VBP_Start(struct backend *b, struct vrt_backend_probe const *p); -void VBP_Stop(struct backend *b); +void VBP_Start(struct backend *b, struct vrt_backend_probe const *p, const char *hosthdr); +void VBP_Stop(struct backend *b, struct vrt_backend_probe const *p); - /* Init functions for directors */ typedef void dir_init_f(struct cli *, struct director **, int , const void*); dir_init_f VRT_init_dir_simple; Modified: trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 13:22:31 UTC (rev 5091) +++ trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 15:27:21 UTC (rev 5092) @@ -56,7 +56,6 @@ */ static VTAILQ_HEAD(, backend) backends = VTAILQ_HEAD_INITIALIZER(backends); - /*-------------------------------------------------------------------- */ @@ -66,7 +65,6 @@ ASSERT_CLI(); VTAILQ_REMOVE(&backends, b, list); - free(b->hosthdr); free(b->ipv4); free(b->ipv4_addr); free(b->ipv6); @@ -122,10 +120,7 @@ vbe->backend = NULL; VBE_ReleaseConn(vbe); } - if (b->probe != NULL) - VBP_Stop(b); - else - VBE_Nuke(b); + VBE_Nuke(b); } void @@ -222,14 +217,7 @@ REPLACE(b->ipv4_addr, vb->ipv4_addr); REPLACE(b->ipv6_addr, vb->ipv6_addr); REPLACE(b->port, vb->port); - REPLACE(b->hosthdr, vb->hosthdr); - b->connect_timeout = vb->connect_timeout; - b->first_byte_timeout = vb->first_byte_timeout; - b->between_bytes_timeout = vb->between_bytes_timeout; - b->max_conn = vb->max_connections; - b->saintmode_threshold = vb->saintmode_threshold; - /* * Copy over the sockaddrs */ @@ -240,13 +228,13 @@ assert(b->ipv4 != NULL || b->ipv6 != NULL); - VBP_Start(b, vb->probe); + b->healthy = 1; + VTAILQ_INSERT_TAIL(&backends, b, list); VSC_main->n_backend++; return (b); } - /*--------------------------------------------------------------------*/ void @@ -293,10 +281,9 @@ ASSERT_CLI(); VTAILQ_FOREACH(b, &backends, list) { CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); - cli_out(cli, "%p %s(%s,%s,:%s) %d %d/%d\n", + cli_out(cli, "%p %s(%s,%s,:%s) %d %d\n", b, b->vcl_name, b->ipv4_addr, b->ipv6_addr, b->port, - b->refcount, - b->n_conn, b->max_conn); + b->refcount, b->n_conn); } } Modified: trunk/varnish-cache/bin/varnishd/cache_backend_poll.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2010-08-11 13:22:31 UTC (rev 5091) +++ trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2010-08-11 15:27:21 UTC (rev 5092) @@ -57,11 +57,23 @@ /* Default averaging rate, we want something pretty responsive */ #define AVG_RATE 4 +struct vbp_vcl { + unsigned magic; +#define VBP_VCL_MAGIC 0x70829764 + + VTAILQ_ENTRY(vbp_vcl) list; + const struct vrt_backend_probe *probe; + const char *hosthdr; +}; + struct vbp_target { unsigned magic; #define VBP_TARGET_MAGIC 0x6b7cb656 struct backend *backend; + VTAILQ_HEAD( ,vbp_vcl) vcls; + + const struct vrt_backend_probe *probe_cache; struct vrt_backend_probe probe; int stop; char *req; @@ -86,6 +98,8 @@ static VTAILQ_HEAD(, vbp_target) vbp_list = VTAILQ_HEAD_INITIALIZER(vbp_list); +static struct lock vbp_mtx; + static const char default_request[] = "GET / HTTP/1.1\r\n" "Connection: close\r\n" @@ -413,27 +427,51 @@ }; /*-------------------------------------------------------------------- - * Start/Stop called from cache_backend_cfg.c + * Start/Stop called from cache_backend.c */ void -VBP_Start(struct backend *b, struct vrt_backend_probe const *p) +VBP_Start(struct backend *b, const struct vrt_backend_probe *p, const char *hosthdr) { struct vbp_target *vt; struct vsb *vsb; + struct vbp_vcl *vcl; + int startthread = 0; ASSERT_CLI(); - if (p == NULL) { - b->healthy = 1; + if (p == NULL) return; + + Lck_Lock(&vbp_mtx); + if (b->probe == NULL) { + ALLOC_OBJ(vt, VBP_TARGET_MAGIC); + XXXAN(vt); + VTAILQ_INIT(&vt->vcls); + vt->backend = b; + startthread = 1; + VTAILQ_INSERT_TAIL(&vbp_list, vt, list); + } else { + vt = b->probe; } - ALLOC_OBJ(vt, VBP_TARGET_MAGIC); - AN(vt); - vt->backend = b; - vt->probe = *p; + VTAILQ_FOREACH(vcl, &vt->vcls, list) + if (vcl->probe == p) + break; + if (vcl == NULL) { + ALLOC_OBJ(vcl, VBP_VCL_MAGIC); + XXXAN(vcl); + vcl->probe = p; + vcl->hosthdr = hosthdr; + VTAILQ_INSERT_HEAD(&vt->vcls, vcl, list); + } else { + VTAILQ_REMOVE(&vt->vcls, vcl, list); + VTAILQ_INSERT_HEAD(&vt->vcls, vcl, list); + } + + vt->probe = *vcl->probe; + p = &vt->probe; if(p->request != NULL) { @@ -443,8 +481,8 @@ XXXAN(vsb); vsb_printf(vsb, "GET %s HTTP/1.1\r\n", p->url != NULL ? p->url : "/"); - if (b->hosthdr != NULL) - vsb_printf(vsb, "Host: %s\r\n", b->hosthdr); + if (hosthdr != NULL) + vsb_printf(vsb, "Host: %s\r\n", hosthdr); vsb_printf(vsb, "Connection: close\r\n"); vsb_printf(vsb, "\r\n"); vsb_finish(vsb); @@ -455,25 +493,48 @@ } vt->req_len = strlen(vt->req); - b->probe = vt; - - VTAILQ_INSERT_TAIL(&vbp_list, vt, list); - - AZ(pthread_create(&vt->thread, NULL, vbp_wrk_poll_backend, vt)); + Lck_Unlock(&vbp_mtx); + if (startthread) + AZ(pthread_create(&vt->thread, NULL, vbp_wrk_poll_backend, vt)); } void -VBP_Stop(struct backend *b) +VBP_Stop(struct backend *b, struct vrt_backend_probe const *p) { struct vbp_target *vt; + struct vbp_vcl *vcl; void *ret; + int first; + ASSERT_CLI(); + + if (p == NULL) + return; + CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); - ASSERT_CLI(); - if (b->probe == NULL) + Lck_Lock(&vbp_mtx); + AN(b->probe); + vt = b->probe; + VTAILQ_FOREACH(vcl, &vt->vcls, list) + if (vcl->probe == p) + break; + AN(vcl); + first = (vcl == VTAILQ_FIRST(&vt->vcls)); + VTAILQ_REMOVE(&vt->vcls, vcl, list); + Lck_Unlock(&vbp_mtx); + + FREE_OBJ(vcl); + if (!first) return; - CHECK_OBJ_NOTNULL(b->probe, VBP_TARGET_MAGIC); + vcl = VTAILQ_FIRST(&vt->vcls); + if (vcl != NULL) { + VBP_Start(b, vcl->probe, vcl->hosthdr); + return; + } + + /* No more polling for this backend */ + vt = b->probe; vt->stop = 1; @@ -493,5 +554,6 @@ VBP_Init(void) { + Lck_New(&vbp_mtx); CLI_AddFuncs(debug_cmds); } Modified: trunk/varnish-cache/bin/varnishd/cache_dir.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir.c 2010-08-11 13:22:31 UTC (rev 5091) +++ trunk/varnish-cache/bin/varnishd/cache_dir.c 2010-08-11 15:27:21 UTC (rev 5092) @@ -38,21 +38,6 @@ #include "cache.h" #include "cache_backend.h" -/*-------------------------------------------------------------------- - * Create default Host: header for backend request - */ -void -VDI_AddHostHeader(const struct sess *sp) -{ - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->wrk->bereq, HTTP_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); - http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->bereq, - "Host: %s", sp->vbc->backend->hosthdr); -} - /* Close a connection ------------------------------------------------*/ void Modified: trunk/varnish-cache/bin/varnishd/cache_vcl.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vcl.c 2010-08-11 13:22:31 UTC (rev 5091) +++ trunk/varnish-cache/bin/varnishd/cache_vcl.c 2010-08-11 15:27:21 UTC (rev 5092) @@ -290,6 +290,7 @@ ccf_config_use(struct cli *cli, const char * const *av, void *priv) { struct vcls *vcl; + int i; (void)av; (void)priv; @@ -302,6 +303,10 @@ Lck_Lock(&vcl_mtx); vcl_active = vcl; Lck_Unlock(&vcl_mtx); + + /* Tickle this VCL's backends to take over health polling */ + for(i = 1; i < vcl->conf->ndirector; i++) + VBE_UseHealth(vcl->conf->director[i]); } /*--------------------------------------------------------------------*/ From phk at varnish-cache.org Wed Aug 11 19:44:01 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 11 Aug 2010 21:44:01 +0200 Subject: r5093 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-11 21:44:00 +0200 (Wed, 11 Aug 2010) New Revision: 5093 Modified: trunk/varnish-cache/bin/varnishd/cache_backend_poll.c Log: Push the new backend naming reality into the backend probe code and make it work again to the point where all test-cases pass. Modified: trunk/varnish-cache/bin/varnishd/cache_backend_poll.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2010-08-11 15:27:21 UTC (rev 5092) +++ trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2010-08-11 19:44:00 UTC (rev 5093) @@ -62,7 +62,8 @@ #define VBP_VCL_MAGIC 0x70829764 VTAILQ_ENTRY(vbp_vcl) list; - const struct vrt_backend_probe *probe; + const struct vrt_backend_probe *probep; + struct vrt_backend_probe probe; const char *hosthdr; }; @@ -73,10 +74,10 @@ struct backend *backend; VTAILQ_HEAD( ,vbp_vcl) vcls; - const struct vrt_backend_probe *probe_cache; struct vrt_backend_probe probe; int stop; - char *req; + struct vsb *vsb; + char *req; int req_len; char resp_buf[128]; @@ -305,6 +306,31 @@ } /*-------------------------------------------------------------------- + * Build request from probe spec + */ + +static void +vbp_build_req(struct vsb *vsb, const struct vbp_vcl *vcl) +{ + + XXXAN(vsb); + XXXAN(vcl); + vsb_clear(vsb); + if(vcl->probe.request != NULL) { + vsb_cat(vsb, vcl->probe.request); + } else { + vsb_printf(vsb, "GET %s HTTP/1.1\r\n", + vcl->probe.url != NULL ? vcl->probe.url : "/"); + if (vcl->hosthdr != NULL) + vsb_printf(vsb, "Host: %s\r\n", vcl->hosthdr); + vsb_printf(vsb, "Connection: close\r\n"); + vsb_printf(vsb, "\r\n"); + } + vsb_finish(vsb); + AZ(vsb_overflowed(vsb)); +} + +/*-------------------------------------------------------------------- * One thread per backend to be poked. */ @@ -312,48 +338,28 @@ vbp_wrk_poll_backend(void *priv) { struct vbp_target *vt; - unsigned u; + struct vbp_vcl *vcl = NULL; THR_SetName("backend poll"); CAST_OBJ_NOTNULL(vt, priv, VBP_TARGET_MAGIC); - /* - * Establish defaults - * XXX: we could make these defaults parameters - */ - if (vt->probe.request == NULL) - vt->probe.request = default_request; - if (vt->probe.timeout == 0.0) - vt->probe.timeout = 2.0; - if (vt->probe.interval == 0.0) - vt->probe.interval = 5.0; - if (vt->probe.window == 0) - vt->probe.window = 8; - if (vt->probe.threshold == 0) - vt->probe.threshold = 3; - if (vt->probe.exp_status == 0) - vt->probe.exp_status = 200; + while (!vt->stop) { + Lck_Lock(&vbp_mtx); + if (VTAILQ_FIRST(&vt->vcls) != vcl) { + vcl = VTAILQ_FIRST(&vt->vcls); + vbp_build_req(vt->vsb, vcl); + vt->probe = vcl->probe; + } + Lck_Unlock(&vbp_mtx); - if (vt->probe.threshold == ~0U) - vt->probe.initial = vt->probe.threshold - 1; + vt->req = vsb_data(vt->vsb); + vt->req_len = vsb_len(vt->vsb); - if (vt->probe.initial > vt->probe.threshold) - vt->probe.initial = vt->probe.threshold; - - printf("Probe(\"%s\", %g, %g)\n", - vt->req, vt->probe.timeout, vt->probe.interval); - - for (u = 0; u < vt->probe.initial; u++) { vbp_start_poke(vt); - vt->happy |= 1; + vbp_poke(vt); vbp_has_poked(vt); - } - while (!vt->stop) { - vbp_start_poke(vt); - vbp_poke(vt); - vbp_has_poked(vt); if (!vt->stop) TIM_sleep(vt->probe.interval); } @@ -427,6 +433,46 @@ }; /*-------------------------------------------------------------------- + * A new VCL wants to probe this backend, + */ + +static struct vbp_vcl * +vbp_new_vcl(const struct vrt_backend_probe *p, const char *hosthdr) +{ + struct vbp_vcl *vcl; + + ALLOC_OBJ(vcl, VBP_VCL_MAGIC); + XXXAN(vcl); + vcl->probep = p; + vcl->probe = *p; + vcl->hosthdr = hosthdr; + + /* + * Sanitize and insert defaults + * XXX: we could make these defaults parameters + */ + if (vcl->probe.request == NULL) + vcl->probe.request = default_request; + if (vcl->probe.timeout == 0.0) + vcl->probe.timeout = 2.0; + if (vcl->probe.interval == 0.0) + vcl->probe.interval = 5.0; + if (vcl->probe.window == 0) + vcl->probe.window = 8; + if (vcl->probe.threshold == 0) + vcl->probe.threshold = 3; + if (vcl->probe.exp_status == 0) + vcl->probe.exp_status = 200; + + if (vcl->probe.threshold == ~0U) + vcl->probe.initial = vcl->probe.threshold - 1; + + if (vcl->probe.initial > vcl->probe.threshold) + vcl->probe.initial = vcl->probe.threshold; + return (vcl); +} + +/*-------------------------------------------------------------------- * Start/Stop called from cache_backend.c */ @@ -434,68 +480,54 @@ VBP_Start(struct backend *b, const struct vrt_backend_probe *p, const char *hosthdr) { struct vbp_target *vt; - struct vsb *vsb; struct vbp_vcl *vcl; int startthread = 0; + unsigned u; ASSERT_CLI(); if (p == NULL) return; - Lck_Lock(&vbp_mtx); if (b->probe == NULL) { ALLOC_OBJ(vt, VBP_TARGET_MAGIC); XXXAN(vt); VTAILQ_INIT(&vt->vcls); vt->backend = b; + vt->vsb = vsb_newauto(); + XXXAN(vt->vsb); + b->probe = vt; startthread = 1; VTAILQ_INSERT_TAIL(&vbp_list, vt, list); } else { vt = b->probe; } - VTAILQ_FOREACH(vcl, &vt->vcls, list) - if (vcl->probe == p) - break; + VTAILQ_FOREACH(vcl, &vt->vcls, list) { + if (vcl->probep != p) + continue; - if (vcl == NULL) { - ALLOC_OBJ(vcl, VBP_VCL_MAGIC); - XXXAN(vcl); - vcl->probe = p; - vcl->hosthdr = hosthdr; - VTAILQ_INSERT_HEAD(&vt->vcls, vcl, list); - } else { + AZ(startthread); + Lck_Lock(&vbp_mtx); VTAILQ_REMOVE(&vt->vcls, vcl, list); VTAILQ_INSERT_HEAD(&vt->vcls, vcl, list); + Lck_Unlock(&vbp_mtx); + return; } - vt->probe = *vcl->probe; + vcl = vbp_new_vcl(p, hosthdr); + Lck_Lock(&vbp_mtx); + VTAILQ_INSERT_HEAD(&vt->vcls, vcl, list); + Lck_Unlock(&vbp_mtx); - p = &vt->probe; - - if(p->request != NULL) { - REPLACE(vt->req, p->request); - } else { - vsb = vsb_newauto(); - XXXAN(vsb); - vsb_printf(vsb, "GET %s HTTP/1.1\r\n", - p->url != NULL ? p->url : "/"); - if (hosthdr != NULL) - vsb_printf(vsb, "Host: %s\r\n", hosthdr); - vsb_printf(vsb, "Connection: close\r\n"); - vsb_printf(vsb, "\r\n"); - vsb_finish(vsb); - AZ(vsb_overflowed(vsb)); - vt->req = strdup(vsb_data(vsb)); - XXXAN(vt->req); - vsb_delete(vsb); + if (startthread) { + for (u = 0; u < vcl->probe.initial; u++) { + vbp_start_poke(vt); + vt->happy |= 1; + vbp_has_poked(vt); + } + AZ(pthread_create(&vt->thread, NULL, vbp_wrk_poll_backend, vt)); } - vt->req_len = strlen(vt->req); - - Lck_Unlock(&vbp_mtx); - if (startthread) - AZ(pthread_create(&vt->thread, NULL, vbp_wrk_poll_backend, vt)); } void @@ -504,7 +536,6 @@ struct vbp_target *vt; struct vbp_vcl *vcl; void *ret; - int first; ASSERT_CLI(); @@ -513,36 +544,32 @@ CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); - Lck_Lock(&vbp_mtx); AN(b->probe); vt = b->probe; VTAILQ_FOREACH(vcl, &vt->vcls, list) - if (vcl->probe == p) + if (vcl->probep == p) break; + AN(vcl); - first = (vcl == VTAILQ_FIRST(&vt->vcls)); + + Lck_Lock(&vbp_mtx); VTAILQ_REMOVE(&vt->vcls, vcl, list); Lck_Unlock(&vbp_mtx); FREE_OBJ(vcl); - if (!first) + + if (!VTAILQ_EMPTY(&vt->vcls)) return; - vcl = VTAILQ_FIRST(&vt->vcls); - if (vcl != NULL) { - VBP_Start(b, vcl->probe, vcl->hosthdr); - return; - } /* No more polling for this backend */ - vt = b->probe; - vt->stop = 1; AZ(pthread_cancel(vt->thread)); AZ(pthread_join(vt->thread, &ret)); VTAILQ_REMOVE(&vbp_list, vt, list); b->probe = NULL; + vsb_delete(vt->vsb); FREE_OBJ(vt); } From phk at varnish-cache.org Wed Aug 11 20:08:30 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 11 Aug 2010 22:08:30 +0200 Subject: r5094 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-11 22:08:29 +0200 (Wed, 11 Aug 2010) New Revision: 5094 Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c Log: Properly eliminate NULL pointer printing in backend ID. Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 19:44:00 UTC (rev 5093) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 20:08:29 UTC (rev 5094) @@ -476,6 +476,7 @@ { struct vdi_simple *vs; + ASSERT_CLI(); CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); Modified: trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 19:44:00 UTC (rev 5093) +++ trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 20:08:29 UTC (rev 5094) @@ -102,10 +102,12 @@ int i; struct vbc *vbe, *vbe2; + ASSERT_CLI(); CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); assert(b->refcount > 0); i = --b->refcount; + b->vsc->vcls--; Lck_Unlock(&b->mtx); if (i > 0) return; @@ -191,6 +193,7 @@ memcmp(b->ipv6, vb->ipv6_sockaddr + 1, b->ipv6len))) continue; b->refcount++; + b->vsc->vcls++; return (b); } @@ -201,9 +204,12 @@ b->refcount = 1; bprintf(buf, "%s(%s,%s,%s)", - vb->vcl_name, vb->ipv4_addr, vb->ipv6_addr, vb->port); + vb->vcl_name, + vb->ipv4_addr == NULL ? "" : vb->ipv4_addr, + vb->ipv6_addr == NULL ? "" : vb->ipv6_addr, vb->port); b->vsc = VSM_Alloc(sizeof *b->vsc, VSC_CLASS, VSC_TYPE_VBE, buf); + b->vsc->vcls++; VTAILQ_INIT(&b->connlist); From phk at varnish-cache.org Wed Aug 11 20:52:20 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 11 Aug 2010 22:52:20 +0200 Subject: r5095 - in trunk/varnish-cache: bin/varnishd bin/varnishstat include Message-ID: Author: phk Date: 2010-08-11 22:52:20 +0200 (Wed, 11 Aug 2010) New Revision: 5095 Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c trunk/varnish-cache/bin/varnishd/cache_backend_poll.c trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c trunk/varnish-cache/include/vsc_fields.h Log: Add another per-backend variable to show the happy health-probe bitmap. Add cheesy display of same in varnishstat curses mode: 16 0.00 1.00 uptime - Client uptime 1 . . VBE.fs(192.168.60.20,,80).vcls - VCL references 0000000000 <____VVVVVVVVVVVVVVVVVVVV VBE.fs(192.168.60.20,,80).happy - Happy health probes top bits bottom bits one-by-one We need to start thinking about how to structure varnishstat output... Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 20:08:29 UTC (rev 5094) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-11 20:52:20 UTC (rev 5095) @@ -430,7 +430,6 @@ if (strcmp(vdi->name, "simple")) return; - printf("USE HEALTH %p\n", vdi); CAST_OBJ_NOTNULL(vs, vdi->priv, VDI_SIMPLE_MAGIC); if (vs->vrt->probe == NULL) return; Modified: trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 20:08:29 UTC (rev 5094) +++ trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c 2010-08-11 20:52:20 UTC (rev 5095) @@ -102,7 +102,6 @@ int i; struct vbc *vbe, *vbe2; - ASSERT_CLI(); CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); assert(b->refcount > 0); Modified: trunk/varnish-cache/bin/varnishd/cache_backend_poll.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2010-08-11 20:08:29 UTC (rev 5094) +++ trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2010-08-11 20:52:20 UTC (rev 5095) @@ -101,11 +101,6 @@ static struct lock vbp_mtx; -static const char default_request[] = - "GET / HTTP/1.1\r\n" - "Connection: close\r\n" - "\r\n"; - /*-------------------------------------------------------------------- * Poke one backend, once, but possibly at both IPv4 and IPv6 addresses. * @@ -303,6 +298,7 @@ vt->backend->vcl_name, logmsg, bits, vt->good, vt->probe.threshold, vt->probe.window, vt->last, vt->avg, vt->resp_buf); + vt->backend->vsc->happy = vt->happy; } /*-------------------------------------------------------------------- @@ -451,8 +447,6 @@ * Sanitize and insert defaults * XXX: we could make these defaults parameters */ - if (vcl->probe.request == NULL) - vcl->probe.request = default_request; if (vcl->probe.timeout == 0.0) vcl->probe.timeout = 2.0; if (vcl->probe.interval == 0.0) Modified: trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c =================================================================== --- trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c 2010-08-11 20:08:29 UTC (rev 5094) +++ trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c 2010-08-11 20:52:20 UTC (rev 5095) @@ -215,6 +215,15 @@ ju, (ju - (intmax_t)pt->ref)/lt, ju / up, pt->name)); pt->ref = ju; + } else if (pt->type == 'b') { + AC(mvprintw(line, 0, " %010.10jx <", + (ju >> 24) & 0xffffffffffLL)); + for (ch = 0x800000; ch; ch >>= 1) + if (ju & ch) + AC(printw("V")); + else + AC(printw("_")); + AC(printw(" %s", pt->name)); } else { AC(mvprintw(line, 0, "%12ju %12s %12s %s\n", Modified: trunk/varnish-cache/include/vsc_fields.h =================================================================== --- trunk/varnish-cache/include/vsc_fields.h 2010-08-11 20:08:29 UTC (rev 5094) +++ trunk/varnish-cache/include/vsc_fields.h 2010-08-11 20:52:20 UTC (rev 5095) @@ -193,6 +193,7 @@ #endif VSC_F_VBE(vcls, uint64_t, 0, 'i', "VCL references") +VSC_F_VBE(happy, uint64_t, 0, 'b', "Happy health probes") #ifdef __VSC_F_VBE #undef VSC_F_VBE From phk at varnish-cache.org Thu Aug 12 08:13:15 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 12 Aug 2010 10:13:15 +0200 Subject: r5096 - in trunk/varnish-cache/bin: varnishd varnishtest varnishtest/tests Message-ID: Author: phk Date: 2010-08-12 10:13:15 +0200 (Thu, 12 Aug 2010) New Revision: 5096 Added: trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc Modified: trunk/varnish-cache/bin/varnishd/cache_backend_poll.c trunk/varnish-cache/bin/varnishd/cache_fetch.c trunk/varnish-cache/bin/varnishtest/vtc_server.c Log: Set backend health good if we stop polling the health. Modified: trunk/varnish-cache/bin/varnishd/cache_backend_poll.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2010-08-11 20:52:20 UTC (rev 5095) +++ trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2010-08-12 08:13:15 UTC (rev 5096) @@ -557,10 +557,14 @@ /* No more polling for this backend */ + b->healthy = 1; + vt->stop = 1; AZ(pthread_cancel(vt->thread)); AZ(pthread_join(vt->thread, &ret)); + b->healthy = 1; + VTAILQ_REMOVE(&vbp_list, vt, list); b->probe = NULL; vsb_delete(vt->vsb); Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-11 20:52:20 UTC (rev 5095) +++ trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-12 08:13:15 UTC (rev 5096) @@ -396,7 +396,7 @@ i = HTC_Rx(sp->wrk->htc); if (i < 0) { WSP(sp, SLT_FetchError, - "http read error: %d", errno); + "http read error: %d (%s)", errno, strerror(errno)); VDI_CloseFd(sp); /* XXX: other cleanup ? */ return (__LINE__); Added: trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc (rev 0) +++ trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc 2010-08-12 08:13:15 UTC (rev 5096) @@ -0,0 +1,48 @@ +# $Id$ + +test "Dropping polling of a backend" + +server s1 -repeat 1 { + rxreq + txresp +} -start + +varnish v1 -vcl { + backend s1 { + .host = "${s1_addr}"; + .port = "${s1_port}"; + .probe = { + .window = 8; + .initial = 7; + .threshold = 8; + .interval = 0.1s; + } + } +} -start + +delay 1 + +varnish v1 -vcl { + backend s1 { + .host = "${s1_addr}"; + .port = "${s1_port}"; + } +} -cliok "vcl.use vcl2" -cliok "vcl.discard vcl1" + +delay .5 + +varnish v1 -cliok "vcl.list" +varnish v1 -cliok "debug.health" + +server s1 { + rxreq + expect req.url == /foo + txresp -bodylen 4 +} -start + +client c1 { + txreq -url /foo + rxresp + expect resp.status == 200 + expect resp.bodylen == 4 +} -run Modified: trunk/varnish-cache/bin/varnishtest/vtc_server.c =================================================================== --- trunk/varnish-cache/bin/varnishtest/vtc_server.c 2010-08-11 20:52:20 UTC (rev 5095) +++ trunk/varnish-cache/bin/varnishtest/vtc_server.c 2010-08-12 08:13:15 UTC (rev 5096) @@ -112,9 +112,6 @@ vtc_log(vl, 0, "Shutdown failed: %s", strerror(errno)); TCP_close(&fd); } - macro_def(s->vl, s->name, "addr", NULL); - macro_def(s->vl, s->name, "port", NULL); - macro_def(s->vl, s->name, "sock", NULL); vtc_log(vl, 2, "Ending"); return (NULL); } @@ -155,6 +152,9 @@ { CHECK_OBJ_NOTNULL(s, SERVER_MAGIC); + macro_def(s->vl, s->name, "addr", NULL); + macro_def(s->vl, s->name, "port", NULL); + macro_def(s->vl, s->name, "sock", NULL); vtc_logclose(s->vl); free(s->name); /* XXX: MEMLEAK (?) (VSS ??) */ From phk at varnish-cache.org Thu Aug 12 08:38:52 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 12 Aug 2010 10:38:52 +0200 Subject: r5097 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-12 10:38:51 +0200 (Thu, 12 Aug 2010) New Revision: 5097 Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_backend.c Log: Constification Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2010-08-12 08:13:15 UTC (rev 5096) +++ trunk/varnish-cache/bin/varnishd/cache.h 2010-08-12 08:38:51 UTC (rev 5097) @@ -473,7 +473,7 @@ extern pthread_t VCA_thread; /* cache_backend.c */ -void VBE_UseHealth(struct director *vdi); +void VBE_UseHealth(const struct director *vdi); struct vbc *VDI_GetFd(const struct director *, struct sess *sp); int VDI_Healthy(double now, const struct director *, uintptr_t target); Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-12 08:13:15 UTC (rev 5096) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-12 08:38:51 UTC (rev 5097) @@ -127,7 +127,7 @@ static int vbe_TryConnect(const struct sess *sp, int pf, const struct sockaddr *sa, - socklen_t salen, struct vdi_simple *vs) + socklen_t salen, const struct vdi_simple *vs) { int s, i, tmo; double tmod; @@ -166,7 +166,7 @@ /*--------------------------------------------------------------------*/ static int -bes_conn_try(const struct sess *sp, struct vdi_simple *vs) +bes_conn_try(const struct sess *sp, const struct vdi_simple *vs) { int s; struct backend *bp = vs->backend; @@ -261,15 +261,17 @@ */ static unsigned int -vbe_Healthy(double now, uintptr_t target, struct vdi_simple *vs, struct backend *backend) +vbe_Healthy(double now, uintptr_t target, const struct vdi_simple *vs) { struct trouble *tr; struct trouble *tr2; struct trouble *old; unsigned i = 0, retval; unsigned int threshold; + struct backend *backend; CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC); + backend = vs->backend; CHECK_OBJ_NOTNULL(backend, BACKEND_MAGIC); if (!backend->healthy) @@ -369,7 +371,7 @@ VDI_CloseFd(sp); } - if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, vs, bp)) { + if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, vs)) { VSC_main->backend_unhealthy++; return (NULL); } @@ -422,7 +424,7 @@ */ void -VBE_UseHealth(struct director *vdi) +VBE_UseHealth(const struct director *vdi) { struct vdi_simple *vs; @@ -466,7 +468,7 @@ CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); - return (vbe_Healthy(now, target, vs, vs->backend)); + return (vbe_Healthy(now, target, vs)); } /*lint -e{818} not const-able */ From phk at varnish-cache.org Thu Aug 12 08:40:14 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 12 Aug 2010 10:40:14 +0200 Subject: r5098 - in trunk/varnish-cache: bin/varnishd lib/libvcl Message-ID: Author: phk Date: 2010-08-12 10:40:13 +0200 (Thu, 12 Aug 2010) New Revision: 5098 Modified: trunk/varnish-cache/bin/varnishd/cache_dir_dns.c trunk/varnish-cache/bin/varnishd/flint.lnt trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c Log: Some minor cleaups and additional asserts to get rid of the worst FlexeLint spammage. Modified: trunk/varnish-cache/bin/varnishd/cache_dir_dns.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-12 08:38:51 UTC (rev 5097) +++ trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-12 08:40:13 UTC (rev 5098) @@ -79,14 +79,13 @@ pthread_rwlock_t rwlock; const char *suffix; double ttl; - const unsigned max_cache_size; }; /* Compare an IPv4 backend to a IPv4 addr/len */ static int -vdi_dns_comp_addrinfo4(struct backend *bp, +vdi_dns_comp_addrinfo4(const struct backend *bp, const struct sockaddr_in *addr, const socklen_t len) { @@ -104,7 +103,7 @@ /* Compare an IPv6 backend to a IPv6 addr/len */ static int -vdi_dns_comp_addrinfo6(struct backend *bp, +vdi_dns_comp_addrinfo6(const struct backend *bp, struct sockaddr_in6 *addr, const socklen_t len) { @@ -128,12 +127,14 @@ /* Check if a backends socket is the same as addr */ static int -vdi_dns_comp_addrinfo(struct director *dir, +vdi_dns_comp_addrinfo(const struct director *dir, struct sockaddr *addr, const socklen_t len) { struct backend *bp; + bp = vdi_get_backend_if_simple(dir); + AN(bp); if (addr->sa_family == PF_INET && bp->ipv4) { return (vdi_dns_comp_addrinfo4(bp, (struct sockaddr_in *) addr, len)); @@ -279,8 +280,9 @@ hint.ai_socktype = SOCK_STREAM; ALLOC_OBJ(new, VDI_DNSDIR_MAGIC); + XXXAN(new); new->hostname = calloc(sizeof(char), strlen(hostname)+1); - assert(new->hostname != NULL); + XXXAN(new->hostname); strcpy(new->hostname, hostname); error = getaddrinfo(hostname, "80", &hint, &res0); @@ -292,15 +294,15 @@ } for (res = res0; res; res = res->ai_next) { - if (res->ai_family != PF_INET && - res->ai_family != PF_INET6) + if (res->ai_family != PF_INET && res->ai_family != PF_INET6) continue; for (i = 0; i < vs->nhosts; i++) { if (vdi_dns_comp_addrinfo(vs->hosts[i], - res->ai_addr, res->ai_addrlen)) { + res->ai_addr, res->ai_addrlen)) { new->hosts[host] = vs->hosts[i]; - CHECK_OBJ_NOTNULL(new->hosts[host], DIRECTOR_MAGIC); + CHECK_OBJ_NOTNULL(new->hosts[host], + DIRECTOR_MAGIC); host++; } } @@ -327,11 +329,11 @@ int ret; AZ(pthread_rwlock_rdlock(&vs->rwlock)); ret = vdi_dns_cache_has(sp, vs, hostname, &backend, 0); - pthread_rwlock_unlock(&vs->rwlock); + AZ(pthread_rwlock_unlock(&vs->rwlock)); if (!ret) { AZ(pthread_rwlock_wrlock(&vs->rwlock)); ret = vdi_dns_cache_add(sp, vs, hostname, &backend); - pthread_rwlock_unlock(&vs->rwlock); + AZ(pthread_rwlock_unlock(&vs->rwlock)); } else VSC_main->dir_dns_hit++; @@ -434,17 +436,15 @@ vdi_dns_fini(struct director *d) { struct vdi_dns *vs; - struct director **vh; CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_DNS_MAGIC); - vh = vs->hosts; free(vs->hosts); free(vs->dir.vcl_name); vs->dir.magic = 0; /* FIXME: Free the cache */ - pthread_rwlock_destroy(&vs->rwlock); + AZ(pthread_rwlock_destroy(&vs->rwlock)); FREE_OBJ(vs); } @@ -482,6 +482,6 @@ vs->nhosts = t->nmember; vs->ttl = t->ttl; VTAILQ_INIT(&vs->cachelist); - pthread_rwlock_init(&vs->rwlock, NULL); + AZ(pthread_rwlock_init(&vs->rwlock, NULL)); bp[idx] = &vs->dir; } Modified: trunk/varnish-cache/bin/varnishd/flint.lnt =================================================================== --- trunk/varnish-cache/bin/varnishd/flint.lnt 2010-08-12 08:38:51 UTC (rev 5097) +++ trunk/varnish-cache/bin/varnishd/flint.lnt 2010-08-12 08:40:13 UTC (rev 5098) @@ -100,6 +100,8 @@ -sem(WS_Init, custodial(2)) -sem(http_Setup, custodial(2)) +-sem(vdi_dns_cache_list_add, custodial(3)) + -e455 // thread lock -e458 // unprotected read -e763 // Redundant declaration for symbol '...' previously declared Modified: trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c 2010-08-12 08:38:51 UTC (rev 5097) +++ trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c 2010-08-12 08:40:13 UTC (rev 5098) @@ -35,7 +35,6 @@ #include #include -#include #include #include #include @@ -51,7 +50,7 @@ * Parse directors */ -struct vcc_dir_backend_defaults { +static struct vcc_dir_backend_defaults { char *port; char *hostheader; double connect_timeout; @@ -72,20 +71,21 @@ b_defaults.saint = UINT_MAX; } -static struct token *dns_first; +static const struct token *dns_first; static void print_backend(struct vcc *tl, int serial, - uint8_t *ip) + const uint8_t *ip) { char vgcname[BUFSIZ]; char strip[16]; struct token tmptok; struct vsb *vsb; - sprintf(strip, "%d.%d.%d.%d",ip[3],ip[2],ip[1],ip[0]); + + sprintf(strip, "%u.%u.%u.%u", ip[3], ip[2], ip[1], ip[0]); tmptok.dec = strip; - sprintf(vgcname,"%.*s_%d",PF(tl->t_dir),serial); + sprintf(vgcname,"%.*s_%d",PF(tl->t_dir), serial); vsb = vsb_newauto(); AN(vsb); tl->fb = vsb; @@ -127,6 +127,7 @@ Ff(tl, 0, "\tVRT_fini_dir(cli, VGCDIR(%s));\n", vgcname); tl->ndirector++; } + /* * Output backends for all IPs in the range supplied by * "a[0].a[1].a[2].a[3]/inmask". @@ -138,7 +139,7 @@ static void vcc_dir_dns_makebackend(struct vcc *tl, int *serial, - unsigned char a[], + const unsigned char a[], int inmask) { uint32_t ip4=0; @@ -258,7 +259,8 @@ vcc_dir_dns_parse_backend_options(tl); while (tl->t->tok == CSTR) { mask = 32; - ret = sscanf(tl->t->dec, "%hhu.%hhu.%hhu.%hhu",&a[0],&a[1],&a[2],&a[3]); + ret = sscanf(tl->t->dec, "%hhu.%hhu.%hhu.%hhu", + &a[0], &a[1], &a[2], &a[3]); assert(ret == 4); vcc_NextToken(tl); if (tl->t->tok == '/') { @@ -277,7 +279,7 @@ { struct token *t_field, *t_be, *t_suffix = NULL; double ttl = 60.0; - int nbh, nelem = 0; + int nelem = 0; struct fld_spec *fs; const char *first; char *p; @@ -294,7 +296,6 @@ first = ""; t_be = tl->t; vcc_ResetFldSpec(fs); - nbh = -1; ExpectErr(tl, '{'); vcc_NextToken(tl); From phk at varnish-cache.org Thu Aug 12 08:58:21 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 12 Aug 2010 10:58:21 +0200 Subject: r5099 - trunk/varnish-cache/lib/libvcl Message-ID: Author: phk Date: 2010-08-12 10:58:21 +0200 (Thu, 12 Aug 2010) New Revision: 5099 Modified: trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c Log: Use bprintf() into static buffers to get overflow assert. Whitespace nits Modified: trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c 2010-08-12 08:40:13 UTC (rev 5098) +++ trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c 2010-08-12 08:58:21 UTC (rev 5099) @@ -60,7 +60,8 @@ unsigned saint; } b_defaults; -static void vcc_dir_initialize_defaults(void) +static void +vcc_dir_initialize_defaults(void) { b_defaults.port = NULL; b_defaults.hostheader = NULL; @@ -83,16 +84,17 @@ struct token tmptok; struct vsb *vsb; - sprintf(strip, "%u.%u.%u.%u", ip[3], ip[2], ip[1], ip[0]); + bprintf(strip, "%u.%u.%u.%u", ip[3], ip[2], ip[1], ip[0]); tmptok.dec = strip; - sprintf(vgcname,"%.*s_%d",PF(tl->t_dir), serial); + bprintf(vgcname, "%.*s_%d", PF(tl->t_dir), serial); vsb = vsb_newauto(); AN(vsb); tl->fb = vsb; Fc(tl, 0, "\t{ .host = VGC_backend_%s },\n",vgcname); Fh(tl, 1, "\n#define VGC_backend_%s %d\n", vgcname, serial); - Fb(tl, 0, "\nstatic const struct vrt_backend vgc_dir_priv_%s = {\n", vgcname); + Fb(tl, 0, "\nstatic const struct vrt_backend vgc_dir_priv_%s = {\n", + vgcname); Fb(tl, 0, "\t.vcl_name = \"%.*s", PF(tl->t_dir)); if (serial >= 0) @@ -308,7 +310,8 @@ vcc_ParseBackendHost(tl, nelem, &p); ERRCHK(tl); AN(p); - Fc(tl, 0, "%s .host = VGC_backend_%s", first, p); + Fc(tl, 0, "%s .host = VGC_backend_%s", + first, p); } else { ErrInternal(tl); } @@ -316,8 +319,8 @@ } vcc_FieldsOk(tl, fs); if (tl->err) { - vsb_printf(tl->sb, - "\nIn member host specification starting at:\n"); + vsb_printf(tl->sb, "\nIn member host" + " specification starting at:\n"); vcc_ErrWhere(tl, t_be); return; } @@ -340,8 +343,7 @@ vcc_NextToken(tl); } Fc(tl, 0, "};\n"); - Fc(tl, 0, - "\nstatic const struct vrt_dir_dns vgc_dir_priv_%.*s = {\n", + Fc(tl, 0, "\nstatic const struct vrt_dir_dns vgc_dir_priv_%.*s = {\n", PF(tl->t_dir)); Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(tl->t_dir)); Fc(tl, 0, "\t.nmember = %d,\n", nelem); From phk at varnish-cache.org Thu Aug 12 09:48:46 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 12 Aug 2010 11:48:46 +0200 Subject: r5100 - in trunk/varnish-cache/bin: varnishstat varnishtop Message-ID: Author: phk Date: 2010-08-12 11:48:45 +0200 (Thu, 12 Aug 2010) New Revision: 5100 Modified: trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c trunk/varnish-cache/bin/varnishtop/varnishtop.c Log: Don't assert good returns from ncurses for now. Fixes: #741 Modified: trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c =================================================================== --- trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c 2010-08-12 08:58:21 UTC (rev 5099) +++ trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c 2010-08-12 09:48:45 UTC (rev 5100) @@ -52,7 +52,11 @@ #include "varnishapi.h" #include "varnishstat.h" +#if 0 #define AC(x) assert((x) != ERR) +#else +#define AC(x) x +#endif struct pt { VTAILQ_ENTRY(pt) next; @@ -202,13 +206,13 @@ line = 3; VTAILQ_FOREACH(pt, &pthead, next) { - if (line >= LINES) - break; ju = *pt->ptr; if (ju == 0 && !pt->seen) continue; pt->seen = 1; line++; + if (line >= LINES) + break; if (pt->type == 'a') { AC(mvprintw(line, 0, "%12ju %12.2f %12.2f %s\n", Modified: trunk/varnish-cache/bin/varnishtop/varnishtop.c =================================================================== --- trunk/varnish-cache/bin/varnishtop/varnishtop.c 2010-08-12 08:58:21 UTC (rev 5099) +++ trunk/varnish-cache/bin/varnishtop/varnishtop.c 2010-08-12 09:48:45 UTC (rev 5100) @@ -54,7 +54,11 @@ #include "vsl.h" #include "varnishapi.h" +#if 0 #define AC(x) assert((x) != ERR) +#else +#define AC(x) x +#endif struct top { uint8_t tag; From phk at varnish-cache.org Fri Aug 13 09:40:18 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Fri, 13 Aug 2010 11:40:18 +0200 Subject: r5101 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-13 11:40:18 +0200 (Fri, 13 Aug 2010) New Revision: 5101 Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_backend.c trunk/varnish-cache/bin/varnishd/cache_fetch.c Log: Rework the FetchHdr() and surroundings a litle bit, to get us a return value that indicates if a failure should be retried. Condition for retry is that the connection is recycled and fails before we receive any data from the other end. (The actual retry is not implemented yet) Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2010-08-12 09:48:45 UTC (rev 5100) +++ trunk/varnish-cache/bin/varnishd/cache.h 2010-08-13 09:40:18 UTC (rev 5101) @@ -456,6 +456,8 @@ struct vdi_simple *vdis; int fd; + uint8_t recycled; + /* Timeouts */ double first_byte_timeout; double between_bytes_timeout; Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-12 09:48:45 UTC (rev 5100) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-13 09:40:18 UTC (rev 5101) @@ -94,6 +94,7 @@ assert(vc->backend == NULL); assert(vc->fd < 0); + vc->recycled = 0; if (params->cache_vbcs) { Lck_Lock(&VBE_mtx); VTAILQ_INSERT_HEAD(&vbcs, vc, list); @@ -364,11 +365,15 @@ WSP(sp, SLT_Backend, "%d %s %s", vc->fd, sp->director->vcl_name, bp->vcl_name); vc->vdis = vs; + vc->recycled = 1; return (vc); } VSC_main->backend_toolate++; - sp->vbc = vc; - VDI_CloseFd(sp); + WSL(sp->wrk, SLT_BackendClose, vc->fd, "%s", bp->vcl_name); + TCP_close(&vc->fd); + VBE_DropRefConn(bp); + vc->backend = NULL; + VBE_ReleaseConn(vc); } if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, vs)) { Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-12 09:48:45 UTC (rev 5100) +++ trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-13 09:40:18 UTC (rev 5101) @@ -324,7 +324,15 @@ return (0); } -/*--------------------------------------------------------------------*/ +/*-------------------------------------------------------------------- + * Send request, and receive the HTTP protocol response, but not the + * response body. + * + * Return value: + * -1 failure, not retryable + * 0 success + * 1 failure which can be retried. + */ int FetchHdr(struct sess *sp) @@ -333,35 +341,38 @@ struct worker *w; char *b; struct http *hp; + int retry = -1; int i; - double tmo; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); + w = sp->wrk; + AN(sp->director); AZ(sp->obj); + if (sp->objcore != NULL) { /* pass has no objcore */ CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC); AN(sp->objhead); /* details in hash_slinger.h */ AN(sp->objcore->flags & OC_F_BUSY); } - /* Transmit request */ - - w = sp->wrk; hp = sp->wrk->bereq; sp->vbc = VDI_GetFd(NULL, sp); if (sp->vbc == NULL) { WSP(sp, SLT_FetchError, "no backend connection"); - return (__LINE__); + return (-1); } vc = sp->vbc; + if (vc->recycled) + retry = 1; + /* * Now that we know our backend, we can set a default Host: - * header if one is necessary. - * XXX: This possibly ought to go into the default VCL + * header if one is necessary. This cannot be done in the VCL + * because the backend may be chosen by a director. */ if (!http_GetHdr(hp, H_Host, &b)) VDI_AddHostHeader(sp); @@ -373,10 +384,11 @@ /* Deal with any message-body the request might have */ i = FetchReqBody(sp); if (WRW_FlushRelease(w) || i > 0) { - WSP(sp, SLT_FetchError, "backend write error: %d", errno); + WSP(sp, SLT_FetchError, "backend write error: %d (%s)", + errno, strerror(errno)); VDI_CloseFd(sp); /* XXX: other cleanup ? */ - return (__LINE__); + return (retry); } /* Checkpoint the vsl.here */ @@ -390,31 +402,39 @@ HTC_Init(sp->wrk->htc, sp->wrk->ws, vc->fd); TCP_set_read_timeout(vc->fd, vc->first_byte_timeout); - tmo = vc->first_byte_timeout; - do { + i = HTC_Rx(sp->wrk->htc); + + if (i < 0) { + WSP(sp, SLT_FetchError, "http first read error: %d %d (%s)", + i, errno, strerror(errno)); + VDI_CloseFd(sp); + /* XXX: other cleanup ? */ + /* Retryable if we never received anything */ + return (i == -1 ? retry : -1); + } + + TCP_set_read_timeout(vc->fd, vc->between_bytes_timeout); + + while (i == 0) { i = HTC_Rx(sp->wrk->htc); if (i < 0) { WSP(sp, SLT_FetchError, - "http read error: %d (%s)", errno, strerror(errno)); + "http first read error: %d %d (%s)", + i, errno, strerror(errno)); VDI_CloseFd(sp); /* XXX: other cleanup ? */ - return (__LINE__); + return (-1); } + } - if (vc->between_bytes_timeout != tmo) { - TCP_set_read_timeout(vc->fd, vc->between_bytes_timeout); - tmo = vc->between_bytes_timeout; - } - } while (i == 0); - hp = sp->wrk->beresp; if (http_DissectResponse(sp->wrk, sp->wrk->htc, hp)) { WSP(sp, SLT_FetchError, "http format error"); VDI_CloseFd(sp); /* XXX: other cleanup ? */ - return (__LINE__); + return (-1); } return (0); } From phk at varnish-cache.org Fri Aug 13 10:14:06 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Fri, 13 Aug 2010 12:14:06 +0200 Subject: r5102 - in trunk/varnish-cache: bin/varnishd include Message-ID: Author: phk Date: 2010-08-13 12:14:05 +0200 (Fri, 13 Aug 2010) New Revision: 5102 Modified: trunk/varnish-cache/bin/varnishd/cache_center.c trunk/varnish-cache/include/vsc_fields.h Log: Retry backend fetches one time if we got a recycled conncetion and the transfer failed before we received anything. Fixes: #749 Modified: trunk/varnish-cache/bin/varnishd/cache_center.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-13 09:40:18 UTC (rev 5101) +++ trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-13 10:14:05 UTC (rev 5102) @@ -439,6 +439,15 @@ http_Setup(sp->wrk->beresp, sp->wrk->ws); i = FetchHdr(sp); + /* + * If we recycle a backend connection, there is a finite chance + * that the backend closed it before we get a request to it. + * Do a single retry in that case. + */ + if (i == 1) { + VSC_main->backend_retry++; + i = FetchHdr(sp); + } /* * Save a copy before it might get mangled in VCL. When it comes to Modified: trunk/varnish-cache/include/vsc_fields.h =================================================================== --- trunk/varnish-cache/include/vsc_fields.h 2010-08-13 09:40:18 UTC (rev 5101) +++ trunk/varnish-cache/include/vsc_fields.h 2010-08-13 10:14:05 UTC (rev 5102) @@ -55,6 +55,7 @@ VSC_F_MAIN(backend_toolate, uint64_t, 0, 'a', "Backend conn. was closed") VSC_F_MAIN(backend_recycle, uint64_t, 0, 'a', "Backend conn. recycles") VSC_F_MAIN(backend_unused, uint64_t, 0, 'a', "Backend conn. unused") +VSC_F_MAIN(backend_retry, uint64_t, 0, 'a', "Backend conn. retry") VSC_F_MAIN(fetch_head, uint64_t, 1, 'a', "Fetch head") VSC_F_MAIN(fetch_length, uint64_t, 1, 'a', "Fetch with Length") From phk at varnish-cache.org Fri Aug 13 10:19:40 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Fri, 13 Aug 2010 12:19:40 +0200 Subject: r5103 - trunk/varnish-cache/lib/libvcl Message-ID: Author: phk Date: 2010-08-13 12:19:40 +0200 (Fri, 13 Aug 2010) New Revision: 5103 Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c Log: Add a missing assert. Spotted by: pprocacci (Thanks!) Fixes: #752 Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.c 2010-08-13 10:14:05 UTC (rev 5102) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.c 2010-08-13 10:19:40 UTC (rev 5103) @@ -365,6 +365,7 @@ sp = calloc(sizeof *sp, 1); assert(sp != NULL); sp->name = strdup(name); + AN(sp->name); sp->b = b; sp->e = e; return (sp); From phk at varnish-cache.org Fri Aug 13 10:39:40 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Fri, 13 Aug 2010 12:39:40 +0200 Subject: r5104 - in trunk/varnish-cache/bin/varnishtest: . tests Message-ID: Author: phk Date: 2010-08-13 12:39:40 +0200 (Fri, 13 Aug 2010) New Revision: 5104 Added: trunk/varnish-cache/bin/varnishtest/tests/c00036.vtc Modified: trunk/varnish-cache/bin/varnishtest/t001.vtc Log: Add a testcase for backend retries. Modified: trunk/varnish-cache/bin/varnishtest/t001.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/t001.vtc 2010-08-13 10:19:40 UTC (rev 5103) +++ trunk/varnish-cache/bin/varnishtest/t001.vtc 2010-08-13 10:39:40 UTC (rev 5104) @@ -4,33 +4,28 @@ server s1 -repeat 1 { rxreq - txresp \ - -hdr "Connection: close" \ - -hdr "Test1: foobar" \ - -hdr "Test2: foobar" \ - -body "012345\n" -} + txresp -bodylen 5 + rxreq + accept + rxreq + txresp -bodylen 6 +} -start -varnish v1 -launch - varnish v1 -vcl+backend { sub vcl_recv { - pipe; + return(pass); } -} +} -start -varnish v1 -start - -server s1 -start - client c1 { - txreq -url "/" + txreq rxresp expect resp.status == 200 -} + expect resp.bodylen == 5 + txreq + rxresp + expect resp.status == 200 + expect resp.bodylen == 6 +} -run -client c1 -run - -# server s1 -wait - -# varnish v1 -wait +varnish v1 -expect backend_retry == 1 Added: trunk/varnish-cache/bin/varnishtest/tests/c00036.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/c00036.vtc (rev 0) +++ trunk/varnish-cache/bin/varnishtest/tests/c00036.vtc 2010-08-13 10:39:40 UTC (rev 5104) @@ -0,0 +1,35 @@ +# $Id$ + +test "Backend close retry" + +server s1 -repeat 1 { + rxreq + txresp -bodylen 5 + + rxreq + accept + + rxreq + txresp -bodylen 6 + +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + return(pass); + } +} -start + +client c1 { + txreq + rxresp + expect resp.status == 200 + expect resp.bodylen == 5 + + txreq + rxresp + expect resp.status == 200 + expect resp.bodylen == 6 +} -run + +varnish v1 -expect backend_retry == 1 From phk at varnish-cache.org Fri Aug 13 10:40:13 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Fri, 13 Aug 2010 12:40:13 +0200 Subject: r5105 - trunk/varnish-cache/bin/varnishtest Message-ID: Author: phk Date: 2010-08-13 12:40:12 +0200 (Fri, 13 Aug 2010) New Revision: 5105 Removed: trunk/varnish-cache/bin/varnishtest/t001.vtc Log: Remove this old test file Deleted: trunk/varnish-cache/bin/varnishtest/t001.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/t001.vtc 2010-08-13 10:39:40 UTC (rev 5104) +++ trunk/varnish-cache/bin/varnishtest/t001.vtc 2010-08-13 10:40:12 UTC (rev 5105) @@ -1,31 +0,0 @@ -# Test that we get anything through at all -# -# $Id$ - -server s1 -repeat 1 { - rxreq - txresp -bodylen 5 - rxreq - accept - rxreq - txresp -bodylen 6 -} -start - -varnish v1 -vcl+backend { - sub vcl_recv { - return(pass); - } -} -start - -client c1 { - txreq - rxresp - expect resp.status == 200 - expect resp.bodylen == 5 - txreq - rxresp - expect resp.status == 200 - expect resp.bodylen == 6 -} -run - -varnish v1 -expect backend_retry == 1 From tfheen at varnish-cache.org Fri Aug 13 11:15:20 2010 From: tfheen at varnish-cache.org (tfheen at varnish-cache.org) Date: Fri, 13 Aug 2010 13:15:20 +0200 Subject: r5106 - trunk/varnish-cache/bin/varnishd Message-ID: Author: tfheen Date: 2010-08-13 13:15:20 +0200 (Fri, 13 Aug 2010) New Revision: 5106 Modified: trunk/varnish-cache/bin/varnishd/cache_center.c Log: Correct embedded dot about obj.* in vcl_fetch The embedded dot claimed obj.* was available in vcl_fetch, something it's not. Fix this. Thanks to Yves Hwang for spotting this. Modified: trunk/varnish-cache/bin/varnishd/cache_center.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-13 10:40:12 UTC (rev 5105) +++ trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-13 11:15:20 UTC (rev 5106) @@ -399,7 +399,7 @@ DOT ] DOT vcl_fetch [ DOT shape=record -DOT label="vcl_fetch()|req.\nobj.\nbereq.\nberesp." +DOT label="vcl_fetch()|req.\nbereq.\nberesp." DOT ] DOT fetch -> vcl_fetch [style=bold,color=blue,weight=2] DOT fetch_pass [ From kristian at varnish-cache.org Fri Aug 13 11:52:04 2010 From: kristian at varnish-cache.org (kristian at varnish-cache.org) Date: Fri, 13 Aug 2010 13:52:04 +0200 Subject: r5107 - trunk/varnish-cache/bin/varnishtest Message-ID: Author: kristian Date: 2010-08-13 13:52:04 +0200 (Fri, 13 Aug 2010) New Revision: 5107 Added: trunk/varnish-cache/bin/varnishtest/Makefile.kristian Log: Add a varnishtests/Makefile.kristian for parallel tests Usage: cd bin/varnishtest/; make -f Makefile.kristian -j20 Added: trunk/varnish-cache/bin/varnishtest/Makefile.kristian =================================================================== --- trunk/varnish-cache/bin/varnishtest/Makefile.kristian (rev 0) +++ trunk/varnish-cache/bin/varnishtest/Makefile.kristian 2010-08-13 11:52:04 UTC (rev 5107) @@ -0,0 +1,35 @@ +# Usage: make -f Makefile.kristian -j20 (for 20 parallel jobs) + +SHELL = /bin/sh + +# Complete all tests even if one fails +MAKEFLAGS = -k + +objs=$(addsuffix .done,$(basename $(notdir $(wildcard tests/*vtc)))) + +check: $(objs) + @echo "===================" + @echo "All tests succeeded" + @echo "===================" + +# Capture output of varnishtest for a specific test. Only output it if the +# test failed. +# +# XXX: 'echo' in dash (often used as /bin/sh) does not support -E and +# always interpret \n's(as in a \ and a n, not a real line break), +# thus the /bin/echo -E crud to avoid double line breaks on +# "body | \n". +# +# XXX: Even if this doesn't create a real file, it's not a phony target per +# se, as it has to fire every time you run 'make check'. +%.done: tests/%.vtc + @if output=$$(./varnishtest $< 2>&1 ); then\ + echo "$< OK";\ + else\ + ret=$$?;\ + /bin/echo -E 1>&2 "$$output";\ + echo 1>&2 $< "FAILED ($$ret)\n";\ + exit $$ret;\ + fi; + +.PHONY: check From perbu at varnish-cache.org Fri Aug 13 12:07:24 2010 From: perbu at varnish-cache.org (perbu at varnish-cache.org) Date: Fri, 13 Aug 2010 14:07:24 +0200 Subject: r5108 - trunk/varnish-cache/doc/sphinx/reference Message-ID: Author: perbu Date: 2010-08-13 14:07:24 +0200 (Fri, 13 Aug 2010) New Revision: 5108 Modified: trunk/varnish-cache/doc/sphinx/reference/varnishd.rst Log: described critbit in the man page Modified: trunk/varnish-cache/doc/sphinx/reference/varnishd.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/reference/varnishd.rst 2010-08-13 11:52:04 UTC (rev 5107) +++ trunk/varnish-cache/doc/sphinx/reference/varnishd.rst 2010-08-13 12:07:24 UTC (rev 5108) @@ -131,8 +131,10 @@ key. The buckets parameter specifies the number of entries in the hash table. The default is 16383. -critbit XXX - Very nice. +critbit + A self-scaling tree structure. The default hash algorithm in 2.1. In + comparison to a more traditional B tree the critbit tree is almost + completely lockless. Storage Types ------------- From kristian at varnish-cache.org Fri Aug 13 18:53:43 2010 From: kristian at varnish-cache.org (kristian at varnish-cache.org) Date: Fri, 13 Aug 2010 20:53:43 +0200 Subject: r5109 - in trunk/varnish-tools: . cookie-stripper Message-ID: Author: kristian Date: 2010-08-13 20:53:42 +0200 (Fri, 13 Aug 2010) New Revision: 5109 Added: trunk/varnish-tools/cookie-stripper/ trunk/varnish-tools/cookie-stripper/varnish_cookie_strip.sh Log: tools/cookie-stripper: Script to generate simple VCL that strips specific cookies. Added: trunk/varnish-tools/cookie-stripper/varnish_cookie_strip.sh =================================================================== --- trunk/varnish-tools/cookie-stripper/varnish_cookie_strip.sh (rev 0) +++ trunk/varnish-tools/cookie-stripper/varnish_cookie_strip.sh 2010-08-13 18:53:42 UTC (rev 5109) @@ -0,0 +1,104 @@ +#!/bin/sh +# Author: Kristian Lyngstol +# Date: August 2010 +# More info: http://kristianlyng.wordpress.com +# License: Consider it public domain. +# + +usage() { + echo + echo "Varnish Cookie-strip VCL generator" + echo "Copyright (C) 2010 Kristian Lyngstol " + echo + echo "$0 [-b backend:port] [-i indentation] [-c cookie] [-c cookie] ..." + echo "Generates VCL for Varnish to strip cookies." + echo " -c \tStrip cookie named \`cookie'. Can be" + echo " \tspecified multiple times" + echo " -b \tAlso generate the backend definition to use" + echo " \ta web server at host:port as the backend. Both" + echo " \thost AND port, separated by colon, must be specified" + echo " -t \tUse \`indent' when indenting the code, instead of" + echo " \t4 spaces." + echo " -i \tCreate case-insensitive cookie matching" + echo + echo "Example: $0 -b localhost:8181 -c __utmz -c __utma > /etc/varnish/default.vcl" + echo + echo "The VCL generated is for Varnish 2.1 and beyond and with the" + echo "-b option there is no need to add or modify the final VCL to" + echo "make Varnish \"just work\"" +} +ind() { + echo -n "$indent" +} + +TEMP=`getopt -o hb:c:it: -n $0 -- "$@"` + +if [ $? != 0 ] ; then echo "$(usage)" >&2 ; exit 1 ; fi + +eval set -- "$TEMP" + +icase="" +indent=" " +backend="" +cookiestring="" + + +while true ; do + case "$1" in + -b) backend="$2"; shift 2;; + -i) icase="(?i)"; shift 1;; + -t) indent="$2"; shift 2;; + -c) cookiestrip="$cookiestrip $2"; shift 2;; + -h) usage; exit 0 ;; + --) shift; break ;; + *) echo "Internal error! See $0 -h" ; exit 1 ;; + esac +done + +host=`echo $backend | sed s/:.*//` +port=`echo $backend | sed s/.*://` + +if [ ! -z "$backend" ]; then + if [ -z "$host" ] || [ -z "$port" ]; then + echo "Invalid backend \"$backend\"" 1>&2 + echo "$(usage)" 1>&2 + exit 1; + fi + + + echo "backend default {" + ind + echo ".host = \"$host\";" + ind + echo ".port = \"$port\";" + echo "}" + echo +fi + +if [ -z "$cookiestrip" ] && [ -z "$backend" ]; then + echo "No -c or -b option specified." 1>&2 + echo "$(usage)" 1>&2 + exit 2; +fi + +echo "sub vcl_recv {" +for a in $cookiestrip; do + ind + echo "# Remove cookie $a" + ind + echo -n 'set req.http.cookie = regsub(req.http.cookie,'; + echo -n "\"${icase}$a=[^;]*;?( |$)\"" + echo ',"");' +done + +echo +ind +echo "# Remove the cookie header if it's empty after cleanup" +ind +echo 'if (req.http.cookie ~ "^ *$") {' +ind +ind +echo 'remove req.http.cookie;' +ind +echo '}' +echo '}' Property changes on: trunk/varnish-tools/cookie-stripper/varnish_cookie_strip.sh ___________________________________________________________________ Added: svn:executable + * From phk at varnish-cache.org Mon Aug 16 10:59:18 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 16 Aug 2010 12:59:18 +0200 Subject: r5110 - trunk/varnish-cache/lib/libvarnish Message-ID: Author: phk Date: 2010-08-16 12:59:18 +0200 (Mon, 16 Aug 2010) New Revision: 5110 Modified: trunk/varnish-cache/lib/libvarnish/cli_common.c Log: Polish while looking for clues to #754/#744 Modified: trunk/varnish-cache/lib/libvarnish/cli_common.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/cli_common.c 2010-08-13 18:53:42 UTC (rev 5109) +++ trunk/varnish-cache/lib/libvarnish/cli_common.c 2010-08-16 10:59:18 UTC (rev 5110) @@ -90,6 +90,7 @@ { int i, l; struct iovec iov[3]; + char nl[2] = "\n"; char res[CLI_LINE0_LEN + 2]; /* * NUL + one more so we can catch * any misformats by snprintf @@ -97,16 +98,22 @@ assert(cli->result >= 100); assert(cli->result <= 999); /*lint !e650 const out of range */ + i = snprintf(res, sizeof res, "%-3d %-8d\n", cli->result, vsb_len(cli->sb)); assert(i == CLI_LINE0_LEN); - iov[0].iov_base = (void*)(uintptr_t)res; - iov[1].iov_base = (void*)(uintptr_t)vsb_data(cli->sb); - iov[2].iov_base = (void*)(uintptr_t)"\n"; - for (l = i = 0; i < 3; i++) { - iov[i].iov_len = strlen(iov[i].iov_base); + + iov[0].iov_base = res; + iov[0].iov_len = CLI_LINE0_LEN; + + iov[1].iov_base = vsb_data(cli->sb); + iov[1].iov_len = vsb_len(cli->sb); + + iov[2].iov_base = nl; + iov[2].iov_len = 1; + + for (l = i = 0; i < 3; i++) l += iov[i].iov_len; - } i = writev(fd, iov, 3); return (i != l); } From omegabk at gmail.com Wed Aug 18 13:42:20 2010 From: omegabk at gmail.com (omega bk) Date: Wed, 18 Aug 2010 15:42:20 +0200 Subject: VRT functions Message-ID: hello all, sorry if it's not the right place. i just need to know where to get documented VRT_* functions. for example, how works in detail VRT_SetHdr VRT_GetHdr VRT_l_obj_ttl thanks for your help Fisher -------------- next part -------------- An HTML attachment was scrubbed... URL: From phk at varnish-cache.org Sat Aug 21 12:00:59 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Sat, 21 Aug 2010 14:00:59 +0200 Subject: r5111 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-21 14:00:59 +0200 (Sat, 21 Aug 2010) New Revision: 5111 Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c Log: Emit varnishd ident as part of banner. Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-16 10:59:18 UTC (rev 5110) +++ trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-21 12:00:59 UTC (rev 5111) @@ -99,6 +99,8 @@ cli_out(cli, "-----------------------------\n"); cli_out(cli, "Varnish HTTP accelerator CLI.\n"); cli_out(cli, "-----------------------------\n"); + cli_out(cli, "%s\n", vsb_data(vident) + 1); + cli_out(cli, "\n"); cli_out(cli, "Type 'help' for command list.\n"); cli_out(cli, "Type 'quit' to close CLI session.\n"); if (child_pid < 0) @@ -154,7 +156,6 @@ char *q; unsigned u; - (void)av; (void)priv; /* * Command not recognized in master, try cacher if it is From phk at varnish-cache.org Sat Aug 21 12:02:18 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Sat, 21 Aug 2010 14:02:18 +0200 Subject: r5112 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-21 14:02:17 +0200 (Sat, 21 Aug 2010) New Revision: 5112 Modified: trunk/varnish-cache/bin/varnishd/cache_cli.c Log: Log the length of cli responses to VSL Modified: trunk/varnish-cache/bin/varnishd/cache_cli.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_cli.c 2010-08-21 12:00:59 UTC (rev 5111) +++ trunk/varnish-cache/bin/varnishd/cache_cli.c 2010-08-21 12:02:17 UTC (rev 5112) @@ -95,7 +95,8 @@ cli_cb_after(const struct cli *cli) { Lck_Unlock(&cli_mtx); - VSL(SLT_CLI, 0, "Wr %03u %s", cli->result, vsb_data(cli->sb)); + VSL(SLT_CLI, 0, "Wr %03u %u %s", + cli->result, vsb_len(cli->sb), vsb_data(cli->sb)); } void @@ -183,4 +184,3 @@ CLI_AddFuncs(master_cmds); } - From phk at varnish-cache.org Sat Aug 21 12:03:19 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Sat, 21 Aug 2010 14:03:19 +0200 Subject: r5113 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-21 14:03:19 +0200 (Sat, 21 Aug 2010) New Revision: 5113 Modified: trunk/varnish-cache/bin/varnishd/default.vcl Log: Don't mess with X-forwarded-for on restarts. Fixes: #758 Modified: trunk/varnish-cache/bin/varnishd/default.vcl =================================================================== --- trunk/varnish-cache/bin/varnishd/default.vcl 2010-08-21 12:02:17 UTC (rev 5112) +++ trunk/varnish-cache/bin/varnishd/default.vcl 2010-08-21 12:03:19 UTC (rev 5113) @@ -40,11 +40,13 @@ */ sub vcl_recv { - if (req.http.x-forwarded-for) { - set req.http.X-Forwarded-For = - req.http.X-Forwarded-For ", " client.ip; - } else { - set req.http.X-Forwarded-For = client.ip; + if (req.restarts == 0) { + if (req.http.x-forwarded-for) { + set req.http.X-Forwarded-For = + req.http.X-Forwarded-For ", " client.ip; + } else { + set req.http.X-Forwarded-For = client.ip; + } } if (req.request != "GET" && req.request != "HEAD" && From phk at varnish-cache.org Sat Aug 21 12:21:48 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Sat, 21 Aug 2010 14:21:48 +0200 Subject: r5114 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-21 14:21:48 +0200 (Sat, 21 Aug 2010) New Revision: 5114 Modified: trunk/varnish-cache/bin/varnishd/cache_cli.c Log: Add a couple of documenting asserts. Modified: trunk/varnish-cache/bin/varnishd/cache_cli.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_cli.c 2010-08-21 12:03:19 UTC (rev 5113) +++ trunk/varnish-cache/bin/varnishd/cache_cli.c 2010-08-21 12:21:48 UTC (rev 5114) @@ -85,6 +85,7 @@ cli_cb_before(const struct cli *cli) { + ASSERT_CLI(); VSL(SLT_CLI, 0, "Rd %s", cli->cmd); VCL_Poll(); VBE_Poll(); @@ -94,6 +95,8 @@ static void cli_cb_after(const struct cli *cli) { + + ASSERT_CLI(); Lck_Unlock(&cli_mtx); VSL(SLT_CLI, 0, "Wr %03u %u %s", cli->result, vsb_len(cli->sb), vsb_data(cli->sb)); @@ -167,7 +170,6 @@ { NULL } }; - /*-------------------------------------------------------------------- * Initialize the CLI subsystem */ From phk at varnish-cache.org Sat Aug 21 12:34:16 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Sat, 21 Aug 2010 14:34:16 +0200 Subject: r5115 - trunk/varnish-cache/lib/libvarnish Message-ID: Author: phk Date: 2010-08-21 14:34:15 +0200 (Sat, 21 Aug 2010) New Revision: 5115 Modified: trunk/varnish-cache/lib/libvarnish/cli_serve.c Log: Only provide help on commands authorrized for the current CLI session Modified: trunk/varnish-cache/lib/libvarnish/cli_serve.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/cli_serve.c 2010-08-21 12:21:48 UTC (rev 5114) +++ trunk/varnish-cache/lib/libvarnish/cli_serve.c 2010-08-21 12:34:15 UTC (rev 5115) @@ -129,6 +129,8 @@ debug = 1; } else { VTAILQ_FOREACH(cfn, &cs->funcs, list) { + if (cfn->auth > cli->auth) + continue; for (cp = cfn->clp; cp->request != NULL; cp++) { if (!strcmp(cp->request, av[2])) { cli_out(cli, "%s\n%s\n", @@ -148,6 +150,8 @@ return; } VTAILQ_FOREACH(cfn, &cs->funcs, list) { + if (cfn->auth > cli->auth) + continue; for (cp = cfn->clp; cp->request != NULL; cp++) { d = 0; h = 0; From phk at varnish-cache.org Sat Aug 21 14:57:13 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Sat, 21 Aug 2010 16:57:13 +0200 Subject: r5116 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-21 16:57:13 +0200 (Sat, 21 Aug 2010) New Revision: 5116 Modified: trunk/varnish-cache/bin/varnishd/mgt.h trunk/varnish-cache/bin/varnishd/mgt_child.c trunk/varnish-cache/bin/varnishd/mgt_cli.c Log: Whenever the CLI comms with the child process runs of the rails, we have to kill the child: We cannot get the CLI pipes back in sync, even if the child process was just preoccupied with something for much longer than cli_timeout. Fixes: #744 Modified: trunk/varnish-cache/bin/varnishd/mgt.h =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt.h 2010-08-21 12:34:15 UTC (rev 5115) +++ trunk/varnish-cache/bin/varnishd/mgt.h 2010-08-21 14:57:13 UTC (rev 5116) @@ -49,6 +49,7 @@ void MGT_Run(void); void mgt_stop_child(void); void mgt_got_fd(int fd); +void MGT_Child_Cli_Fail(void); /* mgt_cli.c */ Modified: trunk/varnish-cache/bin/varnishd/mgt_child.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_child.c 2010-08-21 12:34:15 UTC (rev 5115) +++ trunk/varnish-cache/bin/varnishd/mgt_child.c 2010-08-21 14:57:13 UTC (rev 5116) @@ -201,14 +201,33 @@ return (0); if (!mgt_cli_askchild(NULL, NULL, "ping\n")) return (0); - REPORT(LOG_ERR, - "Child (%jd) not responding to ping, killing it.", + return (0); +} + +/*-------------------------------------------------------------------- + * If CLI communications with the child process fails, there is nothing + * for us to do but to drag it behind the barn and get it over with. + * + * The typical case is where the child process fails to return a reply + * before the cli_timeout expires. This invalidates the CLI pipes for + * all future use, as we don't know if the child was just slow and the + * result gets piped later on, or if the child is catatonic. + */ + +void +MGT_Child_Cli_Fail(void) +{ + + if (child_state != CH_RUNNING) + return; + if (child_pid < 0) + return; + REPORT(LOG_ERR, "Child (%jd) not responding to CLI, killing it.", (intmax_t)child_pid); if (params->diag_bitmap & 0x1000) (void)kill(child_pid, SIGKILL); else (void)kill(child_pid, SIGQUIT); - return (0); } /*--------------------------------------------------------------------*/ Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-21 12:34:15 UTC (rev 5115) +++ trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-21 14:57:13 UTC (rev 5116) @@ -178,16 +178,16 @@ if (i != strlen(cli->cmd)) { cli_result(cli, CLIS_COMMS); cli_out(cli, "CLI communication error"); + MGT_Child_Cli_Fail(); return; } i = write(cli_o, "\n", 1); if (i != 1) { cli_result(cli, CLIS_COMMS); cli_out(cli, "CLI communication error"); + MGT_Child_Cli_Fail(); return; } - - assert(i == 1 || errno == EPIPE); (void)cli_readres(cli_i, &u, &q, params->cli_timeout); cli_result(cli, u); cli_out(cli, "%s", q); @@ -233,12 +233,15 @@ *status = CLIS_COMMS; if (resp != NULL) *resp = strdup("CLI communication error"); + MGT_Child_Cli_Fail(); return (CLIS_COMMS); } (void)cli_readres(cli_i, &u, resp, params->cli_timeout); if (status != NULL) *status = u; + if (u == CLIS_COMMS) + MGT_Child_Cli_Fail(); return (u == CLIS_OK ? 0 : u); } From phk at varnish-cache.org Mon Aug 23 09:34:34 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 23 Aug 2010 11:34:34 +0200 Subject: r5117 - in trunk/varnish-cache: bin/varnishd bin/varnishreplay lib/libvarnish lib/libvcl Message-ID: Author: phk Date: 2010-08-23 11:34:33 +0200 (Mon, 23 Aug 2010) New Revision: 5117 Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c trunk/varnish-cache/bin/varnishd/mgt_param.c trunk/varnish-cache/bin/varnishd/mgt_vcc.c trunk/varnish-cache/bin/varnishreplay/varnishreplay.c trunk/varnish-cache/lib/libvarnish/vss.c trunk/varnish-cache/lib/libvcl/vcc_backend.c Log: Have VSS_resolve() call VSS_parse() and only use the provided port argument as a default, if the host argument does not specify a port. Elminate most separate calls to VSS_parse() Make it possible to specify address and port of backends in VCL using only the .host field. Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-21 14:57:13 UTC (rev 5116) +++ trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-23 09:34:33 UTC (rev 5117) @@ -542,7 +542,6 @@ mgt_cli_telnet(const char *T_arg) { struct vss_addr **ta; - char *addr, *port; int i, n, sock, good; struct telnet *tn; char *p; @@ -553,9 +552,7 @@ AN(p); strcpy(p, T_arg); - XXXAZ(VSS_parse(T_arg, &addr, &port)); - - n = VSS_resolve(addr, port, &ta); + n = VSS_resolve(T_arg, NULL, &ta); if (n == 0) { fprintf(stderr, "Could not open management port\n"); exit(2); @@ -578,19 +575,15 @@ } free(ta); if (good == 0) { - REPORT(LOG_ERR, "-T %s:%s could not be listened on.", - addr, port); + REPORT(LOG_ERR, "-T %s could not be listened on.", T_arg); exit(2); } - free(addr); - free(port); } /* Reverse CLI ("Master") connections --------------------------------*/ static int M_fd = -1; static struct vev *M_poker, *M_conn; -static char *M_addr, *M_port; static struct vss_addr **M_ta; static int M_nta, M_nxt; static double M_poll = 0.1; @@ -666,11 +659,7 @@ { (void)M_arg; - if (VSS_parse(M_arg, &M_addr, &M_port) || M_port == NULL) { - fprintf(stderr, "Could not parse -M argument\n"); - exit (1); - } - M_nta = VSS_resolve(M_addr, M_port, &M_ta); + M_nta = VSS_resolve(M_arg, NULL, &M_ta); if (M_nta <= 0) { fprintf(stderr, "Could resolve -M argument to address\n"); exit (1); Modified: trunk/varnish-cache/bin/varnishd/mgt_param.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_param.c 2010-08-21 14:57:13 UTC (rev 5116) +++ trunk/varnish-cache/bin/varnishd/mgt_param.c 2010-08-23 09:34:33 UTC (rev 5117) @@ -378,18 +378,9 @@ VTAILQ_INIT(&lsh); for (i = 1; av[i] != NULL; i++) { struct vss_addr **ta; - char *host, *port; int j, n; - if (VSS_parse(av[i], &host, &port) != 0) { - cli_out(cli, "Invalid listen address "); - cli_quote(cli, av[i]); - cli_result(cli, CLIS_PARAM); - break; - } - n = VSS_resolve(host, port ? port : "http", &ta); - free(host); - free(port); + n = VSS_resolve(av[i], "http", &ta); if (n == 0) { cli_out(cli, "Invalid listen address "); cli_quote(cli, av[i]); Modified: trunk/varnish-cache/bin/varnishd/mgt_vcc.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_vcc.c 2010-08-21 14:57:13 UTC (rev 5116) +++ trunk/varnish-cache/bin/varnishd/mgt_vcc.c 2010-08-23 09:34:33 UTC (rev 5117) @@ -362,7 +362,6 @@ int mgt_vcc_default(const char *b_arg, const char *f_arg, char *vcl, int C_flag) { - char *addr, *port; char *vf; struct vsb *sb; struct vclprog *vp; @@ -381,26 +380,10 @@ * XXX: a bug for a backend to not reply at that time, so then * XXX: again: we should check it here in the "trivial" case. */ - if (VSS_parse(b_arg, &addr, &port) != 0 || addr == NULL) { - /* - * (addr == NULL && port != NULL) is possible if - * the user incorrectly specified an address such - * as ":80", which is a valid listening address. - * In the future, we may want to interpret this as - * a shortcut for "localhost:80". - */ - free(port); - fprintf(stderr, "invalid backend address\n"); - return (1); - } - bprintf(buf, "backend default {\n" " .host = \"%s\";\n" - " .port = \"%s\";\n" - "}\n", addr, port ? port : "http"); - free(addr); - free(port); + "}\n", b_arg); vcl = strdup(buf); AN(vcl); } Modified: trunk/varnish-cache/bin/varnishreplay/varnishreplay.c =================================================================== --- trunk/varnish-cache/bin/varnishreplay/varnishreplay.c 2010-08-21 14:57:13 UTC (rev 5116) +++ trunk/varnish-cache/bin/varnishreplay/varnishreplay.c 2010-08-23 09:34:33 UTC (rev 5117) @@ -678,16 +678,9 @@ { struct vss_addr **ta; struct vss_addr *tap; - char *addr, *port; int i, n; - if (VSS_parse(address, &addr, &port) != 0) { - thread_log(0, 0, "Invalid address"); - exit(2); - } - n = VSS_resolve(addr, port, &ta); - free(addr); - free(port); + n = VSS_resolve(address, NULL, &ta); if (n == 0) { thread_log(0, 0, "Could not connect to server"); exit(2); Modified: trunk/varnish-cache/lib/libvarnish/vss.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/vss.c 2010-08-21 14:57:13 UTC (rev 5116) +++ trunk/varnish-cache/lib/libvarnish/vss.c 2010-08-23 09:34:33 UTC (rev 5117) @@ -79,7 +79,10 @@ * "0.0.0.0" - "0.0.0.0:80" * "[::1]" - "[::1]:80" * "[::]" - "[::]:80" + * + * See also RFC5952 */ + int VSS_parse(const char *str, char **addr, char **port) { @@ -129,6 +132,9 @@ * * The return value is the number of addresses resoved, or zero. * + * If the addr argument contains a port specification, that takes + * precedence over the port argument. + * * XXX: We need a function to free the allocated addresses. */ int @@ -137,15 +143,27 @@ struct addrinfo hints, *res0, *res; struct vss_addr **va; int i, ret; + char *adp, *hop; memset(&hints, 0, sizeof hints); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; - ret = getaddrinfo(addr, port, &hints, &res0); - if (ret != 0) { - fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(ret)); + + ret = VSS_parse(addr, &hop, &adp); + if (ret) return (0); - } + + if (adp == NULL) + ret = getaddrinfo(addr, port, &hints, &res0); + else + ret = getaddrinfo(hop, adp, &hints, &res0); + + free(hop); + free(adp); + + if (ret != 0) + return (0); + XXXAN(res0); for (res = res0, i = 0; res != NULL; res = res->ai_next, ++i) /* nothing */ ; Modified: trunk/varnish-cache/lib/libvcl/vcc_backend.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-08-21 14:57:13 UTC (rev 5116) +++ trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-08-23 09:34:33 UTC (rev 5117) @@ -60,9 +60,11 @@ #include #include #include +#include #include #include "vsb.h" +#include "vss.h" #include "vcc_priv.h" #include "vcc_compile.h" @@ -74,22 +76,6 @@ char *vgcname; }; -static const char * -CheckHostPort(const char *host, const char *port) -{ - struct addrinfo *res, hint; - int error; - - memset(&hint, 0, sizeof hint); - hint.ai_family = PF_UNSPEC; - hint.ai_socktype = SOCK_STREAM; - error = getaddrinfo(host, port, &hint, &res); - if (error) - return (gai_strerror(error)); - freeaddrinfo(res); - return (NULL); -} - static int emit_sockaddr(struct vcc *tl, void *sa, unsigned sal) { @@ -122,21 +108,47 @@ * and put it in an official sockaddr when we load the VCL. */ +#include + void -Emit_Sockaddr(struct vcc *tl, const struct token *t_host, - const char *port) +Emit_Sockaddr(struct vcc *tl, const struct token *t_host, const char *port) { struct addrinfo *res, *res0, *res1, hint; int n4, n6, error, retval, x; const char *emit, *multiple; char hbuf[NI_MAXHOST]; + char *hop, *pop; AN(t_host->dec); retval = 0; memset(&hint, 0, sizeof hint); hint.ai_family = PF_UNSPEC; hint.ai_socktype = SOCK_STREAM; - error = getaddrinfo(t_host->dec, port, &hint, &res0); + + if (VSS_parse(t_host->dec, &hop, &pop)) { + vsb_printf(tl->sb, + "Backend host '%.*s': wrong syntax (unbalanced [...] ?)\n", + PF(t_host) ); + vcc_ErrWhere(tl, t_host); + return; + } + if (pop != NULL) + error = getaddrinfo(hop, pop, &hint, &res0); + else + error = getaddrinfo(t_host->dec, port, &hint, &res0); + free(hop); + free(pop); + if (error) { + vsb_printf(tl->sb, + "Backend host '%.*s'" + " could not be resolved to an IP address:\n", PF(t_host)); + vsb_printf(tl->sb, + "\t%s\n" + "(Sorry if that error message is gibberish.)\n", + gai_strerror(error)); + vcc_ErrWhere(tl, t_host); + return; + } AZ(error); n4 = n6 = 0; multiple = NULL; @@ -432,7 +444,6 @@ struct token *t_port = NULL; struct token *t_hosthdr = NULL; unsigned saint = UINT_MAX; - const char *ep; struct fld_spec *fs; struct vsb *vsb; unsigned u; @@ -567,26 +578,10 @@ /* Check that the hostname makes sense */ assert(t_host != NULL); - ep = CheckHostPort(t_host->dec, "80"); - if (ep != NULL) { - vsb_printf(tl->sb, "Backend host '%.*s': %s\n", PF(t_host), ep); - vcc_ErrWhere(tl, t_host); - return; - } - - /* Check that the portname makes sense */ - if (t_port != NULL) { - ep = CheckHostPort("127.0.0.1", t_port->dec); - if (ep != NULL) { - vsb_printf(tl->sb, - "Backend port '%.*s': %s\n", PF(t_port), ep); - vcc_ErrWhere(tl, t_port); - return; - } + if (t_port != NULL) Emit_Sockaddr(tl, t_host, t_port->dec); - } else { + else Emit_Sockaddr(tl, t_host, "80"); - } ERRCHK(tl); ExpectErr(tl, '}'); From ingvar at varnish-cache.org Tue Aug 24 15:49:52 2010 From: ingvar at varnish-cache.org (ingvar at varnish-cache.org) Date: Tue, 24 Aug 2010 17:49:52 +0200 Subject: r5118 - trunk/varnish-cache Message-ID: Author: ingvar Date: 2010-08-24 17:49:52 +0200 (Tue, 24 Aug 2010) New Revision: 5118 Modified: trunk/varnish-cache/configure.ac Log: Just a typofix Modified: trunk/varnish-cache/configure.ac =================================================================== --- trunk/varnish-cache/configure.ac 2010-08-23 09:34:33 UTC (rev 5117) +++ trunk/varnish-cache/configure.ac 2010-08-24 15:49:52 UTC (rev 5118) @@ -423,7 +423,7 @@ JEMALLOC_LDADD= AC_ARG_ENABLE(jemalloc, AS_HELP_STRING([--disable-jemalloc],[do not use jemalloc (default is yes on Linux, no everywhere else)]), -[if "x$enableval" = "xyes"; then +[if test "x$enableval" = "xyes"; then JEMALLOC_SUBDIR=libjemalloc JEMALLOC_LDADD='$(top_builddir)/lib/libjemalloc/libjemalloc_mt.la' fi], From phk at varnish-cache.org Tue Aug 24 15:56:49 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Tue, 24 Aug 2010 17:56:49 +0200 Subject: r5119 - in trunk/varnish-cache: bin/varnishd bin/varnishtest bin/varnishtest/tests doc/sphinx/phk lib/libvarnish Message-ID: Author: phk Date: 2010-08-24 17:56:49 +0200 (Tue, 24 Aug 2010) New Revision: 5119 Added: trunk/varnish-cache/doc/sphinx/phk/ipv6suckage.rst Modified: trunk/varnish-cache/bin/varnishd/cache_panic.c trunk/varnish-cache/bin/varnishd/cache_vrt.c trunk/varnish-cache/bin/varnishd/mgt_cli.c trunk/varnish-cache/bin/varnishtest/tests/v00010.vtc trunk/varnish-cache/bin/varnishtest/vtc_server.c trunk/varnish-cache/bin/varnishtest/vtc_varnish.c trunk/varnish-cache/doc/sphinx/phk/index.rst trunk/varnish-cache/lib/libvarnish/vss.c Log: Always report sockaddr's as IP# PORT# Explain why. Modified: trunk/varnish-cache/bin/varnishd/cache_panic.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_panic.c 2010-08-24 15:49:52 UTC (rev 5118) +++ trunk/varnish-cache/bin/varnishd/cache_panic.c 2010-08-24 15:56:49 UTC (rev 5119) @@ -215,7 +215,7 @@ vsb_printf(vsp, "sp = %p {\n", sp); vsb_printf(vsp, " fd = %d, id = %d, xid = %u,\n", sp->fd, sp->id, sp->xid); - vsb_printf(vsp, " client = %s:%s,\n", + vsb_printf(vsp, " client = %s %s,\n", sp->addr ? sp->addr : "?.?.?.?", sp->port ? sp->port : "?"); switch (sp->step) { Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-24 15:49:52 UTC (rev 5118) +++ trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-24 15:56:49 UTC (rev 5119) @@ -752,6 +752,10 @@ return (vrt_hostname); } +/*-------------------------------------------------------------------- + * XXX: This is pessimistically silly + */ + int VRT_r_server_port(struct sess *sp) { Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-24 15:49:52 UTC (rev 5118) +++ trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-24 15:56:49 UTC (rev 5119) @@ -444,7 +444,7 @@ AN(vsb); TCP_myname(fd, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1); TCP_hisname(fd, abuf2, sizeof abuf2, pbuf2, sizeof pbuf2); - vsb_printf(vsb, "%s %s:%s %s:%s", pfx, abuf2, pbuf2, abuf1, pbuf1); + vsb_printf(vsb, "%s %s %s %s %s", pfx, abuf2, pbuf2, abuf1, pbuf1); vsb_finish(vsb); AZ(vsb_overflowed(vsb)); return (vsb); Modified: trunk/varnish-cache/bin/varnishtest/tests/v00010.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/v00010.vtc 2010-08-24 15:49:52 UTC (rev 5118) +++ trunk/varnish-cache/bin/varnishtest/tests/v00010.vtc 2010-08-24 15:56:49 UTC (rev 5119) @@ -25,7 +25,7 @@ varnish v1 -cliok "param.set diag_bitmap 0x00001000" # Force the (random) port selected to be used again after restart. -varnish v1 -cliok "param.set listen_address ${v1_sock}" +varnish v1 -cliok "param.set listen_address ${v1_addr}:${v1_port}" # varnishtest defaults to auto_restart off, to avoid masking bugs. varnish v1 -cliok "param.set auto_restart on" Modified: trunk/varnish-cache/bin/varnishtest/vtc_server.c =================================================================== --- trunk/varnish-cache/bin/varnishtest/vtc_server.c 2010-08-24 15:49:52 UTC (rev 5118) +++ trunk/varnish-cache/bin/varnishtest/vtc_server.c 2010-08-24 15:56:49 UTC (rev 5119) @@ -95,7 +95,7 @@ vl = vtc_logopen(s->name); - vtc_log(vl, 2, "Started on %s:%s", s->aaddr, s->aport); + vtc_log(vl, 2, "Started on %s %s", s->aaddr, s->aport); for (i = 0; i < s->repeat; i++) { if (s->repeat > 1) vtc_log(vl, 3, "Iteration %d", i); @@ -185,12 +185,12 @@ s->aport, sizeof s->aport); macro_def(s->vl, s->name, "addr", "%s", s->aaddr); macro_def(s->vl, s->name, "port", "%s", s->aport); - macro_def(s->vl, s->name, "sock", "%s:%s", s->aaddr, s->aport); + macro_def(s->vl, s->name, "sock", "%s %s", s->aaddr, s->aport); /* Record the actual port, and reuse it on subsequent starts */ if (!strcmp(s->port, "0")) REPLACE(s->port, s->aport); } - vtc_log(s->vl, 1, "Listen on %s:%s", s->addr, s->port); + vtc_log(s->vl, 1, "Listen on %s %s", s->addr, s->port); s->run = 1; AZ(pthread_create(&s->tp, NULL, server_thread, s)); } Modified: trunk/varnish-cache/bin/varnishtest/vtc_varnish.c =================================================================== --- trunk/varnish-cache/bin/varnishtest/vtc_varnish.c 2010-08-24 15:49:52 UTC (rev 5118) +++ trunk/varnish-cache/bin/varnishtest/vtc_varnish.c 2010-08-24 15:56:49 UTC (rev 5119) @@ -281,7 +281,7 @@ vsb_printf(vsb, " -p syslog_cli_traffic=off"); vsb_printf(vsb, " -a '%s'", "127.0.0.1:0"); vsb_printf(vsb, " -S %s/_S", v->workdir); - vsb_printf(vsb, " -M %s:%s", abuf, pbuf); + vsb_printf(vsb, " -M '%s %s'", abuf, pbuf); vsb_printf(vsb, " -P %s/varnishd.pid", v->workdir); vsb_printf(vsb, " %s", vsb_data(v->storage)); vsb_printf(vsb, " %s", vsb_data(v->args)); @@ -410,7 +410,7 @@ vtc_log(v->vl, 2, "Listen on %s %s", h, p); macro_def(v->vl, v->name, "addr", "%s", h); macro_def(v->vl, v->name, "port", "%s", p); - macro_def(v->vl, v->name, "sock", "%s:%s", h, p); + macro_def(v->vl, v->name, "sock", "%s %s", h, p); } /********************************************************************** Modified: trunk/varnish-cache/doc/sphinx/phk/index.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/phk/index.rst 2010-08-24 15:49:52 UTC (rev 5118) +++ trunk/varnish-cache/doc/sphinx/phk/index.rst 2010-08-24 15:56:49 UTC (rev 5119) @@ -8,6 +8,7 @@ .. toctree:: + ipv6suckage.rst backends.rst platforms.rst barriers.rst Added: trunk/varnish-cache/doc/sphinx/phk/ipv6suckage.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/phk/ipv6suckage.rst (rev 0) +++ trunk/varnish-cache/doc/sphinx/phk/ipv6suckage.rst 2010-08-24 15:56:49 UTC (rev 5119) @@ -0,0 +1,66 @@ +.. _phk_ipv6suckage: + +============ +IPv6 Suckage +============ + +In my drawer full of cassette tapes, is a 6 tape collection published +by Carl Malamuds "Internet Talk Radio", the first and by far the +geekiest radio station on the internet. + +The tapes are from 1994 and the topic is "IPng", the IPv4 replacement +that eventually became IPv6. To say that I am a bit jaded about +IPv6 by now, is accusing the pope of being religious. + +IPv4 addresses in numeric form, are written as 192.168.0.1 and to +not confuse IPv6 with IPv4, it was decided in RFC1884 that IPv6 +would use colons and groups of 16 bits, and because 128 bits are a +lot of bits, the secret '::' trick was introduced, to supress all +the zero bits that we may not ever need anyway: 1080::8:800:200C:417A + +Colon was chosen because it was already used in MAC/ethernet addresses +and did no damage there and it is not a troublesome metacharacter +in shells. No worries. + +Most protocols have a Well Known Service number, TELNET is 23, SSH +is 22 and HTTP is 80 so usually people will only have to care about +the IP number. + +Except when they don't, for instance when they run more than one +webserver on the same machine. + +No worries, says the power that controls what URLs look like, we +will just stick the port number after the IP# with a colon: + + http://192.168.0.1:8080/... + +That obviously does not work with IPv6, so RFC3986 comes around and +says "darn, we didn't think of that" and puts the IPV6 address in +[...] giving us: + + http://[1080::8:800:200C:417A]:8080/ + +Remember that "harmless in shells" detail ? Yeah, sorry about that. + +Now, there are also a RFC sanctioned API for translating a socket +address into an ascii string, getnameinfo(), and if you tell it that +you want a numeric return, you get a numeric return, and you don't +even need to know if it is a IPv4 or IPv6 address in the first place. + +But it returns the IP# in one buffer and the port number in another, +so if you want to format the sockaddr in the by RFC5952 recommended +way (the same as RFC3986), you need to inspect the version field +in the sockaddr to see if you should do + + "%s:%s", host, port +or + "[%s]:%s", host, port + +Careless standardization costs code, have I mentioned this before ? + +Varnish reports socket addresses as two fields: IP space PORT, +now you know why. + +Until next time, + +Poul-Henning, 2010-08-24 Modified: trunk/varnish-cache/lib/libvarnish/vss.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/vss.c 2010-08-24 15:49:52 UTC (rev 5118) +++ trunk/varnish-cache/lib/libvarnish/vss.c 2010-08-24 15:56:49 UTC (rev 5119) @@ -105,6 +105,8 @@ } else { /* IPv4 address of the form 127.0.0.1:80, or non-numeric */ p = strchr(str, ':'); + if (p == NULL) + p = strchr(str, ' '); if (p == NULL) { *addr = strdup(str); XXXAN(*addr); From ingvar at varnish-cache.org Wed Aug 25 08:07:04 2010 From: ingvar at varnish-cache.org (ingvar at varnish-cache.org) Date: Wed, 25 Aug 2010 10:07:04 +0200 Subject: r5120 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: Author: ingvar Date: 2010-08-25 10:07:04 +0200 (Wed, 25 Aug 2010) New Revision: 5120 Modified: trunk/varnish-cache/bin/varnishtest/tests/c00031.vtc Log: A stack size of 128k is too small for rhel6/ppc64. Upping to 256k. Modified: trunk/varnish-cache/bin/varnishtest/tests/c00031.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/c00031.vtc 2010-08-24 15:56:49 UTC (rev 5119) +++ trunk/varnish-cache/bin/varnishtest/tests/c00031.vtc 2010-08-25 08:07:04 UTC (rev 5120) @@ -9,7 +9,7 @@ txresp } -start -varnish v1 -arg "-p thread_pool_stack=131072" -vcl+backend {} -start +varnish v1 -arg "-p thread_pool_stack=262144" -vcl+backend {} -start client c1 { txreq -url "/" From ingvar at varnish-cache.org Wed Aug 25 08:08:22 2010 From: ingvar at varnish-cache.org (ingvar at varnish-cache.org) Date: Wed, 25 Aug 2010 10:08:22 +0200 Subject: r5121 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: Author: ingvar Date: 2010-08-25 10:08:22 +0200 (Wed, 25 Aug 2010) New Revision: 5121 Modified: trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc Log: Upping this test to 1s. It times out on some builds on ppc64. Modified: trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc 2010-08-25 08:07:04 UTC (rev 5120) +++ trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc 2010-08-25 08:08:22 UTC (rev 5121) @@ -29,7 +29,7 @@ } } -cliok "vcl.use vcl2" -cliok "vcl.discard vcl1" -delay .5 +delay 1 varnish v1 -cliok "vcl.list" varnish v1 -cliok "debug.health" From phk at varnish-cache.org Wed Aug 25 08:42:46 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 25 Aug 2010 10:42:46 +0200 Subject: r5122 - trunk/varnish-cache/lib/libvarnish Message-ID: Author: phk Date: 2010-08-25 10:42:45 +0200 (Wed, 25 Aug 2010) New Revision: 5122 Modified: trunk/varnish-cache/lib/libvarnish/vss.c Log: Look for separating space before colon, so that we can grok ":: 50239" as a socketaddr. Modified: trunk/varnish-cache/lib/libvarnish/vss.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/vss.c 2010-08-25 08:08:22 UTC (rev 5121) +++ trunk/varnish-cache/lib/libvarnish/vss.c 2010-08-25 08:42:45 UTC (rev 5122) @@ -104,9 +104,9 @@ } } else { /* IPv4 address of the form 127.0.0.1:80, or non-numeric */ - p = strchr(str, ':'); + p = strchr(str, ' '); if (p == NULL) - p = strchr(str, ' '); + p = strchr(str, ':'); if (p == NULL) { *addr = strdup(str); XXXAN(*addr); From phk at varnish-cache.org Wed Aug 25 08:49:27 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 25 Aug 2010 10:49:27 +0200 Subject: r5123 - in trunk/varnish-cache/bin: varnishadm varnishd Message-ID: Author: phk Date: 2010-08-25 10:49:27 +0200 (Wed, 25 Aug 2010) New Revision: 5123 Modified: trunk/varnish-cache/bin/varnishadm/varnishadm.c trunk/varnish-cache/bin/varnishd/mgt_cli.c Log: The -T argument can be specified as :0 which will just find one or two (IPv4/6) available sockets. In this case, writing the :0 into the VSM will not tell varnishadm where to look. Write the actual socket addresses, one per line instead, and have varnishadm try them all. Make -n mutually exclusive with -S and -T on varnishadm. Modified: trunk/varnish-cache/bin/varnishadm/varnishadm.c =================================================================== --- trunk/varnish-cache/bin/varnishadm/varnishadm.c 2010-08-25 08:42:45 UTC (rev 5122) +++ trunk/varnish-cache/bin/varnishadm/varnishadm.c 2010-08-25 08:49:27 UTC (rev 5123) @@ -79,21 +79,23 @@ sock = VSS_open(T_arg, timeout); if (sock < 0) { - fprintf(stderr, "Connection failed\n"); - exit(1); + fprintf(stderr, "Connection failed (%s)\n", T_arg); + return (-1); } (void)cli_readres(sock, &status, &answer, timeout); if (status == CLIS_AUTH) { if (S_arg == NULL) { fprintf(stderr, "Authentication required\n"); - exit(1); + AZ(close(sock)); + return(-1); } fd = open(S_arg, O_RDONLY); if (fd < 0) { fprintf(stderr, "Cannot open \"%s\": %s\n", S_arg, strerror(errno)); - exit (1); + AZ(close(sock)); + return (-1); } CLI_response(fd, answer, buf); AZ(close(fd)); @@ -106,7 +108,8 @@ } if (status != CLIS_OK) { fprintf(stderr, "Rejected %u\n%s\n", status, answer); - exit(1); + AZ(close(sock)); + return (-1); } free(answer); @@ -114,10 +117,12 @@ (void)cli_readres(sock, &status, &answer, timeout); if (status != CLIS_OK || strstr(answer, "PONG") == NULL) { fprintf(stderr, "No pong received from server\n"); - exit(1); + AZ(close(sock)); + return(-1); } free(answer); + fprintf(stderr, "CLI connected to %s\n", T_arg); return (sock); } @@ -205,19 +210,61 @@ usage(void) { fprintf(stderr, - "usage: varnishadm [-t timeout] [-S secretfile] " + "usage: varnishadm [-n ident] [-t timeout] [-S secretfile] " "-T [address]:port command [...]\n"); + fprintf(stderr, "\t-n is mutually exlusive with -S and -T\n"); exit(1); } +static int +n_arg_sock(const char *n_arg) +{ + char *T_arg = NULL; + char *S_arg = NULL; + struct VSM_data *vsd; + char *p; + int sock; + + vsd = VSM_New(); + assert(VSL_Arg(vsd, 'n', n_arg)); + if (VSM_Open(vsd, 1)) { + fprintf(stderr, "Could not open shared memory\n"); + return (-1); + } + if (T_arg == NULL) { + p = VSM_Find_Chunk(vsd, "Arg", "-T", "", NULL); + if (p == NULL) { + fprintf(stderr, "No -T arg in shared memory\n"); + return (-1); + } + T_arg = strdup(p); + } + if (S_arg == NULL) { + p = VSM_Find_Chunk(vsd, "Arg", "-S", "", NULL); + if (p != NULL) + S_arg = strdup(p); + } + sock = -1; + while (*T_arg) { + p = strchr(T_arg, '\n'); + AN(p); + *p = '\0'; + sock = cli_sock(T_arg, S_arg); + if (sock >= 0) + break; + T_arg = p + 1; + } + free(T_arg); + free(S_arg); + return (sock); +} + int main(int argc, char * const *argv) { const char *T_arg = NULL; const char *S_arg = NULL; const char *n_arg = NULL; - struct VSM_data *vsd; - char *p; int opt, sock; while ((opt = getopt(argc, argv, "n:S:T:t:")) != -1) { @@ -243,30 +290,19 @@ argv += optind; if (n_arg != NULL) { - vsd = VSM_New(); - assert(VSL_Arg(vsd, 'n', n_arg)); - if (!VSM_Open(vsd, 1)) { - if (T_arg == NULL) { - p = VSM_Find_Chunk(vsd, "Arg", "-T", "", NULL); - if (p != NULL) { - T_arg = strdup(p); - } - } - if (S_arg == NULL) { - p = VSM_Find_Chunk(vsd, "Arg", "-S", "", NULL); - if (p != NULL) { - S_arg = strdup(p); - } - } + if (T_arg != NULL || S_arg != NULL) { + usage(); } + sock = n_arg_sock(n_arg); + if (sock < 0) + exit(2); + } else if (T_arg == NULL) { + usage(); + } else { + assert(T_arg != NULL); + sock = cli_sock(T_arg, S_arg); } - if (T_arg == NULL) - usage(); - - assert(T_arg != NULL); - sock = cli_sock(T_arg, S_arg); - if (argc > 0) do_args(sock, argc, argv); else Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-25 08:42:45 UTC (rev 5122) +++ trunk/varnish-cache/bin/varnishd/mgt_cli.c 2010-08-25 08:49:27 UTC (rev 5123) @@ -545,23 +545,24 @@ int i, n, sock, good; struct telnet *tn; char *p; + struct vsb *vsb; + char abuf[TCP_ADDRBUFSIZE]; + char pbuf[TCP_PORTBUFSIZE]; - /* Save in shmem */ - i = strlen(T_arg); - p = VSM_Alloc(i + 1, "Arg", "-T", ""); - AN(p); - strcpy(p, T_arg); - n = VSS_resolve(T_arg, NULL, &ta); if (n == 0) { - fprintf(stderr, "Could not open management port\n"); + REPORT(LOG_ERR, "-T %s Could not be resolved\n", T_arg); exit(2); } good = 0; + vsb = vsb_newauto(); + XXXAN(vsb); for (i = 0; i < n; ++i) { sock = VSS_listen(ta[i], 10); if (sock < 0) continue; + TCP_myname(sock, abuf, sizeof abuf, pbuf, sizeof pbuf); + vsb_printf(vsb, "%s %s\n", abuf, pbuf); good++; tn = telnet_new(sock); tn->ev = vev_new(); @@ -578,6 +579,13 @@ REPORT(LOG_ERR, "-T %s could not be listened on.", T_arg); exit(2); } + vsb_finish(vsb); + AZ(vsb_overflowed(vsb)); + /* Save in shmem */ + p = VSM_Alloc(vsb_len(vsb) + 1, "Arg", "-T", ""); + AN(p); + strcpy(p, vsb_data(vsb)); + vsb_delete(vsb); } /* Reverse CLI ("Master") connections --------------------------------*/ From phk at varnish-cache.org Wed Aug 25 08:52:44 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 25 Aug 2010 10:52:44 +0200 Subject: r5124 - trunk/varnish-cache/lib/libvarnish Message-ID: Author: phk Date: 2010-08-25 10:52:44 +0200 (Wed, 25 Aug 2010) New Revision: 5124 Modified: trunk/varnish-cache/lib/libvarnish/tcp.c Log: An XXX comment Modified: trunk/varnish-cache/lib/libvarnish/tcp.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/tcp.c 2010-08-25 08:49:27 UTC (rev 5123) +++ trunk/varnish-cache/lib/libvarnish/tcp.c 2010-08-25 08:52:44 UTC (rev 5124) @@ -72,6 +72,10 @@ i = getnameinfo(addr, l, abuf, alen, pbuf, plen, NI_NUMERICHOST | NI_NUMERICSERV); if (i) { + /* + * XXX this printf is shitty, but we may not have space + * for the gai_strerror in the bufffer :-( + */ printf("getnameinfo = %d %s\n", i, gai_strerror(i)); strlcpy(abuf, "Conversion", alen); strlcpy(pbuf, "Failed", plen); From phk at varnish-cache.org Wed Aug 25 08:57:04 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 25 Aug 2010 10:57:04 +0200 Subject: r5125 - in trunk/varnish-cache: bin/varnishd bin/varnishtest/tests doc/sphinx include lib/libvarnishapi Message-ID: Author: phk Date: 2010-08-25 10:57:04 +0200 (Wed, 25 Aug 2010) New Revision: 5125 Modified: trunk/varnish-cache/bin/varnishd/cache_dir.c trunk/varnish-cache/bin/varnishd/cache_dir_dns.c trunk/varnish-cache/bin/varnishtest/tests/b00033.vtc trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc trunk/varnish-cache/bin/varnishtest/tests/c00036.vtc trunk/varnish-cache/bin/varnishtest/tests/r00722.vtc trunk/varnish-cache/bin/varnishtest/tests/r00730.vtc trunk/varnish-cache/bin/varnishtest/tests/r00733.vtc trunk/varnish-cache/bin/varnishtest/tests/r00742.vtc trunk/varnish-cache/bin/varnishtest/tests/v00027.vtc trunk/varnish-cache/bin/varnishtest/tests/v00028.vtc trunk/varnish-cache/doc/sphinx/index.rst trunk/varnish-cache/include/vmod.h trunk/varnish-cache/lib/libvarnishapi/vsl_api.h Log: Add missing svn:keywords Modified: trunk/varnish-cache/bin/varnishd/cache_dir.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir.c 2010-08-25 08:52:44 UTC (rev 5124) +++ trunk/varnish-cache/bin/varnishd/cache_dir.c 2010-08-25 08:57:04 UTC (rev 5125) @@ -33,7 +33,7 @@ #include "config.h" #include "svnid.h" -SVNID("$Id: cache_backend.c 5089 2010-08-11 12:12:47Z phk $") +SVNID("$Id$") #include "cache.h" #include "cache_backend.h" Property changes on: trunk/varnish-cache/bin/varnishd/cache_dir.c ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/bin/varnishd/cache_dir_dns.c ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/bin/varnishtest/tests/b00033.vtc ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/bin/varnishtest/tests/c00035.vtc ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/bin/varnishtest/tests/c00036.vtc ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/bin/varnishtest/tests/r00722.vtc ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/bin/varnishtest/tests/r00730.vtc ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/bin/varnishtest/tests/r00733.vtc ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/bin/varnishtest/tests/r00742.vtc ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/bin/varnishtest/tests/v00027.vtc ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/bin/varnishtest/tests/v00028.vtc ___________________________________________________________________ Added: svn:keywords + Id Modified: trunk/varnish-cache/doc/sphinx/index.rst =================================================================== --- trunk/varnish-cache/doc/sphinx/index.rst 2010-08-25 08:52:44 UTC (rev 5124) +++ trunk/varnish-cache/doc/sphinx/index.rst 2010-08-25 08:57:04 UTC (rev 5125) @@ -32,4 +32,4 @@ * :ref:`search` -$Id: $ +$Id$ Property changes on: trunk/varnish-cache/doc/sphinx/index.rst ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/include/vmod.h ___________________________________________________________________ Added: svn:keywords + Id Modified: trunk/varnish-cache/lib/libvarnishapi/vsl_api.h =================================================================== --- trunk/varnish-cache/lib/libvarnishapi/vsl_api.h 2010-08-25 08:52:44 UTC (rev 5124) +++ trunk/varnish-cache/lib/libvarnishapi/vsl_api.h 2010-08-25 08:57:04 UTC (rev 5125) @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: vsm_api.h -1 $ + * $Id$ */ struct vsl { Property changes on: trunk/varnish-cache/lib/libvarnishapi/vsl_api.h ___________________________________________________________________ Added: svn:keywords + Id From phk at varnish-cache.org Wed Aug 25 09:01:06 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 25 Aug 2010 11:01:06 +0200 Subject: r5126 - in trunk/varnish-cache: bin/varnishtest/tests lib/libvcl Message-ID: Author: phk Date: 2010-08-25 11:01:05 +0200 (Wed, 25 Aug 2010) New Revision: 5126 Modified: trunk/varnish-cache/bin/varnishtest/tests/r00742.vtc trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c trunk/varnish-cache/lib/libvcl/vcc_types.h Log: More svn:keywords fixup Modified: trunk/varnish-cache/bin/varnishtest/tests/r00742.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/r00742.vtc 2010-08-25 08:57:04 UTC (rev 5125) +++ trunk/varnish-cache/bin/varnishtest/tests/r00742.vtc 2010-08-25 09:01:05 UTC (rev 5126) @@ -1,4 +1,4 @@ -# $Id# +# $Id$ test "% escapes in VCL source and vcl.show" Property changes on: trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c ___________________________________________________________________ Added: svn:keywords + Id Property changes on: trunk/varnish-cache/lib/libvcl/vcc_types.h ___________________________________________________________________ Added: svn:keywords + Id From phk at varnish-cache.org Wed Aug 25 09:19:43 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 25 Aug 2010 11:19:43 +0200 Subject: r5127 - in trunk/varnish-cache: bin/varnishadm bin/varnishd bin/varnishstat bin/varnishtest include lib/libvarnish lib/libvarnishapi lib/libvcl Message-ID: Author: phk Date: 2010-08-25 11:19:43 +0200 (Wed, 25 Aug 2010) New Revision: 5127 Modified: trunk/varnish-cache/bin/varnishadm/varnishadm.c trunk/varnish-cache/bin/varnishd/cache_backend_poll.c trunk/varnish-cache/bin/varnishd/cache_center.c trunk/varnish-cache/bin/varnishd/cache_dir_dns.c trunk/varnish-cache/bin/varnishd/cache_fetch.c trunk/varnish-cache/bin/varnishd/cache_vcl.c trunk/varnish-cache/bin/varnishd/mgt_shmem.c trunk/varnish-cache/bin/varnishd/mgt_vcc.c trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c trunk/varnish-cache/bin/varnishtest/vtc_http.c trunk/varnish-cache/include/varnishapi.h trunk/varnish-cache/lib/libvarnish/vtmpfile.c trunk/varnish-cache/lib/libvarnishapi/vsl.c trunk/varnish-cache/lib/libvcl/vcc_backend.c trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c trunk/varnish-cache/lib/libvcl/vcc_expr.c trunk/varnish-cache/lib/libvcl/vcc_parse.c Log: white-space anal-retentive fixup Modified: trunk/varnish-cache/bin/varnishadm/varnishadm.c =================================================================== --- trunk/varnish-cache/bin/varnishadm/varnishadm.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/bin/varnishadm/varnishadm.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -241,7 +241,7 @@ } if (S_arg == NULL) { p = VSM_Find_Chunk(vsd, "Arg", "-S", "", NULL); - if (p != NULL) + if (p != NULL) S_arg = strdup(p); } sock = -1; @@ -250,7 +250,7 @@ AN(p); *p = '\0'; sock = cli_sock(T_arg, S_arg); - if (sock >= 0) + if (sock >= 0) break; T_arg = p + 1; } Modified: trunk/varnish-cache/bin/varnishd/cache_backend_poll.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -77,7 +77,7 @@ struct vrt_backend_probe probe; int stop; struct vsb *vsb; - char *req; + char *req; int req_len; char resp_buf[128]; Modified: trunk/varnish-cache/bin/varnishd/cache_center.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/bin/varnishd/cache_center.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -262,7 +262,7 @@ WSL_Flush(sp->wrk, 0); /* If we did an ESI include, don't mess up our state */ - if (sp->esis > 0) + if (sp->esis > 0) return (1); memset(&sp->acct_req, 0, sizeof sp->acct_req); Modified: trunk/varnish-cache/bin/varnishd/cache_dir_dns.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/bin/varnishd/cache_dir_dns.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -55,12 +55,12 @@ #define VDI_DNS_MAX_CACHE 1024 #define VDI_DNS_GROUP_MAX_BACKENDS 1024 -/* DNS Cache entry +/* DNS Cache entry */ struct vdi_dns_hostgroup { unsigned magic; #define VDI_DNSDIR_MAGIC 0x1bacab21 - char *hostname; + char *hostname; struct director *hosts[VDI_DNS_GROUP_MAX_BACKENDS]; unsigned nhosts; unsigned next_host; /* Next to use...*/ @@ -85,7 +85,7 @@ /* Compare an IPv4 backend to a IPv4 addr/len */ static int -vdi_dns_comp_addrinfo4(const struct backend *bp, +vdi_dns_comp_addrinfo4(const struct backend *bp, const struct sockaddr_in *addr, const socklen_t len) { @@ -226,7 +226,7 @@ if (vdi_dns_groupmatch(hostgr, hostname)) { ret = (vdi_dns_pick_host(sp, hostgr)); *backend = ret; - if (*backend != NULL) + if (*backend != NULL) CHECK_OBJ_NOTNULL(*backend, DIRECTOR_MAGIC); return 1; } @@ -274,7 +274,7 @@ if (vdi_dns_cache_has(sp, vs, hostname, backend, 1)) return 1; - + memset(&hint, 0, sizeof hint); hint.ai_family = PF_UNSPEC; hint.ai_socktype = SOCK_STREAM; @@ -311,7 +311,7 @@ new->nhosts = host; vdi_dns_cache_list_add(sp, vs, new); - *backend = vdi_dns_pick_host(sp, new); + *backend = vdi_dns_pick_host(sp, new); return 1; } @@ -367,7 +367,7 @@ if (http_GetHdr(hp, H_Host, &p) == 0) return (NULL); - /* We need a working copy since it's going to be modified */ + /* We need a working copy since it's going to be modified */ strncpy(hostname, p, sizeof(hostname)); /* remove port-portion of the Host-header, if present. */ @@ -399,7 +399,7 @@ dir = vdi_dns_find_backend(sp, vs); if (!dir || !VDI_Healthy_sp(sp, dir)) return (NULL); - + vbe = VDI_GetFd(dir, sp); return (vbe); } Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/bin/varnishd/cache_fetch.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -367,7 +367,6 @@ vc = sp->vbc; if (vc->recycled) retry = 1; - /* * Now that we know our backend, we can set a default Host: Modified: trunk/varnish-cache/bin/varnishd/cache_vcl.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vcl.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/bin/varnishd/cache_vcl.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -305,7 +305,7 @@ Lck_Unlock(&vcl_mtx); /* Tickle this VCL's backends to take over health polling */ - for(i = 1; i < vcl->conf->ndirector; i++) + for(i = 1; i < vcl->conf->ndirector; i++) VBE_UseHealth(vcl->conf->director[i]); } Modified: trunk/varnish-cache/bin/varnishd/mgt_shmem.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_shmem.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/bin/varnishd/mgt_shmem.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -38,7 +38,7 @@ * | * v * Open old VSM, - * check pid --------> exit/fail (-n message) + * check pid --------> exit/fail (-n message) * | * +<----------------------+ * | ^ @@ -81,7 +81,7 @@ * | | * v | * +-------------->+ - * + * */ #include "config.h" Modified: trunk/varnish-cache/bin/varnishd/mgt_vcc.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_vcc.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/bin/varnishd/mgt_vcc.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -277,7 +277,7 @@ (void)unlink(sf); vsb_delete(cmdsb); - if (!i) + if (!i) i = SUB_run(sb, run_dlopen, of, "dlopen", 10); if (i) { Modified: trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c =================================================================== --- trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -223,7 +223,7 @@ AC(mvprintw(line, 0, " %010.10jx <", (ju >> 24) & 0xffffffffffLL)); for (ch = 0x800000; ch; ch >>= 1) - if (ju & ch) + if (ju & ch) AC(printw("V")); else AC(printw("_")); Modified: trunk/varnish-cache/bin/varnishtest/vtc_http.c =================================================================== --- trunk/varnish-cache/bin/varnishtest/vtc_http.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/bin/varnishtest/vtc_http.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -508,8 +508,8 @@ int bodylen = 0; char *b, *c; char *body = NULL, *nullbody; - + (void)cmd; (void)vl; CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC); Modified: trunk/varnish-cache/include/varnishapi.h =================================================================== --- trunk/varnish-cache/include/varnishapi.h 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/include/varnishapi.h 2010-08-25 09:19:43 UTC (rev 5127) @@ -54,7 +54,7 @@ * You can have multiple active VSL_data handles at the same time * referencing the same or different shared memory files. * Returns: - * Pointer to usable VSL_data handle. + * Pointer to usable VSL_data handle. */ typedef void vsm_diag_f(void *priv, const char *fmt, ...); @@ -96,7 +96,7 @@ * If diag is non-zero, diagnostics are emitted. * Returns: * 0 on success - * != 0 on failure + * != 0 on failure */ int VSM_ReOpen(struct VSM_data *vd, int diag); @@ -161,7 +161,7 @@ int VSC_Arg(struct VSM_data *vd, int arg, const char *opt); /* - * Handle standard stat-presenter arguments + * Handle standard stat-presenter arguments * Return: * -1 error * 0 not handled @@ -212,9 +212,9 @@ * If diag is non-zero, diagnostics are emitted. * Returns: * 0 on success - * != 0 on failure + * != 0 on failure */ - + #define VSL_ARGS "bCcdI:i:k:n:r:s:X:x:" #define VSL_b_USAGE "[-b]" #define VSL_c_USAGE "[-c]" @@ -229,18 +229,18 @@ #define VSL_x_USAGE "[-x tag]" #define VSL_X_USAGE "[-X regexp]" #define VSL_USAGE "[-bCcd] " \ - VSL_i_USAGE " " \ + VSL_i_USAGE " " \ VSL_I_USAGE " " \ VSL_k_USAGE " " \ VSL_n_USAGE " " \ VSL_r_USAGE " " \ VSL_s_USAGE " " \ VSL_X_USAGE " " \ - VSL_x_USAGE - + VSL_x_USAGE + int VSL_Arg(struct VSM_data *vd, int arg, const char *opt); /* - * Handle standard log-presenter arguments + * Handle standard log-presenter arguments * Return: * -1 error * 0 not handled Modified: trunk/varnish-cache/lib/libvarnish/vtmpfile.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/vtmpfile.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/lib/libvarnish/vtmpfile.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -110,7 +110,7 @@ else if (pfx != NULL) { bprintf(fnb, "/%s/%s", pfx, fn); /* XXX: graceful length check */ fd = open(fnb, O_RDONLY); - } else + } else fd = open(fn, O_RDONLY); if (fd < 0) return (NULL); Modified: trunk/varnish-cache/lib/libvarnishapi/vsl.c =================================================================== --- trunk/varnish-cache/lib/libvarnishapi/vsl.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/lib/libvarnishapi/vsl.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -66,7 +66,7 @@ VSL_Setup(struct VSM_data *vd) { struct vsl *vsl; - + CHECK_OBJ_NOTNULL(vd, VSM_MAGIC); AZ(vd->vsc); AZ(vd->vsl); Modified: trunk/varnish-cache/lib/libvcl/vcc_backend.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -578,7 +578,7 @@ /* Check that the hostname makes sense */ assert(t_host != NULL); - if (t_port != NULL) + if (t_port != NULL) Emit_Sockaddr(tl, t_host, t_port->dec); else Emit_Sockaddr(tl, t_host, "80"); Modified: trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/lib/libvcl/vcc_dir_dns.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -139,7 +139,7 @@ * uint8_ts. */ static void -vcc_dir_dns_makebackend(struct vcc *tl, +vcc_dir_dns_makebackend(struct vcc *tl, int *serial, const unsigned char a[], int inmask) Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -309,7 +309,7 @@ vcc_ErrWhere(tl, top); return; } - } else + } else break; lfmt = afmt; } Modified: trunk/varnish-cache/lib/libvcl/vcc_parse.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_parse.c 2010-08-25 09:01:05 UTC (rev 5126) +++ trunk/varnish-cache/lib/libvcl/vcc_parse.c 2010-08-25 09:19:43 UTC (rev 5127) @@ -225,7 +225,7 @@ vcc_Cond_3(tl); Fb(tl, 1, ")\n"); return; - } + } vsb_printf(tl->sb, "Syntax error in condition.\n" "Expected '(', '!' or variable name.\n" From ingvar at varnish-cache.org Wed Aug 25 09:30:05 2010 From: ingvar at varnish-cache.org (ingvar at varnish-cache.org) Date: Wed, 25 Aug 2010 11:30:05 +0200 Subject: r5128 - trunk/varnish-cache/redhat Message-ID: Author: ingvar Date: 2010-08-25 11:30:04 +0200 (Wed, 25 Aug 2010) New Revision: 5128 Modified: trunk/varnish-cache/redhat/varnish.spec Log: makes trunk build again, including new docs Modified: trunk/varnish-cache/redhat/varnish.spec =================================================================== --- trunk/varnish-cache/redhat/varnish.spec 2010-08-25 09:19:43 UTC (rev 5127) +++ trunk/varnish-cache/redhat/varnish.spec 2010-08-25 09:30:04 UTC (rev 5128) @@ -1,7 +1,7 @@ Summary: High-performance HTTP accelerator Name: varnish Version: 2.1.4 -Release: 0.svn20100730%{?dist} +Release: 0.svn20100824r5117%{?dist} License: BSD Group: System Environment/Daemons URL: http://www.varnish-cache.org/ @@ -10,7 +10,9 @@ # The svn sources needs autoconf, automake and libtool to generate a suitable # configure script. Release tarballs would not need this BuildRequires: automake autoconf libtool -BuildRequires: ncurses-devel libxslt groff pcre-devel pkgconfig +BuildRequires: ncurses-devel libxslt groff pcre-devel pkgconfig tex(latex) +BuildRequires: python-docutils >= 0.6 +BuildRequires: python-sphinx >= 0.6 Requires: varnish-libs = %{version}-%{release} Requires: logrotate Requires: ncurses @@ -103,12 +105,9 @@ %endif # Remove "--disable static" if you want to build static libraries -# jemalloc is not compatible with Red Hat's ppc* RHEL5 kernel koji server :-( +# jemalloc is not compatible with Red Hat's ppc64 RHEL kernel :-( %ifarch ppc64 ppc - if [[ `uname -r` =~ "2.6.18-.*" ]] - then %configure --disable-static --localstatedir=/var/lib --disable-jemalloc - else %configure --disable-static --localstatedir=/var/lib - fi + %configure --disable-static --localstatedir=/var/lib --disable-jemalloc %else %configure --disable-static --localstatedir=/var/lib %endif @@ -169,8 +168,8 @@ %endif %endif -#LD_LIBRARY_PATH="lib/libvarnish/.libs:lib/libvarnishcompat/.libs:lib/libvarnishapi/.libs:lib/libvcl/.libs" bin/varnishd/varnishd -b 127.0.0.1:80 -C -n /tmp/foo -#%{__make} check LD_LIBRARY_PATH="../../lib/libvarnish/.libs:../../lib/libvarnishcompat/.libs:../../lib/libvarnishapi/.libs:../../lib/libvcl/.libs" +LD_LIBRARY_PATH="lib/libvarnish/.libs:lib/libvarnishcompat/.libs:lib/libvarnishapi/.libs:lib/libvcl/.libs" bin/varnishd/varnishd -b 127.0.0.1:80 -C -n /tmp/foo +%{__make} check LD_LIBRARY_PATH="../../lib/libvarnish/.libs:../../lib/libvarnishcompat/.libs:../../lib/libvarnishapi/.libs:../../lib/libvcl/.libs" %install rm -rf %{buildroot} @@ -270,9 +269,9 @@ %postun libs -p /sbin/ldconfig %changelog -* Thu Jul 29 2010 Ingvar Hagelund - 2.1.4-0.svn20100730 +* Thu Jul 29 2010 Ingvar Hagelund - 2.1.4-0.svn20100824r5117 - Replaced specific include files with a wildcard glob -- Needs python-sphinx to build sphinx documentation +- Needs python-sphinx and deps to build sphinx documentation - Builds html and latex documentation. Put that in a subpackage varnish-docs * Thu Jul 29 2010 Ingvar Hagelund - 2.1.3-1 From phk at varnish-cache.org Wed Aug 25 09:47:48 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 25 Aug 2010 11:47:48 +0200 Subject: r5129 - trunk/varnish-cache/lib/libvcl Message-ID: Author: phk Date: 2010-08-25 11:47:48 +0200 (Wed, 25 Aug 2010) New Revision: 5129 Modified: trunk/varnish-cache/lib/libvcl/vcc_parse.c Log: Add comments with BNF-ish syntax since this is starting to get hairy. Modified: trunk/varnish-cache/lib/libvcl/vcc_parse.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_parse.c 2010-08-25 09:30:04 UTC (rev 5128) +++ trunk/varnish-cache/lib/libvcl/vcc_parse.c 2010-08-25 09:47:48 UTC (rev 5129) @@ -163,6 +163,25 @@ } } +/*-------------------------------------------------------------------- + * SYNTAX: + * Cond_3: + * Typed_Expr Relation Compat_Typed_Expr + * Typed_Expr: + * VarName + * FuncCall + * Relation: + * Subset('==', '!=', '<', '<=', '>', '>=', '~', '!~') + * Compat_Typed_Expr + * Typed_Expr + * Typed_Const + * + * Since we cannot tell if "10 s" is a TIME or DURATION type, or for that + * matter if "127.0.0.1" is a STRING or IP type, we demand that the expression + * before the relational operator provides us with a type which can be used to + * guide parsing of other expression. + */ + static void vcc_Cond_3(struct vcc *tl) { @@ -207,6 +226,13 @@ } } +/*-------------------------------------------------------------------- + * SYNTAX: + * Cond_2: + * '!'? '(' Conditional ')' + * '!'? Cond_3 + */ + static void vcc_Cond_2(struct vcc *tl) { @@ -236,6 +262,12 @@ return; } +/*-------------------------------------------------------------------- + * SYNTAX: + * Cond_1: + * Cond_2 { '&&' Cond_2 }* + */ + static void vcc_Cond_1(struct vcc *tl) { @@ -251,6 +283,12 @@ Fb(tl, 1, ")\n"); } +/*-------------------------------------------------------------------- + * SYNTAX: + * Cond_0: + * Cond_1 { '||' Cond_1 }* + */ + static void vcc_Cond_0(struct vcc *tl) { @@ -266,6 +304,12 @@ Fb(tl, 1, ")\n"); } +/*-------------------------------------------------------------------- + * SYNTAX: + * Conditional: + * '(' Cond_0 ')' + */ + static void vcc_Conditional(struct vcc *tl) { @@ -278,7 +322,16 @@ SkipToken(tl, ')'); } -/*--------------------------------------------------------------------*/ +/*-------------------------------------------------------------------- + * SYNTAX: + * IfStmt: + * 'if' Conditional Compound Branch1* Branch2 + * Branch1: + * 'elseif' Conditional Compound + * Branch2: + * 'else' Compound + * null + */ static void vcc_IfStmt(struct vcc *tl) @@ -317,7 +370,17 @@ } } -/*--------------------------------------------------------------------*/ +/*-------------------------------------------------------------------- + * SYNTAX: + * Compound: + * '{' Stmt* '}' + * + * Stmt: + * Compound + * IfStmt + * CSRC + * Id(Action) (XXX) + */ static void vcc_Compound(struct vcc *tl) @@ -371,7 +434,11 @@ } } -/*--------------------------------------------------------------------*/ +/*-------------------------------------------------------------------- + * SYNTAX: + * Function: + * 'sub' ID(name) Compound + */ static void vcc_Function(struct vcc *tl) From phk at varnish-cache.org Wed Aug 25 19:01:35 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Wed, 25 Aug 2010 21:01:35 +0200 Subject: r5130 - in trunk/varnish-cache: bin/varnishtest/tests lib/libvcl Message-ID: Author: phk Date: 2010-08-25 21:01:35 +0200 (Wed, 25 Aug 2010) New Revision: 5130 Modified: trunk/varnish-cache/bin/varnishtest/tests/v00016.vtc trunk/varnish-cache/lib/libvcl/vcc_acl.c trunk/varnish-cache/lib/libvcl/vcc_action.c trunk/varnish-cache/lib/libvcl/vcc_compile.h trunk/varnish-cache/lib/libvcl/vcc_expr.c trunk/varnish-cache/lib/libvcl/vcc_parse.c trunk/varnish-cache/lib/libvcl/vcc_token.c Log: Rewrite of the "if (foo)" code in VCC to actually build expressions the way we learned to do it back in the 1950'ies. Until now, VCC has used sort of a massaged C-expression and with the introduction of things like regexp matching and ACLs that turned sort of ugly. This code is classic recursive expression parsing with a couple of twists: 1. We don't build a tree, because we are not going to optimize stuff, we leave that to the C compiler. 2. Instead of the tree we build a string with magic markers that let us get the indentation of the produced C code right anyway. 3. We do type-hinted parsing, in an attempt to produce intelligent error messages and sensible semantics. This code passes all testcases with a single change: We can now compile "if (2 == 3)". This is probably a good thing (?) Beware of bugs... Modified: trunk/varnish-cache/bin/varnishtest/tests/v00016.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/v00016.vtc 2010-08-25 09:47:48 UTC (rev 5129) +++ trunk/varnish-cache/bin/varnishtest/tests/v00016.vtc 2010-08-25 19:01:35 UTC (rev 5130) @@ -95,7 +95,7 @@ sub vcl_hash { if (req.hash != "foo") { } } } -varnish v1 -badvcl { +varnish v1 -vcl { backend b { .host = "127.0.0.1"; } sub vcl_hash { if (2 == 3) { } } } Modified: trunk/varnish-cache/lib/libvcl/vcc_acl.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_acl.c 2010-08-25 09:47:48 UTC (rev 5129) +++ trunk/varnish-cache/lib/libvcl/vcc_acl.c 2010-08-25 19:01:35 UTC (rev 5130) @@ -449,41 +449,19 @@ } void -vcc_Cond_Ip(struct vcc *tl, const char *a1) +vcc_Acl_Hack(struct vcc *tl, char *b) { - unsigned tcond; char acln[32]; + unsigned tcond; - switch (tl->t->tok) { - /* XXX: T_NOMATCH */ - case '~': - vcc_NextToken(tl); - ExpectErr(tl, ID); - vcc_AddRef(tl, tl->t, R_ACL); - Fb(tl, 1, "match_acl_named_%.*s(sp, %s)\n", - PF(tl->t), a1); - vcc_NextToken(tl); - break; - case T_EQ: - case T_NEQ: - - VTAILQ_INIT(&tl->acl); - tcond = tl->t->tok; - vcc_NextToken(tl); - bprintf(acln, "%u", tl->cnt); - vcc_acl_entry(tl); - vcc_acl_emit(tl, acln, 1); - Fb(tl, 1, "%smatch_acl_anon_%s(sp, %s)\n", - (tcond == T_NEQ ? "!" : ""), acln, a1); - break; - default: - vsb_printf(tl->sb, "Invalid condition "); - vcc_ErrToken(tl, tl->t); - vsb_printf(tl->sb, " on IP number variable\n"); - vsb_printf(tl->sb, " only '==', '!=' and '~' are legal\n"); - vcc_ErrWhere(tl, tl->t); - break; - } + VTAILQ_INIT(&tl->acl); + tcond = tl->t->tok; + vcc_NextToken(tl); + bprintf(acln, "%u", tl->cnt); + vcc_acl_entry(tl); + vcc_acl_emit(tl, acln, 1); + sprintf(b, "%smatch_acl_anon_%s(sp, \v1)", + (tcond == T_NEQ ? "!" : ""), acln); } void Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_action.c 2010-08-25 09:47:48 UTC (rev 5129) +++ trunk/varnish-cache/lib/libvcl/vcc_action.c 2010-08-25 19:01:35 UTC (rev 5130) @@ -101,6 +101,7 @@ /*--------------------------------------------------------------------*/ +#if 1 static void illegal_assignment(const struct vcc *tl, const char *type) { @@ -110,12 +111,14 @@ vsb_printf(tl->sb, " only '=' is legal for %s\n", type); } +#endif static void parse_set(struct vcc *tl) { const struct var *vp; - struct token *at, *vt; + struct token *vt; + struct token *at; vcc_NextToken(tl); ExpectErr(tl, ID); @@ -124,7 +127,12 @@ ERRCHK(tl); assert(vp != NULL); Fb(tl, 1, "%s", vp->lname); +#if 0 vcc_NextToken(tl); + SkipToken(tl, '='); + vcc_Expr(tl, vp->fmt); +#else + vcc_NextToken(tl); switch (vp->fmt) { case INT: case TIME: @@ -212,6 +220,7 @@ vcc_ErrWhere(tl, tl->t); return; } +#endif } /*--------------------------------------------------------------------*/ Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-25 09:47:48 UTC (rev 5129) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-25 19:01:35 UTC (rev 5130) @@ -174,7 +174,7 @@ /* vcc_acl.c */ void vcc_Acl(struct vcc *tl); -void vcc_Cond_Ip(struct vcc *tl, const char *a1); +void vcc_Acl_Hack(struct vcc *tl, char *b); /* vcc_action.c */ int vcc_ParseAction(struct vcc *tl); @@ -224,7 +224,7 @@ void vcc_TimeVal(struct vcc *tl, double *); unsigned vcc_UintVal(struct vcc *tl); double vcc_DoubleVal(struct vcc *tl); -void vcc_Expr(struct vcc *tl, enum var_type fmt); +void vcc_Expr(struct vcc *tl, enum var_type typ); /* vcc_dir_dns.c */ parsedirector_f vcc_ParseDnsDirector; Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-25 09:47:48 UTC (rev 5129) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-25 19:01:35 UTC (rev 5130) @@ -25,6 +25,8 @@ * 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. + * + * XXX: add VRT_count()'s */ #include "config.h" @@ -43,21 +45,18 @@ #include "vcc_compile.h" #include "libvarnish.h" -/*--------------------------------------------------------------------*/ +static const char * +vcc_Type(enum var_type fmt) +{ + switch(fmt) { +#define VCC_TYPE(a) case a: return(#a); +#include "vcc_types.h" +#undef VCC_TYPE + default: + return("Unknown Type"); + } +} -#define L(tl, foo) do { \ - tl->indent += INDENT; \ - foo; \ - tl->indent -= INDENT; \ -} while (0) - -#if 0 -#define C(tl, sep) do { \ - Fb(tl, 1, "VRT_count(sp, %u)%s\n", ++tl->cnt, sep); \ - tl->t->cnt = tl->cnt; \ -} while (0) -#endif - /*-------------------------------------------------------------------- * Recognize and convert units of time, return seconds. */ @@ -190,158 +189,507 @@ *d = v * sc; } -/*--------------------------------------------------------------------*/ +/*-------------------------------------------------------------------- + * + */ +struct expr { + unsigned magic; +#define EXPR_MAGIC 0x38c794ab + enum var_type fmt; + struct vsb *vsb; + /* XXX: first and last token */ +}; + +static void vcc_expr0(struct vcc *tl, struct expr **e, enum var_type fmt); + +static struct expr * +vcc_new_expr(void) +{ + struct expr *e; + + /* XXX: use TlAlloc() ? */ + ALLOC_OBJ(e, EXPR_MAGIC); + AN(e); + e->vsb = vsb_newauto(); + e->fmt = VOID; + return (e); +} + static void -vcc_Expr2(struct vcc *tl, enum var_type *fmt) +vcc_delete_expr(struct expr *e) { + if (e == NULL) + return; + CHECK_OBJ_NOTNULL(e, EXPR_MAGIC); + vsb_delete(e->vsb); + FREE_OBJ(e); +} + +/*-------------------------------------------------------------------- + * We want to get the indentation right in the emitted C code so we have + * to represent it symbolically until we are ready to render. + * + * Many of the operations have very schematic output syntaxes, so we + * use the same facility to simplify the text-processing of emitting + * a given operation on two subexpressions. + * + * We use '\v' as the magic escape character. + * \v1 insert subexpression 1 + * \v2 insert subexpression 2 + * \v+ increase indentation + * \v- increase indentation + * anything else is literal + * + * When editing, we check if any of the subexpressions contain a newline + * and issue it as an indented block of so. + * + * XXX: check line lengths in edit, should pass indent in for this + */ + +static struct expr * +vcc_expr_edit(enum var_type fmt, const char *p, struct expr *e1, struct expr *e2) +{ + struct expr *e; + char *q; + + q = strchr(vsb_data(e1->vsb), '\n'); + if (q == NULL && e2 != NULL) + q = strchr(vsb_data(e2->vsb), '\n'); + e = vcc_new_expr(); + while (*p != '\0') { + if (*p != '\v') { + vsb_putc(e->vsb, *p); + p++; + continue; + } + p++; + switch(*p) { + case '+': vsb_cat(e->vsb, "\v+"); break; + case '-': vsb_cat(e->vsb, "\v-"); break; + case '1': + case '2': + if (q != NULL) + vsb_cat(e->vsb, "\v+\n"); + if (*p == '1') + vsb_cat(e->vsb, vsb_data(e1->vsb)); + else + vsb_cat(e->vsb, vsb_data(e2->vsb)); + if (q != NULL) + vsb_cat(e->vsb, "\v-\n"); + break; + default: + assert(__LINE__ == 0); + } + p++; + } + vsb_finish(e->vsb); + AZ(vsb_overflowed(e->vsb)); + vcc_delete_expr(e1); + vcc_delete_expr(e2); + e->fmt = fmt; + return (e); +} + +/*-------------------------------------------------------------------- + * Expand finished expression into C-source code + */ + +static void +vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1) +{ + char *p; + int i; + + for (i = 0; i < ind; i++) + vsb_cat(d, " "); + for (p = vsb_data(e1->vsb); *p != '\0'; p++) { + if (*p == '\n') { + vsb_putc(d, '\n'); + if (p[1] != '\0') { + for (i = 0; i < ind; i++) + vsb_cat(d, " "); + } + continue; + } + if (*p != '\v') { + vsb_putc(d, *p); + continue; + } + p++; + switch(*p) { + case '+': ind += 2; break; + case '-': ind -= 2; break; + default: + assert(__LINE__ == 0); + } + } +} + +/*-------------------------------------------------------------------- + * SYNTAX: + * Expr4: + * '(' Expr0 ')' + * CNUM + * CSTR + */ + +static void +vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt) +{ + struct expr *e1, *e2; const struct symbol *sym; const struct var *vp; double d; - int frac; - *fmt = VOID; + *e = NULL; + if (tl->t->tok == '(') { + SkipToken(tl, '('); + vcc_expr0(tl, &e2, fmt); + ERRCHK(tl); + SkipToken(tl, ')'); + *e = vcc_expr_edit(e2->fmt, "(\v1)", e2, NULL); + return; + } + e1 = vcc_new_expr(); switch(tl->t->tok) { case ID: sym = VCC_FindSymbol(tl, tl->t); if (sym == NULL) { - vsb_printf(tl->sb, - "Unknown symbol in numeric expression:\n"); + vsb_printf(tl->sb, "Symbol not found: "); vcc_ErrToken(tl, tl->t); - vsb_printf(tl->sb, "\n"); vcc_ErrWhere(tl, tl->t); return; } + AN(sym); + vcc_AddUses(tl, tl->t, sym->r_methods, "Not available"); AN(sym->var); vp = vcc_FindVar(tl, tl->t, 0, "cannot be read"); ERRCHK(tl); assert(vp != NULL); - Fb(tl, 1, "%s\n", vp->rname); - *fmt = sym->fmt; + vsb_printf(e1->vsb, "%s", vp->rname); + e1->fmt = vp->fmt; vcc_NextToken(tl); - return; + break; + case CSTR: + assert(fmt != VOID); + EncToken(e1->vsb, tl->t); + e1->fmt = STRING; + vcc_NextToken(tl); + break; case CNUM: - vcc_NumVal(tl, &d, &frac); - ERRCHK(tl); - if (tl->t->tok == ID) { - d *= vcc_TimeUnit(tl); + assert(fmt != VOID); + if (fmt == DURATION) { + vcc_RTimeVal(tl, &d); ERRCHK(tl); - *fmt = DURATION; - } else if (!frac) { - *fmt = INT; + vsb_printf(e1->vsb, "%g", d); + e1->fmt = DURATION; } else { - WRONG("numeric constant botch"); + vsb_printf(e1->vsb, "%.*s", PF(tl->t)); + vcc_NextToken(tl); + e1->fmt = INT; } - Fb(tl, 1, "%g\n", d); + break; + default: + e1->fmt = fmt; + vsb_printf(e1->vsb, "", PF(tl->t), tl->t->tok); + vcc_NextToken(tl); + break; + } + + vsb_finish(e1->vsb); + AZ(vsb_overflowed(e1->vsb)); + *e = e1; +} + +/*-------------------------------------------------------------------- + * SYNTAX: + * Expr3: + * Expr4 { {'*'|'/'} Expr4 } * + */ + +static void +vcc_expr_mul(struct vcc *tl, struct expr **e, enum var_type fmt) +{ + struct expr *e2; + enum var_type f2, f3; + + *e = NULL; + vcc_expr4(tl, e, fmt); + ERRCHK(tl); + f3 = f2 = (*e)->fmt; + + switch(f2) { + case INT: f2 = INT; break; + case DURATION: f2 = INT; break; /* XXX: should be Double */ + default: return; + } + while (tl->t->tok == '+' || tl->t->tok == '-') { + vcc_NextToken(tl); + vcc_expr4(tl, &e2, f2); + ERRCHK(tl); + if (tl->t->tok == '+') + *e = vcc_expr_edit(f3, "(\v1+\v2)", *e, e2); + else + *e = vcc_expr_edit(f3, "(\v1-\v2)", *e, e2); + } +} +/*-------------------------------------------------------------------- + * SYNTAX: + * ExprAdd: + * ExprMul { {'+'|'-'} ExprMul } * + */ + +static void +vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt) +{ + struct expr *e2; + enum var_type f2; + + *e = NULL; + vcc_expr_mul(tl, e, fmt); + ERRCHK(tl); + f2 = (*e)->fmt; + + switch(f2) { + case INT: break; + case TIME: f2 = DURATION; break; + case DURATION: f2 = DURATION; break; default: - vsb_printf(tl->sb, - "Unknown token in numeric expression:\n"); - vcc_ErrToken(tl, tl->t); - vsb_printf(tl->sb, "\n"); - vcc_ErrWhere(tl, tl->t); return; } + + while (tl->t->tok == '+' || tl->t->tok == '-') { + vcc_NextToken(tl); + vcc_expr_mul(tl, &e2, f2); + ERRCHK(tl); + if (tl->t->tok == '+') + *e = vcc_expr_edit(f2, "(\v1+\v2)", *e, e2); + else + *e = vcc_expr_edit(f2, "(\v1-\v2)", *e, e2); + } } +/*-------------------------------------------------------------------- + * SYNTAX: + * ExprCmp: + * ExprAdd + * ExprAdd Relation ExprAdd + * ExprAdd(STRING) '~' CString + * ExprAdd(STRING) '!~' CString + * ExprAdd(IP) '~' IP + * ExprAdd(IP) '!~' IP + */ + +static const struct cmps { + enum var_type fmt; + unsigned token; + const char *emit; +} vcc_cmps[] = { + {INT, T_EQ, "(\v1 == \v2)" }, + {INT, T_NEQ, "(\v1 != \v2)" }, + {INT, T_LEQ, "(\v1 <= \v2)" }, + {INT, T_GEQ, "(\v1 >= \v2)" }, + {INT, '<', "(\v1 < \v2)" }, + {INT, '>', "(\v1 > \v2)" }, + + {DURATION, T_EQ, "(\v1 == \v2)" }, + {DURATION, T_NEQ, "(\v1 != \v2)" }, + {DURATION, T_LEQ, "(\v1 <= \v2)" }, + {DURATION, T_GEQ, "(\v1 >= \v2)" }, + {DURATION, '<', "(\v1 < \v2)" }, + {DURATION, '>', "(\v1 > \v2)" }, + + {STRING, T_EQ, "!VRT_strcmp(\v1, \v2)" }, + {STRING, T_NEQ, "VRT_strcmp(\v1, \v2)" }, + + {VOID, 0, NULL} +}; + static void -vcc_Expr1(struct vcc *tl, enum var_type fmt) +vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt) { - enum var_type lfmt, rfmt, afmt; - struct token *top; - struct token *tfirst; + struct expr *e2; + const struct cmps *cp; + char buf[256]; + char *re; + const char *not; + struct token *tk; - tfirst = tl->t; - Fb(tl, 1, "(\n"); - L(tl, vcc_Expr2(tl, &lfmt)); + *e = NULL; + + if (fmt == BOOL && tl->t->tok == '!') { + vcc_NextToken(tl); + vcc_expr_add(tl, &e2, fmt); + ERRCHK(tl); + *e = vcc_expr_edit(BOOL, "!(\v1)", e2, NULL); + return; + } + + vcc_expr_add(tl, e, fmt); ERRCHK(tl); - afmt = lfmt; - while (1) { - top = tl->t; - if (tl->t->tok == '+') { - vcc_NextToken(tl); - Fb(tl, 1, " +\n"); - L(tl, vcc_Expr2(tl, &rfmt)); - ERRCHK(tl); - if (lfmt == INT && rfmt == INT) - afmt = INT; - else if (lfmt == DURATION && rfmt == DURATION) - afmt = DURATION; - else if (lfmt == TIME && rfmt == DURATION) - afmt = TIME; - else if (lfmt == DURATION && rfmt == TIME) - afmt = TIME; - else { - vsb_printf(tl->sb, - /* XXX print actual types */ - "Incompatible types in addition.\n" - "Legal combinations:\n" - "\tINT+INT,\n" - "\tDURATION+DURATION,\n" - "\tDURATION+TIME,\n" - "\tTIME+DURATION\n"); - vcc_ErrWhere(tl, top); - return; - } - } else if (tl->t->tok == '-') { - vcc_NextToken(tl); - Fb(tl, 1, " -\n"); - L(tl, vcc_Expr2(tl, &rfmt)); - if (lfmt == INT && rfmt == INT) - afmt = INT; - else if (lfmt == DURATION && rfmt == DURATION) - afmt = DURATION; - else if (lfmt == TIME && rfmt == DURATION) - afmt = TIME; - else if (lfmt == TIME && rfmt == TIME) - afmt = DURATION; - else { - vsb_printf(tl->sb, - /* XXX print actual types */ - "Incompatible types in subtraction.\n" - "Legal combinations:\n" - "\tINT-INT,\n" - "\tDURATION-DURATION,\n" - "\tTIME-DURATION,\n" - "\tTIME-TIME,\n"); - vcc_ErrWhere(tl, top); - return; - } - } else + + if ((*e)->fmt == BOOL) + return; + + tk = tl->t; + for (cp = vcc_cmps; cp->fmt != VOID; cp++) + if ((*e)->fmt == cp->fmt && tl->t->tok == cp->token) break; - lfmt = afmt; + if (cp->fmt != VOID) { + vcc_NextToken(tl); + vcc_expr_add(tl, &e2, (*e)->fmt); + if (e2->fmt != (*e)->fmt) { /* XXX */ + vsb_printf(tl->sb, "Comparison of different types\n"); + vsb_printf(tl->sb, "Left side has type %s\n", + vcc_Type((*e)->fmt)); + vsb_printf(tl->sb, "Right side has type %s\n", + vcc_Type(e2->fmt)); + vcc_ErrToken(tl, tk); + vcc_ErrWhere(tl, tk); + return; + } + *e = vcc_expr_edit(BOOL, cp->emit, *e, e2); + return; } - Fb(tl, 1, ")\n"); - if (fmt != afmt) { - vsb_printf(tl->sb, - /* XXX print actual types */ - "Add/Subtract results in wrong type.\n" - "\nExpression starting at:\n" ); - vcc_ErrWhere(tl, tfirst); - vsb_printf(tl->sb, "\nending before:\n\n"); - vcc_ErrWhere(tl, tl->t); + if ((*e)->fmt == STRING && + (tl->t->tok == '~' || tl->t->tok == T_NOMATCH)) { + not = tl->t->tok == '~' ? "" : "!"; + vcc_NextToken(tl); + ExpectErr(tl, CSTR); + re = vcc_regexp(tl); + ERRCHK(tl); + vcc_NextToken(tl); + bprintf(buf, "%sVRT_re_match(\v1, %s)", not, re); + *e = vcc_expr_edit(BOOL, buf, *e, NULL); return; } + if ((*e)->fmt == IP && + (tl->t->tok == '~' || tl->t->tok == T_NOMATCH)) { + not = tl->t->tok == '~' ? "" : "!"; + vcc_NextToken(tl); + ExpectErr(tl, ID); + vcc_AddRef(tl, tl->t, R_ACL); + bprintf(buf, "%smatch_acl_named_%.*s(sp, \v1)", not, PF(tl->t)); + vcc_NextToken(tl); + *e = vcc_expr_edit(BOOL, buf, *e, NULL); + return; + } + if ((*e)->fmt == IP && (tl->t->tok == T_EQ || tl->t->tok == T_NEQ)) { + vcc_Acl_Hack(tl, buf); + *e = vcc_expr_edit(BOOL, buf, *e, NULL); + return; + } + if ((*e)->fmt == BACKEND && + (tl->t->tok == T_EQ || tl->t->tok == T_NEQ)) { + vcc_NextToken(tl); + ExpectErr(tl, ID); + vcc_AddRef(tl, tl->t, R_BACKEND); + bprintf(buf, "(\v1 %.*s VGCDIR(_%.*s))", PF(tk), PF(tl->t)); + vcc_NextToken(tl); + *e = vcc_expr_edit(BOOL, buf, *e, NULL); + return; + } + if (fmt == BOOL) { + switch((*e)->fmt) { + case STRING: + *e = vcc_expr_edit(BOOL, "(\v1 != 0)", *e, NULL); + return; + default: + break; + } + } + if (fmt == VOID || fmt != (*e)->fmt) { + vsb_printf(tl->sb, "WANT: %s has %s next %.*s (%s)\n", + vcc_Type(fmt), vcc_Type((*e)->fmt), + PF(tl->t), vsb_data((*e)->vsb)); + tl->err = 1; + } } -void -vcc_Expr(struct vcc *tl, enum var_type fmt) +/*-------------------------------------------------------------------- + * SYNTAX: + * ExprCand: + * ExprAdd { '&&' ExprAdd } * + */ + +static void +vcc_expr_cand(struct vcc *tl, struct expr **e, enum var_type fmt) { + struct expr *e2; - switch (fmt) { - case DURATION: - case INT: - case TIME: - /* These types support addition and subtraction */ - Fb(tl, 1, "(\n"); - L(tl, vcc_Expr1(tl, fmt)); + *e = NULL; + vcc_expr_cmp(tl, e, fmt); + ERRCHK(tl); + if ((*e)->fmt != BOOL) + return; + while (tl->t->tok == T_CAND) { + vcc_NextToken(tl); + vcc_expr_cmp(tl, &e2, fmt); ERRCHK(tl); - Fb(tl, 1, ")\n"); + *e = vcc_expr_edit(BOOL, "(\v1&&\v2)", *e, e2); + } +} + +/*-------------------------------------------------------------------- + * SYNTAX: + * Expr0: + * ExprCand { '||' ExprCand } * + */ + +static void +vcc_expr0(struct vcc *tl, struct expr **e, enum var_type fmt) +{ + struct expr *e2; + + *e = NULL; + vcc_expr_cand(tl, e, fmt); + ERRCHK(tl); + if ((*e)->fmt != BOOL) return; - default: - WRONG("type not implemented yet"); + while (tl->t->tok == T_COR) { + vcc_NextToken(tl); + vcc_expr_cand(tl, &e2, fmt); + ERRCHK(tl); + *e = vcc_expr_edit(BOOL, "(\v1||\v2)", *e, e2); } } +/*-------------------------------------------------------------------- + * This function parses and emits the C-code to evaluate an expression + * + * We know up front what kind of type we want the expression to be, + * and this function is the backstop if that doesn't succeed. + */ + +void +vcc_Expr(struct vcc *tl, enum var_type fmt) +{ + struct expr *e; + struct token *t1; + + assert(fmt != VOID); + + t1 = tl->t; + vcc_expr0(tl, &e, fmt); + if (!tl->err && fmt != e->fmt) { + vsb_printf(tl->sb, "Expression has type %s, expected %s\n", + vcc_Type(e->fmt), vcc_Type(fmt)); + tl->err = 1; + } + if (!tl->err) { + vcc_expr_fmt(tl->fb, tl->indent, e); + vsb_putc(tl->fb, '\n'); + } else { + vsb_printf(tl->sb, "Expression starts here:\n"); + vcc_ErrWhere(tl, t1); + if (t1 != tl->t) { + vsb_printf(tl->sb, "Expression ends here:\n"); + vcc_ErrWhere(tl, tl->t); + } + } + vcc_delete_expr(e); +} Modified: trunk/varnish-cache/lib/libvcl/vcc_parse.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_parse.c 2010-08-25 09:47:48 UTC (rev 5129) +++ trunk/varnish-cache/lib/libvcl/vcc_parse.c 2010-08-25 19:01:35 UTC (rev 5130) @@ -44,7 +44,6 @@ /*--------------------------------------------------------------------*/ static void vcc_Compound(struct vcc *tl); -static void vcc_Conditional(struct vcc *tl); /*--------------------------------------------------------------------*/ @@ -59,253 +58,8 @@ tl->t->cnt = tl->cnt; \ } while (0) -/*--------------------------------------------------------------------*/ - -static void -vcc_inval_test(struct vcc *tl, const char *type, const char *valid) -{ - vsb_printf(tl->sb, "Invalid test "); - vcc_ErrToken(tl, tl->t); - vsb_printf(tl->sb, " on expression of type %s.\n", type); - vsb_printf(tl->sb, " only %s are legal\n", valid); - vcc_ErrWhere(tl, tl->t); -} - -/*--------------------------------------------------------------------*/ - -static void -vcc_Cond_String(struct vcc *tl, const char *a1) -{ - char *p; - - switch (tl->t->tok) { - case '~': - case T_NOMATCH: - Fb(tl, 1, "%sVRT_re_match(", - tl->t->tok == '~' ? "" : "!"); - vcc_NextToken(tl); - ExpectErr(tl, CSTR); - p = vcc_regexp(tl); - ERRCHK(tl); - vcc_NextToken(tl); - Fb(tl, 1, "%s, %s)\n", a1, p); - break; - case T_LEQ: - case T_GEQ: - case '>': - case '<': - vcc_inval_test(tl, "STRING", "'==', '!=', '~' and '!~'"); - break; - case T_EQ: - case T_NEQ: - Fb(tl, 1, "%sVRT_strcmp(%s, ", - tl->t->tok == T_EQ ? "!" : "", a1); - vcc_NextToken(tl); - if (!vcc_StringVal(tl)) { - vcc_ExpectedStringval(tl); - break; - } - Fb(tl, 0, ")\n"); - break; - default: - Fb(tl, 1, "%s != (void*)0\n", a1); - break; - } -} - -static void -vcc_Cond_Bool(const struct vcc *tl, const char *a1) -{ - - Fb(tl, 1, "%s\n", a1); -} - -static void -vcc_Cond_Backend(struct vcc *tl, const char *a1) -{ - - Fb(tl, 1, "%s\n", a1); - if (tl->t->tok == T_EQ || tl->t->tok == T_NEQ) { - Fb(tl, 1, " %.*s\n", PF(tl->t)); - } else { - vcc_inval_test(tl, "BACKEND", "'==' and '!='"); - return; - } - vcc_NextToken(tl); - vcc_ExpectCid(tl); - ERRCHK(tl); - vcc_AddRef(tl, tl->t, R_BACKEND); - Fb(tl, 1, "VGCDIR(_%.*s)\n", PF(tl->t)); - vcc_NextToken(tl); -} - -static void -vcc_Cond_Num(struct vcc *tl, enum var_type fmt, const char *fmtn, - const char *a1) -{ - - Fb(tl, 1, "%s ", a1); - switch (tl->t->tok) { - case T_EQ: - case T_NEQ: - case T_LEQ: - case T_GEQ: - case '>': - case '<': - Fb(tl, 0, "%.*s\n", PF(tl->t)); - vcc_NextToken(tl); - vcc_Expr(tl, fmt); - break; - default: - vcc_inval_test(tl, fmtn, - "'==', '!=', '<', '>', '<=' and '>='"); - break; - } -} - /*-------------------------------------------------------------------- * SYNTAX: - * Cond_3: - * Typed_Expr Relation Compat_Typed_Expr - * Typed_Expr: - * VarName - * FuncCall - * Relation: - * Subset('==', '!=', '<', '<=', '>', '>=', '~', '!~') - * Compat_Typed_Expr - * Typed_Expr - * Typed_Const - * - * Since we cannot tell if "10 s" is a TIME or DURATION type, or for that - * matter if "127.0.0.1" is a STRING or IP type, we demand that the expression - * before the relational operator provides us with a type which can be used to - * guide parsing of other expression. - */ - -static void -vcc_Cond_3(struct vcc *tl) -{ - const struct var *vp; - const struct symbol *sym; - const char *left; - - sym = VCC_FindSymbol(tl, tl->t); - if (sym == NULL) { - vsb_printf(tl->sb, - "Syntax error in condition.\n" - "Expected '(', '!' or variable name.\n" - "Found "); - vcc_ErrToken(tl, tl->t); - vsb_printf(tl->sb, "\n"); - vcc_ErrWhere(tl, tl->t); - return; - } - vcc_AddUses(tl, tl->t, sym->r_methods, "Not available"); - AN(sym->var); - vp = vcc_FindVar(tl, tl->t, 0, "cannot be read"); - ERRCHK(tl); - assert(vp != NULL); - left = vp->rname; - vcc_NextToken(tl); - - switch (vp->fmt) { - case BACKEND: L(tl, vcc_Cond_Backend(tl, left)); break; - case BOOL: L(tl, vcc_Cond_Bool(tl, left)); break; - case DURATION: L(tl, vcc_Cond_Num(tl, DURATION, "DURATION", left)); break; - case INT: L(tl, vcc_Cond_Num(tl, INT, "INT", left)); break; - case IP: L(tl, vcc_Cond_Ip(tl, left)); break; - case STRING: L(tl, vcc_Cond_String(tl, left)); break; - case TIME: L(tl, vcc_Cond_Num(tl, TIME, "TIME", left)); break; - default: - vsb_printf(tl->sb, - "Variable '%s'" - " has no conditions that can be checked\n", - vp->name); - vcc_ErrWhere(tl, tl->t); - return; - } -} - -/*-------------------------------------------------------------------- - * SYNTAX: - * Cond_2: - * '!'? '(' Conditional ')' - * '!'? Cond_3 - */ - -static void -vcc_Cond_2(struct vcc *tl) -{ - - C(tl, ","); - if (tl->t->tok == '!') { - Fb(tl, 1, "!"); - vcc_NextToken(tl); - } - if (tl->t->tok == '(') { - vcc_Conditional(tl); - return; - } - if (tl->t->tok == ID) { - Fb(tl, 1, "(\n"); - vcc_Cond_3(tl); - Fb(tl, 1, ")\n"); - return; - } - vsb_printf(tl->sb, - "Syntax error in condition.\n" - "Expected '(', '!' or variable name.\n" - "Found "); - vcc_ErrToken(tl, tl->t); - vsb_printf(tl->sb, "\n"); - vcc_ErrWhere(tl, tl->t); - return; -} - -/*-------------------------------------------------------------------- - * SYNTAX: - * Cond_1: - * Cond_2 { '&&' Cond_2 }* - */ - -static void -vcc_Cond_1(struct vcc *tl) -{ - - Fb(tl, 1, "(\n"); - L(tl, vcc_Cond_2(tl)); - while (tl->t->tok == T_CAND) { - vcc_NextToken(tl); - Fb(tl, 1, ") && (\n"); - L(tl, vcc_Cond_2(tl)); - ERRCHK(tl); - } - Fb(tl, 1, ")\n"); -} - -/*-------------------------------------------------------------------- - * SYNTAX: - * Cond_0: - * Cond_1 { '||' Cond_1 }* - */ - -static void -vcc_Cond_0(struct vcc *tl) -{ - - Fb(tl, 1, "(\n"); - L(tl, vcc_Cond_1(tl)); - while (tl->t->tok == T_COR) { - vcc_NextToken(tl); - Fb(tl, 1, ") || (\n"); - L(tl, vcc_Cond_1(tl)); - ERRCHK(tl); - } - Fb(tl, 1, ")\n"); -} - -/*-------------------------------------------------------------------- - * SYNTAX: * Conditional: * '(' Cond_0 ')' */ @@ -316,7 +70,7 @@ SkipToken(tl, '('); Fb(tl, 1, "(\n"); - L(tl, vcc_Cond_0(tl)); + vcc_Expr(tl, BOOL); ERRCHK(tl); Fb(tl, 1, ")\n"); SkipToken(tl, ')'); @@ -348,7 +102,7 @@ case T_ELSE: vcc_NextToken(tl); if (tl->t->tok != T_IF) { - Fb(tl, 1, "else \n"); + Fb(tl, 1, "else\n"); L(tl, vcc_Compound(tl)); ERRCHK(tl); return; Modified: trunk/varnish-cache/lib/libvcl/vcc_token.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_token.c 2010-08-25 09:47:48 UTC (rev 5129) +++ trunk/varnish-cache/lib/libvcl/vcc_token.c 2010-08-25 19:01:35 UTC (rev 5130) @@ -105,6 +105,7 @@ vcc_icoord(vsb, t, NULL); } +/* XXX: should take first+last token */ void vcc_ErrWhere(struct vcc *tl, const struct token *t) { From phk at varnish-cache.org Thu Aug 26 08:48:49 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 26 Aug 2010 10:48:49 +0200 Subject: r5131 - in trunk/varnish-cache: bin/varnishd bin/varnishtest/tests include lib/libvcl Message-ID: Author: phk Date: 2010-08-26 10:48:49 +0200 (Thu, 26 Aug 2010) New Revision: 5131 Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c trunk/varnish-cache/bin/varnishd/default.vcl trunk/varnish-cache/bin/varnishtest/tests/r00251.vtc trunk/varnish-cache/bin/varnishtest/tests/r00693.vtc trunk/varnish-cache/bin/varnishtest/tests/v00001.vtc trunk/varnish-cache/bin/varnishtest/tests/v00018.vtc trunk/varnish-cache/include/vrt.h trunk/varnish-cache/lib/libvcl/vcc_action.c trunk/varnish-cache/lib/libvcl/vcc_expr.c trunk/varnish-cache/lib/libvcl/vcc_string.c trunk/varnish-cache/lib/libvcl/vcc_types.h Log: The new string concatenation syntax is STRING + STRING + STRING [...] For now we assemble the string in the worker threads workspace. I will reintroduce the optimization to pass it to VRT uncollected where appropriate, once I get the new expression system pushed through. Add a hacked up "regsub" function call for now, once functions gets introduced it should be treated like any other function. Add "true", "false" BOOL constants, REAL constants Move the "set" statement over to the new expressions. Fix testcases to use new string concat syntax where applicable. "set req.url = 1;" was impossible before, now it works. Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-25 19:01:35 UTC (rev 5130) +++ trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-26 08:48:49 UTC (rev 5131) @@ -143,13 +143,13 @@ /*lint -e{818} ap,hp could be const */ static char * -vrt_assemble_string(struct http *hp, const char *h, const char *p, va_list ap) +vrt_build_string(struct ws *ws, const char *h, const char *p, va_list ap) { char *b, *e; unsigned u, x; - u = WS_Reserve(hp->ws, 0); - e = b = hp->ws->f; + u = WS_Reserve(ws, 0); + e = b = ws->f; e += u; if (h != NULL) { x = strlen(h); @@ -173,16 +173,45 @@ *b = '\0'; b++; if (b > e) { - WS_Release(hp->ws, 0); + WS_Release(ws, 0); return (NULL); } else { e = b; - b = hp->ws->f; - WS_Release(hp->ws, e - b); + b = ws->f; + WS_Release(ws, e - b); return (b); } } +/*-------------------------------------------------------------------- + * XXX: Optimize the single element case ? + */ + +/*lint -e{818} ap,hp could be const */ +static char * +vrt_assemble_string(struct http *hp, const char *h, const char *p, va_list ap) +{ + + return (vrt_build_string(hp->ws, h, p, ap)); +} + +/*-------------------------------------------------------------------- + * Build a string on the worker threads workspace + */ + +const char * +VRT_String(const struct sess *sp, const char *p, ...) +{ + va_list ap; + char *b; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + va_start(ap, p); + b = vrt_build_string(sp->wrk->ws, NULL, p, ap); + va_end(ap); + return (b); +} + /*--------------------------------------------------------------------*/ void @@ -892,12 +921,14 @@ } const char * -VRT_backend_string(struct sess *sp) +VRT_backend_string(struct sess *sp, const struct director *d) { CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - if (sp->director == NULL) + if (d == NULL) + d = sp->director; + if (d == NULL) return (NULL); - return (sp->director->vcl_name); + return (d->vcl_name); } /*--------------------------------------------------------------------*/ Modified: trunk/varnish-cache/bin/varnishd/default.vcl =================================================================== --- trunk/varnish-cache/bin/varnishd/default.vcl 2010-08-25 19:01:35 UTC (rev 5130) +++ trunk/varnish-cache/bin/varnishd/default.vcl 2010-08-26 08:48:49 UTC (rev 5131) @@ -43,7 +43,7 @@ if (req.restarts == 0) { if (req.http.x-forwarded-for) { set req.http.X-Forwarded-For = - req.http.X-Forwarded-For ", " client.ip; + req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } Modified: trunk/varnish-cache/bin/varnishtest/tests/r00251.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/r00251.vtc 2010-08-25 19:01:35 UTC (rev 5130) +++ trunk/varnish-cache/bin/varnishtest/tests/r00251.vtc 2010-08-26 08:48:49 UTC (rev 5131) @@ -13,8 +13,8 @@ varnish v1 -vcl+backend { sub vcl_fetch { set beresp.http.Snafu1 = - "zoom" - regsub(beresp.http.Foomble, "ar", "\0\0") + "zoom" + + regsub(beresp.http.Foomble, "ar", "\0\0") + "box"; } } -start Modified: trunk/varnish-cache/bin/varnishtest/tests/r00693.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/r00693.vtc 2010-08-25 19:01:35 UTC (rev 5130) +++ trunk/varnish-cache/bin/varnishtest/tests/r00693.vtc 2010-08-26 08:48:49 UTC (rev 5131) @@ -24,37 +24,37 @@ sub vcl_recv { set req.http.foo = - req.http.bar - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" "0123456789abcdef" - "0123456789abcdef" + req.http.bar + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "0123456789abcdef" + + "0123456789abcdef" + "01234567"; set req.http.baz = "BAZ"; return (pass); Modified: trunk/varnish-cache/bin/varnishtest/tests/v00001.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/v00001.vtc 2010-08-25 19:01:35 UTC (rev 5130) +++ trunk/varnish-cache/bin/varnishtest/tests/v00001.vtc 2010-08-26 08:48:49 UTC (rev 5131) @@ -13,8 +13,8 @@ varnish v1 -vcl+backend { sub vcl_recv { set req.http.foobar = - req.url - req.request + req.url + + req.request + req.proto; set req.url = "/"; set req.proto = "HTTP/1.2"; @@ -22,7 +22,7 @@ } sub vcl_miss { set bereq.http.foobar = - bereq.url + bereq.url + bereq.proto; set bereq.url = "/"; set bereq.proto = "HTTP/1.2"; @@ -30,7 +30,7 @@ } sub vcl_fetch { set beresp.http.foobar = - beresp.proto beresp.response beresp.status; + beresp.proto + beresp.response + beresp.status; set beresp.proto = "HTTP/1.2"; set beresp.response = "For circular files"; set beresp.status = 903; @@ -42,9 +42,7 @@ # XXX should be moved to it's own test set resp.http.x-served-by-hostname = server.hostname; set resp.http.x-served-by-identity = server.identity; - set resp.http.foobar = - resp.proto - resp.status; + set resp.http.foobar = resp.proto + resp.status; } } -start Modified: trunk/varnish-cache/bin/varnishtest/tests/v00018.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/v00018.vtc 2010-08-25 19:01:35 UTC (rev 5130) +++ trunk/varnish-cache/bin/varnishtest/tests/v00018.vtc 2010-08-26 08:48:49 UTC (rev 5131) @@ -56,7 +56,7 @@ sub vcl_hash { hash_data(req.hash); } } -varnish v1 -badvcl { +varnish v1 -vcl { backend b { .host = "127.0.0.1"; } sub vcl_recv { set req.url = 1; } } Modified: trunk/varnish-cache/include/vrt.h =================================================================== --- trunk/varnish-cache/include/vrt.h 2010-08-25 19:01:35 UTC (rev 5130) +++ trunk/varnish-cache/include/vrt.h 2010-08-26 08:48:49 UTC (rev 5131) @@ -189,10 +189,12 @@ char *VRT_int_string(const struct sess *sp, int); char *VRT_double_string(const struct sess *sp, double); char *VRT_time_string(const struct sess *sp, double); -const char *VRT_backend_string(struct sess *sp); +const char *VRT_backend_string(struct sess *sp, const struct director *d); #define VRT_done(sp, hand) \ do { \ VRT_handling(sp, hand); \ return (1); \ } while (0) + +const char *VRT_String(const struct sess *sp, const char *p, ...); Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_action.c 2010-08-25 19:01:35 UTC (rev 5130) +++ trunk/varnish-cache/lib/libvcl/vcc_action.c 2010-08-26 08:48:49 UTC (rev 5131) @@ -101,126 +101,64 @@ /*--------------------------------------------------------------------*/ -#if 1 -static void -illegal_assignment(const struct vcc *tl, const char *type) -{ +static const struct arith { + enum var_type type; + unsigned oper; + enum var_type want; +} arith[] = { + { INT, T_INCR, INT }, + { INT, T_DECR, INT }, + { INT, T_MUL, INT }, + { INT, T_DIV, INT }, + { INT, '=', INT }, + { INT, 0, INT }, + { TIME, T_INCR, DURATION }, + { TIME, T_DECR, DURATION }, + { TIME, T_MUL, REAL }, + { TIME, T_DIV, REAL }, + { TIME, '=', TIME }, + { TIME, 0, TIME }, + { DURATION, T_INCR, DURATION }, + { DURATION, T_DECR, DURATION }, + { DURATION, T_MUL, REAL }, + { DURATION, T_DIV, REAL }, + { DURATION, '=', DURATION }, + { DURATION, 0, DURATION }, + { VOID, '=', VOID } +}; - vsb_printf(tl->sb, "Invalid assignment operator "); - vcc_ErrToken(tl, tl->t); - vsb_printf(tl->sb, - " only '=' is legal for %s\n", type); -} -#endif - static void parse_set(struct vcc *tl) { const struct var *vp; - struct token *vt; - struct token *at; + const struct arith *ap; + enum var_type fmt; vcc_NextToken(tl); ExpectErr(tl, ID); - vt = tl->t; vp = vcc_FindVar(tl, tl->t, 1, "cannot be set"); ERRCHK(tl); assert(vp != NULL); Fb(tl, 1, "%s", vp->lname); -#if 0 vcc_NextToken(tl); - SkipToken(tl, '='); - vcc_Expr(tl, vp->fmt); -#else - vcc_NextToken(tl); - switch (vp->fmt) { - case INT: - case TIME: - case DURATION: - if (tl->t->tok != '=') + fmt = vp->fmt; + for (ap = arith; ap->type != VOID; ap++) { + if (ap->type != fmt) + continue; + if (ap->oper != tl->t->tok) + continue; + if (ap->oper != '=') Fb(tl, 0, "%s %c ", vp->rname, *tl->t->b); - at = tl->t; vcc_NextToken(tl); - switch (at->tok) { - case T_MUL: - case T_DIV: - Fb(tl, 0, "%g", vcc_DoubleVal(tl)); - break; - case T_INCR: - case T_DECR: - case '=': - vcc_VarVal(tl, vp, vt); - ERRCHK(tl); - break; - default: - vsb_printf(tl->sb, "Invalid assignment operator.\n"); - vcc_ErrWhere(tl, at); - return; - } - Fb(tl, 0, ");\n"); + fmt = ap->want; break; - case BACKEND: - if (tl->t->tok != '=') { - illegal_assignment(tl, "backend"); - return; - } - vcc_NextToken(tl); - vcc_ExpectCid(tl); - ERRCHK(tl); - vcc_AddRef(tl, tl->t, R_BACKEND); - Fb(tl, 0, "VGCDIR(_%.*s)", PF(tl->t)); - vcc_NextToken(tl); - Fb(tl, 0, ");\n"); - break; - case STRING: - if (tl->t->tok != '=') { - illegal_assignment(tl, "strings"); - return; - } - vcc_NextToken(tl); - if (!vcc_StringVal(tl)) { - ERRCHK(tl); - vcc_ExpectedStringval(tl); - return; - } - do - Fb(tl, 0, ", "); - while (vcc_StringVal(tl)); - if (tl->t->tok != ';') { - ERRCHK(tl); - vsb_printf(tl->sb, - "Expected variable, string or semicolon\n"); - vcc_ErrWhere(tl, tl->t); - return; - } - Fb(tl, 0, "vrt_magic_string_end);\n"); - break; - case BOOL: - if (tl->t->tok != '=') { - illegal_assignment(tl, "boolean"); - return; - } - vcc_NextToken(tl); - ExpectErr(tl, ID); - if (vcc_IdIs(tl->t, "true")) { - Fb(tl, 0, " 1);\n", vp->lname); - } else if (vcc_IdIs(tl->t, "false")) { - Fb(tl, 0, " 0);\n", vp->lname); - } else { - vsb_printf(tl->sb, - "Expected true or false\n"); - vcc_ErrWhere(tl, tl->t); - return; - } - vcc_NextToken(tl); - break; - default: - vsb_printf(tl->sb, - "Assignments not possible for type of '%s'\n", vp->name); - vcc_ErrWhere(tl, tl->t); - return; } -#endif + if (ap->type == VOID) + SkipToken(tl, ap->oper); + vcc_Expr(tl, fmt); + if (vp->fmt == STRING) + Fb(tl, 1, ", vrt_magic_string_end"); + Fb(tl, 0, ");\n"); } /*--------------------------------------------------------------------*/ Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-25 19:01:35 UTC (rev 5130) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-26 08:48:49 UTC (rev 5131) @@ -273,8 +273,10 @@ vsb_cat(e->vsb, "\v+\n"); if (*p == '1') vsb_cat(e->vsb, vsb_data(e1->vsb)); - else + else { + AN(e2); vsb_cat(e->vsb, vsb_data(e2->vsb)); + } if (q != NULL) vsb_cat(e->vsb, "\v-\n"); break; @@ -327,6 +329,35 @@ } /*-------------------------------------------------------------------- + */ + +static void +hack_regsub(struct vcc *tl, struct expr **e, int all) +{ + struct expr *e2; + char *p; + char buf[128]; + + SkipToken(tl, ID); + SkipToken(tl, '('); + + vcc_expr0(tl, &e2, STRING); + + SkipToken(tl, ','); + ExpectErr(tl, CSTR); + p = vcc_regexp(tl); + vcc_NextToken(tl); + + bprintf(buf, "VRT_regsub(sp, %d,\n\v1,\n%s\n", all, p); + *e = vcc_expr_edit(STRING, buf, e2, *e); + + SkipToken(tl, ','); + vcc_expr0(tl, &e2, STRING); + *e = vcc_expr_edit(STRING, "\v1, \v2)", *e, e2); + SkipToken(tl, ')'); +} + +/*-------------------------------------------------------------------- * SYNTAX: * Expr4: * '(' Expr0 ')' @@ -354,10 +385,42 @@ e1 = vcc_new_expr(); switch(tl->t->tok) { case ID: + if (vcc_IdIs(tl->t, "regsub")) { + vcc_delete_expr(e1); + hack_regsub(tl, e, 0); + return; + } + if (vcc_IdIs(tl->t, "regsuball")) { + vcc_delete_expr(e1); + hack_regsub(tl, e, 1); + return; + } + if (vcc_IdIs(tl->t, "true")) { + vcc_NextToken(tl); + vsb_printf(e1->vsb, "(1==1)"); + e1->fmt = BOOL; + break; + } + if (vcc_IdIs(tl->t, "false")) { + vcc_NextToken(tl); + vsb_printf(e1->vsb, "(0!=0)"); + e1->fmt = BOOL; + break; + } + if (fmt == BACKEND) { + vcc_ExpectCid(tl); + vcc_AddRef(tl, tl->t, R_BACKEND); + vsb_printf(e1->vsb, "VGCDIR(_%.*s)", PF(tl->t)); + e1->fmt = BACKEND; + vcc_NextToken(tl); + break; + } sym = VCC_FindSymbol(tl, tl->t); if (sym == NULL) { vsb_printf(tl->sb, "Symbol not found: "); vcc_ErrToken(tl, tl->t); + vsb_printf(tl->sb, " (expected type %s):\n", + vcc_Type(fmt)); vcc_ErrWhere(tl, tl->t); return; } @@ -385,6 +448,9 @@ ERRCHK(tl); vsb_printf(e1->vsb, "%g", d); e1->fmt = DURATION; + } else if (fmt == REAL) { + vsb_printf(e1->vsb, "%g", vcc_DoubleVal(tl)); + e1->fmt = REAL; } else { vsb_printf(e1->vsb, "%.*s", PF(tl->t)); vcc_NextToken(tl); @@ -422,7 +488,7 @@ switch(f2) { case INT: f2 = INT; break; - case DURATION: f2 = INT; break; /* XXX: should be Double */ + case DURATION: f2 = REAL; break; default: return; } @@ -454,6 +520,19 @@ ERRCHK(tl); f2 = (*e)->fmt; + if (f2 == STRING && tl->t->tok == '+') { + *e = vcc_expr_edit(STRING, "\v+VRT_String(sp,\n\v1", *e, NULL); + while (tl->t->tok == '+') { + vcc_NextToken(tl); + vcc_expr0(tl, &e2, STRING); + assert(e2->fmt == STRING); + *e = vcc_expr_edit(STRING, "\v1, \v2", *e, e2); + } + *e = vcc_expr_edit(STRING, "\v1, vrt_magic_string_end)", + *e, NULL); + return; + } + switch(f2) { case INT: break; case TIME: f2 = DURATION; break; @@ -517,6 +596,7 @@ char buf[256]; char *re; const char *not; + const char *p; struct token *tk; *e = NULL; @@ -602,6 +682,20 @@ break; } } + if (fmt == STRING) { + p = NULL; + switch((*e)->fmt) { + case BACKEND: p = "VRT_backend_string(sp, \v1)"; break; + case INT: p = "VRT_int_string(sp, \v1)"; break; + case IP: p = "VRT_IP_string(sp, \v1)"; break; + case TIME: p = "VRT_time_string(sp, \v1)"; break; + default: break; + } + if (p != NULL) { + *e = vcc_expr_edit(STRING, p, *e, NULL); + return; + } + } if (fmt == VOID || fmt != (*e)->fmt) { vsb_printf(tl->sb, "WANT: %s has %s next %.*s (%s)\n", vcc_Type(fmt), vcc_Type((*e)->fmt), Modified: trunk/varnish-cache/lib/libvcl/vcc_string.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_string.c 2010-08-25 19:01:35 UTC (rev 5130) +++ trunk/varnish-cache/lib/libvcl/vcc_string.c 2010-08-26 08:48:49 UTC (rev 5131) @@ -185,7 +185,7 @@ Fb(tl, 0, "VRT_double_string(sp, %s)", vp->rname); break; case BACKEND: - Fb(tl, 0, "VRT_backend_string(sp)"); + Fb(tl, 0, "VRT_backend_string(sp, NULL)"); break; default: vsb_printf(tl->sb, "String representation of '%s'" Modified: trunk/varnish-cache/lib/libvcl/vcc_types.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_types.h 2010-08-25 19:01:35 UTC (rev 5130) +++ trunk/varnish-cache/lib/libvcl/vcc_types.h 2010-08-26 08:48:49 UTC (rev 5131) @@ -37,3 +37,4 @@ VCC_TYPE(STRING) VCC_TYPE(IP) VCC_TYPE(HEADER) +VCC_TYPE(REAL) From phk at varnish-cache.org Thu Aug 26 09:30:18 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 26 Aug 2010 11:30:18 +0200 Subject: r5132 - trunk/varnish-cache/lib/libvcl Message-ID: Author: phk Date: 2010-08-26 11:30:18 +0200 (Thu, 26 Aug 2010) New Revision: 5132 Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c trunk/varnish-cache/lib/libvcl/vcc_expr.c Log: Get don't subtract when addition is required. Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_action.c 2010-08-26 08:48:49 UTC (rev 5131) +++ trunk/varnish-cache/lib/libvcl/vcc_action.c 2010-08-26 09:30:18 UTC (rev 5132) @@ -65,37 +65,25 @@ static void parse_error(struct vcc *tl) { - const struct var *vp; + int paran = 0; vcc_NextToken(tl); - if (tl->t->tok == ID) { - vp = vcc_FindVar(tl, tl->t, 0, "cannot be read"); - ERRCHK(tl); - assert(vp != NULL); - if (vp->fmt == INT) { - Fb(tl, 1, "VRT_error(sp, %s", vp->rname); - vcc_NextToken(tl); - } else { - Fb(tl, 1, "VRT_error(sp, 0"); - } - } else if (tl->t->tok == CNUM) { - Fb(tl, 1, "VRT_error(sp, %u", vcc_UintVal(tl)); - } else - Fb(tl, 1, "VRT_error(sp, 0"); - if (tl->t->tok == CSTR) { - Fb(tl, 0, ", %.*s", PF(tl->t)); + if (tl->t->tok == '(') { + paran = 1; vcc_NextToken(tl); - } else if (tl->t->tok == ID) { - Fb(tl, 0, ", "); - if (!vcc_StringVal(tl)) { - ERRCHK(tl); - vcc_ExpectedStringval(tl); - return; - } + } + Fb(tl, 1, "VRT_error(sp,\n"); + vcc_Expr(tl, INT); + if (tl->t->tok == ',') { + Fb(tl, 1, ",\n"); + vcc_NextToken(tl); + vcc_Expr(tl, STRING); } else { - Fb(tl, 0, ", (const char *)0"); + Fb(tl, 1, ", 0\n"); } - Fb(tl, 0, ");\n"); + if (paran) + SkipToken(tl, ')'); + Fb(tl, 1, ");\n"); Fb(tl, 1, "VRT_done(sp, VCL_RET_ERROR);\n"); } Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-26 08:48:49 UTC (rev 5131) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-26 09:30:18 UTC (rev 5132) @@ -480,6 +480,7 @@ { struct expr *e2; enum var_type f2, f3; + struct token *tk; *e = NULL; vcc_expr4(tl, e, fmt); @@ -493,10 +494,11 @@ return; } while (tl->t->tok == '+' || tl->t->tok == '-') { + tk = tl->t; vcc_NextToken(tl); vcc_expr4(tl, &e2, f2); ERRCHK(tl); - if (tl->t->tok == '+') + if (tk->tok == '+') *e = vcc_expr_edit(f3, "(\v1+\v2)", *e, e2); else *e = vcc_expr_edit(f3, "(\v1-\v2)", *e, e2); From phk at varnish-cache.org Thu Aug 26 10:40:27 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 26 Aug 2010 12:40:27 +0200 Subject: r5133 - in trunk/varnish-cache: bin/varnishd bin/varnishtest/tests lib/libvcl Message-ID: Author: phk Date: 2010-08-26 12:40:26 +0200 (Thu, 26 Aug 2010) New Revision: 5133 Modified: trunk/varnish-cache/bin/varnishd/default.vcl trunk/varnish-cache/bin/varnishd/flint.lnt trunk/varnish-cache/bin/varnishtest/tests/c00022.vtc trunk/varnish-cache/bin/varnishtest/tests/v00010.vtc trunk/varnish-cache/bin/varnishtest/tests/v00018.vtc trunk/varnish-cache/lib/libvcl/vcc_action.c trunk/varnish-cache/lib/libvcl/vcc_expr.c trunk/varnish-cache/lib/libvcl/vcc_string.c Log: Push the new expressions into all other actions. Get precedence of the implicit cast to STRING right. Modified: trunk/varnish-cache/bin/varnishd/default.vcl =================================================================== --- trunk/varnish-cache/bin/varnishd/default.vcl 2010-08-26 09:30:18 UTC (rev 5132) +++ trunk/varnish-cache/bin/varnishd/default.vcl 2010-08-26 10:40:26 UTC (rev 5133) @@ -126,13 +126,13 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - "} obj.status " " obj.response {" + "} + obj.status + " " + obj.response + {" -

Error "} obj.status " " obj.response {"

-

"} obj.response {"

+

Error "} + obj.status + " " + obj.response + {"

+

"} + obj.response + {"

Guru Meditation:

-

XID: "} req.xid {"

+

XID: "} + req.xid + {"


Varnish cache server

Modified: trunk/varnish-cache/bin/varnishd/flint.lnt =================================================================== --- trunk/varnish-cache/bin/varnishd/flint.lnt 2010-08-26 09:30:18 UTC (rev 5132) +++ trunk/varnish-cache/bin/varnishd/flint.lnt 2010-08-26 10:40:26 UTC (rev 5133) @@ -73,6 +73,7 @@ -efile(451, "http_headers.h") // No include guard -efile(451, "stat_field.h") // No include guard -efile(451, "acct_fields.h") // No include guard +-efile(451, "vcc_types.h") // No include guard -efile(451, "config.h") // No include guard ////////////// // -e458 // unprotected access Modified: trunk/varnish-cache/bin/varnishtest/tests/c00022.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/c00022.vtc 2010-08-26 09:30:18 UTC (rev 5132) +++ trunk/varnish-cache/bin/varnishtest/tests/c00022.vtc 2010-08-26 10:40:26 UTC (rev 5133) @@ -27,7 +27,7 @@ error 410; } if (req.request == "PURGESTR") { - purge ("" req.http.purge); + purge ("" + req.http.purge); error 410; } } Modified: trunk/varnish-cache/bin/varnishtest/tests/v00010.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/v00010.vtc 2010-08-26 09:30:18 UTC (rev 5132) +++ trunk/varnish-cache/bin/varnishtest/tests/v00010.vtc 2010-08-26 10:40:26 UTC (rev 5133) @@ -17,7 +17,7 @@ sub vcl_fetch { if (beresp.http.panic) { - panic "Had Panic header: " beresp.http.panic; + panic "Had Panic header: " + beresp.http.panic; } } } -start Modified: trunk/varnish-cache/bin/varnishtest/tests/v00018.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/v00018.vtc 2010-08-26 09:30:18 UTC (rev 5132) +++ trunk/varnish-cache/bin/varnishtest/tests/v00018.vtc 2010-08-26 10:40:26 UTC (rev 5133) @@ -15,8 +15,8 @@ varnish v1 -vcl { backend b { .host = "127.0.0.1"; } - sub vcl_miss { error req.url ; } - sub vcl_pass { error "the butter please" ; } + sub vcl_miss { error 100 req.url ; } + sub vcl_pass { error 100 "the butter please" ; } sub vcl_fetch { error beresp.status req.url; } } Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_action.c 2010-08-26 09:30:18 UTC (rev 5132) +++ trunk/varnish-cache/lib/libvcl/vcc_action.c 2010-08-26 10:40:26 UTC (rev 5133) @@ -65,24 +65,27 @@ static void parse_error(struct vcc *tl) { - int paran = 0; vcc_NextToken(tl); + Fb(tl, 1, "VRT_error(sp,\n"); if (tl->t->tok == '(') { - paran = 1; vcc_NextToken(tl); - } - Fb(tl, 1, "VRT_error(sp,\n"); - vcc_Expr(tl, INT); - if (tl->t->tok == ',') { - Fb(tl, 1, ",\n"); - vcc_NextToken(tl); - vcc_Expr(tl, STRING); + vcc_Expr(tl, INT); + if (tl->t->tok == ',') { + Fb(tl, 1, ",\n"); + vcc_NextToken(tl); + vcc_Expr(tl, STRING); + } else + Fb(tl, 1, ", 0\n"); + SkipToken(tl, ')'); } else { - Fb(tl, 1, ", 0\n"); + vcc_Expr(tl, INT); + if (tl->t->tok != ';') { + Fb(tl, 1, ",\n"); + vcc_Expr(tl, STRING); + } else + Fb(tl, 1, ", 0\n"); } - if (paran) - SkipToken(tl, ')'); Fb(tl, 1, ");\n"); Fb(tl, 1, "VRT_done(sp, VCL_RET_ERROR);\n"); } @@ -235,10 +238,8 @@ } vcc_NextToken(tl); Fb(tl, 1, " "); - if (!vcc_StringVal(tl)) { - vcc_ExpectedStringval(tl); - return; - } + vcc_Expr(tl, STRING); + ERRCHK(tl); Fb(tl, 0, ",\n"); if (tl->t->tok == ')') break; @@ -250,13 +251,9 @@ tl->indent -= INDENT; } else { Fb(tl, 1, "VRT_ban_string(sp, "); - if (!vcc_StringVal(tl)) { - vcc_ExpectedStringval(tl); - return; - } - do - Fb(tl, 0, ", "); - while (vcc_StringVal(tl)); + vcc_Expr(tl, STRING); + ERRCHK(tl); + Fb(tl, 0, ", "); Fb(tl, 0, "vrt_magic_string_end);\n"); } @@ -275,10 +272,8 @@ vcc_NextToken(tl); Fb(tl, 1, "VRT_ban(sp, \"req.url\", \"~\", "); - if (!vcc_StringVal(tl)) { - vcc_ExpectedStringval(tl); - return; - } + vcc_Expr(tl, STRING); + ERRCHK(tl); ExpectErr(tl, ')'); vcc_NextToken(tl); Fb(tl, 0, ", 0);\n"); @@ -314,14 +309,9 @@ SkipToken(tl, '('); Fb(tl, 1, "VRT_hashdata(sp, "); - if (!vcc_StringVal(tl)) { - vcc_ExpectedStringval(tl); - return; - } - do - Fb(tl, 0, ", "); - while (vcc_StringVal(tl)); - Fb(tl, 0, " vrt_magic_string_end);\n"); + vcc_Expr(tl, STRING); + ERRCHK(tl); + Fb(tl, 0, ", vrt_magic_string_end);\n"); SkipToken(tl, ')'); } @@ -333,14 +323,9 @@ vcc_NextToken(tl); Fb(tl, 1, "VRT_panic(sp, "); - if (!vcc_StringVal(tl)) { - vcc_ExpectedStringval(tl); - return; - } - do - Fb(tl, 0, ", "); - while (vcc_StringVal(tl)); - Fb(tl, 0, " vrt_magic_string_end);\n"); + vcc_Expr(tl, STRING); + ERRCHK(tl); + Fb(tl, 0, ", vrt_magic_string_end);\n"); } /*--------------------------------------------------------------------*/ @@ -393,14 +378,9 @@ vcc_NextToken(tl); Fb(tl, 1, "VRT_synth_page(sp, 0, "); - if (!vcc_StringVal(tl)) { - vcc_ExpectedStringval(tl); - return; - } - do - Fb(tl, 0, ", "); - while (vcc_StringVal(tl)); - Fb(tl, 0, " vrt_magic_string_end);\n"); + vcc_Expr(tl, STRING); + ERRCHK(tl); + Fb(tl, 0, ", vrt_magic_string_end);\n"); } /*--------------------------------------------------------------------*/ @@ -410,14 +390,9 @@ vcc_NextToken(tl); Fb(tl, 1, "VRT_log(sp, "); - if (!vcc_StringVal(tl)) { - vcc_ExpectedStringval(tl); - return; - } - do - Fb(tl, 0, ", "); - while (vcc_StringVal(tl)); - Fb(tl, 0, " vrt_magic_string_end);\n"); + vcc_Expr(tl, STRING); + ERRCHK(tl); + Fb(tl, 0, ", vrt_magic_string_end);\n"); } /*--------------------------------------------------------------------*/ Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-26 09:30:18 UTC (rev 5132) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-26 10:40:26 UTC (rev 5133) @@ -359,14 +359,14 @@ /*-------------------------------------------------------------------- * SYNTAX: - * Expr4: + * Expr5: * '(' Expr0 ')' * CNUM * CSTR */ static void -vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt) +vcc_expr5(struct vcc *tl, struct expr **e, enum var_type fmt) { struct expr *e1, *e2; const struct symbol *sym; @@ -470,6 +470,34 @@ } /*-------------------------------------------------------------------- + */ +static void +vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt) +{ + const char *p; + + *e = NULL; + vcc_expr5(tl, e, fmt); + ERRCHK(tl); + if (fmt == STRING) { + p = NULL; + switch((*e)->fmt) { + case BACKEND: p = "VRT_backend_string(sp, \v1)"; break; + case INT: p = "VRT_int_string(sp, \v1)"; break; + case IP: p = "VRT_IP_string(sp, \v1)"; break; + case TIME: p = "VRT_time_string(sp, \v1)"; break; + case DURATION: p = "VRT_double_string(sp, \v1)"; break; + /* XXX: should have "s" suffix ? */ + default: break; + } + if (p != NULL) { + *e = vcc_expr_edit(STRING, p, *e, NULL); + return; + } + } +} + +/*-------------------------------------------------------------------- * SYNTAX: * Expr3: * Expr4 { {'*'|'/'} Expr4 } * @@ -497,6 +525,7 @@ tk = tl->t; vcc_NextToken(tl); vcc_expr4(tl, &e2, f2); + assert(e2->fmt == f2); ERRCHK(tl); if (tk->tok == '+') *e = vcc_expr_edit(f3, "(\v1+\v2)", *e, e2); @@ -526,9 +555,9 @@ *e = vcc_expr_edit(STRING, "\v+VRT_String(sp,\n\v1", *e, NULL); while (tl->t->tok == '+') { vcc_NextToken(tl); - vcc_expr0(tl, &e2, STRING); + vcc_expr_mul(tl, &e2, STRING); assert(e2->fmt == STRING); - *e = vcc_expr_edit(STRING, "\v1, \v2", *e, e2); + *e = vcc_expr_edit(STRING, "\v1,\n\v2", *e, e2); } *e = vcc_expr_edit(STRING, "\v1, vrt_magic_string_end)", *e, NULL); @@ -546,6 +575,7 @@ while (tl->t->tok == '+' || tl->t->tok == '-') { vcc_NextToken(tl); vcc_expr_mul(tl, &e2, f2); + assert(e2->fmt == f2); ERRCHK(tl); if (tl->t->tok == '+') *e = vcc_expr_edit(f2, "(\v1+\v2)", *e, e2); @@ -598,7 +628,6 @@ char buf[256]; char *re; const char *not; - const char *p; struct token *tk; *e = NULL; @@ -684,20 +713,6 @@ break; } } - if (fmt == STRING) { - p = NULL; - switch((*e)->fmt) { - case BACKEND: p = "VRT_backend_string(sp, \v1)"; break; - case INT: p = "VRT_int_string(sp, \v1)"; break; - case IP: p = "VRT_IP_string(sp, \v1)"; break; - case TIME: p = "VRT_time_string(sp, \v1)"; break; - default: break; - } - if (p != NULL) { - *e = vcc_expr_edit(STRING, p, *e, NULL); - return; - } - } if (fmt == VOID || fmt != (*e)->fmt) { vsb_printf(tl->sb, "WANT: %s has %s next %.*s (%s)\n", vcc_Type(fmt), vcc_Type((*e)->fmt), Modified: trunk/varnish-cache/lib/libvcl/vcc_string.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_string.c 2010-08-26 09:30:18 UTC (rev 5132) +++ trunk/varnish-cache/lib/libvcl/vcc_string.c 2010-08-26 10:40:26 UTC (rev 5133) @@ -77,134 +77,3 @@ Ff(tl, 0, "\tVRT_re_fini(%s);\n", buf); return (p); } - -/*--------------------------------------------------------------------*/ - -static int -vcc_regsub(struct vcc *tl, int all) -{ - char *p; - - vcc_NextToken(tl); - - Fb(tl, 0, "VRT_regsub(sp, %d, ", all); - - Expect(tl, '('); - if (tl->err) - return (0); - vcc_NextToken(tl); - - if (!vcc_StringVal(tl)) { - vcc_ExpectedStringval(tl); - return (0); - } - - Expect(tl, ','); - if (tl->err) - return (0); - vcc_NextToken(tl); - - Expect(tl, CSTR); - if (tl->err) - return (0); - p = vcc_regexp(tl); - vcc_NextToken(tl); - Fb(tl, 0, ", %s, ", p); - - Expect(tl, ','); - if (tl->err) - return (0); - vcc_NextToken(tl); - - if (!vcc_StringVal(tl)) { - vcc_ExpectedStringval(tl); - return (0); - } - - Expect(tl, ')'); - if (tl->err) - return (0); - vcc_NextToken(tl); - Fb(tl, 0, ")"); - - return (1); -} - -/*-------------------------------------------------------------------- - * Parse a string value and emit something that results in a usable - * "const char *". - * There are three possible outcomes: - * tl->err != 0 means something bad happened and a message is emitted. - * return (0) means "could not use this token" - * return (1) means "done" - */ - -int -vcc_StringVal(struct vcc *tl) -{ - const struct var *vp; - - if (tl->t->tok == CSTR) { - EncToken(tl->fb, tl->t); - vcc_NextToken(tl); - return (1); - } - if (tl->t->tok == ID && vcc_IdIs(tl->t, "regsub")) - return (vcc_regsub(tl, 0)); - if (tl->t->tok == ID && vcc_IdIs(tl->t, "regsuball")) - return (vcc_regsub(tl, 1)); - if (tl->t->tok == ID && vcc_IdIs(tl->t, "now")) { - Fb(tl, 0, "VRT_time_string(sp, VRT_r_now(sp))"); - vcc_NextToken(tl); - return 1; - } - if (tl->t->tok == ID) { - vp = vcc_FindVar(tl, tl->t, 0, "cannot be read"); - if (tl->err) - return (0); - assert(vp != NULL); - switch (vp->fmt) { - case STRING: - Fb(tl, 0, "%s", vp->rname); - break; - case IP: - Fb(tl, 0, "VRT_IP_string(sp, %s)", vp->rname); - break; - case INT: - Fb(tl, 0, "VRT_int_string(sp, %s)", vp->rname); - break; -#if 0 - case FLOAT: - Fb(tl, 0, "VRT_double_string(sp, %s)", vp->rname); - break; -#endif - case TIME: - Fb(tl, 0, "VRT_time_string(sp, %s)", vp->rname); - break; - case DURATION: - Fb(tl, 0, "VRT_double_string(sp, %s)", vp->rname); - break; - case BACKEND: - Fb(tl, 0, "VRT_backend_string(sp, NULL)"); - break; - default: - vsb_printf(tl->sb, "String representation of '%s'" - " not implemented yet.\n", vp->name); - vcc_ErrWhere(tl, tl->t); - return (0); - } - vcc_NextToken(tl); - return (1); - } - return (0); -} - -void -vcc_ExpectedStringval(struct vcc *tl) -{ - - if (!tl->err) { - vsb_printf(tl->sb, "Expected string variable or constant\n"); - vcc_ErrWhere(tl, tl->t); - } -} From phk at varnish-cache.org Thu Aug 26 13:12:55 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 26 Aug 2010 15:12:55 +0200 Subject: r5134 - in trunk/varnish-cache: bin/varnishd include lib/libvcl Message-ID: Author: phk Date: 2010-08-26 15:12:55 +0200 (Thu, 26 Aug 2010) New Revision: 5134 Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c trunk/varnish-cache/include/vrt.h trunk/varnish-cache/lib/libvcl/vcc_action.c trunk/varnish-cache/lib/libvcl/vcc_expr.c trunk/varnish-cache/lib/libvcl/vcc_parse.c trunk/varnish-cache/lib/libvcl/vcc_types.h Log: Introduce STRING_LIST type so we don't needlessly assemble strings on the thrad workspace. Fix multiplication. Cleanup indentation in C-source output Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-26 10:40:26 UTC (rev 5133) +++ trunk/varnish-cache/bin/varnishd/cache_vrt.c 2010-08-26 13:12:55 UTC (rev 5134) @@ -1007,15 +1007,10 @@ /*--------------------------------------------------------------------*/ void -VRT_log(struct sess *sp, const char *str, ...) +VRT_log(struct sess *sp, const char *str) { - va_list ap; - char *b; - va_start(ap, str); - b = vrt_assemble_string(sp->http, NULL, str, ap); - va_end(ap); - WSP(sp, SLT_VCL_Log, "%s", b); + WSP(sp, SLT_VCL_Log, "%s", str); } /*--------------------------------------------------------------------*/ @@ -1056,22 +1051,16 @@ /*--------------------------------------------------------------------*/ void -VRT_ban_string(struct sess *sp, const char *str, ...) +VRT_ban_string(struct sess *sp, const char *str) { - char *p, *a1, *a2, *a3; + char *a1, *a2, *a3; char **av; - va_list ap; struct ban *b; int good; int i; - va_start(ap, str); - p = vrt_assemble_string(sp->http, NULL, str, ap); - if (p == NULL) - /* XXX: report error how ? */ - return; - - av = ParseArgv(p, 0); + (void)sp; + av = ParseArgv(str, 0); if (av[0] != NULL) { /* XXX: report error how ? */ FreeArgv(av); Modified: trunk/varnish-cache/include/vrt.h =================================================================== --- trunk/varnish-cache/include/vrt.h 2010-08-26 10:40:26 UTC (rev 5133) +++ trunk/varnish-cache/include/vrt.h 2010-08-26 13:12:55 UTC (rev 5134) @@ -153,9 +153,9 @@ void VRT_panic(struct sess *sp, const char *, ...); void VRT_ban(struct sess *sp, char *, ...); -void VRT_ban_string(struct sess *sp, const char *, ...); +void VRT_ban_string(struct sess *sp, const char *); void VRT_purge(struct sess *sp, double ttl, double grace); -void VRT_log(struct sess *, const char *msg, ...); +void VRT_log(struct sess *, const char *msg); void VRT_count(const struct sess *, unsigned); int VRT_rewrite(const char *, const char *); Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_action.c 2010-08-26 10:40:26 UTC (rev 5133) +++ trunk/varnish-cache/lib/libvcl/vcc_action.c 2010-08-26 13:12:55 UTC (rev 5134) @@ -146,10 +146,12 @@ } if (ap->type == VOID) SkipToken(tl, ap->oper); - vcc_Expr(tl, fmt); - if (vp->fmt == STRING) - Fb(tl, 1, ", vrt_magic_string_end"); - Fb(tl, 0, ");\n"); + if (fmt == STRING) { + vcc_Expr(tl, STRING_LIST); + } else { + vcc_Expr(tl, fmt); + } + Fb(tl, 1, ");\n"); } /*--------------------------------------------------------------------*/ @@ -253,8 +255,7 @@ Fb(tl, 1, "VRT_ban_string(sp, "); vcc_Expr(tl, STRING); ERRCHK(tl); - Fb(tl, 0, ", "); - Fb(tl, 0, "vrt_magic_string_end);\n"); + Fb(tl, 0, ");\n"); } ExpectErr(tl, ')'); @@ -309,9 +310,9 @@ SkipToken(tl, '('); Fb(tl, 1, "VRT_hashdata(sp, "); - vcc_Expr(tl, STRING); + vcc_Expr(tl, STRING_LIST); ERRCHK(tl); - Fb(tl, 0, ", vrt_magic_string_end);\n"); + Fb(tl, 0, ");\n"); SkipToken(tl, ')'); } @@ -378,9 +379,9 @@ vcc_NextToken(tl); Fb(tl, 1, "VRT_synth_page(sp, 0, "); - vcc_Expr(tl, STRING); + vcc_Expr(tl, STRING_LIST); ERRCHK(tl); - Fb(tl, 0, ", vrt_magic_string_end);\n"); + Fb(tl, 0, ");\n"); } /*--------------------------------------------------------------------*/ @@ -392,7 +393,7 @@ Fb(tl, 1, "VRT_log(sp, "); vcc_Expr(tl, STRING); ERRCHK(tl); - Fb(tl, 0, ", vrt_magic_string_end);\n"); + Fb(tl, 0, ");\n"); } /*--------------------------------------------------------------------*/ Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-26 10:40:26 UTC (rev 5133) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-26 13:12:55 UTC (rev 5134) @@ -247,38 +247,68 @@ * XXX: check line lengths in edit, should pass indent in for this */ +static void +vcc_show(const char *p) +{ + + fprintf(stderr, "<"); + for (; *p; p++) { + if (*p == '\n') + fprintf(stderr, "\\n"); + else if (*p == '\v') + fprintf(stderr, "\\v"); + else + fprintf(stderr, "%c", *p); + } + fprintf(stderr, ">\n"); +} + + static struct expr * vcc_expr_edit(enum var_type fmt, const char *p, struct expr *e1, struct expr *e2) { struct expr *e; - char *q; + int nl = 1; - q = strchr(vsb_data(e1->vsb), '\n'); - if (q == NULL && e2 != NULL) - q = strchr(vsb_data(e2->vsb), '\n'); + fprintf(stderr, "EDIT:"); + vcc_show(p); + if (e1 != NULL) { + fprintf(stderr, "E1:"); + vcc_show(vsb_data(e1->vsb)); + } + if (e2 != NULL) { + fprintf(stderr, "E2:"); + vcc_show(vsb_data(e2->vsb)); + } + e = vcc_new_expr(); while (*p != '\0') { + if (*p == '\n') { + if (!nl) + vsb_putc(e->vsb, *p); + nl = 1; + p++; + continue; + } + nl = 0; if (*p != '\v') { vsb_putc(e->vsb, *p); p++; continue; } + assert(*p == '\v'); p++; switch(*p) { case '+': vsb_cat(e->vsb, "\v+"); break; case '-': vsb_cat(e->vsb, "\v-"); break; case '1': case '2': - if (q != NULL) - vsb_cat(e->vsb, "\v+\n"); if (*p == '1') vsb_cat(e->vsb, vsb_data(e1->vsb)); else { AN(e2); vsb_cat(e->vsb, vsb_data(e2->vsb)); } - if (q != NULL) - vsb_cat(e->vsb, "\v-\n"); break; default: assert(__LINE__ == 0); @@ -290,6 +320,8 @@ vcc_delete_expr(e1); vcc_delete_expr(e2); e->fmt = fmt; + fprintf(stderr, "RESULT:"); + vcc_show(vsb_data(e->vsb)); return (e); } @@ -479,7 +511,7 @@ *e = NULL; vcc_expr5(tl, e, fmt); ERRCHK(tl); - if (fmt == STRING) { + if (fmt == STRING || fmt == STRING_LIST) { p = NULL; switch((*e)->fmt) { case BACKEND: p = "VRT_backend_string(sp, \v1)"; break; @@ -491,7 +523,7 @@ default: break; } if (p != NULL) { - *e = vcc_expr_edit(STRING, p, *e, NULL); + *e = vcc_expr_edit(fmt, p, *e, NULL); return; } } @@ -521,16 +553,16 @@ default: return; } - while (tl->t->tok == '+' || tl->t->tok == '-') { + while (tl->t->tok == '*' || tl->t->tok == '/') { tk = tl->t; vcc_NextToken(tl); vcc_expr4(tl, &e2, f2); assert(e2->fmt == f2); ERRCHK(tl); - if (tk->tok == '+') - *e = vcc_expr_edit(f3, "(\v1+\v2)", *e, e2); + if (tk->tok == '*') + *e = vcc_expr_edit(f3, "(\v1*\v2)", *e, e2); else - *e = vcc_expr_edit(f3, "(\v1-\v2)", *e, e2); + *e = vcc_expr_edit(f3, "(\v1/\v2)", *e, e2); } } @@ -551,6 +583,17 @@ ERRCHK(tl); f2 = (*e)->fmt; + if (fmt == STRING_LIST && f2 == STRING) { + if (f2 == STRING) + (*e)->fmt = STRING_LIST; + while (tl->t->tok == '+') { + vcc_NextToken(tl); + vcc_expr_mul(tl, &e2, STRING); + *e = vcc_expr_edit(STRING_LIST, "\v1,\n\v2", *e, e2); + } + return; + } + if (f2 == STRING && tl->t->tok == '+') { *e = vcc_expr_edit(STRING, "\v+VRT_String(sp,\n\v1", *e, NULL); while (tl->t->tok == '+') { @@ -735,14 +778,16 @@ *e = NULL; vcc_expr_cmp(tl, e, fmt); ERRCHK(tl); - if ((*e)->fmt != BOOL) + if ((*e)->fmt != BOOL || tl->t->tok != T_CAND) return; + *e = vcc_expr_edit(BOOL, "(\v+\n\v1", *e, NULL); while (tl->t->tok == T_CAND) { vcc_NextToken(tl); vcc_expr_cmp(tl, &e2, fmt); ERRCHK(tl); - *e = vcc_expr_edit(BOOL, "(\v1&&\v2)", *e, e2); + *e = vcc_expr_edit(BOOL, "\v1\v-\n&&\v+\n\v2", *e, e2); } + *e = vcc_expr_edit(BOOL, "\v1\v-\n)", *e, NULL); } /*-------------------------------------------------------------------- @@ -792,6 +837,10 @@ tl->err = 1; } if (!tl->err) { + if (e->fmt == STRING_LIST) { + e = vcc_expr_edit(STRING_LIST, + "\v+\n\v1,\nvrt_magic_string_end\v-", e, NULL); + } vcc_expr_fmt(tl->fb, tl->indent, e); vsb_putc(tl->fb, '\n'); } else { Modified: trunk/varnish-cache/lib/libvcl/vcc_parse.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_parse.c 2010-08-26 10:40:26 UTC (rev 5133) +++ trunk/varnish-cache/lib/libvcl/vcc_parse.c 2010-08-26 13:12:55 UTC (rev 5134) @@ -69,8 +69,8 @@ { SkipToken(tl, '('); - Fb(tl, 1, "(\n"); - vcc_Expr(tl, BOOL); + Fb(tl, 0, "(\n"); + L(tl, vcc_Expr(tl, BOOL)); ERRCHK(tl); Fb(tl, 1, ")\n"); SkipToken(tl, ')'); @@ -92,8 +92,8 @@ { SkipToken(tl, T_IF); - Fb(tl, 1, "if \n"); - L(tl, vcc_Conditional(tl)); + Fb(tl, 1, "if "); + vcc_Conditional(tl); ERRCHK(tl); L(tl, vcc_Compound(tl)); ERRCHK(tl); @@ -110,9 +110,9 @@ /* FALLTHROUGH */ case T_ELSEIF: case T_ELSIF: - Fb(tl, 1, "else if \n"); + Fb(tl, 1, "else if "); vcc_NextToken(tl); - L(tl, vcc_Conditional(tl)); + vcc_Conditional(tl); ERRCHK(tl); L(tl, vcc_Compound(tl)); ERRCHK(tl); Modified: trunk/varnish-cache/lib/libvcl/vcc_types.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_types.h 2010-08-26 10:40:26 UTC (rev 5133) +++ trunk/varnish-cache/lib/libvcl/vcc_types.h 2010-08-26 13:12:55 UTC (rev 5134) @@ -35,6 +35,7 @@ VCC_TYPE(TIME) VCC_TYPE(DURATION) VCC_TYPE(STRING) +VCC_TYPE(STRING_LIST) VCC_TYPE(IP) VCC_TYPE(HEADER) VCC_TYPE(REAL) From ingvar at varnish-cache.org Thu Aug 26 13:49:35 2010 From: ingvar at varnish-cache.org (ingvar at varnish-cache.org) Date: Thu, 26 Aug 2010 15:49:35 +0200 Subject: r5135 - trunk/varnish-cache/redhat Message-ID: Author: ingvar Date: 2010-08-26 15:49:35 +0200 (Thu, 26 Aug 2010) New Revision: 5135 Modified: trunk/varnish-cache/redhat/README.redhat trunk/varnish-cache/redhat/varnish.spec Log: fixed a typo and changed to a more recent version number example in README.redhat Modified: trunk/varnish-cache/redhat/README.redhat =================================================================== --- trunk/varnish-cache/redhat/README.redhat 2010-08-26 13:12:55 UTC (rev 5134) +++ trunk/varnish-cache/redhat/README.redhat 2010-08-26 13:49:35 UTC (rev 5135) @@ -79,5 +79,5 @@ This builds a source rpm. Then you can, for example on a RHEL4 system, do something like this: -rpmbuild --define "dist el4" --rebuild /path/to/varnish-1.1.2.src.rpm +rpmbuild --define "dist .el4" --rebuild /path/to/varnish-2.1.4-0.svn20100826r5134.src.rpm Modified: trunk/varnish-cache/redhat/varnish.spec =================================================================== --- trunk/varnish-cache/redhat/varnish.spec 2010-08-26 13:12:55 UTC (rev 5134) +++ trunk/varnish-cache/redhat/varnish.spec 2010-08-26 13:49:35 UTC (rev 5135) @@ -1,7 +1,7 @@ Summary: High-performance HTTP accelerator Name: varnish Version: 2.1.4 -Release: 0.svn20100824r5117%{?dist} +Release: 0.svn20100826r5134%{?dist} License: BSD Group: System Environment/Daemons URL: http://www.varnish-cache.org/ From phk at varnish-cache.org Thu Aug 26 15:44:18 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 26 Aug 2010 17:44:18 +0200 Subject: r5136 - trunk/varnish-cache/lib/libvcl Message-ID: Author: phk Date: 2010-08-26 17:44:18 +0200 (Thu, 26 Aug 2010) New Revision: 5136 Modified: trunk/varnish-cache/lib/libvcl/vcc_backend.c trunk/varnish-cache/lib/libvcl/vcc_expr.c trunk/varnish-cache/lib/libvcl/vcc_types.h Log: More whitespace and string-casting magic. Remove some debugging that snug into last commit Modified: trunk/varnish-cache/lib/libvcl/vcc_backend.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-08-26 13:49:35 UTC (rev 5135) +++ trunk/varnish-cache/lib/libvcl/vcc_backend.c 2010-08-26 15:44:18 UTC (rev 5136) @@ -439,7 +439,6 @@ vcc_ParseHostDef(struct vcc *tl, int serial, const char *vgcname) { struct token *t_field; - struct token *t_first; struct token *t_host = NULL; struct token *t_port = NULL; struct token *t_hosthdr = NULL; @@ -462,7 +461,6 @@ "?max_connections", "?saintmode_threshold", NULL); - t_first = tl->t; SkipToken(tl, '{'); Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-26 13:49:35 UTC (rev 5135) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-26 15:44:18 UTC (rev 5136) @@ -225,7 +225,6 @@ vsb_delete(e->vsb); FREE_OBJ(e); } - /*-------------------------------------------------------------------- * We want to get the indentation right in the emitted C code so we have * to represent it symbolically until we are ready to render. @@ -247,40 +246,12 @@ * XXX: check line lengths in edit, should pass indent in for this */ -static void -vcc_show(const char *p) -{ - - fprintf(stderr, "<"); - for (; *p; p++) { - if (*p == '\n') - fprintf(stderr, "\\n"); - else if (*p == '\v') - fprintf(stderr, "\\v"); - else - fprintf(stderr, "%c", *p); - } - fprintf(stderr, ">\n"); -} - - static struct expr * vcc_expr_edit(enum var_type fmt, const char *p, struct expr *e1, struct expr *e2) { struct expr *e; int nl = 1; - fprintf(stderr, "EDIT:"); - vcc_show(p); - if (e1 != NULL) { - fprintf(stderr, "E1:"); - vcc_show(vsb_data(e1->vsb)); - } - if (e2 != NULL) { - fprintf(stderr, "E2:"); - vcc_show(vsb_data(e2->vsb)); - } - e = vcc_new_expr(); while (*p != '\0') { if (*p == '\n') { @@ -320,8 +291,6 @@ vcc_delete_expr(e1); vcc_delete_expr(e2); e->fmt = fmt; - fprintf(stderr, "RESULT:"); - vcc_show(vsb_data(e->vsb)); return (e); } @@ -337,17 +306,20 @@ for (i = 0; i < ind; i++) vsb_cat(d, " "); - for (p = vsb_data(e1->vsb); *p != '\0'; p++) { + p = vsb_data(e1->vsb); + while (*p != '\0') { if (*p == '\n') { vsb_putc(d, '\n'); if (p[1] != '\0') { for (i = 0; i < ind; i++) vsb_cat(d, " "); } + p++; continue; } if (*p != '\v') { vsb_putc(d, *p); + p++; continue; } p++; @@ -357,6 +329,7 @@ default: assert(__LINE__ == 0); } + p++; } } @@ -364,6 +337,30 @@ */ static void +vcc_expr_tostring(struct expr **e, enum var_type fmt) +{ + const char *p; + + AN(fmt == STRING || fmt == STRING_LIST); + + p = NULL; + switch((*e)->fmt) { + case BACKEND: p = "VRT_backend_string(sp, \v1)"; break; + case INT: p = "VRT_int_string(sp, \v1)"; break; + case IP: p = "VRT_IP_string(sp, \v1)"; break; + case TIME: p = "VRT_time_string(sp, \v1)"; break; + case DURATION: p = "VRT_double_string(sp, \v1)"; break; + /* XXX: should have "s" suffix ? */ + default: break; + } + if (p != NULL) + *e = vcc_expr_edit(fmt, p, *e, NULL); +} + +/*-------------------------------------------------------------------- + */ + +static void hack_regsub(struct vcc *tl, struct expr **e, int all) { struct expr *e2; @@ -391,14 +388,14 @@ /*-------------------------------------------------------------------- * SYNTAX: - * Expr5: + * Expr4: * '(' Expr0 ')' * CNUM * CSTR */ static void -vcc_expr5(struct vcc *tl, struct expr **e, enum var_type fmt) +vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt) { struct expr *e1, *e2; const struct symbol *sym; @@ -502,34 +499,6 @@ } /*-------------------------------------------------------------------- - */ -static void -vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt) -{ - const char *p; - - *e = NULL; - vcc_expr5(tl, e, fmt); - ERRCHK(tl); - if (fmt == STRING || fmt == STRING_LIST) { - p = NULL; - switch((*e)->fmt) { - case BACKEND: p = "VRT_backend_string(sp, \v1)"; break; - case INT: p = "VRT_int_string(sp, \v1)"; break; - case IP: p = "VRT_IP_string(sp, \v1)"; break; - case TIME: p = "VRT_time_string(sp, \v1)"; break; - case DURATION: p = "VRT_double_string(sp, \v1)"; break; - /* XXX: should have "s" suffix ? */ - default: break; - } - if (p != NULL) { - *e = vcc_expr_edit(fmt, p, *e, NULL); - return; - } - } -} - -/*-------------------------------------------------------------------- * SYNTAX: * Expr3: * Expr4 { {'*'|'/'} Expr4 } * @@ -577,6 +546,7 @@ { struct expr *e2; enum var_type f2; + struct token *tk; *e = NULL; vcc_expr_mul(tl, e, fmt); @@ -584,11 +554,13 @@ f2 = (*e)->fmt; if (fmt == STRING_LIST && f2 == STRING) { - if (f2 == STRING) - (*e)->fmt = STRING_LIST; + (*e)->fmt = STRING_LIST; while (tl->t->tok == '+') { vcc_NextToken(tl); vcc_expr_mul(tl, &e2, STRING); + if (e2->fmt != STRING && e2->fmt != STRING_LIST) + vcc_expr_tostring(&e2, f2); + assert(e2->fmt == STRING || e2->fmt == STRING_LIST); *e = vcc_expr_edit(STRING_LIST, "\v1,\n\v2", *e, e2); } return; @@ -599,7 +571,10 @@ while (tl->t->tok == '+') { vcc_NextToken(tl); vcc_expr_mul(tl, &e2, STRING); - assert(e2->fmt == STRING); + if (e2->fmt != STRING && e2->fmt != STRING_LIST) + vcc_expr_tostring(&e2, f2); + + assert(e2->fmt == STRING || e2->fmt == STRING_LIST); *e = vcc_expr_edit(STRING, "\v1,\n\v2", *e, e2); } *e = vcc_expr_edit(STRING, "\v1, vrt_magic_string_end)", @@ -616,11 +591,12 @@ } while (tl->t->tok == '+' || tl->t->tok == '-') { + tk = tl->t; vcc_NextToken(tl); vcc_expr_mul(tl, &e2, f2); assert(e2->fmt == f2); ERRCHK(tl); - if (tl->t->tok == '+') + if (tk->tok == '+') *e = vcc_expr_edit(f2, "(\v1+\v2)", *e, e2); else *e = vcc_expr_edit(f2, "(\v1-\v2)", *e, e2); @@ -756,12 +732,6 @@ break; } } - if (fmt == VOID || fmt != (*e)->fmt) { - vsb_printf(tl->sb, "WANT: %s has %s next %.*s (%s)\n", - vcc_Type(fmt), vcc_Type((*e)->fmt), - PF(tl->t), vsb_data((*e)->vsb)); - tl->err = 1; - } } /*-------------------------------------------------------------------- @@ -804,14 +774,18 @@ *e = NULL; vcc_expr_cand(tl, e, fmt); ERRCHK(tl); - if ((*e)->fmt != BOOL) + if (fmt == STRING || fmt == STRING_LIST) + vcc_expr_tostring(e, fmt); + if ((*e)->fmt != BOOL || tl->t->tok != T_COR) return; + *e = vcc_expr_edit(BOOL, "(\v+\n\v1", *e, NULL); while (tl->t->tok == T_COR) { vcc_NextToken(tl); vcc_expr_cand(tl, &e2, fmt); ERRCHK(tl); - *e = vcc_expr_edit(BOOL, "(\v1||\v2)", *e, e2); + *e = vcc_expr_edit(BOOL, "\v1\v-\n||\v+\n\v2", *e, e2); } + *e = vcc_expr_edit(BOOL, "\v1\v-\n)", *e, NULL); } /*-------------------------------------------------------------------- Modified: trunk/varnish-cache/lib/libvcl/vcc_types.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_types.h 2010-08-26 13:49:35 UTC (rev 5135) +++ trunk/varnish-cache/lib/libvcl/vcc_types.h 2010-08-26 15:44:18 UTC (rev 5136) @@ -28,6 +28,7 @@ * $Id$ */ +/*lint -save -e525 -e539 */ VCC_TYPE(VOID) VCC_TYPE(BACKEND) VCC_TYPE(BOOL) @@ -39,3 +40,4 @@ VCC_TYPE(IP) VCC_TYPE(HEADER) VCC_TYPE(REAL) +/*lint -restore */ From phk at varnish-cache.org Thu Aug 26 16:02:05 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 26 Aug 2010 18:02:05 +0200 Subject: r5137 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: Author: phk Date: 2010-08-26 18:02:04 +0200 (Thu, 26 Aug 2010) New Revision: 5137 Modified: trunk/varnish-cache/bin/varnishtest/tests/v00020.vtc Log: More coverage of vcc_expr.c Modified: trunk/varnish-cache/bin/varnishtest/tests/v00020.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/v00020.vtc 2010-08-26 15:44:18 UTC (rev 5136) +++ trunk/varnish-cache/bin/varnishtest/tests/v00020.vtc 2010-08-26 16:02:04 UTC (rev 5137) @@ -1,6 +1,6 @@ # $Id$ -test "VCL compiler coverage test: vcc_parse.c" +test "VCL compiler coverage test: vcc_parse.c & vcc_expr.c" varnish v1 -vcl { backend b { .host = "127.0.0.1"; } @@ -17,6 +17,11 @@ backend b { .host = "127.0.0.1"; } sub vcl_fetch { set beresp.ttl = 1w; + set beresp.ttl *= 1.5; + set beresp.ttl = 1.5 s * 2.5; + set beresp.ttl = 1.5 s / 2.5; + set beresp.ttl = 1.5h + 1.5s; + set beresp.ttl = 1.5h - 1.5s; } } From phk at varnish-cache.org Thu Aug 26 16:05:36 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Thu, 26 Aug 2010 18:05:36 +0200 Subject: r5138 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: Author: phk Date: 2010-08-26 18:05:35 +0200 (Thu, 26 Aug 2010) New Revision: 5138 Modified: trunk/varnish-cache/bin/varnishtest/tests/v00020.vtc Log: Coverage for the last bit of vcc_expr.c Modified: trunk/varnish-cache/bin/varnishtest/tests/v00020.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/v00020.vtc 2010-08-26 16:02:04 UTC (rev 5137) +++ trunk/varnish-cache/bin/varnishtest/tests/v00020.vtc 2010-08-26 16:05:35 UTC (rev 5138) @@ -25,3 +25,11 @@ } } +varnish v1 -badvcl { + sub vcl_recv { + if (req.restarts == req.url) { + set req.http.foo = "foo" + 3; + } + + } +} From phk at varnish-cache.org Fri Aug 27 07:20:57 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Fri, 27 Aug 2010 09:20:57 +0200 Subject: r5139 - in trunk/varnish-cache: bin/varnishd include lib/libvcl Message-ID: Author: phk Date: 2010-08-27 09:20:57 +0200 (Fri, 27 Aug 2010) New Revision: 5139 Modified: trunk/varnish-cache/bin/varnishd/cache_panic.c trunk/varnish-cache/bin/varnishd/flint.lnt trunk/varnish-cache/bin/varnishd/steps.h trunk/varnish-cache/include/http_headers.h trunk/varnish-cache/lib/libvcl/generate.py trunk/varnish-cache/lib/libvcl/vcc_xref.c Log: Move Flexelint supressing comments into the parameter include files that cause them, rather than try to patch all the indentation warnings they cause wherever they are used. Modified: trunk/varnish-cache/bin/varnishd/cache_panic.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_panic.c 2010-08-26 16:05:35 UTC (rev 5138) +++ trunk/varnish-cache/bin/varnishd/cache_panic.c 2010-08-27 07:20:57 UTC (rev 5139) @@ -219,11 +219,9 @@ sp->addr ? sp->addr : "?.?.?.?", sp->port ? sp->port : "?"); switch (sp->step) { -/*lint -save -e525 */ #define STEP(l, u) case STP_##u: stp = "STP_" #u; break; #include "steps.h" #undef STEP -/*lint -restore */ default: stp = NULL; } hand = VCC_Return_Name(sp->handling); Modified: trunk/varnish-cache/bin/varnishd/flint.lnt =================================================================== --- trunk/varnish-cache/bin/varnishd/flint.lnt 2010-08-26 16:05:35 UTC (rev 5138) +++ trunk/varnish-cache/bin/varnishd/flint.lnt 2010-08-27 07:20:57 UTC (rev 5139) @@ -96,8 +96,6 @@ -emacro(527, NEEDLESS_RETURN) // unreachable code --efunc(525, VCC_Return_Name) // Negative indent - -sem(WS_Init, custodial(2)) -sem(http_Setup, custodial(2)) @@ -129,18 +127,10 @@ // cache.h -emacro(506, INCOMPL) // Constant value Boolean -// cache_center.c --efunc(525, CNT_Session) // Negative indentation from line --efunc(525, http_FilterFields) // Negative indentation from line --efunc(525, http_EstimateWS) // Negative indentation from line --efunc(539, http_FilterFields) // Positive indentation from line --efunc(539, http_EstimateWS) // Positive indentation from line - -esym(525, __builtin_frame_address) // Not defined -esym(525, __builtin_return_address) // Not defined // cache_vcl.c --efunc(525, vcl_handlingname) // Negative indentation from line -esym(528, vcl_handlingname) // Not referenced -e641 // Converting enum 'cli_status_e' to int Modified: trunk/varnish-cache/bin/varnishd/steps.h =================================================================== --- trunk/varnish-cache/bin/varnishd/steps.h 2010-08-26 16:05:35 UTC (rev 5138) +++ trunk/varnish-cache/bin/varnishd/steps.h 2010-08-27 07:20:57 UTC (rev 5139) @@ -29,6 +29,7 @@ * $Id$ */ +/*lint -save -e525 -e539 */ STEP(wait, WAIT) STEP(first, FIRST) STEP(recv, RECV) @@ -42,3 +43,4 @@ STEP(deliver, DELIVER) STEP(error, ERROR) STEP(done, DONE) +/*lint -restore */ Modified: trunk/varnish-cache/include/http_headers.h =================================================================== --- trunk/varnish-cache/include/http_headers.h 2010-08-26 16:05:35 UTC (rev 5138) +++ trunk/varnish-cache/include/http_headers.h 2010-08-27 07:20:57 UTC (rev 5139) @@ -42,6 +42,8 @@ * */ +/*lint -save -e525 -e539 */ + #ifndef HTTPH_R_PASS #define HTTPH_R_PASS (1 << 0) /* Request (c->b) in pass mode */ #define HTTPH_A_PASS (1 << 1) /* Response (b->c)in pass mode */ @@ -99,3 +101,5 @@ HTTPH("Via", H_Via, 2, 0, 0, 0, 0) /* RFC2616 14.45 */ HTTPH("Warning", H_Warning, 2, 0, 0, 0, 0) /* RFC2616 14.46 */ HTTPH("WWW-Authenticate", H_WWW_Authenticate, 2, 0, 0, 0, 0) /* RFC2616 14.47 */ + +/*lint -restore */ Modified: trunk/varnish-cache/lib/libvcl/generate.py =================================================================== --- trunk/varnish-cache/lib/libvcl/generate.py 2010-08-26 16:05:35 UTC (rev 5138) +++ trunk/varnish-cache/lib/libvcl/generate.py 2010-08-27 07:20:57 UTC (rev 5139) @@ -581,6 +581,8 @@ file_header(fo) +fo.write("\n/*lint -save -e525 -e539 */\n") + fo.write("\n#ifdef VCL_RET_MAC\n") l = list(rets.keys()) l.sort() @@ -603,6 +605,7 @@ p = "| " fo.write("))\n") fo.write("#endif\n") +fo.write("\n/*lint -restore */\n") fo.close() ####################################################################### Modified: trunk/varnish-cache/lib/libvcl/vcc_xref.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_xref.c 2010-08-26 16:05:35 UTC (rev 5138) +++ trunk/varnish-cache/lib/libvcl/vcc_xref.c 2010-08-27 07:20:57 UTC (rev 5139) @@ -270,7 +270,7 @@ } u = p->ret_bitmap & ~bitmap; if (u) { -/*lint -save -e525 -e539 */ + #define VCL_RET_MAC(l, U, B) \ if (u & (1 << (VCL_RET_##U))) { \ vsb_printf(tl->sb, "Invalid return \"" #l "\"\n");\ @@ -278,7 +278,7 @@ } #include "vcl_returns.h" #undef VCL_RET_MAC -/*lint -restore */ + vsb_printf(tl->sb, "\n...in subroutine \"%.*s\"\n", PF(p->name)); vcc_ErrWhere(tl, p->name); @@ -317,11 +317,9 @@ #define VCL_RET_MAC(l, U, B) \ if (m->ret_bitmap & ((1 << VCL_RET_##U))) \ vsb_printf(tl->sb, " \"%s\"", #l); -/*lint -save -e525 -e539 */ + #include "vcl_returns.h" -/*lint +e525 */ #undef VCL_RET_MAC -/*lint -restore */ vsb_printf(tl->sb, "\n"); return (1); } From phk at varnish-cache.org Fri Aug 27 08:11:38 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Fri, 27 Aug 2010 10:11:38 +0200 Subject: r5140 - trunk/varnish-cache/lib/libvcl Message-ID: Author: phk Date: 2010-08-27 10:11:38 +0200 (Fri, 27 Aug 2010) New Revision: 5140 Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h trunk/varnish-cache/lib/libvcl/vcc_expr.c trunk/varnish-cache/lib/libvcl/vcc_token.c Log: Add a facility for marking a range of tokens in an error message. Use it for Expressions Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-27 07:20:57 UTC (rev 5139) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-27 08:11:38 UTC (rev 5140) @@ -249,7 +249,9 @@ void vcc_Coord(const struct vcc *tl, struct vsb *vsb, const struct token *t); void vcc_ErrToken(const struct vcc *tl, const struct token *t); -void vcc_ErrWhere(struct vcc *tl, const struct token *t); +void vcc_ErrWhere(struct vcc *, const struct token *); +void vcc_ErrWhere2(struct vcc *, const struct token *, const struct token *); + void vcc__Expect(struct vcc *tl, unsigned tok, int line); int vcc_Teq(const struct token *t1, const struct token *t2); int vcc_IdIs(const struct token *t, const char *p); Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-27 07:20:57 UTC (rev 5139) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-27 08:11:38 UTC (rev 5140) @@ -673,12 +673,10 @@ vcc_NextToken(tl); vcc_expr_add(tl, &e2, (*e)->fmt); if (e2->fmt != (*e)->fmt) { /* XXX */ - vsb_printf(tl->sb, "Comparison of different types\n"); - vsb_printf(tl->sb, "Left side has type %s\n", - vcc_Type((*e)->fmt)); - vsb_printf(tl->sb, "Right side has type %s\n", - vcc_Type(e2->fmt)); + vsb_printf(tl->sb, "Comparison of different types: "); + vsb_printf(tl->sb, "%s ", vcc_Type((*e)->fmt)); vcc_ErrToken(tl, tk); + vsb_printf(tl->sb, " %s\n", vcc_Type(e2->fmt)); vcc_ErrWhere(tl, tk); return; } @@ -818,12 +816,7 @@ vcc_expr_fmt(tl->fb, tl->indent, e); vsb_putc(tl->fb, '\n'); } else { - vsb_printf(tl->sb, "Expression starts here:\n"); - vcc_ErrWhere(tl, t1); - if (t1 != tl->t) { - vsb_printf(tl->sb, "Expression ends here:\n"); - vcc_ErrWhere(tl, tl->t); - } + vcc_ErrWhere2(tl, t1, tl->t); } vcc_delete_expr(e); } Modified: trunk/varnish-cache/lib/libvcl/vcc_token.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_token.c 2010-08-27 07:20:57 UTC (rev 5139) +++ trunk/varnish-cache/lib/libvcl/vcc_token.c 2010-08-27 08:11:38 UTC (rev 5140) @@ -68,56 +68,78 @@ tl->err = 1; } +/*-------------------------------------------------------------------- + * Find start of source-line of token + */ + static void -vcc_icoord(struct vsb *vsb, const struct token *t, const char **ll) +vcc_iline(const struct token *t, const char **ll, int tail) { + const char *p, *b, *x; + + b = t->src->b; + if (ll != NULL) + *ll = b; + x = tail ? t->e - 1 : t->b; + for (p = b; p < x; p++) { + if (*p == '\n') { + if (ll != NULL) + *ll = p + 1; + } + } +} + +/*-------------------------------------------------------------------- + * Find and print src+line+pos of this token + */ + +static void +vcc_icoord(struct vsb *vsb, const struct token *t, int tail) +{ unsigned lin, pos; - const char *p, *b; - struct source *sp; + const char *p, *b, *x; lin = 1; pos = 0; - sp = t->src; - b = sp->b; - if (ll != NULL) - *ll = b; - for (p = b; p < t->b; p++) { + b = t->src->b; + x = tail ? t->e - 1 : t->b; + for (p = b; p < x; p++) { if (*p == '\n') { lin++; pos = 0; - if (ll != NULL) - *ll = p + 1; } else if (*p == '\t') { pos &= ~7; pos += 8; } else pos++; } - vsb_printf(vsb, "(%s Line %d Pos %d)", sp->name, lin, pos + 1); + vsb_printf(vsb, "('%s' Line %d Pos %d)", t->src->name, lin, pos + 1); } +/*--------------------------------------------------------------------*/ + void vcc_Coord(const struct vcc *tl, struct vsb *vsb, const struct token *t) { if (t == NULL) t = tl->t; - vcc_icoord(vsb, t, NULL); + vcc_icoord(vsb, t, 0); } -/* XXX: should take first+last token */ -void -vcc_ErrWhere(struct vcc *tl, const struct token *t) +/*-------------------------------------------------------------------- + * Output one line of source code, starting at 'l' and ending at the + * first NL or 'le'. + */ + +static void +vcc_quoteline(const struct vcc *tl, const char *l, const char *le) { + const char *p; unsigned x, y; - const char *p, *l, *e; - vcc_icoord(tl->sb, t, &l); - vsb_printf(tl->sb, "\n"); - x = y = 0; - e = t->src->e; - for (p = l; p < e && *p != '\n'; p++) { + for (p = l; p < le && *p != '\n'; p++) { if (*p == '\t') { y &= ~7; y += 8; @@ -131,29 +153,102 @@ vsb_bcat(tl->sb, p, 1); } } - vsb_cat(tl->sb, "\n"); + vsb_putc(tl->sb, '\n'); +} + +/*-------------------------------------------------------------------- + * Output a marker line for a sourceline starting at 'l' and ending at + * the first NL or 'le'. Characters between 'b' and 'e' are marked. + */ + +static void +vcc_markline(const struct vcc *tl, const char *l, const char *le, + const char *b, const char *e) +{ + const char *p; + unsigned x, y; + char c; + x = y = 0; - for (p = l; p < e && *p != '\n'; p++) { - if (p >= t->b && p < t->e) { - vsb_bcat(tl->sb, "#", 1); - x++; - y++; - continue; - } + for (p = l; p < le && *p != '\n'; p++) { + if (p >= b && p < e) + c = '#'; + else + c = '-'; + if (*p == '\t') { y &= ~7; y += 8; } else y++; while (x < y) { - vsb_bcat(tl->sb, "-", 1); + vsb_putc(tl->sb, c); x++; } } - vsb_cat(tl->sb, "\n"); + vsb_putc(tl->sb, '\n'); +} + +/*--------------------------------------------------------------------*/ +/* XXX: should take first+last token */ + +void +vcc_ErrWhere2(struct vcc *tl, const struct token *t, const struct token *t2) +{ + const char *l1, *l2, *l3; + + vcc_iline(t, &l1, 0); + t2 = VTAILQ_PREV(t2, tokenhead, list); + vcc_iline(t2, &l2, 1); + + + if (l1 == l2) { + vcc_icoord(tl->sb, t, 0); + vsb_cat(tl->sb, " -- "); + vcc_icoord(tl->sb, t2, 1); + vsb_putc(tl->sb, '\n'); + /* Two tokens on same line */ + vcc_quoteline(tl, l1, t->src->e); + vcc_markline(tl, l1, t->src->e, t->b, t2->e); + } else { + /* Two tokens different lines */ + l3 = strchr(l1, '\n'); + AN(l3); + /* XXX: t had better be before t2 */ + vcc_icoord(tl->sb, t, 0); + if (l3 + 1 == l2) { + vsb_cat(tl->sb, " -- "); + vcc_icoord(tl->sb, t2, 1); + } + vsb_putc(tl->sb, '\n'); + vcc_quoteline(tl, l1, t->src->e); + vcc_markline(tl, l1, t->src->e, t->b, t2->e); + if (l3 + 1 != l2) { + vsb_cat(tl->sb, "[...]\n"); + vcc_icoord(tl->sb, t2, 1); + vsb_putc(tl->sb, '\n'); + } + vcc_quoteline(tl, l2, t->src->e); + vcc_markline(tl, l2, t->src->e, t->b, t2->e); + } + vsb_putc(tl->sb, '\n'); tl->err = 1; } +void +vcc_ErrWhere(struct vcc *tl, const struct token *t) +{ + const char *l1; + + vcc_iline(t, &l1, 0); + vcc_icoord(tl->sb, t, 0); + vsb_putc(tl->sb, '\n'); + vcc_quoteline(tl, l1, t->src->e); + vcc_markline(tl, l1, t->src->e, t->b, t->e); + vsb_putc(tl->sb, '\n'); + tl->err = 1; +} + /*--------------------------------------------------------------------*/ void From phk at varnish-cache.org Fri Aug 27 09:23:34 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Fri, 27 Aug 2010 11:23:34 +0200 Subject: r5141 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: Author: phk Date: 2010-08-27 11:23:34 +0200 (Fri, 27 Aug 2010) New Revision: 5141 Modified: trunk/varnish-cache/bin/varnishtest/tests/v00019.vtc Log: Coverage of new multi-token error messages. Modified: trunk/varnish-cache/bin/varnishtest/tests/v00019.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/v00019.vtc 2010-08-27 08:11:38 UTC (rev 5140) +++ trunk/varnish-cache/bin/varnishtest/tests/v00019.vtc 2010-08-27 09:23:34 UTC (rev 5141) @@ -54,3 +54,34 @@ backend b { .host = "127.0.0.1"; } ? } + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_recv { + if ("foo" + "bar" == 777) { + set req.http.host = 1; + } + } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_recv { + if ("foo" + "bar" == + 777) { + set req.http.host = 1; + } + } +} + +varnish v1 -badvcl { + backend b { .host = "127.0.0.1"; } + sub vcl_recv { + if ("foo" + "bar" == + + + 777) { + set req.http.host = 1; + } + } +} From phk at varnish-cache.org Fri Aug 27 10:31:55 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Fri, 27 Aug 2010 12:31:55 +0200 Subject: r5142 - trunk/varnish-cache/lib/libvcl Message-ID: Author: phk Date: 2010-08-27 12:31:55 +0200 (Fri, 27 Aug 2010) New Revision: 5142 Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c Log: Unify the concatenation code STRING and STRING_LIST. Keep track of constant subexpressions and use it avoid building multipart constant strings on the workspace, when the C-compiler will happily build them for us at compile time. Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-27 09:23:34 UTC (rev 5141) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-27 10:31:55 UTC (rev 5142) @@ -198,7 +198,8 @@ #define EXPR_MAGIC 0x38c794ab enum var_type fmt; struct vsb *vsb; - /* XXX: first and last token */ + uint8_t constant; + struct token *t1, *t2; }; static void vcc_expr0(struct vcc *tl, struct expr **e, enum var_type fmt); @@ -288,6 +289,16 @@ } vsb_finish(e->vsb); AZ(vsb_overflowed(e->vsb)); + if (e1 != NULL) + e->t1 = e1->t1; + else if (e2 != NULL) + e->t1 = e2->t1; + if (e2 != NULL) + e->t2 = e2->t1; + else if (e1 != NULL) + e->t1 = e1->t1; + if ((e1 == NULL || e1->constant) && (e2 == NULL || e2->constant)) + e->constant = 1; vcc_delete_expr(e1); vcc_delete_expr(e2); e->fmt = fmt; @@ -468,6 +479,8 @@ assert(fmt != VOID); EncToken(e1->vsb, tl->t); e1->fmt = STRING; + e1->t1 = tl->t; + e1->constant = 1; vcc_NextToken(tl); break; case CNUM: @@ -485,11 +498,13 @@ vcc_NextToken(tl); e1->fmt = INT; } + e1->constant = 1; break; default: - e1->fmt = fmt; - vsb_printf(e1->vsb, "", PF(tl->t), tl->t->tok); - vcc_NextToken(tl); + vsb_printf(tl->sb, "Unknown token "); + vcc_ErrToken(tl, tl->t); + vsb_printf(tl->sb, " when looking for %s\n\n", vcc_Type(fmt)); + vcc_ErrWhere(tl, tl->t); break; } @@ -553,35 +568,30 @@ ERRCHK(tl); f2 = (*e)->fmt; - if (fmt == STRING_LIST && f2 == STRING) { - (*e)->fmt = STRING_LIST; + if ((f2 == STRING_LIST || f2 == STRING) && tl->t->tok == '+') { while (tl->t->tok == '+') { vcc_NextToken(tl); vcc_expr_mul(tl, &e2, STRING); if (e2->fmt != STRING && e2->fmt != STRING_LIST) vcc_expr_tostring(&e2, f2); + ERRCHK(tl); assert(e2->fmt == STRING || e2->fmt == STRING_LIST); - *e = vcc_expr_edit(STRING_LIST, "\v1,\n\v2", *e, e2); + if ((*e)->constant && e2->constant) { + assert((*e)->fmt == STRING); + assert(e2->fmt == STRING); + *e = vcc_expr_edit(STRING, "\v1\n\v2", *e, e2); + } else { + *e = vcc_expr_edit(STRING_LIST, + "\v1,\n\v2", *e, e2); + } } - return; } + if (fmt != STRING_LIST && (*e)->fmt == STRING_LIST) + *e = vcc_expr_edit(STRING, + "\v+VRT_String(sp,\n\v1,\nvrt_magic_string_end)", *e, NULL); + if (fmt == STRING_LIST && (*e)->fmt == STRING) + (*e)->fmt = STRING_LIST; - if (f2 == STRING && tl->t->tok == '+') { - *e = vcc_expr_edit(STRING, "\v+VRT_String(sp,\n\v1", *e, NULL); - while (tl->t->tok == '+') { - vcc_NextToken(tl); - vcc_expr_mul(tl, &e2, STRING); - if (e2->fmt != STRING && e2->fmt != STRING_LIST) - vcc_expr_tostring(&e2, f2); - - assert(e2->fmt == STRING || e2->fmt == STRING_LIST); - *e = vcc_expr_edit(STRING, "\v1,\n\v2", *e, e2); - } - *e = vcc_expr_edit(STRING, "\v1, vrt_magic_string_end)", - *e, NULL); - return; - } - switch(f2) { case INT: break; case TIME: f2 = DURATION; break; From phk at varnish-cache.org Fri Aug 27 18:43:20 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Fri, 27 Aug 2010 20:43:20 +0200 Subject: r5143 - trunk/varnish-cache/lib/libvcl Message-ID: Author: phk Date: 2010-08-27 20:43:20 +0200 (Fri, 27 Aug 2010) New Revision: 5143 Modified: trunk/varnish-cache/lib/libvcl/generate.py Log: Fix a fence-post error in generate.py's code to include a file verbatim. Modified: trunk/varnish-cache/lib/libvcl/generate.py =================================================================== --- trunk/varnish-cache/lib/libvcl/generate.py 2010-08-27 10:31:55 UTC (rev 5142) +++ trunk/varnish-cache/lib/libvcl/generate.py 2010-08-27 18:43:20 UTC (rev 5143) @@ -522,7 +522,9 @@ if x > w - 3: fo.write("\"\n") x = 0 - fo.write("\");\n") + if x != 0: + fo.write("\"") + fo.write(";\n") ####################################################################### From phk at varnish-cache.org Fri Aug 27 23:48:10 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Sat, 28 Aug 2010 01:48:10 +0200 Subject: r5144 - trunk/varnish-cache/lib/libvcl Message-ID: Author: phk Date: 2010-08-28 01:48:10 +0200 (Sat, 28 Aug 2010) New Revision: 5144 Modified: trunk/varnish-cache/lib/libvcl/generate.py Log: Gah, so much for testing trivial changes before commit. Modified: trunk/varnish-cache/lib/libvcl/generate.py =================================================================== --- trunk/varnish-cache/lib/libvcl/generate.py 2010-08-27 18:43:20 UTC (rev 5143) +++ trunk/varnish-cache/lib/libvcl/generate.py 2010-08-27 23:48:10 UTC (rev 5144) @@ -524,7 +524,8 @@ x = 0 if x != 0: fo.write("\"") - fo.write(";\n") + if l != 0: + fo.write("\t);\n") ####################################################################### From phk at varnish-cache.org Mon Aug 30 09:12:44 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 11:12:44 +0200 Subject: r5145 - in trunk/varnish-cache/lib: . libvcl libvmod_std Message-ID: Author: phk Date: 2010-08-30 11:12:44 +0200 (Mon, 30 Aug 2010) New Revision: 5145 Added: trunk/varnish-cache/lib/libvcl/vcc_vmod.c trunk/varnish-cache/lib/libvmod_std/ trunk/varnish-cache/lib/libvmod_std/Makefile.am trunk/varnish-cache/lib/libvmod_std/vmod.py trunk/varnish-cache/lib/libvmod_std/vmod.spec trunk/varnish-cache/lib/libvmod_std/vmod_std.c Modified: trunk/varnish-cache/lib/Makefile.am trunk/varnish-cache/lib/libvcl/Makefile.am trunk/varnish-cache/lib/libvcl/vcc_compile.c trunk/varnish-cache/lib/libvcl/vcc_compile.h trunk/varnish-cache/lib/libvcl/vcc_parse.c Log: Add the outline of the VMOD "std" which will in the future contain the standard functions supported in VCC. For now put the very magic python script that ties the C code to the VCL typesystem and the VCC compiler here. Eventually it goes elsewere. Modified: trunk/varnish-cache/lib/Makefile.am =================================================================== --- trunk/varnish-cache/lib/Makefile.am 2010-08-27 23:48:10 UTC (rev 5144) +++ trunk/varnish-cache/lib/Makefile.am 2010-08-30 09:12:44 UTC (rev 5145) @@ -5,6 +5,7 @@ libvarnish \ libvarnishapi \ libvcl \ + libvmod_std \ @JEMALLOC_SUBDIR@ DIST_SUBDIRS = \ @@ -12,4 +13,5 @@ libvarnish \ libvarnishapi \ libvcl \ + libvmod_std \ libjemalloc Modified: trunk/varnish-cache/lib/libvcl/Makefile.am =================================================================== --- trunk/varnish-cache/lib/libvcl/Makefile.am 2010-08-27 23:48:10 UTC (rev 5144) +++ trunk/varnish-cache/lib/libvcl/Makefile.am 2010-08-30 09:12:44 UTC (rev 5145) @@ -28,6 +28,7 @@ vcc_symb.c \ vcc_token.c \ vcc_var.c \ + vcc_vmod.c \ vcc_xref.c EXTRA_DIST = \ Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.c 2010-08-27 23:48:10 UTC (rev 5144) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.c 2010-08-30 09:12:44 UTC (rev 5145) @@ -189,7 +189,7 @@ /*--------------------------------------------------------------------*/ -static void +void EncString(struct vsb *sb, const char *b, const char *e, int mode) { Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-27 23:48:10 UTC (rev 5144) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-30 09:12:44 UTC (rev 5145) @@ -212,6 +212,7 @@ void EncToken(struct vsb *sb, const struct token *t); int IsMethod(const struct token *t); void *TlAlloc(struct vcc *tl, unsigned len); +void EncString(struct vsb *sb, const char *b, const char *e, int mode); /* vcc_dir_random.c */ parsedirector_f vcc_ParseRandomDirector; @@ -269,6 +270,9 @@ void vcc_VarVal(struct vcc *tl, const struct var *vp, const struct token *vt); +/* vcc_vmod.c */ +void vcc_ParseImport(struct vcc *tl); + /* vcc_xref.c */ void vcc_AddDef(struct vcc *tl, struct token *t, enum ref_type type); void vcc_AddRef(struct vcc *tl, struct token *t, enum ref_type type); Modified: trunk/varnish-cache/lib/libvcl/vcc_parse.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_parse.c 2010-08-27 23:48:10 UTC (rev 5144) +++ trunk/varnish-cache/lib/libvcl/vcc_parse.c 2010-08-30 09:12:44 UTC (rev 5145) @@ -261,6 +261,7 @@ { "backend", vcc_ParseDirector }, { "director", vcc_ParseDirector }, { "probe", vcc_ParseProbe }, + { "import", vcc_ParseImport }, { NULL, NULL } }; Added: trunk/varnish-cache/lib/libvcl/vcc_vmod.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_vmod.c (rev 0) +++ trunk/varnish-cache/lib/libvcl/vcc_vmod.c 2010-08-30 09:12:44 UTC (rev 5145) @@ -0,0 +1,119 @@ +/*- + * Copyright (c) 2010 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 THE 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. + */ + +#include "config.h" + +#include "svnid.h" +SVNID("$Id$"); + +#include +#include + +#include "vsb.h" + +#include "vcc_priv.h" +#include "vcc_compile.h" +#include "libvarnish.h" + +void +vcc_ParseImport(struct vcc *tl) +{ + void *hdl; + char fn[1024]; + struct token *mod; + const char *modname; + const char *proto; + // int *modlen; + + SkipToken(tl, ID); + + ExpectErr(tl, ID); + mod = tl->t; + vcc_NextToken(tl); + + if (tl->t->tok == ID) { + vcc_NextToken(tl); + ExpectErr(tl, CSTR); + bprintf(fn, "%s", tl->t->dec); + vcc_NextToken(tl); + } else { + Fi(tl, 0, ", NULL);\n"); + bprintf(fn, "XXX: %s", "XXX: no default path"); + } + + Fh(tl, 0, "static void *VGC_vmod_%.*s;\n", PF(mod)); + + Fi(tl, 0, "\tVRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod)); + Fi(tl, 0, "\t &Vmod_Func_%.*s,\n", PF(mod)); + Fi(tl, 0, "\t sizeof(Vmod_Func_%.*s),\n", PF(mod)); + Fi(tl, 0, "\t \"%.*s\",\n", PF(mod)); + if (fn != NULL) { + Fi(tl, 0, "\t "); + EncString(tl->fi, fn, NULL, 0); + } else { + Fi(tl, 0, "\t 0"); + } + Fi(tl, 0, ");\n"); + + /* XXX: zero the function pointer structure */ + Ff(tl, 0, "\tVRT_Vmod_Fini(&VGC_vmod_%.*s);\n", PF(mod)); + + SkipToken(tl, ';'); + + hdl = dlopen(fn, RTLD_NOW | RTLD_LOCAL); + if (hdl == NULL) { + vsb_printf(tl->sb, "Could not load module %.*s\n\t%s\n\t%s\n", + PF(mod), fn, dlerror()); + vcc_ErrWhere(tl, mod); + return; + } + + modname = dlsym(hdl, "Vmod_Name"); + if (modname == NULL) { + vsb_printf(tl->sb, "Could not load module %.*s\n\t%s\n\t%s\n", + PF(mod), fn, "Symbol Vmod_Name not found"); + vcc_ErrWhere(tl, mod); + return; + } + if (!vcc_IdIs(mod, modname)) { + vsb_printf(tl->sb, "Could not load module %.*s\n\t%s\n", + PF(mod), fn); + vsb_printf(tl->sb, "\tModule has wrong name: <%s>\n", modname); + vcc_ErrWhere(tl, mod); + return; + } + + proto = dlsym(hdl, "Vmod_Proto"); + if (modname == NULL) { + vsb_printf(tl->sb, "Could not load module %.*s\n\t%s\n\t%s\n", + PF(mod), fn, "Symbol Vmod_Proto not found"); + vcc_ErrWhere(tl, mod); + return; + } + Fh(tl, 0, "\n%s\n", proto); +} Added: trunk/varnish-cache/lib/libvmod_std/Makefile.am =================================================================== --- trunk/varnish-cache/lib/libvmod_std/Makefile.am (rev 0) +++ trunk/varnish-cache/lib/libvmod_std/Makefile.am 2010-08-30 09:12:44 UTC (rev 5145) @@ -0,0 +1,18 @@ +# $Id$ + +INCLUDES = -I$(top_srcdir)/include + +lib_LTLIBRARIES = libvmod_std.la + +libvmod_std_la_LDFLAGS = -version-info 1:0:0 + +libvmod_std_la_SOURCES = \ + $(builddir)/vmod.c \ + vmod_std.c + +$(builddir)/vmod.c $(builddir)/vmod.h: $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.spec + @PYTHON@ $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.spec + +EXTRA_DIST = vmod.py + +CLEANFILES = $(builddir)/vmod.c $(builddir)/vmod.h Added: trunk/varnish-cache/lib/libvmod_std/vmod.py =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod.py (rev 0) +++ trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-08-30 09:12:44 UTC (rev 5145) @@ -0,0 +1,177 @@ +#!/usr/local/bin/python +#- +# Copyright (c) 2010 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 THE 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. +# +# Read the vmod.spec file and produce the vmod.h and vmod.c files. +# +# vmod.h contains the prototypes for the published functions, the module +# C-code should include this file to ensure type-consistency. +# +# vmod.c contains the symbols which VCC and varnishd will use to access +# the module: A structure of properly typed function pointers, the +# size of this structure in bytes, and the definition of the structure +# as a string, suitable for inclusion in the C-source of the compile VCL +# program. +# +# $Id$ + +import sys + +if len(sys.argv) == 2: + specfile = sys.argv[1] +else: + specfile = "vmod.psec" + +type_tab = dict() + +type_tab['VOID'] = "V" +type_tab['REAL'] = "R" +type_tab['STRING'] = "S" +type_tab['STRING_LIST'] = "L" + +ctypes = { + 'IP': "struct sockaddr *", + 'STRING': "const char *", + 'STRING_LIST': "const char *, ...", + 'BOOL': "unsigned", + 'BACKEND': "struct director *", + 'TIME': "double", + 'REAL': "double", + 'DURATION': "double", + 'INT': "int", + 'HEADER': "const char *", +} + +####################################################################### + +modname = "???" +pstruct = "" +pinit = "" +tdl = "" +plist = "" + +def do_func(fname, rval, args): + global pstruct + global pinit + global plist + global tdl + print(fname, rval, args) + + proto = ctypes[rval] + " vmod_" + fname + "(" + sproto = ctypes[rval] + " td_" + fname + "(" + s="" + for i in args: + proto += s + ctypes[i] + sproto += s + ctypes[i] + s = ", " + proto += ")" + sproto += ")" + + plist += proto + ";\n" + tdl += "typedef\t" + sproto + ";\n" + + pstruct += "\ttd_" + fname + "\t*" + fname + ";\n" + pinit += "\tvmod_" + fname + ",\n" + +####################################################################### + +f = open(specfile, "r") + +for l0 in f: + # print("# " + l0) + i = l0.find("#") + if i == 0: + continue + if i >= 0: + line = l0[:i-1] + else: + line = l0 + line = line.expandtabs().strip() + l = line.partition(" ") + + if l[0] == "Module": + modname = l[2].strip(); + continue + + if l[0] != "Function": + assert False + + l = l[2].strip().partition(" ") + rt_type = l[0] + + l = l[2].strip().partition("(") + fname = l[0].strip() + + args = list() + + while True: + l = l[2].strip().partition(",") + if len(l[2]) == 0: + break + args.append(l[0]) + l = l[0].strip().partition(")") + args.append(l[0]) + do_func(fname, rt_type, args) + +####################################################################### +def dumps(s): + while True: + l = s.partition("\n") + if len(l[0]) == 0: + break + fc.write('\t"' + l[0] + '\\n"\n') + s = l[2] + +####################################################################### + +fc = open("vmod.c", "w") +fh = open("vmod.h", "w") + +fh.write(plist) + +fc.write('#include "vmod.h"\n') +fc.write("\n"); + +fc.write(tdl); +fc.write("\n"); + +fc.write("const struct Vmod_Func_" + modname + " {\n") +fc.write(pstruct + "} Vmod_Func = {\n" + pinit + "};\n") +fc.write("\n"); + +fc.write("const int Vmod_Len = sizeof(Vmod_Func);\n") +fc.write("\n"); + +fc.write('const char Vmod_Proto[] = \n') +dumps(tdl); +fc.write('\t"\\n"\n') +dumps("struct Vmod_Func_" + modname + " {\n") +dumps(pstruct + "} Vmod_Func_" + modname + ";\n") +fc.write('\t;\n') +fc.write("\n"); + +fc.write('const char Vmod_Name[] = "' + modname + '";\n') Property changes on: trunk/varnish-cache/lib/libvmod_std/vmod.py ___________________________________________________________________ Added: svn:executable + * Added: trunk/varnish-cache/lib/libvmod_std/vmod.spec =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod.spec (rev 0) +++ trunk/varnish-cache/lib/libvmod_std/vmod.spec 2010-08-30 09:12:44 UTC (rev 5145) @@ -0,0 +1,4 @@ +Module std +Function STRING toupper(STRING_LIST) +Function STRING tolower ( STRING_LIST) +Function REAL real(STRING, REAL) Added: trunk/varnish-cache/lib/libvmod_std/vmod_std.c =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod_std.c (rev 0) +++ trunk/varnish-cache/lib/libvmod_std/vmod_std.c 2010-08-30 09:12:44 UTC (rev 5145) @@ -0,0 +1,26 @@ +#include "vmod.h" + +const char * +vmod_toupper(const char *s, ...) +{ + + (void)s; + return ("UPPER"); +} + +const char * +vmod_tolower(const char *s, ...) +{ + + (void)s; + return ("LOWER"); +} + +double +vmod_real(const char *s, double d) +{ + + (void)s; + (void)d; + return (3.1415); +} From phk at varnish-cache.org Mon Aug 30 09:15:16 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 11:15:16 +0200 Subject: r5146 - in trunk/varnish-cache: . bin/varnishd include Message-ID: Author: phk Date: 2010-08-30 11:15:15 +0200 (Mon, 30 Aug 2010) New Revision: 5146 Added: trunk/varnish-cache/bin/varnishd/cache_vrt_vmod.c Modified: trunk/varnish-cache/bin/varnishd/Makefile.am trunk/varnish-cache/configure.ac trunk/varnish-cache/include/vrt.h Log: Add the VRT functions for importing a module. Tie the vmod_std module into the build. The initial VCC bits for modules snug into the previous commit. Modified: trunk/varnish-cache/bin/varnishd/Makefile.am =================================================================== --- trunk/varnish-cache/bin/varnishd/Makefile.am 2010-08-30 09:12:44 UTC (rev 5145) +++ trunk/varnish-cache/bin/varnishd/Makefile.am 2010-08-30 09:15:15 UTC (rev 5146) @@ -42,6 +42,7 @@ cache_vcl.c \ cache_vrt.c \ cache_vrt_re.c \ + cache_vrt_vmod.c \ cache_wrw.c \ cache_ws.c \ hash_classic.c \ Copied: trunk/varnish-cache/bin/varnishd/cache_vrt_vmod.c (from rev 5144, trunk/varnish-cache/bin/varnishd/cache_vrt.c) =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vrt_vmod.c (rev 0) +++ trunk/varnish-cache/bin/varnishd/cache_vrt_vmod.c 2010-08-30 09:15:15 UTC (rev 5146) @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2009 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 THE 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. + * + * Runtime support for compiled VCL programs + */ + +#include "config.h" + +#include "svnid.h" +SVNID("$Id$") + +#include +#include +#include + +#include "vrt.h" +#include "cache.h" + +/*-------------------------------------------------------------------- + * Modules stuff + */ + +struct vmod { + char *nm; + char *path; + void *hdl; + const void *funcs; + int funclen; +}; + +void +VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path) +{ + struct vmod *v; + void *x; + const int *i; + const char *p; + + v = calloc(sizeof *v, 1); + AN(v); + REPLACE(v->nm, nm); + REPLACE(v->path, path); + fprintf(stderr, "LOAD MODULE %s (%s)\n", v->nm, v->path); + v->hdl = dlopen(v->path, RTLD_NOW | RTLD_LOCAL); + if (v->hdl == NULL) + fprintf(stderr, "Err: %s\n", dlerror()); + AN(v->hdl); + + x = dlsym(v->hdl, "Vmod_Name"); + AN(x); + p = x; + fprintf(stderr, "Loaded name: %p\n", p); + fprintf(stderr, "Loaded name: %s\n", p); + + x = dlsym(v->hdl, "Vmod_Len"); + AN(x); + i = x; + fprintf(stderr, "Loaded len: %p\n", i); + fprintf(stderr, "Loaded len: %d\n", *i); + assert(len == *i); + + x = dlsym(v->hdl, "Vmod_Func"); + AN(x); + fprintf(stderr, "Loaded Funcs at: %p\n", x); + memcpy(ptr, x, len); + + v->funcs = x; + v->funclen = *i; + + *hdl = v; +} + +void +VRT_Vmod_Fini(void **hdl) +{ + struct vmod *v; + + AN(*hdl); + v = *hdl; + fprintf(stderr, "UNLOAD MODULE %s\n", v->nm); + free(*hdl); + *hdl = NULL; +} Modified: trunk/varnish-cache/configure.ac =================================================================== --- trunk/varnish-cache/configure.ac 2010-08-30 09:12:44 UTC (rev 5145) +++ trunk/varnish-cache/configure.ac 2010-08-30 09:15:15 UTC (rev 5146) @@ -462,6 +462,7 @@ lib/libvarnishapi/Makefile lib/libvarnishcompat/Makefile lib/libvcl/Makefile + lib/libvmod_std/Makefile lib/libjemalloc/Makefile man/Makefile redhat/Makefile Modified: trunk/varnish-cache/include/vrt.h =================================================================== --- trunk/varnish-cache/include/vrt.h 2010-08-30 09:12:44 UTC (rev 5145) +++ trunk/varnish-cache/include/vrt.h 2010-08-30 09:15:15 UTC (rev 5146) @@ -185,6 +185,13 @@ int idx, const void *priv); void VRT_fini_dir(struct cli *, struct director *); +/* Modules related */ +void VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, + const char *path); +void VRT_Vmod_Fini(void **hdl); + +/* Convert things to string */ + char *VRT_IP_string(const struct sess *sp, const struct sockaddr *sa); char *VRT_int_string(const struct sess *sp, int); char *VRT_double_string(const struct sess *sp, double); From phk at varnish-cache.org Mon Aug 30 11:04:38 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 13:04:38 +0200 Subject: r5147 - trunk/varnish-cache/lib/libvmod_std Message-ID: Author: phk Date: 2010-08-30 13:04:38 +0200 (Mon, 30 Aug 2010) New Revision: 5147 Modified: trunk/varnish-cache/lib/libvmod_std/vmod.py trunk/varnish-cache/lib/libvmod_std/vmod.spec trunk/varnish-cache/lib/libvmod_std/vmod_std.c Log: Flesh out the toupper and tolower functions. Emit a VCC friendly specification string for each functions. Modified: trunk/varnish-cache/lib/libvmod_std/vmod.py =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-08-30 09:15:15 UTC (rev 5146) +++ trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-08-30 11:04:38 UTC (rev 5147) @@ -73,21 +73,22 @@ pinit = "" tdl = "" plist = "" +slist = "" def do_func(fname, rval, args): global pstruct global pinit global plist + global slist global tdl print(fname, rval, args) - proto = ctypes[rval] + " vmod_" + fname + "(" - sproto = ctypes[rval] + " td_" + fname + "(" - s="" + proto = ctypes[rval] + " vmod_" + fname + "(struct sess *" + sproto = ctypes[rval] + " td_" + fname + "(struct sess *" + s=", " for i in args: proto += s + ctypes[i] sproto += s + ctypes[i] - s = ", " proto += ")" sproto += ")" @@ -97,6 +98,13 @@ pstruct += "\ttd_" + fname + "\t*" + fname + ";\n" pinit += "\tvmod_" + fname + ",\n" + s = modname + '.' + fname + "\\0" + s += "Vmod_Func_" + modname + "." + fname + "\\0" + s += type_tab[rval] + for i in args: + s += type_tab[i] + slist += '\t"' + s + '",\n' + ####################################################################### f = open(specfile, "r") @@ -151,14 +159,22 @@ fc = open("vmod.c", "w") fh = open("vmod.h", "w") +fh.write('struct sess;\n') +fh.write("\n"); + fh.write(plist) fc.write('#include "vmod.h"\n') fc.write("\n"); +fc.write('struct sess;\n') +fc.write("\n"); + fc.write(tdl); fc.write("\n"); +fc.write('const char Vmod_Name[] = "' + modname + '";\n') + fc.write("const struct Vmod_Func_" + modname + " {\n") fc.write(pstruct + "} Vmod_Func = {\n" + pinit + "};\n") fc.write("\n"); @@ -174,4 +190,4 @@ fc.write('\t;\n') fc.write("\n"); -fc.write('const char Vmod_Name[] = "' + modname + '";\n') +fc.write('const char *Vmod_Spec[] = {\n' + slist + '\t0\n};\n') Modified: trunk/varnish-cache/lib/libvmod_std/vmod.spec =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod.spec 2010-08-30 09:15:15 UTC (rev 5146) +++ trunk/varnish-cache/lib/libvmod_std/vmod.spec 2010-08-30 11:04:38 UTC (rev 5147) @@ -1,4 +1,3 @@ Module std Function STRING toupper(STRING_LIST) -Function STRING tolower ( STRING_LIST) -Function REAL real(STRING, REAL) +Function STRING tolower(STRING_LIST) Modified: trunk/varnish-cache/lib/libvmod_std/vmod_std.c =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod_std.c 2010-08-30 09:15:15 UTC (rev 5146) +++ trunk/varnish-cache/lib/libvmod_std/vmod_std.c 2010-08-30 11:04:38 UTC (rev 5147) @@ -1,26 +1,72 @@ +#include +#include +#include "vrt.h" +#include "../../bin/varnishd/cache.h" + #include "vmod.h" const char * -vmod_toupper(const char *s, ...) +vmod_toupper(struct sess *sp, const char *s, ...) { + va_list ap; + unsigned u; + char *b, *e; + const char *p; - (void)s; - return ("UPPER"); + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + va_start(ap, s); + u = WS_Reserve(sp->wrk->ws, 0); + e = b = sp->wrk->ws->f; + e += u; + p = s; + while (p != vrt_magic_string_end && b < e) { + for (; b < e && *p != '\0'; p++) + *b++ = toupper(*p); + p = va_arg(ap, const char *); + } + if (b < e) + *b = '\0'; + b++; + if (b > e) { + WS_Release(sp->wrk->ws, 0); + return (NULL); + } else { + e = b; + b = sp->wrk->ws->f; + WS_Release(sp->wrk->ws, e - b); + return (b); + } } const char * -vmod_tolower(const char *s, ...) +vmod_tolower(struct sess *sp, const char *s, ...) { + va_list ap; + unsigned u; + char *b, *e; + const char *p; - (void)s; - return ("LOWER"); + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + va_start(ap, s); + u = WS_Reserve(sp->wrk->ws, 0); + e = b = sp->wrk->ws->f; + e += u; + p = s; + while (p != vrt_magic_string_end && b < e) { + for (; b < e && *p != '\0'; p++) + *b++ = tolower(*p); + p = va_arg(ap, const char *); + } + if (b < e) + *b = '\0'; + b++; + if (b > e) { + WS_Release(sp->wrk->ws, 0); + return (NULL); + } else { + e = b; + b = sp->wrk->ws->f; + WS_Release(sp->wrk->ws, e - b); + return (b); + } } - -double -vmod_real(const char *s, double d) -{ - - (void)s; - (void)d; - return (3.1415); -} From phk at varnish-cache.org Mon Aug 30 11:06:05 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 13:06:05 +0200 Subject: r5148 - trunk/varnish-cache/lib/libvcl Message-ID: Author: phk Date: 2010-08-30 13:06:05 +0200 (Mon, 30 Aug 2010) New Revision: 5148 Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h trunk/varnish-cache/lib/libvcl/vcc_expr.c trunk/varnish-cache/lib/libvcl/vcc_types.h trunk/varnish-cache/lib/libvcl/vcc_vmod.c Log: Pick up the specification strings, and build symbols from them. Add code to implement function calls, based on symbols. Add type-single-char values to definitions in vcc_types.h. Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-30 11:04:38 UTC (rev 5147) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-30 11:06:05 UTC (rev 5148) @@ -39,7 +39,7 @@ struct acl_e; enum var_type { -#define VCC_TYPE(foo) foo, +#define VCC_TYPE(foo, bar) foo, #include "vcc_types.h" #undef VCC_TYPE }; @@ -75,6 +75,8 @@ char *name; unsigned nlen; unsigned wildcard; + const char *cfunc; + const char *args; const struct var *var; enum var_type fmt; unsigned r_methods; Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-30 11:04:38 UTC (rev 5147) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-30 11:06:05 UTC (rev 5148) @@ -49,14 +49,28 @@ vcc_Type(enum var_type fmt) { switch(fmt) { -#define VCC_TYPE(a) case a: return(#a); +#define VCC_TYPE(a, b) case a: return(#a); #include "vcc_types.h" #undef VCC_TYPE default: - return("Unknown Type"); + assert("Unknwon Type"); + return(NULL); } } +static enum var_type +vcc_Ltype(char c) +{ + switch (c) { +#define VCC_TYPE(a, b) case b: return(a); +#include "vcc_types.h" +#undef VCC_TYPE + default: + assert("Unknwon Type"); + return(0); + } +} + /*-------------------------------------------------------------------- * Recognize and convert units of time, return seconds. */ @@ -398,6 +412,46 @@ } /*-------------------------------------------------------------------- + */ + +static void +vcc_expr_call(struct vcc *tl, struct expr **e, const struct symbol *sym) +{ + const char *p, *q; + struct expr *e1; + + (void)tl; + (void)e; + AN(sym->cfunc); + AN(sym->args); + SkipToken(tl, ID); + SkipToken(tl, '('); + p = sym->args; + (*e)->fmt = vcc_Ltype(*p++); + vsb_printf((*e)->vsb, "%s(sp, \v+", sym->cfunc); + vsb_finish((*e)->vsb); + AZ(vsb_overflowed((*e)->vsb)); + q = "\v1\n\v2"; + while (*p != '\0') { + e1 = NULL; + vcc_expr0(tl, &e1, vcc_Ltype(*p)); + ERRCHK(tl); + assert(e1->fmt == vcc_Ltype(*p)); + if (e1->fmt == STRING_LIST) { + e1 = vcc_expr_edit(STRING_LIST, + "\v+\n\v1,\nvrt_magic_string_end\v-", e1, NULL); + } + *e = vcc_expr_edit((*e)->fmt, q, *e, e1); + q = "\v1,\n\v2"; + p++; + if (*p != '\0') + SkipToken(tl, ','); + } + SkipToken(tl, ')'); + *e = vcc_expr_edit((*e)->fmt, "\v1\n)\v-", *e, NULL); +} + +/*-------------------------------------------------------------------- * SYNTAX: * Expr4: * '(' Expr0 ')' @@ -466,14 +520,20 @@ } AN(sym); - vcc_AddUses(tl, tl->t, sym->r_methods, "Not available"); - AN(sym->var); - vp = vcc_FindVar(tl, tl->t, 0, "cannot be read"); - ERRCHK(tl); - assert(vp != NULL); - vsb_printf(e1->vsb, "%s", vp->rname); - e1->fmt = vp->fmt; - vcc_NextToken(tl); + if (sym->var != NULL) { + vcc_AddUses(tl, tl->t, sym->r_methods, "Not available"); + vp = vcc_FindVar(tl, tl->t, 0, "cannot be read"); + ERRCHK(tl); + assert(vp != NULL); + vsb_printf(e1->vsb, "%s", vp->rname); + e1->fmt = vp->fmt; + vcc_NextToken(tl); + } else if (sym->cfunc != NULL) { + vcc_expr_call(tl, &e1, sym); + ERRCHK(tl); + *e = e1; + return; + } break; case CSTR: assert(fmt != VOID); Modified: trunk/varnish-cache/lib/libvcl/vcc_types.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_types.h 2010-08-30 11:04:38 UTC (rev 5147) +++ trunk/varnish-cache/lib/libvcl/vcc_types.h 2010-08-30 11:06:05 UTC (rev 5148) @@ -29,15 +29,15 @@ */ /*lint -save -e525 -e539 */ -VCC_TYPE(VOID) -VCC_TYPE(BACKEND) -VCC_TYPE(BOOL) -VCC_TYPE(INT) -VCC_TYPE(TIME) -VCC_TYPE(DURATION) -VCC_TYPE(STRING) -VCC_TYPE(STRING_LIST) -VCC_TYPE(IP) -VCC_TYPE(HEADER) -VCC_TYPE(REAL) +VCC_TYPE(VOID, 'V') +VCC_TYPE(BACKEND, 'D') +VCC_TYPE(BOOL, 'B') +VCC_TYPE(INT, 'I') +VCC_TYPE(TIME, 'T') +VCC_TYPE(DURATION, 'M') +VCC_TYPE(STRING, 'S') +VCC_TYPE(STRING_LIST, 'L') +VCC_TYPE(IP, 'A') +VCC_TYPE(HEADER, 'H') +VCC_TYPE(REAL, 'R') /*lint -restore */ Modified: trunk/varnish-cache/lib/libvcl/vcc_vmod.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_vmod.c 2010-08-30 11:04:38 UTC (rev 5147) +++ trunk/varnish-cache/lib/libvcl/vcc_vmod.c 2010-08-30 11:06:05 UTC (rev 5148) @@ -33,6 +33,7 @@ #include #include +#include #include "vsb.h" @@ -48,6 +49,9 @@ struct token *mod; const char *modname; const char *proto; + const char **spec; + struct symbol *sym; + const char *p; // int *modlen; SkipToken(tl, ID); @@ -115,5 +119,20 @@ vcc_ErrWhere(tl, mod); return; } + spec = dlsym(hdl, "Vmod_Spec"); + if (modname == NULL) { + vsb_printf(tl->sb, "Could not load module %.*s\n\t%s\n\t%s\n", + PF(mod), fn, "Symbol Vmod_Spec not found"); + vcc_ErrWhere(tl, mod); + return; + } + for (; *spec != NULL; spec++) { + p = *spec; + sym = VCC_AddSymbol(tl, p); + p += strlen(p) + 1; + sym->cfunc = p; + p += strlen(p) + 1; + sym->args = p; + } Fh(tl, 0, "\n%s\n", proto); } From phk at varnish-cache.org Mon Aug 30 11:06:30 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 13:06:30 +0200 Subject: r5149 - trunk/varnish-cache/bin/varnishd Message-ID: Author: phk Date: 2010-08-30 13:06:30 +0200 (Mon, 30 Aug 2010) New Revision: 5149 Modified: trunk/varnish-cache/bin/varnishd/cache_vrt_vmod.c Log: Remove debugging noise Modified: trunk/varnish-cache/bin/varnishd/cache_vrt_vmod.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vrt_vmod.c 2010-08-30 11:06:05 UTC (rev 5148) +++ trunk/varnish-cache/bin/varnishd/cache_vrt_vmod.c 2010-08-30 11:06:30 UTC (rev 5149) @@ -65,28 +65,20 @@ AN(v); REPLACE(v->nm, nm); REPLACE(v->path, path); - fprintf(stderr, "LOAD MODULE %s (%s)\n", v->nm, v->path); v->hdl = dlopen(v->path, RTLD_NOW | RTLD_LOCAL); - if (v->hdl == NULL) - fprintf(stderr, "Err: %s\n", dlerror()); AN(v->hdl); x = dlsym(v->hdl, "Vmod_Name"); AN(x); p = x; - fprintf(stderr, "Loaded name: %p\n", p); - fprintf(stderr, "Loaded name: %s\n", p); x = dlsym(v->hdl, "Vmod_Len"); AN(x); i = x; - fprintf(stderr, "Loaded len: %p\n", i); - fprintf(stderr, "Loaded len: %d\n", *i); assert(len == *i); x = dlsym(v->hdl, "Vmod_Func"); AN(x); - fprintf(stderr, "Loaded Funcs at: %p\n", x); memcpy(ptr, x, len); v->funcs = x; @@ -102,7 +94,6 @@ AN(*hdl); v = *hdl; - fprintf(stderr, "UNLOAD MODULE %s\n", v->nm); free(*hdl); *hdl = NULL; } From tfheen at varnish-cache.org Mon Aug 30 12:01:05 2010 From: tfheen at varnish-cache.org (tfheen at varnish-cache.org) Date: Mon, 30 Aug 2010 14:01:05 +0200 Subject: r5150 - branches/2.1/varnish-cache/bin/varnishtop Message-ID: Author: tfheen Date: 2010-08-30 14:01:05 +0200 (Mon, 30 Aug 2010) New Revision: 5150 Modified: branches/2.1/varnish-cache/bin/varnishtop/varnishtop.c Log: Fix segfault on 32 bit machines Adjust the size of the rec field to match what's in shmlog. No corresponding -trunk commit as the code has been reworked already. Fixes #765 Modified: branches/2.1/varnish-cache/bin/varnishtop/varnishtop.c =================================================================== --- branches/2.1/varnish-cache/bin/varnishtop/varnishtop.c 2010-08-30 11:06:30 UTC (rev 5149) +++ branches/2.1/varnish-cache/bin/varnishtop/varnishtop.c 2010-08-30 12:01:05 UTC (rev 5150) @@ -55,7 +55,7 @@ #include "varnishapi.h" struct top { - unsigned char rec[4]; + unsigned char rec[SHMLOG_DATA-1]; unsigned char *rec_data; unsigned clen; unsigned hash; From phk at varnish-cache.org Mon Aug 30 12:02:17 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 14:02:17 +0200 Subject: r5151 - trunk/varnish-cache/lib/libvmod_std Message-ID: Author: phk Date: 2010-08-30 14:02:17 +0200 (Mon, 30 Aug 2010) New Revision: 5151 Added: trunk/varnish-cache/lib/libvmod_std/vmod.vcc Removed: trunk/varnish-cache/lib/libvmod_std/vmod.spec Modified: trunk/varnish-cache/lib/libvmod_std/Makefile.am trunk/varnish-cache/lib/libvmod_std/vmod.py Log: Rename vmod.spec to vmod.vcc to compensate for old RedHat package megalomania. Modified: trunk/varnish-cache/lib/libvmod_std/Makefile.am =================================================================== --- trunk/varnish-cache/lib/libvmod_std/Makefile.am 2010-08-30 12:01:05 UTC (rev 5150) +++ trunk/varnish-cache/lib/libvmod_std/Makefile.am 2010-08-30 12:02:17 UTC (rev 5151) @@ -10,9 +10,9 @@ $(builddir)/vmod.c \ vmod_std.c -$(builddir)/vmod.c $(builddir)/vmod.h: $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.spec - @PYTHON@ $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.spec +$(builddir)/vmod.c $(builddir)/vmod.h: $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.vcc + @PYTHON@ $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.vcc -EXTRA_DIST = vmod.py +EXTRA_DIST = vmod.py vmod.vcc CLEANFILES = $(builddir)/vmod.c $(builddir)/vmod.h Modified: trunk/varnish-cache/lib/libvmod_std/vmod.py =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-08-30 12:01:05 UTC (rev 5150) +++ trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-08-30 12:02:17 UTC (rev 5151) @@ -44,7 +44,7 @@ if len(sys.argv) == 2: specfile = sys.argv[1] else: - specfile = "vmod.psec" + specfile = "vmod.vcc" type_tab = dict() Deleted: trunk/varnish-cache/lib/libvmod_std/vmod.spec =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod.spec 2010-08-30 12:01:05 UTC (rev 5150) +++ trunk/varnish-cache/lib/libvmod_std/vmod.spec 2010-08-30 12:02:17 UTC (rev 5151) @@ -1,3 +0,0 @@ -Module std -Function STRING toupper(STRING_LIST) -Function STRING tolower(STRING_LIST) Copied: trunk/varnish-cache/lib/libvmod_std/vmod.vcc (from rev 5147, trunk/varnish-cache/lib/libvmod_std/vmod.spec) =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod.vcc (rev 0) +++ trunk/varnish-cache/lib/libvmod_std/vmod.vcc 2010-08-30 12:02:17 UTC (rev 5151) @@ -0,0 +1,3 @@ +Module std +Function STRING toupper(STRING_LIST) +Function STRING tolower(STRING_LIST) From tfheen at varnish-cache.org Mon Aug 30 12:09:42 2010 From: tfheen at varnish-cache.org (tfheen at varnish-cache.org) Date: Mon, 30 Aug 2010 14:09:42 +0200 Subject: r5152 - trunk/varnish-cache/lib/libvmod_std Message-ID: Author: tfheen Date: 2010-08-30 14:09:42 +0200 (Mon, 30 Aug 2010) New Revision: 5152 Modified: trunk/varnish-cache/lib/libvmod_std/Makefile.am Log: Include files from builddir/include too Modified: trunk/varnish-cache/lib/libvmod_std/Makefile.am =================================================================== --- trunk/varnish-cache/lib/libvmod_std/Makefile.am 2010-08-30 12:02:17 UTC (rev 5151) +++ trunk/varnish-cache/lib/libvmod_std/Makefile.am 2010-08-30 12:09:42 UTC (rev 5152) @@ -1,6 +1,6 @@ # $Id$ -INCLUDES = -I$(top_srcdir)/include +INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include lib_LTLIBRARIES = libvmod_std.la From phk at varnish-cache.org Mon Aug 30 12:37:23 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 14:37:23 +0200 Subject: r5153 - trunk/varnish-cache/lib/libvmod_std Message-ID: Author: phk Date: 2010-08-30 14:37:23 +0200 (Mon, 30 Aug 2010) New Revision: 5153 Modified: trunk/varnish-cache/lib/libvmod_std/Makefile.am trunk/varnish-cache/lib/libvmod_std/vmod.py trunk/varnish-cache/lib/libvmod_std/vmod_std.c Log: Rename the generated files from vmod.[ch] to vcc_if.[ch] to avoid clashing with include/vmod.h Modified: trunk/varnish-cache/lib/libvmod_std/Makefile.am =================================================================== --- trunk/varnish-cache/lib/libvmod_std/Makefile.am 2010-08-30 12:09:42 UTC (rev 5152) +++ trunk/varnish-cache/lib/libvmod_std/Makefile.am 2010-08-30 12:37:23 UTC (rev 5153) @@ -7,12 +7,12 @@ libvmod_std_la_LDFLAGS = -version-info 1:0:0 libvmod_std_la_SOURCES = \ - $(builddir)/vmod.c \ + $(builddir)/vcc_if.c \ vmod_std.c -$(builddir)/vmod.c $(builddir)/vmod.h: $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.vcc +$(builddir)/vcc_if.c $(builddir)/vcc_if.h: $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.vcc @PYTHON@ $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.vcc EXTRA_DIST = vmod.py vmod.vcc -CLEANFILES = $(builddir)/vmod.c $(builddir)/vmod.h +CLEANFILES = $(builddir)/vcc_if.c $(builddir)/vcc_if.h Modified: trunk/varnish-cache/lib/libvmod_std/vmod.py =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-08-30 12:09:42 UTC (rev 5152) +++ trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-08-30 12:37:23 UTC (rev 5153) @@ -156,15 +156,15 @@ ####################################################################### -fc = open("vmod.c", "w") -fh = open("vmod.h", "w") +fc = open("vcc_if.c", "w") +fh = open("vcc_if.h", "w") fh.write('struct sess;\n') fh.write("\n"); fh.write(plist) -fc.write('#include "vmod.h"\n') +fc.write('#include "vcc_if.h"\n') fc.write("\n"); fc.write('struct sess;\n') Modified: trunk/varnish-cache/lib/libvmod_std/vmod_std.c =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod_std.c 2010-08-30 12:09:42 UTC (rev 5152) +++ trunk/varnish-cache/lib/libvmod_std/vmod_std.c 2010-08-30 12:37:23 UTC (rev 5153) @@ -3,7 +3,7 @@ #include "vrt.h" #include "../../bin/varnishd/cache.h" -#include "vmod.h" +#include "vcc_if.h" const char * vmod_toupper(struct sess *sp, const char *s, ...) From phk at varnish-cache.org Mon Aug 30 12:37:56 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 14:37:56 +0200 Subject: r5154 - in trunk/varnish-cache: include lib/libvcl Message-ID: Author: phk Date: 2010-08-30 14:37:56 +0200 (Mon, 30 Aug 2010) New Revision: 5154 Removed: trunk/varnish-cache/include/vmod.h Modified: trunk/varnish-cache/lib/libvcl/generate.py Log: Delete include/vmod.h we don't need it anyway Deleted: trunk/varnish-cache/include/vmod.h =================================================================== --- trunk/varnish-cache/include/vmod.h 2010-08-30 12:37:23 UTC (rev 5153) +++ trunk/varnish-cache/include/vmod.h 2010-08-30 12:37:56 UTC (rev 5154) @@ -1,38 +0,0 @@ -/*- - * Copyright (c) 2010 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 THE 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$ - * - * VCL modules - * - * XXX: When this file is changed, lib/libvcl/generate.py *MUST* be rerun. - */ - -struct vmod_conf { - unsigned magic; -#define VMOD_CONF_MAGIC 0x3f017730 -}; Modified: trunk/varnish-cache/lib/libvcl/generate.py =================================================================== --- trunk/varnish-cache/lib/libvcl/generate.py 2010-08-30 12:37:23 UTC (rev 5153) +++ trunk/varnish-cache/lib/libvcl/generate.py 2010-08-30 12:37:56 UTC (rev 5154) @@ -785,7 +785,6 @@ """) emit_file(fo, buildroot + "/include/vcl.h") -emit_file(fo, srcroot + "/include/vmod.h") emit_file(fo, srcroot + "/include/vrt.h") emit_file(fo, buildroot + "/include/vrt_obj.h") From phk at varnish-cache.org Mon Aug 30 12:38:58 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 14:38:58 +0200 Subject: r5155 - trunk/varnish-cache/include Message-ID: Author: phk Date: 2010-08-30 14:38:58 +0200 (Mon, 30 Aug 2010) New Revision: 5155 Modified: trunk/varnish-cache/include/Makefile.am Log: Remember to remove vmod.h here also Modified: trunk/varnish-cache/include/Makefile.am =================================================================== --- trunk/varnish-cache/include/Makefile.am 2010-08-30 12:37:56 UTC (rev 5154) +++ trunk/varnish-cache/include/Makefile.am 2010-08-30 12:38:58 UTC (rev 5155) @@ -45,7 +45,6 @@ vlu.h \ vbm.h \ vmb.h \ - vmod.h \ vre.h \ vrt.h \ vrt_obj.h \ From phk at varnish-cache.org Mon Aug 30 12:42:02 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 14:42:02 +0200 Subject: r5156 - trunk/varnish-cache/include Message-ID: Author: phk Date: 2010-08-30 14:42:02 +0200 (Mon, 30 Aug 2010) New Revision: 5156 Modified: trunk/varnish-cache/include/Makefile.am Log: Yet another vmod.h reference Modified: trunk/varnish-cache/include/Makefile.am =================================================================== --- trunk/varnish-cache/include/Makefile.am 2010-08-30 12:38:58 UTC (rev 5155) +++ trunk/varnish-cache/include/Makefile.am 2010-08-30 12:42:02 UTC (rev 5156) @@ -50,7 +50,7 @@ vrt_obj.h \ vss.h -vcl_returns.h vcl.h vrt_obj.h: $(top_srcdir)/lib/libvcl/generate.py $(top_srcdir)/include/vmod.h $(top_srcdir)/include/vrt.h +vcl_returns.h vcl.h vrt_obj.h: $(top_srcdir)/lib/libvcl/generate.py $(top_srcdir)/include/vrt.h @PYTHON@ $(top_srcdir)/lib/libvcl/generate.py $(top_srcdir) $(top_builddir) CLEANFILES = vcl_returns.h \ From phk at varnish-cache.org Mon Aug 30 12:44:51 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 14:44:51 +0200 Subject: r5157 - trunk/varnish-cache/lib/libvcl Message-ID: Author: phk Date: 2010-08-30 14:44:50 +0200 (Mon, 30 Aug 2010) New Revision: 5157 Modified: trunk/varnish-cache/lib/libvcl/Makefile.am Log: Aaaand yet another vmod.h reference to remove Modified: trunk/varnish-cache/lib/libvcl/Makefile.am =================================================================== --- trunk/varnish-cache/lib/libvcl/Makefile.am 2010-08-30 12:42:02 UTC (rev 5156) +++ trunk/varnish-cache/lib/libvcl/Makefile.am 2010-08-30 12:44:50 UTC (rev 5157) @@ -34,7 +34,7 @@ EXTRA_DIST = \ generate.py -$(builddir)/vcc_obj.c $(builddir)/vcc_fixed_token.c $(builddir)/vcc_token_defs.h: $(srcdir)/generate.py $(top_srcdir)/include/vmod.h $(top_srcdir)/include/vrt.h +$(builddir)/vcc_obj.c $(builddir)/vcc_fixed_token.c $(builddir)/vcc_token_defs.h: $(srcdir)/generate.py $(top_srcdir)/include/vrt.h @PYTHON@ $(top_srcdir)/lib/libvcl/generate.py $(top_srcdir) $(top_builddir) CLEANFILES = $(builddir)/vcc_token_defs.h \ From phk at varnish-cache.org Mon Aug 30 12:52:09 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Mon, 30 Aug 2010 14:52:09 +0200 Subject: r5158 - in trunk/varnish-cache: include lib/libvarnish Message-ID: Author: phk Date: 2010-08-30 14:52:09 +0200 (Mon, 30 Aug 2010) New Revision: 5158 Modified: trunk/varnish-cache/include/vmb.h trunk/varnish-cache/lib/libvarnish/vmb.c Log: Don't compile the pthread based memory-barrier fall back unless we actually need it. Modified: trunk/varnish-cache/include/vmb.h =================================================================== --- trunk/varnish-cache/include/vmb.h 2010-08-30 12:44:50 UTC (rev 5157) +++ trunk/varnish-cache/include/vmb.h 2010-08-30 12:52:09 UTC (rev 5158) @@ -74,6 +74,8 @@ #else +#define VMB_NEEDS_PTHREAD_WORKAROUND_THIS_IS_BAD_FOR_PERFORMANCE 1 + #define VMB() vmb_pthread() #define VWMB() vmb_pthread() #define VRMB() vmb_pthread() Modified: trunk/varnish-cache/lib/libvarnish/vmb.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/vmb.c 2010-08-30 12:44:50 UTC (rev 5157) +++ trunk/varnish-cache/lib/libvarnish/vmb.c 2010-08-30 12:52:09 UTC (rev 5158) @@ -30,6 +30,8 @@ #include "libvarnish.h" #include "vmb.h" +#ifdef VMB_NEEDS_PTHREAD_WORKAROUND_THIS_IS_BAD_FOR_PERFORMANCE + static pthread_mutex_t mb_mtx; static pthread_once_t mb_mtx_once = PTHREAD_ONCE_INIT; @@ -50,3 +52,5 @@ AZ(pthread_mutex_lock(&mb_mtx)); AZ(pthread_mutex_unlock(&mb_mtx)); } + +#endif From tfheen at varnish-cache.org Mon Aug 30 12:54:07 2010 From: tfheen at varnish-cache.org (tfheen at varnish-cache.org) Date: Mon, 30 Aug 2010 14:54:07 +0200 Subject: r5159 - trunk/varnish-tools/nagios Message-ID: Author: tfheen Date: 2010-08-30 14:54:07 +0200 (Mon, 30 Aug 2010) New Revision: 5159 Modified: trunk/varnish-tools/nagios/check_varnish.c Log: Fix nagios plugin Make the nagios plugin compile again, needed updates for the VSL/VSM/VSC changes. It still doesn't support other counters than the main ones. Modified: trunk/varnish-tools/nagios/check_varnish.c =================================================================== --- trunk/varnish-tools/nagios/check_varnish.c 2010-08-30 12:52:09 UTC (rev 5158) +++ trunk/varnish-tools/nagios/check_varnish.c 2010-08-30 12:54:07 UTC (rev 5159) @@ -1,5 +1,6 @@ /*- * Copyright (c) 2007-2009 Linpro AS + * Copyright (c) 2010 Varnish Software AS * All rights reserved. * * Author: Cecilie Fritzvold @@ -39,8 +40,9 @@ #include #include #include +#include -#include "shmlog.h" +#include "vsc.h" #include "varnishapi.h" static int verbose = 0; @@ -163,7 +165,7 @@ * Check the statistics for the requested parameter. */ static void -check_stats(struct varnish_stats *VSL_stats, char *param) +check_stats(const struct vsc_main *stats, char *param) { const char *info; struct timeval tv; @@ -171,36 +173,30 @@ intmax_t value; int status; - gettimeofday(&tv, NULL); - up = tv.tv_sec - VSL_stats->start_time; - if (strcmp(param, "uptime") == 0) { - value = up; - info = "Uptime"; - } - else if (strcmp(param, "ratio") == 0) { - intmax_t total = VSL_stats->cache_hit + VSL_stats->cache_miss; + if (strcmp(param, "ratio") == 0) { + intmax_t total = stats->cache_hit + stats->cache_miss; - value = total ? (100 * VSL_stats->cache_hit / total) : 0; + value = total ? (100 * stats->cache_hit / total) : 0; info = "Cache hit ratio"; } else if (strcmp(param, "usage") == 0) { - intmax_t total = VSL_stats->sm_balloc + VSL_stats->sm_bfree; + intmax_t total = stats->sm_balloc + stats->sm_bfree; - value = total ? (100 * VSL_stats->sm_balloc / total) : 0; + value = total ? (100 * stats->sm_balloc / total) : 0; info = "Cache file usage"; } -#define MAC_STAT(n, t, f, i, d) \ +#define VSC_F_MAIN(n, t, l, f, e) \ else if (strcmp(param, #n) == 0) { \ - value = VSL_stats->n; \ - info = d; \ + value = stats->n; \ + info = e; \ } -#include "stat_field.h" -#undef MAC_STAT +#include "vsc_fields.h" +#undef VSC_F_MAIN else printf("Unknown parameter '%s'\n", param); status = check_thresholds(value); - printf("VARNISH %s: %s|%s=%jd\n", status_text[status], info, param, value); + printf("VARNISH %s: %s (%'jd)|%s=%jd\n", status_text[status], info, value, param, value); exit(status); } @@ -245,11 +241,17 @@ int main(int argc, char **argv) { - struct varnish_stats *VSL_stats; + struct VSM_data *vd; const char *n_arg = NULL; + const struct vsc_main *VSC_main; char *param = NULL; int opt; + setlocale(LC_ALL, ""); + + vd = VSM_New(); + VSC_Setup(vd); + while ((opt = getopt(argc, argv, "c:hn:p:vw:")) != -1) { switch (opt) { case 'c': @@ -260,7 +262,7 @@ help(); break; case 'n': - n_arg = optarg; + VSC_Arg(vd, opt, optarg); break; case 'p': param = strdup(optarg); @@ -277,9 +279,11 @@ } } - if ((VSL_stats = VSL_OpenStats(n_arg)) == NULL) + if (VSC_Open(vd, 1)) exit(1); + VSC_main = VSC_Main(vd); + /* Default: if no param specified, check hit ratio. If no warning * and critical values are specified either, set these to default. */ @@ -294,7 +298,7 @@ if (!param) usage(); - check_stats(VSL_stats, param); + check_stats(VSC_main, param); exit(0); } From martin at varnish-cache.org Tue Aug 31 07:45:29 2010 From: martin at varnish-cache.org (martin at varnish-cache.org) Date: Tue, 31 Aug 2010 09:45:29 +0200 Subject: r5160 - trunk/varnish-cache/bin/varnishd Message-ID: Author: martin Date: 2010-08-31 09:45:29 +0200 (Tue, 31 Aug 2010) New Revision: 5160 Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c trunk/varnish-cache/bin/varnishd/cache_dir.c Log: Add explicit log flushing when backend connections close to keep log chronology. This is to avoid log lines for the same (reused) FD coming before the closing connection when load is high. Fixes #739 Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-30 12:54:07 UTC (rev 5159) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2010-08-31 07:45:29 UTC (rev 5160) @@ -370,6 +370,11 @@ } VSC_main->backend_toolate++; WSL(sp->wrk, SLT_BackendClose, vc->fd, "%s", bp->vcl_name); + + /* Checkpoint log to flush all info related to this connection + before the OS reuses the FD */ + WSL_Flush(sp->wrk, 0); + TCP_close(&vc->fd); VBE_DropRefConn(bp); vc->backend = NULL; Modified: trunk/varnish-cache/bin/varnishd/cache_dir.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir.c 2010-08-30 12:54:07 UTC (rev 5159) +++ trunk/varnish-cache/bin/varnishd/cache_dir.c 2010-08-31 07:45:29 UTC (rev 5160) @@ -52,6 +52,11 @@ bp = sp->vbc->backend; WSL(sp->wrk, SLT_BackendClose, sp->vbc->fd, "%s", bp->vcl_name); + + /* Checkpoint log to flush all info related to this connection + before the OS reuses the FD */ + WSL_Flush(sp->wrk, 0); + TCP_close(&sp->vbc->fd); VBE_DropRefConn(bp); sp->vbc->backend = NULL; From martin at varnish-cache.org Tue Aug 31 07:53:49 2010 From: martin at varnish-cache.org (martin at varnish-cache.org) Date: Tue, 31 Aug 2010 09:53:49 +0200 Subject: r5161 - branches/2.1/varnish-cache/bin/varnishd Message-ID: Author: martin Date: 2010-08-31 09:53:49 +0200 (Tue, 31 Aug 2010) New Revision: 5161 Modified: branches/2.1/varnish-cache/bin/varnishd/cache_backend.c Log: Add explicit log flushing when backend connections close to keep log chronology. This is to avoid log lines for the same (reused) FD coming before the closing connection when load is high. Trunk r5160 reworked for 2.1 branch. Modified: branches/2.1/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- branches/2.1/varnish-cache/bin/varnishd/cache_backend.c 2010-08-31 07:45:29 UTC (rev 5160) +++ branches/2.1/varnish-cache/bin/varnishd/cache_backend.c 2010-08-31 07:53:49 UTC (rev 5161) @@ -386,6 +386,11 @@ bp = sp->vbe->backend; WSL(sp->wrk, SLT_BackendClose, sp->vbe->fd, "%s", bp->vcl_name); + + /* Checkpoint log to flush all info related to this connection + before the OS reuses the FD */ + WSL_Flush(sp->wrk, 0); + TCP_close(&sp->vbe->fd); VBE_DropRefConn(bp); sp->vbe->backend = NULL; From martin at varnish-cache.org Tue Aug 31 10:35:16 2010 From: martin at varnish-cache.org (martin at varnish-cache.org) Date: Tue, 31 Aug 2010 12:35:16 +0200 Subject: r5162 - trunk/varnish-cache/bin/varnishncsa Message-ID: Author: martin Date: 2010-08-31 12:35:16 +0200 (Tue, 31 Aug 2010) New Revision: 5162 Modified: trunk/varnish-cache/bin/varnishncsa/varnishncsa.c Log: Make varnishncsa only consider log information between the open and close log tags for a connection, and clear the collected log data on seeing the open tag. This resolves an issue with log data where varnishncsa would consider a set of data as bogus because of extra data in the log belonging to the previous connection. Support case 164. Modified: trunk/varnish-cache/bin/varnishncsa/varnishncsa.c =================================================================== --- trunk/varnish-cache/bin/varnishncsa/varnishncsa.c 2010-08-31 07:53:49 UTC (rev 5161) +++ trunk/varnish-cache/bin/varnishncsa/varnishncsa.c 2010-08-31 10:35:16 UTC (rev 5162) @@ -96,7 +96,8 @@ char *df_s; /* %s, Status */ struct tm df_t; /* %t, Date and time */ char *df_u; /* %u, Remote user */ - int bogus; /* bogus request */ + int active; /* Is log line in an active trans */ + int complete; /* Is log line complete */ } **ll; static size_t nll; @@ -177,6 +178,25 @@ return (p); } +static void +clean_logline(struct logline *lp) +{ +#define freez(x) do { if (x) free(x); x = NULL; } while (0); + freez(lp->df_H); + freez(lp->df_Host); + freez(lp->df_Referer); + freez(lp->df_Uq); + freez(lp->df_User_agent); + freez(lp->df_X_Forwarded_For); + freez(lp->df_b); + freez(lp->df_h); + freez(lp->df_m); + freez(lp->df_s); + freez(lp->df_u); +#undef freez + memset(lp, 0, sizeof *lp); +} + static int collect_backend(struct logline *lp, enum vsl_tag tag, unsigned spec, const char *ptr, unsigned len) @@ -188,52 +208,72 @@ switch (tag) { case SLT_BackendOpen: - if (lp->df_h != NULL) - lp->bogus = 1; + if(lp->active || lp->df_h != NULL) { + /* New start for active line, + clean it and start from scratch */ + clean_logline(lp); + } + lp->active = 1; + if (isprefix(ptr, "default", end, &next)) + lp->df_h = trimfield(next, end); else - if (isprefix(ptr, "default", end, &next)) - lp->df_h = trimfield(next, end); - else - lp->df_h = trimfield(ptr, end); + lp->df_h = trimfield(ptr, end); break; case SLT_TxRequest: - if (lp->df_m != NULL) - lp->bogus = 1; - else - lp->df_m = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_m != NULL) { + clean_logline(lp); + break; + } + lp->df_m = trimline(ptr, end); break; case SLT_TxURL: - if (lp->df_Uq != NULL) - lp->bogus = 1; - else - lp->df_Uq = trimline(ptr, end); + if(!lp->active) + break; + if(lp->df_Uq != NULL) { + clean_logline(lp); + break; + } + lp->df_Uq = trimline(ptr, end); break; case SLT_TxProtocol: - if (lp->df_H != NULL) - lp->bogus = 1; - else - lp->df_H = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_H != NULL) { + clean_logline(lp); + break; + } + lp->df_H = trimline(ptr, end); break; case SLT_RxStatus: - if (lp->df_s != NULL) - lp->bogus = 1; - else - lp->df_s = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_s != NULL) { + clean_logline(lp); + break; + } + lp->df_s = trimline(ptr, end); break; case SLT_RxHeader: + if(!lp->active) + break; if (isprefix(ptr, "content-length:", end, &next)) lp->df_b = trimline(next, end); else if (isprefix(ptr, "date:", end, &next) && - strptime(next, "%a, %d %b %Y %T", &lp->df_t) == NULL) - lp->bogus = 1; + strptime(next, "%a, %d %b %Y %T", &lp->df_t) == NULL) { + clean_logline(lp); + } break; case SLT_TxHeader: + if(!lp->active) + break; if (isprefix(ptr, "user-agent:", end, &next)) lp->df_User_agent = trimline(next, end); else if (isprefix(ptr, "referer:", end, &next)) @@ -249,14 +289,16 @@ case SLT_BackendReuse: case SLT_BackendClose: + if(!lp->active) + break; /* got it all */ - return (0); + lp->complete = 1; + break; default: break; } - /* more to come */ return (1); } @@ -273,41 +315,57 @@ switch (tag) { case SLT_ReqStart: - if (lp->df_h != NULL) - lp->bogus = 1; - else - lp->df_h = trimfield(ptr, end); + if(lp->active || lp->df_h != NULL) { + /* New start for active line, + clean it and start from scratch */ + clean_logline(lp); + } + lp->active = 1; + lp->df_h = trimfield(ptr, end); break; case SLT_RxRequest: - if (lp->df_m != NULL) - lp->bogus = 1; - else - lp->df_m = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_m != NULL) { + clean_logline(lp); + break; + } + lp->df_m = trimline(ptr, end); break; case SLT_RxURL: - if (lp->df_Uq != NULL) - lp->bogus = 1; - else - lp->df_Uq = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_Uq != NULL) { + clean_logline(lp); + break; + } + lp->df_Uq = trimline(ptr, end); break; case SLT_RxProtocol: - if (lp->df_H != NULL) - lp->bogus = 1; - else - lp->df_H = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_H != NULL) { + clean_logline(lp); + break; + } + lp->df_H = trimline(ptr, end); break; case SLT_TxStatus: + if(!lp->active) + break; if (lp->df_s != NULL) - lp->bogus = 1; + clean_logline(lp); else lp->df_s = trimline(ptr, end); break; case SLT_RxHeader: + if(!lp->active) + break; if (isprefix(ptr, "user-agent:", end, &next)) lp->df_User_agent = trimline(next, end); else if (isprefix(ptr, "referer:", end, &next)) @@ -322,33 +380,42 @@ break; case SLT_Length: - if (lp->df_b != NULL) - lp->bogus = 1; - else - lp->df_b = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_b != NULL) { + clean_logline(lp); + break; + } + lp->df_b = trimline(ptr, end); break; case SLT_SessionClose: + if(!lp->active) + break; if (strncmp(ptr, "pipe", len) == 0 || - strncmp(ptr, "error", len) == 0) - lp->bogus = 1; + strncmp(ptr, "error", len) == 0) { + clean_logline(lp); + break; + } break; case SLT_ReqEnd: + if(!lp->active) + break; if (sscanf(ptr, "%*u %*u.%*u %ld.", &l) != 1) { - lp->bogus = 1; - } else { - t = l; - localtime_r(&t, &lp->df_t); + clean_logline(lp); + break; } + t = l; + localtime_r(&t, &lp->df_t); /* got it all */ - return (0); + lp->complete = 1; + break; default: break; } - /* more to come */ return (1); } @@ -379,105 +446,95 @@ lp = ll[fd]; if (spec & VSL_S_BACKEND) { - if (collect_backend(lp, tag, spec, ptr, len)) - return (reopen); + collect_backend(lp, tag, spec, ptr, len); } else if (spec & VSL_S_CLIENT) { - if (collect_client(lp, tag, spec, ptr, len)) - return (reopen); + collect_client(lp, tag, spec, ptr, len); } else { /* huh? */ return (reopen); } + if(!lp->complete) + return (reopen); + #if 0 /* non-optional fields */ - if (!lp->df_m || !lp->df_Uq || !lp->df_H || !lp->df_s) - lp->bogus = 1; + if (!lp->df_m || !lp->df_Uq || !lp->df_H || !lp->df_s) { + clean_logline(lp); + return (reopen); + } #endif - if (!lp->bogus) { - fo = priv; + /* We have a complete data set - log a line */ - /* %h */ - if (!lp->df_h && spec & VSL_S_BACKEND) - fprintf(fo, "127.0.0.1 "); - else if (lp->df_X_Forwarded_For && prefer_x_forwarded_for) - fprintf(fo, "%s ", lp->df_X_Forwarded_For); - else - fprintf(fo, "%s ", lp->df_h ? lp->df_h : "-"); + fo = priv; - /* %l */ - fprintf(fo, "- "); + /* %h */ + if (!lp->df_h && spec & VSL_S_BACKEND) + fprintf(fo, "127.0.0.1 "); + else if (lp->df_X_Forwarded_For && prefer_x_forwarded_for) + fprintf(fo, "%s ", lp->df_X_Forwarded_For); + else + fprintf(fo, "%s ", lp->df_h ? lp->df_h : "-"); - /* %u: decode authorization string */ - if (lp->df_u != NULL) { - char *rubuf; - size_t rulen; + /* %l */ + fprintf(fo, "- "); - base64_init(); - rulen = ((strlen(lp->df_u) + 3) * 4) / 3; - rubuf = malloc(rulen); - assert(rubuf != NULL); - base64_decode(rubuf, rulen, lp->df_u); - q = strchr(rubuf, ':'); - if (q != NULL) - *q = '\0'; - fprintf(fo, "%s ", rubuf); - free(rubuf); - } else { - fprintf(fo, "- "); - } + /* %u: decode authorization string */ + if (lp->df_u != NULL) { + char *rubuf; + size_t rulen; - /* %t */ - strftime(tbuf, sizeof tbuf, "[%d/%b/%Y:%T %z]", &lp->df_t); - fprintf(fo, "%s ", tbuf); + base64_init(); + rulen = ((strlen(lp->df_u) + 3) * 4) / 3; + rubuf = malloc(rulen); + assert(rubuf != NULL); + base64_decode(rubuf, rulen, lp->df_u); + q = strchr(rubuf, ':'); + if (q != NULL) + *q = '\0'; + fprintf(fo, "%s ", rubuf); + free(rubuf); + } else { + fprintf(fo, "- "); + } - /* - * Fake "%r". This would be a lot easier if Varnish - * normalized the request URL. - */ - fprintf(fo, "\"%s ", lp->df_m); - if (lp->df_Host) { - if (strncmp(lp->df_Host, "http://", 7) != 0) - fprintf(fo, "http://"); - fprintf(fo, "%s", lp->df_Host); - } - fprintf(fo, "%s ", lp->df_Uq); - fprintf(fo, "%s\" ", lp->df_H); + /* %t */ + strftime(tbuf, sizeof tbuf, "[%d/%b/%Y:%T %z]", &lp->df_t); + fprintf(fo, "%s ", tbuf); - /* %s */ - fprintf(fo, "%s ", lp->df_s); + /* + * Fake "%r". This would be a lot easier if Varnish + * normalized the request URL. + */ + fprintf(fo, "\"%s ", lp->df_m); + if (lp->df_Host) { + if (strncmp(lp->df_Host, "http://", 7) != 0) + fprintf(fo, "http://"); + fprintf(fo, "%s", lp->df_Host); + } + fprintf(fo, "%s ", lp->df_Uq); + fprintf(fo, "%s\" ", lp->df_H); - /* %b */ - fprintf(fo, "%s ", lp->df_b ? lp->df_b : "-"); + /* %s */ + fprintf(fo, "%s ", lp->df_s); - /* %{Referer}i */ - fprintf(fo, "\"%s\" ", - lp->df_Referer ? lp->df_Referer : "-"); + /* %b */ + fprintf(fo, "%s ", lp->df_b ? lp->df_b : "-"); - /* %{User-agent}i */ - fprintf(fo, "\"%s\"\n", - lp->df_User_agent ? lp->df_User_agent : "-"); + /* %{Referer}i */ + fprintf(fo, "\"%s\" ", + lp->df_Referer ? lp->df_Referer : "-"); - /* flush the stream */ - fflush(fo); - } + /* %{User-agent}i */ + fprintf(fo, "\"%s\"\n", + lp->df_User_agent ? lp->df_User_agent : "-"); + /* flush the stream */ + fflush(fo); + /* clean up */ -#define freez(x) do { if (x) free(x); x = NULL; } while (0); - freez(lp->df_H); - freez(lp->df_Host); - freez(lp->df_Referer); - freez(lp->df_Uq); - freez(lp->df_User_agent); - freez(lp->df_X_Forwarded_For); - freez(lp->df_b); - freez(lp->df_h); - freez(lp->df_m); - freez(lp->df_s); - freez(lp->df_u); -#undef freez - memset(lp, 0, sizeof *lp); + clean_logline(lp); return (reopen); } From phk at varnish-cache.org Tue Aug 31 10:59:08 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Tue, 31 Aug 2010 12:59:08 +0200 Subject: r5163 - in trunk/varnish-cache/lib: libvcl libvmod_std Message-ID: Author: phk Date: 2010-08-31 12:59:07 +0200 (Tue, 31 Aug 2010) New Revision: 5163 Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h trunk/varnish-cache/lib/libvcl/vcc_expr.c trunk/varnish-cache/lib/libvcl/vcc_types.h trunk/varnish-cache/lib/libvmod_std/vmod.py Log: Forget the single-char type indicators, it is not preformance critical and just leads to confusion. Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-31 10:35:16 UTC (rev 5162) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-08-31 10:59:07 UTC (rev 5163) @@ -39,7 +39,7 @@ struct acl_e; enum var_type { -#define VCC_TYPE(foo, bar) foo, +#define VCC_TYPE(foo) foo, #include "vcc_types.h" #undef VCC_TYPE }; Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-31 10:35:16 UTC (rev 5162) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-31 10:59:07 UTC (rev 5163) @@ -49,7 +49,7 @@ vcc_Type(enum var_type fmt) { switch(fmt) { -#define VCC_TYPE(a, b) case a: return(#a); +#define VCC_TYPE(a) case a: return(#a); #include "vcc_types.h" #undef VCC_TYPE default: @@ -58,19 +58,6 @@ } } -static enum var_type -vcc_Ltype(char c) -{ - switch (c) { -#define VCC_TYPE(a, b) case b: return(a); -#include "vcc_types.h" -#undef VCC_TYPE - default: - assert("Unknwon Type"); - return(0); - } -} - /*-------------------------------------------------------------------- * Recognize and convert units of time, return seconds. */ @@ -413,12 +400,31 @@ /*-------------------------------------------------------------------- */ +#if 0 +#define VCC_TYPE(a) case a: return(#a); +#include "vcc_types.h" +#undef VCC_TYPE +#endif +static enum var_type +vcc_arg_type(const char **p) +{ + +#define VCC_TYPE(a) if (!strcmp(#a, *p)) { *p += strlen(#a) + 1; return (a);} +#include "vcc_types.h" +#undef VCC_TYPE + return (VOID); +} + +/*-------------------------------------------------------------------- + */ + static void vcc_expr_call(struct vcc *tl, struct expr **e, const struct symbol *sym) { const char *p, *q; struct expr *e1; + enum var_type fmt; (void)tl; (void)e; @@ -427,23 +433,23 @@ SkipToken(tl, ID); SkipToken(tl, '('); p = sym->args; - (*e)->fmt = vcc_Ltype(*p++); + (*e)->fmt = vcc_arg_type(&p); vsb_printf((*e)->vsb, "%s(sp, \v+", sym->cfunc); vsb_finish((*e)->vsb); AZ(vsb_overflowed((*e)->vsb)); q = "\v1\n\v2"; while (*p != '\0') { e1 = NULL; - vcc_expr0(tl, &e1, vcc_Ltype(*p)); + fmt = vcc_arg_type(&p); + vcc_expr0(tl, &e1, fmt); ERRCHK(tl); - assert(e1->fmt == vcc_Ltype(*p)); + assert(e1->fmt == fmt); if (e1->fmt == STRING_LIST) { e1 = vcc_expr_edit(STRING_LIST, "\v+\n\v1,\nvrt_magic_string_end\v-", e1, NULL); } *e = vcc_expr_edit((*e)->fmt, q, *e, e1); q = "\v1,\n\v2"; - p++; if (*p != '\0') SkipToken(tl, ','); } Modified: trunk/varnish-cache/lib/libvcl/vcc_types.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_types.h 2010-08-31 10:35:16 UTC (rev 5162) +++ trunk/varnish-cache/lib/libvcl/vcc_types.h 2010-08-31 10:59:07 UTC (rev 5163) @@ -29,15 +29,15 @@ */ /*lint -save -e525 -e539 */ -VCC_TYPE(VOID, 'V') -VCC_TYPE(BACKEND, 'D') -VCC_TYPE(BOOL, 'B') -VCC_TYPE(INT, 'I') -VCC_TYPE(TIME, 'T') -VCC_TYPE(DURATION, 'M') -VCC_TYPE(STRING, 'S') -VCC_TYPE(STRING_LIST, 'L') -VCC_TYPE(IP, 'A') -VCC_TYPE(HEADER, 'H') -VCC_TYPE(REAL, 'R') +VCC_TYPE(VOID) +VCC_TYPE(BACKEND) +VCC_TYPE(BOOL) +VCC_TYPE(INT) +VCC_TYPE(TIME) +VCC_TYPE(DURATION) +VCC_TYPE(STRING) +VCC_TYPE(STRING_LIST) +VCC_TYPE(IP) +VCC_TYPE(HEADER) +VCC_TYPE(REAL) /*lint -restore */ Modified: trunk/varnish-cache/lib/libvmod_std/vmod.py =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-08-31 10:35:16 UTC (rev 5162) +++ trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-08-31 10:59:07 UTC (rev 5163) @@ -48,11 +48,6 @@ type_tab = dict() -type_tab['VOID'] = "V" -type_tab['REAL'] = "R" -type_tab['STRING'] = "S" -type_tab['STRING_LIST'] = "L" - ctypes = { 'IP': "struct sockaddr *", 'STRING': "const char *", @@ -100,10 +95,10 @@ s = modname + '.' + fname + "\\0" s += "Vmod_Func_" + modname + "." + fname + "\\0" - s += type_tab[rval] + s += rval for i in args: - s += type_tab[i] - slist += '\t"' + s + '",\n' + s += '\\0' + i + slist += '\t"' + s + '\\0",\n' ####################################################################### From martin at varnish-cache.org Tue Aug 31 11:04:00 2010 From: martin at varnish-cache.org (martin at varnish-cache.org) Date: Tue, 31 Aug 2010 13:04:00 +0200 Subject: r5164 - in branches/2.1: . varnish-cache/bin/varnishd varnish-cache/bin/varnishncsa varnish-cache/bin/varnishtest/tests varnish-cache/include varnish-cache/lib/libvarnish varnish-cache/lib/libvcl Message-ID: Author: martin Date: 2010-08-31 13:03:59 +0200 (Tue, 31 Aug 2010) New Revision: 5164 Modified: branches/2.1/ branches/2.1/varnish-cache/bin/varnishd/cache_backend.h branches/2.1/varnish-cache/bin/varnishd/cache_backend_cfg.c branches/2.1/varnish-cache/bin/varnishd/vparam.h branches/2.1/varnish-cache/bin/varnishncsa/varnishncsa.c branches/2.1/varnish-cache/bin/varnishtest/tests/c00019.vtc branches/2.1/varnish-cache/bin/varnishtest/tests/r00325.vtc branches/2.1/varnish-cache/bin/varnishtest/tests/r00416.vtc branches/2.1/varnish-cache/bin/varnishtest/tests/v00011.vtc branches/2.1/varnish-cache/include/vct.h branches/2.1/varnish-cache/include/vev.h branches/2.1/varnish-cache/lib/libvarnish/tcp.c branches/2.1/varnish-cache/lib/libvarnish/vev.c branches/2.1/varnish-cache/lib/libvcl/vcc_dir_random.c Log: Merge r5162: Make varnishncsa only consider log information between the open and close log tags for a connection, and clear the collected log data on seeing the open tag. This resolves an issue with log data where varnishncsa would consider a set of data as bogus because of extra data in the log belonging to the previous connection. Support case 164. Property changes on: branches/2.1 ___________________________________________________________________ Modified: svn:mergeinfo - /trunk:4637,4640,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk:4637,4640,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Property changes on: branches/2.1/varnish-cache/bin/varnishd/cache_backend.h ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/bin/varnishd/cache_backend.h:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/bin/varnishd/cache_backend.h:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Property changes on: branches/2.1/varnish-cache/bin/varnishd/cache_backend_cfg.c ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Property changes on: branches/2.1/varnish-cache/bin/varnishd/vparam.h ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/bin/varnishd/vparam.h:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/bin/varnishd/vparam.h:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Modified: branches/2.1/varnish-cache/bin/varnishncsa/varnishncsa.c =================================================================== --- branches/2.1/varnish-cache/bin/varnishncsa/varnishncsa.c 2010-08-31 10:59:07 UTC (rev 5163) +++ branches/2.1/varnish-cache/bin/varnishncsa/varnishncsa.c 2010-08-31 11:03:59 UTC (rev 5164) @@ -96,7 +96,8 @@ char *df_s; /* %s, Status */ struct tm df_t; /* %t, Date and time */ char *df_u; /* %u, Remote user */ - int bogus; /* bogus request */ + int active; /* Is log line in an active trans */ + int complete; /* Is log line complete */ } **ll; static size_t nll; @@ -177,6 +178,25 @@ return (p); } +static void +clean_logline(struct logline *lp) +{ +#define freez(x) do { if (x) free(x); x = NULL; } while (0); + freez(lp->df_H); + freez(lp->df_Host); + freez(lp->df_Referer); + freez(lp->df_Uq); + freez(lp->df_User_agent); + freez(lp->df_X_Forwarded_For); + freez(lp->df_b); + freez(lp->df_h); + freez(lp->df_m); + freez(lp->df_s); + freez(lp->df_u); +#undef freez + memset(lp, 0, sizeof *lp); +} + static int collect_backend(struct logline *lp, enum shmlogtag tag, unsigned spec, const char *ptr, unsigned len) @@ -188,52 +208,72 @@ switch (tag) { case SLT_BackendOpen: - if (lp->df_h != NULL) - lp->bogus = 1; + if(lp->active || lp->df_h != NULL) { + /* New start for active line, + clean it and start from scratch */ + clean_logline(lp); + } + lp->active = 1; + if (isprefix(ptr, "default", end, &next)) + lp->df_h = trimfield(next, end); else - if (isprefix(ptr, "default", end, &next)) - lp->df_h = trimfield(next, end); - else - lp->df_h = trimfield(ptr, end); + lp->df_h = trimfield(ptr, end); break; case SLT_TxRequest: - if (lp->df_m != NULL) - lp->bogus = 1; - else - lp->df_m = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_m != NULL) { + clean_logline(lp); + break; + } + lp->df_m = trimline(ptr, end); break; case SLT_TxURL: - if (lp->df_Uq != NULL) - lp->bogus = 1; - else - lp->df_Uq = trimline(ptr, end); + if(!lp->active) + break; + if(lp->df_Uq != NULL) { + clean_logline(lp); + break; + } + lp->df_Uq = trimline(ptr, end); break; case SLT_TxProtocol: - if (lp->df_H != NULL) - lp->bogus = 1; - else - lp->df_H = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_H != NULL) { + clean_logline(lp); + break; + } + lp->df_H = trimline(ptr, end); break; case SLT_RxStatus: - if (lp->df_s != NULL) - lp->bogus = 1; - else - lp->df_s = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_s != NULL) { + clean_logline(lp); + break; + } + lp->df_s = trimline(ptr, end); break; case SLT_RxHeader: + if(!lp->active) + break; if (isprefix(ptr, "content-length:", end, &next)) lp->df_b = trimline(next, end); else if (isprefix(ptr, "date:", end, &next) && - strptime(next, "%a, %d %b %Y %T", &lp->df_t) == NULL) - lp->bogus = 1; + strptime(next, "%a, %d %b %Y %T", &lp->df_t) == NULL) { + clean_logline(lp); + } break; case SLT_TxHeader: + if(!lp->active) + break; if (isprefix(ptr, "user-agent:", end, &next)) lp->df_User_agent = trimline(next, end); else if (isprefix(ptr, "referer:", end, &next)) @@ -249,14 +289,16 @@ case SLT_BackendReuse: case SLT_BackendClose: + if(!lp->active) + break; /* got it all */ - return (0); + lp->complete = 1; + break; default: break; } - /* more to come */ return (1); } @@ -273,41 +315,57 @@ switch (tag) { case SLT_ReqStart: - if (lp->df_h != NULL) - lp->bogus = 1; - else - lp->df_h = trimfield(ptr, end); + if(lp->active || lp->df_h != NULL) { + /* New start for active line, + clean it and start from scratch */ + clean_logline(lp); + } + lp->active = 1; + lp->df_h = trimfield(ptr, end); break; case SLT_RxRequest: - if (lp->df_m != NULL) - lp->bogus = 1; - else - lp->df_m = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_m != NULL) { + clean_logline(lp); + break; + } + lp->df_m = trimline(ptr, end); break; case SLT_RxURL: - if (lp->df_Uq != NULL) - lp->bogus = 1; - else - lp->df_Uq = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_Uq != NULL) { + clean_logline(lp); + break; + } + lp->df_Uq = trimline(ptr, end); break; case SLT_RxProtocol: - if (lp->df_H != NULL) - lp->bogus = 1; - else - lp->df_H = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_H != NULL) { + clean_logline(lp); + break; + } + lp->df_H = trimline(ptr, end); break; case SLT_TxStatus: + if(!lp->active) + break; if (lp->df_s != NULL) - lp->bogus = 1; + clean_logline(lp); else lp->df_s = trimline(ptr, end); break; case SLT_RxHeader: + if(!lp->active) + break; if (isprefix(ptr, "user-agent:", end, &next)) lp->df_User_agent = trimline(next, end); else if (isprefix(ptr, "referer:", end, &next)) @@ -322,33 +380,42 @@ break; case SLT_Length: - if (lp->df_b != NULL) - lp->bogus = 1; - else - lp->df_b = trimline(ptr, end); + if(!lp->active) + break; + if (lp->df_b != NULL) { + clean_logline(lp); + break; + } + lp->df_b = trimline(ptr, end); break; case SLT_SessionClose: + if(!lp->active) + break; if (strncmp(ptr, "pipe", len) == 0 || - strncmp(ptr, "error", len) == 0) - lp->bogus = 1; + strncmp(ptr, "error", len) == 0) { + clean_logline(lp); + break; + } break; case SLT_ReqEnd: + if(!lp->active) + break; if (sscanf(ptr, "%*u %*u.%*u %ld.", &l) != 1) { - lp->bogus = 1; - } else { - t = l; - localtime_r(&t, &lp->df_t); + clean_logline(lp); + break; } + t = l; + localtime_r(&t, &lp->df_t); /* got it all */ - return (0); + lp->complete = 1; + break; default: break; } - /* more to come */ return (1); } @@ -379,105 +446,95 @@ lp = ll[fd]; if (spec & VSL_S_BACKEND) { - if (collect_backend(lp, tag, spec, ptr, len)) - return (reopen); + collect_backend(lp, tag, spec, ptr, len); } else if (spec & VSL_S_CLIENT) { - if (collect_client(lp, tag, spec, ptr, len)) - return (reopen); + collect_client(lp, tag, spec, ptr, len); } else { /* huh? */ return (reopen); } + if(!lp->complete) + return (reopen); + #if 0 /* non-optional fields */ - if (!lp->df_m || !lp->df_Uq || !lp->df_H || !lp->df_s) - lp->bogus = 1; + if (!lp->df_m || !lp->df_Uq || !lp->df_H || !lp->df_s) { + clean_logline(lp); + return (reopen); + } #endif - if (!lp->bogus) { - fo = priv; + /* We have a complete data set - log a line */ - /* %h */ - if (!lp->df_h && spec & VSL_S_BACKEND) - fprintf(fo, "127.0.0.1 "); - else if (lp->df_X_Forwarded_For && prefer_x_forwarded_for) - fprintf(fo, "%s ", lp->df_X_Forwarded_For); - else - fprintf(fo, "%s ", lp->df_h ? lp->df_h : "-"); + fo = priv; - /* %l */ - fprintf(fo, "- "); + /* %h */ + if (!lp->df_h && spec & VSL_S_BACKEND) + fprintf(fo, "127.0.0.1 "); + else if (lp->df_X_Forwarded_For && prefer_x_forwarded_for) + fprintf(fo, "%s ", lp->df_X_Forwarded_For); + else + fprintf(fo, "%s ", lp->df_h ? lp->df_h : "-"); - /* %u: decode authorization string */ - if (lp->df_u != NULL) { - char *rubuf; - size_t rulen; + /* %l */ + fprintf(fo, "- "); - base64_init(); - rulen = ((strlen(lp->df_u) + 3) * 4) / 3; - rubuf = malloc(rulen); - assert(rubuf != NULL); - base64_decode(rubuf, rulen, lp->df_u); - q = strchr(rubuf, ':'); - if (q != NULL) - *q = '\0'; - fprintf(fo, "%s ", rubuf); - free(rubuf); - } else { - fprintf(fo, "- "); - } + /* %u: decode authorization string */ + if (lp->df_u != NULL) { + char *rubuf; + size_t rulen; - /* %t */ - strftime(tbuf, sizeof tbuf, "[%d/%b/%Y:%T %z]", &lp->df_t); - fprintf(fo, "%s ", tbuf); + base64_init(); + rulen = ((strlen(lp->df_u) + 3) * 4) / 3; + rubuf = malloc(rulen); + assert(rubuf != NULL); + base64_decode(rubuf, rulen, lp->df_u); + q = strchr(rubuf, ':'); + if (q != NULL) + *q = '\0'; + fprintf(fo, "%s ", rubuf); + free(rubuf); + } else { + fprintf(fo, "- "); + } - /* - * Fake "%r". This would be a lot easier if Varnish - * normalized the request URL. - */ - fprintf(fo, "\"%s ", lp->df_m); - if (lp->df_Host) { - if (strncmp(lp->df_Host, "http://", 7) != 0) - fprintf(fo, "http://"); - fprintf(fo, "%s", lp->df_Host); - } - fprintf(fo, "%s ", lp->df_Uq); - fprintf(fo, "%s\" ", lp->df_H); + /* %t */ + strftime(tbuf, sizeof tbuf, "[%d/%b/%Y:%T %z]", &lp->df_t); + fprintf(fo, "%s ", tbuf); - /* %s */ - fprintf(fo, "%s ", lp->df_s); + /* + * Fake "%r". This would be a lot easier if Varnish + * normalized the request URL. + */ + fprintf(fo, "\"%s ", lp->df_m); + if (lp->df_Host) { + if (strncmp(lp->df_Host, "http://", 7) != 0) + fprintf(fo, "http://"); + fprintf(fo, "%s", lp->df_Host); + } + fprintf(fo, "%s ", lp->df_Uq); + fprintf(fo, "%s\" ", lp->df_H); - /* %b */ - fprintf(fo, "%s ", lp->df_b ? lp->df_b : "-"); + /* %s */ + fprintf(fo, "%s ", lp->df_s); - /* %{Referer}i */ - fprintf(fo, "\"%s\" ", - lp->df_Referer ? lp->df_Referer : "-"); + /* %b */ + fprintf(fo, "%s ", lp->df_b ? lp->df_b : "-"); - /* %{User-agent}i */ - fprintf(fo, "\"%s\"\n", - lp->df_User_agent ? lp->df_User_agent : "-"); + /* %{Referer}i */ + fprintf(fo, "\"%s\" ", + lp->df_Referer ? lp->df_Referer : "-"); - /* flush the stream */ - fflush(fo); - } + /* %{User-agent}i */ + fprintf(fo, "\"%s\"\n", + lp->df_User_agent ? lp->df_User_agent : "-"); + /* flush the stream */ + fflush(fo); + /* clean up */ -#define freez(x) do { if (x) free(x); x = NULL; } while (0); - freez(lp->df_H); - freez(lp->df_Host); - freez(lp->df_Referer); - freez(lp->df_Uq); - freez(lp->df_User_agent); - freez(lp->df_X_Forwarded_For); - freez(lp->df_b); - freez(lp->df_h); - freez(lp->df_m); - freez(lp->df_s); - freez(lp->df_u); -#undef freez - memset(lp, 0, sizeof *lp); + clean_logline(lp); return (reopen); } Property changes on: branches/2.1/varnish-cache/bin/varnishtest/tests/c00019.vtc ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/bin/varnishtest/tests/c00019.vtc:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/bin/varnishtest/tests/c00019.vtc:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Property changes on: branches/2.1/varnish-cache/bin/varnishtest/tests/r00325.vtc ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/bin/varnishtest/tests/r00325.vtc:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/bin/varnishtest/tests/r00325.vtc:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Property changes on: branches/2.1/varnish-cache/bin/varnishtest/tests/r00416.vtc ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/bin/varnishtest/tests/r00416.vtc:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/bin/varnishtest/tests/r00416.vtc:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Property changes on: branches/2.1/varnish-cache/bin/varnishtest/tests/v00011.vtc ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/bin/varnishtest/tests/v00011.vtc:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/bin/varnishtest/tests/v00011.vtc:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Property changes on: branches/2.1/varnish-cache/include/vct.h ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/include/vct.h:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/include/vct.h:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Property changes on: branches/2.1/varnish-cache/include/vev.h ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/include/vev.h:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/include/vev.h:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Property changes on: branches/2.1/varnish-cache/lib/libvarnish/tcp.c ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/lib/libvarnish/tcp.c:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/lib/libvarnish/tcp.c:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Property changes on: branches/2.1/varnish-cache/lib/libvarnish/vev.c ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/lib/libvarnish/vev.c:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/lib/libvarnish/vev.c:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 Property changes on: branches/2.1/varnish-cache/lib/libvcl/vcc_dir_random.c ___________________________________________________________________ Modified: svn:mergeinfo - /trunk/varnish-cache/lib/libvcl/vcc_dir_random.c:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048 + /trunk/varnish-cache/lib/libvcl/vcc_dir_random.c:4637,4643-4650,4654-4670,4686,4689-4690,4700,4712,4715-4719,4731,4749-4750,4757-4758,4762,4783,4818,4823,4829,4842,4859-4861,4864-4868,4912,4967-4968,4971,4973-4975,4977,4979-4981,4986,4989,5016,5048,5162 From phk at varnish-cache.org Tue Aug 31 11:07:52 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Tue, 31 Aug 2010 13:07:52 +0200 Subject: r5165 - trunk/varnish-cache/lib/libvmod_std Message-ID: Author: phk Date: 2010-08-31 13:07:52 +0200 (Tue, 31 Aug 2010) New Revision: 5165 Modified: trunk/varnish-cache/lib/libvmod_std/vmod_std.c Log: Eliminate pointless code duplication Modified: trunk/varnish-cache/lib/libvmod_std/vmod_std.c =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod_std.c 2010-08-31 11:03:59 UTC (rev 5164) +++ trunk/varnish-cache/lib/libvmod_std/vmod_std.c 2010-08-31 11:07:52 UTC (rev 5165) @@ -5,23 +5,24 @@ #include "vcc_if.h" -const char * -vmod_toupper(struct sess *sp, const char *s, ...) +static const char * +vmod_updown(struct sess *sp, int up, const char *s, va_list ap) { - va_list ap; unsigned u; char *b, *e; const char *p; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - va_start(ap, s); u = WS_Reserve(sp->wrk->ws, 0); e = b = sp->wrk->ws->f; e += u; p = s; while (p != vrt_magic_string_end && b < e) { for (; b < e && *p != '\0'; p++) - *b++ = toupper(*p); + if (up) + *b++ = toupper(*p); + else + *b++ = tolower(*p); p = va_arg(ap, const char *); } if (b < e) @@ -39,34 +40,27 @@ } const char * -vmod_tolower(struct sess *sp, const char *s, ...) +vmod_toupper(struct sess *sp, const char *s, ...) { + const char *p; va_list ap; - unsigned u; - char *b, *e; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + va_start(ap, s); + p = vmod_updown(sp, 1, s, ap); + va_end(ap); + return (p); +} + +const char * +vmod_tolower(struct sess *sp, const char *s, ...) +{ const char *p; + va_list ap; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); va_start(ap, s); - u = WS_Reserve(sp->wrk->ws, 0); - e = b = sp->wrk->ws->f; - e += u; - p = s; - while (p != vrt_magic_string_end && b < e) { - for (; b < e && *p != '\0'; p++) - *b++ = tolower(*p); - p = va_arg(ap, const char *); - } - if (b < e) - *b = '\0'; - b++; - if (b > e) { - WS_Release(sp->wrk->ws, 0); - return (NULL); - } else { - e = b; - b = sp->wrk->ws->f; - WS_Release(sp->wrk->ws, e - b); - return (b); - } + p = vmod_updown(sp, 0, s, ap); + va_end(ap); + return (p); } From phk at varnish-cache.org Tue Aug 31 11:56:08 2010 From: phk at varnish-cache.org (phk at varnish-cache.org) Date: Tue, 31 Aug 2010 13:56:08 +0200 Subject: r5166 - in trunk/varnish-cache: include lib/libvcl lib/libvmod_std Message-ID: Author: phk Date: 2010-08-31 13:56:08 +0200 (Tue, 31 Aug 2010) New Revision: 5166 Modified: trunk/varnish-cache/include/vrt.h trunk/varnish-cache/lib/libvcl/vcc_expr.c trunk/varnish-cache/lib/libvcl/vcc_vmod.c trunk/varnish-cache/lib/libvmod_std/vmod.py trunk/varnish-cache/lib/libvmod_std/vmod.vcc trunk/varnish-cache/lib/libvmod_std/vmod_std.c Log: Add a "metafunction" facility to VMOD, which tells modules whenever a new VCL program initializes of finishes. This also gives access to a per-VCL private void* which can be passed as a hidden argument to the member functions. If modules hold any global state, they should use the meta function to keep track of when the last VCL program finishes and clean up their internal global state then. Modified: trunk/varnish-cache/include/vrt.h =================================================================== --- trunk/varnish-cache/include/vrt.h 2010-08-31 11:07:52 UTC (rev 5165) +++ trunk/varnish-cache/include/vrt.h 2010-08-31 11:56:08 UTC (rev 5166) @@ -189,6 +189,7 @@ void VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path); void VRT_Vmod_Fini(void **hdl); +typedef int vmod_meta_f(void **, const struct VCL_conf *); /* Convert things to string */ Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-31 11:07:52 UTC (rev 5165) +++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-08-31 11:56:08 UTC (rev 5166) @@ -422,7 +422,7 @@ static void vcc_expr_call(struct vcc *tl, struct expr **e, const struct symbol *sym) { - const char *p, *q; + const char *p, *q, *r; struct expr *e1; enum var_type fmt; @@ -441,17 +441,29 @@ while (*p != '\0') { e1 = NULL; fmt = vcc_arg_type(&p); - vcc_expr0(tl, &e1, fmt); - ERRCHK(tl); - assert(e1->fmt == fmt); - if (e1->fmt == STRING_LIST) { - e1 = vcc_expr_edit(STRING_LIST, - "\v+\n\v1,\nvrt_magic_string_end\v-", e1, NULL); + if (fmt == VOID && !strcmp(p, "PRIV_VCL")) { + e1 = vcc_new_expr(); + r = strchr(sym->name, '.'); + AN(r); + vsb_printf(e1->vsb, "&vmod_priv_%.*s", + r - sym->name, sym->name); + vsb_finish(e1->vsb); + AZ(vsb_overflowed(e1->vsb)); + p += strlen(p) + 1; + } else { + vcc_expr0(tl, &e1, fmt); + ERRCHK(tl); + assert(e1->fmt == fmt); + if (e1->fmt == STRING_LIST) { + e1 = vcc_expr_edit(STRING_LIST, + "\v+\n\v1,\nvrt_magic_string_end\v-", + e1, NULL); + } + if (*p != '\0') + SkipToken(tl, ','); } *e = vcc_expr_edit((*e)->fmt, q, *e, e1); q = "\v1,\n\v2"; - if (*p != '\0') - SkipToken(tl, ','); } SkipToken(tl, ')'); *e = vcc_expr_edit((*e)->fmt, "\v1\n)\v-", *e, NULL); Modified: trunk/varnish-cache/lib/libvcl/vcc_vmod.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_vmod.c 2010-08-31 11:07:52 UTC (rev 5165) +++ trunk/varnish-cache/lib/libvcl/vcc_vmod.c 2010-08-31 11:56:08 UTC (rev 5166) @@ -128,11 +128,18 @@ } for (; *spec != NULL; spec++) { p = *spec; - sym = VCC_AddSymbol(tl, p); - p += strlen(p) + 1; - sym->cfunc = p; - p += strlen(p) + 1; - sym->args = p; + if (!strcmp(p, "META")) { + p += strlen(p) + 1; + Fh(tl, 0, "static void *vmod_priv_%.*s;\n", PF(mod)); + Fi(tl, 0, "\t%s(&vmod_priv_%.*s, &VCL_conf);\n", p, PF(mod)); + Ff(tl, 0, "\t%s(&vmod_priv_%.*s, 0);\n", p, PF(mod)); + } else { + sym = VCC_AddSymbol(tl, p); + p += strlen(p) + 1; + sym->cfunc = p; + p += strlen(p) + 1; + sym->args = p; + } } Fh(tl, 0, "\n%s\n", proto); } Modified: trunk/varnish-cache/lib/libvmod_std/vmod.py =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-08-31 11:07:52 UTC (rev 5165) +++ trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-08-31 11:56:08 UTC (rev 5166) @@ -59,10 +59,12 @@ 'DURATION': "double", 'INT': "int", 'HEADER': "const char *", + 'PRIV_VCL': "void **", } ####################################################################### +metaname = "" modname = "???" pstruct = "" pinit = "" @@ -79,7 +81,7 @@ print(fname, rval, args) proto = ctypes[rval] + " vmod_" + fname + "(struct sess *" - sproto = ctypes[rval] + " td_" + fname + "(struct sess *" + sproto = ctypes[rval] + " td_" + modname + "_" + fname + "(struct sess *" s=", " for i in args: proto += s + ctypes[i] @@ -88,9 +90,9 @@ sproto += ")" plist += proto + ";\n" - tdl += "typedef\t" + sproto + ";\n" + tdl += "typedef " + sproto + ";\n" - pstruct += "\ttd_" + fname + "\t*" + fname + ";\n" + pstruct += "\ttd_" + modname + "_" + fname + "\t*" + fname + ";\n" pinit += "\tvmod_" + fname + ",\n" s = modname + '.' + fname + "\\0" @@ -120,6 +122,10 @@ modname = l[2].strip(); continue + if l[0] == "Meta": + metaname = l[2].strip(); + continue + if l[0] != "Function": assert False @@ -151,18 +157,28 @@ ####################################################################### +if metaname != "": + plist += "int " + metaname + "(void **, const struct VCL_conf *);\n" + pstruct += "\tvmod_meta_f\t*_meta;\n" + pinit += "\t" + metaname + ",\n" + slist += '\t"META\\0Vmod_Func_' + modname + '._meta",\n' + +####################################################################### + fc = open("vcc_if.c", "w") fh = open("vcc_if.h", "w") fh.write('struct sess;\n') +fh.write('struct VCL_conf;\n') fh.write("\n"); fh.write(plist) + fc.write('#include "vcc_if.h"\n') +fc.write('#include "vrt.h"\n') fc.write("\n"); -fc.write('struct sess;\n') fc.write("\n"); fc.write(tdl); @@ -186,3 +202,6 @@ fc.write("\n"); fc.write('const char *Vmod_Spec[] = {\n' + slist + '\t0\n};\n') + +fc.write("\n") + Modified: trunk/varnish-cache/lib/libvmod_std/vmod.vcc =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod.vcc 2010-08-31 11:07:52 UTC (rev 5165) +++ trunk/varnish-cache/lib/libvmod_std/vmod.vcc 2010-08-31 11:56:08 UTC (rev 5166) @@ -1,3 +1,4 @@ Module std +Meta meta_function Function STRING toupper(STRING_LIST) -Function STRING tolower(STRING_LIST) +Function STRING tolower(PRIV_VCL, STRING_LIST) Modified: trunk/varnish-cache/lib/libvmod_std/vmod_std.c =================================================================== --- trunk/varnish-cache/lib/libvmod_std/vmod_std.c 2010-08-31 11:07:52 UTC (rev 5165) +++ trunk/varnish-cache/lib/libvmod_std/vmod_std.c 2010-08-31 11:56:08 UTC (rev 5166) @@ -53,14 +53,31 @@ } const char * -vmod_tolower(struct sess *sp, const char *s, ...) +vmod_tolower(struct sess *sp, void **vcl_priv, const char *s, ...) { const char *p; va_list ap; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + assert(*vcl_priv == (void *)8); va_start(ap, s); p = vmod_updown(sp, 0, s, ap); va_end(ap); return (p); } + +int +meta_function(void **priv, const struct VCL_conf *cfg) +{ + if (cfg != NULL) { + // Initialization in new VCL program + // Hang any private data/state off *priv + *priv = (void *)8; + } else { + // Cleaup in new VCL program + // Cleanup/Free any private data/state hanging of *priv + assert(*priv == (void *)8); + *priv = NULL; + } + return (0); +}