CONTRIB: move mod_defender out of the tree

As previously mentioned SPOA code has nothing to do in the haproxy core
since they're not dependent on haproxy's version. This one was moved to
its own repository here with complete history:

  https://github.com/haproxytech/spoa-mod_defender
diff --git a/.gitignore b/.gitignore
index 1065291..94e5b8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,6 +49,5 @@
 dev/tcploop/tcploop
 dev/hpack/decode
 dev/hpack/gen-rht
-contrib/mod_defender/defender
 /src/dlmalloc.c
 /tests/test_hashes
diff --git a/contrib/mod_defender/Makefile b/contrib/mod_defender/Makefile
deleted file mode 100644
index dfd0b74..0000000
--- a/contrib/mod_defender/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-DESTDIR    =
-PREFIX     = /usr/local
-BINDIR     = $(PREFIX)/bin
-
-CC ?= gcc
-LD = $(CC)
-
-CXX ?= g++
-
-ifeq ($(MOD_DEFENDER_SRC),)
-MOD_DEFENDER_SRC := ./mod_defender_src
-endif
-
-ifeq ($(APACHE2_INC),)
-APACHE2_INC := /usr/include/apache2
-endif
-
-ifeq ($(APR_INC),)
-APR_INC := /usr/include/apr-1.0
-endif
-
-ifeq ($(EVENT_LIB),)
-EVENT_LIB := -levent
-endif
-
-ifeq ($(EVENT_INC),)
-EVENT_INC := /usr/include
-endif
-
-CFLAGS  += -g -Wall -pthread
-INCS += -Iinclude -I$(MOD_DEFENDER_SRC) -I$(APACHE2_INC) -I$(APR_INC) -I$(EVENT_INC)
-LIBS += -lpthread  $(EVENT_LIB) -levent_pthreads -lapr-1 -laprutil-1 -lstdc++ -lm
-
-CXXFLAGS = -g -std=gnu++11
-CXXINCS += -I$(MOD_DEFENDER_SRC) -I$(MOD_DEFENDER_SRC)/deps -I$(APACHE2_INC) -I$(APR_INC)
-
-SRCS = standalone.o spoa.o defender.o \
-	$(wildcard $(MOD_DEFENDER_SRC)/deps/libinjection/*.c)
-OBJS = $(patsubst %.c, %.o, $(SRCS))
-
-CXXSRCS = $(wildcard $(MOD_DEFENDER_SRC)/*.cpp)
-CXXOBJS = $(patsubst %.cpp, %.o, $(CXXSRCS))
-
-defender: $(OBJS) $(CXXOBJS)
-	$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
-
-install: defender
-	install defender $(DESTDIR)$(BINDIR)
-
-clean:
-	rm -f defender $(OBJS) $(CXXOBJS)
-
-%.o:	%.c
-	$(CC) $(CFLAGS) $(INCS) -c -o $@ $<
-
-%.o:	%.cpp
-	$(CXX) $(CXXFLAGS) $(CXXINCS) -c -o $@ $<
diff --git a/contrib/mod_defender/README b/contrib/mod_defender/README
deleted file mode 100644
index f417773..0000000
--- a/contrib/mod_defender/README
+++ /dev/null
@@ -1,159 +0,0 @@
-                       --------------------------
-                        Mod Defender for HAProxy
-                       --------------------------
-
-
-This is a service that talks SPOE protocol and uses the Mod Defender
-(https://github.com/VultureProject/mod_defender) functionality to detect
-HTTP attacks. It returns a HTTP status code to indicate whether the request
-is suspicious or not, based on NAXSI rules. The value of the returned code
-can be used in HAProxy rules to determine if the HTTP request should be
-blocked/rejected.
-
-Unlike ModSecurity, Mod Defender is a whitelist based WAF (everything is
-disallowed, unless there are rules saying otherwise). It's a partial
-replication of NAXSI and it uses NAXSI compatible rules configuration
-format.
-
-
-1) How to build it
-------------------
-
-Required packages :
-
-    * Mod Defender source (https://github.com/VultureProject/mod_defender)
-    * Asynchronous event notification library and headers (libevent)
-    * Apache 2 (>= 2.4) development headers
-    * APR library and headers
-    * GNU C (gcc) and C++ (g++) >= 4.9
-    * GNU Standard C++ Library v3 (libstdc++)
-    * GNU Make
-
-
-Compile the source :
-
-    $ make MOD_DEFENDER_SRC=/path/to/mod_defender_src
-
-
-2) Configuration
-----------------
-
-Download the Naxsi core rules file :
-
-    $ wget -O /path/to/core.rules \
-    https://raw.githubusercontent.com/nbs-system/naxsi/master/naxsi_config/naxsi_core.rules
-
-
-Create the Mod Defender configuration file. For example :
-
-    # Defender toggle
-    Defender On
-    # Match log path
-    MatchLog /path/to/defender_match.log
-    # JSON Match log path
-    JSONMatchLog /path/to/defender_json_match.log
-    # Request body limit
-    RequestBodyLimit 8388608
-    # Learning mode toggle
-    LearningMode Off
-    # Extensive Learning log toggle
-    ExtensiveLog Off
-    # Libinjection SQL toggle
-    LibinjectionSQL On
-    # Libinjection XSS toggle
-    LibinjectionXSS On
-
-    # Rules
-    Include /path/to/core.rules
-
-    # Score action
-    CheckRule "$SQL >= 8" BLOCK
-    CheckRule "$RFI >= 8" BLOCK
-    CheckRule "$TRAVERSAL >= 4" BLOCK
-    CheckRule "$EVADE >= 4" BLOCK
-    CheckRule "$XSS >= 8" BLOCK
-    CheckRule "$UPLOAD >= 8" BLOCK
-
-    # Whitelists
-    # ....
-
-
-Next step is to configure the SPOE for use with the Mod Defender service.
-Example configuration (args elements order is important) :
-
-    [mod_defender]
-
-    spoe-agent mod-defender-agent
-        messages check-request
-        option   var-prefix    defender
-        timeout  hello         100ms
-        timeout  idle          30s
-        timeout  processing    15ms
-        use-backend spoe-mod-defender
-
-    spoe-message check-request
-        args src unique-id method path query req.ver req.hdrs_bin req.body
-        event on-frontend-http-request
-
-
-The engine is in the scope "mod_defender". To enable it, you must set the
-following line in a frontend/listener section :
-
-    frontend my_frontend
-        ...
-        filter spoe engine mod_defender config /path/to/spoe-mod-defender.conf
-        ...
-
-
-Also, we must define the "spoe-mod-defender" backend in HAProxy configuration :
-
-    backend spoe-mod-defender
-      mode tcp
-      balance roundrobin
-      timeout connect 5s
-      timeout server  3m
-      server defender1 127.0.0.1:12345
-
-
-The Mod Defender status is returned in a variable "sess.defender.status" --
-it contains the returned HTTP status code. The request is considered
-malicious if the variable contains value greater than zero.
-
-The following rule can be used to reject all suspicious HTTP requests :
-
-    http-request deny if { var(sess.defender.status) -m int gt 0 }
-
-
-3) Start the service
---------------------
-
-To start the service, you need to use "defender" binary :
-
-    $ ./defender -h
-    Usage : ./defender [OPTION]...
-        -h                   Print this message
-        -f <config-file>     Mod Defender configuration file
-        -l <log-file>        Mod Defender log file
-        -d                   Enable the debug mode
-        -m <max-frame-size>  Specify the maximum frame size (default : 16384)
-        -p <port>            Specify the port to listen on (default : 12345)
-        -n <num-workers>     Specify the number of workers (default : 10)
-        -c <capability>      Enable the support of the specified capability
-        -t <time>            Set a delay to process a message (default: 0)
-                               The value is specified in milliseconds by default,
-                               but can be in any other unit if the number is suffixed
-                               by a unit (us, ms, s)
-
-        Supported capabilities: fragmentation, pipelining, async
-
-Example:
-
-    $ ./defender -n 4 -f /path/to/mod_defender.conf -d -l /path/to/error.log
-
-
-4) Known bugs and limitations
------------------------------
-
-In its current state, the module is limited by haproxy to the analysis of
-the first buffer. One workaround may consist in significantly increasing
-haproxy's buffer size.
diff --git a/contrib/mod_defender/defender.c b/contrib/mod_defender/defender.c
deleted file mode 100644
index fa3910e..0000000
--- a/contrib/mod_defender/defender.c
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Mod Defender for HAProxy
- *
- * Copyright 2017 HAProxy Technologies, Dragan Dosen <ddosen@haproxy.com>
- *
- * Mod Defender
- * Copyright (c) 2017 Annihil (https://github.com/VultureProject/mod_defender)
- *
- * Parts of code based on Apache HTTP Server source
- * Copyright 2015 The Apache Software Foundation (http://www.apache.org/)
- *
- * This program 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 of the License, or (at your option) any later version.
- *
- */
-#include <stdio.h>
-#include <stdarg.h>
-
-#include <haproxy/spoe.h>
-#include <haproxy/tools.h>
-
-#include <http_core.h>
-#include <http_main.h>
-#include <http_log.h>
-#include <http_request.h>
-
-#include <apr_pools.h>
-#include <apr_strings.h>
-
-#include "spoa.h"
-#include "standalone.h"
-#include "defender.h"
-
-#define DEFENDER_NAME "defender"
-#define DEFENDER_INPUT_FILTER "DEFENDER_IN"
-#define DEFENDER_DEFAULT_UNIQUE_ID "unique_id"
-#define DEFENDER_BRIGADE_REQUEST "defender-brigade-request"
-
-extern module AP_MODULE_DECLARE_DATA defender_module;
-
-DECLARE_HOOK(int,post_config,(apr_pool_t *pconf,apr_pool_t *plog, apr_pool_t *ptemp,server_rec *s))
-DECLARE_HOOK(int,fixups,(request_rec *r))
-DECLARE_HOOK(int,header_parser,(request_rec *r))
-
-char *defender_name = DEFENDER_NAME;
-const char *defender_argv[] = { DEFENDER_NAME, NULL };
-const char *defender_unknown_hostname = "";
-
-void *defender_module_config = NULL;
-static server_rec *server = NULL;
-apr_pool_t *defender_pool = NULL;
-
-char hostname[MAX_HOSTNAME_LEN];
-char defender_cwd[MAXPATHLEN];
-
-static apr_status_t defender_bucket_read(apr_bucket *b, const char **str,
-                                         apr_size_t *len, apr_read_type_e block);
-static void defender_bucket_destroy(void *data);
-
-static const apr_bucket_type_t apr_bucket_type_defender = {
-	"defender", 8, APR_BUCKET_DATA,
-	defender_bucket_destroy,
-	defender_bucket_read,
-	apr_bucket_setaside_noop,
-	apr_bucket_shared_split,
-	apr_bucket_shared_copy
-};
-
-struct apr_bucket_defender {
-	apr_bucket_refcount refcount;
-	struct buffer buf;
-};
-
-static apr_status_t defender_bucket_read(apr_bucket *b, const char **str,
-                                         apr_size_t *len, apr_read_type_e block)
-{
-	struct apr_bucket_defender *d = b->data;
-
-	*str = d->buf.area;
-	*len = d->buf.data;
-
-	return APR_SUCCESS;
-}
-
-static void defender_bucket_destroy(void *data)
-{
-	struct apr_bucket_defender *d = data;
-
-	if (apr_bucket_shared_destroy(d))
-		apr_bucket_free(d);
-}
-
-static apr_bucket *defender_bucket_make(apr_bucket *b,
-					const struct buffer *buf)
-{
-	struct apr_bucket_defender *d;
-
-	d = apr_bucket_alloc(sizeof(*d), b->list);
-
-	d->buf.area = buf->area;
-	d->buf.data = buf->data;
-	d->buf.size = 0;
-
-	b = apr_bucket_shared_make(b, d, 0, buf->data);
-	b->type = &apr_bucket_type_defender;
-	return b;
-}
-
-static apr_bucket *defender_bucket_create(const struct buffer *buf,
-                                          apr_bucket_alloc_t *list)
-{
-	apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
-
-	APR_BUCKET_INIT(b);
-	b->free = apr_bucket_free;
-	b->list = list;
-	return defender_bucket_make(b, buf);
-}
-
-static void defender_logger(int level, char *str)
-{
-	LOG(&null_worker, "%s", str);
-}
-
-static char *defender_strdup(apr_pool_t *pool, const char *src, uint64_t len)
-{
-	char *dst;
-
-	if (!(dst = apr_pcalloc(pool, len + 1)))
-		return NULL;
-
-	memcpy(dst, src, len);
-	dst[len] = '\0';
-
-	return dst;
-}
-
-static char *defender_printf(apr_pool_t *pool, const char *fmt, ...)
-{
-	va_list argp;
-	char *dst;
-	int len;
-
-	va_start(argp, fmt);
-	len = vsnprintf(NULL, 0, fmt, argp);
-	va_end(argp);
-
-	if (len < 0)
-		return NULL;
-
-	if (!(dst = apr_pcalloc(pool, len + 1)))
-		return NULL;
-
-	va_start(argp, fmt);
-	len = vsnprintf(dst, len + 1, fmt, argp);
-	va_end(argp);
-
-	return dst;
-}
-
-static char *defender_addr2str(apr_pool_t *pool, struct sample *addr)
-{
-	sa_family_t family;
-	const void *src;
-	char *dst;
-
-	switch (addr->data.type) {
-	case SMP_T_IPV4:
-		src = &addr->data.u.ipv4;
-		family = AF_INET;
-		break;
-	case SMP_T_IPV6:
-		src = &addr->data.u.ipv6;
-		family = AF_INET6;
-		break;
-	default:
-		return NULL;
-	}
-
-	if (!(dst = apr_pcalloc(pool, INET6_ADDRSTRLEN + 1)))
-		return NULL;
-
-	if (inet_ntop(family, src, dst, INET6_ADDRSTRLEN))
-		return dst;
-
-	return NULL;
-}
-
-static void defender_pre_config()
-{
-	apr_pool_t *ptemp = NULL;
-
-	defender_module.module_index = 0;
-	defender_module.register_hooks(defender_pool);
-
-	apr_pool_create(&ptemp, defender_pool);
-	run_ap_hook_post_config(defender_pool, defender_pool, ptemp, server);
-	apr_pool_destroy(ptemp);
-}
-
-static const char *defender_read_config(const char *file)
-{
-	apr_pool_t *ptemp = NULL;
-	const char *err;
-	const char *fullname;
-
-	defender_module_config = defender_module.create_dir_config(defender_pool, "/");
-	if (defender_module_config == NULL) {
-		return "cannot allocate space for the configuration structure";
-	}
-
-	apr_pool_create(&ptemp, defender_pool);
-
-	fullname = ap_server_root_relative(ptemp, file);
-
-	err = read_module_config(server, defender_module_config,
-	                         defender_module.cmds,
-	                         defender_pool, ptemp, fullname);
-
-	apr_pool_destroy(ptemp);
-
-    return err;
-}
-
-static void defender_post_config()
-{
-	apr_pool_t *ptemp = NULL;
-
-	apr_pool_create(&ptemp, defender_pool);
-	run_ap_hook_post_config(defender_pool, defender_pool, ptemp, server);
-	apr_pool_destroy(ptemp);
-}
-
-static const char *defender_set_logger(const char *file)
-{
-	char *logname;
-
-	logger = defender_logger;
-
-	if (file == NULL)
-		return NULL;
-
-	logname = ap_server_root_relative(defender_pool, file);
-
-	if (apr_file_open(&server->error_log, logname,
-	                  APR_APPEND | APR_WRITE | APR_CREATE | APR_LARGEFILE,
-	                  APR_OS_DEFAULT, defender_pool) != APR_SUCCESS) {
-		return apr_pstrcat(defender_pool, "Cannot open log file, ",
-		                   logname, NULL);
-	}
-	server->error_fname = logname;
-
-	return NULL;
-}
-
-static apr_status_t defender_input_filter(ap_filter_t *f,
-                                          apr_bucket_brigade *new_bb,
-                                          ap_input_mode_t mode,
-                                          apr_read_type_e block,
-                                          apr_off_t readbytes)
-{
-	apr_bucket_brigade *bb = NULL;
-	apr_bucket *b = NULL, *a = NULL;
-	apr_status_t rv;
-
-	bb = (apr_bucket_brigade *)apr_table_get(f->r->notes, DEFENDER_BRIGADE_REQUEST);
-
-	if (bb == NULL || (bb && !APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb)))) {
-		b = apr_bucket_eos_create(f->c->bucket_alloc);
-		APR_BRIGADE_INSERT_TAIL(new_bb, b);
-		if (bb == NULL)
-			return APR_SUCCESS;
-	}
-
-	rv = apr_brigade_partition(bb, readbytes, &a);
-	if (rv != APR_SUCCESS && rv != APR_INCOMPLETE)
-		return rv;
-
-	b = APR_BRIGADE_FIRST(bb);
-
-	while (b != a) {
-		if (APR_BUCKET_IS_EOS(b))
-			ap_remove_input_filter(f);
-
-		APR_BUCKET_REMOVE(b);
-		APR_BRIGADE_INSERT_TAIL(new_bb, b);
-		b = APR_BRIGADE_FIRST(bb);
-	}
-
-	return APR_SUCCESS;
-}
-
-static conn_rec *defender_create_conn()
-{
-	conn_rec *c = NULL;
-	apr_pool_t *ptrans = NULL;
-
-	apr_pool_create(&ptrans, defender_pool);
-
-	c = apr_pcalloc(ptrans, sizeof(conn_rec));
-
-	c->pool = ptrans;
-	c->local_ip = "127.0.0.1";
-	c->local_addr = server->addrs->host_addr;
-	c->local_host = defender_name;
-	c->client_addr = server->addrs->host_addr;
-	c->remote_host = defender_name;
-
-	c->id = 1;
-	c->base_server = server;
-	c->bucket_alloc = apr_bucket_alloc_create(ptrans);
-
-	return c;
-}
-
-static request_rec *defender_create_request(conn_rec *conn)
-{
-	request_rec *r = NULL;
-	apr_pool_t *p = NULL;
-	struct ap_logconf *l;
-
-	apr_pool_create(&p, conn->pool);
-
-	r = apr_pcalloc(p, sizeof(request_rec));
-
-	r->pool = p;
-	r->connection = conn;
-	r->server = conn->base_server;
-
-	r->headers_in = apr_table_make(p, 25);
-	r->headers_out = apr_table_make(p, 12);
-	r->subprocess_env = apr_table_make(p, 25);
-	r->err_headers_out = apr_table_make(p, 5);
-	r->notes = apr_table_make(p, 5);
-
-	r->request_config = apr_palloc(p, sizeof(void *));
-	r->per_dir_config = apr_palloc(p, sizeof(void *));
-	((void **)r->per_dir_config)[0] = defender_module_config;
-
-	r->handler = defender_name;
-
-	r->parsed_uri.scheme = "http";
-	r->parsed_uri.is_initialized = 1;
-	r->parsed_uri.port = 80;
-	r->parsed_uri.port_str = "80";
-	r->parsed_uri.fragment = "";
-
-	r->input_filters = NULL;
-	r->output_filters = NULL;
-
-	l = apr_pcalloc(p, sizeof(struct ap_logconf));
-	l->level = APLOG_DEBUG;
-	r->log = l;
-
-	return r;
-}
-
-static int defender_process_headers(request_rec *r)
-{
-	return run_ap_hook_header_parser(r);
-}
-
-static int defender_process_body(request_rec *r)
-{
-	ap_add_input_filter(DEFENDER_INPUT_FILTER, NULL, r, r->connection);
-	return run_ap_hook_fixups(r);
-}
-
-int defender_init(const char *config_file, const char *log_file)
-{
-	apr_status_t rv;
-	const char *msg;
-
-	if (!config_file) {
-		LOG(&null_worker, "Mod Defender configuration file not specified.\n");
-		return 0;
-	}
-
-	apr_initialize();
-	apr_pool_create(&defender_pool, NULL);
-	apr_hook_global_pool = defender_pool;
-
-	ap_server_root = getcwd(defender_cwd, APR_PATH_MAX);
-
-	server = (server_rec *) apr_palloc(defender_pool, sizeof(server_rec));
-	server->process = apr_palloc(defender_pool, sizeof(process_rec));
-	server->process->argc = 1;
-	server->process->argv = defender_argv;
-	server->process->short_name = defender_name;
-	server->process->pconf = defender_pool;
-	server->process->pool = defender_pool;
-
-	server->addrs = apr_palloc(defender_pool, sizeof(server_addr_rec));
-	rv = apr_sockaddr_info_get(&server->addrs->host_addr,
-	                           "127.0.0.1", APR_UNSPEC, 0, 0,
-	                           defender_pool);
-	if (rv != APR_SUCCESS) {
-		LOG(&null_worker, "Mod Defender getaddrinfo failed.\n");
-		return 0;
-	}
-
-	server->path = "/";
-	server->pathlen = strlen(server->path);
-	server->port = 0;
-	server->server_admin = defender_name;
-	server->server_scheme = "";
-	server->error_fname = NULL;
-	server->error_log = NULL;
-	server->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
-	server->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
-	server->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
-	server->timeout = apr_time_from_sec(DEFAULT_TIMEOUT);
-
-	memset(hostname, 0, sizeof(hostname));
-	gethostname(hostname, sizeof(hostname) - 1);
-	server->server_hostname = hostname;
-
-	server->addrs->host_port = 0;
-	server->names = server->wild_names = NULL;
-	server->is_virtual = 0;
-
-	server->lookup_defaults = NULL;
-	server->module_config = NULL;
-
-	msg = defender_set_logger(log_file);
-	if (msg != NULL) {
-		LOG(&null_worker, "Mod Defender init failed: %s\n", msg);
-		return 0;
-	}
-
-	ap_register_input_filter(DEFENDER_INPUT_FILTER, defender_input_filter,
-	                         NULL, AP_FTYPE_RESOURCE);
-
-	defender_pre_config();
-
-	msg = defender_read_config(config_file);
-	if (msg != NULL) {
-		LOG(&null_worker, "Mod Defender configuration failed: %s\n", msg);
-		return 0;
-	}
-
-	defender_post_config();
-
-	return 1;
-}
-
-int defender_process_request(struct worker *worker, struct defender_request *request)
-{
-	struct conn_rec *c = NULL;
-	struct request_rec *r = NULL;
-
-	struct apr_bucket_brigade *bb = NULL;
-	struct apr_bucket *d = NULL, *e = NULL;
-
-	struct buffer *method;
-	struct buffer *path;
-	struct buffer *query;
-	struct buffer *version;
-	struct buffer *body;
-
-	struct defender_header hdr;
-	char *hdr_ptr, *hdr_end;
-
-	const char *ptr;
-
-	int status = DECLINED;
-
-	if (!(c = defender_create_conn()))
-		goto out;
-
-	if (!(r = defender_create_request(c)))
-		goto out;
-
-	/* request */
-	r->request_time = apr_time_now();
-
-	if (request->clientip.data.type != SMP_T_IPV4 &&
-	    request->clientip.data.type != SMP_T_IPV6)
-		goto out;
-
-	if (!(r->useragent_ip = defender_addr2str(r->pool, &request->clientip)))
-		goto out;
-
-	if (request->id.data.u.str.area && request->id.data.u.str.data > 0) {
-		apr_table_setn(r->subprocess_env, "UNIQUE_ID",
-		               defender_strdup(r->pool, request->id.data.u.str.area,
-		                               request->id.data.u.str.data));
-	}
-	else {
-		apr_table_setn(r->subprocess_env, "UNIQUE_ID",
-		               DEFENDER_DEFAULT_UNIQUE_ID);
-	}
-
-	method = &request->method.data.u.str;
-	path = &request->path.data.u.str;
-	query = &request->query.data.u.str;
-	version = &request->version.data.u.str;
-
-	r->method_number = lookup_builtin_method(method->area, method->data);
-	if (!(r->method = defender_strdup(r->pool, method->area, method->data)))
-		goto out;
-
-	r->unparsed_uri = defender_printf(r->pool, "%.*s%s%.*s",
-	                                  path->data, path->area,
-	                                  query->data > 0 ? "?" : "",
-	                                  query->data, query->area);
-	if (!r->unparsed_uri)
-		goto out;
-
-	if (!(r->uri = defender_strdup(r->pool, path->area, path->data)))
-		goto out;
-
-	r->parsed_uri.path = r->filename = r->uri;
-
-	if (!(r->args = defender_strdup(r->pool, query->area, query->data)))
-		goto out;
-
-	r->parsed_uri.query = r->args;
-
-	r->protocol = defender_printf(r->pool, "%s%.*s",
-	                              version->data > 0 ? "HTTP/" : "",
-	                              version->data, version->area);
-	if (!r->protocol)
-		goto out;
-
-	r->the_request = defender_printf(r->pool, "%.*s %s%s%s",
-	                                 method->data, method->area,
-	                                 r->unparsed_uri,
-	                                 version->data > 0 ? " " : "",
-	                                 r->protocol);
-	if (!r->the_request)
-		goto out;
-
-	/* headers */
-	if (request->headers.data.type != SMP_T_BIN)
-		goto misc;
-
-	hdr_ptr = request->headers.data.u.str.area;
-	hdr_end = hdr_ptr + request->headers.data.u.str.data;
-
-	while (1) {
-		memset(&hdr, 0, sizeof(hdr));
-
-		if (decode_varint(&hdr_ptr, hdr_end, &hdr.name.len) == -1)
-			goto out;
-		if (!(hdr.name.str = defender_strdup(r->pool, hdr_ptr, hdr.name.len)))
-			goto out;
-
-		hdr_ptr += hdr.name.len;
-		if (hdr_ptr > hdr_end)
-			goto out;
-
-		if (decode_varint(&hdr_ptr, hdr_end, &hdr.value.len) == -1)
-			goto out;
-		if (!(hdr.value.str = defender_strdup(r->pool, hdr_ptr, hdr.value.len)))
-			goto out;
-
-		hdr_ptr += hdr.value.len;
-		if (hdr_ptr > hdr_end)
-			goto out;
-
-		if (!hdr.name.len && !hdr.value.len)
-			break;
-
-		apr_table_setn(r->headers_in, hdr.name.str, hdr.value.str);
-	}
-
-misc:
-
-	r->hostname = apr_table_get(r->headers_in, "Host");
-	if (!r->hostname)
-		r->hostname = defender_unknown_hostname;
-	r->parsed_uri.hostname = (char *)r->hostname;
-
-	r->content_type = apr_table_get(r->headers_in, "Content-Type");
-	r->content_encoding = apr_table_get(r->headers_in, "Content-Encoding");
-	ptr = apr_table_get(r->headers_in, "Content-Length");
-	if (ptr)
-		r->clength = strtol(ptr, NULL, 10);
-
-	/* body */
-	body = &request->body.data.u.str;
-
-	bb = apr_brigade_create(r->pool, c->bucket_alloc);
-	if (bb == NULL)
-		goto out;
-
-	d = defender_bucket_create(body, c->bucket_alloc);
-	if (d == NULL)
-		goto out;
-
-	APR_BRIGADE_INSERT_TAIL(bb, d);
-
-	e = apr_bucket_eos_create(c->bucket_alloc);
-	APR_BRIGADE_INSERT_TAIL(bb, e);
-
-	apr_table_setn(r->notes, DEFENDER_BRIGADE_REQUEST, (char *)bb);
-
-	/* process */
-	status = defender_process_headers(r);
-
-	if (status == DECLINED)
-		status = defender_process_body(r);
-
-	apr_brigade_cleanup(bb);
-
-	/* success */
-	if (status == DECLINED)
-		status = OK;
-
-out:
-
-	if (r && r->pool) {
-		apr_table_clear(r->headers_in);
-		apr_table_clear(r->headers_out);
-		apr_table_clear(r->subprocess_env);
-		apr_table_clear(r->err_headers_out);
-		apr_table_clear(r->notes);
-		apr_pool_destroy(r->pool);
-	}
-
-	if (c && c->pool) {
-		apr_bucket_alloc_destroy(c->bucket_alloc);
-		apr_pool_destroy(c->pool);
-	}
-
-	return status;
-}
diff --git a/contrib/mod_defender/defender.h b/contrib/mod_defender/defender.h
deleted file mode 100644
index 59241b2..0000000
--- a/contrib/mod_defender/defender.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Mod Defender for HAProxy
- *
- * Copyright 2017 HAProxy Technologies, Dragan Dosen <ddosen@haproxy.com>
- *
- * This program 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 of the License, or (at your option) any later version.
- *
- */
-#ifndef __DEFENDER_H__
-#define __DEFENDER_H__
-
-#include <haproxy/sample-t.h>
-
-struct defender_request {
-	struct sample clientip;
-	struct sample id;
-	struct sample method;
-	struct sample path;
-	struct sample query;
-	struct sample version;
-	struct sample headers;
-	struct sample body;
-};
-
-struct defender_header {
-	struct {
-		char     *str;
-		uint64_t  len;
-	} name;
-	struct {
-		char     *str;
-		uint64_t  len;
-	} value;
-};
-
-int defender_init(const char *config_file, const char *log_file);
-int defender_process_request(struct worker *worker, struct defender_request *request);
-
-#endif /* __DEFENDER_H__ */
diff --git a/contrib/mod_defender/include/haproxy/api-t.h b/contrib/mod_defender/include/haproxy/api-t.h
deleted file mode 100644
index edb33a8..0000000
--- a/contrib/mod_defender/include/haproxy/api-t.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * include/haproxy/api-t.h
- * This provides definitions for all common types or type modifiers used
- * everywhere in the code, and suitable for use in structure fields.
- *
- * Copyright (C) 2020 Willy Tarreau - w@1wt.eu
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _HAPROXY_TYPES_H
-#define _HAPROXY_TYPES_H
-
-#include <inttypes.h>
-#include <stddef.h>
-
-#include <haproxy/compat.h>
-#include <haproxy/compiler.h>
-#include <haproxy/defaults.h>
-#include <haproxy/list-t.h>
-
-#endif /* _HAPROXY_TYPES_H */
diff --git a/contrib/mod_defender/include/haproxy/api.h b/contrib/mod_defender/include/haproxy/api.h
deleted file mode 100644
index a5d7805..0000000
--- a/contrib/mod_defender/include/haproxy/api.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * include/haproxy/api.h
- *
- * Include wrapper that assembles all includes required by every haproxy file.
- * Please do not add direct definitions into this file.
- *
- * Copyright (C) 2020 Willy Tarreau - w@1wt.eu
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _HAPROXY_BASE_H
-#define _HAPROXY_BASE_H
-
-#include <haproxy/api-t.h>
-
-#endif
diff --git a/contrib/mod_defender/include/haproxy/buf-t.h b/contrib/mod_defender/include/haproxy/buf-t.h
deleted file mode 100644
index 3c0f8b5..0000000
--- a/contrib/mod_defender/include/haproxy/buf-t.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * include/haproxy/buf-t.h
- * Simple buffer handling - types definitions.
- *
- * Copyright (C) 2000-2020 Willy Tarreau - w@1wt.eu
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _HAPROXY_BUF_T_H
-#define _HAPROXY_BUF_T_H
-
-#include <haproxy/api-t.h>
-
-/* Structure defining a buffer's head */
-struct buffer {
-	size_t size;                /* buffer size in bytes */
-	char  *area;                /* points to <size> bytes */
-	size_t data;                /* amount of data after head including wrapping */
-	size_t head;                /* start offset of remaining data relative to area */
-};
-
-/* A buffer may be in 3 different states :
- *   - unallocated : size == 0, area == 0  (b_is_null() is true)
- *   - waiting     : size == 0, area != 0  (b_is_null() is true)
- *   - allocated   : size  > 0, area  > 0  (b_is_null() is false)
- */
-
-/* initializers for certain buffer states. It is important that the NULL buffer
- * remains the one with all fields initialized to zero so that a calloc() or a
- * memset() on a struct automatically sets a NULL buffer.
- */
-#define BUF_NULL   ((struct buffer){ })
-#define BUF_WANTED ((struct buffer){ .area = (char *)1 })
-#define BUF_RING   ((struct buffer){ .area = (char *)2 })
-
-#endif /* _HAPROXY_BUF_T_H */
-
-/*
- * Local variables:
- *  c-indent-level: 8
- *  c-basic-offset: 8
- * End:
- */
diff --git a/contrib/mod_defender/include/haproxy/compat.h b/contrib/mod_defender/include/haproxy/compat.h
deleted file mode 100644
index 39d46c2..0000000
--- a/contrib/mod_defender/include/haproxy/compat.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * include/haproxy/compat.h
- * Operating system compatibility interface.
- *
- * Copyright (C) 2000-2020 Willy Tarreau - w@1wt.eu
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _HAPROXY_COMPAT_H
-#define _HAPROXY_COMPAT_H
-
-#include <limits.h>
-#include <signal.h>
-#include <time.h>
-#include <unistd.h>
-/* This is needed on Linux for Netfilter includes */
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-
-/* These are a few short names for commonly used types whose size and sometimes
- * signedness depends on the architecture. Be careful not to rely on a few
- * common but wrong assumptions:
- *  - char is not always signed (ARM, AARCH64, PPC)
- *  - long is not always large enough for a pointer (Windows)
- * These types are needed with the standard C API (string.h, printf, syscalls).
- *
- * When a fixed size is needed (protocol interoperability), better use the
- * standard types provided by stdint.h:
- *   - size_t    : unsigned int of default word size, large enough for any
- *                 object in memory
- *   - ssize_t   : signed int of default word size, used by some syscalls
- *   - uintptr_t : an unsigned int large enough to store any pointer
- *   - ptrdiff_t : a signed int large enough to hold a distance between 2 ptrs
- *   - int<size>_t : a signed int of <size> bits (8,16,32,64 work everywhere)
- *   - uint<size>_t : an unsigned int of <size> bits
- */
-typedef signed char        schar;
-typedef unsigned char      uchar;
-typedef unsigned short     ushort;
-typedef unsigned int       uint;
-typedef unsigned long      ulong;
-typedef unsigned long long ullong;
-typedef long long          llong;
-
-
-/* set any optional field in a struct to this type to save ifdefs. Its address
- * will still be valid but it will not reserve any room nor require any
- * initialization.
- */
-typedef struct { } empty_t;
-
-// Redefine some limits that are not present everywhere
-#ifndef LLONG_MAX
-# define LLONG_MAX 9223372036854775807LL
-# define LLONG_MIN (-LLONG_MAX - 1LL)
-#endif
-
-#ifndef ULLONG_MAX
-# define ULLONG_MAX	(LLONG_MAX * 2ULL + 1)
-#endif
-
-#ifndef LONGBITS
-#define LONGBITS  ((unsigned int)sizeof(long) * 8)
-#endif
-
-#ifndef BITS_PER_INT
-#define BITS_PER_INT    (8*sizeof(int))
-#endif
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-
-/* this is for libc5 for example */
-#ifndef TCP_NODELAY
-#define TCP_NODELAY     1
-#endif
-
-#ifndef SHUT_RD
-#define SHUT_RD	        0
-#endif
-
-#ifndef SHUT_WR
-#define SHUT_WR	        1
-#endif
-
-/* only Linux defines it */
-#ifndef MSG_NOSIGNAL
-#define MSG_NOSIGNAL	0
-#endif
-
-/* AIX does not define MSG_DONTWAIT. We'll define it to zero, and test it
- * wherever appropriate.
- */
-#ifndef MSG_DONTWAIT
-#define MSG_DONTWAIT	0
-#endif
-
-/* Only Linux defines MSG_MORE */
-#ifndef MSG_MORE
-#define MSG_MORE	0
-#endif
-
-/* On Linux 2.4 and above, MSG_TRUNC can be used on TCP sockets to drop any
- * pending data. Let's rely on NETFILTER to detect if this is supported.
- */
-#ifdef USE_NETFILTER
-#define MSG_TRUNC_CLEARS_INPUT
-#endif
-
-/* Maximum path length, OS-dependant */
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 128
-#endif
-
-/* longest UNIX socket name */
-#ifndef UNIX_MAX_PATH
-#define UNIX_MAX_PATH 108
-#endif
-
-/* On Linux, allows pipes to be resized */
-#ifndef F_SETPIPE_SZ
-#define F_SETPIPE_SZ (1024 + 7)
-#endif
-
-/* On FreeBSD we don't have SI_TKILL but SI_LWP instead */
-#if !defined(SI_TKILL) && defined(SI_LWP)
-#define SI_TKILL SI_LWP
-#endif
-
-/* systems without such defines do not know clockid_t or timer_t */
-#if !(_POSIX_TIMERS > 0)
-#undef clockid_t
-#define clockid_t empty_t
-#undef timer_t
-#define timer_t empty_t
-#endif
-
-/* define a dummy value to designate "no timer". Use only 32 bits. */
-#ifndef TIMER_INVALID
-#define TIMER_INVALID ((timer_t)(unsigned long)(0xfffffffful))
-#endif
-
-#if defined(USE_TPROXY) && defined(USE_NETFILTER)
-#include <linux/types.h>
-#include <linux/netfilter_ipv6.h>
-#include <linux/netfilter_ipv4.h>
-#endif
-
-/* On Linux, IP_TRANSPARENT and/or IP_FREEBIND generally require a kernel patch */
-#if defined(USE_LINUX_TPROXY)
-#if !defined(IP_FREEBIND)
-#define IP_FREEBIND 15
-#endif /* !IP_FREEBIND */
-#if !defined(IP_TRANSPARENT)
-#define IP_TRANSPARENT 19
-#endif /* !IP_TRANSPARENT */
-#if !defined(IPV6_TRANSPARENT)
-#define IPV6_TRANSPARENT 75
-#endif /* !IPV6_TRANSPARENT */
-#endif /* USE_LINUX_TPROXY */
-
-#if defined(IP_FREEBIND)       \
- || defined(IP_BINDANY)        \
- || defined(IPV6_BINDANY)      \
- || defined(SO_BINDANY)        \
- || defined(IP_TRANSPARENT)    \
- || defined(IPV6_TRANSPARENT)
-#define CONFIG_HAP_TRANSPARENT
-#endif
-
-/* We'll try to enable SO_REUSEPORT on Linux 2.4 and 2.6 if not defined.
- * There are two families of values depending on the architecture. Those
- * are at least valid on Linux 2.4 and 2.6, reason why we'll rely on the
- * USE_NETFILTER define.
- */
-#if !defined(SO_REUSEPORT) && defined(USE_NETFILTER)
-#if    (SO_REUSEADDR == 2)
-#define SO_REUSEPORT 15
-#elif  (SO_REUSEADDR == 0x0004)
-#define SO_REUSEPORT 0x0200
-#endif /* SO_REUSEADDR */
-#endif /* SO_REUSEPORT */
-
-/* only Linux defines TCP_FASTOPEN */
-#ifdef USE_TFO
-#ifndef TCP_FASTOPEN
-#define TCP_FASTOPEN 23
-#endif
-
-#ifndef TCP_FASTOPEN_CONNECT
-#define TCP_FASTOPEN_CONNECT 30
-#endif
-#endif
-
-/* If IPv6 is supported, define IN6_IS_ADDR_V4MAPPED() if missing. */
-#if defined(IPV6_TCLASS) && !defined(IN6_IS_ADDR_V4MAPPED)
-#define IN6_IS_ADDR_V4MAPPED(a) \
-((((const uint32_t *) (a))[0] == 0) \
-&& (((const uint32_t *) (a))[1] == 0) \
-&& (((const uint32_t *) (a))[2] == htonl (0xffff)))
-#endif
-
-#if defined(__dietlibc__)
-#include <strings.h>
-#endif
-
-/* crypt_r() has been present in glibc since 2.2 and on FreeBSD since 12.0
- * (12000002). No other OS makes any mention of it for now. Feel free to add
- * valid known combinations below if needed to relax the crypt() lock when
- * using threads.
- */
-#if (defined(__GNU_LIBRARY__) && (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) \
- || (defined(__FreeBSD__) && __FreeBSD_version >= 1200002)
-#define HA_HAVE_CRYPT_R
-#endif
-
-/* some backtrace() implementations are broken or incomplete, in this case we
- * can replace them. We must not do it all the time as some are more accurate
- * than ours.
- */
-#ifdef USE_BACKTRACE
-#if defined(__aarch64__)
-/* on aarch64 at least from gcc-4.7.4 to 7.4.1 we only get a single entry, which
- * is pointless. Ours works though it misses the faulty function itself,
- * probably due to an alternate stack for the signal handler which does not
- * create a new frame hence doesn't store the caller's return address.
- */
-#elif defined(__clang__) && defined(__x86_64__)
-/* this is on FreeBSD, clang 4.0 to 8.0 produce don't go further than the
- * sighandler.
- */
-#else
-#define HA_HAVE_WORKING_BACKTRACE
-#endif
-#endif
-
-/* malloc_trim() can be very convenient to reclaim unused memory especially
- * from huge pattern files. It's available (and really usable) in glibc 2.8 and
- * above.
- */
-#if (defined(__GNU_LIBRARY__) && (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 8))
-#include <malloc.h>
-#define HA_HAVE_MALLOC_TRIM
-#endif
-
-/* glibc 2.26 includes a thread-local cache which makes it fast enough in threads */
-#if (defined(__GNU_LIBRARY__) && (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 26))
-#include <malloc.h>
-#define HA_HAVE_FAST_MALLOC
-#endif
-
-/* Max number of file descriptors we send in one sendmsg(). Linux seems to be
- * able to send 253 fds per sendmsg(), not sure about the other OSes.
- */
-#define MAX_SEND_FD 253
-
-/* Make the new complex name for the xxhash function easier to remember
- * and use.
- */
-#ifndef XXH3
-#define XXH3(data, len, seed) XXH3_64bits_withSeed(data, len, seed)
-#endif
-
-#endif /* _HAPROXY_COMPAT_H */
-
-/*
- * Local variables:
- *  c-indent-level: 8
- *  c-basic-offset: 8
- * End:
- */
diff --git a/contrib/mod_defender/include/haproxy/compiler.h b/contrib/mod_defender/include/haproxy/compiler.h
deleted file mode 100644
index 7255767..0000000
--- a/contrib/mod_defender/include/haproxy/compiler.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * include/haproxy/compiler.h
- * This files contains some compiler-specific settings.
- *
- * Copyright (C) 2000-2020 Willy Tarreau - w@1wt.eu
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _HAPROXY_COMPILER_H
-#define _HAPROXY_COMPILER_H
-
-#ifdef DEBUG_USE_ABORT
-#include <stdlib.h>
-#endif
-
-/*
- * Gcc before 3.0 needs [0] to declare a variable-size array
- */
-#ifndef VAR_ARRAY
-#if defined(__GNUC__) && (__GNUC__ < 3)
-#define VAR_ARRAY	0
-#else
-#define VAR_ARRAY
-#endif
-#endif
-
-#if !defined(__GNUC__)
-/* Some versions of glibc irresponsibly redefine __attribute__() to empty for
- * non-gcc compilers, and as such, silently break all constructors with other
- * other compilers. Let's make sure such incompatibilities are detected if any,
- * or that the attribute is properly enforced.
- */
-#undef __attribute__
-#define __attribute__(x) __attribute__(x)
-#endif
-
-/* By default, gcc does not inline large chunks of code, but we want it to
- * respect our choices.
- */
-#if !defined(forceinline)
-#if !defined(__GNUC__) || (__GNUC__ < 3)
-#define forceinline inline
-#else
-#define forceinline inline __attribute__((always_inline))
-#endif
-#endif
-
-/* silence the "unused" warnings without having to place painful #ifdefs.
- * For use with variables or functions.
- */
-#define __maybe_unused __attribute__((unused))
-
-/* These macros are used to declare a section name for a variable.
- * WARNING: keep section names short, as MacOS limits them to 16 characters.
- * The _START and _STOP attributes have to be placed after the start and stop
- * weak symbol declarations, and are only used by MacOS.
- */
-#if !defined(USE_OBSOLETE_LINKER)
-
-#ifdef __APPLE__
-#define HA_SECTION(s)           __attribute__((__section__("__DATA, " s)))
-#define HA_SECTION_START(s)     __asm("section$start$__DATA$" s)
-#define HA_SECTION_STOP(s)      __asm("section$end$__DATA$" s)
-#else
-#define HA_SECTION(s)           __attribute__((__section__(s)))
-#define HA_SECTION_START(s)
-#define HA_SECTION_STOP(s)
-#endif
-
-#else // obsolete linker below, let's just not force any section
-
-#define HA_SECTION(s)
-#define HA_SECTION_START(s)
-#define HA_SECTION_STOP(s)
-
-#endif // USE_OBSOLETE_LINKER
-
-/* use this attribute on a variable to move it to the read_mostly section */
-#define __read_mostly           HA_SECTION("read_mostly")
-
-/* This allows gcc to know that some locations are never reached, for example
- * after a longjmp() in the Lua code, hence that some errors caught by such
- * methods cannot propagate further. This is important with gcc versions 6 and
- * above which can more aggressively detect null dereferences. The builtin
- * below was introduced in gcc 4.5, and before it we didn't care.
- */
-#ifdef DEBUG_USE_ABORT
-#define my_unreachable() abort()
-#else
-#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
-#define my_unreachable() __builtin_unreachable()
-#else
-#define my_unreachable()
-#endif
-#endif
-
-/* This macro may be used to block constant propagation that lets the compiler
- * detect a possible NULL dereference on a variable resulting from an explicit
- * assignment in an impossible check. Sometimes a function is called which does
- * safety checks and returns NULL if safe conditions are not met. The place
- * where it's called cannot hit this condition and dereferencing the pointer
- * without first checking it will make the compiler emit a warning about a
- * "potential null pointer dereference" which is hard to work around. This
- * macro "washes" the pointer and prevents the compiler from emitting tests
- * branching to undefined instructions. It may only be used when the developer
- * is absolutely certain that the conditions are guaranteed and that the
- * pointer passed in argument cannot be NULL by design.
- */
-#define ALREADY_CHECKED(p) do { asm("" : "=rm"(p) : "0"(p)); } while (0)
-
-/* same as above but to be used to pass the input value to the output but
- * without letting the compiler know about its initial properties.
- */
-#define DISGUISE(v) ({ typeof(v) __v = (v); ALREADY_CHECKED(__v); __v; })
-
-/*
- * Gcc >= 3 provides the ability for the program to give hints to the
- * compiler about what branch of an if is most likely to be taken. This
- * helps the compiler produce the most compact critical paths, which is
- * generally better for the cache and to reduce the number of jumps.
- */
-#if !defined(likely)
-#if !defined(__GNUC__) || (__GNUC__ < 3)
-#define __builtin_expect(x,y) (x)
-#define likely(x) (x)
-#define unlikely(x) (x)
-#else
-#define likely(x) (__builtin_expect((x) != 0, 1))
-#define unlikely(x) (__builtin_expect((x) != 0, 0))
-#endif
-#endif
-
-#ifndef __GNUC_PREREQ__
-#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
-#define __GNUC_PREREQ__(ma, mi) \
-        (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi))
-#else
-#define __GNUC_PREREQ__(ma, mi) 0
-#endif
-#endif
-
-#ifndef offsetof
-#if __GNUC_PREREQ__(4, 1)
-#define offsetof(type, field)  __builtin_offsetof(type, field)
-#else
-#define offsetof(type, field) \
-        ((size_t)(uintptr_t)((const volatile void *)&((type *)0)->field))
-#endif
-#endif
-
-/* Some architectures have a double-word CAS, sometimes even dual-8 bytes.
- * Some architectures support unaligned accesses, others are fine with them
- * but only for non-atomic operations. Also mention those supporting unaligned
- * accesses and being little endian, and those where unaligned accesses are
- * known to be fast (almost as fast as aligned ones).
- */
-#if defined(__x86_64__)
-#define HA_UNALIGNED
-#define HA_UNALIGNED_LE
-#define HA_UNALIGNED_LE64
-#define HA_UNALIGNED_FAST
-#define HA_UNALIGNED_ATOMIC
-#define HA_HAVE_CAS_DW
-#define HA_CAS_IS_8B
-#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
-#define HA_UNALIGNED
-#define HA_UNALIGNED_LE
-#define HA_UNALIGNED_ATOMIC
-#elif defined (__aarch64__) || defined(__ARM_ARCH_8A)
-#define HA_UNALIGNED
-#define HA_UNALIGNED_LE
-#define HA_UNALIGNED_LE64
-#define HA_UNALIGNED_FAST
-#define HA_HAVE_CAS_DW
-#define HA_CAS_IS_8B
-#elif defined(__arm__) && (defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__))
-#define HA_UNALIGNED
-#define HA_UNALIGNED_LE
-#define HA_UNALIGNED_FAST
-#define HA_HAVE_CAS_DW
-#endif
-
-
-/* sets alignment for current field or variable */
-#ifndef ALIGNED
-#define ALIGNED(x) __attribute__((aligned(x)))
-#endif
-
-/* sets alignment only on architectures preventing unaligned atomic accesses */
-#ifndef MAYBE_ALIGNED
-#ifndef HA_UNALIGNED
-#define MAYBE_ALIGNED(x)  ALIGNED(x)
-#else
-#define MAYBE_ALIGNED(x)
-#endif
-#endif
-
-/* sets alignment only on architectures preventing unaligned atomic accesses */
-#ifndef ATOMIC_ALIGNED
-#ifndef HA_UNALIGNED_ATOMIC
-#define ATOMIC_ALIGNED(x)  ALIGNED(x)
-#else
-#define ATOMIC_ALIGNED(x)
-#endif
-#endif
-
-/* sets alignment for current field or variable only when threads are enabled.
- * Typically used to respect cache line alignment to avoid false sharing.
- */
-#ifndef THREAD_ALIGNED
-#ifdef USE_THREAD
-#define THREAD_ALIGNED(x) __attribute__((aligned(x)))
-#else
-#define THREAD_ALIGNED(x)
-#endif
-#endif
-
-/* add a mandatory alignment for next fields in a structure */
-#ifndef ALWAYS_ALIGN
-#define ALWAYS_ALIGN(x)  union { } ALIGNED(x)
-#endif
-
-/* add an optional alignment for next fields in a structure, only for archs
- * which do not support unaligned accesses.
- */
-#ifndef MAYBE_ALIGN
-#ifndef HA_UNALIGNED
-#define MAYBE_ALIGN(x)  union { } ALIGNED(x)
-#else
-#define MAYBE_ALIGN(x)
-#endif
-#endif
-
-/* add an optional alignment for next fields in a structure, only for archs
- * which do not support unaligned accesses for atomic operations.
- */
-#ifndef ATOMIC_ALIGN
-#ifndef HA_UNALIGNED_ATOMIC
-#define ATOMIC_ALIGN(x)  union { } ALIGNED(x)
-#else
-#define ATOMIC_ALIGN(x)
-#endif
-#endif
-
-/* add an optional alignment for next fields in a structure, only when threads
- * are enabled. Typically used to respect cache line alignment to avoid false
- * sharing.
- */
-#ifndef THREAD_ALIGN
-#ifdef USE_THREAD
-#define THREAD_ALIGN(x) union { } ALIGNED(x)
-#else
-#define THREAD_ALIGN(x)
-#endif
-#endif
-
-/* The THREAD_LOCAL type attribute defines thread-local storage and is defined
- * to __thread when threads are enabled or empty when disabled.
- */
-#ifdef USE_THREAD
-#define THREAD_LOCAL __thread
-#else
-#define THREAD_LOCAL
-#endif
-
-/* The __decl_thread() statement is shows the argument when threads are enabled
- * or hides it when disabled. The purpose is to condition the presence of some
- * variables or struct members to the fact that threads are enabled, without
- * having to enclose them inside a #ifdef USE_THREAD/#endif clause.
- */
-#ifdef USE_THREAD
-#define __decl_thread(decl) decl
-#else
-#define __decl_thread(decl)
-#endif
-
-/* clang has a __has_feature() macro which reports true/false on a number of
- * internally supported features. Let's make sure this macro is always defined
- * and returns zero when not supported.
- */
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-
-#endif /* _HAPROXY_COMPILER_H */
diff --git a/contrib/mod_defender/include/haproxy/defaults.h b/contrib/mod_defender/include/haproxy/defaults.h
deleted file mode 100644
index f6a15db..0000000
--- a/contrib/mod_defender/include/haproxy/defaults.h
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * include/haproxy/defaults.h
- * Miscellaneous default values.
- *
- * Copyright (C) 2000-2020 Willy Tarreau - w@1wt.eu
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _HAPROXY_DEFAULTS_H
-#define _HAPROXY_DEFAULTS_H
-
-/* MAX_PROCS defines the highest limit for the global "nbproc" value. It
- * defaults to the number of bits in a long integer but may be lowered to save
- * resources on embedded systems.
- */
-#ifndef MAX_PROCS
-#define MAX_PROCS LONGBITS
-#endif
-
-/* MAX_THREADS defines the highest limit for the global nbthread value. It
- * defaults to the number of bits in a long integer when threads are enabled
- * but may be lowered to save resources on embedded systems.
-*/
-#ifndef USE_THREAD
-/* threads disabled, 1 thread max */
-#define MAX_THREADS 1
-#define MAX_THREADS_MASK 1
-
-#else
-/* threads enabled, max_threads defaults to long bits */
-#ifndef MAX_THREADS
-#define MAX_THREADS LONGBITS
-#endif
-#define MAX_THREADS_MASK (~0UL >> (LONGBITS - MAX_THREADS))
-#endif
-
-/*
- * BUFSIZE defines the size of a read and write buffer. It is the maximum
- * amount of bytes which can be stored by the proxy for each stream. However,
- * when reading HTTP headers, the proxy needs some spare space to add or rewrite
- * headers if needed. The size of this spare is defined with MAXREWRITE. So it
- * is not possible to process headers longer than BUFSIZE-MAXREWRITE bytes. By
- * default, BUFSIZE=16384 bytes and MAXREWRITE=min(1024,BUFSIZE/2), so the
- * maximum length of headers accepted is 15360 bytes.
- */
-#ifndef BUFSIZE
-#define BUFSIZE	        16384
-#endif
-
-/* certain buffers may only be allocated for responses in order to avoid
- * deadlocks caused by request queuing. 2 buffers is the absolute minimum
- * acceptable to ensure that a request gaining access to a server can get
- * a response buffer even if it doesn't completely flush the request buffer.
- * The worst case is an applet making use of a request buffer that cannot
- * completely be sent while the server starts to respond, and all unreserved
- * buffers are allocated by request buffers from pending connections in the
- * queue waiting for this one to flush. Both buffers reserved buffers may
- * thus be used at the same time.
- */
-#ifndef RESERVED_BUFS
-#define RESERVED_BUFS   2
-#endif
-
-// reserved buffer space for header rewriting
-#ifndef MAXREWRITE
-#define MAXREWRITE      1024
-#endif
-
-#ifndef REQURI_LEN
-#define REQURI_LEN      1024
-#endif
-
-#ifndef CAPTURE_LEN
-#define CAPTURE_LEN     64
-#endif
-
-#ifndef MAX_SYSLOG_LEN
-#define MAX_SYSLOG_LEN          1024
-#endif
-
-/* 64kB to archive startup-logs seems way more than enough */
-#ifndef STARTUP_LOG_SIZE
-#define STARTUP_LOG_SIZE        65536
-#endif
-
-// maximum line size when parsing config
-#ifndef LINESIZE
-#define LINESIZE	2048
-#endif
-
-// max # args on a configuration line
-#define MAX_LINE_ARGS   64
-
-// maximum line size when parsing crt-bind-list config
-#define CRT_LINESIZE    65536
-
-// max # args on crt-bind-list configuration line
-#define MAX_CRT_ARGS  2048
-
-// max # args on a command issued on the CLI ("stats socket")
-// This should cover at least 5 + twice the # of data_types
-#define MAX_CLI_ARGS  64
-
-// max # of matches per regexp
-#define	MAX_MATCH       10
-
-// max # of headers in one HTTP request or response
-// By default, about 100 headers (+1 for the first line)
-#ifndef MAX_HTTP_HDR
-#define MAX_HTTP_HDR    101
-#endif
-
-// max # of headers in history when looking for header #-X
-#ifndef MAX_HDR_HISTORY
-#define MAX_HDR_HISTORY 10
-#endif
-
-// max # of stick counters per session (at least 3 for sc0..sc2)
-#ifndef MAX_SESS_STKCTR
-#define MAX_SESS_STKCTR 3
-#endif
-
-// max # of extra stick-table data types that can be registered at runtime
-#ifndef STKTABLE_EXTRA_DATA_TYPES
-#define STKTABLE_EXTRA_DATA_TYPES 0
-#endif
-
-// max # of stick-table filter entries that can be used during dump
-#ifndef STKTABLE_FILTER_LEN
-#define STKTABLE_FILTER_LEN 4
-#endif
-
-// max # of loops we can perform around a read() which succeeds.
-// It's very frequent that the system returns a few TCP segments at a time.
-#ifndef MAX_READ_POLL_LOOPS
-#define MAX_READ_POLL_LOOPS 4
-#endif
-
-// minimum number of bytes read at once above which we don't try to read
-// more, in order not to risk facing an EAGAIN. Most often, if we read
-// at least 10 kB, we can consider that the system has tried to read a
-// full buffer and got multiple segments (>1 MSS for jumbo frames, >7 MSS
-// for normal frames) did not bother truncating the last segment.
-#ifndef MIN_RECV_AT_ONCE_ENOUGH
-#define MIN_RECV_AT_ONCE_ENOUGH (7*1448)
-#endif
-
-// The minimum number of bytes to be forwarded that is worth trying to splice.
-// Below 4kB, it's not worth allocating pipes nor pretending to zero-copy.
-#ifndef MIN_SPLICE_FORWARD
-#define MIN_SPLICE_FORWARD 4096
-#endif
-
-// the max number of events returned in one call to poll/epoll. Too small a
-// value will cause lots of calls, and too high a value may cause high latency.
-#ifndef MAX_POLL_EVENTS
-#define MAX_POLL_EVENTS 200
-#endif
-
-// The maximum number of connections accepted at once by a thread for a single
-// listener. It used to default to 64 divided by the number of processes but
-// the tasklet-based model is much more scalable and benefits from smaller
-// values. Experimentation has shown that 4 gives the highest accept rate for
-// all thread values, and that 3 and 5 come very close, as shown below (HTTP/1
-// connections forwarded per second at multi-accept 4 and 64):
-//
-// ac\thr|    1    2     4     8     16
-// ------+------------------------------
-//      4|   80k  106k  168k  270k  336k
-//     64|   63k   89k  145k  230k  274k
-//
-#ifndef MAX_ACCEPT
-#define MAX_ACCEPT 4
-#endif
-
-// The base max number of tasks to run at once to be used when not set by
-// tune.runqueue-depth. It will automatically be divided by the square root
-// of the number of threads for better fairness. As such, 64 threads will
-// use 35 and a single thread will use 280.
-#ifndef RUNQUEUE_DEPTH
-#define RUNQUEUE_DEPTH 280
-#endif
-
-// cookie delimiter in "prefix" mode. This character is inserted between the
-// persistence cookie and the original value. The '~' is allowed by RFC6265,
-// and should not be too common in server names.
-#ifndef COOKIE_DELIM
-#define COOKIE_DELIM    '~'
-#endif
-
-// this delimiter is used between a server's name and a last visit date in
-// cookies exchanged with the client.
-#ifndef COOKIE_DELIM_DATE
-#define COOKIE_DELIM_DATE       '|'
-#endif
-
-#define CONN_RETRIES    3
-
-#define	CHK_CONNTIME    2000
-#define	DEF_CHKINTR     2000
-#define DEF_MAILALERTTIME 10000
-#define DEF_FALLTIME    3
-#define DEF_RISETIME    2
-#define DEF_AGENT_FALLTIME    1
-#define DEF_AGENT_RISETIME    1
-#define DEF_CHECK_PATH  ""
-
-
-#define DEF_HANA_ONERR		HANA_ONERR_FAILCHK
-#define DEF_HANA_ERRLIMIT	10
-
-// X-Forwarded-For header default
-#define DEF_XFORWARDFOR_HDR	"X-Forwarded-For"
-
-// X-Original-To header default
-#define DEF_XORIGINALTO_HDR	"X-Original-To"
-
-/* Default connections limit.
- *
- * A system limit can be enforced at build time in order to avoid using haproxy
- * beyond reasonable system limits. For this, just define SYSTEM_MAXCONN to the
- * absolute limit accepted by the system. If the configuration specifies a
- * higher value, it will be capped to SYSTEM_MAXCONN and a warning will be
- * emitted. The only way to override this limit will be to set it via the
- * command-line '-n' argument. If SYSTEM_MAXCONN is not set, a minimum value
- * of 100 will be used for DEFAULT_MAXCONN which almost guarantees that a
- * process will correctly start in any situation.
- */
-#ifdef SYSTEM_MAXCONN
-#undef  DEFAULT_MAXCONN
-#define DEFAULT_MAXCONN SYSTEM_MAXCONN
-#elif !defined(DEFAULT_MAXCONN)
-#define DEFAULT_MAXCONN 100
-#endif
-
-/* Minimum check interval for spread health checks. Servers with intervals
- * greater than or equal to this value will have their checks spread apart
- * and will be considered when searching the minimal interval.
- * Others will be ignored for the minimal interval and will have their checks
- * scheduled on a different basis.
- */
-#ifndef SRV_CHK_INTER_THRES
-#define SRV_CHK_INTER_THRES 1000
-#endif
-
-/* Specifies the string used to report the version and release date on the
- * statistics page. May be defined to the empty string ("") to permanently
- * disable the feature.
- */
-#ifndef STATS_VERSION_STRING
-#define STATS_VERSION_STRING " version " HAPROXY_VERSION ", released " HAPROXY_DATE
-#endif
-
-/* This is the default statistics URI */
-#ifdef CONFIG_STATS_DEFAULT_URI
-#define STATS_DEFAULT_URI CONFIG_STATS_DEFAULT_URI
-#else
-#define STATS_DEFAULT_URI "/haproxy?stats"
-#endif
-
-/* This is the default statistics realm */
-#ifdef CONFIG_STATS_DEFAULT_REALM
-#define STATS_DEFAULT_REALM CONFIG_STATS_DEFAULT_REALM
-#else
-#define STATS_DEFAULT_REALM "HAProxy Statistics"
-#endif
-
-/* Maximum signal queue size, and also number of different signals we can
- * handle.
- */
-#ifndef MAX_SIGNAL
-#define MAX_SIGNAL 256
-#endif
-
-/* Maximum host name length */
-#ifndef MAX_HOSTNAME_LEN
-#if MAXHOSTNAMELEN
-#define MAX_HOSTNAME_LEN	MAXHOSTNAMELEN
-#else
-#define MAX_HOSTNAME_LEN	64
-#endif // MAXHOSTNAMELEN
-#endif // MAX_HOSTNAME_LEN
-
-/* Maximum health check description length */
-#ifndef HCHK_DESC_LEN
-#define HCHK_DESC_LEN	128
-#endif
-
-/* ciphers used as defaults on connect */
-#ifndef CONNECT_DEFAULT_CIPHERS
-#define CONNECT_DEFAULT_CIPHERS NULL
-#endif
-
-/* ciphers used as defaults on TLS 1.3 connect */
-#ifndef CONNECT_DEFAULT_CIPHERSUITES
-#define CONNECT_DEFAULT_CIPHERSUITES NULL
-#endif
-
-/* ciphers used as defaults on listeners */
-#ifndef LISTEN_DEFAULT_CIPHERS
-#define LISTEN_DEFAULT_CIPHERS NULL
-#endif
-
-/* cipher suites used as defaults on TLS 1.3 listeners */
-#ifndef LISTEN_DEFAULT_CIPHERSUITES
-#define LISTEN_DEFAULT_CIPHERSUITES NULL
-#endif
-
-/* named curve used as defaults for ECDHE ciphers */
-#ifndef ECDHE_DEFAULT_CURVE
-#define ECDHE_DEFAULT_CURVE "prime256v1"
-#endif
-
-/* ssl cache size */
-#ifndef SSLCACHESIZE
-#define SSLCACHESIZE 20000
-#endif
-
-/* ssl max dh param size */
-#ifndef SSL_DEFAULT_DH_PARAM
-#define SSL_DEFAULT_DH_PARAM 0
-#endif
-
-/* max memory cost per SSL session */
-#ifndef SSL_SESSION_MAX_COST
-#define SSL_SESSION_MAX_COST (16*1024)    // measured
-#endif
-
-/* max memory cost per SSL handshake (on top of session) */
-#ifndef SSL_HANDSHAKE_MAX_COST
-#define SSL_HANDSHAKE_MAX_COST (76*1024)  // measured
-#endif
-
-#ifndef DEFAULT_SSL_CTX_CACHE
-#define DEFAULT_SSL_CTX_CACHE 1000
-#endif
-
-/* approximate stream size (for maxconn estimate) */
-#ifndef STREAM_MAX_COST
-#define STREAM_MAX_COST (sizeof(struct stream) + \
-                          2 * sizeof(struct channel) + \
-                          2 * sizeof(struct connection) + \
-                          global.tune.requri_len + \
-                          2 * global.tune.cookie_len)
-#endif
-
-/* available memory estimate : count about 3% of overhead in various structures */
-#ifndef MEM_USABLE_RATIO
-#define MEM_USABLE_RATIO 0.97
-#endif
-
-/* default per-thread pool cache size when enabled */
-#ifndef CONFIG_HAP_POOL_CACHE_SIZE
-#define CONFIG_HAP_POOL_CACHE_SIZE 1048576
-#endif
-
-/* Number of samples used to compute the times reported in stats. A power of
- * two is highly recommended, and this value multiplied by the largest response
- * time must not overflow and unsigned int. See freq_ctr.h for more information.
- * We consider that values are accurate to 95% with two batches of samples below,
- * so in order to advertise accurate times across 1k samples, we effectively
- * measure over 512.
- */
-#ifndef TIME_STATS_SAMPLES
-#define TIME_STATS_SAMPLES 512
-#endif
-
-/* max ocsp cert id asn1 encoded length */
-#ifndef OCSP_MAX_CERTID_ASN1_LENGTH
-#define OCSP_MAX_CERTID_ASN1_LENGTH 128
-#endif
-
-#ifndef OCSP_MAX_RESPONSE_TIME_SKEW
-#define OCSP_MAX_RESPONSE_TIME_SKEW 300
-#endif
-
-/* Number of TLS tickets to check, used for rotation */
-#ifndef TLS_TICKETS_NO
-#define TLS_TICKETS_NO 3
-#endif
-
-/* pattern lookup default cache size, in number of entries :
- * 10k entries at 10k req/s mean 1% risk of a collision after 60 years, that's
- * already much less than the memory's reliability in most machines and more
- * durable than most admin's life expectancy. A collision will result in a
- * valid result to be returned for a different entry from the same list.
- */
-#ifndef DEFAULT_PAT_LRU_SIZE
-#define DEFAULT_PAT_LRU_SIZE 10000
-#endif
-
-/* maximum number of pollers that may be registered */
-#ifndef MAX_POLLERS
-#define MAX_POLLERS	10
-#endif
-
-/* Make all xxhash functions inline, with implementations being directly
- * included within xxhash.h.
- */
-#ifndef XXH_INLINE_ALL
-#define XXH_INLINE_ALL
-#endif
-
-#endif /* _HAPROXY_DEFAULTS_H */
diff --git a/contrib/mod_defender/include/haproxy/http-t.h b/contrib/mod_defender/include/haproxy/http-t.h
deleted file mode 100644
index 81bd8ab..0000000
--- a/contrib/mod_defender/include/haproxy/http-t.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * include/haproxy/http-t.h
- *
- * Version-agnostic and implementation-agnostic HTTP protocol definitions.
- *
- * Copyright (C) 2000-2020 Willy Tarreau - w@1wt.eu
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _HAPROXY_HTTP_T_H
-#define _HAPROXY_HTTP_T_H
-
-#include <inttypes.h>
-#include <haproxy/buf-t.h>
-
-/*
- * some macros mainly used when parsing header fields.
- * from RFC7230:
- *   CTL                 = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
- *   SEP                 = one of the 17 defined separators or SP or HT
- *   LWS                 = CR, LF, SP or HT
- *   SPHT                = SP or HT. Use this macro and not a boolean expression for best speed.
- *   CRLF                = CR or LF. Use this macro and not a boolean expression for best speed.
- *   token               = any CHAR except CTL or SEP. Use this macro and not a boolean expression for best speed.
- *
- * added for ease of use:
- *   ver_token           = 'H', 'P', 'T', '/', '.', and digits.
- */
-#define HTTP_FLG_CTL  0x01
-#define HTTP_FLG_SEP  0x02
-#define HTTP_FLG_LWS  0x04
-#define HTTP_FLG_SPHT 0x08
-#define HTTP_FLG_CRLF 0x10
-#define HTTP_FLG_TOK  0x20
-#define HTTP_FLG_VER  0x40
-#define HTTP_FLG_DIG  0x80
-
-#define HTTP_IS_CTL(x)       (http_char_classes[(uint8_t)(x)] & HTTP_FLG_CTL)
-#define HTTP_IS_SEP(x)       (http_char_classes[(uint8_t)(x)] & HTTP_FLG_SEP)
-#define HTTP_IS_LWS(x)       (http_char_classes[(uint8_t)(x)] & HTTP_FLG_LWS)
-#define HTTP_IS_SPHT(x)      (http_char_classes[(uint8_t)(x)] & HTTP_FLG_SPHT)
-#define HTTP_IS_CRLF(x)      (http_char_classes[(uint8_t)(x)] & HTTP_FLG_CRLF)
-#define HTTP_IS_TOKEN(x)     (http_char_classes[(uint8_t)(x)] & HTTP_FLG_TOK)
-#define HTTP_IS_VER_TOKEN(x) (http_char_classes[(uint8_t)(x)] & HTTP_FLG_VER)
-#define HTTP_IS_DIGIT(x)     (http_char_classes[(uint8_t)(x)] & HTTP_FLG_DIG)
-
-/* Known HTTP methods */
-enum http_meth_t {
-	HTTP_METH_OPTIONS,
-	HTTP_METH_GET,
-	HTTP_METH_HEAD,
-	HTTP_METH_POST,
-	HTTP_METH_PUT,
-	HTTP_METH_DELETE,
-	HTTP_METH_TRACE,
-	HTTP_METH_CONNECT,
-	HTTP_METH_OTHER, /* Must be the last entry */
-} __attribute__((packed));
-
-/* Known HTTP authentication schemes */
-enum ht_auth_m {
-	HTTP_AUTH_WRONG		= -1,		/* missing or unknown */
-	HTTP_AUTH_UNKNOWN	= 0,
-	HTTP_AUTH_BASIC,
-	HTTP_AUTH_DIGEST,
-} __attribute__((packed));
-
-/* All implemented HTTP status codes */
-enum {
-	HTTP_ERR_200 = 0,
-	HTTP_ERR_400,
-	HTTP_ERR_401,
-	HTTP_ERR_403,
-	HTTP_ERR_404,
-	HTTP_ERR_405,
-	HTTP_ERR_407,
-	HTTP_ERR_408,
-	HTTP_ERR_410,
-	HTTP_ERR_413,
-	HTTP_ERR_421,
-	HTTP_ERR_425,
-	HTTP_ERR_429,
-	HTTP_ERR_500,
-	HTTP_ERR_501,
-	HTTP_ERR_502,
-	HTTP_ERR_503,
-	HTTP_ERR_504,
-	HTTP_ERR_SIZE
-};
-
-/* Note: the strings below make use of chunks. Chunks may carry an allocated
- * size in addition to the length. The size counts from the beginning (str)
- * to the end. If the size is unknown, it MUST be zero, in which case the
- * sample will automatically be duplicated when a change larger than <len> has
- * to be performed. Thus it is safe to always set size to zero.
- */
-struct http_meth {
-	enum http_meth_t meth;
-	struct buffer str;
-};
-
-struct http_auth_data {
-	enum ht_auth_m method;                /* one of HTTP_AUTH_* */
-	/* 7 bytes unused here */
-	struct buffer method_data;            /* points to the creditial part from 'Authorization:' header */
-	char *user, *pass;                    /* extracted username & password */
-};
-
-enum http_etag_type {
-	ETAG_INVALID = 0,
-	ETAG_STRONG,
-	ETAG_WEAK
-};
-
-#endif /* _HAPROXY_HTTP_T_H */
-
-/*
- * Local variables:
- *  c-indent-level: 8
- *  c-basic-offset: 8
- * End:
- */
diff --git a/contrib/mod_defender/include/haproxy/intops.h b/contrib/mod_defender/include/haproxy/intops.h
deleted file mode 100644
index 40e87f9..0000000
--- a/contrib/mod_defender/include/haproxy/intops.h
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * include/haproxy/intops.h
- * Functions for integer operations.
- *
- * Copyright (C) 2020 Willy Tarreau - w@1wt.eu
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-#ifndef _HAPROXY_INTOPS_H
-#define _HAPROXY_INTOPS_H
-
-#include <haproxy/api.h>
-
-/* Multiply the two 32-bit operands and shift the 64-bit result right 32 bits.
- * This is used to compute fixed ratios by setting one of the operands to
- * (2^32*ratio).
- */
-static inline unsigned int mul32hi(unsigned int a, unsigned int b)
-{
-	return ((unsigned long long)a * b + a) >> 32;
-}
-
-/* gcc does not know when it can safely divide 64 bits by 32 bits. Use this
- * function when you know for sure that the result fits in 32 bits, because
- * it is optimal on x86 and on 64bit processors.
- */
-static inline unsigned int div64_32(unsigned long long o1, unsigned int o2)
-{
-	unsigned long long result;
-#ifdef __i386__
-	asm("divl %2"
-	    : "=A" (result)
-	    : "A"(o1), "rm"(o2));
-#else
-	result = o1 / o2;
-#endif
-	return result;
-}
-
-/* rotate left a 64-bit integer by <bits:[0-5]> bits */
-static inline uint64_t rotl64(uint64_t v, uint8_t bits)
-{
-#if !defined(__ARM_ARCH_8A) && !defined(__x86_64__)
-	bits &= 63;
-#endif
-	v = (v << bits) | (v >> (-bits & 63));
-	return v;
-}
-
-/* rotate right a 64-bit integer by <bits:[0-5]> bits */
-static inline uint64_t rotr64(uint64_t v, uint8_t bits)
-{
-#if !defined(__ARM_ARCH_8A) && !defined(__x86_64__)
-	bits &= 63;
-#endif
-	v = (v >> bits) | (v << (-bits & 63));
-	return v;
-}
-
-/* Simple popcountl implementation. It returns the number of ones in a word.
- * Described here : https://graphics.stanford.edu/~seander/bithacks.html
- */
-static inline unsigned int my_popcountl(unsigned long a)
-{
-	a = a - ((a >> 1) & ~0UL/3);
-	a = (a & ~0UL/15*3) + ((a >> 2) & ~0UL/15*3);
-	a = (a + (a >> 4)) & ~0UL/255*15;
-	return (unsigned long)(a * (~0UL/255)) >> (sizeof(unsigned long) - 1) * 8;
-}
-
-/* returns non-zero if <a> has at least 2 bits set */
-static inline unsigned long atleast2(unsigned long a)
-{
-	return a & (a - 1);
-}
-
-/* Simple ffs implementation. It returns the position of the lowest bit set to
- * one, starting at 1. It is illegal to call it with a==0 (undefined result).
- */
-static inline unsigned int my_ffsl(unsigned long a)
-{
-	unsigned long cnt;
-
-#if defined(__x86_64__)
-	__asm__("bsf %1,%0\n" : "=r" (cnt) : "rm" (a));
-	cnt++;
-#else
-
-	cnt = 1;
-#if LONG_MAX > 0x7FFFFFFFL /* 64bits */
-	if (!(a & 0xFFFFFFFFUL)) {
-		a >>= 32;
-		cnt += 32;
-	}
-#endif
-	if (!(a & 0XFFFFU)) {
-		a >>= 16;
-		cnt += 16;
-	}
-	if (!(a & 0XFF)) {
-		a >>= 8;
-		cnt += 8;
-	}
-	if (!(a & 0xf)) {
-		a >>= 4;
-		cnt += 4;
-	}
-	if (!(a & 0x3)) {
-		a >>= 2;
-		cnt += 2;
-	}
-	if (!(a & 0x1)) {
-		cnt += 1;
-	}
-#endif /* x86_64 */
-
-	return cnt;
-}
-
-/* Simple fls implementation. It returns the position of the highest bit set to
- * one, starting at 1. It is illegal to call it with a==0 (undefined result).
- */
-static inline unsigned int my_flsl(unsigned long a)
-{
-	unsigned long cnt;
-
-#if defined(__x86_64__)
-	__asm__("bsr %1,%0\n" : "=r" (cnt) : "rm" (a));
-	cnt++;
-#else
-
-	cnt = 1;
-#if LONG_MAX > 0x7FFFFFFFUL /* 64bits */
-	if (a & 0xFFFFFFFF00000000UL) {
-		a >>= 32;
-		cnt += 32;
-	}
-#endif
-	if (a & 0XFFFF0000U) {
-		a >>= 16;
-		cnt += 16;
-	}
-	if (a & 0XFF00) {
-		a >>= 8;
-		cnt += 8;
-	}
-	if (a & 0xf0) {
-		a >>= 4;
-		cnt += 4;
-	}
-	if (a & 0xc) {
-		a >>= 2;
-		cnt += 2;
-	}
-	if (a & 0x2) {
-		cnt += 1;
-	}
-#endif /* x86_64 */
-
-	return cnt;
-}
-
-/* Build a word with the <bits> lower bits set (reverse of my_popcountl) */
-static inline unsigned long nbits(int bits)
-{
-	if (--bits < 0)
-		return 0;
-	else
-		return (2UL << bits) - 1;
-}
-
-/* Turns 64-bit value <a> from host byte order to network byte order.
- * The principle consists in letting the compiler detect we're playing
- * with a union and simplify most or all operations. The asm-optimized
- * htonl() version involving bswap (x86) / rev (arm) / other is a single
- * operation on little endian, or a NOP on big-endian. In both cases,
- * this lets the compiler "see" that we're rebuilding a 64-bit word from
- * two 32-bit quantities that fit into a 32-bit register. In big endian,
- * the whole code is optimized out. In little endian, with a decent compiler,
- * a few bswap and 2 shifts are left, which is the minimum acceptable.
- */
-static inline unsigned long long my_htonll(unsigned long long a)
-{
-#if defined(__x86_64__)
-	__asm__ volatile("bswapq %0" : "=r"(a) : "0"(a));
-	return a;
-#else
-	union {
-		struct {
-			unsigned int w1;
-			unsigned int w2;
-		} by32;
-		unsigned long long by64;
-	} w = { .by64 = a };
-	return ((unsigned long long)htonl(w.by32.w1) << 32) | htonl(w.by32.w2);
-#endif
-}
-
-/* Turns 64-bit value <a> from network byte order to host byte order. */
-static inline unsigned long long my_ntohll(unsigned long long a)
-{
-	return my_htonll(a);
-}
-
-/* sets bit <bit> into map <map>, which must be long-aligned */
-static inline void ha_bit_set(unsigned long bit, long *map)
-{
-	map[bit / (8 * sizeof(*map))] |= 1UL << (bit & (8 * sizeof(*map) - 1));
-}
-
-/* clears bit <bit> from map <map>, which must be long-aligned */
-static inline void ha_bit_clr(unsigned long bit, long *map)
-{
-	map[bit / (8 * sizeof(*map))] &= ~(1UL << (bit & (8 * sizeof(*map) - 1)));
-}
-
-/* flips bit <bit> from map <map>, which must be long-aligned */
-static inline void ha_bit_flip(unsigned long bit, long *map)
-{
-	map[bit / (8 * sizeof(*map))] ^= 1UL << (bit & (8 * sizeof(*map) - 1));
-}
-
-/* returns non-zero if bit <bit> from map <map> is set, otherwise 0 */
-static inline int ha_bit_test(unsigned long bit, const long *map)
-{
-	return !!(map[bit / (8 * sizeof(*map))] & 1UL << (bit & (8 * sizeof(*map) - 1)));
-}
-
-/* hash a 32-bit integer to another 32-bit integer. This code may be large when
- * inlined, use full_hash() instead.
- */
-static inline unsigned int __full_hash(unsigned int a)
-{
-	/* This function is one of Bob Jenkins' full avalanche hashing
-	 * functions, which when provides quite a good distribution for little
-	 * input variations. The result is quite suited to fit over a 32-bit
-	 * space with enough variations so that a randomly picked number falls
-	 * equally before any server position.
-	 * Check http://burtleburtle.net/bob/hash/integer.html for more info.
-	 */
-	a = (a+0x7ed55d16) + (a<<12);
-	a = (a^0xc761c23c) ^ (a>>19);
-	a = (a+0x165667b1) + (a<<5);
-	a = (a+0xd3a2646c) ^ (a<<9);
-	a = (a+0xfd7046c5) + (a<<3);
-	a = (a^0xb55a4f09) ^ (a>>16);
-
-	/* ensure values are better spread all around the tree by multiplying
-	 * by a large prime close to 3/4 of the tree.
-	 */
-	return a * 3221225473U;
-}
-
-/*
- * Return integer equivalent of character <c> for a hex digit (0-9, a-f, A-F),
- * otherwise -1. This compact form helps gcc produce efficient code.
- */
-static inline int hex2i(int c)
-{
-	if ((unsigned char)(c -= '0') > 9) {
-		if ((unsigned char)(c -= 'A' - '0') > 5 &&
-			      (unsigned char)(c -= 'a' - 'A') > 5)
-			c = -11;
-		c += 10;
-	}
-	return c;
-}
-
-/* This one is 6 times faster than strtoul() on athlon, but does
- * no check at all.
- */
-static inline unsigned int __str2ui(const char *s)
-{
-	unsigned int i = 0;
-	while (*s) {
-		i = i * 10 - '0';
-		i += (unsigned char)*s++;
-	}
-	return i;
-}
-
-/* This one is 5 times faster than strtoul() on athlon with checks.
- * It returns the value of the number composed of all valid digits read.
- */
-static inline unsigned int __str2uic(const char *s)
-{
-	unsigned int i = 0;
-	unsigned int j;
-
-	while (1) {
-		j = (*s++) - '0';
-		if (j > 9)
-			break;
-		i *= 10;
-		i += j;
-	}
-	return i;
-}
-
-/* This one is 28 times faster than strtoul() on athlon, but does
- * no check at all!
- */
-static inline unsigned int __strl2ui(const char *s, int len)
-{
-	unsigned int i = 0;
-
-	while (len-- > 0) {
-		i = i * 10 - '0';
-		i += (unsigned char)*s++;
-	}
-	return i;
-}
-
-/* This one is 7 times faster than strtoul() on athlon with checks.
- * It returns the value of the number composed of all valid digits read.
- */
-static inline unsigned int __strl2uic(const char *s, int len)
-{
-	unsigned int i = 0;
-	unsigned int j, k;
-
-	while (len-- > 0) {
-		j = (*s++) - '0';
-		k = i * 10;
-		if (j > 9)
-			break;
-		i = k + j;
-	}
-	return i;
-}
-
-/* This function reads an unsigned integer from the string pointed to by <s>
- * and returns it. The <s> pointer is adjusted to point to the first unread
- * char. The function automatically stops at <end>.
- */
-static inline unsigned int __read_uint(const char **s, const char *end)
-{
-	const char *ptr = *s;
-	unsigned int i = 0;
-	unsigned int j, k;
-
-	while (ptr < end) {
-		j = *ptr - '0';
-		k = i * 10;
-		if (j > 9)
-			break;
-		i = k + j;
-		ptr++;
-	}
-	*s = ptr;
-	return i;
-}
-
-/* returns the number of bytes needed to encode <v> as a varint. Be careful, use
- * it only with constants as it generates a large code (typ. 180 bytes). Use the
- * varint_bytes() version instead in case of doubt.
- */
-static inline int __varint_bytes(uint64_t v)
-{
-	switch (v) {
-	case 0x0000000000000000 ... 0x00000000000000ef: return 1;
-	case 0x00000000000000f0 ... 0x00000000000008ef: return 2;
-	case 0x00000000000008f0 ... 0x00000000000408ef: return 3;
-	case 0x00000000000408f0 ... 0x00000000020408ef: return 4;
-	case 0x00000000020408f0 ... 0x00000001020408ef: return 5;
-	case 0x00000001020408f0 ... 0x00000081020408ef: return 6;
-	case 0x00000081020408f0 ... 0x00004081020408ef: return 7;
-	case 0x00004081020408f0 ... 0x00204081020408ef: return 8;
-	case 0x00204081020408f0 ... 0x10204081020408ef: return 9;
-	default: return 10;
-	}
-}
-
-/* Encode the integer <i> into a varint (variable-length integer). The encoded
- * value is copied in <*buf>. Here is the encoding format:
- *
- *        0 <= X < 240        : 1 byte  (7.875 bits)  [ XXXX XXXX ]
- *      240 <= X < 2288       : 2 bytes (11 bits)     [ 1111 XXXX ] [ 0XXX XXXX ]
- *     2288 <= X < 264432     : 3 bytes (18 bits)     [ 1111 XXXX ] [ 1XXX XXXX ]   [ 0XXX XXXX ]
- *   264432 <= X < 33818864   : 4 bytes (25 bits)     [ 1111 XXXX ] [ 1XXX XXXX ]*2 [ 0XXX XXXX ]
- * 33818864 <= X < 4328786160 : 5 bytes (32 bits)     [ 1111 XXXX ] [ 1XXX XXXX ]*3 [ 0XXX XXXX ]
- * ...
- *
- * On success, it returns the number of written bytes and <*buf> is moved after
- * the encoded value. Otherwise, it returns -1. */
-static inline int encode_varint(uint64_t i, char **buf, char *end)
-{
-	unsigned char *p = (unsigned char *)*buf;
-	int r;
-
-	if (p >= (unsigned char *)end)
-		return -1;
-
-	if (i < 240) {
-		*p++ = i;
-		*buf = (char *)p;
-		return 1;
-	}
-
-	*p++ = (unsigned char)i | 240;
-	i = (i - 240) >> 4;
-	while (i >= 128) {
-		if (p >= (unsigned char *)end)
-			return -1;
-		*p++ = (unsigned char)i | 128;
-		i = (i - 128) >> 7;
-	}
-
-	if (p >= (unsigned char *)end)
-		return -1;
-	*p++ = (unsigned char)i;
-
-	r    = ((char *)p - *buf);
-	*buf = (char *)p;
-	return r;
-}
-
-/* Decode a varint from <*buf> and save the decoded value in <*i>. See
- * 'spoe_encode_varint' for details about varint.
- * On success, it returns the number of read bytes and <*buf> is moved after the
- * varint. Otherwise, it returns -1. */
-static inline int decode_varint(char **buf, char *end, uint64_t *i)
-{
-	unsigned char *p = (unsigned char *)*buf;
-	int r;
-
-	if (p >= (unsigned char *)end)
-		return -1;
-
-	*i = *p++;
-	if (*i < 240) {
-		*buf = (char *)p;
-		return 1;
-	}
-
-	r = 4;
-	do {
-		if (p >= (unsigned char *)end)
-			return -1;
-		*i += (uint64_t)*p << r;
-		r  += 7;
-	} while (*p++ >= 128);
-
-	r    = ((char *)p - *buf);
-	*buf = (char *)p;
-	return r;
-}
-
-#endif /* _HAPROXY_INTOPS_H */
-
-/*
- * Local variables:
- *  c-indent-level: 8
- *  c-basic-offset: 8
- * End:
- */
diff --git a/contrib/mod_defender/include/haproxy/list-t.h b/contrib/mod_defender/include/haproxy/list-t.h
deleted file mode 100644
index dd8493e..0000000
--- a/contrib/mod_defender/include/haproxy/list-t.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * include/haproxy/list-t.h
- * Circular list manipulation types definitions
- *
- * Copyright (C) 2002-2020 Willy Tarreau - w@1wt.eu
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _HAPROXY_LIST_T_H
-#define _HAPROXY_LIST_T_H
-
-
-/* these are circular or bidirectionnal lists only. Each list pointer points to
- * another list pointer in a structure, and not the structure itself. The
- * pointer to the next element MUST be the first one so that the list is easily
- * cast as a single linked list or pointer.
- */
-struct list {
-    struct list *n;	/* next */
-    struct list *p;	/* prev */
-};
-
-/* This is similar to struct list, but we want to be sure the compiler will
- * yell at you if you use macroes for one when you're using the other. You have
- * to expicitely cast if that's really what you want to do.
- */
-struct mt_list {
-    struct mt_list *next;
-    struct mt_list *prev;
-};
-
-
-/* a back-ref is a pointer to a target list entry. It is used to detect when an
- * element being deleted is currently being tracked by another user. The best
- * example is a user dumping the session table. The table does not fit in the
- * output buffer so we have to set a mark on a session and go on later. But if
- * that marked session gets deleted, we don't want the user's pointer to go in
- * the wild. So we can simply link this user's request to the list of this
- * session's users, and put a pointer to the list element in ref, that will be
- * used as the mark for next iteration.
- */
-struct bref {
-	struct list users;
-	struct list *ref; /* pointer to the target's list entry */
-};
-
-/* a word list is a generic list with a pointer to a string in each element. */
-struct wordlist {
-	struct list list;
-	char *s;
-};
-
-/* this is the same as above with an additional pointer to a condition. */
-struct cond_wordlist {
-	struct list list;
-	void *cond;
-	char *s;
-};
-
-#endif /* _HAPROXY_LIST_T_H */
diff --git a/contrib/mod_defender/include/haproxy/list.h b/contrib/mod_defender/include/haproxy/list.h
deleted file mode 100644
index cbff73f..0000000
--- a/contrib/mod_defender/include/haproxy/list.h
+++ /dev/null
@@ -1,804 +0,0 @@
-/*
- * include/haproxy/list.h
- * Circular list manipulation macros and functions.
- *
- * Copyright (C) 2002-2020 Willy Tarreau - w@1wt.eu
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _HAPROXY_LIST_H
-#define _HAPROXY_LIST_H
-
-#include <haproxy/api.h>
-
-/* First undefine some macros which happen to also be defined on OpenBSD,
- * in sys/queue.h, used by sys/event.h
- */
-#undef LIST_HEAD
-#undef LIST_INIT
-#undef LIST_NEXT
-
-/* ILH = Initialized List Head : used to prevent gcc from moving an empty
- * list to BSS. Some older version tend to trim all the array and cause
- * corruption.
- */
-#define ILH		{ .n = (struct list *)1, .p = (struct list *)2 }
-
-#define LIST_HEAD(a)	((void *)(&(a)))
-
-#define LIST_INIT(l) ((l)->n = (l)->p = (l))
-
-#define LIST_HEAD_INIT(l) { &l, &l }
-
-/* adds an element at the beginning of a list ; returns the element */
-#define LIST_INSERT(lh, el) ({ (el)->n = (lh)->n; (el)->n->p = (lh)->n = (el); (el)->p = (lh); (el); })
-
-/* adds an element at the end of a list ; returns the element */
-#define LIST_APPEND(lh, el) ({ (el)->p = (lh)->p; (el)->p->n = (lh)->p = (el); (el)->n = (lh); (el); })
-
-/* adds the contents of a list <old> at the beginning of another list <new>. The old list head remains untouched. */
-#define LIST_SPLICE(new, old) do {				     \
-		if (!LIST_ISEMPTY(old)) {			     \
-			(old)->p->n = (new)->n; (old)->n->p = (new); \
-			(new)->n->p = (old)->p; (new)->n = (old)->n; \
-		}						     \
-	} while (0)
-
-/* adds the contents of a list whose first element is <old> and last one is
- * <old->prev> at the end of another list <new>. The old list DOES NOT have
- * any head here.
- */
-#define LIST_SPLICE_END_DETACHED(new, old) do {              \
-		typeof(new) __t;                             \
-		(new)->p->n = (old);                         \
-		(old)->p->n = (new);                         \
-		__t = (old)->p;                              \
-		(old)->p = (new)->p;                         \
-		(new)->p = __t;                              \
-	} while (0)
-
-/* removes an element from a list and returns it */
-#define LIST_DELETE(el) ({ typeof(el) __ret = (el); (el)->n->p = (el)->p; (el)->p->n = (el)->n; (__ret); })
-
-/* removes an element from a list, initializes it and returns it.
- * This is faster than LIST_DELETE+LIST_INIT as we avoid reloading the pointers.
- */
-#define LIST_DEL_INIT(el) ({ \
-	typeof(el) __ret = (el);                        \
-	typeof(__ret->n) __n = __ret->n;                \
-	typeof(__ret->p) __p = __ret->p;                \
-	__n->p = __p; __p->n = __n;                     \
-	__ret->n = __ret->p = __ret;                    \
-	__ret;                                          \
-})
-
-/* returns a pointer of type <pt> to a structure containing a list head called
- * <el> at address <lh>. Note that <lh> can be the result of a function or macro
- * since it's used only once.
- * Example: LIST_ELEM(cur_node->args.next, struct node *, args)
- */
-#define LIST_ELEM(lh, pt, el) ((pt)(((const char *)(lh)) - ((size_t)&((pt)NULL)->el)))
-
-/* checks if the list head <lh> is empty or not */
-#define LIST_ISEMPTY(lh) ((lh)->n == (lh))
-
-/* checks if the list element <el> was added to a list or not. This only
- * works when detached elements are reinitialized (using LIST_DEL_INIT)
- */
-#define LIST_INLIST(el) ((el)->n != (el))
-
-/* returns a pointer of type <pt> to a structure following the element
- * which contains list head <lh>, which is known as element <el> in
- * struct pt.
- * Example: LIST_NEXT(args, struct node *, list)
- */
-#define LIST_NEXT(lh, pt, el) (LIST_ELEM((lh)->n, pt, el))
-
-
-/* returns a pointer of type <pt> to a structure preceding the element
- * which contains list head <lh>, which is known as element <el> in
- * struct pt.
- */
-#undef LIST_PREV
-#define LIST_PREV(lh, pt, el) (LIST_ELEM((lh)->p, pt, el))
-
-/*
- * Simpler FOREACH_ITEM macro inspired from Linux sources.
- * Iterates <item> through a list of items of type "typeof(*item)" which are
- * linked via a "struct list" member named <member>. A pointer to the head of
- * the list is passed in <list_head>. No temporary variable is needed. Note
- * that <item> must not be modified during the loop.
- * Example: list_for_each_entry(cur_acl, known_acl, list) { ... };
- */ 
-#define list_for_each_entry(item, list_head, member)                      \
-	for (item = LIST_ELEM((list_head)->n, typeof(item), member);     \
-	     &item->member != (list_head);                                \
-	     item = LIST_ELEM(item->member.n, typeof(item), member))
-
-/*
- * Same as list_for_each_entry but starting from current point
- * Iterates <item> through the list starting from <item>
- * It's basically the same macro but without initializing item to the head of
- * the list.
- */
-#define list_for_each_entry_from(item, list_head, member) \
-	for ( ; &item->member != (list_head); \
-	     item = LIST_ELEM(item->member.n, typeof(item), member))
-
-/*
- * Simpler FOREACH_ITEM_SAFE macro inspired from Linux sources.
- * Iterates <item> through a list of items of type "typeof(*item)" which are
- * linked via a "struct list" member named <member>. A pointer to the head of
- * the list is passed in <list_head>. A temporary variable <back> of same type
- * as <item> is needed so that <item> may safely be deleted if needed.
- * Example: list_for_each_entry_safe(cur_acl, tmp, known_acl, list) { ... };
- */ 
-#define list_for_each_entry_safe(item, back, list_head, member)           \
-	for (item = LIST_ELEM((list_head)->n, typeof(item), member),     \
-	     back = LIST_ELEM(item->member.n, typeof(item), member);     \
-	     &item->member != (list_head);                                \
-	     item = back, back = LIST_ELEM(back->member.n, typeof(back), member))
-
-
-/*
- * Same as list_for_each_entry_safe but starting from current point
- * Iterates <item> through the list starting from <item>
- * It's basically the same macro but without initializing item to the head of
- * the list.
- */
-#define list_for_each_entry_safe_from(item, back, list_head, member) \
-	for (back = LIST_ELEM(item->member.n, typeof(item), member);     \
-	     &item->member != (list_head);                                \
-	     item = back, back = LIST_ELEM(back->member.n, typeof(back), member))
-
-/*
- * Iterate backwards <item> through a list of items of type "typeof(*item)"
- * which are linked via a "struct list" member named <member>. A pointer to
- * the head of the list is passed in <list_head>. No temporary variable is
- * needed. Note that <item> must not be modified during the loop.
- * Example: list_for_each_entry_rev(cur_acl, known_acl, list) { ... };
- */
-#define list_for_each_entry_rev(item, list_head, member)                 \
-	for (item = LIST_ELEM((list_head)->p, typeof(item), member);     \
-	     &item->member != (list_head);                               \
-	     item = LIST_ELEM(item->member.p, typeof(item), member))
-
-/*
- * Same as list_for_each_entry_rev but starting from current point
- * Iterate backwards <item> through the list starting from <item>
- * It's basically the same macro but without initializing item to the head of
- * the list.
- */
-#define list_for_each_entry_from_rev(item, list_head, member) \
-	for ( ; &item->member != (list_head); \
-	     item = LIST_ELEM(item->member.p, typeof(item), member))
-
-/*
- * Iterate backwards <item> through a list of items of type "typeof(*item)"
- * which are linked via a "struct list" member named <member>. A pointer to
- * the head of the list is passed in <list_head>. A temporary variable <back>
- * of same type as <item> is needed so that <item> may safely be deleted
- * if needed.
- * Example: list_for_each_entry_safe_rev(cur_acl, tmp, known_acl, list) { ... };
- */
-#define list_for_each_entry_safe_rev(item, back, list_head, member)      \
-	for (item = LIST_ELEM((list_head)->p, typeof(item), member),     \
-	     back = LIST_ELEM(item->member.p, typeof(item), member);     \
-	     &item->member != (list_head);                               \
-	     item = back, back = LIST_ELEM(back->member.p, typeof(back), member))
-
-/*
- * Same as list_for_each_entry_safe_rev but starting from current point
- * Iterate backwards <item> through the list starting from <item>
- * It's basically the same macro but without initializing item to the head of
- * the list.
- */
-#define list_for_each_entry_safe_from_rev(item, back, list_head, member) \
-	for (back = LIST_ELEM(item->member.p, typeof(item), member);     \
-	     &item->member != (list_head);                               \
-	     item = back, back = LIST_ELEM(back->member.p, typeof(back), member))
-
-
-/*
- * Locked version of list manipulation macros.
- * It is OK to use those concurrently from multiple threads, as long as the
- * list is only used with the locked variants.
- */
-#define MT_LIST_BUSY ((struct mt_list *)1)
-
-/*
- * Add an item at the beginning of a list.
- * Returns 1 if we added the item, 0 otherwise (because it was already in a
- * list).
- */
-#define MT_LIST_TRY_INSERT(_lh, _el)                                              \
-     ({                                                                    \
-        int _ret = 0;                                                      \
-	struct mt_list *lh = (_lh), *el = (_el);                           \
-	for (;;__ha_cpu_relax()) {                                         \
-		struct mt_list *n, *n2;                                    \
-		struct mt_list *p, *p2;                                    \
-		n = _HA_ATOMIC_XCHG(&(lh)->next, MT_LIST_BUSY);            \
-		if (n == MT_LIST_BUSY)                                     \
-		        continue;                                          \
-		p = _HA_ATOMIC_XCHG(&n->prev, MT_LIST_BUSY);               \
-		if (p == MT_LIST_BUSY) {                                   \
-			(lh)->next = n;                                    \
-			__ha_barrier_store();                              \
-			continue;                                          \
-		}                                                          \
-		n2 = _HA_ATOMIC_XCHG(&el->next, MT_LIST_BUSY);             \
-		if (n2 != el) { /* element already linked */               \
-			if (n2 != MT_LIST_BUSY)                            \
-				el->next = n2;                             \
-			n->prev = p;                                       \
-			__ha_barrier_store();                              \
-			lh->next = n;                                      \
-			__ha_barrier_store();                              \
-			if (n2 == MT_LIST_BUSY)                            \
-				continue;                                  \
-			break;                                             \
-		}                                                          \
-		p2 = _HA_ATOMIC_XCHG(&el->prev, MT_LIST_BUSY);             \
-		if (p2 != el) {                                            \
-			if (p2 != MT_LIST_BUSY)                            \
-				el->prev = p2;                             \
-			n->prev = p;                                       \
-			el->next = el;                                     \
-			__ha_barrier_store();                              \
-			lh->next = n;                                      \
-			__ha_barrier_store();                              \
-			if (p2 == MT_LIST_BUSY)                            \
-				continue;                                  \
-			break;                                             \
-		}                                                          \
-		(el)->next = n;                                            \
-		(el)->prev = p;                                            \
-		__ha_barrier_store();                                      \
-		n->prev = (el);                                            \
-		__ha_barrier_store();                                      \
-		p->next = (el);                                            \
-		__ha_barrier_store();                                      \
-		_ret = 1;                                                  \
-		break;                                                     \
-	}                                                                  \
-	(_ret);                                                            \
-     })
-
-/*
- * Add an item at the end of a list.
- * Returns 1 if we added the item, 0 otherwise (because it was already in a
- * list).
- */
-#define MT_LIST_TRY_APPEND(_lh, _el)                                             \
-    ({                                                                     \
-	int _ret = 0;                                                      \
-	struct mt_list *lh = (_lh), *el = (_el);                           \
-	for (;;__ha_cpu_relax()) {                                         \
-		struct mt_list *n, *n2;                                    \
-		struct mt_list *p, *p2;                                    \
-		p = _HA_ATOMIC_XCHG(&(lh)->prev, MT_LIST_BUSY);            \
-		if (p == MT_LIST_BUSY)                                     \
-		        continue;                                          \
-		n = _HA_ATOMIC_XCHG(&p->next, MT_LIST_BUSY);               \
-		if (n == MT_LIST_BUSY) {                                   \
-			(lh)->prev = p;                                    \
-			__ha_barrier_store();                              \
-			continue;                                          \
-		}                                                          \
-		p2 = _HA_ATOMIC_XCHG(&el->prev, MT_LIST_BUSY);             \
-		if (p2 != el) {                                            \
-			if (p2 != MT_LIST_BUSY)                            \
-				el->prev = p2;                             \
-			p->next = n;                                       \
-			__ha_barrier_store();                              \
-			lh->prev = p;                                      \
-			__ha_barrier_store();                              \
-			if (p2 == MT_LIST_BUSY)                            \
-				continue;                                  \
-			break;                                             \
-		}                                                          \
-		n2 = _HA_ATOMIC_XCHG(&el->next, MT_LIST_BUSY);             \
-		if (n2 != el) { /* element already linked */               \
-			if (n2 != MT_LIST_BUSY)                            \
-				el->next = n2;                             \
-			p->next = n;                                       \
-			el->prev = el;                                     \
-			__ha_barrier_store();                              \
-			lh->prev = p;                                      \
-			__ha_barrier_store();                              \
-			if (n2 == MT_LIST_BUSY)                            \
-				continue;                                  \
-			break;                                             \
-		}                                                          \
-		(el)->next = n;                                            \
-		(el)->prev = p;                                            \
-		__ha_barrier_store();                                      \
-		p->next = (el);                                            \
-		__ha_barrier_store();                                      \
-		n->prev = (el);                                            \
-		__ha_barrier_store();                                      \
-		_ret = 1;                                                  \
-		break;                                                     \
-	}                                                                  \
-	(_ret);                                                            \
-    })
-
-/*
- * Add an item at the beginning of a list.
- * It is assumed the element can't already be in a list, so it isn't checked.
- */
-#define MT_LIST_INSERT(_lh, _el)                                              \
-     ({                                                                    \
-        int _ret = 0;                                                      \
-	struct mt_list *lh = (_lh), *el = (_el);                           \
-	for (;;__ha_cpu_relax()) {                                         \
-		struct mt_list *n;                                         \
-		struct mt_list *p;                                         \
-		n = _HA_ATOMIC_XCHG(&(lh)->next, MT_LIST_BUSY);            \
-		if (n == MT_LIST_BUSY)                                     \
-		        continue;                                          \
-		p = _HA_ATOMIC_XCHG(&n->prev, MT_LIST_BUSY);               \
-		if (p == MT_LIST_BUSY) {                                   \
-			(lh)->next = n;                                    \
-			__ha_barrier_store();                              \
-			continue;                                          \
-		}                                                          \
-		(el)->next = n;                                            \
-		(el)->prev = p;                                            \
-		__ha_barrier_store();                                      \
-		n->prev = (el);                                            \
-		__ha_barrier_store();                                      \
-		p->next = (el);                                            \
-		__ha_barrier_store();                                      \
-		_ret = 1;                                                  \
-		break;                                                     \
-	}                                                                  \
-	(_ret);                                                            \
-     })
-
-/*
- * Add an item at the end of a list.
- * It is assumed the element can't already be in a list, so it isn't checked
- */
-#define MT_LIST_APPEND(_lh, _el)                                     \
-    ({                                                                     \
-	int _ret = 0;                                                      \
-	struct mt_list *lh = (_lh), *el = (_el);                           \
-	for (;;__ha_cpu_relax()) {                                         \
-		struct mt_list *n;                                         \
-		struct mt_list *p;                                         \
-		p = _HA_ATOMIC_XCHG(&(lh)->prev, MT_LIST_BUSY);            \
-		if (p == MT_LIST_BUSY)                                     \
-		        continue;                                          \
-		n = _HA_ATOMIC_XCHG(&p->next, MT_LIST_BUSY);               \
-		if (n == MT_LIST_BUSY) {                                   \
-			(lh)->prev = p;                                    \
-			__ha_barrier_store();                              \
-			continue;                                          \
-		}                                                          \
-		(el)->next = n;                                            \
-		(el)->prev = p;                                            \
-		__ha_barrier_store();                                      \
-		p->next = (el);                                            \
-		__ha_barrier_store();                                      \
-		n->prev = (el);                                            \
-		__ha_barrier_store();                                      \
-		_ret = 1;                                                  \
-		break;                                                     \
-	}                                                                  \
-	(_ret);                                                            \
-    })
-
-/*
- * Detach a list from its head. A pointer to the first element is returned
- * and the list is closed. If the list was empty, NULL is returned. This may
- * exclusively be used with lists modified by MT_LIST_TRY_INSERT/MT_LIST_TRY_APPEND. This
- * is incompatible with MT_LIST_DELETE run concurrently.
- * If there's at least one element, the next of the last element will always
- * be NULL.
- */
-#define MT_LIST_BEHEAD(_lh) ({                                      \
-        struct mt_list *lh = (_lh);                                 \
-	struct mt_list *_n;                                         \
-	struct mt_list *_p;                                         \
-	for (;;__ha_cpu_relax()) {                                  \
-		_p = _HA_ATOMIC_XCHG(&(lh)->prev, MT_LIST_BUSY);    \
-		if (_p == MT_LIST_BUSY)                             \
-		        continue;                                   \
-		if (_p == (lh)) {                                   \
-			(lh)->prev = _p;                            \
-			__ha_barrier_store();                       \
-			_n = NULL;                                  \
-			break;                                      \
-		}                                                   \
-		_n = _HA_ATOMIC_XCHG(&(lh)->next, MT_LIST_BUSY);    \
-		if (_n == MT_LIST_BUSY) {                           \
-			(lh)->prev = _p;                            \
-			__ha_barrier_store();                       \
-			continue;                                   \
-		}                                                   \
-		if (_n == (lh)) {                                   \
-			(lh)->next = _n;                            \
-			(lh)->prev = _p;                            \
-			__ha_barrier_store();                       \
-			_n = NULL;                                  \
-			break;                                      \
-		}                                                   \
-		(lh)->next = (lh);                                  \
-		(lh)->prev = (lh);                                  \
-		__ha_barrier_store();                               \
-		_n->prev = _p;                                      \
-		__ha_barrier_store();                               \
-		_p->next = NULL;                                    \
-		__ha_barrier_store();                               \
-		break;                                              \
-	}                                                           \
-	(_n);                                                       \
-})
-
-
-/* Remove an item from a list.
- * Returns 1 if we removed the item, 0 otherwise (because it was in no list).
- */
-#define MT_LIST_DELETE(_el)                                                   \
-    ({                                                                     \
-        int _ret = 0;                                                      \
-	struct mt_list *el = (_el);                                        \
-	for (;;__ha_cpu_relax()) {                                         \
-		struct mt_list *n, *n2;                                    \
-		struct mt_list *p, *p2 = NULL;                             \
-		n = _HA_ATOMIC_XCHG(&(el)->next, MT_LIST_BUSY);            \
-		if (n == MT_LIST_BUSY)                                     \
-		        continue;                                          \
-		p = _HA_ATOMIC_XCHG(&(el)->prev, MT_LIST_BUSY);            \
-		if (p == MT_LIST_BUSY) {                                   \
-			(el)->next = n;                                    \
-			__ha_barrier_store();                              \
-			continue;                                          \
-		}                                                          \
-		if (p != (el)) {                                           \
-		        p2 = _HA_ATOMIC_XCHG(&p->next, MT_LIST_BUSY);      \
-		        if (p2 == MT_LIST_BUSY) {                          \
-		                (el)->prev = p;                            \
-				(el)->next = n;                            \
-				__ha_barrier_store();                      \
-				continue;                                  \
-			}                                                  \
-		}                                                          \
-		if (n != (el)) {                                           \
-		        n2 = _HA_ATOMIC_XCHG(&n->prev, MT_LIST_BUSY);      \
-			if (n2 == MT_LIST_BUSY) {                          \
-				if (p2 != NULL)                            \
-					p->next = p2;                      \
-				(el)->prev = p;                            \
-				(el)->next = n;                            \
-				__ha_barrier_store();                      \
-				continue;                                  \
-			}                                                  \
-		}                                                          \
-		n->prev = p;                                               \
-		p->next = n;                                               \
-		if (p != (el) && n != (el))                                \
-			_ret = 1;                                          \
-		__ha_barrier_store();                                      \
-		(el)->prev = (el);                                         \
-		(el)->next = (el);                                         \
-		__ha_barrier_store();                                      \
-		break;                                                     \
-	}                                                                  \
-	(_ret);                                                            \
-    })
-
-
-/* Remove the first element from the list, and return it */
-#define MT_LIST_POP(_lh, pt, el)                                           \
-	({                                                                 \
-		 void *_ret;                                               \
-		 struct mt_list *lh = (_lh);                               \
-		 for (;;__ha_cpu_relax()) {                                \
-			 struct mt_list *n, *n2;                           \
-			 struct mt_list *p, *p2;                           \
-			 n = _HA_ATOMIC_XCHG(&(lh)->next, MT_LIST_BUSY);   \
-			 if (n == MT_LIST_BUSY)                            \
-			         continue;                                 \
-			 if (n == (lh)) {                                  \
-				 (lh)->next = lh;                          \
-				 __ha_barrier_store();                     \
-				 _ret = NULL;                              \
-				 break;                                    \
-			 }                                                 \
-			 p = _HA_ATOMIC_XCHG(&n->prev, MT_LIST_BUSY);      \
-			 if (p == MT_LIST_BUSY) {                          \
-				 (lh)->next = n;                           \
-				 __ha_barrier_store();                     \
-				 continue;                                 \
-			 }                                                 \
-			 n2 = _HA_ATOMIC_XCHG(&n->next, MT_LIST_BUSY);     \
-			 if (n2 == MT_LIST_BUSY) {                         \
-				 n->prev = p;                              \
-				 __ha_barrier_store();                     \
-				 (lh)->next = n;                           \
-				 __ha_barrier_store();                     \
-				 continue;                                 \
-			 }                                                 \
-			 p2 = _HA_ATOMIC_XCHG(&n2->prev, MT_LIST_BUSY);    \
-			 if (p2 == MT_LIST_BUSY) {                         \
-				 n->next = n2;                             \
-				 n->prev = p;                              \
-				 __ha_barrier_store();                     \
-				 (lh)->next = n;                           \
-				 __ha_barrier_store();                     \
-				 continue;                                 \
-			 }                                                 \
-			 (lh)->next = n2;                                  \
-			 (n2)->prev = (lh);                                \
-			 __ha_barrier_store();                             \
-			 (n)->prev = (n);                                  \
-			 (n)->next = (n);	                           \
-			 __ha_barrier_store();                             \
-			 _ret = MT_LIST_ELEM(n, pt, el);                   \
-			 break;                                            \
-		 }                                                         \
-		 (_ret);                                                   \
-	 })
-
-#define MT_LIST_HEAD(a)	((void *)(&(a)))
-
-#define MT_LIST_INIT(l) ((l)->next = (l)->prev = (l))
-
-#define MT_LIST_HEAD_INIT(l) { &l, &l }
-/* returns a pointer of type <pt> to a structure containing a list head called
- * <el> at address <lh>. Note that <lh> can be the result of a function or macro
- * since it's used only once.
- * Example: MT_LIST_ELEM(cur_node->args.next, struct node *, args)
- */
-#define MT_LIST_ELEM(lh, pt, el) ((pt)(((const char *)(lh)) - ((size_t)&((pt)NULL)->el)))
-
-/* checks if the list head <lh> is empty or not */
-#define MT_LIST_ISEMPTY(lh) ((lh)->next == (lh))
-
-/* returns a pointer of type <pt> to a structure following the element
- * which contains list head <lh>, which is known as element <el> in
- * struct pt.
- * Example: MT_LIST_NEXT(args, struct node *, list)
- */
-#define MT_LIST_NEXT(lh, pt, el) (MT_LIST_ELEM((lh)->next, pt, el))
-
-
-/* returns a pointer of type <pt> to a structure preceding the element
- * which contains list head <lh>, which is known as element <el> in
- * struct pt.
- */
-#undef MT_LIST_PREV
-#define MT_LIST_PREV(lh, pt, el) (MT_LIST_ELEM((lh)->prev, pt, el))
-
-/* checks if the list element <el> was added to a list or not. This only
- * works when detached elements are reinitialized (using LIST_DEL_INIT)
- */
-#define MT_LIST_INLIST(el) ((el)->next != (el))
-
-/* Lock an element in the list, to be sure it won't be removed.
- * It needs to be synchronized somehow to be sure it's not removed
- * from the list in the meanwhile.
- * This returns a struct mt_list, that will be needed at unlock time.
- */
-#define MT_LIST_LOCK_ELT(_el)                                              \
-	({                                                                 \
-		struct mt_list ret;                                        \
-		struct mt_liet *el = (_el);                                \
-		for (;;__ha_cpu_relax()) {                                 \
-			struct mt_list *n, *n2;                            \
-			struct mt_list *p, *p2 = NULL;                     \
-			n = _HA_ATOMIC_XCHG(&(el)->next, MT_LIST_BUSY);    \
-			if (n == MT_LIST_BUSY)                             \
-			        continue;                                  \
-			p = _HA_ATOMIC_XCHG(&(el)->prev, MT_LIST_BUSY);    \
-			if (p == MT_LIST_BUSY) {                           \
-				(el)->next = n;                            \
-				__ha_barrier_store();                      \
-				continue;                                  \
-			}                                                  \
-			if (p != (el)) {                                   \
-			        p2 = _HA_ATOMIC_XCHG(&p->next, MT_LIST_BUSY);\
-			        if (p2 == MT_LIST_BUSY) {                  \
-			                (el)->prev = p;                    \
-					(el)->next = n;                    \
-					__ha_barrier_store();              \
-					continue;                          \
-				}                                          \
-			}                                                  \
-			if (n != (el)) {                                   \
-			        n2 = _HA_ATOMIC_XCHG(&n->prev, MT_LIST_BUSY);\
-				if (n2 == MT_LIST_BUSY) {                  \
-					if (p2 != NULL)                    \
-						p->next = p2;              \
-					(el)->prev = p;                    \
-					(el)->next = n;                    \
-					__ha_barrier_store();              \
-					continue;                          \
-				}                                          \
-			}                                                  \
-			ret.next = n;                                      \
-			ret.prev = p;                                      \
-			break;                                             \
-		}                                                          \
-		ret;                                                       \
-	})
-
-/* Unlock an element previously locked by MT_LIST_LOCK_ELT. "np" is the
- * struct mt_list returned by MT_LIST_LOCK_ELT().
- */
-#define MT_LIST_UNLOCK_ELT(_el, np)                                        \
-	do {                                                               \
-		struct mt_list *n = (np).next, *p = (np).prev;             \
-		struct mt_list *el = (_el);                                \
-		(el)->next = n;                                            \
-		(el)->prev = p;                                            \
-		if (n != (el))                                             \
-			n->prev = (el);                                    \
-		if (p != (el))                                             \
-			p->next = (el);                                    \
-	} while (0)
-
-/* Internal macroes for the foreach macroes */
-#define _MT_LIST_UNLOCK_NEXT(el, np)                                       \
-	do {                                                               \
-		struct mt_list *n = (np);                                  \
-		(el)->next = n;                                            \
-		if (n != (el))                                             \
-		        n->prev = (el);                                    \
-	} while (0)
-
-/* Internal macroes for the foreach macroes */
-#define _MT_LIST_UNLOCK_PREV(el, np)                                       \
-	do {                                                               \
-		struct mt_list *p = (np);                                  \
-		(el)->prev = p;                                            \
-		if (p != (el))                                             \
-		        p->next = (el);                                    \
-	} while (0)
-
-#define _MT_LIST_LOCK_NEXT(el)                                             \
-	({                                                                 \
-	        struct mt_list *n = NULL;                                  \
-		for (;;__ha_cpu_relax()) {                                 \
-			struct mt_list *n2;                                \
-			n = _HA_ATOMIC_XCHG(&((el)->next), MT_LIST_BUSY);  \
-			if (n == MT_LIST_BUSY)                             \
-			        continue;                                  \
-			if (n != (el)) {                                   \
-			        n2 = _HA_ATOMIC_XCHG(&n->prev, MT_LIST_BUSY);\
-				if (n2 == MT_LIST_BUSY) {                  \
-					(el)->next = n;                    \
-					__ha_barrier_store();              \
-					continue;                          \
-				}                                          \
-			}                                                  \
-			break;                                             \
-		}                                                          \
-		n;                                                         \
-	})
-
-#define _MT_LIST_LOCK_PREV(el)                                             \
-	({                                                                 \
-	        struct mt_list *p = NULL;                                  \
-		for (;;__ha_cpu_relax()) {                                 \
-			struct mt_list *p2;                                \
-			p = _HA_ATOMIC_XCHG(&((el)->prev), MT_LIST_BUSY);  \
-			if (p == MT_LIST_BUSY)                             \
-			        continue;                                  \
-			if (p != (el)) {                                   \
-			        p2 = _HA_ATOMIC_XCHG(&p->next, MT_LIST_BUSY);\
-				if (p2 == MT_LIST_BUSY) {                  \
-					(el)->prev = p;                    \
-					__ha_barrier_store();              \
-					continue;                          \
-				}                                          \
-			}                                                  \
-			break;                                             \
-		}                                                          \
-		p;                                                         \
-	})
-
-#define _MT_LIST_RELINK_DELETED(elt2)                                      \
-    do {                                                                   \
-	    struct mt_list *n = elt2.next, *p = elt2.prev;                 \
-	    ALREADY_CHECKED(p);                                            \
-	    n->prev = p;                                                   \
-	    p->next = n;                                                   \
-    } while (0);
-
-/* Equivalent of MT_LIST_DELETE(), to be used when parsing the list with mt_list_entry_for_each_safe().
- * It should be the element currently parsed (tmpelt1)
- */
-#define MT_LIST_DELETE_SAFE(_el)                                              \
-	do {                                                               \
-		struct mt_list *el = (_el);                                \
-		(el)->prev = (el);                                         \
-		(el)->next = (el);                                         \
-		(_el) = NULL;                                              \
-	} while (0)
-
-/* Safe as MT_LIST_DELETE_SAFE, but it won't reinit the element */
-#define MT_LIST_DELETE_SAFE_NOINIT(_el)                                       \
-	do {                                                               \
-		(_el) = NULL;                                              \
-	} while (0)
-
-/* Simpler FOREACH_ITEM_SAFE macro inspired from Linux sources.
- * Iterates <item> through a list of items of type "typeof(*item)" which are
- * linked via a "struct list" member named <member>. A pointer to the head of
- * the list is passed in <list_head>. A temporary variable <back> of same type
- * as <item> is needed so that <item> may safely be deleted if needed.
- * tmpelt1 is a temporary struct mt_list *, and tmpelt2 is a temporary
- * struct mt_list, used internally, both are needed for MT_LIST_DELETE_SAFE.
- * Example: list_for_each_entry_safe(cur_acl, tmp, known_acl, list, elt1, elt2)
- * { ... };
- * If you want to remove the current element, please use MT_LIST_DELETE_SAFE.
- */
-#define mt_list_for_each_entry_safe(item, list_head, member, tmpelt, tmpelt2)           \
-        for ((tmpelt) = NULL; (tmpelt) != MT_LIST_BUSY; ({                    \
-					if (tmpelt) {                         \
-					if (tmpelt2.prev)                     \
-						MT_LIST_UNLOCK_ELT(tmpelt, tmpelt2);           \
-					else                                  \
-						_MT_LIST_UNLOCK_NEXT(tmpelt, tmpelt2.next); \
-				} else                                        \
-				_MT_LIST_RELINK_DELETED(tmpelt2);             \
-				(tmpelt) = MT_LIST_BUSY;                      \
-				}))                                           \
-	for ((tmpelt) = (list_head), (tmpelt2).prev = NULL, (tmpelt2).next = _MT_LIST_LOCK_NEXT(tmpelt); ({ \
-	              (item) = MT_LIST_ELEM((tmpelt2.next), typeof(item), member);  \
-		      if (&item->member != (list_head)) {                     \
-		                if (tmpelt2.prev != &item->member)            \
-					tmpelt2.next = _MT_LIST_LOCK_NEXT(&item->member); \
-				else \
-					tmpelt2.next = tmpelt;                \
-				if (tmpelt != NULL) {                         \
-					if (tmpelt2.prev)                     \
-						_MT_LIST_UNLOCK_PREV(tmpelt, tmpelt2.prev); \
-					tmpelt2.prev = tmpelt;                \
-				}                                             \
-				(tmpelt) = &item->member;                     \
-			}                                                     \
-	    }),                                                               \
-	     &item->member != (list_head);)
-
-static __inline struct list *mt_list_to_list(struct mt_list *list)
-{
-	union {
-		struct mt_list *mt_list;
-		struct list *list;
-	} mylist;
-
-	mylist.mt_list = list;
-	return mylist.list;
-}
-
-static __inline struct mt_list *list_to_mt_list(struct list *list)
-{
-	union {
-		struct mt_list *mt_list;
-		struct list *list;
-	} mylist;
-
-	mylist.list = list;
-	return mylist.mt_list;
-
-}
-
-#endif /* _HAPROXY_LIST_H */
diff --git a/contrib/mod_defender/include/haproxy/sample-t.h b/contrib/mod_defender/include/haproxy/sample-t.h
deleted file mode 100644
index 7fb9f5e..0000000
--- a/contrib/mod_defender/include/haproxy/sample-t.h
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * include/haproxy/sample-t.h
- * Macros, variables and structures for sample management.
- *
- * Copyright (C) 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
- * Copyright (C) 2012-2013 Willy Tarreau <w@1wt.eu>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _HAPROXY_SAMPLE_T_H
-#define _HAPROXY_SAMPLE_T_H
-
-#include <haproxy/api-t.h>
-#include <haproxy/sample_data-t.h>
-
-/* input and output sample types */
-enum {
-	SMP_T_ANY = 0,   /* any type */
-	SMP_T_BOOL,      /* boolean */
-	SMP_T_SINT,      /* signed 64bits integer type */
-	SMP_T_ADDR,      /* ipv4 or ipv6, only used for input type compatibility */
-	SMP_T_IPV4,      /* ipv4 type */
-	SMP_T_IPV6,      /* ipv6 type */
-	SMP_T_STR,       /* char string type */
-	SMP_T_BIN,       /* buffer type */
-	SMP_T_METH,      /* contain method */
-	SMP_TYPES        /* number of types, must always be last */
-};
-
-/* Sample sources are used to establish a relation between fetch keywords and
- * the location where they're about to be used. They're reserved for internal
- * use and are not meant to be known outside the sample management code.
- */
-enum {
-	SMP_SRC_CONST,  /* constat elements known at configuration time */
-	SMP_SRC_INTRN,  /* internal context-less information */
-	SMP_SRC_LISTN,  /* listener which accepted the connection */
-	SMP_SRC_FTEND,  /* frontend which accepted the connection */
-	SMP_SRC_L4CLI,  /* L4 information about the client */
-	SMP_SRC_L5CLI,  /* fetch uses client information from embryonic session */
-	SMP_SRC_TRACK,  /* fetch involves track counters */
-	SMP_SRC_L6REQ,  /* fetch uses raw information from the request buffer */
-	SMP_SRC_HRQHV,  /* fetch uses volatile information about HTTP request headers (eg: value) */
-	SMP_SRC_HRQHP,  /* fetch uses persistent information about HTTP request headers (eg: meth) */
-	SMP_SRC_HRQBO,  /* fetch uses information about HTTP request body */
-	SMP_SRC_BKEND,  /* fetch uses information about the backend */
-	SMP_SRC_SERVR,  /* fetch uses information about the selected server */
-	SMP_SRC_L4SRV,  /* fetch uses information about the server L4 connection */
-	SMP_SRC_L5SRV,  /* fetch uses information about the server L5 connection */
-	SMP_SRC_L6RES,  /* fetch uses raw information from the response buffer */
-	SMP_SRC_HRSHV,  /* fetch uses volatile information about HTTP response headers (eg: value) */
-	SMP_SRC_HRSHP,  /* fetch uses persistent information about HTTP response headers (eg: status) */
-	SMP_SRC_HRSBO,  /* fetch uses information about HTTP response body */
-	SMP_SRC_RQFIN,  /* final information about request buffer (eg: tot bytes) */
-	SMP_SRC_RSFIN,  /* final information about response buffer (eg: tot bytes) */
-	SMP_SRC_TXFIN,  /* final information about the transaction (eg: #comp rate) */
-	SMP_SRC_SSFIN,  /* final information about the stream (eg: #requests, final flags) */
-	SMP_SRC_ENTRIES /* nothing after this */
-};
-
-/* Sample checkpoints are a list of places where samples may be used. This is
- * an internal enum used only to build SMP_VAL_*.
- */
-enum {
-	SMP_CKP_FE_CON_ACC,  /* FE connection accept rules ("tcp request connection") */
-	SMP_CKP_FE_SES_ACC,  /* FE stream accept rules (to come soon) */
-	SMP_CKP_FE_REQ_CNT,  /* FE request content rules ("tcp request content") */
-	SMP_CKP_FE_HRQ_HDR,  /* FE HTTP request headers (rules, headers, monitor, stats, redirect) */
-	SMP_CKP_FE_HRQ_BDY,  /* FE HTTP request body */
-	SMP_CKP_FE_SET_BCK,  /* FE backend switching rules ("use_backend") */
-	SMP_CKP_BE_REQ_CNT,  /* BE request content rules ("tcp request content") */
-	SMP_CKP_BE_HRQ_HDR,  /* BE HTTP request headers (rules, headers, monitor, stats, redirect) */
-	SMP_CKP_BE_HRQ_BDY,  /* BE HTTP request body */
-	SMP_CKP_BE_SET_SRV,  /* BE server switching rules ("use_server", "balance", "force-persist", "stick", ...) */
-	SMP_CKP_BE_SRV_CON,  /* BE server connect (eg: "source") */
-	SMP_CKP_BE_RES_CNT,  /* BE response content rules ("tcp response content") */
-	SMP_CKP_BE_HRS_HDR,  /* BE HTTP response headers (rules, headers) */
-	SMP_CKP_BE_HRS_BDY,  /* BE HTTP response body (stick-store rules are there) */
-	SMP_CKP_BE_STO_RUL,  /* BE stick-store rules */
-	SMP_CKP_FE_RES_CNT,  /* FE response content rules ("tcp response content") */
-	SMP_CKP_FE_HRS_HDR,  /* FE HTTP response headers (rules, headers) */
-	SMP_CKP_FE_HRS_BDY,  /* FE HTTP response body */
-	SMP_CKP_FE_LOG_END,  /* FE log at the end of the txn/stream */
-	SMP_CKP_BE_CHK_RUL,  /* BE tcp-check rules */
-	SMP_CKP_CFG_PARSER,  /* config parser (i.e. before boot) */
-	SMP_CKP_CLI_PARSER,  /* command line parser */
-	SMP_CKP_ENTRIES /* nothing after this */
-};
-
-/* SMP_USE_* are flags used to declare fetch keywords. Fetch methods are
- * associated with bitfields composed of these values, generally only one, to
- * indicate where the contents may be sampled. Some fetches are ambiguous as
- * they apply to either the request or the response depending on the context,
- * so they will have 2 of these bits (eg: hdr(), payload(), ...). These are
- * stored in smp->use.
- */
-enum {
-	SMP_USE_CONST = 1 << SMP_SRC_CONST,  /* constant values known at config time */
-	SMP_USE_INTRN = 1 << SMP_SRC_INTRN,  /* internal context-less information */
-	SMP_USE_LISTN = 1 << SMP_SRC_LISTN,  /* listener which accepted the connection */
-	SMP_USE_FTEND = 1 << SMP_SRC_FTEND,  /* frontend which accepted the connection */
-	SMP_USE_L4CLI = 1 << SMP_SRC_L4CLI,  /* L4 information about the client */
-	SMP_USE_L5CLI = 1 << SMP_SRC_L5CLI,  /* fetch uses client information from embryonic session */
-	SMP_USE_TRACK = 1 << SMP_SRC_TRACK,  /* fetch involves track counters */
-	SMP_USE_L6REQ = 1 << SMP_SRC_L6REQ,  /* fetch uses raw information from the request buffer */
-	SMP_USE_HRQHV = 1 << SMP_SRC_HRQHV,  /* fetch uses volatile information about HTTP request headers (eg: value) */
-	SMP_USE_HRQHP = 1 << SMP_SRC_HRQHP,  /* fetch uses persistent information about HTTP request headers (eg: meth) */
-	SMP_USE_HRQBO = 1 << SMP_SRC_HRQBO,  /* fetch uses information about HTTP request body */
-	SMP_USE_BKEND = 1 << SMP_SRC_BKEND,  /* fetch uses information about the backend */
-	SMP_USE_SERVR = 1 << SMP_SRC_SERVR,  /* fetch uses information about the selected server */
-	SMP_USE_L4SRV = 1 << SMP_SRC_L4SRV,  /* fetch uses information about the server L4 connection */
-	SMP_USE_L5SRV = 1 << SMP_SRC_L5SRV,  /* fetch uses information about the server L5 connection */
-	SMP_USE_L6RES = 1 << SMP_SRC_L6RES,  /* fetch uses raw information from the response buffer */
-	SMP_USE_HRSHV = 1 << SMP_SRC_HRSHV,  /* fetch uses volatile information about HTTP response headers (eg: value) */
-	SMP_USE_HRSHP = 1 << SMP_SRC_HRSHP,  /* fetch uses persistent information about HTTP response headers (eg: status) */
-	SMP_USE_HRSBO = 1 << SMP_SRC_HRSBO,  /* fetch uses information about HTTP response body */
-	SMP_USE_RQFIN = 1 << SMP_SRC_RQFIN,  /* final information about request buffer (eg: tot bytes) */
-	SMP_USE_RSFIN = 1 << SMP_SRC_RSFIN,  /* final information about response buffer (eg: tot bytes) */
-	SMP_USE_TXFIN = 1 << SMP_SRC_TXFIN,  /* final information about the transaction (eg: #comp rate) */
-	SMP_USE_SSFIN = 1 << SMP_SRC_SSFIN,  /* final information about the stream (eg: #requests, final flags) */
-
-	/* This composite one is useful to detect if an http_txn needs to be allocated */
-	SMP_USE_HTTP_ANY = SMP_USE_HRQHV | SMP_USE_HRQHP | SMP_USE_HRQBO |
-	                   SMP_USE_HRSHV | SMP_USE_HRSHP | SMP_USE_HRSBO,
-};
-
-/* Sample validity is computed from the fetch sources above when keywords
- * are registered. Each fetch method may be used at different locations. The
- * configuration parser will check whether the fetches are compatible with the
- * location where they're used. These are stored in smp->val.
- */
-enum {
-	SMP_VAL___________ = 0,        /* Just used as a visual marker */
-	SMP_VAL_FE_CON_ACC = 1 << SMP_CKP_FE_CON_ACC,  /* FE connection accept rules ("tcp request connection") */
-	SMP_VAL_FE_SES_ACC = 1 << SMP_CKP_FE_SES_ACC,  /* FE stream accept rules (to come soon) */
-	SMP_VAL_FE_REQ_CNT = 1 << SMP_CKP_FE_REQ_CNT,  /* FE request content rules ("tcp request content") */
-	SMP_VAL_FE_HRQ_HDR = 1 << SMP_CKP_FE_HRQ_HDR,  /* FE HTTP request headers (rules, headers, monitor, stats, redirect) */
-	SMP_VAL_FE_HRQ_BDY = 1 << SMP_CKP_FE_HRQ_BDY,  /* FE HTTP request body */
-	SMP_VAL_FE_SET_BCK = 1 << SMP_CKP_FE_SET_BCK,  /* FE backend switching rules ("use_backend") */
-	SMP_VAL_BE_REQ_CNT = 1 << SMP_CKP_BE_REQ_CNT,  /* BE request content rules ("tcp request content") */
-	SMP_VAL_BE_HRQ_HDR = 1 << SMP_CKP_BE_HRQ_HDR,  /* BE HTTP request headers (rules, headers, monitor, stats, redirect) */
-	SMP_VAL_BE_HRQ_BDY = 1 << SMP_CKP_BE_HRQ_BDY,  /* BE HTTP request body */
-	SMP_VAL_BE_SET_SRV = 1 << SMP_CKP_BE_SET_SRV,  /* BE server switching rules ("use_server", "balance", "force-persist", "stick", ...) */
-	SMP_VAL_BE_SRV_CON = 1 << SMP_CKP_BE_SRV_CON,  /* BE server connect (eg: "source") */
-	SMP_VAL_BE_RES_CNT = 1 << SMP_CKP_BE_RES_CNT,  /* BE response content rules ("tcp response content") */
-	SMP_VAL_BE_HRS_HDR = 1 << SMP_CKP_BE_HRS_HDR,  /* BE HTTP response headers (rules, headers) */
-	SMP_VAL_BE_HRS_BDY = 1 << SMP_CKP_BE_HRS_BDY,  /* BE HTTP response body (stick-store rules are there) */
-	SMP_VAL_BE_STO_RUL = 1 << SMP_CKP_BE_STO_RUL,  /* BE stick-store rules */
-	SMP_VAL_FE_RES_CNT = 1 << SMP_CKP_FE_RES_CNT,  /* FE response content rules ("tcp response content") */
-	SMP_VAL_FE_HRS_HDR = 1 << SMP_CKP_FE_HRS_HDR,  /* FE HTTP response headers (rules, headers) */
-	SMP_VAL_FE_HRS_BDY = 1 << SMP_CKP_FE_HRS_BDY,  /* FE HTTP response body */
-	SMP_VAL_FE_LOG_END = 1 << SMP_CKP_FE_LOG_END,  /* FE log at the end of the txn/stream */
-	SMP_VAL_BE_CHK_RUL = 1 << SMP_CKP_BE_CHK_RUL,  /* BE tcp-check rule */
-	SMP_VAL_CFG_PARSER = 1 << SMP_CKP_CFG_PARSER,  /* within config parser */
-	SMP_VAL_CLI_PARSER = 1 << SMP_CKP_CLI_PARSER,  /* within command line parser */
-
-	/* a few combinations to decide what direction to try to fetch (useful for logs) */
-	SMP_VAL_REQUEST    = SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
-	                     SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
-	                     SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
-	                     SMP_VAL_BE_SET_SRV | SMP_VAL_BE_CHK_RUL,
-
-	SMP_VAL_RESPONSE   = SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT | SMP_VAL_BE_HRS_HDR |
-	                     SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL | SMP_VAL_FE_RES_CNT |
-	                     SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY | SMP_VAL_FE_LOG_END |
-	                     SMP_VAL_BE_CHK_RUL,
-};
-
-/* Sample fetch options are passed to sample fetch functions to add precision
- * about what is desired :
- *   - fetch direction (req/resp)
- *   - intermediary / final fetch
- */
-enum {
-	SMP_OPT_DIR_REQ = 0,    /* direction = request */
-	SMP_OPT_DIR_RES = 1,    /* direction = response */
-	SMP_OPT_DIR     = (SMP_OPT_DIR_REQ|SMP_OPT_DIR_RES), /* mask to get direction */
-	SMP_OPT_FINAL   = 2,    /* final fetch, contents won't change anymore */
-	SMP_OPT_ITERATE = 4,    /* fetches may be iterated if supported (for ACLs) */
-};
-
-/* Flags used to describe fetched samples. MAY_CHANGE indicates that the result
- * of the fetch might still evolve, for instance because of more data expected,
- * even if the fetch has failed. VOL_* indicates how long a result may be cached.
- */
-enum {
-	SMP_F_NOT_LAST   = 1 << 0, /* other occurrences might exist for this sample */
-	SMP_F_MAY_CHANGE = 1 << 1, /* sample is unstable and might change (eg: request length) */
-	SMP_F_VOL_TEST   = 1 << 2, /* result must not survive longer than the test (eg: time) */
-	SMP_F_VOL_1ST    = 1 << 3, /* result sensitive to changes in first line (eg: URI) */
-	SMP_F_VOL_HDR    = 1 << 4, /* result sensitive to changes in headers */
-	SMP_F_VOL_TXN    = 1 << 5, /* result sensitive to new transaction (eg: HTTP version) */
-	SMP_F_VOL_SESS   = 1 << 6, /* result sensitive to new session (eg: src IP) */
-	SMP_F_VOLATILE   = (1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6), /* any volatility condition */
-	SMP_F_CONST      = 1 << 7, /* This sample use constant memory. May diplicate it before changes */
-};
-
-/* needed below */
-struct session;
-struct stream;
-struct arg;
-
-/* a sample context might be used by any sample fetch function in order to
- * store information needed across multiple calls (eg: restart point for a
- * next occurrence). By definition it may store up to 8 pointers, or any
- * scalar (double, int, long long).
- */
-union smp_ctx {
-	void *p;        /* any pointer */
-	int i;          /* any integer */
-	long long ll;   /* any long long or smaller */
-	double d;       /* any float or double */
-	void *a[8];     /* any array of up to 8 pointers */
-};
-
-/* a sample is a typed data extracted from a stream. It has a type, contents,
- * validity constraints, a context for use in iterative calls.
- */
-struct sample {
-	unsigned int flags;       /* SMP_F_* */
-	struct sample_data data;
-	union smp_ctx ctx;
-
-	/* Some sample analyzer (sample-fetch or converters) needs to
-	 * known the attached proxy, session and stream. The sample-fetches
-	 * and the converters function pointers cannot be called without
-	 * these 3 pointers filled.
-	 */
-	struct proxy *px;
-	struct session *sess;
-	struct stream *strm; /* WARNING! MAY BE NULL! (eg: tcp-request connection) */
-	unsigned int opt; /* fetch options (SMP_OPT_*) */
-};
-
-/* Descriptor for a sample conversion */
-struct sample_conv {
-	const char *kw;                           /* configuration keyword  */
-	int (*process)(const struct arg *arg_p,
-	               struct sample *smp,
-	               void *private);            /* process function */
-	uint64_t arg_mask;                        /* arguments (ARG*()) */
-	int (*val_args)(struct arg *arg_p,
-	                struct sample_conv *smp_conv,
-	                const char *file, int line,
-			char **err_msg);          /* argument validation function */
-	unsigned int in_type;                     /* expected input sample type */
-	unsigned int out_type;                    /* output sample type */
-	void *private;                            /* private values. only used by maps and Lua */
-};
-
-/* sample conversion expression */
-struct sample_conv_expr {
-	struct list list;                         /* member of a sample_expr */
-	struct sample_conv *conv;                 /* sample conversion used */
-	struct arg *arg_p;                        /* optional arguments */
-};
-
-/* Descriptor for a sample fetch method */
-struct sample_fetch {
-	const char *kw;                           /* configuration keyword */
-	int (*process)(const struct arg *arg_p,
-	               struct sample *smp,
-	               const char *kw,            /* fetch processing function */
-	               void *private);            /* private value. */
-	uint64_t arg_mask;                        /* arguments (ARG*()) */
-	int (*val_args)(struct arg *arg_p,
-			char **err_msg);          /* argument validation function */
-	unsigned long out_type;                   /* output sample type */
-	unsigned int use;                         /* fetch source (SMP_USE_*) */
-	unsigned int val;                         /* fetch validity (SMP_VAL_*) */
-	void *private;                            /* private values. only used by Lua */
-};
-
-/* sample expression */
-struct sample_expr {
-	struct list list;                         /* member of list of sample, currently not used */
-	struct sample_fetch *fetch;               /* sample fetch method */
-	struct arg *arg_p;                        /* optional pointer to arguments to fetch function */
-	struct list conv_exprs;                   /* list of conversion expression to apply */
-};
-
-/* sample fetch keywords list */
-struct sample_fetch_kw_list {
-	struct list list;                         /* head of sample fetch keyword list */
-	struct sample_fetch kw[VAR_ARRAY];        /* array of sample fetch descriptors */
-};
-
-/* sample conversion keywords list */
-struct sample_conv_kw_list {
-	struct list list;                         /* head of sample conversion keyword list */
-	struct sample_conv kw[VAR_ARRAY];         /* array of sample conversion descriptors */
-};
-
-typedef int (*sample_cast_fct)(struct sample *smp);
-
-#endif /* _HAPROXY_SAMPLE_T_H */
diff --git a/contrib/mod_defender/include/haproxy/sample_data-t.h b/contrib/mod_defender/include/haproxy/sample_data-t.h
deleted file mode 100644
index 2546028..0000000
--- a/contrib/mod_defender/include/haproxy/sample_data-t.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * include/haproxy/sample_data-t.h
- * Definitions of sample data
- *
- * Copyright (C) 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
- * Copyright (C) 2020 Willy Tarreau <w@1wt.eu>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _HAPROXY_SAMPLE_DATA_T_H
-#define _HAPROXY_SAMPLE_DATA_T_H
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <haproxy/buf-t.h>
-#include <haproxy/http-t.h>
-
-/* Note: the strings below make use of chunks. Chunks may carry an allocated
- * size in addition to the length. The size counts from the beginning (str)
- * to the end. If the size is unknown, it MUST be zero, in which case the
- * sample will automatically be duplicated when a change larger than <len> has
- * to be performed. Thus it is safe to always set size to zero.
- */
-union sample_value {
-	long long int   sint;  /* used for signed 64bits integers */
-	struct in_addr  ipv4;  /* used for ipv4 addresses */
-	struct in6_addr ipv6;  /* used for ipv6 addresses */
-	struct buffer    str;   /* used for char strings or buffers */
-	struct http_meth meth;  /* used for http method */
-};
-
-/* Used to store sample constant */
-struct sample_data {
-	int type;                 /* SMP_T_* */
-	union sample_value u;     /* sample data */
-};
-
-#endif /* _HAPROXY_SAMPLE_DATA_T_H */
diff --git a/contrib/mod_defender/include/haproxy/spoe-t.h b/contrib/mod_defender/include/haproxy/spoe-t.h
deleted file mode 100644
index 62ad547..0000000
--- a/contrib/mod_defender/include/haproxy/spoe-t.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * include/haproxy/spoe-t.h
- * Macros, variables and structures for the SPOE filter.
- *
- * Copyright (C) 2017 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _HAPROXY_SPOE_T_H
-#define _HAPROXY_SPOE_T_H
-
-
-/* Type of list of messages */
-#define SPOE_MSGS_BY_EVENT 0x01
-#define SPOE_MSGS_BY_GROUP 0x02
-
-/* Flags set on the SPOE agent */
-#define SPOE_FL_CONT_ON_ERR       0x00000001 /* Do not stop events processing when an error occurred */
-#define SPOE_FL_PIPELINING        0x00000002 /* Set when SPOE agent supports pipelining (set by default) */
-#define SPOE_FL_ASYNC             0x00000004 /* Set when SPOE agent supports async (set by default) */
-#define SPOE_FL_SND_FRAGMENTATION 0x00000008 /* Set when SPOE agent supports sending fragmented payload */
-#define SPOE_FL_RCV_FRAGMENTATION 0x00000010 /* Set when SPOE agent supports receiving fragmented payload */
-#define SPOE_FL_FORCE_SET_VAR     0x00000020 /* Set when SPOE agent will set all variables from agent (and not only known variables) */
-
-/* Flags set on the SPOE context */
-#define SPOE_CTX_FL_CLI_CONNECTED 0x00000001 /* Set after that on-client-session event was processed */
-#define SPOE_CTX_FL_SRV_CONNECTED 0x00000002 /* Set after that on-server-session event was processed */
-#define SPOE_CTX_FL_REQ_PROCESS   0x00000004 /* Set when SPOE is processing the request */
-#define SPOE_CTX_FL_RSP_PROCESS   0x00000008 /* Set when SPOE is processing the response */
-#define SPOE_CTX_FL_FRAGMENTED    0x00000010 /* Set when a fragmented frame is processing */
-
-#define SPOE_CTX_FL_PROCESS (SPOE_CTX_FL_REQ_PROCESS|SPOE_CTX_FL_RSP_PROCESS)
-
-/* Flags set on the SPOE applet */
-#define SPOE_APPCTX_FL_PIPELINING    0x00000001 /* Set if pipelining is supported */
-#define SPOE_APPCTX_FL_ASYNC         0x00000002 /* Set if asynchronus frames is supported */
-#define SPOE_APPCTX_FL_FRAGMENTATION 0x00000004 /* Set if fragmentation is supported */
-
-#define SPOE_APPCTX_ERR_NONE    0x00000000 /* no error yet, leave it to zero */
-#define SPOE_APPCTX_ERR_TOUT    0x00000001 /* SPOE applet timeout */
-
-/* Flags set on the SPOE frame */
-#define SPOE_FRM_FL_FIN         0x00000001
-#define SPOE_FRM_FL_ABRT        0x00000002
-
-/* Masks to get data type or flags value */
-#define SPOE_DATA_T_MASK  0x0F
-#define SPOE_DATA_FL_MASK 0xF0
-
-/* Flags to set Boolean values */
-#define SPOE_DATA_FL_FALSE 0x00
-#define SPOE_DATA_FL_TRUE  0x10
-
-/* All possible states for a SPOE context */
-enum spoe_ctx_state {
-	SPOE_CTX_ST_NONE = 0,
-	SPOE_CTX_ST_READY,
-	SPOE_CTX_ST_ENCODING_MSGS,
-	SPOE_CTX_ST_SENDING_MSGS,
-	SPOE_CTX_ST_WAITING_ACK,
-	SPOE_CTX_ST_DONE,
-	SPOE_CTX_ST_ERROR,
-};
-
-/* All possible states for a SPOE applet */
-enum spoe_appctx_state {
-	SPOE_APPCTX_ST_CONNECT = 0,
-	SPOE_APPCTX_ST_CONNECTING,
-	SPOE_APPCTX_ST_IDLE,
-	SPOE_APPCTX_ST_PROCESSING,
-	SPOE_APPCTX_ST_SENDING_FRAG_NOTIFY,
-	SPOE_APPCTX_ST_WAITING_SYNC_ACK,
-	SPOE_APPCTX_ST_DISCONNECT,
-	SPOE_APPCTX_ST_DISCONNECTING,
-	SPOE_APPCTX_ST_EXIT,
-	SPOE_APPCTX_ST_END,
-};
-
-/* All supported SPOE actions */
-enum spoe_action_type {
-	SPOE_ACT_T_SET_VAR = 1,
-	SPOE_ACT_T_UNSET_VAR,
-	SPOE_ACT_TYPES,
-};
-
-/* All supported SPOE events */
-enum spoe_event {
-	SPOE_EV_NONE = 0,
-
-	/* Request events */
-	SPOE_EV_ON_CLIENT_SESS = 1,
-	SPOE_EV_ON_TCP_REQ_FE,
-	SPOE_EV_ON_TCP_REQ_BE,
-	SPOE_EV_ON_HTTP_REQ_FE,
-	SPOE_EV_ON_HTTP_REQ_BE,
-
-	/* Response events */
-	SPOE_EV_ON_SERVER_SESS,
-	SPOE_EV_ON_TCP_RSP,
-	SPOE_EV_ON_HTTP_RSP,
-
-	SPOE_EV_EVENTS
-};
-
-/* Errors triggered by streams */
-enum spoe_context_error {
-	SPOE_CTX_ERR_NONE = 0,
-	SPOE_CTX_ERR_TOUT,
-	SPOE_CTX_ERR_RES,
-	SPOE_CTX_ERR_TOO_BIG,
-	SPOE_CTX_ERR_FRAG_FRAME_ABRT,
-	SPOE_CTX_ERR_INTERRUPT,
-	SPOE_CTX_ERR_UNKNOWN = 255,
-	SPOE_CTX_ERRS,
-};
-
-/* Errors triggered by SPOE applet */
-enum spoe_frame_error {
-	SPOE_FRM_ERR_NONE = 0,
-	SPOE_FRM_ERR_IO,
-	SPOE_FRM_ERR_TOUT,
-	SPOE_FRM_ERR_TOO_BIG,
-	SPOE_FRM_ERR_INVALID,
-	SPOE_FRM_ERR_NO_VSN,
-	SPOE_FRM_ERR_NO_FRAME_SIZE,
-	SPOE_FRM_ERR_NO_CAP,
-	SPOE_FRM_ERR_BAD_VSN,
-	SPOE_FRM_ERR_BAD_FRAME_SIZE,
-	SPOE_FRM_ERR_FRAG_NOT_SUPPORTED,
-	SPOE_FRM_ERR_INTERLACED_FRAMES,
-	SPOE_FRM_ERR_FRAMEID_NOTFOUND,
-	SPOE_FRM_ERR_RES,
-	SPOE_FRM_ERR_UNKNOWN = 99,
-	SPOE_FRM_ERRS,
-};
-
-/* Scopes used for variables set by agents. It is a way to be agnotic to vars
- * scope. */
-enum spoe_vars_scope {
-	SPOE_SCOPE_PROC = 0, /* <=> SCOPE_PROC  */
-	SPOE_SCOPE_SESS,     /* <=> SCOPE_SESS */
-	SPOE_SCOPE_TXN,      /* <=> SCOPE_TXN  */
-	SPOE_SCOPE_REQ,      /* <=> SCOPE_REQ  */
-	SPOE_SCOPE_RES,      /* <=> SCOPE_RES  */
-};
-
-/* Frame Types sent by HAProxy and by agents */
-enum spoe_frame_type {
-	SPOE_FRM_T_UNSET = 0,
-
-	/* Frames sent by HAProxy */
-	SPOE_FRM_T_HAPROXY_HELLO = 1,
-	SPOE_FRM_T_HAPROXY_DISCON,
-	SPOE_FRM_T_HAPROXY_NOTIFY,
-
-	/* Frames sent by the agents */
-	SPOE_FRM_T_AGENT_HELLO = 101,
-	SPOE_FRM_T_AGENT_DISCON,
-	SPOE_FRM_T_AGENT_ACK
-};
-
-/* All supported data types */
-enum spoe_data_type {
-	SPOE_DATA_T_NULL = 0,
-	SPOE_DATA_T_BOOL,
-	SPOE_DATA_T_INT32,
-	SPOE_DATA_T_UINT32,
-	SPOE_DATA_T_INT64,
-	SPOE_DATA_T_UINT64,
-	SPOE_DATA_T_IPV4,
-	SPOE_DATA_T_IPV6,
-	SPOE_DATA_T_STR,
-	SPOE_DATA_T_BIN,
-	SPOE_DATA_TYPES
-};
-
-
-#endif /* _HAPROXY_SPOE_T_H */
diff --git a/contrib/mod_defender/include/haproxy/spoe.h b/contrib/mod_defender/include/haproxy/spoe.h
deleted file mode 100644
index b7b981a..0000000
--- a/contrib/mod_defender/include/haproxy/spoe.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * include/haproxy/spoe.h
- * Encoding/Decoding functions for the SPOE filters (and other helpers).
- *
- * Copyright (C) 2017 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _HAPROXY_SPOE_H
-#define _HAPROXY_SPOE_H
-
-#include <string.h>
-#include <haproxy/api.h>
-#include <haproxy/intops.h>
-#include <haproxy/sample-t.h>
-#include <haproxy/spoe-t.h>
-
-
-/* Encode a buffer. Its length <len> is encoded as a varint, followed by a copy
- * of <str>. It must have enough space in <*buf> to encode the buffer, else an
- * error is triggered.
- * On success, it returns <len> and <*buf> is moved after the encoded value. If
- * an error occurred, it returns -1. */
-static inline int
-spoe_encode_buffer(const char *str, size_t len, char **buf, char *end)
-{
-	char *p = *buf;
-	int   ret;
-
-	if (p >= end)
-		return -1;
-
-	if (!len) {
-		*p++ = 0;
-		*buf = p;
-		return 0;
-	}
-
-	ret = encode_varint(len, &p, end);
-	if (ret == -1 || p + len > end)
-		return -1;
-
-	memcpy(p, str, len);
-	*buf = p + len;
-	return len;
-}
-
-/* Encode a buffer, possibly partially. It does the same thing than
- * 'spoe_encode_buffer', but if there is not enough space, it does not fail.
- * On success, it returns the number of copied bytes and <*buf> is moved after
- * the encoded value. If an error occurred, it returns -1. */
-static inline int
-spoe_encode_frag_buffer(const char *str, size_t len, char **buf, char *end)
-{
-	char *p = *buf;
-	int   ret;
-
-	if (p >= end)
-		return -1;
-
-	if (!len) {
-		*p++ = 0;
-		*buf = p;
-		return 0;
-	}
-
-	ret = encode_varint(len, &p, end);
-	if (ret == -1 || p >= end)
-		return -1;
-
-	ret = (p+len < end) ? len : (end - p);
-	memcpy(p, str, ret);
-	*buf = p + ret;
-	return ret;
-}
-
-/* Decode a buffer. The buffer length is decoded and saved in <*len>. <*str>
- * points on the first byte of the buffer.
- * On success, it returns the buffer length and <*buf> is moved after the
- * encoded buffer. Otherwise, it returns -1. */
-static inline int
-spoe_decode_buffer(char **buf, char *end, char **str, uint64_t *len)
-{
-	char    *p = *buf;
-	uint64_t sz;
-	int      ret;
-
-	*str = NULL;
-	*len = 0;
-
-	ret = decode_varint(&p, end, &sz);
-	if (ret == -1 || p + sz > end)
-		return -1;
-
-	*str = p;
-	*len = sz;
-	*buf = p + sz;
-	return sz;
-}
-
-/* Encode a typed data using value in <smp>. On success, it returns the number
- * of copied bytes and <*buf> is moved after the encoded value. If an error
- * occurred, it returns -1.
- *
- * If the value is too big to be encoded, depending on its type, then encoding
- * failed or the value is partially encoded. Only strings and binaries can be
- * partially encoded. */
-static inline int
-spoe_encode_data(struct sample *smp, char **buf, char *end)
-{
-	char *p = *buf;
-	int   ret;
-
-	if (p >= end)
-		return -1;
-
-	if (smp == NULL) {
-		*p++ = SPOE_DATA_T_NULL;
-		goto end;
-	}
-
-	switch (smp->data.type) {
-		case SMP_T_BOOL:
-			*p    = SPOE_DATA_T_BOOL;
-			*p++ |= ((!smp->data.u.sint) ? SPOE_DATA_FL_FALSE : SPOE_DATA_FL_TRUE);
-			break;
-
-		case SMP_T_SINT:
-			*p++ = SPOE_DATA_T_INT64;
-			if (encode_varint(smp->data.u.sint, &p, end) == -1)
-				return -1;
-			break;
-
-		case SMP_T_IPV4:
-			if (p + 5 > end)
-				return -1;
-			*p++ = SPOE_DATA_T_IPV4;
-			memcpy(p, &smp->data.u.ipv4, 4);
-			p += 4;
-			break;
-
-		case SMP_T_IPV6:
-			if (p + 17 > end)
-				return -1;
-			*p++ = SPOE_DATA_T_IPV6;
-			memcpy(p, &smp->data.u.ipv6, 16);
-			p += 16;
-			break;
-
-		case SMP_T_STR:
-		case SMP_T_BIN: {
-			/* If defined, get length and offset of the sample by reading the sample
-			 * context. ctx.a[0] is the pointer to the length and ctx.a[1] is the
-			 * pointer to the offset. If the offset is greater than 0, it means the
-			 * sample is partially encoded. In this case, we only need to encode the
-			 * reamining. When all the sample is encoded, the offset is reset to 0.
-			 * So the caller know it can try to encode the next sample. */
-			struct buffer *chk = &smp->data.u.str;
-			unsigned int *len  = smp->ctx.a[0];
-			unsigned int *off  = smp->ctx.a[1];
-
-			if (!*off) {
-				/* First evaluation of the sample : encode the
-				 * type (string or binary), the buffer length
-				 * (as a varint) and at least 1 byte of the
-				 * buffer. */
-				struct buffer *chk = &smp->data.u.str;
-
-				*p++ = (smp->data.type == SMP_T_STR)
-					? SPOE_DATA_T_STR
-					: SPOE_DATA_T_BIN;
-				ret = spoe_encode_frag_buffer(chk->area,
-							      chk->data, &p,
-							      end);
-				if (ret == -1)
-					return -1;
-				*len = chk->data;
-			}
-			else {
-				/* The sample has been fragmented, encode remaining data */
-				ret = MIN(*len - *off, end - p);
-				memcpy(p, chk->area + *off, ret);
-				p += ret;
-			}
-			/* Now update <*off> */
-			if (ret + *off != *len)
-				*off += ret;
-			else
-				*off = 0;
-			break;
-		}
-
-		case SMP_T_METH: {
-			char   *m;
-			size_t  len;
-
-			*p++ = SPOE_DATA_T_STR;
-			switch (smp->data.u.meth.meth) {
-				case HTTP_METH_OPTIONS: m = "OPTIONS"; len = 7; break;
-				case HTTP_METH_GET    : m = "GET";     len = 3; break;
-				case HTTP_METH_HEAD   : m = "HEAD";    len = 4; break;
-				case HTTP_METH_POST   : m = "POST";    len = 4; break;
-				case HTTP_METH_PUT    : m = "PUT";     len = 3; break;
-				case HTTP_METH_DELETE : m = "DELETE";  len = 6; break;
-				case HTTP_METH_TRACE  : m = "TRACE";   len = 5; break;
-				case HTTP_METH_CONNECT: m = "CONNECT"; len = 7; break;
-
-				default :
-					m   = smp->data.u.meth.str.area;
-					len = smp->data.u.meth.str.data;
-			}
-			if (spoe_encode_buffer(m, len, &p, end) == -1)
-				return -1;
-			break;
-		}
-
-		default:
-			*p++ = SPOE_DATA_T_NULL;
-			break;
-	}
-
-  end:
-	ret  = (p - *buf);
-	*buf = p;
-	return ret;
-}
-
-/* Skip a typed data. If an error occurred, -1 is returned, otherwise the number
- * of skipped bytes is returned and the <*buf> is moved after skipped data.
- *
- * A types data is composed of a type (1 byte) and corresponding data:
- *  - boolean: non additional data (0 bytes)
- *  - integers: a variable-length integer (see decode_varint)
- *  - ipv4: 4 bytes
- *  - ipv6: 16 bytes
- *  - binary and string: a buffer prefixed by its size, a variable-length
- *    integer (see spoe_decode_buffer) */
-static inline int
-spoe_skip_data(char **buf, char *end)
-{
-	char    *str, *p = *buf;
-	int      type, ret;
-	uint64_t v, sz;
-
-	if (p >= end)
-		return -1;
-
-	type = *p++;
-	switch (type & SPOE_DATA_T_MASK) {
-		case SPOE_DATA_T_BOOL:
-			break;
-		case SPOE_DATA_T_INT32:
-		case SPOE_DATA_T_INT64:
-		case SPOE_DATA_T_UINT32:
-		case SPOE_DATA_T_UINT64:
-			if (decode_varint(&p, end, &v) == -1)
-				return -1;
-			break;
-		case SPOE_DATA_T_IPV4:
-			if (p+4 > end)
-				return -1;
-			p += 4;
-			break;
-		case SPOE_DATA_T_IPV6:
-			if (p+16 > end)
-				return -1;
-			p += 16;
-			break;
-		case SPOE_DATA_T_STR:
-		case SPOE_DATA_T_BIN:
-			/* All the buffer must be skipped */
-			if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-				return -1;
-			break;
-	}
-
-	ret  = (p - *buf);
-	*buf = p;
-	return ret;
-}
-
-/* Decode a typed data and fill <smp>. If an error occurred, -1 is returned,
- * otherwise the number of read bytes is returned and <*buf> is moved after the
- * decoded data. See spoe_skip_data for details. */
-static inline int
-spoe_decode_data(char **buf, char *end, struct sample *smp)
-{
-	char  *str, *p = *buf;
-	int    type, r = 0;
-	uint64_t sz;
-
-	if (p >= end)
-		return -1;
-
-	type = *p++;
-	switch (type & SPOE_DATA_T_MASK) {
-		case SPOE_DATA_T_BOOL:
-			smp->data.u.sint = ((type & SPOE_DATA_FL_MASK) == SPOE_DATA_FL_TRUE);
-			smp->data.type = SMP_T_BOOL;
-			break;
-		case SPOE_DATA_T_INT32:
-		case SPOE_DATA_T_INT64:
-		case SPOE_DATA_T_UINT32:
-		case SPOE_DATA_T_UINT64:
-			if (decode_varint(&p, end, (uint64_t *)&smp->data.u.sint) == -1)
-				return -1;
-			smp->data.type = SMP_T_SINT;
-			break;
-		case SPOE_DATA_T_IPV4:
-			if (p+4 > end)
-				return -1;
-			smp->data.type = SMP_T_IPV4;
-			memcpy(&smp->data.u.ipv4, p, 4);
-			p += 4;
-			break;
-		case SPOE_DATA_T_IPV6:
-			if (p+16 > end)
-				return -1;
-			memcpy(&smp->data.u.ipv6, p, 16);
-			smp->data.type = SMP_T_IPV6;
-			p += 16;
-			break;
-		case SPOE_DATA_T_STR:
-		case SPOE_DATA_T_BIN:
-			/* All the buffer must be decoded */
-			if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-				return -1;
-			smp->data.u.str.area = str;
-			smp->data.u.str.data = sz;
-			smp->data.type = (type == SPOE_DATA_T_STR) ? SMP_T_STR : SMP_T_BIN;
-			break;
-	}
-
-	r    = (p - *buf);
-	*buf = p;
-	return r;
-}
-
-#endif /* _HAPROXY_SPOE_H */
diff --git a/contrib/mod_defender/include/haproxy/tools.h b/contrib/mod_defender/include/haproxy/tools.h
deleted file mode 100644
index 7bd0c51..0000000
--- a/contrib/mod_defender/include/haproxy/tools.h
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * include/haproxy/tools.h
- * This files contains some general purpose functions and macros.
- *
- * Copyright (C) 2000-2020 Willy Tarreau - w@1wt.eu
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, version 2.1
- * exclusively.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _HAPROXY_TOOLS_H
-#define _HAPROXY_TOOLS_H
-
-#include <string.h>
-#include <stdio.h>
-#include <time.h>
-#include <stdarg.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/****** string-specific macros and functions ******/
-/* if a > max, then bound <a> to <max>. The macro returns the new <a> */
-#define UBOUND(a, max)	({ typeof(a) b = (max); if ((a) > b) (a) = b; (a); })
-
-/* if a < min, then bound <a> to <min>. The macro returns the new <a> */
-#define LBOUND(a, min)	({ typeof(a) b = (min); if ((a) < b) (a) = b; (a); })
-
-#define SWAP(a, b) do { typeof(a) t; t = a; a = b; b = t; } while(0)
-
-/* returns true if <c> is an identifier character, that is, a digit, a letter,
- * or '-', '+', '_', ':' or '.'. This is usable for proxy names, server names,
- * ACL names, sample fetch names, and converter names.
- */
-static inline char *cut_crlf(char *s) {
-
-	while (*s != '\r' && *s != '\n') {
-		char *p = s++;
-
-		if (!*p)
-			return p;
-	}
-
-	*s++ = '\0';
-
-	return s;
-}
-
-static inline char *ltrim(char *s, char c) {
-
-	if (c)
-		while (*s == c)
-			s++;
-
-	return s;
-}
-
-static inline char *rtrim(char *s, char c) {
-
-	char *p = s + strlen(s);
-
-	while (p-- > s)
-		if (*p == c)
-			*p = '\0';
-		else
-			break;
-
-	return s;
-}
-
-static inline char *alltrim(char *s, char c) {
-
-	rtrim(s, c);
-
-	return ltrim(s, c);
-}
-
-/* This function converts the time_t value <now> into a broken out struct tm
- * which must be allocated by the caller. It is highly recommended to use this
- * function instead of localtime() because that one requires a time_t* which
- * is not always compatible with tv_sec depending on OS/hardware combinations.
- */
-static inline void get_localtime(const time_t now, struct tm *tm)
-{
-	localtime_r(&now, tm);
-}
-
-/* This function converts the time_t value <now> into a broken out struct tm
- * which must be allocated by the caller. It is highly recommended to use this
- * function instead of gmtime() because that one requires a time_t* which
- * is not always compatible with tv_sec depending on OS/hardware combinations.
- */
-static inline void get_gmtime(const time_t now, struct tm *tm)
-{
-	gmtime_r(&now, tm);
-}
-
-/* Counts a number of elapsed days since 01/01/0000 based solely on elapsed
- * years and assuming the regular rule for leap years applies. It's fake but
- * serves as a temporary origin. It's worth remembering that it's the first
- * year of each period that is leap and not the last one, so for instance year
- * 1 sees 366 days since year 0 was leap. For this reason we have to apply
- * modular arithmetic which is why we offset the year by 399 before
- * subtracting the excess at the end. No overflow here before ~11.7 million
- * years.
- */
-static inline unsigned int days_since_zero(unsigned int y)
-{
-	return y * 365 + (y + 399) / 4 - (y + 399) / 100 + (y + 399) / 400
-	       - 399 / 4 + 399 / 100;
-}
-
-/* sets the address family to AF_UNSPEC so that is_addr() does not match */
-static inline void clear_addr(struct sockaddr_storage *addr)
-{
-	addr->ss_family = AF_UNSPEC;
-}
-
-/* returns non-zero if addr has a valid and non-null IPv4 or IPv6 address,
- * otherwise zero.
- */
-static inline int is_inet_addr(const struct sockaddr_storage *addr)
-{
-	int i;
-
-	switch (addr->ss_family) {
-	case AF_INET:
-		return *(int *)&((struct sockaddr_in *)addr)->sin_addr;
-	case AF_INET6:
-		for (i = 0; i < sizeof(struct in6_addr) / sizeof(int); i++)
-			if (((int *)&((struct sockaddr_in6 *)addr)->sin6_addr)[i] != 0)
-				return ((int *)&((struct sockaddr_in6 *)addr)->sin6_addr)[i];
-	}
-	return 0;
-}
-
-/* returns port in network byte order */
-static inline int get_net_port(struct sockaddr_storage *addr)
-{
-	switch (addr->ss_family) {
-	case AF_INET:
-		return ((struct sockaddr_in *)addr)->sin_port;
-	case AF_INET6:
-		return ((struct sockaddr_in6 *)addr)->sin6_port;
-	}
-	return 0;
-}
-
-/* returns port in host byte order */
-static inline int get_host_port(struct sockaddr_storage *addr)
-{
-	switch (addr->ss_family) {
-	case AF_INET:
-		return ntohs(((struct sockaddr_in *)addr)->sin_port);
-	case AF_INET6:
-		return ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
-	}
-	return 0;
-}
-
-/* returns address len for <addr>'s family, 0 for unknown families */
-static inline int get_addr_len(const struct sockaddr_storage *addr)
-{
-	switch (addr->ss_family) {
-	case AF_INET:
-		return sizeof(struct sockaddr_in);
-	case AF_INET6:
-		return sizeof(struct sockaddr_in6);
-	case AF_UNIX:
-		return sizeof(struct sockaddr_un);
-	}
-	return 0;
-}
-
-/* set port in host byte order */
-static inline int set_net_port(struct sockaddr_storage *addr, int port)
-{
-	switch (addr->ss_family) {
-	case AF_INET:
-		((struct sockaddr_in *)addr)->sin_port = port;
-		break;
-	case AF_INET6:
-		((struct sockaddr_in6 *)addr)->sin6_port = port;
-		break;
-	}
-	return 0;
-}
-
-/* set port in network byte order */
-static inline int set_host_port(struct sockaddr_storage *addr, int port)
-{
-	switch (addr->ss_family) {
-	case AF_INET:
-		((struct sockaddr_in *)addr)->sin_port = htons(port);
-		break;
-	case AF_INET6:
-		((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
-		break;
-	}
-	return 0;
-}
-
-/* after increasing a pointer value, it can exceed the first buffer
- * size. This function transform the value of <ptr> according with
- * the expected position. <chunks> is an array of the one or two
- * available chunks. The first value is the start of the first chunk,
- * the second value if the end+1 of the first chunks. The third value
- * is NULL or the start of the second chunk and the fourth value is
- * the end+1 of the second chunk. The function returns 1 if does a
- * wrap, else returns 0.
- */
-static inline int fix_pointer_if_wrap(const char **chunks, const char **ptr)
-{
-	if (*ptr < chunks[1])
-		return 0;
-	if (!chunks[2])
-		return 0;
-	*ptr = chunks[2] + ( *ptr - chunks[1] );
-	return 1;
-}
-
-/************************* Composite address manipulation *********************
- * Composite addresses are simply unsigned long data in which the higher bits
- * represent a pointer, and the two lower bits are flags. There are several
- * places where we just want to associate one or two flags to a pointer (eg,
- * to type it), and these functions permit this. The pointer is necessarily a
- * 32-bit aligned pointer, as its two lower bits will be cleared and replaced
- * with the flags.
- *****************************************************************************/
-
-/* Masks the two lower bits of a composite address and converts it to a
- * pointer. This is used to mix some bits with some aligned pointers to
- * structs and to retrieve the original (32-bit aligned) pointer.
- */
-static inline void *caddr_to_ptr(unsigned long caddr)
-{
-	return (void *)(caddr & ~3UL);
-}
-
-/* Only retrieves the two lower bits of a composite address. This is used to mix
- * some bits with some aligned pointers to structs and to retrieve the original
- * data (2 bits).
- */
-static inline unsigned int caddr_to_data(unsigned long caddr)
-{
-	return (caddr & 3UL);
-}
-
-/* Combines the aligned pointer whose 2 lower bits will be masked with the bits
- * from <data> to form a composite address. This is used to mix some bits with
- * some aligned pointers to structs and to retrieve the original (32-bit aligned)
- * pointer.
- */
-static inline unsigned long caddr_from_ptr(void *ptr, unsigned int data)
-{
-	return (((unsigned long)ptr) & ~3UL) + (data & 3);
-}
-
-/* sets the 2 bits of <data> in the <caddr> composite address */
-static inline unsigned long caddr_set_flags(unsigned long caddr, unsigned int data)
-{
-	return caddr | (data & 3);
-}
-
-/* clears the 2 bits of <data> in the <caddr> composite address */
-static inline unsigned long caddr_clr_flags(unsigned long caddr, unsigned int data)
-{
-	return caddr & ~(unsigned long)(data & 3);
-}
-
-static inline unsigned char utf8_return_code(unsigned int code)
-{
-	return code & 0xf0;
-}
-
-static inline unsigned char utf8_return_length(unsigned char code)
-{
-	return code & 0x0f;
-}
-
-/* returns a 64-bit a timestamp with the finest resolution available. The
- * unit is intentionally not specified. It's mostly used to compare dates.
- */
-#if defined(__i386__) || defined(__x86_64__)
-static inline unsigned long long rdtsc()
-{
-     unsigned int a, d;
-     asm volatile("rdtsc" : "=a" (a), "=d" (d));
-     return a + ((unsigned long long)d << 32);
-}
-#else
-static inline unsigned long long rdtsc()
-{
-	struct timeval tv;
-	gettimeofday(&tv, NULL);
-	return tv.tv_sec * 1000000 + tv.tv_usec;
-}
-#endif
-
-/* Note that this may result in opening libgcc() on first call, so it may need
- * to have been called once before chrooting.
- */
-static forceinline int my_backtrace(void **buffer, int max)
-{
-#if !defined(USE_BACKTRACE)
-	return 0;
-#elif defined(HA_HAVE_WORKING_BACKTRACE)
-	return backtrace(buffer, max);
-#else
-	const struct frame {
-		const struct frame *next;
-		void *ra;
-	} *frame;
-	int count;
-
-	frame = __builtin_frame_address(0);
-	for (count = 0; count < max && may_access(frame) && may_access(frame->ra);) {
-		buffer[count++] = frame->ra;
-		frame = frame->next;
-	}
-	return count;
-#endif
-}
-
-/* same as realloc() except that ptr is also freed upon failure */
-static inline void *my_realloc2(void *ptr, size_t size)
-{
-	void *ret;
-
-	ret = realloc(ptr, size);
-	if (!ret && size)
-		free(ptr);
-	return ret;
-}
-
-#endif /* _HAPROXY_TOOLS_H */
diff --git a/contrib/mod_defender/spoa.c b/contrib/mod_defender/spoa.c
deleted file mode 100644
index c554da8..0000000
--- a/contrib/mod_defender/spoa.c
+++ /dev/null
@@ -1,1891 +0,0 @@
-/*
- * Mod Defender for HAProxy
- *
- * Copyright 2017 HAProxy Technologies, Dragan Dosen <ddosen@haproxy.com>
- *
- * Based on "A Random IP reputation service acting as a Stream Processing Offload Agent"
- * Copyright 2016 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
- *
- * This program 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 of the License, or (at your option) any later version.
- *
- */
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <stdio.h>
-#include <signal.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <err.h>
-#include <ctype.h>
-
-#include <pthread.h>
-
-#include <event2/util.h>
-#include <event2/event.h>
-#include <event2/event_struct.h>
-#include <event2/thread.h>
-
-#include <haproxy/list.h>
-#include <haproxy/spoe.h>
-
-#include "spoa.h"
-#include "defender.h"
-
-#define DEFAULT_PORT       12345
-#define CONNECTION_BACKLOG 10
-#define NUM_WORKERS        10
-#define MAX_FRAME_SIZE     16384
-#define SPOP_VERSION       "2.0"
-
-#define SLEN(str) (sizeof(str)-1)
-
-#define DEBUG(x...)				\
-	do {					\
-		if (debug)			\
-			LOG(x);			\
-	} while (0)
-
-
-enum spoa_state {
-	SPOA_ST_CONNECTING = 0,
-	SPOA_ST_PROCESSING,
-	SPOA_ST_DISCONNECTING,
-};
-
-enum spoa_frame_type {
-	SPOA_FRM_T_UNKNOWN = 0,
-	SPOA_FRM_T_HAPROXY,
-	SPOA_FRM_T_AGENT,
-};
-
-struct spoe_engine {
-	char       *id;
-
-	struct list processing_frames;
-	struct list outgoing_frames;
-
-	struct list clients;
-	struct list list;
-};
-
-struct spoe_frame {
-	enum spoa_frame_type type;
-	char                *buf;
-	unsigned int         offset;
-	unsigned int         len;
-
-	unsigned int         stream_id;
-	unsigned int         frame_id;
-	unsigned int         flags;
-	bool                 hcheck;          /* true is the CONNECT frame is a healthcheck */
-	bool                 fragmented;      /* true if the frame is fragmented */
-	int                  defender_status; /* mod_defender returned status */
-
-	struct event         process_frame_event;
-	struct worker       *worker;
-	struct spoe_engine  *engine;
-	struct client       *client;
-	struct list          list;
-
-	char                *frag_buf; /* used to accumulate payload of a fragmented frame */
-	unsigned int         frag_len;
-
-	char                 data[0];
-};
-
-struct client {
-	int                 fd;
-	unsigned long       id;
-	enum spoa_state     state;
-
-	struct event        read_frame_event;
-	struct event        write_frame_event;
-
-	struct spoe_frame  *incoming_frame;
-	struct spoe_frame  *outgoing_frame;
-
-	struct list         processing_frames;
-	struct list         outgoing_frames;
-
-	unsigned int        max_frame_size;
-	int                 status_code;
-
-	char               *engine_id;
-	struct spoe_engine *engine;
-	bool                pipelining;
-	bool                async;
-	bool                fragmentation;
-
-	struct worker      *worker;
-	struct list         by_worker;
-	struct list         by_engine;
-};
-
-/* Globals */
-static struct worker *workers          = NULL;
-struct worker         null_worker      = { .id = 0 };
-static unsigned long  clicount         = 0;
-static int            server_port      = DEFAULT_PORT;
-static int            num_workers      = NUM_WORKERS;
-static unsigned int   max_frame_size   = MAX_FRAME_SIZE;
-struct timeval        processing_delay = {0, 0};
-static bool           debug            = false;
-static bool           pipelining       = false;
-static bool           async            = false;
-static bool           fragmentation    = false;
-
-
-static const char *spoe_frm_err_reasons[SPOE_FRM_ERRS] = {
-	[SPOE_FRM_ERR_NONE]               = "normal",
-	[SPOE_FRM_ERR_IO]                 = "I/O error",
-	[SPOE_FRM_ERR_TOUT]               = "a timeout occurred",
-	[SPOE_FRM_ERR_TOO_BIG]            = "frame is too big",
-	[SPOE_FRM_ERR_INVALID]            = "invalid frame received",
-	[SPOE_FRM_ERR_NO_VSN]             = "version value not found",
-	[SPOE_FRM_ERR_NO_FRAME_SIZE]      = "max-frame-size value not found",
-	[SPOE_FRM_ERR_NO_CAP]             = "capabilities value not found",
-	[SPOE_FRM_ERR_BAD_VSN]            = "unsupported version",
-	[SPOE_FRM_ERR_BAD_FRAME_SIZE]     = "max-frame-size too big or too small",
-	[SPOE_FRM_ERR_FRAG_NOT_SUPPORTED] = "fragmentation not supported",
-	[SPOE_FRM_ERR_INTERLACED_FRAMES]  = "invalid interlaced frames",
-	[SPOE_FRM_ERR_FRAMEID_NOTFOUND]   = "frame-id not found",
-	[SPOE_FRM_ERR_RES]                = "resource allocation error",
-	[SPOE_FRM_ERR_UNKNOWN]            = "an unknown error occurred",
-};
-
-static void signal_cb(evutil_socket_t, short, void *);
-static void accept_cb(evutil_socket_t, short, void *);
-static void worker_monitor_cb(evutil_socket_t, short, void *);
-static void process_frame_cb(evutil_socket_t, short, void *);
-static void read_frame_cb(evutil_socket_t, short, void *);
-static void write_frame_cb(evutil_socket_t, short, void *);
-
-static void use_spoe_engine(struct client *);
-static void unuse_spoe_engine(struct client *);
-static void release_frame(struct spoe_frame *);
-static void release_client(struct client *);
-
-/* Check the protocol version. It returns -1 if an error occurred, the number of
- * read bytes otherwise. */
-static int
-check_proto_version(struct spoe_frame *frame, char **buf, char *end)
-{
-	char      *str, *p = *buf;
-	uint64_t   sz;
-	int        ret;
-
-	/* Get the list of all supported versions by HAProxy */
-	if ((*p++ & SPOE_DATA_T_MASK) != SPOE_DATA_T_STR)
-		return -1;
-	ret = spoe_decode_buffer(&p, end, &str, &sz);
-	if (ret == -1 || !str)
-		return -1;
-
-	DEBUG(frame->worker, "<%lu> Supported versions : %.*s",
-	      frame->client->id, (int)sz, str);
-
-	/* TODO: Find the right version in supported ones */
-
-	ret  = (p - *buf);
-	*buf = p;
-	return ret;
-}
-
-/* Check max frame size value. It returns -1 if an error occurred, the number of
- * read bytes otherwise. */
-static int
-check_max_frame_size(struct spoe_frame *frame, char **buf, char *end)
-{
-	char    *p = *buf;
-	uint64_t sz;
-	int      type, ret;
-
-	/* Get the max-frame-size value of HAProxy */
-	type =  *p++;
-	if ((type & SPOE_DATA_T_MASK) != SPOE_DATA_T_INT32  &&
-	    (type & SPOE_DATA_T_MASK) != SPOE_DATA_T_INT64  &&
-	    (type & SPOE_DATA_T_MASK) != SPOE_DATA_T_UINT32 &&
-	    (type & SPOE_DATA_T_MASK) != SPOE_DATA_T_UINT64)
-		return -1;
-	if (decode_varint(&p, end, &sz) == -1)
-		return -1;
-
-	/* Keep the lower value */
-	if (sz < frame->client->max_frame_size)
-		frame->client->max_frame_size = sz;
-
-	DEBUG(frame->worker, "<%lu> HAProxy maximum frame size : %u",
-	      frame->client->id, (unsigned int)sz);
-
-	ret  = (p - *buf);
-	*buf = p;
-	return ret;
-}
-
-/* Check healthcheck value. It returns -1 if an error occurred, the number of
- * read bytes otherwise. */
-static int
-check_healthcheck(struct spoe_frame *frame, char **buf, char *end)
-{
-	char *p = *buf;
-	int   type, ret;
-
-	/* Get the "healthcheck" value */
-	type = *p++;
-	if ((type & SPOE_DATA_T_MASK) != SPOE_DATA_T_BOOL)
-		return -1;
-	frame->hcheck = ((type & SPOE_DATA_FL_TRUE) == SPOE_DATA_FL_TRUE);
-
-	DEBUG(frame->worker, "<%lu> HELLO healthcheck : %s",
-	      frame->client->id, (frame->hcheck ? "true" : "false"));
-
-	ret  = (p - *buf);
-	*buf = p;
-	return ret;
-}
-
-/* Check capabilities value. It returns -1 if an error occurred, the number of
- * read bytes otherwise. */
-static int
-check_capabilities(struct spoe_frame *frame, char **buf, char *end)
-{
-	struct client *client = frame->client;
-	char          *str, *p = *buf;
-	uint64_t       sz;
-	int            ret;
-
-	if ((*p++ & SPOE_DATA_T_MASK) != SPOE_DATA_T_STR)
-		return -1;
-	if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-		return -1;
-	if (str == NULL) /* this is not an error */
-		goto end;
-
-	DEBUG(frame->worker, "<%lu> HAProxy capabilities : %.*s",
-	      client->id, (int)sz, str);
-
-	while (sz) {
-		char *delim;
-
-		/* Skip leading spaces */
-		for (; isspace(*str) && sz; sz--);
-
-		if (sz >= 10 && !strncmp(str, "pipelining", 10)) {
-			str += 10; sz -= 10;
-			if (!sz || isspace(*str) || *str == ',') {
-				DEBUG(frame->worker,
-				      "<%lu> HAProxy supports frame pipelining",
-				      client->id);
-				client->pipelining = true;
-			}
-		}
-		else if (sz >= 5 && !strncmp(str, "async", 5)) {
-			str += 5; sz -= 5;
-			if (!sz || isspace(*str) || *str == ',') {
-				DEBUG(frame->worker,
-				      "<%lu> HAProxy supports asynchronous frame",
-				      client->id);
-				client->async = true;
-			}
-		}
-		else if (sz >= 13 && !strncmp(str, "fragmentation", 13)) {
-			str += 13; sz -= 13;
-			if (!sz || isspace(*str) || *str == ',') {
-				DEBUG(frame->worker,
-				      "<%lu> HAProxy supports fragmented frame",
-				      client->id);
-				client->fragmentation = true;
-			}
-		}
-
-		if (!sz || (delim = memchr(str, ',', sz)) == NULL)
-			break;
-		delim++;
-		sz -= (delim - str);
-		str = delim;
-	}
-  end:
-	ret  = (p - *buf);
-	*buf = p;
-	return ret;
-}
-
-/* Check engine-id value. It returns -1 if an error occurred, the number of
- * read bytes otherwise. */
-static int
-check_engine_id(struct spoe_frame *frame, char **buf, char *end)
-{
-	struct client *client = frame->client;
-	char          *str, *p = *buf;
-	uint64_t       sz;
-	int            ret;
-
-	if ((*p++ & SPOE_DATA_T_MASK) != SPOE_DATA_T_STR)
-		return -1;
-
-	if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-		return -1;
-	if (str == NULL) /* this is not an error */
-		goto end;
-
-	if (client->engine != NULL)
-		goto end;
-
-	DEBUG(frame->worker, "<%lu> HAProxy engine id : %.*s",
-	      client->id, (int)sz, str);
-
-	client->engine_id = strndup(str, (int)sz);
-  end:
-	ret  = (p - *buf);
-	*buf = p;
-	return ret;
-}
-
-static int
-acc_payload(struct spoe_frame *frame)
-{
-	struct client *client = frame->client;
-	char          *buf;
-	size_t         len = frame->len - frame->offset;
-	int            ret = frame->offset;
-
-	/* No need to accumulation payload */
-	if (frame->fragmented == false)
-		return ret;
-
-	buf = realloc(frame->frag_buf, frame->frag_len + len);
-	if (buf == NULL) {
-		client->status_code = SPOE_FRM_ERR_RES;
-		return -1;
-	}
-	memcpy(buf + frame->frag_len, frame->buf + frame->offset, len);
-	frame->frag_buf  = buf;
-	frame->frag_len += len;
-
-	if (!(frame->flags & SPOE_FRM_FL_FIN)) {
-		/* Wait for next parts */
-		frame->buf    = (char *)(frame->data);
-		frame->offset = 0;
-		frame->len    = 0;
-		frame->flags  = 0;
-		return 1;
-	}
-
-	frame->buf    = frame->frag_buf;
-	frame->len    = frame->frag_len;
-	frame->offset = 0;
-	return ret;
-}
-
-/* Check disconnect status code. It returns -1 if an error occurred, the number
- * of read bytes otherwise. */
-static int
-check_discon_status_code(struct spoe_frame *frame, char **buf, char *end)
-{
-	char    *p = *buf;
-	uint64_t sz;
-	int      type, ret;
-
-	/* Get the "status-code" value */
-	type =  *p++;
-	if ((type & SPOE_DATA_T_MASK) != SPOE_DATA_T_INT32 &&
-	    (type & SPOE_DATA_T_MASK) != SPOE_DATA_T_INT64 &&
-	    (type & SPOE_DATA_T_MASK) != SPOE_DATA_T_UINT32 &&
-	    (type & SPOE_DATA_T_MASK) != SPOE_DATA_T_UINT64)
-		return -1;
-	if (decode_varint(&p, end, &sz) == -1)
-		return -1;
-
-	frame->client->status_code = (unsigned int)sz;
-
-	DEBUG(frame->worker, "<%lu> Disconnect status code : %u",
-	      frame->client->id, frame->client->status_code);
-
-	ret  = (p - *buf);
-	*buf = p;
-	return ret;
-}
-
-/* Check the disconnect message. It returns -1 if an error occurred, the number
- * of read bytes otherwise. */
-static int
-check_discon_message(struct spoe_frame *frame, char **buf, char *end)
-{
-	char    *str, *p = *buf;
-	uint64_t sz;
-	int      ret;
-
-	/* Get the "message" value */
-	if ((*p++ & SPOE_DATA_T_MASK) != SPOE_DATA_T_STR)
-		return -1;
-	ret = spoe_decode_buffer(&p, end, &str, &sz);
-	if (ret == -1 || !str)
-		return -1;
-
-	DEBUG(frame->worker, "<%lu> Disconnect message : %.*s",
-	      frame->client->id, (int)sz, str);
-
-	ret  = (p - *buf);
-	*buf = p;
-	return ret;
-}
-
-
-
-/* Decode a HELLO frame received from HAProxy. It returns -1 if an error
- * occurred, otherwise the number of read bytes. HELLO frame cannot be
- * ignored and having another frame than a HELLO frame is an error. */
-static int
-handle_hahello(struct spoe_frame *frame)
-{
-	struct client *client = frame->client;
-	char          *p, *end;
-
-	p = frame->buf;
-	end = frame->buf + frame->len;
-
-	/* Check frame type: we really want a HELLO frame */
-	if (*p++ != SPOE_FRM_T_HAPROXY_HELLO)
-		goto error;
-
-	DEBUG(frame->worker, "<%lu> Decode HAProxy HELLO frame", client->id);
-
-	/* Retrieve flags */
-	memcpy((char *)&(frame->flags), p, 4);
-	frame->flags = ntohl(frame->flags);
-	p += 4;
-
-	/* Fragmentation is not supported for HELLO frame */
-	if (!(frame->flags & SPOE_FRM_FL_FIN)) {
-		client->status_code = SPOE_FRM_ERR_FRAG_NOT_SUPPORTED;
-		goto error;
-	}
-
-	/* stream-id and frame-id must be cleared */
-	if (*p != 0 || *(p+1) != 0) {
-		client->status_code = SPOE_FRM_ERR_INVALID;
-		goto error;
-	}
-	p += 2;
-
-	/* Loop on K/V items */
-	while (p < end) {
-		char     *str;
-		uint64_t  sz;
-
-		/* Decode the item name */
-		spoe_decode_buffer(&p, end, &str, &sz);
-		if (!str) {
-			client->status_code = SPOE_FRM_ERR_INVALID;
-			goto error;
-		}
-
-		/* Check "supported-versions" K/V item */
-		if (!memcmp(str, "supported-versions", sz)) {
-			if (check_proto_version(frame, &p, end)  == -1) {
-				client->status_code = SPOE_FRM_ERR_INVALID;
-				goto error;
-			}
-		}
-		/* Check "max-frame-size" K/V item */
-		else if (!memcmp(str, "max-frame-size", sz)) {
-			if (check_max_frame_size(frame, &p, end) == -1) {
-				client->status_code = SPOE_FRM_ERR_INVALID;
-				goto error;
-			}
-		}
-		/* Check "healthcheck" K/V item */
-		else if (!memcmp(str, "healthcheck", sz)) {
-			if (check_healthcheck(frame, &p, end) == -1) {
-				client->status_code = SPOE_FRM_ERR_INVALID;
-				goto error;
-			}
-		}
-		/* Check "capabilities" K/V item */
-		else if (!memcmp(str, "capabilities", sz)) {
-			if (check_capabilities(frame, &p, end) == -1) {
-				client->status_code = SPOE_FRM_ERR_INVALID;
-				goto error;
-			}
-		}
-		/* Check "engine-id" K/V item */
-		else if (!memcmp(str, "engine-id", sz)) {
-			if (check_engine_id(frame, &p, end) == -1) {
-				client->status_code = SPOE_FRM_ERR_INVALID;
-				goto error;
-			}
-		}
-		else {
-			DEBUG(frame->worker, "<%lu> Skip K/V item : key=%.*s",
-			      client->id, (int)sz, str);
-
-			/* Silently ignore unknown item */
-			if (spoe_skip_data(&p, end) == -1) {
-				client->status_code = SPOE_FRM_ERR_INVALID;
-				goto error;
-			}
-		}
-	}
-
-	if (async == false || client->engine_id == NULL)
-		client->async = false;
-	if (pipelining == false)
-		client->pipelining = false;
-
-	if (client->async == true)
-		use_spoe_engine(client);
-
-	return (p - frame->buf);
-  error:
-	return -1;
-}
-
-/* Decode a DISCONNECT frame received from HAProxy. It returns -1 if an error
- * occurred, otherwise the number of read bytes. DISCONNECT frame cannot be
- * ignored and having another frame than a DISCONNECT frame is an error.*/
-static int
-handle_hadiscon(struct spoe_frame *frame)
-{
-	struct client *client = frame->client;
-	char          *p, *end;
-
-	p = frame->buf;
-	end = frame->buf + frame->len;
-
-	/* Check frame type: we really want a DISCONNECT frame */
-	if (*p++ != SPOE_FRM_T_HAPROXY_DISCON)
-		goto error;
-
-	DEBUG(frame->worker, "<%lu> Decode HAProxy DISCONNECT frame", client->id);
-
-	/* Retrieve flags */
-	memcpy((char *)&(frame->flags), p, 4);
-	frame->flags = ntohl(frame->flags);
-	p += 4;
-
-	/* Fragmentation is not supported for DISCONNECT frame */
-	if (!(frame->flags & SPOE_FRM_FL_FIN)) {
-		client->status_code = SPOE_FRM_ERR_FRAG_NOT_SUPPORTED;
-		goto error;
-	}
-
-	/* stream-id and frame-id must be cleared */
-	if (*p != 0 || *(p+1) != 0) {
-		client->status_code = SPOE_FRM_ERR_INVALID;
-		goto error;
-	}
-	p += 2;
-
-	client->status_code = SPOE_FRM_ERR_NONE;
-
-	/* Loop on K/V items */
-	while (p < end) {
-		char     *str;
-		uint64_t  sz;
-
-		/* Decode item key */
-		spoe_decode_buffer(&p, end, &str, &sz);
-		if (!str) {
-			client->status_code = SPOE_FRM_ERR_INVALID;
-			goto error;
-		}
-
-		/* Check "status-code" K/V item */
-		if (!memcmp(str, "status-code", sz)) {
-			if (check_discon_status_code(frame, &p, end) == -1) {
-				client->status_code = SPOE_FRM_ERR_INVALID;
-				goto error;
-			}
-		}
-		/* Check "message" K/V item */
-		else if (!memcmp(str, "message", sz)) {
-			if (check_discon_message(frame, &p, end) == -1) {
-				client->status_code = SPOE_FRM_ERR_INVALID;
-				goto error;
-			}
-		}
-		else {
-			DEBUG(frame->worker, "<%lu> Skip K/V item : key=%.*s",
-			      client->id, (int)sz, str);
-
-			/* Silently ignore unknown item */
-			if (spoe_skip_data(&p, end) == -1) {
-				client->status_code = SPOE_FRM_ERR_INVALID;
-				goto error;
-			}
-		}
-	}
-
-	return (p - frame->buf);
-  error:
-	return -1;
-}
-
-/* Decode a NOTIFY frame received from HAProxy. It returns -1 if an error
- * occurred, 0 if it must be must be ignored, otherwise the number of read
- * bytes. */
-static int
-handle_hanotify(struct spoe_frame *frame)
-{
-	struct client *client = frame->client;
-	char          *p, *end;
-	uint64_t       stream_id, frame_id;
-
-	p = frame->buf;
-	end = frame->buf + frame->len;
-
-	/* Check frame type */
-	if (*p++ != SPOE_FRM_T_HAPROXY_NOTIFY)
-		goto ignore;
-
-	DEBUG(frame->worker, "<%lu> Decode HAProxy NOTIFY frame", client->id);
-
-	/* Retrieve flags */
-	memcpy((char *)&(frame->flags), p, 4);
-	frame->flags = ntohl(frame->flags);
-	p += 4;
-
-	/* Fragmentation is not supported */
-	if (!(frame->flags & SPOE_FRM_FL_FIN) && fragmentation == false) {
-		client->status_code = SPOE_FRM_ERR_FRAG_NOT_SUPPORTED;
-		goto error;
-	}
-
-	/* Read the stream-id and frame-id */
-	if (decode_varint(&p, end, &stream_id) == -1)
-		goto ignore;
-	if (decode_varint(&p, end, &frame_id) == -1)
-		goto ignore;
-
-	frame->stream_id = (unsigned int)stream_id;
-	frame->frame_id  = (unsigned int)frame_id;
-
-	DEBUG(frame->worker, "<%lu> STREAM-ID=%u - FRAME-ID=%u"
-	      " - %s frame received"
-	      " - frag_len=%u - len=%u - offset=%ld",
-	      client->id, frame->stream_id, frame->frame_id,
-	      (frame->flags & SPOE_FRM_FL_FIN) ? "unfragmented" : "fragmented",
-	      frame->frag_len, frame->len, p - frame->buf);
-
-	frame->fragmented = !(frame->flags & SPOE_FRM_FL_FIN);
-	frame->offset = (p - frame->buf);
-	return acc_payload(frame);
-
-  ignore:
-	return 0;
-
-  error:
-	return -1;
-}
-
-/* Decode next part of a fragmented frame received from HAProxy. It returns -1
- * if an error occurred, 0 if it must be must be ignored, otherwise the number
- * of read bytes. */
-static int
-handle_hafrag(struct spoe_frame *frame)
-{
-	struct client *client = frame->client;
-	char          *p, *end;
-	uint64_t       stream_id, frame_id;
-
-	p = frame->buf;
-	end = frame->buf + frame->len;
-
-	/* Check frame type */
-	if (*p++ != SPOE_FRM_T_UNSET)
-		goto ignore;
-
-	DEBUG(frame->worker, "<%lu> Decode Next part of a fragmented frame", client->id);
-
-	/* Fragmentation is not supported */
-	if (fragmentation == false) {
-		client->status_code = SPOE_FRM_ERR_FRAG_NOT_SUPPORTED;
-		goto error;
-	}
-
-	/* Retrieve flags */
-	memcpy((char *)&(frame->flags), p, 4);
-	frame->flags = ntohl(frame->flags);
-	p+= 4;
-
-	/* Read the stream-id and frame-id */
-	if (decode_varint(&p, end, &stream_id) == -1)
-		goto ignore;
-	if (decode_varint(&p, end, &frame_id) == -1)
-		goto ignore;
-
-	if (frame->fragmented == false                  ||
-	    frame->stream_id != (unsigned int)stream_id ||
-	    frame->frame_id  != (unsigned int)frame_id) {
-		client->status_code = SPOE_FRM_ERR_INTERLACED_FRAMES;
-		goto error;
-	}
-
-	if (frame->flags & SPOE_FRM_FL_ABRT) {
-		DEBUG(frame->worker, "<%lu> STREAM-ID=%u - FRAME-ID=%u"
-		      " - Abort processing of a fragmented frame"
-		      " - frag_len=%u - len=%u - offset=%ld",
-		      client->id, frame->stream_id, frame->frame_id,
-		      frame->frag_len, frame->len, p - frame->buf);
-		goto ignore;
-	}
-
-	DEBUG(frame->worker, "<%lu> STREAM-ID=%u - FRAME-ID=%u"
-	      " - %s fragment of a fragmented frame received"
-	      " - frag_len=%u - len=%u - offset=%ld",
-	      client->id, frame->stream_id, frame->frame_id,
-	      (frame->flags & SPOE_FRM_FL_FIN) ? "last" : "next",
-	      frame->frag_len, frame->len, p - frame->buf);
-
-	frame->offset = (p - frame->buf);
-	return acc_payload(frame);
-
-  ignore:
-	return 0;
-
-  error:
-	return -1;
-}
-
-/* Encode a HELLO frame to send it to HAProxy. It returns the number of written
- * bytes. */
-static int
-prepare_agenthello(struct spoe_frame *frame)
-{
-	struct client *client = frame->client;
-	char          *p, *end;
-	char           capabilities[64];
-	int            n;
-	unsigned int   flags  = SPOE_FRM_FL_FIN;
-
-	DEBUG(frame->worker, "<%lu> Encode Agent HELLO frame", client->id);
-	frame->type = SPOA_FRM_T_AGENT;
-
-	p   = frame->buf;
-	end = frame->buf+max_frame_size;
-
-	/* Frame Type */
-	*p++ = SPOE_FRM_T_AGENT_HELLO;
-
-	/* Set flags */
-	flags = htonl(flags);
-	memcpy(p, (char *)&flags, 4);
-	p += 4;
-
-	/* No stream-id and frame-id for HELLO frames */
-	*p++ = 0;
-	*p++ = 0;
-
-	/* "version" K/V item */
-	spoe_encode_buffer("version", 7, &p, end);
-	*p++ = SPOE_DATA_T_STR;
-	spoe_encode_buffer(SPOP_VERSION, SLEN(SPOP_VERSION), &p, end);
-	DEBUG(frame->worker, "<%lu> Agent version : %s",
-	      client->id, SPOP_VERSION);
-
-
-	/* "max-frame-size" K/V item */
-	spoe_encode_buffer("max-frame-size", 14, &p ,end);
-	*p++ = SPOE_DATA_T_UINT32;
-	encode_varint(client->max_frame_size, &p, end);
-	DEBUG(frame->worker, "<%lu> Agent maximum frame size : %u",
-	      client->id, client->max_frame_size);
-
-	/* "capabilities" K/V item */
-	spoe_encode_buffer("capabilities", 12, &p, end);
-	*p++ = SPOE_DATA_T_STR;
-
-	memset(capabilities, 0, sizeof(capabilities));
-	n = 0;
-
-	/*     1. Fragmentation capability ? */
-	if (fragmentation == true) {
-		memcpy(capabilities, "fragmentation", 13);
-		n += 13;
-	}
-	/*     2. Pipelining capability ? */
-	if (client->pipelining == true) {
-		if (n) capabilities[n++] = ',';
-		memcpy(capabilities + n, "pipelining", 10);
-		n += 10;
-	}
-	/*     3. Async capability ? */
-	if (client->async == true) {
-		if (n) capabilities[n++] = ',';
-		memcpy(capabilities + n, "async", 5);
-		n += 5;
-	}
-	spoe_encode_buffer(capabilities, n, &p, end);
-
-	DEBUG(frame->worker, "<%lu> Agent capabilities : %.*s",
-	      client->id, n, capabilities);
-
-	frame->len = (p - frame->buf);
-	return frame->len;
-}
-
-/* Encode a DISCONNECT frame to send it to HAProxy. It returns the number of
- * written bytes. */
-static int
-prepare_agentdicon(struct spoe_frame *frame)
-{
-	struct client *client = frame->client;
-	char           *p, *end;
-	const char     *reason;
-	int             rlen;
-	unsigned int    flags  = SPOE_FRM_FL_FIN;
-
-	DEBUG(frame->worker, "<%lu> Encode Agent DISCONNECT frame", client->id);
-	frame->type = SPOA_FRM_T_AGENT;
-
-	p   = frame->buf;
-	end = frame->buf+max_frame_size;
-
-	if (client->status_code >= SPOE_FRM_ERRS)
-		client->status_code = SPOE_FRM_ERR_UNKNOWN;
-	reason = spoe_frm_err_reasons[client->status_code];
-	rlen   = strlen(reason);
-
-	/* Frame type */
-	*p++ = SPOE_FRM_T_AGENT_DISCON;
-
-	/* Set flags */
-	flags = htonl(flags);
-	memcpy(p, (char *)&flags, 4);
-	p += 4;
-
-	/* No stream-id and frame-id for DISCONNECT frames */
-	*p++ = 0;
-	*p++ = 0;
-
-	/* There are 2 mandatory items: "status-code" and "message" */
-
-	/* "status-code" K/V item */
-	spoe_encode_buffer("status-code", 11, &p, end);
-	*p++ = SPOE_DATA_T_UINT32;
-	encode_varint(client->status_code, &p, end);
-	DEBUG(frame->worker, "<%lu> Disconnect status code : %u",
-	      client->id, client->status_code);
-
-	/* "message" K/V item */
-	spoe_encode_buffer("message", 7, &p, end);
-	*p++ = SPOE_DATA_T_STR;
-	spoe_encode_buffer(reason, rlen, &p, end);
-	DEBUG(frame->worker, "<%lu> Disconnect message : %s",
-	      client->id, reason);
-
-	frame->len = (p - frame->buf);
-	return frame->len;
-}
-
-/* Encode a ACK frame to send it to HAProxy. It returns the number of written
- * bytes. */
-static int
-prepare_agentack(struct spoe_frame *frame)
-{
-	char        *p, *end;
-	unsigned int flags  = SPOE_FRM_FL_FIN;
-
-	/* Be careful here, in async mode, frame->client can be NULL */
-
-	DEBUG(frame->worker, "Encode Agent ACK frame");
-	frame->type = SPOA_FRM_T_AGENT;
-
-	p   = frame->buf;
-	end = frame->buf+max_frame_size;
-
-	/* Frame type */
-	*p++ = SPOE_FRM_T_AGENT_ACK;
-
-	/* Set flags */
-	flags = htonl(flags);
-	memcpy(p, (char *)&flags, 4);
-	p += 4;
-
-	/* Set stream-id and frame-id for ACK frames */
-	encode_varint(frame->stream_id, &p, end);
-	encode_varint(frame->frame_id, &p, end);
-
-	DEBUG(frame->worker, "STREAM-ID=%u - FRAME-ID=%u",
-	      frame->stream_id, frame->frame_id);
-
-	frame->len = (p - frame->buf);
-	return frame->len;
-}
-
-static int
-create_server_socket(void)
-{
-	struct sockaddr_in listen_addr;
-	int                fd, yes = 1;
-
-	fd = socket(AF_INET, SOCK_STREAM, 0);
-	if (fd < 0) {
-		LOG(&null_worker, "Failed to create service socket : %m");
-		return -1;
-	}
-
-	memset(&listen_addr, 0, sizeof(listen_addr));
-	listen_addr.sin_family = AF_INET;
-	listen_addr.sin_addr.s_addr = INADDR_ANY;
-	listen_addr.sin_port = htons(server_port);
-
-	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0 ||
-	    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) < 0) {
-		LOG(&null_worker, "Failed to set option on server socket : %m");
-		return -1;
-	}
-
-	if (bind(fd, (struct sockaddr *) &listen_addr, sizeof(listen_addr)) < 0) {
-		LOG(&null_worker, "Failed to bind server socket : %m");
-		return -1;
-	}
-
-	if (listen(fd, CONNECTION_BACKLOG) < 0) {
-		LOG(&null_worker, "Failed to listen on server socket : %m");
-		return -1;
-	}
-
-	return fd;
-}
-
-static void
-release_frame(struct spoe_frame *frame)
-{
-	struct worker *worker;
-
-	if (frame == NULL)
-		return;
-
-	if (event_pending(&frame->process_frame_event, EV_TIMEOUT, NULL))
-		event_del(&frame->process_frame_event);
-
-	worker = frame->worker;
-	LIST_DELETE(&frame->list);
-	if (frame->frag_buf)
-		free(frame->frag_buf);
-	memset(frame, 0, sizeof(*frame)+max_frame_size+4);
-	LIST_APPEND(&worker->frames, &frame->list);
-}
-
-static void
-release_client(struct client *c)
-{
-	struct spoe_frame *frame, *back;
-
-	if (c == NULL)
-		return;
-
-	DEBUG(c->worker, "<%lu> Release client", c->id);
-
-	LIST_DELETE(&c->by_worker);
-	c->worker->nbclients--;
-
-	unuse_spoe_engine(c);
-	free(c->engine_id);
-
-	if (event_pending(&c->read_frame_event, EV_READ, NULL))
-		event_del(&c->read_frame_event);
-	if (event_pending(&c->write_frame_event, EV_WRITE, NULL))
-		event_del(&c->write_frame_event);
-
-	release_frame(c->incoming_frame);
-	release_frame(c->outgoing_frame);
-	list_for_each_entry_safe(frame, back, &c->processing_frames, list) {
-		release_frame(frame);
-	}
-	list_for_each_entry_safe(frame, back, &c->outgoing_frames, list) {
-		release_frame(frame);
-	}
-
-	if (c->fd >= 0)
-		close(c->fd);
-
-	free(c);
-}
-
-static void
-reset_frame(struct spoe_frame *frame)
-{
-	if (frame == NULL)
-		return;
-
-	if (frame->frag_buf)
-		free(frame->frag_buf);
-
-	frame->type            = SPOA_FRM_T_UNKNOWN;
-	frame->buf             = (char *)(frame->data);
-	frame->offset          = 0;
-	frame->len             = 0;
-	frame->stream_id       = 0;
-	frame->frame_id        = 0;
-	frame->flags           = 0;
-	frame->hcheck          = false;
-	frame->fragmented      = false;
-	frame->defender_status = -1;
-	frame->frag_buf        = NULL;
-	frame->frag_len        = 0;
-	LIST_INIT(&frame->list);
-}
-
-static void
-use_spoe_engine(struct client *client)
-{
-	struct spoe_engine *eng;
-
-	if (client->engine_id == NULL)
-		return;
-
-	list_for_each_entry(eng, &client->worker->engines, list) {
-		if (strcmp(eng->id, client->engine_id) == 0)
-			goto end;
-	}
-
-	if ((eng = malloc(sizeof(*eng))) == NULL) {
-		client->async = false;
-		return;
-	}
-
-	eng->id = strdup(client->engine_id);
-	LIST_INIT(&eng->clients);
-	LIST_INIT(&eng->processing_frames);
-	LIST_INIT(&eng->outgoing_frames);
-	LIST_APPEND(&client->worker->engines, &eng->list);
-	LOG(client->worker, "Add new SPOE engine '%s'", eng->id);
-
-  end:
-	client->engine = eng;
-	LIST_APPEND(&eng->clients, &client->by_engine);
-}
-
-static void
-unuse_spoe_engine(struct client *client)
-{
-	struct spoe_engine *eng;
-	struct spoe_frame  *frame, *back;
-
-	if (client == NULL || client->engine == NULL)
-		return;
-
-	eng = client->engine;
-	client->engine = NULL;
-	LIST_DELETE(&client->by_engine);
-	if (!LIST_ISEMPTY(&eng->clients))
-		return;
-
-	LOG(client->worker, "Remove SPOE engine '%s'", eng->id);
-	LIST_DELETE(&eng->list);
-
-	list_for_each_entry_safe(frame, back, &eng->processing_frames, list) {
-		release_frame(frame);
-	}
-	list_for_each_entry_safe(frame, back, &eng->outgoing_frames, list) {
-		release_frame(frame);
-	}
-	free(eng->id);
-	free(eng);
-}
-
-
-static struct spoe_frame *
-acquire_incoming_frame(struct client *client)
-{
-	struct spoe_frame *frame;
-
-	frame = client->incoming_frame;
-	if (frame != NULL)
-		return frame;
-
-	if (LIST_ISEMPTY(&client->worker->frames)) {
-		if ((frame = calloc(1, sizeof(*frame)+max_frame_size+4)) == NULL) {
-			LOG(client->worker, "Failed to allocate new frame : %m");
-			return NULL;
-		}
-	}
-	else {
-		frame = LIST_NEXT(&client->worker->frames, typeof(frame), list);
-		LIST_DELETE(&frame->list);
-	}
-
-	reset_frame(frame);
-	frame->worker = client->worker;
-	frame->engine = client->engine;
-	frame->client = client;
-
-	if (event_assign(&frame->process_frame_event, client->worker->base, -1,
-			 EV_TIMEOUT|EV_PERSIST, process_frame_cb, frame) < 0) {
-		LOG(client->worker, "Failed to create frame event");
-		return NULL;
-	}
-
-	client->incoming_frame = frame;
-	return frame;
-}
-
-static struct spoe_frame *
-acquire_outgoing_frame(struct client *client)
-{
-	struct spoe_engine *engine = client->engine;
-	struct spoe_frame  *frame = NULL;
-
-	if (client->outgoing_frame != NULL)
-		frame = client->outgoing_frame;
-	else if (!LIST_ISEMPTY(&client->outgoing_frames)) {
-		frame = LIST_NEXT(&client->outgoing_frames, typeof(frame), list);
-		LIST_DELETE(&frame->list);
-		client->outgoing_frame = frame;
-	}
-	else if (engine!= NULL && !LIST_ISEMPTY(&engine->outgoing_frames)) {
-		frame = LIST_NEXT(&engine->outgoing_frames, typeof(frame), list);
-		LIST_DELETE(&frame->list);
-		client->outgoing_frame = frame;
-	}
-	return frame;
-}
-
-static void
-write_frame(struct client *client, struct spoe_frame *frame)
-{
-	uint32_t netint;
-
-	LIST_DELETE(&frame->list);
-
-	frame->buf    = (char *)(frame->data);
-	frame->offset = 0;
-	netint        = htonl(frame->len);
-	memcpy(frame->buf, &netint, 4);
-
-	if (client != NULL) { /* HELLO or DISCONNECT frames */
-		event_add(&client->write_frame_event, NULL);
-
-		/* Try to process the frame as soon as possible, and always
-		 * attach it to the client */
-		if (client->async || client->pipelining) {
-			if (client->outgoing_frame == NULL)
-				client->outgoing_frame = frame;
-			else
-				LIST_INSERT(&client->outgoing_frames, &frame->list);
-		}
-		else {
-			client->outgoing_frame = frame;
-			event_del(&client->read_frame_event);
-		}
-	}
-	else { /* for all other frames */
-		if (frame->client == NULL) { /* async mode ! */
-			LIST_APPEND(&frame->engine->outgoing_frames, &frame->list);
-			list_for_each_entry(client, &frame->engine->clients, by_engine)
-				event_add(&client->write_frame_event, NULL);
-		}
-		else if (frame->client->pipelining) {
-			LIST_APPEND(&frame->client->outgoing_frames, &frame->list);
-			event_add(&frame->client->write_frame_event, NULL);
-		}
-		else {
-			frame->client->outgoing_frame = frame;
-			event_add(&frame->client->write_frame_event, NULL);
-			event_del(&frame->client->read_frame_event);
-		}
-	}
-}
-
-static void
-process_incoming_frame(struct spoe_frame *frame)
-{
-	struct client *client = frame->client;
-
-	if (event_add(&frame->process_frame_event, &processing_delay) < 0) {
-		LOG(client->worker, "Failed to process incoming frame");
-		release_frame(frame);
-		return;
-	}
-
-	if (client->async) {
-		frame->client = NULL;
-		LIST_APPEND(&frame->engine->processing_frames, &frame->list);
-	}
-	else if (client->pipelining)
-		LIST_APPEND(&client->processing_frames, &frame->list);
-	else
-		event_del(&client->read_frame_event);
-}
-
-static void
-signal_cb(evutil_socket_t sig, short events, void *user_data)
-{
-	struct event_base *base = user_data;
-	int                i;
-
-	DEBUG(&null_worker, "Stopping the server");
-
-	event_base_loopbreak(base);
-	DEBUG(&null_worker, "Main event loop stopped");
-
-	for (i = 0; i < num_workers; i++) {
-		event_base_loopbreak(workers[i].base);
-		DEBUG(&null_worker, "Event loop stopped for worker %02d",
-		      workers[i].id);
-	}
-}
-
-static void
-worker_monitor_cb(evutil_socket_t fd, short events, void *arg)
-{
-	struct worker *worker = arg;
-
-	LOG(worker, "%u clients connected", worker->nbclients);
-}
-
-static void
-process_frame_cb(evutil_socket_t fd, short events, void *arg)
-{
-	struct spoe_frame *frame  = arg;
-	char              *p, *end;
-	int                ret;
-
-	DEBUG(frame->worker,
-	      "Process frame messages : STREAM-ID=%u - FRAME-ID=%u - length=%u bytes",
-	      frame->stream_id, frame->frame_id, frame->len - frame->offset);
-
-	p   = frame->buf + frame->offset;
-	end = frame->buf + frame->len;
-
-	/* Loop on messages */
-	while (p < end) {
-		char    *str;
-		uint64_t sz;
-		int      nbargs;
-
-		/* Decode the message name */
-		spoe_decode_buffer(&p, end, &str, &sz);
-		if (!str)
-			goto stop_processing;
-
-		DEBUG(frame->worker, "Process SPOE Message '%.*s'", (int)sz, str);
-
-		nbargs = *p++;                     /* Get the number of arguments */
-		frame->offset = (p - frame->buf);  /* Save index to handle errors and skip args */
-		if (!memcmp(str, "check-request", sz)) {
-			struct defender_request request;
-
-			memset(&request, 0, sizeof(request));
-
-			if (nbargs != 8)
-				goto skip_message;
-
-			if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-				goto stop_processing;
-			if (spoe_decode_data(&p, end, &request.clientip) == -1)
-				goto skip_message;
-
-			if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-				goto stop_processing;
-			if (spoe_decode_data(&p, end, &request.id) == -1)
-				goto skip_message;
-
-			if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-				goto stop_processing;
-			if (spoe_decode_data(&p, end, &request.method) == -1)
-				goto skip_message;
-
-			if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-				goto stop_processing;
-			if (spoe_decode_data(&p, end, &request.path) == -1)
-				goto skip_message;
-
-			if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-				goto stop_processing;
-			if (spoe_decode_data(&p, end, &request.query) == -1)
-				goto skip_message;
-
-			if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-				goto stop_processing;
-			if (spoe_decode_data(&p, end, &request.version) == -1)
-				goto skip_message;
-
-			if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-				goto stop_processing;
-			if (spoe_decode_data(&p, end, &request.headers) == -1)
-				goto skip_message;
-
-			if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-				goto stop_processing;
-			if (spoe_decode_data(&p, end, &request.body) == -1)
-				goto skip_message;
-
-			frame->defender_status = defender_process_request(frame->worker, &request);
-		}
-		else {
-		  skip_message:
-			p = frame->buf + frame->offset; /* Restore index */
-
-			while (nbargs-- > 0) {
-				/* Silently ignore argument: its name and its value */
-				if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
-					goto stop_processing;
-				if (spoe_skip_data(&p, end) == -1)
-					goto stop_processing;
-			}
-		}
-	}
-
-  stop_processing:
-	/* Prepare agent ACK frame */
-	frame->buf    = (char *)(frame->data) + 4;
-	frame->offset = 0;
-	frame->len    = 0;
-	frame->flags  = 0;
-
-	ret = prepare_agentack(frame);
-	p   = frame->buf + ret;
-	end = frame->buf+max_frame_size;
-
-	if (frame->defender_status != -1) {
-		DEBUG(frame->worker, "Add action : set variable status=%u",
-		      frame->defender_status);
-
-		*p++ = SPOE_ACT_T_SET_VAR;                      /* Action type */
-		*p++ = 3;                                       /* Number of args */
-		*p++ = SPOE_SCOPE_SESS;                         /* Arg 1: the scope */
-		spoe_encode_buffer("status", 6, &p, end);       /* Arg 2: variable name */
-		*p++ = SPOE_DATA_T_UINT32;
-		encode_varint(frame->defender_status, &p, end); /* Arg 3: variable value */
-		frame->len = (p - frame->buf);
-	}
-	write_frame(NULL, frame);
-}
-
-static void
-read_frame_cb(evutil_socket_t fd, short events, void *arg)
-{
-	struct client     *client = arg;
-	struct spoe_frame *frame;
-	uint32_t           netint;
-	int                n;
-
-	DEBUG(client->worker, "<%lu> %s", client->id, __FUNCTION__);
-	if ((frame = acquire_incoming_frame(client)) == NULL)
-		goto close;
-
-	frame->type = SPOA_FRM_T_HAPROXY;
-	if (frame->buf == (char *)(frame->data)) {
-		/* Read the frame length: frame->buf points on length part (frame->data) */
-		n = read(client->fd, frame->buf+frame->offset, 4-frame->offset);
-		if (n <= 0) {
-			if (n < 0)
-				LOG(client->worker, "Failed to read frame length : %m");
-			goto close;
-		}
-		frame->offset += n;
-		if (frame->offset != 4)
-			return;
-		memcpy(&netint, frame->buf, 4);
-		frame->buf   += 4;
-		frame->offset = 0;
-		frame->len    = ntohl(netint);
-	}
-
-	/* Read the frame: frame->buf points on frame part (frame->data+4)*/
-	n = read(client->fd, frame->buf + frame->offset,
-		 frame->len - frame->offset);
-	if (n <= 0) {
-		if (n < 0) {
-			LOG(client->worker, "Frame to read frame : %m");
-			goto close;
-		}
-		return;
-	}
-	frame->offset += n;
-	if (frame->offset != frame->len)
-		return;
-	frame->offset = 0;
-
-	DEBUG(client->worker, "<%lu> New Frame of %u bytes received",
-	      client->id, frame->len);
-
-	switch (client->state) {
-		case SPOA_ST_CONNECTING:
-			if (handle_hahello(frame) < 0) {
-				LOG(client->worker, "Failed to decode HELLO frame");
-				goto disconnect;
-			}
-			prepare_agenthello(frame);
-			goto write_frame;
-
-		case SPOA_ST_PROCESSING:
-			if (frame->buf[0] == SPOE_FRM_T_HAPROXY_DISCON) {
-				client->state = SPOA_ST_DISCONNECTING;
-				goto disconnecting;
-			}
-			if (frame->buf[0] == SPOE_FRM_T_UNSET)
-				n = handle_hafrag(frame);
-			else
-				n = handle_hanotify(frame);
-
-			if (n < 0) {
-				LOG(client->worker, "Failed to decode frame: %s",
-				    spoe_frm_err_reasons[client->status_code]);
-				goto disconnect;
-			}
-			else if (n == 0) {
-				LOG(client->worker, "Ignore invalid/unknown/aborted frame");
-				goto ignore_frame;
-			}
-			else if (n == 1)
-				goto noop;
-			else
-				goto process_frame;
-
-		case SPOA_ST_DISCONNECTING:
-		  disconnecting:
-			if (handle_hadiscon(frame) < 0) {
-				LOG(client->worker, "Failed to decode DISCONNECT frame");
-				goto disconnect;
-			}
-			if (client->status_code != SPOE_FRM_ERR_NONE)
-				LOG(client->worker, "<%lu> Peer closed connection: %s",
-				    client->id, spoe_frm_err_reasons[client->status_code]);
-			goto disconnect;
-	}
-
-  noop:
-	return;
-
-  ignore_frame:
-	reset_frame(frame);
-	return;
-
-  process_frame:
-	process_incoming_frame(frame);
-	client->incoming_frame = NULL;
-	return;
-
-  write_frame:
-	write_frame(client, frame);
-	client->incoming_frame = NULL;
-	return;
-
-  disconnect:
-	client->state = SPOA_ST_DISCONNECTING;
-	if (prepare_agentdicon(frame) < 0) {
-		LOG(client->worker, "Failed to encode DISCONNECT frame");
-		goto close;
-	}
-	goto write_frame;
-
-  close:
-	release_client(client);
-}
-
-static void
-write_frame_cb(evutil_socket_t fd, short events, void *arg)
-{
-	struct client     *client = arg;
-	struct spoe_frame *frame;
-	int                n;
-
-	DEBUG(client->worker, "<%lu> %s", client->id, __FUNCTION__);
-	if ((frame = acquire_outgoing_frame(client)) == NULL) {
-		event_del(&client->write_frame_event);
-		return;
-	}
-
-	if (frame->buf == (char *)(frame->data)) {
-		/* Write the frame length: frame->buf points on length part (frame->data) */
-		n = write(client->fd, frame->buf+frame->offset, 4-frame->offset);
-		if (n <= 0) {
-			if (n < 0)
-				LOG(client->worker, "Failed to write frame length : %m");
-			goto close;
-		}
-		frame->offset += n;
-		if (frame->offset != 4)
-			return;
-		frame->buf   += 4;
-		frame->offset = 0;
-	}
-
-	/* Write the frame: frame->buf points on frame part (frame->data+4)*/
-	n = write(client->fd, frame->buf + frame->offset,
-		  frame->len - frame->offset);
-	if (n <= 0) {
-		if (n < 0) {
-			LOG(client->worker, "Failed to write frame : %m");
-			goto close;
-		}
-		return;
-	}
-	frame->offset += n;
-	if (frame->offset != frame->len)
-		return;
-
-	DEBUG(client->worker, "<%lu> Frame of %u bytes send",
-	      client->id, frame->len);
-
-	switch (client->state) {
-		case SPOA_ST_CONNECTING:
-			if (frame->hcheck == true) {
-				DEBUG(client->worker,
-				      "<%lu> Close client after healthcheck",
-				      client->id);
-				goto close;
-			}
-			client->state = SPOA_ST_PROCESSING;
-			break;
-
-		case SPOA_ST_PROCESSING:
-			break;
-
-		case SPOA_ST_DISCONNECTING:
-			goto close;
-	}
-
-	release_frame(frame);
-	client->outgoing_frame = NULL;
-	if (!client->async && !client->pipelining) {
-		event_del(&client->write_frame_event);
-		event_add(&client->read_frame_event, NULL);
-	}
-	return;
-
-  close:
-	release_client(client);
-}
-
-static void
-accept_cb(int listener, short event, void *arg)
-{
-	struct worker     *worker;
-	struct client     *client;
-	int                fd;
-
-	worker = &workers[clicount++ % num_workers];
-
-	if ((fd = accept(listener, NULL, NULL)) < 0) {
-		if (errno != EAGAIN && errno != EWOULDBLOCK)
-			LOG(worker, "Failed to accept client connection : %m");
-		return;
-	}
-
-	DEBUG(&null_worker,
-	      "<%lu> New Client connection accepted and assigned to worker %02d",
-	      clicount, worker->id);
-
-	if (evutil_make_socket_nonblocking(fd) < 0) {
-		LOG(&null_worker, "Failed to set client socket to non-blocking : %m");
-		close(fd);
-		return;
-	}
-
-	if ((client = calloc(1, sizeof(*client))) == NULL) {
-		LOG(&null_worker, "Failed to allocate memory for client state : %m");
-		close(fd);
-		return;
-	}
-
-	client->id             = clicount;
-	client->fd             = fd;
-	client->worker         = worker;
-	client->state          = SPOA_ST_CONNECTING;
-	client->status_code    = SPOE_FRM_ERR_NONE;
-	client->max_frame_size = max_frame_size;
-	client->engine         = NULL;
-	client->pipelining     = false;
-	client->async          = false;
-	client->incoming_frame = NULL;
-	client->outgoing_frame = NULL;
-	LIST_INIT(&client->processing_frames);
-	LIST_INIT(&client->outgoing_frames);
-
-	LIST_APPEND(&worker->clients, &client->by_worker);
-
-	worker->nbclients++;
-
-	if (event_assign(&client->read_frame_event, worker->base, fd,
-			 EV_READ|EV_PERSIST, read_frame_cb, client) < 0     ||
-	    event_assign(&client->write_frame_event, worker->base, fd,
-			 EV_WRITE|EV_PERSIST, write_frame_cb, client) < 0) {
-		LOG(&null_worker, "Failed to create client events");
-		release_client(client);
-		return;
-	}
-	event_add(&client->read_frame_event,  NULL);
-}
-
-static void *
-worker_function(void *data)
-{
-	struct client     *client, *cback;
-	struct spoe_frame *frame, *fback;
-	struct worker     *worker = data;
-
-	DEBUG(worker, "Worker ready to process client messages");
-	event_base_dispatch(worker->base);
-
-	list_for_each_entry_safe(client, cback, &worker->clients, by_worker) {
-		release_client(client);
-	}
-
-	list_for_each_entry_safe(frame, fback, &worker->frames, list) {
-		LIST_DELETE(&frame->list);
-		free(frame);
-	}
-
-	event_free(worker->monitor_event);
-	event_base_free(worker->base);
-	DEBUG(worker, "Worker is stopped");
-	pthread_exit(&null_worker);
-}
-
-
-static int
-parse_processing_delay(const char *str)
-{
-        unsigned long value;
-
-        value = 0;
-        while (1) {
-                unsigned int j;
-
-                j = *str - '0';
-                if (j > 9)
-                        break;
-                str++;
-                value *= 10;
-                value += j;
-        }
-
-        switch (*str) {
-		case '\0': /* no unit = millisecond */
-			value *= 1000;
-			break;
-		case 's': /* second */
-			value *= 1000000;
-			str++;
-			break;
-		case 'm': /* millisecond : "ms" */
-			if (str[1] != 's')
-				return -1;
-			value *= 1000;
-			str += 2;
-			break;
-		case 'u': /* microsecond : "us" */
-			if (str[1] != 's')
-				return -1;
-			str += 2;
-			break;
-		default:
-			return -1;
-        }
-	if (*str)
-		return -1;
-
-	processing_delay.tv_sec = (time_t)(value / 1000000);
-	processing_delay.tv_usec = (suseconds_t)(value % 1000000);
-        return 0;
-}
-
-
-static void
-usage(char *prog)
-{
-	fprintf(stderr,
-		"Usage : %s [OPTION]...\n"
-		"    -h                   Print this message\n"
-		"    -f <config-file>     Mod Defender configuration file\n"
-		"    -l <log-file>        Mod Defender log file\n"
-		"    -d                   Enable the debug mode\n"
-		"    -m <max-frame-size>  Specify the maximum frame size (default : %u)\n"
-		"    -p <port>            Specify the port to listen on (default : %d)\n"
-		"    -n <num-workers>     Specify the number of workers (default : %d)\n"
-		"    -c <capability>      Enable the support of the specified capability\n"
-		"    -t <time>            Set a delay to process a message (default: 0)\n"
-		"                           The value is specified in milliseconds by default,\n"
-		"                           but can be in any other unit if the number is suffixed\n"
-		"                           by a unit (us, ms, s)\n"
-		"\n"
-		"    Supported capabilities: fragmentation, pipelining, async\n",
-		prog, MAX_FRAME_SIZE, DEFAULT_PORT, NUM_WORKERS);
-}
-
-int
-main(int argc, char **argv)
-{
-	struct event_base *base = NULL;
-	struct event      *signal_event = NULL, *accept_event = NULL;
-	int                opt, i, fd = -1;
-	const char        *config_file = NULL;
-	const char        *log_file    = NULL;
-
-	// TODO: add '-t <processing-time>' option
-	while ((opt = getopt(argc, argv, "hf:l:dm:n:p:c:t:")) != -1) {
-		switch (opt) {
-			case 'h':
-				usage(argv[0]);
-				return EXIT_SUCCESS;
-			case 'f':
-				config_file = optarg;
-				break;
-			case 'l':
-				log_file = optarg;
-				break;
-			case 'd':
-				debug = true;
-				break;
-			case 'm':
-				max_frame_size = atoi(optarg);
-				break;
-			case 'n':
-				num_workers = atoi(optarg);
-				break;
-			case 'p':
-				server_port = atoi(optarg);
-				break;
-			case 'c':
-				if (strcmp(optarg, "pipelining") == 0)
-					pipelining = true;
-				else if (strcmp(optarg, "async") == 0)
-					async = true;
-				else if (strcmp(optarg, "fragmentation") == 0)
-					fragmentation = true;
-				else
-					fprintf(stderr, "WARNING: unsupported capability '%s'\n", optarg);
-				break;
-			case 't':
-				if (!parse_processing_delay(optarg))
-					break;
-				fprintf(stderr, "%s: failed to parse time '%s'.\n", argv[0], optarg);
-				fprintf(stderr, "Try '%s -h' for more information.\n", argv[0]);
-				return EXIT_FAILURE;
-			default:
-				usage(argv[0]);
-				return EXIT_FAILURE;
-		}
-	}
-
-	if (!defender_init(config_file, log_file))
-		goto error;
-
-	if (num_workers <= 0) {
-		LOG(&null_worker, "%s : Invalid number of workers '%d'\n",
-		    argv[0], num_workers);
-		goto error;
-	}
-
-	if (server_port <= 0) {
-		LOG(&null_worker, "%s : Invalid port '%d'\n",
-		    argv[0], server_port);
-		goto error;
-	}
-
-	if (evthread_use_pthreads() < 0) {
-		LOG(&null_worker, "No pthreads support for libevent");
-		goto error;
-	}
-
-	if ((base = event_base_new()) == NULL) {
-		LOG(&null_worker, "Failed to initialize libevent : %m");
-		goto error;
-	}
-
-	signal(SIGPIPE, SIG_IGN);
-
-	if ((fd = create_server_socket()) < 0) {
-		LOG(&null_worker, "Failed to create server socket");
-		goto error;
-	}
-	if (evutil_make_socket_nonblocking(fd) < 0) {
-		LOG(&null_worker, "Failed to set server socket to non-blocking");
-		goto error;
-	}
-
-	if ((workers = calloc(num_workers, sizeof(*workers))) == NULL) {
-		LOG(&null_worker, "Failed to set allocate memory for workers");
-		goto error;
-	}
-
-	for (i = 0; i < num_workers; ++i) {
-		struct worker *w = &workers[i];
-
-		w->id        = i+1;
-		w->nbclients = 0;
-		LIST_INIT(&w->engines);
-		LIST_INIT(&w->clients);
-		LIST_INIT(&w->frames);
-
-		if ((w->base = event_base_new()) == NULL) {
-			LOG(&null_worker,
-			    "Failed to initialize libevent for worker %02d : %m",
-			    w->id);
-			goto error;
-		}
-
-		w->monitor_event = event_new(w->base, fd, EV_PERSIST,
-					     worker_monitor_cb, (void *)w);
-		if (w->monitor_event == NULL ||
-		    event_add(w->monitor_event, (struct timeval[]){{5,0}}) < 0) {
-			LOG(&null_worker,
-			    "Failed to create monitor event for worker %02d",
-			    w->id);
-			goto error;
-		}
-
-		if (pthread_create(&w->thread, NULL, worker_function, (void *)w)) {
-			LOG(&null_worker,
-			    "Failed to start thread for worker %02d : %m",
-			    w->id);
-		}
-		DEBUG(&null_worker, "Worker %02d initialized", w->id);
-	}
-
-	accept_event = event_new(base, fd, EV_READ|EV_PERSIST, accept_cb,
-				 (void *)base);
-	if (accept_event == NULL || event_add(accept_event, NULL) < 0) {
-		LOG(&null_worker, "Failed to create accept event : %m");
-	}
-
-	signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);
-	if (signal_event == NULL || event_add(signal_event, NULL) < 0) {
-		LOG(&null_worker, "Failed to create signal event : %m");
-	}
-
-	DEBUG(&null_worker,
-	      "Server is ready"
-	      " [fragmentation=%s - pipelining=%s - async=%s - debug=%s - max-frame-size=%u]",
-	      (fragmentation?"true":"false"), (pipelining?"true":"false"), (async?"true":"false"),
-	      (debug?"true":"false"), max_frame_size);
-	event_base_dispatch(base);
-
-	for (i = 0; i < num_workers; i++) {
-		struct worker *w = &workers[i];
-
-		pthread_join(w->thread, NULL);
-		DEBUG(&null_worker, "Worker %02d terminated", w->id);
-	}
-
-	free(workers);
-	event_free(signal_event);
-	event_free(accept_event);
-	event_base_free(base);
-	close(fd);
-	return EXIT_SUCCESS;
-
-  error:
-	if (workers != NULL)
-		free(workers);
-	if (signal_event != NULL)
-		event_free(signal_event);
-	if (accept_event != NULL)
-		event_free(accept_event);
-	if (base != NULL)
-		event_base_free(base);
-	if (fd != -1)
-		close(fd);
-	return EXIT_FAILURE;
-}
diff --git a/contrib/mod_defender/spoa.h b/contrib/mod_defender/spoa.h
deleted file mode 100644
index 726007f..0000000
--- a/contrib/mod_defender/spoa.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Mod Defender for HAProxy
- *
- * Copyright 2017 HAProxy Technologies, Dragan Dosen <ddosen@haproxy.com>
- *
- * Based on "A Random IP reputation service acting as a Stream Processing Offload Agent"
- * Copyright 2016 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
- *
- * This program 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 of the License, or (at your option) any later version.
- *
- */
-#ifndef __SPOA_H__
-#define __SPOA_H__
-
-#include <sys/time.h>
-#undef LIST_HEAD
-
-#include <event2/util.h>
-#include <event2/event.h>
-#include <event2/event_struct.h>
-#include <event2/thread.h>
-
-#define LOG(worker, fmt, args...)                                       \
-	do {								\
-		struct timeval  now;					\
-                                                                        \
-		gettimeofday(&now, NULL);				\
-		fprintf(stderr, "%ld.%06ld [%02d] " fmt "\n",		\
-			now.tv_sec, now.tv_usec, (worker)->id, ##args);	\
-	} while (0)
-
-struct worker {
-	pthread_t           thread;
-	int                 id;
-	struct event_base  *base;
-	struct event       *monitor_event;
-
-	struct list         engines;
-
-	unsigned int        nbclients;
-	struct list         clients;
-
-	struct list         frames;
-};
-
-extern struct worker null_worker;
-
-#endif /* __SPOA_H__ */
diff --git a/contrib/mod_defender/standalone.c b/contrib/mod_defender/standalone.c
deleted file mode 100644
index 58d1940..0000000
--- a/contrib/mod_defender/standalone.c
+++ /dev/null
@@ -1,1636 +0,0 @@
-/*
- * Mod Defender for HAProxy
- *
- * Support for the Mod Defender code on non-Apache platforms.
- *
- * Copyright 2017 HAProxy Technologies, Dragan Dosen <ddosen@haproxy.com>
- *
- * Parts of code based on Apache HTTP Server source
- * Copyright 2015 The Apache Software Foundation (http://www.apache.org/)
- *
- * This program 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 of the License, or (at your option) any later version.
- *
- */
-#include <limits.h>
-
-#include <http_core.h>
-#include <http_main.h>
-#include <http_log.h>
-
-#include <apr_lib.h>
-#include <apr_strings.h>
-#include <apr_fnmatch.h>
-
-#include "standalone.h"
-
-#define MAX_ARGC 64
-#define MAX_INCLUDE_DIR_DEPTH 128
-
-#define SLASHES "/"
-
-#define FILTER_POOL apr_hook_global_pool
-#define TRIE_INITIAL_SIZE 4
-
-typedef struct filter_trie_node filter_trie_node;
-
-typedef struct {
-	int c;
-	filter_trie_node *child;
-} filter_trie_child_ptr;
-
-struct filter_trie_node {
-	ap_filter_rec_t *frec;
-	filter_trie_child_ptr *children;
-	int nchildren;
-	int size;
-};
-
-typedef struct {
-	const char *fname;
-} fnames;
-
-AP_DECLARE_DATA const char *ap_server_root = "/";
-
-void (*logger)(int level, char *str) = NULL;
-
-static void str_tolower(char *str)
-{
-	while (*str) {
-		*str = apr_tolower(*str);
-		++str;
-	}
-}
-
-static char x2c(const char *what)
-{
-	char digit;
-
-#if !APR_CHARSET_EBCDIC
-	digit = ((what[0] >= 'A') ? ((what[0] & 0xdf) - 'A') + 10
-	        : (what[0] - '0'));
-	digit *= 16;
-	digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10
-	         : (what[1] - '0'));
-#else /*APR_CHARSET_EBCDIC*/
-	char xstr[5];
-	xstr[0]='0';
-	xstr[1]='x';
-	xstr[2]=what[0];
-	xstr[3]=what[1];
-	xstr[4]='\0';
-	digit = apr_xlate_conv_byte(ap_hdrs_from_ascii,
-	                            0xFF & strtol(xstr, NULL, 16));
-#endif /*APR_CHARSET_EBCDIC*/
-	return (digit);
-}
-
-static int unescape_url(char *url, const char *forbid, const char *reserved)
-{
-	int badesc, badpath;
-	char *x, *y;
-
-	badesc = 0;
-	badpath = 0;
-	/* Initial scan for first '%'. Don't bother writing values before
-	 * seeing a '%' */
-	y = strchr(url, '%');
-	if (y == NULL) {
-		return OK;
-	}
-	for (x = y; *y; ++x, ++y) {
-		if (*y != '%') {
-			*x = *y;
-		}
-		else {
-			if (!apr_isxdigit(*(y + 1)) || !apr_isxdigit(*(y + 2))) {
-				badesc = 1;
-				*x = '%';
-			}
-			else {
-				char decoded;
-				decoded = x2c(y + 1);
-				if ((decoded == '\0')
-				    || (forbid && ap_strchr_c(forbid, decoded))) {
-					badpath = 1;
-					*x = decoded;
-					y += 2;
-				}
-				else if (reserved && ap_strchr_c(reserved, decoded)) {
-					*x++ = *y++;
-					*x++ = *y++;
-					*x = *y;
-				}
-				else {
-					*x = decoded;
-					y += 2;
-				}
-			}
-		}
-	}
-	*x = '\0';
-	if (badesc) {
-		return HTTP_BAD_REQUEST;
-	}
-	else if (badpath) {
-		return HTTP_NOT_FOUND;
-	}
-	else {
-		return OK;
-	}
-}
-
-AP_DECLARE(int) ap_unescape_url(char *url)
-{
-	/* Traditional */
-	return unescape_url(url, SLASHES, NULL);
-}
-
-AP_DECLARE(void) ap_get_server_revision(ap_version_t *version)
-{
-	version->major = AP_SERVER_MAJORVERSION_NUMBER;
-	version->minor = AP_SERVER_MINORVERSION_NUMBER;
-	version->patch = AP_SERVER_PATCHLEVEL_NUMBER;
-	version->add_string = AP_SERVER_ADD_STRING;
-}
-
-static void log_error_core(const char *file, int line, int module_index,
-                           int level,
-                           apr_status_t status, const server_rec *s,
-                           const conn_rec *c,
-                           const request_rec *r, apr_pool_t *pool,
-                           const char *fmt, va_list args)
-{
-	char errstr[MAX_STRING_LEN];
-
-	apr_vsnprintf(errstr, MAX_STRING_LEN, fmt, args);
-
-	if (logger != NULL)
-		logger(level, errstr);
-}
-
-AP_DECLARE(void) ap_log_error_(const char *file, int line, int module_index,
-                               int level, apr_status_t status,
-                               const server_rec *s, const char *fmt, ...)
-{
-	va_list args;
-
-	va_start(args, fmt);
-	log_error_core(file, line, module_index, level, status, s, NULL, NULL,
-	               NULL, fmt, args);
-	va_end(args);
-}
-
-AP_DECLARE(void) ap_log_rerror_(const char *file, int line, int module_index,
-                                int level, apr_status_t status,
-                                const request_rec *r, const char *fmt, ...)
-{
-	va_list args;
-
-	va_start(args, fmt);
-	log_error_core(file, line, module_index, level, status, r->server, NULL, r,
-	               NULL, fmt, args);
-	va_end(args);
-}
-
-AP_DECLARE(void) ap_log_cerror_(const char *file, int line, int module_index,
-                                int level, apr_status_t status,
-                                const conn_rec *c, const char *fmt, ...)
-{
-	va_list args;
-
-	va_start(args, fmt);
-	log_error_core(file, line, module_index, level, status, c->base_server, c,
-	               NULL, NULL, fmt, args);
-	va_end(args);
-}
-
-AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program)
-{
-	return NULL;
-}
-
-AP_DECLARE(apr_file_t *) ap_piped_log_write_fd(piped_log *pl)
-{
-	return NULL;
-}
-
-static cmd_parms default_parms =
-{NULL, 0, 0, NULL, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
-
-AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *file)
-{
-	char *newpath = NULL;
-	apr_status_t rv;
-	rv = apr_filepath_merge(&newpath, ap_server_root, file,
-	                        APR_FILEPATH_TRUENAME, p);
-	if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv)
-	                                  || APR_STATUS_IS_ENOENT(rv)
-	                                  || APR_STATUS_IS_ENOTDIR(rv))) {
-		return newpath;
-	}
-	else {
-		return NULL;
-	}
-}
-
-AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *next,
-                                        apr_bucket_brigade *bb,
-                                        ap_input_mode_t mode,
-                                        apr_read_type_e block,
-                                        apr_off_t readbytes)
-{
-	if (next) {
-		return next->frec->filter_func.in_func(next, bb, mode, block,
-		                                       readbytes);
-	}
-	return AP_NOBODY_READ;
-}
-
-static void
-argstr_to_table(char *str, apr_table_t *parms)
-{
-	char *key;
-	char *value;
-	char *strtok_state;
-
-	if (str == NULL) {
-		return;
-	}
-
-	key = apr_strtok(str, "&", &strtok_state);
-	while (key) {
-		value = strchr(key, '=');
-		if (value) {
-			*value = '\0';      /* Split the string in two */
-			value++;            /* Skip passed the = */
-		}
-		else {
-			value = "1";
-		}
-		ap_unescape_url(key);
-		ap_unescape_url(value);
-		apr_table_set(parms, key, value);
-		key = apr_strtok(NULL, "&", &strtok_state);
-	}
-}
-
-AP_DECLARE(void) ap_args_to_table(request_rec *r, apr_table_t **table)
-{
-	apr_table_t *t = apr_table_make(r->pool, 10);
-	argstr_to_table(apr_pstrdup(r->pool, r->args), t);
-	*table = t;
-}
-
-/* Link a trie node to its parent
- */
-static void trie_node_link(apr_pool_t *p, filter_trie_node *parent,
-                           filter_trie_node *child, int c)
-{
-	int i, j;
-
-	if (parent->nchildren == parent->size) {
-		filter_trie_child_ptr *new;
-		parent->size *= 2;
-		new = (filter_trie_child_ptr *)apr_palloc(p, parent->size *
-		                                          sizeof(filter_trie_child_ptr));
-		memcpy(new, parent->children, parent->nchildren *
-		       sizeof(filter_trie_child_ptr));
-		parent->children = new;
-	}
-
-	for (i = 0; i < parent->nchildren; i++) {
-		if (c == parent->children[i].c) {
-			return;
-		}
-		else if (c < parent->children[i].c) {
-			break;
-		}
-	}
-	for (j = parent->nchildren; j > i; j--) {
-		parent->children[j].c = parent->children[j - 1].c;
-		parent->children[j].child = parent->children[j - 1].child;
-	}
-	parent->children[i].c = c;
-	parent->children[i].child = child;
-
-	parent->nchildren++;
-}
-
-/* Allocate a new node for a trie.
- * If parent is non-NULL, link the new node under the parent node with
- * key 'c' (or, if an existing child node matches, return that one)
- */
-static filter_trie_node *trie_node_alloc(apr_pool_t *p,
-                                         filter_trie_node *parent, char c)
-{
-	filter_trie_node *new_node;
-	if (parent) {
-		int i;
-		for (i = 0; i < parent->nchildren; i++) {
-			if (c == parent->children[i].c) {
-				return parent->children[i].child;
-			}
-			else if (c < parent->children[i].c) {
-				break;
-			}
-		}
-		new_node = (filter_trie_node *)apr_palloc(p, sizeof(filter_trie_node));
-		trie_node_link(p, parent, new_node, c);
-	}
-	else { /* No parent node */
-		new_node = (filter_trie_node *)apr_palloc(p,
-		           sizeof(filter_trie_node));
-	}
-
-	new_node->frec = NULL;
-	new_node->nchildren = 0;
-	new_node->size = TRIE_INITIAL_SIZE;
-	new_node->children = (filter_trie_child_ptr *)apr_palloc(p,
-	                     new_node->size * sizeof(filter_trie_child_ptr));
-	return new_node;
-}
-
-static filter_trie_node *registered_output_filters = NULL;
-static filter_trie_node *registered_input_filters = NULL;
-
-
-static apr_status_t filter_cleanup(void *ctx)
-{
-	registered_output_filters = NULL;
-	registered_input_filters = NULL;
-	return APR_SUCCESS;
-}
-
-static ap_filter_rec_t *register_filter(const char *name,
-                                        ap_filter_func filter_func,
-                                        ap_init_filter_func filter_init,
-                                        ap_filter_type ftype,
-                                        filter_trie_node **reg_filter_set)
-{
-	ap_filter_rec_t *frec;
-	char *normalized_name;
-	const char *n;
-	filter_trie_node *node;
-
-	if (!*reg_filter_set) {
-		*reg_filter_set = trie_node_alloc(FILTER_POOL, NULL, 0);
-	}
-
-	normalized_name = apr_pstrdup(FILTER_POOL, name);
-	str_tolower(normalized_name);
-
-	node = *reg_filter_set;
-	for (n = normalized_name; *n; n++) {
-		filter_trie_node *child = trie_node_alloc(FILTER_POOL, node, *n);
-		if (apr_isalpha(*n)) {
-			trie_node_link(FILTER_POOL, node, child, apr_toupper(*n));
-		}
-		node = child;
-	}
-	if (node->frec) {
-		frec = node->frec;
-	}
-	else {
-		frec = apr_pcalloc(FILTER_POOL, sizeof(*frec));
-		node->frec = frec;
-		frec->name = normalized_name;
-	}
-	frec->filter_func = filter_func;
-	frec->filter_init_func = filter_init;
-	frec->ftype = ftype;
-
-	apr_pool_cleanup_register(FILTER_POOL, NULL, filter_cleanup,
-	                          apr_pool_cleanup_null);
-	return frec;
-}
-
-AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name,
-                                                       ap_in_filter_func filter_func,
-                                                       ap_init_filter_func filter_init,
-                                                       ap_filter_type ftype)
-{
-	ap_filter_func f;
-	f.in_func = filter_func;
-	return register_filter(name, f, filter_init, ftype,
-	                       &registered_input_filters);
-}
-
-static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx,
-                                          request_rec *r, conn_rec *c,
-                                          ap_filter_t **r_filters,
-                                          ap_filter_t **p_filters,
-                                          ap_filter_t **c_filters)
-{
-	apr_pool_t *p = frec->ftype < AP_FTYPE_CONNECTION && r ? r->pool : c->pool;
-	ap_filter_t *f = apr_palloc(p, sizeof(*f));
-	ap_filter_t **outf;
-
-	if (frec->ftype < AP_FTYPE_PROTOCOL) {
-		if (r) {
-			outf = r_filters;
-		}
-		else {
-			ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(00080)
-			              "a content filter was added without a request: %s", frec->name);
-			return NULL;
-		}
-	}
-	else if (frec->ftype < AP_FTYPE_CONNECTION) {
-		if (r) {
-			outf = p_filters;
-		}
-		else {
-			ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(00081)
-			              "a protocol filter was added without a request: %s", frec->name);
-			return NULL;
-		}
-	}
-	else {
-		outf = c_filters;
-	}
-
-	f->frec = frec;
-	f->ctx = ctx;
-	/* f->r must always be NULL for connection filters */
-	f->r = frec->ftype < AP_FTYPE_CONNECTION ? r : NULL;
-	f->c = c;
-	f->next = NULL;
-
-	if (INSERT_BEFORE(f, *outf)) {
-		f->next = *outf;
-
-		if (*outf) {
-			ap_filter_t *first = NULL;
-
-			if (r) {
-				/* If we are adding our first non-connection filter,
-				 * Then don't try to find the right location, it is
-				 * automatically first.
-				 */
-				if (*r_filters != *c_filters) {
-					first = *r_filters;
-					while (first && (first->next != (*outf))) {
-						first = first->next;
-					}
-				}
-			}
-			if (first && first != (*outf)) {
-				first->next = f;
-			}
-		}
-		*outf = f;
-	}
-	else {
-		ap_filter_t *fscan = *outf;
-		while (!INSERT_BEFORE(f, fscan->next))
-			fscan = fscan->next;
-
-		f->next = fscan->next;
-		fscan->next = f;
-	}
-
-	if (frec->ftype < AP_FTYPE_CONNECTION && (*r_filters == *c_filters)) {
-		*r_filters = *p_filters;
-	}
-	return f;
-}
-
-static ap_filter_t *add_any_filter(const char *name, void *ctx,
-                                   request_rec *r, conn_rec *c,
-                                   const filter_trie_node *reg_filter_set,
-                                   ap_filter_t **r_filters,
-                                   ap_filter_t **p_filters,
-                                   ap_filter_t **c_filters)
-{
-	if (reg_filter_set) {
-		const char *n;
-		const filter_trie_node *node;
-
-		node = reg_filter_set;
-		for (n = name; *n; n++) {
-			int start, end;
-			start = 0;
-			end = node->nchildren - 1;
-			while (end >= start) {
-				int middle = (end + start) / 2;
-				char ch = node->children[middle].c;
-				if (*n == ch) {
-					node = node->children[middle].child;
-					break;
-				}
-				else if (*n < ch) {
-					end = middle - 1;
-				}
-				else {
-					start = middle + 1;
-				}
-			}
-			if (end < start) {
-				node = NULL;
-				break;
-			}
-		}
-
-		if (node && node->frec) {
-			return add_any_filter_handle(node->frec, ctx, r, c, r_filters,
-			                             p_filters, c_filters);
-		}
-	}
-
-	ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, r ? r->connection : c, APLOGNO(00082)
-	              "an unknown filter was not added: %s", name);
-	return NULL;
-}
-
-AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx,
-                                              request_rec *r, conn_rec *c)
-{
-	return add_any_filter(name, ctx, r, c, registered_input_filters,
-	                      r ? &r->input_filters : NULL,
-	                      r ? &r->proto_input_filters : NULL,
-	                      &c->input_filters);
-}
-
-static void remove_any_filter(ap_filter_t *f, ap_filter_t **r_filt, ap_filter_t **p_filt,
-                              ap_filter_t **c_filt)
-{
-	ap_filter_t **curr = r_filt ? r_filt : c_filt;
-	ap_filter_t *fscan = *curr;
-
-	if (p_filt && *p_filt == f)
-		*p_filt = (*p_filt)->next;
-
-	if (*curr == f) {
-		*curr = (*curr)->next;
-		return;
-	}
-
-	while (fscan->next != f) {
-		if (!(fscan = fscan->next)) {
-			return;
-		}
-	}
-
-	fscan->next = f->next;
-}
-
-AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f)
-{
-	remove_any_filter(f, f->r ? &f->r->input_filters : NULL,
-	                  f->r ? &f->r->proto_input_filters : NULL,
-	                  &f->c->input_filters);
-}
-
-static int cfg_closefile(ap_configfile_t *cfp)
-{
-#ifdef DEBUG
-	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,
-	             "Done with config file %s", cfp->name);
-#endif
-	return (cfp->close == NULL) ? 0 : cfp->close(cfp->param);
-}
-
-/* we can't use apr_file_* directly because of linking issues on Windows */
-static apr_status_t cfg_close(void *param)
-{
-	return apr_file_close(param);
-}
-
-static apr_status_t cfg_getch(char *ch, void *param)
-{
-	return apr_file_getc(ch, param);
-}
-
-static apr_status_t cfg_getstr(void *buf, apr_size_t bufsiz, void *param)
-{
-	return apr_file_gets(buf, bufsiz, param);
-}
-
-/* Read one line from open ap_configfile_t, strip LF, increase line number */
-/* If custom handler does not define a getstr() function, read char by char */
-static apr_status_t cfg_getline_core(char *buf, apr_size_t bufsize,
-                                     apr_size_t offset, ap_configfile_t *cfp)
-{
-	apr_status_t rc;
-	/* If a "get string" function is defined, use it */
-	if (cfp->getstr != NULL) {
-		char *cp;
-		char *cbuf = buf + offset;
-		apr_size_t cbufsize = bufsize - offset;
-
-		while (1) {
-			++cfp->line_number;
-			rc = cfp->getstr(cbuf, cbufsize, cfp->param);
-			if (rc == APR_EOF) {
-				if (cbuf != buf + offset) {
-					*cbuf = '\0';
-					break;
-				}
-				else {
-					return APR_EOF;
-				}
-			}
-			if (rc != APR_SUCCESS) {
-				return rc;
-			}
-
-			/*
-			 *  check for line continuation,
-			 *  i.e. match [^\\]\\[\r]\n only
-			 */
-			cp = cbuf;
-			cp += strlen(cp);
-			if (cp > buf && cp[-1] == LF) {
-				cp--;
-				if (cp > buf && cp[-1] == CR)
-					cp--;
-				if (cp > buf && cp[-1] == '\\') {
-					cp--;
-					/*
-					 * line continuation requested -
-					 * then remove backslash and continue
-					 */
-					cbufsize -= (cp-cbuf);
-					cbuf = cp;
-					continue;
-				}
-			}
-			else if (cp - buf >= bufsize - 1) {
-				return APR_ENOSPC;
-			}
-			break;
-		}
-	} else {
-		/* No "get string" function defined; read character by character */
-		apr_size_t i = offset;
-
-		if (bufsize < 2) {
-			/* too small, assume caller is crazy */
-			return APR_EINVAL;
-		}
-		buf[offset] = '\0';
-
-		while (1) {
-			char c;
-			rc = cfp->getch(&c, cfp->param);
-			if (rc == APR_EOF) {
-				if (i > offset)
-					break;
-				else
-					return APR_EOF;
-			}
-			if (rc != APR_SUCCESS)
-				return rc;
-			if (c == LF) {
-				++cfp->line_number;
-				/* check for line continuation */
-				if (i > 0 && buf[i-1] == '\\') {
-					i--;
-					continue;
-				}
-				else {
-					break;
-				}
-			}
-			buf[i] = c;
-			++i;
-			if (i >= bufsize - 1) {
-				return APR_ENOSPC;
-			}
-		}
-		buf[i] = '\0';
-	}
-	return APR_SUCCESS;
-}
-
-static int cfg_trim_line(char *buf)
-{
-	char *start, *end;
-	/*
-	 * Leading and trailing white space is eliminated completely
-	 */
-	start = buf;
-	while (apr_isspace(*start))
-		++start;
-	/* blast trailing whitespace */
-	end = &start[strlen(start)];
-	while (--end >= start && apr_isspace(*end))
-		*end = '\0';
-	/* Zap leading whitespace by shifting */
-	if (start != buf)
-		memmove(buf, start, end - start + 2);
-#ifdef DEBUG_CFG_LINES
-	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, APLOGNO(00555) "Read config: '%s'", buf);
-#endif
-	return end - start + 1;
-}
-
-/* Read one line from open ap_configfile_t, strip LF, increase line number */
-/* If custom handler does not define a getstr() function, read char by char */
-static apr_status_t cfg_getline(char *buf, apr_size_t bufsize,
-                                ap_configfile_t *cfp)
-{
-	apr_status_t rc = cfg_getline_core(buf, bufsize, 0, cfp);
-	if (rc == APR_SUCCESS)
-		cfg_trim_line(buf);
-	return rc;
-}
-
-static char *substring_conf(apr_pool_t *p, const char *start, int len,
-                            char quote)
-{
-	char *result = apr_palloc(p, len + 1);
-	char *resp = result;
-	int i;
-
-	for (i = 0; i < len; ++i) {
-		if (start[i] == '\\' && (start[i + 1] == '\\'
-		                         || (quote && start[i + 1] == quote)))
-			*resp++ = start[++i];
-		else
-			*resp++ = start[i];
-	}
-
-	*resp++ = '\0';
-#if RESOLVE_ENV_PER_TOKEN
-	return (char *)ap_resolve_env(p,result);
-#else
-	return result;
-#endif
-}
-
-static char *getword_conf(apr_pool_t *p, const char **line)
-{
-	const char *str = *line, *strend;
-	char *res;
-	char quote;
-
-	while (apr_isspace(*str))
-		++str;
-
-	if (!*str) {
-		*line = str;
-		return "";
-	}
-
-	if ((quote = *str) == '"' || quote == '\'') {
-		strend = str + 1;
-		while (*strend && *strend != quote) {
-			if (*strend == '\\' && strend[1] &&
-			    (strend[1] == quote || strend[1] == '\\')) {
-				strend += 2;
-			}
-			else {
-				++strend;
-			}
-		}
-		res = substring_conf(p, str + 1, strend - str - 1, quote);
-
-		if (*strend == quote)
-			++strend;
-	}
-	else {
-		strend = str;
-		while (*strend && !apr_isspace(*strend))
-			++strend;
-
-		res = substring_conf(p, str, strend - str, 0);
-	}
-
-	while (apr_isspace(*strend))
-		++strend;
-	*line = strend;
-	return res;
-}
-
-/* Open a ap_configfile_t as FILE, return open ap_configfile_t struct pointer */
-static apr_status_t pcfg_openfile(ap_configfile_t **ret_cfg,
-                                  apr_pool_t *p, const char *name)
-{
-	ap_configfile_t *new_cfg;
-	apr_file_t *file = NULL;
-	apr_finfo_t finfo;
-	apr_status_t status;
-#ifdef DEBUG
-	char buf[120];
-#endif
-
-	if (name == NULL) {
-		ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(00552)
-		             "Internal error: pcfg_openfile() called with NULL filename");
-		return APR_EBADF;
-	}
-
-	status = apr_file_open(&file, name, APR_READ | APR_BUFFERED,
-	                       APR_OS_DEFAULT, p);
-#ifdef DEBUG
-	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(00553)
-	             "Opening config file %s (%s)",
-	             name, (status != APR_SUCCESS) ?
-	             apr_strerror(status, buf, sizeof(buf)) : "successful");
-#endif
-	if (status != APR_SUCCESS)
-		return status;
-
-	status = apr_file_info_get(&finfo, APR_FINFO_TYPE, file);
-	if (status != APR_SUCCESS)
-		return status;
-
-	if (finfo.filetype != APR_REG &&
-		strcmp(name, "/dev/null") != 0) {
-		ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(00554)
-		             "Access to file %s denied by server: not a regular file",
-		             name);
-		apr_file_close(file);
-		return APR_EBADF;
-	}
-
-	new_cfg = apr_palloc(p, sizeof(*new_cfg));
-	new_cfg->param = file;
-	new_cfg->name = apr_pstrdup(p, name);
-	new_cfg->getch = cfg_getch;
-	new_cfg->getstr = cfg_getstr;
-	new_cfg->close = cfg_close;
-	new_cfg->line_number = 0;
-	*ret_cfg = new_cfg;
-	return APR_SUCCESS;
-}
-
-static const command_rec *find_command(const char *name,
-                                       const command_rec *cmds)
-{
-	while (cmds->name) {
-		if (strcasecmp(name, cmds->name) == 0)
-			return cmds;
-		++cmds;
-	}
-
-	return NULL;
-}
-
-static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms,
-                              void *mconfig, const char *args)
-{
-	int override_list_ok = 0;
-	char *w, *w2, *w3;
-	const char *errmsg = NULL;
-
-	/** Have we been provided a list of acceptable directives? */
-	if (parms->override_list != NULL) {
-		if (apr_table_get(parms->override_list, cmd->name) != NULL) {
-			override_list_ok = 1;
-		}
-	}
-
-	if ((parms->override & cmd->req_override) == 0 && !override_list_ok) {
-		return apr_pstrcat(parms->pool, cmd->name,
-		                   " not allowed here", NULL);
-	}
-
-	parms->info = cmd->cmd_data;
-	parms->cmd = cmd;
-
-	switch (cmd->args_how) {
-	case RAW_ARGS:
-#ifdef RESOLVE_ENV_PER_TOKEN
-		args = ap_resolve_env(parms->pool,args);
-#endif
-		return cmd->AP_RAW_ARGS(parms, mconfig, args);
-
-	case TAKE_ARGV:
-		{
-			char *argv[MAX_ARGC];
-			int argc = 0;
-
-			do {
-				w = getword_conf(parms->pool, &args);
-				if (*w == '\0' && *args == '\0') {
-					break;
-				}
-				argv[argc] = w;
-				argc++;
-			} while (argc < MAX_ARGC && *args != '\0');
-
-			return cmd->AP_TAKE_ARGV(parms, mconfig, argc, argv);
-		}
-
-	case NO_ARGS:
-		if (*args != 0)
-			return apr_pstrcat(parms->pool, cmd->name, " takes no arguments",
-			                   NULL);
-
-		return cmd->AP_NO_ARGS(parms, mconfig);
-
-	case TAKE1:
-		w = getword_conf(parms->pool, &args);
-
-		if (*w == '\0' || *args != 0)
-			return apr_pstrcat(parms->pool, cmd->name, " takes one argument",
-			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
-		return cmd->AP_TAKE1(parms, mconfig, w);
-
-	case TAKE2:
-		w = getword_conf(parms->pool, &args);
-		w2 = getword_conf(parms->pool, &args);
-
-		if (*w == '\0' || *w2 == '\0' || *args != 0)
-			return apr_pstrcat(parms->pool, cmd->name, " takes two arguments",
-			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
-		return cmd->AP_TAKE2(parms, mconfig, w, w2);
-
-	case TAKE12:
-		w = getword_conf(parms->pool, &args);
-		w2 = getword_conf(parms->pool, &args);
-
-		if (*w == '\0' || *args != 0)
-			return apr_pstrcat(parms->pool, cmd->name, " takes 1-2 arguments",
-			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
-		return cmd->AP_TAKE2(parms, mconfig, w, *w2 ? w2 : NULL);
-
-	case TAKE3:
-		w = getword_conf(parms->pool, &args);
-		w2 = getword_conf(parms->pool, &args);
-		w3 = getword_conf(parms->pool, &args);
-
-		if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0)
-			return apr_pstrcat(parms->pool, cmd->name, " takes three arguments",
-			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
-		return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
-
-	case TAKE23:
-		w = getword_conf(parms->pool, &args);
-		w2 = getword_conf(parms->pool, &args);
-		w3 = *args ? getword_conf(parms->pool, &args) : NULL;
-
-		if (*w == '\0' || *w2 == '\0' || *args != 0)
-			return apr_pstrcat(parms->pool, cmd->name,
-			                   " takes two or three arguments",
-			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
-		return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
-
-	case TAKE123:
-		w = getword_conf(parms->pool, &args);
-		w2 = *args ? getword_conf(parms->pool, &args) : NULL;
-		w3 = *args ? getword_conf(parms->pool, &args) : NULL;
-
-		if (*w == '\0' || *args != 0)
-			return apr_pstrcat(parms->pool, cmd->name,
-			                   " takes one, two or three arguments",
-			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
-		return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
-
-	case TAKE13:
-		w = getword_conf(parms->pool, &args);
-		w2 = *args ? getword_conf(parms->pool, &args) : NULL;
-		w3 = *args ? getword_conf(parms->pool, &args) : NULL;
-
-		if (*w == '\0' || (w2 && *w2 && !w3) || *args != 0)
-			return apr_pstrcat(parms->pool, cmd->name,
-			                   " takes one or three arguments",
-			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
-		return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
-
-	case ITERATE:
-		w = getword_conf(parms->pool, &args);
-
-		if (*w == '\0')
-			return apr_pstrcat(parms->pool, cmd->name,
-			                   " requires at least one argument",
-			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
-		while (*w != '\0') {
-			errmsg = cmd->AP_TAKE1(parms, mconfig, w);
-
-			if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
-				return errmsg;
-
-			w = getword_conf(parms->pool, &args);
-		}
-
-		return errmsg;
-
-	case ITERATE2:
-		w = getword_conf(parms->pool, &args);
-
-		if (*w == '\0' || *args == 0)
-			return apr_pstrcat(parms->pool, cmd->name,
-			                   " requires at least two arguments",
-			                   cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
-		while (*(w2 = getword_conf(parms->pool, &args)) != '\0') {
-
-			errmsg = cmd->AP_TAKE2(parms, mconfig, w, w2);
-
-			if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
-				return errmsg;
-		}
-
-		return errmsg;
-
-	case FLAG:
-		/*
-		 * This is safe to use temp_pool here, because the 'flag' itself is not
-		 * forwarded as-is
-		 */
-		w = getword_conf(parms->temp_pool, &args);
-
-		if (*w == '\0' || (strcasecmp(w, "on") != 0 && strcasecmp(w, "off") != 0))
-			return apr_pstrcat(parms->pool, cmd->name, " must be On or Off",
-			                   NULL);
-
-		return cmd->AP_FLAG(parms, mconfig, strcasecmp(w, "off") != 0);
-
-	default:
-		return apr_pstrcat(parms->pool, cmd->name,
-		                   " is improperly configured internally (server bug)",
-		                   NULL);
-	}
-}
-
-static int is_directory(apr_pool_t *p, const char *path)
-{
-	apr_finfo_t finfo;
-
-	if (apr_stat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS)
-		return 0;                /* in error condition, just return no */
-
-	return (finfo.filetype == APR_DIR);
-}
-
-static char *make_full_path(apr_pool_t *a, const char *src1,
-                            const char *src2)
-{
-	apr_size_t len1, len2;
-	char *path;
-
-	len1 = strlen(src1);
-	len2 = strlen(src2);
-	/* allocate +3 for '/' delimiter, trailing NULL and overallocate
-	 * one extra byte to allow the caller to add a trailing '/'
-	 */
-	path = (char *)apr_palloc(a, len1 + len2 + 3);
-	if (len1 == 0) {
-		*path = '/';
-		memcpy(path + 1, src2, len2 + 1);
-	}
-	else {
-		char *next;
-		memcpy(path, src1, len1);
-		next = path + len1;
-		if (next[-1] != '/') {
-			*next++ = '/';
-		}
-		memcpy(next, src2, len2 + 1);
-	}
-	return path;
-}
-
-static int fname_alphasort(const void *fn1, const void *fn2)
-{
-	const fnames *f1 = fn1;
-	const fnames *f2 = fn2;
-
-	return strcmp(f1->fname,f2->fname);
-}
-
-static const char *process_resource_config(const char *fname,
-                                           apr_array_header_t *ari,
-                                           apr_pool_t *p,
-                                           apr_pool_t *ptemp)
-{
-	*(char **)apr_array_push(ari) = (char *)fname;
-	return NULL;
-}
-
-static const char *process_resource_config_nofnmatch(const char *fname,
-                                                     apr_array_header_t *ari,
-                                                     apr_pool_t *p,
-                                                     apr_pool_t *ptemp,
-                                                     unsigned depth,
-                                                     int optional)
-{
-	const char *error;
-	apr_status_t rv;
-
-	if (is_directory(ptemp, fname)) {
-		apr_dir_t *dirp;
-		apr_finfo_t dirent;
-		int current;
-		apr_array_header_t *candidates = NULL;
-		fnames *fnew;
-		char *path = apr_pstrdup(ptemp, fname);
-
-		if (++depth > MAX_INCLUDE_DIR_DEPTH) {
-			return apr_psprintf(p, "Directory %s exceeds the maximum include "
-			                    "directory nesting level of %u. You have "
-			                    "probably a recursion somewhere.", path,
-			                    MAX_INCLUDE_DIR_DEPTH);
-		}
-
-		/*
-		 * first course of business is to grok all the directory
-		 * entries here and store 'em away. Recall we need full pathnames
-		 * for this.
-		 */
-		rv = apr_dir_open(&dirp, path, ptemp);
-		if (rv != APR_SUCCESS) {
-			return apr_psprintf(p, "Could not open config directory %s: %pm",
-			                    path, &rv);
-		}
-
-		candidates = apr_array_make(ptemp, 1, sizeof(fnames));
-		while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) {
-			/* strip out '.' and '..' */
-			if (strcmp(dirent.name, ".") != 0
-			    && strcmp(dirent.name, "..") != 0) {
-				fnew = (fnames *) apr_array_push(candidates);
-				fnew->fname = make_full_path(ptemp, path, dirent.name);
-			}
-		}
-
-		apr_dir_close(dirp);
-		if (candidates->nelts != 0) {
-			qsort((void *) candidates->elts, candidates->nelts,
-			      sizeof(fnames), fname_alphasort);
-
-			/*
-			 * Now recurse these... we handle errors and subdirectories
-			 * via the recursion, which is nice
-			 */
-			for (current = 0; current < candidates->nelts; ++current) {
-				fnew = &((fnames *) candidates->elts)[current];
-				error = process_resource_config_nofnmatch(fnew->fname,
-				                                          ari, p, ptemp,
-				                                          depth, optional);
-				if (error) {
-					return error;
-				}
-			}
-		}
-
-		return NULL;
-	}
-
-	return process_resource_config(fname, ari, p, ptemp);
-}
-
-static const char *process_resource_config_fnmatch(const char *path,
-                                                   const char *fname,
-                                                   apr_array_header_t *ari,
-                                                   apr_pool_t *p,
-                                                   apr_pool_t *ptemp,
-                                                   unsigned depth,
-                                                   int optional)
-{
-	const char *rest;
-	apr_status_t rv;
-	apr_dir_t *dirp;
-	apr_finfo_t dirent;
-	apr_array_header_t *candidates = NULL;
-	fnames *fnew;
-	int current;
-
-	/* find the first part of the filename */
-	rest = ap_strchr_c(fname, '/');
-	if (rest) {
-		fname = apr_pstrndup(ptemp, fname, rest - fname);
-		rest++;
-	}
-
-	/* optimisation - if the filename isn't a wildcard, process it directly */
-	if (!apr_fnmatch_test(fname)) {
-		path = make_full_path(ptemp, path, fname);
-		if (!rest) {
-			return process_resource_config_nofnmatch(path,
-			                                         ari, p,
-			                                         ptemp, 0, optional);
-		}
-		else {
-			return process_resource_config_fnmatch(path, rest,
-			                                       ari, p,
-			                                       ptemp, 0, optional);
-		}
-	}
-
-	/*
-	 * first course of business is to grok all the directory
-	 * entries here and store 'em away. Recall we need full pathnames
-	 * for this.
-	 */
-	rv = apr_dir_open(&dirp, path, ptemp);
-	if (rv != APR_SUCCESS) {
-		return apr_psprintf(p, "Could not open config directory %s: %pm",
-		                    path, &rv);
-	}
-
-	candidates = apr_array_make(ptemp, 1, sizeof(fnames));
-	while (apr_dir_read(&dirent, APR_FINFO_DIRENT | APR_FINFO_TYPE, dirp) == APR_SUCCESS) {
-		/* strip out '.' and '..' */
-		if (strcmp(dirent.name, ".") != 0
-		    && strcmp(dirent.name, "..") != 0
-		    && (apr_fnmatch(fname, dirent.name,
-			                APR_FNM_PERIOD) == APR_SUCCESS)) {
-			const char *full_path = make_full_path(ptemp, path, dirent.name);
-			/* If matching internal to path, and we happen to match something
-			 * other than a directory, skip it
-			 */
-			if (rest && (rv == APR_SUCCESS) && (dirent.filetype != APR_DIR)) {
-				continue;
-			}
-			fnew = (fnames *) apr_array_push(candidates);
-			fnew->fname = full_path;
-		}
-	}
-
-	apr_dir_close(dirp);
-	if (candidates->nelts != 0) {
-		const char *error;
-
-		qsort((void *) candidates->elts, candidates->nelts,
-		      sizeof(fnames), fname_alphasort);
-
-		/*
-		 * Now recurse these... we handle errors and subdirectories
-		 * via the recursion, which is nice
-		 */
-		for (current = 0; current < candidates->nelts; ++current) {
-			fnew = &((fnames *) candidates->elts)[current];
-			if (!rest) {
-				error = process_resource_config_nofnmatch(fnew->fname,
-				                                          ari, p,
-				                                          ptemp, 0, optional);
-			}
-			else {
-				error = process_resource_config_fnmatch(fnew->fname, rest,
-				                                        ari, p,
-				                                        ptemp, 0, optional);
-			}
-			if (error) {
-				return error;
-			}
-		}
-	}
-	else {
-
-		if (!optional) {
-			return apr_psprintf(p, "No matches for the wildcard '%s' in '%s', failing "
-			                    "(use IncludeOptional if required)", fname, path);
-		}
-	}
-
-	return NULL;
-}
-
-static const char *process_fnmatch_configs(const char *fname,
-                                           apr_array_header_t *ari,
-                                           apr_pool_t *p,
-                                           apr_pool_t *ptemp,
-                                           int optional)
-{
-	if (!apr_fnmatch_test(fname)) {
-		return process_resource_config_nofnmatch(fname, ari, p, ptemp, 0, optional);
-	}
-	else {
-		apr_status_t status;
-		const char *rootpath, *filepath = fname;
-
-		/* locate the start of the directories proper */
-		status = apr_filepath_root(&rootpath, &filepath, APR_FILEPATH_TRUENAME, ptemp);
-
-		/* we allow APR_SUCCESS and APR_EINCOMPLETE */
-		if (APR_ERELATIVE == status) {
-			return apr_pstrcat(p, "Include must have an absolute path, ", fname, NULL);
-		}
-		else if (APR_EBADPATH == status) {
-			return apr_pstrcat(p, "Include has a bad path, ", fname, NULL);
-		}
-
-		/* walk the filepath */
-		return process_resource_config_fnmatch(rootpath, filepath, ari, p, ptemp,
-		                                       0, optional);
-	}
-}
-
-const char *read_module_config(server_rec *s, void *mconfig,
-                               const command_rec *cmds,
-                               apr_pool_t *p, apr_pool_t *ptemp,
-                               const char *filename)
-{
-	apr_array_header_t *ari, *arr;
-	ap_directive_t *newdir;
-	cmd_parms *parms;
-
-	char line[MAX_STRING_LEN];
-	const char *errmsg;
-	const char *err = NULL;
-
-	ari = apr_array_make(p, 1, sizeof(char *));
-	arr = apr_array_make(p, 1, sizeof(cmd_parms));
-
-	errmsg = process_fnmatch_configs(filename, ari, p, ptemp, 0);
-
-	if (errmsg != NULL)
-		goto out;
-
-	while (ari->nelts || arr->nelts) {
-
-		/* similar to process_command_config() */
-		if (ari->nelts) {
-			char *inc = *(char **)apr_array_pop(ari);
-
-			parms = (cmd_parms *)apr_array_push(arr);
-			*parms = default_parms;
-			parms->pool = p;
-			parms->temp_pool = ptemp;
-			parms->server = s;
-			parms->override = (RSRC_CONF | ACCESS_CONF);
-			parms->override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI;
-
-			if (pcfg_openfile(&parms->config_file, p, inc) != APR_SUCCESS) {
-				apr_array_pop(arr);
-				errmsg = apr_pstrcat(p, "Cannot open file: ", inc, NULL);
-				goto out;
-			}
-		}
-
-		if (arr->nelts > MAX_INCLUDE_DIR_DEPTH) {
-			errmsg = apr_psprintf(p, "Exceeded the maximum include "
-			                      "directory nesting level of %u. You have "
-			                      "probably a recursion somewhere.",
-			                      MAX_INCLUDE_DIR_DEPTH);
-			goto out;
-		}
-
-		if (!(parms = (cmd_parms *)apr_array_pop(arr)))
-			break;
-
-		while (!(cfg_getline(line, MAX_STRING_LEN, parms->config_file))) {
-
-			const command_rec *cmd;
-			char *cmd_name;
-			const char *args = line;
-			int optional = 0;
-
-			if (*line == '#' || *line == '\0')
-				continue;
-
-			if (!(cmd_name = getword_conf(p, &args)))
-				continue;
-
-			/* similar to invoke_cmd() */
-			if (strcasecmp(cmd_name, "IncludeOptional") == 0 ||
-			    strcasecmp(cmd_name, "Include") == 0)
-			{
-				char *w, *fullname;
-
-				if (strcasecmp(cmd_name, "IncludeOptional") == 0)
-					optional = 1;
-
-				w = getword_conf(parms->pool, &args);
-
-				if (*w == '\0' || *args != 0) {
-					errmsg = apr_pstrcat(parms->pool, cmd_name, " takes one argument", NULL);
-					goto out;
-				}
-
-				fullname = ap_server_root_relative(ptemp, w);
-				errmsg = process_fnmatch_configs(fullname, ari, p, ptemp, optional);
-
-				*(cmd_parms *)apr_array_push(arr) = *parms;
-
-				if(errmsg != NULL)
-					goto out;
-
-				parms = NULL;
-				break;
-			}
-
-			if (!(cmd = find_command(cmd_name, cmds))) {
-				errmsg = apr_pstrcat(parms->pool, "Invalid command '",
-				                     cmd_name, "'", NULL);
-				goto out;
-			}
-
-			newdir = apr_pcalloc(p, sizeof(ap_directive_t));
-			newdir->filename = parms->config_file->name;
-			newdir->line_num = parms->config_file->line_number;
-			newdir->directive = cmd_name;
-			newdir->args = apr_pstrdup(p, args);
-
-			parms->directive = newdir;
-
-			if ((errmsg = invoke_cmd(cmd, parms, mconfig, args)) != NULL)
-				break;
-		}
-
-		if (parms != NULL)
-			cfg_closefile(parms->config_file);
-
-		if (errmsg != NULL)
-			break;
-	}
-
-	if (errmsg) {
-		if (parms) {
-			err = apr_psprintf(p, "Syntax error on line %d of %s: %s",
-			                   parms->config_file->line_number,
-			                   parms->config_file->name,
-			                   errmsg);
-			errmsg = err;
-		}
-	}
-
-out:
-
-	while ((parms = (cmd_parms *)apr_array_pop(arr)) != NULL)
-		cfg_closefile(parms->config_file);
-
-	return errmsg;
-}
-
-int lookup_builtin_method(const char *method, apr_size_t len)
-{
-	/* Note: from Apache 2 HTTP Server source. */
-
-	/* Note: the following code was generated by the "shilka" tool from
-	   the "cocom" parsing/compilation toolkit. It is an optimized lookup
-	   based on analysis of the input keywords. Postprocessing was done
-	   on the shilka output, but the basic structure and analysis is
-	   from there. Should new HTTP methods be added, then manual insertion
-	   into this code is fine, or simply re-running the shilka tool on
-	   the appropriate input. */
-
-	/* Note: it is also quite reasonable to just use our method_registry,
-	   but I'm assuming (probably incorrectly) we want more speed here
-	   (based on the optimizations the previous code was doing). */
-
-	switch (len)
-	{
-	case 3:
-		switch (method[0])
-		{
-		case 'P':
-			return (method[1] == 'U'
-			        && method[2] == 'T'
-			        ? M_PUT : UNKNOWN_METHOD);
-		case 'G':
-			return (method[1] == 'E'
-			        && method[2] == 'T'
-			        ? M_GET : UNKNOWN_METHOD);
-		default:
-			return UNKNOWN_METHOD;
-		}
-
-	case 4:
-		switch (method[0])
-		{
-		case 'H':
-			return (method[1] == 'E'
-			        && method[2] == 'A'
-			        && method[3] == 'D'
-			        ? M_GET : UNKNOWN_METHOD);
-		case 'P':
-			return (method[1] == 'O'
-			        && method[2] == 'S'
-			        && method[3] == 'T'
-			        ? M_POST : UNKNOWN_METHOD);
-		case 'M':
-			return (method[1] == 'O'
-			        && method[2] == 'V'
-			        && method[3] == 'E'
-			        ? M_MOVE : UNKNOWN_METHOD);
-		case 'L':
-			return (method[1] == 'O'
-			        && method[2] == 'C'
-			        && method[3] == 'K'
-			        ? M_LOCK : UNKNOWN_METHOD);
-		case 'C':
-			return (method[1] == 'O'
-			        && method[2] == 'P'
-			        && method[3] == 'Y'
-			        ? M_COPY : UNKNOWN_METHOD);
-		default:
-			return UNKNOWN_METHOD;
-		}
-
-	case 5:
-		switch (method[2])
-		{
-		case 'T':
-			return (memcmp(method, "PATCH", 5) == 0
-			        ? M_PATCH : UNKNOWN_METHOD);
-		case 'R':
-			return (memcmp(method, "MERGE", 5) == 0
-			        ? M_MERGE : UNKNOWN_METHOD);
-		case 'C':
-			return (memcmp(method, "MKCOL", 5) == 0
-			        ? M_MKCOL : UNKNOWN_METHOD);
-		case 'B':
-			return (memcmp(method, "LABEL", 5) == 0
-			        ? M_LABEL : UNKNOWN_METHOD);
-		case 'A':
-			return (memcmp(method, "TRACE", 5) == 0
-			        ? M_TRACE : UNKNOWN_METHOD);
-		default:
-			return UNKNOWN_METHOD;
-		}
-
-	case 6:
-		switch (method[0])
-		{
-		case 'U':
-			switch (method[5])
-			{
-			case 'K':
-				return (memcmp(method, "UNLOCK", 6) == 0
-				        ? M_UNLOCK : UNKNOWN_METHOD);
-			case 'E':
-				return (memcmp(method, "UPDATE", 6) == 0
-				        ? M_UPDATE : UNKNOWN_METHOD);
-			default:
-				return UNKNOWN_METHOD;
-			}
-		case 'R':
-			return (memcmp(method, "REPORT", 6) == 0
-			        ? M_REPORT : UNKNOWN_METHOD);
-		case 'D':
-			return (memcmp(method, "DELETE", 6) == 0
-			        ? M_DELETE : UNKNOWN_METHOD);
-		default:
-			return UNKNOWN_METHOD;
-		}
-
-	case 7:
-		switch (method[1])
-		{
-		case 'P':
-			return (memcmp(method, "OPTIONS", 7) == 0
-			        ? M_OPTIONS : UNKNOWN_METHOD);
-		case 'O':
-			return (memcmp(method, "CONNECT", 7) == 0
-			        ? M_CONNECT : UNKNOWN_METHOD);
-		case 'H':
-			return (memcmp(method, "CHECKIN", 7) == 0
-			        ? M_CHECKIN : UNKNOWN_METHOD);
-		default:
-			return UNKNOWN_METHOD;
-		}
-
-	case 8:
-		switch (method[0])
-		{
-		case 'P':
-			return (memcmp(method, "PROPFIND", 8) == 0
-			        ? M_PROPFIND : UNKNOWN_METHOD);
-		case 'C':
-			return (memcmp(method, "CHECKOUT", 8) == 0
-			        ? M_CHECKOUT : UNKNOWN_METHOD);
-		default:
-			return UNKNOWN_METHOD;
-		}
-
-	case 9:
-		return (memcmp(method, "PROPPATCH", 9) == 0
-                ? M_PROPPATCH : UNKNOWN_METHOD);
-
-	case 10:
-		switch (method[0])
-		{
-		case 'U':
-			return (memcmp(method, "UNCHECKOUT", 10) == 0
-			        ? M_UNCHECKOUT : UNKNOWN_METHOD);
-		case 'M':
-			return (memcmp(method, "MKACTIVITY", 10) == 0
-			        ? M_MKACTIVITY : UNKNOWN_METHOD);
-		default:
-			return UNKNOWN_METHOD;
-		}
-
-	case 11:
-		return (memcmp(method, "MKWORKSPACE", 11) == 0
-		        ? M_MKWORKSPACE : UNKNOWN_METHOD);
-
-	case 15:
-		return (memcmp(method, "VERSION-CONTROL", 15) == 0
-		        ? M_VERSION_CONTROL : UNKNOWN_METHOD);
-
-	case 16:
-		return (memcmp(method, "BASELINE-CONTROL", 16) == 0
-		        ? M_BASELINE_CONTROL : UNKNOWN_METHOD);
-
-	default:
-		return UNKNOWN_METHOD;
-	}
-
-	/* NOTREACHED */
-}
diff --git a/contrib/mod_defender/standalone.h b/contrib/mod_defender/standalone.h
deleted file mode 100644
index 9c9ccdd..0000000
--- a/contrib/mod_defender/standalone.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Mod Defender for HAProxy
- *
- * Support for the Mod Defender code on non-Apache platforms.
- *
- * Copyright 2017 HAProxy Technologies, Dragan Dosen <ddosen@haproxy.com>
- *
- * Parts of code based on Apache HTTP Server source
- * Copyright 2015 The Apache Software Foundation (http://www.apache.org/)
- *
- * This program 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 of the License, or (at your option) any later version.
- *
- */
-#ifndef __STANDALONE_H__
-#define __STANDALONE_H__
-
-#include <http_core.h>
-#include <http_main.h>
-#include <http_config.h>
-
-#include <apr_pools.h>
-#include <apr_hooks.h>
-
-#define INSERT_BEFORE(f, before_this) ((before_this) == NULL                \
-                           || (before_this)->frec->ftype > (f)->frec->ftype \
-                           || (before_this)->r != (f)->r)
-
-#define DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args)                           \
-ns##_HOOK_##name##_t *run_##ns##_hook_##name = NULL;                           \
-link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf,                \
-                                      const char * const *aszPre,              \
-                                      const char * const *aszSucc, int nOrder) \
-{                                                                              \
-	run_##ns##_hook_##name = pf;                                           \
-}
-
-#define DECLARE_HOOK(ret,name,args) \
-	DECLARE_EXTERNAL_HOOK(ap,AP,ret,name,args)
-
-#define UNKNOWN_METHOD (-1)
-
-extern void (*logger)(int level, char *str);
-extern const char *read_module_config(server_rec *s, void *mconfig,
-                                      const command_rec *cmds,
-                                      apr_pool_t *p, apr_pool_t *ptemp,
-                                      const char *filename);
-extern int lookup_builtin_method(const char *method, apr_size_t len);
-
-#endif /* __STANDALONE_H__ */