Commit b6d73107 authored by Julian Wiesener's avatar Julian Wiesener

Initial commit

parents
*.o
*.so
*.la
*.lo
.deps/
.libs/
vcc_if.c
vcc_if.h
Makefile
vmod_vslp.3
README.html
aclocal.m4
autom4te.cache
config.*
configure
depcomp
install-sh
libtool
ltmain.sh
m4
missing
Makefile.in
stamp-h1
Copyright (c) 2009-2013 UPLEX - Nils Goroll Systemoptimierung
...
See LICENSE for details.
You're free to use and distribute this under terms in the
LICENSE. Please add your relevant copyright statements.
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.
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src
EXTRA_DIST = README.rst
dist_man_MANS = vmod_vslp.3
MAINTAINERCLEANFILES = $(dist_man_MANS)
vmod_vslp.3: README.rst
if HAVE_RST2MAN
${RST2MAN} README.rst $@
else
@echo "========================================"
@echo "You need rst2man installed to make dist"
@echo "========================================"
@false
endif
===============
vmod_vslp
===============
------------------------------------------
Varnish Consistent Hashing Director Module
------------------------------------------
:Author: Julian Wiesener
:Date: 2013-08-14
:Version: 1.0
:Manual section: 3
.. _synopsis:
SYNOPSIS
========
::
import vslp;
sub vcl_init {
new vd = vslp.vslp();
vd.add_backend(be1);
vd.add_backend(be2);
vd.add_backend(be3);
vd.init_hashcircle(150); #number of replicas
}
sub vcl_recv {
set req.backend = vd.backend();
}
DESCRIPTION
===========
FUNCTIONS
=========
LIMITATIONS
===========
INSTALLATION
============
The source tree is based on autotools to configure the building, and
does also have the necessary bits in place to do functional unit tests
using the varnishtest tool.
Usage::
./configure VARNISHSRC=DIR [VMODDIR=DIR]
`VARNISHSRC` is the directory of the Varnish source tree for which to
compile your vmod.
Optionally you can also set the vmod install directory by adding
`VMODDIR=DIR` (defaults to the pkg-config discovered directory from your
Varnish installation).
Make targets:
* make - builds the vmod
* make install - installs your vmod in `VMODDIR`
* make check - runs the unit tests in ``src/tests/*.vtc``
HISTORY
=======
Version 1.0: Initial version.
COPYRIGHT
=========
This document is licensed under the same license as the
libvmod-vslp project. See LICENSE for details.
Copyright (c) 2013 UPLEX Nils Goroll Systemoptimierung. All rights
reserved.
#!/bin/sh
#
# $Id$
#
warn() {
echo "WARNING: $@" 1>&2
}
case `uname -s` in
Darwin)
LIBTOOLIZE=glibtoolize
;;
FreeBSD)
LIBTOOLIZE=libtoolize
;;
Linux)
LIBTOOLIZE=libtoolize
;;
SunOS)
LIBTOOLIZE=libtoolize
;;
*)
warn "unrecognized platform:" `uname -s`
LIBTOOLIZE=libtoolize
esac
automake_version=`automake --version | tr ' ' '\n' | egrep '^[0-9]\.[0-9a-z.-]+'`
if [ -z "$automake_version" ] ; then
warn "unable to determine automake version"
else
case $automake_version in
0.*|1.[0-8]|1.[0-8][.-]*)
warn "automake ($automake_version) detected; 1.9 or newer recommended"
;;
*)
;;
esac
fi
set -ex
aclocal
$LIBTOOLIZE --copy --force
autoheader
automake --add-missing --copy --foreign
autoconf
AC_PREREQ(2.59)
AC_COPYRIGHT([Copyright (c) 2013 UPLEX - Nils Goroll Systemoptimierung, 2011 Varnish Software AS])
AC_INIT([libvmod-vslp], [master])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR(src/vmod_vslp.vcc)
AM_CONFIG_HEADER(config.h)
AC_CANONICAL_SYSTEM
AC_LANG(C)
AM_INIT_AUTOMAKE([foreign])
AC_GNU_SOURCE
AC_PROG_CC
AC_PROG_CC_STDC
if test "x$ac_cv_prog_cc_c99" = xno; then
AC_MSG_ERROR([Could not find a C99 compatible compiler])
fi
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LIBTOOL
AC_PROG_MAKE_SET
# Check for rst utilities
AC_CHECK_PROGS(RST2MAN, [rst2man rst2man.py], "no")
if test "x$RST2MAN" = "xno"; then
AC_MSG_WARN([rst2man not found - not building man pages])
fi
AM_CONDITIONAL(HAVE_RST2MAN, [test "x$RST2MAN" != "xno"])
# Check for pkg-config
PKG_PROG_PKG_CONFIG
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([sys/stdlib.h])
# Check for python
AC_CHECK_PROGS(PYTHON, [python3 python3.1 python3.2 python2.7 python2.6 python2.5 python2 python], [AC_MSG_ERROR([Python is needed to build this vmod, please install python.])])
# Varnish source tree
AC_ARG_VAR([VARNISHSRC], [path to Varnish source tree (mandatory)])
if test "x$VARNISHSRC" = x; then
AC_MSG_ERROR([No Varnish source tree specified])
fi
VARNISHSRC=`cd $VARNISHSRC && pwd`
AC_CHECK_FILE([$VARNISHSRC/include/vrt.h],
[],
[AC_MSG_FAILURE(["$VARNISHSRC" is not a Varnish source directory])]
)
# Check that varnishtest is built in the varnish source directory
AC_CHECK_FILE([$VARNISHSRC/bin/varnishtest/varnishtest],
[],
[AC_MSG_FAILURE([Can't find "$VARNISHSRC/bin/varnishtest/varnishtest". Please build your varnish source directory])]
)
# vmod installation dir
AC_ARG_VAR([VMODDIR], [vmod installation directory @<:@LIBDIR/varnish/vmods@:>@])
if test "x$VMODDIR" = x; then
VMODDIR=`pkg-config --variable=vmoddir varnishapi`
if test "x$VMODDIR" = x; then
AC_MSG_FAILURE([Can't determine vmod installation directory])
fi
fi
# This corresponds to FreeBSD's WARNS level 6
DEVELOPER_CFLAGS="-Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wunused-parameter -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls -Wformat"
# Additional flags for GCC 4
EXTRA_DEVELOPER_CFLAGS="-Wextra -Wno-missing-field-initializers -Wno-sign-compare"
# --enable-developer-warnings
AC_ARG_ENABLE(developer-warnings,
AS_HELP_STRING([--enable-developer-warnings],[enable strict warnings (default is NO)]),
CFLAGS="${CFLAGS} ${DEVELOPER_CFLAGS}")
# --enable-debugging-symbols
AC_ARG_ENABLE(debugging-symbols,
AS_HELP_STRING([--enable-debugging-symbols],[enable debugging symbols (default is NO)]),
CFLAGS="${CFLAGS} -O0 -g -fno-inline")
# --enable-diagnostics
AC_ARG_ENABLE(diagnostics,
AS_HELP_STRING([--enable-diagnostics],[enable run-time diagnostics (default is NO)]),
CFLAGS="${CFLAGS} -DDIAGNOSTICS")
# --enable-extra-developer-warnings
AC_ARG_ENABLE(extra-developer-warnings,
AS_HELP_STRING([--enable-extra-developer-warnings],[enable even stricter warnings (default is NO)]),
[],
[enable_extra_developer_warnings=no])
if test "x$enable_stack_protector" != "xno"; then
save_CFLAGS="$CFLAGS"
CFLAGS="${CFLAGS} ${EXTRA_DEVELOPER_CFLAGS}"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([],[],[])],
[],
[AC_MSG_WARN([All of ${EXTRA_DEVELOPER_CFLAGS} not supported, disabling])
CFLAGS="$save_CFLAGS"])
fi
# --enable-stack-protector
AC_ARG_ENABLE(stack-protector,
AS_HELP_STRING([--enable-stack-protector],[enable stack protector (default is NO)]),
[],
[enable_stack_protector=no])
if test "x$enable_stack_protector" != "xno"; then
save_CFLAGS="$CFLAGS"
CFLAGS="${CFLAGS} -fstack-protector-all"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([],[],[])],
[],
[AC_MSG_WARN([-fstack-protector not supported, disabling])
CFLAGS="$save_CFLAGS"])
fi
# --enable-tests
AC_ARG_ENABLE(tests,
AS_HELP_STRING([--enable-tests],[build test programs (default is NO)]))
AM_CONDITIONAL([ENABLE_TESTS], [test x$enable_tests = xyes])
# --enable-werror
AC_ARG_ENABLE(werror,
AS_HELP_STRING([--enable-werror],[use -Werror (default is NO)]),
CFLAGS="${CFLAGS} -Werror")
AC_CONFIG_FILES([
Makefile
src/Makefile
])
AC_OUTPUT
AM_CPPFLAGS = \
-I$(VARNISHSRC)/include \
-I$(VARNISHSRC)/bin/varnishd \
-I$(VARNISHSRC)/lib/libvgz
AM_LDFLAGS = $(AM_LT_LDFLAGS)
vmoddir = $(VMODDIR)
vmod_LTLIBRARIES = libvmod_vslp.la
vmod_srcdir = $(top_srcdir)/src
vmodtool = $(VARNISHSRC)/lib/libvcl/vmodtool.py
libvmod_vslp_la_LDFLAGS = $(AM_LDFLAGS) -module -export-dynamic -avoid-version -shared
libvmod_vslp_la_SOURCES = \
vmod_vslp.c \
vslp_dir.c \
vslp_hash.c
nodist_libvmod_vslp_la_SOURCES = \
vcc_if.c \
vcc_if.h
# BUILT_SOURCES is only a hack and dependency tracking does not help for the first build
vmod_vslp.lo: vcc_if.h
vcc_if.c vcc_if.h: $(vmodtool) $(vmod_srcdir)/vmod_vslp.vcc
@PYTHON@ $(vmodtool) $(vmod_srcdir)/vmod_vslp.vcc
VMOD_TESTS = tests/*.vtc
check: $(VARNISHSRC)/bin/varnishtest/varnishtest
$(VARNISHSRC)/bin/varnishtest/varnishtest \
-Dvarnishd=$(VARNISHSRC)/bin/varnishd/varnishd \
-Dvmod_topbuild=$(abs_top_builddir) \
tests/*.vtc
EXTRA_DIST = \
vmod_vslp.vcc \
$(VMOD_TESTS)
CLEANFILES = $(builddir)/vcc_if.c $(builddir)/vcc_if.h
varnishtest "VSLP director"
server s1 {
rxreq
txresp -body "ech3Ooj"
} -start
server s2 {
rxreq
txresp -body "ieQu2qua"
} -start
server s3 {
rxreq
txresp -body "xiuFi3Pe"
} -start
varnish v1 -vcl+backend {
import vslp from "${vmod_topbuild}/src/.libs/libvmod_vslp.so" ;
sub vcl_init {
new vd = vslp.vslp();
vd.add_backend(s1);
vd.add_backend(s2);
vd.add_backend(s3);
vd.set_rampup_ratio(0);
vd.init_hashcircle(25);
}
sub vcl_recv {
set req.backend = vd.backend();
return(pass);
}
} -start
client c1 {
txreq -url /eishoSu2
rxresp
expect resp.body == "ech3Ooj"
txreq -url /Zainao9d
rxresp
expect resp.body == "ieQu2qua"
txreq -url /Aunah3uo
rxresp
expect resp.body == "xiuFi3Pe"
} -run
varnishtest "VSLP director/int key"
server s1 {
rxreq
txresp -body "ech3Ooj"
} -start
server s2 {
rxreq
txresp -body "ieQu2qua"
} -start
server s3 {
rxreq
txresp -body "xiuFi3Pe"
} -start
varnish v1 -vcl+backend {
import vslp from "${vmod_topbuild}/src/.libs/libvmod_vslp.so" ;
sub vcl_init {
new vd = vslp.vslp();
vd.add_backend(s1);
vd.add_backend(s2);
vd.add_backend(s3);
vd.set_rampup_ratio(0);
vd.init_hashcircle(25);
}
sub vcl_recv {
if(req.url == "/1") {
set req.backend = vd.backend_by_int(1);
}
if(req.url == "/2") {
set req.backend = vd.backend_by_int(2147483647);
}
if(req.url == "/3") {
set req.backend = vd.backend_by_int(4294967295);
}
return(pass);
}
} -start
client c1 {
txreq -url /1
rxresp
expect resp.body == "ech3Ooj"
txreq -url /2
rxresp
expect resp.body == "ieQu2qua"
txreq -url /3
rxresp
expect resp.body == "xiuFi3Pe"
} -run
varnishtest "VSLP director SHA256"
server s1 {
rxreq
txresp -body "ech3Ooj"
} -start
server s2 {
rxreq
txresp -body "ieQu2qua"
} -start
server s3 {
rxreq
txresp -body "xiuFi3Pe"
} -start
varnish v1 -vcl+backend {
import vslp from "${vmod_topbuild}/src/.libs/libvmod_vslp.so" ;
sub vcl_init {
new vd = vslp.vslp();
vd.add_backend(s1);
vd.add_backend(s2);
vd.add_backend(s3);
vd.set_rampup_ratio(0);
vd.set_hash(SHA256);
vd.init_hashcircle(25);
}
sub vcl_recv {
set req.backend = vd.backend();
return(pass);
}
} -start
client c1 {
txreq -url /Boo0aixe
rxresp
expect resp.body == "ech3Ooj"
txreq -url /eishoSu2
rxresp
expect resp.body == "ieQu2qua"
txreq -url /Aunah3uo
rxresp
expect resp.body == "xiuFi3Pe"
} -run
varnishtest "VSLP director RS"
server s1 {
rxreq
txresp -body "ech3Ooj"
} -start
server s2 {
rxreq
txresp -body "ieQu2qua"
} -start
server s3 {
rxreq
txresp -body "xiuFi3Pe"
} -start
varnish v1 -vcl+backend {
import vslp from "${vmod_topbuild}/src/.libs/libvmod_vslp.so" ;
sub vcl_init {
new vd = vslp.vslp();
vd.add_backend(s1);
vd.add_backend(s2);
vd.add_backend(s3);
vd.set_rampup_ratio(0);
vd.set_hash(RS);
vd.init_hashcircle(25);
}
sub vcl_recv {
set req.backend = vd.backend();
return(pass);
}
} -start
client c1 {
txreq -url /we0eeTho
rxresp
expect resp.body == "ech3Ooj"
txreq -url /mae8ooNu
rxresp
expect resp.body == "ieQu2qua"
txreq -url /oob3dahS
rxresp
expect resp.body == "xiuFi3Pe"
} -run
varnishtest "VSLP director String"
server s1 {
rxreq
txresp -body "ech3Ooj"
} -start
server s2 {
rxreq
txresp -body "ieQu2qua"
} -start
server s3 {
rxreq
txresp -body "xiuFi3Pe"
} -start
varnish v1 -vcl+backend {
import vslp from "${vmod_topbuild}/src/.libs/libvmod_vslp.so" ;
sub vcl_init {
new vd = vslp.vslp();
vd.add_backend(s1);
vd.add_backend(s2);
vd.add_backend(s3);
vd.set_rampup_ratio(0);
vd.init_hashcircle(25);
}
sub vcl_recv {
if(req.url == "/1") {
set req.backend = vd.backend_by_string("/eishoSu2");
}
if(req.url == "/2") {
set req.backend = vd.backend_by_string_hash("/eishoSu2", SHA256);
}
if(req.url == "/3") {
set req.backend = vd.backend_by_string_hash("/oob3dahS", RS);
}
return(pass);
}
} -start
client c1 {
txreq -url /1
rxresp
expect resp.body == "ech3Ooj"
txreq -url /2
rxresp
expect resp.body == "ieQu2qua"
txreq -url /3
rxresp
expect resp.body == "xiuFi3Pe"
} -run
varnishtest "VSLP director Restarts"
server s1 {
rxreq
txresp -body "ech3Ooj"
rxreq
txresp -body "ech3Ooj"
rxreq
txresp -body "ech3Ooj"
} -start
server s2 {
rxreq
txresp -body "ieQu2qua"
rxreq
txresp -body "ieQu2qua"
rxreq
txresp -body "ieQu2qua"
} -start
server s3 {
rxreq
txresp -body "xiuFi3Pe"
rxreq
txresp -body "xiuFi3Pe"
rxreq
txresp -body "xiuFi3Pe"
} -start
varnish v1 -vcl+backend {
import vslp from "${vmod_topbuild}/src/.libs/libvmod_vslp.so" ;
sub vcl_init {
new vd = vslp.vslp();
vd.add_backend(s1);
vd.add_backend(s2);
vd.add_backend(s3);
vd.set_rampup_ratio(0);
vd.init_hashcircle(25);
}
sub vcl_recv {
set req.backend = vd.backend_by_string("/eishoSu2");
if(req.url == "/2" && req.restarts > 0) {
unset req.http.vrstart;
}
if(req.url == "/3" && req.restarts > 1) {
unset req.http.vrstart;
}
return(pass);
}
sub vcl_deliver {
if(req.http.vrstart) {
return(restart);
}
}
} -start
client c1 {
txreq -url /1
rxresp
expect resp.body == "ech3Ooj"
txreq -url /2 -hdr "vrstart: 1"
rxresp
expect resp.body == "ieQu2qua"
txreq -url /3 -hdr "vrstart: 1"
rxresp
expect resp.body == "xiuFi3Pe"
} -run
varnishtest "VSLP director Unhealthy"
server s1 {
rxreq
txresp -body "ech3Ooj"
} -start
server s2 {
rxreq
txresp -body "ieQu2qua"
} -start
server s3 {
rxreq
txresp -body "xiuFi3Pe"
} -start
varnish v1 -vcl+backend {
import vslp from "${vmod_topbuild}/src/.libs/libvmod_vslp.so" ;
sub vcl_init {
new vd = vslp.vslp();
vd.add_backend(s1);
vd.add_backend(s2);
vd.add_backend(s3);
vd.set_rampup_ratio(0);
vd.init_hashcircle(25);
}
sub vcl_recv {
set req.backend = vd.backend_by_string("/eishoSu2");
return(pass);
}
sub vcl_deliver {
if(req.http.vrstart) {
return(restart);
}
}
} -start
varnish v1 -cliok "backend.set_health s1 sick"
client c1 {
txreq
rxresp
expect resp.body == "ieQu2qua"
} -run
varnish v1 -cliok "backend.set_health s2 sick"
client c1 {
txreq
rxresp
expect resp.body == "xiuFi3Pe"
} -run
varnishtest "VSLP director Rampup Time"
server s1 {
rxreq
txresp -body "ech3Ooj"
} -start
server s2 {
rxreq
txresp -body "ieQu2qua"
rxreq
txresp -body "ieQu2qua"
} -start
server s3 {
rxreq
txresp -body "xiuFi3Pe"
} -start
varnish v1 -vcl+backend {
import vslp from "${vmod_topbuild}/src/.libs/libvmod_vslp.so" ;
sub vcl_init {
new vd = vslp.vslp();
vd.add_backend(s1);
vd.add_backend(s2);
vd.add_backend(s3);
vd.set_rampup_ratio(0);
vd.set_rampup_time(15s);
vd.init_hashcircle(25);
}
sub vcl_recv {
set req.backend = vd.backend_by_string("/eishoSu2");
return(pass);
}
sub vcl_deliver {
if(req.http.vrstart) {
return(restart);
}
}
} -start
varnish v1 -cliok "backend.set_health s1 sick"
client c1 {
txreq
rxresp
expect resp.body == "ieQu2qua"
} -run
varnish v1 -cliok "backend.set_health s1 healthy"
client c1 {
txreq
rxresp
expect resp.body == "ieQu2qua"
} -run
delay 16
client c1 {
txreq
rxresp
expect resp.body == "ech3Ooj"
} -run
varnishtest "VSLP director"
server s1 {
rxreq
txresp -body "ech3Ooj"
rxreq
txresp -body "ech3Ooj"
rxreq
txresp -body "ech3Ooj"
} -start
server s2 {
rxreq
txresp -body "ieQu2qua"
rxreq
txresp -body "ieQu2qua"
} -start
server s3 {
rxreq
txresp -body "xiuFi3Pe"
} -start
varnish v1 -vcl+backend {
import vslp from "${vmod_topbuild}/src/.libs/libvmod_vslp.so" ;
sub vcl_init {
new vd = vslp.vslp();
vd.add_backend(s1);
vd.add_backend(s2);
vd.add_backend(s3);
vd.set_rampup_ratio(0.40);
vd.init_hashcircle(25);
}
sub vcl_recv {
set req.backend = vd.backend();
return(pass);
}
} -start
varnish v1 -cliok "debug.srandom 1"
client c1 {
txreq -url /eishoSu2 -hdr "vdebug: 1"
rxresp
expect resp.body == "ieQu2qua"
txreq -url /eishoSu2 -hdr "vdebug: 2"
rxresp
expect resp.body == "ech3Ooj"
txreq -url /eishoSu2 -hdr "vdebug: 3"
rxresp
expect resp.body == "ech3Ooj"
txreq -url /eishoSu2 -hdr "vdebug: 4"
rxresp
expect resp.body == "ech3Ooj"
txreq -url /eishoSu2 -hdr "vdebug: 5"
rxresp
expect resp.body == "ieQu2qua"
} -run
/*-
* Copyright (c) 2009-2013 UPLEX - Nils Goroll Systemoptimierung
* All rights reserved.
*
* Author: Julian Wiesener <jw@uplex.de>
*
* 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 <stdlib.h>
#include <stdint.h>
#include <arpa/inet.h>
#include "cache/cache.h"
#include "cache/cache_backend.h"
#include "vrt.h"
#include "vbm.h"
#include "vcc_if.h"
#include "vslp_hash.h"
#include "vslp_dir.h"
struct vmod_vslp_vslp {
unsigned magic;
#define VMOD_VSLP_VSLP_MAGIC 0x6e63e1bf
struct vslpdir *vslpd;
};
VCL_VOID __match_proto__(td_vslp_vslp__init)
vmod_vslp__init(const struct vrt_ctx *ctx, struct vmod_vslp_vslp **vslpdp, const char *vcl_name)
{
struct vmod_vslp_vslp *vslpd;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(vslpdp);
AZ(*vslpdp);
ALLOC_OBJ(vslpd, VMOD_VSLP_VSLP_MAGIC);
AN(vslpd);
*vslpdp = vslpd;
vslpdir_new(&vslpd->vslpd, vcl_name, vslpd);
}
VCL_VOID __match_proto__(td_vslp_vslp__fini)
vmod_vslp__fini(struct vmod_vslp_vslp **vslpdp)
{
struct vmod_vslp_vslp *vslpd;
vslpd = *vslpdp;
*vslpdp = NULL;
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
vslpdir_delete(&vslpd->vslpd);
FREE_OBJ(vslpd);
}
VCL_VOID __match_proto__(td_vslp_vslp_add_backend)
vmod_vslp_add_backend(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd, VCL_BACKEND be)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
vslpdir_add_backend(vslpd->vslpd, be);
}
VCL_VOID __match_proto__(td_vslp_set_rampup_ratio)
vmod_vslp_set_rampup_ratio(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd, VCL_REAL ratio)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
vslpdir_set_rampup_ratio(vslpd->vslpd, ratio);
}
VCL_VOID __match_proto__(td_vslp_set_rampup_time)
vmod_vslp_set_rampup_time(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd, VCL_DURATION duration)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
vslpdir_set_rampup_time(vslpd->vslpd, duration);
}
VCL_VOID __match_proto__(td_vslp_vslp_set_hash)
vmod_vslp_set_hash(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd, VCL_ENUM hash_m)
{
hash_func hash_fp;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
hash_fp = vslp_get_hash_fp(hash_m);
vslpdir_set_hash(vslpd->vslpd, hash_fp);
}
VCL_VOID __match_proto__(td_vslp_init_hashcircle)
vmod_vslp_init_hashcircle(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd, VCL_INT replicas)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
vslpdir_init_hashcircle(vslpd->vslpd, replicas);
}
VCL_BACKEND __match_proto__(td_vslp_vslp_backend)
vmod_vslp_backend(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd)
{
uint32_t hash;
VCL_BACKEND be;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
AN(ctx->http_req);
AN(ctx->http_req->hd);
hash = vslpd->vslpd->hash_fp(ctx->http_req->hd[HTTP_HDR_URL].b);
be = vslpdir_pick_be(vslpd->vslpd, ctx, hash);
return (be);
}
VCL_BACKEND __match_proto__(td_vslp_vslp_backend_by_int)
vmod_vslp_backend_by_int(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd, VCL_INT i)
{
VCL_BACKEND be;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
be = vslpdir_pick_be(vslpd->vslpd, ctx, i);
return (be);
}
VCL_BACKEND __match_proto__(td_vslp_vslp_backend_by_string)
vmod_vslp_backend_by_string(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd, VCL_STRING s)
{
uint32_t hash;
VCL_BACKEND be;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
hash = vslpd->vslpd->hash_fp(s);
be = vslpdir_pick_be(vslpd->vslpd, ctx, hash);
return (be);
}
VCL_BACKEND __match_proto__(td_vslp_vslp_backend_by_string_hash)
vmod_vslp_backend_by_string_hash(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd, VCL_STRING s, VCL_ENUM hash_m)
{
uint32_t hash;
hash_func hash_fp;
VCL_BACKEND be;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
hash_fp = vslp_get_hash_fp(hash_m);
hash = hash_fp(s);
be = vslpdir_pick_be(vslpd->vslpd, ctx, hash);
return (be);
}
#-
# Copyright (c) 2009-2013 UPLEX - Nils Goroll Systemoptimierung
# All rights reserved.
#
# Author: Julian Wiesener <jw@uplex.de>
#
# 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.
Module vslp
Object vslp() {
Method VOID .add_backend(BACKEND)
Method VOID .set_rampup_ratio(REAL)
Method VOID .set_rampup_time(DURATION)
Method VOID .set_hash(ENUM { CRC32, SHA256, RS })
Method VOID .init_hashcircle(INT)
Method BACKEND .backend()
Method BACKEND .backend_by_int(INT)
Method BACKEND .backend_by_string(STRING)
Method BACKEND .backend_by_string_hash(STRING, ENUM { CRC32, SHA256, RS })
}
This diff is collapsed.
/*-
* Copyright (c) 2009-2013 UPLEX - Nils Goroll Systemoptimierung
* All rights reserved.
*
* Author: Julian Wiesener <jw@uplex.de>
*
* 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.
*/
struct vbitmap;
struct be_state {
unsigned magic;
#define VSLP_BESTATE_MAGIC 0x14e33bd2
time_t recover_time;
uint32_t state;
uint32_t canon_point;
};
struct vslp_hostnode {
uint32_t point;
unsigned int host;
};
struct vslp_host {
VCL_BACKEND *backend;
uint32_t canon_point;
};
struct vslpdir {
unsigned magic;
#define VSLPDIR_MAGIC 0xdbb7d59f
pthread_mutex_t mtx;
unsigned n_backend;
unsigned l_backend;
VCL_BACKEND *backend;
struct be_state *bstate;
time_t rampup_time;
double altsrv_p;
hash_func hash_fp;
struct vslp_hostnode *hashcircle;
VCL_INT replicas;
};
void vslpdir_new(struct vslpdir **vslpdp, const char *vcl_name, void *priv);
void vslpdir_delete(struct vslpdir **vslpdp);
void vslpdir_add_backend(struct vslpdir *vslpd, VCL_BACKEND be);
void vslpdir_set_rampup_ratio(struct vslpdir *vslpd, VCL_REAL ratio);
void vslpdir_set_rampup_time(struct vslpdir *vslpd, VCL_DURATION duration);
void vslpdir_set_hash(struct vslpdir *vslpd, hash_func hash_m);
void vslpdir_init_hashcircle(struct vslpdir *vslpd, VCL_INT replicas);
void vslpdir_lock(struct vslpdir *vslpd);
void vslpdir_unlock(struct vslpdir *vslpd);
void vslpdir_expand(struct vslpdir *vslpd, unsigned n);
unsigned vslpdir_any_healthy(struct vslpdir *vslpd, const uint8_t *digest);
VCL_BACKEND vslpdir_pick_be(struct vslpdir *vslpd, const struct vrt_ctx *ctx, uint32_t hash);
/*-
* Copyright (c) 2009-2013 UPLEX - Nils Goroll Systemoptimierung
* All rights reserved.
*
* Authors: Nils Goroll <nils.goroll@uplex.de>
* Geoffrey Simmons <geoff.simmons@uplex.de>
* Julian Wiesener <jw@uplex.de>
*
* 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 <stdint.h>
#include <string.h>
#include "cache/cache.h"
#include "vrt.h"
#include "vgz.h"
#include "vsha256.h"
#include "vslp_hash.h"
uint32_t vslp_hash_crc32(VCL_STRING s)
{
uint32_t crc;
crc = crc32(~0U, (const unsigned char*)s, strlen(s));
crc ^= ~0U;
crc++;
return (crc ? crc : 1);
}
uint32_t vslp_hash_sha256(VCL_STRING s)
{
uint32_t res = 0;
struct SHA256Context sha256;
union {
unsigned char digest[32];
uint32_t uint32_digest[8];
} sha256_digest;
SHA256_Init(&sha256);
SHA256_Update(&sha256, s, strlen(s));
SHA256_Final(sha256_digest.digest, &sha256);
/*
* use low 32 bits only
* XXX: Are these the best bits to pick?
*/
res = sha256_digest.uint32_digest[7];
res++;
return (res ? res : 1);
}
uint32_t vslp_hash_rs(VCL_STRING s)
{
uint32_t res = 0;
/* hash function from Robert Sedgwicks 'Algorithms in C' book */
const uint32_t b = 378551;
uint32_t a = 63689;
while (*s) {
res = res * a + (*s++);
a *= b;
}
res++;
return (res ? res : 1);
}
hash_func vslp_get_hash_fp(VCL_ENUM hash_m)
{
if (!strcmp(hash_m, "CRC32"))
return vslp_hash_crc32;
if (!strcmp(hash_m, "SHA256"))
return vslp_hash_sha256;
if (!strcmp(hash_m, "RS"))
return vslp_hash_rs;
WRONG("Illegal VMOD enum");
}
/*-
* Copyright (c) 2009-2013 UPLEX - Nils Goroll Systemoptimierung
* All rights reserved.
*
* Author: Julian Wiesener <jw@uplex.de>
*
* 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.
*/
typedef uint32_t (*hash_func)(VCL_STRING);
uint32_t vslp_hash_crc32(VCL_STRING s);
uint32_t vslp_hash_sha256(VCL_STRING s);
uint32_t vslp_hash_rs(VCL_STRING s);
hash_func vslp_get_hash_fp(VCL_ENUM hash_m);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment