From roger at seriousorange.com Mon Dec 3 08:35:58 2012 From: roger at seriousorange.com (Roger Nesbitt) Date: Mon, 3 Dec 2012 08:35:58 +0000 Subject: PROXY protocol Message-ID: <14131780-63FD-41FD-A3C0-B249A61C92C3@seriousorange.com> Hello, I've got a big chunk of time free and would like to scratch my own itch by implementing the PROXY protocol, as defined at this URL: http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt My thoughts are to initially implement version 1 of the protocol as part of the HTTP server component. This will allow SSL frontends such as stunnel to pass through client IP information, a feature that seems to be often requested. I'm completely new to the Varnish source; after having a little look today I assume that a VMOD will not be possible due to the integration required into the HTTP parser. On first looks, I'm thinking of a detection hook in http1_detect(), although I'd have to figure out some way to indicate that it's the first http request handled on a new connection. If a PROXY line is detected, the code would put the source/destination IP addresses and ports into new variables (maybe something like proxy.source_ip, proxy.dest_ip, proxy.source_port, proxy.dest_port) and leave it up to the user to build an X-Forwarded-For header in VCL should they wish (after checking that client.ip is trusted.) Detecting the PROXY line should just be a single memcmp; I'm not sure whether the community would want this feature to be able to be manually enabled and disabled. Is anyone else currently working on this? Does this idea and general strategy seem sound? Thanks for your help and suggestions. Roger -------------- next part -------------- An HTML attachment was scrubbed... URL: From phk at phk.freebsd.dk Mon Dec 3 09:24:33 2012 From: phk at phk.freebsd.dk (Poul-Henning Kamp) Date: Mon, 03 Dec 2012 09:24:33 +0000 Subject: a6b9848 Eliminated duplicated code for trimming the tail of the banlist. In-Reply-To: References: Message-ID: <5480.1354526673@critter.freebsd.dk> -------- In message , Martin Blix Grydeland writes: >I was looking at this patch, and I believe there is a problem with regard >to how you implemented this. > >I believe the loop in ban_lurker() around successful ban_lurker_work calls >when the ban_lurker is enabled, has the potential of running for much >longer than intended. So long as there is a new ban added at an interval >shorter than 2*ban_lurker_sleep, this loop will continue running, and then >no tail bans will ever be dropped. I have added a tail-trimming operation for every 10 successfull iterations of the ban-lurker. -- Poul-Henning Kamp | UNIX since Zilog Zeus 3.20 phk at FreeBSD.ORG | TCP/IP since RFC 956 FreeBSD committer | BSD since 4.3-tahoe Never attribute to malice what can adequately be explained by incompetence. From martin at varnish-software.com Mon Dec 3 10:09:49 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 3 Dec 2012 11:09:49 +0100 Subject: [PATCH 1/7] Fix bug in smp_baninfo causing duplicate ban entries. Message-ID: <1354529395-6805-1-git-send-email-martin@varnish-software.com> When generalizing the ban event reporting to the stevedores, where the event was reported first for each stevedore, and then for each silo on the global silos list. Fix this by adding a flag for when the silo is fully opened and ready for accepting ban events, and don't recurse on the global silos list. --- bin/varnishd/storage/storage_persistent.c | 16 +++++++++++----- bin/varnishd/storage/storage_persistent.h | 5 +++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c index 1efa24b..e2cf429 100644 --- a/bin/varnishd/storage/storage_persistent.c +++ b/bin/varnishd/storage/storage_persistent.c @@ -88,13 +88,16 @@ smp_baninfo(struct stevedore *stv, enum baninfo event, { struct smp_sc *sc; - (void)stv; + CAST_OBJ_NOTNULL(sc, stv->priv, SMP_SC_MAGIC); + + if (!(sc->flags & SMP_SC_OPENED)) + /* Ignore ban events until we have been opened */ + return; + switch (event) { case BI_NEW: - VTAILQ_FOREACH(sc, &silos, list) { - smp_appendban(sc, &sc->ban1, len, ban); - smp_appendban(sc, &sc->ban2, len, ban); - } + smp_appendban(sc, &sc->ban1, len, ban); + smp_appendban(sc, &sc->ban2, len, ban); break; default: /* Ignored */ @@ -331,6 +334,9 @@ smp_open(const struct stevedore *st) if (smp_open_segs(sc, &sc->seg1)) AZ(smp_open_segs(sc, &sc->seg2)); + /* We are now open for business */ + sc->flags |= SMP_SC_OPENED; + /* * Grap a reference to the tail of the ban list, until the thread * has loaded all objects, so we can be sure that all of our diff --git a/bin/varnishd/storage/storage_persistent.h b/bin/varnishd/storage/storage_persistent.h index cb2efb3..6609e78 100644 --- a/bin/varnishd/storage/storage_persistent.h +++ b/bin/varnishd/storage/storage_persistent.h @@ -106,8 +106,9 @@ struct smp_sc { pthread_t bgthread; unsigned flags; -#define SMP_SC_LOADED (1 << 0) -#define SMP_SC_STOP (1 << 1) +#define SMP_SC_OPENED (1 << 0) +#define SMP_SC_LOADED (1 << 1) +#define SMP_SC_STOP (1 << 2) const struct stevedore *stevedore; int fd; -- 1.7.10.4 From martin at varnish-software.com Mon Dec 3 10:09:50 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 3 Dec 2012 11:09:50 +0100 Subject: [PATCH 2/7] Report BAN event persistence failures back to cache_ban.c In-Reply-To: <1354529395-6805-1-git-send-email-martin@varnish-software.com> References: <1354529395-6805-1-git-send-email-martin@varnish-software.com> Message-ID: <1354529395-6805-2-git-send-email-martin@varnish-software.com> --- bin/varnishd/cache/cache.h | 2 +- bin/varnishd/cache/cache_ban.c | 6 +++--- bin/varnishd/storage/stevedore.c | 13 +++++++++++-- bin/varnishd/storage/storage.h | 2 +- bin/varnishd/storage/storage_persistent.c | 18 ++++++++++++------ 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 4b29167..6a0d1a4 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -1060,7 +1060,7 @@ void STV_free(struct storage *st); void STV_open(void); void STV_close(void); void STV_Freestore(struct object *o); -void STV_BanInfo(enum baninfo event, const uint8_t *ban, unsigned len); +int STV_BanInfo(enum baninfo event, const uint8_t *ban, unsigned len); /* storage_synth.c */ struct vsb *SMS_Makesynth(struct object *obj); diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index 57fadb9..21abf41 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -476,7 +476,7 @@ BAN_Insert(struct ban *b) else be = NULL; - STV_BanInfo(BI_NEW, b->spec, ln); /* Notify stevedores */ + AZ(STV_BanInfo(BI_NEW, b->spec, ln)); /* Notify stevedores */ Lck_Unlock(&ban_mtx); if (be == NULL) @@ -682,7 +682,7 @@ BAN_Compile(void) AZ(ban_shutdown); /* Notify stevedores */ - STV_BanInfo(BI_NEW, ban_magic->spec, ban_len(ban_magic->spec)); + AZ(STV_BanInfo(BI_NEW, ban_magic->spec, ban_len(ban_magic->spec))); ban_start = VTAILQ_FIRST(&ban_head); WRK_BgThread(&ban_thread, "ban-lurker", ban_lurker, NULL); @@ -875,7 +875,7 @@ ban_cleantail(void) VSC_C_main->bans--; VSC_C_main->bans_deleted++; VTAILQ_REMOVE(&ban_head, b, list); - STV_BanInfo(BI_DROP, b->spec, ban_len(b->spec)); + AZ(STV_BanInfo(BI_DROP, b->spec, ban_len(b->spec))); } else { b = NULL; } diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c index 5262b70..be16057 100644 --- a/bin/varnishd/storage/stevedore.c +++ b/bin/varnishd/storage/stevedore.c @@ -453,14 +453,23 @@ STV_close(void) stv->close(stv); } -void +/*------------------------------------------------------------------- + * Notify the stevedores of BAN related events. A non-zero return + * value indicates that the stevedore is unable to persist the + * event. + */ + +int STV_BanInfo(enum baninfo event, const uint8_t *ban, unsigned len) { struct stevedore *stv; + int r = 0; VTAILQ_FOREACH(stv, &stv_stevedores, list) if (stv->baninfo != NULL) - stv->baninfo(stv, event, ban, len); + r |= stv->baninfo(stv, event, ban, len); + + return (r); } /*-------------------------------------------------------------------- diff --git a/bin/varnishd/storage/storage.h b/bin/varnishd/storage/storage.h index e9971e7..cddf6ef 100644 --- a/bin/varnishd/storage/storage.h +++ b/bin/varnishd/storage/storage.h @@ -48,7 +48,7 @@ typedef struct object *storage_allocobj_f(struct stevedore *, struct busyobj *, struct objcore **, unsigned ltot, const struct stv_objsecrets *); typedef void storage_close_f(const struct stevedore *); typedef void storage_signal_close_f(const struct stevedore *); -typedef void storage_baninfo_f(struct stevedore *, enum baninfo event, +typedef int storage_baninfo_f(struct stevedore *, enum baninfo event, const uint8_t *ban, unsigned len); /* Prototypes for VCL variable responders */ diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c index e2cf429..d02ae88 100644 --- a/bin/varnishd/storage/storage_persistent.c +++ b/bin/varnishd/storage/storage_persistent.c @@ -68,41 +68,47 @@ static VTAILQ_HEAD(,smp_sc) silos = VTAILQ_HEAD_INITIALIZER(silos); * Add bans to silos */ -static void +static int smp_appendban(struct smp_sc *sc, struct smp_signspace *spc, uint32_t len, const uint8_t *ban) { (void)sc; - assert(SIGNSPACE_FREE(spc) >= len); + if (SIGNSPACE_FREE(spc) < len) + return (-1); memcpy(SIGNSPACE_FRONT(spc), ban, len); smp_append_signspace(spc, len); + + return (0); } /* Trust that cache_ban.c takes care of locking */ -static void +static int smp_baninfo(struct stevedore *stv, enum baninfo event, const uint8_t *ban, unsigned len) { struct smp_sc *sc; + int r = 0; CAST_OBJ_NOTNULL(sc, stv->priv, SMP_SC_MAGIC); if (!(sc->flags & SMP_SC_OPENED)) /* Ignore ban events until we have been opened */ - return; + return (0); switch (event) { case BI_NEW: - smp_appendban(sc, &sc->ban1, len, ban); - smp_appendban(sc, &sc->ban2, len, ban); + r |= smp_appendban(sc, &sc->ban1, len, ban); + r |= smp_appendban(sc, &sc->ban2, len, ban); break; default: /* Ignored */ break; } + + return (r); } /*-------------------------------------------------------------------- -- 1.7.10.4 From martin at varnish-software.com Mon Dec 3 10:09:54 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 3 Dec 2012 11:09:54 +0100 Subject: [PATCH 6/7] Add a test case for ban list syncing across silos In-Reply-To: <1354529395-6805-1-git-send-email-martin@varnish-software.com> References: <1354529395-6805-1-git-send-email-martin@varnish-software.com> Message-ID: <1354529395-6805-6-git-send-email-martin@varnish-software.com> --- bin/varnishtest/tests/p00008.vtc | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 bin/varnishtest/tests/p00008.vtc diff --git a/bin/varnishtest/tests/p00008.vtc b/bin/varnishtest/tests/p00008.vtc new file mode 100644 index 0000000..e2ab62f --- /dev/null +++ b/bin/varnishtest/tests/p00008.vtc @@ -0,0 +1,80 @@ +varnishtest "Ban list sync across silos" + +shell "rm -f ${tmpdir}/_.per[12]" + +# Silo 1 & 2 +# Prime each with an object with X-Foo: foo +server s1 { + rxreq + expect req.url == "/silo1" + txresp -hdr "X-Foo: foo" + + rxreq + expect req.url == "/silo2" + txresp -hdr "X-Foo: foo" +} -start +varnish v1 \ + -arg "-pfeature=+wait_silo" \ + -arg "-pban_lurker_sleep=0" \ + -storage "-sper1=persistent,${tmpdir}/_.per1,10m -sper2=persistent,${tmpdir}/_.per2,10m" \ + -vcl+backend { + sub vcl_fetch { + set beresp.storage = "per1"; + if (req.url ~ "silo2") { + set beresp.storage = "per2"; + } + } + } -start +client c1 { + txreq -url "/silo1" + rxresp + expect resp.status == 200 + expect resp.http.x-foo == "foo" + + txreq -url "/silo2" + rxresp + expect resp.status == 200 + expect resp.http.x-foo == "foo" +} -run +varnish v1 -stop +server s1 -wait + +# Only silo 1 +# Ban on obj.http.x-foo == foo +varnish v2 \ + -arg "-pfeature=+wait_silo" \ + -arg "-pban_lurker_sleep=0" \ + -storage "-spersistent,${tmpdir}/_.per1,10m" \ + -vcl+backend { } -start +varnish v2 -cliok "ban obj.http.x-foo == foo" +varnish v2 -cliok "ban.list" +varnish v2 -stop + +# Silo 1 & 2 +# Bans should be transferred +varnish v3 \ + -arg "-pfeature=+wait_silo" \ + -arg "-pban_lurker_sleep=0" \ + -storage "-spersistent,${tmpdir}/_.per1,10m -spersistent,${tmpdir}/_.per2,10m" \ + -vcl+backend { } -start +varnish v3 -cliok "ban.list" +varnish v3 -stop + +# Only silo 2 +# Check that /silo2 is banned +server s1 { + rxreq + expect req.url == "/silo2" + txresp -hdr "X-Foo: bar" +} -start +varnish v4 \ + -arg "-pfeature=+wait_silo" \ + -arg "-pban_lurker_sleep=0" \ + -storage "-spersistent,${tmpdir}/_.per2,10m" \ + -vcl+backend { } -start +client c1 -connect ${v4_sock} { + txreq -url "/silo2" + rxresp + expect resp.status == 200 + expect resp.http.x-foo == "bar" +} -run -- 1.7.10.4 From martin at varnish-software.com Mon Dec 3 10:09:51 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 3 Dec 2012 11:09:51 +0100 Subject: [PATCH 3/7] Add a facility to export a complete ban list to the stevedores. Call this on startup, after reading the persisted ban lists, to make sure all stevedores has all the bans from every stevedore stored. In-Reply-To: <1354529395-6805-1-git-send-email-martin@varnish-software.com> References: <1354529395-6805-1-git-send-email-martin@varnish-software.com> Message-ID: <1354529395-6805-3-git-send-email-martin@varnish-software.com> --- bin/varnishd/cache/cache.h | 1 + bin/varnishd/cache/cache_ban.c | 27 +++++++++++++++++++++++++-- bin/varnishd/storage/stevedore.c | 16 ++++++++++++++++ bin/varnishd/storage/storage.h | 3 +++ bin/varnishd/storage/storage_persistent.c | 21 +++++++++++++++++++++ 5 files changed, 66 insertions(+), 2 deletions(-) diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 6a0d1a4..f97f8a7 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -1061,6 +1061,7 @@ void STV_open(void); void STV_close(void); void STV_Freestore(struct object *o); int STV_BanInfo(enum baninfo event, const uint8_t *ban, unsigned len); +void STV_BanExport(const uint8_t *bans, unsigned len); /* storage_synth.c */ struct vsb *SMS_Makesynth(struct object *obj); diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index 21abf41..4e912ee 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -566,6 +566,28 @@ BAN_RefBan(struct objcore *oc, double t0, const struct ban *tail) } /*-------------------------------------------------------------------- + * Compile a full ban list and export this area to the stevedores for + * persistence. + */ + +static void +ban_export(void) +{ + struct ban *b; + struct vsb vsb; + + /* XXX: Use the ban entry size measurements to hit the target + * and avoid multiple allocations */ + VSB_new(&vsb, NULL, 64 * VSC_C_main->bans, VSB_AUTOEXTEND); + VTAILQ_FOREACH_REVERSE(b, &ban_head, banhead_s, list) { + VSB_bcat(&vsb, b->spec, ban_len(b->spec)); + } + VSB_finish(&vsb); + STV_BanExport((const uint8_t *)VSB_data(&vsb), VSB_len(&vsb)); + VSB_delete(&vsb); +} + +/*-------------------------------------------------------------------- * Put a skeleton ban in the list, unless there is an identical, * time & condition, ban already in place. * @@ -681,8 +703,9 @@ BAN_Compile(void) ASSERT_CLI(); AZ(ban_shutdown); - /* Notify stevedores */ - AZ(STV_BanInfo(BI_NEW, ban_magic->spec, ban_len(ban_magic->spec))); + /* All bans have been read from all persistent stevedores. Export + the compiled list */ + ban_export(); ban_start = VTAILQ_FIRST(&ban_head); WRK_BgThread(&ban_thread, "ban-lurker", ban_lurker, NULL); diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c index be16057..63400eb 100644 --- a/bin/varnishd/storage/stevedore.c +++ b/bin/varnishd/storage/stevedore.c @@ -472,6 +472,22 @@ STV_BanInfo(enum baninfo event, const uint8_t *ban, unsigned len) return (r); } +/*------------------------------------------------------------------- + * Export a complete ban list to the stevedores for persistence. + * The stevedores should clear any previous ban lists and replace + * them with this list. + */ + +void +STV_BanExport(const uint8_t *bans, unsigned len) +{ + struct stevedore *stv; + + VTAILQ_FOREACH(stv, &stv_stevedores, list) + if (stv->banexport != NULL) + stv->banexport(stv, bans, len); +} + /*-------------------------------------------------------------------- * VRT functions for stevedores */ diff --git a/bin/varnishd/storage/storage.h b/bin/varnishd/storage/storage.h index cddf6ef..4a69bb0 100644 --- a/bin/varnishd/storage/storage.h +++ b/bin/varnishd/storage/storage.h @@ -50,6 +50,8 @@ typedef void storage_close_f(const struct stevedore *); typedef void storage_signal_close_f(const struct stevedore *); typedef int storage_baninfo_f(struct stevedore *, enum baninfo event, const uint8_t *ban, unsigned len); +typedef void storage_banexport_f(struct stevedore *, const uint8_t *bans, + unsigned len); /* Prototypes for VCL variable responders */ #define VRTSTVTYPE(ct) typedef ct storage_var_##ct(const struct stevedore *); @@ -74,6 +76,7 @@ struct stevedore { storage_allocobj_f *allocobj; /* --//-- */ storage_signal_close_f *signal_close; /* --//-- */ storage_baninfo_f *baninfo; /* --//-- */ + storage_banexport_f *banexport; /* --//-- */ struct lru *lru; diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c index d02ae88..37bcea3 100644 --- a/bin/varnishd/storage/storage_persistent.c +++ b/bin/varnishd/storage/storage_persistent.c @@ -111,6 +111,26 @@ smp_baninfo(struct stevedore *stv, enum baninfo event, return (r); } +static void +smp_banexport_spc(struct smp_signspace *spc, const uint8_t *bans, unsigned len) +{ + smp_reset_signspace(spc); + assert(SIGNSPACE_FREE(spc) >= len); + memcpy(SIGNSPACE_DATA(spc), bans, len); + smp_append_signspace(spc, len); + smp_sync_sign(&spc->ctx); +} + +static void +smp_banexport(struct stevedore *stv, const uint8_t *bans, unsigned len) +{ + struct smp_sc *sc; + + CAST_OBJ_NOTNULL(sc, stv->priv, SMP_SC_MAGIC); + smp_banexport_spc(&sc->ban1, bans, len); + smp_banexport_spc(&sc->ban2, bans, len); +} + /*-------------------------------------------------------------------- * Attempt to open and read in a ban list */ @@ -586,6 +606,7 @@ const struct stevedore smp_stevedore = { .free = smp_free, .signal_close = smp_signal_close, .baninfo = smp_baninfo, + .banexport = smp_banexport, }; /*-------------------------------------------------------------------- -- 1.7.10.4 From martin at varnish-software.com Mon Dec 3 10:09:55 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 3 Dec 2012 11:09:55 +0100 Subject: [PATCH 7/7] Fix test case In-Reply-To: <1354529395-6805-1-git-send-email-martin@varnish-software.com> References: <1354529395-6805-1-git-send-email-martin@varnish-software.com> Message-ID: <1354529395-6805-7-git-send-email-martin@varnish-software.com> Varnishtest -storage option can not be specified multiple times to append. Fix the test case to list all the silos in one -storage option. --- bin/varnishtest/tests/p00002.vtc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/varnishtest/tests/p00002.vtc b/bin/varnishtest/tests/p00002.vtc index dc6e584..53bf892 100644 --- a/bin/varnishtest/tests/p00002.vtc +++ b/bin/varnishtest/tests/p00002.vtc @@ -10,8 +10,7 @@ server s1 { varnish v1 \ -arg "-pfeature=+wait_silo" \ -arg "-pban_lurker_sleep=0" \ - -storage "-spersistent,${tmpdir}/_.per1,10m" \ - -storage "-spersistent,${tmpdir}/_.per2,10m" \ + -storage "-spersistent,${tmpdir}/_.per1,10m -spersistent,${tmpdir}/_.per2,10m" \ -vcl+backend { } -start client c1 { -- 1.7.10.4 From martin at varnish-software.com Mon Dec 3 10:09:52 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 3 Dec 2012 11:09:52 +0100 Subject: [PATCH 4/7] Try to export the ban list on STV_BanInfo failures. In-Reply-To: <1354529395-6805-1-git-send-email-martin@varnish-software.com> References: <1354529395-6805-1-git-send-email-martin@varnish-software.com> Message-ID: <1354529395-6805-4-git-send-email-martin@varnish-software.com> When STV_BanInfo fails, it means the stevedore has run out of space to persist the list. An export should descrease the size. --- bin/varnishd/cache/cache_ban.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index 4e912ee..e1b60e0 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -99,6 +99,7 @@ struct ban_test { const void *arg2_spec; }; +static void ban_info(enum baninfo event, const uint8_t *ban, unsigned len); static VTAILQ_HEAD(banhead_s,ban) ban_head = VTAILQ_HEAD_INITIALIZER(ban_head); static struct lock ban_mtx; static struct ban *ban_magic; @@ -476,7 +477,7 @@ BAN_Insert(struct ban *b) else be = NULL; - AZ(STV_BanInfo(BI_NEW, b->spec, ln)); /* Notify stevedores */ + ban_info(BI_NEW, b->spec, ln); /* Notify stevedores */ Lck_Unlock(&ban_mtx); if (be == NULL) @@ -587,6 +588,21 @@ ban_export(void) VSB_delete(&vsb); } +static void +ban_info(enum baninfo event, const uint8_t *ban, unsigned len) +{ + if (STV_BanInfo(event, ban, len)) { + /* One or more stevedores reported failure. Export the + * list instead. The exported list should take up less + * space due to drops being purged and gones being + * truncated. */ + /* XXX: Keep some measure of how much space can be + * saved, and only export if it's worth it. Assert if + * not */ + ban_export(); + } +} + /*-------------------------------------------------------------------- * Put a skeleton ban in the list, unless there is an identical, * time & condition, ban already in place. @@ -898,7 +914,7 @@ ban_cleantail(void) VSC_C_main->bans--; VSC_C_main->bans_deleted++; VTAILQ_REMOVE(&ban_head, b, list); - AZ(STV_BanInfo(BI_DROP, b->spec, ban_len(b->spec))); + ban_info(BI_DROP, b->spec, ban_len(b->spec)); } else { b = NULL; } -- 1.7.10.4 From martin at varnish-software.com Mon Dec 3 10:09:53 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Mon, 3 Dec 2012 11:09:53 +0100 Subject: [PATCH 5/7] Export the ban list on shutdown to compact it In-Reply-To: <1354529395-6805-1-git-send-email-martin@varnish-software.com> References: <1354529395-6805-1-git-send-email-martin@varnish-software.com> Message-ID: <1354529395-6805-5-git-send-email-martin@varnish-software.com> --- bin/varnishd/cache/cache_ban.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index e1b60e0..489f33c 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -1280,4 +1280,9 @@ BAN_Shutdown(void) AZ(pthread_join(ban_thread, &status)); AZ(status); + + Lck_Lock(&ban_mtx); + /* Export the ban list to compact it */ + ban_export(); + Lck_Unlock(&ban_mtx); } -- 1.7.10.4 From roger at seriousorange.com Mon Dec 3 14:10:45 2012 From: roger at seriousorange.com (Roger Nesbitt) Date: Mon, 3 Dec 2012 14:10:45 +0000 Subject: PROXY protocol In-Reply-To: <14131780-63FD-41FD-A3C0-B249A61C92C3@seriousorange.com> References: <14131780-63FD-41FD-A3C0-B249A61C92C3@seriousorange.com> Message-ID: Replying to myself, I decided to jump in and just see how far I could get. Looks like I've got something working, a patch of my prototype is here: http://seriousorange.com/varnish-proxy-proto.patch The one obvious thing wrong with it is that I'm using malloc() to get some memory for configuration (and never freeing it); I can't figure out which memory routines are the right ones to use. Hopefully someone can point me in the right direction with that. Comments gratefully appreciated. Roger Le 3 d?c. 2012 ? 08:35, Roger Nesbitt a ?crit : > Hello, > > I've got a big chunk of time free and would like to scratch my own itch by implementing the PROXY protocol, as defined at this URL: > http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt > > My thoughts are to initially implement version 1 of the protocol as part of the HTTP server component. This will allow SSL frontends such as stunnel to pass through client IP information, a feature that seems to be often requested. > > I'm completely new to the Varnish source; after having a little look today I assume that a VMOD will not be possible due to the integration required into the HTTP parser. > > On first looks, I'm thinking of a detection hook in http1_detect(), although I'd have to figure out some way to indicate that it's the first http request handled on a new connection. If a PROXY line is detected, the code would put the source/destination IP addresses and ports into new variables (maybe something like proxy.source_ip, proxy.dest_ip, proxy.source_port, proxy.dest_port) and leave it up to the user to build an X-Forwarded-For header in VCL should they wish (after checking that client.ip is trusted.) > > Detecting the PROXY line should just be a single memcmp; I'm not sure whether the community would want this feature to be able to be manually enabled and disabled. > > Is anyone else currently working on this? Does this idea and general strategy seem sound? > > Thanks for your help and suggestions. > Roger > _______________________________________________ > varnish-dev mailing list > varnish-dev at varnish-cache.org > https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcos.hack at abril.com.br Mon Dec 3 19:01:16 2012 From: marcos.hack at abril.com.br (Marcos Paulo Hack) Date: Mon, 3 Dec 2012 19:01:16 +0000 Subject: RFC 5861 support Message-ID: <34AEF30D921AD846A83E78166A8B45341B34E7F2@ABRWPDAGDP04.gabril.com.br> Hello. Is there any working in progress or intention to implement RFC 5861 (stale-*) cache-control extensions? Regards. Marcos AVISO LEGAL: Esta mensagem e arquivos podem conter informacoes confidenciais e ou legalmente protegidas. Caso tenha recebido por engano, favor devolve-la ao remetente e elimina-la do seu sistema, nao divulgando ou utilizando a totalidade ou parte desta mensagem ou dos documentos a ela anexados. From marcos.hack at abril.com.br Tue Dec 4 12:58:47 2012 From: marcos.hack at abril.com.br (Marcos Paulo Hack) Date: Tue, 4 Dec 2012 12:58:47 +0000 Subject: RFC 5861 support In-Reply-To: References: <34AEF30D921AD846A83E78166A8B45341B34E7F2@ABRWPDAGDP04.gabril.com.br> <34AEF30D921AD846A83E78166A8B45341B34E9E6@ABRWPDAGDP04.gabril.com.br> Message-ID: <34AEF30D921AD846A83E78166A8B45341B34ECD5@ABRWPDAGDP04.gabril.com.br> Hi Andrea. On Dec 4, 2012, at 6:08 AM, Andrea Campi > wrote: On Tue, Dec 4, 2012 at 2:42 AM, Marcos Paulo Hack > wrote: Hi Andrea. As discussed in IRC channel, the grace mode should be used to implement the stale-while-revalidate directive, but there is no easy (or even viable) way to implement stale-if-error using VLC. Do logs exist for that conversation? I would be interested in the rationale for that. I couldn't find the channel log anywhere so I attached here. At face value it sounds like a useful implementation of stale-if-error can be done in VCL using saint mode. Other than that, I'll probably end up doing a VMOD anyway. The only problem with stale-while-revalidate using grace mode is that it isn't really asynchronous as discussed here [1]. So a VMOD implementation should be required to be full compliance with the RFC. Looking at the RFC some more, I have some questions. I'll probably get in touch with the editor of the RFC: * I am unclear on whether this is intended for reverse proxies that can be considered "part of the application" or if remote proxies and user agents are allowed to use it too. The use of Cache-Control suggest the latter, but in that case I would like to see an implementation in a browser before I start sending these headers out in the wild. I realize user agents are free to show stale content anyway, but they usually don't. Vice versa, it looks like these extensions may be useful also in Surrogate-Control, where we can easily ensure they never make it past Varnish. * I don't like stale-if-error in a request. I won't comment on its useful from the point of view of the user agent (other than saying it would make for a complex UI). But from the point of view of Varnish, the only useful use case I can see is *reducing* the allowed staleness?since by definition it can't make it any longer than the time the object persists in the cache. If I were to implement this, I would just ignore this in requests. Thoughts? I'll probably start working on this and edge-arch over the next week, so any reasoned opinion is appreciated as it may very well save me time ;) Good questions. You should talk to Mark Nottingham, indeed. Just a side note: the folks of Traffic Server just finished their experimental implementation a month ago, maybe you can find some useful insights over there ;) [1] https://www.varnish-cache.org/lists/pipermail/varnish-misc/2012-March/021800.html [2] https://github.com/apache/trafficserver/tree/master/plugins/experimental/rfc5861 Regards. Marcos AVISO LEGAL: Esta mensagem e arquivos podem conter informacoes confidenciais e ou legalmente protegidas. Caso tenha recebido por engano, favor devolve-la ao remetente e elimina-la do seu sistema, nao divulgando ou utilizando a totalidade ou parte desta mensagem ou dos documentos a ela anexados. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: linpro_varnish_channel-RFC5861.txt URL: From andrea.campi at zephirworks.com Tue Dec 4 13:26:30 2012 From: andrea.campi at zephirworks.com (Andrea Campi) Date: Tue, 4 Dec 2012 14:26:30 +0100 Subject: RFC 5861 support In-Reply-To: <34AEF30D921AD846A83E78166A8B45341B34ECD5@ABRWPDAGDP04.gabril.com.br> References: <34AEF30D921AD846A83E78166A8B45341B34E7F2@ABRWPDAGDP04.gabril.com.br> <34AEF30D921AD846A83E78166A8B45341B34E9E6@ABRWPDAGDP04.gabril.com.br> <34AEF30D921AD846A83E78166A8B45341B34ECD5@ABRWPDAGDP04.gabril.com.br> Message-ID: On Tue, Dec 4, 2012 at 1:58 PM, Marcos Paulo Hack wrote: > Hi Andrea. > > On Dec 4, 2012, at 6:08 AM, Andrea Campi > wrote: > > At face value it sounds like a useful implementation of stale-if-error can > be done in VCL using saint mode. > > Other than that, I'll probably end up doing a VMOD anyway. > > > The only problem with stale-while-revalidate using grace mode is that it > isn't really asynchronous as discussed here [1]. So a VMOD implementation > should be required to be full compliance with the RFC. > The RFC does say: indicates that it is fresh for 600 seconds, and it may continue to be served stale for up to an additional 30 seconds while an asynchronous validation is attempted. However later on: Since asynchronous validation will only happen if a request occurs after the response has become stale, but before the end of the stale- while-revalidate window, the size of that window and the likelihood of a request during it determines how likely it is that all requests will be served without delay. If the window is too small, or traffic is too sparse, some requests will fall outside of it, and block until the server can validate the cached response. The way I read this is that the RFC doesn't concern itself with telling us that we *must* make an asynchronous request. Instead, the assumed goal is to allow as many requests as possible to continue unimpeded. Let me turn this around: I'm not going to attempt to change the architecture of Varnish to do asynchronous background requests. Given that, would implementing the RFC still be useful? I think so, because it allows us to push responsibility for deciding how much grace to apply to an object out of the VCL and into the bbackend, where it belongs. Would such an implementation still conform to the RFC? I think so. If you tested this as a blackbox, all you would see if that one request will take longer, but other than that it would work as expected. Besides, when in doubt between perfect compliance with a standard some day in the future, or a 90% implementation that solves a real problem today, I'll pick the latter any day and twice on Sundays ;) Andrea -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcos.hack at abril.com.br Tue Dec 4 15:25:56 2012 From: marcos.hack at abril.com.br (Marcos Paulo Hack) Date: Tue, 4 Dec 2012 15:25:56 +0000 Subject: RFC 5861 support In-Reply-To: References: <34AEF30D921AD846A83E78166A8B45341B34E7F2@ABRWPDAGDP04.gabril.com.br> <34AEF30D921AD846A83E78166A8B45341B34E9E6@ABRWPDAGDP04.gabril.com.br> <34AEF30D921AD846A83E78166A8B45341B34ECD5@ABRWPDAGDP04.gabril.com.br> Message-ID: <34AEF30D921AD846A83E78166A8B45341B34EEF8@ABRWPDAGDP04.gabril.com.br> I agree, Andrea. Grace and saint modes should be enough to implement a very good approximation of the behaviour defined in the RFC right now and solve the majority of use cases, including mine :) Thanks for your attention and I'll keep in touch to follow any progress about that. Best regards. Marcos On Dec 4, 2012, at 11:26 AM, Andrea Campi > wrote: On Tue, Dec 4, 2012 at 1:58 PM, Marcos Paulo Hack > wrote: Hi Andrea. On Dec 4, 2012, at 6:08 AM, Andrea Campi > wrote: At face value it sounds like a useful implementation of stale-if-error can be done in VCL using saint mode. Other than that, I'll probably end up doing a VMOD anyway. The only problem with stale-while-revalidate using grace mode is that it isn't really asynchronous as discussed here [1]. So a VMOD implementation should be required to be full compliance with the RFC. The RFC does say: indicates that it is fresh for 600 seconds, and it may continue to be served stale for up to an additional 30 seconds while an asynchronous validation is attempted. However later on: Since asynchronous validation will only happen if a request occurs after the response has become stale, but before the end of the stale- while-revalidate window, the size of that window and the likelihood of a request during it determines how likely it is that all requests will be served without delay. If the window is too small, or traffic is too sparse, some requests will fall outside of it, and block until the server can validate the cached response. The way I read this is that the RFC doesn't concern itself with telling us that we *must* make an asynchronous request. Instead, the assumed goal is to allow as many requests as possible to continue unimpeded. Let me turn this around: I'm not going to attempt to change the architecture of Varnish to do asynchronous background requests. Given that, would implementing the RFC still be useful? I think so, because it allows us to push responsibility for deciding how much grace to apply to an object out of the VCL and into the bbackend, where it belongs. Would such an implementation still conform to the RFC? I think so. If you tested this as a blackbox, all you would see if that one request will take longer, but other than that it would work as expected. Besides, when in doubt between perfect compliance with a standard some day in the future, or a 90% implementation that solves a real problem today, I'll pick the latter any day and twice on Sundays ;) Andrea AVISO LEGAL: Esta mensagem e arquivos podem conter informacoes confidenciais e ou legalmente protegidas. Caso tenha recebido por engano, favor devolve-la ao remetente e elimina-la do seu sistema, nao divulgando ou utilizando a totalidade ou parte desta mensagem ou dos documentos a ela anexados. -------------- next part -------------- An HTML attachment was scrubbed... URL: From huozhe at gmail.com Tue Dec 4 19:04:52 2012 From: huozhe at gmail.com (Zheng Liu) Date: Tue, 4 Dec 2012 11:04:52 -0800 Subject: unsubscribe Message-ID: On Tue, Dec 4, 2012 at 5:26 AM, wrote: > Send varnish-dev mailing list submissions to > varnish-dev at varnish-cache.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev > or, via email, send a message with subject or body 'help' to > varnish-dev-request at varnish-cache.org > > You can reach the person managing the list at > varnish-dev-owner at varnish-cache.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of varnish-dev digest..." > > > Today's Topics: > > 1. Re: RFC 5861 support (Marcos Paulo Hack) > 2. Re: RFC 5861 support (Andrea Campi) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Tue, 4 Dec 2012 12:58:47 +0000 > From: Marcos Paulo Hack > To: Andrea Campi > Cc: "varnish-dev at varnish-cache.org" > Subject: Re: RFC 5861 support > Message-ID: > < > 34AEF30D921AD846A83E78166A8B45341B34ECD5 at ABRWPDAGDP04.gabril.com.br> > Content-Type: text/plain; charset="utf-8" > > Hi Andrea. > > On Dec 4, 2012, at 6:08 AM, Andrea Campi > > wrote: > > > On Tue, Dec 4, 2012 at 2:42 AM, Marcos Paulo Hack < > marcos.hack at abril.com.br> wrote: > Hi Andrea. > > As discussed in IRC channel, the grace mode should be used to implement > the stale-while-revalidate directive, but there is no easy (or even viable) > way to implement stale-if-error using VLC. > > Do logs exist for that conversation? I would be interested in the > rationale for that. > > I couldn't find the channel log anywhere so I attached here. > > At face value it sounds like a useful implementation of stale-if-error can > be done in VCL using saint mode. > > Other than that, I'll probably end up doing a VMOD anyway. > > The only problem with stale-while-revalidate using grace mode is that it > isn't really asynchronous as discussed here [1]. So a VMOD implementation > should be required to be full compliance with the RFC. > > > Looking at the RFC some more, I have some questions. I'll probably get in > touch with the editor of the RFC: > > * I am unclear on whether this is intended for reverse proxies that can be > considered "part of the application" or if remote proxies and user agents > are allowed to use it too. > The use of Cache-Control suggest the latter, but in that case I would like > to see an implementation in a browser before I start sending these headers > out in the wild. I realize user agents are free to show stale content > anyway, but they usually don't. > Vice versa, it looks like these extensions may be useful also in > Surrogate-Control, where we can easily ensure they never make it past > Varnish. > > * I don't like stale-if-error in a request. I won't comment on its useful > from the point of view of the user agent (other than saying it would make > for a complex UI). > But from the point of view of Varnish, the only useful use case I can see > is *reducing* the allowed staleness?since by definition it can't make it > any longer than the time the object persists in the cache. > If I were to implement this, I would just ignore this in requests. > > Thoughts? I'll probably start working on this and edge-arch over the next > week, so any reasoned opinion is appreciated as it may very well save me > time ;) > > Good questions. You should talk to Mark Nottingham, indeed. > > Just a side note: the folks of Traffic Server just finished their > experimental implementation a month ago, maybe you can find some useful > insights over there ;) > > [1] > https://www.varnish-cache.org/lists/pipermail/varnish-misc/2012-March/021800.html > [2] > https://github.com/apache/trafficserver/tree/master/plugins/experimental/rfc5861 > > Regards. > Marcos > > > > AVISO LEGAL: Esta mensagem e arquivos podem conter informacoes > confidenciais e ou legalmente protegidas. > Caso tenha recebido por engano, favor devolve-la ao remetente e elimina-la > do seu sistema, nao divulgando ou utilizando a totalidade ou parte desta > mensagem ou dos documentos a ela anexados. > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > https://www.varnish-cache.org/lists/pipermail/varnish-dev/attachments/20121204/7be68fc7/attachment-0001.html > > > -------------- next part -------------- > An embedded and charset-unspecified text was scrubbed... > Name: linpro_varnish_channel-RFC5861.txt > URL: < > https://www.varnish-cache.org/lists/pipermail/varnish-dev/attachments/20121204/7be68fc7/attachment-0001.txt > > > > ------------------------------ > > Message: 2 > Date: Tue, 4 Dec 2012 14:26:30 +0100 > From: Andrea Campi > To: Marcos Paulo Hack > Cc: "varnish-dev at varnish-cache.org" > Subject: Re: RFC 5861 support > Message-ID: > < > CACXW+KH1ixaeV-8jVdSQBJN6E3ovU_P4nSyk8uiq-3syNHKeHg at mail.gmail.com> > Content-Type: text/plain; charset="utf-8" > > On Tue, Dec 4, 2012 at 1:58 PM, Marcos Paulo Hack > wrote: > > > Hi Andrea. > > > > On Dec 4, 2012, at 6:08 AM, Andrea Campi > > wrote: > > > > At face value it sounds like a useful implementation of stale-if-error > can > > be done in VCL using saint mode. > > > > Other than that, I'll probably end up doing a VMOD anyway. > > > > > > The only problem with stale-while-revalidate using grace mode is that it > > isn't really asynchronous as discussed here [1]. So a VMOD implementation > > should be required to be full compliance with the RFC. > > > > > The RFC does say: > > indicates that it is fresh for 600 seconds, and it may continue to be > served stale for up to an additional 30 seconds while an asynchronous > validation is attempted. > > > However later on: > > > Since asynchronous validation will only happen if a request occurs > after the response has become stale, but before the end of the stale- > while-revalidate window, the size of that window and the likelihood > of a request during it determines how likely it is that all requests > will be served without delay. If the window is too small, or traffic > is too sparse, some requests will fall outside of it, and block until > the server can validate the cached response. > > > The way I read this is that the RFC doesn't concern itself with telling us > that we *must* make an asynchronous request. > Instead, the assumed goal is to allow as many requests as possible to > continue unimpeded. > > Let me turn this around: I'm not going to attempt to change the > architecture of Varnish to do asynchronous background requests. > Given that, would implementing the RFC still be useful? > I think so, because it allows us to push responsibility for deciding how > much grace to apply to an object out of the VCL and into the bbackend, > where it belongs. > Would such an implementation still conform to the RFC? I think so. If you > tested this as a blackbox, all you would see if that one request will take > longer, but other than that it would work as expected. > > Besides, when in doubt between perfect compliance with a standard some day > in the future, or a 90% implementation that solves a real problem today, > I'll pick the latter any day and twice on Sundays ;) > > > Andrea > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: < > https://www.varnish-cache.org/lists/pipermail/varnish-dev/attachments/20121204/ead8e0e1/attachment.html > > > > ------------------------------ > > _______________________________________________ > varnish-dev mailing list > varnish-dev at varnish-cache.org > https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev > > End of varnish-dev Digest, Vol 81, Issue 4 > ****************************************** > -------------- next part -------------- An HTML attachment was scrubbed... URL: From phk at phk.freebsd.dk Mon Dec 10 09:24:35 2012 From: phk at phk.freebsd.dk (Poul-Henning Kamp) Date: Mon, 10 Dec 2012 09:24:35 +0000 Subject: RFC: new vcl_lookup{} proposal In-Reply-To: References: <20314.1347867221@critter.freebsd.dk> Message-ID: <55848.1355131475@critter.freebsd.dk> -------- In message , Martin Blix Grydeland writes: A couple of months ago (!) we talked about a vcl_lookup{} function to always follow vcl_hash{} Vcl_lookup{} in it self is not a big problem, but it amplifies a problem we have had since day one: How do we merge VCL-code snippets from the user with the default VCL in a sane and intuitive way ? The current "default.vcl is always appended" method increasingly breaks down, faced with more and more complicated VCLs, and it certainly has been one of the most FAQs. Martin proposed a modularization of the default.vcl, so that one could do stuff like: sub default_vcl_recv { call default_vcl_recv_xff; call default_vcl_recv_check_method; call default_vcl_recv_check_pass; call default_vcl_recv_check_auth; return (lookup); } I can see this helping the high-skill users, who for all practical purposes have written their own VCL, in particular it would help them upgrading to a newer Varnish, since they could rely on the default VCL where they don't have private magic. But for the novice users, this will just make VCL even harder to understand. So maybe what we really need is a VCL-writer script for the beginners, which will spit out a VCL based on a high-level description of features ? Something along the lines of: Support PURGE command ? [yes|no] Serve stale objects while fetching [yes|no] How stale can they be ? [2 m] Serve stale objects when backend is down [yes|no] How stale can they be ? [1 h] Images can always be cached [yes|no] Gzip compress URLs matching [] Enable ESI for URLS matching [] There's probably a few more we should have on there, but you get the idea... Obviously, as they get more sofisticated, the users can "go native" by modifying the generated VCL and run "raw". Would this work ? -- Poul-Henning Kamp | UNIX since Zilog Zeus 3.20 phk at FreeBSD.ORG | TCP/IP since RFC 956 FreeBSD committer | BSD since 4.3-tahoe Never attribute to malice what can adequately be explained by incompetence. From martin at varnish-software.com Wed Dec 12 14:13:55 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Wed, 12 Dec 2012 15:13:55 +0100 Subject: PROXY protocol In-Reply-To: References: <14131780-63FD-41FD-A3C0-B249A61C92C3@seriousorange.com> Message-ID: Hi Roger, The PROXY protocol is something that has been discussed, and it's addition seen as something we'd like to have in Varnish. There is however, as far as I know, no work in progress other than your own to add it to Varnish. And as you write, it would make it much more convenient to use SSL terminators with Varnish. I have had a look at your current patch, and while it will work, I believe it is a bit too hackish to be considered for inclusion in it's current form. As the PROXY protocol is a wrapper protocol of sorts, it should be handled specifically with it's own parsing and verification, and then handed over to the HTTP parsing when that has been verified. Your current automagic parsing by piggybacking on the HTTP parsing also has security implications, as it allows a client to craft PROXY lines into the stream that will be picked up, which can be used as an attack vector. I believe that adding this to Varnish will be much easier to accomplish using current master as the basis. This because a lot of structural changes in preparation for multiprotocol support has already been done there, and this work is not available on the 3.0 or the -plus branch. Some thoughts outlined: - The support should be linked to the listening socket, so that the wrapper protocol can be verified and completed before treating it as an HTTP socket. (This socket will then only accept PROXY connections, not regular HTTP connections) - Either a separate FSM should be defined, or special steps of the http1_fsm defined, to handle the PROXY initial states. When the PROXY protocol has been dealt with, state processing should jump to the HTTP. (Requiring some FSM indirection pointer on the sessions, pointing to the current FSM in use). - The addresses parsed from the PROXY lines should replace the client.ip and client.port values. This will allow it to be used with existing VCL scripts and ACL checks, without having to code in special support in VCL configurations. (Discussion item: Should the PROXY ip and port be visible to VCL?) - Any memory allocations necessary should be done on the request object's workspace. This should then be allocated at the front of this before handing the request object to the HTTP FSM. (If the PROXY ip and port is not stored, there might not be need for any dynamic memory allocation) These thoughts are subject to Poul-Henning's review and opinions as he is the architect of Varnish. He is busy with other major changes at the moment, so he might not have the time to look into this in detail at this time. Regards, Martin Blix Grydeland On Mon, Dec 3, 2012 at 3:10 PM, Roger Nesbitt wrote: > Replying to myself, I decided to jump in and just see how far I could get. > Looks like I've got something working, a patch of my prototype is here: > > http://seriousorange.com/varnish-proxy-proto.patch > > The one obvious thing wrong with it is that I'm using malloc() to get some > memory for configuration (and never freeing it); I can't figure out which > memory routines are the right ones to use. Hopefully someone can point me > in the right direction with that. > > Comments gratefully appreciated. > Roger > > Le 3 d?c. 2012 ? 08:35, Roger Nesbitt a ?crit : > > Hello, > > I've got a big chunk of time free and would like to scratch my own itch by > implementing the PROXY protocol, as defined at this URL: > http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt > > My thoughts are to initially implement version 1 of the protocol as part > of the HTTP server component. This will allow SSL frontends such as > stunnel to pass through client IP information, a feature that seems to be > often requested. > > I'm completely new to the Varnish source; after having a little look today > I assume that a VMOD will not be possible due to the integration required > into the HTTP parser. > > On first looks, I'm thinking of a detection hook in http1_detect(), > although I'd have to figure out some way to indicate that it's the first > http request handled on a new connection. If a PROXY line is detected, the > code would put the source/destination IP addresses and ports into new > variables (maybe something like proxy.source_ip, proxy.dest_ip, > proxy.source_port, proxy.dest_port) and leave it up to the user to build an > X-Forwarded-For header in VCL should they wish (after checking that > client.ip is trusted.) > > Detecting the PROXY line should just be a single memcmp; I'm not sure > whether the community would want this feature to be able to be manually > enabled and disabled. > > Is anyone else currently working on this? Does this idea and general > strategy seem sound? > > Thanks for your help and suggestions. > Roger > _______________________________________________ > varnish-dev mailing list > varnish-dev at varnish-cache.org > https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev > > > > _______________________________________________ > varnish-dev mailing list > varnish-dev at varnish-cache.org > https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev > -- *Martin Blix Grydeland* Senior Developer | Varnish Software AS Cell: +47 21 98 92 60 We Make Websites Fly! -------------- next part -------------- An HTML attachment was scrubbed... URL: From martin at varnish-software.com Wed Dec 12 15:14:31 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Wed, 12 Dec 2012 16:14:31 +0100 Subject: PROXY protocol In-Reply-To: References: <14131780-63FD-41FD-A3C0-B249A61C92C3@seriousorange.com> Message-ID: Hi Roger, Please find answers in-line. Regards, Martin Blix Grydeland On Wed, Dec 12, 2012 at 3:27 PM, Roger Nesbitt wrote: > Hi Martin, > > Thanks for the comments. I agree your strategy is a cleaner one. It's > going to mean that I have to understand the Varnish code to a greater > depth, but I've got some time free so I'm happy to do that. > > How would you suggest that the user configures a particular port so that > it uses the PROXY handler instead of the HTTP one? Maybe this is a new > feature that I'm not aware of. Any docs or code you can point me at would > be greatly appreciated. > My first thought is to add some optional prefix with the protocol selection in front on the listening options to varnishd, defaulting to http1 if not present. A bit like how the -s option is handled. E.g. "-a localhost:80 -a proxy,localhost:444 -a http1,:8080" Some indirection should be on the listening socket structs to determine which function then should get called to set up the connection for processing by the correct fsm. Also some pointer on the session struct to point to the fsm handling the connection will be needed. Note that this is plugging code not yet existing that will have to be added as well. We don't handle any other protocols than regular HTTP1(.1) at this time. Though the changes into two fsm's in master, one for the connection (cache_http1_fsm.c) and one for the requests (cache_req_fsm.c) should make it easier to add the PROXY support as well. So I'm thinking having a cache_proxy_fsm.c to handle the PROXY part, where the PROXY line should be read and parsed, and then changing to cache_http1_fsm.c when all has been processed and verified is the way to go. (FSM here is finite-state-machine) Disclaimer: This is based on my understanding of Poul-Henning's vision of how the multiprotocol support will be in Varnish, so this may not be sound advice ;-) > > A summary document of the abbreviations used in the code would help too, I > looked through the wiki but didn't find anything that explains all the > three- and four-letter acronyms. > https://www.varnish-cache.org/trac/wiki/VTLA is the only documentation available for those, but I guess it isn't completely up-to-date. > > Thanks, > Roger > > > -- *Martin Blix Grydeland* Senior Developer | Varnish Software AS Cell: +47 21 98 92 60 We Make Websites Fly! -------------- next part -------------- An HTML attachment was scrubbed... URL: From martin at varnish-software.com Thu Dec 13 12:16:45 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Thu, 13 Dec 2012 13:16:45 +0100 Subject: [PATCH] Set the split character back to '=' after applying the runtime parameter to preserve the arguments as seen e.g. ps. Message-ID: <1355401005-27989-1-git-send-email-martin@varnish-software.com> Fixes: #1238 --- bin/varnishd/mgt/mgt_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index fe6e489..2b3c709 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -465,6 +465,7 @@ main(int argc, char * const *argv) AN(p); *p++ = '\0'; MCF_ParamSet(cli, optarg, p); + *--p = '='; cli_check(cli); break; case 'r': -- 1.7.10.4 From martin at varnish-software.com Fri Dec 14 17:40:59 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 14 Dec 2012 18:40:59 +0100 Subject: [PATCH 1/5] Keep track of persisted ban byte usage, and it's overhead. Message-ID: <1355506863-20819-1-git-send-email-martin@varnish-software.com> --- bin/varnishd/cache/cache_ban.c | 15 ++++++++++++--- include/tbl/vsc_f_main.h | 9 +++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index 47e4f70..a96bc9c 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -262,13 +262,16 @@ ban_equal(const uint8_t *bs1, const uint8_t *bs2) static void ban_mark_gone(struct ban *b) { + unsigned ln; CHECK_OBJ_NOTNULL(b, BAN_MAGIC); + ln = ban_len(b->spec); b->flags |= BAN_F_GONE; b->spec[BANS_FLAGS] |= BANS_FLAG_GONE; VWMB(); vbe32enc(b->spec + BANS_LENGTH, 0); VSC_C_main->bans_gone++; + VSC_C_main->bans_bytes_overhead += ln - ban_len(b->spec); } /*-------------------------------------------------------------------- @@ -484,6 +487,7 @@ BAN_Insert(struct ban *b) * the stevedores has been opened, but before any new objects * can have entered the cache (thus no objects in the mean * time depending on ban_magic in the list) */ + VSC_C_main->bans_bytes_persisted += ln; if (b != ban_magic) ban_info(BI_NEW, b->spec, ln); /* Notify stevedores */ Lck_Unlock(&ban_mtx); @@ -584,17 +588,20 @@ ban_export(void) { struct ban *b; struct vsb vsb; + unsigned ln; Lck_AssertHeld(&ban_mtx); - /* XXX: Use the ban entry size measurements to hit the target - * and avoid multiple allocations */ - AN(VSB_new(&vsb, NULL, 64 * VSC_C_main->bans, VSB_AUTOEXTEND)); + ln = VSC_C_main->bans_bytes_persisted - VSC_C_main->bans_bytes_overhead; + AN(VSB_new(&vsb, NULL, ln, VSB_AUTOEXTEND)); VTAILQ_FOREACH_REVERSE(b, &ban_head, banhead_s, list) { AZ(VSB_bcat(&vsb, b->spec, ban_len(b->spec))); } AZ(VSB_finish(&vsb)); + assert(VSB_len(&vsb) == ln); STV_BanExport((const uint8_t *)VSB_data(&vsb), VSB_len(&vsb)); VSB_delete(&vsb); + VSC_C_main->bans_bytes_persisted = ln; + VSC_C_main->bans_bytes_overhead = 0; } static void @@ -665,6 +672,7 @@ ban_reload(const uint8_t *ban, unsigned len) VTAILQ_INSERT_TAIL(&ban_head, b2, list); else VTAILQ_INSERT_BEFORE(b, b2, list); + VSC_C_main->bans_bytes_persisted += len; /* Hunt down older duplicates */ for (b = VTAILQ_NEXT(b2, list); b != NULL; b = VTAILQ_NEXT(b, list)) { @@ -930,6 +938,7 @@ ban_cleantail(void) VSC_C_main->bans--; VSC_C_main->bans_deleted++; VTAILQ_REMOVE(&ban_head, b, list); + VSC_C_main->bans_bytes_overhead += ban_len(b->spec); ban_info(BI_DROP, b->spec, ban_len(b->spec)); } else { b = NULL; diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h index d9c78ce..a7de6e0 100644 --- a/include/tbl/vsc_f_main.h +++ b/include/tbl/vsc_f_main.h @@ -467,6 +467,15 @@ VSC_F(bans_dups, uint64_t, 0, 'c', "Bans superseded by other bans", "Count of bans replaced by later identical bans." ) +VSC_F(bans_bytes_persisted, uint64_t, 0, 'g', + "Bytes used by the persisted ban lists", + "Number of bytes used by the persisted ban lists." +) +VSC_F(bans_bytes_overhead, uint64_t, 0, 'g', + "Bytes of overhead in the persisted ban lists", + "Number of bytes of overhead accumulated through dropped and" + " gone bans in the persistent ban lists." +) /**********************************************************************/ -- 1.7.10.4 From martin at varnish-software.com Fri Dec 14 17:41:00 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 14 Dec 2012 18:41:00 +0100 Subject: [PATCH 2/5] Add assert on overhead size on size of overhead with regard to the size of the persisted ban lists, so that we don't try to continously reexport the list for very little gain when space is tight. In-Reply-To: <1355506863-20819-1-git-send-email-martin@varnish-software.com> References: <1355506863-20819-1-git-send-email-martin@varnish-software.com> Message-ID: <1355506863-20819-2-git-send-email-martin@varnish-software.com> --- bin/varnishd/cache/cache_ban.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index a96bc9c..64474a7 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -611,10 +611,13 @@ ban_info(enum baninfo event, const uint8_t *ban, unsigned len) /* One or more stevedores reported failure. Export the * list instead. The exported list should take up less * space due to drops being purged and gones being - * truncated. */ - /* XXX: Keep some measure of how much space can be - * saved, and only export if it's worth it. Assert if - * not */ + * truncated. We assert that the overhead constitues + * at least 10% of the persisted size so that we don't + * try to continously reexport on tight space. If the + * assertion fails, the persistent stevedores have too + * little space for their ban lists */ + assert(VSC_C_main->bans_bytes_overhead > + VSC_C_main->bans_bytes_persisted / 10); ban_export(); } } -- 1.7.10.4 From martin at varnish-software.com Fri Dec 14 17:41:01 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 14 Dec 2012 18:41:01 +0100 Subject: [PATCH 3/5] Fix the length recorded for truncated bans (it should be the length of the header, not 0). In-Reply-To: <1355506863-20819-1-git-send-email-martin@varnish-software.com> References: <1355506863-20819-1-git-send-email-martin@varnish-software.com> Message-ID: <1355506863-20819-3-git-send-email-martin@varnish-software.com> Add a test case for reload of truncated bans. --- bin/varnishd/cache/cache_ban.c | 2 +- bin/varnishtest/tests/p00009.vtc | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 bin/varnishtest/tests/p00009.vtc diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index 64474a7..afff464 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -269,7 +269,7 @@ ban_mark_gone(struct ban *b) b->flags |= BAN_F_GONE; b->spec[BANS_FLAGS] |= BANS_FLAG_GONE; VWMB(); - vbe32enc(b->spec + BANS_LENGTH, 0); + vbe32enc(b->spec + BANS_LENGTH, BANS_HEAD_LEN); VSC_C_main->bans_gone++; VSC_C_main->bans_bytes_overhead += ln - ban_len(b->spec); } diff --git a/bin/varnishtest/tests/p00009.vtc b/bin/varnishtest/tests/p00009.vtc new file mode 100644 index 0000000..4898c43 --- /dev/null +++ b/bin/varnishtest/tests/p00009.vtc @@ -0,0 +1,41 @@ +varnishtest "Check persisted truncated gone bans" + +# Test that bans which has been gone'd, truncated and persisted works + +shell "rm -f ${tmpdir}/_.per1" + +server s1 { + rxreq + txresp -hdr "x-foo: foo" +} -start + +varnish v1 \ + -arg "-pfeature=+wait_silo" \ + -arg "-pban_lurker_sleep=0.01" \ + -storage "-sper1=persistent,${tmpdir}/_.per1,10m" \ + -vcl+backend { + } +varnish v1 -start + +# Add a ban that will (with lurker help) become a truncated gone ban last +# in the list +varnish v1 -cliok "ban obj.http.x-foo == bar" +delay 1 + +# Add an object that will point to our ban +client c1 { + txreq + rxresp + expect resp.http.x-foo == "foo" +} -run + +# Force a reload +varnish v1 -stop +varnish v1 -start + +# Check that our object is still there +client c1 { + txreq + rxresp + expect resp.http.x-foo == "foo" +} -run -- 1.7.10.4 From martin at varnish-software.com Fri Dec 14 17:41:02 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 14 Dec 2012 18:41:02 +0100 Subject: [PATCH 4/5] Mark the ban_magic as gone also in the persisted ban spec, so it can be recognized as such on reload In-Reply-To: <1355506863-20819-1-git-send-email-martin@varnish-software.com> References: <1355506863-20819-1-git-send-email-martin@varnish-software.com> Message-ID: <1355506863-20819-4-git-send-email-martin@varnish-software.com> --- bin/varnishd/cache/cache_ban.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index afff464..a06fd98 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -265,6 +265,8 @@ ban_mark_gone(struct ban *b) unsigned ln; CHECK_OBJ_NOTNULL(b, BAN_MAGIC); + AN(b->spec); + AZ(b->flags & BAN_F_GONE); ln = ban_len(b->spec); b->flags |= BAN_F_GONE; b->spec[BANS_FLAGS] |= BANS_FLAG_GONE; @@ -1268,9 +1270,8 @@ BAN_Init(void) ban_magic = BAN_New(); AN(ban_magic); - ban_magic->flags |= BAN_F_GONE; - VSC_C_main->bans_gone++; BAN_Insert(ban_magic); + ban_mark_gone(ban_magic); } /*-------------------------------------------------------------------- -- 1.7.10.4 From martin at varnish-software.com Fri Dec 14 17:41:03 2012 From: martin at varnish-software.com (Martin Blix Grydeland) Date: Fri, 14 Dec 2012 18:41:03 +0100 Subject: [PATCH 5/5] Honor the persisted GONE flag on reload of bans, and keep the duplicate counters consistent on reloads. In-Reply-To: <1355506863-20819-1-git-send-email-martin@varnish-software.com> References: <1355506863-20819-1-git-send-email-martin@varnish-software.com> Message-ID: <1355506863-20819-5-git-send-email-martin@varnish-software.com> Add a test case for this. --- bin/varnishd/cache/cache_ban.c | 14 +++++----- bin/varnishtest/tests/p00010.vtc | 56 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 bin/varnishtest/tests/p00010.vtc diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index a06fd98..5d4cef0 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -636,7 +636,7 @@ static void ban_reload(const uint8_t *ban, unsigned len) { struct ban *b, *b2; - int gone = 0; + int dup = 0; double t0, t1, t2 = 9e99; ASSERT_CLI(); @@ -653,11 +653,8 @@ ban_reload(const uint8_t *ban, unsigned len) return; if (t1 < t0) break; - if (ban_equal(b->spec, ban)) { - gone |= BAN_F_GONE; - VSC_C_main->bans_dups++; - VSC_C_main->bans_gone++; - } + if (ban_equal(b->spec, ban)) + dup = 1; } VSC_C_main->bans++; @@ -668,11 +665,14 @@ ban_reload(const uint8_t *ban, unsigned len) b2->spec = malloc(len); AN(b2->spec); memcpy(b2->spec, ban, len); - b2->flags |= gone; if (ban[BANS_FLAGS] & BANS_FLAG_REQ) { VSC_C_main->bans_req++; b2->flags |= BAN_F_REQ; } + if (dup) + VSC_C_main->bans_dups++; + if (dup || ban[BANS_FLAGS] & BANS_FLAG_GONE) + ban_mark_gone(b2); if (b == NULL) VTAILQ_INSERT_TAIL(&ban_head, b2, list); else diff --git a/bin/varnishtest/tests/p00010.vtc b/bin/varnishtest/tests/p00010.vtc new file mode 100644 index 0000000..36196d7 --- /dev/null +++ b/bin/varnishtest/tests/p00010.vtc @@ -0,0 +1,56 @@ +varnishtest "Check that reloaded bans with gone flag are really gone on restart" + +shell "rm -f ${tmpdir}/_.per[12]" + +server s1 { + rxreq + txresp -hdr "x-foo: foo" + + accept + rxreq + txresp -hdr "x-foo: bar" +} -start + +varnish v1 \ + -arg "-pfeature=+wait_silo" \ + -arg "-pban_lurker_sleep=0" \ + -storage "-sper1=persistent,${tmpdir}/_.per1,10m -sper2=persistent,${tmpdir}/_.per2,10m" \ + -vcl+backend { + } +varnish v1 -start + +client c1 { + txreq + rxresp + expect resp.http.x-foo == "foo" +} -run + +varnish v1 -cliok "ban req.url == /test" +varnish v1 -cliok "ban req.url == /test" +varnish v1 -cliok "ban.list" + +# Expect ban_magic plus the 2 we added +varnish v1 -expect bans == 3 + +# Expect 1 of the 2 added to be marked dup +varnish v1 -expect bans_dups == 1 + +# Expect ban_magic plus our 1 dup to be marked gone +varnish v1 -expect bans_gone == 2 + +# Restart +varnish v1 -stop +varnish v1 -start +varnish v1 -cliok "ban.list" + +# Check that our object is still there +client c1 { + txreq + rxresp + expect resp.http.x-foo == "foo" +} -run + +# Expect our duplicate +varnish v1 -expect bans_dups == 1 +# One more than before restart due to the new ban_magic +varnish v1 -expect bans_gone == 3 -- 1.7.10.4 From fgsch at lodoss.net Sun Dec 23 18:15:03 2012 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Sun, 23 Dec 2012 18:15:03 +0000 Subject: [PATCH]: spelling diff Message-ID: <20121223181503.f49367b9320ebcf260c5794b@lodoss.net> Hi, Some spelling corrections while I was looking at the docs. f.- diff --git a/doc/sphinx/reference/varnish-cli.rst b/doc/sphinx/reference/varnish-cli.rst index 88b05fe..c34ae7b 100644 --- a/doc/sphinx/reference/varnish-cli.rst +++ b/doc/sphinx/reference/varnish-cli.rst @@ -81,7 +81,7 @@ backend.list backend.set_health matcher state Sets the health state on a specific backend. This is useful if - you want to take a certain backend out of sirculations. + you want to take a certain backend out of circulation. ban *field operator argument* [&& field operator argument [...]] Immediately invalidate all documents matching the ban diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 98c1c47..325470c 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -483,7 +483,7 @@ vcl_fetch hit_for_pass Pass in fetch. Passes the object without caching it. This will - create a socalled hit_for_pass object which has the side effect + create a so-called hit_for_pass object which has the side effect that the decision not to cache will be cached. This is to allow would-be uncachable requests to be passed to the backend at the same time. The same logic is not necessary in vcl_recv because @@ -545,7 +545,7 @@ default code. Multiple subroutines ~~~~~~~~~~~~~~~~~~~~ -If multiple subroutines with the the name of one of the builtin +If multiple subroutines with the name of one of the builtin ones are defined, they are concatenated in the order in which they appear in the source. The default versions distributed with Varnish will be implicitly diff --git a/doc/sphinx/reference/vmod.rst b/doc/sphinx/reference/vmod.rst index a76dee1..b9eb22a 100644 --- a/doc/sphinx/reference/vmod.rst +++ b/doc/sphinx/reference/vmod.rst @@ -34,7 +34,7 @@ The vmod.vcc file The interface between your VMOD and the VCL compiler ("VCC") and the VCL runtime ("VRT") is defined in the vmod.vcc file which a python -script called "vmod.py" turns into thaumathurgically challenged C +script called "vmod.py" turns into thaumaturgically challenged C data structures that does all the hard work. The std VMODs vmod.vcc file looks somewhat like this:: From suruiqin at blackmeng.com Thu Dec 20 03:26:57 2012 From: suruiqin at blackmeng.com (=?utf-8?B?6IuP55Ge6ZKm77yI6LSd5rGJ77yJ?=) Date: Thu, 20 Dec 2012 03:26:57 -0000 Subject: no varnishstat Message-ID: An HTML attachment was scrubbed... URL: