Commit f4de4802 authored by Geoff Simmons's avatar Geoff Simmons

initial commit, passes the first test

parents
((nil . ((indent-tabs-mode . t)))
(c-mode . ((c-file-style . "BSD"))))
Makefile
Makefile.in
.deps/
.libs/
*.o
*.lo
*.la
*~
*.[1-9]
/aclocal.m4
/autom4te.cache/
/compile
/config.guess
/config.h
/config.h.in
/config.log
/config.status
/config.sub
/configure
/depcomp
/install-sh
/libtool
/ltmain.sh
/missing
/stamp-h1
/m4/
/src/vcc_if.c
/src/vcc_if.h
/src/vmod_*rst
See LICENSE for details.
Copyright (c) 2015 UPLEX Nils Goroll Systemoptimierung
All rights reserved.
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 -I ${LIBVARNISHAPI_DATAROOTDIR}/aclocal
SUBDIRS = src
DISTCHECK_CONFIGURE_FLAGS = \
VMOD_DIR='$${libdir}/varnish/vmods'
EXTRA_DIST = README.rst LICENSE vmod-oob_probe.spec debian
doc_DATA = README.rst LICENSE
dist_man_MANS = vmod_oob_probe.3
MAINTAINERCLEANFILES = $(dist_man_MANS)
vmod_oob_probe.3: src/vmod_oob_probe.man.rst
%.1 %.2 %.3 %.4 %.5 %.6 %.7 %.8 %.9:
if HAVE_RST2MAN
${RST2MAN} $< $@
else
@echo "========================================"
@echo "You need rst2man installed to make dist"
@echo "========================================"
@false
endif
#!/bin/sh
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
# check for varnishapi.m4 in custom paths
dataroot=$(pkg-config --variable=datarootdir varnishapi 2>/dev/null)
if [ -z "$dataroot" ] ; then
cat >&2 <<'EOF'
Package varnishapi was not found in the pkg-config search path.
Perhaps you should add the directory containing `varnishapi.pc'
to the PKG_CONFIG_PATH environment variable
EOF
exit 1
fi
set -ex
aclocal -I m4 -I ${dataroot}/aclocal
$LIBTOOLIZE --copy --force
autoheader
automake --add-missing --copy --foreign
autoconf
AC_PREREQ(2.59)
AC_COPYRIGHT([Copyright (c) 2015 UPLEX Nils Goroll Systemoptimierung])
AC_INIT([libvmod-oob_probe], [trunk])
AC_CONFIG_MACRO_DIR([m4])
m4_ifndef([VARNISH_VMOD_INCLUDES], AC_MSG_ERROR([Need varnish.m4 -- see README.rst]))
AC_CONFIG_SRCDIR(src/vmod.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"])
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([sys/stdlib.h])
# backwards compat with older pkg-config
# - pull in AC_DEFUN from pkg.m4
m4_ifndef([PKG_CHECK_VAR], [
# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# -------------------------------------------
# Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])# PKG_CHECK_VAR
])
PKG_CHECK_MODULES([libvarnishapi], [varnishapi])
PKG_CHECK_VAR([LIBVARNISHAPI_PREFIX], [varnishapi], [prefix])
PKG_CHECK_VAR([LIBVARNISHAPI_DATAROOTDIR], [varnishapi], [datarootdir])
PKG_CHECK_VAR([LIBVARNISHAPI_BINDIR], [varnishapi], [bindir])
PKG_CHECK_VAR([LIBVARNISHAPI_SBINDIR], [varnishapi], [sbindir])
AC_SUBST([LIBVARNISHAPI_DATAROOTDIR])
# Varnish include files tree
VARNISH_VMOD_INCLUDES
VARNISH_VMOD_DIR
VARNISH_VMODTOOL
# inherit the prefix from Varnish.
# acessing ac_ variable because AC_PREFIX_DEFAULT acts too early
ac_default_prefix=$LIBVARNISHAPI_PREFIX
AC_PATH_PROG([VARNISHTEST], [varnishtest], [],
[$LIBVARNISHAPI_BINDIR:$LIBVARNISHAPI_SBINDIR:$PATH])
AC_PATH_PROG([VARNISHD], [varnishd], [],
[$LIBVARNISHAPI_SBINDIR:$LIBVARNISHAPI_BINDIR:$PATH])
AC_CONFIG_FILES([
Makefile
src/Makefile
])
AC_OUTPUT
AM_CPPFLAGS = @VMOD_INCLUDES@ -Wall -Werror
vmoddir = @VMOD_DIR@
vmod_LTLIBRARIES = libvmod_oob_probe.la
libvmod_oob_probe_la_LDFLAGS = -module -export-dynamic -avoid-version -shared
libvmod_oob_probe_la_SOURCES = \
vmod.c
nodist_libvmod_oob_probe_la_SOURCES = \
vcc_if.c \
vcc_if.h
vmod_oob_probe.lo: vcc_if.c vcc_if.h
vcc_if.c: vcc_if.h
vcc_if.h: @VMODTOOL@ $(top_srcdir)/src/vmod.vcc
@VMODTOOL@ $(top_srcdir)/src/vmod.vcc
VMOD_TESTS = $(top_srcdir)/src/tests/*.vtc
.PHONY: $(VMOD_TESTS)
$(top_srcdir)/src/tests/*.vtc: libvmod_oob_probe.la
@VARNISHTEST@ -Dvarnishd=@VARNISHD@ -Dvmod_topbuild=$(abs_top_builddir) $@
check: $(VMOD_TESTS)
EXTRA_DIST = \
vmod.vcc \
$(VMOD_TESTS)
CLEANFILES = \
$(builddir)/vcc_if.c \
$(builddir)/vcc_if.h \
$(builddir)/vmod_oob_probe.rst \
$(builddir)/vmod_oob_probe.man.rst
varnishtest "Test VMOD oob_probe (cf. v00014.vtc)"
server s1 {
rxreq
expect req.url == "/"
txresp -body "slash"
rxreq
expect req.url == "/foo"
txresp -body "foobar"
} -start
server s2 -repeat 3 {
rxreq
expect req.url == "/"
txresp -body "slash"
} -start
varnish v1 -vcl {
import oob_probe from "${vmod_topbuild}/src/.libs/libvmod_oob_probe.so";
import ${vmod_std};
probe foo {
.url = "/";
.timeout = 1s;
.interval = 1s;
.window = 3;
.threshold = 2;
.initial = 0;
}
backend default {
.host = "${s1_addr}";
.port = "${s1_port}";
.max_connections = 1;
}
sub vcl_init {
oob_probe.probe_port(default, foo, "${s2_port}");
}
sub vcl_recv {
if (std.healthy(default)) {
return(synth(200,"Backend healthy"));
} else {
return(synth(500,"Backend sick"));
}
}
} -start
varnish v1 -cli "backend.list -p"
client c1 {
txreq
rxresp
expect resp.status == 500
} -run
delay 2.5
client c1 {
txreq -url "/foo"
rxresp
expect resp.status == 200
} -run
/*-
* Copyright (c) 2015 UPLEX Nils Goroll Systemoptimierung
* All rights reserved
*
* Author: Geoffrey Simmons <geoffrey.simmons@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 <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdarg.h>
#include "vcl.h"
#include "vrt.h"
#include "vas.h"
#include "vsa.h"
#include "cache/cache.h"
#include "cache/cache_director.h"
#include "cache/cache_backend.h"
#include "vapi/vsl.h"
#include "vcc_if.h"
static void
errmsg(VRT_CTX, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
if (ctx->method == VCL_MET_INIT) {
AN(ctx->msg);
VSB_vprintf(ctx->msg, fmt, args);
VRT_handling(ctx, VCL_RET_FAIL);
}
else {
AN(ctx->vsl);
VSLbv(ctx->vsl, SLT_VCL_Error, fmt, args);
}
va_end(args);
}
static int
check(VRT_CTX, VCL_BACKEND be, VCL_PROBE probe, VCL_STRING port)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
CHECK_OBJ_NOTNULL(probe, VRT_BACKEND_PROBE_MAGIC);
AN(port);
if (be->resolve != NULL) {
errmsg(ctx, "vmod backend_oob_probe error: "
"%s is a cluster director, not a backend", be->vcl_name);
return 0;
}
return 1;
}
static struct suckaddr *
get_suckaddr(VCL_STRING host, VCL_STRING port, int family)
{
struct addrinfo hints, *res = NULL;
struct suckaddr *sa = NULL;
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = family;
if (getaddrinfo(host, port, &hints, &res) != 0)
return NULL;
if (res->ai_next != NULL)
return NULL;
sa = VSA_Malloc(res->ai_addr, res->ai_addrlen);
AN(sa);
assert(VSA_Get_Proto(sa) == family);
freeaddrinfo(res);
return sa;
}
static void
insert_probe(struct backend *bp, VCL_PROBE probe, struct suckaddr *sa4,
struct suckaddr *sa6)
{
struct tcp_pool *tpool;
if (bp->probe != NULL)
VBP_Remove(bp);
tpool = VBT_Ref(sa4, sa6);
AN(tpool);
VBP_Insert(bp, probe, tpool);
AN(bp->probe);
}
VCL_VOID
vmod_probe_port(VRT_CTX, VCL_BACKEND be, VCL_PROBE probe, VCL_STRING port)
{
struct backend *bp;
struct suckaddr *sa4 = NULL, *sa6 = NULL;
if (!check(ctx, be, probe, port))
return;
CAST_OBJ_NOTNULL(bp, be->priv, BACKEND_MAGIC);
assert(bp->ipv4_addr != NULL || bp->ipv6_addr != NULL);
if (bp->ipv4_addr != NULL)
sa4 = get_suckaddr(bp->ipv4_addr, port, AF_INET);
if (bp->ipv6_addr != NULL)
sa6 = get_suckaddr(bp->ipv6_addr, port, AF_INET6);
if (sa4 == NULL && sa6 == NULL) {
errmsg(ctx, "vmod backend_oob_probe error: "
"Bad port specification %s", port);
return;
}
insert_probe(bp, probe, sa4, sa6);
}
VCL_VOID
vmod_probe_addr(VRT_CTX, VCL_BACKEND be, VCL_PROBE probe, VCL_STRING host,
VCL_STRING port)
{
struct backend *bp;
struct suckaddr *sa4 = NULL, *sa6 = NULL;
if (!check(ctx, be, probe, port))
return;
AN(host);
CAST_OBJ_NOTNULL(bp, be->priv, BACKEND_MAGIC);
sa4 = get_suckaddr(host, port, AF_INET);
sa6 = get_suckaddr(host, port, AF_INET6);
if (sa4 == NULL && sa6 == NULL) {
errmsg(ctx, "vmod backend_oob_probe error: "
"Cannot resolve %s:%s as a unique IPv4 or IPv6 address",
host, port);
return;
}
insert_probe(bp, probe, sa4, sa6);
}
VCL_STRING
vmod_version(VRT_CTX __attribute__((unused)))
{
return VERSION;
}
#-
# Copyright (c) 2015 UPLEX Nils Goroll Systemoptimierung
# All rights reserved
#
# Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
#
# See LICENCE
#
$Module oob_probe 3 Varnish Module to Assign Out-Of-Band Probes to Backends
DESCRIPTION
===========
This Varnish module provides functions to assign an out-of-band probe
to a backend; that is, a probe that listens at a different port on the
backend host, or at a different host. The use case is for backend apps
that provide a "health agent" or something similar, listening at a
network location that is different from the location of the main app.
$Function VOID probe_port(BACKEND backend, PROBE probe, STRING port)
$Function VOID probe_addr(BACKEND backend, PROBE probe, STRING addr,
STRING port)
$Function STRING version()
COPYRIGHT
=========
This document is licensed under the same conditions as the
libvmod-oob_probe project. See LICENSE for details.
* Copyright (c) 2015 UPLEX Nils Goroll Systemoptimierung
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