Blob Blame History Raw
/*
 * Soft:        Keepalived is a failover program for the LVS project
 *              <www.linuxvirtualserver.org>. It monitor & manipulate
 *              a loadbalanced server pool using multi-layer checks.
 *
 * Part:        check_http.c include file.
 *
 * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
 *              Jan Holmberg, <jan@artech.net>
 *
 *              This program is distributed in the hope that it will be useful,
 *              but WITHOUT ANY WARRANTY; without even the implied warranty of
 *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *              See the GNU General Public License for more details.
 *
 *              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
 *              2 of the License, or (at your option) any later version.
 *
 * Copyright (C) 2001-2017 Alexandre Cassen, <acassen@gmail.com>
 */

#ifndef _CHECK_HTTP_H
#define _CHECK_HTTP_H

/* system includes */
#include <sys/types.h>
#include <stdbool.h>
#include <openssl/md5.h>
#include <openssl/ssl.h>
#ifdef _WITH_REGEX_CHECK_
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
#ifdef _WITH_REGEX_TIMERS_
#include <time.h>
#endif
#endif
#include <stdbool.h>

/* local includes */
#include "scheduler.h"
#include "list.h"

/* Checker argument structure  */
/* ssl specific thread arguments defs */
typedef struct _request {
	char				*buffer;
	char				*extracted;
	int				error;
	int				status_code;
	size_t				len;
	SSL				*ssl;
	BIO				*bio;
	MD5_CTX				context;
	size_t				content_len;
	size_t				rx_bytes;
#ifdef _WITH_REGEX_CHECK_
	bool				regex_matched;
	size_t				start_offset;	/* Offset into buffer to match from */
	size_t				regex_subject_offset;	/* Offset into web page of start of buffer */
#ifdef _WITH_REGEX_TIMERS_
	struct timespec			req_time;
	unsigned			num_match_calls;
#endif
#endif
} request_t;

#ifdef _WITH_REGEX_CHECK_
typedef struct _regex {
	unsigned char			*pattern;
	int				pcre2_options;
	pcre2_code			*pcre2_reCompiled;
	pcre2_match_data		*pcre2_match_data;
	uint32_t			pcre2_max_lookbehind;
	unsigned			use_count;
#ifdef _WITH_REGEX_TIMERS_
	struct timespec			regex_time;
	unsigned			num_match_calls;
	unsigned			num_regex_urls;
#endif
} regex_t;
#endif

typedef struct _url {
	char				*path;
	uint8_t				*digest;
	int				status_code;
	char				*virtualhost;
	ssize_t				len_mismatch;
#ifdef _WITH_REGEX_CHECK_
	bool				regex_no_match;
	regex_t				*regex;
	size_t				regex_min_offset;
	size_t				regex_max_offset;	/* One beyond max offset */
#ifndef PCRE2_DONT_USE_JIT
	bool				regex_use_stack;
#endif
#endif
} url_t;

typedef struct _http_checker {
	unsigned			proto;
	unsigned			url_it;		/* current url checked index */
	request_t			*req;		/* GET buffer and SSL args */
	list				url;
	char				*virtualhost;
#ifdef _HAVE_SSL_SET_TLSEXT_HOST_NAME_
	bool				enable_sni;
#endif
} http_checker_t;

/* global defs */
#define GET_BUFFER_LENGTH 2048U
#define MAX_BUFFER_LENGTH 4096U
#define PROTO_HTTP	0x01
#define PROTO_SSL	0x02

/* GET processing command */
#define REQUEST_TEMPLATE "GET %s HTTP/1.0\r\n" \
			 "User-Agent: KeepAliveClient\r\n" \
			 "Host: %s%s\r\n\r\n"

#define REQUEST_TEMPLATE_IPV6 "GET %s HTTP/1.0\r\n" \
			 "User-Agent: KeepAliveClient\r\n" \
			 "Host: [%s]%s\r\n\r\n"

/* macro utility */
#define FMT_HTTP_RS(C) FMT_CHK(C)

#ifdef _REGEX_DEBUG_
extern bool do_regex_debug;
#endif
#ifdef _WITH_REGEX_TIMERS_
extern bool do_regex_timers;
#endif

/* Define prototypes */
extern void install_http_check_keyword(void);
extern int timeout_epilog(thread_t *, const char *);
extern void http_process_response(request_t *, size_t, url_t *);
extern int http_handle_response(thread_t *, unsigned char digest[16], bool);
#ifdef THREAD_DUMP
extern void register_check_http_addresses(void);
#endif

#endif