Compare commits
162 Commits
20250513-q
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
577fa44691 | ||
|
830affc17d | ||
|
33cd96a5e9 | ||
|
5a0ae9e9be | ||
|
869fb457ed | ||
|
dc3fb3a731 | ||
|
603afd495b | ||
|
a286d5476b | ||
|
4031bf7432 | ||
|
1efaca8a57 | ||
|
f8d096c05f | ||
|
e8775d51df | ||
|
93b904702f | ||
|
e7f1db0348 | ||
|
a0db93f3d8 | ||
|
044ad3a602 | ||
|
2c3f3eaaed | ||
|
b5067a972c | ||
|
01f011faeb | ||
|
8c573deb9f | ||
|
bf6e576cfd | ||
|
cdcecb9b65 | ||
|
855fd63f90 | ||
|
b9703cf711 | ||
|
f6ef3bbc8a | ||
|
034cf74437 | ||
|
d1cd0bb987 | ||
|
fc90964b55 | ||
|
8c2f2615f4 | ||
|
f085a2f5bf | ||
|
a62098bfb0 | ||
|
e226a7cb79 | ||
|
2d076178c6 | ||
|
b4a9b53515 | ||
|
e27b7b4889 | ||
|
43d88a44f1 | ||
|
266b10b8a4 | ||
|
89d5a59933 | ||
|
f7c0f5ac1b | ||
|
29fb1aee57 | ||
|
9831f596ea | ||
|
52ec3430f2 | ||
|
9c84f64652 | ||
|
f49bbd36b9 | ||
|
1408d94bc4 | ||
|
7c76252d8a | ||
|
1e45690656 | ||
|
a4e1296208 | ||
|
24fc44c44d | ||
|
0e67687ca9 | ||
|
5a711551a2 | ||
|
990c9f95f7 | ||
|
9c751a3cc1 | ||
|
f66b495f8e | ||
|
bdd5e58179 | ||
|
1ecf2e9bab | ||
|
b5525fe759 | ||
|
b2f64af341 | ||
|
6993981cd6 | ||
|
9df380a152 | ||
|
18f9c71041 | ||
|
79445766a3 | ||
|
0d8ecb1edc | ||
|
6b74633069 | ||
|
0cdf529720 | ||
|
5f1fad1690 | ||
|
f5d41803d3 | ||
|
16eb0fab31 | ||
|
12c3ffbb48 | ||
|
b72a8bb138 | ||
|
b599138842 | ||
|
c10ce1c85b | ||
|
aa53887398 | ||
|
a0dcab5c45 | ||
|
89b04f2191 | ||
|
8c4bb8cab3 | ||
|
6786b05297 | ||
|
8ee650a88b | ||
|
7c788f0984 | ||
|
913b2d6c83 | ||
|
368d01361a | ||
|
889ef6f67b | ||
|
e262e4bbe4 | ||
|
1f12e45b0a | ||
|
943958c3ff | ||
|
6ccf770fe2 | ||
|
c7c017ec3c | ||
|
d04843167c | ||
|
f0b40b49b8 | ||
|
8ee8b8a04d | ||
|
d8951ec70f | ||
|
534b09f2a2 | ||
|
239785fd27 | ||
|
294c47a5ef | ||
|
8e8cdf114b | ||
|
b88164d9c0 | ||
|
9f4cd435d3 | ||
|
8809251ee0 | ||
|
e134140d28 | ||
|
a6458fd426 | ||
|
2502435eb3 | ||
|
21ce685fcd | ||
|
cb7a2444d1 | ||
|
50fca6f0b7 | ||
|
94ded5523f | ||
|
508e074a32 | ||
|
6a18d28ba2 | ||
|
bc4c3c7969 | ||
|
c0ecef71d7 | ||
|
c64781c2c8 | ||
|
4d4da515f2 | ||
|
99e755d673 | ||
|
2808e3577f | ||
|
82c2911248 | ||
|
5b937b7a97 | ||
|
ef9511be90 | ||
|
e70c23e517 | ||
|
da9792cca8 | ||
|
083708daf8 | ||
|
52c2247d90 | ||
|
770098f5e3 | ||
|
5261e35b8f | ||
|
e9248243e9 | ||
|
38456f63a3 | ||
|
da8d6d1b2c | ||
|
d607940915 | ||
|
90441e9bfe | ||
|
84ffb3d0a9 | ||
|
28c7a22790 | ||
|
b40ce97ecc | ||
|
5e088e3f8e | ||
|
4de5090976 | ||
|
2570892c41 | ||
|
1c0f2e62ad | ||
|
3494775a1f | ||
|
7244f16ac4 | ||
|
0ac41ff97e | ||
|
a1577a89a0 | ||
|
eee57b4d3f | ||
|
00d90e8839 | ||
|
01e3b2119a | ||
|
f286288471 | ||
|
07d41a043c | ||
|
cf45bf1ad8 | ||
|
b437094853 | ||
|
8b121ab6f7 | ||
|
156f4bd7a6 | ||
|
f5ed309449 | ||
|
e399daa67e | ||
|
5c628d4e09 | ||
|
4b52d5e406 | ||
|
09d4c9519e | ||
|
3b2fb5cc15 | ||
|
0a8bfb5b90 | ||
|
dcdf27af70 | ||
|
bbe302087c | ||
|
08eee0d9cf | ||
|
849a3af14e | ||
|
b3ac1a636c | ||
|
dc6a3c329a | ||
|
894595b711 | ||
|
a2822b1776 |
95
.github/workflows/aws-lc-fips.yml
vendored
95
.github/workflows/aws-lc-fips.yml
vendored
@ -5,97 +5,8 @@ on:
|
|||||||
- cron: "0 0 * * 4"
|
- cron: "0 0 * * 4"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
uses: ./.github/workflows/aws-lc-template.yml
|
||||||
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
|
with:
|
||||||
steps:
|
command: "from matrix import determine_latest_aws_lc_fips; print(determine_latest_aws_lc_fips(''))"
|
||||||
- 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 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
|
|
||||||
|
|
||||||
|
103
.github/workflows/aws-lc-template.yml
vendored
Normal file
103
.github/workflows/aws-lc-template.yml
vendored
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
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
|
||||||
|
|
95
.github/workflows/aws-lc.yml
vendored
95
.github/workflows/aws-lc.yml
vendored
@ -5,97 +5,8 @@ on:
|
|||||||
- cron: "0 0 * * 4"
|
- cron: "0 0 * * 4"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
uses: ./.github/workflows/aws-lc-template.yml
|
||||||
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
|
with:
|
||||||
steps:
|
command: "from matrix import determine_latest_aws_lc; print(determine_latest_aws_lc(''))"
|
||||||
- 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 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
|
|
||||||
|
|
||||||
|
130
CHANGELOG
130
CHANGELOG
@ -1,6 +1,136 @@
|
|||||||
ChangeLog :
|
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
|
2025/05/14 : 3.2-dev16
|
||||||
- BUG/MEDIUM: mux-quic: fix crash on invalid fctl frame dereference
|
- BUG/MEDIUM: mux-quic: fix crash on invalid fctl frame dereference
|
||||||
- DEBUG: pool: permit per-pool UAF configuration
|
- DEBUG: pool: permit per-pool UAF configuration
|
||||||
|
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
|
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
|
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.4. 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.5. It is recommended to use
|
||||||
at least OpenSSL 1.1.1 to have support for all SSL keywords and configuration
|
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,
|
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
|
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
|
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
|
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
|
options. Note that QUIC is not fully supported when haproxy is built with
|
||||||
OpenSSL. In this case, QUICTLS is the preferred alternative. As of writing
|
OpenSSL < 3.5 version. In this case, QUICTLS is the preferred alternative.
|
||||||
this, the QuicTLS project follows OpenSSL very closely and provides update
|
As of writing this, the QuicTLS project follows OpenSSL very closely and provides
|
||||||
simultaneously, but being a volunteer-driven project, its long-term future does
|
update simultaneously, but being a volunteer-driven project, its long-term future
|
||||||
not look certain enough to convince operating systems to package it, so it
|
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.
|
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
|
A fifth option is wolfSSL (https://github.com/wolfSSL/wolfssl). It is the only
|
||||||
@ -500,10 +500,11 @@ 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
|
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".
|
the frontend side. In order to enable it, use "USE_QUIC=1 USE_OPENSSL=1".
|
||||||
|
|
||||||
Note that QUIC is not fully supported by the OpenSSL library. Indeed QUIC 0-RTT
|
Note that QUIC is not always fully supported by the OpenSSL library depending on
|
||||||
cannot be supported by OpenSSL contrary to others libraries with full QUIC
|
its version. Indeed QUIC 0-RTT cannot be supported by OpenSSL for versions before
|
||||||
support. The preferred option is to use QUICTLS. This is a fork of OpenSSL with
|
3.5 contrary to others libraries with full QUIC support. The preferred option is
|
||||||
a QUIC-compatible API. Its repository is available at this location:
|
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
|
https://github.com/quictls/openssl
|
||||||
|
|
||||||
@ -531,14 +532,18 @@ 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
|
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"
|
LDFLAGS="-Wl,-rpath,/opt/wolfssl-5.6.0/lib"
|
||||||
|
|
||||||
As last resort, haproxy may be compiled against OpenSSL as follows:
|
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:
|
||||||
|
|
||||||
$ make TARGET=generic USE_OPENSSL=1 USE_QUIC=1 USE_QUIC_OPENSSL_COMPAT=1
|
$ make TARGET=generic USE_OPENSSL=1 USE_QUIC=1 USE_QUIC_OPENSSL_COMPAT=1
|
||||||
|
|
||||||
Note that QUIC 0-RTT is not supported by haproxy QUIC stack when built against
|
In addition to this requirements, the QUIC listener bindings must be explicitly
|
||||||
OpenSSL. In addition to this compilation requirements, the QUIC listener
|
enabled with a specific QUIC tuning parameter. (see "limited-quic" global
|
||||||
bindings must be explicitly enabled with a specific QUIC tuning parameter.
|
parameter of haproxy Configuration Manual).
|
||||||
(see "limited-quic" global parameter of haproxy Configuration Manual).
|
|
||||||
|
|
||||||
|
|
||||||
5) How to build HAProxy
|
5) How to build HAProxy
|
||||||
|
4
Makefile
4
Makefile
@ -660,7 +660,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/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/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/qpack-tbl.o src/quic_cc_drs.o src/quic_fctl.o \
|
||||||
src/cbuf.o src/quic_enc.o
|
src/quic_enc.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(USE_QUIC_OPENSSL_COMPAT:0=),)
|
ifneq ($(USE_QUIC_OPENSSL_COMPAT:0=),)
|
||||||
@ -984,7 +984,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_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/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/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/cfgparse-tcp.o src/lb_ss.o src/chunk.o src/counters.o \
|
||||||
src/cfgparse-unix.o src/regex.o src/fcgi.o src/uri_auth.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/eb64tree.o src/eb32tree.o src/eb32sctree.o src/lru.o \
|
||||||
src/limits.o src/ebimtree.o src/wdt.o src/hpack-tbl.o \
|
src/limits.o src/ebimtree.o src/wdt.o src/hpack-tbl.o \
|
||||||
|
@ -389,6 +389,9 @@ listed below. Metrics from extra counters are not listed.
|
|||||||
| haproxy_server_max_connect_time_seconds |
|
| haproxy_server_max_connect_time_seconds |
|
||||||
| haproxy_server_max_response_time_seconds |
|
| haproxy_server_max_response_time_seconds |
|
||||||
| haproxy_server_max_total_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_internal_errors_total |
|
||||||
| haproxy_server_unsafe_idle_connections_current |
|
| haproxy_server_unsafe_idle_connections_current |
|
||||||
| haproxy_server_safe_idle_connections_current |
|
| haproxy_server_safe_idle_connections_current |
|
||||||
|
@ -173,6 +173,8 @@ 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_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_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_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_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_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"),
|
[ST_I_PX_RT_MAX] = IST("Maximum observed time spent waiting for a server response"),
|
||||||
@ -1342,6 +1344,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
secs = (double)sv->check.duration / 1000.0;
|
secs = (double)sv->check.duration / 1000.0;
|
||||||
val = mkf_flt(FN_DURATION, secs);
|
val = mkf_flt(FN_DURATION, secs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ST_I_PX_REQ_TOT:
|
case ST_I_PX_REQ_TOT:
|
||||||
if (px->mode != PR_MODE_HTTP) {
|
if (px->mode != PR_MODE_HTTP) {
|
||||||
sv = NULL;
|
sv = NULL;
|
||||||
@ -1364,6 +1367,36 @@ 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];
|
labels[lb_idx+1].value = promex_hrsp_code[ctx->field_num - ST_I_PX_HRSP_1XX];
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
70
dev/patchbot/prompts/prompt15-3.3-mist7bv2-pfx.txt
Normal file
70
dev/patchbot/prompts/prompt15-3.3-mist7bv2-pfx.txt
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
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.
|
||||||
|
|
29
dev/patchbot/prompts/prompt15-3.3-mist7bv2-sfx.txt
Normal file
29
dev/patchbot/prompts/prompt15-3.3-mist7bv2-sfx.txt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
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
@ -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
|
the time spent in the process, while the latter might also account for time
|
||||||
stuck on paging in etc.
|
stuck on paging in etc.
|
||||||
|
|
||||||
Then wdt_ping() is called to arm the timer. t's set to trigger every
|
Then wdt_ping() is called to arm the timer. It's set to trigger every
|
||||||
<wdt_warn_blocked_traffic_ns> interval. It is also called by wdt_handler()
|
<wdt_warn_blocked_traffic_ns> interval. It is also called by wdt_handler()
|
||||||
to reprogram a new wakeup after it has ticked.
|
to reprogram a new wakeup after it has ticked.
|
||||||
|
|
||||||
@ -37,15 +37,18 @@ 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
|
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
|
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
|
its prev_cpu_time. If the lack of progress is at least as large as the warning
|
||||||
threshold and no context switch happened since last call, ha_stuck_warning() is
|
threshold, then the signal is bounced to the faulty thread if it's not the
|
||||||
called to emit a warning about that thread. In any case the context switch
|
current one. Since this bounce is based on the time spent without update, it
|
||||||
counter for that thread is updated.
|
already doesn't happen often.
|
||||||
|
|
||||||
If the thread was already marked as stuck, then the thread is considered as
|
Once on the faulty thread, two checks are performed:
|
||||||
definitely stuck. Then ha_panic() is directly called if the thread is the
|
1) if the thread was already marked as stuck, then the thread is considered
|
||||||
current one, otherwise ha_kill() is used to resend the signal directly to the
|
as definitely stuck, and ha_panic() is called. It will not return.
|
||||||
target thread, which will in turn go through this handler and handle the panic
|
|
||||||
itself.
|
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.
|
||||||
|
|
||||||
Most of the time there's no panic of course, and a wdt_ping() is performed
|
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.
|
before leaving the handler to reprogram a check for that thread.
|
||||||
@ -61,12 +64,12 @@ set TAINTED_WARN_BLOCKED_TRAFFIC.
|
|||||||
|
|
||||||
ha_panic() uses the current thread's trash buffer to produce the messages, as
|
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
|
we don't care about its contents since that thread will never return. However
|
||||||
ha_stuck_warning() instead uses a local 4kB buffer in the thread's stack.
|
ha_stuck_warning() instead uses a local 8kB buffer in the thread's stack.
|
||||||
ha_panic() will call ha_thread_dump_fill() for each thread, to complete the
|
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
|
buffer being filled with each thread's dump messages. ha_stuck_warning() only
|
||||||
calls the function for the current thread. In both cases the message is then
|
calls ha_thread_dump_one(), which works on the current thread. In both cases
|
||||||
directly sent to fd #2 (stderr) and ha_thread_dump_one() is called to release
|
the message is then directly sent to fd #2 (stderr) and ha_thread_dump_done()
|
||||||
the dumped thread.
|
is called to release the dumped thread.
|
||||||
|
|
||||||
Both print a few extra messages, but ha_panic() just ends by looping on abort()
|
Both print a few extra messages, but ha_panic() just ends by looping on abort()
|
||||||
until the process dies.
|
until the process dies.
|
||||||
@ -110,13 +113,19 @@ ha_dump_backtrace() before returning.
|
|||||||
ha_dump_backtrace() produces a backtrace into a local buffer (100 entries max),
|
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
|
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.
|
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
|
3. Improvements
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
The symbols resolution is extremely expensive, particularly for the warnings
|
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
|
which should be fast. But we need it, it's just unfortunate that it strikes at
|
||||||
the wrong moment.
|
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)..
|
||||||
|
|
||||||
In an ideal case, ha_dump_backtrace() would dump the pointers to a local array,
|
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
|
which would then later be resolved asynchronously in a tasklet. This can work
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
-----------------------
|
-----------------------
|
||||||
HAProxy Starter Guide
|
HAProxy Starter Guide
|
||||||
-----------------------
|
-----------------------
|
||||||
version 3.2
|
version 3.3
|
||||||
|
|
||||||
|
|
||||||
This document is an introduction to HAProxy for all those who don't know it, as
|
This document is an introduction to HAProxy for all those who don't know it, as
|
||||||
|
@ -893,7 +893,9 @@ Core class
|
|||||||
|
|
||||||
**context**: init, task, action
|
**context**: init, task, action
|
||||||
|
|
||||||
This function returns a new object of a *httpclient* class.
|
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.
|
||||||
|
|
||||||
:returns: A :ref:`httpclient_class` object.
|
:returns: A :ref:`httpclient_class` object.
|
||||||
|
|
||||||
@ -2581,7 +2583,9 @@ HTTPClient class
|
|||||||
.. js:class:: HTTPClient
|
.. js:class:: HTTPClient
|
||||||
|
|
||||||
The httpclient class allows issue of outbound HTTP requests through a simple
|
The httpclient class allows issue of outbound HTTP requests through a simple
|
||||||
API without the knowledge of HAProxy internals.
|
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.
|
||||||
|
|
||||||
.. js:function:: HTTPClient.get(httpclient, request)
|
.. js:function:: HTTPClient.get(httpclient, request)
|
||||||
.. js:function:: HTTPClient.head(httpclient, request)
|
.. js:function:: HTTPClient.head(httpclient, request)
|
||||||
@ -3916,21 +3920,25 @@ AppletTCP class
|
|||||||
*size* is missing, the function tries to read all the content of the stream
|
*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
|
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
|
case the function will return no longer than this delay, with the amount of
|
||||||
available data (possibly none).
|
available data, or nil if there is no data. An empty string is returned if the
|
||||||
|
connection is closed.
|
||||||
|
|
||||||
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
||||||
:param integer size: the required read size.
|
:param integer size: the required read size.
|
||||||
:returns: always return a string, the string can be empty if the connection is
|
:returns: return nil if the timeout has expired and no data was available but
|
||||||
closed.
|
can still be received. Otherwise, a string is returned, possibly an empty
|
||||||
|
string if the connection is closed.
|
||||||
|
|
||||||
.. js:function:: AppletTCP.try_receive(applet)
|
.. js:function:: AppletTCP.try_receive(applet)
|
||||||
|
|
||||||
Reads available data from the TCP stream and returns immediately. Returns a
|
Reads available data from the TCP stream and returns immediately. Returns a
|
||||||
string containing read bytes that may possibly be empty if no bytes are
|
string containing read bytes or nil if no bytes are available at that time. An
|
||||||
available at that time.
|
empty string is returned if the connection is closed.
|
||||||
|
|
||||||
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
||||||
:returns: always return a string, the string can be empty.
|
: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.
|
||||||
|
|
||||||
.. js:function:: AppletTCP.send(appletmsg)
|
.. js:function:: AppletTCP.send(appletmsg)
|
||||||
|
|
||||||
@ -4617,10 +4625,10 @@ HTTPMessage class
|
|||||||
added with the "chunked" value. In both cases, all existing "Content-Length"
|
added with the "chunked" value. In both cases, all existing "Content-Length"
|
||||||
and "Transfer-Encoding" headers are removed.
|
and "Transfer-Encoding" headers are removed.
|
||||||
|
|
||||||
This fnuction should be used in the filter context to be able to alter the
|
This function should be used in the filter context to be able to alter the
|
||||||
payload of the HTTP message. The internal state fo the HTTP message is updated
|
payload of the HTTP message. The internal state of the HTTP message is updated
|
||||||
accordingly. :js:func:`HTTPMessage.add_header()` or
|
accordingly. :js:func:`HTTPMessage.add_header()` or
|
||||||
:js:func:`HTTPMessage.set_header()` functions must to be used in that case.
|
:js:func:`HTTPMessage.set_header()` functions must be used in that case.
|
||||||
|
|
||||||
:param class_httpmessage http_msg: The manipulated HTTP message.
|
:param class_httpmessage http_msg: The manipulated HTTP message.
|
||||||
:param type length: The new payload length to set. It can be an integer or
|
:param type length: The new payload length to set. It can be an integer or
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
------------------------
|
------------------------
|
||||||
HAProxy Management Guide
|
HAProxy Management Guide
|
||||||
------------------------
|
------------------------
|
||||||
version 3.2
|
version 3.3
|
||||||
|
|
||||||
|
|
||||||
This document describes how to start, stop, manage, and troubleshoot HAProxy,
|
This document describes how to start, stop, manage, and troubleshoot HAProxy,
|
||||||
@ -1662,10 +1662,10 @@ acme status
|
|||||||
This command outputs, separated by a tab:
|
This command outputs, separated by a tab:
|
||||||
- The name of the certificate configured in haproxy
|
- The name of the certificate configured in haproxy
|
||||||
- The acme section used in the configuration
|
- The acme section used in the configuration
|
||||||
- The state of the acme task, either "Running" or "Scheduled"
|
- The state of the acme task, either "Running", "Scheduled" or "Stopped"
|
||||||
- The UTC expiration date of the certificate in ISO8601 format
|
- The UTC expiration date of the certificate in ISO8601 format
|
||||||
- The relative expiration time (0d if expired)
|
- The relative expiration time (0d if expired)
|
||||||
- The UTC expiration date of the certificate in ISO8601 format
|
- The UTC scheduled date of the certificate in ISO8601 format
|
||||||
- The relative schedule time (0d if Running)
|
- The relative schedule time (0d if Running)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -1724,8 +1724,9 @@ add server <backend>/<server> [args]*
|
|||||||
The <server> name must not be already used in the backend. A special
|
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
|
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
|
algorithm. A subset of keywords from the server config file statement can be
|
||||||
used to configure the server behavior. Also note that no settings will be
|
used to configure the server behavior (see "add server help" to list them).
|
||||||
reused from an hypothetical 'default-server' statement in the same backend.
|
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"
|
Currently a dynamic server is statically initialized with the "none"
|
||||||
init-addr method. This means that no resolution will be undertaken if a FQDN
|
init-addr method. This means that no resolution will be undertaken if a FQDN
|
||||||
@ -1755,78 +1756,10 @@ add server <backend>/<server> [args]*
|
|||||||
servers. Please refer to the "u-limit" global keyword documentation in this
|
servers. Please refer to the "u-limit" global keyword documentation in this
|
||||||
case.
|
case.
|
||||||
|
|
||||||
Here is the list of the currently supported keywords :
|
add server help
|
||||||
|
List the keywords supported for dynamic servers by the current haproxy
|
||||||
- agent-addr
|
version. Keyword syntax is similar to the server line from the configuration
|
||||||
- agent-check
|
file, please refer to their individual documentation for details.
|
||||||
- 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 ssl ca-file <cafile> <payload>
|
||||||
Add a new certificate to a ca-file. This command is useful when you reached
|
Add a new certificate to a ca-file. This command is useful when you reached
|
||||||
@ -3293,7 +3226,29 @@ show servers conn [<backend>]
|
|||||||
The output consists in a header line showing the fields titles, then one
|
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,
|
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
|
the address, port and a series or values. The number of fields varies
|
||||||
depending on thread count.
|
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.
|
||||||
|
|
||||||
Given the threaded nature of idle connections, it's important to understand
|
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
|
that some values may change once read, and that as such, consistency within a
|
||||||
|
@ -112,7 +112,7 @@ local function rotate_piece(piece, piece_id, px, py, board)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function render(applet, board, piece, piece_id, px, py, score)
|
function render(applet, board, piece, piece_id, px, py, score)
|
||||||
local output = clear_screen .. cursor_home
|
local output = cursor_home
|
||||||
output = output .. game_name .. " - Lines: " .. score .. "\r\n"
|
output = output .. game_name .. " - Lines: " .. score .. "\r\n"
|
||||||
output = output .. "+" .. string.rep("-", board_width * 2) .. "+\r\n"
|
output = output .. "+" .. string.rep("-", board_width * 2) .. "+\r\n"
|
||||||
for y = 1, board_height do
|
for y = 1, board_height do
|
||||||
@ -160,6 +160,7 @@ function handler(applet)
|
|||||||
end
|
end
|
||||||
|
|
||||||
applet:send(cursor_hide)
|
applet:send(cursor_hide)
|
||||||
|
applet:send(clear_screen)
|
||||||
|
|
||||||
-- fall the piece by one line every delay
|
-- fall the piece by one line every delay
|
||||||
local function fall_piece()
|
local function fall_piece()
|
||||||
@ -214,7 +215,7 @@ function handler(applet)
|
|||||||
|
|
||||||
local input = applet:receive(1, delay)
|
local input = applet:receive(1, delay)
|
||||||
if input then
|
if input then
|
||||||
if input == "q" then
|
if input == "" or input == "q" then
|
||||||
game_over = true
|
game_over = true
|
||||||
elseif input == "\27" then
|
elseif input == "\27" then
|
||||||
local a = applet:receive(1, delay)
|
local a = applet:receive(1, delay)
|
||||||
|
@ -282,6 +282,92 @@ static inline void applet_expect_data(struct appctx *appctx)
|
|||||||
se_fl_clr(appctx->sedesc, SE_FL_EXP_NO_DATA);
|
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(). */
|
/* Should only be used via wrappers applet_putchk() / applet_putchk_stress(). */
|
||||||
static inline int _applet_putchk(struct appctx *appctx, struct buffer *chunk,
|
static inline int _applet_putchk(struct appctx *appctx, struct buffer *chunk,
|
||||||
int stress)
|
int stress)
|
||||||
@ -318,9 +404,10 @@ static inline int _applet_putchk(struct appctx *appctx, struct buffer *chunk,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writes chunk <chunk> into the input channel of the stream attached to this
|
/* writes chunk <chunk> into the applet output buffer (see applet_get_outbuf).
|
||||||
* appctx's endpoint, and marks the SC_FL_NEED_ROOM on a channel full error.
|
*
|
||||||
* See ci_putchk() for the list of return codes.
|
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||||
|
* shutdown, invalid call...)
|
||||||
*/
|
*/
|
||||||
static inline int applet_putchk(struct appctx *appctx, struct buffer *chunk)
|
static inline int applet_putchk(struct appctx *appctx, struct buffer *chunk)
|
||||||
{
|
{
|
||||||
@ -333,9 +420,10 @@ static inline int applet_putchk_stress(struct appctx *appctx, struct buffer *chu
|
|||||||
return _applet_putchk(appctx, chunk, 1);
|
return _applet_putchk(appctx, chunk, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writes <len> chars from <blk> into the input channel of the stream attached
|
/* writes <len> chars from <blk> into the applet output buffer (see applet_get_outbuf).
|
||||||
* 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.
|
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||||
|
* shutdown, invalid call...)
|
||||||
*/
|
*/
|
||||||
static inline int applet_putblk(struct appctx *appctx, const char *blk, int len)
|
static inline int applet_putblk(struct appctx *appctx, const char *blk, int len)
|
||||||
{
|
{
|
||||||
@ -367,10 +455,11 @@ static inline int applet_putblk(struct appctx *appctx, const char *blk, int len)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writes chars from <str> up to the trailing zero (excluded) into the input
|
/* writes chars from <str> up to the trailing zero (excluded) into the applet
|
||||||
* channel of the stream attached to this appctx's endpoint, and marks the
|
* output buffer (see applet_get_outbuf).
|
||||||
* SC_FL_NEED_ROOM on a channel full error. See ci_putstr() for the list of
|
*
|
||||||
* return codes.
|
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||||
|
* shutdown, invalid call...)
|
||||||
*/
|
*/
|
||||||
static inline int applet_putstr(struct appctx *appctx, const char *str)
|
static inline int applet_putstr(struct appctx *appctx, const char *str)
|
||||||
{
|
{
|
||||||
@ -403,9 +492,10 @@ static inline int applet_putstr(struct appctx *appctx, const char *str)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writes character <chr> into the input channel of the stream attached to this
|
/* writes character <chr> into the applet's output buffer (see applet_get_outbuf).
|
||||||
* appctx's endpoint, and marks the SC_FL_NEED_ROOM on a channel full error.
|
*
|
||||||
* See ci_putchr() for the list of return codes.
|
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||||
|
* shutdown, invalid call...)
|
||||||
*/
|
*/
|
||||||
static inline int applet_putchr(struct appctx *appctx, char chr)
|
static inline int applet_putchr(struct appctx *appctx, char chr)
|
||||||
{
|
{
|
||||||
@ -438,6 +528,283 @@ static inline int applet_putchr(struct appctx *appctx, char chr)
|
|||||||
return ret;
|
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 */
|
#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 */
|
/* set the time of last session on the backend */
|
||||||
static inline void be_set_sess_last(struct proxy *be)
|
static inline void be_set_sess_last(struct proxy *be)
|
||||||
{
|
{
|
||||||
be->be_counters.last_sess = ns_to_sec(now_ns);
|
HA_ATOMIC_STORE(&be->be_counters.shared->tg[tgid - 1]->last_sess, ns_to_sec(now_ns));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function returns non-zero if the designated server will be
|
/* This function returns non-zero if the designated server will be
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 */
|
|
@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 */
|
|
@ -25,108 +25,144 @@
|
|||||||
|
|
||||||
#include <haproxy/freq_ctr-t.h>
|
#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 */
|
/* counters used by listeners and frontends */
|
||||||
struct fe_counters {
|
struct fe_counters_shared_tg {
|
||||||
unsigned int conn_max; /* max # of active sessions */
|
COUNTERS_SHARED_TG;
|
||||||
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) */
|
|
||||||
|
|
||||||
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 denied_sess; /* denied session requests (tcp-req-sess rules) */
|
||||||
long long failed_rewrites; /* failed rewrites (warning) */
|
long long denied_conn; /* denied connection requests (tcp-req-conn rules) */
|
||||||
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 */
|
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 {
|
union {
|
||||||
struct {
|
struct {
|
||||||
long long cum_req[4]; /* cumulated number of processed other/h1/h2/h3 requests */
|
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 */
|
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;
|
} http;
|
||||||
} p; /* protocol-specific stats */
|
} p; /* protocol-specific stats */
|
||||||
|
|
||||||
struct freq_ctr sess_per_sec; /* sessions per second on this server */
|
long long failed_req; /* failed requests (eg: invalid or timeout) */
|
||||||
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 */
|
|
||||||
|
|
||||||
unsigned long last_change; /* last time, when the state was changed */
|
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 */
|
||||||
|
|
||||||
|
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) */
|
||||||
|
|
||||||
|
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 comp_rsp; /* number of compressed responses */
|
||||||
|
long long rsp[6]; /* http response codes */
|
||||||
|
|
||||||
|
} 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 be_counters_shared {
|
||||||
|
COUNTERS_SHARED;
|
||||||
|
struct be_counters_shared_tg *tg[MAX_TGROUPS];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* counters used by servers and backends */
|
/* counters used by servers and backends */
|
||||||
struct be_counters {
|
struct be_counters {
|
||||||
|
struct be_counters_shared *shared; /* shared counters */
|
||||||
unsigned int conn_max; /* max # of active sessions */
|
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 cps_max; /* maximum of new connections received per second */
|
||||||
unsigned int sps_max; /* maximum of new connections accepted per second (sessions) */
|
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 nbpend_max; /* max number of pending connections with no server assigned yet */
|
||||||
unsigned int cur_sess_max; /* max number of currently active sessions */
|
unsigned int cur_sess_max; /* max number of currently active sessions */
|
||||||
|
|
||||||
long long bytes_in; /* number of bytes transferred from the client to the server */
|
struct freq_ctr _sess_per_sec; /* sessions per second on this frontend, used to compute sps_max (internal use only) */
|
||||||
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 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 */
|
unsigned int qtime_max, ctime_max, dtime_max, ttime_max; /* maximum of conn_time, queue_time, data_time, total_time observed */
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct {
|
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 */
|
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;
|
} http;
|
||||||
} p; /* protocol-specific stats */
|
} 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 */
|
#endif /* _HAPROXY_COUNTERS_T_H */
|
||||||
|
102
include/haproxy/counters.h
Normal file
102
include/haproxy/counters.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* 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 */
|
@ -499,6 +499,7 @@ 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)
|
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);
|
extern void sock_conn_iocb(int);
|
||||||
|
struct tgroup_info *tginfo = &ha_tgroup_info[tgid - 1];
|
||||||
int newstate;
|
int newstate;
|
||||||
|
|
||||||
/* conn_fd_handler should support edge-triggered FDs */
|
/* conn_fd_handler should support edge-triggered FDs */
|
||||||
@ -528,7 +529,7 @@ static inline void fd_insert(int fd, void *owner, void (*iocb)(int fd), int tgid
|
|||||||
BUG_ON(fdtab[fd].state != 0);
|
BUG_ON(fdtab[fd].state != 0);
|
||||||
BUG_ON(tgid < 1 || tgid > MAX_TGROUPS);
|
BUG_ON(tgid < 1 || tgid > MAX_TGROUPS);
|
||||||
|
|
||||||
thread_mask &= tg->threads_enabled;
|
thread_mask &= tginfo->threads_enabled;
|
||||||
BUG_ON(thread_mask == 0);
|
BUG_ON(thread_mask == 0);
|
||||||
|
|
||||||
fd_claim_tgid(fd, tgid);
|
fd_claim_tgid(fd, tgid);
|
||||||
|
@ -197,6 +197,7 @@ struct global {
|
|||||||
int pattern_cache; /* max number of entries in the pattern cache. */
|
int pattern_cache; /* max number of entries in the pattern cache. */
|
||||||
int sslcachesize; /* SSL cache size in session, defaults to 20000 */
|
int sslcachesize; /* SSL cache size in session, defaults to 20000 */
|
||||||
int comp_maxlevel; /* max HTTP compression level */
|
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_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_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 */
|
int pool_low_count; /* max number of opened fd before we stop using new idle connections */
|
||||||
|
@ -121,6 +121,7 @@ enum li_status {
|
|||||||
#define BC_SSL_O_NONE 0x0000
|
#define BC_SSL_O_NONE 0x0000
|
||||||
#define BC_SSL_O_NO_TLS_TICKETS 0x0100 /* disable session resumption tickets */
|
#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_PREF_CLIE_CIPH 0x0200 /* prefer client ciphers */
|
||||||
|
#define BC_SSL_O_STRICT_SNI 0x0400 /* refuse negotiation if sni doesn't match a certificate */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct tls_version_filter {
|
struct tls_version_filter {
|
||||||
@ -169,7 +170,6 @@ struct bind_conf {
|
|||||||
unsigned long long ca_ignerr_bitfield[IGNERR_BF_SIZE]; /* ignored verify errors in handshake if depth > 0 */
|
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 */
|
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 */
|
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 */
|
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_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 */
|
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 fe_counters *counters; /* statistics counters */
|
||||||
struct mt_list wait_queue; /* link element to make the listener wait for something (LI_LIMITED) */
|
struct mt_list wait_queue; /* link element to make the listener wait for something (LI_LIMITED) */
|
||||||
char *name; /* listener's name */
|
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 */
|
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 */
|
struct list by_fe; /* chaining in frontend's list of listeners */
|
||||||
|
@ -28,9 +28,6 @@ enum qcs_type {
|
|||||||
QCS_SRV_BIDI,
|
QCS_SRV_BIDI,
|
||||||
QCS_CLT_UNI,
|
QCS_CLT_UNI,
|
||||||
QCS_SRV_UNI,
|
QCS_SRV_UNI,
|
||||||
|
|
||||||
/* Must be the last one */
|
|
||||||
QCS_MAX_TYPES
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum qcc_app_st {
|
enum qcc_app_st {
|
||||||
@ -205,7 +202,7 @@ struct qcc_app_ops {
|
|||||||
/* Initialize <qcs> stream app context or leave it to NULL if rejected. */
|
/* Initialize <qcs> stream app context or leave it to NULL if rejected. */
|
||||||
int (*attach)(struct qcs *qcs, void *conn_ctx);
|
int (*attach)(struct qcs *qcs, void *conn_ctx);
|
||||||
|
|
||||||
/* Convert received HTTP payload to HTX. */
|
/* Convert received HTTP payload to HTX. Returns amount of decoded bytes from <b> or a negative error code. */
|
||||||
ssize_t (*rcv_buf)(struct qcs *qcs, struct buffer *b, int fin);
|
ssize_t (*rcv_buf)(struct qcs *qcs, struct buffer *b, int fin);
|
||||||
|
|
||||||
/* Convert HTX to HTTP payload for sending. */
|
/* Convert HTX to HTTP payload for sending. */
|
||||||
@ -235,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 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_ERRL_DONE 0x00000002 /* local error properly handled, connection can be released */
|
||||||
/* unused 0x00000004 */
|
#define QC_CF_IS_BACK 0x00000004 /* backend side */
|
||||||
#define QC_CF_CONN_FULL 0x00000008 /* no stream buffers available on connection */
|
#define QC_CF_CONN_FULL 0x00000008 /* no stream buffers available on connection */
|
||||||
/* unused 0x00000010 */
|
/* unused 0x00000010 */
|
||||||
#define QC_CF_ERR_CONN 0x00000020 /* fatal error reported by transport layer */
|
#define QC_CF_ERR_CONN 0x00000020 /* fatal error reported by transport layer */
|
||||||
|
@ -51,15 +51,7 @@ static inline int qmux_stream_rx_bufsz(void)
|
|||||||
return global.tune.bufsize - NCB_RESERVED_SZ;
|
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_MASK 0x3
|
||||||
#define QCS_ID_TYPE_SHIFT 2
|
|
||||||
/* The less significant bit of a stream ID is set for a server initiated stream */
|
/* The less significant bit of a stream ID is set for a server initiated stream */
|
||||||
#define QCS_ID_SRV_INTIATOR_BIT 0x1
|
#define QCS_ID_SRV_INTIATOR_BIT 0x1
|
||||||
/* This bit is set for unidirectional streams */
|
/* This bit is set for unidirectional streams */
|
||||||
@ -82,16 +74,6 @@ static inline int quic_stream_is_remote(struct qcc *qcc, uint64_t id)
|
|||||||
return !quic_stream_is_local(qcc, 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)
|
static inline char *qcs_st_to_str(enum qcs_state st)
|
||||||
{
|
{
|
||||||
switch (st) {
|
switch (st) {
|
||||||
|
@ -46,7 +46,25 @@
|
|||||||
|
|
||||||
#ifdef USE_QUIC_OPENSSL_COMPAT
|
#ifdef USE_QUIC_OPENSSL_COMPAT
|
||||||
#include <haproxy/quic_openssl_compat.h>
|
#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
|
||||||
|
#endif /* USE_QUIC_OPENSSL_COMPAT */
|
||||||
|
|
||||||
#if defined(OPENSSL_IS_AWSLC)
|
#if defined(OPENSSL_IS_AWSLC)
|
||||||
#define OPENSSL_NO_DH
|
#define OPENSSL_NO_DH
|
||||||
|
@ -311,6 +311,10 @@ struct proxy {
|
|||||||
char flags; /* bit field PR_FL_* */
|
char flags; /* bit field PR_FL_* */
|
||||||
enum pr_mode mode; /* mode = PR_MODE_TCP, PR_MODE_HTTP, ... */
|
enum pr_mode mode; /* mode = PR_MODE_TCP, PR_MODE_HTTP, ... */
|
||||||
char cap; /* supported capabilities (PR_CAP_*) */
|
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 */
|
unsigned int maxconn; /* max # of active streams on the frontend */
|
||||||
|
|
||||||
int options; /* PR_O_REDISP, PR_O_TRANSP, ... */
|
int options; /* PR_O_REDISP, PR_O_TRANSP, ... */
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <haproxy/thread.h>
|
#include <haproxy/thread.h>
|
||||||
|
|
||||||
extern struct proxy *proxies_list;
|
extern struct proxy *proxies_list;
|
||||||
|
extern struct list proxies;
|
||||||
extern struct eb_root used_proxy_id; /* list of proxy IDs in use */
|
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 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 */
|
extern struct eb_root proxy_by_name; /* tree of proxies sorted by name */
|
||||||
@ -135,22 +136,24 @@ static inline void proxy_reset_timeouts(struct proxy *proxy)
|
|||||||
/* increase the number of cumulated connections received on the designated frontend */
|
/* 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)
|
static inline void proxy_inc_fe_conn_ctr(struct listener *l, struct proxy *fe)
|
||||||
{
|
{
|
||||||
_HA_ATOMIC_INC(&fe->fe_counters.cum_conn);
|
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->cum_conn);
|
||||||
if (l && l->counters)
|
if (l && l->counters)
|
||||||
_HA_ATOMIC_INC(&l->counters->cum_conn);
|
_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_UPDATE_MAX(&fe->fe_counters.cps_max,
|
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 */
|
/* 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)
|
static inline void proxy_inc_fe_sess_ctr(struct listener *l, struct proxy *fe)
|
||||||
{
|
{
|
||||||
|
|
||||||
_HA_ATOMIC_INC(&fe->fe_counters.cum_sess);
|
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->cum_sess);
|
||||||
if (l && l->counters)
|
if (l && l->counters)
|
||||||
_HA_ATOMIC_INC(&l->counters->cum_sess);
|
_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_UPDATE_MAX(&fe->fe_counters.sps_max,
|
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.
|
/* increase the number of cumulated HTTP sessions on the designated frontend.
|
||||||
@ -160,20 +163,21 @@ static inline void proxy_inc_fe_cum_sess_ver_ctr(struct listener *l, struct prox
|
|||||||
unsigned int http_ver)
|
unsigned int http_ver)
|
||||||
{
|
{
|
||||||
if (http_ver == 0 ||
|
if (http_ver == 0 ||
|
||||||
http_ver > sizeof(fe->fe_counters.cum_sess_ver) / sizeof(*fe->fe_counters.cum_sess_ver))
|
http_ver > sizeof(fe->fe_counters.shared->tg[tgid - 1]->cum_sess_ver) / sizeof(*fe->fe_counters.shared->tg[tgid - 1]->cum_sess_ver))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_HA_ATOMIC_INC(&fe->fe_counters.cum_sess_ver[http_ver - 1]);
|
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->cum_sess_ver[http_ver - 1]);
|
||||||
if (l && l->counters)
|
if (l && l->counters)
|
||||||
_HA_ATOMIC_INC(&l->counters->cum_sess_ver[http_ver - 1]);
|
_HA_ATOMIC_INC(&l->counters->shared->tg[tgid - 1]->cum_sess_ver[http_ver - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* increase the number of cumulated streams on the designated backend */
|
/* increase the number of cumulated streams on the designated backend */
|
||||||
static inline void proxy_inc_be_ctr(struct proxy *be)
|
static inline void proxy_inc_be_ctr(struct proxy *be)
|
||||||
{
|
{
|
||||||
_HA_ATOMIC_INC(&be->be_counters.cum_sess);
|
_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_UPDATE_MAX(&be->be_counters.sps_max,
|
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.
|
/* increase the number of cumulated requests on the designated frontend.
|
||||||
@ -183,14 +187,15 @@ static inline void proxy_inc_be_ctr(struct proxy *be)
|
|||||||
static inline void proxy_inc_fe_req_ctr(struct listener *l, struct proxy *fe,
|
static inline void proxy_inc_fe_req_ctr(struct listener *l, struct proxy *fe,
|
||||||
unsigned int http_ver)
|
unsigned int http_ver)
|
||||||
{
|
{
|
||||||
if (http_ver >= sizeof(fe->fe_counters.p.http.cum_req) / sizeof(*fe->fe_counters.p.http.cum_req))
|
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))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_HA_ATOMIC_INC(&fe->fe_counters.p.http.cum_req[http_ver]);
|
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->p.http.cum_req[http_ver]);
|
||||||
if (l && l->counters)
|
if (l && l->counters)
|
||||||
_HA_ATOMIC_INC(&l->counters->p.http.cum_req[http_ver]);
|
_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_UPDATE_MAX(&fe->fe_counters.p.http.rps_max,
|
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.p.http.rps_max,
|
||||||
update_freq_ctr(&fe->fe_counters.req_per_sec, 1));
|
update_freq_ctr(&fe->fe_counters.p.http._req_per_sec, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns non-zero if the proxy is configured to retry a request if we got that status, 0 otherwise */
|
/* Returns non-zero if the proxy is configured to retry a request if we got that status, 0 otherwise */
|
||||||
|
@ -28,22 +28,22 @@
|
|||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include <haproxy/cbuf-t.h>
|
#include <import/ebtree-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/openssl-compat.h>
|
||||||
#include <haproxy/mux_quic-t.h>
|
|
||||||
#include <haproxy/quic_cid-t.h>
|
#include <haproxy/quic_cid-t.h>
|
||||||
#include <haproxy/quic_cc-t.h>
|
#include <haproxy/quic_cc-t.h>
|
||||||
#include <haproxy/quic_loss-t.h>
|
#include <haproxy/quic_frame-t.h>
|
||||||
#include <haproxy/quic_openssl_compat-t.h>
|
#include <haproxy/quic_openssl_compat-t.h>
|
||||||
#include <haproxy/quic_stats-t.h>
|
#include <haproxy/quic_stats-t.h>
|
||||||
#include <haproxy/quic_tls-t.h>
|
#include <haproxy/quic_tls-t.h>
|
||||||
#include <haproxy/quic_tp-t.h>
|
#include <haproxy/quic_tp-t.h>
|
||||||
#include <haproxy/task.h>
|
#include <haproxy/show_flags-t.h>
|
||||||
|
#include <haproxy/ssl_sock-t.h>
|
||||||
#include <import/ebtree-t.h>
|
#include <haproxy/task-t.h>
|
||||||
|
|
||||||
typedef unsigned long long ull;
|
typedef unsigned long long ull;
|
||||||
|
|
||||||
@ -228,6 +228,9 @@ struct quic_version {
|
|||||||
extern const struct quic_version quic_versions[];
|
extern const struct quic_version quic_versions[];
|
||||||
extern const size_t quic_versions_nb;
|
extern const size_t quic_versions_nb;
|
||||||
extern const struct quic_version *preferred_version;
|
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 */
|
/* unused: 0x01 */
|
||||||
/* Flag the packet number space as requiring an ACK frame to be sent. */
|
/* Flag the packet number space as requiring an ACK frame to be sent. */
|
||||||
@ -279,6 +282,10 @@ struct quic_conn_cntrs {
|
|||||||
long long streams_blocked_uni; /* total number of times STREAMS_BLOCKED_UNI frame was received */
|
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 \
|
#define QUIC_CONN_COMMON \
|
||||||
struct { \
|
struct { \
|
||||||
/* Connection owned socket FD. */ \
|
/* Connection owned socket FD. */ \
|
||||||
@ -301,6 +308,7 @@ struct quic_conn_cntrs {
|
|||||||
/* Number of received bytes. */ \
|
/* Number of received bytes. */ \
|
||||||
uint64_t rx; \
|
uint64_t rx; \
|
||||||
} bytes; \
|
} bytes; \
|
||||||
|
size_t max_udp_payload; \
|
||||||
/* First DCID used by client on its Initial packet. */ \
|
/* First DCID used by client on its Initial packet. */ \
|
||||||
struct quic_cid odcid; \
|
struct quic_cid odcid; \
|
||||||
/* DCID of our endpoint - not updated when a new DCID is used */ \
|
/* DCID of our endpoint - not updated when a new DCID is used */ \
|
||||||
@ -311,7 +319,7 @@ struct quic_conn_cntrs {
|
|||||||
* with a connection \
|
* with a connection \
|
||||||
*/ \
|
*/ \
|
||||||
struct eb_root *cids; \
|
struct eb_root *cids; \
|
||||||
struct listener *li; /* only valid for frontend connections */ \
|
enum obj_type *target; \
|
||||||
/* Idle timer task */ \
|
/* Idle timer task */ \
|
||||||
struct task *idle_timer_task; \
|
struct task *idle_timer_task; \
|
||||||
unsigned int idle_expire; \
|
unsigned int idle_expire; \
|
||||||
@ -334,7 +342,10 @@ struct quic_conn {
|
|||||||
int tps_tls_ext;
|
int tps_tls_ext;
|
||||||
int state;
|
int state;
|
||||||
enum qc_mux_state mux_state; /* status of the connection/mux layer */
|
enum qc_mux_state mux_state; /* status of the connection/mux layer */
|
||||||
#ifdef USE_QUIC_OPENSSL_COMPAT
|
#ifdef HAVE_OPENSSL_QUIC
|
||||||
|
uint32_t prot_level;
|
||||||
|
#endif
|
||||||
|
#if defined(USE_QUIC_OPENSSL_COMPAT) || defined(HAVE_OPENSSL_QUIC)
|
||||||
unsigned char enc_params[QUIC_TP_MAX_ENCLEN]; /* encoded QUIC transport parameters */
|
unsigned char enc_params[QUIC_TP_MAX_ENCLEN]; /* encoded QUIC transport parameters */
|
||||||
size_t enc_params_len;
|
size_t enc_params_len;
|
||||||
#endif
|
#endif
|
||||||
@ -383,10 +394,10 @@ struct quic_conn {
|
|||||||
/* RX buffer */
|
/* RX buffer */
|
||||||
struct buffer buf;
|
struct buffer buf;
|
||||||
struct list pkt_list;
|
struct list pkt_list;
|
||||||
struct {
|
|
||||||
/* Number of open or closed streams */
|
/* first unhandled streams ID, set by MUX after release */
|
||||||
uint64_t nb_streams;
|
uint64_t stream_max_uni;
|
||||||
} strms[QCS_MAX_TYPES];
|
uint64_t stream_max_bidi;
|
||||||
} rx;
|
} rx;
|
||||||
struct {
|
struct {
|
||||||
struct quic_tls_kp prv_rx;
|
struct quic_tls_kp prv_rx;
|
||||||
@ -449,6 +460,7 @@ struct quic_conn_closed {
|
|||||||
#define QUIC_FL_CONN_HPKTNS_DCD (1U << 16) /* Handshake packet number space discarded */
|
#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_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_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 */
|
/* gap here */
|
||||||
#define QUIC_FL_CONN_TO_KILL (1U << 24) /* Unusable connection, to be killed */
|
#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) */
|
#define QUIC_FL_CONN_TX_TP_RECEIVED (1U << 25) /* Peer transport parameters have been received (used for the transmitting part) */
|
||||||
|
@ -69,7 +69,8 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
|||||||
struct quic_connection_id *conn_id,
|
struct quic_connection_id *conn_id,
|
||||||
struct sockaddr_storage *local_addr,
|
struct sockaddr_storage *local_addr,
|
||||||
struct sockaddr_storage *peer_addr,
|
struct sockaddr_storage *peer_addr,
|
||||||
int server, int token, void *owner);
|
int token, void *owner,
|
||||||
|
struct connection *conn);
|
||||||
int quic_build_post_handshake_frames(struct quic_conn *qc);
|
int quic_build_post_handshake_frames(struct quic_conn *qc);
|
||||||
const struct quic_version *qc_supported_version(uint32_t version);
|
const struct quic_version *qc_supported_version(uint32_t version);
|
||||||
int quic_peer_validated_addr(struct quic_conn *qc);
|
int quic_peer_validated_addr(struct quic_conn *qc);
|
||||||
@ -163,6 +164,22 @@ static inline void quic_free_ncbuf(struct ncbuf *ncbuf)
|
|||||||
*ncbuf = NCBUF_NULL;
|
*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 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_connection_close(struct quic_conn *qc, const struct quic_err err);
|
||||||
void quic_set_tls_alert(struct quic_conn *qc, int alert);
|
void quic_set_tls_alert(struct quic_conn *qc, int alert);
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include <haproxy/quic_rx-t.h>
|
#include <haproxy/quic_rx-t.h>
|
||||||
|
|
||||||
int quic_dgram_parse(struct quic_dgram *dgram, struct quic_conn *from_qc,
|
int quic_dgram_parse(struct quic_dgram *dgram, struct quic_conn *from_qc,
|
||||||
struct listener *li);
|
enum obj_type *obj_type);
|
||||||
int qc_treat_rx_pkts(struct quic_conn *qc);
|
int qc_treat_rx_pkts(struct quic_conn *qc);
|
||||||
int qc_parse_hd_form(struct quic_rx_packet *pkt,
|
int qc_parse_hd_form(struct quic_rx_packet *pkt,
|
||||||
unsigned char **pos, const unsigned char *end);
|
unsigned char **pos, const unsigned char *end);
|
||||||
|
@ -31,7 +31,9 @@
|
|||||||
|
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/connection-t.h>
|
#include <haproxy/connection-t.h>
|
||||||
|
#include <haproxy/fd-t.h>
|
||||||
#include <haproxy/listener-t.h>
|
#include <haproxy/listener-t.h>
|
||||||
|
#include <haproxy/obj_type.h>
|
||||||
#include <haproxy/quic_conn-t.h>
|
#include <haproxy/quic_conn-t.h>
|
||||||
#include <haproxy/quic_sock-t.h>
|
#include <haproxy/quic_sock-t.h>
|
||||||
|
|
||||||
@ -77,7 +79,8 @@ static inline char qc_test_fd(struct quic_conn *qc)
|
|||||||
*/
|
*/
|
||||||
static inline int qc_fd(struct quic_conn *qc)
|
static inline int qc_fd(struct quic_conn *qc)
|
||||||
{
|
{
|
||||||
return qc_test_fd(qc) ? qc->fd : qc->li->rx.fd;
|
/* TODO: check this: For backends, qc->fd is always initialized */
|
||||||
|
return qc_test_fd(qc) ? qc->fd : __objt_listener(qc->target)->rx.fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to increment <l> handshake current counter. If listener limit is
|
/* Try to increment <l> handshake current counter. If listener limit is
|
||||||
|
@ -34,8 +34,10 @@
|
|||||||
#include <haproxy/ssl_sock-t.h>
|
#include <haproxy/ssl_sock-t.h>
|
||||||
|
|
||||||
int ssl_quic_initial_ctx(struct bind_conf *bind_conf);
|
int ssl_quic_initial_ctx(struct bind_conf *bind_conf);
|
||||||
int qc_alloc_ssl_sock_ctx(struct quic_conn *qc);
|
SSL_CTX *ssl_quic_srv_new_ssl_ctx(void);
|
||||||
|
int qc_alloc_ssl_sock_ctx(struct quic_conn *qc, struct connection *conn);
|
||||||
int qc_ssl_provide_all_quic_data(struct quic_conn *qc, struct ssl_sock_ctx *ctx);
|
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)
|
static inline void qc_free_ssl_sock_ctx(struct ssl_sock_ctx **ctx)
|
||||||
{
|
{
|
||||||
|
@ -291,6 +291,29 @@ 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
|
/* Return the address of the QUIC TLS encryption level associated to <level> internal
|
||||||
* encryption level and attached to <qc> QUIC connection if succeeded, or
|
* encryption level and attached to <qc> QUIC connection if succeeded, or
|
||||||
* NULL if failed.
|
* NULL if failed.
|
||||||
|
@ -26,6 +26,9 @@ int qc_lstnr_params_init(struct quic_conn *qc,
|
|||||||
const unsigned char *dcid, size_t dcidlen,
|
const unsigned char *dcid, size_t dcidlen,
|
||||||
const unsigned char *scid, size_t scidlen,
|
const unsigned char *scid, size_t scidlen,
|
||||||
const struct quic_cid *token_odcid);
|
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).
|
/* Dump <cid> transport parameter connection ID value if present (non null length).
|
||||||
* Used only for debugging purposes.
|
* Used only for debugging purposes.
|
||||||
|
@ -99,5 +99,6 @@ struct quic_rx_crypto_frm {
|
|||||||
#define QUIC_EV_CONN_KP (1ULL << 50)
|
#define QUIC_EV_CONN_KP (1ULL << 50)
|
||||||
#define QUIC_EV_CONN_SSL_COMPAT (1ULL << 51)
|
#define QUIC_EV_CONN_SSL_COMPAT (1ULL << 51)
|
||||||
#define QUIC_EV_CONN_BIND_TID (1ULL << 52)
|
#define QUIC_EV_CONN_BIND_TID (1ULL << 52)
|
||||||
|
#define QUIC_EV_CONN_RELEASE_RCD (1ULL << 53)
|
||||||
|
|
||||||
#endif /* _HAPROXY_QUIC_TRACE_T_H */
|
#endif /* _HAPROXY_QUIC_TRACE_T_H */
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <haproxy/buf-t.h>
|
#include <haproxy/buf-t.h>
|
||||||
#include <haproxy/list-t.h>
|
#include <haproxy/list-t.h>
|
||||||
|
#include <haproxy/pool.h>
|
||||||
#include <haproxy/quic_conn-t.h>
|
#include <haproxy/quic_conn-t.h>
|
||||||
#include <haproxy/quic_tls-t.h>
|
#include <haproxy/quic_tls-t.h>
|
||||||
#include <haproxy/quic_pacing-t.h>
|
#include <haproxy/quic_pacing-t.h>
|
||||||
|
@ -8,6 +8,16 @@
|
|||||||
#include <haproxy/buf-t.h>
|
#include <haproxy/buf-t.h>
|
||||||
#include <haproxy/chunk.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)
|
static inline void bdata_ctr_init(struct bdata_ctr *ctr)
|
||||||
{
|
{
|
||||||
ctr->tot = 0;
|
ctr->tot = 0;
|
||||||
|
@ -171,6 +171,7 @@ enum srv_init_state {
|
|||||||
#define SRV_F_DEFSRV_USE_SSL 0x4000 /* default-server uses SSL */
|
#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_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_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) */
|
/* configured server options for send-proxy (server->pp_opts) */
|
||||||
#define SRV_PP_V1 0x0001 /* proxy protocol version 1 */
|
#define SRV_PP_V1 0x0001 /* proxy protocol version 1 */
|
||||||
@ -477,6 +478,9 @@ struct server {
|
|||||||
char *alpn_str; /* ALPN protocol string */
|
char *alpn_str; /* ALPN protocol string */
|
||||||
int alpn_len; /* ALPN protocol string length */
|
int alpn_len; /* ALPN protocol string length */
|
||||||
} ssl_ctx;
|
} 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 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 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 */
|
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);
|
void srv_take(struct server *srv);
|
||||||
struct server *srv_drop(struct server *srv);
|
struct server *srv_drop(struct server *srv);
|
||||||
void srv_free_params(struct server *srv);
|
void srv_free_params(struct server *srv);
|
||||||
int srv_init_per_thr(struct server *srv);
|
int srv_init(struct server *srv);
|
||||||
void srv_set_ssl(struct server *s, int use_ssl);
|
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_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);
|
const char *srv_op_st_chg_cause(enum srv_op_st_chg_cause cause);
|
||||||
@ -181,15 +181,16 @@ const struct mux_ops *srv_get_ws_proto(struct server *srv);
|
|||||||
/* increase the number of cumulated streams on the designated server */
|
/* increase the number of cumulated streams on the designated server */
|
||||||
static inline void srv_inc_sess_ctr(struct server *s)
|
static inline void srv_inc_sess_ctr(struct server *s)
|
||||||
{
|
{
|
||||||
_HA_ATOMIC_INC(&s->counters.cum_sess);
|
_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_UPDATE_MAX(&s->counters.sps_max,
|
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 */
|
/* set the time of last session on the designated server */
|
||||||
static inline void srv_set_sess_last(struct server *s)
|
static inline void srv_set_sess_last(struct server *s)
|
||||||
{
|
{
|
||||||
s->counters.last_sess = ns_to_sec(now_ns);
|
HA_ATOMIC_STORE(&s->counters.shared->tg[tgid - 1]->last_sess, ns_to_sec(now_ns));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns the current server throttle rate between 0 and 100% */
|
/* returns the current server throttle rate between 0 and 100% */
|
||||||
@ -319,6 +320,39 @@ static inline int srv_is_transparent(const struct server *srv)
|
|||||||
(srv->flags & SRV_F_MAPPORTS);
|
(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 */
|
#endif /* _HAPROXY_SERVER_H */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -28,9 +28,11 @@
|
|||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/connection-t.h>
|
#include <haproxy/connection-t.h>
|
||||||
#include <haproxy/listener-t.h>
|
#include <haproxy/listener-t.h>
|
||||||
|
#include <haproxy/protocol-t.h>
|
||||||
#include <haproxy/sock-t.h>
|
#include <haproxy/sock-t.h>
|
||||||
|
|
||||||
int sock_create_server_socket(struct connection *conn, struct proxy *be, int *stream_err);
|
int sock_create_server_socket(struct connection *conn, struct proxy *be,
|
||||||
|
enum proto_type proto_type, int sock_type, int *stream_err);
|
||||||
void sock_enable(struct receiver *rx);
|
void sock_enable(struct receiver *rx);
|
||||||
void sock_disable(struct receiver *rx);
|
void sock_disable(struct receiver *rx);
|
||||||
void sock_unbind(struct receiver *rx);
|
void sock_unbind(struct receiver *rx);
|
||||||
|
@ -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,
|
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);
|
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,
|
int ckch_inst_new_load_srv_store(const char *path, struct ckch_store *ckchs,
|
||||||
struct ckch_inst **ckchi, char **err);
|
struct ckch_inst **ckchi, char **err, int is_quic);
|
||||||
int ckch_inst_rebuild(struct ckch_store *ckch_store, struct ckch_inst *ckchi,
|
int ckch_inst_rebuild(struct ckch_store *ckch_store, struct ckch_inst *ckchi,
|
||||||
struct ckch_inst **new_inst, char **err);
|
struct ckch_inst **new_inst, char **err);
|
||||||
|
|
||||||
|
@ -342,6 +342,11 @@ enum stat_idx_info {
|
|||||||
ST_I_INF_MAX
|
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. */
|
/* Represent an exposed statistic. */
|
||||||
struct stat_col {
|
struct stat_col {
|
||||||
const char *name; /* short name, used notably in CSV headers */
|
const char *name; /* short name, used notably in CSV headers */
|
||||||
@ -350,8 +355,8 @@ struct stat_col {
|
|||||||
|
|
||||||
uint32_t type; /* combination of field_nature and field_format */
|
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 */
|
uint8_t cap; /* mask of stats_domain_px_cap to restrain metrics to an object types subset */
|
||||||
uint8_t generic; /* bit set if generic */
|
/* 1 byte hole */
|
||||||
/* 2 bytes hole */
|
uint16_t flags; /* STAT_COL_FL_* flags */
|
||||||
|
|
||||||
/* used only for generic metrics */
|
/* used only for generic metrics */
|
||||||
struct {
|
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. */
|
/* 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)
|
static inline int stcol_is_generic(const struct stat_col *col)
|
||||||
{
|
{
|
||||||
return col->generic;
|
return col->flags & STAT_COL_FL_GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline enum field_format stcol_format(const struct stat_col *col)
|
static inline enum field_format stcol_format(const struct stat_col *col)
|
||||||
|
@ -362,8 +362,8 @@ static inline void stream_choose_redispatch(struct stream *s)
|
|||||||
s->scb->state = SC_ST_REQ;
|
s->scb->state = SC_ST_REQ;
|
||||||
} else {
|
} else {
|
||||||
if (objt_server(s->target))
|
if (objt_server(s->target))
|
||||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.retries);
|
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->tg[tgid - 1]->retries);
|
||||||
_HA_ATOMIC_INC(&s->be->be_counters.retries);
|
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->retries);
|
||||||
s->scb->state = SC_ST_ASS;
|
s->scb->state = SC_ST_ASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#ifdef CONFIG_PRODUCT_BRANCH
|
#ifdef CONFIG_PRODUCT_BRANCH
|
||||||
#define PRODUCT_BRANCH CONFIG_PRODUCT_BRANCH
|
#define PRODUCT_BRANCH CONFIG_PRODUCT_BRANCH
|
||||||
#else
|
#else
|
||||||
#define PRODUCT_BRANCH "3.2"
|
#define PRODUCT_BRANCH "3.3"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PRODUCT_STATUS
|
#ifdef CONFIG_PRODUCT_STATUS
|
||||||
|
@ -14,7 +14,7 @@ See also: doc/regression-testing.txt
|
|||||||
|
|
||||||
* vtest compilation *
|
* vtest compilation *
|
||||||
|
|
||||||
$ git clone https://github.com/vtest/VTest
|
$ git clone https://github.com/vtest/VTest2
|
||||||
|
|
||||||
$ cd VTest
|
$ cd VTest
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
vtest "Test for balance URI"
|
vtest "Test for balance URI"
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
#REQUIRE_VERSION=2.3
|
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
rxreq
|
rxreq
|
||||||
|
2
reg-tests/cache/caching_rules.vtc
vendored
2
reg-tests/cache/caching_rules.vtc
vendored
@ -2,8 +2,6 @@ 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 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.
|
# 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
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
|
2
reg-tests/cache/expires.vtc
vendored
2
reg-tests/cache/expires.vtc
vendored
@ -1,7 +1,5 @@
|
|||||||
varnishtest "Expires support"
|
varnishtest "Expires support"
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.3
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
|
2
reg-tests/cache/if-modified-since.vtc
vendored
2
reg-tests/cache/if-modified-since.vtc
vendored
@ -1,7 +1,5 @@
|
|||||||
varnishtest "If-Modified-Since support"
|
varnishtest "If-Modified-Since support"
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.3
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
|
2
reg-tests/cache/if-none-match.vtc
vendored
2
reg-tests/cache/if-none-match.vtc
vendored
@ -1,7 +1,5 @@
|
|||||||
varnishtest "If-None-Match support"
|
varnishtest "If-None-Match support"
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.3
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
|
2
reg-tests/cache/post_on_entry.vtc
vendored
2
reg-tests/cache/post_on_entry.vtc
vendored
@ -1,7 +1,5 @@
|
|||||||
varnishtest "A successful unsafe method (POST for instance) on a cached entry must disable it."
|
varnishtest "A successful unsafe method (POST for instance) on a cached entry must disable it."
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
|
2
reg-tests/cache/vary.vtc
vendored
2
reg-tests/cache/vary.vtc
vendored
@ -1,7 +1,5 @@
|
|||||||
varnishtest "Vary support"
|
varnishtest "Vary support"
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
|
2
reg-tests/cache/vary_accept_encoding.vtc
vendored
2
reg-tests/cache/vary_accept_encoding.vtc
vendored
@ -1,7 +1,5 @@
|
|||||||
varnishtest "Check the Accept-Encoding processing implemented in the Vary mechanism"
|
varnishtest "Check the Accept-Encoding processing implemented in the Vary mechanism"
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
|
@ -6,7 +6,6 @@ feature ignore_unknown_macro
|
|||||||
# The first health-checks passed tests are checked for all these servers
|
# The first health-checks passed tests are checked for all these servers
|
||||||
# thanks to syslog messages.
|
# thanks to syslog messages.
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
#EXCLUDE_TARGETS=freebsd
|
#EXCLUDE_TARGETS=freebsd
|
||||||
#REGTEST_TYPE=slow
|
#REGTEST_TYPE=slow
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
varnishtest "Health-checks"
|
varnishtest "Health-checks"
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
#EXCLUDE_TARGETS=freebsd,osx,generic
|
#EXCLUDE_TARGETS=freebsd,osx,generic
|
||||||
#REGTEST_TYPE=slow
|
#REGTEST_TYPE=slow
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
varnishtest "Health-check test"
|
varnishtest "Health-check test"
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
#EXCLUDE_TARGETS=freebsd
|
#EXCLUDE_TARGETS=freebsd
|
||||||
#REGTEST_TYPE=slow
|
#REGTEST_TYPE=slow
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
varnishtest "Health-checks: http-check send test"
|
varnishtest "Health-checks: http-check send test"
|
||||||
#REGTEST_TYPE=slow
|
#REGTEST_TYPE=slow
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
# This script tests HTTP health-checks and more particularly the "http-check
|
# This script tests HTTP health-checks and more particularly the "http-check
|
||||||
|
@ -5,8 +5,6 @@ feature cmd "$HAPROXY_PROGRAM -cc 'feature(TPROXY)'"
|
|||||||
# as private and should only be reused for requests of the same session.
|
# as private and should only be reused for requests of the same session.
|
||||||
# This is similar to the http-reuse never mode
|
# This is similar to the http-reuse never mode
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
haproxy h1 -conf {
|
haproxy h1 -conf {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
varnishtest "Test the http-reuse with special connection parameters"
|
varnishtest "Test the http-reuse with special connection parameters"
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
#REQUIRE_OPTIONS=OPENSSL
|
#REQUIRE_OPTIONS=OPENSSL
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
@ -4,8 +4,6 @@ varnishtest "Test the proper interaction between http-reuse and dispatch mode"
|
|||||||
# reused for requests of the same session
|
# reused for requests of the same session
|
||||||
# This is similar to the http-reuse never mode
|
# This is similar to the http-reuse never mode
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
haproxy h1 -conf {
|
haproxy h1 -conf {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
varnishtest "Check that the TLVs are properly validated"
|
varnishtest "Check that the TLVs are properly validated"
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
# We need one HAProxy for each test, because apparently the connection by
|
# We need one HAProxy for each test, because apparently the connection by
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
varnishtest "Test connection upgrades from TCP to HTTP"
|
varnishtest "Test connection upgrades from TCP to HTTP"
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
varnishtest "fix converters Test"
|
varnishtest "fix converters Test"
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
varnishtest "iif converter Test"
|
varnishtest "iif converter Test"
|
||||||
#REQUIRE_VERSION=2.3
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
varnishtest "JSON Query converters Test"
|
varnishtest "JSON Query converters Test"
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
varnishtest "mqtt converters Test"
|
varnishtest "mqtt converters Test"
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
@ -235,4 +234,4 @@ client c3_31_1 -connect ${h1_fe1_sock} {
|
|||||||
# Valid MQTT 3.1 CONNECT packet (id: test_sub - username: test - passwd: passwd)
|
# Valid MQTT 3.1 CONNECT packet (id: test_sub - username: test - passwd: passwd)
|
||||||
sendhex "102400064d514973647003c200000008746573745f7375620004746573740006706173737764"
|
sendhex "102400064d514973647003c200000008746573745f7375620004746573740006706173737764"
|
||||||
recv 4
|
recv 4
|
||||||
} -run
|
} -run
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
varnishtest "url_enc converter test"
|
varnishtest "url_enc converter test"
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
varnishtest "Filtering test with several filters and random forwarding (via trace filter)"
|
varnishtest "Filtering test with several filters and random forwarding (via trace filter)"
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
#REQUIRE_OPTION=ZLIB|SLZ
|
#REQUIRE_OPTION=ZLIB|SLZ
|
||||||
#REGTEST_TYPE=slow
|
#REGTEST_TYPE=slow
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ varnishtest "HTTP request tests: H1 request target parsing"
|
|||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=3.0
|
feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(3.0-dev0)'"
|
||||||
|
|
||||||
haproxy h1 -conf {
|
haproxy h1 -conf {
|
||||||
global
|
global
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
varnishtest "A test to be sure payload is skipped for bodyless responses"
|
varnishtest "A test to be sure payload is skipped for bodyless responses"
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
rxreq
|
rxreq
|
||||||
txresp \
|
txresp \
|
||||||
|
@ -5,8 +5,6 @@ feature cmd "$HAPROXY_PROGRAM $HAPROXY_ARGS -cc 'enabled(FAST-FORWARD)'"
|
|||||||
feature cmd "$HAPROXY_PROGRAM $HAPROXY_ARGS -cc 'enabled(SPLICE)'"
|
feature cmd "$HAPROXY_PROGRAM $HAPROXY_ARGS -cc 'enabled(SPLICE)'"
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
rxreq
|
rxreq
|
||||||
txresp \
|
txresp \
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
varnishtest "cannot add the HTX EOM block because the buffer is full"
|
|
||||||
feature ignore_unknown_macro
|
|
||||||
|
|
||||||
#REQUIRE_VERSION_BELOW=2.4
|
|
||||||
#REGTEST_TYPE=devel
|
|
||||||
|
|
||||||
# This test checks that an HTTP message is properly processed when we failed to
|
|
||||||
# add the HTX EOM block in an HTX message during the parsing because the buffer
|
|
||||||
# is full. Some space must be released in the buffer to make it possible. This
|
|
||||||
# requires an extra pass in the H1 multiplexer. Here, we must be sure the mux is
|
|
||||||
# called while there is no more incoming data.
|
|
||||||
|
|
||||||
server s1 {
|
|
||||||
rxreq
|
|
||||||
expect req.bodylen == 15200
|
|
||||||
txresp -bodylen 15220
|
|
||||||
} -start
|
|
||||||
|
|
||||||
syslog S -level info {
|
|
||||||
recv
|
|
||||||
expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 be1/srv1 [0-9]*/[0-9]*/[0-9]*/[0-9]*/[0-9]* 200 .* - - ---- .* .* \"GET / HTTP/1\\.1\""
|
|
||||||
} -start
|
|
||||||
|
|
||||||
haproxy h1 -conf {
|
|
||||||
global
|
|
||||||
tune.bufsize 16384
|
|
||||||
tune.maxrewrite 1024
|
|
||||||
|
|
||||||
defaults
|
|
||||||
mode http
|
|
||||||
timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
|
|
||||||
timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
|
|
||||||
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
|
|
||||||
|
|
||||||
backend be1
|
|
||||||
tcp-response inspect-delay 100ms
|
|
||||||
tcp-response content accept if { res.len gt 15272 }
|
|
||||||
tcp-response content reject
|
|
||||||
|
|
||||||
http-response deny if { internal.htx.has_eom -m bool } or { internal.htx.free_data gt 1024 }
|
|
||||||
server srv1 ${s1_addr}:${s1_port}
|
|
||||||
|
|
||||||
frontend fe1
|
|
||||||
option httplog
|
|
||||||
option http-buffer-request
|
|
||||||
log ${S_addr}:${S_port} local0 debug err
|
|
||||||
bind "fd@${fe1}"
|
|
||||||
http-request deny if ! { req.body_len eq 15200 } or { internal.htx.has_eom -m bool } or { internal.htx.free_data gt 1024 }
|
|
||||||
use_backend be1
|
|
||||||
} -start
|
|
||||||
|
|
||||||
haproxy h1 -cli {
|
|
||||||
send "trace h1 sink stderr; trace h1 level developer; trace h1 verbosity complete; trace h1 start now"
|
|
||||||
}
|
|
||||||
|
|
||||||
client c1 -connect ${h1_fe1_sock} {
|
|
||||||
txreq -bodylen 15200
|
|
||||||
rxresp
|
|
||||||
expect resp.status == 200
|
|
||||||
expect resp.bodylen == 15220
|
|
||||||
} -run
|
|
@ -1,7 +1,6 @@
|
|||||||
varnishtest "A test for the wait-for-body HTTP action"
|
varnishtest "A test for the wait-for-body HTTP action"
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
#REGTEST_TYPE=slow
|
#REGTEST_TYPE=slow
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
|
@ -8,8 +8,6 @@ varnishtest "h1/h2 support for protocol upgrade test"
|
|||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
# http/1.1 server
|
# http/1.1 server
|
||||||
server srv_h1 {
|
server srv_h1 {
|
||||||
rxreq
|
rxreq
|
||||||
|
@ -12,8 +12,6 @@ varnishtest "WebSocket test"
|
|||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
# valid websocket server
|
# valid websocket server
|
||||||
server s1 {
|
server s1 {
|
||||||
rxreq
|
rxreq
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
varnishtest "Test IPv4/IPv6 except param for the forwardfor and originalto options"
|
varnishtest "Test IPv4/IPv6 except param for the forwardfor and originalto options"
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
# This config tests the except parameter for the HTTP forwardfor and originalto
|
# This config tests the except parameter for the HTTP forwardfor and originalto
|
||||||
# options.
|
# options.
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
varnishtest "normalize-uri tests"
|
varnishtest "normalize-uri tests"
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
# This reg-test tests the http-request normalize-uri action.
|
# This reg-test tests the http-request normalize-uri action.
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@ varnishtest "http-request set-timeout test"
|
|||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
server srv_h1 -repeat 9 {
|
server srv_h1 -repeat 9 {
|
||||||
rxreq
|
rxreq
|
||||||
txresp
|
txresp
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
varnishtest "Verify logging of relative/absolute URI path"
|
varnishtest "Verify logging of relative/absolute URI path"
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
rxreq
|
rxreq
|
||||||
txresp -hdr "Connection: close"
|
txresp -hdr "Connection: close"
|
||||||
|
@ -49,6 +49,7 @@ client c1 -connect ${h1_frt_sock} -repeat 100 {
|
|||||||
syslog Slog -wait
|
syslog Slog -wait
|
||||||
|
|
||||||
shell {
|
shell {
|
||||||
|
set +e
|
||||||
ss -pt | grep CLOSE-WAIT.*haproxy.*pid=${h1_pid}
|
ss -pt | grep CLOSE-WAIT.*haproxy.*pid=${h1_pid}
|
||||||
exit $((!$?))
|
exit $((!$?))
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
varnishtest "Lua: txn:get_priv() scope"
|
varnishtest "Lua: txn:get_priv() scope"
|
||||||
#REQUIRE_OPTIONS=LUA,OPENSSL
|
#REQUIRE_OPTIONS=LUA,OPENSSL
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
#REGTEST_TYPE=bug
|
#REGTEST_TYPE=bug
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
@ -355,8 +355,8 @@ client c9 -connect ${h1_mainfe_sock} {
|
|||||||
} -run
|
} -run
|
||||||
|
|
||||||
client c10 -connect ${h1_mainfe_sock} {
|
client c10 -connect ${h1_mainfe_sock} {
|
||||||
txreq -url "/converter" -hdr "X-Cust: foobar"
|
txreq -url "/converter" -hdr "User-Agent: c10" -hdr "X-Cust: foobar"
|
||||||
rxresp
|
rxresp
|
||||||
expect resp.status == 200
|
expect resp.status == 200
|
||||||
expect resp.http.x-var == "proc.req_len=35 sess.x_cust=foobar"
|
expect resp.http.x-var == "proc.req_len=52 sess.x_cust=foobar"
|
||||||
} -run
|
} -run
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
varnishtest "Hash validity test"
|
varnishtest "Hash validity test"
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
varnishtest "ub64dec sample fetche Test"
|
varnishtest "ub64dec sample fetche Test"
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
haproxy h1 -conf {
|
haproxy h1 -conf {
|
||||||
|
@ -2,8 +2,6 @@ varnishtest "Add server via cli"
|
|||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
server s1 {
|
server s1 {
|
||||||
rxreq
|
rxreq
|
||||||
txresp
|
txresp
|
||||||
|
@ -5,8 +5,6 @@ varnishtest "Delete server via cli"
|
|||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
# static server
|
# static server
|
||||||
server s1 -repeat 3 {
|
server s1 -repeat 3 {
|
||||||
rxreq
|
rxreq
|
||||||
|
@ -3,7 +3,6 @@ varnishtest "Set server ssl via CLI"
|
|||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
# for "set server <srv> ssl"
|
# for "set server <srv> ssl"
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
#REGTEST_TYPE=devel
|
#REGTEST_TYPE=devel
|
||||||
#REQUIRE_OPTIONS=OPENSSL
|
#REQUIRE_OPTIONS=OPENSSL
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ haproxy h1 -conf {
|
|||||||
tune.ssl.capture-buffer-size 1
|
tune.ssl.capture-buffer-size 1
|
||||||
crt-base ${testdir}
|
crt-base ${testdir}
|
||||||
stats socket "${tmpdir}/h1/stats" level admin
|
stats socket "${tmpdir}/h1/stats" level admin
|
||||||
|
ssl-default-bind-options strict-sni
|
||||||
|
|
||||||
defaults
|
defaults
|
||||||
mode http
|
mode http
|
||||||
@ -47,13 +48,14 @@ haproxy h1 -conf {
|
|||||||
server s3 "${tmpdir}/first-ssl.sock" ssl verify none sni str(record2.bug940.domain.tld)
|
server s3 "${tmpdir}/first-ssl.sock" ssl verify none sni str(record2.bug940.domain.tld)
|
||||||
|
|
||||||
listen first-ssl-fe
|
listen first-ssl-fe
|
||||||
|
# note: strict-sni is enforced from ssl-default-bind-options above
|
||||||
mode http
|
mode http
|
||||||
bind "${tmpdir}/first-ssl.sock" ssl strict-sni crt-list ${testdir}/simple.crt-list
|
bind "${tmpdir}/first-ssl.sock" ssl crt-list ${testdir}/simple.crt-list
|
||||||
server s1 ${s1_addr}:${s1_port}
|
server s1 ${s1_addr}:${s1_port}
|
||||||
|
|
||||||
listen second-ssl-fe
|
listen second-ssl-fe
|
||||||
mode http
|
mode http
|
||||||
bind "${tmpdir}/second-ssl.sock" ssl crt-list ${testdir}/localhost.crt-list
|
bind "${tmpdir}/second-ssl.sock" ssl no-strict-sni crt-list ${testdir}/localhost.crt-list
|
||||||
server s1 ${s1_addr}:${s1_port}
|
server s1 ${s1_addr}:${s1_port}
|
||||||
} -start
|
} -start
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ varnishtest "Delete server via cli and update certificates"
|
|||||||
|
|
||||||
feature ignore_unknown_macro
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
#REQUIRE_OPTIONS=OPENSSL
|
#REQUIRE_OPTIONS=OPENSSL
|
||||||
feature cmd "command -v socat"
|
feature cmd "command -v socat"
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 1"
|
echo "==== test 1"
|
||||||
@ -77,6 +78,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 2"
|
echo "==== test 2"
|
||||||
@ -107,6 +109,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 3"
|
echo "==== test 3"
|
||||||
@ -138,6 +141,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 4"
|
echo "==== test 4"
|
||||||
@ -169,6 +173,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 5"
|
echo "==== test 5"
|
||||||
@ -200,6 +205,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 6"
|
echo "==== test 6"
|
||||||
@ -232,6 +238,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 7"
|
echo "==== test 7"
|
||||||
@ -263,6 +270,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 8"
|
echo "==== test 8"
|
||||||
@ -295,6 +303,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 9"
|
echo "==== test 9"
|
||||||
@ -327,6 +336,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 10"
|
echo "==== test 10"
|
||||||
@ -359,6 +369,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 11"
|
echo "==== test 11"
|
||||||
@ -391,6 +402,7 @@ listen ssl-lst
|
|||||||
server s1 127.0.0.1:80
|
server s1 127.0.0.1:80
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
set +e
|
||||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||||
haproxy_ret=$?
|
haproxy_ret=$?
|
||||||
echo "==== test 12"
|
echo "==== test 12"
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
# This should be backported to 1.8
|
# This should be backported to 1.8
|
||||||
|
|
||||||
#REGTEST_TYPE=bug
|
#REGTEST_TYPE=bug
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
varnishtest "stick-tables: Test expirations when used with table_*"
|
varnishtest "stick-tables: Test expirations when used with table_*"
|
||||||
|
|
||||||
|
@ -6,8 +6,6 @@ feature ignore_unknown_macro
|
|||||||
# do the job they are supposed to do.
|
# do the job they are supposed to do.
|
||||||
# If we remove one of the "stick on" rule, this script fails.
|
# If we remove one of the "stick on" rule, this script fails.
|
||||||
|
|
||||||
#REQUIRE_VERSION=2.4
|
|
||||||
|
|
||||||
server s_not_used_1 {}
|
server s_not_used_1 {}
|
||||||
server s_not_used_2 {}
|
server s_not_used_2 {}
|
||||||
server s_not_used_3 {}
|
server s_not_used_3 {}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
set -eux
|
set -eux
|
||||||
|
|
||||||
curl -fsSL https://github.com/wlallemand/VTest/archive/refs/heads/haproxy-sd_notify.tar.gz -o VTest.tar.gz
|
curl -fsSL https://github.com/vtest/VTest2/archive/main.tar.gz -o VTest.tar.gz
|
||||||
mkdir ../vtest
|
mkdir ../vtest
|
||||||
tar xvf VTest.tar.gz -C ../vtest --strip-components=1
|
tar xvf VTest.tar.gz -C ../vtest --strip-components=1
|
||||||
# Special flags due to: https://github.com/vtest/VTest/issues/12
|
# Special flags due to: https://github.com/vtest/VTest/issues/12
|
||||||
@ -24,7 +24,7 @@ set -e
|
|||||||
# temporarily detect Apple Silicon (it's using /opt/homebrew instead of /usr/local)
|
# temporarily detect Apple Silicon (it's using /opt/homebrew instead of /usr/local)
|
||||||
#
|
#
|
||||||
if test -f /opt/homebrew/include/pcre2.h; then
|
if test -f /opt/homebrew/include/pcre2.h; then
|
||||||
make -j${CPUS} FLAGS="-O2 -s -Wall" INCS="-Isrc -Ilib -I/usr/local/include -I/opt/homebrew/include -pthread"
|
make -j${CPUS} FLAGS="-O2 -s -Wall" INCS="-I. -Isrc -Ilib -I/usr/local/include -I/opt/homebrew/include -pthread"
|
||||||
else
|
else
|
||||||
make -j${CPUS} FLAGS="-O2 -s -Wall"
|
make -j${CPUS} FLAGS="-O2 -s -Wall"
|
||||||
fi
|
fi
|
||||||
|
@ -52,10 +52,6 @@ _help()
|
|||||||
#REQUIRE_SERVICE=prometheus-exporter
|
#REQUIRE_SERVICE=prometheus-exporter
|
||||||
#REQUIRE_SERVICES=prometheus-exporter,foo
|
#REQUIRE_SERVICES=prometheus-exporter,foo
|
||||||
|
|
||||||
# To define a range of versions that a test can run with:
|
|
||||||
#REQUIRE_VERSION=0.0
|
|
||||||
#REQUIRE_VERSION_BELOW=99.9
|
|
||||||
|
|
||||||
Configure environment variables to set the haproxy and vtest binaries to use
|
Configure environment variables to set the haproxy and vtest binaries to use
|
||||||
setenv HAPROXY_PROGRAM /usr/local/sbin/haproxy
|
setenv HAPROXY_PROGRAM /usr/local/sbin/haproxy
|
||||||
setenv VTEST_PROGRAM /usr/local/bin/vtest
|
setenv VTEST_PROGRAM /usr/local/bin/vtest
|
||||||
@ -124,15 +120,13 @@ _findtests() {
|
|||||||
set -- $(grep '^#[0-9A-Z_]*=' "$i")
|
set -- $(grep '^#[0-9A-Z_]*=' "$i")
|
||||||
IFS="$OLDIFS"
|
IFS="$OLDIFS"
|
||||||
|
|
||||||
require_version=""; require_version_below=""; require_options="";
|
require_options="";
|
||||||
require_services=""; exclude_targets=""; regtest_type=""
|
require_services=""; exclude_targets=""; regtest_type=""
|
||||||
requiredoption=""; requiredservice=""; excludedtarget="";
|
requiredoption=""; requiredservice=""; excludedtarget="";
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
v="$1"; v="${v#*=}"
|
v="$1"; v="${v#*=}"
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"#REQUIRE_VERSION="*) require_version="$v" ;;
|
|
||||||
"#REQUIRE_VERSION_BELOW="*) require_version_below="$v" ;;
|
|
||||||
"#REQUIRE_OPTIONS="*) require_options="$v" ;;
|
"#REQUIRE_OPTIONS="*) require_options="$v" ;;
|
||||||
"#REQUIRE_SERVICES="*) require_services="$v" ;;
|
"#REQUIRE_SERVICES="*) require_services="$v" ;;
|
||||||
"#EXCLUDE_TARGETS="*) exclude_targets="$v" ;;
|
"#EXCLUDE_TARGETS="*) exclude_targets="$v" ;;
|
||||||
@ -171,21 +165,6 @@ _findtests() {
|
|||||||
IFS=","; set -- $require_services; IFS=$OLDIFS; require_services="$*"
|
IFS=","; set -- $require_services; IFS=$OLDIFS; require_services="$*"
|
||||||
IFS=","; set -- $exclude_targets; IFS=$OLDIFS; exclude_targets="$*"
|
IFS=","; set -- $exclude_targets; IFS=$OLDIFS; exclude_targets="$*"
|
||||||
|
|
||||||
if [ -n "$require_version" ]; then
|
|
||||||
if [ $(_version "$HAPROXY_VERSION") -lt $(_version "$require_version") ]; then
|
|
||||||
echo " Skip $i because option haproxy is version: $HAPROXY_VERSION"
|
|
||||||
echo " REASON: this test requires at least version: $require_version"
|
|
||||||
skiptest=1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ -n "$require_version_below" ]; then
|
|
||||||
if [ $(_version "$HAPROXY_VERSION") -ge $(_version "$require_version_below") ]; then
|
|
||||||
echo " Skip $i because option haproxy is version: $HAPROXY_VERSION"
|
|
||||||
echo " REASON: this test requires a version below: $require_version_below"
|
|
||||||
skiptest=1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
for excludedtarget in $exclude_targets; do
|
for excludedtarget in $exclude_targets; do
|
||||||
if [ "$excludedtarget" = "$TARGET" ]; then
|
if [ "$excludedtarget" = "$TARGET" ]; then
|
||||||
echo " Skip $i because haproxy is compiled for the excluded target $TARGET"
|
echo " Skip $i because haproxy is compiled for the excluded target $TARGET"
|
||||||
|
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