mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-01-16 06:11:00 +01:00
Compare commits
No commits in common. "master" and "v3.3-dev11" have entirely different histories.
master
...
v3.3-dev11
2
.github/h2spec.config
vendored
2
.github/h2spec.config
vendored
@ -19,7 +19,7 @@ defaults
|
||||
|
||||
frontend h2
|
||||
mode http
|
||||
bind 127.0.0.1:8443 ssl crt reg-tests/ssl/certs/common.pem alpn h2,http/1.1
|
||||
bind 127.0.0.1:8443 ssl crt reg-tests/ssl/common.pem alpn h2,http/1.1
|
||||
default_backend h2b
|
||||
|
||||
backend h2b
|
||||
|
||||
2
.github/matrix.py
vendored
2
.github/matrix.py
vendored
@ -280,7 +280,7 @@ def main(ref_name):
|
||||
if "haproxy-" in ref_name:
|
||||
os = "macos-13" # stable branch
|
||||
else:
|
||||
os = "macos-26" # development branch
|
||||
os = "macos-15" # development branch
|
||||
|
||||
TARGET = "osx"
|
||||
for CC in ["clang"]:
|
||||
|
||||
2
.github/workflows/openssl-ech.yml
vendored
2
.github/workflows/openssl-ech.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
||||
run: env SSL_LIB=${HOME}/opt/ scripts/build-curl.sh
|
||||
- name: Compile HAProxy
|
||||
run: |
|
||||
make -j$(nproc) CC=gcc TARGET=linux-glibc \
|
||||
make -j$(nproc) ERR=1 CC=gcc TARGET=linux-glibc \
|
||||
USE_QUIC=1 USE_OPENSSL=1 USE_ECH=1 \
|
||||
SSL_LIB=${HOME}/opt/lib SSL_INC=${HOME}/opt/include \
|
||||
DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" \
|
||||
|
||||
77
.github/workflows/openssl-master.yml
vendored
77
.github/workflows/openssl-master.yml
vendored
@ -1,77 +0,0 @@
|
||||
name: openssl master
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 3 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- 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
|
||||
sudo apt-get --no-install-recommends -y install libpsl-dev
|
||||
- uses: ./.github/actions/setup-vtest
|
||||
- name: Install OpenSSL master
|
||||
run: env OPENSSL_VERSION="git-master" GIT_TYPE="branch" scripts/build-ssl.sh
|
||||
- name: Compile HAProxy
|
||||
run: |
|
||||
make -j$(nproc) ERR=1 CC=gcc TARGET=linux-glibc \
|
||||
USE_QUIC=1 USE_OPENSSL=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: 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: Run Unit tests
|
||||
id: unittests
|
||||
run: |
|
||||
make unit-tests
|
||||
- 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
|
||||
32
.github/workflows/openssl-nodeprecated.yml
vendored
Normal file
32
.github/workflows/openssl-nodeprecated.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
#
|
||||
# special purpose CI: test against OpenSSL built in "no-deprecated" mode
|
||||
# let us run those builds weekly
|
||||
#
|
||||
# for example, OpenWRT uses such OpenSSL builds (those builds are smaller)
|
||||
#
|
||||
#
|
||||
# some details might be found at NL: https://www.mail-archive.com/haproxy@formilux.org/msg35759.html
|
||||
# GH: https://github.com/haproxy/haproxy/issues/367
|
||||
|
||||
name: openssl no-deprecated
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * 4"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup-vtest
|
||||
- name: Compile HAProxy
|
||||
run: |
|
||||
make DEFINE="-DOPENSSL_API_COMPAT=0x10100000L -DOPENSSL_NO_DEPRECATED" -j3 CC=gcc ERR=1 TARGET=linux-glibc USE_OPENSSL=1
|
||||
- name: Run VTest
|
||||
run: |
|
||||
make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
|
||||
2
.github/workflows/vtest.yml
vendored
2
.github/workflows/vtest.yml
vendored
@ -113,7 +113,7 @@ jobs:
|
||||
DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" \
|
||||
${{ join(matrix.FLAGS, ' ') }} \
|
||||
ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/"
|
||||
sudo make install-bin
|
||||
sudo make install
|
||||
- name: Compile admin/halog/halog
|
||||
run: |
|
||||
make -j$(nproc) admin/halog/halog \
|
||||
|
||||
359
CHANGELOG
359
CHANGELOG
@ -1,365 +1,6 @@
|
||||
ChangeLog :
|
||||
===========
|
||||
|
||||
2026/01/07 : 3.4-dev2
|
||||
- BUG/MEDIUM: mworker/listener: ambiguous use of RX_F_INHERITED with shards
|
||||
- BUG/MEDIUM: http-ana: Properly detect client abort when forwarding response (v2)
|
||||
- BUG/MEDIUM: stconn: Don't report abort from SC if read0 was already received
|
||||
- BUG/MEDIUM: quic: Don't try to use hystart if not implemented
|
||||
- CLEANUP: backend: Remove useless test on server's xprt
|
||||
- CLEANUP: tcpcheck: Remove useless test on the xprt used for healthchecks
|
||||
- CLEANUP: ssl-sock: Remove useless tests on connection when resuming TLS session
|
||||
- REGTESTS: quic: fix a TLS stack usage
|
||||
- REGTESTS: list all skipped tests including 'feature cmd' ones
|
||||
- CI: github: remove openssl no-deprecated job
|
||||
- CI: github: add a job to test the master branch of OpenSSL
|
||||
- CI: github: openssl-master.yml misses actions/checkout
|
||||
- BUG/MEDIUM: backend: Do not remove CO_FL_SESS_IDLE in assign_server()
|
||||
- CI: github: use git prefix for openssl-master.yml
|
||||
- BUG/MEDIUM: mux-h2: synchronize all conditions to create a new backend stream
|
||||
- REGTESTS: fix error when no test are skipped
|
||||
- MINOR: cpu-topo: Turn the cpu policy configuration into a struct
|
||||
- MEDIUM: cpu-topo: Add a "threads-per-core" keyword to cpu-policy
|
||||
- MEDIUM: cpu-topo: Add a "cpu-affinity" option
|
||||
- MEDIUM: cpu-topo: Add a new "max-threads-per-group" global keyword
|
||||
- MEDIUM: cpu-topo: Add the "per-thread" cpu_affinity
|
||||
- MEDIUM: cpu-topo: Add the "per-ccx" cpu_affinity
|
||||
- BUG/MINOR: cpu-topo: fix -Wlogical-not-parentheses build with clang
|
||||
- DOC: config: fix number of values for "cpu-affinity"
|
||||
- MINOR: tools: add a secure implementation of memset
|
||||
- MINOR: mux-h2: add missing glitch count for non-decodable H2 headers
|
||||
- MINOR: mux-h2: perform a graceful close at 75% glitches threshold
|
||||
- MEDIUM: mux-h1: implement basic glitches support
|
||||
- MINOR: mux-h1: perform a graceful close at 75% glitches threshold
|
||||
- MEDIUM: cfgparse: acknowledge that proxy ID auto numbering starts at 2
|
||||
- MINOR: cfgparse: remove useless checks on no server in backend
|
||||
- OPTIM/MINOR: proxy: do not init proxy management task if unused
|
||||
- MINOR: patterns: preliminary changes for reorganization
|
||||
- MEDIUM: patterns: reorganize pattern reference elements
|
||||
- CLEANUP: patterns: remove dead code
|
||||
- OPTIM: patterns: cache the current generation
|
||||
- MINOR: tcp: add new bind option "tcp-ss" to instruct the kernel to save the SYN
|
||||
- MINOR: protocol: support a generic way to call getsockopt() on a connection
|
||||
- MINOR: tcp: implement the get_opt() function
|
||||
- MINOR: tcp_sample: implement the fc_saved_syn sample fetch function
|
||||
- CLEANUP: assorted typo fixes in the code, commits and doc
|
||||
- BUG/MEDIUM: cpu-topo: Don't forget to reset visited_ccx.
|
||||
- BUG/MAJOR: set the correct generation ID in pat_ref_append().
|
||||
- BUG/MINOR: backend: fix the conn_retries check for TFO
|
||||
- BUG/MINOR: backend: inspect request not response buffer to check for TFO
|
||||
- MINOR: net_helper: add sample converters to decode ethernet frames
|
||||
- MINOR: net_helper: add sample converters to decode IP packet headers
|
||||
- MINOR: net_helper: add sample converters to decode TCP headers
|
||||
- MINOR: net_helper: add ip.fp() to build a simplified fingerprint of a SYN
|
||||
- MINOR: net_helper: prepare the ip.fp() converter to support more options
|
||||
- MINOR: net_helper: add an option to ip.fp() to append the TTL to the fingerprint
|
||||
- MINOR: net_helper: add an option to ip.fp() to append the source address
|
||||
- DOC: config: fix the length attribute name for stick tables of type binary / string
|
||||
- MINOR: mworker/cli: only keep positive PIDs in proc_list
|
||||
- CLEANUP: mworker: remove duplicate list.h include
|
||||
- BUG/MINOR: mworker/cli: fix show proc pagination using reload counter
|
||||
- MINOR: mworker/cli: extract worker "show proc" row printer
|
||||
- MINOR: cpu-topo: Factorize code
|
||||
- MINOR: cpu-topo: Rename variables to better fit their usage
|
||||
- BUG/MEDIUM: peers: Properly handle shutdown when trying to get a line
|
||||
- BUG/MEDIUM: mux-h1: Take care to update <kop> value during zero-copy forwarding
|
||||
- MINOR: threads: Avoid using a thread group mask when stopping.
|
||||
- MINOR: hlua: Add support for lua 5.5
|
||||
- MEDIUM: cpu-topo: Add an optional directive for per-group affinity
|
||||
- BUG/MEDIUM: mworker: can't use signals after a failed reload
|
||||
- BUG/MEDIUM: stconn: Move data from <kip> to <kop> during zero-copy forwarding
|
||||
- DOC: config: fix a few typos and refine cpu-affinity
|
||||
- MINOR: receiver: Remove tgroup_mask from struct shard_info
|
||||
- BUG/MINOR: quic: fix deprecated warning for window size keyword
|
||||
|
||||
2025/12/10 : 3.4-dev1
|
||||
- BUG/MINOR: jwt: Missing "case" in switch statement
|
||||
- DOC: configuration: ECH support details
|
||||
- Revert "MINOR: quic: use dynamic cc_algo on bind_conf"
|
||||
- MINOR: quic: define quic_cc_algo as const
|
||||
- MINOR: quic: extract cc-algo parsing in a dedicated function
|
||||
- MINOR: quic: implement cc-algo server keyword
|
||||
- BUG/MINOR: quic-be: Missing keywords array NULL termination
|
||||
- REGTESTS: ssl enable tls12_reuse.vtc for AWS-LC
|
||||
- REGTESTS: ssl: split tls*_reuse in stateless and stateful resume tests
|
||||
- BUG/MEDIUM: connection: fix "bc_settings_streams_limit" typo
|
||||
- BUG/MEDIUM: config: ignore empty args in skipped blocks
|
||||
- DOC: config: mention clearer that the cache's total-max-size is mandatory
|
||||
- DOC: config: reorder the cache section's keywords
|
||||
- BUG/MINOR: quic/ssl: crash in ClientHello callback ssl traces
|
||||
- BUG/MINOR: quic-be: handshake errors without connection stream closure
|
||||
- MINOR: quic: Add useful debugging traces in qc_idle_timer_do_rearm()
|
||||
- REGTESTS: ssl: Move all the SSL certificates, keys, crt-lists inside "certs" directory
|
||||
- REGTESTS: quic/ssl: ssl/del_ssl_crt-list.vtc supported by QUIC
|
||||
- REGTESTS: quic: dynamic_server_ssl.vtc supported by QUIC
|
||||
- REGTESTS: quic: issuers_chain_path.vtc supported by QUIC
|
||||
- REGTESTS: quic: new_del_ssl_cafile.vtc supported by QUIC
|
||||
- REGTESTS: quic: ocsp_auto_update.vtc supported by QUIC
|
||||
- REGTESTS: quic: set_ssl_bug_2265.vtc supported by QUIC
|
||||
- MINOR: quic: avoid code duplication in TLS alert callback
|
||||
- BUG/MINOR: quic-be: missing connection stream closure upon TLS alert to send
|
||||
- REGTESTS: quic: set_ssl_cafile.vtc supported by QUIC
|
||||
- REGTESTS: quic: set_ssl_cert_noext.vtc supported by QUIC
|
||||
- REGTESTS: quic: set_ssl_cert.vtc supported by QUIC
|
||||
- REGTESTS: quic: set_ssl_crlfile.vtc supported by QUIC
|
||||
- REGTESTS: quic: set_ssl_server_cert.vtc supported by QUIC
|
||||
- REGTESTS: quic: show_ssl_ocspresponse.vtc supported by QUIC
|
||||
- REGTESTS: quic: ssl_client_auth.vtc supported by QUIC
|
||||
- REGTESTS: quic: ssl_client_samples.vtc supported by QUIC
|
||||
- REGTESTS: quic: ssl_default_server.vtc supported by QUIC
|
||||
- REGTESTS: quic: new_del_ssl_crlfile.vtc supported by QUIC
|
||||
- REGTESTS: quic: ssl_frontend_samples.vtc supported by QUIC
|
||||
- REGTESTS: quic: ssl_server_samples.vtc supported by QUIC
|
||||
- REGTESTS: quic: ssl_simple_crt-list.vtc supported by QUIC
|
||||
- REGTESTS: quic: ssl_sni_auto.vtc code provision for QUIC
|
||||
- REGTESTS: quic: ssl_curve_name.vtc supported by QUIC
|
||||
- REGTESTS: quic: add_ssl_crt-list.vtc supported by QUIC
|
||||
- REGTESTS: add ssl_ciphersuites.vtc (TCP & QUIC)
|
||||
- BUG/MINOR: quic: do not set first the default QUIC curves
|
||||
- REGTESTS: quic/ssl: Add ssl_curves_selection.vtc
|
||||
- BUG/MINOR: ssl: Don't allow to set NULL sni
|
||||
- MEDIUM: quic: Add connection as argument when qc_new_conn() is called
|
||||
- MINOR: ssl: Add a function to hash SNIs
|
||||
- MINOR: ssl: Store hash of the SNI for cached TLS sessions
|
||||
- MINOR: ssl: Compare hashes instead of SNIs when a session is cached
|
||||
- MINOR: connection/ssl: Store the SNI hash value in the connection itself
|
||||
- MEDIUM: tcpcheck/backend: Get the connection SNI before initializing SSL ctx
|
||||
- BUG/MEDIUM: ssl: Don't reuse TLS session if the connection's SNI differs
|
||||
- MEDIUM: ssl/server: No longer store the SNI of cached TLS sessions
|
||||
- BUG/MINOR: log: Dump good %B and %U values in logs
|
||||
- BUG/MEDIUM: http-ana: Don't close server connection on read0 in TUNNEL mode
|
||||
- DOC: config: Fix description of the spop mode
|
||||
- DOC: config: Improve spop mode documentation
|
||||
- MINOR: ssl: Split ssl_crt-list_filters.vtc in two files by TLS version
|
||||
- REGTESTS: quic: tls13_ssl_crt-list_filters.vtc supported by QUIC
|
||||
- BUG/MEDIUM: h3: do not access QCS <sd> if not allocated
|
||||
- CLEANUP: mworker/cli: remove useless variable
|
||||
- BUG/MINOR: mworker/cli: 'show proc' is limited by buffer size
|
||||
- BUG/MEDIUM: ssl: Always check the ALPN after handshake
|
||||
- MINOR: connections: Add a new CO_FL_SSL_NO_CACHED_INFO flag
|
||||
- BUG/MEDIUM: ssl: Don't store the ALPN for check connections
|
||||
- BUG/MEDIUM: ssl: Don't resume session for check connections
|
||||
- CLEANUP: improvements to the alignment macros
|
||||
- CLEANUP: use the automatic alignment feature
|
||||
- CLEANUP: more conversions and cleanups for alignment
|
||||
- BUG/MEDIUM: h3: fix access to QCS <sd> definitely
|
||||
- MINOR: h2/trace: emit a trace of the received RST_STREAM type
|
||||
|
||||
2025/11/26 : 3.4-dev0
|
||||
- MINOR: version: mention that it's development again
|
||||
|
||||
2025/11/26 : 3.3.0
|
||||
- BUG/MINOR: acme: better challenge_ready processing
|
||||
- BUG/MINOR: acme: warning ‘ctx’ may be used uninitialized
|
||||
- MINOR: httpclient: complete the https log
|
||||
- BUG/MEDIUM: server: do not use default SNI if manually set
|
||||
- BUG/MINOR: freq_ctr: Prevent possible signed overflow in freq_ctr_overshoot_period
|
||||
- DOC: ssl: Document the restrictions on 0RTT.
|
||||
- DOC: ssl: Note that 0rtt works fork QUIC with QuicTLS too.
|
||||
- BUG/MEDIUM: quic: do not prevent sending if no BE token
|
||||
- BUG/MINOR: quic/server: free quic_retry_token on srv drop
|
||||
- MINOR: quic: split global CID tree between FE and BE sides
|
||||
- MINOR: quic: use separate global quic_conns FE/BE lists
|
||||
- MINOR: quic: add "clo" filter on show quic
|
||||
- MINOR: quic: dump backend connections on show quic
|
||||
- MINOR: quic: mark backend conns on show quic
|
||||
- BUG/MINOR: quic: fix uninit list on show quic handler
|
||||
- BUG/MINOR: quic: release BE quic_conn on connect failure
|
||||
- BUG/MINOR: server: fix srv_drop() crash on partially init srv
|
||||
- BUG/MINOR: h3: do no crash on forwarding multiple chained response
|
||||
- BUG/MINOR: h3: handle properly buf alloc failure on response forwarding
|
||||
- BUG/MEDIUM: server/ssl: Unset the SNI for new server connections if none is set
|
||||
- BUG/MINOR: acme: fix ha_alert() call
|
||||
- Revert "BUG/MEDIUM: server/ssl: Unset the SNI for new server connections if none is set"
|
||||
- BUG/MINOR: sock-inet: ignore conntrack for transparent sockets on Linux
|
||||
- DEV: patchbot: prepare for new version 3.4-dev
|
||||
- DOC: update INSTALL with the range of gcc compilers and openssl versions
|
||||
- MINOR: version: mention that 3.3 is stable now
|
||||
|
||||
2025/11/21 : 3.3-dev14
|
||||
- MINOR: stick-tables: Rename stksess shards to use buckets
|
||||
- MINOR: quic: do not use quic_newcid_from_hash64 on BE side
|
||||
- MINOR: quic: support multiple random CID generation for BE side
|
||||
- MINOR: quic: try to clarify quic_conn CIDs fields direction
|
||||
- MINOR: quic: refactor qc_new_conn() prototype
|
||||
- MINOR: quic: remove <ipv4> arg from qc_new_conn()
|
||||
- MEDIUM: mworker: set the mworker-max-reloads to 50
|
||||
- BUG/MEDIUM: quic-be: prevent use of MUX for 0-RTT sessions without secrets
|
||||
- CLEANUP: startup: move confusing msg variable
|
||||
- BUG/MEDIUM: mworker: signals inconsistencies during startup and reload
|
||||
- BUG/MINOR: mworker: wrong signals during startup
|
||||
- BUG/MINOR: acme: P-256 doesn't work with openssl >= 3.0
|
||||
- REGTESTS: ssl: split the SSL reuse test into TLS 1.2/1.3
|
||||
- BUILD: Makefile: make install with admin tools
|
||||
- CI: github: make install-bin instead of make install
|
||||
- BUG/MINOR: ssl: remove dead code in ssl_sock_from_buf()
|
||||
- BUG/MINOR: mux-quic: implement max-reuse server parameter
|
||||
- MINOR: quic: fix trace on quic_conn_closed release
|
||||
- BUG/MINOR: quic: do not decrement jobs for backend conns
|
||||
- BUG/MINOR: quic: fix FD usage for quic_conn_closed on backend side
|
||||
- BUILD: Makefile: remove halog from install-admin
|
||||
- REGTESTS: ssl: add basic 0rtt tests for TLSv1.2, TLSv1.3 and QUIC
|
||||
- REGTESTS: ssl: also verify that 0-rtt properly advertises early-data:1
|
||||
- MINOR: quic/flags: add missing QUIC flags for flags dev tool.
|
||||
- MINOR: quic: uneeded xprt context variable passed as parameter
|
||||
- MINOR: limits: keep a copy of the rough estimate of needed FDs in global struct
|
||||
- MINOR: limits: explain a bit better what to do when fd limits are exceeded
|
||||
- BUG/MEDIUM: quic-be/ssl_sock: TLS callback called without connection
|
||||
- BUG/MINOR: acme: alert when the map doesn't exist at startup
|
||||
- DOC: acme: add details about the DNS-01 support
|
||||
- DOC: acme: explain how to dump the certificates
|
||||
- DOC: acme: configuring acme needs a crt file
|
||||
- DOC: acme: add details about key pair generation in ACME section
|
||||
- BUG/MEDIUM: queues: Don't forget to unlock the queue before exiting
|
||||
- MINOR: muxes: Support an optional ALPN string when defining mux protocols
|
||||
- MINOR: config: Do proto detection for listeners before checks about ALPN
|
||||
- BUG/MEDIUM: config: Use the mux protocol ALPN by default for listeners if forced
|
||||
- DOC: config: Add a note about conflict with ALPN/NPN settings and proto keyword
|
||||
- MINOR: quic: store source address for backend conns
|
||||
- BUG/MINOR: quic: flag conn with CO_FL_FDLESS on backend side
|
||||
- ADMIN: dump-certs: let dry-run compare certificates
|
||||
- BUG/MEDIUM: connection/ssl: also fix the ssl_sock_io_cb() regarding idle list
|
||||
- DOC: http: document 413 response code
|
||||
- MINOR: limits: display the computed maxconn using ha_notice()
|
||||
- BUG/MEDIUM: applet: Fix conditions to detect spinning loop with the new API
|
||||
- BUG/MEDIUM: cli: State the cli have no more data to deliver if it yields
|
||||
- MINOR: h3: adjust sedesc update for known input payload len
|
||||
- BUG/MINOR: mux-quic: fix sedesc leak on BE side
|
||||
- OPTIM: mux-quic: delay FE sedesc alloc to stream creation
|
||||
- BUG/MEDIUM: quic-be: quic_conn_closed buffer overflow
|
||||
- BUG/MINOR: mux-quic: check access on qcs stream-endpoint
|
||||
- BUG/MINOR: acme: handle multiple auth with the same name
|
||||
- BUG/MINOR: acme: prevent creating map entries with dns-01
|
||||
|
||||
2025/11/14 : 3.3-dev13
|
||||
- BUG/MEDIUM: config: for word expansion, empty or non-existing are the same
|
||||
- BUG/MINOR: quic: close connection on CID alloc failure
|
||||
- MINOR: quic: adjust CID conn tree alloc in qc_new_conn()
|
||||
- MINOR: quic: split CID alloc/generation function
|
||||
- BUG/MEDIUM: quic: handle collision on CID generation
|
||||
- MINOR: quic: extend traces on CID allocation
|
||||
- MEDIUM/OPTIM: quic: alloc quic_conn after CID collision check
|
||||
- MINOR: stats-proxy: ensure future-proof FN_AGE manipulation in me_generate_field()
|
||||
- BUG/MEDIUM: stats-file: fix shm-stats-file preload not working anymore
|
||||
- BUG/MINOR: do not account backend connections into maxconn
|
||||
- BUG/MEDIUM: init: 'devnullfd' not properly closed for master
|
||||
- BUG/MINOR: acme: more explicit error when BIO_new_file()
|
||||
- BUG/MEDIUM: quic-be: do not launch the connection migration process
|
||||
- MINOR: quic-be: Parse the NEW_TOKEN frame
|
||||
- MEDIUM: quic-be: Parse, store and reuse tokens provided by NEW_TOKEN
|
||||
- MINOR: quic-be: helper functions to save/restore transport params (0-RTT)
|
||||
- MINOR: quic-be: helper quic_reuse_srv_params() function to reuse server params (0-RTT)
|
||||
- MINOR: quic-be: Save the backend 0-RTT parameters
|
||||
- MEDIUM: quic-be: modify ssl_sock_srv_try_reuse_sess() to reuse backend sessions (0-RTT)
|
||||
- MINOR: quic-be: allow the preparation of 0-RTT packets
|
||||
- MINOR: quic-be: Send post handshake frames from list of frames (0-RTT)
|
||||
- MEDIUM: quic-be: qc_send_mux() adaptation for 0-RTT
|
||||
- MINOR: quic-be: discard the 0-RTT keys
|
||||
- MEDIUM: quic-be: enable the use of 0-RTT
|
||||
- MINOR: quic-be: validate the 0-RTT transport parameters
|
||||
- MINOR: quic-be: do not create the mux after handshake completion (for 0-RTT)
|
||||
- MINOR: quic-be: avoid a useless I/O callback wakeup for 0-RTT sessions
|
||||
- BUG/MEDIUM: acme: move from mt_list to a rwlock + ebmbtree
|
||||
- BUG/MINOR: acme: can't override the default resolver
|
||||
- MINOR: ssl/sample: expose ssl_*c_curve for AWS-LC
|
||||
- MINOR: check: delay MUX init when SSL ALPN is used
|
||||
- MINOR: cfgdiag: adjust diag on servers
|
||||
- BUG/MINOR: check: only try connection reuse for http-check rulesets
|
||||
- BUG/MINOR: check: fix reuse-pool if MUX inherited from server
|
||||
- MINOR: check: clarify check-reuse-pool interaction with reuse policy
|
||||
- DOC: configuration: add missing ssllib_name_startswith()
|
||||
- DOC: configuration: add missing openssl_version predicates
|
||||
- MINOR: cfgcond: add "awslc_api_atleast" and "awslc_api_before"
|
||||
- REGTESTS: ssl: activate ssl_curve_name.vtc for AWS-LC
|
||||
- BUILD: ech: fix clang warnings
|
||||
- BUG/MEDIUM: stick-tables: Always return the good stksess from stktable_set_entry
|
||||
- BUG/MINOR: stick-tables: Fix return value for __stksess_kill()
|
||||
- CLEANUP: stick-tables: Don't needlessly compute shard number in stksess_free()
|
||||
- MINOR: h1: h1_release() should return if it destroyed the connection
|
||||
- BUG/MEDIUM: h1: prevent a crash on HTTP/2 upgrade
|
||||
- MINOR: check: use auto SNI for QUIC checks
|
||||
- MINOR: check: ensure QUIC checks configuration coherency
|
||||
- CLEANUP: peers: remove an unneeded null check
|
||||
- Revert "BUG/MEDIUM: connections: permit to permanently remove an idle conn"
|
||||
- BUG/MEDIUM: connection: do not reinsert a purgeable conn in idle list
|
||||
- DEBUG: extend DEBUG_STRESS to ease testing and turn on extra checks
|
||||
- DEBUG: add BUG_ON_STRESS(): a BUG_ON() implemented only when DEBUG_STRESS > 0
|
||||
- DEBUG: servers: add a few checks for stress-testing idle conns
|
||||
- BUG/MINOR: check: fix QUIC check test when QUIC disabled
|
||||
- BUG/MINOR: quic-be: missing version negotiation
|
||||
- CLEANUP: quic: Missing succesful SSL handshake backend trace (OpenSSL 3.5)
|
||||
- BUG/MINOR: quic-be: backend SSL session reuse fix (OpenSSL 3.5)
|
||||
- REGTEST: quic: quic/ssl_reuse.vtc supports OpenSSL 3.5 QUIC API
|
||||
|
||||
2025/11/08 : 3.3-dev12
|
||||
- MINOR: quic: enable SSL on QUIC servers automatically
|
||||
- MINOR: quic: reject conf with QUIC servers if not compiled
|
||||
- OPTIM: quic: adjust automatic ALPN setting for QUIC servers
|
||||
- MINOR: sample: optional AAD parameter support to aes_gcm_enc/dec
|
||||
- REGTESTS: converters: check USE_OPENSSL in aes_gcm.vtc
|
||||
- BUG/MINOR: resolvers: ensure fair round robin iteration
|
||||
- BUG/MAJOR: stats-file: fix crash on non-x86 platform caused by unaligned cast
|
||||
- OPTIM: backend: skip conn reuse for incompatible proxies
|
||||
- SCRIPTS: build-ssl: allow to build a FIPS version without FIPS
|
||||
- OPTIM: proxy: move atomically access fields out of the read-only ones
|
||||
- SCRIPTS: build-ssl: fix rpath in AWS-LC install for openssl and bssl bin
|
||||
- CI: github: update to macos-26
|
||||
- BUG/MINOR: quic: fix crash on client handshake abort
|
||||
- MINOR: quic: do not set conn member if ssl_sock_ctx
|
||||
- MINOR: quic: remove connection arg from qc_new_conn()
|
||||
- BUG/MEDIUM: server: Add a rwlock to path parameter
|
||||
- BUG/MEDIUM: server: Also call srv_reset_path_parameters() on srv up
|
||||
- BUG/MEDIUM: mux-h1: fix 414 / 431 status code reporting
|
||||
- BUG/MEDIUM: mux-h2: make sure not to move a dead connection to idle
|
||||
- BUG/MEDIUM: connections: permit to permanently remove an idle conn
|
||||
- MEDIUM: cfgparse: deprecate 'master-worker' keyword alone
|
||||
- MEDIUM: cfgparse: 'daemon' not compatible with -Ws
|
||||
- DOC: configuration: deprecate the master-worker keyword
|
||||
- MINOR: quic: remove <mux_state> field
|
||||
- BUG/MEDIUM: stick-tables: Make sure we handle expiration on all tables
|
||||
- MEDIUM: stick-tables: Optimize the expiration process a bit.
|
||||
- MEDIUM: ssl/ckch: use ckch_store instead of ckch_data for ckch_conf_kws
|
||||
- MINOR: acme: generate a temporary key pair
|
||||
- MEDIUM: acme: generate a key pair when no file are available
|
||||
- BUILD: ssl/ckch: wrong function name in ckch_conf_kws
|
||||
- BUILD: acme: acme_gen_tmp_x509() signedness and unused variables
|
||||
- BUG/MINOR: acme: fix initialization issue in acme_gen_tmp_x509()
|
||||
- BUILD: ssl/ckch: fix ckch_conf_kws parsing without ACME
|
||||
- MINOR: server: move the lock inside srv_add_idle()
|
||||
- DOC: acme: crt-store allows you to start without a certificate
|
||||
- BUG/MINOR: acme: allow 'key' when generating cert
|
||||
- MINOR: stconn: Add counters to SC to know number of bytes received and sent
|
||||
- MINOR: stream: Add samples to get number of bytes received or sent on each side
|
||||
- MINOR: counters: Add req_in/req_out/res_in/res_out counters for fe/be/srv/li
|
||||
- MINOR: stream: Remove bytes_in and bytes_out counters from stream
|
||||
- MINOR: counters: Remove bytes_in and bytes_out counter from fe/be/srv/li
|
||||
- MINOR: stats: Add stats about request and response bytes received and sent
|
||||
- MINOR: applet: Add function to get amount of data in the output buffer
|
||||
- MINOR: channel: Remove total field from channels
|
||||
- DEBUG: stream: Add bytes_in/bytes_out value for both SC in session dump
|
||||
- MEDIUM: stktables: Limit the number of stick counters to 100
|
||||
- BUG/MINOR: config: Limit "tune.maxpollevents" parameter to 1000000
|
||||
- BUG/MEDIUM: server: close a race around ready_srv when deleting a server
|
||||
- BUG/MINOR: config: emit warning for empty args when *not* in discovery mode
|
||||
- BUG/MEDIUM: config: solve the empty argument problem again
|
||||
- MEDIUM: config: now reject configs with empty arguments
|
||||
- MINOR: tools: add support for ist to the word fingerprinting functions
|
||||
- MINOR: tools: add env_suggest() to suggest alternate variable names
|
||||
- MINOR: tools: have parse_line's error pointer point to unknown variable names
|
||||
- MINOR: cfgparse: try to suggest correct variable names on errors
|
||||
- IMPORT: cebtree: Replace offset calculation with offsetof to avoid UB
|
||||
- BUG/MINOR: acme: wrong dns-01 challenge in the log
|
||||
- MEDIUM: backend: Defer conn_xprt_start() after mux creation
|
||||
- MINOR: peers: Improve traces for peers
|
||||
- MEDIUM: peers: No longer ack updates during a full resync
|
||||
- MEDIUM: peers: Remove commitupdate field on stick-tables
|
||||
- BUG/MEDIUM: peers: Fix update message parsing during a full resync
|
||||
- MINOR: sample/stats: Add "bytes" in req_{in,out} and res_{in,out} names
|
||||
- BUG/MEDIUM: stick-tables: Make sure updates are seen as local
|
||||
- BUG/MEDIUM: proxy: use aligned allocations for struct proxy
|
||||
- BUG/MEDIUM: proxy: use aligned allocations for struct proxy_per_tgroup
|
||||
- BUG/MINOR: acme: avoid a possible crash on error paths
|
||||
|
||||
2025/10/31 : 3.3-dev11
|
||||
- BUG/MEDIUM: mt_list: Make sure not to unlock the element twice
|
||||
- BUG/MINOR: quic-be: unchecked connections during handshakes
|
||||
|
||||
18
INSTALL
18
INSTALL
@ -111,7 +111,7 @@ HAProxy requires a working GCC or Clang toolchain and GNU make :
|
||||
may want to retry with "gmake" which is the name commonly used for GNU make
|
||||
on BSD systems.
|
||||
|
||||
- GCC >= 4.7 (up to 15 tested). Older versions are no longer supported due to
|
||||
- GCC >= 4.7 (up to 14 tested). Older versions are no longer supported due to
|
||||
the latest mt_list update which only uses c11-like atomics. Newer versions
|
||||
may sometimes break due to compiler regressions or behaviour changes. The
|
||||
version shipped with your operating system is very likely to work with no
|
||||
@ -237,7 +237,7 @@ to forcefully enable it using "USE_LIBCRYPT=1".
|
||||
-----------------
|
||||
For SSL/TLS, it is necessary to use a cryptography library. HAProxy currently
|
||||
supports the OpenSSL library, and is known to build and work with branches
|
||||
1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, and 3.0 to 3.6. It is recommended to use
|
||||
1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, and 3.0 to 3.5. It is recommended to use
|
||||
at least OpenSSL 1.1.1 to have support for all SSL keywords and configuration
|
||||
in HAProxy. OpenSSL follows a long-term support cycle similar to HAProxy's,
|
||||
and each of the branches above receives its own fixes, without forcing you to
|
||||
@ -259,15 +259,11 @@ reported to work as well. While there are some efforts from the community to
|
||||
ensure they work well, OpenSSL remains the primary target and this means that
|
||||
in case of conflicting choices, OpenSSL support will be favored over other
|
||||
options. Note that QUIC is not fully supported when haproxy is built with
|
||||
OpenSSL < 3.5.2 version. In this case, QUICTLS or AWS-LC are the preferred
|
||||
alternatives. As of writing this, the QuicTLS project follows OpenSSL very
|
||||
closely and provides update simultaneously, but being a volunteer-driven
|
||||
project, its long-term future does not look certain enough to convince
|
||||
operating systems to package it, so it needs to be build locally. Recent
|
||||
versions of AWS-LC (>= 1.22 and the FIPS branches) are pretty complete and
|
||||
generally more performant than other OpenSSL derivatives, but may behave
|
||||
slightly differently, particularly when dealing with outdated setups. See
|
||||
the section about QUIC in this document.
|
||||
OpenSSL < 3.5 version. In this case, QUICTLS is the preferred alternative.
|
||||
As of writing this, the QuicTLS project follows OpenSSL very closely and provides
|
||||
update simultaneously, but being a volunteer-driven project, its long-term future
|
||||
does not look certain enough to convince operating systems to package it, so it
|
||||
needs to be build locally. See the section about QUIC in this document.
|
||||
|
||||
A fifth option is wolfSSL (https://github.com/wolfSSL/wolfssl). It is the only
|
||||
supported alternative stack not based on OpenSSL, yet which implements almost
|
||||
|
||||
11
Makefile
11
Makefile
@ -643,7 +643,7 @@ ifneq ($(USE_OPENSSL:0=),)
|
||||
OPTIONS_OBJS += src/ssl_sock.o src/ssl_ckch.o src/ssl_ocsp.o src/ssl_crtlist.o \
|
||||
src/ssl_sample.o src/cfgparse-ssl.o src/ssl_gencert.o \
|
||||
src/ssl_utils.o src/jwt.o src/ssl_clienthello.o src/jws.o src/acme.o \
|
||||
src/ssl_trace.o src/jwe.o
|
||||
src/ssl_trace.o
|
||||
endif
|
||||
|
||||
ifneq ($(USE_ENGINE:0=),)
|
||||
@ -992,7 +992,7 @@ OBJS += src/mux_h2.o src/mux_h1.o src/mux_fcgi.o src/log.o \
|
||||
src/cfgcond.o src/proto_udp.o src/lb_fwlc.o src/ebmbtree.o \
|
||||
src/proto_uxdg.o src/cfgdiag.o src/sock_unix.o src/sha1.o \
|
||||
src/lb_fas.o src/clock.o src/sock_inet.o src/ev_select.o \
|
||||
src/lb_map.o src/shctx.o src/hpack-dec.o src/net_helper.o \
|
||||
src/lb_map.o src/shctx.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-unix.o src/regex.o src/fcgi.o src/uri_auth.o \
|
||||
@ -1123,11 +1123,6 @@ install-doc:
|
||||
$(INSTALL) -m 644 doc/$$x.txt "$(DESTDIR)$(DOCDIR)" ; \
|
||||
done
|
||||
|
||||
install-admin:
|
||||
$(Q)$(INSTALL) -d "$(DESTDIR)$(SBINDIR)"
|
||||
$(Q)$(INSTALL) admin/cli/haproxy-dump-certs "$(DESTDIR)$(SBINDIR)"
|
||||
$(Q)$(INSTALL) admin/cli/haproxy-reload "$(DESTDIR)$(SBINDIR)"
|
||||
|
||||
install-bin:
|
||||
$(Q)for i in haproxy $(EXTRA); do \
|
||||
if ! [ -e "$$i" ]; then \
|
||||
@ -1138,7 +1133,7 @@ install-bin:
|
||||
$(Q)$(INSTALL) -d "$(DESTDIR)$(SBINDIR)"
|
||||
$(Q)$(INSTALL) haproxy $(EXTRA) "$(DESTDIR)$(SBINDIR)"
|
||||
|
||||
install: install-bin install-admin install-man install-doc
|
||||
install: install-bin install-man install-doc
|
||||
|
||||
uninstall:
|
||||
$(Q)rm -f "$(DESTDIR)$(MANDIR)"/man1/haproxy.1
|
||||
|
||||
@ -103,11 +103,6 @@ dump_certificate() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
# dry run will just return before trying to move the files
|
||||
if [ "${DRY_RUN}" != "0" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# move the current certificates to ".old.timestamp"
|
||||
if [ -f "${prev_crt}" ] && [ -f "${prev_key}" ]; then
|
||||
mv "${prev_crt}" "${prev_crt}.${d}"
|
||||
@ -128,7 +123,7 @@ dump_all_certificates() {
|
||||
export KEY_FILENAME
|
||||
|
||||
if read_certificate "$line"; then
|
||||
dump_certificate "$NAME" "$CRT_FILENAME" "$KEY_FILENAME"
|
||||
[ "${DRY_RUN}" = "0" ] && dump_certificate "$NAME" "$CRT_FILENAME" "$KEY_FILENAME"
|
||||
else
|
||||
echo "[WARNING] ($$) : can't dump \"$name\", crt/key filename details not found in \"show ssl cert\"" >&2
|
||||
fi
|
||||
|
||||
@ -55,7 +55,7 @@ usage() {
|
||||
echo " -S, --master-socket <path> Use the master socket at <path> (default: ${MASTER_SOCKET})"
|
||||
echo " -d, --debug Debug mode, set -x"
|
||||
echo " -t, --timeout Timeout (socat -t) (default: ${TIMEOUT})"
|
||||
echo " -s, --silent Silent mode (no output)"
|
||||
echo " -s, --silent Slient mode (no output)"
|
||||
echo " -v, --verbose Verbose output (output from haproxy on failure)"
|
||||
echo " -vv Even more verbose output (output from haproxy on success and failure)"
|
||||
echo " -h, --help This help"
|
||||
|
||||
@ -59,9 +59,9 @@ struct ring_v2 {
|
||||
struct ring_v2a {
|
||||
size_t size; // storage size
|
||||
size_t rsvd; // header length (used for file-backed maps)
|
||||
size_t tail ALIGNED(64); // storage tail
|
||||
size_t head ALIGNED(64); // storage head
|
||||
char area[0] ALIGNED(64); // storage area begins immediately here
|
||||
size_t tail __attribute__((aligned(64))); // storage tail
|
||||
size_t head __attribute__((aligned(64))); // storage head
|
||||
char area[0] __attribute__((aligned(64))); // storage area begins immediately here
|
||||
};
|
||||
|
||||
/* display the message and exit with the code */
|
||||
|
||||
@ -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.4-dev, and maintenance branches are 3.3 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.3 first, then 3.2, then 3.1, then 3.0
|
||||
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.3 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.4
|
||||
version 3.3
|
||||
|
||||
|
||||
This document is an introduction to HAProxy for all those who don't know it, as
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
------------------------
|
||||
HAProxy Management Guide
|
||||
------------------------
|
||||
version 3.4
|
||||
version 3.3
|
||||
|
||||
|
||||
This document describes how to start, stop, manage, and troubleshoot HAProxy,
|
||||
@ -2474,11 +2474,6 @@ prompt [help | n | i | p | timed]*
|
||||
advanced scripts, and the non-interactive mode (default) to basic scripts.
|
||||
Note that the non-interactive mode is not available for the master socket.
|
||||
|
||||
publish backend <backend>
|
||||
Activates content switching to a backend instance. This is the reverse
|
||||
operation of "unpublish backend" command. This command is restricted and can
|
||||
only be issued on sockets configured for levels "operator" or "admin".
|
||||
|
||||
quit
|
||||
Close the connection when in interactive mode.
|
||||
|
||||
@ -2847,13 +2842,6 @@ operator
|
||||
increased. It also drops expert and experimental mode. See also "show cli
|
||||
level".
|
||||
|
||||
unpublish backend <backend>
|
||||
Marks the backend as unqualified for future traffic selection. In effect,
|
||||
use_backend / default_backend rules which reference it are ignored and the
|
||||
next content switching rules are evaluated. Contrary to disabled backends,
|
||||
servers health checks remain active. This command is restricted and can only
|
||||
be issued on sockets configured for levels "operator" or "admin".
|
||||
|
||||
user
|
||||
Decrease the CLI level of the current CLI session to user. It can't be
|
||||
increased. It also drops expert and experimental mode. See also "show cli
|
||||
@ -3354,10 +3342,9 @@ show quic [<format>] [<filter>]
|
||||
in the format will instead show a more detailed help message.
|
||||
|
||||
The final argument is used to restrict or extend the connection list. By
|
||||
default, active frontend connections only are displayed. Use the extra
|
||||
argument "clo" to list instead closing frontend connections, "be" for backend
|
||||
connections or "all" for every categories. It's also possible to restrict to
|
||||
a single connection by specifying its hexadecimal address.
|
||||
default, connections on closing or draining state are not displayed. Use the
|
||||
extra argument "all" to include them in the output. It's also possible to
|
||||
restrict to a single connection by specifying its hexadecimal address.
|
||||
|
||||
show servers conn [<backend>]
|
||||
Dump the current and idle connections state of the servers belonging to the
|
||||
|
||||
@ -85,8 +85,7 @@ struct acme_ctx {
|
||||
struct ist finalize;
|
||||
struct ist certificate;
|
||||
struct task *task;
|
||||
struct ebmb_node node;
|
||||
char name[VAR_ARRAY];
|
||||
struct mt_list el;
|
||||
};
|
||||
|
||||
#define ACME_EV_SCHED (1ULL << 0) /* scheduling wakeup */
|
||||
|
||||
@ -4,9 +4,6 @@
|
||||
|
||||
#include <haproxy/ssl_ckch-t.h>
|
||||
|
||||
int ckch_conf_acme_init(void *value, char *buf, struct ckch_store *s, int cli, const char *filename, int linenum, char **err);
|
||||
EVP_PKEY *acme_gen_tmp_pkey();
|
||||
X509 *acme_gen_tmp_x509();
|
||||
|
||||
int ckch_conf_acme_init(void *value, char *buf, struct ckch_data *d, int cli, const char *filename, int linenum, char **err);
|
||||
|
||||
#endif
|
||||
|
||||
@ -125,8 +125,8 @@ struct activity {
|
||||
unsigned int ctr2; // general purposee debug counter
|
||||
#endif
|
||||
char __pad[0]; // unused except to check remaining room
|
||||
char __end[0] THREAD_ALIGNED();
|
||||
} THREAD_ALIGNED();
|
||||
char __end[0] __attribute__((aligned(64))); // align size to 64.
|
||||
};
|
||||
|
||||
/* 256 entries for callers * callees should be highly sufficient (~45 seen usually) */
|
||||
#define SCHED_ACT_HASH_BITS 8
|
||||
@ -146,7 +146,7 @@ struct sched_activity {
|
||||
uint64_t lkw_time; /* lock waiting time */
|
||||
uint64_t lkd_time; /* locked time */
|
||||
uint64_t mem_time; /* memory ops wait time */
|
||||
} THREAD_ALIGNED();
|
||||
};
|
||||
|
||||
#endif /* _HAPROXY_ACTIVITY_T_H */
|
||||
|
||||
|
||||
@ -340,33 +340,12 @@ static inline size_t applet_input_data(const struct appctx *appctx)
|
||||
return co_data(sc_oc(appctx_sc(appctx)));
|
||||
}
|
||||
|
||||
/* Returns the amount of HTX data in the output buffer (see applet_get_outbuf) */
|
||||
static inline size_t applet_htx_output_data(const struct appctx *appctx)
|
||||
{
|
||||
if (appctx_app_test(appctx, APPLET_FL_NEW_API))
|
||||
return htx_used_space(htxbuf(&appctx->outbuf));
|
||||
else
|
||||
return ci_data(sc_ic(appctx_sc(appctx)));
|
||||
}
|
||||
|
||||
/* Returns the amount of data in the output buffer (see applet_get_outbuf) */
|
||||
static inline size_t applet_output_data(const struct appctx *appctx)
|
||||
{
|
||||
if (appctx_app_test(appctx, APPLET_FL_HTX))
|
||||
return applet_htx_output_data(appctx);
|
||||
|
||||
if (appctx_app_test(appctx, APPLET_FL_NEW_API))
|
||||
return b_data(&appctx->outbuf);
|
||||
else
|
||||
return ci_data(sc_ic(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 output data.
|
||||
* than available ouput data.
|
||||
*
|
||||
* This function is not HTX aware.
|
||||
*/
|
||||
@ -392,7 +371,7 @@ static inline void applet_reset_input(struct appctx *appctx)
|
||||
co_skip(sc_oc(appctx_sc(appctx)), co_data(sc_oc(appctx_sc(appctx))));
|
||||
}
|
||||
|
||||
/* Returns the amount of space available at the HTX output buffer (see applet_get_outbuf).
|
||||
/* Returns the amout of space available at the HTX output buffer (see applet_get_outbuf).
|
||||
*/
|
||||
static inline size_t applet_htx_output_room(const struct appctx *appctx)
|
||||
{
|
||||
@ -402,7 +381,7 @@ static inline size_t applet_htx_output_room(const struct appctx *appctx)
|
||||
return channel_recv_max(sc_ic(appctx_sc(appctx)));
|
||||
}
|
||||
|
||||
/* Returns the amount of space available at the output buffer (see applet_get_outbuf).
|
||||
/* 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)
|
||||
{
|
||||
|
||||
@ -46,8 +46,6 @@ int alloc_bind_address(struct sockaddr_storage **ss,
|
||||
struct server *srv, struct proxy *be,
|
||||
struct stream *s);
|
||||
|
||||
int be_reuse_mode(const struct proxy *be, const struct server *srv);
|
||||
|
||||
int64_t be_calculate_conn_hash(struct server *srv, struct stream *strm,
|
||||
struct session *sess,
|
||||
struct sockaddr_storage *src,
|
||||
@ -85,20 +83,10 @@ static inline int be_usable_srv(struct proxy *be)
|
||||
return be->srv_bck;
|
||||
}
|
||||
|
||||
/* Returns true if <be> backend can be used as target to a switching rules. */
|
||||
static inline int be_is_eligible(const struct proxy *be)
|
||||
{
|
||||
/* A disabled or unpublished backend cannot be selected for traffic.
|
||||
* Note that STOPPED state is ignored as there is a risk of breaking
|
||||
* requests during soft-stop.
|
||||
*/
|
||||
return !(be->flags & (PR_FL_DISABLED|PR_FL_BE_UNPUBLISHED));
|
||||
}
|
||||
|
||||
/* set the time of last session on the backend */
|
||||
static inline void be_set_sess_last(struct proxy *be)
|
||||
{
|
||||
if (be->be_counters.shared.tg)
|
||||
if (be->be_counters.shared.tg[tgid - 1])
|
||||
HA_ATOMIC_STORE(&be->be_counters.shared.tg[tgid - 1]->last_sess, ns_to_sec(now_ns));
|
||||
}
|
||||
|
||||
@ -179,12 +167,6 @@ void set_backend_down(struct proxy *be);
|
||||
|
||||
unsigned int gen_hash(const struct proxy* px, const char* key, unsigned long len);
|
||||
|
||||
/* Returns true if connection reuse is supported by <be> backend. */
|
||||
static inline int be_supports_conn_reuse(const struct proxy *be)
|
||||
{
|
||||
return be->mode == PR_MODE_HTTP || be->mode == PR_MODE_SPOP;
|
||||
}
|
||||
|
||||
#endif /* _HAPROXY_BACKEND_H */
|
||||
|
||||
/*
|
||||
|
||||
@ -40,23 +40,6 @@
|
||||
#define DPRINTF(x...)
|
||||
#endif
|
||||
|
||||
/* Let's make DEBUG_STRESS equal to zero if not set or not valid, or to
|
||||
* 1 if set. This way it is always set and should be easy to use in "if ()"
|
||||
* statements without requiring ifdefs, while remaining compatible with
|
||||
* "#if DEBUG_STRESS > 0". We also force DEBUG_STRICT and DEBUG_STRICT_ACTION
|
||||
* when stressed.
|
||||
*/
|
||||
#if !defined(DEBUG_STRESS)
|
||||
# define DEBUG_STRESS 0
|
||||
#elif DEBUG_STRESS != 0
|
||||
# undef DEBUG_STRESS
|
||||
# define DEBUG_STRESS 1 // make sure comparison >0 always works
|
||||
# undef DEBUG_STRICT
|
||||
# define DEBUG_STRICT 2 // enable BUG_ON
|
||||
# undef DEBUG_STRICT_ACTION
|
||||
# define DEBUG_STRICT_ACTION 3 // enable crash on match
|
||||
#endif
|
||||
|
||||
#define DUMP_TRACE() do { extern void ha_backtrace_to_stderr(void); ha_backtrace_to_stderr(); } while (0)
|
||||
|
||||
/* First, let's try to handle some arch-specific crashing methods. We prefer
|
||||
@ -424,20 +407,6 @@ extern __attribute__((__weak__)) struct debug_count __stop_dbg_cnt HA_SECTION_S
|
||||
# define COUNT_IF_HOT(cond, ...) DISGUISE(cond)
|
||||
#endif
|
||||
|
||||
/* turn BUG_ON_STRESS() into a real statement when DEBUG_STRESS is set,
|
||||
* otherwise simply ignore it, at the risk of failing to notice if the
|
||||
* condition would build at all. We don't really care if BUG_ON_STRESS
|
||||
* doesn't always build, because it's meant to be used only in certain
|
||||
* scenarios, possibly requiring certain combinations of options. We
|
||||
* just want to be certain that the condition is not implemented at all
|
||||
* when not used, so as to encourage developers to put a lot of them at
|
||||
* zero cost.
|
||||
*/
|
||||
#if DEBUG_STRESS > 0
|
||||
# define BUG_ON_STRESS(cond, ...) BUG_ON(cond, __VA_ARGS__)
|
||||
#else
|
||||
# define BUG_ON_STRESS(cond, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
/* When not optimizing, clang won't remove that code, so only compile it in when optimizing */
|
||||
#if defined(__GNUC__) && defined(__OPTIMIZE__)
|
||||
@ -537,7 +506,7 @@ struct mem_stats {
|
||||
size_t size;
|
||||
struct ha_caller caller;
|
||||
const void *extra; // extra info specific to this call (e.g. pool ptr)
|
||||
} ALIGNED(sizeof(void*));
|
||||
} __attribute__((aligned(sizeof(void*))));
|
||||
|
||||
#undef calloc
|
||||
#define calloc(x,y) ({ \
|
||||
|
||||
@ -54,8 +54,6 @@ enum cond_predicate {
|
||||
CFG_PRED_OSSL_VERSION_ATLEAST, // "openssl_version_atleast"
|
||||
CFG_PRED_OSSL_VERSION_BEFORE, // "openssl_version_before"
|
||||
CFG_PRED_SSLLIB_NAME_STARTSWITH, // "ssllib_name_startswith"
|
||||
CFG_PRED_AWSLC_API_ATLEAST, // "awslc_api_atleast"
|
||||
CFG_PRED_AWSLC_API_BEFORE, // "awslc_api_before"
|
||||
CFG_PRED_ENABLED, // "enabled"
|
||||
};
|
||||
|
||||
|
||||
@ -140,7 +140,7 @@ int warnif_misplaced_tcp_req_sess(struct proxy *proxy, const char *file, int lin
|
||||
int warnif_misplaced_tcp_req_cont(struct proxy *proxy, const char *file, int line, const char *arg, const char *arg2);
|
||||
int warnif_misplaced_tcp_res_cont(struct proxy *proxy, const char *file, int line, const char *arg, const char *arg2);
|
||||
int warnif_misplaced_quic_init(struct proxy *proxy, const char *file, int line, const char *arg, const char *arg2);
|
||||
int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, char **err);
|
||||
int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line);
|
||||
int warnif_tcp_http_cond(const struct proxy *px, const struct acl_cond *cond);
|
||||
int too_many_args_idx(int maxarg, int index, char **args, char **msg, int *err_code);
|
||||
int too_many_args(int maxarg, char **args, char **msg, int *err_code);
|
||||
|
||||
@ -204,6 +204,7 @@ struct channel {
|
||||
unsigned short last_read; /* 16 lower bits of last read date (max pause=65s) */
|
||||
unsigned char xfer_large; /* number of consecutive large xfers */
|
||||
unsigned char xfer_small; /* number of consecutive small xfers */
|
||||
unsigned long long total; /* total data read */
|
||||
int analyse_exp; /* expiration date for current analysers (if set) */
|
||||
};
|
||||
|
||||
|
||||
@ -323,6 +323,7 @@ static inline void channel_init(struct channel *chn)
|
||||
chn->to_forward = 0;
|
||||
chn->last_read = now_ms;
|
||||
chn->xfer_small = chn->xfer_large = 0;
|
||||
chn->total = 0;
|
||||
chn->analysers = 0;
|
||||
chn->flags = 0;
|
||||
chn->output = 0;
|
||||
@ -376,6 +377,7 @@ static inline void channel_add_input(struct channel *chn, unsigned int len)
|
||||
c_adv(chn, fwd);
|
||||
}
|
||||
/* notify that some data was read */
|
||||
chn->total += len;
|
||||
chn->flags |= CF_READ_EVENT;
|
||||
}
|
||||
|
||||
|
||||
@ -31,23 +31,6 @@
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* DEFVAL() returns either the second argument as-is, or <def> if absent. This
|
||||
* is for use in macros arguments.
|
||||
*/
|
||||
#define DEFVAL(_def,...) _FIRST_ARG(NULL, ##__VA_ARGS__, (_def))
|
||||
|
||||
/* DEFNULL() returns either the argument as-is, or NULL if absent. This is for
|
||||
* use in macros arguments.
|
||||
*/
|
||||
#define DEFNULL(...) DEFVAL(NULL, ##__VA_ARGS__)
|
||||
|
||||
/* DEFZERO() returns either the argument as-is, or 0 if absent. This is for
|
||||
* use in macros arguments.
|
||||
*/
|
||||
#define DEFZERO(...) DEFVAL(0, ##__VA_ARGS__)
|
||||
|
||||
#define _FIRST_ARG(a, b, ...) b
|
||||
|
||||
/*
|
||||
* Gcc before 3.0 needs [0] to declare a variable-size array
|
||||
*/
|
||||
@ -432,13 +415,6 @@
|
||||
* for multi_threading, see THREAD_PAD() below. *
|
||||
\*****************************************************************************/
|
||||
|
||||
/* Cache line size for alignment purposes. This value is incorrect for some
|
||||
* Apple CPUs which have 128 bytes cache lines.
|
||||
*/
|
||||
#ifndef CACHELINE_SIZE
|
||||
#define CACHELINE_SIZE 64
|
||||
#endif
|
||||
|
||||
/* sets alignment for current field or variable */
|
||||
#ifndef ALIGNED
|
||||
#define ALIGNED(x) __attribute__((aligned(x)))
|
||||
@ -462,12 +438,12 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Sets alignment for current field or variable only when threads are enabled.
|
||||
* When no parameters are provided, we align to the cache line size.
|
||||
/* sets alignment for current field or variable only when threads are enabled.
|
||||
* Typically used to respect cache line alignment to avoid false sharing.
|
||||
*/
|
||||
#ifndef THREAD_ALIGNED
|
||||
#ifdef USE_THREAD
|
||||
#define THREAD_ALIGNED(...) ALIGNED(DEFVAL(CACHELINE_SIZE, ##__VA_ARGS__))
|
||||
#define THREAD_ALIGNED(x) __attribute__((aligned(x)))
|
||||
#else
|
||||
#define THREAD_ALIGNED(x)
|
||||
#endif
|
||||
@ -500,12 +476,13 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Add an optional alignment for next fields in a structure, only when threads
|
||||
* are enabled. When no parameters are provided, we align to the cache line size.
|
||||
/* add an optional alignment for next fields in a structure, only when threads
|
||||
* are enabled. Typically used to respect cache line alignment to avoid false
|
||||
* sharing.
|
||||
*/
|
||||
#ifndef THREAD_ALIGN
|
||||
#ifdef USE_THREAD
|
||||
#define THREAD_ALIGN(...) union { } ALIGNED(DEFVAL(CACHELINE_SIZE, ##__VA_ARGS__))
|
||||
#define THREAD_ALIGN(x) union { } ALIGNED(x)
|
||||
#else
|
||||
#define THREAD_ALIGN(x)
|
||||
#endif
|
||||
@ -530,7 +507,7 @@
|
||||
/* add mandatory padding of the specified size between fields in a structure,
|
||||
* This is used to avoid false sharing of cache lines for dynamically allocated
|
||||
* structures which cannot guarantee alignment, or to ensure that the size of
|
||||
* the struct remains consistent on architectures with different alignment
|
||||
* the struct remains consistent on architectures with different aligment
|
||||
* constraints
|
||||
*/
|
||||
#ifndef ALWAYS_PAD
|
||||
|
||||
@ -145,7 +145,7 @@ enum {
|
||||
CO_FL_WAIT_ROOM = 0x00000800, /* data sink is full */
|
||||
|
||||
CO_FL_WANT_SPLICING = 0x00001000, /* we wish to use splicing on the connection when possible */
|
||||
CO_FL_SSL_NO_CACHED_INFO = 0x00002000, /* Don't use any cached information when creating a new SSL connection */
|
||||
/* unused: 0x00002000 */
|
||||
|
||||
CO_FL_EARLY_SSL_HS = 0x00004000, /* We have early data pending, don't start SSL handshake yet */
|
||||
CO_FL_EARLY_DATA = 0x00008000, /* At least some of the data are early data */
|
||||
@ -212,13 +212,13 @@ static forceinline char *conn_show_flags(char *buf, size_t len, const char *deli
|
||||
/* flags */
|
||||
_(CO_FL_SAFE_LIST, _(CO_FL_IDLE_LIST, _(CO_FL_CTRL_READY,
|
||||
_(CO_FL_REVERSED, _(CO_FL_ACT_REVERSING, _(CO_FL_OPT_MARK, _(CO_FL_OPT_TOS,
|
||||
_(CO_FL_XPRT_READY, _(CO_FL_WANT_DRAIN, _(CO_FL_WAIT_ROOM, _(CO_FL_SSL_NO_CACHED_INFO, _(CO_FL_EARLY_SSL_HS,
|
||||
_(CO_FL_XPRT_READY, _(CO_FL_WANT_DRAIN, _(CO_FL_WAIT_ROOM, _(CO_FL_EARLY_SSL_HS,
|
||||
_(CO_FL_EARLY_DATA, _(CO_FL_SOCKS4_SEND, _(CO_FL_SOCKS4_RECV, _(CO_FL_SOCK_RD_SH,
|
||||
_(CO_FL_SOCK_WR_SH, _(CO_FL_ERROR, _(CO_FL_FDLESS, _(CO_FL_WAIT_L4_CONN,
|
||||
_(CO_FL_WAIT_L6_CONN, _(CO_FL_SEND_PROXY, _(CO_FL_ACCEPT_PROXY, _(CO_FL_ACCEPT_CIP,
|
||||
_(CO_FL_SSL_WAIT_HS, _(CO_FL_PRIVATE, _(CO_FL_RCVD_PROXY, _(CO_FL_SESS_IDLE,
|
||||
_(CO_FL_XPRT_TRACKED
|
||||
)))))))))))))))))))))))))))));
|
||||
))))))))))))))))))))))))))));
|
||||
/* epilogue */
|
||||
_(~0U);
|
||||
return buf;
|
||||
@ -476,7 +476,7 @@ struct xprt_ops {
|
||||
void (*dump_info)(struct buffer *, const struct connection *);
|
||||
/*
|
||||
* Returns the value for various capabilities.
|
||||
* Returns 0 if the capability is known, with the actual value in arg,
|
||||
* Returns 0 if the capability is known, iwth the actual value in arg,
|
||||
* or -1 otherwise
|
||||
*/
|
||||
int (*get_capability)(struct connection *connection, void *xprt_ctx, enum xprt_capabilities, void *arg);
|
||||
@ -660,7 +660,6 @@ struct connection {
|
||||
struct buffer name; /* Only used for passive reverse. Used as SNI when connection added to server idle pool. */
|
||||
} reverse;
|
||||
|
||||
uint64_t sni_hash; /* Hash of the SNI. Used to cache the TLS session and try to reuse it. set to 0 is there is no SNI */
|
||||
uint32_t term_evts_log; /* Termination events log: first 4 events reported from fd, handshake or xprt */
|
||||
uint32_t mark; /* set network mark, if CO_FL_OPT_MARK is set */
|
||||
uint8_t tos; /* set ip tos, if CO_FL_OPT_TOS is set */
|
||||
@ -671,7 +670,6 @@ struct mux_proto_list {
|
||||
enum proto_proxy_mode mode;
|
||||
enum proto_proxy_side side;
|
||||
const struct mux_ops *mux;
|
||||
const char *alpn; /* Default alpn to set by default when the mux protocol is forced (optional, in binary form) */
|
||||
struct list list;
|
||||
};
|
||||
|
||||
@ -795,7 +793,7 @@ struct idle_conns {
|
||||
struct mt_list toremove_conns;
|
||||
struct task *cleanup_task;
|
||||
__decl_thread(HA_SPINLOCK_T idle_conns_lock);
|
||||
} THREAD_ALIGNED();
|
||||
} THREAD_ALIGNED(64);
|
||||
|
||||
|
||||
/* Termination events logs:
|
||||
|
||||
@ -45,10 +45,8 @@
|
||||
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 req_in; /* number of bytes received from the client */\
|
||||
long long req_out; /* number of bytes sent to the server */\
|
||||
long long res_in; /* number of bytes received from the server */\
|
||||
long long res_out; /* number of bytes sent to the client */\
|
||||
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 */\
|
||||
@ -66,7 +64,7 @@ struct counters_shared {
|
||||
COUNTERS_SHARED;
|
||||
struct {
|
||||
COUNTERS_SHARED_TG;
|
||||
} **tg;
|
||||
} *tg[MAX_TGROUPS];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -101,7 +99,7 @@ struct fe_counters_shared_tg {
|
||||
|
||||
struct fe_counters_shared {
|
||||
COUNTERS_SHARED;
|
||||
struct fe_counters_shared_tg **tg;
|
||||
struct fe_counters_shared_tg *tg[MAX_TGROUPS];
|
||||
};
|
||||
|
||||
/* counters used by listeners and frontends */
|
||||
@ -160,7 +158,7 @@ struct be_counters_shared_tg {
|
||||
|
||||
struct be_counters_shared {
|
||||
COUNTERS_SHARED;
|
||||
struct be_counters_shared_tg **tg;
|
||||
struct be_counters_shared_tg *tg[MAX_TGROUPS];
|
||||
};
|
||||
|
||||
/* counters used by servers and backends */
|
||||
|
||||
@ -43,13 +43,11 @@ void counters_be_shared_drop(struct be_counters_shared *counters);
|
||||
*/
|
||||
#define COUNTERS_SHARED_LAST_OFFSET(scounters, type, offset) \
|
||||
({ \
|
||||
unsigned long last = 0; \
|
||||
unsigned long last = HA_ATOMIC_LOAD((type *)((char *)scounters[0] + offset));\
|
||||
unsigned long now_seconds = ns_to_sec(now_ns); \
|
||||
int it; \
|
||||
\
|
||||
if (scounters) \
|
||||
last = HA_ATOMIC_LOAD((type *)((char *)scounters[0] + offset));\
|
||||
for (it = 1; (it < global.nbtgroups && scounters); it++) { \
|
||||
for (it = 1; (it < global.nbtgroups && scounters[it]); it++) { \
|
||||
unsigned long cur = HA_ATOMIC_LOAD((type *)((char *)scounters[it] + offset));\
|
||||
if ((now_seconds - cur) < (now_seconds - last)) \
|
||||
last = cur; \
|
||||
@ -76,7 +74,7 @@ void counters_be_shared_drop(struct be_counters_shared *counters);
|
||||
uint64_t __ret = 0; \
|
||||
int it; \
|
||||
\
|
||||
for (it = 0; (it < global.nbtgroups && scounters); it++) \
|
||||
for (it = 0; (it < global.nbtgroups && scounters[it]); it++) \
|
||||
__ret += rfunc((type *)((char *)scounters[it] + offset)); \
|
||||
__ret; \
|
||||
})
|
||||
@ -96,7 +94,7 @@ void counters_be_shared_drop(struct be_counters_shared *counters);
|
||||
uint64_t __ret = 0; \
|
||||
int it; \
|
||||
\
|
||||
for (it = 0; (it < global.nbtgroups && scounters); it++) \
|
||||
for (it = 0; (it < global.nbtgroups && scounters[it]); it++) \
|
||||
__ret += rfunc(&scounters[it]->elem, arg1, arg2); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
@ -202,7 +202,7 @@ struct fdtab {
|
||||
#ifdef DEBUG_FD
|
||||
unsigned int event_count; /* number of events reported */
|
||||
#endif
|
||||
} THREAD_ALIGNED();
|
||||
} THREAD_ALIGNED(64);
|
||||
|
||||
/* polled mask, one bit per thread and per direction for each FD */
|
||||
struct polled_mask {
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
ullong _freq_ctr_total_from_values(uint period, int pend, uint tick, ullong past, ullong curr);
|
||||
ullong freq_ctr_total(const struct freq_ctr *ctr, uint period, int pend);
|
||||
ullong freq_ctr_total_estimate(const struct freq_ctr *ctr, uint period, int pend);
|
||||
uint freq_ctr_overshoot_period(const struct freq_ctr *ctr, uint period, uint freq);
|
||||
int freq_ctr_overshoot_period(const struct freq_ctr *ctr, uint period, uint freq);
|
||||
uint update_freq_ctr_period_slow(struct freq_ctr *ctr, uint period, uint inc);
|
||||
|
||||
/* Only usable during single threaded startup phase. */
|
||||
|
||||
@ -233,7 +233,6 @@ struct global {
|
||||
* than 255 arguments
|
||||
*/
|
||||
/* 2-bytes hole */
|
||||
int est_fd_usage; /* rough estimate of reserved FDs (listeners, pollers etc) */
|
||||
int cfg_curr_line; /* line number currently being parsed */
|
||||
const char *cfg_curr_file; /* config file currently being parsed or NULL */
|
||||
char *cfg_curr_section; /* config section name currently being parsed or NULL */
|
||||
@ -261,7 +260,6 @@ struct global {
|
||||
unsigned int req_count; /* request counter (HTTP or TCP session) for logs and unique_id */
|
||||
int last_checks;
|
||||
uint32_t anon_key;
|
||||
int maxthrpertgroup; /* Maximum number of threads per thread group */
|
||||
|
||||
/* leave this at the end to make sure we don't share this cache line by accident */
|
||||
ALWAYS_ALIGN(64);
|
||||
|
||||
@ -255,7 +255,6 @@ struct hlua_patref_iterator_context {
|
||||
struct hlua_patref *ref;
|
||||
struct bref bref; /* back-reference from the pat_ref_elt being accessed
|
||||
* during listing */
|
||||
struct pat_ref_gen *gen; /* the generation we are iterating over */
|
||||
};
|
||||
|
||||
#else /* USE_LUA */
|
||||
|
||||
@ -184,7 +184,6 @@ enum {
|
||||
PERSIST_TYPE_NONE = 0, /* no persistence */
|
||||
PERSIST_TYPE_FORCE, /* force-persist */
|
||||
PERSIST_TYPE_IGNORE, /* ignore-persist */
|
||||
PERSIST_TYPE_BE_SWITCH, /* force-be-switch */
|
||||
};
|
||||
|
||||
/* final results for http-request rules */
|
||||
|
||||
@ -270,7 +270,7 @@ struct htx {
|
||||
/* XXX 4 bytes unused */
|
||||
|
||||
/* Blocks representing the HTTP message itself */
|
||||
char blocks[VAR_ARRAY] ALIGNED(8);
|
||||
char blocks[VAR_ARRAY] __attribute__((aligned(8)));
|
||||
};
|
||||
|
||||
#endif /* _HAPROXY_HTX_T_H */
|
||||
|
||||
@ -186,7 +186,7 @@ struct bind_conf {
|
||||
#endif
|
||||
#ifdef USE_QUIC
|
||||
struct quic_transport_params quic_params; /* QUIC transport parameters. */
|
||||
const struct quic_cc_algo *quic_cc_algo; /* QUIC control congestion algorithm */
|
||||
struct quic_cc_algo *quic_cc_algo; /* QUIC control congestion algorithm */
|
||||
size_t max_cwnd; /* QUIC maximumu congestion control window size (kB) */
|
||||
enum quic_sock_mode quic_mode; /* QUIC socket allocation strategy */
|
||||
#endif
|
||||
@ -204,7 +204,6 @@ struct bind_conf {
|
||||
unsigned int backlog; /* if set, listen backlog */
|
||||
int maxconn; /* maximum connections allowed on this listener */
|
||||
int (*accept)(struct connection *conn); /* upper layer's accept() */
|
||||
int tcp_ss; /* for TCP, Save SYN */
|
||||
int level; /* stats access level (ACCESS_LVL_*) */
|
||||
int severity_output; /* default severity output format in cli feedback messages */
|
||||
short int nice; /* nice value to assign to the instantiated tasks */
|
||||
@ -310,7 +309,7 @@ struct bind_kw_list {
|
||||
struct accept_queue_ring {
|
||||
uint32_t idx; /* (head << 16) | tail */
|
||||
struct tasklet *tasklet; /* tasklet of the thread owning this ring */
|
||||
struct connection *entry[ACCEPT_QUEUE_SIZE] THREAD_ALIGNED();
|
||||
struct connection *entry[ACCEPT_QUEUE_SIZE] __attribute((aligned(64)));
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -231,7 +231,7 @@ const char *listener_state_str(const struct listener *l);
|
||||
struct task *accept_queue_process(struct task *t, void *context, unsigned int state);
|
||||
struct task *manage_global_listener_queue(struct task *t, void *context, unsigned int state);
|
||||
|
||||
extern struct accept_queue_ring accept_queue_rings[MAX_THREADS] THREAD_ALIGNED();
|
||||
extern struct accept_queue_ring accept_queue_rings[MAX_THREADS] __attribute__((aligned(64)));
|
||||
|
||||
extern const char* li_status_st[LI_STATE_COUNT];
|
||||
enum li_status get_li_status(struct listener *l);
|
||||
|
||||
@ -41,7 +41,6 @@ struct qcc {
|
||||
struct connection *conn;
|
||||
uint64_t nb_sc; /* number of attached stream connectors */
|
||||
uint64_t nb_hreq; /* number of in-progress http requests */
|
||||
uint64_t tot_sc; /* total number of stream connectors seen since conn init */
|
||||
uint32_t flags; /* QC_CF_* */
|
||||
enum qcc_app_st app_st; /* application layer state */
|
||||
int glitches; /* total number of glitches on this connection */
|
||||
|
||||
@ -77,8 +77,7 @@ enum ssl_encryption_level_t {
|
||||
|
||||
#if defined(OPENSSL_IS_AWSLC)
|
||||
#define OPENSSL_NO_DH
|
||||
#define SSL_CTX_set1_sigalgs_list SSL_CTX_set1_sigalgs_list
|
||||
#define SSL_set_quic_early_data_enabled SSL_set_early_data_enabled
|
||||
#define SSL_CTX_set1_sigalgs_list SSL_CTX_set1_sigalgs_list
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@ -107,34 +107,20 @@ struct pat_ref {
|
||||
struct list list; /* Used to chain refs. */
|
||||
char *reference; /* The reference name. */
|
||||
char *display; /* String displayed to identify the pattern origin. */
|
||||
struct ceb_root *gen_root; /* The tree mapping generation IDs to pattern reference elements */
|
||||
struct list head; /* The head of the list of struct pat_ref_elt. */
|
||||
struct ceb_root *ceb_root; /* The tree where pattern reference elements are attached. */
|
||||
struct list pat; /* The head of the list of struct pattern_expr. */
|
||||
unsigned int flags; /* flags PAT_REF_*. */
|
||||
unsigned int curr_gen; /* current generation number (anything below can be removed) */
|
||||
unsigned int next_gen; /* next generation number (insertions use this one) */
|
||||
/* We keep a cached pointer to the current generation for performance. */
|
||||
struct {
|
||||
struct pat_ref_gen *data;
|
||||
unsigned int id;
|
||||
} cached_gen;
|
||||
int unique_id; /* Each pattern reference have unique id. */
|
||||
unsigned long long revision; /* updated for each update */
|
||||
unsigned long long entry_cnt; /* the total number of entries */
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
__decl_thread(HA_RWLOCK_T lock); /* Lock used to protect pat ref elements */
|
||||
event_hdl_sub_list e_subs; /* event_hdl: pat_ref's subscribers list (atomically updated) */
|
||||
};
|
||||
|
||||
/* This struct represents all the elements in a pattern reference generation. The tree
|
||||
* is used most of the time, but we also maintain a list for when order matters.
|
||||
*/
|
||||
struct pat_ref_gen {
|
||||
struct list head; /* The head of the list of struct pat_ref_elt. */
|
||||
struct ceb_root *elt_root; /* The tree where pattern reference elements are attached. */
|
||||
struct ceb_node gen_node; /* Linkage for the gen_root cebtree in struct pat_ref */
|
||||
unsigned int gen_id;
|
||||
};
|
||||
|
||||
/* This is a part of struct pat_ref. Each entry contains one pattern and one
|
||||
* associated value as original string. All derivative forms (via exprs) are
|
||||
* accessed from list_head or tree_head. Be careful, it's variable-sized!
|
||||
@ -147,7 +133,7 @@ struct pat_ref_elt {
|
||||
char *sample;
|
||||
unsigned int gen_id; /* generation of pat_ref this was made for */
|
||||
int line;
|
||||
struct ceb_node node; /* Node to attach this element to its <pat_ref_gen> cebtree. */
|
||||
struct ceb_node node; /* Node to attach this element to its <pat_ref> ebtree. */
|
||||
const char pattern[0]; // const only to make sure nobody tries to free it.
|
||||
};
|
||||
|
||||
|
||||
@ -189,10 +189,8 @@ struct pat_ref *pat_ref_new(const char *reference, const char *display, unsigned
|
||||
struct pat_ref *pat_ref_newid(int unique_id, const char *display, unsigned int flags);
|
||||
struct pat_ref_elt *pat_ref_find_elt(struct pat_ref *ref, const char *key);
|
||||
struct pat_ref_elt *pat_ref_gen_find_elt(struct pat_ref *ref, unsigned int gen_id, const char *key);
|
||||
struct pat_ref_elt *pat_ref_append(struct pat_ref *ref, unsigned int gen, const char *pattern, const char *sample, int line);
|
||||
struct pat_ref_elt *pat_ref_append(struct pat_ref *ref, const char *pattern, const char *sample, int line);
|
||||
struct pat_ref_elt *pat_ref_load(struct pat_ref *ref, unsigned int gen, const char *pattern, const char *sample, int line, char **err);
|
||||
struct pat_ref_gen *pat_ref_gen_new(struct pat_ref *ref, unsigned int gen_id);
|
||||
struct pat_ref_gen *pat_ref_gen_get(struct pat_ref *ref, unsigned int gen_id);
|
||||
int pat_ref_push(struct pat_ref_elt *elt, struct pattern_expr *expr, int patflags, char **err);
|
||||
int pat_ref_add(struct pat_ref *ref, const char *pattern, const char *sample, char **err);
|
||||
int pat_ref_set(struct pat_ref *ref, const char *pattern, const char *sample, char **err);
|
||||
|
||||
@ -63,7 +63,7 @@ struct pool_cache_head {
|
||||
unsigned int tid; /* thread id, for debugging only */
|
||||
struct pool_head *pool; /* assigned pool, for debugging only */
|
||||
ulong fill_pattern; /* pattern used to fill the area on free */
|
||||
} THREAD_ALIGNED();
|
||||
} THREAD_ALIGNED(64);
|
||||
|
||||
/* This describes a pool registration, which is what was passed to
|
||||
* create_pool() and that might have been merged with an existing pool.
|
||||
@ -139,7 +139,7 @@ struct pool_head {
|
||||
struct list regs; /* registrations: alt names for this pool */
|
||||
|
||||
/* heavily read-write part */
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
|
||||
/* these entries depend on the pointer value, they're used to reduce
|
||||
* the contention on fast-changing values. The alignment here is
|
||||
@ -148,7 +148,7 @@ struct pool_head {
|
||||
* just meant to shard elements and there are no per-free_list stats.
|
||||
*/
|
||||
struct {
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
struct pool_item *free_list; /* list of free shared objects */
|
||||
unsigned int allocated; /* how many chunks have been allocated */
|
||||
unsigned int used; /* how many chunks are currently in use */
|
||||
@ -156,8 +156,8 @@ struct pool_head {
|
||||
unsigned int failed; /* failed allocations (indexed by hash of TID) */
|
||||
} buckets[CONFIG_HAP_POOL_BUCKETS];
|
||||
|
||||
struct pool_cache_head cache[MAX_THREADS] THREAD_ALIGNED(); /* pool caches */
|
||||
} THREAD_ALIGNED();
|
||||
struct pool_cache_head cache[MAX_THREADS] THREAD_ALIGNED(64); /* pool caches */
|
||||
} __attribute__((aligned(64)));
|
||||
|
||||
#endif /* _HAPROXY_POOL_T_H */
|
||||
|
||||
|
||||
@ -160,7 +160,6 @@ struct protocol {
|
||||
/* default I/O handler */
|
||||
void (*default_iocb)(int fd); /* generic I/O handler (typically accept callback) */
|
||||
int (*get_info)(struct connection *conn, long long int *info, int info_num); /* Callback to get connection level statistical counters */
|
||||
int (*get_opt)(const struct connection *conn, int level, int optname, void *buf, int size); /* getsockopt(level:optname) into buf:size */
|
||||
|
||||
uint flags; /* flags describing protocol support (PROTO_F_*) */
|
||||
uint nb_receivers; /* number of receivers (under proto_lock) */
|
||||
|
||||
@ -247,7 +247,6 @@ enum PR_SRV_STATE_FILE {
|
||||
#define PR_FL_IMPLICIT_REF 0x10 /* The default proxy is implicitly referenced by another proxy */
|
||||
#define PR_FL_PAUSED 0x20 /* The proxy was paused at run time (reversible) */
|
||||
#define PR_FL_CHECKED 0x40 /* The proxy configuration was fully checked (including postparsing checks) */
|
||||
#define PR_FL_BE_UNPUBLISHED 0x80 /* The proxy cannot be targetted by content switching rules */
|
||||
|
||||
struct stream;
|
||||
|
||||
@ -305,7 +304,7 @@ struct error_snapshot {
|
||||
struct proxy_per_tgroup {
|
||||
struct queue queue;
|
||||
struct lbprm_per_tgrp lbprm;
|
||||
} THREAD_ALIGNED();
|
||||
} THREAD_ALIGNED(64);
|
||||
|
||||
struct proxy {
|
||||
enum obj_type obj_type; /* object type == OBJ_TYPE_PROXY */
|
||||
@ -357,8 +356,7 @@ struct proxy {
|
||||
struct server *srv, *defsrv; /* known servers; default server configuration */
|
||||
struct lbprm lbprm; /* load-balancing parameters */
|
||||
int srv_act, srv_bck; /* # of servers eligible for LB (UP|!checked) AND (enabled+weight!=0) */
|
||||
int load_server_state_from_file; /* location of the file containing server state.
|
||||
* flag PR_SRV_STATE_FILE_* */
|
||||
int served; /* # of active sessions currently being served */
|
||||
int cookie_len; /* strlen(cookie_name), computed only once */
|
||||
struct server *ready_srv; /* a server being ready to serve requests */
|
||||
char *cookie_domain; /* domain used to insert the cookie */
|
||||
@ -403,6 +401,9 @@ struct proxy {
|
||||
char *id; /* proxy id (name), indexed by <conf.name_node> below */
|
||||
char *desc; /* proxy description */
|
||||
struct proxy_per_tgroup *per_tgrp; /* array of per-tgroup stuff such as queues */
|
||||
unsigned int queueslength; /* Sum of the length of each queue */
|
||||
int totpend; /* total number of pending connections on this instance (for stats) */
|
||||
unsigned int feconn, beconn; /* # of active frontend and backends streams */
|
||||
unsigned int fe_sps_lim; /* limit on new sessions per second on the frontend */
|
||||
unsigned int fullconn; /* #conns on backend above which servers are used at full load */
|
||||
struct ist server_id_hdr_name; /* the header to use to send the server id (name) */
|
||||
@ -494,6 +495,8 @@ struct proxy {
|
||||
struct email_alertq *queues; /* per-mailer alerts queues */
|
||||
} email_alert;
|
||||
|
||||
int load_server_state_from_file; /* location of the file containing server state.
|
||||
* flag PR_SRV_STATE_FILE_* */
|
||||
char *server_state_file_name; /* used when load_server_state_from_file is set to
|
||||
* PR_SRV_STATE_FILE_LOCAL. Give a specific file name for
|
||||
* this backend. If not specified or void, then the backend
|
||||
@ -505,12 +508,6 @@ struct proxy {
|
||||
|
||||
EXTRA_COUNTERS(extra_counters_fe);
|
||||
EXTRA_COUNTERS(extra_counters_be);
|
||||
|
||||
THREAD_ALIGN();
|
||||
unsigned int queueslength; /* Sum of the length of each queue */
|
||||
int served; /* # of active sessions currently being served */
|
||||
int totpend; /* total number of pending connections on this instance (for stats) */
|
||||
unsigned int feconn, beconn; /* # of active frontend and backends streams */
|
||||
};
|
||||
|
||||
struct switching_rule {
|
||||
|
||||
@ -166,12 +166,12 @@ static inline int proxy_abrt_close(const struct proxy *px)
|
||||
/* 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)
|
||||
{
|
||||
if (fe->fe_counters.shared.tg) {
|
||||
if (fe->fe_counters.shared.tg[tgid - 1])
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.shared.tg[tgid - 1]->cum_conn);
|
||||
update_freq_ctr(&fe->fe_counters.shared.tg[tgid - 1]->conn_per_sec, 1);
|
||||
}
|
||||
if (l && l->counters && l->counters->shared.tg)
|
||||
if (l && l->counters && l->counters->shared.tg[tgid - 1])
|
||||
_HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->cum_conn);
|
||||
if (fe->fe_counters.shared.tg[tgid - 1])
|
||||
update_freq_ctr(&fe->fe_counters.shared.tg[tgid - 1]->conn_per_sec, 1);
|
||||
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.cps_max,
|
||||
update_freq_ctr(&fe->fe_counters._conn_per_sec, 1));
|
||||
}
|
||||
@ -179,12 +179,12 @@ static inline void proxy_inc_fe_conn_ctr(struct listener *l, struct proxy *fe)
|
||||
/* 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)
|
||||
{
|
||||
if (fe->fe_counters.shared.tg) {
|
||||
if (fe->fe_counters.shared.tg[tgid - 1])
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.shared.tg[tgid - 1]->cum_sess);
|
||||
update_freq_ctr(&fe->fe_counters.shared.tg[tgid - 1]->sess_per_sec, 1);
|
||||
}
|
||||
if (l && l->counters && l->counters->shared.tg)
|
||||
if (l && l->counters && l->counters->shared.tg[tgid - 1])
|
||||
_HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->cum_sess);
|
||||
if (fe->fe_counters.shared.tg[tgid - 1])
|
||||
update_freq_ctr(&fe->fe_counters.shared.tg[tgid - 1]->sess_per_sec, 1);
|
||||
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.sps_max,
|
||||
update_freq_ctr(&fe->fe_counters._sess_per_sec, 1));
|
||||
}
|
||||
@ -199,19 +199,19 @@ static inline void proxy_inc_fe_cum_sess_ver_ctr(struct listener *l, struct prox
|
||||
http_ver > sizeof(fe->fe_counters.shared.tg[tgid - 1]->cum_sess_ver) / sizeof(*fe->fe_counters.shared.tg[tgid - 1]->cum_sess_ver))
|
||||
return;
|
||||
|
||||
if (fe->fe_counters.shared.tg)
|
||||
if (fe->fe_counters.shared.tg[tgid - 1])
|
||||
_HA_ATOMIC_INC(&fe->fe_counters.shared.tg[tgid - 1]->cum_sess_ver[http_ver - 1]);
|
||||
if (l && l->counters && l->counters->shared.tg && l->counters->shared.tg[tgid - 1])
|
||||
if (l && l->counters && l->counters->shared.tg[tgid - 1])
|
||||
_HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->cum_sess_ver[http_ver - 1]);
|
||||
}
|
||||
|
||||
/* increase the number of cumulated streams on the designated backend */
|
||||
static inline void proxy_inc_be_ctr(struct proxy *be)
|
||||
{
|
||||
if (be->be_counters.shared.tg) {
|
||||
if (be->be_counters.shared.tg[tgid - 1])
|
||||
_HA_ATOMIC_INC(&be->be_counters.shared.tg[tgid - 1]->cum_sess);
|
||||
if (be->be_counters.shared.tg[tgid - 1])
|
||||
update_freq_ctr(&be->be_counters.shared.tg[tgid - 1]->sess_per_sec, 1);
|
||||
}
|
||||
HA_ATOMIC_UPDATE_MAX(&be->be_counters.sps_max,
|
||||
update_freq_ctr(&be->be_counters._sess_per_sec, 1));
|
||||
}
|
||||
@ -226,12 +226,12 @@ static inline void proxy_inc_fe_req_ctr(struct listener *l, struct proxy *fe,
|
||||
if (http_ver >= sizeof(fe->fe_counters.shared.tg[tgid - 1]->p.http.cum_req) / sizeof(*fe->fe_counters.shared.tg[tgid - 1]->p.http.cum_req))
|
||||
return;
|
||||
|
||||
if (fe->fe_counters.shared.tg) {
|
||||
if (fe->fe_counters.shared.tg[tgid - 1])
|
||||
_HA_ATOMIC_INC(&fe->fe_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);
|
||||
}
|
||||
if (l && l->counters && l->counters->shared.tg)
|
||||
if (l && l->counters && l->counters->shared.tg[tgid - 1])
|
||||
_HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->p.http.cum_req[http_ver]);
|
||||
if (fe->fe_counters.shared.tg[tgid - 1])
|
||||
update_freq_ctr(&fe->fe_counters.shared.tg[tgid - 1]->req_per_sec, 1);
|
||||
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.p.http.rps_max,
|
||||
update_freq_ctr(&fe->fe_counters.p.http._req_per_sec, 1));
|
||||
}
|
||||
|
||||
@ -35,13 +35,13 @@
|
||||
|
||||
#define QUIC_CC_INFINITE_SSTHESH ((uint32_t)-1)
|
||||
|
||||
extern const struct quic_cc_algo quic_cc_algo_nr;
|
||||
extern const struct quic_cc_algo quic_cc_algo_cubic;
|
||||
extern const struct quic_cc_algo quic_cc_algo_bbr;
|
||||
extern const struct quic_cc_algo *default_quic_cc_algo;
|
||||
extern struct quic_cc_algo quic_cc_algo_nr;
|
||||
extern struct quic_cc_algo quic_cc_algo_cubic;
|
||||
extern struct quic_cc_algo quic_cc_algo_bbr;
|
||||
extern struct quic_cc_algo *default_quic_cc_algo;
|
||||
|
||||
/* Fake algorithm with its fixed window */
|
||||
extern const struct quic_cc_algo quic_cc_algo_nocc;
|
||||
extern struct quic_cc_algo quic_cc_algo_nocc;
|
||||
|
||||
extern unsigned long long last_ts;
|
||||
|
||||
@ -90,7 +90,7 @@ enum quic_cc_algo_type {
|
||||
struct quic_cc {
|
||||
/* <conn> is there only for debugging purpose. */
|
||||
struct quic_conn *qc;
|
||||
const struct quic_cc_algo *algo;
|
||||
struct quic_cc_algo *algo;
|
||||
uint32_t priv[144];
|
||||
};
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
#include <haproxy/quic_loss.h>
|
||||
#include <haproxy/thread.h>
|
||||
|
||||
void quic_cc_init(struct quic_cc *cc, const struct quic_cc_algo *algo, struct quic_conn *qc);
|
||||
void quic_cc_init(struct quic_cc *cc, struct quic_cc_algo *algo, struct quic_conn *qc);
|
||||
void quic_cc_event(struct quic_cc *cc, struct quic_cc_event *ev);
|
||||
void quic_cc_state_trace(struct buffer *buf, const struct quic_cc *cc);
|
||||
|
||||
@ -83,7 +83,7 @@ static inline void *quic_cc_priv(const struct quic_cc *cc)
|
||||
* which is true for an IPv4 path, if not false for an IPv6 path.
|
||||
*/
|
||||
static inline void quic_cc_path_init(struct quic_cc_path *path, int ipv4, unsigned long max_cwnd,
|
||||
const struct quic_cc_algo *algo,
|
||||
struct quic_cc_algo *algo,
|
||||
struct quic_conn *qc)
|
||||
{
|
||||
unsigned int max_dgram_sz;
|
||||
|
||||
@ -24,12 +24,6 @@ struct quic_cid {
|
||||
unsigned char len; /* size of QUIC CID */
|
||||
};
|
||||
|
||||
/* Determines whether a CID is used for frontend or backend connections. */
|
||||
enum quic_cid_side {
|
||||
QUIC_CID_SIDE_FE,
|
||||
QUIC_CID_SIDE_BE
|
||||
};
|
||||
|
||||
/* QUIC connection id attached to a QUIC connection.
|
||||
*
|
||||
* This structure is used to match received packets DCIDs with the
|
||||
@ -40,12 +34,11 @@ struct quic_connection_id {
|
||||
uint64_t retire_prior_to;
|
||||
unsigned char stateless_reset_token[QUIC_STATELESS_RESET_TOKEN_LEN];
|
||||
|
||||
struct ebmb_node node; /* node for receiver tree, cid.data as key */
|
||||
struct quic_cid cid; /* CID data */
|
||||
struct ebmb_node node; /* node for receiver tree, cid.data as key */
|
||||
struct quic_cid cid; /* CID data */
|
||||
|
||||
struct quic_conn *qc; /* QUIC connection using this CID */
|
||||
uint tid; /* Attached Thread ID for the connection. */
|
||||
enum quic_cid_side side; /* side where this CID is used */
|
||||
struct quic_conn *qc; /* QUIC connection using this CID */
|
||||
uint tid; /* Attached Thread ID for the connection. */
|
||||
};
|
||||
|
||||
#endif /* _HAPROXY_QUIC_CID_T_H */
|
||||
|
||||
@ -15,19 +15,12 @@
|
||||
#include <haproxy/quic_rx-t.h>
|
||||
#include <haproxy/proto_quic.h>
|
||||
|
||||
extern struct quic_cid_tree *quic_fe_cid_trees;
|
||||
extern struct quic_cid_tree *quic_be_cid_trees;
|
||||
extern struct quic_cid_tree *quic_cid_trees;
|
||||
|
||||
struct quic_connection_id *quic_cid_alloc(enum quic_cid_side side);
|
||||
|
||||
int quic_cid_generate_random(struct quic_connection_id *conn_id);
|
||||
int quic_cid_generate_from_hash(struct quic_connection_id *conn_id, uint64_t hash64);
|
||||
int quic_cid_derive_from_odcid(struct quic_connection_id *conn_id,
|
||||
const struct quic_cid *orig,
|
||||
const struct sockaddr_storage *addr);
|
||||
|
||||
void quic_cid_register_seq_num(struct quic_connection_id *conn_id,
|
||||
struct quic_conn *qc);
|
||||
struct quic_connection_id *new_quic_cid(struct eb_root *root,
|
||||
struct quic_conn *qc,
|
||||
const struct quic_cid *orig,
|
||||
const struct sockaddr_storage *addr);
|
||||
|
||||
int quic_cid_insert(struct quic_connection_id *conn_id, int *new_tid);
|
||||
int quic_cmp_cid_conn(const unsigned char *cid, size_t cid_len,
|
||||
@ -82,18 +75,25 @@ static inline uchar quic_cid_tree_idx(const struct quic_cid *cid)
|
||||
return _quic_cid_tree_idx(cid->data);
|
||||
}
|
||||
|
||||
/* Returns the tree instance responsible for <conn_id> storage. */
|
||||
static inline struct quic_cid_tree *quic_cid_get_tree(const struct quic_connection_id *conn_id)
|
||||
/* Insert <conn_id> into global CID tree. Do not check if value is already
|
||||
* present in the tree. As such, it should not be used for the first DCID of a
|
||||
* connection instance.
|
||||
*/
|
||||
static inline void _quic_cid_insert(struct quic_connection_id *conn_id)
|
||||
{
|
||||
const int tree_idx = quic_cid_tree_idx(&conn_id->cid);
|
||||
return conn_id->side == QUIC_CID_SIDE_FE ?
|
||||
&quic_fe_cid_trees[tree_idx] : &quic_be_cid_trees[tree_idx];
|
||||
const uchar idx = quic_cid_tree_idx(&conn_id->cid);
|
||||
struct quic_cid_tree *tree = &quic_cid_trees[idx];
|
||||
|
||||
HA_RWLOCK_WRLOCK(QC_CID_LOCK, &tree->lock);
|
||||
ebmb_insert(&tree->root, &conn_id->node, conn_id->cid.len);
|
||||
HA_RWLOCK_WRUNLOCK(QC_CID_LOCK, &tree->lock);
|
||||
}
|
||||
|
||||
/* Remove <conn_id> from global CID tree as a thread-safe operation. */
|
||||
static inline void quic_cid_delete(struct quic_connection_id *conn_id)
|
||||
{
|
||||
struct quic_cid_tree __maybe_unused *tree = quic_cid_get_tree(conn_id);
|
||||
const uchar idx = quic_cid_tree_idx(&conn_id->cid);
|
||||
struct quic_cid_tree __maybe_unused *tree = &quic_cid_trees[idx];
|
||||
|
||||
HA_RWLOCK_WRLOCK(QC_CID_LOCK, &tree->lock);
|
||||
ebmb_delete(&conn_id->node);
|
||||
|
||||
@ -243,6 +243,17 @@ extern const struct quic_version *quic_version_2;
|
||||
/* The maximum number of bytes of CRYPTO data in flight during handshakes. */
|
||||
#define QUIC_CRYPTO_IN_FLIGHT_MAX 4096
|
||||
|
||||
/* Status of the MUX layer. This defines how to handle app data.
|
||||
*
|
||||
* During a standard quic_conn lifetime it transitions like this :
|
||||
* QC_MUX_NULL -> QC_MUX_READY -> QC_MUX_RELEASED
|
||||
*/
|
||||
enum qc_mux_state {
|
||||
QC_MUX_NULL, /* not allocated, data should be buffered */
|
||||
QC_MUX_READY, /* allocated, ready to handle data */
|
||||
QC_MUX_RELEASED, /* released, data can be dropped */
|
||||
};
|
||||
|
||||
/* Counters at QUIC connection level */
|
||||
struct quic_conn_cntrs {
|
||||
long long dropped_pkt; /* total number of dropped packets */
|
||||
@ -292,13 +303,9 @@ struct qcc_app_ops;
|
||||
size_t max_udp_payload; \
|
||||
/* First DCID used by client on its Initial packet. */ \
|
||||
struct quic_cid odcid; \
|
||||
/* Peer chosen CID, used as dest for packets sent from our endpoint \
|
||||
* - not updated when a new DCID is used \
|
||||
*/ \
|
||||
/* DCID of our endpoint - not updated when a new DCID is used */ \
|
||||
struct quic_cid dcid; \
|
||||
/* Local CID used to dispatch received datagrams to this endpoint \
|
||||
* - not updated when a new SCID is used \
|
||||
*/ \
|
||||
/* first SCID of our endpoint - not updated when a new SCID is used */ \
|
||||
struct quic_cid scid; \
|
||||
/* tree of quic_connection_id - used to match a received packet DCID \
|
||||
* with a connection \
|
||||
@ -326,6 +333,7 @@ struct quic_conn {
|
||||
/* QUIC transport parameters TLS extension */
|
||||
int tps_tls_ext;
|
||||
int state;
|
||||
enum qc_mux_state mux_state; /* status of the connection/mux layer */
|
||||
#ifdef HAVE_OPENSSL_QUIC
|
||||
uint32_t prot_level;
|
||||
#endif
|
||||
@ -434,7 +442,7 @@ struct quic_conn_closed {
|
||||
#define QUIC_FL_CONN_NEED_POST_HANDSHAKE_FRMS (1U << 2) /* HANDSHAKE_DONE must be sent */
|
||||
#define QUIC_FL_CONN_IS_BACK (1U << 3) /* conn used on backend side */
|
||||
#define QUIC_FL_CONN_ACCEPT_REGISTERED (1U << 4)
|
||||
#define QUIC_FL_CONN_UDP_GSO_EIO (1U << 5) /* GSO disabled due to a EIO occurred on same listener */
|
||||
#define QUIC_FL_CONN_UDP_GSO_EIO (1U << 5) /* GSO disabled due to a EIO occured on same listener */
|
||||
#define QUIC_FL_CONN_IDLE_TIMER_RESTARTED_AFTER_READ (1U << 6)
|
||||
#define QUIC_FL_CONN_RETRANS_NEEDED (1U << 7)
|
||||
#define QUIC_FL_CONN_RETRANS_OLD_DATA (1U << 8) /* retransmission in progress for probing with already sent data */
|
||||
@ -449,7 +457,6 @@ struct quic_conn_closed {
|
||||
#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. */
|
||||
#define QUIC_FL_CONN_XPRT_CLOSED (1U << 20) /* close callback of xprt layer already called */
|
||||
/* 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) */
|
||||
@ -490,14 +497,13 @@ static forceinline char *qc_show_flags(char *buf, size_t len, const char *delim,
|
||||
_(QUIC_FL_CONN_PEER_VALIDATED_ADDR,
|
||||
_(QUIC_FL_CONN_NO_TOKEN_RCVD,
|
||||
_(QUIC_FL_CONN_SCID_RECEIVED,
|
||||
_(QUIC_FL_CONN_XPRT_CLOSED,
|
||||
_(QUIC_FL_CONN_TO_KILL,
|
||||
_(QUIC_FL_CONN_TX_TP_RECEIVED,
|
||||
_(QUIC_FL_CONN_FINALIZED,
|
||||
_(QUIC_FL_CONN_EXP_TIMER,
|
||||
_(QUIC_FL_CONN_CLOSING,
|
||||
_(QUIC_FL_CONN_DRAINING,
|
||||
_(QUIC_FL_CONN_IMMEDIATE_CLOSE))))))))))))))))))))))))))));
|
||||
_(QUIC_FL_CONN_IMMEDIATE_CLOSE)))))))))))))))))))))))))));
|
||||
/* epilogue */
|
||||
_(~0U);
|
||||
return buf;
|
||||
|
||||
@ -64,15 +64,15 @@ struct task *quic_conn_app_io_cb(struct task *t, void *context, unsigned int sta
|
||||
|
||||
void quic_conn_closed_err_count_inc(struct quic_conn *qc, struct quic_frame *frm);
|
||||
int qc_h3_request_reject(struct quic_conn *qc, uint64_t id);
|
||||
struct quic_conn *qc_new_conn(void *target,
|
||||
const struct quic_rx_packet *initial_pkt,
|
||||
struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
struct quic_cid *dcid, struct quic_cid *scid,
|
||||
const struct quic_cid *token_odcid,
|
||||
struct connection *connection,
|
||||
struct quic_connection_id *conn_id,
|
||||
struct sockaddr_storage *local_addr,
|
||||
struct sockaddr_storage *peer_addr);
|
||||
int quic_build_post_handshake_frames(struct quic_conn *qc,
|
||||
struct list *to_frms_list);
|
||||
struct sockaddr_storage *peer_addr,
|
||||
int token, void *owner,
|
||||
struct connection *conn);
|
||||
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);
|
||||
void qc_set_timer(struct quic_conn *qc);
|
||||
@ -82,9 +82,6 @@ void qc_idle_timer_rearm(struct quic_conn *qc, int read, int arm_ack);
|
||||
void qc_check_close_on_released_mux(struct quic_conn *qc);
|
||||
int quic_stateless_reset_token_cpy(unsigned char *pos, size_t len,
|
||||
const unsigned char *salt, size_t saltlen);
|
||||
int quic_reuse_srv_params(struct quic_conn *qc,
|
||||
const unsigned char *alpn,
|
||||
const struct quic_early_transport_params *etps);
|
||||
|
||||
/* Returns true if <qc> is used on the backed side (as a client). */
|
||||
static inline int qc_is_back(const struct quic_conn *qc)
|
||||
@ -92,12 +89,6 @@ static inline int qc_is_back(const struct quic_conn *qc)
|
||||
return qc->flags & QUIC_FL_CONN_IS_BACK;
|
||||
}
|
||||
|
||||
static inline enum quic_cid_side qc_cid_side(const struct quic_conn *qc)
|
||||
{
|
||||
return !(qc->flags & QUIC_FL_CONN_IS_BACK) ?
|
||||
QUIC_CID_SIDE_FE : QUIC_CID_SIDE_BE;
|
||||
}
|
||||
|
||||
/* Free the CIDs attached to <conn> QUIC connection. */
|
||||
static inline void free_quic_conn_cids(struct quic_conn *conn)
|
||||
{
|
||||
@ -228,9 +219,5 @@ extern uint64_t (*quic_hash64_from_cid)(const unsigned char *cid, int size, cons
|
||||
/* Function pointer that can be used to derive a new CID from the previously computed hash */
|
||||
extern void (*quic_newcid_from_hash64)(unsigned char *cid, int size, uint64_t hash, const unsigned char *secret, size_t secretlen);
|
||||
|
||||
/* QUIC xprt layer functions */
|
||||
int qc_wait_for_conn(const struct quic_conn *qc);
|
||||
int qc_is_conn_ready(const struct quic_conn *qc);
|
||||
|
||||
#endif /* USE_QUIC */
|
||||
#endif /* _HAPROXY_QUIC_CONN_H */
|
||||
|
||||
@ -161,10 +161,7 @@ struct qf_crypto {
|
||||
|
||||
struct qf_new_token {
|
||||
uint64_t len;
|
||||
/* Used only to send data */
|
||||
unsigned char w_data[QUIC_TOKEN_LEN];
|
||||
/* Used only to receive data */
|
||||
const unsigned char *r_data;
|
||||
unsigned char data[QUIC_TOKEN_LEN];
|
||||
};
|
||||
|
||||
struct qf_stream {
|
||||
|
||||
@ -49,7 +49,6 @@ int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t count,
|
||||
int flags, uint16_t gso_size);
|
||||
int qc_rcv_buf(struct quic_conn *qc);
|
||||
void quic_conn_sock_fd_iocb(int fd);
|
||||
void quic_conn_closed_sock_fd_iocb(int fd);
|
||||
|
||||
void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src,
|
||||
const struct sockaddr_storage *dst);
|
||||
|
||||
@ -17,7 +17,5 @@
|
||||
#include <haproxy/pool-t.h>
|
||||
|
||||
extern struct pool_head *pool_head_quic_ssl_sock_ctx;
|
||||
extern const char *default_quic_ciphersuites;
|
||||
extern const char *default_quic_curves;
|
||||
|
||||
#endif /* _HAPROXY_QUIC_SSL_T_H */
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
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, void *target);
|
||||
int qc_alloc_ssl_sock_ctx(struct quic_conn *qc, struct connection *conn);
|
||||
int qc_ssl_provide_all_quic_data(struct quic_conn *qc, struct ssl_sock_ctx *ctx);
|
||||
int qc_ssl_do_hanshake(struct quic_conn *qc, struct ssl_sock_ctx *ctx);
|
||||
|
||||
@ -81,12 +81,7 @@ static inline const char *quic_ssl_early_data_status_str(const SSL *ssl)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else /* !HAVE_SSL_0RTT_QUIC */
|
||||
static inline int qc_ssl_eary_data_accepted(const SSL *ssl)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
static inline const char *quic_ssl_early_data_status_str(const SSL *ssl)
|
||||
{
|
||||
return "NOT_SUPPORTED";
|
||||
|
||||
@ -112,18 +112,6 @@ struct quic_transport_params {
|
||||
struct tp_version_information version_information;
|
||||
};
|
||||
|
||||
/* Transport parameters to be saved for 0-RTT sessions. */
|
||||
struct quic_early_transport_params {
|
||||
uint64_t max_udp_payload_size;
|
||||
uint64_t active_connection_id_limit;
|
||||
uint64_t initial_max_data;
|
||||
uint64_t initial_max_stream_data_bidi_local;
|
||||
uint64_t initial_max_stream_data_bidi_remote;
|
||||
uint64_t initial_max_stream_data_uni;
|
||||
uint64_t initial_max_streams_bidi;
|
||||
uint64_t initial_max_streams_uni;
|
||||
};
|
||||
|
||||
/* Return type for QUIC TP decode function */
|
||||
enum quic_tp_dec_err {
|
||||
QUIC_TP_DEC_ERR_NONE = 0, /* no error */
|
||||
|
||||
@ -18,13 +18,7 @@ int quic_transport_params_encode(unsigned char *buf,
|
||||
|
||||
int quic_transport_params_store(struct quic_conn *conn, int server,
|
||||
const unsigned char *buf,
|
||||
const unsigned char *end, int edata_accepted);
|
||||
void qc_early_transport_params_cpy(struct quic_conn *qc,
|
||||
struct quic_early_transport_params *e,
|
||||
struct quic_transport_params *p);
|
||||
void qc_early_transport_params_reuse(struct quic_conn *qc,
|
||||
struct quic_transport_params *p,
|
||||
const struct quic_early_transport_params *e);
|
||||
const unsigned char *end);
|
||||
|
||||
int qc_lstnr_params_init(struct quic_conn *qc,
|
||||
const struct quic_transport_params *listener_params,
|
||||
@ -129,23 +123,5 @@ static inline void quic_transport_params_dump(struct buffer *b,
|
||||
quic_tp_version_info_dump(b, &p->version_information, local);
|
||||
}
|
||||
|
||||
static inline void quic_early_transport_params_dump(struct buffer *b,
|
||||
const struct quic_conn *qc,
|
||||
const struct quic_early_transport_params *p)
|
||||
{
|
||||
chunk_appendf(b, " mudp_payload_sz=%llu", (ull)p->max_udp_payload_size);
|
||||
chunk_appendf(b, " act_cid_limit=%llu\n", (ull)p->active_connection_id_limit);
|
||||
|
||||
chunk_appendf(b, " md=%llu", (ull)p->initial_max_data);
|
||||
chunk_appendf(b, " msd_bidi_l=%llu",
|
||||
(ull)p->initial_max_stream_data_bidi_local);
|
||||
chunk_appendf(b, " msd_bidi_r=%llu",
|
||||
(ull)p->initial_max_stream_data_bidi_remote);
|
||||
chunk_appendf(b, " msd_uni=%llu",
|
||||
(ull)p->initial_max_stream_data_uni);
|
||||
chunk_appendf(b, " ms_bidi=%llu", (ull)p->initial_max_streams_bidi);
|
||||
chunk_appendf(b, " ms_uni=%llu\n", (ull)p->initial_max_streams_uni);
|
||||
}
|
||||
|
||||
#endif /* USE_QUIC */
|
||||
#endif /* _HAPROXY_QUIC_TP_H */
|
||||
|
||||
@ -100,6 +100,5 @@ struct quic_rx_crypto_frm {
|
||||
#define QUIC_EV_CONN_SSL_COMPAT (1ULL << 51)
|
||||
#define QUIC_EV_CONN_BIND_TID (1ULL << 52)
|
||||
#define QUIC_EV_CONN_RELEASE_RCD (1ULL << 53)
|
||||
#define QUIC_EV_EARLY_TRANSP_PARAMS (1ULL << 54)
|
||||
|
||||
#endif /* _HAPROXY_QUIC_TRACE_T_H */
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
#include <haproxy/api-t.h>
|
||||
|
||||
/* Counter which can be used to measure data amount across several buffers. */
|
||||
/* Counter which can be used to measure data amount accross several buffers. */
|
||||
struct bdata_ctr {
|
||||
uint64_t tot; /* sum of data present in all underlying buffers */
|
||||
uint8_t bcnt; /* current number of allocated underlying buffers */
|
||||
|
||||
@ -33,12 +33,11 @@
|
||||
|
||||
/* Bit values for receiver->flags */
|
||||
#define RX_F_BOUND 0x00000001 /* receiver already bound */
|
||||
#define RX_F_INHERITED_FD 0x00000002 /* inherited FD from the parent process (fd@) */
|
||||
#define RX_F_INHERITED 0x00000002 /* inherited FD from the parent process (fd@) or duped from another local receiver */
|
||||
#define RX_F_MWORKER 0x00000004 /* keep the FD open in the master but close it in the children */
|
||||
#define RX_F_MUST_DUP 0x00000008 /* this receiver's fd must be dup() from a reference; ignore socket-level ops here */
|
||||
#define RX_F_NON_SUSPENDABLE 0x00000010 /* this socket cannot be suspended hence must always be unbound */
|
||||
#define RX_F_PASS_PKTINFO 0x00000020 /* pass pktinfo in received messages */
|
||||
#define RX_F_INHERITED_SOCK 0x00000040 /* inherited sock that could be duped from another local receiver */
|
||||
|
||||
/* Bit values for rx_settings->options */
|
||||
#define RX_O_FOREIGN 0x00000001 /* receives on foreign addresses */
|
||||
@ -64,8 +63,9 @@ struct rx_settings {
|
||||
struct shard_info {
|
||||
uint nbgroups; /* number of groups in this shard (=#rx); Zero = unused. */
|
||||
uint nbthreads; /* number of threads in this shard (>=nbgroups) */
|
||||
ulong tgroup_mask; /* bitmask of thread groups having a member here */
|
||||
struct receiver *ref; /* first one, reference for FDs to duplicate */
|
||||
struct receiver **members; /* all members of the shard (one per thread group) */
|
||||
struct receiver *members[MAX_TGROUPS]; /* all members of the shard (one per thread group) */
|
||||
};
|
||||
|
||||
/* This describes a receiver with all its characteristics (address, options, etc) */
|
||||
|
||||
@ -130,11 +130,11 @@ struct ring_wait_cell {
|
||||
struct ring_storage {
|
||||
size_t size; // storage size
|
||||
size_t rsvd; // header length (used for file-backed maps)
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
size_t tail; // storage tail
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
size_t head; // storage head
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
char area[0]; // storage area begins immediately here
|
||||
};
|
||||
|
||||
@ -149,7 +149,7 @@ struct ring {
|
||||
|
||||
/* keep the queue in a separate cache line below */
|
||||
struct {
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
struct ring_wait_cell *ptr;
|
||||
} queue[RING_WAIT_QUEUES + 1]; // wait queue + 1 spacer
|
||||
};
|
||||
|
||||
@ -63,7 +63,6 @@ int smp_expr_output_type(struct sample_expr *expr);
|
||||
int c_none(struct sample *smp);
|
||||
int c_pseudo(struct sample *smp);
|
||||
int smp_dup(struct sample *smp);
|
||||
int sample_check_arg_base64(struct arg *arg, char **err);
|
||||
|
||||
/*
|
||||
* This function just apply a cast on sample. It returns 0 if the cast is not
|
||||
|
||||
@ -276,9 +276,6 @@ struct srv_per_thread {
|
||||
struct ceb_root *idle_conns; /* Shareable idle connections */
|
||||
struct ceb_root *safe_conns; /* Safe idle connections */
|
||||
struct ceb_root *avail_conns; /* Connections in use, but with still new streams available */
|
||||
#ifdef USE_QUIC
|
||||
struct ist quic_retry_token;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Each server will have one occurrence of this structure per thread group */
|
||||
@ -294,7 +291,7 @@ struct srv_per_tgroup {
|
||||
struct eb_root *lb_tree; /* For LB algos with split between thread groups, the tree to be used, for each group */
|
||||
unsigned npos, lpos; /* next and last positions in the LB tree, protected by LB lock */
|
||||
unsigned rweight; /* remainder of weight in the current LB tree */
|
||||
} THREAD_ALIGNED();
|
||||
} THREAD_ALIGNED(64);
|
||||
|
||||
/* Configure the protocol selection for websocket */
|
||||
enum __attribute__((__packed__)) srv_ws_mode {
|
||||
@ -323,11 +320,7 @@ enum renegotiate_mode {
|
||||
#define MAX_ALPN_SIZE 16
|
||||
|
||||
struct path_parameters {
|
||||
__decl_thread(HA_RWLOCK_T param_lock);
|
||||
char nego_alpn[MAX_ALPN_SIZE];
|
||||
#ifdef USE_QUIC
|
||||
struct quic_early_transport_params tps;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct proxy;
|
||||
@ -396,7 +389,7 @@ struct server {
|
||||
/* The elements below may be changed on every single request by any
|
||||
* thread, and generally at the same time.
|
||||
*/
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
struct eb32_node idle_node; /* When to next do cleanup in the idle connections */
|
||||
unsigned int curr_idle_conns; /* Current number of orphan idling connections, both the idle and the safe lists */
|
||||
unsigned int curr_idle_nb; /* Current number of connections in the idle list */
|
||||
@ -414,7 +407,7 @@ struct server {
|
||||
/* Element below are usd by LB algorithms and must be doable in
|
||||
* parallel to other threads reusing connections above.
|
||||
*/
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
__decl_thread(HA_SPINLOCK_T lock); /* may enclose the proxy's lock, must not be taken under */
|
||||
union {
|
||||
struct eb32_node lb_node; /* node used for tree-based load balancing */
|
||||
@ -428,7 +421,7 @@ struct server {
|
||||
};
|
||||
|
||||
/* usually atomically updated by any thread during parsing or on end of request */
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
int cur_sess; /* number of currently active sessions (including syn_sent) */
|
||||
int served; /* # of active sessions currently being served (ie not pending) */
|
||||
int consecutive_errors; /* current number of consecutive errors */
|
||||
@ -436,7 +429,7 @@ struct server {
|
||||
struct be_counters counters; /* statistics counters */
|
||||
|
||||
/* Below are some relatively stable settings, only changed under the lock */
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
|
||||
struct eb_root *lb_tree; /* we want to know in what tree the server is */
|
||||
struct tree_occ *lb_nodes; /* lb_nodes_tot * struct tree_occ */
|
||||
@ -485,7 +478,7 @@ struct server {
|
||||
unsigned char *ptr;
|
||||
int size;
|
||||
int allocated_size;
|
||||
uint64_t sni_hash; /* Hash of the SNI used for the session */
|
||||
char *sni; /* SNI used for the session */
|
||||
__decl_thread(HA_RWLOCK_T sess_lock);
|
||||
} * reused_sess;
|
||||
|
||||
@ -514,8 +507,6 @@ struct server {
|
||||
} ssl_ctx;
|
||||
#ifdef USE_QUIC
|
||||
struct quic_transport_params quic_params; /* QUIC transport parameters */
|
||||
const struct quic_cc_algo *quic_cc_algo; /* QUIC control congestion algorithm */
|
||||
size_t quic_max_cwnd; /* QUIC maximum congestion control window size (kB) */
|
||||
#endif
|
||||
struct path_parameters path_params; /* Connection parameters for that server */
|
||||
struct resolv_srvrq *srvrq; /* Pointer representing the DNS SRV requeest, if any */
|
||||
|
||||
@ -99,7 +99,7 @@ void srv_release_conn(struct server *srv, struct connection *conn);
|
||||
struct connection *srv_lookup_conn(struct ceb_root **tree, uint64_t hash);
|
||||
struct connection *srv_lookup_conn_next(struct ceb_root **tree, struct connection *conn);
|
||||
|
||||
void srv_add_idle(struct server *srv, struct connection *conn, int is_safe);
|
||||
void _srv_add_idle(struct server *srv, struct connection *conn, int is_safe);
|
||||
int srv_add_to_idle_list(struct server *srv, struct connection *conn, int is_safe);
|
||||
void srv_add_to_avail_list(struct server *srv, struct connection *conn);
|
||||
struct task *srv_cleanup_toremove_conns(struct task *task, void *context, unsigned int state);
|
||||
@ -207,7 +207,7 @@ static inline void server_index_id(struct proxy *px, struct server *srv)
|
||||
/* increase the number of cumulated streams on the designated server */
|
||||
static inline void srv_inc_sess_ctr(struct server *s)
|
||||
{
|
||||
if (s->counters.shared.tg) {
|
||||
if (s->counters.shared.tg[tgid - 1]) {
|
||||
_HA_ATOMIC_INC(&s->counters.shared.tg[tgid - 1]->cum_sess);
|
||||
update_freq_ctr(&s->counters.shared.tg[tgid - 1]->sess_per_sec, 1);
|
||||
}
|
||||
@ -218,7 +218,7 @@ static inline void srv_inc_sess_ctr(struct server *s)
|
||||
/* set the time of last session on the designated server */
|
||||
static inline void srv_set_sess_last(struct server *s)
|
||||
{
|
||||
if (s->counters.shared.tg)
|
||||
if (s->counters.shared.tg[tgid - 1])
|
||||
HA_ATOMIC_STORE(&s->counters.shared.tg[tgid - 1]->last_sess, ns_to_sec(now_ns));
|
||||
}
|
||||
|
||||
@ -370,8 +370,6 @@ static inline void srv_detach(struct server *srv)
|
||||
|
||||
prev->next = srv->next;
|
||||
}
|
||||
/* reset the proxy's ready_srv if it was this one */
|
||||
HA_ATOMIC_CAS(&px->ready_srv, &srv, NULL);
|
||||
}
|
||||
|
||||
/* Returns a pointer to the first server matching id <id> in backend <bk>.
|
||||
@ -385,8 +383,12 @@ static inline struct server *server_find_by_id(struct proxy *bk, int id)
|
||||
|
||||
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 */
|
||||
|
||||
@ -46,7 +46,6 @@ struct connection *sock_accept_conn(struct listener *l, int *status);
|
||||
void sock_accept_iocb(int fd);
|
||||
void sock_conn_ctrl_init(struct connection *conn);
|
||||
void sock_conn_ctrl_close(struct connection *conn);
|
||||
int sock_conn_get_opt(const struct connection *conn, int level, int optname, void *buf, int size);
|
||||
void sock_conn_iocb(int fd);
|
||||
int sock_conn_check(struct connection *conn);
|
||||
int sock_drain(struct connection *conn);
|
||||
|
||||
@ -89,6 +89,7 @@ struct ckch_store {
|
||||
struct list ckch_inst; /* list of ckch_inst which uses this ckch_node */
|
||||
struct list crtlist_entry; /* list of entries which use this store */
|
||||
struct ckch_conf conf;
|
||||
struct task *acme_task;
|
||||
struct ebmb_node node;
|
||||
char path[VAR_ARRAY];
|
||||
};
|
||||
@ -203,7 +204,7 @@ struct ckch_conf_kws {
|
||||
const char *name;
|
||||
ssize_t offset;
|
||||
enum parse_type_t type;
|
||||
int (*func)(void *value, char *buf, struct ckch_store *s, int cli, const char *filename, int linenum, char **err);
|
||||
int (*func)(void *value, char *buf, struct ckch_data *d, int cli, const char *filename, int linenum, char **err);
|
||||
};
|
||||
|
||||
extern struct ckch_conf_kws ckch_conf_kws[];
|
||||
|
||||
@ -90,11 +90,10 @@ extern int (*ssl_commit_crlfile_cb)(const char *path, X509_STORE *ctx, char **er
|
||||
*
|
||||
*/
|
||||
#define DECLARE_CKCH_CONF_LOAD(name, base, callback) \
|
||||
static inline int ckch_conf_load_##name(void *value, char *buf, struct ckch_store *s, int cli, const char *filename, int linenum, char **err) \
|
||||
static inline int ckch_conf_load_##name(void *value, char *buf, struct ckch_data *d, int cli, const char *filename, int linenum, char **err) \
|
||||
{ \
|
||||
char path[PATH_MAX]; \
|
||||
int err_code = 0; \
|
||||
struct ckch_data *d = s->data; \
|
||||
if (cli) \
|
||||
return 0; \
|
||||
err_code |= path_base(value, (base), path, err); \
|
||||
|
||||
@ -56,7 +56,7 @@ void ssl_destroy_ocsp_update_task(void);
|
||||
int ssl_ocsp_update_insert(struct certificate_ocsp *ocsp);
|
||||
int __ssl_ocsp_update_insert_unlocked(struct certificate_ocsp *ocsp);
|
||||
|
||||
int ocsp_update_init(void *value, char *buf, struct ckch_store *s, int cli, const char *filename, int linenum, char **err);
|
||||
int ocsp_update_init(void *value, char *buf, struct ckch_data *d, int cli, const char *filename, int linenum, char **err);
|
||||
|
||||
#endif /* (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP) */
|
||||
|
||||
|
||||
@ -254,7 +254,7 @@ struct ssl_keylog {
|
||||
#define SSL_SOCK_F_KTLS_SEND (1 << 2) /* kTLS send is configured on that socket */
|
||||
#define SSL_SOCK_F_KTLS_RECV (1 << 3) /* kTLS receive is configure on that socket */
|
||||
#define SSL_SOCK_F_CTRL_SEND (1 << 4) /* We want to send a kTLS control message for that socket */
|
||||
#define SSL_SOCK_F_HAS_ALPN (1 << 5) /* An ALPN has been negotiated */
|
||||
#define SSL_SOCK_F_HAS_ALPN (1 << 5) /* An ALPN has been negociated */
|
||||
|
||||
struct ssl_sock_ctx {
|
||||
struct connection *conn;
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
#include <haproxy/proxy-t.h>
|
||||
#include <haproxy/quic_conn-t.h>
|
||||
#include <haproxy/ssl_sock-t.h>
|
||||
#include <haproxy/stats.h>
|
||||
#include <haproxy/thread.h>
|
||||
|
||||
extern struct list tlskeys_reference;
|
||||
@ -58,7 +57,6 @@ extern struct pool_head *pool_head_ssl_keylog_str;
|
||||
extern struct list openssl_providers;
|
||||
extern struct stats_module ssl_stats_module;
|
||||
|
||||
uint64_t ssl_sock_sni_hash(const struct ist sni);
|
||||
int ssl_sock_prep_ctx_and_inst(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
|
||||
SSL_CTX *ctx, struct ckch_inst *ckch_inst, char **err);
|
||||
int ssl_sock_prep_srv_ctx_and_inst(const struct server *srv, SSL_CTX *ctx,
|
||||
@ -73,7 +71,7 @@ int ssl_sock_get_alpn(const struct connection *conn, void *xprt_ctx,
|
||||
const char **str, int *len);
|
||||
int ssl_bio_and_sess_init(struct connection *conn, SSL_CTX *ssl_ctx,
|
||||
SSL **ssl, BIO **bio, BIO_METHOD *bio_meth, void *ctx);
|
||||
int ssl_sock_srv_try_reuse_sess(struct ssl_sock_ctx *ctx, struct server *srv);
|
||||
void ssl_sock_srv_try_reuse_sess(struct ssl_sock_ctx *ctx, struct server *srv);
|
||||
const char *ssl_sock_get_sni(struct connection *conn);
|
||||
const char *ssl_sock_get_cert_sig(struct connection *conn);
|
||||
const char *ssl_sock_get_cipher_name(struct connection *conn);
|
||||
@ -91,7 +89,6 @@ unsigned int ssl_sock_get_verify_result(struct connection *conn);
|
||||
void ssl_sock_update_counters(SSL *ssl,
|
||||
struct ssl_counters *counters,
|
||||
struct ssl_counters *counters_px, int backend);
|
||||
void ssl_sock_handle_hs_error(struct connection *conn);
|
||||
#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
|
||||
int ssl_sock_update_tlskey_ref(struct tls_keys_ref *ref,
|
||||
struct buffer *tlskey);
|
||||
@ -244,30 +241,6 @@ static inline struct connection *ssl_sock_get_conn(const SSL *s, struct ssl_sock
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set at <counters> and <counters_px> addresses the SSL statistical counters */
|
||||
static inline void ssl_sock_get_stats_counters(struct connection *conn,
|
||||
struct ssl_counters **counters,
|
||||
struct ssl_counters **counters_px)
|
||||
{
|
||||
switch (obj_type(conn->target)) {
|
||||
case OBJ_TYPE_LISTENER: {
|
||||
struct listener *li = __objt_listener(conn->target);
|
||||
*counters = EXTRA_COUNTERS_GET(li->extra_counters, &ssl_stats_module);
|
||||
*counters_px = EXTRA_COUNTERS_GET(li->bind_conf->frontend->extra_counters_fe,
|
||||
&ssl_stats_module);
|
||||
break;
|
||||
}
|
||||
case OBJ_TYPE_SERVER: {
|
||||
struct server *srv = __objt_server(conn->target);
|
||||
*counters = EXTRA_COUNTERS_GET(srv->extra_counters, &ssl_stats_module);
|
||||
*counters_px = EXTRA_COUNTERS_GET(srv->proxy->extra_counters_be,
|
||||
&ssl_stats_module);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_OPENSSL */
|
||||
#endif /* _HAPROXY_SSL_SOCK_H */
|
||||
|
||||
@ -57,9 +57,6 @@ const char *nid2nist(int nid);
|
||||
const char *sigalg2str(int sigalg);
|
||||
const char *curveid2str(int curve_id);
|
||||
|
||||
int aes_process(struct buffer *data, struct buffer *nonce, struct buffer *key, int key_size,
|
||||
struct buffer *aead_tag, struct buffer *aad, struct buffer *out, int decrypt, int gcm);
|
||||
|
||||
#endif /* _HAPROXY_SSL_UTILS_H */
|
||||
#endif /* USE_OPENSSL */
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ enum stfile_domain {
|
||||
};
|
||||
|
||||
#define SHM_STATS_FILE_VER_MAJOR 1
|
||||
#define SHM_STATS_FILE_VER_MINOR 2
|
||||
#define SHM_STATS_FILE_VER_MINOR 0
|
||||
|
||||
#define SHM_STATS_FILE_HEARTBEAT_TIMEOUT 60 /* passed this delay (seconds) process which has not
|
||||
* sent heartbeat will be considered down
|
||||
@ -64,9 +64,9 @@ struct shm_stats_file_hdr {
|
||||
*/
|
||||
struct shm_stats_file_object {
|
||||
char guid[GUID_MAX_LEN + 1];
|
||||
uint16_t tgid; // thread group ID
|
||||
uint8_t tgid; // thread group ID from 1 to 64
|
||||
uint8_t type; // SHM_STATS_FILE_OBJECT_TYPE_* to know how to handle object.data
|
||||
ALWAYS_PAD(5); // 5 bytes hole, ensure it remains the same size 32 vs 64 bits arch
|
||||
ALWAYS_PAD(6); // 6 bytes hole, ensure it remains the same size 32 vs 64 bits arch
|
||||
uint64_t users; // bitfield that corresponds to users of the object (see shm_stats_file_hdr slots)
|
||||
/* as the struct may hold any of the types described here, let's make it
|
||||
* so it may store up to the heaviest one using an union
|
||||
|
||||
@ -489,10 +489,7 @@ enum stat_idx_px {
|
||||
ST_I_PX_H3REQ,
|
||||
ST_I_PX_PROTO,
|
||||
ST_I_PX_PRIV_IDLE_CUR,
|
||||
ST_I_PX_REQ_IN,
|
||||
ST_I_PX_REQ_OUT,
|
||||
ST_I_PX_RES_IN,
|
||||
ST_I_PX_RES_OUT,
|
||||
|
||||
/* must always be the last one */
|
||||
ST_I_PX_MAX
|
||||
};
|
||||
|
||||
@ -313,8 +313,8 @@ struct se_abort_info {
|
||||
*
|
||||
* <kip> is the known input payload length. It is set by the stream endpoint
|
||||
* that produce data and decremented once consumed by the app
|
||||
* layer. Depending on the endpoint, this value may be unset. It may be set
|
||||
* only once if the payload length is fully known from the beginning (a
|
||||
* loyer. Depending on the enpoint, this value may be unset. It may be set
|
||||
* only once if the payload lenght is fully known from the begining (a
|
||||
* HTTP message with a content-length for instance), or incremented
|
||||
* periodically when more data are expected (a chunk-encoded HTTP message
|
||||
* for instance). On the app side, this value is decremented when data are
|
||||
@ -377,9 +377,6 @@ struct stconn {
|
||||
* -1 : the SC is waiting for room but not on a specific amount of data
|
||||
* >= 0 : min free space required to progress. 0 means SC must be unblocked ASAP
|
||||
*/
|
||||
unsigned long long bytes_in; /* total number of bytes received from the SE */
|
||||
unsigned long long bytes_out; /* total number of bytes sent to the SE */
|
||||
|
||||
struct wait_event wait_event; /* We're in a wait list */
|
||||
struct sedesc *sedesc; /* points to the stream endpoint descriptor */
|
||||
enum obj_type *app; /* points to the applicative point (stream or check) */
|
||||
|
||||
@ -206,7 +206,7 @@ struct stktable {
|
||||
void *ptr; /* generic ptr to check if set or not */
|
||||
} write_to; /* updates received on the source table will also update write_to */
|
||||
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
|
||||
struct {
|
||||
struct eb_root keys; /* head of sticky session tree */
|
||||
@ -216,20 +216,21 @@ struct stktable {
|
||||
|
||||
__decl_thread(HA_RWLOCK_T sh_lock); /* for the trees above */
|
||||
int next_exp; /* Next expiration for this table */
|
||||
} buckets[CONFIG_HAP_TBL_BUCKETS];
|
||||
} shards[CONFIG_HAP_TBL_BUCKETS];
|
||||
|
||||
unsigned int refcnt; /* number of local peer over all peers sections
|
||||
attached to this table */
|
||||
unsigned int current; /* number of sticky sessions currently in table */
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
|
||||
struct eb_root updates; /* head of sticky updates sequence tree, uses updt_lock */
|
||||
struct mt_list *pend_updts; /* list of updates to be added to the update sequence tree, one per thread-group */
|
||||
unsigned int update; /* uses updt_lock */
|
||||
unsigned int localupdate; /* uses updt_lock */
|
||||
unsigned int commitupdate;/* used to identify the latest local updates pending for sync, uses updt_lock */
|
||||
struct tasklet *updt_task;/* tasklet responsible for pushing the pending updates into the tree */
|
||||
|
||||
THREAD_ALIGN();
|
||||
THREAD_ALIGN(64);
|
||||
/* this lock is heavily used and must be on its own cache line */
|
||||
__decl_thread(HA_RWLOCK_T updt_lock); /* lock protecting the updates part */
|
||||
|
||||
|
||||
@ -193,11 +193,11 @@ static inline void *stktable_data_ptr_idx(struct stktable *t, struct stksess *ts
|
||||
return __stktable_data_ptr(t, ts, type) + idx*stktable_type_size(stktable_data_types[type].std_type);
|
||||
}
|
||||
|
||||
/* return a bucket number for key <key> of len <len> present in table <t>, for
|
||||
/* return a shard number for key <key> of len <len> present in table <t>, for
|
||||
* use with the tree indexing. The value will be from 0 to
|
||||
* CONFIG_HAP_TBL_BUCKETS-1.
|
||||
*/
|
||||
static inline uint stktable_calc_bucket_num(const struct stktable *t, const void *key, size_t len)
|
||||
static inline uint stktable_calc_shard_num(const struct stktable *t, const void *key, size_t len)
|
||||
{
|
||||
#if CONFIG_HAP_TBL_BUCKETS > 1
|
||||
return XXH32(key, len, t->hash_seed) % CONFIG_HAP_TBL_BUCKETS;
|
||||
@ -219,13 +219,13 @@ static inline int __stksess_kill_if_expired(struct stktable *t, struct stksess *
|
||||
* Decrease the refcount of a stksess and release it if the refcount falls to 0
|
||||
* _AND_ if the session expired. Note,, the refcount is always decremented.
|
||||
*
|
||||
* This function locks the corresponding table bucket to proceed. When this
|
||||
* This function locks the corresponding table shard to proceed. When this
|
||||
* function is called, the caller must be sure it owns a reference on the
|
||||
* stksess (refcount >= 1).
|
||||
*/
|
||||
static inline void stksess_kill_if_expired(struct stktable *t, struct stksess *ts)
|
||||
{
|
||||
uint bucket;
|
||||
uint shard;
|
||||
size_t len;
|
||||
|
||||
if (t->expire != TICK_ETERNITY && tick_is_expired(ts->expire, now_ms)) {
|
||||
@ -234,15 +234,15 @@ static inline void stksess_kill_if_expired(struct stktable *t, struct stksess *t
|
||||
else
|
||||
len = t->key_size;
|
||||
|
||||
bucket = stktable_calc_bucket_num(t, ts->key.key, len);
|
||||
shard = stktable_calc_shard_num(t, ts->key.key, len);
|
||||
|
||||
/* make the compiler happy when bucket is not used without threads */
|
||||
ALREADY_CHECKED(bucket);
|
||||
/* make the compiler happy when shard is not used without threads */
|
||||
ALREADY_CHECKED(shard);
|
||||
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->buckets[bucket].sh_lock);
|
||||
HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->shards[shard].sh_lock);
|
||||
if (!HA_ATOMIC_SUB_FETCH(&ts->ref_cnt, 1))
|
||||
__stksess_kill_if_expired(t, ts);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->buckets[bucket].sh_lock);
|
||||
HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->shards[shard].sh_lock);
|
||||
}
|
||||
else
|
||||
HA_ATOMIC_SUB_FETCH(&ts->ref_cnt, 1);
|
||||
|
||||
@ -225,10 +225,8 @@ struct strm_logs {
|
||||
unsigned long t_close; /* total stream duration */
|
||||
unsigned long srv_queue_pos; /* number of streams de-queued while waiting for a connection slot on this server */
|
||||
unsigned long prx_queue_pos; /* number of streams de-qeuued while waiting for a connection slot on this instance */
|
||||
long long req_in; /* number of bytes received from the client */
|
||||
long long req_out; /* number of bytes sent to the server */
|
||||
long long res_in; /* number of bytes received from the server */
|
||||
long long res_out; /* number of bytes sent to the client */
|
||||
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 */
|
||||
};
|
||||
|
||||
struct stream {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#ifndef _HAPROXY_STRESS_H
|
||||
#define _HAPROXY_STRESS_H
|
||||
|
||||
#if defined(DEBUG_STRESS) && (DEBUG_STRESS > 0)
|
||||
#ifdef DEBUG_STRESS
|
||||
enum { mode_stress = 1 };
|
||||
#else
|
||||
enum { mode_stress = 0 };
|
||||
|
||||
@ -91,7 +91,7 @@ extern struct pool_head *pool_head_task;
|
||||
extern struct pool_head *pool_head_tasklet;
|
||||
extern struct pool_head *pool_head_notification;
|
||||
|
||||
__decl_thread(extern HA_RWLOCK_T wq_lock THREAD_ALIGNED());
|
||||
__decl_thread(extern HA_RWLOCK_T wq_lock THREAD_ALIGNED(64));
|
||||
|
||||
void __tasklet_wakeup_on(struct tasklet *tl, int thr);
|
||||
struct list *__tasklet_wakeup_after(struct list *head, struct tasklet *tl);
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
|
||||
/* declare a self-initializing spinlock, aligned on a cache line */
|
||||
#define __decl_aligned_spinlock(lock) \
|
||||
HA_SPINLOCK_T (lock) ALIGNED(64) = 0;
|
||||
HA_SPINLOCK_T (lock) __attribute__((aligned(64))) = 0;
|
||||
|
||||
/* declare a self-initializing rwlock */
|
||||
#define __decl_rwlock(lock) \
|
||||
@ -59,7 +59,7 @@
|
||||
|
||||
/* declare a self-initializing rwlock, aligned on a cache line */
|
||||
#define __decl_aligned_rwlock(lock) \
|
||||
HA_RWLOCK_T (lock) ALIGNED(64) = 0;
|
||||
HA_RWLOCK_T (lock) __attribute__((aligned(64))) = 0;
|
||||
|
||||
#else /* !USE_THREAD */
|
||||
|
||||
@ -72,7 +72,7 @@
|
||||
|
||||
/* declare a self-initializing spinlock, aligned on a cache line */
|
||||
#define __decl_aligned_spinlock(lock) \
|
||||
HA_SPINLOCK_T (lock) THREAD_ALIGNED(); \
|
||||
HA_SPINLOCK_T (lock) __attribute__((aligned(64))); \
|
||||
INITCALL1(STG_LOCK, ha_spin_init, &(lock))
|
||||
|
||||
/* declare a self-initializing rwlock */
|
||||
@ -82,7 +82,7 @@
|
||||
|
||||
/* declare a self-initializing rwlock, aligned on a cache line */
|
||||
#define __decl_aligned_rwlock(lock) \
|
||||
HA_RWLOCK_T (lock) THREAD_ALIGNED(); \
|
||||
HA_RWLOCK_T (lock) __attribute__((aligned(64))); \
|
||||
INITCALL1(STG_LOCK, ha_rwlock_init, &(lock))
|
||||
|
||||
#endif /* USE_THREAD */
|
||||
|
||||
@ -60,6 +60,7 @@ extern int thread_cpus_enabled_at_boot;
|
||||
/* Only way found to replace variables with constants that are optimized away
|
||||
* at build time.
|
||||
*/
|
||||
enum { all_tgroups_mask = 1UL };
|
||||
enum { tid_bit = 1UL };
|
||||
enum { tid = 0 };
|
||||
enum { tgid = 1 };
|
||||
@ -207,6 +208,7 @@ void wait_for_threads_completion();
|
||||
void set_thread_cpu_affinity();
|
||||
unsigned long long ha_get_pthread_id(unsigned int thr);
|
||||
|
||||
extern volatile unsigned long all_tgroups_mask;
|
||||
extern volatile unsigned int rdv_requests;
|
||||
extern volatile unsigned int isolated_thread;
|
||||
extern THREAD_LOCAL unsigned int tid; /* The thread id */
|
||||
|
||||
@ -42,7 +42,7 @@ struct thread_set {
|
||||
ulong abs[(MAX_THREADS + LONGBITS - 1) / LONGBITS];
|
||||
ulong rel[MAX_TGROUPS];
|
||||
};
|
||||
ulong nbgrps; /* Number of thread groups, 0 for abs */
|
||||
ulong grps; /* bit field of all non-empty groups, 0 for abs */
|
||||
};
|
||||
|
||||
/* tasklet classes */
|
||||
@ -86,7 +86,7 @@ struct tgroup_info {
|
||||
|
||||
/* pad to cache line (64B) */
|
||||
char __pad[0]; /* unused except to check remaining room */
|
||||
char __end[0] THREAD_ALIGNED();
|
||||
char __end[0] __attribute__((aligned(64)));
|
||||
};
|
||||
|
||||
/* This structure describes the group-specific context (e.g. active threads
|
||||
@ -103,7 +103,7 @@ struct tgroup_ctx {
|
||||
|
||||
/* pad to cache line (64B) */
|
||||
char __pad[0]; /* unused except to check remaining room */
|
||||
char __end[0] THREAD_ALIGNED();
|
||||
char __end[0] __attribute__((aligned(64)));
|
||||
};
|
||||
|
||||
/* This structure describes all the per-thread info we need. When threads are
|
||||
@ -124,7 +124,7 @@ struct thread_info {
|
||||
|
||||
/* pad to cache line (64B) */
|
||||
char __pad[0]; /* unused except to check remaining room */
|
||||
char __end[0] THREAD_ALIGNED();
|
||||
char __end[0] __attribute__((aligned(64)));
|
||||
};
|
||||
|
||||
/* This structure describes all the per-thread context we need. This is
|
||||
@ -150,8 +150,7 @@ struct thread_ctx {
|
||||
struct list buffer_wq[DYNBUF_NBQ]; /* buffer waiters, 4 criticality-based queues */
|
||||
struct list pool_lru_head; /* oldest objects in thread-local pool caches */
|
||||
struct list streams; /* list of streams attached to this thread */
|
||||
struct list quic_conns_fe; /* list of active FE quic-conns attached to this thread */
|
||||
struct list quic_conns_be; /* list of active BE quic-conns attached to this thread */
|
||||
struct list quic_conns; /* list of active quic-conns attached to this thread */
|
||||
struct list quic_conns_clo; /* list of closing quic-conns attached to this thread */
|
||||
struct list queued_checks; /* checks waiting for a connection slot */
|
||||
struct list tasklets[TL_CLASSES]; /* tasklets (and/or tasks) to run, by class */
|
||||
|
||||
@ -77,7 +77,7 @@ static inline int thread_set_nth_group(const struct thread_set *ts, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ts->nbgrps) {
|
||||
if (ts->grps) {
|
||||
for (i = 0; i < MAX_TGROUPS; i++)
|
||||
if (ts->rel[i] && !n--)
|
||||
return i + 1;
|
||||
@ -95,7 +95,7 @@ static inline ulong thread_set_nth_tmask(const struct thread_set *ts, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ts->nbgrps) {
|
||||
if (ts->grps) {
|
||||
for (i = 0; i < MAX_TGROUPS; i++)
|
||||
if (ts->rel[i] && !n--)
|
||||
return ts->rel[i];
|
||||
@ -111,7 +111,7 @@ static inline void thread_set_pin_grp1(struct thread_set *ts, ulong mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
ts->nbgrps = 1;
|
||||
ts->grps = 1;
|
||||
ts->rel[0] = mask;
|
||||
for (i = 1; i < MAX_TGROUPS; i++)
|
||||
ts->rel[i] = 0;
|
||||
|
||||
@ -47,6 +47,23 @@
|
||||
/* return the largest possible integer of type <ret>, with all bits set */
|
||||
#define MAX_RANGE(ret) (~(typeof(ret))0)
|
||||
|
||||
/* DEFVAL() returns either the second argument as-is, or <def> if absent. This
|
||||
* is for use in macros arguments.
|
||||
*/
|
||||
#define DEFVAL(_def,...) _FIRST_ARG(NULL, ##__VA_ARGS__, (_def))
|
||||
|
||||
/* DEFNULL() returns either the argument as-is, or NULL if absent. This is for
|
||||
* use in macros arguments.
|
||||
*/
|
||||
#define DEFNULL(...) DEFVAL(NULL, ##__VA_ARGS__)
|
||||
|
||||
/* DEFZERO() returns either the argument as-is, or 0 if absent. This is for
|
||||
* use in macros arguments.
|
||||
*/
|
||||
#define DEFZERO(...) DEFVAL(0, ##__VA_ARGS__)
|
||||
|
||||
#define _FIRST_ARG(a, b, ...) b
|
||||
|
||||
/* options flags for parse_line() */
|
||||
#define PARSE_OPT_SHARP 0x00000001 // '#' ends the line
|
||||
#define PARSE_OPT_BKSLASH 0x00000002 // '\' escapes chars
|
||||
|
||||
@ -1022,16 +1022,13 @@ int my_unsetenv(const char *name);
|
||||
* some expansion is made.
|
||||
*/
|
||||
char *env_expand(char *in);
|
||||
struct ist env_suggest(struct ist word);
|
||||
int is_path_mode(mode_t mode, const char *path_fmt, ...);
|
||||
int is_file_present(const char *path_fmt, ...);
|
||||
int is_dir_present(const char *path_fmt, ...);
|
||||
uint32_t parse_line(char *in, char *out, size_t *outlen, char **args, int *nbargs, uint32_t opts, const char **errptr);
|
||||
ssize_t read_line_to_trash(const char *path_fmt, ...);
|
||||
size_t sanitize_for_printing(char *line, size_t pos, size_t width);
|
||||
void update_word_fingerprint_with_len(uint8_t *fp, struct ist word);
|
||||
void update_word_fingerprint(uint8_t *fp, const char *word);
|
||||
void make_word_fingerprint_with_len(uint8_t *fp, struct ist word);
|
||||
void make_word_fingerprint(uint8_t *fp, const char *word);
|
||||
int word_fingerprint_distance(const uint8_t *fp1, const uint8_t *fp2);
|
||||
|
||||
@ -1413,8 +1410,7 @@ static inline int warn_if_lower(const char *text, long min)
|
||||
value = atol(text);
|
||||
return value && value < min;
|
||||
}
|
||||
/* compare the current AWS-LC API number to a string */
|
||||
int awslc_compare_current_api(const char *version);
|
||||
|
||||
/* compare the current OpenSSL version to a string */
|
||||
int openssl_compare_current_version(const char *version);
|
||||
/* compare the current OpenSSL name to a string */
|
||||
@ -1490,6 +1486,4 @@ int path_base(const char *path, const char *base, char *dst, char **err);
|
||||
|
||||
void ha_freearray(char ***array);
|
||||
|
||||
void ha_memset_s(void *s, int c, size_t n);
|
||||
|
||||
#endif /* _HAPROXY_TOOLS_H */
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
#ifdef CONFIG_PRODUCT_BRANCH
|
||||
#define PRODUCT_BRANCH CONFIG_PRODUCT_BRANCH
|
||||
#else
|
||||
#define PRODUCT_BRANCH "3.4"
|
||||
#define PRODUCT_BRANCH "3.3"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PRODUCT_STATUS
|
||||
|
||||
@ -63,7 +63,7 @@
|
||||
* the same split bit as its parent node, it is necessary its associated leaf
|
||||
*
|
||||
* When descending along the tree, it is possible to know that a search key is
|
||||
* not present, because its XOR with both of the branches is strictly higher
|
||||
* not present, because its XOR with both of the branches is stricly higher
|
||||
* than the inter-branch XOR. The reason is simple : the inter-branch XOR will
|
||||
* have its highest bit set indicating the split bit. Since it's the bit that
|
||||
* differs between the two branches, the key cannot have it both set and
|
||||
@ -555,7 +555,7 @@ struct ceb_node *_ceb_descend(struct ceb_root **root,
|
||||
/* the parent will be the (possibly virtual) node so that
|
||||
* &lparent->l == root, i.e. container_of(root, struct ceb_node, b[0]).
|
||||
*/
|
||||
lparent = (struct ceb_node *)((char *)root - offsetof(struct ceb_node, b));
|
||||
lparent = (struct ceb_node *)((char *)root - (long)&((struct ceb_node *)0)->b[0]);
|
||||
gparent = lparent;
|
||||
if (ret_nparent)
|
||||
*ret_nparent = NULL;
|
||||
|
||||
@ -1 +0,0 @@
|
||||
../ssl/certs/
|
||||
1
reg-tests/checks/common.pem
Symbolic link
1
reg-tests/checks/common.pem
Symbolic link
@ -0,0 +1 @@
|
||||
../ssl/common.pem
|
||||
@ -39,7 +39,7 @@ haproxy htst -conf {
|
||||
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
|
||||
|
||||
frontend fe1
|
||||
bind "fd@${fe1}" ssl crt ${testdir}/certs/common.pem
|
||||
bind "fd@${fe1}" ssl crt ${testdir}/common.pem
|
||||
|
||||
frontend fe2
|
||||
bind "fd@${fe2}"
|
||||
|
||||
@ -45,10 +45,10 @@ haproxy htst -conf {
|
||||
server fe1 ${htst_fe1_addr}:${htst_fe1_port}
|
||||
|
||||
frontend fe1
|
||||
bind "fd@${fe1}" ssl crt ${testdir}/certs/common.pem curves P-256:P-384
|
||||
bind "fd@${fe1}" ssl crt ${testdir}/common.pem curves P-256:P-384
|
||||
|
||||
frontend fe3
|
||||
bind "fd@${fe3}" ssl crt ${testdir}/certs/common.pem
|
||||
bind "fd@${fe3}" ssl crt ${testdir}/common.pem
|
||||
} -start
|
||||
|
||||
haproxy h1 -conf {
|
||||
|
||||
@ -62,7 +62,7 @@ haproxy htst -conf {
|
||||
server fe1 ${htst_fe1_addr}:${htst_fe1_port}
|
||||
|
||||
frontend fe1
|
||||
bind "fd@${fe1}" ssl crt ${testdir}/certs/common.pem
|
||||
bind "fd@${fe1}" ssl crt ${testdir}/common.pem
|
||||
|
||||
} -start
|
||||
|
||||
|
||||
@ -60,15 +60,15 @@ haproxy h1 -conf {
|
||||
frontend fe1
|
||||
option httplog
|
||||
log ${S1_addr}:${S1_port} len 2048 local0 debug err
|
||||
bind "fd@${fe1}" ssl crt ${testdir}/certs/common.pem
|
||||
bind "fd@${fe1}" ssl crt ${testdir}/common.pem
|
||||
use_backend be1
|
||||
|
||||
frontend fe2
|
||||
bind "fd@${fe2}" ssl crt ${testdir}/certs/common.pem
|
||||
bind "fd@${fe2}" ssl crt ${testdir}/common.pem
|
||||
use_backend be2
|
||||
|
||||
frontend fe3
|
||||
bind "fd@${fe3}" ssl crt ${testdir}/certs/common.pem
|
||||
bind "fd@${fe3}" ssl crt ${testdir}/common.pem
|
||||
use_backend be3
|
||||
} -start
|
||||
|
||||
@ -108,19 +108,19 @@ haproxy h2 -conf {
|
||||
option httpchk OPTIONS * HTTP/1.1
|
||||
http-check send hdr Host www
|
||||
log ${S2_addr}:${S2_port} daemon
|
||||
server srv1 ${h1_fe1_addr}:${h1_fe1_port} ssl crt ${testdir}/certs/common.pem verify none check
|
||||
server srv1 ${h1_fe1_addr}:${h1_fe1_port} ssl crt ${testdir}/common.pem verify none check
|
||||
|
||||
backend be4
|
||||
option log-health-checks
|
||||
log ${S4_addr}:${S4_port} daemon
|
||||
server srv2 ${h1_fe2_addr}:${h1_fe2_port} ssl crt ${testdir}/certs/common.pem verify none check-ssl check
|
||||
server srv2 ${h1_fe2_addr}:${h1_fe2_port} ssl crt ${testdir}/common.pem verify none check-ssl check
|
||||
|
||||
backend be6
|
||||
option log-health-checks
|
||||
option httpchk OPTIONS * HTTP/1.1
|
||||
http-check send hdr Host www
|
||||
log ${S6_addr}:${S6_port} daemon
|
||||
server srv3 127.0.0.1:80 crt ${testdir}/certs/common.pem verify none check check-ssl port ${h1_fe3_port} addr ${h1_fe3_addr}:80
|
||||
server srv3 127.0.0.1:80 crt ${testdir}/common.pem verify none check check-ssl port ${h1_fe3_port} addr ${h1_fe3_addr}:80
|
||||
} -start
|
||||
|
||||
syslog S1 -wait
|
||||
|
||||
@ -1 +0,0 @@
|
||||
../ssl/certs/
|
||||
1
reg-tests/compression/common.pem
Symbolic link
1
reg-tests/compression/common.pem
Symbolic link
@ -0,0 +1 @@
|
||||
../ssl/common.pem
|
||||
@ -22,7 +22,7 @@ defaults
|
||||
mode http
|
||||
|
||||
frontend main-https
|
||||
bind "fd@${fe1}" ssl crt ${testdir}/certs/common.pem
|
||||
bind "fd@${fe1}" ssl crt ${testdir}/common.pem
|
||||
compression algo gzip
|
||||
compression type text/html text/plain application/json application/javascript
|
||||
compression offload
|
||||
|
||||
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