Commit 33855115 authored by Geoff Simmons's avatar Geoff Simmons

Update for compatibility with Varnish since version 5.1.0.

parent c6bb8049
Pipeline #141 skipped
......@@ -219,11 +219,11 @@ BUILD/INSTALL
Requirements
------------
This version of the tracking reader is compatible with Varnish
versions 4.1.x and 5.0.0. ``trackrdrd`` is built against an existing
Varnish installation on the same host, which in the standard case can
be found with usual settings for the ``PATH`` environment variable in
the ``configure`` step described below.
This version of the tracking reader is compatible with Varnish since
version 5.1.0. ``trackrdrd`` is built against an existing Varnish
installation on the same host, which in the standard case can be found
with usual settings for the ``PATH`` environment variable in the
``configure`` step described below.
The build requires the following tools/packages:
......
AC_PREREQ(2.63)
AC_COPYRIGHT([Copyright (c) 2012-2015 Otto Gmbh & Co KG])
AC_INIT([trackrdrd], [4.1])
AC_COPYRIGHT([Copyright (c) 2012-2017 Otto Gmbh & Co KG])
AC_INIT([trackrdrd], [trunk])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR(src/trackrdrd.c)
AM_CONFIG_HEADER(config.h)
......@@ -45,9 +45,9 @@ AM_CONDITIONAL(HAVE_RST2MAN, [test "x$RST2MAN" != "xno"])
# Check for pkg-config
PKG_PROG_PKG_CONFIG
PKG_CHECK_MODULES([VARNISH], [varnishapi >= 4.1.0 varnishapi <= 5.0.0],
PKG_CHECK_MODULES([VARNISH], [varnishapi >= 5.1.0],
[ac_varnish_pkgdatadir=`$PKG_CONFIG --variable=pkgdatadir varnishapi`],
[AC_MSG_ERROR([Varnish 4.1.x or 5.0.0 installation is required])])
[AC_MSG_ERROR([Varnish 5.1.0 or later is required])])
if test "x$ac_varnish_pkgdatadir" = x; then
AC_MSG_ERROR([couldn't get Varnish data dir from pkg-config])
fi
......@@ -58,7 +58,6 @@ AC_SUBST(VARNISH_LIBS)
AC_SUBST(VARNISH_PKG_INCLUDE, $ac_varnish_pkgincludedir)
AC_SUBST(VARNISH_SHARE_INCLUDE, "$ac_varnish_pkgdatadir/include")
AC_SUBST(VARNISH_PKG_LIB, $ac_varnish_libdir)
AC_SUBST(VARNISH_LIBVARNISH_LIB, "-L$ac_varnish_libdir/varnish")
# Checks for header files.
AC_HEADER_STDC
......@@ -66,10 +65,6 @@ AC_CHECK_HEADERS([execinfo.h])
# Check for library functions
AC_CHECK_FUNCS([getline])
AC_CHECK_FUNCS([gethrtime])
AC_CHECK_FUNCS([clock_gettime])
AC_CHECK_FUNCS([timegm])
AC_CHECK_FUNCS([nanosleep])
## From Varnish configure.ac
# white lie - we don't actually test it
......
......@@ -21,12 +21,13 @@ trackrdrd_SOURCES = \
child.c \
handler.c \
assert.c \
vtim.h \
vtim.c
vfl.h \
vfl.c \
vpf.h \
vpf.c
trackrdrd_LDADD = \
${PTHREAD_LIBS} @VARNISH_LIBS@ ${LIBM} \
-L${VARNISH_PKG_LIB}/varnish -lvarnish
${PTHREAD_LIBS} @VARNISH_LIBS@ ${LIBM}
trackrdrd_LDFLAGS = -ldl
......
......@@ -28,7 +28,7 @@ test_data_SOURCES = \
test_data_LDADD = \
../data.$(OBJEXT) \
../assert.$(OBJEXT) \
@VARNISH_LIBS@ -L${VARNISH_PKG_LIB}/varnish -lvarnish
@VARNISH_LIBS@
test_append_SOURCES = \
../child.c \
......@@ -46,8 +46,7 @@ test_append_LDADD = \
../config.$(OBJEXT) \
../config_common.$(OBJEXT) \
../sandbox.$(OBJEXT) \
../vtim.$(OBJEXT) \
@VARNISH_LIBS@ -L${VARNISH_PKG_LIB}/varnish -lvarnish
@VARNISH_LIBS@
test_append_CFLAGS = -DTEST_DRIVER
......@@ -98,7 +97,6 @@ test_worker_LDADD = \
../spmcq.$(OBJEXT) \
../data.$(OBJEXT) \
../assert.$(OBJEXT) \
../vtim.$(OBJEXT) \
../config.$(OBJEXT) \
../config_common.$(OBJEXT) \
-L${VARNISH_PKG_LIB}/varnish -lvarnish
@VARNISH_LIBS@
......@@ -35,9 +35,10 @@
#include "minunit.h"
#include "vtim.h"
#include "../trackrdrd.h"
#include "../data.h"
#include "../vtim.h"
#define DEBUG 0
#define debug_print(fmt, ...) \
......
/*-
* Copyright (c) 2007 Dag-Erling Coïdan Smørgrav
* 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
* in this position and unchanged.
* 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 THE 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.
* Derived from:
* $FreeBSD: head/lib/libutil/flopen.c 184094 2008-10-20 18:11:30Z des $
*/
#include "config.h"
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include "vfl.h"
int
VFL_Open(const char *path, int flags, ...)
{
int fd, operation, serrno, trunc;
struct flock lock;
struct stat sb, fsb;
mode_t mode;
#ifdef O_EXLOCK
flags &= ~O_EXLOCK;
#endif
mode = 0;
if (flags & O_CREAT) {
va_list ap;
va_start(ap, flags);
mode = (mode_t)va_arg(ap, int); /* mode_t promoted to int */
va_end(ap);
}
memset(&lock, 0, sizeof lock);
lock.l_type = ((flags & O_ACCMODE) == O_RDONLY) ? F_RDLCK : F_WRLCK;
lock.l_whence = SEEK_SET;
operation = (flags & O_NONBLOCK) ? F_SETLK : F_SETLKW;
trunc = (flags & O_TRUNC);
flags &= ~O_TRUNC;
for (;;) {
if ((fd = open(path, flags, mode)) == -1)
/* non-existent or no access */
return (-1);
if (fcntl(fd, operation, &lock) == -1) {
/* unsupported or interrupted */
serrno = errno;
(void)close(fd);
errno = serrno;
return (-1);
}
if (stat(path, &sb) == -1) {
/* disappeared from under our feet */
(void)close(fd);
continue;
}
if (fstat(fd, &fsb) == -1) {
/* can't happen [tm] */
serrno = errno;
(void)close(fd);
errno = serrno;
return (-1);
}
if (sb.st_dev != fsb.st_dev ||
sb.st_ino != fsb.st_ino) {
/* changed under our feet */
(void)close(fd);
continue;
}
if (trunc && ftruncate(fd, 0) != 0) {
/* can't happen [tm] */
serrno = errno;
(void)close(fd);
errno = serrno;
return (-1);
}
return (fd);
}
}
/* Tests if the given fd is locked through flopen
* If pid is non-NULL, stores the pid of the process holding the lock there
* Returns 1 if the file is locked
* Returns 0 if the file is unlocked
* Returns -1 on error (and errno)
*/
int
VFL_Test(int fd, pid_t *pid)
{
struct flock lock;
memset(&lock, 0, sizeof lock);
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
if (fcntl(fd, F_GETLK, &lock) == -1)
return (-1);
if (lock.l_type == F_UNLCK)
return (0);
if (pid != NULL)
*pid = lock.l_pid;
return (1);
}
/*-
* Copyright (c) 2006 Verdens Gang AS
* Copyright (c) 2006-2011 Varnish Software AS
* Copyright (c) 2007 Dag-Erling Coïdan Smørgrav
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* 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.
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 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.
......@@ -17,7 +15,7 @@
* 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
* ARE DISCLAIMED. IN NO EVENT SHALL THE 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)
......@@ -26,14 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Derived from:
* $FreeBSD: src/lib/libutil/libutil.h,v 1.44 2007/05/10 15:01:42 des Exp $
*/
/* from libvarnish/vtim.c */
#define VTIM_FORMAT_SIZE 30
void VTIM_format(double t, char *p);
double VTIM_parse(const char *p);
double VTIM_mono(void);
double VTIM_real(void);
void VTIM_sleep(double t);
struct timespec VTIM_timespec(double t);
struct timeval VTIM_timeval(double t);
#ifndef VFL_H_INCLUDED
#define VFL_H_INCLUDED
int VFL_Open(const char *, int, ...);
int VFL_Test(int fd, pid_t *pid);
#endif
......@@ -40,8 +40,8 @@
#include <string.h>
#include <unistd.h>
#include "flopen.h"
#include "vas.h"
#include "vas.h" // XXX Flexelint "not used" - but req'ed for assert()
#include "vfl.h"
#include "vpf.h"
struct vpf_fh {
......@@ -128,7 +128,7 @@ VPF_Open(const char *path, mode_t mode, pid_t *pidptr)
* PID file will be truncated again in VPF_Write(), so
* VPF_Write() can be called multiple times.
*/
fd = flopen(pfh->pf_path,
fd = VFL_Open(pfh->pf_path,
O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, mode);
if (fd == -1) {
if (errno == EWOULDBLOCK && pidptr != NULL) {
......
/*-
* Copyright (c) 2006 Verdens Gang AS
* Copyright (c) 2006-2011 Varnish Software AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* 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.
*
* Semi-trivial functions to handle HTTP header timestamps according to
* RFC 2616 section 3.3.
*
* In the highly unlikely event of performance trouble, handbuilt versions
* would likely be faster than relying on the OS time functions.
*
* We must parse three different formats:
* 000000000011111111112222222222
* 012345678901234567890123456789
* ------------------------------
* "Sun, 06 Nov 1994 08:49:37 GMT" RFC822 & RFC1123
* "Sunday, 06-Nov-94 08:49:37 GMT" RFC850
* "Sun Nov 6 08:49:37 1994" ANSI-C asctime()
*
* And always output the RFC1123 format.
*
*/
#include "config.h"
#include <sys/time.h>
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "vas.h"
#include "vtim.h"
/*
* Note on Solaris: for some reason, clock_gettime(CLOCK_MONOTONIC, &ts) is not
* implemented in assembly, but falls into a syscall, while gethrtime() doesn't,
* so we save a syscall by using gethrtime() if it is defined.
*/
double
VTIM_mono(void)
{
#ifdef HAVE_GETHRTIME
return (gethrtime() * 1e-9);
#elif HAVE_CLOCK_GETTIME
struct timespec ts;
AZ(clock_gettime(CLOCK_MONOTONIC, &ts));
return (ts.tv_sec + 1e-9 * ts.tv_nsec);
#else
struct timeval tv;
AZ(gettimeofday(&tv, NULL));
return (tv.tv_sec + 1e-6 * tv.tv_usec);
#endif
}
double
VTIM_real(void)
{
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
AZ(clock_gettime(CLOCK_REALTIME, &ts));
return (ts.tv_sec + 1e-9 * ts.tv_nsec);
#else
struct timeval tv;
AZ(gettimeofday(&tv, NULL));
return (tv.tv_sec + 1e-6 * tv.tv_usec);
#endif
}
void
VTIM_format(double t, char *p)
{
struct tm tm;
time_t tt;
tt = (time_t) t;
(void)gmtime_r(&tt, &tm);
AN(strftime(p, VTIM_FORMAT_SIZE, "%a, %d %b %Y %T GMT", &tm));
}
/* XXX: add statistics ? */
static const char *fmts[] = {
"%a, %d %b %Y %T GMT", /* RFC 822 & RFC 1123 */
"%A, %d-%b-%y %T GMT", /* RFC 850 */
"%a %b %d %T %Y", /* ANSI-C asctime() */
"%F %T", /* ISO 8601 (incorrect, only in 4.0) */
"%FT%T", /* ISO 8601 */
NULL
};
double
VTIM_parse(const char *p)
{
double t;
struct tm tm;
const char **r;
for (r = fmts; *r != NULL; r++) {
memset(&tm, 0, sizeof tm);
if (strptime(p, *r, &tm) != NULL) {
/*
* Make sure this is initialized on the off-chance
* that some raving loonie would apply DST to UTC.
*/
tm.tm_isdst = -1;
#if defined(HAVE_TIMEGM)
t = timegm(&tm);
#else
/*
* Ahh, another POSIX_STUPIDITY, how unexpected.
* Instead of, as would have been logical, to have
* tm_timezone element, mktime() is standardized as
* always working in localtime. This brilliant idea
* came from the same people who said "leap-seconds ?
* Naah, screw it!".
*
* On broken systems without a working timegm(),
* it is the responsibility of the calling program
* to set the timezone to UTC. We check that.
*/
t = mktime(&tm);
AZ(strcmp(tzname[0], "UTC"));
#endif
return (t);
}
}
return (0);
}
void
VTIM_sleep(double t)
{
#ifdef HAVE_NANOSLEEP
struct timespec ts;
ts = VTIM_timespec(t);
(void)nanosleep(&ts, NULL);
#else
if (t >= 1.) {
(void)sleep(floor(t));
t -= floor(t);
}
/* XXX: usleep() is not mandated to be thread safe */
t *= 1e6;
if (t > 0)
(void)usleep(floor(t));
#endif
}
struct timeval
VTIM_timeval(double t)
{
struct timeval tv;
tv.tv_sec = (time_t)trunc(t);
tv.tv_usec = (int)(1e6 * (t - tv.tv_sec));
return (tv);
}
struct timespec
VTIM_timespec(double t)
{
struct timespec tv;
tv.tv_sec = (time_t)trunc(t);
tv.tv_nsec = (int)(1e9 * (t - tv.tv_sec));
return (tv);
}
#ifdef TEST_DRIVER
/*
* Compile with:
* cc -o foo -DTEST_DRIVER -I../.. -I../../include time.c assert.c
* (Solaris)
* cc -o foo -DTEST_DRIVER -I../.. -I../../include -lm time.c assert.c
* Test with:
* env TZ=UTC ./foo
* env TZ=CET ./foo
*/
static void
tst(const char *s, time_t good)
{
time_t t;
char buf[BUFSIZ];
t = VTIM_parse(s);
VTIM_format(t, buf);
printf("%-30s -> %12jd -> %s\n", s, (intmax_t)t, buf);
if (t != good) {
printf("Parse error! Got: %jd should have %jd diff %jd\n",
(intmax_t)t, (intmax_t)good, (intmax_t)(t - good));
exit(4);
}
}
static int
tst_delta_check(const char *name, double begin, double end, double ref)
{
const double tol_max = 1.1;
const double tol_min = 1;
printf("%s delta for %fs sleep: %f\n", name, ref, (end - begin));
if ((end - begin) > tol_max * ref) {
printf("%s delta above tolerance: ((%f - %f) = %f) > %f\n",
name, end, begin, (end - begin), tol_max);
return (1);
} else if ((end - begin) < tol_min * ref) {
printf("%s delta below tolerance: ((%f - %f) = %f) < %f\n",
name, end, begin, (end - begin), tol_min);
return (1);
}
return (0);
}
static void
tst_delta()
{
double m_begin, m_end;
double r_begin, r_end;
const double ref = 1;
int err = 0;
r_begin = VTIM_real();
m_begin = VTIM_mono();
VTIM_sleep(ref);
r_end = VTIM_real();
m_end = VTIM_mono();
err += tst_delta_check("VTIM_mono", m_begin, m_end, ref);
err += tst_delta_check("VTIM_real", r_begin, r_end, ref);
if (err) {
printf("%d time delta test errrors\n", err);
exit(4);
}
}
int
main(int argc, char **argv)
{
time_t t;
char buf[BUFSIZ];
time(&t);
memset(buf, 0x55, sizeof buf);
VTIM_format(t, buf);
printf("scan = %d <%s>\n", VTIM_parse(buf), buf);
/* Examples from RFC2616 section 3.3.1 */
tst("Sun, 06 Nov 1994 08:49:37 GMT", 784111777);
tst("Sunday, 06-Nov-94 08:49:37 GMT", 784111777);
tst("Sun Nov 6 08:49:37 1994", 784111777);
tst_delta();
return (0);
}
#endif
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