summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2014-11-01 12:10:23 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2014-11-01 12:10:23 (GMT)
commitdacdfd20c9e59e088bfb23c2852b566acc6ad06f (patch) (side-by-side diff)
tree9c8acf2e253afd9593d5f6fccd560f7173485d48
parent4d452a770122daf33fdbe0a549e2804b6f2db086 (diff)
downloadvmod-tbf-dacdfd20c9e59e088bfb23c2852b566acc6ad06f.tar.gz
vmod-tbf-dacdfd20c9e59e088bfb23c2852b566acc6ad06f.tar.bz2
Support for VCL 4.0
* NEWS: Update. * configure.ac: Version 1.0.90 Detect Varnish version, set up the C defines and automake conditionals to indicate it. * src/.gitignore: Update. * src/Makefile.am: Don't distribute vcc_if.c and vcc_if.h, build them for the current Varnish version. * src/tbf.h: New file. * src/getla.c: Include tbf.h, rewrite to compile with both 3.0 and 4.0 * src/sleep.c: Likewise. * src/tbf.c: Likewise. * src/time.c: Likewise. * src/vmod_tbf.vcc: Rewrite using v4.0 format. * tests/.gitignore: New file. * tests/Makefile.am: Build test00.vtc and test02.vtc * tests/test00.vtc: Rename to tests/test00.vti, add conditional compilation directives. * tests/test02.vtc: Rename to tests/test02.vti, add conditional compilation directives.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--NEWS11
-rw-r--r--configure.ac14
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile.am31
-rw-r--r--src/getla.c11
-rw-r--r--src/sleep.c8
-rw-r--r--src/tbf.c30
-rw-r--r--src/tbf.h38
-rw-r--r--src/time.c23
-rw-r--r--src/vmod_tbf.vcc47
-rw-r--r--tests/.gitignore2
-rw-r--r--tests/Makefile.am31
-rw-r--r--tests/test00.vti (renamed from tests/test00.vtc)6
-rw-r--r--tests/test02.vti (renamed from tests/test02.vtc)6
14 files changed, 183 insertions, 76 deletions
diff --git a/NEWS b/NEWS
index 9c771b3..f5bcc13 100644
--- a/NEWS
+++ b/NEWS
@@ -1,21 +1,26 @@
-vmod-tbf -- history of user-visible changes. 2013-10-19
-Copyright (C) 2013 Sergey Poznyakoff
+vmod-tbf -- history of user-visible changes. 2014-10-31
+Copyright (C) 2013-2014 Sergey Poznyakoff
See the end of file for copying conditions.
Please send vmod-tbf bug reports to <gray@gnu.org>
+Version 1.0.90 (git)
+
+Support for VCL 4.0
+
+
Version 1.0, 2013-10-19
Initial release
=========================================================================
Copyright information:
-Copyright (C) 2013 Sergey Poznyakoff
+Copyright (C) 2013-2014 Sergey Poznyakoff
Permission is granted to anyone to make or distribute verbatim copies
of this document as received, in any medium, provided that the
copyright notice and this permission notice are preserved,
thus giving the recipient permission to redistribute in turn.
diff --git a/configure.ac b/configure.ac
index 6af8fd6..70fd78d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -11,13 +11,13 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with vmod-tbf. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ(2.69)
-AC_INIT([vmod-tbf], 1.0, [gray@gnu.org])
+AC_INIT([vmod-tbf], 1.0.90, [gray@gnu.org])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR(src/vmod_tbf.vcc)
AM_CONFIG_HEADER(config.h)
AC_CANONICAL_SYSTEM
@@ -64,15 +64,23 @@ fi
case "$VARNISHSRC" in
/*) ;;
*) AC_MSG_ERROR([varnish source path must be absolute pathname])
esac
VARNISHSRC=`cd $VARNISHSRC && pwd`
+VARNISHVERSION=
AC_CHECK_FILE([$VARNISHSRC/include/varnishapi.h],
- [],
- [AC_MSG_FAILURE(["$VARNISHSRC" is not a Varnish source directory])])
+ [VARNISHVERSION=3],
+ [AC_CHECK_FILE([$VARNISHSRC/include/vapi/vsm.h],
+ [VARNISHVERSION=4],
+ [AC_MSG_FAILURE(["$VARNISHSRC" is not a Varnish source directory])]) ])
+AC_SUBST([VARNISHVERSION],$VARNISHVERSION)
+
+AC_DEFINE_UNQUOTED([VARNISHVERSION],$VARNISHVERSION,[Varnish major version number])
+AM_CONDITIONAL([VARNISH3],[test $VARNISHVERSION -eq 3])
+AM_CONDITIONAL([VARNISH4],[test $VARNISHVERSION -eq 4])
# Check that varnishtest is built in the varnish source directory
AC_CHECK_FILE([$VARNISHSRC/bin/varnishtest/varnishtest],
[],
[AC_MSG_FAILURE([cannot find "$VARNISHSRC/bin/varnishtest/varnishtest". Please build your varnish source directory])]
)
diff --git a/src/.gitignore b/src/.gitignore
index 7f6e438..ce7aef0 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,2 +1,3 @@
vcc_if.c
vcc_if.h
+*.rst
diff --git a/src/Makefile.am b/src/Makefile.am
index 727d33b..f4e3bec 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,34 +13,53 @@
#
# You should have received a copy of the GNU General Public License
# along with vmod-tbf. If not, see <http://www.gnu.org/licenses/>.
AM_CPPFLAGS=\
-I$(VARNISHSRC)/include\
+ -I$(VARNISHSRC)/bin/varnishd\
-I$(VARNISHSRC)\
-DLOCALSTATEDIR=\"$(localstatedir)\"
dist_man_MANS=vmod-tbf.3 vmod_tbf.3
vmoddir = $(VMODDIR)
vmod_LTLIBRARIES = libvmod_tbf.la
libvmod_tbf_la_LDFLAGS=-module -export-dynamic -avoid-version
libvmod_tbf_la_LIBADD=
libvmod_tbf_la_SOURCES = \
+ tbf.c\
+ tbf.h\
getla.c\
sleep.c\
- time.c\
- tbf.c\
+ time.c
+nodist_libvmod_tbf_la_SOURCES = \
vcc_if.c vcc_if.h
-BUILT_SOURCES = vcc_if.c vcc_if.h
+tbf.lo: vcc_if.h
+
+CLEANFILES = vcc_if.c vcc_if.h *.rst
+
+if VARNISH4
+ vmodtool = $(VARNISHSRC)/lib/libvcc/vmodtool.py
+ vmodtoolargs = --strict
+ vccfile = $(top_srcdir)/src/vmod_tbf.vcc
+else
+ vmodtool = $(VARNISHSRC)/lib/libvmod_std/vmod.py
+ vmodtoolargs =
+ vccfile = vmod_tbf.vcc3
+
+vmod_tbf.vcc3: $(top_srcdir)/src/vmod_tbf.vcc
+ CLEANFILES += vmod_tbf.vcc3
+endif
-vcc_if.c vcc_if.h: $(VARNISHSRC)/lib/libvmod_std/vmod.py $(top_srcdir)/src/vmod_tbf.vcc
- @PYTHON@ $(VARNISHSRC)/lib/libvmod_std/vmod.py $(top_srcdir)/src/vmod_tbf.vcc
+.vcc.vcc3:
+ sed -n '/^\$$/{s///;s/\(Module *[^ ][^ ]*\).*/\1/;p}' $< > $@
+vcc_if.c vcc_if.h: $(vmodtool) $(vccfile)
+ @PYTHON@ $(vmodtool) $(vmodtoolargs) $(vccfile)
EXTRA_DIST = \
vmod_tbf.vcc
-CLEANFILES = $(builddir)/vcc_if.c $(builddir)/vcc_if.h
diff --git a/src/getla.c b/src/getla.c
index c735956..51791c4 100644
--- a/src/getla.c
+++ b/src/getla.c
@@ -12,21 +12,16 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with vmod-tbf. If not, see <http://www.gnu.org/licenses/>.
*/
#define _BSD_SOURCE
-#include <config.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <syslog.h>
+#include "tbf.h"
#if defined(HAVE_SYSINFO) && defined(HAVE_SYS_SYSINFO_H)
# include <sys/sysinfo.h>
#endif
-#include "vrt.h"
-#include "vcc_if.h"
static double
sys_getla(int what)
{
#if defined(HAVE_GETLOADAVG)
double loadavg[3];
@@ -47,14 +42,14 @@ sys_getla(int what)
#else
syslog(LOG_DAEMON|LOG_CRIT, "tbf.getla is not implemented");
return 0.0;
#endif
}
-double
-vmod_getla(struct sess *sp, int what)
+VCL_REAL
+vmod_getla(MOD_CTX ctx, VCL_INT what)
{
switch (what) {
case 1:
what = 0;
break;
case 5:
diff --git a/src/sleep.c b/src/sleep.c
index 70c4337..9242475 100644
--- a/src/sleep.c
+++ b/src/sleep.c
@@ -11,20 +11,18 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with vmod-tbf. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <config.h>
+#include "tbf.h"
#include <errno.h>
#include <time.h>
-#include "vrt.h"
-#include "vcc_if.h"
-void
-vmod_sleep(struct sess *sp, double t)
+VCL_VOID
+vmod_sleep(MOD_CTX ctx, VCL_REAL t)
{
struct timespec ts, ret;
ts.tv_sec = t;
ts.tv_nsec = (t - ts.tv_sec) * 1e9;
diff --git a/src/tbf.c b/src/tbf.c
index 7050fc7..56a4ad1 100644
--- a/src/tbf.c
+++ b/src/tbf.c
@@ -11,23 +11,18 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with vmod-tbf. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <config.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
+#include "tbf.h"
#include <syslog.h>
#include <inttypes.h>
#include <sys/stat.h>
+#include <sys/time.h>
#include <db.h>
-#include "vrt.h"
-#include "vcc_if.h"
-#include "bin/varnishd/cache.h"
static int debug_level;
static void
debugprt(const char *fmt, ...)
{
@@ -348,24 +343,24 @@ tbf_init(struct vmod_priv *priv, const struct VCL_conf *vclconf)
{
VTAILQ_INIT(&keylock_head);
VTAILQ_INIT(&keylock_avail);
}
void
-vmod_open(struct sess *sp, const char *dir, const char *params)
+vmod_open(MOD_CTX ctx, const char *dir, const char *params)
{
if (db) {
syslog(LOG_DAEMON|LOG_ERR, "tbf.open called twice");
return;
}
tbf_set_db_dir(dir);
tbf_open_safe(params);
}
void
-vmod_close(struct sess *sp)
+vmod_close(MOD_CTX ctx)
{
pthread_mutex_lock(&mutex);
if (db) {
debug(1, ("closing database %s", dbname));
db->close(db, 0);
db = NULL;
@@ -374,13 +369,13 @@ vmod_close(struct sess *sp)
tbf_disabled = 0;
}
pthread_mutex_unlock(&mutex);
}
void
-vmod_sync(struct sess *sp)
+vmod_sync(MOD_CTX ctx)
{
if (db) {
debug(1, ("synchronizing database"));
db->sync(db, 0);
}
}
@@ -407,13 +402,13 @@ vmod_sync(struct sess *sp)
struct tbf_bucket {
uint64_t timestamp; /* microseconds since epoch */
size_t tokens; /* tokens available */
};
int
-tbf_proc(struct sess *sp, DB *db, const char *key, int cost,
+tbf_proc(MOD_CTX ctx, DB *db, const char *key, int cost,
unsigned long interval, int burst_size)
{
DBT keydat, content;
struct timeval tv;
uint64_t now;
uint64_t elapsed;
@@ -496,14 +491,15 @@ tbf_proc(struct sess *sp, DB *db, const char *key, int cost,
autosync_count = 0;
}
return res;
}
-unsigned
-vmod_rate(struct sess *sp, const char *key, int cost, double t, int burst_size)
+VCL_BOOL
+vmod_rate(MOD_CTX ctx, VCL_STRING key, VCL_INT cost, VCL_REAL t,
+ VCL_INT burst_size)
{
unsigned long interval = t * USEC_PER_SEC;
int rc;
debug(2, ("entering rate(%s,%d,%g,%d)", key, cost, t, burst_size));
@@ -524,26 +520,26 @@ vmod_rate(struct sess *sp, const char *key, int cost, double t, int burst_size)
if (db) {
struct keylock *kp;
kp = keylock_find_safe(key);
debug(2, ("found key %s, ref %u", key, kp->refcnt));
AZ(pthread_mutex_lock(&kp->mutex));
- rc = tbf_proc(sp, db, key, cost, interval, burst_size);
+ rc = tbf_proc(ctx, db, key, cost, interval, burst_size);
if (--kp->refcnt == 0)
keylock_remove_safe(kp);
AZ(pthread_mutex_unlock(&kp->mutex));
} else
rc = false;
return rc;
}
#define ISWS(c) ((c)==' '||(c)=='\t')
-unsigned
-vmod_check(struct sess *sp, const char *key, const char *spec)
+VCL_BOOL
+vmod_check(MOD_CTX ctx, VCL_STRING key, VCL_STRING spec)
{
double t, v, n;
char *p;
#define SKIPWS(init) for (init; *spec && ISWS(*spec); spec++)
int burst;
@@ -598,8 +594,8 @@ vmod_check(struct sess *sp, const char *key, const char *spec)
SKIPWS(++spec);
if (*spec)
syslog(LOG_DAEMON|LOG_WARNING, "garbage after rate spec: %s",
spec);
- return vmod_rate(sp, key, 1, n/v, v/n+1);
+ return vmod_rate(ctx, key, 1, n/v, v/n+1);
}
diff --git a/src/tbf.h b/src/tbf.h
new file mode 100644
index 0000000..3c7a118
--- a/dev/null
+++ b/src/tbf.h
@@ -0,0 +1,38 @@
+/* This file is part of vmod-tbf
+ Copyright (C) 2013-2014 Sergey Poznyakoff
+
+ Vmod-tbf is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Vmod-tbf is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with vmod-tbf. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <config.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <syslog.h>
+#include "vrt.h"
+#include "vcc_if.h"
+#include "pthread.h"
+#if VARNISHVERSION == 3
+# include "bin/varnishd/cache.h"
+# define VCL_VOID void
+# define VCL_INT int
+# define VCL_REAL double
+# define VCL_BOOL unsigned
+# define VCL_STRING const char *
+# define MOD_CTX struct sess *
+# define WSPTR(s) ((s)->wrk->ws)
+#else
+# include "bin/varnishd/cache/cache.h"
+# define MOD_CTX const struct vrt_ctx *
+# define WSPTR(s) ((s)->ws)
+#endif
diff --git a/src/time.c b/src/time.c
index 01919de..9a5068b 100644
--- a/src/time.c
+++ b/src/time.c
@@ -11,39 +11,34 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with vmod-tbf. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <config.h>
-#include <stdlib.h>
-#include <stdio.h>
+#include "tbf.h"
#include <time.h>
-#include "vrt.h"
-#include "vcc_if.h"
-#include "bin/varnishd/cache.h"
-int
-vmod_systime(struct sess *sp)
+VCL_INT
+vmod_systime(MOD_CTX ctx)
{
return time(NULL);
}
-const char *
-vmod_strftime(struct sess *sp, const char *format, int timestamp)
+VCL_STRING
+vmod_strftime(MOD_CTX ctx, VCL_STRING format, VCL_INT timestamp)
{
time_t ts = (time_t) timestamp;
size_t u, n;
char *p;
- u = WS_Reserve(sp->wrk->ws, 0);
- p = sp->wrk->ws->f;
+ u = WS_Reserve(WSPTR(ctx), 0);
+ p = WSPTR(ctx)->f;
n = strftime(p, u, format, gmtime(&ts));
if (n == 0) {
- WS_Release(sp->wrk->ws, 0);
+ WS_Release(WSPTR(ctx), 0);
return NULL;
}
- WS_Release(sp->wrk->ws, n + 1);
+ WS_Release(WSPTR(ctx), n + 1);
return p;
}
diff --git a/src/vmod_tbf.vcc b/src/vmod_tbf.vcc
index 3634807..b27093b 100644
--- a/src/vmod_tbf.vcc
+++ b/src/vmod_tbf.vcc
@@ -1,11 +1,36 @@
-Module tbf
-Init tbf_init
-Function VOID open(STRING, STRING)
-Function VOID close()
-Function VOID sync()
-Function BOOL rate(STRING, INT, DURATION, INT)
-Function BOOL check(STRING, STRING)
-Function REAL getla(INT)
-Function INT systime()
-Function STRING strftime(STRING, INT)
-Function VOID sleep(DURATION)
+# This file is part of vmod-tbf
+# Copyright (C) 2013 Sergey Poznyakoff
+#
+# Vmod-tbf is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# Vmod-tbf is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with vmod-tbf. If not, see <http://www.gnu.org/licenses/>.
+
+$Module tbf 3 Token Bucket Filtering for Varnish
+
+COLOPHON
+========
+This document provides a short description of the **vmod-tbf** module.
+For a detailed documentation, please see vmod-tbf(3) manual page.
+
+DESCRIPTION
+===========
+
+$Init tbf_init
+$Function VOID open(STRING, STRING)
+$Function VOID close()
+$Function VOID sync()
+$Function BOOL rate(STRING, INT, DURATION, INT)
+$Function BOOL check(STRING, STRING)
+$Function REAL getla(INT)
+$Function INT systime()
+$Function STRING strftime(STRING, INT)
+$Function VOID sleep(DURATION)
diff --git a/tests/.gitignore b/tests/.gitignore
new file mode 100644
index 0000000..6f6760a
--- a/dev/null
+++ b/tests/.gitignore
@@ -0,0 +1,2 @@
+test00.vtc
+test02.vtc
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4790115..0f90aa7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,19 +1,40 @@
+VMOD_VTC = \
+ test01.vtc\
+ test03.vtc\
+ time00.vtc
+
+VMOD_VTI = \
+ test00.vti\
+ test02.vti
+
+BUILT_TESTS = $(VMOD_VTI:.vti=.vtc)
+
VMOD_TESTS = \
- test00.vtc\
+ test00.vti\
test01.vtc\
- test02.vtc\
+ test02.vti\
test03.vtc\
time00.vtc
-EXTRA_DIST=$(VMOD_TESTS)
+.vti.vtc:
+ sed 's/^#VARNISH$(VARNISHVERSION)#//' $< > $@
+
+EXTRA_DIST=$(VMOD_VTC) $(VMOD_VTI)
+CLEANFILES=$(BUILT_TESTS)
+
distclean-local:
rm -fr tbf
-check:
- cd $(abs_srcdir); \
+check: $(BUILT_TESTS)
for t in $(VMOD_TESTS); do \
+ n=$${t%%.vti}; \
+ if [ $$n != $$t ]; then \
+ t=$(abs_builddir)/$${n}.vtc;\
+ else \
+ t=$(abs_srcdir)/$$t;\
+ fi; \
$(VARNISHSRC)/bin/varnishtest/varnishtest \
-Dvarnishd=$(VARNISHSRC)/bin/varnishd/varnishd \
-Dvmod_topsrc=$(abs_top_srcdir) \
-Dvmod_topbuild=$(abs_top_builddir) $$t; \
done
diff --git a/tests/test00.vtc b/tests/test00.vti
index f69f5ed..05084c7 100644
--- a/tests/test00.vtc
+++ b/tests/test00.vti
@@ -12,15 +12,17 @@ varnish v1 -vcl+backend {
}
sub vcl_fini {
tbf.close();
}
sub vcl_recv {
if (!tbf.rate("url:"+req.url, 1, 20 s, 5)) {
- error 420 "Overlimit";
+#VARNISH3# error 420 "Overlimit";
+#VARNISH4# return (synth(420, "Overlimit"));
}
- return (lookup);
+#VARNISH3# return (lookup);
+#VARNISH4# return (hash);
}
} -start
client c1 {
txreq -url "/"
rxresp
diff --git a/tests/test02.vtc b/tests/test02.vti
index 8df6730..1b5e6b3 100644
--- a/tests/test02.vtc
+++ b/tests/test02.vti
@@ -12,15 +12,17 @@ varnish v1 -vcl+backend {
}
sub vcl_fini {
tbf.close();
}
sub vcl_recv {
if (!tbf.check("url:"+req.url, "4 req/s")) {
- error 420 "Overlimit";
+#VARNISH3# error 420 "Overlimit";
+#VARNISH4# return (synth(420, "Overlimit"));
}
- return (lookup);
+#VARNISH3# return (lookup);
+#VARNISH4# return (hash);
}
} -start
client c1 {
txreq -url "/"
rxresp

Return to:

Send suggestions and report system problems to the System administrator.