From da76459dc21b5af2449af2d36eb95226cb186ce2 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:35:11 +0200 Subject: Adding upstream version 2.6.12. Signed-off-by: Daniel Baumann --- admin/dyncookie/dyncookie.c | 56 + admin/halog/README | 4 + admin/halog/fgets2.c | 267 +++ admin/halog/halog.c | 1910 ++++++++++++++++++++ admin/iprange/Makefile | 13 + admin/iprange/ip6range.c | 397 ++++ admin/iprange/iprange.c | 202 +++ admin/netsnmp-perl/README | 111 ++ .../cacti_data_query_haproxy_backends.xml | 750 ++++++++ .../cacti_data_query_haproxy_frontends.xml | 750 ++++++++ admin/netsnmp-perl/haproxy.pl | 249 +++ admin/netsnmp-perl/haproxy_backend.xml | 83 + admin/netsnmp-perl/haproxy_frontend.xml | 83 + admin/netsnmp-perl/haproxy_socket.xml | 90 + admin/release-estimator/README.md | 68 + admin/release-estimator/release-estimator.py | 429 +++++ admin/selinux/README | 18 + admin/selinux/haproxy.fc | 6 + admin/selinux/haproxy.if | 2 + admin/selinux/haproxy.te | 66 + admin/syntax-highlight/haproxy.vim | 164 ++ admin/systemd/Makefile | 8 + admin/systemd/haproxy.service.in | 37 + admin/wireshark-dissectors/peers/Makefile | 17 + admin/wireshark-dissectors/peers/README | 78 + admin/wireshark-dissectors/peers/packet-happp.c | 1679 +++++++++++++++++ .../peers/wireshark.happp.dissector.patch | 24 + 27 files changed, 7561 insertions(+) create mode 100644 admin/dyncookie/dyncookie.c create mode 100644 admin/halog/README create mode 100644 admin/halog/fgets2.c create mode 100644 admin/halog/halog.c create mode 100644 admin/iprange/Makefile create mode 100644 admin/iprange/ip6range.c create mode 100644 admin/iprange/iprange.c create mode 100644 admin/netsnmp-perl/README create mode 100644 admin/netsnmp-perl/cacti_data_query_haproxy_backends.xml create mode 100644 admin/netsnmp-perl/cacti_data_query_haproxy_frontends.xml create mode 100644 admin/netsnmp-perl/haproxy.pl create mode 100644 admin/netsnmp-perl/haproxy_backend.xml create mode 100644 admin/netsnmp-perl/haproxy_frontend.xml create mode 100644 admin/netsnmp-perl/haproxy_socket.xml create mode 100644 admin/release-estimator/README.md create mode 100755 admin/release-estimator/release-estimator.py create mode 100644 admin/selinux/README create mode 100644 admin/selinux/haproxy.fc create mode 100644 admin/selinux/haproxy.if create mode 100644 admin/selinux/haproxy.te create mode 100644 admin/syntax-highlight/haproxy.vim create mode 100644 admin/systemd/Makefile create mode 100644 admin/systemd/haproxy.service.in create mode 100644 admin/wireshark-dissectors/peers/Makefile create mode 100644 admin/wireshark-dissectors/peers/README create mode 100644 admin/wireshark-dissectors/peers/packet-happp.c create mode 100644 admin/wireshark-dissectors/peers/wireshark.happp.dissector.patch (limited to 'admin') diff --git a/admin/dyncookie/dyncookie.c b/admin/dyncookie/dyncookie.c new file mode 100644 index 0000000..ddb71a7 --- /dev/null +++ b/admin/dyncookie/dyncookie.c @@ -0,0 +1,56 @@ +/* + * Dynamic server cookie calculator + * + * Copyright 2021 Willy Tarreau + * + * 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. + * + */ + +#include +#include +#include +#include + +#include + +__attribute__((noreturn)) void die(int code, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + exit(code); +} + +int main(int argc, char **argv) +{ + size_t key_len; + int addr_len; + char *buf; + int port; + + if (argc < 4) + die(1, "Usage: %s \n", argv[0]); + + key_len = strlen(argv[1]); + buf = realloc(strdup(argv[1]), key_len + 16 + 4); + if (!buf) + die(2, "Not enough memory\n"); + + if (inet_pton(AF_INET, argv[2], buf + key_len) > 0) + addr_len = 4; + else if (inet_pton(AF_INET6, argv[2], buf + key_len) > 0) + addr_len = 16; + else + die(3, "Cannot parse address <%s> as IPv4/IPv6\n", argv[2]); + + port = htonl(atoi(argv[3])); + memcpy(buf + key_len + addr_len, &port, 4); + printf("%016llx\n", (long long)XXH64(buf, key_len + addr_len + 4, 0)); + return 0; +} diff --git a/admin/halog/README b/admin/halog/README new file mode 100644 index 0000000..ff1bb12 --- /dev/null +++ b/admin/halog/README @@ -0,0 +1,4 @@ +This needs to be built from the top makefile, for example : + + make admin/halog/halog + diff --git a/admin/halog/fgets2.c b/admin/halog/fgets2.c new file mode 100644 index 0000000..7fbe16b --- /dev/null +++ b/admin/halog/fgets2.c @@ -0,0 +1,267 @@ +/* + * fast fgets() replacement for log parsing + * + * Copyright 2000-2012 Willy Tarreau + * + * 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 + * + * This function manages its own buffer and returns a pointer to that buffer + * in order to avoid expensive memory copies. It also checks for line breaks + * 32 or 64 bits at a time. It could be improved a lot using mmap() but we + * would not be allowed to replace trailing \n with zeroes and we would be + * limited to small log files on 32-bit machines. + * + */ + +#include +#include +#include +#include + +#ifndef FGETS2_BUFSIZE +#define FGETS2_BUFSIZE (256*1024) +#endif + +/* memchr() is faster in glibc with SSE since commit 093ecf92998de2 */ +#if defined(__x86_64__) && defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 15)) +#define USE_MEMCHR +#endif + +/* return non-zero if the integer contains at least one zero byte */ +static inline __attribute__((unused)) unsigned int has_zero32(unsigned int x) +{ + unsigned int y; + + /* Principle: we want to perform 4 tests on one 32-bit int at once. For + * this, we have to simulate an SIMD instruction which we don't have by + * default. The principle is that a zero byte is the only one which + * will cause a 1 to appear on the upper bit of a byte/word/etc... when + * we subtract 1. So we can detect a zero byte if a one appears at any + * of the bits 7, 15, 23 or 31 where it was not. It takes only one + * instruction to test for the presence of any of these bits, but it is + * still complex to check for their initial absence. Thus, we'll + * proceed differently : we first save and clear only those bits, then + * we check in the final result if one of them is present and was not. + * The order of operations below is important to save registers and + * tests. The result is used as a boolean, so the last test must apply + * on the constant so that it can efficiently be inlined. + */ +#if defined(__i386__) + /* gcc on x86 loves copying registers over and over even on code that + * simple, so let's do it by hand to prevent it from doing so :-( + */ + asm("lea -0x01010101(%0),%1\n" + "not %0\n" + "and %1,%0\n" + : "=a" (x), "=r"(y) + : "0" (x) + ); + return x & 0x80808080; +#else + y = x - 0x01010101; /* generate a carry */ + x = ~x & y; /* clear the bits that were already set */ + return x & 0x80808080; +#endif +} + +/* return non-zero if the argument contains at least one zero byte. See principle above. */ +static inline __attribute__((unused)) unsigned long long has_zero64(unsigned long long x) +{ + unsigned long long y; + + y = x - 0x0101010101010101ULL; /* generate a carry */ + y &= ~x; /* clear the bits that were already set */ + return y & 0x8080808080808080ULL; +} + +static inline __attribute__((unused)) unsigned long has_zero(unsigned long x) +{ + return (sizeof(x) == 8) ? has_zero64(x) : has_zero32(x); +} + +/* find a '\n' between and . Warning: may read slightly past . + * If no '\n' is found, is returned. + */ +static char *find_lf(char *next, char *end) +{ +#if defined USE_MEMCHR + /* some recent libc use platform-specific optimizations to provide more + * efficient byte search than below (eg: glibc 2.11 on x86_64). + */ + next = memchr(next, '\n', end - next); + if (!next) + next = end; +#else + if (sizeof(long) == 4) { /* 32-bit system */ + /* this is a speed-up, we read 32 bits at once and check for an + * LF character there. We stop if found then continue one at a + * time. + */ + while (next < end && (((unsigned long)next) & 3) && *next != '\n') + next++; + + /* Now next is multiple of 4 or equal to end. We know we can safely + * read up to 32 bytes past end if needed because they're allocated. + */ + while (next < end) { + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + } + } + else { /* 64-bit system */ + /* this is a speed-up, we read 64 bits at once and check for an + * LF character there. We stop if found then continue one at a + * time. + */ + if (next <= end) { + /* max 3 bytes tested here */ + while ((((unsigned long)next) & 3) && *next != '\n') + next++; + + /* maybe we have can skip 4 more bytes */ + if ((((unsigned long)next) & 4) && !has_zero32(*(unsigned int *)next ^ 0x0A0A0A0AU)) + next += 4; + } + + /* now next is multiple of 8 or equal to end */ + while (next <= (end-68)) { + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + } + + /* maybe we can skip 4 more bytes */ + if (!has_zero32(*(unsigned int *)next ^ 0x0A0A0A0AU)) + next += 4; + } + + /* We finish if needed : if is below , it means we + * found an LF in one of the 4 following bytes. + */ + while (next < end) { + if (*next == '\n') + break; + next++; + } +#endif + return next; +} + +const char *fgets2(FILE *stream) +{ + static char buffer[FGETS2_BUFSIZE + 68]; /* Note: +32 is enough on 32-bit systems */ + static char *end = buffer; + static char *line = buffer; + char *next; + int ret; + + next = line; + + while (1) { + next = find_lf(next, end); + if (next < end) { + const char *start = line; + *next = '\0'; + line = next + 1; + return start; + } + + /* we found an incomplete line. First, let's move the + * remaining part of the buffer to the beginning, then + * try to complete the buffer with a new read. We can't + * rely on anymore because it went past . + */ + if (line > buffer) { + if (end != line) + memmove(buffer, line, end - line); + end = buffer + (end - line); + next = end; + line = buffer; + } else { + if (end == buffer + FGETS2_BUFSIZE) + return NULL; + } + + ret = read(fileno(stream), end, buffer + FGETS2_BUFSIZE - end); + + if (ret <= 0) { + if (end == line) + return NULL; + + *end = '\0'; + end = line; /* ensure we stop next time */ + return line; + } + + end += ret; + *end = '\n'; /* make parser stop ASAP */ + /* search for '\n' again */ + } +} + +#ifdef BENCHMARK +int main() { + const char *p; + unsigned int lines = 0; + + while ((p=fgets2(stdin))) + lines++; + printf("lines=%u\n", lines); + return 0; +} +#endif diff --git a/admin/halog/halog.c b/admin/halog/halog.c new file mode 100644 index 0000000..45eec75 --- /dev/null +++ b/admin/halog/halog.c @@ -0,0 +1,1910 @@ +/* + * haproxy log statistics reporter + * + * Copyright 2000-2012 Willy Tarreau + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#define SOURCE_FIELD 5 +#define ACCEPT_FIELD 6 +#define SERVER_FIELD 8 +#define TIME_FIELD 9 +#define STATUS_FIELD 10 +#define BYTES_SENT_FIELD 11 +#define TERM_CODES_FIELD 14 +#define CONN_FIELD 15 +#define QUEUE_LEN_FIELD 16 +#define METH_FIELD 17 +#define URL_FIELD 18 +#define MAXLINE 16384 +#define QBITS 4 + +#define SEP(c) ((unsigned char)(c) <= ' ') +#define SKIP_CHAR(p,c) do { while (1) { int __c = (unsigned char)*p++; if (__c == c) break; if (__c <= ' ') { p--; break; } } } while (0) + +/* [0] = err/date, [1] = req, [2] = conn, [3] = resp, [4] = data */ +static struct eb_root timers[5] = { + EB_ROOT_UNIQUE, EB_ROOT_UNIQUE, EB_ROOT_UNIQUE, + EB_ROOT_UNIQUE, EB_ROOT_UNIQUE, +}; + +struct timer { + struct eb32_node node; + unsigned int count; +}; + +struct srv_st { + unsigned int st_cnt[6]; /* 0xx to 5xx */ + unsigned int nb_ct, nb_rt, nb_ok; + unsigned long long cum_ct, cum_rt; + struct ebmb_node node; + /* don't put anything else here, the server name will be there */ +}; + +struct url_stat { + union { + struct ebpt_node url; + struct eb64_node val; + } node; + char *url; + unsigned long long total_time; /* sum(all reqs' times) */ + unsigned long long total_time_ok; /* sum(all OK reqs' times) */ + unsigned long long total_bytes_sent; /* sum(all bytes sent) */ + unsigned int nb_err, nb_req; +}; + +#define FILT_COUNT_ONLY 0x01 +#define FILT_INVERT 0x02 +#define FILT_QUIET 0x04 +#define FILT_ERRORS_ONLY 0x08 +#define FILT_ACC_DELAY 0x10 +#define FILT_ACC_COUNT 0x20 +#define FILT_GRAPH_TIMERS 0x40 +#define FILT_PERCENTILE 0x80 +#define FILT_TIME_RESP 0x100 + +#define FILT_INVERT_ERRORS 0x200 +#define FILT_INVERT_TIME_RESP 0x400 + +#define FILT_COUNT_STATUS 0x800 +#define FILT_COUNT_SRV_STATUS 0x1000 +#define FILT_COUNT_TERM_CODES 0x2000 + +#define FILT_COUNT_URL_ONLY 0x004000 +#define FILT_COUNT_URL_COUNT 0x008000 +#define FILT_COUNT_URL_ERR 0x010000 +#define FILT_COUNT_URL_TTOT 0x020000 +#define FILT_COUNT_URL_TAVG 0x040000 +#define FILT_COUNT_URL_TTOTO 0x080000 +#define FILT_COUNT_URL_TAVGO 0x100000 + +#define FILT_HTTP_ONLY 0x200000 +#define FILT_TERM_CODE_NAME 0x400000 +#define FILT_INVERT_TERM_CODE_NAME 0x800000 + +#define FILT_HTTP_STATUS 0x1000000 +#define FILT_INVERT_HTTP_STATUS 0x2000000 +#define FILT_QUEUE_ONLY 0x4000000 +#define FILT_QUEUE_SRV_ONLY 0x8000000 + +#define FILT_COUNT_URL_BAVG 0x10000000 +#define FILT_COUNT_URL_BTOT 0x20000000 + +#define FILT_COUNT_URL_ANY (FILT_COUNT_URL_ONLY|FILT_COUNT_URL_COUNT|FILT_COUNT_URL_ERR| \ + FILT_COUNT_URL_TTOT|FILT_COUNT_URL_TAVG|FILT_COUNT_URL_TTOTO|FILT_COUNT_URL_TAVGO| \ + FILT_COUNT_URL_BAVG|FILT_COUNT_URL_BTOT) + +#define FILT_COUNT_COOK_CODES 0x40000000 +#define FILT_COUNT_IP_COUNT 0x80000000 + +#define FILT2_TIMESTAMP 0x01 +#define FILT2_PRESERVE_QUERY 0x02 +#define FILT2_EXTRACT_CAPTURE 0x04 + +unsigned int filter = 0; +unsigned int filter2 = 0; +unsigned int filter_invert = 0; +const char *line; +int linenum = 0; +int parse_err = 0; +int lines_out = 0; +int lines_max = -1; + +const char *fgets2(FILE *stream); + +void filter_count_url(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_count_ip(const char *source_field, const char *accept_field, const char *time_field, struct timer **tptr); +void filter_count_srv_status(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_count_cook_codes(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_count_term_codes(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_count_status(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_graphs(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_output_line(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_extract_capture(const char *accept_field, const char *time_field, unsigned int, unsigned int); +void filter_accept_holes(const char *accept_field, const char *time_field, struct timer **tptr); + +void usage(FILE *output, const char *msg) +{ + fprintf(output, + "%s" + "Usage:\n" + " halog [-h|--help] for long help\n" + " halog [input_filters]* [modifiers]* [output_format] < log\n" + " inp = [-e|-E] [-H] [-Q|-QS] [-rt|-RT