Compare commits
6 Commits
master
...
20250424-c
Author | SHA1 | Date | |
---|---|---|---|
|
95ff3a4918 | ||
|
1a74169549 | ||
|
134188ee7c | ||
|
3b6884b9ab | ||
|
0e44ef48c5 | ||
|
3479f230e0 |
80
.github/workflows/aws-lc-fips.yml
vendored
80
.github/workflows/aws-lc-fips.yml
vendored
@ -5,8 +5,82 @@ on:
|
||||
- cron: "0 0 * * 4"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
uses: ./.github/workflows/aws-lc-template.yml
|
||||
with:
|
||||
command: "from matrix import determine_latest_aws_lc_fips; print(determine_latest_aws_lc_fips(''))"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install VTest
|
||||
run: |
|
||||
scripts/build-vtest.sh
|
||||
- name: Determine latest AWS-LC release
|
||||
id: get_aws_lc_release
|
||||
run: |
|
||||
result=$(cd .github && python3 -c "from matrix import determine_latest_aws_lc_fips; print(determine_latest_aws_lc_fips(''))")
|
||||
echo $result
|
||||
echo "result=$result" >> $GITHUB_OUTPUT
|
||||
- name: Cache AWS-LC
|
||||
id: cache_aws_lc
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: '~/opt/'
|
||||
key: ssl-${{ steps.get_aws_lc_release.outputs.result }}-Ubuntu-latest-gcc
|
||||
- name: Install apt dependencies
|
||||
run: |
|
||||
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
|
||||
sudo apt-get --no-install-recommends -y install socat gdb
|
||||
- name: Install AWS-LC
|
||||
if: ${{ steps.cache_ssl.outputs.cache-hit != 'true' }}
|
||||
run: env ${{ steps.get_aws_lc_release.outputs.result }} scripts/build-ssl.sh
|
||||
- name: Compile HAProxy
|
||||
run: |
|
||||
make -j$(nproc) ERR=1 CC=gcc TARGET=linux-glibc \
|
||||
USE_OPENSSL_AWSLC=1 USE_QUIC=1 \
|
||||
SSL_LIB=${HOME}/opt/lib SSL_INC=${HOME}/opt/include \
|
||||
DEBUG="-DDEBUG_POOL_INTEGRITY" \
|
||||
ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/"
|
||||
sudo make install
|
||||
- name: Show HAProxy version
|
||||
id: show-version
|
||||
run: |
|
||||
ldd $(which haproxy)
|
||||
haproxy -vv
|
||||
echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
|
||||
- name: Install problem matcher for VTest
|
||||
run: echo "::add-matcher::.github/vtest.json"
|
||||
- name: Run VTest for HAProxy
|
||||
id: vtest
|
||||
run: |
|
||||
# This is required for macOS which does not actually allow to increase
|
||||
# the '-n' soft limit to the hard limit, thus failing to run.
|
||||
ulimit -n 65536
|
||||
# allow to catch coredumps
|
||||
ulimit -c unlimited
|
||||
make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
|
||||
- name: Show VTest results
|
||||
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
|
||||
run: |
|
||||
for folder in ${TMPDIR:-/tmp}/haregtests-*/vtc.*; do
|
||||
printf "::group::"
|
||||
cat $folder/INFO
|
||||
cat $folder/LOG
|
||||
echo "::endgroup::"
|
||||
done
|
||||
exit 1
|
||||
- name: Show coredumps
|
||||
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
|
||||
run: |
|
||||
failed=false
|
||||
shopt -s nullglob
|
||||
for file in /tmp/core.*; do
|
||||
failed=true
|
||||
printf "::group::"
|
||||
gdb -ex 'thread apply all bt full' ./haproxy $file
|
||||
echo "::endgroup::"
|
||||
done
|
||||
if [ "$failed" = true ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
103
.github/workflows/aws-lc-template.yml
vendored
103
.github/workflows/aws-lc-template.yml
vendored
@ -1,103 +0,0 @@
|
||||
name: AWS-LC template
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
command:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install VTest
|
||||
run: |
|
||||
scripts/build-vtest.sh
|
||||
- name: Determine latest AWS-LC release
|
||||
id: get_aws_lc_release
|
||||
run: |
|
||||
result=$(cd .github && python3 -c "${{ inputs.command }}")
|
||||
echo $result
|
||||
echo "result=$result" >> $GITHUB_OUTPUT
|
||||
- name: Cache AWS-LC
|
||||
id: cache_aws_lc
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: '~/opt/'
|
||||
key: ssl-${{ steps.get_aws_lc_release.outputs.result }}-Ubuntu-latest-gcc
|
||||
- name: Install apt dependencies
|
||||
run: |
|
||||
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
|
||||
sudo apt-get --no-install-recommends -y install socat gdb jose
|
||||
- name: Install AWS-LC
|
||||
if: ${{ steps.cache_ssl.outputs.cache-hit != 'true' }}
|
||||
run: env ${{ steps.get_aws_lc_release.outputs.result }} scripts/build-ssl.sh
|
||||
- name: Compile HAProxy
|
||||
run: |
|
||||
make -j$(nproc) ERR=1 CC=gcc TARGET=linux-glibc \
|
||||
USE_OPENSSL_AWSLC=1 USE_QUIC=1 \
|
||||
SSL_LIB=${HOME}/opt/lib SSL_INC=${HOME}/opt/include \
|
||||
DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" \
|
||||
ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/"
|
||||
sudo make install
|
||||
- name: Show HAProxy version
|
||||
id: show-version
|
||||
run: |
|
||||
ldd $(which haproxy)
|
||||
haproxy -vv
|
||||
echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
|
||||
- name: Install problem matcher for VTest
|
||||
run: echo "::add-matcher::.github/vtest.json"
|
||||
- name: Run VTest for HAProxy
|
||||
id: vtest
|
||||
run: |
|
||||
# This is required for macOS which does not actually allow to increase
|
||||
# the '-n' soft limit to the hard limit, thus failing to run.
|
||||
ulimit -n 65536
|
||||
# allow to catch coredumps
|
||||
ulimit -c unlimited
|
||||
make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
|
||||
- name: Run Unit tests
|
||||
id: unittests
|
||||
run: |
|
||||
make unit-tests
|
||||
- name: Show VTest results
|
||||
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
|
||||
run: |
|
||||
for folder in ${TMPDIR:-/tmp}/haregtests-*/vtc.*; do
|
||||
printf "::group::"
|
||||
cat $folder/INFO
|
||||
cat $folder/LOG
|
||||
echo "::endgroup::"
|
||||
done
|
||||
exit 1
|
||||
- name: Show coredumps
|
||||
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
|
||||
run: |
|
||||
failed=false
|
||||
shopt -s nullglob
|
||||
for file in /tmp/core.*; do
|
||||
failed=true
|
||||
printf "::group::"
|
||||
gdb -ex 'thread apply all bt full' ./haproxy $file
|
||||
echo "::endgroup::"
|
||||
done
|
||||
if [ "$failed" = true ]; then
|
||||
exit 1;
|
||||
fi
|
||||
- name: Show Unit-Tests results
|
||||
if: ${{ failure() && steps.unittests.outcome == 'failure' }}
|
||||
run: |
|
||||
for result in ${TMPDIR:-/tmp}/ha-unittests-*/results/res.*; do
|
||||
printf "::group::"
|
||||
cat $result
|
||||
echo "::endgroup::"
|
||||
done
|
||||
exit 1
|
||||
|
80
.github/workflows/aws-lc.yml
vendored
80
.github/workflows/aws-lc.yml
vendored
@ -5,8 +5,82 @@ on:
|
||||
- cron: "0 0 * * 4"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
uses: ./.github/workflows/aws-lc-template.yml
|
||||
with:
|
||||
command: "from matrix import determine_latest_aws_lc; print(determine_latest_aws_lc(''))"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install VTest
|
||||
run: |
|
||||
scripts/build-vtest.sh
|
||||
- name: Determine latest AWS-LC release
|
||||
id: get_aws_lc_release
|
||||
run: |
|
||||
result=$(cd .github && python3 -c "from matrix import determine_latest_aws_lc; print(determine_latest_aws_lc(''))")
|
||||
echo $result
|
||||
echo "result=$result" >> $GITHUB_OUTPUT
|
||||
- name: Cache AWS-LC
|
||||
id: cache_aws_lc
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: '~/opt/'
|
||||
key: ssl-${{ steps.get_aws_lc_release.outputs.result }}-Ubuntu-latest-gcc
|
||||
- name: Install apt dependencies
|
||||
run: |
|
||||
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
|
||||
sudo apt-get --no-install-recommends -y install socat gdb
|
||||
- name: Install AWS-LC
|
||||
if: ${{ steps.cache_ssl.outputs.cache-hit != 'true' }}
|
||||
run: env ${{ steps.get_aws_lc_release.outputs.result }} scripts/build-ssl.sh
|
||||
- name: Compile HAProxy
|
||||
run: |
|
||||
make -j$(nproc) ERR=1 CC=gcc TARGET=linux-glibc \
|
||||
USE_OPENSSL_AWSLC=1 USE_QUIC=1 \
|
||||
SSL_LIB=${HOME}/opt/lib SSL_INC=${HOME}/opt/include \
|
||||
DEBUG="-DDEBUG_POOL_INTEGRITY" \
|
||||
ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/"
|
||||
sudo make install
|
||||
- name: Show HAProxy version
|
||||
id: show-version
|
||||
run: |
|
||||
ldd $(which haproxy)
|
||||
haproxy -vv
|
||||
echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
|
||||
- name: Install problem matcher for VTest
|
||||
run: echo "::add-matcher::.github/vtest.json"
|
||||
- name: Run VTest for HAProxy
|
||||
id: vtest
|
||||
run: |
|
||||
# This is required for macOS which does not actually allow to increase
|
||||
# the '-n' soft limit to the hard limit, thus failing to run.
|
||||
ulimit -n 65536
|
||||
# allow to catch coredumps
|
||||
ulimit -c unlimited
|
||||
make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
|
||||
- name: Show VTest results
|
||||
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
|
||||
run: |
|
||||
for folder in ${TMPDIR:-/tmp}/haregtests-*/vtc.*; do
|
||||
printf "::group::"
|
||||
cat $folder/INFO
|
||||
cat $folder/LOG
|
||||
echo "::endgroup::"
|
||||
done
|
||||
exit 1
|
||||
- name: Show coredumps
|
||||
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
|
||||
run: |
|
||||
failed=false
|
||||
shopt -s nullglob
|
||||
for file in /tmp/core.*; do
|
||||
failed=true
|
||||
printf "::group::"
|
||||
gdb -ex 'thread apply all bt full' ./haproxy $file
|
||||
echo "::endgroup::"
|
||||
done
|
||||
if [ "$failed" = true ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
15
.github/workflows/compliance.yml
vendored
15
.github/workflows/compliance.yml
vendored
@ -11,8 +11,13 @@ permissions:
|
||||
jobs:
|
||||
h2spec:
|
||||
name: h2spec
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- TARGET: linux-glibc
|
||||
CC: gcc
|
||||
os: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install h2spec
|
||||
@ -23,12 +28,12 @@ jobs:
|
||||
tar xvf h2spec.tar.gz
|
||||
sudo install -m755 h2spec /usr/local/bin/h2spec
|
||||
echo "version=${H2SPEC_VERSION}" >> $GITHUB_OUTPUT
|
||||
- name: Compile HAProxy with gcc
|
||||
- name: Compile HAProxy with ${{ matrix.CC }}
|
||||
run: |
|
||||
make -j$(nproc) all \
|
||||
ERR=1 \
|
||||
TARGET=linux-glibc \
|
||||
CC=gcc \
|
||||
TARGET=${{ matrix.TARGET }} \
|
||||
CC=${{ matrix.CC }} \
|
||||
DEBUG="-DDEBUG_POOL_INTEGRITY" \
|
||||
USE_OPENSSL=1
|
||||
sudo make install
|
||||
|
18
.github/workflows/musl.yml
vendored
18
.github/workflows/musl.yml
vendored
@ -22,11 +22,11 @@ jobs:
|
||||
echo '/tmp/core/core.%h.%e.%t' > /proc/sys/kernel/core_pattern
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: apk add gcc gdb make tar git python3 libc-dev linux-headers pcre-dev pcre2-dev openssl-dev lua5.3-dev grep socat curl musl-dbg lua5.3-dbg jose
|
||||
run: apk add gcc gdb make tar git python3 libc-dev linux-headers pcre-dev pcre2-dev openssl-dev lua5.3-dev grep socat curl musl-dbg lua5.3-dbg
|
||||
- name: Install VTest
|
||||
run: scripts/build-vtest.sh
|
||||
- name: Build
|
||||
run: make -j$(nproc) TARGET=linux-musl DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" ARCH_FLAGS='-ggdb3' CC=cc V=1 USE_LUA=1 LUA_INC=/usr/include/lua5.3 LUA_LIB=/usr/lib/lua5.3 USE_OPENSSL=1 USE_PCRE2=1 USE_PCRE2_JIT=1 USE_PROMEX=1
|
||||
run: make -j$(nproc) TARGET=linux-musl ARCH_FLAGS='-ggdb3' CC=cc V=1 USE_LUA=1 LUA_INC=/usr/include/lua5.3 LUA_LIB=/usr/lib/lua5.3 USE_OPENSSL=1 USE_PCRE2=1 USE_PCRE2_JIT=1 USE_PROMEX=1
|
||||
- name: Show version
|
||||
run: ./haproxy -vv
|
||||
- name: Show linked libraries
|
||||
@ -37,10 +37,6 @@ jobs:
|
||||
- name: Run VTest
|
||||
id: vtest
|
||||
run: make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
|
||||
- name: Run Unit tests
|
||||
id: unittests
|
||||
run: |
|
||||
make unit-tests
|
||||
- name: Show coredumps
|
||||
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
|
||||
run: |
|
||||
@ -64,13 +60,3 @@ jobs:
|
||||
cat $folder/LOG
|
||||
echo "::endgroup::"
|
||||
done
|
||||
- name: Show Unit-Tests results
|
||||
if: ${{ failure() && steps.unittests.outcome == 'failure' }}
|
||||
run: |
|
||||
for result in ${TMPDIR:-/tmp}/ha-unittests-*/results/res.*; do
|
||||
printf "::group::"
|
||||
cat $result
|
||||
echo "::endgroup::"
|
||||
done
|
||||
exit 1
|
||||
|
||||
|
1
.github/workflows/quictls.yml
vendored
1
.github/workflows/quictls.yml
vendored
@ -15,7 +15,6 @@ permissions:
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install VTest
|
||||
|
19
.github/workflows/wolfssl.yml
vendored
19
.github/workflows/wolfssl.yml
vendored
@ -11,7 +11,6 @@ permissions:
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install VTest
|
||||
@ -20,7 +19,7 @@ jobs:
|
||||
- name: Install apt dependencies
|
||||
run: |
|
||||
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
|
||||
sudo apt-get --no-install-recommends -y install socat gdb jose
|
||||
sudo apt-get --no-install-recommends -y install socat gdb
|
||||
- name: Install WolfSSL
|
||||
run: env WOLFSSL_VERSION=git-master WOLFSSL_DEBUG=1 scripts/build-ssl.sh
|
||||
- name: Compile HAProxy
|
||||
@ -28,7 +27,7 @@ jobs:
|
||||
make -j$(nproc) ERR=1 CC=gcc TARGET=linux-glibc \
|
||||
USE_OPENSSL_WOLFSSL=1 USE_QUIC=1 \
|
||||
SSL_LIB=${HOME}/opt/lib SSL_INC=${HOME}/opt/include \
|
||||
DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" \
|
||||
DEBUG="-DDEBUG_POOL_INTEGRITY" \
|
||||
ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/" \
|
||||
ARCH_FLAGS="-ggdb3 -fsanitize=address"
|
||||
sudo make install
|
||||
@ -49,10 +48,6 @@ jobs:
|
||||
# allow to catch coredumps
|
||||
ulimit -c unlimited
|
||||
make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
|
||||
- name: Run Unit tests
|
||||
id: unittests
|
||||
run: |
|
||||
make unit-tests
|
||||
- name: Show VTest results
|
||||
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
|
||||
run: |
|
||||
@ -77,13 +72,3 @@ jobs:
|
||||
if [ "$failed" = true ]; then
|
||||
exit 1;
|
||||
fi
|
||||
- name: Show Unit-Tests results
|
||||
if: ${{ failure() && steps.unittests.outcome == 'failure' }}
|
||||
run: |
|
||||
for result in ${TMPDIR:-/tmp}/ha-unittests-*/results/res.*; do
|
||||
printf "::group::"
|
||||
cat $result
|
||||
echo "::endgroup::"
|
||||
done
|
||||
exit 1
|
||||
|
||||
|
379
CHANGELOG
379
CHANGELOG
@ -1,385 +1,6 @@
|
||||
ChangeLog :
|
||||
===========
|
||||
|
||||
2025/06/11 : 3.3-dev1
|
||||
- BUILD: tools: properly define ha_dump_backtrace() to avoid a build warning
|
||||
- DOC: config: Fix a typo in 2.7 (Name format for maps and ACLs)
|
||||
- REGTESTS: Do not use REQUIRE_VERSION for HAProxy 2.5+ (5)
|
||||
- REGTESTS: Remove REQUIRE_VERSION=2.3 from all tests
|
||||
- REGTESTS: Remove REQUIRE_VERSION=2.4 from all tests
|
||||
- REGTESTS: Remove tests with REQUIRE_VERSION_BELOW=2.4
|
||||
- REGTESTS: Remove support for REQUIRE_VERSION and REQUIRE_VERSION_BELOW
|
||||
- MINOR: server: group postinit server tasks under _srv_postparse()
|
||||
- MINOR: stats: add stat_col flags
|
||||
- MINOR: stats: add ME_NEW_COMMON() helper
|
||||
- MINOR: proxy: collect per-capability stat in proxy_cond_disable()
|
||||
- MINOR: proxy: add a true list containing all proxies
|
||||
- MINOR: log: only run postcheck_log_backend() checks on backend
|
||||
- MEDIUM: proxy: use global proxy list for REGISTER_POST_PROXY_CHECK() hook
|
||||
- MEDIUM: server: automatically add server to proxy list in new_server()
|
||||
- MEDIUM: server: add and use srv_init() function
|
||||
- BUG/MAJOR: leastconn: Protect tree_elt with the lbprm lock
|
||||
- BUG/MEDIUM: check: Requeue healthchecks on I/O events to handle check timeout
|
||||
- CLEANUP: applet: Update comment for applet_put* functions
|
||||
- DEBUG: check: Add the healthcheck's expiration date in the trace messags
|
||||
- BUG/MINOR: mux-spop: Fix null-pointer deref on SPOP stream allocation failure
|
||||
- CLEANUP: sink: remove useless cleanup in sink_new_from_logger()
|
||||
- MAJOR: counters: add shared counters base infrastructure
|
||||
- MINOR: counters: add shared counters helpers to get and drop shared pointers
|
||||
- MINOR: counters: add common struct and flags to {fe,be}_counters_shared
|
||||
- MEDIUM: counters: manage shared counters using dedicated helpers
|
||||
- CLEANUP: counters: merge some common counters between {fe,be}_counters_shared
|
||||
- MINOR: counters: add local-only internal rates to compute some maxes
|
||||
- MAJOR: counters: dispatch counters over thread groups
|
||||
- BUG/MEDIUM: cli: Properly parse empty lines and avoid crashed
|
||||
- BUG/MINOR: config: emit warning for empty args only in discovery mode
|
||||
- BUG/MINOR: config: fix arg number reported on empty arg warning
|
||||
- BUG/MINOR: quic: Missing SSL session object freeing
|
||||
- MINOR: applet: Add API functions to manipulate input and output buffers
|
||||
- MINOR: applet: Add API functions to get data from the input buffer
|
||||
- CLEANUP: applet: Simplify a bit comments for applet_put* functions
|
||||
- MEDIUM: hlua: Update TCP applet functions to use the new applet API
|
||||
- BUG/MEDIUM: fd: Use the provided tgid in fd_insert() to get tgroup_info
|
||||
- BUG/MINIR: h1: Fix doc of 'accept-unsafe-...-request' about URI parsing
|
||||
|
||||
2025/05/28 : 3.3-dev0
|
||||
- MINOR: version: mention that it's development again
|
||||
|
||||
2025/05/28 : 3.2.0
|
||||
- MINOR: promex: Add agent check status/code/duration metrics
|
||||
- MINOR: ssl: support strict-sni in ssl-default-bind-options
|
||||
- MINOR: ssl: also provide the "tls-tickets" bind option
|
||||
- MINOR: server: define CLI I/O handler for "add server"
|
||||
- MINOR: server: implement "add server help"
|
||||
- MINOR: server: use stress mode for "add server help"
|
||||
- BUG/MEDIUM: server: fix crash after duplicate GUID insertion
|
||||
- BUG/MEDIUM: server: fix potential null-deref after previous fix
|
||||
- MINOR: config: list recently added sections with -dKcfg
|
||||
- BUG/MAJOR: cache: Crash because of wrong cache entry deleted
|
||||
- DOC: configuration: fix the example in crt-store
|
||||
- DOC: config: clarify the wording around single/double quotes
|
||||
- DOC: config: clarify the legacy cookie and header captures
|
||||
- DOC: config: fix alphabetical ordering of layer 7 sample fetch functions
|
||||
- DOC: config: fix alphabetical ordering of layer 6 sample fetch functions
|
||||
- DOC: config: fix alphabetical ordering of layer 5 sample fetch functions
|
||||
- DOC: config: fix alphabetical ordering of layer 4 sample fetch functions
|
||||
- DOC: config: fix alphabetical ordering of internal sample fetch functions
|
||||
- BUG/MINOR: h3: Set HTX flags corresponding to the scheme found in the request
|
||||
- BUG/MEDIUM: h3: Declare absolute URI as normalized when a :authority is found
|
||||
- DOC: config: mention in bytes_in and bytes_out that they're read on input
|
||||
- DOC: config: clarify the basics of ACLs (call point, multi-valued etc)
|
||||
- REGTESTS: Make the script testing conditional set-var compatible with Vtest2
|
||||
- REGTESTS: Explicitly allow failing shell commands in some scripts
|
||||
- MINOR: listeners: Add support for a label on bind line
|
||||
- BUG/MEDIUM: cli/ring: Properly handle shutdown in "show event" I/O handler
|
||||
- BUG/MEDIUM: hlua: Properly detect shudowns for TCP applets based on the new API
|
||||
- BUG/MEDIUM: hlua: Fix getline() for TCP applets to work with applet's buffers
|
||||
- BUG/MEDIUM: hlua: Fix receive API for TCP applets to properly handle shutdowns
|
||||
- CI: vtest: Rely on VTest2 to run regression tests
|
||||
- CI: vtest: Fix the build script to properly work on MaOS
|
||||
- CI: combine AWS-LC and AWS-LC-FIPS by template
|
||||
- BUG/MEDIUM: httpclient: Throw an error if an lua httpclient instance is reused
|
||||
- DOC: hlua: Add a note to warn user about httpclient object reuse
|
||||
- DOC: hlua: fix a few typos in HTTPMessage.set_body_len() documentation
|
||||
- DEV: patchbot: prepare for new version 3.3-dev
|
||||
- MINOR: version: mention that it's 3.2 LTS now.
|
||||
|
||||
2025/05/21 : 3.2-dev17
|
||||
- DOC: configuration: explicit multi-choice on bind shards option
|
||||
- BUG/MINOR: sink: detect and warn when using "send-proxy" options with ring servers
|
||||
- BUG/MEDIUM: peers: also limit the number of incoming updates
|
||||
- MEDIUM: hlua: Add function to change the body length of an HTTP Message
|
||||
- BUG/MEDIUM: stconn: Disable 0-copy forwarding for filters altering the payload
|
||||
- BUG/MINOR: h3: don't insert more than one Host header
|
||||
- BUG/MEDIUM: h1/h2/h3: reject forbidden chars in the Host header field
|
||||
- DOC: config: properly index "table and "stick-table" in their section
|
||||
- DOC: management: change reference to configuration manual
|
||||
- BUILD: debug: mark ha_crash_now() as attribute(noreturn)
|
||||
- IMPORT: slz: avoid multiple shifts on 64-bits
|
||||
- IMPORT: slz: support crc32c for lookup hash on sse4 but only if requested
|
||||
- IMPORT: slz: use a better hash for machines with a fast multiply
|
||||
- IMPORT: slz: fix header used for empty zlib message
|
||||
- IMPORT: slz: silence a build warning on non-x86 non-arm
|
||||
- BUG/MAJOR: leastconn: do not loop forever when facing saturated servers
|
||||
- BUG/MAJOR: queue: properly keep count of the queue length
|
||||
- BUG/MINOR: quic: fix crash on quic_conn alloc failure
|
||||
- BUG/MAJOR: leastconn: never reuse the node after dropping the lock
|
||||
- MINOR: acme: renewal notification over the dpapi sink
|
||||
- CLEANUP: quic: Useless BIO_METHOD initialization
|
||||
- MINOR: quic: Add useful error traces about qc_ssl_sess_init() failures
|
||||
- MINOR: quic: Allow the use of the new OpenSSL 3.5.0 QUIC TLS API (to be completed)
|
||||
- MINOR: quic: implement all remaining callbacks for OpenSSL 3.5 QUIC API
|
||||
- MINOR: quic: OpenSSL 3.5 internal QUIC custom extension for transport parameters reset
|
||||
- MINOR: quic: OpenSSL 3.5 trick to support 0-RTT
|
||||
- DOC: update INSTALL for QUIC with OpenSSL 3.5 usages
|
||||
- DOC: management: update 'acme status'
|
||||
- BUG/MEDIUM: wdt: always ignore the first watchdog wakeup
|
||||
- CLEANUP: wdt: clarify the comments on the common exit path
|
||||
- BUILD: ssl: avoid possible printf format warning in traces
|
||||
- BUILD: acme: fix build issue on 32-bit archs with 64-bit time_t
|
||||
- DOC: management: precise some of the fields of "show servers conn"
|
||||
- BUG/MEDIUM: mux-quic: fix BUG_ON() on rxbuf alloc error
|
||||
- DOC: watchdog: update the doc to reflect the recent changes
|
||||
- BUG/MEDIUM: acme: check if acme domains are configured
|
||||
- BUG/MINOR: acme: fix formatting issue in error and logs
|
||||
- EXAMPLES: lua: avoid screen refresh effect in "trisdemo"
|
||||
- CLEANUP: quic: remove unused cbuf module
|
||||
- MINOR: quic: move function to check stream type in utils
|
||||
- MINOR: quic: refactor handling of streams after MUX release
|
||||
- MINOR: quic: add some missing includes
|
||||
- MINOR: quic: adjust quic_conn-t.h include list
|
||||
- CLEANUP: cfgparse: alphabetically sort the global keywords
|
||||
- MINOR: glitches: add global setting "tune.glitches.kill.cpu-usage"
|
||||
|
||||
2025/05/14 : 3.2-dev16
|
||||
- BUG/MEDIUM: mux-quic: fix crash on invalid fctl frame dereference
|
||||
- DEBUG: pool: permit per-pool UAF configuration
|
||||
- MINOR: acme: add the global option 'acme.scheduler'
|
||||
- DEBUG: pools: add a new integrity mode "backup" to copy the released area
|
||||
- MEDIUM: sock-inet: re-check IPv6 connectivity every 30s
|
||||
- BUG/MINOR: ssl: doesn't fill conf->crt with first arg
|
||||
- BUG/MINOR: ssl: prevent multiple 'crt' on the same ssl-f-use line
|
||||
- BUG/MINOR: ssl/ckch: always free() the previous entry during parsing
|
||||
- MINOR: tools: ha_freearray() frees an array of string
|
||||
- BUG/MINOR: ssl/ckch: always ha_freearray() the previous entry during parsing
|
||||
- MINOR: ssl/ckch: warn when the same keyword was used twice
|
||||
- BUG/MINOR: threads: fix soft-stop without multithreading support
|
||||
- BUG/MINOR: tools: improve parse_line()'s robustness against empty args
|
||||
- BUG/MINOR: cfgparse: improve the empty arg position report's robustness
|
||||
- BUG/MINOR: server: dont depend on proxy for server cleanup in srv_drop()
|
||||
- BUG/MINOR: server: perform lbprm deinit for dynamic servers
|
||||
- MINOR: http: add a function to validate characters of :authority
|
||||
- BUG/MEDIUM: h2/h3: reject some forbidden chars in :authority before reassembly
|
||||
- MINOR: quic: account Tx data per stream
|
||||
- MINOR: mux-quic: account Rx data per stream
|
||||
- MINOR: quic: add stream format for "show quic"
|
||||
- MINOR: quic: display QCS info on "show quic stream"
|
||||
- MINOR: quic: display stream age
|
||||
- BUG/MINOR: cpu-topo: fix group-by-cluster policy for disordered clusters
|
||||
- MINOR: cpu-topo: add a new "group-by-ccx" CPU policy
|
||||
- MINOR: cpu-topo: provide a function to sort clusters by average capacity
|
||||
- MEDIUM: cpu-topo: change "performance" to consider per-core capacity
|
||||
- MEDIUM: cpu-topo: change "efficiency" to consider per-core capacity
|
||||
- MEDIUM: cpu-topo: prefer grouping by CCX for "performance" and "efficiency"
|
||||
- MEDIUM: config: change default limits to 1024 threads and 32 groups
|
||||
- BUG/MINOR: hlua: Fix Channel:data() and Channel:line() to respect documentation
|
||||
- DOC: config: Fix a typo in the "term_events" definition
|
||||
- BUG/MINOR: spoe: Don't report error on applet release if filter is in DONE state
|
||||
- BUG/MINOR: mux-spop: Don't report error for stream if ACK was already received
|
||||
- BUG/MINOR: mux-spop: Make the demux stream ID a signed integer
|
||||
- BUG/MINOR: mux-spop: Don't open new streams for SPOP connection on error
|
||||
- MINOR: mux-spop: Don't set SPOP connection state to FRAME_H after ACK parsing
|
||||
- BUG/MEDIUM: mux-spop: Remove frame parsing states from the SPOP connection state
|
||||
- BUG/MEDIUM: mux-spop: Properly handle CLOSING state
|
||||
- BUG/MEDIUM: spop-conn: Report short read for partial frames payload
|
||||
- BUG/MEDIUM: mux-spop: Properly detect truncated frames on demux to report error
|
||||
- BUG/MEDIUM: mux-spop; Don't report a read error if there are pending data
|
||||
- DEBUG: mux-spop: Review some trace messages to adjust the message or the level
|
||||
- DOC: config: move address formats definition to section 2
|
||||
- DOC: config: move stick-tables and peers to their own section
|
||||
- DOC: config: move the extraneous sections out of the "global" definition
|
||||
- CI: AWS-LC(fips): enable unit tests
|
||||
- CI: AWS-LC: enable unit tests
|
||||
- CI: compliance: limit run on forks only to manual + cleanup
|
||||
- CI: musl: enable unit tests
|
||||
- CI: QuicTLS (weekly): limit run on forks only to manual dispatch
|
||||
- CI: WolfSSL: enable unit tests
|
||||
|
||||
2025/05/09 : 3.2-dev15
|
||||
- BUG/MEDIUM: stktable: fix sc_*(<ctr>) BUG_ON() regression with ctx > 9
|
||||
- BUG/MINOR: acme/cli: don't output error on success
|
||||
- BUG/MINOR: tools: do not create an empty arg from trailing spaces
|
||||
- MEDIUM: config: warn about the consequences of empty arguments on a config line
|
||||
- MINOR: tools: make parse_line() provide hints about empty args
|
||||
- MINOR: cfgparse: visually show the input line on empty args
|
||||
- BUG/MINOR: tools: always terminate empty lines
|
||||
- BUG/MINOR: tools: make parseline report the required space for the trailing 0
|
||||
- DEBUG: threads: don't keep lock label "OTHER" in the per-thread history
|
||||
- DEBUG: threads: merge successive idempotent lock operations in history
|
||||
- DEBUG: threads: display held locks in threads dumps
|
||||
- BUG/MINOR: proxy: only use proxy_inc_fe_cum_sess_ver_ctr() with frontends
|
||||
- Revert "BUG/MEDIUM: mux-spop: Handle CLOSING state and wait for AGENT DISCONNECT frame"
|
||||
- MINOR: acme/cli: 'acme status' show the status acme-configured certificates
|
||||
- MEDIUM: acme/ssl: remove 'acme ps' in favor of 'acme status'
|
||||
- DOC: configuration: add "acme" section to the keywords list
|
||||
- DOC: configuration: add the "crt-store" keyword
|
||||
- BUG/MAJOR: queue: lock around the call to pendconn_process_next_strm()
|
||||
- MINOR: ssl: add filename and linenum for ssl-f-use errors
|
||||
- BUG/MINOR: ssl: can't use crt-store some certificates in ssl-f-use
|
||||
- BUG/MINOR: tools: only fill first empty arg when not out of range
|
||||
- MINOR: debug: bump the dump buffer to 8kB
|
||||
- MINOR: stick-tables: add "ipv4" as an alias for the "ip" type
|
||||
- MINOR: quic: extend return value during TP parsing
|
||||
- BUG/MINOR: quic: use proper error code on missing CID in TPs
|
||||
- BUG/MINOR: quic: use proper error code on invalid server TP
|
||||
- BUG/MINOR: quic: reject retry_source_cid TP on server side
|
||||
- BUG/MINOR: quic: use proper error code on invalid received TP value
|
||||
- BUG/MINOR: quic: fix TP reject on invalid max-ack-delay
|
||||
- BUG/MINOR: quic: reject invalid max_udp_payload size
|
||||
- BUG/MEDIUM: peers: hold the refcnt until updating ts->seen
|
||||
- BUG/MEDIUM: stick-tables: close a tiny race in __stksess_kill()
|
||||
- BUG/MINOR: cli: fix too many args detection for commands
|
||||
- MINOR: server: ensure server postparse tasks are run for dynamic servers
|
||||
- BUG/MEDIUM: stick-table: always remove update before adding a new one
|
||||
- BUG/MEDIUM: quic: free stream_desc on all data acked
|
||||
- BUG/MINOR: cfgparse: consider the special case of empty arg caused by \x00
|
||||
- DOC: config: recommend disabling libc-based resolution with resolvers
|
||||
|
||||
2025/05/02 : 3.2-dev14
|
||||
- MINOR: acme: retry label always do a request
|
||||
- MINOR: acme: does not leave task for next request
|
||||
- BUG/MINOR: acme: reinit the retries only at next request
|
||||
- MINOR: acme: change the default max retries to 5
|
||||
- MINOR: acme: allow a delay after a valid response
|
||||
- MINOR: acme: wait 5s before checking the challenges results
|
||||
- MINOR: acme: emit a log when starting
|
||||
- MINOR: acme: delay of 5s after the finalize
|
||||
- BUG/MEDIUM: quic: Let it be known if the tasklet has been released.
|
||||
- BUG/MAJOR: tasks: fix task accounting when killed
|
||||
- CLEANUP: tasks: use the local state, not t->state, to check for tasklets
|
||||
- DOC: acme: external account binding is not supported
|
||||
- MINOR: hlua: ignore "tune.lua.bool-sample-conversion" if set after "lua-load"
|
||||
- MEDIUM: peers: Give up if we fail to take locks in hot path
|
||||
- MEDIUM: stick-tables: defer adding updates to a tasklet
|
||||
- MEDIUM: stick-tables: Limit the number of old entries we remove
|
||||
- MEDIUM: stick-tables: Limit the number of entries we expire
|
||||
- MINOR: cfgparse-global: add explicit error messages in cfg_parse_global_env_opts
|
||||
- MINOR: ssl: add function to extract X509 notBefore date in time_t
|
||||
- BUILD: acme: need HAVE_ASN1_TIME_TO_TM
|
||||
- MINOR: acme: move the acme task init in a dedicated function
|
||||
- MEDIUM: acme: add a basic scheduler
|
||||
- MINOR: acme: emit a log when the scheduler can't start the task
|
||||
|
||||
2025/04/30 : 3.2-dev13
|
||||
- MEDIUM: checks: Make sure we return the tasklet from srv_chk_io_cb
|
||||
- MEDIUM: listener: Make sure w ereturn the tasklet from accept_queue_process
|
||||
- MEDIUM: mux_fcgi: Make sure we return the tasklet from fcgi_deferred_shut
|
||||
- MEDIUM: quic: Make sure we return the tasklet from qcc_io_cb
|
||||
- MEDIUM: quic: Make sure we return NULL in quic_conn_app_io_cb if needed
|
||||
- MEDIUM: quic: Make sure we return the tasklet from quic_accept_run
|
||||
- BUG/MAJOR: tasklets: Make sure he tasklet can't run twice
|
||||
- BUG/MAJOR: listeners: transfer connection accounting when switching listeners
|
||||
- MINOR: ssl/cli: add a '-t' option to 'show ssl sni'
|
||||
- DOC: config: fix ACME paragraph rendering issue
|
||||
- DOC: config: clarify log-forward "host" option
|
||||
- MINOR: promex: expose ST_I_PX_RATE (current_session_rate)
|
||||
- BUILD: acme: use my_strndup() instead of strndup()
|
||||
- BUILD: leastconn: fix build warning when building without threads on old machines
|
||||
- MINOR: threads: prepare DEBUG_THREAD to receive more values
|
||||
- MINOR: threads: turn the full lock debugging to DEBUG_THREAD=2
|
||||
- MEDIUM: threads: keep history of taken locks with DEBUG_THREAD > 0
|
||||
- MINOR: threads/cli: display the lock history on "show threads"
|
||||
- MEDIUM: thread: set DEBUG_THREAD to 1 by default
|
||||
- BUG/MINOR: ssl/acme: free EVP_PKEY upon error
|
||||
- MINOR: acme: separate the code generating private keys
|
||||
- MINOR: acme: failure when no directory is specified
|
||||
- MEDIUM: acme: generate the account file when not found
|
||||
- MEDIUM: acme: use 'crt-base' to load the account key
|
||||
- MINOR: compiler: add more macros to detect macro definitions
|
||||
- MINOR: cli: split APPCTX_CLI_ST1_PROMPT into two distinct flags
|
||||
- MEDIUM: cli: make the prompt mode configurable between n/i/p
|
||||
- MEDIUM: mcli: make the prompt mode configurable between i/p
|
||||
- MEDIUM: mcli: replicate the current mode when enterin the worker process
|
||||
- DOC: configuration: acme account key are auto generated
|
||||
- CLEANUP: acme: remove old TODO for account key
|
||||
- DOC: configuration: add quic4 to the ssl-f-use example
|
||||
- BUG/MINOR: acme: does not try to unlock after a failed trylock
|
||||
- BUG/MINOR: mux-h2: fix the offset of the pattern for the ping frame
|
||||
- MINOR: tcp: add support for setting TCP_NOTSENT_LOWAT on both sides
|
||||
- BUG/MINOR: acme: creating an account should not end the task
|
||||
- MINOR: quic: rename min/max fields for congestion window algo
|
||||
- MINOR: quic: refactor BBR API
|
||||
- BUG/MINOR: quic: ensure cwnd limits are always enforced
|
||||
- MINOR: thread: define cshared type
|
||||
- MINOR: quic: account for global congestion window
|
||||
- MEDIUM: quic: limit global Tx memory
|
||||
- MEDIUM: acme: use a map to store tokens and thumbprints
|
||||
- BUG/MINOR: acme: remove references to virt@acme
|
||||
- MINOR: applet: add appctx_schedule() macro
|
||||
- BUG/MINOR: dns: add tempo between 2 connection attempts for dns servers
|
||||
- CLEANUP: dns: remove unused dns_stream_server struct member
|
||||
- BUG/MINOR: dns: prevent ds accumulation within dss
|
||||
- CLEANUP: proxy: mention that px->conn_retries isn't relevant in some cases
|
||||
- DOC: ring: refer to newer RFC5424
|
||||
- MINOR: tools: make my_strndup() take a size_t len instead of and int
|
||||
- MINOR: Add "sigalg" to "sigalg name" helper function
|
||||
- MINOR: ssl: Add traces to ssl init/close functions
|
||||
- MINOR: ssl: Add traces to recv/send functions
|
||||
- MINOR: ssl: Add traces to ssl_sock_io_cb function
|
||||
- MINOR: ssl: Add traces around SSL_do_handshake call
|
||||
- MINOR: ssl: Add traces to verify callback
|
||||
- MINOR: ssl: Add ocsp stapling callback traces
|
||||
- MINOR: ssl: Add traces to the switchctx callback
|
||||
- MINOR: ssl: Add traces about sigalg extension parsing in clientHello callback
|
||||
- MINOR: Add 'conn' param to ssl_sock_chose_sni_ctx
|
||||
- BUG/MEDIUM: mux-spop: Wait end of handshake to declare a spop connection ready
|
||||
- BUG/MEDIUM: mux-spop: Handle CLOSING state and wait for AGENT DISCONNECT frame
|
||||
- BUG/MINOR: mux-h1: Don't pretend connection was released for TCP>H1>H2 upgrade
|
||||
- BUG/MINOR: mux-h1: Fix trace message in h1_detroy() to not relay on connection
|
||||
- BUILD: ssl: Fix wolfssl build
|
||||
- BUG/MINOR: mux-spop: Use the right bitwise operator in spop_ctl()
|
||||
- MEDIUM: mux-quic: increase flow-control on each bufsize
|
||||
- MINOR: mux-quic: limit emitted MSD frames count per qcs
|
||||
- MINOR: add hlua_yield_asap() helper
|
||||
- MINOR: hlua_fcn: enforce yield after *_get_stats() methods
|
||||
- DOC: config: restore default values for resolvers hold directive
|
||||
- MINOR: ssl/cli: "acme ps" shows the acme tasks
|
||||
- MINOR: acme: acme_ctx_destroy() returns upon NULL
|
||||
- MINOR: acme: use acme_ctx_destroy() upon error
|
||||
- MEDIUM: tasks: Mutualize code between tasks and tasklets.
|
||||
- MEDIUM: tasks: More code factorization
|
||||
- MEDIUM: tasks: Remove TASK_IN_LIST and use TASK_QUEUED instead.
|
||||
- MINOR: tasks: Remove unused tasklet_remove_from_tasklet_list
|
||||
- MEDIUM: tasks: Mutualize the TASK_KILLED code between tasks and tasklets
|
||||
- BUG/MEDIUM: connections: Report connection closing in conn_create_mux()
|
||||
- BUILD/MEDIUM: quic: Make sure we build with recent changes
|
||||
|
||||
2025/04/25 : 3.2-dev12
|
||||
- BUG/MINOR: quic: do not crash on CRYPTO ncbuf alloc failure
|
||||
- BUG/MINOR: proxy: always detach a proxy from the names tree on free()
|
||||
- CLEANUP: proxy: detach the name node in proxy_free_common() instead
|
||||
- CLEANUP: Slightly reorder some proxy option flags to free slots
|
||||
- MINOR: proxy: Add options to drop HTTP trailers during message forwarding
|
||||
- MINOR: h1-htx: Skip C-L and T-E headers for 1xx and 204 messages during parsing
|
||||
- MINOR: mux-h1: Keep custom "Content-Length: 0" header in 1xx and 204 messages
|
||||
- MINOR: hlua/h1: Use http_parse_cont_len_header() to parse content-length value
|
||||
- CLEANUP: h1: Remove now useless h1_parse_cont_len_header() function
|
||||
- BUG/MEDIUM: mux-spop: Respect the negociated max-frame-size value to send frames
|
||||
- MINOR: http-act: Add 'pause' action to temporarily suspend the message analysis
|
||||
- MINOR: acme/cli: add the 'acme renew' command to the help message
|
||||
- MINOR: httpclient: add an "https" log-format
|
||||
- MEDIUM: acme: use a customized proxy
|
||||
- MEDIUM: acme: rename "uri" into "directory"
|
||||
- MEDIUM: acme: rename "account" into "account-key"
|
||||
- MINOR: stick-table: use a separate lock label for updates
|
||||
- MINOR: h3: simplify h3_rcv_buf return path
|
||||
- BUG/MINOR: mux-quic: fix possible infinite loop during decoding
|
||||
- BUG/MINOR: mux-quic: do not decode if conn in error
|
||||
- BUG/MINOR: cli: Issue an error when too many args are passed for a command
|
||||
- MINOR: cli: Use a full prompt command for bidir connections with workers
|
||||
- MAJOR: cli: Refacor parsing and execution of pipelined commands
|
||||
- MINOR: cli: Rename some CLI applet states to reflect recent refactoring
|
||||
- CLEANUP: applet: Update st0/st1 comment in appctx structure
|
||||
- BUG/MINOR: hlua: Fix I/O handler of lua CLI commands to not rely on the SC
|
||||
- BUG/MINOR: ring: Fix I/O handler of "show event" command to not rely on the SC
|
||||
- MINOR: cli/applet: Move appctx fields only used by the CLI in a private context
|
||||
- MINOR: cache: Add a pointer on the cache in the cache applet context
|
||||
- MINOR: hlua: Use the applet name in error messages for lua services
|
||||
- MINOR: applet: Save the "use-service" rule in the stream to init a service applet
|
||||
- CLEANUP: applet: Remove unsued rule pointer in appctx structure
|
||||
- BUG/MINOR: master/cli: properly trim the '@@' process name in error messages
|
||||
- MEDIUM: resolvers: add global "dns-accept-family" directive
|
||||
- MINOR: resolvers: add command-line argument -4 to force IPv4-only DNS
|
||||
- MINOR: sock-inet: detect apparent IPv6 connectivity
|
||||
- MINOR: resolvers: add "dns-accept-family auto" to rely on detected IPv6
|
||||
- MEDIUM: acme: use Retry-After value for retries
|
||||
- MEDIUM: acme: reset the remaining retries
|
||||
- MEDIUM: acme: better error/retry management of the challenge checks
|
||||
- BUG/MEDIUM: cli: Handle applet shutdown when waiting for a command line
|
||||
- Revert "BUG/MINOR: master/cli: properly trim the '@@' process name in error messages"
|
||||
- BUG/MINOR: master/cli: only parse the '@@' prefix on complete lines
|
||||
- MINOR: resolvers: use the runtime IPv6 status instead of boot time one
|
||||
|
||||
2025/04/18 : 3.2-dev11
|
||||
- CI: enable weekly QuicTLS build
|
||||
- DOC: management: slightly clarify the prefix role of the '@' command
|
||||
|
33
INSTALL
33
INSTALL
@ -237,7 +237,7 @@ to forcefully enable it using "USE_LIBCRYPT=1".
|
||||
-----------------
|
||||
For SSL/TLS, it is necessary to use a cryptography library. HAProxy currently
|
||||
supports the OpenSSL library, and is known to build and work with branches
|
||||
1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, and 3.0 to 3.5. It is recommended to use
|
||||
1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, and 3.0 to 3.4. It is recommended to use
|
||||
at least OpenSSL 1.1.1 to have support for all SSL keywords and configuration
|
||||
in HAProxy. OpenSSL follows a long-term support cycle similar to HAProxy's,
|
||||
and each of the branches above receives its own fixes, without forcing you to
|
||||
@ -259,10 +259,10 @@ reported to work as well. While there are some efforts from the community to
|
||||
ensure they work well, OpenSSL remains the primary target and this means that
|
||||
in case of conflicting choices, OpenSSL support will be favored over other
|
||||
options. Note that QUIC is not fully supported when haproxy is built with
|
||||
OpenSSL < 3.5 version. In this case, QUICTLS is the preferred alternative.
|
||||
As of writing this, the QuicTLS project follows OpenSSL very closely and provides
|
||||
update simultaneously, but being a volunteer-driven project, its long-term future
|
||||
does not look certain enough to convince operating systems to package it, so it
|
||||
OpenSSL. In this case, QUICTLS is the preferred alternative. As of writing
|
||||
this, the QuicTLS project follows OpenSSL very closely and provides update
|
||||
simultaneously, but being a volunteer-driven project, its long-term future does
|
||||
not look certain enough to convince operating systems to package it, so it
|
||||
needs to be build locally. See the section about QUIC in this document.
|
||||
|
||||
A fifth option is wolfSSL (https://github.com/wolfSSL/wolfssl). It is the only
|
||||
@ -500,11 +500,10 @@ QUIC is the new transport layer protocol and is required for HTTP/3. This
|
||||
protocol stack is currently supported as an experimental feature in haproxy on
|
||||
the frontend side. In order to enable it, use "USE_QUIC=1 USE_OPENSSL=1".
|
||||
|
||||
Note that QUIC is not always fully supported by the OpenSSL library depending on
|
||||
its version. Indeed QUIC 0-RTT cannot be supported by OpenSSL for versions before
|
||||
3.5 contrary to others libraries with full QUIC support. The preferred option is
|
||||
to use QUICTLS. This is a fork of OpenSSL with a QUIC-compatible API. Its
|
||||
repository is available at this location:
|
||||
Note that QUIC is not fully supported by the OpenSSL library. Indeed QUIC 0-RTT
|
||||
cannot be supported by OpenSSL contrary to others libraries with full QUIC
|
||||
support. The preferred option is to use QUICTLS. This is a fork of OpenSSL with
|
||||
a QUIC-compatible API. Its repository is available at this location:
|
||||
|
||||
https://github.com/quictls/openssl
|
||||
|
||||
@ -532,18 +531,14 @@ way assuming that wolfSSL was installed in /opt/wolfssl-5.6.0 as shown in 4.5:
|
||||
SSL_INC=/opt/wolfssl-5.6.0/include SSL_LIB=/opt/wolfssl-5.6.0/lib
|
||||
LDFLAGS="-Wl,-rpath,/opt/wolfssl-5.6.0/lib"
|
||||
|
||||
As last resort, haproxy may be compiled against OpenSSL as follows from 3.5
|
||||
version with 0-RTT support:
|
||||
|
||||
$ make TARGET=generic USE_OPENSSL=1 USE_QUIC=1
|
||||
|
||||
or as follows for all OpenSSL versions but without O-RTT support:
|
||||
As last resort, haproxy may be compiled against OpenSSL as follows:
|
||||
|
||||
$ make TARGET=generic USE_OPENSSL=1 USE_QUIC=1 USE_QUIC_OPENSSL_COMPAT=1
|
||||
|
||||
In addition to this requirements, the QUIC listener bindings must be explicitly
|
||||
enabled with a specific QUIC tuning parameter. (see "limited-quic" global
|
||||
parameter of haproxy Configuration Manual).
|
||||
Note that QUIC 0-RTT is not supported by haproxy QUIC stack when built against
|
||||
OpenSSL. In addition to this compilation requirements, the QUIC listener
|
||||
bindings must be explicitly enabled with a specific QUIC tuning parameter.
|
||||
(see "limited-quic" global parameter of haproxy Configuration Manual).
|
||||
|
||||
|
||||
5) How to build HAProxy
|
||||
|
13
Makefile
13
Makefile
@ -261,7 +261,7 @@ endif
|
||||
# without appearing here. Currently defined DEBUG macros include DEBUG_FULL,
|
||||
# DEBUG_MEM_STATS, DEBUG_DONT_SHARE_POOLS, DEBUG_FD, DEBUG_POOL_INTEGRITY,
|
||||
# DEBUG_NO_POOLS, DEBUG_FAIL_ALLOC, DEBUG_STRICT_ACTION=[0-3], DEBUG_HPACK,
|
||||
# DEBUG_AUTH, DEBUG_SPOE, DEBUG_UAF, DEBUG_THREAD=0-2, DEBUG_STRICT, DEBUG_DEV,
|
||||
# DEBUG_AUTH, DEBUG_SPOE, DEBUG_UAF, DEBUG_THREAD, DEBUG_STRICT, DEBUG_DEV,
|
||||
# DEBUG_TASK, DEBUG_MEMORY_POOLS, DEBUG_POOL_TRACING, DEBUG_QPACK, DEBUG_LIST,
|
||||
# DEBUG_COUNTERS=[0-2], DEBUG_STRESS, DEBUG_UNIT.
|
||||
DEBUG =
|
||||
@ -630,10 +630,9 @@ ifneq ($(USE_OPENSSL:0=),)
|
||||
SSL_LDFLAGS := $(if $(SSL_LIB),-L$(SSL_LIB)) -lssl -lcrypto
|
||||
endif
|
||||
USE_SSL := $(if $(USE_SSL:0=),$(USE_SSL:0=),implicit)
|
||||
OPTIONS_OBJS += src/ssl_sock.o src/ssl_ckch.o src/ssl_ocsp.o src/ssl_crtlist.o \
|
||||
src/ssl_sample.o src/cfgparse-ssl.o src/ssl_gencert.o \
|
||||
src/ssl_utils.o src/jwt.o src/ssl_clienthello.o src/jws.o src/acme.o \
|
||||
src/ssl_trace.o
|
||||
OPTIONS_OBJS += src/ssl_sock.o src/ssl_ckch.o src/ssl_ocsp.o src/ssl_crtlist.o \
|
||||
src/ssl_sample.o src/cfgparse-ssl.o src/ssl_gencert.o \
|
||||
src/ssl_utils.o src/jwt.o src/ssl_clienthello.o src/jws.o src/acme.o
|
||||
endif
|
||||
|
||||
ifneq ($(USE_ENGINE:0=),)
|
||||
@ -660,7 +659,7 @@ OPTIONS_OBJS += src/mux_quic.o src/h3.o src/quic_rx.o src/quic_tx.o \
|
||||
src/quic_cc_nocc.o src/quic_cc.o src/quic_pacing.o \
|
||||
src/h3_stats.o src/quic_stats.o src/qpack-enc.o \
|
||||
src/qpack-tbl.o src/quic_cc_drs.o src/quic_fctl.o \
|
||||
src/quic_enc.o
|
||||
src/cbuf.o src/quic_enc.o
|
||||
endif
|
||||
|
||||
ifneq ($(USE_QUIC_OPENSSL_COMPAT:0=),)
|
||||
@ -984,7 +983,7 @@ OBJS += src/mux_h2.o src/mux_h1.o src/mux_fcgi.o src/log.o \
|
||||
src/lb_fas.o src/clock.o src/sock_inet.o src/ev_select.o \
|
||||
src/lb_map.o src/shctx.o src/mworker-prog.o src/hpack-dec.o \
|
||||
src/arg.o src/signal.o src/fix.o src/dynbuf.o src/guid.o \
|
||||
src/cfgparse-tcp.o src/lb_ss.o src/chunk.o src/counters.o \
|
||||
src/cfgparse-tcp.o src/lb_ss.o src/chunk.o \
|
||||
src/cfgparse-unix.o src/regex.o src/fcgi.o src/uri_auth.o \
|
||||
src/eb64tree.o src/eb32tree.o src/eb32sctree.o src/lru.o \
|
||||
src/limits.o src/ebimtree.o src/wdt.o src/hpack-tbl.o \
|
||||
|
@ -389,9 +389,6 @@ listed below. Metrics from extra counters are not listed.
|
||||
| haproxy_server_max_connect_time_seconds |
|
||||
| haproxy_server_max_response_time_seconds |
|
||||
| haproxy_server_max_total_time_seconds |
|
||||
| haproxy_server_agent_status |
|
||||
| haproxy_server_agent_code |
|
||||
| haproxy_server_agent_duration_seconds |
|
||||
| haproxy_server_internal_errors_total |
|
||||
| haproxy_server_unsafe_idle_connections_current |
|
||||
| haproxy_server_safe_idle_connections_current |
|
||||
|
@ -173,8 +173,6 @@ const struct ist promex_st_metric_desc[ST_I_PX_MAX] = {
|
||||
[ST_I_PX_CTIME] = IST("Avg. connect time for last 1024 successful connections."),
|
||||
[ST_I_PX_RTIME] = IST("Avg. response time for last 1024 successful connections."),
|
||||
[ST_I_PX_TTIME] = IST("Avg. total time for last 1024 successful connections."),
|
||||
[ST_I_PX_AGENT_STATUS] = IST("Status of last agent check, per state label value."),
|
||||
[ST_I_PX_AGENT_DURATION] = IST("Total duration of the latest server agent check, in seconds."),
|
||||
[ST_I_PX_QT_MAX] = IST("Maximum observed time spent in the queue"),
|
||||
[ST_I_PX_CT_MAX] = IST("Maximum observed time spent waiting for a connection to complete"),
|
||||
[ST_I_PX_RT_MAX] = IST("Maximum observed time spent waiting for a server response"),
|
||||
@ -1344,7 +1342,6 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
||||
secs = (double)sv->check.duration / 1000.0;
|
||||
val = mkf_flt(FN_DURATION, secs);
|
||||
break;
|
||||
|
||||
case ST_I_PX_REQ_TOT:
|
||||
if (px->mode != PR_MODE_HTTP) {
|
||||
sv = NULL;
|
||||
@ -1367,36 +1364,6 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
||||
labels[lb_idx+1].value = promex_hrsp_code[ctx->field_num - ST_I_PX_HRSP_1XX];
|
||||
break;
|
||||
|
||||
case ST_I_PX_AGENT_STATUS:
|
||||
if ((sv->agent.state & (CHK_ST_ENABLED|CHK_ST_PAUSED)) != CHK_ST_ENABLED)
|
||||
goto next_sv;
|
||||
|
||||
for (; ctx->obj_state < HCHK_STATUS_SIZE; ctx->obj_state++) {
|
||||
if (get_check_status_result(ctx->obj_state) < CHK_RES_FAILED)
|
||||
continue;
|
||||
val = mkf_u32(FO_STATUS, sv->agent.status == ctx->obj_state);
|
||||
check_state = get_check_status_info(ctx->obj_state);
|
||||
labels[lb_idx+1].name = ist("state");
|
||||
labels[lb_idx+1].value = ist(check_state);
|
||||
if (!promex_dump_ts(appctx, prefix, name, desc,
|
||||
type,
|
||||
&val, labels, &out, max))
|
||||
goto full;
|
||||
}
|
||||
ctx->obj_state = 0;
|
||||
goto next_sv;
|
||||
case ST_I_PX_AGENT_CODE:
|
||||
if ((sv->agent.state & (CHK_ST_ENABLED|CHK_ST_PAUSED)) != CHK_ST_ENABLED)
|
||||
goto next_sv;
|
||||
val = mkf_u32(FN_OUTPUT, (sv->agent.status < HCHK_STATUS_L57DATA) ? 0 : sv->agent.code);
|
||||
break;
|
||||
case ST_I_PX_AGENT_DURATION:
|
||||
if (sv->agent.status < HCHK_STATUS_CHECKED)
|
||||
goto next_sv;
|
||||
secs = (double)sv->agent.duration / 1000.0;
|
||||
val = mkf_flt(FN_DURATION, secs);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1,70 +0,0 @@
|
||||
BEGININPUT
|
||||
BEGINCONTEXT
|
||||
|
||||
HAProxy's development cycle consists in one development branch, and multiple
|
||||
maintenance branches.
|
||||
|
||||
All the development is made into the development branch exclusively. This
|
||||
includes mostly new features, doc updates, cleanups and or course, fixes.
|
||||
|
||||
The maintenance branches, also called stable branches, never see any
|
||||
development, and only receive ultra-safe fixes for bugs that affect them,
|
||||
that are picked from the development branch.
|
||||
|
||||
Branches are numbered in 0.1 increments. Every 6 months, upon a new major
|
||||
release, the development branch enters maintenance and a new development branch
|
||||
is created with a new, higher version. The current development branch is
|
||||
3.3-dev, and maintenance branches are 3.2 and below.
|
||||
|
||||
Fixes created in the development branch for issues that were introduced in an
|
||||
earlier branch are applied in descending order to each and every version till
|
||||
that branch that introduced the issue: 3.2 first, then 3.1, then 3.0, then 2.9
|
||||
and so on. This operation is called "backporting". A fix for an issue is never
|
||||
backported beyond the branch that introduced the issue. An important point is
|
||||
that the project maintainers really aim at zero regression in maintenance
|
||||
branches, so they're never willing to take any risk backporting patches that
|
||||
are not deemed strictly necessary.
|
||||
|
||||
Fixes consist of patches managed using the Git version control tool and are
|
||||
identified by a Git commit ID and a commit message. For this reason we
|
||||
indistinctly talk about backporting fixes, commits, or patches; all mean the
|
||||
same thing. When mentioning commit IDs, developers always use a short form
|
||||
made of the first 8 characters only, and expect the AI assistant to do the
|
||||
same.
|
||||
|
||||
It seldom happens that some fixes depend on changes that were brought by other
|
||||
patches that were not in some branches and that will need to be backported as
|
||||
well for the fix to work. In this case, such information is explicitly provided
|
||||
in the commit message by the patch's author in natural language.
|
||||
|
||||
Developers are serious and always indicate if a patch needs to be backported.
|
||||
Sometimes they omit the exact target branch, or they will say that the patch is
|
||||
"needed" in some older branch, but it means the same. If a commit message
|
||||
doesn't mention any backport instructions, it means that the commit does not
|
||||
have to be backported. And patches that are not strictly bug fixes nor doc
|
||||
improvements are normally not backported. For example, fixes for design
|
||||
limitations, architectural improvements and performance optimizations are
|
||||
considered too risky for a backport. Finally, all bug fixes are tagged as
|
||||
"BUG" at the beginning of their subject line. Patches that are not tagged as
|
||||
such are not bugs, and must never be backported unless their commit message
|
||||
explicitly requests so.
|
||||
|
||||
ENDCONTEXT
|
||||
|
||||
A developer is reviewing the development branch, trying to spot which commits
|
||||
need to be backported to maintenance branches. This person is already expert
|
||||
on HAProxy and everything related to Git, patch management, and the risks
|
||||
associated with backports, so he doesn't want to be told how to proceed nor to
|
||||
review the contents of the patch.
|
||||
|
||||
The goal for this developer is to get some help from the AI assistant to save
|
||||
some precious time on this tedious review work. In order to do a better job, he
|
||||
needs an accurate summary of the information and instructions found in each
|
||||
commit message. Specifically he needs to figure if the patch fixes a problem
|
||||
affecting an older branch or not, if it needs to be backported, if so to which
|
||||
branches, and if other patches need to be backported along with it.
|
||||
|
||||
The indented text block below after an "id" line and starting with a Subject line
|
||||
is a commit message from the HAProxy development branch that describes a patch
|
||||
applied to that branch, starting with its subject line, please read it carefully.
|
||||
|
@ -1,29 +0,0 @@
|
||||
|
||||
ENDINPUT
|
||||
BEGININSTRUCTION
|
||||
|
||||
You are an AI assistant that follows instruction extremely well. Help as much
|
||||
as you can, responding to a single question using a single response.
|
||||
|
||||
The developer wants to know if he needs to backport the patch above to fix
|
||||
maintenance branches, for which branches, and what possible dependencies might
|
||||
be mentioned in the commit message. Carefully study the commit message and its
|
||||
backporting instructions if any (otherwise it should probably not be backported),
|
||||
then provide a very concise and short summary that will help the developer decide
|
||||
to backport it, or simply to skip it.
|
||||
|
||||
Start by explaining in one or two sentences what you recommend for this one and why.
|
||||
Finally, based on your analysis, give your general conclusion as "Conclusion: X"
|
||||
where X is a single word among:
|
||||
- "yes", if you recommend to backport the patch right now either because
|
||||
it explicitly states this or because it's a fix for a bug that affects
|
||||
a maintenance branch (3.2 or lower);
|
||||
- "wait", if this patch explicitly mentions that it must be backported, but
|
||||
only after waiting some time.
|
||||
- "no", if nothing clearly indicates a necessity to backport this patch (e.g.
|
||||
lack of explicit backport instructions, or it's just an improvement);
|
||||
- "uncertain" otherwise for cases not covered above
|
||||
|
||||
ENDINSTRUCTION
|
||||
|
||||
Explanation:
|
File diff suppressed because it is too large
Load Diff
@ -204,14 +204,6 @@ the cache, when this option is set, objects are picked from the cache from the
|
||||
oldest one instead of the freshest one. This way even late memory corruptions
|
||||
have a chance to be detected.
|
||||
|
||||
Another non-destructive approach is to use "-dMbackup". A full copy of the
|
||||
object is made after its end, which eases inspection (e.g. of the parts
|
||||
scratched by the pool_item elements), and a comparison is made upon allocation
|
||||
of that object, just like with "-dMintegrity", causing a crash on mismatch. The
|
||||
initial 4 words corresponding to the list are ignored as well. Note that when
|
||||
both "-dMbackup" and "-dMintegrity" are used, the copy is performed before
|
||||
being scratched, and the comparison is done by "-dMintegrity" only.
|
||||
|
||||
When build option DEBUG_MEMORY_POOLS is set, or the boot-time option "-dMtag"
|
||||
is passed on the executable's command line, pool objects are allocated with
|
||||
one extra pointer compared to the requested size, so that the bytes that follow
|
||||
@ -350,9 +342,7 @@ struct pool_head *create_pool(char *name, uint size, uint flags)
|
||||
"-dMno-merge" is passed on the executable's command line, the pools
|
||||
also need to have the exact same name to be merged. In addition, unless
|
||||
MEM_F_EXACT is set in <flags>, the object size will usually be rounded
|
||||
up to the size of pointers (16 or 32 bytes). MEM_F_UAF may be set on a
|
||||
per-pool basis to enable the UAF detection only for this specific pool,
|
||||
saving the massive overhead of global usage. The name that will appear
|
||||
up to the size of pointers (16 or 32 bytes). The name that will appear
|
||||
in the pool upon merging is the name of the first created pool. The
|
||||
returned pointer is the new (or reused) pool head, or NULL upon error.
|
||||
Pools created this way must be destroyed using pool_destroy().
|
||||
|
@ -21,7 +21,7 @@ falls back to CLOCK_REALTIME. The former is more accurate as it really counts
|
||||
the time spent in the process, while the latter might also account for time
|
||||
stuck on paging in etc.
|
||||
|
||||
Then wdt_ping() is called to arm the timer. It's set to trigger every
|
||||
Then wdt_ping() is called to arm the timer. t's set to trigger every
|
||||
<wdt_warn_blocked_traffic_ns> interval. It is also called by wdt_handler()
|
||||
to reprogram a new wakeup after it has ticked.
|
||||
|
||||
@ -37,18 +37,15 @@ If the thread was not marked as stuck, it's verified that no progress was made
|
||||
for at least one second, in which case the TH_FL_STUCK flag is set. The lack of
|
||||
progress is measured by the distance between the thread's current cpu_time and
|
||||
its prev_cpu_time. If the lack of progress is at least as large as the warning
|
||||
threshold, then the signal is bounced to the faulty thread if it's not the
|
||||
current one. Since this bounce is based on the time spent without update, it
|
||||
already doesn't happen often.
|
||||
threshold and no context switch happened since last call, ha_stuck_warning() is
|
||||
called to emit a warning about that thread. In any case the context switch
|
||||
counter for that thread is updated.
|
||||
|
||||
Once on the faulty thread, two checks are performed:
|
||||
1) if the thread was already marked as stuck, then the thread is considered
|
||||
as definitely stuck, and ha_panic() is called. It will not return.
|
||||
|
||||
2) a check is made to verify if the scheduler is still ticking, by reading
|
||||
and setting a variable that only the scheduler can clear when leaving a
|
||||
task. If the scheduler didn't make any progress, ha_stuck_warning() is
|
||||
called to emit a warning about that thread.
|
||||
If the thread was already marked as stuck, then the thread is considered as
|
||||
definitely stuck. Then ha_panic() is directly called if the thread is the
|
||||
current one, otherwise ha_kill() is used to resend the signal directly to the
|
||||
target thread, which will in turn go through this handler and handle the panic
|
||||
itself.
|
||||
|
||||
Most of the time there's no panic of course, and a wdt_ping() is performed
|
||||
before leaving the handler to reprogram a check for that thread.
|
||||
@ -64,12 +61,12 @@ set TAINTED_WARN_BLOCKED_TRAFFIC.
|
||||
|
||||
ha_panic() uses the current thread's trash buffer to produce the messages, as
|
||||
we don't care about its contents since that thread will never return. However
|
||||
ha_stuck_warning() instead uses a local 8kB buffer in the thread's stack.
|
||||
ha_stuck_warning() instead uses a local 4kB buffer in the thread's stack.
|
||||
ha_panic() will call ha_thread_dump_fill() for each thread, to complete the
|
||||
buffer being filled with each thread's dump messages. ha_stuck_warning() only
|
||||
calls ha_thread_dump_one(), which works on the current thread. In both cases
|
||||
the message is then directly sent to fd #2 (stderr) and ha_thread_dump_done()
|
||||
is called to release the dumped thread.
|
||||
calls the function for the current thread. In both cases the message is then
|
||||
directly sent to fd #2 (stderr) and ha_thread_dump_one() is called to release
|
||||
the dumped thread.
|
||||
|
||||
Both print a few extra messages, but ha_panic() just ends by looping on abort()
|
||||
until the process dies.
|
||||
@ -113,19 +110,13 @@ ha_dump_backtrace() before returning.
|
||||
ha_dump_backtrace() produces a backtrace into a local buffer (100 entries max),
|
||||
then dumps the code bytes nearby the crashing instrution, dumps pointers and
|
||||
tries to resolve function names, and sends all of that into the target buffer.
|
||||
On some architectures (x86_64, arm64), it will also try to detect and decode
|
||||
call instructions and resolve them to called functions.
|
||||
|
||||
3. Improvements
|
||||
---------------
|
||||
|
||||
The symbols resolution is extremely expensive, particularly for the warnings
|
||||
which should be fast. But we need it, it's just unfortunate that it strikes at
|
||||
the wrong moment. At least ha_dump_backtrace() does disable signals while it's
|
||||
resolving, in order to avoid unwanted re-entrance. In addition, the called
|
||||
function resolve_sym_name() uses some locking and refrains from calling the
|
||||
dladdr family of functions in a re-entrant way (in the worst case only well
|
||||
known symbols will be resolved)..
|
||||
the wrong moment.
|
||||
|
||||
In an ideal case, ha_dump_backtrace() would dump the pointers to a local array,
|
||||
which would then later be resolved asynchronously in a tasklet. This can work
|
||||
|
@ -1,7 +1,7 @@
|
||||
-----------------------
|
||||
HAProxy Starter Guide
|
||||
-----------------------
|
||||
version 3.3
|
||||
version 3.2
|
||||
|
||||
|
||||
This document is an introduction to HAProxy for all those who don't know it, as
|
||||
|
@ -893,9 +893,7 @@ Core class
|
||||
|
||||
**context**: init, task, action
|
||||
|
||||
This function returns a new object of a *httpclient* class. An *httpclient*
|
||||
object must be used to process one and only one request. It must never be
|
||||
reused to process several requests.
|
||||
This function returns a new object of a *httpclient* class.
|
||||
|
||||
:returns: A :ref:`httpclient_class` object.
|
||||
|
||||
@ -2583,9 +2581,7 @@ HTTPClient class
|
||||
.. js:class:: HTTPClient
|
||||
|
||||
The httpclient class allows issue of outbound HTTP requests through a simple
|
||||
API without the knowledge of HAProxy internals. Any instance must be used to
|
||||
process one and only one request. It must never be reused to process several
|
||||
requests.
|
||||
API without the knowledge of HAProxy internals.
|
||||
|
||||
.. js:function:: HTTPClient.get(httpclient, request)
|
||||
.. js:function:: HTTPClient.head(httpclient, request)
|
||||
@ -3920,25 +3916,21 @@ AppletTCP class
|
||||
*size* is missing, the function tries to read all the content of the stream
|
||||
until the end. An optional timeout may be specified in milliseconds. In this
|
||||
case the function will return no longer than this delay, with the amount of
|
||||
available data, or nil if there is no data. An empty string is returned if the
|
||||
connection is closed.
|
||||
available data (possibly none).
|
||||
|
||||
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
||||
:param integer size: the required read size.
|
||||
:returns: return nil if the timeout has expired and no data was available but
|
||||
can still be received. Otherwise, a string is returned, possibly an empty
|
||||
string if the connection is closed.
|
||||
:returns: always return a string, the string can be empty if the connection is
|
||||
closed.
|
||||
|
||||
.. js:function:: AppletTCP.try_receive(applet)
|
||||
|
||||
Reads available data from the TCP stream and returns immediately. Returns a
|
||||
string containing read bytes or nil if no bytes are available at that time. An
|
||||
empty string is returned if the connection is closed.
|
||||
string containing read bytes that may possibly be empty if no bytes are
|
||||
available at that time.
|
||||
|
||||
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
||||
:returns: return nil if no data was available but can still be
|
||||
received. Otherwise, a string is returned, possibly an empty string if the
|
||||
connection is closed.
|
||||
:returns: always return a string, the string can be empty.
|
||||
|
||||
.. js:function:: AppletTCP.send(appletmsg)
|
||||
|
||||
@ -4615,27 +4607,6 @@ HTTPMessage class
|
||||
data by default.
|
||||
:returns: an integer containing the amount of bytes copied or -1.
|
||||
|
||||
.. js:function:: HTTPMessage.set_body_len(http_msg, length)
|
||||
|
||||
This function changes the expected payload length of the HTTP message
|
||||
**http_msg**. **length** can be an integer value. In that case, a
|
||||
"Content-Length" header is added with the given value. It is also possible to
|
||||
pass the **"chunked"** string instead of an integer value to force the HTTP
|
||||
message to be chunk-encoded. In that case, a "Transfer-Encoding" header is
|
||||
added with the "chunked" value. In both cases, all existing "Content-Length"
|
||||
and "Transfer-Encoding" headers are removed.
|
||||
|
||||
This function should be used in the filter context to be able to alter the
|
||||
payload of the HTTP message. The internal state of the HTTP message is updated
|
||||
accordingly. :js:func:`HTTPMessage.add_header()` or
|
||||
:js:func:`HTTPMessage.set_header()` functions must be used in that case.
|
||||
|
||||
:param class_httpmessage http_msg: The manipulated HTTP message.
|
||||
:param type length: The new payload length to set. It can be an integer or
|
||||
the string "chunked".
|
||||
:returns: true if the payload length was successfully updated, false
|
||||
otherwise.
|
||||
|
||||
.. js:function:: HTTPMessage.set_eom(http_msg)
|
||||
|
||||
This function set the end of message for the HTTP message **http_msg**.
|
||||
|
@ -1,7 +1,7 @@
|
||||
------------------------
|
||||
HAProxy Management Guide
|
||||
------------------------
|
||||
version 3.3
|
||||
version 3.2
|
||||
|
||||
|
||||
This document describes how to start, stop, manage, and troubleshoot HAProxy,
|
||||
@ -192,11 +192,6 @@ list of options is :
|
||||
|
||||
-Ws : master-worker mode with support of `notify` type of systemd service.
|
||||
|
||||
-4 : force DNS resolvers to query and accept IPv4 addresses only ("A"
|
||||
records). This can be used when facing difficulties in certain
|
||||
environments lacking end-to-end dual-stack connectivity. It overrides
|
||||
the global "dns-accept-family" directive and forces it to "ipv4".
|
||||
|
||||
-c : only performs a check of the configuration files and exits before trying
|
||||
to bind. The exit status is zero if everything is OK, or non-zero if an
|
||||
error is encountered. Presence of warnings will be reported if any.
|
||||
@ -325,16 +320,6 @@ list of options is :
|
||||
last released. This works best with "no-merge", "cold-first" and "tag".
|
||||
Enabling this option will slightly increase the CPU usage.
|
||||
|
||||
- backup / no-backup:
|
||||
This option performs a copy of each released object at release time,
|
||||
allowing developers to inspect them. It also performs a comparison at
|
||||
allocation time to detect if anything changed in between, indicating a
|
||||
use-after-free condition. This doubles the memory usage and slightly
|
||||
increases the CPU usage (similar to "integrity"). If combined with
|
||||
"integrity", it still duplicates the contents but doesn't perform the
|
||||
comparison (which is performed by "integrity"). Just like "integrity",
|
||||
it works best with "no-merge", "cold-first" and "tag".
|
||||
|
||||
- no-global / global:
|
||||
Depending on the operating system, a process-wide global memory cache
|
||||
may be enabled if it is estimated that the standard allocator is too
|
||||
@ -1521,10 +1506,9 @@ that the terminal is handled by the readline library which supports line
|
||||
editing and history, which is very convenient when issuing repeated commands
|
||||
(eg: watch a counter).
|
||||
|
||||
The socket supports three operation modes :
|
||||
- non-interactive, silent
|
||||
- interactive, silent
|
||||
- interactive with prompt
|
||||
The socket supports two operation modes :
|
||||
- interactive
|
||||
- non-interactive
|
||||
|
||||
The non-interactive mode is the default when socat connects to the socket. In
|
||||
this mode, a single line may be sent. It is processed as a whole, responses are
|
||||
@ -1538,25 +1522,12 @@ example :
|
||||
If a command needs to use a semi-colon or a backslash (eg: in a value), it
|
||||
must be preceded by a backslash ('\').
|
||||
|
||||
The interactive mode allows new commands to be sent after the ones from the
|
||||
previous lines finish. It exists in two variants, one silent, which works like
|
||||
the non-interactive mode except that the socket waits for a new command instead
|
||||
of closing, and one where a prompt is displayed ('>') at the beginning of the
|
||||
line. The interactive mode is preferred for advanced tools while the prompt
|
||||
mode is preferred for humans.
|
||||
|
||||
The mode can be changed using the "prompt" command. By default, it toggles the
|
||||
interactive+prompt modes. Entering "prompt" in interactive mode will switch to
|
||||
prompt mode. The command optionally takes a specific mode among which:
|
||||
|
||||
- "n" : non-interactive mode (single command and quits)
|
||||
- "i" : interactive mode (multiple commands, no prompt)
|
||||
- "p" : prompt mode (multiple commands with a prompt)
|
||||
|
||||
Since the default mode is non-interactive, "prompt" must be used as the first
|
||||
command in order to switch it, otherwise the previous command will cause the
|
||||
connection to be closed. Switching to non-interactive mode will result in the
|
||||
connection to be closed after all the commands of the same line complete.
|
||||
The interactive mode displays a prompt ('>') and waits for commands to be
|
||||
entered on the line, then processes them, and displays the prompt again to wait
|
||||
for a new command. This mode is entered via the "prompt" command which must be
|
||||
sent on the first line in non-interactive mode. The mode is a flip switch, if
|
||||
"prompt" is sent in interactive mode, it is disabled and the connection closes
|
||||
after processing the last command of the same line.
|
||||
|
||||
For this reason, when debugging by hand, it's quite common to start with the
|
||||
"prompt" command :
|
||||
@ -1567,9 +1538,6 @@ For this reason, when debugging by hand, it's quite common to start with the
|
||||
...
|
||||
>
|
||||
|
||||
Interactive tools might prefer starting with "prompt i" to switch to interactive
|
||||
mode without the prompt.
|
||||
|
||||
Optionally the process' uptime may be displayed in the prompt. In order to
|
||||
enable this, the "prompt timed" command will enable the prompt and toggle the
|
||||
displaying of the time. The uptime is displayed in format "d:hh:mm:ss" where
|
||||
@ -1653,26 +1621,8 @@ abort ssl crl-file <crlfile>
|
||||
|
||||
acme renew <certificate>
|
||||
Starts an ACME certificate generation task with the given certificate name.
|
||||
The certificate must be linked to an acme section, see section 12.8 "ACME"
|
||||
of the configuration manual. See also "acme status".
|
||||
|
||||
acme status
|
||||
Show the status of every certificates that were configured with ACME.
|
||||
|
||||
This command outputs, separated by a tab:
|
||||
- The name of the certificate configured in haproxy
|
||||
- The acme section used in the configuration
|
||||
- The state of the acme task, either "Running", "Scheduled" or "Stopped"
|
||||
- The UTC expiration date of the certificate in ISO8601 format
|
||||
- The relative expiration time (0d if expired)
|
||||
- The UTC scheduled date of the certificate in ISO8601 format
|
||||
- The relative schedule time (0d if Running)
|
||||
|
||||
Example:
|
||||
$ echo "@1; acme status" | socat /tmp/master.sock - | column -t -s $'\t'
|
||||
# certificate section state expiration date (UTC) expires in scheduled date (UTC) scheduled in
|
||||
ecdsa.pem LE Running 2020-01-18T09:31:12Z 0d 0h00m00s 2020-01-15T21:31:12Z 0d 0h00m00s
|
||||
foobar.pem.rsa LE Scheduled 2025-08-04T11:50:54Z 89d 23h01m13s 2025-07-27T23:50:55Z 82d 11h01m14s
|
||||
The certificate must be linked to an acme section, see section 3.13. of the
|
||||
configuration manual.
|
||||
|
||||
add acl [@<ver>] <acl> <pattern>
|
||||
Add an entry into the acl <acl>. <acl> is the #<id> or the <name> returned by
|
||||
@ -1724,9 +1674,8 @@ add server <backend>/<server> [args]*
|
||||
The <server> name must not be already used in the backend. A special
|
||||
restriction is put on the backend which must used a dynamic load-balancing
|
||||
algorithm. A subset of keywords from the server config file statement can be
|
||||
used to configure the server behavior (see "add server help" to list them).
|
||||
Also note that no settings will be reused from an hypothetical
|
||||
'default-server' statement in the same backend.
|
||||
used to configure the server behavior. Also note that no settings will be
|
||||
reused from an hypothetical 'default-server' statement in the same backend.
|
||||
|
||||
Currently a dynamic server is statically initialized with the "none"
|
||||
init-addr method. This means that no resolution will be undertaken if a FQDN
|
||||
@ -1756,10 +1705,78 @@ add server <backend>/<server> [args]*
|
||||
servers. Please refer to the "u-limit" global keyword documentation in this
|
||||
case.
|
||||
|
||||
add server help
|
||||
List the keywords supported for dynamic servers by the current haproxy
|
||||
version. Keyword syntax is similar to the server line from the configuration
|
||||
file, please refer to their individual documentation for details.
|
||||
Here is the list of the currently supported keywords :
|
||||
|
||||
- agent-addr
|
||||
- agent-check
|
||||
- agent-inter
|
||||
- agent-port
|
||||
- agent-send
|
||||
- allow-0rtt
|
||||
- alpn
|
||||
- addr
|
||||
- backup
|
||||
- ca-file
|
||||
- check
|
||||
- check-alpn
|
||||
- check-proto
|
||||
- check-send-proxy
|
||||
- check-sni
|
||||
- check-ssl
|
||||
- check-via-socks4
|
||||
- ciphers
|
||||
- ciphersuites
|
||||
- cookie
|
||||
- crl-file
|
||||
- crt
|
||||
- disabled
|
||||
- downinter
|
||||
- error-limit
|
||||
- fall
|
||||
- fastinter
|
||||
- force-sslv3/tlsv10/tlsv11/tlsv12/tlsv13
|
||||
- id
|
||||
- init-state
|
||||
- inter
|
||||
- maxconn
|
||||
- maxqueue
|
||||
- minconn
|
||||
- no-ssl-reuse
|
||||
- no-sslv3/tlsv10/tlsv11/tlsv12/tlsv13
|
||||
- no-tls-tickets
|
||||
- npn
|
||||
- observe
|
||||
- on-error
|
||||
- on-marked-down
|
||||
- on-marked-up
|
||||
- pool-low-conn
|
||||
- pool-max-conn
|
||||
- pool-purge-delay
|
||||
- port
|
||||
- proto
|
||||
- proxy-v2-options
|
||||
- rise
|
||||
- send-proxy
|
||||
- send-proxy-v2
|
||||
- send-proxy-v2-ssl
|
||||
- send-proxy-v2-ssl-cn
|
||||
- slowstart
|
||||
- sni
|
||||
- source
|
||||
- ssl
|
||||
- ssl-max-ver
|
||||
- ssl-min-ver
|
||||
- tfo
|
||||
- tls-tickets
|
||||
- track
|
||||
- usesrc
|
||||
- verify
|
||||
- verifyhost
|
||||
- weight
|
||||
- ws
|
||||
|
||||
Their syntax is similar to the server line from the configuration file,
|
||||
please refer to their individual documentation for details.
|
||||
|
||||
add ssl ca-file <cafile> <payload>
|
||||
Add a new certificate to a ca-file. This command is useful when you reached
|
||||
@ -2347,27 +2364,15 @@ prepare map <map>
|
||||
committed. Version numbers are unsigned 32-bit values which wrap at the end,
|
||||
so care must be taken when comparing them in an external program.
|
||||
|
||||
prompt [help | n | i | p | timed]*
|
||||
Changes the behavior of the interactive mode and the prompt displayed at the
|
||||
beginning of the line in interactive mode:
|
||||
- "help" : displays the command's usage
|
||||
- "n" : switches to non-interactive mode
|
||||
- "i" : switches to interactive mode
|
||||
- "p" : switches to interactive + prompt mode
|
||||
- "timed" : toggles displaying the time in the prompt
|
||||
|
||||
Without any option, this will cycle through prompt mode then non-interactive
|
||||
mode. In non-interactive mode, the connection is closed after the last
|
||||
command of the current line compltes. In interactive mode, the connection is
|
||||
not closed after a command completes, so that a new one can be entered. In
|
||||
prompt mode, the interactive mode is still in use, and a prompt will appear
|
||||
at the beginning of the line, indicating to the user that the interpreter is
|
||||
waiting for a new command. The prompt consists in a right angle bracket
|
||||
followed by a space "> ".
|
||||
|
||||
The prompt mode is more suited to human users, the interactive mode to
|
||||
advanced scripts, and the non-interactive mode (default) to basic scripts.
|
||||
Note that the non-interactive mode is not available for the master socket.
|
||||
prompt
|
||||
Toggle the prompt at the beginning of the line and enter or leave interactive
|
||||
mode. In interactive mode, the connection is not closed after a command
|
||||
completes. Instead, the prompt will appear again, indicating the user that
|
||||
the interpreter is waiting for a new command. The prompt consists in a right
|
||||
angle bracket followed by a space "> ". This mode is particularly convenient
|
||||
when one wants to periodically check information such as stats or errors.
|
||||
It is also a good idea to enter interactive mode before issuing a "help"
|
||||
command.
|
||||
|
||||
quit
|
||||
Close the connection when in interactive mode.
|
||||
@ -3207,11 +3212,11 @@ show quic [<format>] [<filter>]
|
||||
|
||||
An optional argument can be specified to control the verbosity. Its value can
|
||||
be interpreted in different way. The first possibility is to used predefined
|
||||
values, "oneline" for the default format, "stream" to list every active
|
||||
streams and "full" to display all information. Alternatively, a list of
|
||||
comma-delimited fields can be specified to restrict output. Currently
|
||||
supported values are "tp", "sock", "pktns", "cc" and "mux". Finally, "help"
|
||||
in the format will instead show a more detailed help message.
|
||||
values, "oneline" for the default format and "full" to display all
|
||||
information. Alternatively, a list of comma-delimited fields can be specified
|
||||
to restrict output. Currently supported values are "tp", "sock", "pktns",
|
||||
"cc" and "mux". Finally, "help" in the format will instead show a more
|
||||
detailed help message.
|
||||
|
||||
The final argument is used to restrict or extend the connection list. By
|
||||
default, connections on closing or draining state are not displayed. Use the
|
||||
@ -3226,29 +3231,7 @@ show servers conn [<backend>]
|
||||
The output consists in a header line showing the fields titles, then one
|
||||
server per line with for each, the backend name and ID, server name and ID,
|
||||
the address, port and a series or values. The number of fields varies
|
||||
depending on thread count. The exact format of the output may vary slightly
|
||||
across versions and depending on the number of threads. One needs to pay
|
||||
attention to the header line to match columns when extracting output values,
|
||||
and to the number of threads as the last columns are per-thread:
|
||||
|
||||
bkname/svname Backend name '/' server name
|
||||
bkid/svid Backend ID '/' server ID
|
||||
addr Server's IP address
|
||||
port Server's port (or zero if none)
|
||||
- Unused field, serves as a visual delimiter
|
||||
purge_delay Interval between connection purges, in milliseconds
|
||||
used_cur Number of connections currently in use
|
||||
used_max Highest value of used_cur since the process started
|
||||
need_est Floating estimate of total needed connections
|
||||
unsafe_nb Number of idle connections considered as "unsafe"
|
||||
safe_nb Number of idle connections considered as "safe"
|
||||
idle_lim Configured maximum number of idle connections
|
||||
idle_cur Total of the per-thread currently idle connections
|
||||
idle_per_thr[NB] Idle conns per thread for each one of the NB threads
|
||||
|
||||
HAProxy will kill a portion of <idle_cur> every <purge_delay> when the total
|
||||
of <idle_cur> + <used_cur> exceeds the estimate <need_est>. This estimate
|
||||
varies based on connection activity.
|
||||
depending on thread count.
|
||||
|
||||
Given the threaded nature of idle connections, it's important to understand
|
||||
that some values may change once read, and that as such, consistency within a
|
||||
@ -3817,7 +3800,7 @@ show ssl providers
|
||||
- fips
|
||||
- base
|
||||
|
||||
show ssl sni [-f <frontend>] [-A] [-t <offset>]
|
||||
show ssl sni [-f <frontend>] [-A]
|
||||
Dump every SNI configured for the designated frontend, or all frontends if no
|
||||
frontend was specified. It allows to see what SNI are offered for a frontend,
|
||||
and to identify if a SNI is defined multiple times by multiple certificates for
|
||||
@ -3826,12 +3809,6 @@ show ssl sni [-f <frontend>] [-A] [-t <offset>]
|
||||
The -A option allows to filter the list and only displays the certificates
|
||||
that are past the notAfter date, allowing to show only expired certificates.
|
||||
|
||||
The -t option takes an offset in seconds, or with a time unit (s, m, h, d),
|
||||
which is added to the current time, allowing to check which certificates
|
||||
expired after the offset when combined with -A.
|
||||
For example if you want to check which certificates would be expired in 30d,
|
||||
just do "show ssl sni -A -t 30d".
|
||||
|
||||
Columns are separated by a single \t, allowing to parse it simply.
|
||||
|
||||
The 'Frontend/Bind' column shows the frontend name followed by the bind line
|
||||
@ -3855,7 +3832,7 @@ show ssl sni [-f <frontend>] [-A] [-t <offset>]
|
||||
leaf certificate.
|
||||
|
||||
Example:
|
||||
$ echo "@1 show ssl sni -A -t 30d" | socat /var/run/haproxy-master.sock - | column -t -s $'\t'
|
||||
$ echo "@1 show ssl sni" | socat /var/run/haproxy-master.sock - | column -t -s $'\t'
|
||||
# Frontend/Bind SNI Negative Filter Type Filename NotAfter NotBefore
|
||||
li1/haproxy.cfg:10021 *.ex.lan !m1.ex.lan rsa example.lan.pem Jun 13 13:37:21 2024 GMT May 14 13:37:21 2024 GMT
|
||||
li1/haproxy.cfg:10021 machine10 - ecdsa machine10.pem.ecdsa Jun 13 13:37:21 2024 GMT May 14 13:37:21 2024 GMT
|
||||
@ -4410,8 +4387,7 @@ Example:
|
||||
interactive session on the worker process by not specifying any command
|
||||
(i.e. "@@1" on its own line). This session can be terminated either by
|
||||
closing the connection or by quitting the worker process (using the "quit"
|
||||
command). In this case, the prompt mode of the master socket (interactive,
|
||||
prompt, timed) is propagated into the worker process.
|
||||
command).
|
||||
|
||||
Examples:
|
||||
# gracefully close connections and delete a server once idle (wait max 10s)
|
||||
|
@ -112,7 +112,7 @@ local function rotate_piece(piece, piece_id, px, py, board)
|
||||
end
|
||||
|
||||
function render(applet, board, piece, piece_id, px, py, score)
|
||||
local output = cursor_home
|
||||
local output = clear_screen .. cursor_home
|
||||
output = output .. game_name .. " - Lines: " .. score .. "\r\n"
|
||||
output = output .. "+" .. string.rep("-", board_width * 2) .. "+\r\n"
|
||||
for y = 1, board_height do
|
||||
@ -160,7 +160,6 @@ function handler(applet)
|
||||
end
|
||||
|
||||
applet:send(cursor_hide)
|
||||
applet:send(clear_screen)
|
||||
|
||||
-- fall the piece by one line every delay
|
||||
local function fall_piece()
|
||||
@ -215,7 +214,7 @@ function handler(applet)
|
||||
|
||||
local input = applet:receive(1, delay)
|
||||
if input then
|
||||
if input == "" or input == "q" then
|
||||
if input == "q" then
|
||||
game_over = true
|
||||
elseif input == "\27" then
|
||||
local a = applet:receive(1, delay)
|
||||
|
@ -5,15 +5,14 @@
|
||||
#include <haproxy/istbuf.h>
|
||||
#include <haproxy/openssl-compat.h>
|
||||
|
||||
#define ACME_RETRY 5
|
||||
#define ACME_RETRY 3
|
||||
|
||||
/* acme section configuration */
|
||||
struct acme_cfg {
|
||||
char *filename; /* config filename */
|
||||
int linenum; /* config linenum */
|
||||
char *name; /* section name */
|
||||
char *directory; /* directory URL */
|
||||
char *map; /* storage for tokens + thumbprint */
|
||||
char *uri; /* directory URL */
|
||||
struct {
|
||||
char *contact; /* email associated to account */
|
||||
char *file; /* account key filename */
|
||||
@ -62,7 +61,6 @@ struct acme_ctx {
|
||||
enum acme_st state;
|
||||
enum http_st http_state;
|
||||
int retries;
|
||||
int retryafter;
|
||||
struct httpclient *hc;
|
||||
struct acme_cfg *cfg;
|
||||
struct ckch_store *store;
|
||||
@ -79,6 +77,5 @@ struct acme_ctx {
|
||||
X509_REQ *req;
|
||||
struct ist finalize;
|
||||
struct ist certificate;
|
||||
struct mt_list el;
|
||||
};
|
||||
#endif
|
||||
|
@ -109,28 +109,22 @@ struct appctx {
|
||||
struct buffer outbuf;
|
||||
size_t to_forward;
|
||||
|
||||
struct buffer *chunk; /* used to store unfinished commands */
|
||||
struct applet *applet; /* applet this context refers to */
|
||||
struct session *sess; /* session for frontend applets (NULL for backend applets) */
|
||||
struct sedesc *sedesc; /* stream endpoint descriptor the applet is attached to */
|
||||
|
||||
struct {
|
||||
struct buffer *cmdline; /* used to store unfinished commands */
|
||||
|
||||
int severity_output; /* used within the cli_io_handler to format severity output of informational feedback */
|
||||
int level; /* the level of CLI which can be lowered dynamically */
|
||||
char payload_pat[8]; /* Payload pattern */
|
||||
char *payload; /* Pointer on the payload. NULL if no payload */
|
||||
uint32_t anon_key; /* the key to anonymise with the hash in cli */
|
||||
/* XXX 4 unused bytes here */
|
||||
int (*io_handler)(struct appctx *appctx); /* used within the cli_io_handler when st0 = CLI_ST_CALLBACK */
|
||||
void (*io_release)(struct appctx *appctx); /* used within the cli_io_handler when st0 = CLI_ST_CALLBACK,
|
||||
if the command is terminated or the session released */
|
||||
} cli_ctx; /* context dedicated to the CLI applet */
|
||||
|
||||
struct act_rule *rule; /* rule associated with the applet. */
|
||||
int (*io_handler)(struct appctx *appctx); /* used within the cli_io_handler when st0 = CLI_ST_CALLBACK */
|
||||
void (*io_release)(struct appctx *appctx); /* used within the cli_io_handler when st0 = CLI_ST_CALLBACK,
|
||||
if the command is terminated or the session released */
|
||||
int cli_severity_output; /* used within the cli_io_handler to format severity output of informational feedback */
|
||||
int cli_level; /* the level of CLI which can be lowered dynamically */
|
||||
char cli_payload_pat[8]; /* Payload pattern */
|
||||
char *cli_payload; /* Pointer on the payload. NULL if no payload */
|
||||
uint32_t cli_anon_key; /* the key to anonymise with the hash in cli */
|
||||
struct buffer_wait buffer_wait; /* position in the list of objects waiting for a buffer */
|
||||
struct task *t; /* task associated to the applet */
|
||||
struct freq_ctr call_rate; /* appctx call rate */
|
||||
/* XXX 4 unused bytes here */
|
||||
struct mt_list wait_entry; /* entry in a list of waiters for an event (e.g. ring events) */
|
||||
|
||||
/* The pointer seen by application code is appctx->svcctx. In 2.7 the
|
||||
|
@ -146,9 +146,6 @@ static inline void __appctx_free(struct appctx *appctx)
|
||||
#define appctx_wakeup(ctx) \
|
||||
_task_wakeup((ctx)->t, TASK_WOKEN_OTHER, MK_CALLER(WAKEUP_TYPE_APPCTX_WAKEUP, 0, 0))
|
||||
|
||||
#define appctx_schedule(ctx, w) \
|
||||
_task_schedule((ctx)->t, w, MK_CALLER(WAKEUP_TYPE_TASK_SCHEDULE, 0, 0))
|
||||
|
||||
/* returns the stream connector the appctx is attached to, via the sedesc */
|
||||
static inline struct stconn *appctx_sc(const struct appctx *appctx)
|
||||
{
|
||||
@ -282,92 +279,6 @@ static inline void applet_expect_data(struct appctx *appctx)
|
||||
se_fl_clr(appctx->sedesc, SE_FL_EXP_NO_DATA);
|
||||
}
|
||||
|
||||
/* Returns the buffer containing data pushed to the applet by the stream. For
|
||||
* applets using its own buffers it is the appctx input buffer. For legacy
|
||||
* applet, it is the output channel buffer.
|
||||
*/
|
||||
static inline struct buffer *applet_get_inbuf(struct appctx *appctx)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
return &appctx->inbuf;
|
||||
else
|
||||
return sc_ob(appctx_sc(appctx));
|
||||
}
|
||||
|
||||
/* Returns the buffer containing data pushed by the applets to the stream. For
|
||||
* applets using its own buffer it is the appctx output buffer. For legacy
|
||||
* applet, it is the input channel buffer.
|
||||
*/
|
||||
static inline struct buffer *applet_get_outbuf(struct appctx *appctx)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
return &appctx->outbuf;
|
||||
else
|
||||
return sc_ib(appctx_sc(appctx));
|
||||
}
|
||||
|
||||
/* Returns the amount of data in the input buffer (see applet_get_inbuf) */
|
||||
static inline size_t applet_input_data(const struct appctx *appctx)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
return b_data(&appctx->inbuf);
|
||||
else
|
||||
return co_data(sc_oc(appctx_sc(appctx)));
|
||||
}
|
||||
|
||||
/* Skips <len> bytes from the input buffer (see applet_get_inbuf).
|
||||
*
|
||||
* This is useful when data have been read directly from the buffer. It is
|
||||
* illegal to call this function with <len> causing a wrapping at the end of the
|
||||
* buffer. It's the caller's responsibility to ensure that <len> is never larger
|
||||
* than available ouput data.
|
||||
*/
|
||||
static inline void applet_skip_input(struct appctx *appctx, size_t len)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
b_del(&appctx->inbuf, len);
|
||||
else
|
||||
co_skip(sc_oc(appctx_sc(appctx)), len);
|
||||
}
|
||||
|
||||
/* Removes all bytes from the input buffer (see applet_get_inbuf).
|
||||
*/
|
||||
static inline void applet_reset_input(struct appctx *appctx)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
b_reset(&appctx->inbuf);
|
||||
applet_fl_clr(appctx, APPCTX_FL_INBLK_FULL);
|
||||
}
|
||||
else
|
||||
co_skip(sc_oc(appctx_sc(appctx)), co_data(sc_oc(appctx_sc(appctx))));
|
||||
}
|
||||
|
||||
/* Returns the amout of space available at the output buffer (see applet_get_outbuf).
|
||||
*/
|
||||
static inline size_t applet_output_room(const struct appctx *appctx)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
return b_room(&appctx->outbuf);
|
||||
else
|
||||
return channel_recv_max(sc_ic(appctx_sc(appctx)));
|
||||
}
|
||||
|
||||
/*Indicates that the applet have more data to deliver and it needs more room in
|
||||
* the output buffer to do so (see applet_get_outbuf).
|
||||
*
|
||||
* For applets using its own buffers, <room_needed> is not used and only
|
||||
* <appctx> flags are updated. For legacy applets, the amount of free space
|
||||
* required must be specified. In this last case, it is the caller
|
||||
* responsibility to be sure <room_needed> is valid.
|
||||
*/
|
||||
static inline void applet_need_room(struct appctx *appctx, size_t room_needed)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
applet_have_more_data(appctx);
|
||||
else
|
||||
sc_need_room(appctx_sc(appctx), room_needed);
|
||||
}
|
||||
|
||||
/* Should only be used via wrappers applet_putchk() / applet_putchk_stress(). */
|
||||
static inline int _applet_putchk(struct appctx *appctx, struct buffer *chunk,
|
||||
int stress)
|
||||
@ -404,10 +315,9 @@ static inline int _applet_putchk(struct appctx *appctx, struct buffer *chunk,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* writes chunk <chunk> into the applet output buffer (see applet_get_outbuf).
|
||||
*
|
||||
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||
* shutdown, invalid call...)
|
||||
/* writes chunk <chunk> into the input channel of the stream attached to this
|
||||
* appctx's endpoint, and marks the SC_FL_NEED_ROOM on a channel full error.
|
||||
* See ci_putchk() for the list of return codes.
|
||||
*/
|
||||
static inline int applet_putchk(struct appctx *appctx, struct buffer *chunk)
|
||||
{
|
||||
@ -420,10 +330,9 @@ static inline int applet_putchk_stress(struct appctx *appctx, struct buffer *chu
|
||||
return _applet_putchk(appctx, chunk, 1);
|
||||
}
|
||||
|
||||
/* writes <len> chars from <blk> into the applet output buffer (see applet_get_outbuf).
|
||||
*
|
||||
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||
* shutdown, invalid call...)
|
||||
/* writes <len> chars from <blk> into the input channel of the stream attached
|
||||
* to this appctx's endpoint, and marks the SC_FL_NEED_ROOM on a channel full
|
||||
* error. See ci_putblk() for the list of return codes.
|
||||
*/
|
||||
static inline int applet_putblk(struct appctx *appctx, const char *blk, int len)
|
||||
{
|
||||
@ -455,11 +364,10 @@ static inline int applet_putblk(struct appctx *appctx, const char *blk, int len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* writes chars from <str> up to the trailing zero (excluded) into the applet
|
||||
* output buffer (see applet_get_outbuf).
|
||||
*
|
||||
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||
* shutdown, invalid call...)
|
||||
/* writes chars from <str> up to the trailing zero (excluded) into the input
|
||||
* channel of the stream attached to this appctx's endpoint, and marks the
|
||||
* SC_FL_NEED_ROOM on a channel full error. See ci_putstr() for the list of
|
||||
* return codes.
|
||||
*/
|
||||
static inline int applet_putstr(struct appctx *appctx, const char *str)
|
||||
{
|
||||
@ -492,10 +400,9 @@ static inline int applet_putstr(struct appctx *appctx, const char *str)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* writes character <chr> into the applet's output buffer (see applet_get_outbuf).
|
||||
*
|
||||
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||
* shutdown, invalid call...)
|
||||
/* writes character <chr> into the input channel of the stream attached to this
|
||||
* appctx's endpoint, and marks the SC_FL_NEED_ROOM on a channel full error.
|
||||
* See ci_putchr() for the list of return codes.
|
||||
*/
|
||||
static inline int applet_putchr(struct appctx *appctx, char chr)
|
||||
{
|
||||
@ -528,283 +435,6 @@ static inline int applet_putchr(struct appctx *appctx, char chr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int applet_may_get(const struct appctx *appctx, size_t len)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
if (len > b_data(&appctx->inbuf)) {
|
||||
if (se_fl_test(appctx->sedesc, SE_FL_SHW))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const struct stconn *sc = appctx_sc(appctx);
|
||||
|
||||
if ((sc->flags & SC_FL_SHUT_DONE) || len > co_data(sc_oc(sc))) {
|
||||
if (sc->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* Gets one char from the applet input buffer (see appet_get_inbuf),
|
||||
*
|
||||
* Return values :
|
||||
* 1 : number of bytes read, equal to requested size.
|
||||
* =0 : not enough data available. <c> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getchar(const struct appctx *appctx, char *c)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = applet_may_get(appctx, 1);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
*c = ((appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
? *(b_head(&appctx->inbuf))
|
||||
: *(co_head(sc_oc(appctx_sc(appctx)))));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Copies one full block of data from the applet input buffer (see
|
||||
* appet_get_inbuf).
|
||||
*
|
||||
* <len> bytes are capied, starting at the offset <offset>.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of bytes read, equal to requested size.
|
||||
* =0 : not enough data available. <blk> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getblk(const struct appctx *appctx, char *blk, int len, int offset)
|
||||
{
|
||||
const struct buffer *buf;
|
||||
int ret;
|
||||
|
||||
ret = applet_may_get(appctx, len+offset);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
buf = ((appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
? &appctx->inbuf
|
||||
: sc_ob(appctx_sc(appctx)));
|
||||
return b_getblk(buf, blk, len, offset);
|
||||
}
|
||||
|
||||
/* Gets one text block representing a word from the applet input buffer (see
|
||||
* appet_get_inbuf).
|
||||
*
|
||||
* The separator is waited for as long as some data can still be received and the
|
||||
* destination is not full. Otherwise, the string may be returned as is, without
|
||||
* the separator.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of bytes read. Includes the separator if present before len or end.
|
||||
* =0 : no separator before end found. <str> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getword(const struct appctx *appctx, char *str, int len, char sep)
|
||||
{
|
||||
const struct buffer *buf;
|
||||
char *p;
|
||||
size_t input, max = len;
|
||||
int ret = 0;
|
||||
|
||||
ret = applet_may_get(appctx, 1);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
buf = &appctx->inbuf;
|
||||
input = b_data(buf);
|
||||
}
|
||||
else {
|
||||
struct stconn *sc = appctx_sc(appctx);
|
||||
|
||||
buf = sc_ob(sc);
|
||||
input = co_data(sc_oc(sc));
|
||||
}
|
||||
|
||||
if (max > input) {
|
||||
max = input;
|
||||
str[max-1] = 0;
|
||||
}
|
||||
|
||||
p = b_head(buf);
|
||||
|
||||
while (max) {
|
||||
*str++ = *p;
|
||||
ret++;
|
||||
max--;
|
||||
if (*p == sep)
|
||||
goto out;
|
||||
p = b_next(buf, p);
|
||||
}
|
||||
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
if (ret < len && (ret < input || b_room(buf)) &&
|
||||
!se_fl_test(appctx->sedesc, SE_FL_SHW))
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
struct stconn *sc = appctx_sc(appctx);
|
||||
|
||||
if (ret < len && (ret < input || channel_may_recv(sc_oc(sc))) &&
|
||||
!(sc->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)))
|
||||
ret = 0;
|
||||
}
|
||||
out:
|
||||
if (max)
|
||||
*str = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Gets one text block representing a line from the applet input buffer (see
|
||||
* appet_get_inbuf).
|
||||
*
|
||||
* The '\n' is waited for as long as some data can still be received and the
|
||||
* destination is not full. Otherwise, the string may be returned as is, without
|
||||
* the '\n'.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of bytes read. Includes the \n if present before len or end.
|
||||
* =0 : no '\n' before end found. <str> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getline(const struct appctx *appctx, char *str, int len)
|
||||
{
|
||||
return applet_getword(appctx, str, len, '\n');
|
||||
}
|
||||
|
||||
/* Gets one or two blocks of data at once from the applet input buffer (see appet_get_inbuf),
|
||||
*
|
||||
* Data are not copied.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of blocks filled (1 or 2). blk1 is always filled before blk2.
|
||||
* =0 : not enough data available. <blk*> are left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getblk_nc(const struct appctx *appctx, const char **blk1, size_t *len1, const char **blk2, size_t *len2)
|
||||
{
|
||||
const struct buffer *buf;
|
||||
size_t max;
|
||||
int ret;
|
||||
|
||||
ret = applet_may_get(appctx, 1);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
buf = &appctx->inbuf;
|
||||
max = b_data(buf);
|
||||
}
|
||||
else {
|
||||
struct stconn *sc = appctx_sc(appctx);
|
||||
|
||||
buf = sc_ob(sc);
|
||||
max = co_data(sc_oc(sc));
|
||||
}
|
||||
|
||||
return b_getblk_nc(buf, blk1, len1, blk2, len2, 0, max);
|
||||
}
|
||||
|
||||
/* Gets one or two blocks of text representing a word from the applet input
|
||||
* buffer (see appet_get_inbuf).
|
||||
*
|
||||
* Data are not copied. The separator is waited for as long as some data can
|
||||
* still be received and the destination is not full. Otherwise, the string may
|
||||
* be returned as is, without the separator.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of bytes read. Includes the separator if present before len or end.
|
||||
* =0 : no separator before end found. <str> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getword_nc(const struct appctx *appctx, const char **blk1, size_t *len1, const char **blk2, size_t *len2, char sep)
|
||||
{
|
||||
int ret;
|
||||
size_t l;
|
||||
|
||||
ret = applet_getblk_nc(appctx, blk1, len1, blk2, len2);
|
||||
if (unlikely(ret <= 0))
|
||||
return ret;
|
||||
|
||||
for (l = 0; l < *len1 && (*blk1)[l] != sep; l++);
|
||||
if (l < *len1 && (*blk1)[l] == sep) {
|
||||
*len1 = l + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ret >= 2) {
|
||||
for (l = 0; l < *len2 && (*blk2)[l] != sep; l++);
|
||||
if (l < *len2 && (*blk2)[l] == sep) {
|
||||
*len2 = l + 1;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have found no LF and the buffer is full or the SC is shut, then
|
||||
* the resulting string is made of the concatenation of the pending
|
||||
* blocks (1 or 2).
|
||||
*/
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
if (b_full(&appctx->inbuf) || se_fl_test(appctx->sedesc, SE_FL_SHW))
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
struct stconn *sc = appctx_sc(appctx);
|
||||
|
||||
if (!channel_may_recv(sc_oc(sc)) || sc->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* No LF yet and not shut yet */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Gets one or two blocks of text representing a line from the applet input
|
||||
* buffer (see appet_get_inbuf).
|
||||
*
|
||||
* Data are not copied. The '\n' is waited for as long as some data can still be
|
||||
* received and the destination is not full. Otherwise, the string may be
|
||||
* returned as is, without the '\n'.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of bytes read. Includes the \n if present before len or end.
|
||||
* =0 : no '\n' before end found. <str> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getline_nc(const struct appctx *appctx, const char **blk1, size_t *len1, const char **blk2, size_t *len2)
|
||||
{
|
||||
return applet_getword_nc(appctx, blk1, len1, blk2, len2, '\n');
|
||||
}
|
||||
|
||||
#endif /* _HAPROXY_APPLET_H */
|
||||
|
||||
/*
|
||||
|
@ -86,7 +86,7 @@ static inline int be_usable_srv(struct proxy *be)
|
||||
/* set the time of last session on the backend */
|
||||
static inline void be_set_sess_last(struct proxy *be)
|
||||
{
|
||||
HA_ATOMIC_STORE(&be->be_counters.shared->tg[tgid - 1]->last_sess, ns_to_sec(now_ns));
|
||||
be->be_counters.last_sess = ns_to_sec(now_ns);
|
||||
}
|
||||
|
||||
/* This function returns non-zero if the designated server will be
|
||||
|
@ -68,7 +68,7 @@
|
||||
#else // not x86
|
||||
|
||||
/* generic implementation, causes a segfault */
|
||||
static inline __attribute((always_inline,noreturn,unused)) void ha_crash_now(void)
|
||||
static inline __attribute((always_inline)) void ha_crash_now(void)
|
||||
{
|
||||
#if __GNUC_PREREQ__(5, 0)
|
||||
#pragma GCC diagnostic push
|
||||
|
46
include/haproxy/cbuf-t.h
Normal file
46
include/haproxy/cbuf-t.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* include/haprox/cbuf-t.h
|
||||
* This file contains definition for circular buffers.
|
||||
*
|
||||
* Copyright 2021 HAProxy Technologies, Frederic Lecaille <flecaille@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_CBUF_T_H
|
||||
#define _HAPROXY_CBUF_T_H
|
||||
#ifdef USE_QUIC
|
||||
#ifndef USE_OPENSSL
|
||||
#error "Must define USE_OPENSSL"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <haproxy/list-t.h>
|
||||
|
||||
extern struct pool_head *pool_head_cbuf;
|
||||
|
||||
struct cbuf {
|
||||
/* buffer */
|
||||
unsigned char *buf;
|
||||
/* buffer size */
|
||||
size_t sz;
|
||||
/* Writer index */
|
||||
size_t wr;
|
||||
/* Reader index */
|
||||
size_t rd;
|
||||
};
|
||||
|
||||
#endif /* _HAPROXY_CBUF_T_H */
|
136
include/haproxy/cbuf.h
Normal file
136
include/haproxy/cbuf.h
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* include/haprox/cbuf.h
|
||||
* This file contains definitions and prototypes for circular buffers.
|
||||
* Inspired from Linux circular buffers (include/linux/circ_buf.h).
|
||||
*
|
||||
* Copyright 2021 HAProxy Technologies, Frederic Lecaille <flecaille@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_CBUF_H
|
||||
#define _HAPROXY_CBUF_H
|
||||
#ifdef USE_QUIC
|
||||
#ifndef USE_OPENSSL
|
||||
#error "Must define USE_OPENSSL"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <haproxy/atomic.h>
|
||||
#include <haproxy/list.h>
|
||||
#include <haproxy/cbuf-t.h>
|
||||
|
||||
struct cbuf *cbuf_new(unsigned char *buf, size_t sz);
|
||||
void cbuf_free(struct cbuf *cbuf);
|
||||
|
||||
/* Amount of data between <rd> and <wr> */
|
||||
#define CBUF_DATA(wr, rd, size) (((wr) - (rd)) & ((size) - 1))
|
||||
|
||||
/* Return the writer position in <cbuf>.
|
||||
* To be used only by the writer!
|
||||
*/
|
||||
static inline unsigned char *cb_wr(struct cbuf *cbuf)
|
||||
{
|
||||
return cbuf->buf + cbuf->wr;
|
||||
}
|
||||
|
||||
/* Reset the reader index.
|
||||
* To be used by a reader!
|
||||
*/
|
||||
static inline void cb_rd_reset(struct cbuf *cbuf)
|
||||
{
|
||||
cbuf->rd = 0;
|
||||
}
|
||||
|
||||
/* Reset the writer index.
|
||||
* To be used by a writer!
|
||||
*/
|
||||
static inline void cb_wr_reset(struct cbuf *cbuf)
|
||||
{
|
||||
cbuf->wr = 0;
|
||||
}
|
||||
|
||||
/* Increase <cbuf> circular buffer data by <count>.
|
||||
* To be used by a writer!
|
||||
*/
|
||||
static inline void cb_add(struct cbuf *cbuf, size_t count)
|
||||
{
|
||||
cbuf->wr = (cbuf->wr + count) & (cbuf->sz - 1);
|
||||
}
|
||||
|
||||
/* Return the reader position in <cbuf>.
|
||||
* To be used only by the reader!
|
||||
*/
|
||||
static inline unsigned char *cb_rd(struct cbuf *cbuf)
|
||||
{
|
||||
return cbuf->buf + cbuf->rd;
|
||||
}
|
||||
|
||||
/* Skip <count> byte in <cbuf> circular buffer.
|
||||
* To be used by a reader!
|
||||
*/
|
||||
static inline void cb_del(struct cbuf *cbuf, size_t count)
|
||||
{
|
||||
cbuf->rd = (cbuf->rd + count) & (cbuf->sz - 1);
|
||||
}
|
||||
|
||||
/* Return the amount of data left in <cbuf>.
|
||||
* To be used only by the writer!
|
||||
*/
|
||||
static inline size_t cb_data(struct cbuf *cbuf)
|
||||
{
|
||||
size_t rd;
|
||||
|
||||
rd = HA_ATOMIC_LOAD(&cbuf->rd);
|
||||
return CBUF_DATA(cbuf->wr, rd, cbuf->sz);
|
||||
}
|
||||
|
||||
/* Return the amount of room left in <cbuf> minus 1 to distinguish
|
||||
* the case where the buffer is full from the case where is is empty
|
||||
* To be used only by the write!
|
||||
*/
|
||||
static inline size_t cb_room(struct cbuf *cbuf)
|
||||
{
|
||||
size_t rd;
|
||||
|
||||
rd = HA_ATOMIC_LOAD(&cbuf->rd);
|
||||
return CBUF_DATA(rd, cbuf->wr + 1, cbuf->sz);
|
||||
}
|
||||
|
||||
/* Return the amount of contiguous data left in <cbuf>.
|
||||
* To be used only by the reader!
|
||||
*/
|
||||
static inline size_t cb_contig_data(struct cbuf *cbuf)
|
||||
{
|
||||
size_t end, n;
|
||||
|
||||
end = cbuf->sz - cbuf->rd;
|
||||
n = (HA_ATOMIC_LOAD(&cbuf->wr) + end) & (cbuf->sz - 1);
|
||||
return n < end ? n : end;
|
||||
}
|
||||
|
||||
/* Return the amount of contiguous space left in <cbuf>.
|
||||
* To be used only by the writer!
|
||||
*/
|
||||
static inline size_t cb_contig_space(struct cbuf *cbuf)
|
||||
{
|
||||
size_t end, n;
|
||||
|
||||
end = cbuf->sz - 1 - cbuf->wr;
|
||||
n = (HA_ATOMIC_LOAD(&cbuf->rd) + end) & (cbuf->sz - 1);
|
||||
return n <= end ? n : end + 1;
|
||||
}
|
||||
|
||||
#endif /* _HAPROXY_CBUF_H */
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include <haproxy/applet-t.h>
|
||||
|
||||
/* Access level for a stats socket (appctx->cli_ctx.level) */
|
||||
/* Access level for a stats socket (appctx->cli_level) */
|
||||
#define ACCESS_LVL_NONE 0x0000
|
||||
#define ACCESS_LVL_USER 0x0001
|
||||
#define ACCESS_LVL_OPER 0x0002
|
||||
@ -41,12 +41,11 @@
|
||||
#define ACCESS_MCLI_SEVERITY_STR 0x0200 /* 'set severity-output string' on master CLI */
|
||||
|
||||
/* flags for appctx->st1 */
|
||||
#define APPCTX_CLI_ST1_PAYLOAD (1 << 0)
|
||||
#define APPCTX_CLI_ST1_NOLF (1 << 1)
|
||||
#define APPCTX_CLI_ST1_LASTCMD (1 << 2)
|
||||
#define APPCTX_CLI_ST1_INTER (1 << 3) /* interactive mode (i.e. don't close after 1st cmd) */
|
||||
#define APPCTX_CLI_ST1_PROMPT (1 << 4) /* display prompt */
|
||||
#define APPCTX_CLI_ST1_TIMED (1 << 5) /* display timer in prompt */
|
||||
#define APPCTX_CLI_ST1_PROMPT (1 << 0)
|
||||
#define APPCTX_CLI_ST1_PAYLOAD (1 << 1)
|
||||
#define APPCTX_CLI_ST1_NOLF (1 << 2)
|
||||
#define APPCTX_CLI_ST1_TIMED (1 << 3)
|
||||
#define APPCTX_CLI_ST1_LASTCMD (1 << 4)
|
||||
|
||||
#define CLI_PREFIX_KW_NB 5
|
||||
#define CLI_MAX_MATCHES 5
|
||||
|
@ -55,24 +55,6 @@
|
||||
#define ___equals_1(x) ____equals_1(comma_for_one ## x 1)
|
||||
#define __equals_1(x) ___equals_1(x)
|
||||
|
||||
/* same but checks if defined as zero, useful to distinguish between -DFOO and
|
||||
* -DFOO=0.
|
||||
*/
|
||||
#define comma_for_zero0 ,
|
||||
#define _____equals_0(x, y, ...) (y)
|
||||
#define ____equals_0(x, ...) _____equals_0(x, 0)
|
||||
#define ___equals_0(x) ____equals_0(comma_for_zero ## x 1)
|
||||
#define __equals_0(x) ___equals_0(x)
|
||||
|
||||
/* same but checks if defined as empty, useful to distinguish between -DFOO= and
|
||||
* -DFOO=anything.
|
||||
*/
|
||||
#define comma_for_empty ,
|
||||
#define _____def_as_empty(x, y, ...) (y)
|
||||
#define ____def_as_empty(x, ...) _____def_as_empty(x, 0)
|
||||
#define ___def_as_empty(x) ____def_as_empty(comma_for_empty ## x 1)
|
||||
#define __def_as_empty(x) ___def_as_empty(x)
|
||||
|
||||
/* gcc 5 and clang 3 brought __has_attribute(), which is not well documented in
|
||||
* the case of gcc, but is convenient since handled at the preprocessor level.
|
||||
* In both cases it's possible to test for __has_attribute() using ifdef. When
|
||||
|
@ -75,7 +75,7 @@ int conn_send_socks4_proxy_request(struct connection *conn);
|
||||
int conn_recv_socks4_proxy_response(struct connection *conn);
|
||||
|
||||
/* If we delayed the mux creation because we were waiting for the handshake, do it now */
|
||||
int conn_create_mux(struct connection *conn, int *closed_connection);
|
||||
int conn_create_mux(struct connection *conn);
|
||||
int conn_notify_mux(struct connection *conn, int old_flags, int forced_wake);
|
||||
int conn_upgrade_mux_fe(struct connection *conn, void *ctx, struct buffer *buf,
|
||||
struct ist mux_proto, int mode);
|
||||
|
@ -25,144 +25,108 @@
|
||||
|
||||
#include <haproxy/freq_ctr-t.h>
|
||||
|
||||
#define COUNTERS_SHARED_F_NONE 0x0000
|
||||
#define COUNTERS_SHARED_F_LOCAL 0x0001 // shared counter struct is actually process-local
|
||||
|
||||
// common to fe_counters_shared and be_counters_shared
|
||||
#define COUNTERS_SHARED \
|
||||
struct { \
|
||||
uint16_t flags; /* COUNTERS_SHARED_F flags */\
|
||||
};
|
||||
#define COUNTERS_SHARED_TG \
|
||||
struct { \
|
||||
unsigned long last_change; /* last time, when the state was changed */\
|
||||
long long srv_aborts; /* aborted responses during DATA phase caused by the server */\
|
||||
long long cli_aborts; /* aborted responses during DATA phase caused by the client */\
|
||||
long long internal_errors; /* internal processing errors */\
|
||||
long long failed_rewrites; /* failed rewrites (warning) */\
|
||||
long long bytes_out; /* number of bytes transferred from the server to the client */\
|
||||
long long bytes_in; /* number of bytes transferred from the client to the server */\
|
||||
long long denied_resp; /* blocked responses because of security concerns */\
|
||||
long long denied_req; /* blocked requests because of security concerns */\
|
||||
long long cum_sess; /* cumulated number of accepted connections */\
|
||||
/* compression counters, index 0 for requests, 1 for responses */\
|
||||
long long comp_in[2]; /* input bytes fed to the compressor */\
|
||||
long long comp_out[2]; /* output bytes emitted by the compressor */\
|
||||
long long comp_byp[2]; /* input bytes that bypassed the compressor (cpu/ram/bw limitation) */\
|
||||
struct freq_ctr sess_per_sec; /* sessions per second on this server */\
|
||||
}
|
||||
|
||||
// for convenience (generic pointer)
|
||||
struct counters_shared {
|
||||
COUNTERS_SHARED;
|
||||
struct {
|
||||
COUNTERS_SHARED_TG;
|
||||
} *tg[MAX_TGROUPS];
|
||||
};
|
||||
|
||||
/* counters used by listeners and frontends */
|
||||
struct fe_counters_shared_tg {
|
||||
COUNTERS_SHARED_TG;
|
||||
|
||||
long long denied_sess; /* denied session requests (tcp-req-sess rules) */
|
||||
long long denied_conn; /* denied connection requests (tcp-req-conn rules) */
|
||||
long long intercepted_req; /* number of monitoring or stats requests intercepted by the frontend */
|
||||
long long cum_conn; /* cumulated number of received connections */
|
||||
struct freq_ctr conn_per_sec; /* received connections per second on the frontend */
|
||||
|
||||
struct freq_ctr req_per_sec; /* HTTP requests per second on the frontend */
|
||||
|
||||
long long cum_sess_ver[3]; /* cumulated number of h1/h2/h3 sessions */
|
||||
union {
|
||||
struct {
|
||||
long long cum_req[4]; /* cumulated number of processed other/h1/h2/h3 requests */
|
||||
long long cache_hits; /* cache hits */
|
||||
long long cache_lookups;/* cache lookups */
|
||||
long long comp_rsp; /* number of compressed responses */
|
||||
long long rsp[6]; /* http response codes */
|
||||
} http;
|
||||
} p; /* protocol-specific stats */
|
||||
|
||||
long long failed_req; /* failed requests (eg: invalid or timeout) */
|
||||
};
|
||||
|
||||
struct fe_counters_shared {
|
||||
COUNTERS_SHARED;
|
||||
struct fe_counters_shared_tg *tg[MAX_TGROUPS];
|
||||
};
|
||||
|
||||
struct fe_counters {
|
||||
struct fe_counters_shared *shared; /* shared counters */
|
||||
unsigned int conn_max; /* max # of active sessions */
|
||||
long long cum_conn; /* cumulated number of received connections */
|
||||
long long cum_sess; /* cumulated number of accepted connections */
|
||||
long long cum_sess_ver[3]; /* cumulated number of h1/h2/h3 sessions */
|
||||
|
||||
unsigned int cps_max; /* maximum of new connections received per second */
|
||||
unsigned int sps_max; /* maximum of new connections accepted per second (sessions) */
|
||||
struct freq_ctr _sess_per_sec; /* sessions per second on this frontend, used to compute sps_max (internal use only) */
|
||||
struct freq_ctr _conn_per_sec; /* connections per second on this frontend, used to compute cps_max (internal use only) */
|
||||
|
||||
long long bytes_in; /* number of bytes transferred from the client to the server */
|
||||
long long bytes_out; /* number of bytes transferred from the server to the client */
|
||||
|
||||
/* compression counters, index 0 for requests, 1 for responses */
|
||||
long long comp_in[2]; /* input bytes fed to the compressor */
|
||||
long long comp_out[2]; /* output bytes emitted by the compressor */
|
||||
long long comp_byp[2]; /* input bytes that bypassed the compressor (cpu/ram/bw limitation) */
|
||||
|
||||
long long denied_req; /* blocked requests because of security concerns */
|
||||
long long denied_resp; /* blocked responses because of security concerns */
|
||||
long long failed_req; /* failed requests (eg: invalid or timeout) */
|
||||
long long denied_conn; /* denied connection requests (tcp-req-conn rules) */
|
||||
long long denied_sess; /* denied session requests (tcp-req-sess rules) */
|
||||
long long failed_rewrites; /* failed rewrites (warning) */
|
||||
long long internal_errors; /* internal processing errors */
|
||||
|
||||
long long cli_aborts; /* aborted responses during DATA phase caused by the client */
|
||||
long long srv_aborts; /* aborted responses during DATA phase caused by the server */
|
||||
long long intercepted_req; /* number of monitoring or stats requests intercepted by the frontend */
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int rps_max; /* maximum of new HTTP requests second observed */
|
||||
struct freq_ctr _req_per_sec; /* HTTP requests per second on the frontend, only used to compute rps_max */
|
||||
} http;
|
||||
} p; /* protocol-specific stats */
|
||||
};
|
||||
|
||||
struct be_counters_shared_tg {
|
||||
COUNTERS_SHARED_TG;
|
||||
|
||||
long long cum_lbconn; /* cumulated number of sessions processed by load balancing (BE only) */
|
||||
|
||||
long long connect; /* number of connection establishment attempts */
|
||||
long long reuse; /* number of connection reuses */
|
||||
unsigned long last_sess; /* last session time */
|
||||
|
||||
long long failed_checks, failed_hana; /* failed health checks and health analyses for servers */
|
||||
long long down_trans; /* up->down transitions */
|
||||
|
||||
union {
|
||||
struct {
|
||||
long long cum_req; /* cumulated number of processed HTTP requests */
|
||||
|
||||
long long cache_hits; /* cache hits */
|
||||
long long cache_lookups;/* cache lookups */
|
||||
long long cum_req[4]; /* cumulated number of processed other/h1/h2/h3 requests */
|
||||
long long comp_rsp; /* number of compressed responses */
|
||||
unsigned int rps_max; /* maximum of new HTTP requests second observed */
|
||||
long long rsp[6]; /* http response codes */
|
||||
|
||||
long long cache_lookups;/* cache lookups */
|
||||
long long cache_hits; /* cache hits */
|
||||
} http;
|
||||
} p; /* protocol-specific stats */
|
||||
|
||||
long long redispatches; /* retried and redispatched connections (BE only) */
|
||||
long long retries; /* retried and redispatched connections (BE only) */
|
||||
long long failed_resp; /* failed responses (BE only) */
|
||||
long long failed_conns; /* failed connect() attempts (BE only) */
|
||||
};
|
||||
struct freq_ctr sess_per_sec; /* sessions per second on this server */
|
||||
struct freq_ctr req_per_sec; /* HTTP requests per second on the frontend */
|
||||
struct freq_ctr conn_per_sec; /* received connections per second on the frontend */
|
||||
|
||||
struct be_counters_shared {
|
||||
COUNTERS_SHARED;
|
||||
struct be_counters_shared_tg *tg[MAX_TGROUPS];
|
||||
unsigned long last_change; /* last time, when the state was changed */
|
||||
};
|
||||
|
||||
/* counters used by servers and backends */
|
||||
struct be_counters {
|
||||
struct be_counters_shared *shared; /* shared counters */
|
||||
unsigned int conn_max; /* max # of active sessions */
|
||||
long long cum_sess; /* cumulated number of accepted connections */
|
||||
long long cum_lbconn; /* cumulated number of sessions processed by load balancing (BE only) */
|
||||
|
||||
unsigned int cps_max; /* maximum of new connections received per second */
|
||||
unsigned int sps_max; /* maximum of new connections accepted per second (sessions) */
|
||||
unsigned int nbpend_max; /* max number of pending connections with no server assigned yet */
|
||||
unsigned int cur_sess_max; /* max number of currently active sessions */
|
||||
|
||||
struct freq_ctr _sess_per_sec; /* sessions per second on this frontend, used to compute sps_max (internal use only) */
|
||||
long long bytes_in; /* number of bytes transferred from the client to the server */
|
||||
long long bytes_out; /* number of bytes transferred from the server to the client */
|
||||
|
||||
/* compression counters, index 0 for requests, 1 for responses */
|
||||
long long comp_in[2]; /* input bytes fed to the compressor */
|
||||
long long comp_out[2]; /* output bytes emitted by the compressor */
|
||||
long long comp_byp[2]; /* input bytes that bypassed the compressor (cpu/ram/bw limitation) */
|
||||
|
||||
long long denied_req; /* blocked requests because of security concerns */
|
||||
long long denied_resp; /* blocked responses because of security concerns */
|
||||
|
||||
long long connect; /* number of connection establishment attempts */
|
||||
long long reuse; /* number of connection reuses */
|
||||
long long failed_conns; /* failed connect() attempts (BE only) */
|
||||
long long failed_resp; /* failed responses (BE only) */
|
||||
long long cli_aborts; /* aborted responses during DATA phase caused by the client */
|
||||
long long srv_aborts; /* aborted responses during DATA phase caused by the server */
|
||||
long long retries; /* retried and redispatched connections (BE only) */
|
||||
long long redispatches; /* retried and redispatched connections (BE only) */
|
||||
long long failed_rewrites; /* failed rewrites (warning) */
|
||||
long long internal_errors; /* internal processing errors */
|
||||
|
||||
long long failed_checks, failed_hana; /* failed health checks and health analyses for servers */
|
||||
long long down_trans; /* up->down transitions */
|
||||
|
||||
unsigned int q_time, c_time, d_time, t_time; /* sums of conn_time, queue_time, data_time, total_time */
|
||||
unsigned int qtime_max, ctime_max, dtime_max, ttime_max; /* maximum of conn_time, queue_time, data_time, total_time observed */
|
||||
|
||||
union {
|
||||
struct {
|
||||
long long cum_req; /* cumulated number of processed HTTP requests */
|
||||
long long comp_rsp; /* number of compressed responses */
|
||||
unsigned int rps_max; /* maximum of new HTTP requests second observed */
|
||||
long long rsp[6]; /* http response codes */
|
||||
long long cache_lookups;/* cache lookups */
|
||||
long long cache_hits; /* cache hits */
|
||||
} http;
|
||||
} p; /* protocol-specific stats */
|
||||
|
||||
struct freq_ctr sess_per_sec; /* sessions per second on this server */
|
||||
|
||||
unsigned long last_sess; /* last session time */
|
||||
unsigned long last_change; /* last time, when the state was changed */
|
||||
};
|
||||
|
||||
#endif /* _HAPROXY_COUNTERS_T_H */
|
||||
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* include/haproxy/counters.h
|
||||
* objects counters management
|
||||
*
|
||||
* Copyright 2025 HAProxy Technologies
|
||||
*
|
||||
* 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_COUNTERS_H
|
||||
# define _HAPROXY_COUNTERS_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <haproxy/counters-t.h>
|
||||
#include <haproxy/guid-t.h>
|
||||
|
||||
struct fe_counters_shared *counters_fe_shared_get(const struct guid_node *guid);
|
||||
struct be_counters_shared *counters_be_shared_get(const struct guid_node *guid);
|
||||
|
||||
void counters_fe_shared_drop(struct fe_counters_shared *counters);
|
||||
void counters_be_shared_drop(struct be_counters_shared *counters);
|
||||
|
||||
/* time oriented helper: get last time (relative to current time) on a given
|
||||
* <scounter> array, for <elem> member (one member per thread group) which is
|
||||
* assumed to be unsigned long type.
|
||||
*
|
||||
* wrapping is handled by taking the lowest diff between now and last counter.
|
||||
* But since wrapping is expected once every ~136 years (starting 01/01/1970),
|
||||
* perhaps it's not worth the extra CPU cost.. let's see.
|
||||
*/
|
||||
#define COUNTERS_SHARED_LAST_OFFSET(scounters, type, offset) \
|
||||
({ \
|
||||
unsigned long last = HA_ATOMIC_LOAD((type *)((char *)scounters[0] + offset));\
|
||||
unsigned long now_seconds = ns_to_sec(now_ns); \
|
||||
int it; \
|
||||
\
|
||||
for (it = 1; it < global.nbtgroups; it++) { \
|
||||
unsigned long cur = HA_ATOMIC_LOAD((type *)((char *)scounters[it] + offset));\
|
||||
if ((now_seconds - cur) < (now_seconds - last)) \
|
||||
last = cur; \
|
||||
} \
|
||||
last; \
|
||||
})
|
||||
|
||||
#define COUNTERS_SHARED_LAST(scounters, elem) \
|
||||
({ \
|
||||
int offset = offsetof(typeof(**scounters), elem); \
|
||||
unsigned long last = COUNTERS_SHARED_LAST_OFFSET(scounters, typeof(scounters[0]->elem), offset); \
|
||||
\
|
||||
last; \
|
||||
})
|
||||
|
||||
|
||||
/* generic unsigned integer addition for all <elem> members from
|
||||
* <scounters> array (one member per thread group)
|
||||
* <rfunc> is function taking pointer as parameter to read from the memory
|
||||
* location pointed to scounters[it].elem
|
||||
*/
|
||||
#define COUNTERS_SHARED_TOTAL_OFFSET(scounters, type, offset, rfunc) \
|
||||
({ \
|
||||
uint64_t __ret = 0; \
|
||||
int it; \
|
||||
\
|
||||
for (it = 0; it < global.nbtgroups; it++) \
|
||||
__ret += rfunc((type *)((char *)scounters[it] + offset)); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define COUNTERS_SHARED_TOTAL(scounters, elem, rfunc) \
|
||||
({ \
|
||||
int offset = offsetof(typeof(**scounters), elem); \
|
||||
uint64_t __ret = COUNTERS_SHARED_TOTAL_OFFSET(scounters, typeof(scounters[0]->elem), offset, rfunc);\
|
||||
\
|
||||
__ret; \
|
||||
})
|
||||
/* same as COUNTERS_SHARED_TOTAL but with <rfunc> taking 2 extras arguments:
|
||||
* <arg1> and <arg2>
|
||||
*/
|
||||
#define COUNTERS_SHARED_TOTAL_ARG2(scounters, elem, rfunc, arg1, arg2) \
|
||||
({ \
|
||||
uint64_t __ret = 0; \
|
||||
int it; \
|
||||
\
|
||||
for (it = 0; it < global.nbtgroups; it++) \
|
||||
__ret += rfunc(&scounters[it]->elem, arg1, arg2); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#endif /* _HAPROXY_COUNTERS_H */
|
@ -44,7 +44,7 @@
|
||||
* doesn't engage us too far.
|
||||
*/
|
||||
#ifndef MAX_TGROUPS
|
||||
#define MAX_TGROUPS 32
|
||||
#define MAX_TGROUPS 16
|
||||
#endif
|
||||
|
||||
#define MAX_THREADS_PER_GROUP __WORDSIZE
|
||||
@ -53,7 +53,7 @@
|
||||
* long bits if more tgroups are enabled.
|
||||
*/
|
||||
#ifndef MAX_THREADS
|
||||
#define MAX_THREADS ((((MAX_TGROUPS) > 1) ? 16 : 1) * (MAX_THREADS_PER_GROUP))
|
||||
#define MAX_THREADS ((((MAX_TGROUPS) > 1) ? 4 : 1) * (MAX_THREADS_PER_GROUP))
|
||||
#endif
|
||||
|
||||
#endif // USE_THREAD
|
||||
@ -349,11 +349,6 @@
|
||||
#define SRV_CHK_INTER_THRES 1000
|
||||
#endif
|
||||
|
||||
/* INET6 connectivity caching interval (in ms) */
|
||||
#ifndef INET6_CONNECTIVITY_CACHE_TIME
|
||||
#define INET6_CONNECTIVITY_CACHE_TIME 30000
|
||||
#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.
|
||||
@ -599,15 +594,6 @@
|
||||
# define DEBUG_STRICT 1
|
||||
#endif
|
||||
|
||||
/* Let's make DEBUG_THREAD default to 1, and make sure it has a value */
|
||||
#ifndef DEBUG_THREAD
|
||||
# if defined(USE_THREAD)
|
||||
# define DEBUG_THREAD 1
|
||||
# else
|
||||
# define DEBUG_THREAD 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Let's make DEBUG_COUNTERS default to 1 to have glitches counters by default */
|
||||
#ifndef DEBUG_COUNTERS
|
||||
# define DEBUG_COUNTERS 1
|
||||
@ -650,17 +636,4 @@
|
||||
#define FWLC_MIN_FREE_ENTRIES 500
|
||||
#endif /* FWLC_MIN_FREE_ENTRIES */
|
||||
|
||||
/*
|
||||
* QUIC
|
||||
*/
|
||||
|
||||
/* Memory usage in bytes on Tx side, 0 for unlimited. */
|
||||
#ifndef QUIC_MAX_TX_MEM
|
||||
#define QUIC_MAX_TX_MEM 0
|
||||
#endif
|
||||
|
||||
#ifndef STKTABLE_MAX_UPDATES_AT_ONCE
|
||||
#define STKTABLE_MAX_UPDATES_AT_ONCE 100
|
||||
#endif /* STKTABLE_MAX_UPDATES_AT_ONCE */
|
||||
|
||||
#endif /* _HAPROXY_DEFAULTS_H */
|
||||
|
@ -42,11 +42,6 @@
|
||||
#define DNS_TCP_MSG_MAX_SIZE 65535
|
||||
#define DNS_TCP_MSG_RING_MAX_SIZE (1 + 1 + 3 + DNS_TCP_MSG_MAX_SIZE) // varint_bytes(DNS_TCP_MSG_MAX_SIZE) == 3
|
||||
|
||||
/* threshold to consider that the link to dns server is failing
|
||||
* and we should stop creating new sessions
|
||||
*/
|
||||
#define DNS_MAX_DSS_CONSECUTIVE_ERRORS 100
|
||||
|
||||
/* DNS request or response header structure */
|
||||
struct dns_header {
|
||||
uint16_t id;
|
||||
@ -84,7 +79,7 @@ struct dns_additional_record {
|
||||
struct dns_stream_server {
|
||||
struct server *srv;
|
||||
struct dns_ring *ring_req;
|
||||
int consecutive_errors; /* number of errors since last successful query (atomically updated without lock) */
|
||||
int max_slots;
|
||||
int maxconn;
|
||||
int idle_conns;
|
||||
int cur_conns;
|
||||
|
@ -499,7 +499,6 @@ static inline long fd_clr_running(int fd)
|
||||
static inline void fd_insert(int fd, void *owner, void (*iocb)(int fd), int tgid, unsigned long thread_mask)
|
||||
{
|
||||
extern void sock_conn_iocb(int);
|
||||
struct tgroup_info *tginfo = &ha_tgroup_info[tgid - 1];
|
||||
int newstate;
|
||||
|
||||
/* conn_fd_handler should support edge-triggered FDs */
|
||||
@ -529,7 +528,7 @@ static inline void fd_insert(int fd, void *owner, void (*iocb)(int fd), int tgid
|
||||
BUG_ON(fdtab[fd].state != 0);
|
||||
BUG_ON(tgid < 1 || tgid > MAX_TGROUPS);
|
||||
|
||||
thread_mask &= tginfo->threads_enabled;
|
||||
thread_mask &= tg->threads_enabled;
|
||||
BUG_ON(thread_mask == 0);
|
||||
|
||||
fd_claim_tgid(fd, tgid);
|
||||
|
@ -184,8 +184,6 @@ struct global {
|
||||
uint client_rcvbuf; /* set client rcvbuf to this value if not null */
|
||||
uint server_sndbuf; /* set server sndbuf to this value if not null */
|
||||
uint server_rcvbuf; /* set server rcvbuf to this value if not null */
|
||||
uint client_notsent_lowat; /* set client tcp_notsent_lowat to this value if not null */
|
||||
uint server_notsent_lowat; /* set client tcp_notsent_lowat to this value if not null */
|
||||
uint frontend_sndbuf; /* set frontend dgram sndbuf to this value if not null */
|
||||
uint frontend_rcvbuf; /* set frontend dgram rcvbuf to this value if not null */
|
||||
uint backend_sndbuf; /* set backend dgram sndbuf to this value if not null */
|
||||
@ -197,7 +195,6 @@ struct global {
|
||||
int pattern_cache; /* max number of entries in the pattern cache. */
|
||||
int sslcachesize; /* SSL cache size in session, defaults to 20000 */
|
||||
int comp_maxlevel; /* max HTTP compression level */
|
||||
uint glitch_kill_maxidle; /* have glitches kill only below this level of idle */
|
||||
int pool_low_ratio; /* max ratio of FDs used before we stop using new idle connections */
|
||||
int pool_high_ratio; /* max ratio of FDs used before we start killing idle connections when creating new connections */
|
||||
int pool_low_count; /* max number of opened fd before we stop using new idle connections */
|
||||
@ -218,7 +215,6 @@ struct global {
|
||||
unsigned int quic_frontend_glitches_threshold;
|
||||
unsigned int quic_frontend_max_data;
|
||||
unsigned int quic_frontend_max_streams_bidi;
|
||||
uint64_t quic_frontend_max_tx_mem;
|
||||
size_t quic_frontend_max_window_size;
|
||||
unsigned int quic_frontend_stream_data_ratio;
|
||||
unsigned int quic_retry_threshold;
|
||||
|
@ -50,7 +50,6 @@
|
||||
#define HLUA_INIT(__hlua) do { (__hlua)->T = 0; } while(0)
|
||||
|
||||
/* Lua HAProxy integration functions. */
|
||||
void hlua_yield_asap(lua_State *L);
|
||||
const char *hlua_traceback(lua_State *L, const char* sep);
|
||||
void hlua_ctx_destroy(struct hlua *lua);
|
||||
void hlua_init();
|
||||
|
@ -232,52 +232,6 @@ static inline int http_path_has_forbidden_char(const struct ist ist, const char
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Checks whether the :authority pseudo header contains dangerous chars that
|
||||
* might affect its reassembly. We want to catch anything below 0x21, above
|
||||
* 0x7e, as well as '@', '[', ']', '/','?', '#', '\', CR, LF, NUL. Then we
|
||||
* fall back to the slow path and decide. Brackets are used for IP-literal and
|
||||
* deserve special case, that is better handled in the slow path. The function
|
||||
* returns 0 if no forbidden char is presnet, non-zero otherwise.
|
||||
*/
|
||||
static inline int http_authority_has_forbidden_char(const struct ist ist)
|
||||
{
|
||||
size_t ofs, len = istlen(ist);
|
||||
const char *p = istptr(ist);
|
||||
int brackets = 0;
|
||||
uchar c;
|
||||
|
||||
/* Many attempts with various methods have shown that moderately recent
|
||||
* compilers (gcc >= 9, clang >= 13) will arrange the code below as an
|
||||
* evaluation tree that remains efficient at -O2 and above (~1.2ns per
|
||||
* char). The immediate next efficient one is the bitmap from 64-bit
|
||||
* registers but it's extremely sensitive to code arrangements and
|
||||
* optimization.
|
||||
*/
|
||||
for (ofs = 0; ofs < len; ofs++) {
|
||||
c = p[ofs];
|
||||
|
||||
if (unlikely(c < 0x21 || c > 0x7e ||
|
||||
c == '#' || c == '/' || c == '?' || c == '@' ||
|
||||
c == '[' || c == '\\' || c == ']')) {
|
||||
/* all of them must be rejected, except '[' which may
|
||||
* only appear at the beginning, and ']' which may
|
||||
* only appear at the end or before a colon.
|
||||
*/
|
||||
if ((c == '[' && ofs == 0) ||
|
||||
(c == ']' && (ofs == len - 1 || p[ofs + 1] == ':'))) {
|
||||
/* that's an IP-literal (see RFC3986#3.2), it's
|
||||
* OK for now.
|
||||
*/
|
||||
brackets ^= 1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* there must be no opening bracket left nor lone closing one */
|
||||
return brackets;
|
||||
}
|
||||
|
||||
/* Checks status code array <array> for the presence of status code <status>.
|
||||
* Returns non-zero if the code is present, zero otherwise. Any status code is
|
||||
* permitted.
|
||||
|
@ -121,7 +121,6 @@ enum li_status {
|
||||
#define BC_SSL_O_NONE 0x0000
|
||||
#define BC_SSL_O_NO_TLS_TICKETS 0x0100 /* disable session resumption tickets */
|
||||
#define BC_SSL_O_PREF_CLIE_CIPH 0x0200 /* prefer client ciphers */
|
||||
#define BC_SSL_O_STRICT_SNI 0x0400 /* refuse negotiation if sni doesn't match a certificate */
|
||||
#endif
|
||||
|
||||
struct tls_version_filter {
|
||||
@ -170,6 +169,7 @@ struct bind_conf {
|
||||
unsigned long long ca_ignerr_bitfield[IGNERR_BF_SIZE]; /* ignored verify errors in handshake if depth > 0 */
|
||||
unsigned long long crt_ignerr_bitfield[IGNERR_BF_SIZE]; /* ignored verify errors in handshake if depth == 0 */
|
||||
void *initial_ctx; /* SSL context for initial negotiation */
|
||||
int strict_sni; /* refuse negotiation if sni doesn't match a certificate */
|
||||
int ssl_options; /* ssl options */
|
||||
struct eb_root sni_ctx; /* sni_ctx tree of all known certs full-names sorted by name */
|
||||
struct eb_root sni_w_ctx; /* sni_ctx tree of all known certs wildcards sorted by name */
|
||||
@ -244,7 +244,7 @@ struct listener {
|
||||
struct fe_counters *counters; /* statistics counters */
|
||||
struct mt_list wait_queue; /* link element to make the listener wait for something (LI_LIMITED) */
|
||||
char *name; /* listener's name */
|
||||
char *label; /* listener's label */
|
||||
|
||||
unsigned int thr_conn[MAX_THREADS_PER_GROUP]; /* number of connections per thread for the group */
|
||||
|
||||
struct list by_fe; /* chaining in frontend's list of listeners */
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include <haproxy/quic_frame-t.h>
|
||||
#include <haproxy/quic_pacing-t.h>
|
||||
#include <haproxy/quic_stream-t.h>
|
||||
#include <haproxy/quic_utils-t.h>
|
||||
#include <haproxy/stconn-t.h>
|
||||
#include <haproxy/task-t.h>
|
||||
#include <haproxy/time-t.h>
|
||||
@ -28,6 +27,9 @@ enum qcs_type {
|
||||
QCS_SRV_BIDI,
|
||||
QCS_CLT_UNI,
|
||||
QCS_SRV_UNI,
|
||||
|
||||
/* Must be the last one */
|
||||
QCS_MAX_TYPES
|
||||
};
|
||||
|
||||
enum qcc_app_st {
|
||||
@ -154,12 +156,10 @@ struct qcs {
|
||||
struct eb_root bufs; /* receive buffers tree ordered by offset */
|
||||
struct buffer app_buf; /* receive buffer used by stconn layer */
|
||||
uint64_t msd; /* current max-stream-data limit to enforce */
|
||||
uint64_t msd_base; /* max-stream-data previous to latest update */
|
||||
struct bdata_ctr data; /* data utilization counter. Note that <tot> is now used for now as accounting may be difficult with ncbuf. */
|
||||
uint64_t msd_init; /* initial max-stream-data */
|
||||
} rx;
|
||||
struct {
|
||||
struct quic_fctl fc; /* stream flow control applied on sending */
|
||||
struct quic_frame *msd_frm; /* MAX_STREAM_DATA frame prepared */
|
||||
} tx;
|
||||
|
||||
struct eb64_node by_id;
|
||||
@ -202,7 +202,7 @@ struct qcc_app_ops {
|
||||
/* Initialize <qcs> stream app context or leave it to NULL if rejected. */
|
||||
int (*attach)(struct qcs *qcs, void *conn_ctx);
|
||||
|
||||
/* Convert received HTTP payload to HTX. Returns amount of decoded bytes from <b> or a negative error code. */
|
||||
/* Convert received HTTP payload to HTX. */
|
||||
ssize_t (*rcv_buf)(struct qcs *qcs, struct buffer *b, int fin);
|
||||
|
||||
/* Convert HTX to HTTP payload for sending. */
|
||||
@ -232,7 +232,7 @@ struct qcc_app_ops {
|
||||
|
||||
#define QC_CF_ERRL 0x00000001 /* fatal error detected locally, connection should be closed soon */
|
||||
#define QC_CF_ERRL_DONE 0x00000002 /* local error properly handled, connection can be released */
|
||||
#define QC_CF_IS_BACK 0x00000004 /* backend side */
|
||||
/* unused 0x00000004 */
|
||||
#define QC_CF_CONN_FULL 0x00000008 /* no stream buffers available on connection */
|
||||
/* unused 0x00000010 */
|
||||
#define QC_CF_ERR_CONN 0x00000020 /* fatal error reported by transport layer */
|
||||
|
@ -51,7 +51,15 @@ static inline int qmux_stream_rx_bufsz(void)
|
||||
return global.tune.bufsize - NCB_RESERVED_SZ;
|
||||
}
|
||||
|
||||
/* Bit shift to get the stream sub ID for internal use which is obtained
|
||||
* shifting the stream IDs by this value, knowing that the
|
||||
* QCS_ID_TYPE_SHIFT less significant bits identify the stream ID
|
||||
* types (client initiated bidirectional, server initiated bidirectional,
|
||||
* client initiated unidirectional, server initiated bidirectional).
|
||||
* Note that there is no reference to such stream sub IDs in the RFC.
|
||||
*/
|
||||
#define QCS_ID_TYPE_MASK 0x3
|
||||
#define QCS_ID_TYPE_SHIFT 2
|
||||
/* The less significant bit of a stream ID is set for a server initiated stream */
|
||||
#define QCS_ID_SRV_INTIATOR_BIT 0x1
|
||||
/* This bit is set for unidirectional streams */
|
||||
@ -74,6 +82,16 @@ static inline int quic_stream_is_remote(struct qcc *qcc, uint64_t id)
|
||||
return !quic_stream_is_local(qcc, id);
|
||||
}
|
||||
|
||||
static inline int quic_stream_is_uni(uint64_t id)
|
||||
{
|
||||
return id & QCS_ID_DIR_BIT;
|
||||
}
|
||||
|
||||
static inline int quic_stream_is_bidi(uint64_t id)
|
||||
{
|
||||
return !quic_stream_is_uni(id);
|
||||
}
|
||||
|
||||
static inline char *qcs_st_to_str(enum qcs_state st)
|
||||
{
|
||||
switch (st) {
|
||||
|
@ -87,9 +87,10 @@ static forceinline char *spop_strm_show_flags(char *buf, size_t len, const char
|
||||
|
||||
/* SPOP connection state (spop_conn->state) */
|
||||
enum spop_conn_st {
|
||||
SPOP_CS_HA_HELLO = 0, /* init done, waiting for sending HELLO frame */
|
||||
SPOP_CS_AGENT_HELLO, /* HELLO frame sent, waiting for agent HELLO frame to define the connection settings */
|
||||
SPOP_CS_RUNNING, /* HELLO handshake finished, exchange NOTIFY/ACK frames */
|
||||
SPOP_CS_HA_HELLO = 0, /* init done, waiting for sending HELLO frame */
|
||||
SPOP_CS_AGENT_HELLO, /* HELLO frame sent, waiting for agent HELLO frame to define the connection settings */
|
||||
SPOP_CS_FRAME_H, /* HELLO handshake finished, waiting for a frame header */
|
||||
SPOP_CS_FRAME_P, /* Frame header received, waiting for a frame data */
|
||||
SPOP_CS_ERROR, /* send DISCONNECT frame to be able ti close the connection */
|
||||
SPOP_CS_CLOSING, /* DISCONNECT frame sent, waiting for the agent DISCONNECT frame before closing */
|
||||
SPOP_CS_CLOSED, /* Agent DISCONNECT frame received and close the connection ASAP */
|
||||
@ -102,7 +103,8 @@ static inline const char *spop_conn_st_to_str(enum spop_conn_st st)
|
||||
switch (st) {
|
||||
case SPOP_CS_HA_HELLO : return "HHL";
|
||||
case SPOP_CS_AGENT_HELLO: return "AHL";
|
||||
case SPOP_CS_RUNNING : return "RUN";
|
||||
case SPOP_CS_FRAME_H : return "FRH";
|
||||
case SPOP_CS_FRAME_P : return "FRP";
|
||||
case SPOP_CS_ERROR : return "ERR";
|
||||
case SPOP_CS_CLOSING : return "CLI";
|
||||
case SPOP_CS_CLOSED : return "CLO";
|
||||
|
@ -46,25 +46,7 @@
|
||||
|
||||
#ifdef USE_QUIC_OPENSSL_COMPAT
|
||||
#include <haproxy/quic_openssl_compat.h>
|
||||
#else
|
||||
#if defined(OSSL_FUNC_SSL_QUIC_TLS_CRYPTO_SEND)
|
||||
/* This macro is defined by the new OpenSSL 3.5.0 QUIC TLS API and it is not
|
||||
* defined by quictls.
|
||||
*/
|
||||
#define HAVE_OPENSSL_QUIC
|
||||
#define SSL_set_quic_transport_params SSL_set_quic_tls_transport_params
|
||||
#define SSL_set_quic_early_data_enabled SSL_set_quic_tls_early_data_enabled
|
||||
#define SSL_quic_read_level(arg) -1
|
||||
|
||||
enum ssl_encryption_level_t {
|
||||
ssl_encryption_initial = 0,
|
||||
ssl_encryption_early_data,
|
||||
ssl_encryption_handshake,
|
||||
ssl_encryption_application
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* USE_QUIC_OPENSSL_COMPAT */
|
||||
|
||||
#if defined(OPENSSL_IS_AWSLC)
|
||||
#define OPENSSL_NO_DH
|
||||
@ -150,7 +132,7 @@ enum ssl_encryption_level_t {
|
||||
#define HAVE_JWS
|
||||
#endif
|
||||
|
||||
#if (defined(HAVE_JWS) && defined(HAVE_ASN1_TIME_TO_TM))
|
||||
#if (defined(HAVE_JWS))
|
||||
#define HAVE_ACME
|
||||
#endif
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
#define MEM_F_SHARED 0x1
|
||||
#define MEM_F_EXACT 0x2
|
||||
#define MEM_F_UAF 0x4
|
||||
|
||||
/* A special pointer for the pool's free_list that indicates someone is
|
||||
* currently manipulating it. Serves as a short-lived lock.
|
||||
@ -52,7 +51,6 @@
|
||||
#define POOL_DBG_TAG 0x00000080 // place a tag at the end of the area
|
||||
#define POOL_DBG_POISON 0x00000100 // poison memory area on pool_alloc()
|
||||
#define POOL_DBG_UAF 0x00000200 // enable use-after-free protection
|
||||
#define POOL_DBG_BACKUP 0x00000400 // backup the object contents on free()
|
||||
|
||||
|
||||
/* This is the head of a thread-local cache */
|
||||
|
@ -30,6 +30,4 @@ extern struct protocol proto_quic6;
|
||||
|
||||
extern struct quic_dghdlr *quic_dghdlrs;
|
||||
|
||||
extern THREAD_LOCAL struct cshared quic_mem_diff;
|
||||
|
||||
#endif /* _HAPROXY_PROTO_QUIC_H */
|
||||
|
@ -311,10 +311,6 @@ struct proxy {
|
||||
char flags; /* bit field PR_FL_* */
|
||||
enum pr_mode mode; /* mode = PR_MODE_TCP, PR_MODE_HTTP, ... */
|
||||
char cap; /* supported capabilities (PR_CAP_*) */
|
||||
/* 4-bytes hole */
|
||||
|
||||
struct list global_list; /* list member for global proxy list */
|
||||
|
||||
unsigned int maxconn; /* max # of active streams on the frontend */
|
||||
|
||||
int options; /* PR_O_REDISP, PR_O_TRANSP, ... */
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <haproxy/thread.h>
|
||||
|
||||
extern struct proxy *proxies_list;
|
||||
extern struct list proxies;
|
||||
extern struct eb_root used_proxy_id; /* list of proxy IDs in use */
|
||||
extern unsigned int error_snapshot_id; /* global ID assigned to each error then incremented */
|
||||
extern struct eb_root proxy_by_name; /* tree of proxies sorted by name */
|
||||
@ -136,24 +135,22 @@ static inline void proxy_reset_timeouts(struct proxy *proxy)
|
||||
/* increase the number of cumulated connections received on the designated frontend */
|
||||
static inline void proxy_inc_fe_conn_ctr(struct listener *l, struct proxy *fe)
|
||||
{
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->cum_conn);
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.cum_conn);
|
||||
if (l && l->counters)
|
||||
_HA_ATOMIC_INC(&l->counters->shared->tg[tgid - 1]->cum_conn);
|
||||
update_freq_ctr(&fe->fe_counters.shared->tg[tgid - 1]->conn_per_sec, 1);
|
||||
_HA_ATOMIC_INC(&l->counters->cum_conn);
|
||||
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.cps_max,
|
||||
update_freq_ctr(&fe->fe_counters._conn_per_sec, 1));
|
||||
update_freq_ctr(&fe->fe_counters.conn_per_sec, 1));
|
||||
}
|
||||
|
||||
/* increase the number of cumulated connections accepted by the designated frontend */
|
||||
static inline void proxy_inc_fe_sess_ctr(struct listener *l, struct proxy *fe)
|
||||
{
|
||||
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->cum_sess);
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.cum_sess);
|
||||
if (l && l->counters)
|
||||
_HA_ATOMIC_INC(&l->counters->shared->tg[tgid - 1]->cum_sess);
|
||||
update_freq_ctr(&fe->fe_counters.shared->tg[tgid - 1]->sess_per_sec, 1);
|
||||
_HA_ATOMIC_INC(&l->counters->cum_sess);
|
||||
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.sps_max,
|
||||
update_freq_ctr(&fe->fe_counters._sess_per_sec, 1));
|
||||
update_freq_ctr(&fe->fe_counters.sess_per_sec, 1));
|
||||
}
|
||||
|
||||
/* increase the number of cumulated HTTP sessions on the designated frontend.
|
||||
@ -163,21 +160,20 @@ static inline void proxy_inc_fe_cum_sess_ver_ctr(struct listener *l, struct prox
|
||||
unsigned int http_ver)
|
||||
{
|
||||
if (http_ver == 0 ||
|
||||
http_ver > sizeof(fe->fe_counters.shared->tg[tgid - 1]->cum_sess_ver) / sizeof(*fe->fe_counters.shared->tg[tgid - 1]->cum_sess_ver))
|
||||
http_ver > sizeof(fe->fe_counters.cum_sess_ver) / sizeof(*fe->fe_counters.cum_sess_ver))
|
||||
return;
|
||||
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->cum_sess_ver[http_ver - 1]);
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.cum_sess_ver[http_ver - 1]);
|
||||
if (l && l->counters)
|
||||
_HA_ATOMIC_INC(&l->counters->shared->tg[tgid - 1]->cum_sess_ver[http_ver - 1]);
|
||||
_HA_ATOMIC_INC(&l->counters->cum_sess_ver[http_ver - 1]);
|
||||
}
|
||||
|
||||
/* increase the number of cumulated streams on the designated backend */
|
||||
static inline void proxy_inc_be_ctr(struct proxy *be)
|
||||
{
|
||||
_HA_ATOMIC_INC(&be->be_counters.shared->tg[tgid - 1]->cum_sess);
|
||||
update_freq_ctr(&be->be_counters.shared->tg[tgid - 1]->sess_per_sec, 1);
|
||||
_HA_ATOMIC_INC(&be->be_counters.cum_sess);
|
||||
HA_ATOMIC_UPDATE_MAX(&be->be_counters.sps_max,
|
||||
update_freq_ctr(&be->be_counters._sess_per_sec, 1));
|
||||
update_freq_ctr(&be->be_counters.sess_per_sec, 1));
|
||||
}
|
||||
|
||||
/* increase the number of cumulated requests on the designated frontend.
|
||||
@ -187,15 +183,14 @@ static inline void proxy_inc_be_ctr(struct proxy *be)
|
||||
static inline void proxy_inc_fe_req_ctr(struct listener *l, struct proxy *fe,
|
||||
unsigned int http_ver)
|
||||
{
|
||||
if (http_ver >= sizeof(fe->fe_counters.shared->tg[tgid - 1]->p.http.cum_req) / sizeof(*fe->fe_counters.shared->tg[tgid - 1]->p.http.cum_req))
|
||||
if (http_ver >= sizeof(fe->fe_counters.p.http.cum_req) / sizeof(*fe->fe_counters.p.http.cum_req))
|
||||
return;
|
||||
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->p.http.cum_req[http_ver]);
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.p.http.cum_req[http_ver]);
|
||||
if (l && l->counters)
|
||||
_HA_ATOMIC_INC(&l->counters->shared->tg[tgid - 1]->p.http.cum_req[http_ver]);
|
||||
update_freq_ctr(&fe->fe_counters.shared->tg[tgid - 1]->req_per_sec, 1);
|
||||
_HA_ATOMIC_INC(&l->counters->p.http.cum_req[http_ver]);
|
||||
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.p.http.rps_max,
|
||||
update_freq_ctr(&fe->fe_counters.p.http._req_per_sec, 1));
|
||||
update_freq_ctr(&fe->fe_counters.req_per_sec, 1));
|
||||
}
|
||||
|
||||
/* Returns non-zero if the proxy is configured to retry a request if we got that status, 0 otherwise */
|
||||
|
@ -107,11 +107,11 @@ struct quic_cc_path {
|
||||
/* Congestion window. */
|
||||
uint64_t cwnd;
|
||||
/* The current maximum congestion window value reached. */
|
||||
uint64_t cwnd_last_max;
|
||||
/* Max limit on congestion window size. */
|
||||
uint64_t limit_max;
|
||||
/* Min limit on congestion window size. */
|
||||
uint64_t limit_min;
|
||||
uint64_t mcwnd;
|
||||
/* The maximum congestion window value which can be reached. */
|
||||
uint64_t max_cwnd;
|
||||
/* Minimum congestion window. */
|
||||
uint64_t min_cwnd;
|
||||
/* Prepared data to be sent (in bytes). */
|
||||
uint64_t prep_in_flight;
|
||||
/* Outstanding data (in bytes). */
|
||||
|
@ -29,11 +29,9 @@
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/buf.h>
|
||||
#include <haproxy/chunk.h>
|
||||
#include <haproxy/proto_quic.h>
|
||||
#include <haproxy/quic_cc-t.h>
|
||||
#include <haproxy/quic_conn-t.h>
|
||||
#include <haproxy/quic_loss.h>
|
||||
#include <haproxy/thread.h>
|
||||
|
||||
void quic_cc_init(struct quic_cc *cc, struct quic_cc_algo *algo, struct quic_conn *qc);
|
||||
void quic_cc_event(struct quic_cc *cc, struct quic_cc_event *ev);
|
||||
@ -93,10 +91,9 @@ static inline void quic_cc_path_init(struct quic_cc_path *path, int ipv4, unsign
|
||||
*(size_t *)&path->mtu = max_dgram_sz;
|
||||
path->initial_wnd = QUIC_MIN(10 * max_dgram_sz, QUIC_MAX(max_dgram_sz << 1, 14720U));
|
||||
path->cwnd = path->initial_wnd;
|
||||
cshared_add(&quic_mem_diff, path->cwnd);
|
||||
path->cwnd_last_max = path->cwnd;
|
||||
path->limit_max = max_cwnd;
|
||||
path->limit_min = max_dgram_sz << 1;
|
||||
path->mcwnd = path->cwnd;
|
||||
path->max_cwnd = max_cwnd;
|
||||
path->min_cwnd = max_dgram_sz << 1;
|
||||
path->prep_in_flight = 0;
|
||||
path->in_flight = 0;
|
||||
path->ifae_pkts = 0;
|
||||
@ -118,9 +115,7 @@ static inline size_t quic_cc_path_prep_data(struct quic_cc_path *path)
|
||||
return path->cwnd - path->prep_in_flight;
|
||||
}
|
||||
|
||||
void quic_cc_path_reset(struct quic_cc_path *path);
|
||||
void quic_cc_path_set(struct quic_cc_path *path, uint64_t val);
|
||||
void quic_cc_path_inc(struct quic_cc_path *path, uint64_t val);
|
||||
int quic_cwnd_may_increase(const struct quic_cc_path *path);
|
||||
|
||||
#endif /* USE_QUIC */
|
||||
#endif /* _PROTO_QUIC_CC_H */
|
||||
|
@ -28,22 +28,22 @@
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <import/ebtree-t.h>
|
||||
#include <haproxy/cbuf-t.h>
|
||||
#include <haproxy/list.h>
|
||||
#include <haproxy/show_flags-t.h>
|
||||
|
||||
#include <haproxy/api-t.h>
|
||||
#include <haproxy/buf-t.h>
|
||||
#include <haproxy/listener-t.h>
|
||||
#include <haproxy/openssl-compat.h>
|
||||
#include <haproxy/mux_quic-t.h>
|
||||
#include <haproxy/quic_cid-t.h>
|
||||
#include <haproxy/quic_cc-t.h>
|
||||
#include <haproxy/quic_frame-t.h>
|
||||
#include <haproxy/quic_loss-t.h>
|
||||
#include <haproxy/quic_openssl_compat-t.h>
|
||||
#include <haproxy/quic_stats-t.h>
|
||||
#include <haproxy/quic_tls-t.h>
|
||||
#include <haproxy/quic_tp-t.h>
|
||||
#include <haproxy/show_flags-t.h>
|
||||
#include <haproxy/ssl_sock-t.h>
|
||||
#include <haproxy/task-t.h>
|
||||
#include <haproxy/task.h>
|
||||
|
||||
#include <import/ebtree-t.h>
|
||||
|
||||
typedef unsigned long long ull;
|
||||
|
||||
@ -228,9 +228,6 @@ struct quic_version {
|
||||
extern const struct quic_version quic_versions[];
|
||||
extern const size_t quic_versions_nb;
|
||||
extern const struct quic_version *preferred_version;
|
||||
extern const struct quic_version *quic_version_draft_29;
|
||||
extern const struct quic_version *quic_version_1;
|
||||
extern const struct quic_version *quic_version_2;
|
||||
|
||||
/* unused: 0x01 */
|
||||
/* Flag the packet number space as requiring an ACK frame to be sent. */
|
||||
@ -282,10 +279,6 @@ struct quic_conn_cntrs {
|
||||
long long streams_blocked_uni; /* total number of times STREAMS_BLOCKED_UNI frame was received */
|
||||
};
|
||||
|
||||
struct connection;
|
||||
struct qcc;
|
||||
struct qcc_app_ops;
|
||||
|
||||
#define QUIC_CONN_COMMON \
|
||||
struct { \
|
||||
/* Connection owned socket FD. */ \
|
||||
@ -308,7 +301,6 @@ struct qcc_app_ops;
|
||||
/* Number of received bytes. */ \
|
||||
uint64_t rx; \
|
||||
} bytes; \
|
||||
size_t max_udp_payload; \
|
||||
/* First DCID used by client on its Initial packet. */ \
|
||||
struct quic_cid odcid; \
|
||||
/* DCID of our endpoint - not updated when a new DCID is used */ \
|
||||
@ -319,7 +311,7 @@ struct qcc_app_ops;
|
||||
* with a connection \
|
||||
*/ \
|
||||
struct eb_root *cids; \
|
||||
enum obj_type *target; \
|
||||
struct listener *li; /* only valid for frontend connections */ \
|
||||
/* Idle timer task */ \
|
||||
struct task *idle_timer_task; \
|
||||
unsigned int idle_expire; \
|
||||
@ -342,10 +334,7 @@ struct quic_conn {
|
||||
int tps_tls_ext;
|
||||
int state;
|
||||
enum qc_mux_state mux_state; /* status of the connection/mux layer */
|
||||
#ifdef HAVE_OPENSSL_QUIC
|
||||
uint32_t prot_level;
|
||||
#endif
|
||||
#if defined(USE_QUIC_OPENSSL_COMPAT) || defined(HAVE_OPENSSL_QUIC)
|
||||
#ifdef USE_QUIC_OPENSSL_COMPAT
|
||||
unsigned char enc_params[QUIC_TP_MAX_ENCLEN]; /* encoded QUIC transport parameters */
|
||||
size_t enc_params_len;
|
||||
#endif
|
||||
@ -394,10 +383,10 @@ struct quic_conn {
|
||||
/* RX buffer */
|
||||
struct buffer buf;
|
||||
struct list pkt_list;
|
||||
|
||||
/* first unhandled streams ID, set by MUX after release */
|
||||
uint64_t stream_max_uni;
|
||||
uint64_t stream_max_bidi;
|
||||
struct {
|
||||
/* Number of open or closed streams */
|
||||
uint64_t nb_streams;
|
||||
} strms[QCS_MAX_TYPES];
|
||||
} rx;
|
||||
struct {
|
||||
struct quic_tls_kp prv_rx;
|
||||
@ -460,7 +449,6 @@ struct quic_conn_closed {
|
||||
#define QUIC_FL_CONN_HPKTNS_DCD (1U << 16) /* Handshake packet number space discarded */
|
||||
#define QUIC_FL_CONN_PEER_VALIDATED_ADDR (1U << 17) /* Peer address is considered as validated for this connection. */
|
||||
#define QUIC_FL_CONN_NO_TOKEN_RCVD (1U << 18) /* Client dit not send any token */
|
||||
#define QUIC_FL_CONN_SCID_RECEIVED (1U << 19) /* (client only: first Initial received. */
|
||||
/* gap here */
|
||||
#define QUIC_FL_CONN_TO_KILL (1U << 24) /* Unusable connection, to be killed */
|
||||
#define QUIC_FL_CONN_TX_TP_RECEIVED (1U << 25) /* Peer transport parameters have been received (used for the transmitting part) */
|
||||
|
@ -69,8 +69,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
struct quic_connection_id *conn_id,
|
||||
struct sockaddr_storage *local_addr,
|
||||
struct sockaddr_storage *peer_addr,
|
||||
int token, void *owner,
|
||||
struct connection *conn);
|
||||
int server, int token, void *owner);
|
||||
int quic_build_post_handshake_frames(struct quic_conn *qc);
|
||||
const struct quic_version *qc_supported_version(uint32_t version);
|
||||
int quic_peer_validated_addr(struct quic_conn *qc);
|
||||
@ -164,22 +163,6 @@ static inline void quic_free_ncbuf(struct ncbuf *ncbuf)
|
||||
*ncbuf = NCBUF_NULL;
|
||||
}
|
||||
|
||||
/* Return the address of the QUIC counters attached to the proxy of
|
||||
* the owner of the connection whose object type address is <o> for
|
||||
* listener and servers, or NULL for others object type.
|
||||
*/
|
||||
static inline void *qc_counters(enum obj_type *o, const struct stats_module *m)
|
||||
{
|
||||
struct proxy *p;
|
||||
struct listener *l = objt_listener(o);
|
||||
struct server *s = objt_server(o);
|
||||
|
||||
p = l ? l->bind_conf->frontend :
|
||||
s ? s->proxy : NULL;
|
||||
|
||||
return p ? EXTRA_COUNTERS_GET(p->extra_counters_fe, m) : NULL;
|
||||
}
|
||||
|
||||
void chunk_frm_appendf(struct buffer *buf, const struct quic_frame *frm);
|
||||
void quic_set_connection_close(struct quic_conn *qc, const struct quic_err err);
|
||||
void quic_set_tls_alert(struct quic_conn *qc, int alert);
|
||||
@ -191,7 +174,7 @@ int qc_notify_send(struct quic_conn *qc);
|
||||
|
||||
void qc_check_close_on_released_mux(struct quic_conn *qc);
|
||||
|
||||
int quic_conn_release(struct quic_conn *qc);
|
||||
void quic_conn_release(struct quic_conn *qc);
|
||||
|
||||
void qc_kill_conn(struct quic_conn *qc);
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <haproxy/quic_rx-t.h>
|
||||
|
||||
int quic_dgram_parse(struct quic_dgram *dgram, struct quic_conn *from_qc,
|
||||
enum obj_type *obj_type);
|
||||
struct listener *li);
|
||||
int qc_treat_rx_pkts(struct quic_conn *qc);
|
||||
int qc_parse_hd_form(struct quic_rx_packet *pkt,
|
||||
unsigned char **pos, const unsigned char *end);
|
||||
|
@ -31,9 +31,7 @@
|
||||
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/connection-t.h>
|
||||
#include <haproxy/fd-t.h>
|
||||
#include <haproxy/listener-t.h>
|
||||
#include <haproxy/obj_type.h>
|
||||
#include <haproxy/quic_conn-t.h>
|
||||
#include <haproxy/quic_sock-t.h>
|
||||
|
||||
@ -79,8 +77,7 @@ static inline char qc_test_fd(struct quic_conn *qc)
|
||||
*/
|
||||
static inline int qc_fd(struct quic_conn *qc)
|
||||
{
|
||||
/* TODO: check this: For backends, qc->fd is always initialized */
|
||||
return qc_test_fd(qc) ? qc->fd : __objt_listener(qc->target)->rx.fd;
|
||||
return qc_test_fd(qc) ? qc->fd : qc->li->rx.fd;
|
||||
}
|
||||
|
||||
/* Try to increment <l> handshake current counter. If listener limit is
|
||||
|
@ -34,10 +34,8 @@
|
||||
#include <haproxy/ssl_sock-t.h>
|
||||
|
||||
int ssl_quic_initial_ctx(struct bind_conf *bind_conf);
|
||||
SSL_CTX *ssl_quic_srv_new_ssl_ctx(void);
|
||||
int qc_alloc_ssl_sock_ctx(struct quic_conn *qc, struct connection *conn);
|
||||
int qc_alloc_ssl_sock_ctx(struct quic_conn *qc);
|
||||
int qc_ssl_provide_all_quic_data(struct quic_conn *qc, struct ssl_sock_ctx *ctx);
|
||||
int quic_ssl_set_tls_cbs(SSL *ssl);
|
||||
|
||||
static inline void qc_free_ssl_sock_ctx(struct ssl_sock_ctx **ctx)
|
||||
{
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include <haproxy/buf-t.h>
|
||||
#include <haproxy/list-t.h>
|
||||
#include <haproxy/quic_utils-t.h>
|
||||
|
||||
/* A QUIC STREAM buffer used for Tx.
|
||||
*
|
||||
@ -44,8 +43,6 @@ struct qc_stream_desc {
|
||||
|
||||
uint64_t ack_offset; /* last acknowledged offset */
|
||||
struct eb_root buf_tree; /* list of active and released buffers */
|
||||
struct bdata_ctr data; /* data utilization counter */
|
||||
ullong origin_ts; /* timestamp for creation date of current stream instance */
|
||||
|
||||
int flags; /* QC_SD_FL_* values */
|
||||
|
||||
|
@ -291,29 +291,6 @@ static inline struct quic_enc_level **ssl_to_qel_addr(struct quic_conn *qc,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_QUIC
|
||||
/* Simple helper function which translate an OpenSSL SSL protection level
|
||||
* to a quictls SSL encryption. This way the code which use the OpenSSL QUIC API
|
||||
* may use the code which uses the quictls API.
|
||||
*/
|
||||
static inline enum ssl_encryption_level_t ssl_prot_level_to_enc_level(struct quic_conn *qc,
|
||||
uint32_t prot_level)
|
||||
{
|
||||
switch (prot_level) {
|
||||
case OSSL_RECORD_PROTECTION_LEVEL_NONE:
|
||||
return ssl_encryption_initial;
|
||||
case OSSL_RECORD_PROTECTION_LEVEL_EARLY:
|
||||
return ssl_encryption_early_data;
|
||||
case OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE:
|
||||
return ssl_encryption_handshake;
|
||||
case OSSL_RECORD_PROTECTION_LEVEL_APPLICATION:
|
||||
return ssl_encryption_application;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return the address of the QUIC TLS encryption level associated to <level> internal
|
||||
* encryption level and attached to <qc> QUIC connection if succeeded, or
|
||||
* NULL if failed.
|
||||
|
@ -115,12 +115,5 @@ struct quic_transport_params {
|
||||
struct tp_version_information version_information;
|
||||
};
|
||||
|
||||
/* Return type for QUIC TP decode function */
|
||||
enum quic_tp_dec_err {
|
||||
QUIC_TP_DEC_ERR_NONE = 0, /* no error */
|
||||
QUIC_TP_DEC_ERR_INVAL, /* invalid value as per RFC 9000 */
|
||||
QUIC_TP_DEC_ERR_TRUNC, /* field encoding too small or too large */
|
||||
};
|
||||
|
||||
#endif /* USE_QUIC */
|
||||
#endif /* _HAPROXY_QUIC_TP_T_H */
|
||||
|
@ -26,9 +26,6 @@ int qc_lstnr_params_init(struct quic_conn *qc,
|
||||
const unsigned char *dcid, size_t dcidlen,
|
||||
const unsigned char *scid, size_t scidlen,
|
||||
const struct quic_cid *token_odcid);
|
||||
void qc_srv_params_init(struct quic_conn *qc,
|
||||
const struct quic_transport_params *srv_params,
|
||||
const unsigned char *scid, size_t scidlen);
|
||||
|
||||
/* Dump <cid> transport parameter connection ID value if present (non null length).
|
||||
* Used only for debugging purposes.
|
||||
|
@ -99,6 +99,5 @@ struct quic_rx_crypto_frm {
|
||||
#define QUIC_EV_CONN_KP (1ULL << 50)
|
||||
#define QUIC_EV_CONN_SSL_COMPAT (1ULL << 51)
|
||||
#define QUIC_EV_CONN_BIND_TID (1ULL << 52)
|
||||
#define QUIC_EV_CONN_RELEASE_RCD (1ULL << 53)
|
||||
|
||||
#endif /* _HAPROXY_QUIC_TRACE_T_H */
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
#include <haproxy/buf-t.h>
|
||||
#include <haproxy/list-t.h>
|
||||
#include <haproxy/pool.h>
|
||||
#include <haproxy/quic_conn-t.h>
|
||||
#include <haproxy/quic_tls-t.h>
|
||||
#include <haproxy/quic_pacing-t.h>
|
||||
|
@ -1,17 +0,0 @@
|
||||
#ifndef _HAPROXY_QUIC_UTILS_T_H
|
||||
#define _HAPROXY_QUIC_UTILS_T_H
|
||||
|
||||
#ifdef USE_QUIC
|
||||
|
||||
#include <haproxy/api-t.h>
|
||||
|
||||
/* Counter which can be used to measure data amount accross several buffers. */
|
||||
struct bdata_ctr {
|
||||
uint64_t tot; /* sum of data present in all underlying buffers */
|
||||
uint8_t bcnt; /* current number of allocated underlying buffers */
|
||||
uint8_t bmax; /* max number of allocated buffers during stream lifetime */
|
||||
};
|
||||
|
||||
#endif /* USE_QUIC */
|
||||
|
||||
#endif /* _HAPROXY_QUIC_UTILS_T_H */
|
@ -1,59 +0,0 @@
|
||||
#ifndef _HAPROXY_QUIC_UTILS_H
|
||||
#define _HAPROXY_QUIC_UTILS_H
|
||||
|
||||
#ifdef USE_QUIC
|
||||
|
||||
#include <haproxy/quic_utils-t.h>
|
||||
|
||||
#include <haproxy/buf-t.h>
|
||||
#include <haproxy/chunk.h>
|
||||
|
||||
static inline int quic_stream_is_uni(uint64_t id)
|
||||
{
|
||||
return id & QCS_ID_DIR_BIT;
|
||||
}
|
||||
|
||||
static inline int quic_stream_is_bidi(uint64_t id)
|
||||
{
|
||||
return !quic_stream_is_uni(id);
|
||||
}
|
||||
|
||||
static inline void bdata_ctr_init(struct bdata_ctr *ctr)
|
||||
{
|
||||
ctr->tot = 0;
|
||||
ctr->bcnt = 0;
|
||||
ctr->bmax = 0;
|
||||
}
|
||||
|
||||
static inline void bdata_ctr_binc(struct bdata_ctr *ctr)
|
||||
{
|
||||
++ctr->bcnt;
|
||||
ctr->bmax = MAX(ctr->bcnt, ctr->bmax);
|
||||
}
|
||||
|
||||
static inline void bdata_ctr_bdec(struct bdata_ctr *ctr)
|
||||
{
|
||||
--ctr->bcnt;
|
||||
}
|
||||
|
||||
static inline void bdata_ctr_add(struct bdata_ctr *ctr, size_t data)
|
||||
{
|
||||
ctr->tot += data;
|
||||
}
|
||||
|
||||
static inline void bdata_ctr_del(struct bdata_ctr *ctr, size_t data)
|
||||
{
|
||||
ctr->tot -= data;
|
||||
}
|
||||
|
||||
static inline void bdata_ctr_print(struct buffer *chunk,
|
||||
const struct bdata_ctr *ctr,
|
||||
const char *prefix)
|
||||
{
|
||||
chunk_appendf(chunk, " %s%d(%d)/%llu",
|
||||
prefix, ctr->bcnt, ctr->bmax, (ullong)ctr->tot);
|
||||
}
|
||||
|
||||
#endif /* USE_QUIC */
|
||||
|
||||
#endif /* _HAPROXY_QUIC_UTILS_H */
|
@ -92,15 +92,6 @@ extern struct pool_head *resolv_requester_pool;
|
||||
*/
|
||||
#define SRV_MAX_PREF_NET 5
|
||||
|
||||
/* bits describing process-wide acceptable address families for DNS responses */
|
||||
enum {
|
||||
RSLV_ACCEPT_IPV4 = 0x01,
|
||||
RSLV_ACCEPT_IPV6 = 0x02,
|
||||
RSLV_ACCEPT_MASK = RSLV_ACCEPT_IPV4 | RSLV_ACCEPT_IPV6,
|
||||
RSLV_FORCED_FAMILY = 0x04,
|
||||
RSLV_AUTO_FAMILY = 0x08,
|
||||
};
|
||||
|
||||
/* NOTE: big endian structure */
|
||||
struct resolv_query_item {
|
||||
char name[DNS_MAX_NAME_SIZE+1]; /* query name */
|
||||
|
@ -32,7 +32,6 @@ struct list;
|
||||
|
||||
extern struct list sec_resolvers;
|
||||
extern unsigned int resolv_failed_resolutions;
|
||||
extern uint resolv_accept_families;
|
||||
|
||||
struct resolvers *find_resolvers_by_id(const char *id);
|
||||
struct dns_nameserver *find_nameserver_by_resolvers_and_id(struct resolvers *parent, unsigned int id);
|
||||
|
@ -171,7 +171,6 @@ enum srv_init_state {
|
||||
#define SRV_F_DEFSRV_USE_SSL 0x4000 /* default-server uses SSL */
|
||||
#define SRV_F_DELETED 0x8000 /* srv is deleted but not yet purged */
|
||||
#define SRV_F_STRICT_MAXCONN 0x10000 /* maxconn is to be strictly enforced, as a limit of outbound connections */
|
||||
#define SRV_F_CHECKED 0x20000 /* set once server was postparsed */
|
||||
|
||||
/* configured server options for send-proxy (server->pp_opts) */
|
||||
#define SRV_PP_V1 0x0001 /* proxy protocol version 1 */
|
||||
@ -478,9 +477,6 @@ struct server {
|
||||
char *alpn_str; /* ALPN protocol string */
|
||||
int alpn_len; /* ALPN protocol string length */
|
||||
} ssl_ctx;
|
||||
#ifdef USE_QUIC
|
||||
struct quic_transport_params quic_params; /* QUIC transport parameters */
|
||||
#endif
|
||||
struct resolv_srvrq *srvrq; /* Pointer representing the DNS SRV requeest, if any */
|
||||
struct list srv_rec_item; /* to attach server to a srv record item */
|
||||
struct list ip_rec_item; /* to attach server to a A or AAAA record item */
|
||||
|
@ -73,7 +73,7 @@ struct server *new_server(struct proxy *proxy);
|
||||
void srv_take(struct server *srv);
|
||||
struct server *srv_drop(struct server *srv);
|
||||
void srv_free_params(struct server *srv);
|
||||
int srv_init(struct server *srv);
|
||||
int srv_init_per_thr(struct server *srv);
|
||||
void srv_set_ssl(struct server *s, int use_ssl);
|
||||
const char *srv_adm_st_chg_cause(enum srv_adm_st_chg_cause cause);
|
||||
const char *srv_op_st_chg_cause(enum srv_op_st_chg_cause cause);
|
||||
@ -181,16 +181,15 @@ const struct mux_ops *srv_get_ws_proto(struct server *srv);
|
||||
/* increase the number of cumulated streams on the designated server */
|
||||
static inline void srv_inc_sess_ctr(struct server *s)
|
||||
{
|
||||
_HA_ATOMIC_INC(&s->counters.shared->tg[tgid - 1]->cum_sess);
|
||||
update_freq_ctr(&s->counters.shared->tg[tgid - 1]->sess_per_sec, 1);
|
||||
_HA_ATOMIC_INC(&s->counters.cum_sess);
|
||||
HA_ATOMIC_UPDATE_MAX(&s->counters.sps_max,
|
||||
update_freq_ctr(&s->counters._sess_per_sec, 1));
|
||||
update_freq_ctr(&s->counters.sess_per_sec, 1));
|
||||
}
|
||||
|
||||
/* set the time of last session on the designated server */
|
||||
static inline void srv_set_sess_last(struct server *s)
|
||||
{
|
||||
HA_ATOMIC_STORE(&s->counters.shared->tg[tgid - 1]->last_sess, ns_to_sec(now_ns));
|
||||
s->counters.last_sess = ns_to_sec(now_ns);
|
||||
}
|
||||
|
||||
/* returns the current server throttle rate between 0 and 100% */
|
||||
@ -320,39 +319,6 @@ static inline int srv_is_transparent(const struct server *srv)
|
||||
(srv->flags & SRV_F_MAPPORTS);
|
||||
}
|
||||
|
||||
/* Detach server from proxy list. It is supported to call this
|
||||
* even if the server is not yet in the list
|
||||
* Must be called under thread isolation or when it is safe to assume
|
||||
* that the parent proxy doesn't is not skimming through the server list
|
||||
*/
|
||||
static inline void srv_detach(struct server *srv)
|
||||
{
|
||||
struct proxy *px = srv->proxy;
|
||||
|
||||
if (px->srv == srv)
|
||||
px->srv = srv->next;
|
||||
else {
|
||||
struct server *prev;
|
||||
|
||||
for (prev = px->srv; prev && prev->next != srv; prev = prev->next)
|
||||
;
|
||||
|
||||
BUG_ON(!prev);
|
||||
|
||||
prev->next = srv->next;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int srv_is_quic(const struct server *srv)
|
||||
{
|
||||
#ifdef USE_QUIC
|
||||
return srv->addr_type.proto_type == PROTO_TYPE_DGRAM &&
|
||||
srv->addr_type.xprt_type == PROTO_TYPE_STREAM;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* _HAPROXY_SERVER_H */
|
||||
|
||||
/*
|
||||
|
@ -28,11 +28,9 @@
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/connection-t.h>
|
||||
#include <haproxy/listener-t.h>
|
||||
#include <haproxy/protocol-t.h>
|
||||
#include <haproxy/sock-t.h>
|
||||
|
||||
int sock_create_server_socket(struct connection *conn, struct proxy *be,
|
||||
enum proto_type proto_type, int sock_type, int *stream_err);
|
||||
int sock_create_server_socket(struct connection *conn, struct proxy *be, int *stream_err);
|
||||
void sock_enable(struct receiver *rx);
|
||||
void sock_disable(struct receiver *rx);
|
||||
void sock_unbind(struct receiver *rx);
|
||||
|
@ -30,8 +30,6 @@
|
||||
extern int sock_inet6_v6only_default;
|
||||
extern int sock_inet_tcp_maxseg_default;
|
||||
extern int sock_inet6_tcp_maxseg_default;
|
||||
extern int sock_inet6_seems_reachable;
|
||||
extern uint last_inet6_check;
|
||||
|
||||
#ifdef HA_HAVE_MPTCP
|
||||
extern int sock_inet_mptcp_maxseg_default;
|
||||
@ -55,6 +53,5 @@ int sock_inet_is_foreign(int fd, sa_family_t family);
|
||||
int sock_inet4_make_foreign(int fd);
|
||||
int sock_inet6_make_foreign(int fd);
|
||||
int sock_inet_bind_receiver(struct receiver *rx, char **errmsg);
|
||||
int is_inet6_reachable(void);
|
||||
|
||||
#endif /* _HAPROXY_SOCK_INET_H */
|
||||
|
@ -62,7 +62,7 @@ struct ckch_inst *ckch_inst_new();
|
||||
int ckch_inst_new_load_store(const char *path, struct ckch_store *ckchs, struct bind_conf *bind_conf,
|
||||
struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount, int is_default, struct ckch_inst **ckchi, char **err);
|
||||
int ckch_inst_new_load_srv_store(const char *path, struct ckch_store *ckchs,
|
||||
struct ckch_inst **ckchi, char **err, int is_quic);
|
||||
struct ckch_inst **ckchi, char **err);
|
||||
int ckch_inst_rebuild(struct ckch_store *ckch_store, struct ckch_inst *ckchi,
|
||||
struct ckch_inst **new_inst, char **err);
|
||||
|
||||
|
@ -316,10 +316,6 @@ struct global_ssl {
|
||||
int disable;
|
||||
} ocsp_update;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ACME
|
||||
int acme_scheduler;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* The order here matters for picking a default context,
|
||||
|
@ -117,8 +117,8 @@ int ssl_sock_switchctx_wolfSSL_cbk(WOLFSSL* ssl, void* arg);
|
||||
|
||||
int increment_sslconn();
|
||||
void ssl_sock_load_cert_sni(struct ckch_inst *ckch_inst, struct bind_conf *bind_conf);
|
||||
struct sni_ctx *ssl_sock_chose_sni_ctx(struct bind_conf *s, struct connection *conn,
|
||||
const char *servername, int have_rsa_sig, int have_ecdsa_sig);
|
||||
struct sni_ctx *ssl_sock_chose_sni_ctx(struct bind_conf *s, const char *servername,
|
||||
int have_rsa_sig, int have_ecdsa_sig);
|
||||
#ifdef SSL_MODE_ASYNC
|
||||
void ssl_async_fd_handler(int fd);
|
||||
void ssl_async_fd_free(int fd);
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* include/haproxy/ssl_trace-t.h
|
||||
* Definitions for SSL traces internal types, constants and flags.
|
||||
*
|
||||
* Copyright (C) 2025
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _HAPROXY_SSL_TRACE_T_H
|
||||
#define _HAPROXY_SSL_TRACE_T_H
|
||||
|
||||
#include <haproxy/trace-t.h>
|
||||
|
||||
extern struct trace_source trace_ssl;
|
||||
|
||||
#define SSL_EV_CONN_NEW (1ULL << 0)
|
||||
#define SSL_EV_CONN_CLOSE (1ULL << 1)
|
||||
#define SSL_EV_CONN_END (1ULL << 2)
|
||||
#define SSL_EV_CONN_ERR (1ULL << 3)
|
||||
#define SSL_EV_CONN_SEND (1ULL << 4)
|
||||
#define SSL_EV_CONN_SEND_EARLY (1ULL << 5)
|
||||
#define SSL_EV_CONN_RECV (1ULL << 6)
|
||||
#define SSL_EV_CONN_RECV_EARLY (1ULL << 7)
|
||||
#define SSL_EV_CONN_IO_CB (1ULL << 8)
|
||||
#define SSL_EV_CONN_HNDSHK (1ULL << 9)
|
||||
#define SSL_EV_CONN_VFY_CB (1ULL << 10)
|
||||
#define SSL_EV_CONN_STAPLING (1ULL << 11)
|
||||
#define SSL_EV_CONN_SWITCHCTX_CB (1ULL << 12)
|
||||
#define SSL_EV_CONN_CHOOSE_SNI_CTX (1ULL << 13)
|
||||
#define SSL_EV_CONN_SIGALG_EXT (1ULL << 14)
|
||||
|
||||
#define TRACE_SOURCE &trace_ssl
|
||||
|
||||
#endif /* _HAPROXY_SSL_TRACE_T_H */
|
@ -50,11 +50,9 @@ const char *x509_get_notafter(X509 *cert);
|
||||
#ifdef HAVE_ASN1_TIME_TO_TM
|
||||
time_t ASN1_to_time_t(ASN1_TIME *asn1_time);
|
||||
time_t x509_get_notafter_time_t(X509 *cert);
|
||||
time_t x509_get_notbefore_time_t(X509 *cert);
|
||||
#endif
|
||||
int curves2nid(const char *curve);
|
||||
const char *nid2nist(int nid);
|
||||
const char *sigalg2str(int sigalg);
|
||||
|
||||
#endif /* _HAPROXY_SSL_UTILS_H */
|
||||
#endif /* USE_OPENSSL */
|
||||
|
@ -342,11 +342,6 @@ enum stat_idx_info {
|
||||
ST_I_INF_MAX
|
||||
};
|
||||
|
||||
/* Flags for stat_col.flags */
|
||||
#define STAT_COL_FL_NONE 0x00
|
||||
#define STAT_COL_FL_GENERIC 0x01 /* stat is generic if set */
|
||||
#define STAT_COL_FL_SHARED 0x02 /* stat may be shared between co-processes if set */
|
||||
|
||||
/* Represent an exposed statistic. */
|
||||
struct stat_col {
|
||||
const char *name; /* short name, used notably in CSV headers */
|
||||
@ -355,8 +350,8 @@ struct stat_col {
|
||||
|
||||
uint32_t type; /* combination of field_nature and field_format */
|
||||
uint8_t cap; /* mask of stats_domain_px_cap to restrain metrics to an object types subset */
|
||||
/* 1 byte hole */
|
||||
uint16_t flags; /* STAT_COL_FL_* flags */
|
||||
uint8_t generic; /* bit set if generic */
|
||||
/* 2 bytes hole */
|
||||
|
||||
/* used only for generic metrics */
|
||||
struct {
|
||||
|
@ -79,7 +79,7 @@ int stats_emit_field_tags(struct buffer *out, const struct field *f,
|
||||
/* Returns true if <col> is fully defined, false if only used as name-desc. */
|
||||
static inline int stcol_is_generic(const struct stat_col *col)
|
||||
{
|
||||
return col->flags & STAT_COL_FL_GENERIC;
|
||||
return col->generic;
|
||||
}
|
||||
|
||||
static inline enum field_format stcol_format(const struct stat_col *col)
|
||||
|
@ -206,7 +206,6 @@ enum sc_flags {
|
||||
|
||||
SC_FL_EOS = 0x00040000, /* End of stream was reached (from down side to up side) */
|
||||
SC_FL_HAVE_BUFF = 0x00080000, /* A buffer is ready, flag will be cleared once allocated */
|
||||
SC_FL_NO_FASTFWD = 0x00100000, /* disable data fast-forwarding */
|
||||
};
|
||||
|
||||
/* This function is used to report flags in debugging tools. Please reflect
|
||||
|
@ -151,8 +151,6 @@ struct stksess {
|
||||
int seen; /* 0 only when no peer has seen this entry yet */
|
||||
struct eb32_node exp; /* ebtree node used to hold the session in expiration tree */
|
||||
struct eb32_node upd; /* ebtree node used to hold the update sequence tree */
|
||||
struct mt_list pend_updts;/* list of entries to be inserted/moved in the update sequence tree */
|
||||
int updt_is_local; /* is the update a local one ? */
|
||||
struct ebmb_node key; /* ebtree node used to hold the session in table */
|
||||
/* WARNING! do not put anything after <keys>, it's used by the key */
|
||||
};
|
||||
@ -222,11 +220,9 @@ struct stktable {
|
||||
THREAD_ALIGN(64);
|
||||
|
||||
struct eb_root updates; /* head of sticky updates sequence tree, uses updt_lock */
|
||||
struct mt_list *pend_updts; /* list of updates to be added to the update sequence tree, one per thread-group */
|
||||
unsigned int update; /* uses updt_lock */
|
||||
unsigned int localupdate; /* uses updt_lock */
|
||||
unsigned int commitupdate;/* used to identify the latest local updates pending for sync, uses updt_lock */
|
||||
struct tasklet *updt_task;/* tasklet responsable for pushing the pending updates into the tree */
|
||||
|
||||
THREAD_ALIGN(64);
|
||||
/* this lock is heavily used and must be on its own cache line */
|
||||
|
@ -362,8 +362,8 @@ static inline void stream_choose_redispatch(struct stream *s)
|
||||
s->scb->state = SC_ST_REQ;
|
||||
} else {
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->tg[tgid - 1]->retries);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->retries);
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.retries);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.retries);
|
||||
s->scb->state = SC_ST_ASS;
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
/* unused 0x00000008 */
|
||||
#define TASK_SELF_WAKING 0x00000010 /* task/tasklet found waking itself */
|
||||
#define TASK_KILLED 0x00000020 /* task/tasklet killed, may now be freed */
|
||||
#define TASK_IN_LIST 0x00000040 /* tasklet is in a tasklet list */
|
||||
#define TASK_HEAVY 0x00000080 /* this task/tasklet is extremely heavy */
|
||||
|
||||
#define TASK_WOKEN_INIT 0x00000100 /* woken up for initialisation purposes */
|
||||
@ -79,10 +80,10 @@ static forceinline char *task_show_state(char *buf, size_t len, const char *deli
|
||||
_(0);
|
||||
/* flags */
|
||||
_(TASK_RUNNING, _(TASK_QUEUED, _(TASK_SELF_WAKING,
|
||||
_(TASK_KILLED, _(TASK_HEAVY, _(TASK_WOKEN_INIT,
|
||||
_(TASK_KILLED, _(TASK_IN_LIST, _(TASK_HEAVY, _(TASK_WOKEN_INIT,
|
||||
_(TASK_WOKEN_TIMER, _(TASK_WOKEN_IO, _(TASK_WOKEN_SIGNAL,
|
||||
_(TASK_WOKEN_MSG, _(TASK_WOKEN_RES, _(TASK_WOKEN_OTHER,
|
||||
_(TASK_F_TASKLET, _(TASK_F_USR1))))))))))))));
|
||||
_(TASK_F_TASKLET, _(TASK_F_USR1)))))))))))))));
|
||||
/* epilogue */
|
||||
_(~0U);
|
||||
return buf;
|
||||
|
@ -394,9 +394,9 @@ static inline void _tasklet_wakeup_on(struct tasklet *tl, int thr, uint f, const
|
||||
|
||||
do {
|
||||
/* do nothing if someone else already added it */
|
||||
if (state & TASK_QUEUED)
|
||||
if (state & TASK_IN_LIST)
|
||||
return;
|
||||
} while (!_HA_ATOMIC_CAS(&tl->state, &state, state | TASK_QUEUED));
|
||||
} while (!_HA_ATOMIC_CAS(&tl->state, &state, state | TASK_IN_LIST));
|
||||
|
||||
/* at this point we're the first ones to add this task to the list */
|
||||
if (likely(caller)) {
|
||||
@ -501,9 +501,9 @@ static inline struct list *_tasklet_wakeup_after(struct list *head, struct taskl
|
||||
|
||||
do {
|
||||
/* do nothing if someone else already added it */
|
||||
if (state & TASK_QUEUED)
|
||||
if (state & TASK_IN_LIST)
|
||||
return head;
|
||||
} while (!_HA_ATOMIC_CAS(&tl->state, &state, state | TASK_QUEUED));
|
||||
} while (!_HA_ATOMIC_CAS(&tl->state, &state, state | TASK_IN_LIST));
|
||||
|
||||
/* at this point we're the first one to add this task to the list */
|
||||
if (likely(caller)) {
|
||||
@ -534,6 +534,21 @@ static inline struct list *_tasklet_wakeup_after(struct list *head, struct taskl
|
||||
#define DEBUG_TASK_PRINT_CALLER(t) do { } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/* Try to remove a tasklet from the list. This call is inherently racy and may
|
||||
* only be performed on the thread that was supposed to dequeue this tasklet.
|
||||
* This way it is safe to call MT_LIST_DELETE without first removing the
|
||||
* TASK_IN_LIST bit, which must absolutely be removed afterwards in case
|
||||
* another thread would want to wake this tasklet up in parallel.
|
||||
*/
|
||||
static inline void tasklet_remove_from_tasklet_list(struct tasklet *t)
|
||||
{
|
||||
if (MT_LIST_DELETE(list_to_mt_list(&t->list))) {
|
||||
_HA_ATOMIC_AND(&t->state, ~TASK_IN_LIST);
|
||||
_HA_ATOMIC_DEC(&ha_thread_ctx[t->tid >= 0 ? t->tid : tid].rq_total);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a new task. The bare minimum is performed (queue pointers and
|
||||
* state). The task is returned. This function should not be used outside of
|
||||
|
@ -41,7 +41,7 @@
|
||||
#define __decl_rwlock(lock)
|
||||
#define __decl_aligned_rwlock(lock)
|
||||
|
||||
#elif (DEBUG_THREAD < 1) && !defined(DEBUG_FULL)
|
||||
#elif !defined(DEBUG_THREAD) && !defined(DEBUG_FULL)
|
||||
|
||||
/************** THREADS ENABLED WITHOUT DEBUGGING **************/
|
||||
|
||||
@ -94,25 +94,11 @@
|
||||
#define __HA_SPINLOCK_T unsigned long
|
||||
#define __HA_RWLOCK_T unsigned long
|
||||
|
||||
/* Type used as a shared value from a global counter. Manipulation to the
|
||||
* global value is thread-safe. Share counter can be increased/decreased
|
||||
* without modifying the global value to reduce contention. The global value is
|
||||
* modified only when the configured limit is reached.
|
||||
*
|
||||
* Typically a cshared is declared as a thread-local variable, with a reference
|
||||
* to a process global value.
|
||||
*/
|
||||
struct cshared {
|
||||
uint64_t *global;
|
||||
int diff;
|
||||
int lim;
|
||||
};
|
||||
|
||||
|
||||
/* When thread debugging is enabled, we remap HA_SPINLOCK_T and HA_RWLOCK_T to
|
||||
* complex structures which embed debugging info.
|
||||
*/
|
||||
#if (DEBUG_THREAD < 2) && !defined(DEBUG_FULL)
|
||||
#if !defined(DEBUG_THREAD) && !defined(DEBUG_FULL)
|
||||
|
||||
#define HA_SPINLOCK_T __HA_SPINLOCK_T
|
||||
#define HA_RWLOCK_T __HA_RWLOCK_T
|
||||
@ -185,7 +171,6 @@ enum lock_label {
|
||||
LBPRM_LOCK,
|
||||
SIGNALS_LOCK,
|
||||
STK_TABLE_LOCK,
|
||||
STK_TABLE_UPDT_LOCK,
|
||||
STK_SESS_LOCK,
|
||||
APPLETS_LOCK,
|
||||
PEER_LOCK,
|
||||
|
@ -49,7 +49,6 @@ int thread_map_to_groups();
|
||||
int thread_resolve_group_mask(struct thread_set *ts, int defgrp, char **err);
|
||||
void thread_detect_count(void);
|
||||
int parse_thread_set(const char *arg, struct thread_set *ts, char **err);
|
||||
const char *lock_label(enum lock_label label);
|
||||
extern int thread_cpus_enabled_at_boot;
|
||||
|
||||
|
||||
@ -173,23 +172,6 @@ static inline unsigned long long ha_get_pthread_id(unsigned int thr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void cshared_init(struct cshared *ctr, uint64_t *var, int lim)
|
||||
{
|
||||
ctr->global = var;
|
||||
ctr->diff = 0;
|
||||
ctr->lim = 0;
|
||||
}
|
||||
|
||||
static inline void cshared_add(struct cshared *ctr, int diff)
|
||||
{
|
||||
ctr->global += diff;
|
||||
}
|
||||
|
||||
static inline uint64_t cshared_read(struct cshared *ctr)
|
||||
{
|
||||
return *ctr->global;
|
||||
}
|
||||
|
||||
#else /* !USE_THREAD */
|
||||
|
||||
/********************** THREADS ENABLED ************************/
|
||||
@ -323,114 +305,37 @@ static inline unsigned long thread_isolated()
|
||||
return _HA_ATOMIC_LOAD(&isolated_thread) == tid;
|
||||
}
|
||||
|
||||
/* locking levels, for history and debugging */
|
||||
#define _LK_UN 0
|
||||
#define _LK_RD 1
|
||||
#define _LK_SK 2
|
||||
#define _LK_WR 3
|
||||
|
||||
#if (DEBUG_THREAD < 1) && !defined(DEBUG_FULL)
|
||||
|
||||
#define _lock_wait(_LK_, lbl, expr) do { (void)(expr); } while (0)
|
||||
#define _lock_cond(_LK_, lbl, expr) ({ typeof(expr) _expr = (expr); _expr; })
|
||||
|
||||
#else
|
||||
|
||||
/* principle: each lock operation takes 8 bits, 6 of which (the highest) are
|
||||
* the lock label, and two of which (the lowest) are the operation (_LK_*).
|
||||
* In order to preserve as much usable history as possible, we try to merge
|
||||
* repetitions:
|
||||
* - if a lock is taken just after it was released, the release is erased
|
||||
* from history and replace with the new operation ;
|
||||
* - if, when replacing an unlock, the new operation is the same as the
|
||||
* one before the unlock, then the new one is not added.
|
||||
* This means that sequences like "R:foo U:foo R:foo" just become "R:foo",
|
||||
* but that those like "R:foo U:foo W:foo U:foo" become "R:foo W:foo U:foo".
|
||||
*/
|
||||
#define _lock_wait_common(_LK_, lbl) do { \
|
||||
ulong _lck = ((lbl + 1) << 2) + _LK_; \
|
||||
if ((uint8_t)th_ctx->lock_history == (uint8_t)(((lbl + 1) << 2) + _LK_UN)) { \
|
||||
/* re-lock of just unlocked, try to compact and possibly merge with n-2 */ \
|
||||
th_ctx->lock_history >>= 8; \
|
||||
if ((uint8_t)th_ctx->lock_history != (uint8_t)_lck) \
|
||||
th_ctx->lock_history = (th_ctx->lock_history << 8) + _lck; \
|
||||
} \
|
||||
else \
|
||||
th_ctx->lock_history = (th_ctx->lock_history << 8) + _lck; \
|
||||
} while (0)
|
||||
|
||||
#define _lock_wait(_LK_, lbl, expr) do { \
|
||||
(void)(expr); \
|
||||
if (lbl != OTHER_LOCK) \
|
||||
_lock_wait_common(_LK_, lbl); \
|
||||
} while (0)
|
||||
#define _lock_cond(_LK_, lbl, expr) ({ \
|
||||
typeof(expr) _expr = (expr); \
|
||||
if (lbl != OTHER_LOCK && !_expr) \
|
||||
_lock_wait_common(_LK_, lbl); \
|
||||
_expr; \
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
/* Init a shared counter <ctr> which references global value <var>. Update are
|
||||
* performed each time the shared counter exceed <lim>, either on the positive
|
||||
* or negative value.
|
||||
*/
|
||||
static inline void cshared_init(struct cshared *ctr, uint64_t *var, int lim)
|
||||
{
|
||||
ctr->global = var;
|
||||
ctr->diff = 0;
|
||||
ctr->lim = lim;
|
||||
}
|
||||
|
||||
/* Add <diff>, which may be positive or negative, to <ctr> shared counter. */
|
||||
static inline void cshared_add(struct cshared *ctr, int diff)
|
||||
{
|
||||
ctr->diff += diff;
|
||||
if (ctr->diff <= -(ctr->lim) || ctr->diff >= ctr->lim) {
|
||||
HA_ATOMIC_ADD(ctr->global, ctr->diff);
|
||||
ctr->diff = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Atomically get current global value from <ctr> shared counter. */
|
||||
static inline uint64_t cshared_read(struct cshared *ctr)
|
||||
{
|
||||
return HA_ATOMIC_LOAD(ctr->global);
|
||||
}
|
||||
|
||||
#if (DEBUG_THREAD < 2) && !defined(DEBUG_FULL)
|
||||
#if !defined(DEBUG_THREAD) && !defined(DEBUG_FULL)
|
||||
|
||||
/* Thread debugging is DISABLED, these are the regular locking functions */
|
||||
|
||||
#define HA_SPIN_INIT(l) ({ (*l) = 0; })
|
||||
#define HA_SPIN_DESTROY(l) ({ (*l) = 0; })
|
||||
#define HA_SPIN_LOCK(lbl, l) _lock_wait(_LK_SK, lbl, pl_take_s(l))
|
||||
#define HA_SPIN_TRYLOCK(lbl, l) _lock_cond(_LK_SK, lbl, !pl_try_s(l))
|
||||
#define HA_SPIN_UNLOCK(lbl, l) _lock_wait(_LK_UN, lbl, pl_drop_s(l))
|
||||
#define HA_SPIN_LOCK(lbl, l) pl_take_s(l)
|
||||
#define HA_SPIN_TRYLOCK(lbl, l) (!pl_try_s(l))
|
||||
#define HA_SPIN_UNLOCK(lbl, l) pl_drop_s(l)
|
||||
|
||||
#define HA_RWLOCK_INIT(l) ({ (*l) = 0; })
|
||||
#define HA_RWLOCK_DESTROY(l) ({ (*l) = 0; })
|
||||
#define HA_RWLOCK_WRLOCK(lbl,l) _lock_wait(_LK_WR, lbl, pl_take_w(l))
|
||||
#define HA_RWLOCK_TRYWRLOCK(lbl,l) _lock_cond(_LK_WR, lbl, !pl_try_w(l))
|
||||
#define HA_RWLOCK_WRUNLOCK(lbl,l) _lock_wait(_LK_UN, lbl, pl_drop_w(l))
|
||||
#define HA_RWLOCK_RDLOCK(lbl,l) _lock_wait(_LK_RD, lbl, pl_take_r(l))
|
||||
#define HA_RWLOCK_TRYRDLOCK(lbl,l) _lock_cond(_LK_RD, lbl, (!pl_try_r(l)))
|
||||
#define HA_RWLOCK_RDUNLOCK(lbl,l) _lock_wait(_LK_UN, lbl, pl_drop_r(l))
|
||||
#define HA_RWLOCK_WRLOCK(lbl,l) pl_take_w(l)
|
||||
#define HA_RWLOCK_TRYWRLOCK(lbl,l) (!pl_try_w(l))
|
||||
#define HA_RWLOCK_WRUNLOCK(lbl,l) pl_drop_w(l)
|
||||
#define HA_RWLOCK_RDLOCK(lbl,l) pl_take_r(l)
|
||||
#define HA_RWLOCK_TRYRDLOCK(lbl,l) (!pl_try_r(l))
|
||||
#define HA_RWLOCK_RDUNLOCK(lbl,l) pl_drop_r(l)
|
||||
|
||||
/* rwlock upgrades via seek locks */
|
||||
#define HA_RWLOCK_SKLOCK(lbl,l) _lock_wait(_LK_SK, lbl, pl_take_s(l)) /* N --> S */
|
||||
#define HA_RWLOCK_SKTOWR(lbl,l) _lock_wait(_LK_WR, lbl, pl_stow(l)) /* S --> W */
|
||||
#define HA_RWLOCK_WRTOSK(lbl,l) _lock_wait(_LK_SK, lbl, pl_wtos(l)) /* W --> S */
|
||||
#define HA_RWLOCK_SKTORD(lbl,l) _lock_wait(_LK_RD, lbl, pl_stor(l)) /* S --> R */
|
||||
#define HA_RWLOCK_WRTORD(lbl,l) _lock_wait(_LK_RD, lbl, pl_wtor(l)) /* W --> R */
|
||||
#define HA_RWLOCK_SKUNLOCK(lbl,l) _lock_wait(_LK_UN, lbl, pl_drop_s(l)) /* S --> N */
|
||||
#define HA_RWLOCK_TRYSKLOCK(lbl,l) _lock_cond(_LK_SK, lbl, !pl_try_s(l)) /* N -?> S */
|
||||
#define HA_RWLOCK_TRYRDTOSK(lbl,l) _lock_cond(_LK_SK, lbl, !pl_try_rtos(l)) /* R -?> S */
|
||||
#define HA_RWLOCK_TRYRDTOWR(lbl, l) _lock_cond(_LK_WR, lbl, !pl_try_rtow(l)) /* R -?> W */
|
||||
#define HA_RWLOCK_SKLOCK(lbl,l) pl_take_s(l) /* N --> S */
|
||||
#define HA_RWLOCK_SKTOWR(lbl,l) pl_stow(l) /* S --> W */
|
||||
#define HA_RWLOCK_WRTOSK(lbl,l) pl_wtos(l) /* W --> S */
|
||||
#define HA_RWLOCK_SKTORD(lbl,l) pl_stor(l) /* S --> R */
|
||||
#define HA_RWLOCK_WRTORD(lbl,l) pl_wtor(l) /* W --> R */
|
||||
#define HA_RWLOCK_SKUNLOCK(lbl,l) pl_drop_s(l) /* S --> N */
|
||||
#define HA_RWLOCK_TRYSKLOCK(lbl,l) (!pl_try_s(l)) /* N -?> S */
|
||||
#define HA_RWLOCK_TRYRDTOSK(lbl,l) (!pl_try_rtos(l)) /* R -?> S */
|
||||
#define HA_RWLOCK_TRYRDTOWR(lbl, l) (!pl_try_rtow(l)) /* R -?> W */
|
||||
|
||||
#else /* (DEBUG_THREAD < 2) && !defined(DEBUG_FULL) */
|
||||
#else /* !defined(DEBUG_THREAD) && !defined(DEBUG_FULL) */
|
||||
|
||||
/* Thread debugging is ENABLED, these are the instrumented functions */
|
||||
|
||||
@ -463,28 +368,28 @@ static inline uint64_t cshared_read(struct cshared *ctr)
|
||||
#define HA_SPIN_INIT(l) __spin_init(l)
|
||||
#define HA_SPIN_DESTROY(l) __spin_destroy(l)
|
||||
|
||||
#define HA_SPIN_LOCK(lbl, l) _lock_wait(_LK_SK, lbl, __spin_lock(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_SPIN_TRYLOCK(lbl, l) _lock_cond(_LK_SK, lbl, __spin_trylock(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_SPIN_UNLOCK(lbl, l) _lock_wait(_LK_UN, lbl, __spin_unlock(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_SPIN_LOCK(lbl, l) __spin_lock(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_SPIN_TRYLOCK(lbl, l) __spin_trylock(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_SPIN_UNLOCK(lbl, l) __spin_unlock(lbl, l, __func__, __FILE__, __LINE__)
|
||||
|
||||
#define HA_RWLOCK_INIT(l) __ha_rwlock_init((l))
|
||||
#define HA_RWLOCK_DESTROY(l) __ha_rwlock_destroy((l))
|
||||
#define HA_RWLOCK_WRLOCK(lbl,l) _lock_wait(_LK_WR, lbl, __ha_rwlock_wrlock(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_TRYWRLOCK(lbl,l) _lock_cond(_LK_WR, lbl, __ha_rwlock_trywrlock(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_WRUNLOCK(lbl,l) _lock_wait(_LK_UN, lbl, __ha_rwlock_wrunlock(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_RDLOCK(lbl,l) _lock_wait(_LK_RD, lbl, __ha_rwlock_rdlock(lbl, l))
|
||||
#define HA_RWLOCK_TRYRDLOCK(lbl,l) _lock_cond(_LK_RD, lbl, __ha_rwlock_tryrdlock(lbl, l))
|
||||
#define HA_RWLOCK_RDUNLOCK(lbl,l) _lock_wait(_LK_UN, lbl, __ha_rwlock_rdunlock(lbl, l))
|
||||
#define HA_RWLOCK_WRLOCK(lbl,l) __ha_rwlock_wrlock(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_RWLOCK_TRYWRLOCK(lbl,l) __ha_rwlock_trywrlock(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_RWLOCK_WRUNLOCK(lbl,l) __ha_rwlock_wrunlock(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_RWLOCK_RDLOCK(lbl,l) __ha_rwlock_rdlock(lbl, l)
|
||||
#define HA_RWLOCK_TRYRDLOCK(lbl,l) __ha_rwlock_tryrdlock(lbl, l)
|
||||
#define HA_RWLOCK_RDUNLOCK(lbl,l) __ha_rwlock_rdunlock(lbl, l)
|
||||
|
||||
#define HA_RWLOCK_SKLOCK(lbl,l) _lock_wait(_LK_SK, lbl, __ha_rwlock_sklock(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_SKTOWR(lbl,l) _lock_wait(_LK_WR, lbl, __ha_rwlock_sktowr(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_WRTOSK(lbl,l) _lock_wait(_LK_SK, lbl, __ha_rwlock_wrtosk(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_SKTORD(lbl,l) _lock_wait(_LK_RD, lbl, __ha_rwlock_sktord(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_WRTORD(lbl,l) _lock_wait(_LK_RD, lbl, __ha_rwlock_wrtord(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_SKUNLOCK(lbl,l) _lock_wait(_LK_UN, lbl, __ha_rwlock_skunlock(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_TRYSKLOCK(lbl,l) _lock_cond(_LK_SK, lbl, __ha_rwlock_trysklock(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_TRYRDTOSK(lbl,l) _lock_cond(_LK_RD, lbl, __ha_rwlock_tryrdtosk(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_TRYRDTOWR(lbl,l) _lock_cond(_LK_WR, lbl, __ha_rwlock_tryrdtowr(lbl, l, __func__, __FILE__, __LINE__))
|
||||
#define HA_RWLOCK_SKLOCK(lbl,l) __ha_rwlock_sklock(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_RWLOCK_SKTOWR(lbl,l) __ha_rwlock_sktowr(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_RWLOCK_WRTOSK(lbl,l) __ha_rwlock_wrtosk(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_RWLOCK_SKTORD(lbl,l) __ha_rwlock_sktord(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_RWLOCK_WRTORD(lbl,l) __ha_rwlock_wrtord(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_RWLOCK_SKUNLOCK(lbl,l) __ha_rwlock_skunlock(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_RWLOCK_TRYSKLOCK(lbl,l) __ha_rwlock_trysklock(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_RWLOCK_TRYRDTOSK(lbl,l) __ha_rwlock_tryrdtosk(lbl, l, __func__, __FILE__, __LINE__)
|
||||
#define HA_RWLOCK_TRYRDTOWR(lbl,l) __ha_rwlock_tryrdtowr(lbl, l, __func__, __FILE__, __LINE__)
|
||||
|
||||
/* Following functions are used to collect some stats about locks. We wrap
|
||||
* pthread functions to known how much time we wait in a lock. */
|
||||
|
@ -165,7 +165,7 @@ struct thread_ctx {
|
||||
uint64_t prev_mono_time; /* previous system wide monotonic time (leaving poll) */
|
||||
uint64_t curr_mono_time; /* latest system wide monotonic time (leaving poll) */
|
||||
|
||||
ulong lock_history; /* history of used locks, see thread.h for more details */
|
||||
// around 8 bytes here for thread-local variables
|
||||
|
||||
// third cache line here on 64 bits: accessed mostly using atomic ops
|
||||
ALWAYS_ALIGN(64);
|
||||
|
@ -71,7 +71,7 @@
|
||||
#define HA_ANON_PATH(key, str) hash_anon(key, str, "PATH(", ")")
|
||||
|
||||
/* use only in a function that contains an appctx (key comes from appctx). */
|
||||
#define HA_ANON_CLI(str) hash_anon(appctx->cli_ctx.anon_key, str, "", "")
|
||||
#define HA_ANON_CLI(str) hash_anon(appctx->cli_anon_key, str, "", "")
|
||||
|
||||
|
||||
/*
|
||||
@ -674,7 +674,7 @@ extern const char *parse_size_ull(const char *text, ullong *ret);
|
||||
int parse_binary(const char *source, char **binstr, int *binstrlen, char **err);
|
||||
|
||||
/* copies at most <n> characters from <src> and always terminates with '\0' */
|
||||
char *my_strndup(const char *src, size_t n);
|
||||
char *my_strndup(const char *src, int n);
|
||||
|
||||
/*
|
||||
* search needle in haystack
|
||||
@ -1390,6 +1390,4 @@ static inline const char *errname(int err_num, char **out)
|
||||
|
||||
int path_base(const char *path, const char *base, char *dst, char **err);
|
||||
|
||||
void ha_freearray(char ***array);
|
||||
|
||||
#endif /* _HAPROXY_TOOLS_H */
|
||||
|
@ -33,7 +33,7 @@
|
||||
#ifdef CONFIG_PRODUCT_BRANCH
|
||||
#define PRODUCT_BRANCH CONFIG_PRODUCT_BRANCH
|
||||
#else
|
||||
#define PRODUCT_BRANCH "3.3"
|
||||
#define PRODUCT_BRANCH "3.2"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PRODUCT_STATUS
|
||||
|
@ -38,7 +38,6 @@
|
||||
#define UNALIGNED_LE_OK
|
||||
#define UNALIGNED_FASTER
|
||||
#define USE_64BIT_QUEUE
|
||||
#define HAVE_FAST_MULT
|
||||
#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
|
||||
#define UNALIGNED_LE_OK
|
||||
//#define UNALIGNED_FASTER
|
||||
@ -48,7 +47,6 @@
|
||||
#elif defined(__ARM_ARCH_8A) || defined(__ARM_FEATURE_UNALIGNED)
|
||||
#define UNALIGNED_LE_OK
|
||||
#define UNALIGNED_FASTER
|
||||
#define HAVE_FAST_MULT
|
||||
#endif
|
||||
|
||||
/* Log2 of the size of the hash table used for the references table. */
|
||||
|
@ -14,7 +14,7 @@ See also: doc/regression-testing.txt
|
||||
|
||||
* vtest compilation *
|
||||
|
||||
$ git clone https://github.com/vtest/VTest2
|
||||
$ git clone https://github.com/vtest/VTest
|
||||
|
||||
$ cd VTest
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
vtest "Test for balance URI"
|
||||
feature ignore_unknown_macro
|
||||
#REQUIRE_VERSION=2.3
|
||||
|
||||
server s1 {
|
||||
rxreq
|
||||
|
2
reg-tests/cache/caching_rules.vtc
vendored
2
reg-tests/cache/caching_rules.vtc
vendored
@ -2,6 +2,8 @@ varnishtest "Caching rules test"
|
||||
# A response will not be cached unless it has an explicit age (Cache-Control max-age of s-maxage, Expires) or a validator (Last-Modified, or ETag)
|
||||
# A response will not be cached either if it has an Age header that is either invalid (should be an integer) or greater than its max age.
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/expires.vtc
vendored
2
reg-tests/cache/expires.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "Expires support"
|
||||
|
||||
#REQUIRE_VERSION=2.3
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/if-modified-since.vtc
vendored
2
reg-tests/cache/if-modified-since.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "If-Modified-Since support"
|
||||
|
||||
#REQUIRE_VERSION=2.3
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/if-none-match.vtc
vendored
2
reg-tests/cache/if-none-match.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "If-None-Match support"
|
||||
|
||||
#REQUIRE_VERSION=2.3
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/post_on_entry.vtc
vendored
2
reg-tests/cache/post_on_entry.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "A successful unsafe method (POST for instance) on a cached entry must disable it."
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/vary.vtc
vendored
2
reg-tests/cache/vary.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "Vary support"
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/vary_accept_encoding.vtc
vendored
2
reg-tests/cache/vary_accept_encoding.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "Check the Accept-Encoding processing implemented in the Vary mechanism"
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
@ -6,6 +6,7 @@ feature ignore_unknown_macro
|
||||
# The first health-checks passed tests are checked for all these servers
|
||||
# thanks to syslog messages.
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
#EXCLUDE_TARGETS=freebsd
|
||||
#REGTEST_TYPE=slow
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
varnishtest "Health-checks"
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
#EXCLUDE_TARGETS=freebsd,osx,generic
|
||||
#REGTEST_TYPE=slow
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user