Compare commits
1 Commits
master
...
20250523-s
Author | SHA1 | Date | |
---|---|---|---|
|
25b668d59a |
95
.github/workflows/aws-lc-fips.yml
vendored
95
.github/workflows/aws-lc-fips.yml
vendored
@ -5,8 +5,97 @@ on:
|
||||
- cron: "0 0 * * 4"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
uses: ./.github/workflows/aws-lc-template.yml
|
||||
with:
|
||||
command: "from matrix import determine_latest_aws_lc_fips; print(determine_latest_aws_lc_fips(''))"
|
||||
runs-on: ubuntu-latest
|
||||
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 "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
103
.github/workflows/aws-lc-template.yml
vendored
@ -1,103 +0,0 @@
|
||||
name: AWS-LC template
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
command:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install VTest
|
||||
run: |
|
||||
scripts/build-vtest.sh
|
||||
- name: Determine latest AWS-LC release
|
||||
id: get_aws_lc_release
|
||||
run: |
|
||||
result=$(cd .github && python3 -c "${{ inputs.command }}")
|
||||
echo $result
|
||||
echo "result=$result" >> $GITHUB_OUTPUT
|
||||
- name: Cache AWS-LC
|
||||
id: cache_aws_lc
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: '~/opt/'
|
||||
key: ssl-${{ steps.get_aws_lc_release.outputs.result }}-Ubuntu-latest-gcc
|
||||
- name: Install apt dependencies
|
||||
run: |
|
||||
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
|
||||
sudo apt-get --no-install-recommends -y install socat gdb jose
|
||||
- name: Install AWS-LC
|
||||
if: ${{ steps.cache_ssl.outputs.cache-hit != 'true' }}
|
||||
run: env ${{ steps.get_aws_lc_release.outputs.result }} scripts/build-ssl.sh
|
||||
- name: Compile HAProxy
|
||||
run: |
|
||||
make -j$(nproc) ERR=1 CC=gcc TARGET=linux-glibc \
|
||||
USE_OPENSSL_AWSLC=1 USE_QUIC=1 \
|
||||
SSL_LIB=${HOME}/opt/lib SSL_INC=${HOME}/opt/include \
|
||||
DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" \
|
||||
ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/"
|
||||
sudo make install
|
||||
- name: Show HAProxy version
|
||||
id: show-version
|
||||
run: |
|
||||
ldd $(which haproxy)
|
||||
haproxy -vv
|
||||
echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
|
||||
- name: Install problem matcher for VTest
|
||||
run: echo "::add-matcher::.github/vtest.json"
|
||||
- name: Run VTest for HAProxy
|
||||
id: vtest
|
||||
run: |
|
||||
# This is required for macOS which does not actually allow to increase
|
||||
# the '-n' soft limit to the hard limit, thus failing to run.
|
||||
ulimit -n 65536
|
||||
# allow to catch coredumps
|
||||
ulimit -c unlimited
|
||||
make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
|
||||
- name: Run Unit tests
|
||||
id: unittests
|
||||
run: |
|
||||
make unit-tests
|
||||
- name: Show VTest results
|
||||
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
|
||||
run: |
|
||||
for folder in ${TMPDIR:-/tmp}/haregtests-*/vtc.*; do
|
||||
printf "::group::"
|
||||
cat $folder/INFO
|
||||
cat $folder/LOG
|
||||
echo "::endgroup::"
|
||||
done
|
||||
exit 1
|
||||
- name: Show coredumps
|
||||
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
|
||||
run: |
|
||||
failed=false
|
||||
shopt -s nullglob
|
||||
for file in /tmp/core.*; do
|
||||
failed=true
|
||||
printf "::group::"
|
||||
gdb -ex 'thread apply all bt full' ./haproxy $file
|
||||
echo "::endgroup::"
|
||||
done
|
||||
if [ "$failed" = true ]; then
|
||||
exit 1;
|
||||
fi
|
||||
- name: Show Unit-Tests results
|
||||
if: ${{ failure() && steps.unittests.outcome == 'failure' }}
|
||||
run: |
|
||||
for result in ${TMPDIR:-/tmp}/ha-unittests-*/results/res.*; do
|
||||
printf "::group::"
|
||||
cat $result
|
||||
echo "::endgroup::"
|
||||
done
|
||||
exit 1
|
||||
|
95
.github/workflows/aws-lc.yml
vendored
95
.github/workflows/aws-lc.yml
vendored
@ -5,8 +5,97 @@ on:
|
||||
- cron: "0 0 * * 4"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
uses: ./.github/workflows/aws-lc-template.yml
|
||||
with:
|
||||
command: "from matrix import determine_latest_aws_lc; print(determine_latest_aws_lc(''))"
|
||||
runs-on: ubuntu-latest
|
||||
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 "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
|
||||
|
||||
|
83
CHANGELOG
83
CHANGELOG
@ -1,89 +1,6 @@
|
||||
ChangeLog :
|
||||
===========
|
||||
|
||||
2025/06/11 : 3.3-dev1
|
||||
- BUILD: tools: properly define ha_dump_backtrace() to avoid a build warning
|
||||
- DOC: config: Fix a typo in 2.7 (Name format for maps and ACLs)
|
||||
- REGTESTS: Do not use REQUIRE_VERSION for HAProxy 2.5+ (5)
|
||||
- REGTESTS: Remove REQUIRE_VERSION=2.3 from all tests
|
||||
- REGTESTS: Remove REQUIRE_VERSION=2.4 from all tests
|
||||
- REGTESTS: Remove tests with REQUIRE_VERSION_BELOW=2.4
|
||||
- REGTESTS: Remove support for REQUIRE_VERSION and REQUIRE_VERSION_BELOW
|
||||
- MINOR: server: group postinit server tasks under _srv_postparse()
|
||||
- MINOR: stats: add stat_col flags
|
||||
- MINOR: stats: add ME_NEW_COMMON() helper
|
||||
- MINOR: proxy: collect per-capability stat in proxy_cond_disable()
|
||||
- MINOR: proxy: add a true list containing all proxies
|
||||
- MINOR: log: only run postcheck_log_backend() checks on backend
|
||||
- MEDIUM: proxy: use global proxy list for REGISTER_POST_PROXY_CHECK() hook
|
||||
- MEDIUM: server: automatically add server to proxy list in new_server()
|
||||
- MEDIUM: server: add and use srv_init() function
|
||||
- BUG/MAJOR: leastconn: Protect tree_elt with the lbprm lock
|
||||
- BUG/MEDIUM: check: Requeue healthchecks on I/O events to handle check timeout
|
||||
- CLEANUP: applet: Update comment for applet_put* functions
|
||||
- DEBUG: check: Add the healthcheck's expiration date in the trace messags
|
||||
- BUG/MINOR: mux-spop: Fix null-pointer deref on SPOP stream allocation failure
|
||||
- CLEANUP: sink: remove useless cleanup in sink_new_from_logger()
|
||||
- MAJOR: counters: add shared counters base infrastructure
|
||||
- MINOR: counters: add shared counters helpers to get and drop shared pointers
|
||||
- MINOR: counters: add common struct and flags to {fe,be}_counters_shared
|
||||
- MEDIUM: counters: manage shared counters using dedicated helpers
|
||||
- CLEANUP: counters: merge some common counters between {fe,be}_counters_shared
|
||||
- MINOR: counters: add local-only internal rates to compute some maxes
|
||||
- MAJOR: counters: dispatch counters over thread groups
|
||||
- BUG/MEDIUM: cli: Properly parse empty lines and avoid crashed
|
||||
- BUG/MINOR: config: emit warning for empty args only in discovery mode
|
||||
- BUG/MINOR: config: fix arg number reported on empty arg warning
|
||||
- BUG/MINOR: quic: Missing SSL session object freeing
|
||||
- MINOR: applet: Add API functions to manipulate input and output buffers
|
||||
- MINOR: applet: Add API functions to get data from the input buffer
|
||||
- CLEANUP: applet: Simplify a bit comments for applet_put* functions
|
||||
- MEDIUM: hlua: Update TCP applet functions to use the new applet API
|
||||
- BUG/MEDIUM: fd: Use the provided tgid in fd_insert() to get tgroup_info
|
||||
- BUG/MINIR: h1: Fix doc of 'accept-unsafe-...-request' about URI parsing
|
||||
|
||||
2025/05/28 : 3.3-dev0
|
||||
- MINOR: version: mention that it's development again
|
||||
|
||||
2025/05/28 : 3.2.0
|
||||
- MINOR: promex: Add agent check status/code/duration metrics
|
||||
- MINOR: ssl: support strict-sni in ssl-default-bind-options
|
||||
- MINOR: ssl: also provide the "tls-tickets" bind option
|
||||
- MINOR: server: define CLI I/O handler for "add server"
|
||||
- MINOR: server: implement "add server help"
|
||||
- MINOR: server: use stress mode for "add server help"
|
||||
- BUG/MEDIUM: server: fix crash after duplicate GUID insertion
|
||||
- BUG/MEDIUM: server: fix potential null-deref after previous fix
|
||||
- MINOR: config: list recently added sections with -dKcfg
|
||||
- BUG/MAJOR: cache: Crash because of wrong cache entry deleted
|
||||
- DOC: configuration: fix the example in crt-store
|
||||
- DOC: config: clarify the wording around single/double quotes
|
||||
- DOC: config: clarify the legacy cookie and header captures
|
||||
- DOC: config: fix alphabetical ordering of layer 7 sample fetch functions
|
||||
- DOC: config: fix alphabetical ordering of layer 6 sample fetch functions
|
||||
- DOC: config: fix alphabetical ordering of layer 5 sample fetch functions
|
||||
- DOC: config: fix alphabetical ordering of layer 4 sample fetch functions
|
||||
- DOC: config: fix alphabetical ordering of internal sample fetch functions
|
||||
- BUG/MINOR: h3: Set HTX flags corresponding to the scheme found in the request
|
||||
- BUG/MEDIUM: h3: Declare absolute URI as normalized when a :authority is found
|
||||
- DOC: config: mention in bytes_in and bytes_out that they're read on input
|
||||
- DOC: config: clarify the basics of ACLs (call point, multi-valued etc)
|
||||
- REGTESTS: Make the script testing conditional set-var compatible with Vtest2
|
||||
- REGTESTS: Explicitly allow failing shell commands in some scripts
|
||||
- MINOR: listeners: Add support for a label on bind line
|
||||
- BUG/MEDIUM: cli/ring: Properly handle shutdown in "show event" I/O handler
|
||||
- BUG/MEDIUM: hlua: Properly detect shudowns for TCP applets based on the new API
|
||||
- BUG/MEDIUM: hlua: Fix getline() for TCP applets to work with applet's buffers
|
||||
- BUG/MEDIUM: hlua: Fix receive API for TCP applets to properly handle shutdowns
|
||||
- CI: vtest: Rely on VTest2 to run regression tests
|
||||
- CI: vtest: Fix the build script to properly work on MaOS
|
||||
- CI: combine AWS-LC and AWS-LC-FIPS by template
|
||||
- BUG/MEDIUM: httpclient: Throw an error if an lua httpclient instance is reused
|
||||
- DOC: hlua: Add a note to warn user about httpclient object reuse
|
||||
- DOC: hlua: fix a few typos in HTTPMessage.set_body_len() documentation
|
||||
- DEV: patchbot: prepare for new version 3.3-dev
|
||||
- MINOR: version: mention that it's 3.2 LTS now.
|
||||
|
||||
2025/05/21 : 3.2-dev17
|
||||
- DOC: configuration: explicit multi-choice on bind shards option
|
||||
- BUG/MINOR: sink: detect and warn when using "send-proxy" options with ring servers
|
||||
|
2
Makefile
2
Makefile
@ -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_map.o src/shctx.o src/mworker-prog.o src/hpack-dec.o \
|
||||
src/arg.o src/signal.o src/fix.o src/dynbuf.o src/guid.o \
|
||||
src/cfgparse-tcp.o src/lb_ss.o src/chunk.o src/counters.o \
|
||||
src/cfgparse-tcp.o src/lb_ss.o src/chunk.o \
|
||||
src/cfgparse-unix.o src/regex.o src/fcgi.o src/uri_auth.o \
|
||||
src/eb64tree.o src/eb32tree.o src/eb32sctree.o src/lru.o \
|
||||
src/limits.o src/ebimtree.o src/wdt.o src/hpack-tbl.o \
|
||||
|
@ -1,70 +0,0 @@
|
||||
BEGININPUT
|
||||
BEGINCONTEXT
|
||||
|
||||
HAProxy's development cycle consists in one development branch, and multiple
|
||||
maintenance branches.
|
||||
|
||||
All the development is made into the development branch exclusively. This
|
||||
includes mostly new features, doc updates, cleanups and or course, fixes.
|
||||
|
||||
The maintenance branches, also called stable branches, never see any
|
||||
development, and only receive ultra-safe fixes for bugs that affect them,
|
||||
that are picked from the development branch.
|
||||
|
||||
Branches are numbered in 0.1 increments. Every 6 months, upon a new major
|
||||
release, the development branch enters maintenance and a new development branch
|
||||
is created with a new, higher version. The current development branch is
|
||||
3.3-dev, and maintenance branches are 3.2 and below.
|
||||
|
||||
Fixes created in the development branch for issues that were introduced in an
|
||||
earlier branch are applied in descending order to each and every version till
|
||||
that branch that introduced the issue: 3.2 first, then 3.1, then 3.0, then 2.9
|
||||
and so on. This operation is called "backporting". A fix for an issue is never
|
||||
backported beyond the branch that introduced the issue. An important point is
|
||||
that the project maintainers really aim at zero regression in maintenance
|
||||
branches, so they're never willing to take any risk backporting patches that
|
||||
are not deemed strictly necessary.
|
||||
|
||||
Fixes consist of patches managed using the Git version control tool and are
|
||||
identified by a Git commit ID and a commit message. For this reason we
|
||||
indistinctly talk about backporting fixes, commits, or patches; all mean the
|
||||
same thing. When mentioning commit IDs, developers always use a short form
|
||||
made of the first 8 characters only, and expect the AI assistant to do the
|
||||
same.
|
||||
|
||||
It seldom happens that some fixes depend on changes that were brought by other
|
||||
patches that were not in some branches and that will need to be backported as
|
||||
well for the fix to work. In this case, such information is explicitly provided
|
||||
in the commit message by the patch's author in natural language.
|
||||
|
||||
Developers are serious and always indicate if a patch needs to be backported.
|
||||
Sometimes they omit the exact target branch, or they will say that the patch is
|
||||
"needed" in some older branch, but it means the same. If a commit message
|
||||
doesn't mention any backport instructions, it means that the commit does not
|
||||
have to be backported. And patches that are not strictly bug fixes nor doc
|
||||
improvements are normally not backported. For example, fixes for design
|
||||
limitations, architectural improvements and performance optimizations are
|
||||
considered too risky for a backport. Finally, all bug fixes are tagged as
|
||||
"BUG" at the beginning of their subject line. Patches that are not tagged as
|
||||
such are not bugs, and must never be backported unless their commit message
|
||||
explicitly requests so.
|
||||
|
||||
ENDCONTEXT
|
||||
|
||||
A developer is reviewing the development branch, trying to spot which commits
|
||||
need to be backported to maintenance branches. This person is already expert
|
||||
on HAProxy and everything related to Git, patch management, and the risks
|
||||
associated with backports, so he doesn't want to be told how to proceed nor to
|
||||
review the contents of the patch.
|
||||
|
||||
The goal for this developer is to get some help from the AI assistant to save
|
||||
some precious time on this tedious review work. In order to do a better job, he
|
||||
needs an accurate summary of the information and instructions found in each
|
||||
commit message. Specifically he needs to figure if the patch fixes a problem
|
||||
affecting an older branch or not, if it needs to be backported, if so to which
|
||||
branches, and if other patches need to be backported along with it.
|
||||
|
||||
The indented text block below after an "id" line and starting with a Subject line
|
||||
is a commit message from the HAProxy development branch that describes a patch
|
||||
applied to that branch, starting with its subject line, please read it carefully.
|
||||
|
@ -1,29 +0,0 @@
|
||||
|
||||
ENDINPUT
|
||||
BEGININSTRUCTION
|
||||
|
||||
You are an AI assistant that follows instruction extremely well. Help as much
|
||||
as you can, responding to a single question using a single response.
|
||||
|
||||
The developer wants to know if he needs to backport the patch above to fix
|
||||
maintenance branches, for which branches, and what possible dependencies might
|
||||
be mentioned in the commit message. Carefully study the commit message and its
|
||||
backporting instructions if any (otherwise it should probably not be backported),
|
||||
then provide a very concise and short summary that will help the developer decide
|
||||
to backport it, or simply to skip it.
|
||||
|
||||
Start by explaining in one or two sentences what you recommend for this one and why.
|
||||
Finally, based on your analysis, give your general conclusion as "Conclusion: X"
|
||||
where X is a single word among:
|
||||
- "yes", if you recommend to backport the patch right now either because
|
||||
it explicitly states this or because it's a fix for a bug that affects
|
||||
a maintenance branch (3.2 or lower);
|
||||
- "wait", if this patch explicitly mentions that it must be backported, but
|
||||
only after waiting some time.
|
||||
- "no", if nothing clearly indicates a necessity to backport this patch (e.g.
|
||||
lack of explicit backport instructions, or it's just an improvement);
|
||||
- "uncertain" otherwise for cases not covered above
|
||||
|
||||
ENDINSTRUCTION
|
||||
|
||||
Explanation:
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
-----------------------
|
||||
HAProxy Starter Guide
|
||||
-----------------------
|
||||
version 3.3
|
||||
version 3.2
|
||||
|
||||
|
||||
This document is an introduction to HAProxy for all those who don't know it, as
|
||||
|
@ -893,9 +893,7 @@ Core class
|
||||
|
||||
**context**: init, task, action
|
||||
|
||||
This function returns a new object of a *httpclient* class. An *httpclient*
|
||||
object must be used to process one and only one request. It must never be
|
||||
reused to process several requests.
|
||||
This function returns a new object of a *httpclient* class.
|
||||
|
||||
:returns: A :ref:`httpclient_class` object.
|
||||
|
||||
@ -2583,9 +2581,7 @@ HTTPClient class
|
||||
.. js:class:: HTTPClient
|
||||
|
||||
The httpclient class allows issue of outbound HTTP requests through a simple
|
||||
API without the knowledge of HAProxy internals. Any instance must be used to
|
||||
process one and only one request. It must never be reused to process several
|
||||
requests.
|
||||
API without the knowledge of HAProxy internals.
|
||||
|
||||
.. js:function:: HTTPClient.get(httpclient, request)
|
||||
.. js:function:: HTTPClient.head(httpclient, request)
|
||||
@ -3920,25 +3916,21 @@ AppletTCP class
|
||||
*size* is missing, the function tries to read all the content of the stream
|
||||
until the end. An optional timeout may be specified in milliseconds. In this
|
||||
case the function will return no longer than this delay, with the amount of
|
||||
available data, or nil if there is no data. An empty string is returned if the
|
||||
connection is closed.
|
||||
available data (possibly none).
|
||||
|
||||
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
||||
:param integer size: the required read size.
|
||||
:returns: return nil if the timeout has expired and no data was available but
|
||||
can still be received. Otherwise, a string is returned, possibly an empty
|
||||
string if the connection is closed.
|
||||
:returns: always return a string, the string can be empty if the connection is
|
||||
closed.
|
||||
|
||||
.. js:function:: AppletTCP.try_receive(applet)
|
||||
|
||||
Reads available data from the TCP stream and returns immediately. Returns a
|
||||
string containing read bytes or nil if no bytes are available at that time. An
|
||||
empty string is returned if the connection is closed.
|
||||
string containing read bytes that may possibly be empty if no bytes are
|
||||
available at that time.
|
||||
|
||||
:param class_AppletTCP applet: An :ref:`applettcp_class`
|
||||
:returns: return nil if no data was available but can still be
|
||||
received. Otherwise, a string is returned, possibly an empty string if the
|
||||
connection is closed.
|
||||
:returns: always return a string, the string can be empty.
|
||||
|
||||
.. js:function:: AppletTCP.send(appletmsg)
|
||||
|
||||
@ -4625,10 +4617,10 @@ HTTPMessage class
|
||||
added with the "chunked" value. In both cases, all existing "Content-Length"
|
||||
and "Transfer-Encoding" headers are removed.
|
||||
|
||||
This function should be used in the filter context to be able to alter the
|
||||
payload of the HTTP message. The internal state of the HTTP message is updated
|
||||
This fnuction 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
|
||||
accordingly. :js:func:`HTTPMessage.add_header()` or
|
||||
:js:func:`HTTPMessage.set_header()` functions must be used in that case.
|
||||
:js:func:`HTTPMessage.set_header()` functions must to be used in that case.
|
||||
|
||||
:param class_httpmessage http_msg: The manipulated HTTP message.
|
||||
:param type length: The new payload length to set. It can be an integer or
|
||||
|
@ -1,7 +1,7 @@
|
||||
------------------------
|
||||
HAProxy Management Guide
|
||||
------------------------
|
||||
version 3.3
|
||||
version 3.2
|
||||
|
||||
|
||||
This document describes how to start, stop, manage, and troubleshoot HAProxy,
|
||||
@ -3402,6 +3402,19 @@ show sess [<id> | all | help] [<options>*]
|
||||
analysis. It is only displayed if it was captured.
|
||||
- susp only show streams considered as suspicious by the developers
|
||||
based on criteria that may in time or vary along versions.
|
||||
- fsrc [<addr>][:<port>] only show streams with <addr> as optional source
|
||||
frontent address and <port> as optional port.
|
||||
- fdst [<addr>][:<port>] only show streams with <addr> as optional destination
|
||||
frontent address and <port> as optional port.
|
||||
- bsrc [<addr>][:<port>] only show streams with <addr> as optional source
|
||||
backend address and <port> as optional port.
|
||||
- bdst [<addr>][:<port>] only show streams with <addr> as optional destination
|
||||
backend address and <port> as optional port.
|
||||
|
||||
Note that for fsrc, fdst, bsrc and bdst options, at least one parameter must
|
||||
be provided (the addresse or the port). Only one address may be used by
|
||||
direction (only one option between fdst and bdst, and only one option between
|
||||
fsrc and bsrc).
|
||||
|
||||
show stat [domain <resolvers|proxy>] [{<iid>|<proxy>} <type> <sid>] \
|
||||
[typed|json] [desc] [up|no-maint]
|
||||
|
@ -215,7 +215,7 @@ function handler(applet)
|
||||
|
||||
local input = applet:receive(1, delay)
|
||||
if input then
|
||||
if input == "" or input == "q" then
|
||||
if input == "q" then
|
||||
game_over = true
|
||||
elseif input == "\27" then
|
||||
local a = applet:receive(1, delay)
|
||||
|
@ -282,92 +282,6 @@ static inline void applet_expect_data(struct appctx *appctx)
|
||||
se_fl_clr(appctx->sedesc, SE_FL_EXP_NO_DATA);
|
||||
}
|
||||
|
||||
/* Returns the buffer containing data pushed to the applet by the stream. For
|
||||
* applets using its own buffers it is the appctx input buffer. For legacy
|
||||
* applet, it is the output channel buffer.
|
||||
*/
|
||||
static inline struct buffer *applet_get_inbuf(struct appctx *appctx)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
return &appctx->inbuf;
|
||||
else
|
||||
return sc_ob(appctx_sc(appctx));
|
||||
}
|
||||
|
||||
/* Returns the buffer containing data pushed by the applets to the stream. For
|
||||
* applets using its own buffer it is the appctx output buffer. For legacy
|
||||
* applet, it is the input channel buffer.
|
||||
*/
|
||||
static inline struct buffer *applet_get_outbuf(struct appctx *appctx)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
return &appctx->outbuf;
|
||||
else
|
||||
return sc_ib(appctx_sc(appctx));
|
||||
}
|
||||
|
||||
/* Returns the amount of data in the input buffer (see applet_get_inbuf) */
|
||||
static inline size_t applet_input_data(const struct appctx *appctx)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
return b_data(&appctx->inbuf);
|
||||
else
|
||||
return co_data(sc_oc(appctx_sc(appctx)));
|
||||
}
|
||||
|
||||
/* Skips <len> bytes from the input buffer (see applet_get_inbuf).
|
||||
*
|
||||
* This is useful when data have been read directly from the buffer. It is
|
||||
* illegal to call this function with <len> causing a wrapping at the end of the
|
||||
* buffer. It's the caller's responsibility to ensure that <len> is never larger
|
||||
* than available ouput data.
|
||||
*/
|
||||
static inline void applet_skip_input(struct appctx *appctx, size_t len)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
b_del(&appctx->inbuf, len);
|
||||
else
|
||||
co_skip(sc_oc(appctx_sc(appctx)), len);
|
||||
}
|
||||
|
||||
/* Removes all bytes from the input buffer (see applet_get_inbuf).
|
||||
*/
|
||||
static inline void applet_reset_input(struct appctx *appctx)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
b_reset(&appctx->inbuf);
|
||||
applet_fl_clr(appctx, APPCTX_FL_INBLK_FULL);
|
||||
}
|
||||
else
|
||||
co_skip(sc_oc(appctx_sc(appctx)), co_data(sc_oc(appctx_sc(appctx))));
|
||||
}
|
||||
|
||||
/* Returns the amout of space available at the output buffer (see applet_get_outbuf).
|
||||
*/
|
||||
static inline size_t applet_output_room(const struct appctx *appctx)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
return b_room(&appctx->outbuf);
|
||||
else
|
||||
return channel_recv_max(sc_ic(appctx_sc(appctx)));
|
||||
}
|
||||
|
||||
/*Indicates that the applet have more data to deliver and it needs more room in
|
||||
* the output buffer to do so (see applet_get_outbuf).
|
||||
*
|
||||
* For applets using its own buffers, <room_needed> is not used and only
|
||||
* <appctx> flags are updated. For legacy applets, the amount of free space
|
||||
* required must be specified. In this last case, it is the caller
|
||||
* responsibility to be sure <room_needed> is valid.
|
||||
*/
|
||||
static inline void applet_need_room(struct appctx *appctx, size_t room_needed)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
applet_have_more_data(appctx);
|
||||
else
|
||||
sc_need_room(appctx_sc(appctx), room_needed);
|
||||
}
|
||||
|
||||
/* Should only be used via wrappers applet_putchk() / applet_putchk_stress(). */
|
||||
static inline int _applet_putchk(struct appctx *appctx, struct buffer *chunk,
|
||||
int stress)
|
||||
@ -404,10 +318,9 @@ static inline int _applet_putchk(struct appctx *appctx, struct buffer *chunk,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* writes chunk <chunk> into the applet output buffer (see applet_get_outbuf).
|
||||
*
|
||||
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||
* shutdown, invalid call...)
|
||||
/* writes chunk <chunk> into the input channel of the stream attached to this
|
||||
* appctx's endpoint, and marks the SC_FL_NEED_ROOM on a channel full error.
|
||||
* See ci_putchk() for the list of return codes.
|
||||
*/
|
||||
static inline int applet_putchk(struct appctx *appctx, struct buffer *chunk)
|
||||
{
|
||||
@ -420,10 +333,9 @@ static inline int applet_putchk_stress(struct appctx *appctx, struct buffer *chu
|
||||
return _applet_putchk(appctx, chunk, 1);
|
||||
}
|
||||
|
||||
/* writes <len> chars from <blk> into the applet output buffer (see applet_get_outbuf).
|
||||
*
|
||||
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||
* shutdown, invalid call...)
|
||||
/* writes <len> chars from <blk> into the input channel of the stream attached
|
||||
* to this appctx's endpoint, and marks the SC_FL_NEED_ROOM on a channel full
|
||||
* error. See ci_putblk() for the list of return codes.
|
||||
*/
|
||||
static inline int applet_putblk(struct appctx *appctx, const char *blk, int len)
|
||||
{
|
||||
@ -455,11 +367,10 @@ static inline int applet_putblk(struct appctx *appctx, const char *blk, int len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* writes chars from <str> up to the trailing zero (excluded) into the applet
|
||||
* output buffer (see applet_get_outbuf).
|
||||
*
|
||||
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||
* shutdown, invalid call...)
|
||||
/* writes chars from <str> up to the trailing zero (excluded) into the input
|
||||
* channel of the stream attached to this appctx's endpoint, and marks the
|
||||
* SC_FL_NEED_ROOM on a channel full error. See ci_putstr() for the list of
|
||||
* return codes.
|
||||
*/
|
||||
static inline int applet_putstr(struct appctx *appctx, const char *str)
|
||||
{
|
||||
@ -492,10 +403,9 @@ static inline int applet_putstr(struct appctx *appctx, const char *str)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* writes character <chr> into the applet's output buffer (see applet_get_outbuf).
|
||||
*
|
||||
* Returns the number of written bytes on success or -1 on error (lake of space,
|
||||
* shutdown, invalid call...)
|
||||
/* writes character <chr> into the input channel of the stream attached to this
|
||||
* appctx's endpoint, and marks the SC_FL_NEED_ROOM on a channel full error.
|
||||
* See ci_putchr() for the list of return codes.
|
||||
*/
|
||||
static inline int applet_putchr(struct appctx *appctx, char chr)
|
||||
{
|
||||
@ -528,283 +438,6 @@ static inline int applet_putchr(struct appctx *appctx, char chr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int applet_may_get(const struct appctx *appctx, size_t len)
|
||||
{
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
if (len > b_data(&appctx->inbuf)) {
|
||||
if (se_fl_test(appctx->sedesc, SE_FL_SHW))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const struct stconn *sc = appctx_sc(appctx);
|
||||
|
||||
if ((sc->flags & SC_FL_SHUT_DONE) || len > co_data(sc_oc(sc))) {
|
||||
if (sc->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* Gets one char from the applet input buffer (see appet_get_inbuf),
|
||||
*
|
||||
* Return values :
|
||||
* 1 : number of bytes read, equal to requested size.
|
||||
* =0 : not enough data available. <c> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getchar(const struct appctx *appctx, char *c)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = applet_may_get(appctx, 1);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
*c = ((appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
? *(b_head(&appctx->inbuf))
|
||||
: *(co_head(sc_oc(appctx_sc(appctx)))));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Copies one full block of data from the applet input buffer (see
|
||||
* appet_get_inbuf).
|
||||
*
|
||||
* <len> bytes are capied, starting at the offset <offset>.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of bytes read, equal to requested size.
|
||||
* =0 : not enough data available. <blk> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getblk(const struct appctx *appctx, char *blk, int len, int offset)
|
||||
{
|
||||
const struct buffer *buf;
|
||||
int ret;
|
||||
|
||||
ret = applet_may_get(appctx, len+offset);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
buf = ((appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
? &appctx->inbuf
|
||||
: sc_ob(appctx_sc(appctx)));
|
||||
return b_getblk(buf, blk, len, offset);
|
||||
}
|
||||
|
||||
/* Gets one text block representing a word from the applet input buffer (see
|
||||
* appet_get_inbuf).
|
||||
*
|
||||
* The separator is waited for as long as some data can still be received and the
|
||||
* destination is not full. Otherwise, the string may be returned as is, without
|
||||
* the separator.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of bytes read. Includes the separator if present before len or end.
|
||||
* =0 : no separator before end found. <str> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getword(const struct appctx *appctx, char *str, int len, char sep)
|
||||
{
|
||||
const struct buffer *buf;
|
||||
char *p;
|
||||
size_t input, max = len;
|
||||
int ret = 0;
|
||||
|
||||
ret = applet_may_get(appctx, 1);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
buf = &appctx->inbuf;
|
||||
input = b_data(buf);
|
||||
}
|
||||
else {
|
||||
struct stconn *sc = appctx_sc(appctx);
|
||||
|
||||
buf = sc_ob(sc);
|
||||
input = co_data(sc_oc(sc));
|
||||
}
|
||||
|
||||
if (max > input) {
|
||||
max = input;
|
||||
str[max-1] = 0;
|
||||
}
|
||||
|
||||
p = b_head(buf);
|
||||
|
||||
while (max) {
|
||||
*str++ = *p;
|
||||
ret++;
|
||||
max--;
|
||||
if (*p == sep)
|
||||
goto out;
|
||||
p = b_next(buf, p);
|
||||
}
|
||||
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
if (ret < len && (ret < input || b_room(buf)) &&
|
||||
!se_fl_test(appctx->sedesc, SE_FL_SHW))
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
struct stconn *sc = appctx_sc(appctx);
|
||||
|
||||
if (ret < len && (ret < input || channel_may_recv(sc_oc(sc))) &&
|
||||
!(sc->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)))
|
||||
ret = 0;
|
||||
}
|
||||
out:
|
||||
if (max)
|
||||
*str = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Gets one text block representing a line from the applet input buffer (see
|
||||
* appet_get_inbuf).
|
||||
*
|
||||
* The '\n' is waited for as long as some data can still be received and the
|
||||
* destination is not full. Otherwise, the string may be returned as is, without
|
||||
* the '\n'.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of bytes read. Includes the \n if present before len or end.
|
||||
* =0 : no '\n' before end found. <str> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getline(const struct appctx *appctx, char *str, int len)
|
||||
{
|
||||
return applet_getword(appctx, str, len, '\n');
|
||||
}
|
||||
|
||||
/* Gets one or two blocks of data at once from the applet input buffer (see appet_get_inbuf),
|
||||
*
|
||||
* Data are not copied.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of blocks filled (1 or 2). blk1 is always filled before blk2.
|
||||
* =0 : not enough data available. <blk*> are left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getblk_nc(const struct appctx *appctx, const char **blk1, size_t *len1, const char **blk2, size_t *len2)
|
||||
{
|
||||
const struct buffer *buf;
|
||||
size_t max;
|
||||
int ret;
|
||||
|
||||
ret = applet_may_get(appctx, 1);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
buf = &appctx->inbuf;
|
||||
max = b_data(buf);
|
||||
}
|
||||
else {
|
||||
struct stconn *sc = appctx_sc(appctx);
|
||||
|
||||
buf = sc_ob(sc);
|
||||
max = co_data(sc_oc(sc));
|
||||
}
|
||||
|
||||
return b_getblk_nc(buf, blk1, len1, blk2, len2, 0, max);
|
||||
}
|
||||
|
||||
/* Gets one or two blocks of text representing a word from the applet input
|
||||
* buffer (see appet_get_inbuf).
|
||||
*
|
||||
* Data are not copied. The separator is waited for as long as some data can
|
||||
* still be received and the destination is not full. Otherwise, the string may
|
||||
* be returned as is, without the separator.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of bytes read. Includes the separator if present before len or end.
|
||||
* =0 : no separator before end found. <str> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getword_nc(const struct appctx *appctx, const char **blk1, size_t *len1, const char **blk2, size_t *len2, char sep)
|
||||
{
|
||||
int ret;
|
||||
size_t l;
|
||||
|
||||
ret = applet_getblk_nc(appctx, blk1, len1, blk2, len2);
|
||||
if (unlikely(ret <= 0))
|
||||
return ret;
|
||||
|
||||
for (l = 0; l < *len1 && (*blk1)[l] != sep; l++);
|
||||
if (l < *len1 && (*blk1)[l] == sep) {
|
||||
*len1 = l + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ret >= 2) {
|
||||
for (l = 0; l < *len2 && (*blk2)[l] != sep; l++);
|
||||
if (l < *len2 && (*blk2)[l] == sep) {
|
||||
*len2 = l + 1;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have found no LF and the buffer is full or the SC is shut, then
|
||||
* the resulting string is made of the concatenation of the pending
|
||||
* blocks (1 or 2).
|
||||
*/
|
||||
if (appctx->flags & APPCTX_FL_INOUT_BUFS) {
|
||||
if (b_full(&appctx->inbuf) || se_fl_test(appctx->sedesc, SE_FL_SHW))
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
struct stconn *sc = appctx_sc(appctx);
|
||||
|
||||
if (!channel_may_recv(sc_oc(sc)) || sc->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* No LF yet and not shut yet */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Gets one or two blocks of text representing a line from the applet input
|
||||
* buffer (see appet_get_inbuf).
|
||||
*
|
||||
* Data are not copied. The '\n' is waited for as long as some data can still be
|
||||
* received and the destination is not full. Otherwise, the string may be
|
||||
* returned as is, without the '\n'.
|
||||
*
|
||||
* Return values :
|
||||
* >0 : number of bytes read. Includes the \n if present before len or end.
|
||||
* =0 : no '\n' before end found. <str> is left undefined.
|
||||
* <0 : no more bytes readable because output is shut.
|
||||
*
|
||||
* The status of the corresponding buffer is not changed. The caller must call
|
||||
* applet_skip_input() to update it.
|
||||
*/
|
||||
static inline int applet_getline_nc(const struct appctx *appctx, const char **blk1, size_t *len1, const char **blk2, size_t *len2)
|
||||
{
|
||||
return applet_getword_nc(appctx, blk1, len1, blk2, len2, '\n');
|
||||
}
|
||||
|
||||
#endif /* _HAPROXY_APPLET_H */
|
||||
|
||||
/*
|
||||
|
@ -86,7 +86,7 @@ static inline int be_usable_srv(struct proxy *be)
|
||||
/* set the time of last session on the backend */
|
||||
static inline void be_set_sess_last(struct proxy *be)
|
||||
{
|
||||
HA_ATOMIC_STORE(&be->be_counters.shared->tg[tgid - 1]->last_sess, ns_to_sec(now_ns));
|
||||
be->be_counters.last_sess = ns_to_sec(now_ns);
|
||||
}
|
||||
|
||||
/* This function returns non-zero if the designated server will be
|
||||
|
@ -25,144 +25,108 @@
|
||||
|
||||
#include <haproxy/freq_ctr-t.h>
|
||||
|
||||
#define COUNTERS_SHARED_F_NONE 0x0000
|
||||
#define COUNTERS_SHARED_F_LOCAL 0x0001 // shared counter struct is actually process-local
|
||||
|
||||
// common to fe_counters_shared and be_counters_shared
|
||||
#define COUNTERS_SHARED \
|
||||
struct { \
|
||||
uint16_t flags; /* COUNTERS_SHARED_F flags */\
|
||||
};
|
||||
#define COUNTERS_SHARED_TG \
|
||||
struct { \
|
||||
unsigned long last_change; /* last time, when the state was changed */\
|
||||
long long srv_aborts; /* aborted responses during DATA phase caused by the server */\
|
||||
long long cli_aborts; /* aborted responses during DATA phase caused by the client */\
|
||||
long long internal_errors; /* internal processing errors */\
|
||||
long long failed_rewrites; /* failed rewrites (warning) */\
|
||||
long long bytes_out; /* number of bytes transferred from the server to the client */\
|
||||
long long bytes_in; /* number of bytes transferred from the client to the server */\
|
||||
long long denied_resp; /* blocked responses because of security concerns */\
|
||||
long long denied_req; /* blocked requests because of security concerns */\
|
||||
long long cum_sess; /* cumulated number of accepted connections */\
|
||||
/* compression counters, index 0 for requests, 1 for responses */\
|
||||
long long comp_in[2]; /* input bytes fed to the compressor */\
|
||||
long long comp_out[2]; /* output bytes emitted by the compressor */\
|
||||
long long comp_byp[2]; /* input bytes that bypassed the compressor (cpu/ram/bw limitation) */\
|
||||
struct freq_ctr sess_per_sec; /* sessions per second on this server */\
|
||||
}
|
||||
|
||||
// for convenience (generic pointer)
|
||||
struct counters_shared {
|
||||
COUNTERS_SHARED;
|
||||
struct {
|
||||
COUNTERS_SHARED_TG;
|
||||
} *tg[MAX_TGROUPS];
|
||||
};
|
||||
|
||||
/* counters used by listeners and frontends */
|
||||
struct fe_counters_shared_tg {
|
||||
COUNTERS_SHARED_TG;
|
||||
|
||||
long long denied_sess; /* denied session requests (tcp-req-sess rules) */
|
||||
long long denied_conn; /* denied connection requests (tcp-req-conn rules) */
|
||||
long long intercepted_req; /* number of monitoring or stats requests intercepted by the frontend */
|
||||
long long cum_conn; /* cumulated number of received connections */
|
||||
struct freq_ctr conn_per_sec; /* received connections per second on the frontend */
|
||||
|
||||
struct freq_ctr req_per_sec; /* HTTP requests per second on the frontend */
|
||||
|
||||
long long cum_sess_ver[3]; /* cumulated number of h1/h2/h3 sessions */
|
||||
union {
|
||||
struct {
|
||||
long long cum_req[4]; /* cumulated number of processed other/h1/h2/h3 requests */
|
||||
long long cache_hits; /* cache hits */
|
||||
long long cache_lookups;/* cache lookups */
|
||||
long long comp_rsp; /* number of compressed responses */
|
||||
long long rsp[6]; /* http response codes */
|
||||
} http;
|
||||
} p; /* protocol-specific stats */
|
||||
|
||||
long long failed_req; /* failed requests (eg: invalid or timeout) */
|
||||
};
|
||||
|
||||
struct fe_counters_shared {
|
||||
COUNTERS_SHARED;
|
||||
struct fe_counters_shared_tg *tg[MAX_TGROUPS];
|
||||
};
|
||||
|
||||
struct fe_counters {
|
||||
struct fe_counters_shared *shared; /* shared counters */
|
||||
unsigned int conn_max; /* max # of active sessions */
|
||||
long long cum_conn; /* cumulated number of received connections */
|
||||
long long cum_sess; /* cumulated number of accepted connections */
|
||||
long long cum_sess_ver[3]; /* cumulated number of h1/h2/h3 sessions */
|
||||
|
||||
unsigned int cps_max; /* maximum of new connections received per second */
|
||||
unsigned int sps_max; /* maximum of new connections accepted per second (sessions) */
|
||||
struct freq_ctr _sess_per_sec; /* sessions per second on this frontend, used to compute sps_max (internal use only) */
|
||||
struct freq_ctr _conn_per_sec; /* connections per second on this frontend, used to compute cps_max (internal use only) */
|
||||
|
||||
long long bytes_in; /* number of bytes transferred from the client to the server */
|
||||
long long bytes_out; /* number of bytes transferred from the server to the client */
|
||||
|
||||
/* compression counters, index 0 for requests, 1 for responses */
|
||||
long long comp_in[2]; /* input bytes fed to the compressor */
|
||||
long long comp_out[2]; /* output bytes emitted by the compressor */
|
||||
long long comp_byp[2]; /* input bytes that bypassed the compressor (cpu/ram/bw limitation) */
|
||||
|
||||
long long denied_req; /* blocked requests because of security concerns */
|
||||
long long denied_resp; /* blocked responses because of security concerns */
|
||||
long long failed_req; /* failed requests (eg: invalid or timeout) */
|
||||
long long denied_conn; /* denied connection requests (tcp-req-conn rules) */
|
||||
long long denied_sess; /* denied session requests (tcp-req-sess rules) */
|
||||
long long failed_rewrites; /* failed rewrites (warning) */
|
||||
long long internal_errors; /* internal processing errors */
|
||||
|
||||
long long cli_aborts; /* aborted responses during DATA phase caused by the client */
|
||||
long long srv_aborts; /* aborted responses during DATA phase caused by the server */
|
||||
long long intercepted_req; /* number of monitoring or stats requests intercepted by the frontend */
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int rps_max; /* maximum of new HTTP requests second observed */
|
||||
struct freq_ctr _req_per_sec; /* HTTP requests per second on the frontend, only used to compute rps_max */
|
||||
} http;
|
||||
} p; /* protocol-specific stats */
|
||||
};
|
||||
|
||||
struct be_counters_shared_tg {
|
||||
COUNTERS_SHARED_TG;
|
||||
|
||||
long long cum_lbconn; /* cumulated number of sessions processed by load balancing (BE only) */
|
||||
|
||||
long long connect; /* number of connection establishment attempts */
|
||||
long long reuse; /* number of connection reuses */
|
||||
unsigned long last_sess; /* last session time */
|
||||
|
||||
long long failed_checks, failed_hana; /* failed health checks and health analyses for servers */
|
||||
long long down_trans; /* up->down transitions */
|
||||
|
||||
union {
|
||||
struct {
|
||||
long long cum_req; /* cumulated number of processed HTTP requests */
|
||||
|
||||
long long cache_hits; /* cache hits */
|
||||
long long cache_lookups;/* cache lookups */
|
||||
long long cum_req[4]; /* cumulated number of processed other/h1/h2/h3 requests */
|
||||
long long comp_rsp; /* number of compressed responses */
|
||||
unsigned int rps_max; /* maximum of new HTTP requests second observed */
|
||||
long long rsp[6]; /* http response codes */
|
||||
|
||||
long long cache_lookups;/* cache lookups */
|
||||
long long cache_hits; /* cache hits */
|
||||
} http;
|
||||
} p; /* protocol-specific stats */
|
||||
|
||||
long long redispatches; /* retried and redispatched connections (BE only) */
|
||||
long long retries; /* retried and redispatched connections (BE only) */
|
||||
long long failed_resp; /* failed responses (BE only) */
|
||||
long long failed_conns; /* failed connect() attempts (BE only) */
|
||||
};
|
||||
struct freq_ctr sess_per_sec; /* sessions per second on this server */
|
||||
struct freq_ctr req_per_sec; /* HTTP requests per second on the frontend */
|
||||
struct freq_ctr conn_per_sec; /* received connections per second on the frontend */
|
||||
|
||||
struct be_counters_shared {
|
||||
COUNTERS_SHARED;
|
||||
struct be_counters_shared_tg *tg[MAX_TGROUPS];
|
||||
unsigned long last_change; /* last time, when the state was changed */
|
||||
};
|
||||
|
||||
/* counters used by servers and backends */
|
||||
struct be_counters {
|
||||
struct be_counters_shared *shared; /* shared counters */
|
||||
unsigned int conn_max; /* max # of active sessions */
|
||||
long long cum_sess; /* cumulated number of accepted connections */
|
||||
long long cum_lbconn; /* cumulated number of sessions processed by load balancing (BE only) */
|
||||
|
||||
unsigned int cps_max; /* maximum of new connections received per second */
|
||||
unsigned int sps_max; /* maximum of new connections accepted per second (sessions) */
|
||||
unsigned int nbpend_max; /* max number of pending connections with no server assigned yet */
|
||||
unsigned int cur_sess_max; /* max number of currently active sessions */
|
||||
|
||||
struct freq_ctr _sess_per_sec; /* sessions per second on this frontend, used to compute sps_max (internal use only) */
|
||||
long long bytes_in; /* number of bytes transferred from the client to the server */
|
||||
long long bytes_out; /* number of bytes transferred from the server to the client */
|
||||
|
||||
/* compression counters, index 0 for requests, 1 for responses */
|
||||
long long comp_in[2]; /* input bytes fed to the compressor */
|
||||
long long comp_out[2]; /* output bytes emitted by the compressor */
|
||||
long long comp_byp[2]; /* input bytes that bypassed the compressor (cpu/ram/bw limitation) */
|
||||
|
||||
long long denied_req; /* blocked requests because of security concerns */
|
||||
long long denied_resp; /* blocked responses because of security concerns */
|
||||
|
||||
long long connect; /* number of connection establishment attempts */
|
||||
long long reuse; /* number of connection reuses */
|
||||
long long failed_conns; /* failed connect() attempts (BE only) */
|
||||
long long failed_resp; /* failed responses (BE only) */
|
||||
long long cli_aborts; /* aborted responses during DATA phase caused by the client */
|
||||
long long srv_aborts; /* aborted responses during DATA phase caused by the server */
|
||||
long long retries; /* retried and redispatched connections (BE only) */
|
||||
long long redispatches; /* retried and redispatched connections (BE only) */
|
||||
long long failed_rewrites; /* failed rewrites (warning) */
|
||||
long long internal_errors; /* internal processing errors */
|
||||
|
||||
long long failed_checks, failed_hana; /* failed health checks and health analyses for servers */
|
||||
long long down_trans; /* up->down transitions */
|
||||
|
||||
unsigned int q_time, c_time, d_time, t_time; /* sums of conn_time, queue_time, data_time, total_time */
|
||||
unsigned int qtime_max, ctime_max, dtime_max, ttime_max; /* maximum of conn_time, queue_time, data_time, total_time observed */
|
||||
|
||||
union {
|
||||
struct {
|
||||
long long cum_req; /* cumulated number of processed HTTP requests */
|
||||
long long comp_rsp; /* number of compressed responses */
|
||||
unsigned int rps_max; /* maximum of new HTTP requests second observed */
|
||||
long long rsp[6]; /* http response codes */
|
||||
long long cache_lookups;/* cache lookups */
|
||||
long long cache_hits; /* cache hits */
|
||||
} http;
|
||||
} p; /* protocol-specific stats */
|
||||
|
||||
struct freq_ctr sess_per_sec; /* sessions per second on this server */
|
||||
|
||||
unsigned long last_sess; /* last session time */
|
||||
unsigned long last_change; /* last time, when the state was changed */
|
||||
};
|
||||
|
||||
#endif /* _HAPROXY_COUNTERS_T_H */
|
||||
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* include/haproxy/counters.h
|
||||
* objects counters management
|
||||
*
|
||||
* Copyright 2025 HAProxy Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation, version 2.1
|
||||
* exclusively.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _HAPROXY_COUNTERS_H
|
||||
# define _HAPROXY_COUNTERS_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <haproxy/counters-t.h>
|
||||
#include <haproxy/guid-t.h>
|
||||
|
||||
struct fe_counters_shared *counters_fe_shared_get(const struct guid_node *guid);
|
||||
struct be_counters_shared *counters_be_shared_get(const struct guid_node *guid);
|
||||
|
||||
void counters_fe_shared_drop(struct fe_counters_shared *counters);
|
||||
void counters_be_shared_drop(struct be_counters_shared *counters);
|
||||
|
||||
/* time oriented helper: get last time (relative to current time) on a given
|
||||
* <scounter> array, for <elem> member (one member per thread group) which is
|
||||
* assumed to be unsigned long type.
|
||||
*
|
||||
* wrapping is handled by taking the lowest diff between now and last counter.
|
||||
* But since wrapping is expected once every ~136 years (starting 01/01/1970),
|
||||
* perhaps it's not worth the extra CPU cost.. let's see.
|
||||
*/
|
||||
#define COUNTERS_SHARED_LAST_OFFSET(scounters, type, offset) \
|
||||
({ \
|
||||
unsigned long last = HA_ATOMIC_LOAD((type *)((char *)scounters[0] + offset));\
|
||||
unsigned long now_seconds = ns_to_sec(now_ns); \
|
||||
int it; \
|
||||
\
|
||||
for (it = 1; it < global.nbtgroups; it++) { \
|
||||
unsigned long cur = HA_ATOMIC_LOAD((type *)((char *)scounters[it] + offset));\
|
||||
if ((now_seconds - cur) < (now_seconds - last)) \
|
||||
last = cur; \
|
||||
} \
|
||||
last; \
|
||||
})
|
||||
|
||||
#define COUNTERS_SHARED_LAST(scounters, elem) \
|
||||
({ \
|
||||
int offset = offsetof(typeof(**scounters), elem); \
|
||||
unsigned long last = COUNTERS_SHARED_LAST_OFFSET(scounters, typeof(scounters[0]->elem), offset); \
|
||||
\
|
||||
last; \
|
||||
})
|
||||
|
||||
|
||||
/* generic unsigned integer addition for all <elem> members from
|
||||
* <scounters> array (one member per thread group)
|
||||
* <rfunc> is function taking pointer as parameter to read from the memory
|
||||
* location pointed to scounters[it].elem
|
||||
*/
|
||||
#define COUNTERS_SHARED_TOTAL_OFFSET(scounters, type, offset, rfunc) \
|
||||
({ \
|
||||
uint64_t __ret = 0; \
|
||||
int it; \
|
||||
\
|
||||
for (it = 0; it < global.nbtgroups; it++) \
|
||||
__ret += rfunc((type *)((char *)scounters[it] + offset)); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define COUNTERS_SHARED_TOTAL(scounters, elem, rfunc) \
|
||||
({ \
|
||||
int offset = offsetof(typeof(**scounters), elem); \
|
||||
uint64_t __ret = COUNTERS_SHARED_TOTAL_OFFSET(scounters, typeof(scounters[0]->elem), offset, rfunc);\
|
||||
\
|
||||
__ret; \
|
||||
})
|
||||
/* same as COUNTERS_SHARED_TOTAL but with <rfunc> taking 2 extras arguments:
|
||||
* <arg1> and <arg2>
|
||||
*/
|
||||
#define COUNTERS_SHARED_TOTAL_ARG2(scounters, elem, rfunc, arg1, arg2) \
|
||||
({ \
|
||||
uint64_t __ret = 0; \
|
||||
int it; \
|
||||
\
|
||||
for (it = 0; it < global.nbtgroups; it++) \
|
||||
__ret += rfunc(&scounters[it]->elem, arg1, arg2); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#endif /* _HAPROXY_COUNTERS_H */
|
@ -499,7 +499,6 @@ static inline long fd_clr_running(int fd)
|
||||
static inline void fd_insert(int fd, void *owner, void (*iocb)(int fd), int tgid, unsigned long thread_mask)
|
||||
{
|
||||
extern void sock_conn_iocb(int);
|
||||
struct tgroup_info *tginfo = &ha_tgroup_info[tgid - 1];
|
||||
int newstate;
|
||||
|
||||
/* conn_fd_handler should support edge-triggered FDs */
|
||||
@ -529,7 +528,7 @@ static inline void fd_insert(int fd, void *owner, void (*iocb)(int fd), int tgid
|
||||
BUG_ON(fdtab[fd].state != 0);
|
||||
BUG_ON(tgid < 1 || tgid > MAX_TGROUPS);
|
||||
|
||||
thread_mask &= tginfo->threads_enabled;
|
||||
thread_mask &= tg->threads_enabled;
|
||||
BUG_ON(thread_mask == 0);
|
||||
|
||||
fd_claim_tgid(fd, tgid);
|
||||
|
@ -244,7 +244,7 @@ struct listener {
|
||||
struct fe_counters *counters; /* statistics counters */
|
||||
struct mt_list wait_queue; /* link element to make the listener wait for something (LI_LIMITED) */
|
||||
char *name; /* listener's name */
|
||||
char *label; /* listener's label */
|
||||
|
||||
unsigned int thr_conn[MAX_THREADS_PER_GROUP]; /* number of connections per thread for the group */
|
||||
|
||||
struct list by_fe; /* chaining in frontend's list of listeners */
|
||||
|
@ -202,7 +202,7 @@ struct qcc_app_ops {
|
||||
/* Initialize <qcs> stream app context or leave it to NULL if rejected. */
|
||||
int (*attach)(struct qcs *qcs, void *conn_ctx);
|
||||
|
||||
/* Convert received HTTP payload to HTX. Returns amount of decoded bytes from <b> or a negative error code. */
|
||||
/* Convert received HTTP payload to HTX. */
|
||||
ssize_t (*rcv_buf)(struct qcs *qcs, struct buffer *b, int fin);
|
||||
|
||||
/* Convert HTX to HTTP payload for sending. */
|
||||
@ -232,7 +232,7 @@ struct qcc_app_ops {
|
||||
|
||||
#define QC_CF_ERRL 0x00000001 /* fatal error detected locally, connection should be closed soon */
|
||||
#define QC_CF_ERRL_DONE 0x00000002 /* local error properly handled, connection can be released */
|
||||
#define QC_CF_IS_BACK 0x00000004 /* backend side */
|
||||
/* unused 0x00000004 */
|
||||
#define QC_CF_CONN_FULL 0x00000008 /* no stream buffers available on connection */
|
||||
/* unused 0x00000010 */
|
||||
#define QC_CF_ERR_CONN 0x00000020 /* fatal error reported by transport layer */
|
||||
|
@ -311,10 +311,6 @@ struct proxy {
|
||||
char flags; /* bit field PR_FL_* */
|
||||
enum pr_mode mode; /* mode = PR_MODE_TCP, PR_MODE_HTTP, ... */
|
||||
char cap; /* supported capabilities (PR_CAP_*) */
|
||||
/* 4-bytes hole */
|
||||
|
||||
struct list global_list; /* list member for global proxy list */
|
||||
|
||||
unsigned int maxconn; /* max # of active streams on the frontend */
|
||||
|
||||
int options; /* PR_O_REDISP, PR_O_TRANSP, ... */
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <haproxy/thread.h>
|
||||
|
||||
extern struct proxy *proxies_list;
|
||||
extern struct list proxies;
|
||||
extern struct eb_root used_proxy_id; /* list of proxy IDs in use */
|
||||
extern unsigned int error_snapshot_id; /* global ID assigned to each error then incremented */
|
||||
extern struct eb_root proxy_by_name; /* tree of proxies sorted by name */
|
||||
@ -136,24 +135,22 @@ static inline void proxy_reset_timeouts(struct proxy *proxy)
|
||||
/* increase the number of cumulated connections received on the designated frontend */
|
||||
static inline void proxy_inc_fe_conn_ctr(struct listener *l, struct proxy *fe)
|
||||
{
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->cum_conn);
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.cum_conn);
|
||||
if (l && l->counters)
|
||||
_HA_ATOMIC_INC(&l->counters->shared->tg[tgid - 1]->cum_conn);
|
||||
update_freq_ctr(&fe->fe_counters.shared->tg[tgid - 1]->conn_per_sec, 1);
|
||||
_HA_ATOMIC_INC(&l->counters->cum_conn);
|
||||
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.cps_max,
|
||||
update_freq_ctr(&fe->fe_counters._conn_per_sec, 1));
|
||||
update_freq_ctr(&fe->fe_counters.conn_per_sec, 1));
|
||||
}
|
||||
|
||||
/* increase the number of cumulated connections accepted by the designated frontend */
|
||||
static inline void proxy_inc_fe_sess_ctr(struct listener *l, struct proxy *fe)
|
||||
{
|
||||
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->cum_sess);
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.cum_sess);
|
||||
if (l && l->counters)
|
||||
_HA_ATOMIC_INC(&l->counters->shared->tg[tgid - 1]->cum_sess);
|
||||
update_freq_ctr(&fe->fe_counters.shared->tg[tgid - 1]->sess_per_sec, 1);
|
||||
_HA_ATOMIC_INC(&l->counters->cum_sess);
|
||||
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.sps_max,
|
||||
update_freq_ctr(&fe->fe_counters._sess_per_sec, 1));
|
||||
update_freq_ctr(&fe->fe_counters.sess_per_sec, 1));
|
||||
}
|
||||
|
||||
/* increase the number of cumulated HTTP sessions on the designated frontend.
|
||||
@ -163,21 +160,20 @@ static inline void proxy_inc_fe_cum_sess_ver_ctr(struct listener *l, struct prox
|
||||
unsigned int http_ver)
|
||||
{
|
||||
if (http_ver == 0 ||
|
||||
http_ver > sizeof(fe->fe_counters.shared->tg[tgid - 1]->cum_sess_ver) / sizeof(*fe->fe_counters.shared->tg[tgid - 1]->cum_sess_ver))
|
||||
http_ver > sizeof(fe->fe_counters.cum_sess_ver) / sizeof(*fe->fe_counters.cum_sess_ver))
|
||||
return;
|
||||
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->cum_sess_ver[http_ver - 1]);
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.cum_sess_ver[http_ver - 1]);
|
||||
if (l && l->counters)
|
||||
_HA_ATOMIC_INC(&l->counters->shared->tg[tgid - 1]->cum_sess_ver[http_ver - 1]);
|
||||
_HA_ATOMIC_INC(&l->counters->cum_sess_ver[http_ver - 1]);
|
||||
}
|
||||
|
||||
/* increase the number of cumulated streams on the designated backend */
|
||||
static inline void proxy_inc_be_ctr(struct proxy *be)
|
||||
{
|
||||
_HA_ATOMIC_INC(&be->be_counters.shared->tg[tgid - 1]->cum_sess);
|
||||
update_freq_ctr(&be->be_counters.shared->tg[tgid - 1]->sess_per_sec, 1);
|
||||
_HA_ATOMIC_INC(&be->be_counters.cum_sess);
|
||||
HA_ATOMIC_UPDATE_MAX(&be->be_counters.sps_max,
|
||||
update_freq_ctr(&be->be_counters._sess_per_sec, 1));
|
||||
update_freq_ctr(&be->be_counters.sess_per_sec, 1));
|
||||
}
|
||||
|
||||
/* increase the number of cumulated requests on the designated frontend.
|
||||
@ -187,15 +183,14 @@ static inline void proxy_inc_be_ctr(struct proxy *be)
|
||||
static inline void proxy_inc_fe_req_ctr(struct listener *l, struct proxy *fe,
|
||||
unsigned int http_ver)
|
||||
{
|
||||
if (http_ver >= sizeof(fe->fe_counters.shared->tg[tgid - 1]->p.http.cum_req) / sizeof(*fe->fe_counters.shared->tg[tgid - 1]->p.http.cum_req))
|
||||
if (http_ver >= sizeof(fe->fe_counters.p.http.cum_req) / sizeof(*fe->fe_counters.p.http.cum_req))
|
||||
return;
|
||||
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.shared->tg[tgid - 1]->p.http.cum_req[http_ver]);
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.p.http.cum_req[http_ver]);
|
||||
if (l && l->counters)
|
||||
_HA_ATOMIC_INC(&l->counters->shared->tg[tgid - 1]->p.http.cum_req[http_ver]);
|
||||
update_freq_ctr(&fe->fe_counters.shared->tg[tgid - 1]->req_per_sec, 1);
|
||||
_HA_ATOMIC_INC(&l->counters->p.http.cum_req[http_ver]);
|
||||
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.p.http.rps_max,
|
||||
update_freq_ctr(&fe->fe_counters.p.http._req_per_sec, 1));
|
||||
update_freq_ctr(&fe->fe_counters.req_per_sec, 1));
|
||||
}
|
||||
|
||||
/* Returns non-zero if the proxy is configured to retry a request if we got that status, 0 otherwise */
|
||||
|
@ -228,9 +228,6 @@ struct quic_version {
|
||||
extern const struct quic_version quic_versions[];
|
||||
extern const size_t quic_versions_nb;
|
||||
extern const struct quic_version *preferred_version;
|
||||
extern const struct quic_version *quic_version_draft_29;
|
||||
extern const struct quic_version *quic_version_1;
|
||||
extern const struct quic_version *quic_version_2;
|
||||
|
||||
/* unused: 0x01 */
|
||||
/* Flag the packet number space as requiring an ACK frame to be sent. */
|
||||
@ -308,7 +305,6 @@ struct qcc_app_ops;
|
||||
/* Number of received bytes. */ \
|
||||
uint64_t rx; \
|
||||
} bytes; \
|
||||
size_t max_udp_payload; \
|
||||
/* First DCID used by client on its Initial packet. */ \
|
||||
struct quic_cid odcid; \
|
||||
/* DCID of our endpoint - not updated when a new DCID is used */ \
|
||||
@ -319,7 +315,7 @@ struct qcc_app_ops;
|
||||
* with a connection \
|
||||
*/ \
|
||||
struct eb_root *cids; \
|
||||
enum obj_type *target; \
|
||||
struct listener *li; /* only valid for frontend connections */ \
|
||||
/* Idle timer task */ \
|
||||
struct task *idle_timer_task; \
|
||||
unsigned int idle_expire; \
|
||||
@ -460,7 +456,6 @@ struct quic_conn_closed {
|
||||
#define QUIC_FL_CONN_HPKTNS_DCD (1U << 16) /* Handshake packet number space discarded */
|
||||
#define QUIC_FL_CONN_PEER_VALIDATED_ADDR (1U << 17) /* Peer address is considered as validated for this connection. */
|
||||
#define QUIC_FL_CONN_NO_TOKEN_RCVD (1U << 18) /* Client dit not send any token */
|
||||
#define QUIC_FL_CONN_SCID_RECEIVED (1U << 19) /* (client only: first Initial received. */
|
||||
/* gap here */
|
||||
#define QUIC_FL_CONN_TO_KILL (1U << 24) /* Unusable connection, to be killed */
|
||||
#define QUIC_FL_CONN_TX_TP_RECEIVED (1U << 25) /* Peer transport parameters have been received (used for the transmitting part) */
|
||||
|
@ -69,8 +69,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
struct quic_connection_id *conn_id,
|
||||
struct sockaddr_storage *local_addr,
|
||||
struct sockaddr_storage *peer_addr,
|
||||
int token, void *owner,
|
||||
struct connection *conn);
|
||||
int server, int token, void *owner);
|
||||
int quic_build_post_handshake_frames(struct quic_conn *qc);
|
||||
const struct quic_version *qc_supported_version(uint32_t version);
|
||||
int quic_peer_validated_addr(struct quic_conn *qc);
|
||||
@ -164,22 +163,6 @@ static inline void quic_free_ncbuf(struct ncbuf *ncbuf)
|
||||
*ncbuf = NCBUF_NULL;
|
||||
}
|
||||
|
||||
/* Return the address of the QUIC counters attached to the proxy of
|
||||
* the owner of the connection whose object type address is <o> for
|
||||
* listener and servers, or NULL for others object type.
|
||||
*/
|
||||
static inline void *qc_counters(enum obj_type *o, const struct stats_module *m)
|
||||
{
|
||||
struct proxy *p;
|
||||
struct listener *l = objt_listener(o);
|
||||
struct server *s = objt_server(o);
|
||||
|
||||
p = l ? l->bind_conf->frontend :
|
||||
s ? s->proxy : NULL;
|
||||
|
||||
return p ? EXTRA_COUNTERS_GET(p->extra_counters_fe, m) : NULL;
|
||||
}
|
||||
|
||||
void chunk_frm_appendf(struct buffer *buf, const struct quic_frame *frm);
|
||||
void quic_set_connection_close(struct quic_conn *qc, const struct quic_err err);
|
||||
void quic_set_tls_alert(struct quic_conn *qc, int alert);
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <haproxy/quic_rx-t.h>
|
||||
|
||||
int quic_dgram_parse(struct quic_dgram *dgram, struct quic_conn *from_qc,
|
||||
enum obj_type *obj_type);
|
||||
struct listener *li);
|
||||
int qc_treat_rx_pkts(struct quic_conn *qc);
|
||||
int qc_parse_hd_form(struct quic_rx_packet *pkt,
|
||||
unsigned char **pos, const unsigned char *end);
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <haproxy/connection-t.h>
|
||||
#include <haproxy/fd-t.h>
|
||||
#include <haproxy/listener-t.h>
|
||||
#include <haproxy/obj_type.h>
|
||||
#include <haproxy/quic_conn-t.h>
|
||||
#include <haproxy/quic_sock-t.h>
|
||||
|
||||
@ -79,8 +78,7 @@ static inline char qc_test_fd(struct quic_conn *qc)
|
||||
*/
|
||||
static inline int qc_fd(struct quic_conn *qc)
|
||||
{
|
||||
/* TODO: check this: For backends, qc->fd is always initialized */
|
||||
return qc_test_fd(qc) ? qc->fd : __objt_listener(qc->target)->rx.fd;
|
||||
return qc_test_fd(qc) ? qc->fd : qc->li->rx.fd;
|
||||
}
|
||||
|
||||
/* Try to increment <l> handshake current counter. If listener limit is
|
||||
|
@ -34,8 +34,7 @@
|
||||
#include <haproxy/ssl_sock-t.h>
|
||||
|
||||
int ssl_quic_initial_ctx(struct bind_conf *bind_conf);
|
||||
SSL_CTX *ssl_quic_srv_new_ssl_ctx(void);
|
||||
int qc_alloc_ssl_sock_ctx(struct quic_conn *qc, struct connection *conn);
|
||||
int qc_alloc_ssl_sock_ctx(struct quic_conn *qc);
|
||||
int qc_ssl_provide_all_quic_data(struct quic_conn *qc, struct ssl_sock_ctx *ctx);
|
||||
int quic_ssl_set_tls_cbs(SSL *ssl);
|
||||
|
||||
|
@ -26,9 +26,6 @@ int qc_lstnr_params_init(struct quic_conn *qc,
|
||||
const unsigned char *dcid, size_t dcidlen,
|
||||
const unsigned char *scid, size_t scidlen,
|
||||
const struct quic_cid *token_odcid);
|
||||
void qc_srv_params_init(struct quic_conn *qc,
|
||||
const struct quic_transport_params *srv_params,
|
||||
const unsigned char *scid, size_t scidlen);
|
||||
|
||||
/* Dump <cid> transport parameter connection ID value if present (non null length).
|
||||
* Used only for debugging purposes.
|
||||
|
@ -171,7 +171,6 @@ enum srv_init_state {
|
||||
#define SRV_F_DEFSRV_USE_SSL 0x4000 /* default-server uses SSL */
|
||||
#define SRV_F_DELETED 0x8000 /* srv is deleted but not yet purged */
|
||||
#define SRV_F_STRICT_MAXCONN 0x10000 /* maxconn is to be strictly enforced, as a limit of outbound connections */
|
||||
#define SRV_F_CHECKED 0x20000 /* set once server was postparsed */
|
||||
|
||||
/* configured server options for send-proxy (server->pp_opts) */
|
||||
#define SRV_PP_V1 0x0001 /* proxy protocol version 1 */
|
||||
@ -478,9 +477,6 @@ struct server {
|
||||
char *alpn_str; /* ALPN protocol string */
|
||||
int alpn_len; /* ALPN protocol string length */
|
||||
} ssl_ctx;
|
||||
#ifdef USE_QUIC
|
||||
struct quic_transport_params quic_params; /* QUIC transport parameters */
|
||||
#endif
|
||||
struct resolv_srvrq *srvrq; /* Pointer representing the DNS SRV requeest, if any */
|
||||
struct list srv_rec_item; /* to attach server to a srv record item */
|
||||
struct list ip_rec_item; /* to attach server to a A or AAAA record item */
|
||||
|
@ -73,7 +73,7 @@ struct server *new_server(struct proxy *proxy);
|
||||
void srv_take(struct server *srv);
|
||||
struct server *srv_drop(struct server *srv);
|
||||
void srv_free_params(struct server *srv);
|
||||
int srv_init(struct server *srv);
|
||||
int srv_init_per_thr(struct server *srv);
|
||||
void srv_set_ssl(struct server *s, int use_ssl);
|
||||
const char *srv_adm_st_chg_cause(enum srv_adm_st_chg_cause cause);
|
||||
const char *srv_op_st_chg_cause(enum srv_op_st_chg_cause cause);
|
||||
@ -181,16 +181,15 @@ const struct mux_ops *srv_get_ws_proto(struct server *srv);
|
||||
/* increase the number of cumulated streams on the designated server */
|
||||
static inline void srv_inc_sess_ctr(struct server *s)
|
||||
{
|
||||
_HA_ATOMIC_INC(&s->counters.shared->tg[tgid - 1]->cum_sess);
|
||||
update_freq_ctr(&s->counters.shared->tg[tgid - 1]->sess_per_sec, 1);
|
||||
_HA_ATOMIC_INC(&s->counters.cum_sess);
|
||||
HA_ATOMIC_UPDATE_MAX(&s->counters.sps_max,
|
||||
update_freq_ctr(&s->counters._sess_per_sec, 1));
|
||||
update_freq_ctr(&s->counters.sess_per_sec, 1));
|
||||
}
|
||||
|
||||
/* set the time of last session on the designated server */
|
||||
static inline void srv_set_sess_last(struct server *s)
|
||||
{
|
||||
HA_ATOMIC_STORE(&s->counters.shared->tg[tgid - 1]->last_sess, ns_to_sec(now_ns));
|
||||
s->counters.last_sess = ns_to_sec(now_ns);
|
||||
}
|
||||
|
||||
/* returns the current server throttle rate between 0 and 100% */
|
||||
@ -320,39 +319,6 @@ static inline int srv_is_transparent(const struct server *srv)
|
||||
(srv->flags & SRV_F_MAPPORTS);
|
||||
}
|
||||
|
||||
/* Detach server from proxy list. It is supported to call this
|
||||
* even if the server is not yet in the list
|
||||
* Must be called under thread isolation or when it is safe to assume
|
||||
* that the parent proxy doesn't is not skimming through the server list
|
||||
*/
|
||||
static inline void srv_detach(struct server *srv)
|
||||
{
|
||||
struct proxy *px = srv->proxy;
|
||||
|
||||
if (px->srv == srv)
|
||||
px->srv = srv->next;
|
||||
else {
|
||||
struct server *prev;
|
||||
|
||||
for (prev = px->srv; prev && prev->next != srv; prev = prev->next)
|
||||
;
|
||||
|
||||
BUG_ON(!prev);
|
||||
|
||||
prev->next = srv->next;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int srv_is_quic(const struct server *srv)
|
||||
{
|
||||
#ifdef USE_QUIC
|
||||
return srv->addr_type.proto_type == PROTO_TYPE_DGRAM &&
|
||||
srv->addr_type.xprt_type == PROTO_TYPE_STREAM;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* _HAPROXY_SERVER_H */
|
||||
|
||||
/*
|
||||
|
@ -28,11 +28,9 @@
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/connection-t.h>
|
||||
#include <haproxy/listener-t.h>
|
||||
#include <haproxy/protocol-t.h>
|
||||
#include <haproxy/sock-t.h>
|
||||
|
||||
int sock_create_server_socket(struct connection *conn, struct proxy *be,
|
||||
enum proto_type proto_type, int sock_type, int *stream_err);
|
||||
int sock_create_server_socket(struct connection *conn, struct proxy *be, int *stream_err);
|
||||
void sock_enable(struct receiver *rx);
|
||||
void sock_disable(struct receiver *rx);
|
||||
void sock_unbind(struct receiver *rx);
|
||||
|
@ -62,7 +62,7 @@ struct ckch_inst *ckch_inst_new();
|
||||
int ckch_inst_new_load_store(const char *path, struct ckch_store *ckchs, struct bind_conf *bind_conf,
|
||||
struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount, int is_default, struct ckch_inst **ckchi, char **err);
|
||||
int ckch_inst_new_load_srv_store(const char *path, struct ckch_store *ckchs,
|
||||
struct ckch_inst **ckchi, char **err, int is_quic);
|
||||
struct ckch_inst **ckchi, char **err);
|
||||
int ckch_inst_rebuild(struct ckch_store *ckch_store, struct ckch_inst *ckchi,
|
||||
struct ckch_inst **new_inst, char **err);
|
||||
|
||||
|
@ -342,11 +342,6 @@ enum stat_idx_info {
|
||||
ST_I_INF_MAX
|
||||
};
|
||||
|
||||
/* Flags for stat_col.flags */
|
||||
#define STAT_COL_FL_NONE 0x00
|
||||
#define STAT_COL_FL_GENERIC 0x01 /* stat is generic if set */
|
||||
#define STAT_COL_FL_SHARED 0x02 /* stat may be shared between co-processes if set */
|
||||
|
||||
/* Represent an exposed statistic. */
|
||||
struct stat_col {
|
||||
const char *name; /* short name, used notably in CSV headers */
|
||||
@ -355,8 +350,8 @@ struct stat_col {
|
||||
|
||||
uint32_t type; /* combination of field_nature and field_format */
|
||||
uint8_t cap; /* mask of stats_domain_px_cap to restrain metrics to an object types subset */
|
||||
/* 1 byte hole */
|
||||
uint16_t flags; /* STAT_COL_FL_* flags */
|
||||
uint8_t generic; /* bit set if generic */
|
||||
/* 2 bytes hole */
|
||||
|
||||
/* used only for generic metrics */
|
||||
struct {
|
||||
|
@ -79,7 +79,7 @@ int stats_emit_field_tags(struct buffer *out, const struct field *f,
|
||||
/* Returns true if <col> is fully defined, false if only used as name-desc. */
|
||||
static inline int stcol_is_generic(const struct stat_col *col)
|
||||
{
|
||||
return col->flags & STAT_COL_FL_GENERIC;
|
||||
return col->generic;
|
||||
}
|
||||
|
||||
static inline enum field_format stcol_format(const struct stat_col *col)
|
||||
|
@ -362,8 +362,8 @@ static inline void stream_choose_redispatch(struct stream *s)
|
||||
s->scb->state = SC_ST_REQ;
|
||||
} else {
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->tg[tgid - 1]->retries);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->retries);
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.retries);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.retries);
|
||||
s->scb->state = SC_ST_ASS;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#ifdef CONFIG_PRODUCT_BRANCH
|
||||
#define PRODUCT_BRANCH CONFIG_PRODUCT_BRANCH
|
||||
#else
|
||||
#define PRODUCT_BRANCH "3.3"
|
||||
#define PRODUCT_BRANCH "3.2"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PRODUCT_STATUS
|
||||
|
@ -14,7 +14,7 @@ See also: doc/regression-testing.txt
|
||||
|
||||
* vtest compilation *
|
||||
|
||||
$ git clone https://github.com/vtest/VTest2
|
||||
$ git clone https://github.com/vtest/VTest
|
||||
|
||||
$ cd VTest
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
vtest "Test for balance URI"
|
||||
feature ignore_unknown_macro
|
||||
#REQUIRE_VERSION=2.3
|
||||
|
||||
server s1 {
|
||||
rxreq
|
||||
|
2
reg-tests/cache/caching_rules.vtc
vendored
2
reg-tests/cache/caching_rules.vtc
vendored
@ -2,6 +2,8 @@ varnishtest "Caching rules test"
|
||||
# A response will not be cached unless it has an explicit age (Cache-Control max-age of s-maxage, Expires) or a validator (Last-Modified, or ETag)
|
||||
# A response will not be cached either if it has an Age header that is either invalid (should be an integer) or greater than its max age.
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/expires.vtc
vendored
2
reg-tests/cache/expires.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "Expires support"
|
||||
|
||||
#REQUIRE_VERSION=2.3
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/if-modified-since.vtc
vendored
2
reg-tests/cache/if-modified-since.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "If-Modified-Since support"
|
||||
|
||||
#REQUIRE_VERSION=2.3
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/if-none-match.vtc
vendored
2
reg-tests/cache/if-none-match.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "If-None-Match support"
|
||||
|
||||
#REQUIRE_VERSION=2.3
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/post_on_entry.vtc
vendored
2
reg-tests/cache/post_on_entry.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "A successful unsafe method (POST for instance) on a cached entry must disable it."
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/vary.vtc
vendored
2
reg-tests/cache/vary.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "Vary support"
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
2
reg-tests/cache/vary_accept_encoding.vtc
vendored
2
reg-tests/cache/vary_accept_encoding.vtc
vendored
@ -1,5 +1,7 @@
|
||||
varnishtest "Check the Accept-Encoding processing implemented in the Vary mechanism"
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
@ -6,6 +6,7 @@ feature ignore_unknown_macro
|
||||
# The first health-checks passed tests are checked for all these servers
|
||||
# thanks to syslog messages.
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
#EXCLUDE_TARGETS=freebsd
|
||||
#REGTEST_TYPE=slow
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
varnishtest "Health-checks"
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
#EXCLUDE_TARGETS=freebsd,osx,generic
|
||||
#REGTEST_TYPE=slow
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
varnishtest "Health-check test"
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
#EXCLUDE_TARGETS=freebsd
|
||||
#REGTEST_TYPE=slow
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
varnishtest "Health-checks: http-check send test"
|
||||
#REGTEST_TYPE=slow
|
||||
#REQUIRE_VERSION=2.4
|
||||
feature ignore_unknown_macro
|
||||
|
||||
# This script tests HTTP health-checks and more particularly the "http-check
|
||||
|
@ -5,6 +5,8 @@ feature cmd "$HAPROXY_PROGRAM -cc 'feature(TPROXY)'"
|
||||
# as private and should only be reused for requests of the same session.
|
||||
# This is similar to the http-reuse never mode
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
haproxy h1 -conf {
|
||||
|
@ -1,4 +1,5 @@
|
||||
varnishtest "Test the http-reuse with special connection parameters"
|
||||
#REQUIRE_VERSION=2.4
|
||||
#REQUIRE_OPTIONS=OPENSSL
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
@ -4,6 +4,8 @@ varnishtest "Test the proper interaction between http-reuse and dispatch mode"
|
||||
# reused for requests of the same session
|
||||
# This is similar to the http-reuse never mode
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
haproxy h1 -conf {
|
||||
|
@ -1,5 +1,7 @@
|
||||
varnishtest "Check that the TLVs are properly validated"
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
# We need one HAProxy for each test, because apparently the connection by
|
||||
|
@ -1,5 +1,7 @@
|
||||
varnishtest "Test connection upgrades from TCP to HTTP"
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
@ -1,4 +1,5 @@
|
||||
varnishtest "fix converters Test"
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
varnishtest "iif converter Test"
|
||||
#REQUIRE_VERSION=2.3
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
varnishtest "JSON Query converters Test"
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
varnishtest "mqtt converters Test"
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
@ -234,4 +235,4 @@ client c3_31_1 -connect ${h1_fe1_sock} {
|
||||
# Valid MQTT 3.1 CONNECT packet (id: test_sub - username: test - passwd: passwd)
|
||||
sendhex "102400064d514973647003c200000008746573745f7375620004746573740006706173737764"
|
||||
recv 4
|
||||
} -run
|
||||
} -run
|
@ -1,5 +1,7 @@
|
||||
varnishtest "url_enc converter test"
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
@ -1,5 +1,6 @@
|
||||
varnishtest "Filtering test with several filters and random forwarding (via trace filter)"
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
#REQUIRE_OPTION=ZLIB|SLZ
|
||||
#REGTEST_TYPE=slow
|
||||
|
||||
|
@ -2,7 +2,7 @@ varnishtest "HTTP request tests: H1 request target parsing"
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(3.0-dev0)'"
|
||||
#REQUIRE_VERSION=3.0
|
||||
|
||||
haproxy h1 -conf {
|
||||
global
|
||||
|
@ -1,6 +1,8 @@
|
||||
varnishtest "A test to be sure payload is skipped for bodyless responses"
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
server s1 {
|
||||
rxreq
|
||||
txresp \
|
||||
|
@ -5,6 +5,8 @@ feature cmd "$HAPROXY_PROGRAM $HAPROXY_ARGS -cc 'enabled(FAST-FORWARD)'"
|
||||
feature cmd "$HAPROXY_PROGRAM $HAPROXY_ARGS -cc 'enabled(SPLICE)'"
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
server s1 {
|
||||
rxreq
|
||||
txresp \
|
||||
|
61
reg-tests/http-messaging/http_msg_full_on_eom.vtc
Normal file
61
reg-tests/http-messaging/http_msg_full_on_eom.vtc
Normal file
@ -0,0 +1,61 @@
|
||||
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,6 +1,7 @@
|
||||
varnishtest "A test for the wait-for-body HTTP action"
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
#REGTEST_TYPE=slow
|
||||
|
||||
server s1 {
|
||||
|
@ -8,6 +8,8 @@ varnishtest "h1/h2 support for protocol upgrade test"
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
# http/1.1 server
|
||||
server srv_h1 {
|
||||
rxreq
|
||||
|
@ -12,6 +12,8 @@ varnishtest "WebSocket test"
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
# valid websocket server
|
||||
server s1 {
|
||||
rxreq
|
||||
|
@ -1,4 +1,5 @@
|
||||
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
|
||||
# options.
|
||||
|
@ -1,4 +1,5 @@
|
||||
varnishtest "normalize-uri tests"
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
# This reg-test tests the http-request normalize-uri action.
|
||||
|
||||
|
@ -2,6 +2,8 @@ varnishtest "http-request set-timeout test"
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
server srv_h1 -repeat 9 {
|
||||
rxreq
|
||||
txresp
|
||||
|
@ -1,6 +1,8 @@
|
||||
varnishtest "Verify logging of relative/absolute URI path"
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
server s1 {
|
||||
rxreq
|
||||
txresp -hdr "Connection: close"
|
||||
|
@ -49,7 +49,6 @@ client c1 -connect ${h1_frt_sock} -repeat 100 {
|
||||
syslog Slog -wait
|
||||
|
||||
shell {
|
||||
set +e
|
||||
ss -pt | grep CLOSE-WAIT.*haproxy.*pid=${h1_pid}
|
||||
exit $((!$?))
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
varnishtest "Lua: txn:get_priv() scope"
|
||||
#REQUIRE_OPTIONS=LUA,OPENSSL
|
||||
#REQUIRE_VERSION=2.4
|
||||
#REGTEST_TYPE=bug
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
@ -355,8 +355,8 @@ client c9 -connect ${h1_mainfe_sock} {
|
||||
} -run
|
||||
|
||||
client c10 -connect ${h1_mainfe_sock} {
|
||||
txreq -url "/converter" -hdr "User-Agent: c10" -hdr "X-Cust: foobar"
|
||||
txreq -url "/converter" -hdr "X-Cust: foobar"
|
||||
rxresp
|
||||
expect resp.status == 200
|
||||
expect resp.http.x-var == "proc.req_len=52 sess.x_cust=foobar"
|
||||
expect resp.http.x-var == "proc.req_len=35 sess.x_cust=foobar"
|
||||
} -run
|
||||
|
@ -1,5 +1,7 @@
|
||||
varnishtest "Hash validity test"
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s1 {
|
||||
|
@ -1,5 +1,7 @@
|
||||
varnishtest "ub64dec sample fetche Test"
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
haproxy h1 -conf {
|
||||
|
@ -2,6 +2,8 @@ varnishtest "Add server via cli"
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
server s1 {
|
||||
rxreq
|
||||
txresp
|
||||
|
@ -5,6 +5,8 @@ varnishtest "Delete server via cli"
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
# static server
|
||||
server s1 -repeat 3 {
|
||||
rxreq
|
||||
|
@ -3,6 +3,7 @@ varnishtest "Set server ssl via CLI"
|
||||
feature ignore_unknown_macro
|
||||
|
||||
# for "set server <srv> ssl"
|
||||
#REQUIRE_VERSION=2.4
|
||||
#REGTEST_TYPE=devel
|
||||
#REQUIRE_OPTIONS=OPENSSL
|
||||
|
||||
|
@ -6,6 +6,7 @@ varnishtest "Delete server via cli and update certificates"
|
||||
|
||||
feature ignore_unknown_macro
|
||||
|
||||
#REQUIRE_VERSION=2.4
|
||||
#REQUIRE_OPTIONS=OPENSSL
|
||||
feature cmd "command -v socat"
|
||||
|
||||
|
@ -47,7 +47,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 1"
|
||||
@ -78,7 +77,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 2"
|
||||
@ -109,7 +107,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 3"
|
||||
@ -141,7 +138,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 4"
|
||||
@ -173,7 +169,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 5"
|
||||
@ -205,7 +200,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 6"
|
||||
@ -238,7 +232,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 7"
|
||||
@ -270,7 +263,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 8"
|
||||
@ -303,7 +295,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 9"
|
||||
@ -336,7 +327,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 10"
|
||||
@ -369,7 +359,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 11"
|
||||
@ -402,7 +391,6 @@ listen ssl-lst
|
||||
server s1 127.0.0.1:80
|
||||
EOF
|
||||
|
||||
set +e
|
||||
haproxy_output="$($HAPROXY_PROGRAM -f ${tmpdir}/ocsp_compat_check.cfg -c 2>&1)"
|
||||
haproxy_ret=$?
|
||||
echo "==== test 12"
|
||||
|
@ -15,6 +15,7 @@
|
||||
# This should be backported to 1.8
|
||||
|
||||
#REGTEST_TYPE=bug
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
varnishtest "stick-tables: Test expirations when used with table_*"
|
||||
|
||||
|
@ -6,6 +6,8 @@ feature ignore_unknown_macro
|
||||
# do the job they are supposed to do.
|
||||
# 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_2 {}
|
||||
server s_not_used_3 {}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
set -eux
|
||||
|
||||
curl -fsSL https://github.com/vtest/VTest2/archive/main.tar.gz -o VTest.tar.gz
|
||||
curl -fsSL https://github.com/wlallemand/VTest/archive/refs/heads/haproxy-sd_notify.tar.gz -o VTest.tar.gz
|
||||
mkdir ../vtest
|
||||
tar xvf VTest.tar.gz -C ../vtest --strip-components=1
|
||||
# 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)
|
||||
#
|
||||
if test -f /opt/homebrew/include/pcre2.h; then
|
||||
make -j${CPUS} FLAGS="-O2 -s -Wall" INCS="-I. -Isrc -Ilib -I/usr/local/include -I/opt/homebrew/include -pthread"
|
||||
make -j${CPUS} FLAGS="-O2 -s -Wall" INCS="-Isrc -Ilib -I/usr/local/include -I/opt/homebrew/include -pthread"
|
||||
else
|
||||
make -j${CPUS} FLAGS="-O2 -s -Wall"
|
||||
fi
|
||||
|
@ -52,6 +52,10 @@ _help()
|
||||
#REQUIRE_SERVICE=prometheus-exporter
|
||||
#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
|
||||
setenv HAPROXY_PROGRAM /usr/local/sbin/haproxy
|
||||
setenv VTEST_PROGRAM /usr/local/bin/vtest
|
||||
@ -120,13 +124,15 @@ _findtests() {
|
||||
set -- $(grep '^#[0-9A-Z_]*=' "$i")
|
||||
IFS="$OLDIFS"
|
||||
|
||||
require_options="";
|
||||
require_version=""; require_version_below=""; require_options="";
|
||||
require_services=""; exclude_targets=""; regtest_type=""
|
||||
requiredoption=""; requiredservice=""; excludedtarget="";
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
v="$1"; v="${v#*=}"
|
||||
case "$1" in
|
||||
"#REQUIRE_VERSION="*) require_version="$v" ;;
|
||||
"#REQUIRE_VERSION_BELOW="*) require_version_below="$v" ;;
|
||||
"#REQUIRE_OPTIONS="*) require_options="$v" ;;
|
||||
"#REQUIRE_SERVICES="*) require_services="$v" ;;
|
||||
"#EXCLUDE_TARGETS="*) exclude_targets="$v" ;;
|
||||
@ -165,6 +171,21 @@ _findtests() {
|
||||
IFS=","; set -- $require_services; IFS=$OLDIFS; require_services="$*"
|
||||
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
|
||||
if [ "$excludedtarget" = "$TARGET" ]; then
|
||||
echo " Skip $i because haproxy is compiled for the excluded target $TARGET"
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <haproxy/backend.h>
|
||||
#include <haproxy/channel.h>
|
||||
#include <haproxy/check.h>
|
||||
#include <haproxy/counters.h>
|
||||
#include <haproxy/frontend.h>
|
||||
#include <haproxy/global.h>
|
||||
#include <haproxy/hash.h>
|
||||
@ -825,8 +824,8 @@ int assign_server(struct stream *s)
|
||||
goto out;
|
||||
}
|
||||
else if (srv != prev_srv) {
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->cum_lbconn);
|
||||
_HA_ATOMIC_INC(&srv->counters.shared->tg[tgid - 1]->cum_lbconn);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.cum_lbconn);
|
||||
_HA_ATOMIC_INC(&srv->counters.cum_lbconn);
|
||||
}
|
||||
s->target = &srv->obj_type;
|
||||
}
|
||||
@ -1000,11 +999,11 @@ int assign_server_and_queue(struct stream *s)
|
||||
s->txn->flags |= TX_CK_DOWN;
|
||||
}
|
||||
s->flags |= SF_REDISP;
|
||||
_HA_ATOMIC_INC(&prev_srv->counters.shared->tg[tgid - 1]->redispatches);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->redispatches);
|
||||
_HA_ATOMIC_INC(&prev_srv->counters.redispatches);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.redispatches);
|
||||
} else {
|
||||
_HA_ATOMIC_INC(&prev_srv->counters.shared->tg[tgid - 1]->retries);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->retries);
|
||||
_HA_ATOMIC_INC(&prev_srv->counters.retries);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.retries);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1992,9 +1991,7 @@ int connect_server(struct stream *s)
|
||||
/* set the correct protocol on the output stream connector */
|
||||
|
||||
if (srv) {
|
||||
struct protocol *proto = protocol_lookup(srv_conn->dst->ss_family, srv->addr_type.proto_type, srv->alt_proto);
|
||||
|
||||
if (conn_prepare(srv_conn, proto, srv->xprt)) {
|
||||
if (conn_prepare(srv_conn, protocol_lookup(srv_conn->dst->ss_family, PROTO_TYPE_STREAM, srv->alt_proto), srv->xprt)) {
|
||||
conn_free(srv_conn);
|
||||
return SF_ERR_INTERNAL;
|
||||
}
|
||||
@ -2020,13 +2017,9 @@ int connect_server(struct stream *s)
|
||||
srv_conn->ctx = s->scb;
|
||||
|
||||
#if defined(USE_OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
|
||||
/* Delay mux initialization if SSL and ALPN/NPN is set. Note
|
||||
* that this is skipped in TCP mode as we only want mux-pt
|
||||
* anyway.
|
||||
*/
|
||||
if (!srv ||
|
||||
(srv->use_ssl != 1 || (!(srv->ssl_ctx.alpn_str) && !(srv->ssl_ctx.npn_str)) ||
|
||||
!IS_HTX_STRM(s)))
|
||||
srv->mux_proto || !IS_HTX_STRM(s)))
|
||||
#endif
|
||||
init_mux = 1;
|
||||
|
||||
@ -2091,13 +2084,13 @@ int connect_server(struct stream *s)
|
||||
s->scb->flags |= SC_FL_NOLINGER;
|
||||
|
||||
if (s->flags & SF_SRV_REUSED) {
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->reuse);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.reuse);
|
||||
if (srv)
|
||||
_HA_ATOMIC_INC(&srv->counters.shared->tg[tgid - 1]->reuse);
|
||||
_HA_ATOMIC_INC(&srv->counters.reuse);
|
||||
} else {
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->connect);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.connect);
|
||||
if (srv)
|
||||
_HA_ATOMIC_INC(&srv->counters.shared->tg[tgid - 1]->connect);
|
||||
_HA_ATOMIC_INC(&srv->counters.connect);
|
||||
}
|
||||
|
||||
err = do_connect_server(s, srv_conn);
|
||||
@ -2286,8 +2279,8 @@ int srv_redispatch_connect(struct stream *s)
|
||||
s->conn_err_type = STRM_ET_QUEUE_ERR;
|
||||
}
|
||||
|
||||
_HA_ATOMIC_INC(&srv->counters.shared->tg[tgid - 1]->failed_conns);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_conns);
|
||||
_HA_ATOMIC_INC(&srv->counters.failed_conns);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
|
||||
return 1;
|
||||
|
||||
case SRV_STATUS_NOSRV:
|
||||
@ -2296,7 +2289,7 @@ int srv_redispatch_connect(struct stream *s)
|
||||
s->conn_err_type = STRM_ET_CONN_ERR;
|
||||
}
|
||||
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_conns);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
|
||||
return 1;
|
||||
|
||||
case SRV_STATUS_QUEUED:
|
||||
@ -2325,8 +2318,8 @@ int srv_redispatch_connect(struct stream *s)
|
||||
if (srv)
|
||||
srv_set_sess_last(srv);
|
||||
if (srv)
|
||||
_HA_ATOMIC_INC(&srv->counters.shared->tg[tgid - 1]->failed_conns);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_conns);
|
||||
_HA_ATOMIC_INC(&srv->counters.failed_conns);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
|
||||
|
||||
/* release other streams waiting for this server */
|
||||
if (may_dequeue_tasks(srv, s->be))
|
||||
@ -2400,8 +2393,8 @@ void back_try_conn_req(struct stream *s)
|
||||
if (srv)
|
||||
srv_set_sess_last(srv);
|
||||
if (srv)
|
||||
_HA_ATOMIC_INC(&srv->counters.shared->tg[tgid - 1]->failed_conns);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_conns);
|
||||
_HA_ATOMIC_INC(&srv->counters.failed_conns);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
|
||||
|
||||
/* release other streams waiting for this server */
|
||||
sess_change_server(s, NULL);
|
||||
@ -2467,8 +2460,8 @@ void back_try_conn_req(struct stream *s)
|
||||
pendconn_cond_unlink(s->pend_pos);
|
||||
|
||||
if (srv)
|
||||
_HA_ATOMIC_INC(&srv->counters.shared->tg[tgid - 1]->failed_conns);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_conns);
|
||||
_HA_ATOMIC_INC(&srv->counters.failed_conns);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
|
||||
sc_abort(sc);
|
||||
sc_shutdown(sc);
|
||||
req->flags |= CF_WRITE_TIMEOUT;
|
||||
@ -2723,8 +2716,8 @@ void back_handle_st_cer(struct stream *s)
|
||||
}
|
||||
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_INC(&objt_server(s->target)->counters.shared->tg[tgid - 1]->failed_conns);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_conns);
|
||||
_HA_ATOMIC_INC(&objt_server(s->target)->counters.failed_conns);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
|
||||
sess_change_server(s, NULL);
|
||||
if (may_dequeue_tasks(objt_server(s->target), s->be))
|
||||
process_srv_queue(objt_server(s->target));
|
||||
@ -2756,8 +2749,8 @@ void back_handle_st_cer(struct stream *s)
|
||||
s->conn_err_type = STRM_ET_CONN_OTHER;
|
||||
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_INC(&objt_server(s->target)->counters.shared->tg[tgid - 1]->internal_errors);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->internal_errors);
|
||||
_HA_ATOMIC_INC(&objt_server(s->target)->counters.internal_errors);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.internal_errors);
|
||||
sess_change_server(s, NULL);
|
||||
if (may_dequeue_tasks(objt_server(s->target), s->be))
|
||||
process_srv_queue(objt_server(s->target));
|
||||
@ -2894,8 +2887,8 @@ void back_handle_st_rdy(struct stream *s)
|
||||
*/
|
||||
void set_backend_down(struct proxy *be)
|
||||
{
|
||||
HA_ATOMIC_STORE(&be->be_counters.shared->tg[tgid - 1]->last_change, ns_to_sec(now_ns));
|
||||
_HA_ATOMIC_INC(&be->be_counters.shared->tg[tgid - 1]->down_trans);
|
||||
be->be_counters.last_change = ns_to_sec(now_ns);
|
||||
_HA_ATOMIC_INC(&be->be_counters.down_trans);
|
||||
|
||||
if (!(global.mode & MODE_STARTING)) {
|
||||
ha_alert("%s '%s' has no server available!\n", proxy_type_str(be), be->id);
|
||||
@ -2967,12 +2960,10 @@ no_cookie:
|
||||
}
|
||||
|
||||
int be_downtime(struct proxy *px) {
|
||||
unsigned long last_change = COUNTERS_SHARED_LAST(px->be_counters.shared->tg, last_change);
|
||||
|
||||
if (px->lbprm.tot_weight && last_change < ns_to_sec(now_ns)) // ignore negative time
|
||||
if (px->lbprm.tot_weight && px->be_counters.last_change < ns_to_sec(now_ns)) // ignore negative time
|
||||
return px->down_time;
|
||||
|
||||
return ns_to_sec(now_ns) - last_change + px->down_time;
|
||||
return ns_to_sec(now_ns) - px->be_counters.last_change + px->down_time;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3410,7 +3401,7 @@ smp_fetch_be_sess_rate(const struct arg *args, struct sample *smp, const char *k
|
||||
|
||||
smp->flags = SMP_F_VOL_TEST;
|
||||
smp->data.type = SMP_T_SINT;
|
||||
smp->data.u.sint = COUNTERS_SHARED_TOTAL(px->be_counters.shared->tg, sess_per_sec, read_freq_ctr);
|
||||
smp->data.u.sint = read_freq_ctr(&px->be_counters.sess_per_sec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -3593,7 +3584,7 @@ smp_fetch_srv_sess_rate(const struct arg *args, struct sample *smp, const char *
|
||||
{
|
||||
smp->flags = SMP_F_VOL_TEST;
|
||||
smp->data.type = SMP_T_SINT;
|
||||
smp->data.u.sint = COUNTERS_SHARED_TOTAL(args->data.srv->counters.shared->tg, sess_per_sec, read_freq_ctr);
|
||||
smp->data.u.sint = read_freq_ctr(&args->data.srv->counters.sess_per_sec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
12
src/cache.c
12
src/cache.c
@ -493,7 +493,7 @@ static struct eb32_node *insert_entry(struct cache *cache, struct cache_tree *tr
|
||||
if (last_clear_ts == date.tv_sec) {
|
||||
/* Too many entries for this primary key, clear the
|
||||
* one that was inserted. */
|
||||
release_entry_locked(tree, new_entry);
|
||||
release_entry_locked(tree, entry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -503,7 +503,7 @@ static struct eb32_node *insert_entry(struct cache *cache, struct cache_tree *tr
|
||||
* the newly inserted one. */
|
||||
entry = container_of(prev, struct cache_entry, eb);
|
||||
entry->last_clear_ts = date.tv_sec;
|
||||
release_entry_locked(tree, new_entry);
|
||||
release_entry_locked(tree, entry);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -2133,9 +2133,9 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p
|
||||
return ACT_RET_CONT;
|
||||
|
||||
if (px == strm_fe(s))
|
||||
_HA_ATOMIC_INC(&px->fe_counters.shared->tg[tgid - 1]->p.http.cache_lookups);
|
||||
_HA_ATOMIC_INC(&px->fe_counters.p.http.cache_lookups);
|
||||
else
|
||||
_HA_ATOMIC_INC(&px->be_counters.shared->tg[tgid - 1]->p.http.cache_lookups);
|
||||
_HA_ATOMIC_INC(&px->be_counters.p.http.cache_lookups);
|
||||
|
||||
cache_tree = get_cache_tree_from_hash(cache, read_u32(s->txn->cache_hash));
|
||||
|
||||
@ -2222,9 +2222,9 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p
|
||||
should_send_notmodified_response(cache, htxbuf(&s->req.buf), res);
|
||||
|
||||
if (px == strm_fe(s))
|
||||
_HA_ATOMIC_INC(&px->fe_counters.shared->tg[tgid - 1]->p.http.cache_hits);
|
||||
_HA_ATOMIC_INC(&px->fe_counters.p.http.cache_hits);
|
||||
else
|
||||
_HA_ATOMIC_INC(&px->be_counters.shared->tg[tgid - 1]->p.http.cache_hits);
|
||||
_HA_ATOMIC_INC(&px->be_counters.p.http.cache_hits);
|
||||
return ACT_RET_CONT;
|
||||
} else {
|
||||
s->target = NULL;
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include <haproxy/check.h>
|
||||
#include <haproxy/chunk.h>
|
||||
#include <haproxy/clock.h>
|
||||
#include <haproxy/counters.h>
|
||||
#ifdef USE_CPU_AFFINITY
|
||||
#include <haproxy/cpuset.h>
|
||||
#include <haproxy/cpu_topo.h>
|
||||
@ -2066,31 +2065,28 @@ next_line:
|
||||
goto next_line;
|
||||
}
|
||||
|
||||
if ((global.mode & MODE_DISCOVERY)) {
|
||||
/* Only print empty arg warning in discovery mode to prevent double display. */
|
||||
for (check_arg = 0; check_arg < arg; check_arg++) {
|
||||
if (!*args[check_arg]) {
|
||||
size_t newpos;
|
||||
for (check_arg = 0; check_arg < arg; check_arg++) {
|
||||
if (!*args[check_arg]) {
|
||||
size_t newpos;
|
||||
|
||||
/* if an empty arg was found, its pointer should be in <errptr>, except
|
||||
* for rare cases such as '\x00' etc. We need to check errptr in any case
|
||||
* and if it's not set, we'll fall back to args's position in the output
|
||||
* string instead (less accurate but still useful).
|
||||
*/
|
||||
if (!errptr) {
|
||||
newpos = args[check_arg] - outline;
|
||||
if (newpos >= strlen(line))
|
||||
newpos = 0; // impossible to report anything, start at the beginning.
|
||||
errptr = line + newpos;
|
||||
}
|
||||
|
||||
/* sanitize input line in-place */
|
||||
newpos = sanitize_for_printing(line, errptr - line, 80);
|
||||
ha_warning("parsing [%s:%d]: argument number %d at position %d is empty and marks the end of the "
|
||||
"argument list; all subsequent arguments will be ignored:\n %s\n %*s\n",
|
||||
file, linenum, check_arg, (int)(errptr - thisline + 1), line, (int)(newpos + 1), "^");
|
||||
break;
|
||||
/* if an empty arg was found, its pointer should be in <errptr>, except
|
||||
* for rare cases such as '\x00' etc. We need to check errptr in any case
|
||||
* and if it's not set, we'll fall back to args's position in the output
|
||||
* string instead (less accurate but still useful).
|
||||
*/
|
||||
if (!errptr) {
|
||||
newpos = args[check_arg] - outline;
|
||||
if (newpos >= strlen(line))
|
||||
newpos = 0; // impossible to report anything, start at the beginning.
|
||||
errptr = line + newpos;
|
||||
}
|
||||
|
||||
/* sanitize input line in-place */
|
||||
newpos = sanitize_for_printing(line, errptr - line, 80);
|
||||
ha_warning("parsing [%s:%d]: argument number %d at position %d is empty and marks the end of the "
|
||||
"argument list; all subsequent arguments will be ignored:\n %s\n %*s\n",
|
||||
file, linenum, check_arg + 1, (int)(errptr - thisline + 1), line, (int)(newpos+1), "^");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2821,13 +2817,28 @@ int check_config_validity()
|
||||
|
||||
/*
|
||||
* we must finish to initialize certain things on the servers,
|
||||
* as some of the fields may be accessed soon
|
||||
* as some of the per_thr/per_tgrp fields may be accessed soon
|
||||
*/
|
||||
|
||||
MT_LIST_FOR_EACH_ENTRY_LOCKED(newsrv, &servers_list, global_list, back) {
|
||||
if (srv_init(newsrv) & ERR_CODE) {
|
||||
if (srv_init_per_thr(newsrv) == -1) {
|
||||
ha_alert("parsing [%s:%d] : failed to allocate per-thread lists for server '%s'.\n",
|
||||
newsrv->conf.file, newsrv->conf.line, newsrv->id);
|
||||
cfgerr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* initialize idle conns lists */
|
||||
if (newsrv->max_idle_conns != 0) {
|
||||
newsrv->curr_idle_thr = calloc(global.nbthread, sizeof(*newsrv->curr_idle_thr));
|
||||
if (!newsrv->curr_idle_thr) {
|
||||
ha_alert("parsing [%s:%d] : failed to allocate idle connection tasks for server '%s'.\n",
|
||||
newsrv->conf.file, newsrv->conf.line, newsrv->id);
|
||||
cfgerr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* starting to initialize the main proxies list */
|
||||
@ -3767,8 +3778,6 @@ out_uri_auth_compat:
|
||||
((newsrv->flags & SRV_F_DEFSRV_USE_SSL) && newsrv->use_ssl != 1)) {
|
||||
if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
|
||||
cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
|
||||
else if (xprt_get(XPRT_QUIC) && xprt_get(XPRT_QUIC)->prepare_srv)
|
||||
cfgerr += xprt_get(XPRT_QUIC)->prepare_srv(newsrv);
|
||||
}
|
||||
|
||||
if ((newsrv->flags & SRV_F_FASTOPEN) &&
|
||||
@ -4115,13 +4124,6 @@ out_uri_auth_compat:
|
||||
int mode = conn_pr_mode_to_proto_mode(curproxy->mode);
|
||||
const struct mux_proto_list *mux_ent;
|
||||
|
||||
if (srv_is_quic(newsrv)) {
|
||||
if (!newsrv->mux_proto) {
|
||||
/* Force QUIC as mux-proto on server with quic addresses, similarly to bind on FE side. */
|
||||
newsrv->mux_proto = get_mux_proto(ist("quic"));
|
||||
}
|
||||
}
|
||||
|
||||
if (!newsrv->mux_proto)
|
||||
continue;
|
||||
|
||||
@ -4271,15 +4273,6 @@ init_proxies_list_stage2:
|
||||
/* enable separate counters */
|
||||
if (curproxy->options2 & PR_O2_SOCKSTAT) {
|
||||
listener->counters = calloc(1, sizeof(*listener->counters));
|
||||
if (listener->counters) {
|
||||
listener->counters->shared = counters_fe_shared_get(&listener->guid);
|
||||
if (!listener->counters->shared) {
|
||||
ha_free(&listener->counters);
|
||||
ha_alert("config: %s '%s': out of memory.\n",
|
||||
proxy_type_str(curproxy), curproxy->id);
|
||||
}
|
||||
|
||||
}
|
||||
if (!listener->name)
|
||||
memprintf(&listener->name, "sock-%d", listener->luid);
|
||||
}
|
||||
|
22
src/check.c
22
src/check.c
@ -34,7 +34,6 @@
|
||||
#include <haproxy/cfgparse.h>
|
||||
#include <haproxy/check.h>
|
||||
#include <haproxy/chunk.h>
|
||||
#include <haproxy/counters.h>
|
||||
#include <haproxy/dgram.h>
|
||||
#include <haproxy/dynbuf.h>
|
||||
#include <haproxy/extcheck.h>
|
||||
@ -195,11 +194,10 @@ static void check_trace(enum trace_level level, uint64_t mask,
|
||||
((check->type == PR_O2_EXT_CHK) ? 'E' : (check->state & CHK_ST_AGENT ? 'A' : 'H')),
|
||||
srv->id);
|
||||
|
||||
chunk_appendf(&trace_buf, " status=%d/%d %s exp=%d",
|
||||
chunk_appendf(&trace_buf, " status=%d/%d %s",
|
||||
(check->health >= check->rise) ? check->health - check->rise + 1 : check->health,
|
||||
(check->health >= check->rise) ? check->fall : check->rise,
|
||||
(check->health >= check->rise) ? (srv->uweight ? "UP" : "DRAIN") : "DOWN",
|
||||
(check->task->expire ? TICKS_TO_MS(check->task->expire - now_ms) : 0));
|
||||
(check->health >= check->rise) ? (srv->uweight ? "UP" : "DRAIN") : "DOWN");
|
||||
}
|
||||
else
|
||||
chunk_appendf(&trace_buf, " : [EMAIL]");
|
||||
@ -516,7 +514,7 @@ void set_server_check_status(struct check *check, short status, const char *desc
|
||||
if ((!(check->state & CHK_ST_AGENT) ||
|
||||
(check->status >= HCHK_STATUS_L57DATA)) &&
|
||||
(check->health > 0)) {
|
||||
_HA_ATOMIC_INC(&s->counters.shared->tg[tgid - 1]->failed_checks);
|
||||
_HA_ATOMIC_INC(&s->counters.failed_checks);
|
||||
report = 1;
|
||||
check->health--;
|
||||
if (check->health < check->rise)
|
||||
@ -744,7 +742,7 @@ void __health_adjust(struct server *s, short status)
|
||||
HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
|
||||
|
||||
HA_ATOMIC_STORE(&s->consecutive_errors, 0);
|
||||
_HA_ATOMIC_INC(&s->counters.shared->tg[tgid - 1]->failed_hana);
|
||||
_HA_ATOMIC_INC(&s->counters.failed_hana);
|
||||
|
||||
if (s->check.fastinter) {
|
||||
/* timer might need to be advanced, it might also already be
|
||||
@ -996,7 +994,6 @@ int httpchk_build_status_header(struct server *s, struct buffer *buf)
|
||||
"UP %d/%d", "UP",
|
||||
"NOLB %d/%d", "NOLB",
|
||||
"no check" };
|
||||
unsigned long last_change = COUNTERS_SHARED_LAST(s->counters.shared->tg, last_change);
|
||||
|
||||
if (!(s->check.state & CHK_ST_ENABLED))
|
||||
sv_state = 6;
|
||||
@ -1034,9 +1031,9 @@ int httpchk_build_status_header(struct server *s, struct buffer *buf)
|
||||
s->queueslength);
|
||||
|
||||
if ((s->cur_state == SRV_ST_STARTING) &&
|
||||
ns_to_sec(now_ns) < last_change + s->slowstart &&
|
||||
ns_to_sec(now_ns) >= last_change) {
|
||||
ratio = MAX(1, 100 * (ns_to_sec(now_ns) - last_change) / s->slowstart);
|
||||
ns_to_sec(now_ns) < s->counters.last_change + s->slowstart &&
|
||||
ns_to_sec(now_ns) >= s->counters.last_change) {
|
||||
ratio = MAX(1, 100 * (ns_to_sec(now_ns) - s->counters.last_change) / s->slowstart);
|
||||
chunk_appendf(buf, "; throttle=%d%%", ratio);
|
||||
}
|
||||
|
||||
@ -1091,11 +1088,6 @@ int wake_srv_chk(struct stconn *sc)
|
||||
ret = -1;
|
||||
task_wakeup(check->task, TASK_WOKEN_IO);
|
||||
}
|
||||
else {
|
||||
/* Check in progress. Queue it to eventually handle timeout
|
||||
* update */
|
||||
task_queue(check->task);
|
||||
}
|
||||
|
||||
if (check->server)
|
||||
HA_SPIN_UNLOCK(SERVER_LOCK, &check->server->lock);
|
||||
|
14
src/cli.c
14
src/cli.c
@ -987,18 +987,12 @@ int cli_parse_cmdline(struct appctx *appctx)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
goto process_cmdline;
|
||||
|
||||
/* The end of the command line was reached. Change the trailing \r, if any,
|
||||
* by a null byte. For the command line, the trailing \r and \n are removed,
|
||||
* but we conserve them for payload mode.
|
||||
*/
|
||||
if (str[len-1] == '\r') {
|
||||
if (str[len-1] == '\r')
|
||||
str[--len] = '\0';
|
||||
if (!len)
|
||||
goto process_cmdline;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for the "payload start" pattern at the end of a
|
||||
@ -1061,7 +1055,6 @@ int cli_parse_cmdline(struct appctx *appctx)
|
||||
}
|
||||
}
|
||||
|
||||
process_cmdline:
|
||||
if (!(appctx->st1 & APPCTX_CLI_ST1_PAYLOAD)) {
|
||||
appctx->st0 = CLI_ST_PROCESS_CMDLINE;
|
||||
break;
|
||||
@ -1423,8 +1416,7 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
|
||||
#if defined(USE_QUIC)
|
||||
else if (fdt.iocb == quic_conn_sock_fd_iocb) {
|
||||
qc = fdtab[fd].owner;
|
||||
li = qc ? objt_listener(qc->target) : NULL;
|
||||
sv = qc ? objt_server(qc->target) : NULL;
|
||||
li = qc ? qc->li : NULL;
|
||||
xprt_ctx = qc ? qc->xprt_ctx : NULL;
|
||||
conn = qc ? qc->conn : NULL;
|
||||
xprt = conn ? conn->xprt : NULL; // in fact it's &ssl_quic
|
||||
@ -3690,6 +3682,8 @@ int mworker_cli_attach_server(char **errmsg)
|
||||
else
|
||||
memprintf(&msg, "old-%d", child->pid);
|
||||
|
||||
newsrv->next = mworker_proxy->srv;
|
||||
mworker_proxy->srv = newsrv;
|
||||
newsrv->conf.file = strdup(msg);
|
||||
newsrv->id = strdup(msg);
|
||||
newsrv->conf.line = 0;
|
||||
|
100
src/counters.c
100
src/counters.c
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* objects counters management
|
||||
*
|
||||
* Copyright 2025 HAProxy Technologies
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <haproxy/atomic.h>
|
||||
#include <haproxy/clock.h>
|
||||
#include <haproxy/counters.h>
|
||||
#include <haproxy/global.h>
|
||||
#include <haproxy/time.h>
|
||||
|
||||
static void _counters_shared_drop(void *counters)
|
||||
{
|
||||
struct counters_shared *shared = counters;
|
||||
int it = 0;
|
||||
|
||||
if (!shared)
|
||||
return;
|
||||
|
||||
/* memory was allocated using calloc(), simply free it */
|
||||
while (it < global.nbtgroups) {
|
||||
free(shared->tg[it]);
|
||||
it += 1;
|
||||
}
|
||||
free(counters);
|
||||
}
|
||||
|
||||
/* release a shared fe counters struct */
|
||||
void counters_fe_shared_drop(struct fe_counters_shared *counters)
|
||||
{
|
||||
_counters_shared_drop(counters);
|
||||
}
|
||||
|
||||
/* release a shared be counters struct */
|
||||
void counters_be_shared_drop(struct be_counters_shared *counters)
|
||||
{
|
||||
_counters_shared_drop(counters);
|
||||
}
|
||||
|
||||
/* retrieved shared counters pointer for a given <guid> object
|
||||
* <size> hint is expected to reflect the actual tg member size (fe/be)
|
||||
* if <guid> is not set, then sharing is disabled
|
||||
* Returns the pointer on success or NULL on failure
|
||||
*/
|
||||
static void*_counters_shared_get(const struct guid_node *guid, size_t size)
|
||||
{
|
||||
struct counters_shared *shared;
|
||||
uint last_change;
|
||||
int it = 0;
|
||||
|
||||
/* no shared memory for now, simply allocate a memory block
|
||||
* for the counters (zero-initialized), ignore guid
|
||||
*/
|
||||
shared = calloc(1, sizeof(*shared));
|
||||
if (!shared)
|
||||
return NULL;
|
||||
if (!guid->node.key)
|
||||
shared->flags |= COUNTERS_SHARED_F_LOCAL;
|
||||
while (it < global.nbtgroups) {
|
||||
shared->tg[it] = calloc(1, size);
|
||||
if (!shared->tg[it]) {
|
||||
_counters_shared_drop(shared);
|
||||
return NULL;
|
||||
}
|
||||
it += 1;
|
||||
}
|
||||
last_change = ns_to_sec(now_ns);
|
||||
|
||||
/* only set one group, only latest value is considered */
|
||||
HA_ATOMIC_STORE(&shared->tg[0]->last_change, last_change);
|
||||
return shared;
|
||||
}
|
||||
|
||||
/* retrieve shared fe counters pointer for a given <guid> object */
|
||||
struct fe_counters_shared *counters_fe_shared_get(const struct guid_node *guid)
|
||||
{
|
||||
return _counters_shared_get(guid, sizeof(struct fe_counters_shared_tg));
|
||||
}
|
||||
|
||||
/* retrieve shared be counters pointer for a given <guid> object */
|
||||
struct be_counters_shared *counters_be_shared_get(const struct guid_node *guid)
|
||||
{
|
||||
return _counters_shared_get(guid, sizeof(struct be_counters_shared_tg));
|
||||
}
|
@ -446,12 +446,12 @@ static int fcgi_flt_http_headers(struct stream *s, struct filter *filter, struct
|
||||
goto end;
|
||||
|
||||
rewrite_err:
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
|
||||
if (sess->listener && sess->listener->counters)
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
|
||||
hdr_rule_err:
|
||||
node = ebpt_first(&hdr_rules);
|
||||
while (node) {
|
||||
|
@ -393,14 +393,14 @@ comp_http_payload(struct stream *s, struct filter *filter, struct http_msg *msg,
|
||||
|
||||
if (st->comp_ctx[dir] && st->comp_ctx[dir]->cur_lvl > 0) {
|
||||
update_freq_ctr(&global.comp_bps_in, consumed);
|
||||
_HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.shared->tg[tgid - 1]->comp_in[dir], consumed);
|
||||
_HA_ATOMIC_ADD(&s->be->be_counters.shared->tg[tgid - 1]->comp_in[dir], consumed);
|
||||
_HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.comp_in[dir], consumed);
|
||||
_HA_ATOMIC_ADD(&s->be->be_counters.comp_in[dir], consumed);
|
||||
update_freq_ctr(&global.comp_bps_out, to_forward);
|
||||
_HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.shared->tg[tgid - 1]->comp_out[dir], to_forward);
|
||||
_HA_ATOMIC_ADD(&s->be->be_counters.shared->tg[tgid - 1]->comp_out[dir], to_forward);
|
||||
_HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.comp_out[dir], to_forward);
|
||||
_HA_ATOMIC_ADD(&s->be->be_counters.comp_out[dir], to_forward);
|
||||
} else {
|
||||
_HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.shared->tg[tgid - 1]->comp_byp[dir], consumed);
|
||||
_HA_ATOMIC_ADD(&s->be->be_counters.shared->tg[tgid - 1]->comp_byp[dir], consumed);
|
||||
_HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.comp_byp[dir], consumed);
|
||||
_HA_ATOMIC_ADD(&s->be->be_counters.comp_byp[dir], consumed);
|
||||
}
|
||||
return to_forward;
|
||||
|
||||
@ -419,9 +419,9 @@ comp_http_end(struct stream *s, struct filter *filter,
|
||||
goto end;
|
||||
|
||||
if (strm_fe(s)->mode == PR_MODE_HTTP)
|
||||
_HA_ATOMIC_INC(&strm_fe(s)->fe_counters.shared->tg[tgid - 1]->p.http.comp_rsp);
|
||||
_HA_ATOMIC_INC(&strm_fe(s)->fe_counters.p.http.comp_rsp);
|
||||
if ((s->flags & SF_BE_ASSIGNED) && (s->be->mode == PR_MODE_HTTP))
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->p.http.comp_rsp);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.p.http.comp_rsp);
|
||||
end:
|
||||
return 1;
|
||||
}
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <haproxy/arg.h>
|
||||
#include <haproxy/chunk.h>
|
||||
#include <haproxy/connection.h>
|
||||
#include <haproxy/counters.h>
|
||||
#include <haproxy/fd.h>
|
||||
#include <haproxy/frontend.h>
|
||||
#include <haproxy/global.h>
|
||||
@ -261,7 +260,7 @@ smp_fetch_fe_req_rate(const struct arg *args, struct sample *smp, const char *kw
|
||||
|
||||
smp->flags = SMP_F_VOL_TEST;
|
||||
smp->data.type = SMP_T_SINT;
|
||||
smp->data.u.sint = COUNTERS_SHARED_TOTAL(px->fe_counters.shared->tg, req_per_sec, read_freq_ctr);
|
||||
smp->data.u.sint = read_freq_ctr(&px->fe_counters.req_per_sec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -281,7 +280,7 @@ smp_fetch_fe_sess_rate(const struct arg *args, struct sample *smp, const char *k
|
||||
|
||||
smp->flags = SMP_F_VOL_TEST;
|
||||
smp->data.type = SMP_T_SINT;
|
||||
smp->data.u.sint = COUNTERS_SHARED_TOTAL(px->fe_counters.shared->tg, sess_per_sec, read_freq_ctr);
|
||||
smp->data.u.sint = read_freq_ctr(&px->fe_counters.sess_per_sec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
67
src/h3.c
67
src/h3.c
@ -36,7 +36,6 @@
|
||||
#include <haproxy/qmux_http.h>
|
||||
#include <haproxy/qpack-dec.h>
|
||||
#include <haproxy/qpack-enc.h>
|
||||
#include <haproxy/quic_conn.h>
|
||||
#include <haproxy/quic_enc.h>
|
||||
#include <haproxy/quic_fctl.h>
|
||||
#include <haproxy/quic_frame.h>
|
||||
@ -680,12 +679,7 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
|
||||
goto out;
|
||||
}
|
||||
|
||||
flags |= HTX_SL_F_HAS_SCHM;
|
||||
if (isteqi(list[hdr_idx].v, ist("http")))
|
||||
flags |= HTX_SL_F_SCHM_HTTP;
|
||||
else if (isteqi(list[hdr_idx].v, ist("https")))
|
||||
flags |= HTX_SL_F_SCHM_HTTPS;
|
||||
else if (!http_validate_scheme(list[hdr_idx].v)) {
|
||||
if (!http_validate_scheme(list[hdr_idx].v)) {
|
||||
TRACE_ERROR("invalid scheme pseudo-header", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
|
||||
h3s->err = H3_ERR_MESSAGE_ERROR;
|
||||
qcc_report_glitch(h3c->qcc, 1);
|
||||
@ -778,7 +772,6 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
|
||||
if (!istlen(scheme)) {
|
||||
/* No scheme (CONNECT), use :authority only. */
|
||||
uri = authority;
|
||||
flags |= HTX_SL_F_HAS_AUTHORITY;
|
||||
}
|
||||
else if (isttest(authority)) {
|
||||
/* Use absolute URI form as :authority is present. */
|
||||
@ -787,20 +780,6 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
|
||||
istcat(&uri, authority, trash.size);
|
||||
if (!isteq(path, ist("*")))
|
||||
istcat(&uri, path, trash.size);
|
||||
|
||||
flags |= HTX_SL_F_HAS_AUTHORITY;
|
||||
if (flags & (HTX_SL_F_SCHM_HTTP|HTX_SL_F_SCHM_HTTPS)) {
|
||||
/* we don't know if it was originally an absolute or a
|
||||
* relative request because newer versions of HTTP use
|
||||
* the absolute URI format by default, which we call
|
||||
* the normalized URI format internally. This is the
|
||||
* strongly recommended way of sending a request for
|
||||
* a regular client, so we cannot distinguish this
|
||||
* from a request intended for a proxy. For other
|
||||
* schemes however there is no doubt.
|
||||
*/
|
||||
flags |= HTX_SL_F_NORMALIZED_URI;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use origin URI form. */
|
||||
@ -1385,13 +1364,9 @@ static ssize_t h3_parse_settings_frm(struct h3c *h3c, const struct buffer *buf,
|
||||
/* Transcode HTTP/3 payload received in buffer <b> to HTX data for stream
|
||||
* <qcs>. If <fin> is set, it indicates that no more data will arrive after.
|
||||
*
|
||||
* It may be necessary to call this function with an empty input buffer to
|
||||
* signal a standalone FIN.
|
||||
*
|
||||
* Returns the amount of decoded bytes from <b> or a negative error code. A
|
||||
* null value can be returned even if input buffer is not empty, meaning that
|
||||
* transcoding cannot be performed due to partial HTTP/3 content. Receive
|
||||
* operation may be called later with newer data available.
|
||||
* Returns the count of consumed bytes or a negative error code. If 0 is
|
||||
* returned, stream data is incomplete, decoding should be call again later
|
||||
* with more content.
|
||||
*/
|
||||
static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
|
||||
{
|
||||
@ -1691,13 +1666,6 @@ static int h3_encode_header(struct buffer *buf,
|
||||
return qpack_encode_header(buf, n, v_strip);
|
||||
}
|
||||
|
||||
/* Convert a HTX status-line and associated headers stored into <htx> into a
|
||||
* HTTP/3 HEADERS response frame. HTX blocks are removed up to end-of-trailer
|
||||
* included.
|
||||
*
|
||||
* Returns the amount of consumed bytes from <htx> buffer or a negative error
|
||||
* code.
|
||||
*/
|
||||
static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
{
|
||||
int err;
|
||||
@ -1852,15 +1820,15 @@ static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
}
|
||||
|
||||
/* Convert a series of HTX trailer blocks from <htx> buffer into <qcs> buffer
|
||||
* as a HTTP/3 HEADERS frame. Forbidden trailers are skipped. HTX trailer
|
||||
* blocks are removed from <htx> up to end-of-trailer included.
|
||||
* as a H3 HEADERS frame. H3 forbidden trailers are skipped. HTX trailer blocks
|
||||
* are removed from <htx> until EOT is found and itself removed.
|
||||
*
|
||||
* If only a EOT HTX block is present without trailer, no H3 frame is produced.
|
||||
* Caller is responsible to emit an empty QUIC STREAM frame to signal the end
|
||||
* of the stream.
|
||||
*
|
||||
* Returns the amount of consumed bytes from <htx> buffer or a negative error
|
||||
* code.
|
||||
* Returns the size of HTX blocks removed. A negative error code is returned in
|
||||
* case of a fatal error which should caused a connection closure.
|
||||
*/
|
||||
static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx)
|
||||
{
|
||||
@ -2032,9 +2000,9 @@ static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx)
|
||||
* underlying HTX area via <buf> as this will be used if zero-copy can be
|
||||
* performed.
|
||||
*
|
||||
* Returns the amount of consumed bytes from <htx> buffer, which corresponds to
|
||||
* the length sum of encoded frames payload. A negative error code is returned
|
||||
* in case of a fatal error which should caused a connection closure.
|
||||
* Returns the total bytes of encoded HTTP/3 payload. This corresponds to the
|
||||
* total bytes of HTX block removed. A negative error code is returned in case
|
||||
* of a fatal error which should caused a connection closure.
|
||||
*/
|
||||
static int h3_resp_data_send(struct qcs *qcs, struct htx *htx,
|
||||
struct buffer *buf, size_t count)
|
||||
@ -2159,14 +2127,6 @@ static int h3_resp_data_send(struct qcs *qcs, struct htx *htx,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Transcode HTX data from <buf> of length <count> into HTTP/3 frame for <qcs>
|
||||
* stream instance. Successfully transcoded HTX blocks are removed from input
|
||||
* buffer.
|
||||
*
|
||||
* Returns the amount of consumed bytes from <buf>. In case of error,
|
||||
* connection is flagged and transcoding is interrupted. The returned value is
|
||||
* unchanged though.
|
||||
*/
|
||||
static size_t h3_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count)
|
||||
{
|
||||
size_t total = 0;
|
||||
@ -2533,6 +2493,7 @@ static int h3_send_goaway(struct h3c *h3c)
|
||||
static int h3_init(struct qcc *qcc)
|
||||
{
|
||||
struct h3c *h3c;
|
||||
const struct listener *li = __objt_listener(qcc->conn->target);
|
||||
|
||||
TRACE_ENTER(H3_EV_H3C_NEW, qcc->conn);
|
||||
|
||||
@ -2549,7 +2510,9 @@ static int h3_init(struct qcc *qcc)
|
||||
h3c->id_goaway = 0;
|
||||
|
||||
qcc->ctx = h3c;
|
||||
h3c->prx_counters = qc_counters(qcc->conn->target, &h3_stats_module);
|
||||
h3c->prx_counters =
|
||||
EXTRA_COUNTERS_GET(li->bind_conf->frontend->extra_counters_fe,
|
||||
&h3_stats_module);
|
||||
LIST_INIT(&h3c->buf_wait.list);
|
||||
|
||||
TRACE_LEAVE(H3_EV_H3C_NEW, qcc->conn);
|
||||
|
@ -75,7 +75,6 @@
|
||||
#include <haproxy/cli.h>
|
||||
#include <haproxy/clock.h>
|
||||
#include <haproxy/connection.h>
|
||||
#include <haproxy/counters.h>
|
||||
#ifdef USE_CPU_AFFINITY
|
||||
#include <haproxy/cpuset.h>
|
||||
#include <haproxy/cpu_topo.h>
|
||||
@ -816,10 +815,10 @@ static void sig_dump_state(struct sig_handler *sh)
|
||||
send_log(p, LOG_NOTICE, "SIGHUP received, dumping servers states for proxy %s.\n", p->id);
|
||||
while (s) {
|
||||
chunk_printf(&trash,
|
||||
"SIGHUP: Server %s/%s is %s. Conn: %d act, %d pend, %llu tot.",
|
||||
"SIGHUP: Server %s/%s is %s. Conn: %d act, %d pend, %lld tot.",
|
||||
p->id, s->id,
|
||||
(s->cur_state != SRV_ST_STOPPED) ? "UP" : "DOWN",
|
||||
s->cur_sess, s->queueslength, (ullong)COUNTERS_SHARED_TOTAL(s->counters.shared->tg, cum_sess, HA_ATOMIC_LOAD));
|
||||
s->cur_sess, s->queueslength, s->counters.cum_sess);
|
||||
ha_warning("%s\n", trash.area);
|
||||
send_log(p, LOG_NOTICE, "%s\n", trash.area);
|
||||
s = s->next;
|
||||
@ -828,21 +827,21 @@ static void sig_dump_state(struct sig_handler *sh)
|
||||
/* FIXME: those info are a bit outdated. We should be able to distinguish between FE and BE. */
|
||||
if (!p->srv) {
|
||||
chunk_printf(&trash,
|
||||
"SIGHUP: Proxy %s has no servers. Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %llu+%llu.",
|
||||
"SIGHUP: Proxy %s has no servers. Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
|
||||
p->id,
|
||||
p->feconn, p->beconn, p->totpend, p->queueslength, (ullong)COUNTERS_SHARED_TOTAL(p->fe_counters.shared->tg, cum_conn, HA_ATOMIC_LOAD), (ullong)COUNTERS_SHARED_TOTAL(p->be_counters.shared->tg, cum_sess, HA_ATOMIC_LOAD));
|
||||
p->feconn, p->beconn, p->totpend, p->queueslength, p->fe_counters.cum_conn, p->be_counters.cum_sess);
|
||||
} else if (p->srv_act == 0) {
|
||||
chunk_printf(&trash,
|
||||
"SIGHUP: Proxy %s %s ! Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %llu+%llu.",
|
||||
"SIGHUP: Proxy %s %s ! Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
|
||||
p->id,
|
||||
(p->srv_bck) ? "is running on backup servers" : "has no server available",
|
||||
p->feconn, p->beconn, p->totpend, p->queueslength, (ullong)COUNTERS_SHARED_TOTAL(p->fe_counters.shared->tg, cum_conn, HA_ATOMIC_LOAD), (ullong)COUNTERS_SHARED_TOTAL(p->be_counters.shared->tg, cum_sess, HA_ATOMIC_LOAD));
|
||||
p->feconn, p->beconn, p->totpend, p->queueslength, p->fe_counters.cum_conn, p->be_counters.cum_sess);
|
||||
} else {
|
||||
chunk_printf(&trash,
|
||||
"SIGHUP: Proxy %s has %d active servers and %d backup servers available."
|
||||
" Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %llu+%llu.",
|
||||
" Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
|
||||
p->id, p->srv_act, p->srv_bck,
|
||||
p->feconn, p->beconn, p->totpend, p->queueslength, (ullong)COUNTERS_SHARED_TOTAL(p->fe_counters.shared->tg, cum_conn, HA_ATOMIC_LOAD), (ullong)COUNTERS_SHARED_TOTAL(p->be_counters.shared->tg, cum_sess, HA_ATOMIC_LOAD));
|
||||
p->feconn, p->beconn, p->totpend, p->queueslength, p->fe_counters.cum_conn, p->be_counters.cum_sess);
|
||||
}
|
||||
ha_warning("%s\n", trash.area);
|
||||
send_log(p, LOG_NOTICE, "%s\n", trash.area);
|
||||
@ -2102,7 +2101,7 @@ static void step_init_2(int argc, char** argv)
|
||||
clock_adjust_now_offset();
|
||||
ready_date = date;
|
||||
|
||||
list_for_each_entry(px, &proxies, global_list) {
|
||||
for (px = proxies_list; px; px = px->next) {
|
||||
struct server *srv;
|
||||
struct post_proxy_check_fct *ppcf;
|
||||
struct post_server_check_fct *pscf;
|
||||
|
90
src/hlua.c
90
src/hlua.c
@ -5299,20 +5299,20 @@ __LJMP static int hlua_applet_tcp_get_priv(lua_State *L)
|
||||
__LJMP static int hlua_applet_tcp_getline_yield(lua_State *L, int status, lua_KContext ctx)
|
||||
{
|
||||
struct hlua_appctx *luactx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
|
||||
struct stconn *sc = appctx_sc(luactx->appctx);
|
||||
int ret;
|
||||
const char *blk1 = NULL;
|
||||
size_t len1 = 0;
|
||||
const char *blk2 = NULL;
|
||||
size_t len2 = 0;
|
||||
const char *blk1;
|
||||
size_t len1;
|
||||
const char *blk2;
|
||||
size_t len2;
|
||||
|
||||
/* Read the maximum amount of data available. */
|
||||
ret = applet_getline_nc(luactx->appctx, &blk1, &len1, &blk2, &len2);
|
||||
ret = co_getline_nc(sc_oc(sc), &blk1, &len1, &blk2, &len2);
|
||||
|
||||
/* Data not yet available. return yield. */
|
||||
if (ret == 0) {
|
||||
applet_need_more_data(luactx->appctx);
|
||||
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_getline_yield, TICK_ETERNITY, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End of data: commit the total strings and return. */
|
||||
@ -5327,10 +5327,10 @@ __LJMP static int hlua_applet_tcp_getline_yield(lua_State *L, int status, lua_KC
|
||||
|
||||
/* don't check the max length read and don't check. */
|
||||
luaL_addlstring(&luactx->b, blk1, len1);
|
||||
if (len2)
|
||||
luaL_addlstring(&luactx->b, blk2, len2);
|
||||
luaL_addlstring(&luactx->b, blk2, len2);
|
||||
|
||||
applet_skip_input(luactx->appctx, len1+len2);
|
||||
/* Consume input channel output buffer data. */
|
||||
co_skip(sc_oc(sc), len1 + len2);
|
||||
luaL_pushresult(&luactx->b);
|
||||
return 1;
|
||||
}
|
||||
@ -5352,22 +5352,26 @@ __LJMP static int hlua_applet_tcp_getline(lua_State *L)
|
||||
__LJMP static int hlua_applet_tcp_recv_try(lua_State *L)
|
||||
{
|
||||
struct hlua_appctx *luactx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
|
||||
struct stconn *sc = appctx_sc(luactx->appctx);
|
||||
size_t len = MAY_LJMP(luaL_checkinteger(L, 2));
|
||||
int exp_date = MAY_LJMP(luaL_checkinteger(L, 3));
|
||||
int ret;
|
||||
const char *blk1 = NULL;
|
||||
size_t len1 = 0;
|
||||
const char *blk2 = NULL;
|
||||
size_t len2 = 0;
|
||||
const char *blk1;
|
||||
size_t len1;
|
||||
const char *blk2;
|
||||
size_t len2;
|
||||
|
||||
/* Read the maximum amount of data available. */
|
||||
ret = applet_getblk_nc(luactx->appctx, &blk1, &len1, &blk2, &len2);
|
||||
if (luactx->appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
ret = b_getblk_nc(&luactx->appctx->inbuf, &blk1, &len1, &blk2, &len2, 0, b_data(&luactx->appctx->inbuf));
|
||||
else
|
||||
ret = co_getblk_nc(sc_oc(sc), &blk1, &len1, &blk2, &len2);
|
||||
|
||||
/* Data not yet available. return yield. */
|
||||
if (ret == 0) {
|
||||
if (tick_is_expired(exp_date, now_ms)) {
|
||||
/* return the result. */
|
||||
lua_pushnil(L);
|
||||
luaL_pushresult(&luactx->b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -5392,9 +5396,11 @@ __LJMP static int hlua_applet_tcp_recv_try(lua_State *L)
|
||||
* the end of data stream.
|
||||
*/
|
||||
luaL_addlstring(&luactx->b, blk1, len1);
|
||||
if (len2)
|
||||
luaL_addlstring(&luactx->b, blk2, len2);
|
||||
applet_skip_input(luactx->appctx, len1+len2);
|
||||
luaL_addlstring(&luactx->b, blk2, len2);
|
||||
if (luactx->appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
b_del(&luactx->appctx->inbuf, len1 + len2);
|
||||
else
|
||||
co_skip(sc_oc(sc), len1 + len2);
|
||||
|
||||
if (tick_is_expired(exp_date, now_ms)) {
|
||||
/* return the result. */
|
||||
@ -5414,14 +5420,15 @@ __LJMP static int hlua_applet_tcp_recv_try(lua_State *L)
|
||||
len -= len1;
|
||||
|
||||
/* Copy the second block. */
|
||||
if (len2) {
|
||||
if (len2 > len)
|
||||
len2 = len;
|
||||
luaL_addlstring(&luactx->b, blk2, len2);
|
||||
len -= len2;
|
||||
}
|
||||
if (len2 > len)
|
||||
len2 = len;
|
||||
luaL_addlstring(&luactx->b, blk2, len2);
|
||||
len -= len2;
|
||||
|
||||
applet_skip_input(luactx->appctx, len1+len2);
|
||||
if (luactx->appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
b_del(&luactx->appctx->inbuf, len1 + len2);
|
||||
else
|
||||
co_skip(sc_oc(sc), len1 + len2);
|
||||
|
||||
/* If there is no other data available, yield waiting for new data. */
|
||||
if (len > 0 && !tick_is_expired(exp_date, now_ms)) {
|
||||
@ -5504,7 +5511,7 @@ __LJMP static int hlua_applet_tcp_try_recv(lua_State *L)
|
||||
lua_pushinteger(L, -1);
|
||||
|
||||
/* set the expiration date (mandatory arg but not relevant here) */
|
||||
lua_pushinteger(L, now_ms);
|
||||
lua_pushinteger(L, TICK_ETERNITY);
|
||||
|
||||
/* Initialise the string catenation. */
|
||||
luaL_buffinit(L, &luactx->b);
|
||||
@ -5530,10 +5537,15 @@ __LJMP static int hlua_applet_tcp_send_yield(lua_State *L, int status, lua_KCont
|
||||
struct hlua_appctx *luactx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
|
||||
const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
|
||||
int l = MAY_LJMP(luaL_checkinteger(L, 3));
|
||||
struct stconn *sc = appctx_sc(luactx->appctx);
|
||||
struct channel *chn = sc_ic(sc);
|
||||
int max;
|
||||
|
||||
/* Get the max amount of data which can be written */
|
||||
max = applet_output_room(luactx->appctx);
|
||||
if (luactx->appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
max = b_room(&luactx->appctx->outbuf);
|
||||
else
|
||||
max = channel_recv_max(chn);
|
||||
|
||||
if (max > (len - l))
|
||||
max = len - l;
|
||||
@ -5550,7 +5562,10 @@ __LJMP static int hlua_applet_tcp_send_yield(lua_State *L, int status, lua_KCont
|
||||
* applet, and returns a yield.
|
||||
*/
|
||||
if (l < len) {
|
||||
applet_need_room(luactx->appctx, applet_output_room(luactx->appctx) + 1);
|
||||
if (luactx->appctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
applet_have_more_data(luactx->appctx);
|
||||
else
|
||||
sc_need_room(sc, channel_recv_max(chn) + 1);
|
||||
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_send_yield, TICK_ETERNITY, 0));
|
||||
}
|
||||
|
||||
@ -8277,12 +8292,6 @@ __LJMP static int hlua_httpclient_send(lua_State *L, enum http_meth_t meth)
|
||||
|
||||
hlua_hc = hlua_checkhttpclient(L, 1);
|
||||
|
||||
/* An HTTPclient instance must never process more that one request. So
|
||||
* at this stage, it must never have been started.
|
||||
*/
|
||||
if (httpclient_started(hlua_hc->hc))
|
||||
WILL_LJMP(luaL_error(L, "httpclient instance cannot be reused. It must process at most one request"));
|
||||
|
||||
lua_pushnil(L); /* first key */
|
||||
while (lua_next(L, 2)) {
|
||||
if (strcmp(lua_tostring(L, -2), "dst") == 0) {
|
||||
@ -9021,7 +9030,7 @@ __LJMP static int hlua_txn_done(lua_State *L)
|
||||
/* let's log the request time */
|
||||
s->logs.request_ts = now_ns;
|
||||
if (s->sess->fe == s->be) /* report it if the request was intercepted by the frontend */
|
||||
_HA_ATOMIC_INC(&s->sess->fe->fe_counters.shared->tg[tgid - 1]->intercepted_req);
|
||||
_HA_ATOMIC_INC(&s->sess->fe->fe_counters.intercepted_req);
|
||||
}
|
||||
|
||||
done:
|
||||
@ -11212,7 +11221,10 @@ out:
|
||||
if (yield)
|
||||
return;
|
||||
|
||||
applet_reset_input(ctx);
|
||||
if (ctx->flags & APPCTX_FL_INOUT_BUFS)
|
||||
b_reset(&ctx->inbuf);
|
||||
else
|
||||
co_skip(sc_oc(sc), co_data(sc_oc(sc)));
|
||||
return;
|
||||
|
||||
error:
|
||||
@ -14690,6 +14702,12 @@ static void hlua_deinit()
|
||||
lua_close(hlua_states[thr]);
|
||||
}
|
||||
|
||||
srv_drop(socket_tcp);
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
srv_drop(socket_ssl);
|
||||
#endif
|
||||
|
||||
free_proxy(socket_proxy);
|
||||
}
|
||||
|
||||
|
@ -6,15 +6,13 @@
|
||||
#include <haproxy/dynbuf.h>
|
||||
#include <haproxy/htx.h>
|
||||
#include <haproxy/http.h>
|
||||
#include <haproxy/istbuf.h>
|
||||
#include <haproxy/mux_quic.h>
|
||||
#include <haproxy/qmux_http.h>
|
||||
#include <haproxy/qmux_trace.h>
|
||||
#include <haproxy/quic_utils.h>
|
||||
#include <haproxy/trace.h>
|
||||
|
||||
/* HTTP/0.9 request -> HTX. */
|
||||
static ssize_t hq_interop_rcv_buf_req(struct qcs *qcs, struct buffer *b, int fin)
|
||||
static ssize_t hq_interop_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
|
||||
{
|
||||
struct htx *htx;
|
||||
struct htx_sl *sl;
|
||||
@ -94,74 +92,12 @@ static ssize_t hq_interop_rcv_buf_req(struct qcs *qcs, struct buffer *b, int fin
|
||||
return b_data(b);
|
||||
}
|
||||
|
||||
/* HTTP/0.9 response -> HTX. */
|
||||
static ssize_t hq_interop_rcv_buf_res(struct qcs *qcs, struct buffer *b, int fin)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
struct htx *htx;
|
||||
struct htx_sl *sl;
|
||||
struct buffer *htx_buf;
|
||||
const struct stream *strm = __sc_strm(qcs->sd->sc);
|
||||
const unsigned int flags = HTX_SL_F_VER_11|HTX_SL_F_XFER_LEN;
|
||||
size_t htx_sent;
|
||||
|
||||
htx_buf = qcc_get_stream_rxbuf(qcs);
|
||||
BUG_ON(!htx_buf);
|
||||
htx = htx_from_buf(htx_buf);
|
||||
|
||||
if (htx_is_empty(htx) && !strm->res.total) {
|
||||
/* First data transfer, add HTX response start-line first. */
|
||||
sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags,
|
||||
ist("HTTP/1.0"), ist("200"), ist(""));
|
||||
BUG_ON(!sl);
|
||||
if (fin && !b_data(b))
|
||||
sl->flags |= HTX_SL_F_BODYLESS;
|
||||
htx_add_endof(htx, HTX_BLK_EOH);
|
||||
}
|
||||
|
||||
if (!b_data(b)) {
|
||||
if (fin && quic_stream_is_bidi(qcs->id)) {
|
||||
if (qcs_http_handle_standalone_fin(qcs)) {
|
||||
htx_to_buf(htx, htx_buf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BUG_ON(b_data(b) > htx_free_data_space(htx)); /* TODO */
|
||||
BUG_ON(b_head(b) + b_data(b) > b_wrap(b)); /* TODO */
|
||||
|
||||
htx_sent = htx_add_data(htx, ist2(b_head(b), b_data(b)));
|
||||
BUG_ON(htx_sent < b_data(b)); /* TODO */
|
||||
ret = htx_sent;
|
||||
|
||||
if (fin && b_data(b) == htx_sent)
|
||||
htx->flags |= HTX_FL_EOM;
|
||||
}
|
||||
|
||||
htx_to_buf(htx, htx_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Returns the amount of decoded bytes from <b> or a negative error code. */
|
||||
static ssize_t hq_interop_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
|
||||
{
|
||||
/* hq-interop parser does not support buffer wrapping. */
|
||||
BUG_ON(b_data(b) != b_contig_data(b, 0));
|
||||
|
||||
return !(qcs->qcc->flags & QC_CF_IS_BACK) ?
|
||||
hq_interop_rcv_buf_req(qcs, b, fin) :
|
||||
hq_interop_rcv_buf_res(qcs, b, fin);
|
||||
}
|
||||
|
||||
/* Returns the amount of consumed bytes from <buf>. */
|
||||
static size_t hq_interop_snd_buf(struct qcs *qcs, struct buffer *buf,
|
||||
size_t count)
|
||||
{
|
||||
enum htx_blk_type btype;
|
||||
struct htx *htx = NULL;
|
||||
struct htx_blk *blk;
|
||||
struct htx_sl *sl = NULL;
|
||||
int32_t idx;
|
||||
uint32_t bsize, fsize;
|
||||
struct buffer *res = NULL;
|
||||
@ -177,25 +113,9 @@ static size_t hq_interop_snd_buf(struct qcs *qcs, struct buffer *buf,
|
||||
btype = htx_get_blk_type(blk);
|
||||
fsize = bsize = htx_get_blksz(blk);
|
||||
|
||||
BUG_ON(btype == HTX_BLK_REQ_SL);
|
||||
|
||||
switch (btype) {
|
||||
case HTX_BLK_REQ_SL:
|
||||
res = qcc_get_stream_txbuf(qcs, &err, 0);
|
||||
if (!res) {
|
||||
BUG_ON(err); /* TODO */
|
||||
goto end;
|
||||
}
|
||||
|
||||
BUG_ON_HOT(sl); /* Only one start-line expected */
|
||||
sl = htx_get_blk_ptr(htx, blk);
|
||||
|
||||
/* Only GET supported for HTTP/0.9. */
|
||||
b_putist(res, ist("GET "));
|
||||
b_putist(res, htx_sl_req_uri(sl));
|
||||
b_putist(res, ist(" HTTP/0.9\r\n"));
|
||||
htx_remove_blk(htx, blk);
|
||||
total += fsize;
|
||||
break;
|
||||
|
||||
case HTX_BLK_DATA:
|
||||
res = qcc_get_stream_txbuf(qcs, &err, 0);
|
||||
if (!res) {
|
||||
|
@ -116,13 +116,13 @@ static enum act_return http_action_set_req_line(struct act_rule *rule, struct pr
|
||||
goto leave;
|
||||
|
||||
fail_rewrite:
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
|
||||
if (s->flags & SF_BE_ASSIGNED)
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
|
||||
if (sess->listener && sess->listener->counters)
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
|
||||
|
||||
if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
|
||||
ret = ACT_RET_ERR;
|
||||
@ -386,13 +386,13 @@ static enum act_return http_action_normalize_uri(struct act_rule *rule, struct p
|
||||
goto leave;
|
||||
|
||||
fail_rewrite:
|
||||
_HA_ATOMIC_ADD(&sess->fe->fe_counters.shared->tg[tgid - 1]->failed_rewrites, 1);
|
||||
_HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_rewrites, 1);
|
||||
if (s->flags & SF_BE_ASSIGNED)
|
||||
_HA_ATOMIC_ADD(&s->be->be_counters.shared->tg[tgid - 1]->failed_rewrites, 1);
|
||||
_HA_ATOMIC_ADD(&s->be->be_counters.failed_rewrites, 1);
|
||||
if (sess->listener && sess->listener->counters)
|
||||
_HA_ATOMIC_ADD(&sess->listener->counters->shared->tg[tgid - 1]->failed_rewrites, 1);
|
||||
_HA_ATOMIC_ADD(&sess->listener->counters->failed_rewrites, 1);
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_ADD(&__objt_server(s->target)->counters.shared->tg[tgid - 1]->failed_rewrites, 1);
|
||||
_HA_ATOMIC_ADD(&__objt_server(s->target)->counters.failed_rewrites, 1);
|
||||
|
||||
if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
|
||||
ret = ACT_RET_ERR;
|
||||
@ -562,13 +562,13 @@ static enum act_return http_action_replace_uri(struct act_rule *rule, struct pro
|
||||
goto leave;
|
||||
|
||||
fail_rewrite:
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
|
||||
if (s->flags & SF_BE_ASSIGNED)
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
|
||||
if (sess->listener && sess->listener->counters)
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
|
||||
|
||||
if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
|
||||
ret = ACT_RET_ERR;
|
||||
@ -642,13 +642,13 @@ static enum act_return action_http_set_status(struct act_rule *rule, struct prox
|
||||
struct session *sess, struct stream *s, int flags)
|
||||
{
|
||||
if (http_res_set_status(rule->arg.http.i, rule->arg.http.str, s) == -1) {
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
|
||||
if (s->flags & SF_BE_ASSIGNED)
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
|
||||
if (sess->listener && sess->listener->counters)
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
|
||||
|
||||
if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
|
||||
if (!(s->flags & SF_ERR_MASK))
|
||||
@ -717,10 +717,10 @@ static enum act_return http_action_reject(struct act_rule *rule, struct proxy *p
|
||||
s->req.analysers &= AN_REQ_FLT_END;
|
||||
s->res.analysers &= AN_RES_FLT_END;
|
||||
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->denied_req);
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.shared->tg[tgid - 1]->denied_req);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.denied_req);
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.denied_req);
|
||||
if (sess->listener && sess->listener->counters)
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->shared->tg[tgid - 1]->denied_req);
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->denied_req);
|
||||
|
||||
if (!(s->flags & SF_ERR_MASK))
|
||||
s->flags |= SF_ERR_PRXCOND;
|
||||
@ -1281,7 +1281,7 @@ static enum act_return http_action_auth(struct act_rule *rule, struct proxy *px,
|
||||
req->analysers &= AN_REQ_FLT_END;
|
||||
|
||||
if (s->sess->fe == s->be) /* report it if the request was intercepted by the frontend */
|
||||
_HA_ATOMIC_INC(&s->sess->fe->fe_counters.shared->tg[tgid - 1]->intercepted_req);
|
||||
_HA_ATOMIC_INC(&s->sess->fe->fe_counters.intercepted_req);
|
||||
|
||||
if (!(s->flags & SF_ERR_MASK))
|
||||
s->flags |= SF_ERR_LOCAL;
|
||||
@ -1449,13 +1449,13 @@ static enum act_return http_action_set_header(struct act_rule *rule, struct prox
|
||||
goto leave;
|
||||
|
||||
fail_rewrite:
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
|
||||
if (s->flags & SF_BE_ASSIGNED)
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
|
||||
if (sess->listener && sess->listener->counters)
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
|
||||
|
||||
if (!(msg->flags & HTTP_MSGF_SOFT_RW)) {
|
||||
ret = ACT_RET_ERR;
|
||||
@ -1581,13 +1581,13 @@ static enum act_return http_action_replace_header(struct act_rule *rule, struct
|
||||
goto leave;
|
||||
|
||||
fail_rewrite:
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
|
||||
if (s->flags & SF_BE_ASSIGNED)
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
|
||||
if (sess->listener && sess->listener->counters)
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->tg[tgid - 1]->failed_rewrites);
|
||||
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
|
||||
|
||||
if (!(msg->flags & HTTP_MSGF_SOFT_RW)) {
|
||||
ret = ACT_RET_ERR;
|
||||
@ -2315,7 +2315,7 @@ static enum act_return http_action_return(struct act_rule *rule, struct proxy *p
|
||||
req->analysers &= AN_REQ_FLT_END;
|
||||
|
||||
if (s->sess->fe == s->be) /* report it if the request was intercepted by the frontend */
|
||||
_HA_ATOMIC_INC(&s->sess->fe->fe_counters.shared->tg[tgid - 1]->intercepted_req);
|
||||
_HA_ATOMIC_INC(&s->sess->fe->fe_counters.intercepted_req);
|
||||
}
|
||||
|
||||
return ACT_RET_ABRT;
|
||||
|
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