mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-04-03 10:01:03 +02:00
Compare commits
No commits in common. "master" and "v3.4-dev5" have entirely different histories.
42
.github/matrix.py
vendored
42
.github/matrix.py
vendored
@ -12,7 +12,6 @@ import functools
|
|||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import urllib.error
|
|
||||||
import urllib.request
|
import urllib.request
|
||||||
from os import environ
|
from os import environ
|
||||||
from packaging import version
|
from packaging import version
|
||||||
@ -20,10 +19,9 @@ from packaging import version
|
|||||||
#
|
#
|
||||||
# this CI is used for both development and stable branches of HAProxy
|
# this CI is used for both development and stable branches of HAProxy
|
||||||
#
|
#
|
||||||
# naming convention used, if branch/tag name matches:
|
# naming convention used, if branch name matches:
|
||||||
#
|
#
|
||||||
# "haproxy-" - stable branches
|
# "haproxy-" - stable branches
|
||||||
# "vX.Y.Z" - release tags
|
|
||||||
# otherwise - development branch (i.e. "latest" ssl variants, "latest" github images)
|
# otherwise - development branch (i.e. "latest" ssl variants, "latest" github images)
|
||||||
#
|
#
|
||||||
|
|
||||||
@ -34,24 +32,13 @@ def get_all_github_tags(url):
|
|||||||
headers = {}
|
headers = {}
|
||||||
if environ.get("GITHUB_TOKEN") is not None:
|
if environ.get("GITHUB_TOKEN") is not None:
|
||||||
headers["Authorization"] = "token {}".format(environ.get("GITHUB_TOKEN"))
|
headers["Authorization"] = "token {}".format(environ.get("GITHUB_TOKEN"))
|
||||||
all_tags = []
|
request = urllib.request.Request(url, headers=headers)
|
||||||
page = 1
|
|
||||||
sep = "&" if "?" in url else "?"
|
|
||||||
while True:
|
|
||||||
paginated_url = "{}{}per_page=100&page={}".format(url, sep, page)
|
|
||||||
request = urllib.request.Request(paginated_url, headers=headers)
|
|
||||||
try:
|
try:
|
||||||
response = urllib.request.urlopen(request)
|
tags = urllib.request.urlopen(request)
|
||||||
except urllib.error.URLError:
|
except:
|
||||||
return all_tags if all_tags else None
|
return None
|
||||||
tags = json.loads(response.read().decode("utf-8"))
|
tags = json.loads(tags.read().decode("utf-8"))
|
||||||
if not tags:
|
return [tag['name'] for tag in tags]
|
||||||
break
|
|
||||||
all_tags.extend([tag['name'] for tag in tags])
|
|
||||||
if len(tags) < 100:
|
|
||||||
break
|
|
||||||
page += 1
|
|
||||||
return all_tags if all_tags else None
|
|
||||||
|
|
||||||
@functools.lru_cache(5)
|
@functools.lru_cache(5)
|
||||||
def determine_latest_openssl(ssl):
|
def determine_latest_openssl(ssl):
|
||||||
@ -77,8 +64,6 @@ def determine_latest_aws_lc(ssl):
|
|||||||
if not tags:
|
if not tags:
|
||||||
return "AWS_LC_VERSION=failed_to_detect"
|
return "AWS_LC_VERSION=failed_to_detect"
|
||||||
valid_tags = list(filter(aws_lc_version_valid, tags))
|
valid_tags = list(filter(aws_lc_version_valid, tags))
|
||||||
if not valid_tags:
|
|
||||||
return "AWS_LC_VERSION=failed_to_detect"
|
|
||||||
latest_tag = max(valid_tags, key=aws_lc_version_string_to_num)
|
latest_tag = max(valid_tags, key=aws_lc_version_string_to_num)
|
||||||
return "AWS_LC_VERSION={}".format(latest_tag[1:])
|
return "AWS_LC_VERSION={}".format(latest_tag[1:])
|
||||||
|
|
||||||
@ -90,12 +75,11 @@ def aws_lc_fips_version_valid(version_string):
|
|||||||
|
|
||||||
@functools.lru_cache(5)
|
@functools.lru_cache(5)
|
||||||
def determine_latest_aws_lc_fips(ssl):
|
def determine_latest_aws_lc_fips(ssl):
|
||||||
tags = get_all_github_tags("https://api.github.com/repos/aws/aws-lc/tags")
|
# the AWS-LC-FIPS tags are at the end of the list, so let's get a lot
|
||||||
|
tags = get_all_github_tags("https://api.github.com/repos/aws/aws-lc/tags?per_page=200")
|
||||||
if not tags:
|
if not tags:
|
||||||
return "AWS_LC_FIPS_VERSION=failed_to_detect"
|
return "AWS_LC_FIPS_VERSION=failed_to_detect"
|
||||||
valid_tags = list(filter(aws_lc_fips_version_valid, tags))
|
valid_tags = list(filter(aws_lc_fips_version_valid, tags))
|
||||||
if not valid_tags:
|
|
||||||
return "AWS_LC_FIPS_VERSION=failed_to_detect"
|
|
||||||
latest_tag = max(valid_tags, key=aws_lc_fips_version_string_to_num)
|
latest_tag = max(valid_tags, key=aws_lc_fips_version_string_to_num)
|
||||||
return "AWS_LC_FIPS_VERSION={}".format(latest_tag[12:])
|
return "AWS_LC_FIPS_VERSION={}".format(latest_tag[12:])
|
||||||
|
|
||||||
@ -136,13 +120,11 @@ def clean_compression(compression):
|
|||||||
def main(ref_name):
|
def main(ref_name):
|
||||||
print("Generating matrix for branch '{}'.".format(ref_name))
|
print("Generating matrix for branch '{}'.".format(ref_name))
|
||||||
|
|
||||||
is_stable = "haproxy-" in ref_name or re.match(r'^v\d+\.\d+\.\d+$', ref_name)
|
|
||||||
|
|
||||||
matrix = []
|
matrix = []
|
||||||
|
|
||||||
# Ubuntu
|
# Ubuntu
|
||||||
|
|
||||||
if is_stable:
|
if "haproxy-" in ref_name:
|
||||||
os = "ubuntu-24.04" # stable branch
|
os = "ubuntu-24.04" # stable branch
|
||||||
os_arm = "ubuntu-24.04-arm" # stable branch
|
os_arm = "ubuntu-24.04-arm" # stable branch
|
||||||
else:
|
else:
|
||||||
@ -246,7 +228,7 @@ def main(ref_name):
|
|||||||
# "BORINGSSL=yes",
|
# "BORINGSSL=yes",
|
||||||
]
|
]
|
||||||
|
|
||||||
if not is_stable: # development branch
|
if "haproxy-" not in ref_name: # development branch
|
||||||
ssl_versions = ssl_versions + [
|
ssl_versions = ssl_versions + [
|
||||||
"OPENSSL_VERSION=latest",
|
"OPENSSL_VERSION=latest",
|
||||||
"LIBRESSL_VERSION=latest",
|
"LIBRESSL_VERSION=latest",
|
||||||
@ -294,7 +276,7 @@ def main(ref_name):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# macOS on dev branches
|
# macOS on dev branches
|
||||||
if not is_stable:
|
if "haproxy-" not in ref_name:
|
||||||
os = "macos-26" # development branch
|
os = "macos-26" # development branch
|
||||||
|
|
||||||
TARGET = "osx"
|
TARGET = "osx"
|
||||||
|
|||||||
3
.github/workflows/contrib.yml
vendored
3
.github/workflows/contrib.yml
vendored
@ -11,6 +11,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
|
- name: Compile admin/halog/halog
|
||||||
|
run: |
|
||||||
|
make admin/halog/halog
|
||||||
- name: Compile dev/flags/flags
|
- name: Compile dev/flags/flags
|
||||||
run: |
|
run: |
|
||||||
make dev/flags/flags
|
make dev/flags/flags
|
||||||
|
|||||||
3
.github/workflows/quic-interop-aws-lc.yml
vendored
3
.github/workflows/quic-interop-aws-lc.yml
vendored
@ -21,9 +21,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Update Docker to the latest
|
|
||||||
uses: docker/setup-docker-action@v4
|
|
||||||
|
|
||||||
- name: Build Docker image
|
- name: Build Docker image
|
||||||
id: push
|
id: push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
|
|||||||
3
.github/workflows/quic-interop-libressl.yml
vendored
3
.github/workflows/quic-interop-libressl.yml
vendored
@ -21,9 +21,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Update Docker to the latest
|
|
||||||
uses: docker/setup-docker-action@v4
|
|
||||||
|
|
||||||
- name: Build Docker image
|
- name: Build Docker image
|
||||||
id: push
|
id: push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
|
|||||||
244
CHANGELOG
244
CHANGELOG
@ -1,250 +1,6 @@
|
|||||||
ChangeLog :
|
ChangeLog :
|
||||||
===========
|
===========
|
||||||
|
|
||||||
2026/03/20 : 3.4-dev7
|
|
||||||
- BUG/MINOR: stconn: Increase SC bytes_out value in se_done_ff()
|
|
||||||
- BUG/MINOR: ssl-sample: Fix sample_conv_sha2() by checking EVP_Digest* failures
|
|
||||||
- BUG/MINOR: backend: Don't get proto to use for webscoket if there is no server
|
|
||||||
- BUG/MINOR: jwt: Missing 'jwt_tokenize' return value check
|
|
||||||
- MINOR: flt_http_comp: define and use proxy_get_comp() helper function
|
|
||||||
- MEDIUM: flt_http_comp: split "compression" filter in 2 distinct filters
|
|
||||||
- CLEANUP: flt_http_comp: comp_state doesn't bother about the direction anymore
|
|
||||||
- BUG/MINOR: admin: haproxy-reload use explicit socat address type
|
|
||||||
- MEDIUM: admin: haproxy-reload conversion to POSIX sh
|
|
||||||
- BUG/MINOR: admin: haproxy-reload rename -vv long option
|
|
||||||
- SCRIPTS: git-show-backports: hide the common ancestor warning in quiet mode
|
|
||||||
- SCRIPTS: git-show-backports: add a restart-from-last option
|
|
||||||
- MINOR: mworker: add a BUG_ON() on mproxy_li in _send_status
|
|
||||||
- BUG/MINOR: mworker: don't set the PROC_O_LEAVING flag on master process
|
|
||||||
- Revert "BUG/MINOR: jwt: Missing 'jwt_tokenize' return value check"
|
|
||||||
- MINOR: jwt: Improve 'jwt_tokenize' function
|
|
||||||
- MINOR: jwt: Convert EC JWK to EVP_PKEY
|
|
||||||
- MINOR: jwt: Parse ec-specific fields in jose header
|
|
||||||
- MINOR: jwt: Manage ECDH-ES algorithm in jwt_decrypt_jwk function
|
|
||||||
- MINOR: jwt: Add ecdh-es+axxxkw support in jwt_decrypt_jwk converter
|
|
||||||
- MINOR: jwt: Manage ec certificates in jwt_decrypt_cert
|
|
||||||
- DOC: jwt: Add ECDH support in jwt_decrypt converters
|
|
||||||
- MINOR: stconn: Call sc_conn_process from the I/O callback if TASK_WOKEN_MSG state was set
|
|
||||||
- MINOR: mux-h2: Rely on h2s_notify_send() when resuming h2s for sending
|
|
||||||
- MINOR: mux-spop: Rely on spop_strm_notify_send() when resuming streams for sending
|
|
||||||
- MINOR: muxes: Wakup the data layer from a mux stream with TASK_WOKEN_IO state
|
|
||||||
- MAJOR: muxes: No longer use app_ops .wake() callback function from muxes
|
|
||||||
- MINOR: applet: Call sc_applet_process() instead of .wake() callback function
|
|
||||||
- MINOR: connection: Call sc_conn_process() instead of .wake() callback function
|
|
||||||
- MEDIUM: stconn: Remove .wake() callback function from app_ops
|
|
||||||
- MINOR: check: Remove wake_srv_chk() function
|
|
||||||
- MINOR: haterm: Remove hstream_wake() function
|
|
||||||
- MINOR: stconn: Wakup the SC with TASK_WOKEN_IO state from opposite side
|
|
||||||
- MEDIUM: stconn: Merge all .chk_rcv() callback functions in sc_chk_rcv()
|
|
||||||
- MINOR: stconn: Remove .chk_rcv() callback functions
|
|
||||||
- MEDIUM: stconn: Merge all .chk_snd() callback functions in sc_chk_snd()
|
|
||||||
- MINOR: stconn: Remove .chk_snd() callback functions
|
|
||||||
- MEDIUM: stconn: Merge all .abort() callback functions in sc_abort()
|
|
||||||
- MINOR: stconn: Remove .abort() callback functions
|
|
||||||
- MEDIUM: stconn: Merge all .shutdown() callback functions in sc_shutdown()
|
|
||||||
- MINOR: stconn: Remove .shutdown() callback functions
|
|
||||||
- MINOR: stconn: Totally app_ops from the stconns
|
|
||||||
- MINOR: stconn: Simplify sc_abort/sc_shutdown by merging calls to se_shutdown
|
|
||||||
- DEBUG: stconn: Add a CHECK_IF() when I/O are performed on a orphan SC
|
|
||||||
- MEDIUM: mworker: exiting when couldn't find the master mworker_proc element
|
|
||||||
- BUILD: ssl: use ASN1_STRING accessors for OpenSSL 4.0 compatibility
|
|
||||||
- BUILD: ssl: make X509_NAME usage OpenSSL 4.0 ready
|
|
||||||
- BUG/MINOR: tcpcheck: Fix typo in error error message for `http-check expect`
|
|
||||||
- BUG/MINOR: jws: fix memory leak in jws_b64_signature
|
|
||||||
- DOC: configuration: http-check expect example typo
|
|
||||||
- DOC/CLEANUP: config: update mentions of the old "Global parameters" section
|
|
||||||
- BUG/MEDIUM: ssl: Handle receiving early data with BoringSSL/AWS-LC
|
|
||||||
- BUG/MINOR: mworker: always stop the receiving listener
|
|
||||||
- BUG/MEDIUM: ssl: Don't report read data as early data with AWS-LC
|
|
||||||
- BUILD: makefile: fix range build without test command
|
|
||||||
- BUG/MINOR: memprof: avoid a small memory leak in "show profiling"
|
|
||||||
- BUG/MINOR: proxy: do not forget to validate quic-initial rules
|
|
||||||
- MINOR: activity: use dynamic allocation for "show profiling" entries
|
|
||||||
- MINOR: tools: extend the pointer hashing code to ease manipulations
|
|
||||||
- MINOR: tools: add a new pointer hash function that also takes an argument
|
|
||||||
- MINOR: memprof: attempt different retry slots for different hashes on collision
|
|
||||||
- MINOR: tinfo: start to add basic thread_exec_ctx
|
|
||||||
- MINOR: memprof: prepare to consider exec_ctx in reporting
|
|
||||||
- MINOR: memprof: also permit to sort output by calling context
|
|
||||||
- MINOR: tools: add a function to write a thread execution context.
|
|
||||||
- MINOR: debug: report the execution context on thread dumps
|
|
||||||
- MINOR: memprof: report the execution context on profiling output
|
|
||||||
- MINOR: initcall: record the file and line declaration of an INITCALL
|
|
||||||
- MINOR: tools: decode execution context TH_EX_CTX_INITCALL
|
|
||||||
- MINOR: tools: support decoding ha_caller type exec context
|
|
||||||
- MINOR: sample: store location for fetch/conv via initcalls
|
|
||||||
- MINOR: sample: also report contexts registered directly
|
|
||||||
- MINOR: tools: support an execution context that is just a function
|
|
||||||
- MINOR: actions: store the location of keywords registered via initcalls
|
|
||||||
- MINOR: actions: also report execution contexts registered directly
|
|
||||||
- MINOR: filters: set the exec context to the current filter config
|
|
||||||
- MINOR: ssl: set the thread execution context during message callbacks
|
|
||||||
- MINOR: connection: track mux calls to report their allocation context
|
|
||||||
- MINOR: task: set execution context on task/tasklet calls
|
|
||||||
- MINOR: applet: set execution context on applet calls
|
|
||||||
- MINOR: cli: keep the info of the current keyword being processed in the appctx
|
|
||||||
- MINOR: cli: keep track of the initcall context since kw registration
|
|
||||||
- MINOR: cli: implement execution context for manually registered keywords
|
|
||||||
- MINOR: activity: support aggregating by caller also for memprofile
|
|
||||||
- MINOR: activity: raise the default number of memprofile buckets to 4k
|
|
||||||
- DOC: internals: short explanation on how thread_exec_ctx works
|
|
||||||
- BUG/MINOR: mworker: only match worker processes when looking for unspawned proc
|
|
||||||
- MINOR: traces: defer processing of "-dt" options
|
|
||||||
- BUG/MINOR: mworker: fix typo &= instead of & in proc list serialization
|
|
||||||
- BUG/MINOR: mworker: set a timeout on the worker socketpair read at startup
|
|
||||||
- BUG/MINOR: mworker: avoid passing NULL version in proc list serialization
|
|
||||||
- BUG/MINOR: sockpair: set FD_CLOEXEC on fd received via SCM_RIGHTS
|
|
||||||
- BUG/MEDIUM: stconn: Don't forget to wakeup applets on shutdown
|
|
||||||
- BUG/MINOR: spoe: Properly switch SPOE filter to WAITING_ACK state
|
|
||||||
- BUG/MEDIUM: spoe: Properly abort processing on client abort
|
|
||||||
- BUG/MEDIUM: stconn: Fix abort on close when a large buffer is used
|
|
||||||
- BUG/MEDIUM: stconn: Don't perform L7 retries with large buffer
|
|
||||||
- BUG/MINOR: h2/h3: Only test number of trailers inserted in HTX message
|
|
||||||
- MINOR: htx: Add function to truncate all blocks after a specific block
|
|
||||||
- BUG/MINOR: h2/h3: Never insert partial headers/trailers in an HTX message
|
|
||||||
- BUG/MINOR: http-ana: Swap L7 buffer with request buffer by hand
|
|
||||||
- BUG/MINOR: stream: Fix crash in stream dump if the current rule has no keyword
|
|
||||||
- BUG/MINOR: mjson: make mystrtod() length-aware to prevent out-of-bounds reads
|
|
||||||
- MEDIUM: stats-file/clock: automatically update now_offset based on shared clock
|
|
||||||
- MINOR: promex: export "haproxy_sticktable_local_updates" metric
|
|
||||||
- BUG/MINOR: spoe: Fix condition to abort processing on client abort
|
|
||||||
- BUILD: spoe: Remove unsused variable
|
|
||||||
- MINOR: tools: add a function to create a tar file header
|
|
||||||
- MINOR: tools: add a function to load a file into a tar archive
|
|
||||||
- MINOR: config: support explicit "on" and "off" for "set-dumpable"
|
|
||||||
- MINOR: debug: read all libs in memory when set-dumpable=libs
|
|
||||||
- DEV: gdb: add a new utility to extract libs from a core dump: libs-from-core
|
|
||||||
- MINOR: debug: copy debug symbols from /usr/lib/debug when present
|
|
||||||
- MINOR: debug: opportunistically load libthread_db.so.1 with set-dumpable=libs
|
|
||||||
- BUG/MINOR: mworker: don't try to access an initializing process
|
|
||||||
- BUG/MEDIUM: peers: enforce check on incoming table key type
|
|
||||||
- BUG/MINOR: mux-h2: properly ignore R bit in GOAWAY stream ID
|
|
||||||
- BUG/MINOR: mux-h2: properly ignore R bit in WINDOW_UPDATE increments
|
|
||||||
- OPTIM: haterm: use chunk builders for generated response headers
|
|
||||||
- BUG/MAJOR: h3: check body size with content-length on empty FIN
|
|
||||||
- BUG/MEDIUM: h3: reject unaligned frames except DATA
|
|
||||||
- BUG/MINOR: mworker/cli: fix show proc pagination losing entries on resume
|
|
||||||
- CI: github: treat vX.Y.Z release tags as stable like haproxy-* branches
|
|
||||||
- MINOR: freq_ctr: add a function to add values with a peak
|
|
||||||
- MINOR: task: maintain a per-thread indicator of the peak run-queue size
|
|
||||||
- MINOR: mux-h2: store the concurrent streams hard limit in the h2c
|
|
||||||
- MINOR: mux-h2: permit to moderate the advertised streams limit depending on load
|
|
||||||
- MINOR: mux-h2: permit to fix a minimum value for the advertised streams limit
|
|
||||||
- BUG/MINOR: mworker: fix sort order of mworker_proc in 'show proc'
|
|
||||||
- CLEANUP: mworker: fix tab/space mess in mworker_env_to_proc_list()
|
|
||||||
|
|
||||||
2026/03/05 : 3.4-dev6
|
|
||||||
- CLEANUP: acme: remove duplicate includes
|
|
||||||
- BUG/MINOR: proxy: detect strdup error on server auto SNI
|
|
||||||
- BUG/MINOR: server: set auto SNI for dynamic servers
|
|
||||||
- BUG/MINOR: server: enable no-check-sni-auto for dynamic servers
|
|
||||||
- MINOR: haterm: provide -b and -c options (RSA key size, ECDSA curves)
|
|
||||||
- MINOR: haterm: add long options for QUIC and TCP "bind" settings
|
|
||||||
- BUG/MINOR: haterm: missing allocation check in copy_argv()
|
|
||||||
- BUG/MINOR: quic: fix counters used on BE side
|
|
||||||
- MINOR: quic: add BUG_ON() on half_open_conn counter access from BE
|
|
||||||
- BUG/MINOR: quic/h3: display QUIC/H3 backend module on HTML stats
|
|
||||||
- BUG/MINOR: acme: acme_ctx_destroy() leaks auth->dns
|
|
||||||
- BUG/MINOR: acme: wrong labels logic always memprintf errmsg
|
|
||||||
- MINOR: ssl: clarify error reporting for unsupported keywords
|
|
||||||
- BUG/MINOR: acme: fix incorrect number of arguments allowed in config
|
|
||||||
- CLEANUP: haterm: remove unreachable labels hstream_add_data()
|
|
||||||
- CLEANUP: haterm: avoid static analyzer warnings about rand() use
|
|
||||||
- CLEANUP: ssl: Remove a useless variable from ssl_gen_x509()
|
|
||||||
- CI: use the latest docker for QUIC Interop
|
|
||||||
- CI: remove redundant "halog" compilation
|
|
||||||
- CLENAUP: cfgparse: accept-invalid-http-* does not support "no"/"defaults"
|
|
||||||
- BUG/MEDIUM: spoe: Acquire context buffer in applet before consuming a frame
|
|
||||||
- MINOR: traces: always mark trace_source as thread-aligned
|
|
||||||
- MINOR: ncbmbuf: improve itbmap_next() code
|
|
||||||
- MINOR: proxy: improve code when checking server name conflicts
|
|
||||||
- MINOR: quic: add a new metric for ncbuf failures
|
|
||||||
- BUG/MINOR: haterm: cannot reset default "haterm" mode
|
|
||||||
- BUG/MEDIUM: cpu-topo: Distribute CPUs fairly across groups
|
|
||||||
- BUG/MINOR: quic: missing app ops init during backend 0-RTT sessions
|
|
||||||
- CLEANUP: ssl: remove outdated comments
|
|
||||||
- MINOR: mux-h2: also count glitches on invalid trailers
|
|
||||||
- MINOR: mux-h2: add a new setting, "tune.h2.log-errors" to tweak error logging
|
|
||||||
- BUG/MEDIUM: mux-h2: make sure to always report pending errors to the stream
|
|
||||||
- BUG/MINOR: server: adjust initialization order for dynamic servers
|
|
||||||
- CLEANUP: tree-wide: drop a few useless null-checks before free()
|
|
||||||
- CLEANUP: quic-stats: include counters from quic_stats
|
|
||||||
- REORG: stats/counters: move extra_counters to counters not stats
|
|
||||||
- CLEANUP: stats: drop stats.h / stats-t.h where not needed
|
|
||||||
- MEDIUM: counters: change the fill_stats() API to pass the module and extra_counters
|
|
||||||
- CLEANUP: counters: only retrieve zeroes for unallocated extra_counters
|
|
||||||
- MEDIUM: counters: add a dedicated storage for extra_counters in various structs
|
|
||||||
- MINOR: counters: store a tgroup step for extra_counters to access multiple tgroups
|
|
||||||
- MEDIUM: counters: store the number of thread groups accessing extra_counters
|
|
||||||
- MINOR: counters: add EXTRA_COUNTERS_BASE() to retrieve extra_counters base storage
|
|
||||||
- MEDIUM: counters: return aggregate extra counters in ->fill_stats()
|
|
||||||
- MEDIUM: counters: make EXTRA_COUNTERS_GET() consider tgid
|
|
||||||
- BUG/MINOR: call EXTRA_COUNTERS_FREE() before srv_free_params() in srv_drop()
|
|
||||||
- MINOR: promex: test applet resume in stress mode
|
|
||||||
- BUG/MINOR: promex: fix server iteration when last server is deleted
|
|
||||||
- BUG/MINOR: proxy: add dynamic backend into ID tree
|
|
||||||
- MINOR: proxy: convert proxy flags to uint
|
|
||||||
- MINOR: server: refactor srv_detach()
|
|
||||||
- MINOR: proxy: define a basic "del backend" CLI
|
|
||||||
- MINOR: proxy: define proxy watcher member
|
|
||||||
- MINOR: stats: protect proxy iteration via watcher
|
|
||||||
- MINOR: promex: use watcher to iterate over backend instances
|
|
||||||
- MINOR: lua: use watcher for proxies iterator
|
|
||||||
- MINOR: proxy: add refcount to proxies
|
|
||||||
- MINOR: proxy: rename default refcount to avoid confusion
|
|
||||||
- MINOR: server: take proxy refcount when deleting a server
|
|
||||||
- MINOR: lua: handle proxy refcount
|
|
||||||
- MINOR: proxy: prevent backend removal when unsupported
|
|
||||||
- MINOR: proxy: prevent deletion of backend referenced by config elements
|
|
||||||
- MINOR: proxy: prevent backend deletion if server still exists in it
|
|
||||||
- MINOR: server: mark backend removal as forbidden if QUIC was used
|
|
||||||
- MINOR: cli: implement wait on be-removable
|
|
||||||
- MINOR: proxy: add comment for defaults_px_ref/unref_all()
|
|
||||||
- MEDIUM: proxy: add lock for global accesses during proxy free
|
|
||||||
- MEDIUM: proxy: add lock for global accesses during default free
|
|
||||||
- MINOR: proxy: use atomic ops for default proxy refcount
|
|
||||||
- MEDIUM: proxy: implement backend deletion
|
|
||||||
- REGTESTS: add a test on "del backend"
|
|
||||||
- REGTESTS: complete "del backend" with unnamed defaults ref free
|
|
||||||
- BUG/MINOR: hlua: fix return with push nil on proxy check
|
|
||||||
- BUG/MEDIUM: stream: Handle TASK_WOKEN_RES as a stream event
|
|
||||||
- MINOR: quic: use signed char type for ALPN manipulation
|
|
||||||
- MINOR: quic/h3: reorganize stream reject after MUX closure
|
|
||||||
- MINOR: mux-quic: add function for ALPN to app-ops conversion
|
|
||||||
- MEDIUM: quic/mux-quic: adjust app-ops install
|
|
||||||
- MINOR: quic: use server cache for ALPN on BE side
|
|
||||||
- BUG/MEDIUM: hpack: correctly deal with too large decoded numbers
|
|
||||||
- BUG/MAJOR: qpack: unchecked length passed to huffman decoder
|
|
||||||
- BUG/MINOR: qpack: fix 1-byte OOB read in qpack_decode_fs_pfx()
|
|
||||||
- BUG/MINOR: quic: fix OOB read in preferred_address transport parameter
|
|
||||||
- BUG/MEDIUM: qpack: correctly deal with too large decoded numbers
|
|
||||||
- BUG/MINOR: hlua: Properly enable/disable line receives from HTTP applet
|
|
||||||
- BUG/MEDIUM: hlua: Fix end of request detection when retrieving payload
|
|
||||||
- BUG/MINOR: hlua: Properly enable/disable receives for TCP applets
|
|
||||||
- MINOR: htx: Add a function to retrieve the HTTP version from a start-line
|
|
||||||
- MINOR: h1-htx: Reports non-HTTP version via dedicated flags
|
|
||||||
- BUG/MINOR: h1-htx: Be sure that H1 response version starts by "HTTP/"
|
|
||||||
- MINOR: http-ana: Save the message version in the http_msg structure
|
|
||||||
- MEDIUM: http-fetch: Rework how HTTP message version is retrieved
|
|
||||||
- MEDIUM: http-ana: Use the version of the opposite side for internal messages
|
|
||||||
- DEBUG: stream: Display the currently running rule in stream dump
|
|
||||||
- MINOR: filters: Use filter API as far as poissible to break loops on filters
|
|
||||||
- MINOR: filters: Set last_entity when a filter fails on stream_start callback
|
|
||||||
- MINOR: stream: Display the currently running filter per channel in stream dump
|
|
||||||
- DOC: config: Use the right alias for %B
|
|
||||||
- BUG/MINOR: channel: Increase the stconn bytes_in value in channel_add_input()
|
|
||||||
- BUG/MINOR: sample: Fix sample to retrieve the number of bytes received and sent
|
|
||||||
- BUG/MINOR: http-ana: Increment scf bytes_out value if an haproxy error is sent
|
|
||||||
- BUG/MAJOR: fcgi: Fix param decoding by properly checking its size
|
|
||||||
- BUG/MAJOR: resolvers: Properly lowered the names found in DNS response
|
|
||||||
- BUG/MEDIUM: mux-fcgi: Use a safe loop to resume each stream eligible for sending
|
|
||||||
- MINOR: mux-fcgi: Use a dedicated function to resume streams eligible for sending
|
|
||||||
- CLEANUP: qpack: simplify length checks in qpack_decode_fs()
|
|
||||||
- MINOR: counters: Introduce COUNTERS_UPDATE_MAX()
|
|
||||||
- MINOR: listeners: Update the frequency counters separately when needed
|
|
||||||
- MINOR: proxies: Update beconn separately
|
|
||||||
- MINOR: stats: Add an option to disable the calculation of max counters
|
|
||||||
|
|
||||||
2026/02/19 : 3.4-dev5
|
2026/02/19 : 3.4-dev5
|
||||||
- DOC: internals: addd mworker V3 internals
|
- DOC: internals: addd mworker V3 internals
|
||||||
- BUG/MINOR: threads: Initialize maxthrpertgroup earlier.
|
- BUG/MINOR: threads: Initialize maxthrpertgroup earlier.
|
||||||
|
|||||||
14
Makefile
14
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 \
|
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_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_utils.o src/jwt.o src/ssl_clienthello.o src/jws.o src/acme.o \
|
||||||
src/acme_resolvers.o src/ssl_trace.o src/jwe.o
|
src/ssl_trace.o src/jwe.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(USE_ENGINE:0=),)
|
ifneq ($(USE_ENGINE:0=),)
|
||||||
@ -670,7 +670,7 @@ OPTIONS_OBJS += src/mux_quic.o src/h3.o src/quic_rx.o src/quic_tx.o \
|
|||||||
src/quic_cc_nocc.o src/quic_cc.o src/quic_pacing.o \
|
src/quic_cc_nocc.o src/quic_cc.o src/quic_pacing.o \
|
||||||
src/h3_stats.o src/quic_stats.o src/qpack-enc.o \
|
src/h3_stats.o src/quic_stats.o src/qpack-enc.o \
|
||||||
src/qpack-tbl.o src/quic_cc_drs.o src/quic_fctl.o \
|
src/qpack-tbl.o src/quic_cc_drs.o src/quic_fctl.o \
|
||||||
src/quic_enc.o src/mux_quic_qstrm.o src/xprt_qstrm.o
|
src/quic_enc.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(USE_QUIC_OPENSSL_COMPAT:0=),)
|
ifneq ($(USE_QUIC_OPENSSL_COMPAT:0=),)
|
||||||
@ -1043,7 +1043,7 @@ IGNORE_OPTS=help install install-man install-doc install-bin \
|
|||||||
uninstall clean tags cscope tar git-tar version update-version \
|
uninstall clean tags cscope tar git-tar version update-version \
|
||||||
opts reg-tests reg-tests-help unit-tests admin/halog/halog dev/flags/flags \
|
opts reg-tests reg-tests-help unit-tests admin/halog/halog dev/flags/flags \
|
||||||
dev/haring/haring dev/ncpu/ncpu dev/poll/poll dev/tcploop/tcploop \
|
dev/haring/haring dev/ncpu/ncpu dev/poll/poll dev/tcploop/tcploop \
|
||||||
dev/term_events/term_events dev/gdb/pm-from-core dev/gdb/libs-from-core
|
dev/term_events/term_events dev/gdb/pm-from-core
|
||||||
|
|
||||||
ifneq ($(TARGET),)
|
ifneq ($(TARGET),)
|
||||||
ifeq ($(filter $(firstword $(MAKECMDGOALS)),$(IGNORE_OPTS)),)
|
ifeq ($(filter $(firstword $(MAKECMDGOALS)),$(IGNORE_OPTS)),)
|
||||||
@ -1077,9 +1077,6 @@ admin/dyncookie/dyncookie: admin/dyncookie/dyncookie.o
|
|||||||
dev/flags/flags: dev/flags/flags.o
|
dev/flags/flags: dev/flags/flags.o
|
||||||
$(cmd_LD) $(ARCH_FLAGS) $(LDFLAGS) -o $@ $^ $(LDOPTS)
|
$(cmd_LD) $(ARCH_FLAGS) $(LDFLAGS) -o $@ $^ $(LDOPTS)
|
||||||
|
|
||||||
dev/gdb/libs-from-core: dev/gdb/libs-from-core.o
|
|
||||||
$(cmd_LD) $(ARCH_FLAGS) $(LDFLAGS) -o $@ $^ $(LDOPTS)
|
|
||||||
|
|
||||||
dev/gdb/pm-from-core: dev/gdb/pm-from-core.o
|
dev/gdb/pm-from-core: dev/gdb/pm-from-core.o
|
||||||
$(cmd_LD) $(ARCH_FLAGS) $(LDFLAGS) -o $@ $^ $(LDOPTS)
|
$(cmd_LD) $(ARCH_FLAGS) $(LDFLAGS) -o $@ $^ $(LDOPTS)
|
||||||
|
|
||||||
@ -1181,7 +1178,7 @@ distclean: clean
|
|||||||
$(Q)rm -f admin/dyncookie/dyncookie
|
$(Q)rm -f admin/dyncookie/dyncookie
|
||||||
$(Q)rm -f dev/haring/haring dev/ncpu/ncpu{,.so} dev/poll/poll dev/tcploop/tcploop
|
$(Q)rm -f dev/haring/haring dev/ncpu/ncpu{,.so} dev/poll/poll dev/tcploop/tcploop
|
||||||
$(Q)rm -f dev/hpack/decode dev/hpack/gen-enc dev/hpack/gen-rht
|
$(Q)rm -f dev/hpack/decode dev/hpack/gen-enc dev/hpack/gen-rht
|
||||||
$(Q)rm -f dev/qpack/decode dev/gdb/pm-from-core dev/gdb/libs-from-core
|
$(Q)rm -f dev/qpack/decode dev/gdb/pm-from-core
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
$(Q)find src include \( -name '*.c' -o -name '*.h' \) -print0 | \
|
$(Q)find src include \( -name '*.c' -o -name '*.h' \) -print0 | \
|
||||||
@ -1335,8 +1332,7 @@ range:
|
|||||||
echo "[ $$index/$$count ] $$commit #############################"; \
|
echo "[ $$index/$$count ] $$commit #############################"; \
|
||||||
git checkout -q $$commit || die 1; \
|
git checkout -q $$commit || die 1; \
|
||||||
$(MAKE) all || die 1; \
|
$(MAKE) all || die 1; \
|
||||||
set -- $(TEST_CMD); \
|
[ -z "$(TEST_CMD)" ] || $(TEST_CMD) || die 1; \
|
||||||
[ "$$#" -eq 0 ] || "$$@" || die 1; \
|
|
||||||
index=$$((index + 1)); \
|
index=$$((index + 1)); \
|
||||||
done; \
|
done; \
|
||||||
echo;echo "Done! $${count} commit(s) built successfully for RANGE $${RANGE}" ; \
|
echo;echo "Done! $${count} commit(s) built successfully for RANGE $${RANGE}" ; \
|
||||||
|
|||||||
@ -407,7 +407,6 @@ listed below. Metrics from extra counters are not listed.
|
|||||||
+----------------------------------------------------+
|
+----------------------------------------------------+
|
||||||
| haproxy_sticktable_size |
|
| haproxy_sticktable_size |
|
||||||
| haproxy_sticktable_used |
|
| haproxy_sticktable_used |
|
||||||
| haproxy_sticktable_local_updates |
|
|
||||||
+----------------------------------------------------+
|
+----------------------------------------------------+
|
||||||
|
|
||||||
* Resolvers metrics
|
* Resolvers metrics
|
||||||
|
|||||||
@ -36,7 +36,6 @@
|
|||||||
#include <haproxy/stats.h>
|
#include <haproxy/stats.h>
|
||||||
#include <haproxy/stconn.h>
|
#include <haproxy/stconn.h>
|
||||||
#include <haproxy/stream.h>
|
#include <haproxy/stream.h>
|
||||||
#include <haproxy/stress.h>
|
|
||||||
#include <haproxy/task.h>
|
#include <haproxy/task.h>
|
||||||
#include <haproxy/tools.h>
|
#include <haproxy/tools.h>
|
||||||
#include <haproxy/version.h>
|
#include <haproxy/version.h>
|
||||||
@ -83,7 +82,6 @@ struct promex_ctx {
|
|||||||
unsigned field_num; /* current field number (ST_I_PX_* etc) */
|
unsigned field_num; /* current field number (ST_I_PX_* etc) */
|
||||||
unsigned mod_field_num; /* first field number of the current module (ST_I_PX_* etc) */
|
unsigned mod_field_num; /* first field number of the current module (ST_I_PX_* etc) */
|
||||||
int obj_state; /* current state among PROMEX_{FRONT|BACK|SRV|LI}_STATE_* */
|
int obj_state; /* current state among PROMEX_{FRONT|BACK|SRV|LI}_STATE_* */
|
||||||
struct watcher px_watch; /* watcher to automatically update next pointer */
|
|
||||||
struct watcher srv_watch; /* watcher to automatically update next pointer */
|
struct watcher srv_watch; /* watcher to automatically update next pointer */
|
||||||
struct list modules; /* list of promex modules to export */
|
struct list modules; /* list of promex modules to export */
|
||||||
struct eb_root filters; /* list of filters to apply on metrics name */
|
struct eb_root filters; /* list of filters to apply on metrics name */
|
||||||
@ -349,10 +347,6 @@ static int promex_dump_ts(struct appctx *appctx, struct ist prefix,
|
|||||||
istcat(&n, prefix, PROMEX_MAX_NAME_LEN);
|
istcat(&n, prefix, PROMEX_MAX_NAME_LEN);
|
||||||
istcat(&n, name, PROMEX_MAX_NAME_LEN);
|
istcat(&n, name, PROMEX_MAX_NAME_LEN);
|
||||||
|
|
||||||
/* In stress mode, force yielding on each metric. */
|
|
||||||
if (STRESS_RUN1(istlen(*out), 0))
|
|
||||||
goto full;
|
|
||||||
|
|
||||||
if ((ctx->flags & PROMEX_FL_METRIC_HDR) &&
|
if ((ctx->flags & PROMEX_FL_METRIC_HDR) &&
|
||||||
!promex_dump_ts_header(n, desc, type, out, max))
|
!promex_dump_ts_header(n, desc, type, out, max))
|
||||||
goto full;
|
goto full;
|
||||||
@ -632,6 +626,8 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_from(mod, &stats_module_list[STATS_DOMAIN_PROXY], list) {
|
list_for_each_entry_from(mod, &stats_module_list[STATS_DOMAIN_PROXY], list) {
|
||||||
|
void *counters;
|
||||||
|
|
||||||
if (!(stats_px_get_cap(mod->domain_flags) & STATS_PX_CAP_FE))
|
if (!(stats_px_get_cap(mod->domain_flags) & STATS_PX_CAP_FE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -668,7 +664,8 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_FE))
|
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_FE))
|
||||||
goto next_px2;
|
goto next_px2;
|
||||||
|
|
||||||
if (!mod->fill_stats(mod, px->extra_counters_fe, stats + ctx->field_num, &ctx->mod_field_num))
|
counters = EXTRA_COUNTERS_GET(px->extra_counters_fe, mod);
|
||||||
|
if (!mod->fill_stats(counters, stats + ctx->field_num, &ctx->mod_field_num))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
val = stats[ctx->field_num + ctx->mod_field_num];
|
val = stats[ctx->field_num + ctx->mod_field_num];
|
||||||
@ -820,6 +817,8 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_from(mod, &stats_module_list[STATS_DOMAIN_PROXY], list) {
|
list_for_each_entry_from(mod, &stats_module_list[STATS_DOMAIN_PROXY], list) {
|
||||||
|
void *counters;
|
||||||
|
|
||||||
if (!(stats_px_get_cap(mod->domain_flags) & STATS_PX_CAP_LI))
|
if (!(stats_px_get_cap(mod->domain_flags) & STATS_PX_CAP_LI))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -865,7 +864,8 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
labels[lb_idx+1].name = ist("mod");
|
labels[lb_idx+1].name = ist("mod");
|
||||||
labels[lb_idx+1].value = ist2(mod->name, strlen(mod->name));
|
labels[lb_idx+1].value = ist2(mod->name, strlen(mod->name));
|
||||||
|
|
||||||
if (!mod->fill_stats(mod, li->extra_counters, stats + ctx->field_num, &ctx->mod_field_num))
|
counters = EXTRA_COUNTERS_GET(li->extra_counters, mod);
|
||||||
|
if (!mod->fill_stats(counters, stats + ctx->field_num, &ctx->mod_field_num))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
val = stats[ctx->field_num + ctx->mod_field_num];
|
val = stats[ctx->field_num + ctx->mod_field_num];
|
||||||
@ -941,6 +941,9 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
if (promex_filter_metric(appctx, prefix, name))
|
if (promex_filter_metric(appctx, prefix, name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!px)
|
||||||
|
px = proxies_list;
|
||||||
|
|
||||||
while (px) {
|
while (px) {
|
||||||
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
||||||
unsigned int srv_state_count[PROMEX_SRV_STATE_COUNT] = { 0 };
|
unsigned int srv_state_count[PROMEX_SRV_STATE_COUNT] = { 0 };
|
||||||
@ -1095,16 +1098,9 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
&val, labels, &out, max))
|
&val, labels, &out, max))
|
||||||
goto full;
|
goto full;
|
||||||
next_px:
|
next_px:
|
||||||
px = watcher_next(&ctx->px_watch, px->next);
|
px = px->next;
|
||||||
}
|
}
|
||||||
watcher_detach(&ctx->px_watch);
|
|
||||||
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
||||||
|
|
||||||
/* Prepare a new iteration for the next stat column.
|
|
||||||
* Update ctx.p[0] via watcher.
|
|
||||||
*/
|
|
||||||
watcher_attach(&ctx->px_watch, proxies_list);
|
|
||||||
px = proxies_list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip extra counters */
|
/* Skip extra counters */
|
||||||
@ -1117,6 +1113,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_from(mod, &stats_module_list[STATS_DOMAIN_PROXY], list) {
|
list_for_each_entry_from(mod, &stats_module_list[STATS_DOMAIN_PROXY], list) {
|
||||||
|
void *counters;
|
||||||
|
|
||||||
if (!(stats_px_get_cap(mod->domain_flags) & STATS_PX_CAP_BE))
|
if (!(stats_px_get_cap(mod->domain_flags) & STATS_PX_CAP_BE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1127,6 +1125,9 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
if (promex_filter_metric(appctx, prefix, name))
|
if (promex_filter_metric(appctx, prefix, name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!px)
|
||||||
|
px = proxies_list;
|
||||||
|
|
||||||
while (px) {
|
while (px) {
|
||||||
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
||||||
struct promex_metric metric;
|
struct promex_metric metric;
|
||||||
@ -1150,7 +1151,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
|
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
|
||||||
goto next_px2;
|
goto next_px2;
|
||||||
|
|
||||||
if (!mod->fill_stats(mod, px->extra_counters_be, stats + ctx->field_num, &ctx->mod_field_num))
|
counters = EXTRA_COUNTERS_GET(px->extra_counters_be, mod);
|
||||||
|
if (!mod->fill_stats(counters, stats + ctx->field_num, &ctx->mod_field_num))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
val = stats[ctx->field_num + ctx->mod_field_num];
|
val = stats[ctx->field_num + ctx->mod_field_num];
|
||||||
@ -1161,39 +1163,25 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
goto full;
|
goto full;
|
||||||
|
|
||||||
next_px2:
|
next_px2:
|
||||||
px = watcher_next(&ctx->px_watch, px->next);
|
px = px->next;
|
||||||
}
|
}
|
||||||
watcher_detach(&ctx->px_watch);
|
|
||||||
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
||||||
|
|
||||||
/* Prepare a new iteration for the next stat column.
|
|
||||||
* Update ctx.p[0] via watcher.
|
|
||||||
*/
|
|
||||||
watcher_attach(&ctx->px_watch, proxies_list);
|
|
||||||
px = proxies_list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->field_num += mod->stats_count;
|
ctx->field_num += mod->stats_count;
|
||||||
ctx->mod_field_num = 0;
|
ctx->mod_field_num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
px = NULL;
|
||||||
if (ret) {
|
|
||||||
watcher_detach(&ctx->px_watch);
|
|
||||||
mod = NULL;
|
mod = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
|
end:
|
||||||
if (out.len) {
|
if (out.len) {
|
||||||
if (!htx_add_data_atonce(htx, out)) {
|
if (!htx_add_data_atonce(htx, out))
|
||||||
watcher_detach(&ctx->px_watch);
|
|
||||||
return -1; /* Unexpected and unrecoverable error */
|
return -1; /* Unexpected and unrecoverable error */
|
||||||
}
|
}
|
||||||
}
|
/* Save pointers (0=current proxy, 1=current stats module) of the current context */
|
||||||
|
ctx->p[0] = px;
|
||||||
/* Save pointers of the current context for dump resumption :
|
|
||||||
* 0=current proxy, 1=current stats module
|
|
||||||
* Note that p[0] is already automatically updated via px_watch.
|
|
||||||
*/
|
|
||||||
ctx->p[1] = mod;
|
ctx->p[1] = mod;
|
||||||
return ret;
|
return ret;
|
||||||
full:
|
full:
|
||||||
@ -1235,6 +1223,9 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
if (promex_filter_metric(appctx, prefix, name))
|
if (promex_filter_metric(appctx, prefix, name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!px)
|
||||||
|
px = proxies_list;
|
||||||
|
|
||||||
while (px) {
|
while (px) {
|
||||||
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
||||||
enum promex_mt_type type;
|
enum promex_mt_type type;
|
||||||
@ -1254,6 +1245,11 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
|
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
|
||||||
goto next_px;
|
goto next_px;
|
||||||
|
|
||||||
|
if (!sv) {
|
||||||
|
watcher_attach(&ctx->srv_watch, px->srv);
|
||||||
|
sv = px->srv;
|
||||||
|
}
|
||||||
|
|
||||||
while (sv) {
|
while (sv) {
|
||||||
labels[lb_idx].name = ist("server");
|
labels[lb_idx].name = ist("server");
|
||||||
labels[lb_idx].value = ist2(sv->id, strlen(sv->id));
|
labels[lb_idx].value = ist2(sv->id, strlen(sv->id));
|
||||||
@ -1409,25 +1405,9 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
|
|
||||||
next_px:
|
next_px:
|
||||||
watcher_detach(&ctx->srv_watch);
|
watcher_detach(&ctx->srv_watch);
|
||||||
px = watcher_next(&ctx->px_watch, px->next);
|
px = px->next;
|
||||||
if (px) {
|
|
||||||
/* Update ctx.p[1] via watcher. */
|
|
||||||
watcher_attach(&ctx->srv_watch, px->srv);
|
|
||||||
sv = ctx->p[1];
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
watcher_detach(&ctx->px_watch);
|
|
||||||
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
||||||
|
|
||||||
/* Prepare a new iteration for the next stat column.
|
|
||||||
* Update ctx.p[0]/p[1] via px_watch/srv_watch.
|
|
||||||
*/
|
|
||||||
watcher_attach(&ctx->px_watch, proxies_list);
|
|
||||||
px = proxies_list;
|
|
||||||
if (likely(px)) {
|
|
||||||
watcher_attach(&ctx->srv_watch, px->srv);
|
|
||||||
sv = ctx->p[1];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip extra counters */
|
/* Skip extra counters */
|
||||||
@ -1440,6 +1420,8 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_from(mod, &stats_module_list[STATS_DOMAIN_PROXY], list) {
|
list_for_each_entry_from(mod, &stats_module_list[STATS_DOMAIN_PROXY], list) {
|
||||||
|
void *counters;
|
||||||
|
|
||||||
if (!(stats_px_get_cap(mod->domain_flags) & STATS_PX_CAP_SRV))
|
if (!(stats_px_get_cap(mod->domain_flags) & STATS_PX_CAP_SRV))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1450,6 +1432,9 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
if (promex_filter_metric(appctx, prefix, name))
|
if (promex_filter_metric(appctx, prefix, name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!px)
|
||||||
|
px = proxies_list;
|
||||||
|
|
||||||
while (px) {
|
while (px) {
|
||||||
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
|
||||||
struct promex_metric metric;
|
struct promex_metric metric;
|
||||||
@ -1470,6 +1455,11 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
|
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
|
||||||
goto next_px2;
|
goto next_px2;
|
||||||
|
|
||||||
|
if (!sv) {
|
||||||
|
watcher_attach(&ctx->srv_watch, px->srv);
|
||||||
|
sv = px->srv;
|
||||||
|
}
|
||||||
|
|
||||||
while (sv) {
|
while (sv) {
|
||||||
labels[lb_idx].name = ist("server");
|
labels[lb_idx].name = ist("server");
|
||||||
labels[lb_idx].value = ist2(sv->id, strlen(sv->id));
|
labels[lb_idx].value = ist2(sv->id, strlen(sv->id));
|
||||||
@ -1481,7 +1471,8 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
goto next_sv2;
|
goto next_sv2;
|
||||||
|
|
||||||
|
|
||||||
if (!mod->fill_stats(mod, sv->extra_counters, stats + ctx->field_num, &ctx->mod_field_num))
|
counters = EXTRA_COUNTERS_GET(sv->extra_counters, mod);
|
||||||
|
if (!mod->fill_stats(counters, stats + ctx->field_num, &ctx->mod_field_num))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
val = stats[ctx->field_num + ctx->mod_field_num];
|
val = stats[ctx->field_num + ctx->mod_field_num];
|
||||||
@ -1497,47 +1488,28 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
|
|
||||||
next_px2:
|
next_px2:
|
||||||
watcher_detach(&ctx->srv_watch);
|
watcher_detach(&ctx->srv_watch);
|
||||||
px = watcher_next(&ctx->px_watch, px->next);
|
px = px->next;
|
||||||
if (px) {
|
|
||||||
/* Update ctx.p[1] via watcher. */
|
|
||||||
watcher_attach(&ctx->srv_watch, px->srv);
|
|
||||||
sv = ctx->p[1];
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
watcher_detach(&ctx->px_watch);
|
|
||||||
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
ctx->flags |= PROMEX_FL_METRIC_HDR;
|
||||||
|
|
||||||
/* Prepare a new iteration for the next stat column.
|
|
||||||
* Update ctx.p[0]/p[1] via px_watch/srv_watch.
|
|
||||||
*/
|
|
||||||
watcher_attach(&ctx->px_watch, proxies_list);
|
|
||||||
px = proxies_list;
|
|
||||||
if (likely(px)) {
|
|
||||||
watcher_attach(&ctx->srv_watch, px->srv);
|
|
||||||
sv = ctx->p[1];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->field_num += mod->stats_count;
|
ctx->field_num += mod->stats_count;
|
||||||
ctx->mod_field_num = 0;
|
ctx->mod_field_num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
px = NULL;
|
||||||
if (ret) {
|
sv = NULL;
|
||||||
watcher_detach(&ctx->px_watch);
|
|
||||||
watcher_detach(&ctx->srv_watch);
|
|
||||||
mod = NULL;
|
mod = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
|
end:
|
||||||
if (out.len) {
|
if (out.len) {
|
||||||
if (!htx_add_data_atonce(htx, out))
|
if (!htx_add_data_atonce(htx, out))
|
||||||
return -1; /* Unexpected and unrecoverable error */
|
return -1; /* Unexpected and unrecoverable error */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save pointers of the current context for dump resumption :
|
/* Save pointers (0=current proxy, 1=current server, 2=current stats module) of the current context */
|
||||||
* 0=current proxy, 1=current server, 2=current stats module
|
ctx->p[0] = px;
|
||||||
* Note that p[0]/p[1] are already automatically updated via px_watch/srv_watch.
|
ctx->p[1] = sv;
|
||||||
*/
|
|
||||||
ctx->p[2] = mod;
|
ctx->p[2] = mod;
|
||||||
return ret;
|
return ret;
|
||||||
full:
|
full:
|
||||||
@ -1545,7 +1517,6 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
watcher_detach(&ctx->px_watch);
|
|
||||||
watcher_detach(&ctx->srv_watch);
|
watcher_detach(&ctx->srv_watch);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1768,11 +1739,6 @@ static int promex_dump_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
ctx->field_num = ST_I_PX_PXNAME;
|
ctx->field_num = ST_I_PX_PXNAME;
|
||||||
ctx->mod_field_num = 0;
|
ctx->mod_field_num = 0;
|
||||||
appctx->st1 = PROMEX_DUMPER_BACK;
|
appctx->st1 = PROMEX_DUMPER_BACK;
|
||||||
|
|
||||||
if (ctx->flags & PROMEX_FL_SCOPE_BACK) {
|
|
||||||
/* Update ctx.p[0] via watcher. */
|
|
||||||
watcher_attach(&ctx->px_watch, proxies_list);
|
|
||||||
}
|
|
||||||
__fallthrough;
|
__fallthrough;
|
||||||
|
|
||||||
case PROMEX_DUMPER_BACK:
|
case PROMEX_DUMPER_BACK:
|
||||||
@ -1790,15 +1756,6 @@ static int promex_dump_metrics(struct appctx *appctx, struct htx *htx)
|
|||||||
ctx->field_num = ST_I_PX_PXNAME;
|
ctx->field_num = ST_I_PX_PXNAME;
|
||||||
ctx->mod_field_num = 0;
|
ctx->mod_field_num = 0;
|
||||||
appctx->st1 = PROMEX_DUMPER_SRV;
|
appctx->st1 = PROMEX_DUMPER_SRV;
|
||||||
|
|
||||||
if (ctx->flags & PROMEX_FL_SCOPE_SERVER) {
|
|
||||||
/* Update ctx.p[0] via watcher. */
|
|
||||||
watcher_attach(&ctx->px_watch, proxies_list);
|
|
||||||
if (likely(proxies_list)) {
|
|
||||||
/* Update ctx.p[1] via watcher. */
|
|
||||||
watcher_attach(&ctx->srv_watch, proxies_list->srv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
__fallthrough;
|
__fallthrough;
|
||||||
|
|
||||||
case PROMEX_DUMPER_SRV:
|
case PROMEX_DUMPER_SRV:
|
||||||
@ -2076,7 +2033,6 @@ static int promex_appctx_init(struct appctx *appctx)
|
|||||||
LIST_INIT(&ctx->modules);
|
LIST_INIT(&ctx->modules);
|
||||||
ctx->filters = EB_ROOT;
|
ctx->filters = EB_ROOT;
|
||||||
appctx->st0 = PROMEX_ST_INIT;
|
appctx->st0 = PROMEX_ST_INIT;
|
||||||
watcher_init(&ctx->px_watch, &ctx->p[0], offsetof(struct proxy, watcher_list));
|
|
||||||
watcher_init(&ctx->srv_watch, &ctx->p[1], offsetof(struct server, watcher_list));
|
watcher_init(&ctx->srv_watch, &ctx->p[1], offsetof(struct server, watcher_list));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2091,11 +2047,6 @@ static void promex_appctx_release(struct appctx *appctx)
|
|||||||
struct promex_metric_filter *flt;
|
struct promex_metric_filter *flt;
|
||||||
struct eb32_node *node, *next;
|
struct eb32_node *node, *next;
|
||||||
|
|
||||||
if (appctx->st1 == PROMEX_DUMPER_BACK ||
|
|
||||||
appctx->st1 == PROMEX_DUMPER_SRV) {
|
|
||||||
watcher_detach(&ctx->px_watch);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appctx->st1 == PROMEX_DUMPER_SRV)
|
if (appctx->st1 == PROMEX_DUMPER_SRV)
|
||||||
watcher_detach(&ctx->srv_watch);
|
watcher_detach(&ctx->srv_watch);
|
||||||
|
|
||||||
|
|||||||
@ -149,7 +149,7 @@ usage() {
|
|||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " -S, --master-socket <path> Use the master socket at <path> (default: ${SOCKET})"
|
echo " -S, --master-socket <path> Use the master socket at <path> (default: ${SOCKET})"
|
||||||
echo " -s, --socket <path> Use the stats socket at <path>"
|
echo " -s, --socket <path> Use the stats socket at <path>"
|
||||||
echo " -p, --path <path> Specify a base path for relative files (default: ${BASEPATH})"
|
echo " -p, --path <path> Specifiy a base path for relative files (default: ${BASEPATH})"
|
||||||
echo " -n, --dry-run Read certificates on the socket but don't dump them"
|
echo " -n, --dry-run Read certificates on the socket but don't dump them"
|
||||||
echo " -d, --debug Debug mode, set -x"
|
echo " -d, --debug Debug mode, set -x"
|
||||||
echo " -v, --verbose Verbose mode"
|
echo " -v, --verbose Verbose mode"
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
export VERBOSE=1
|
export VERBOSE=1
|
||||||
export TIMEOUT=90
|
export TIMEOUT=90
|
||||||
export MASTER_SOCKET="${MASTER_SOCKET:-/var/run/haproxy-master.sock}"
|
export MASTER_SOCKET=${MASTER_SOCKET:-/var/run/haproxy-master.sock}
|
||||||
|
export RET=
|
||||||
|
|
||||||
alert() {
|
alert() {
|
||||||
if [ "$VERBOSE" -ge "1" ]; then
|
if [ "$VERBOSE" -ge "1" ]; then
|
||||||
@ -14,38 +15,32 @@ alert() {
|
|||||||
|
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
if [ -S "$MASTER_SOCKET" ]; then
|
while read -r line; do
|
||||||
socat_addr="UNIX-CONNECT:${MASTER_SOCKET}"
|
|
||||||
|
if [ "$line" = "Success=0" ]; then
|
||||||
|
RET=1
|
||||||
|
elif [ "$line" = "Success=1" ]; then
|
||||||
|
RET=0
|
||||||
|
elif [ "$line" = "Another reload is still in progress." ]; then
|
||||||
|
alert "$line"
|
||||||
|
elif [ "$line" = "--" ]; then
|
||||||
|
continue;
|
||||||
else
|
else
|
||||||
case "$MASTER_SOCKET" in
|
if [ "$RET" = 1 ] && [ "$VERBOSE" = "2" ]; then
|
||||||
*:[0-9]*)
|
echo "$line" >&2
|
||||||
socat_addr="TCP:${MASTER_SOCKET}"
|
elif [ "$VERBOSE" = "3" ]; then
|
||||||
;;
|
echo "$line" >&2
|
||||||
*)
|
fi
|
||||||
alert "Invalid master socket address '${MASTER_SOCKET}': expected a UNIX socket file or <host>:<port>"
|
fi
|
||||||
|
|
||||||
|
done < <(echo "reload" | socat -t"${TIMEOUT}" "${MASTER_SOCKET}" -)
|
||||||
|
|
||||||
|
if [ -z "$RET" ]; then
|
||||||
|
alert "Couldn't finish the reload before the timeout (${TIMEOUT})."
|
||||||
return 1
|
return 1
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "reload" | socat -t"${TIMEOUT}" "$socat_addr" - | {
|
return "$RET"
|
||||||
read -r status || { alert "No status received (connection error or timeout after ${TIMEOUT}s)."; exit 1; }
|
|
||||||
case "$status" in
|
|
||||||
"Success=1") ret=0 ;;
|
|
||||||
"Success=0") ret=1 ;;
|
|
||||||
*) alert "Unexpected response: '$status'"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
read -r _ # consume "--"
|
|
||||||
|
|
||||||
if [ "$VERBOSE" -ge 3 ] || { [ "$ret" = 1 ] && [ "$VERBOSE" -ge 2 ]; }; then
|
|
||||||
cat >&2
|
|
||||||
else
|
|
||||||
cat >/dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit "$ret"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
@ -57,12 +52,12 @@ usage() {
|
|||||||
echo " EXPERIMENTAL script!"
|
echo " EXPERIMENTAL script!"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " -S, --master-socket <addr> Unix socket path or <host>:<port> (default: ${MASTER_SOCKET})"
|
echo " -S, --master-socket <path> Use the master socket at <path> (default: ${MASTER_SOCKET})"
|
||||||
echo " -d, --debug Debug mode, set -x"
|
echo " -d, --debug Debug mode, set -x"
|
||||||
echo " -t, --timeout Timeout (socat -t) (default: ${TIMEOUT})"
|
echo " -t, --timeout Timeout (socat -t) (default: ${TIMEOUT})"
|
||||||
echo " -s, --silent Silent mode (no output)"
|
echo " -s, --silent Silent mode (no output)"
|
||||||
echo " -v, --verbose Verbose output (output from haproxy on failure)"
|
echo " -v, --verbose Verbose output (output from haproxy on failure)"
|
||||||
echo " -vv --verbose=all Very verbose output (output from haproxy on success and failure)"
|
echo " -vv Even more verbose output (output from haproxy on success and failure)"
|
||||||
echo " -h, --help This help"
|
echo " -h, --help This help"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Examples:"
|
echo "Examples:"
|
||||||
@ -89,7 +84,7 @@ main() {
|
|||||||
VERBOSE=2
|
VERBOSE=2
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
-vv|--verbose=all)
|
-vv|--verbose)
|
||||||
VERBOSE=3
|
VERBOSE=3
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|||||||
@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
* Extracts the libs archives from a core dump
|
|
||||||
*
|
|
||||||
* Copyright (C) 2026 Willy Tarreau <w@1wt.eu>
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Note: builds with no option under glibc, and can be built as a minimal
|
|
||||||
* uploadable static executable using nolibc as well:
|
|
||||||
gcc -o libs-from-core -nostdinc -nostdlib -s -Os -static -fno-ident \
|
|
||||||
-fno-exceptions -fno-asynchronous-unwind-tables -fno-unwind-tables \
|
|
||||||
-Wl,--gc-sections,--orphan-handling=discard,-znoseparate-code \
|
|
||||||
-I /path/to/nolibc-sysroot/include libs-from-core.c
|
|
||||||
*/
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <elf.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
void usage(const char *progname)
|
|
||||||
{
|
|
||||||
const char *slash = strrchr(progname, '/');
|
|
||||||
|
|
||||||
if (slash)
|
|
||||||
progname = slash + 1;
|
|
||||||
|
|
||||||
fprintf(stderr,
|
|
||||||
"Usage: %s [-q] <core_file>\n"
|
|
||||||
"Locate a libs archive from an haproxy core dump and dump it to stdout.\n"
|
|
||||||
"Arguments:\n"
|
|
||||||
" -q Query mode: only report offset and length, do not dump\n"
|
|
||||||
" core_file Core dump produced by haproxy\n",
|
|
||||||
progname);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
Elf64_Ehdr *ehdr;
|
|
||||||
Elf64_Phdr *phdr;
|
|
||||||
struct stat st;
|
|
||||||
uint8_t *mem;
|
|
||||||
int i, fd;
|
|
||||||
const char *fname;
|
|
||||||
int quiet = 0;
|
|
||||||
int arg;
|
|
||||||
|
|
||||||
for (arg = 1; arg < argc; arg++) {
|
|
||||||
if (*argv[arg] != '-')
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (strcmp(argv[arg], "-q") == 0)
|
|
||||||
quiet = 1;
|
|
||||||
else if (strcmp(argv[arg], "--") == 0) {
|
|
||||||
arg++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arg < argc) {
|
|
||||||
fname = argv[arg];
|
|
||||||
} else {
|
|
||||||
usage(argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = open(fname, O_RDONLY);
|
|
||||||
|
|
||||||
/* Let's just map the core dump as an ELF header */
|
|
||||||
fstat(fd, &st);
|
|
||||||
mem = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
||||||
if (mem == MAP_FAILED) {
|
|
||||||
perror("mmap()");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the program headers */
|
|
||||||
ehdr = (Elf64_Ehdr *)mem;
|
|
||||||
|
|
||||||
/* check that it's really a core. Should be "\x7fELF" */
|
|
||||||
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
|
|
||||||
fprintf(stderr, "ELF magic not found.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) {
|
|
||||||
fprintf(stderr, "Only 64-bit ELF supported.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ehdr->e_type != ET_CORE) {
|
|
||||||
fprintf(stderr, "ELF type %d, not a core dump.\n", ehdr->e_type);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OK we can safely go with program headers */
|
|
||||||
phdr = (Elf64_Phdr *)(mem + ehdr->e_phoff);
|
|
||||||
|
|
||||||
for (i = 0; i < ehdr->e_phnum; i++) {
|
|
||||||
uint64_t size = phdr[i].p_filesz;
|
|
||||||
uint64_t offset = phdr[i].p_offset;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (phdr[i].p_type != PT_LOAD)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//fprintf(stderr, "Scanning segment %d...\n", ehdr->e_phnum);
|
|
||||||
//fprintf(stderr, "\r%-5d: off=%lx va=%lx sz=%lx ", i, (long)offset, (long)phdr[i].p_vaddr, (long)size);
|
|
||||||
if (!size)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (size < 512) // minimum for a tar header
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* tar magic */
|
|
||||||
if (memcmp(mem + offset + 257, "ustar\0""00", 8) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* uid, gid */
|
|
||||||
if (memcmp(mem + offset + 108, "0000000\0""0000000\0", 16) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* link name */
|
|
||||||
if (memcmp(mem + offset + 157, "haproxy-libs-dump\0", 18) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* OK that's really it */
|
|
||||||
|
|
||||||
if (quiet)
|
|
||||||
printf("offset=%#lx size=%#lx\n", offset, size);
|
|
||||||
else
|
|
||||||
ret = (write(1, mem + offset, size) == size) ? 0 : 1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
//fprintf(stderr, "\r%75s\n", "\r");
|
|
||||||
fprintf(stderr, "libs archive not found. Was 'set-dumpable' set to 'libs' ?\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@ -86,7 +86,7 @@ maintenance model and what the user wants is passed, then the LLM is invited to
|
|||||||
provide its opinion on the need for a backport and an explanation of the reason
|
provide its opinion on the need for a backport and an explanation of the reason
|
||||||
for its choice. This often helps the user to find a quick summary about the
|
for its choice. This often helps the user to find a quick summary about the
|
||||||
patch. All these outputs are then converted to a long HTML page with colors and
|
patch. All these outputs are then converted to a long HTML page with colors and
|
||||||
radio buttons, where patches are preselected based on this classification,
|
radio buttons, where patches are pre-selected based on this classification,
|
||||||
that the user can consult and adjust, read the commits if needed, and the
|
that the user can consult and adjust, read the commits if needed, and the
|
||||||
selected patches finally provide some copy-pastable commands in a text-area to
|
selected patches finally provide some copy-pastable commands in a text-area to
|
||||||
select commit IDs to work on, typically in a form that's suitable for a simple
|
select commit IDs to work on, typically in a form that's suitable for a simple
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -58,13 +58,8 @@ versions. It displays its usage when run without argument or wrong arguments:
|
|||||||
-T <line> : multiple option; append <line> to the "traces" section
|
-T <line> : multiple option; append <line> to the "traces" section
|
||||||
-C : dump the configuration and exit
|
-C : dump the configuration and exit
|
||||||
-D : goes daemon
|
-D : goes daemon
|
||||||
-b <keysize> : RSA key size in bits (ex: "2048", "4096"...)
|
|
||||||
-c <curves> : ECSDA curves (ex: "P-256", "P-384"...)
|
|
||||||
-v : shows version
|
-v : shows version
|
||||||
-d : enable the traces for all http protocols
|
-d : enable the traces for all http protocols
|
||||||
--quic-bind-opts <opts> : append options to QUIC "bind" lines
|
|
||||||
--tcp-bind-opts <opts> : append options to TCP "bind" lines
|
|
||||||
|
|
||||||
|
|
||||||
Arguments -G, -F, -T permit to append one or multiple lines at the end of their
|
Arguments -G, -F, -T permit to append one or multiple lines at the end of their
|
||||||
respective sections. A tab character ('\t') is prepended at the beginning of
|
respective sections. A tab character ('\t') is prepended at the beginning of
|
||||||
@ -134,7 +129,7 @@ HATerm:
|
|||||||
- /?R=<enable> Enable sending random data if >0.
|
- /?R=<enable> Enable sending random data if >0.
|
||||||
|
|
||||||
Note that those arguments may be cumulated on one line separated by a set of
|
Note that those arguments may be cumulated on one line separated by a set of
|
||||||
delimiters among [&?,;/] :
|
delimitors among [&?,;/] :
|
||||||
- GET /?s=20k&c=1&t=700&K=30r HTTP/1.0
|
- GET /?s=20k&c=1&t=700&K=30r HTTP/1.0
|
||||||
- GET /?r=500?s=0?c=0?t=1000 HTTP/1.0
|
- GET /?r=500?s=0?c=0?t=1000 HTTP/1.0
|
||||||
|
|
||||||
|
|||||||
@ -539,22 +539,10 @@ message. These functions are used by HTX analyzers or by multiplexers.
|
|||||||
with the first block not removed, or NULL if everything was removed, and
|
with the first block not removed, or NULL if everything was removed, and
|
||||||
the amount of data drained.
|
the amount of data drained.
|
||||||
|
|
||||||
- htx_xfer() transfers HTX blocks from an HTX message to another, stopping
|
- htx_xfer_blks() transfers HTX blocks from an HTX message to another,
|
||||||
when a specific amount of bytes, including meta-data, was copied. If the
|
stopping after the first block of a specified type is transferred or when
|
||||||
tail block is a DATA block, it may be partially copied. All other block
|
a specific amount of bytes, including meta-data, was moved. If the tail
|
||||||
are transferred at once. By default, copied blocks are removed from the
|
block is a DATA block, it may be partially moved. All other block are
|
||||||
original HTX message and headers and trailers parts cannot be partially
|
|
||||||
copied. But flags can be set to change the default behavior:
|
|
||||||
|
|
||||||
- HTX_XFER_KEEP_SRC_BLKS: source blocks are not removed
|
|
||||||
- HTX_XFER_PARTIAL_HDRS_COPY: partial headers and trailers
|
|
||||||
part can be xferred
|
|
||||||
- HTX_XFER_HDRS_ONLY: Only the headers part is xferred
|
|
||||||
|
|
||||||
- htx_xfer_blks() [DEPRECATED] transfers HTX blocks from an HTX message to
|
|
||||||
another, stopping after the first block of a specified type is transferred
|
|
||||||
or when a specific amount of bytes, including meta-data, was moved. If the
|
|
||||||
tail block is a DATA block, it may be partially moved. All other block are
|
|
||||||
transferred at once or kept. This function returns a mixed value, with the
|
transferred at once or kept. This function returns a mixed value, with the
|
||||||
last block moved, or NULL if nothing was moved, and the amount of data
|
last block moved, or NULL if nothing was moved, and the amount of data
|
||||||
transferred. When HEADERS or TRAILERS blocks must be transferred, this
|
transferred. When HEADERS or TRAILERS blocks must be transferred, this
|
||||||
|
|||||||
@ -114,7 +114,7 @@ SHUT RDY ACT
|
|||||||
1 1 1 => shut pending
|
1 1 1 => shut pending
|
||||||
|
|
||||||
PB: we can land into final shut if one thread disables the FD while another
|
PB: we can land into final shut if one thread disables the FD while another
|
||||||
one that was waiting on it reports it as shut. Theoretically it should be
|
one that was waiting on it reports it as shut. Theorically it should be
|
||||||
implicitly ready though, since reported. But if no data is reported, it
|
implicitly ready though, since reported. But if no data is reported, it
|
||||||
will be reportedly shut only. And no event will be reported then. This
|
will be reportedly shut only. And no event will be reported then. This
|
||||||
might still make sense since it's not active, thus we don't want events.
|
might still make sense since it's not active, thus we don't want events.
|
||||||
|
|||||||
@ -1,50 +0,0 @@
|
|||||||
2026-03-12 - thread execution context
|
|
||||||
|
|
||||||
Thread execution context (thread_exec_ctx) is a combination of type and pointer
|
|
||||||
that are set in the current running thread at th_ctx->exec_ctx when entering
|
|
||||||
certain processing (tasks, sample fetch functions, actions, CLI keywords etc).
|
|
||||||
They're refined along execution, so that a task such as process_stream could
|
|
||||||
temporarily switch to a converter while evaluating an expression and switch
|
|
||||||
back to process_stream. They are reported in thread dumps and are mixed with
|
|
||||||
caller locations for memory profiling. As such they are intentionally not too
|
|
||||||
precise in order to avoid an explosion of the number of buckets. At the moment,
|
|
||||||
the level of granularity it provides is sufficient to try to narrow a
|
|
||||||
misbehaving origin down to a list of keywords. The context types can currently
|
|
||||||
be:
|
|
||||||
|
|
||||||
- something registered via an initcall, with the initcall's location
|
|
||||||
- something registered via an ha_caller, with the caller's location
|
|
||||||
- an explicit sample fetch / converter / action / CLI keyword list
|
|
||||||
- an explicit function (mainly used for actions without keywords)
|
|
||||||
- a task / tasklet (no distinction is made), using the ->process pointer
|
|
||||||
- a filter (e.g. compression), via flt_conf, reporting name
|
|
||||||
- a mux (via the mux_ops, reporting the name)
|
|
||||||
- an applet (e.g. cache, stats, CLI)
|
|
||||||
|
|
||||||
A macro EXEC_CTX_MAKE(type, pointer) makes a thread_exec_ctx from such
|
|
||||||
values.
|
|
||||||
|
|
||||||
A macro EXEC_CTX_NO_RET(ctx, statement) calls a void statement under the
|
|
||||||
specified context.
|
|
||||||
|
|
||||||
A macro EXEC_CTX_WITH_RET(ctx, expr) calls an expression under the specified
|
|
||||||
context.
|
|
||||||
|
|
||||||
Most locations were modified to directly use these macros on the fly, by
|
|
||||||
retrieving the context from where it was set on the element being evaluated
|
|
||||||
(e.g. an action rule contains the context inherited by the action keyword
|
|
||||||
that was used to create it).
|
|
||||||
|
|
||||||
In tools.c, chunk_append_thread_ctx() tries to decode the given exec_ctx and
|
|
||||||
appends it into the provided buffer. It's used by ha_thread_dump_one() and
|
|
||||||
cli_io_handler_show_activity() for memory profiling. In this latter case,
|
|
||||||
the detected thread_ctx are reported in the output under brackets prefixed
|
|
||||||
with "[via ...]" to distinguish call paths to the same allocators.
|
|
||||||
|
|
||||||
A good way to test if a context is properly reported is to place a bleeding
|
|
||||||
malloc() call into one of the monitored functions, e.g.:
|
|
||||||
|
|
||||||
DISGUISE(malloc(8));
|
|
||||||
|
|
||||||
and issue "show profiling memory" after stressing the function. Its context
|
|
||||||
must appear on the right with the number of calls.
|
|
||||||
@ -1731,7 +1731,7 @@ add backend <name> from <defproxy> [mode <mode>] [guid <guid>] [ EXPERIMENTAL ]
|
|||||||
Only TCP or HTTP proxies can be created. All of the settings are inherited
|
Only TCP or HTTP proxies can be created. All of the settings are inherited
|
||||||
from <defproxy> default proxy instance. By default, it is mandatory to
|
from <defproxy> default proxy instance. By default, it is mandatory to
|
||||||
specify the backend mode via the argument of the same name, unless <defproxy>
|
specify the backend mode via the argument of the same name, unless <defproxy>
|
||||||
already defines it explicitly. It is also possible to use an optional GUID
|
already defines it explicitely. It is also possible to use an optional GUID
|
||||||
argument if wanted.
|
argument if wanted.
|
||||||
|
|
||||||
Servers can be added via the command "add server". The backend is initialized
|
Servers can be added via the command "add server". The backend is initialized
|
||||||
@ -1740,7 +1740,10 @@ add backend <name> from <defproxy> [mode <mode>] [guid <guid>] [ EXPERIMENTAL ]
|
|||||||
|
|
||||||
All named default proxies can be used, given that they validate the same
|
All named default proxies can be used, given that they validate the same
|
||||||
inheritance rules applied during configuration parsing. There is some
|
inheritance rules applied during configuration parsing. There is some
|
||||||
exceptions though, for example when the mode is neither TCP nor HTTP.
|
exceptions though, for example when the mode is neither TCP nor HTTP. Another
|
||||||
|
exception is that it is not yet possible to use a default proxies which
|
||||||
|
reference custom HTTP errors, for example via the errorfiles or http-rules
|
||||||
|
keywords.
|
||||||
|
|
||||||
This command is restricted and can only be issued on sockets configured for
|
This command is restricted and can only be issued on sockets configured for
|
||||||
level "admin". Moreover, this feature is still considered in development so it
|
level "admin". Moreover, this feature is still considered in development so it
|
||||||
@ -2121,30 +2124,6 @@ del acl <acl> [<key>|#<ref>]
|
|||||||
listing the content of the acl. Note that if the reference <acl> is a name and
|
listing the content of the acl. Note that if the reference <acl> is a name and
|
||||||
is shared with a map, the entry will be also deleted in the map.
|
is shared with a map, the entry will be also deleted in the map.
|
||||||
|
|
||||||
del backend <name>
|
|
||||||
Removes the backend proxy with the name <name>.
|
|
||||||
|
|
||||||
This operation is only possible for TCP or HTTP proxies. To succeed, the
|
|
||||||
backend instance must have been first unpublished. Also, all of its servers
|
|
||||||
must first be removed (via "del server" CLI). Finally, no stream must still
|
|
||||||
be attached to the backend instance.
|
|
||||||
|
|
||||||
There is additional restrictions which prevent backend removal. First, a
|
|
||||||
backend cannot be removed if it is explicitly referenced by config elements,
|
|
||||||
for example via a use_backend rule or in sample expressions. Some proxies
|
|
||||||
options are also incompatible with runtime deletion. Currently, this is the
|
|
||||||
case when deprecated dispatch or option transparent are used. Also, a backend
|
|
||||||
cannot be removed if there is a stick-table declared in it. Finally, it is
|
|
||||||
impossible for now to remove a backend if QUIC servers were present in it.
|
|
||||||
|
|
||||||
It can be useful to use "wait be-removable" prior to this command to check
|
|
||||||
for the aforementioned requisites. This also provides a method to wait for
|
|
||||||
the final closure of the streams attached to the target backend.
|
|
||||||
|
|
||||||
This command is restricted and can only be issued on sockets configured for
|
|
||||||
level "admin". Moreover, this feature is still considered in development so it
|
|
||||||
also requires experimental mode (see "experimental-mode on").
|
|
||||||
|
|
||||||
del map <map> [<key>|#<ref>]
|
del map <map> [<key>|#<ref>]
|
||||||
Delete all the map entries from the map <map> corresponding to the key <key>.
|
Delete all the map entries from the map <map> corresponding to the key <key>.
|
||||||
<map> is the #<id> or the <name> returned by "show map". If the <ref> is used,
|
<map> is the #<id> or the <name> returned by "show map". If the <ref> is used,
|
||||||
@ -3356,7 +3335,7 @@ show pools [byname|bysize|byusage] [detailed] [match <pfx>] [<nb>]
|
|||||||
- Pool quic_conn_c (152 bytes) : 1337 allocated (203224 bytes), ...
|
- Pool quic_conn_c (152 bytes) : 1337 allocated (203224 bytes), ...
|
||||||
Total: 15 pools, 109578176 bytes allocated, 109578176 used ...
|
Total: 15 pools, 109578176 bytes allocated, 109578176 used ...
|
||||||
|
|
||||||
show profiling [{all | status | tasks | memory}] [byaddr|bytime|byctx|aggr|<max_lines>]*
|
show profiling [{all | status | tasks | memory}] [byaddr|bytime|aggr|<max_lines>]*
|
||||||
Dumps the current profiling settings, one per line, as well as the command
|
Dumps the current profiling settings, one per line, as well as the command
|
||||||
needed to change them. When tasks profiling is enabled, some per-function
|
needed to change them. When tasks profiling is enabled, some per-function
|
||||||
statistics collected by the scheduler will also be emitted, with a summary
|
statistics collected by the scheduler will also be emitted, with a summary
|
||||||
@ -3365,15 +3344,14 @@ show profiling [{all | status | tasks | memory}] [byaddr|bytime|byctx|aggr|<max_
|
|||||||
allocations/releases and their sizes will be reported. It is possible to
|
allocations/releases and their sizes will be reported. It is possible to
|
||||||
limit the dump to only the profiling status, the tasks, or the memory
|
limit the dump to only the profiling status, the tasks, or the memory
|
||||||
profiling by specifying the respective keywords; by default all profiling
|
profiling by specifying the respective keywords; by default all profiling
|
||||||
information are dumped. It is also possible to limit the number of lines of
|
information are dumped. It is also possible to limit the number of lines
|
||||||
of output of each category by specifying a numeric limit. If is possible to
|
of output of each category by specifying a numeric limit. If is possible to
|
||||||
request that the output is sorted by address, by total execution time, or by
|
request that the output is sorted by address or by total execution time
|
||||||
calling context instead of usage, e.g. to ease comparisons between subsequent
|
instead of usage, e.g. to ease comparisons between subsequent calls or to
|
||||||
calls or to check what needs to be optimized, and to aggregate task activity
|
check what needs to be optimized, and to aggregate task activity by called
|
||||||
by called function instead of seeing the details. Please note that profiling
|
function instead of seeing the details. Please note that profiling is
|
||||||
is essentially aimed at developers since it gives hints about where CPU
|
essentially aimed at developers since it gives hints about where CPU cycles
|
||||||
cycles or memory are wasted in the code. There is nothing useful to monitor
|
or memory are wasted in the code. There is nothing useful to monitor there.
|
||||||
there.
|
|
||||||
|
|
||||||
show resolvers [<resolvers section id>]
|
show resolvers [<resolvers section id>]
|
||||||
Dump statistics for the given resolvers section, or all resolvers sections
|
Dump statistics for the given resolvers section, or all resolvers sections
|
||||||
@ -4548,13 +4526,6 @@ wait { -h | <delay> } [<condition> [<args>...]]
|
|||||||
specified condition to be satisfied, to unrecoverably fail, or to remain
|
specified condition to be satisfied, to unrecoverably fail, or to remain
|
||||||
unsatisfied for the whole <delay> duration. The supported conditions are:
|
unsatisfied for the whole <delay> duration. The supported conditions are:
|
||||||
|
|
||||||
- be-removable <proxy> : this will wait for the specified proxy backend to be
|
|
||||||
removable by the "del backend" command. Some conditions will never be
|
|
||||||
accepted (e.g. backend not yet unpublished or with servers in it) and will
|
|
||||||
cause the report of a specific error message indicating what condition is
|
|
||||||
not met. If everything is OK before the delay, a success is returned and
|
|
||||||
the operation is terminated.
|
|
||||||
|
|
||||||
- srv-removable <proxy>/<server> : this will wait for the specified server to
|
- srv-removable <proxy>/<server> : this will wait for the specified server to
|
||||||
be removable by the "del server" command, i.e. be in maintenance and no
|
be removable by the "del server" command, i.e. be in maintenance and no
|
||||||
longer have any connection on it (neither active or idle). Some conditions
|
longer have any connection on it (neither active or idle). Some conditions
|
||||||
|
|||||||
@ -1,69 +0,0 @@
|
|||||||
# Example: log HTTP traffic and TLS session keys to separate destinations
|
|
||||||
#
|
|
||||||
# "option httpslog" sends HTTP access logs to the /dev/log syslog server.
|
|
||||||
# TLS session keys are written to 2 ring buffers.
|
|
||||||
#
|
|
||||||
# Requirements:
|
|
||||||
# - HAProxy built with OpenSSL support
|
|
||||||
# - "tune.ssl.keylog on" in the global section
|
|
||||||
#
|
|
||||||
# Retrieve TLS session keys from the ring buffer via the CLI:
|
|
||||||
# For frontend connections:
|
|
||||||
#
|
|
||||||
# (echo "show events keylog-fc -w"; read) | socat /tmp/worker.socket -
|
|
||||||
#
|
|
||||||
# For backend connections:
|
|
||||||
#
|
|
||||||
# (echo "show events keylog-bc -w"; read) | socat /tmp/worker.socket -
|
|
||||||
#
|
|
||||||
# The result is in SSLKEYLOGFILE format and can be saved to a file and loaded
|
|
||||||
# into Wireshark to decrypt captured TLS traffic.
|
|
||||||
|
|
||||||
global
|
|
||||||
stats socket /tmp/worker.socket mode 0660
|
|
||||||
tune.ssl.keylog on
|
|
||||||
|
|
||||||
# Ring buffer for TLS session keys.
|
|
||||||
# "format raw" stores only the log message text, without any syslog envelope,
|
|
||||||
# producing output in the SSLKEYLOGFILE format directly.
|
|
||||||
ring keylog-fc
|
|
||||||
description "TLS session key frontend log"
|
|
||||||
format raw
|
|
||||||
maxlen 2000
|
|
||||||
size 1M
|
|
||||||
|
|
||||||
ring keylog-bc
|
|
||||||
description "TLS session key backend log"
|
|
||||||
format raw
|
|
||||||
maxlen 2000
|
|
||||||
size 1M
|
|
||||||
|
|
||||||
|
|
||||||
defaults
|
|
||||||
mode http
|
|
||||||
timeout client 30s
|
|
||||||
timeout server 30s
|
|
||||||
timeout connect 5s
|
|
||||||
|
|
||||||
log-profile keylog-fc
|
|
||||||
on any format "${HAPROXY_KEYLOG_FC_LOG_FMT}"
|
|
||||||
|
|
||||||
log-profile keylog-bc
|
|
||||||
on any format "${HAPROXY_KEYLOG_BC_LOG_FMT}"
|
|
||||||
|
|
||||||
frontend https-in
|
|
||||||
bind :443 ssl crt "common.pem"
|
|
||||||
|
|
||||||
option httpslog
|
|
||||||
|
|
||||||
# HTTPs access logs sent to the syslog server
|
|
||||||
log /dev/log format raw local0
|
|
||||||
|
|
||||||
# TLS session keys written to the ring buffer
|
|
||||||
log ring@keylog-fc profile keylog-fc local1
|
|
||||||
log ring@keylog-bc profile keylog-bc local1
|
|
||||||
|
|
||||||
default_backend be1
|
|
||||||
|
|
||||||
backend be1
|
|
||||||
server s1 10.0.0.123:443 ssl verify none
|
|
||||||
@ -2,29 +2,17 @@
|
|||||||
#ifndef _ACME_T_H_
|
#ifndef _ACME_T_H_
|
||||||
#define _ACME_T_H_
|
#define _ACME_T_H_
|
||||||
|
|
||||||
#include <haproxy/acme_resolvers-t.h>
|
|
||||||
#include <haproxy/istbuf.h>
|
#include <haproxy/istbuf.h>
|
||||||
#include <haproxy/openssl-compat.h>
|
#include <haproxy/openssl-compat.h>
|
||||||
|
|
||||||
#if defined(HAVE_ACME)
|
|
||||||
|
|
||||||
#define ACME_RETRY 5
|
#define ACME_RETRY 5
|
||||||
|
|
||||||
/* Readiness requirements for challenge */
|
|
||||||
#define ACME_RDY_NONE 0x00
|
|
||||||
#define ACME_RDY_CLI 0x01
|
|
||||||
#define ACME_RDY_DNS 0x02
|
|
||||||
#define ACME_RDY_DELAY 0x04
|
|
||||||
|
|
||||||
/* acme section configuration */
|
/* acme section configuration */
|
||||||
struct acme_cfg {
|
struct acme_cfg {
|
||||||
char *filename; /* config filename */
|
char *filename; /* config filename */
|
||||||
int linenum; /* config linenum */
|
int linenum; /* config linenum */
|
||||||
char *name; /* section name */
|
char *name; /* section name */
|
||||||
int reuse_key; /* do we need to renew the private key */
|
int reuse_key; /* do we need to renew the private key */
|
||||||
int cond_ready; /* ready condition */
|
|
||||||
unsigned int dns_delay; /* delay in seconds before re-triggering DNS resolution (default: 300) */
|
|
||||||
unsigned int dns_timeout; /* time after which the DNS check shouldn't be retried (default: 600) */
|
|
||||||
char *directory; /* directory URL */
|
char *directory; /* directory URL */
|
||||||
char *map; /* storage for tokens + thumbprint */
|
char *map; /* storage for tokens + thumbprint */
|
||||||
struct {
|
struct {
|
||||||
@ -52,11 +40,6 @@ enum acme_st {
|
|||||||
ACME_NEWACCOUNT,
|
ACME_NEWACCOUNT,
|
||||||
ACME_NEWORDER,
|
ACME_NEWORDER,
|
||||||
ACME_AUTH,
|
ACME_AUTH,
|
||||||
ACME_CLI_WAIT, /* wait for the ACME_RDY_CLI */
|
|
||||||
ACME_INITIAL_DELAY,
|
|
||||||
ACME_RSLV_RETRY_DELAY,
|
|
||||||
ACME_RSLV_TRIGGER,
|
|
||||||
ACME_RSLV_READY,
|
|
||||||
ACME_CHALLENGE,
|
ACME_CHALLENGE,
|
||||||
ACME_CHKCHALLENGE,
|
ACME_CHKCHALLENGE,
|
||||||
ACME_FINALIZE,
|
ACME_FINALIZE,
|
||||||
@ -75,8 +58,6 @@ struct acme_auth {
|
|||||||
struct ist auth; /* auth URI */
|
struct ist auth; /* auth URI */
|
||||||
struct ist chall; /* challenge URI */
|
struct ist chall; /* challenge URI */
|
||||||
struct ist token; /* token */
|
struct ist token; /* token */
|
||||||
int validated; /* already validated */
|
|
||||||
struct acme_rslv *rslv; /* acme dns-01 resolver */
|
|
||||||
int ready; /* is the challenge ready ? */
|
int ready; /* is the challenge ready ? */
|
||||||
void *next;
|
void *next;
|
||||||
};
|
};
|
||||||
@ -103,8 +84,6 @@ struct acme_ctx {
|
|||||||
X509_REQ *req;
|
X509_REQ *req;
|
||||||
struct ist finalize;
|
struct ist finalize;
|
||||||
struct ist certificate;
|
struct ist certificate;
|
||||||
unsigned int dnstasks; /* number of DNS tasks running for this ctx */
|
|
||||||
unsigned int dnsstarttime; /* time at which we started the DNS checks */
|
|
||||||
struct task *task;
|
struct task *task;
|
||||||
struct ebmb_node node;
|
struct ebmb_node node;
|
||||||
char name[VAR_ARRAY];
|
char name[VAR_ARRAY];
|
||||||
@ -122,6 +101,4 @@ struct acme_ctx {
|
|||||||
#define ACME_VERB_ADVANCED 4
|
#define ACME_VERB_ADVANCED 4
|
||||||
#define ACME_VERB_COMPLETE 5
|
#define ACME_VERB_COMPLETE 5
|
||||||
|
|
||||||
#endif /* ! HAVE_ACME */
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
#ifndef _HAPROXY_ACME_RESOLVERS_T_H
|
|
||||||
#define _HAPROXY_ACME_RESOLVERS_T_H
|
|
||||||
|
|
||||||
#include <haproxy/obj_type-t.h>
|
|
||||||
#include <haproxy/resolvers-t.h>
|
|
||||||
|
|
||||||
struct dns_counters;
|
|
||||||
|
|
||||||
/* TXT records for dns-01 */
|
|
||||||
|
|
||||||
struct acme_rslv {
|
|
||||||
enum obj_type obj_type; /* OBJ_TYPE_ACME_RSLV */
|
|
||||||
unsigned int *dnstasks; /* number of running DNS resolution for the same acme_task */
|
|
||||||
char *hostname_dn;
|
|
||||||
int hostname_dn_len;
|
|
||||||
struct resolvers *resolvers;
|
|
||||||
struct resolv_requester *requester;
|
|
||||||
int result; /* RSLV_STATUS_* — NONE until done */
|
|
||||||
int error_code; /* RSLV_RESP_* from the error callback */
|
|
||||||
struct task *acme_task; /* ACME task to wake on completion, or NULL */
|
|
||||||
struct ist txt; /* first TXT record found */
|
|
||||||
int (*success_cb)(struct resolv_requester *, struct dns_counters *);
|
|
||||||
int (*error_cb)(struct resolv_requester *, int);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_ACME_RESOLVERS_T_H */
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
#ifndef _HAPROXY_ACME_RESOLVERS_H
|
|
||||||
#define _HAPROXY_ACME_RESOLVERS_H
|
|
||||||
|
|
||||||
#include <haproxy/openssl-compat.h>
|
|
||||||
|
|
||||||
#if defined(HAVE_ACME)
|
|
||||||
|
|
||||||
#include <haproxy/acme_resolvers-t.h>
|
|
||||||
#include <haproxy/acme-t.h>
|
|
||||||
#include <haproxy/resolvers-t.h>
|
|
||||||
|
|
||||||
struct acme_rslv *acme_rslv_start(struct acme_auth *auth, unsigned int *dnstasks, char **errmsg);
|
|
||||||
void acme_rslv_free(struct acme_rslv *rslv);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_ACME_RESOLVERS_H */
|
|
||||||
@ -151,7 +151,6 @@ struct act_rule {
|
|||||||
struct ist str; /* string param (reason, header name, ...) */
|
struct ist str; /* string param (reason, header name, ...) */
|
||||||
struct lf_expr fmt; /* log-format compatible expression */
|
struct lf_expr fmt; /* log-format compatible expression */
|
||||||
struct my_regex *re; /* used by replace-header/value/uri/path */
|
struct my_regex *re; /* used by replace-header/value/uri/path */
|
||||||
struct sample_expr *expr; /* sample expression used by HTTP action */
|
|
||||||
} http; /* args used by some HTTP rules */
|
} http; /* args used by some HTTP rules */
|
||||||
struct http_reply *http_reply; /* HTTP response to be used by return/deny/tarpit rules */
|
struct http_reply *http_reply; /* HTTP response to be used by return/deny/tarpit rules */
|
||||||
struct redirect_rule *redir; /* redirect rule or "http-request redirect" */
|
struct redirect_rule *redir; /* redirect rule or "http-request redirect" */
|
||||||
@ -199,11 +198,6 @@ struct act_rule {
|
|||||||
struct server *srv; /* target server to attach the connection */
|
struct server *srv; /* target server to attach the connection */
|
||||||
struct sample_expr *name; /* used to differentiate idle connections */
|
struct sample_expr *name; /* used to differentiate idle connections */
|
||||||
} attach_srv; /* 'attach-srv' rule */
|
} attach_srv; /* 'attach-srv' rule */
|
||||||
struct {
|
|
||||||
enum log_orig_id orig;
|
|
||||||
char *profile_name;
|
|
||||||
struct log_profile *profile;
|
|
||||||
} do_log; /* 'do-log' action */
|
|
||||||
struct {
|
struct {
|
||||||
int value;
|
int value;
|
||||||
struct sample_expr *expr;
|
struct sample_expr *expr;
|
||||||
@ -212,7 +206,6 @@ struct act_rule {
|
|||||||
void *p[4];
|
void *p[4];
|
||||||
} act; /* generic pointers to be used by custom actions */
|
} act; /* generic pointers to be used by custom actions */
|
||||||
} arg; /* arguments used by some actions */
|
} arg; /* arguments used by some actions */
|
||||||
struct thread_exec_ctx exec_ctx; /* execution context */
|
|
||||||
struct {
|
struct {
|
||||||
char *file; /* file name where the rule appears (or NULL) */
|
char *file; /* file name where the rule appears (or NULL) */
|
||||||
int line; /* line number where the rule appears */
|
int line; /* line number where the rule appears */
|
||||||
@ -224,9 +217,7 @@ struct action_kw {
|
|||||||
enum act_parse_ret (*parse)(const char **args, int *cur_arg, struct proxy *px,
|
enum act_parse_ret (*parse)(const char **args, int *cur_arg, struct proxy *px,
|
||||||
struct act_rule *rule, char **err);
|
struct act_rule *rule, char **err);
|
||||||
int flags;
|
int flags;
|
||||||
/* 4 bytes here */
|
|
||||||
void *private;
|
void *private;
|
||||||
struct thread_exec_ctx exec_ctx; /* execution context */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct action_kw_list {
|
struct action_kw_list {
|
||||||
|
|||||||
@ -35,7 +35,6 @@ int act_resolution_cb(struct resolv_requester *requester, struct dns_counters *c
|
|||||||
int act_resolution_error_cb(struct resolv_requester *requester, int error_code);
|
int act_resolution_error_cb(struct resolv_requester *requester, int error_code);
|
||||||
const char *action_suggest(const char *word, const struct list *keywords, const char **extra);
|
const char *action_suggest(const char *word, const struct list *keywords, const char **extra);
|
||||||
void free_act_rule(struct act_rule *rule);
|
void free_act_rule(struct act_rule *rule);
|
||||||
void act_add_list(struct list *head, struct action_kw_list *kw_list);
|
|
||||||
|
|
||||||
static inline struct action_kw *action_lookup(struct list *keywords, const char *kw)
|
static inline struct action_kw *action_lookup(struct list *keywords, const char *kw)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
#include <haproxy/api-t.h>
|
#include <haproxy/api-t.h>
|
||||||
#include <haproxy/freq_ctr-t.h>
|
#include <haproxy/freq_ctr-t.h>
|
||||||
#include <haproxy/tinfo-t.h>
|
|
||||||
|
|
||||||
/* bit fields for the "profiling" global variable */
|
/* bit fields for the "profiling" global variable */
|
||||||
#define HA_PROF_TASKS_OFF 0x00000000 /* per-task CPU profiling forced disabled */
|
#define HA_PROF_TASKS_OFF 0x00000000 /* per-task CPU profiling forced disabled */
|
||||||
@ -85,7 +84,6 @@ struct memprof_stats {
|
|||||||
unsigned long long alloc_tot;
|
unsigned long long alloc_tot;
|
||||||
unsigned long long free_tot;
|
unsigned long long free_tot;
|
||||||
void *info; // for pools, ptr to the pool
|
void *info; // for pools, ptr to the pool
|
||||||
struct thread_exec_ctx exec_ctx;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -130,7 +130,6 @@ struct appctx {
|
|||||||
int (*io_handler)(struct appctx *appctx); /* used within the cli_io_handler when st0 = CLI_ST_CALLBACK */
|
int (*io_handler)(struct appctx *appctx); /* used within the cli_io_handler when st0 = CLI_ST_CALLBACK */
|
||||||
void (*io_release)(struct appctx *appctx); /* used within the cli_io_handler when st0 = CLI_ST_CALLBACK,
|
void (*io_release)(struct appctx *appctx); /* used within the cli_io_handler when st0 = CLI_ST_CALLBACK,
|
||||||
if the command is terminated or the session released */
|
if the command is terminated or the session released */
|
||||||
struct cli_kw *kw; /* the keyword being processed */
|
|
||||||
} cli_ctx; /* context dedicated to the CLI applet */
|
} cli_ctx; /* context dedicated to the CLI applet */
|
||||||
|
|
||||||
struct buffer_wait buffer_wait; /* position in the list of objects waiting for a buffer */
|
struct buffer_wait buffer_wait; /* position in the list of objects waiting for a buffer */
|
||||||
|
|||||||
@ -62,13 +62,6 @@ ssize_t applet_append_line(void *ctx, struct ist v1, struct ist v2, size_t ofs,
|
|||||||
static forceinline void applet_fl_set(struct appctx *appctx, uint on);
|
static forceinline void applet_fl_set(struct appctx *appctx, uint on);
|
||||||
static forceinline void applet_fl_clr(struct appctx *appctx, uint off);
|
static forceinline void applet_fl_clr(struct appctx *appctx, uint off);
|
||||||
|
|
||||||
/* macros to switch the calling context to the applet during a call. There's
|
|
||||||
* one with a return value for most calls, and one without for the few like
|
|
||||||
* fct(), shut(), or release() with no return.
|
|
||||||
*/
|
|
||||||
#define CALL_APPLET_WITH_RET(applet, func) EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_APPLET, (applet)), (applet)->func)
|
|
||||||
#define CALL_APPLET_NO_RET(applet, func) EXEC_CTX_NO_RET(EXEC_CTX_MAKE(TH_EX_CTX_APPLET, (applet)), (applet)->func)
|
|
||||||
|
|
||||||
|
|
||||||
static forceinline uint appctx_app_test(const struct appctx *appctx, uint test)
|
static forceinline uint appctx_app_test(const struct appctx *appctx, uint test)
|
||||||
{
|
{
|
||||||
@ -133,7 +126,7 @@ static inline int appctx_init(struct appctx *appctx)
|
|||||||
task_set_thread(appctx->t, tid);
|
task_set_thread(appctx->t, tid);
|
||||||
|
|
||||||
if (appctx->applet->init)
|
if (appctx->applet->init)
|
||||||
return CALL_APPLET_WITH_RET(appctx->applet, init(appctx));
|
return appctx->applet->init(appctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -99,11 +99,8 @@ static inline int be_is_eligible(const struct proxy *be)
|
|||||||
/* set the time of last session on the backend */
|
/* set the time of last session on the backend */
|
||||||
static inline void be_set_sess_last(struct proxy *be)
|
static inline void be_set_sess_last(struct proxy *be)
|
||||||
{
|
{
|
||||||
uint now_sec = ns_to_sec(now_ns);
|
|
||||||
|
|
||||||
if (be->be_counters.shared.tg)
|
if (be->be_counters.shared.tg)
|
||||||
if (HA_ATOMIC_LOAD(&be->be_counters.shared.tg[tgid - 1]->last_sess) != now_sec)
|
HA_ATOMIC_STORE(&be->be_counters.shared.tg[tgid - 1]->last_sess, ns_to_sec(now_ns));
|
||||||
HA_ATOMIC_STORE(&be->be_counters.shared.tg[tgid - 1]->last_sess, now_sec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function returns non-zero if the designated server will be
|
/* This function returns non-zero if the designated server will be
|
||||||
|
|||||||
@ -376,7 +376,6 @@ static inline void channel_add_input(struct channel *chn, unsigned int len)
|
|||||||
c_adv(chn, fwd);
|
c_adv(chn, fwd);
|
||||||
}
|
}
|
||||||
/* notify that some data was read */
|
/* notify that some data was read */
|
||||||
chn_prod(chn)->bytes_in += len;
|
|
||||||
chn->flags |= CF_READ_EVENT;
|
chn->flags |= CF_READ_EVENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,6 @@ enum chk_result {
|
|||||||
#define CHK_ST_FASTINTER 0x0400 /* force fastinter check */
|
#define CHK_ST_FASTINTER 0x0400 /* force fastinter check */
|
||||||
#define CHK_ST_READY 0x0800 /* check ready to migrate or run, see below */
|
#define CHK_ST_READY 0x0800 /* check ready to migrate or run, see below */
|
||||||
#define CHK_ST_SLEEPING 0x1000 /* check was sleeping, i.e. not currently bound to a thread, see below */
|
#define CHK_ST_SLEEPING 0x1000 /* check was sleeping, i.e. not currently bound to a thread, see below */
|
||||||
#define CHK_ST_USE_SMALL_BUFF 0x2000 /* Use small buffers if possible for the request */
|
|
||||||
|
|
||||||
/* 4 possible states for CHK_ST_SLEEPING and CHK_ST_READY:
|
/* 4 possible states for CHK_ST_SLEEPING and CHK_ST_READY:
|
||||||
* SLP RDY State Description
|
* SLP RDY State Description
|
||||||
@ -155,7 +154,7 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct tcpcheck_rule;
|
struct tcpcheck_rule;
|
||||||
struct tcpcheck;
|
struct tcpcheck_rules;
|
||||||
|
|
||||||
struct check {
|
struct check {
|
||||||
enum obj_type obj_type; /* object type == OBJ_TYPE_CHECK */
|
enum obj_type obj_type; /* object type == OBJ_TYPE_CHECK */
|
||||||
@ -174,7 +173,7 @@ struct check {
|
|||||||
signed char use_ssl; /* use SSL for health checks (1: on, 0: server mode, -1: off) */
|
signed char use_ssl; /* use SSL for health checks (1: on, 0: server mode, -1: off) */
|
||||||
int send_proxy; /* send a PROXY protocol header with checks */
|
int send_proxy; /* send a PROXY protocol header with checks */
|
||||||
int reuse_pool; /* try to reuse idle connections */
|
int reuse_pool; /* try to reuse idle connections */
|
||||||
struct tcpcheck *tcpcheck; /* tcp-check to use to perform a health-check */
|
struct tcpcheck_rules *tcpcheck_rules; /* tcp-check send / expect rules */
|
||||||
struct tcpcheck_rule *current_step; /* current step when using tcpcheck */
|
struct tcpcheck_rule *current_step; /* current step when using tcpcheck */
|
||||||
int inter, fastinter, downinter; /* checks: time in milliseconds */
|
int inter, fastinter, downinter; /* checks: time in milliseconds */
|
||||||
enum chk_result result; /* health-check result : CHK_RES_* */
|
enum chk_result result; /* health-check result : CHK_RES_* */
|
||||||
@ -189,7 +188,6 @@ struct check {
|
|||||||
char **envp; /* the environment to use if running a process-based check */
|
char **envp; /* the environment to use if running a process-based check */
|
||||||
struct pid_list *curpid; /* entry in pid_list used for current process-based test, or -1 if not in test */
|
struct pid_list *curpid; /* entry in pid_list used for current process-based test, or -1 if not in test */
|
||||||
struct sockaddr_storage addr; /* the address to check */
|
struct sockaddr_storage addr; /* the address to check */
|
||||||
struct protocol *proto; /* protocol used for check, may be different from the server's one */
|
|
||||||
char *pool_conn_name; /* conn name used on reuse */
|
char *pool_conn_name; /* conn name used on reuse */
|
||||||
char *sni; /* Server name */
|
char *sni; /* Server name */
|
||||||
char *alpn_str; /* ALPN to use for checks */
|
char *alpn_str; /* ALPN to use for checks */
|
||||||
|
|||||||
@ -78,11 +78,12 @@ struct task *process_chk(struct task *t, void *context, unsigned int state);
|
|||||||
struct task *srv_chk_io_cb(struct task *t, void *ctx, unsigned int state);
|
struct task *srv_chk_io_cb(struct task *t, void *ctx, unsigned int state);
|
||||||
|
|
||||||
int check_buf_available(void *target);
|
int check_buf_available(void *target);
|
||||||
struct buffer *check_get_buf(struct check *check, struct buffer *bptr, unsigned int small_buffer);
|
struct buffer *check_get_buf(struct check *check, struct buffer *bptr);
|
||||||
void check_release_buf(struct check *check, struct buffer *bptr);
|
void check_release_buf(struct check *check, struct buffer *bptr);
|
||||||
const char *init_check(struct check *check, int type);
|
const char *init_check(struct check *check, int type);
|
||||||
void free_check(struct check *check);
|
void free_check(struct check *check);
|
||||||
void check_purge(struct check *check);
|
void check_purge(struct check *check);
|
||||||
|
int wake_srv_chk(struct stconn *sc);
|
||||||
|
|
||||||
int init_srv_check(struct server *srv);
|
int init_srv_check(struct server *srv);
|
||||||
int init_srv_agent_check(struct server *srv);
|
int init_srv_agent_check(struct server *srv);
|
||||||
|
|||||||
@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
extern struct pool_head *pool_head_trash;
|
extern struct pool_head *pool_head_trash;
|
||||||
extern struct pool_head *pool_head_large_trash;
|
extern struct pool_head *pool_head_large_trash;
|
||||||
extern struct pool_head *pool_head_small_trash;
|
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
|
|
||||||
@ -49,7 +48,6 @@ int chunk_strcmp(const struct buffer *chk, const char *str);
|
|||||||
int chunk_strcasecmp(const struct buffer *chk, const char *str);
|
int chunk_strcasecmp(const struct buffer *chk, const char *str);
|
||||||
struct buffer *get_trash_chunk(void);
|
struct buffer *get_trash_chunk(void);
|
||||||
struct buffer *get_large_trash_chunk(void);
|
struct buffer *get_large_trash_chunk(void);
|
||||||
struct buffer *get_small_trash_chunk(void);
|
|
||||||
struct buffer *get_trash_chunk_sz(size_t size);
|
struct buffer *get_trash_chunk_sz(size_t size);
|
||||||
struct buffer *get_larger_trash_chunk(struct buffer *chunk);
|
struct buffer *get_larger_trash_chunk(struct buffer *chunk);
|
||||||
int init_trash_buffers(int first);
|
int init_trash_buffers(int first);
|
||||||
@ -135,29 +133,6 @@ static forceinline struct buffer *alloc_large_trash_chunk(void)
|
|||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate a small trash chunk from the reentrant pool. The buffer starts at
|
|
||||||
* the end of the chunk. This chunk must be freed using free_trash_chunk(). This
|
|
||||||
* call may fail and the caller is responsible for checking that the returned
|
|
||||||
* pointer is not NULL.
|
|
||||||
*/
|
|
||||||
static forceinline struct buffer *alloc_small_trash_chunk(void)
|
|
||||||
{
|
|
||||||
struct buffer *chunk;
|
|
||||||
|
|
||||||
if (!pool_head_small_trash)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
chunk = pool_alloc(pool_head_small_trash);
|
|
||||||
if (chunk) {
|
|
||||||
char *buf = (char *)chunk + sizeof(struct buffer);
|
|
||||||
*buf = 0;
|
|
||||||
chunk_init(chunk, buf,
|
|
||||||
pool_head_small_trash->size - sizeof(struct buffer));
|
|
||||||
}
|
|
||||||
return chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a trash chunk accordingly to the requested size. This chunk must be
|
* Allocate a trash chunk accordingly to the requested size. This chunk must be
|
||||||
* freed using free_trash_chunk(). This call may fail and the caller is
|
* freed using free_trash_chunk(). This call may fail and the caller is
|
||||||
@ -165,9 +140,7 @@ static forceinline struct buffer *alloc_small_trash_chunk(void)
|
|||||||
*/
|
*/
|
||||||
static forceinline struct buffer *alloc_trash_chunk_sz(size_t size)
|
static forceinline struct buffer *alloc_trash_chunk_sz(size_t size)
|
||||||
{
|
{
|
||||||
if (pool_head_small_trash && size <= pool_head_small_trash->size)
|
if (likely(size <= pool_head_trash->size))
|
||||||
return alloc_small_trash_chunk();
|
|
||||||
else if (size <= pool_head_trash->size)
|
|
||||||
return alloc_trash_chunk();
|
return alloc_trash_chunk();
|
||||||
else if (pool_head_large_trash && size <= pool_head_large_trash->size)
|
else if (pool_head_large_trash && size <= pool_head_large_trash->size)
|
||||||
return alloc_large_trash_chunk();
|
return alloc_large_trash_chunk();
|
||||||
@ -180,12 +153,10 @@ static forceinline struct buffer *alloc_trash_chunk_sz(size_t size)
|
|||||||
*/
|
*/
|
||||||
static forceinline void free_trash_chunk(struct buffer *chunk)
|
static forceinline void free_trash_chunk(struct buffer *chunk)
|
||||||
{
|
{
|
||||||
if (pool_head_small_trash && chunk && chunk->size == pool_head_small_trash->size - sizeof(struct buffer))
|
if (likely(chunk && chunk->size == pool_head_trash->size - sizeof(struct buffer)))
|
||||||
pool_free(pool_head_small_trash, chunk);
|
|
||||||
else if (pool_head_large_trash && chunk && chunk->size == pool_head_large_trash->size - sizeof(struct buffer))
|
|
||||||
pool_free(pool_head_large_trash, chunk);
|
|
||||||
else
|
|
||||||
pool_free(pool_head_trash, chunk);
|
pool_free(pool_head_trash, chunk);
|
||||||
|
else
|
||||||
|
pool_free(pool_head_large_trash, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copies chunk <src> into <chk>. Returns 0 in case of failure. */
|
/* copies chunk <src> into <chk>. Returns 0 in case of failure. */
|
||||||
|
|||||||
@ -23,7 +23,6 @@
|
|||||||
#define _HAPROXY_CLI_T_H
|
#define _HAPROXY_CLI_T_H
|
||||||
|
|
||||||
#include <haproxy/applet-t.h>
|
#include <haproxy/applet-t.h>
|
||||||
#include <haproxy/tinfo-t.h>
|
|
||||||
|
|
||||||
/* Access level for a stats socket (appctx->cli_ctx.level) */
|
/* Access level for a stats socket (appctx->cli_ctx.level) */
|
||||||
#define ACCESS_LVL_NONE 0x0000
|
#define ACCESS_LVL_NONE 0x0000
|
||||||
@ -101,7 +100,6 @@ enum cli_wait_err {
|
|||||||
enum cli_wait_cond {
|
enum cli_wait_cond {
|
||||||
CLI_WAIT_COND_NONE, // no condition to wait on
|
CLI_WAIT_COND_NONE, // no condition to wait on
|
||||||
CLI_WAIT_COND_SRV_UNUSED,// wait for server to become unused
|
CLI_WAIT_COND_SRV_UNUSED,// wait for server to become unused
|
||||||
CLI_WAIT_COND_BE_UNUSED, // wait for backend to become unused
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cli_wait_ctx {
|
struct cli_wait_ctx {
|
||||||
@ -121,8 +119,6 @@ struct cli_kw {
|
|||||||
void (*io_release)(struct appctx *appctx);
|
void (*io_release)(struct appctx *appctx);
|
||||||
void *private;
|
void *private;
|
||||||
int level; /* this is the level needed to show the keyword usage and to use it */
|
int level; /* this is the level needed to show the keyword usage and to use it */
|
||||||
/* 4-byte hole here */
|
|
||||||
struct thread_exec_ctx exec_ctx; /* execution context */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cli_kw_list {
|
struct cli_kw_list {
|
||||||
|
|||||||
@ -130,8 +130,7 @@ enum {
|
|||||||
|
|
||||||
CO_FL_OPT_TOS = 0x00000020, /* connection has a special sockopt tos */
|
CO_FL_OPT_TOS = 0x00000020, /* connection has a special sockopt tos */
|
||||||
|
|
||||||
CO_FL_QSTRM_SEND = 0x00000040, /* connection uses QMux protocol, needs to exchange transport parameters before starting mux layer */
|
/* unused : 0x00000040, 0x00000080 */
|
||||||
CO_FL_QSTRM_RECV = 0x00000080, /* connection uses QMux protocol, needs to exchange transport parameters before starting mux layer */
|
|
||||||
|
|
||||||
/* These flags indicate whether the Control and Transport layers are initialized */
|
/* These flags indicate whether the Control and Transport layers are initialized */
|
||||||
CO_FL_CTRL_READY = 0x00000100, /* FD was registered, fd_delete() needed */
|
CO_FL_CTRL_READY = 0x00000100, /* FD was registered, fd_delete() needed */
|
||||||
@ -213,14 +212,13 @@ static forceinline char *conn_show_flags(char *buf, size_t len, const char *deli
|
|||||||
/* flags */
|
/* flags */
|
||||||
_(CO_FL_SAFE_LIST, _(CO_FL_IDLE_LIST, _(CO_FL_CTRL_READY,
|
_(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_REVERSED, _(CO_FL_ACT_REVERSING, _(CO_FL_OPT_MARK, _(CO_FL_OPT_TOS,
|
||||||
_(CO_FL_QSTRM_SEND, _(CO_FL_QSTRM_RECV,
|
|
||||||
_(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_SSL_NO_CACHED_INFO, _(CO_FL_EARLY_SSL_HS,
|
||||||
_(CO_FL_EARLY_DATA, _(CO_FL_SOCKS4_SEND, _(CO_FL_SOCKS4_RECV, _(CO_FL_SOCK_RD_SH,
|
_(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_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_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_SSL_WAIT_HS, _(CO_FL_PRIVATE, _(CO_FL_RCVD_PROXY, _(CO_FL_SESS_IDLE,
|
||||||
_(CO_FL_XPRT_TRACKED
|
_(CO_FL_XPRT_TRACKED
|
||||||
)))))))))))))))))))))))))))))));
|
)))))))))))))))))))))))))))));
|
||||||
/* epilogue */
|
/* epilogue */
|
||||||
_(~0U);
|
_(~0U);
|
||||||
return buf;
|
return buf;
|
||||||
@ -347,7 +345,6 @@ enum {
|
|||||||
XPRT_SSL = 1,
|
XPRT_SSL = 1,
|
||||||
XPRT_HANDSHAKE = 2,
|
XPRT_HANDSHAKE = 2,
|
||||||
XPRT_QUIC = 3,
|
XPRT_QUIC = 3,
|
||||||
XPRT_QSTRM = 4,
|
|
||||||
XPRT_ENTRIES /* must be last one */
|
XPRT_ENTRIES /* must be last one */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -359,7 +356,6 @@ enum {
|
|||||||
MX_FL_NO_UPG = 0x00000004, /* set if mux does not support any upgrade */
|
MX_FL_NO_UPG = 0x00000004, /* set if mux does not support any upgrade */
|
||||||
MX_FL_FRAMED = 0x00000008, /* mux working on top of a framed transport layer (QUIC) */
|
MX_FL_FRAMED = 0x00000008, /* mux working on top of a framed transport layer (QUIC) */
|
||||||
MX_FL_REVERSABLE = 0x00000010, /* mux supports connection reversal */
|
MX_FL_REVERSABLE = 0x00000010, /* mux supports connection reversal */
|
||||||
MX_FL_EXPERIMENTAL = 0x00000020, /* requires experimental support directives */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* PROTO token registration */
|
/* PROTO token registration */
|
||||||
|
|||||||
@ -34,7 +34,6 @@
|
|||||||
#include <haproxy/listener-t.h>
|
#include <haproxy/listener-t.h>
|
||||||
#include <haproxy/obj_type.h>
|
#include <haproxy/obj_type.h>
|
||||||
#include <haproxy/pool-t.h>
|
#include <haproxy/pool-t.h>
|
||||||
#include <haproxy/protocol.h>
|
|
||||||
#include <haproxy/server.h>
|
#include <haproxy/server.h>
|
||||||
#include <haproxy/session-t.h>
|
#include <haproxy/session-t.h>
|
||||||
#include <haproxy/task-t.h>
|
#include <haproxy/task-t.h>
|
||||||
@ -50,13 +49,6 @@ extern struct mux_stopping_data mux_stopping_data[MAX_THREADS];
|
|||||||
|
|
||||||
#define IS_HTX_CONN(conn) ((conn)->mux && ((conn)->mux->flags & MX_FL_HTX))
|
#define IS_HTX_CONN(conn) ((conn)->mux && ((conn)->mux->flags & MX_FL_HTX))
|
||||||
|
|
||||||
/* macros to switch the calling context to the mux during a call. There's one
|
|
||||||
* with a return value for most calls, and one without for the few like shut(),
|
|
||||||
* detach() or destroy() with no return.
|
|
||||||
*/
|
|
||||||
#define CALL_MUX_WITH_RET(mux, func) EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_MUX, (mux)), (mux)->func)
|
|
||||||
#define CALL_MUX_NO_RET(mux, func) EXEC_CTX_NO_RET(EXEC_CTX_MAKE(TH_EX_CTX_MUX, (mux)), (mux)->func)
|
|
||||||
|
|
||||||
/* receive a PROXY protocol header over a connection */
|
/* receive a PROXY protocol header over a connection */
|
||||||
int conn_recv_proxy(struct connection *conn, int flag);
|
int conn_recv_proxy(struct connection *conn, int flag);
|
||||||
int conn_send_proxy(struct connection *conn, unsigned int flag);
|
int conn_send_proxy(struct connection *conn, unsigned int flag);
|
||||||
@ -488,7 +480,7 @@ static inline int conn_install_mux(struct connection *conn, const struct mux_ops
|
|||||||
|
|
||||||
conn->mux = mux;
|
conn->mux = mux;
|
||||||
conn->ctx = ctx;
|
conn->ctx = ctx;
|
||||||
ret = mux->init ? CALL_MUX_WITH_RET(mux, init(conn, prx, sess, &BUF_NULL)) : 0;
|
ret = mux->init ? mux->init(conn, prx, sess, &BUF_NULL) : 0;
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
conn->mux = NULL;
|
conn->mux = NULL;
|
||||||
conn->ctx = NULL;
|
conn->ctx = NULL;
|
||||||
@ -610,13 +602,13 @@ void list_mux_proto(FILE *out);
|
|||||||
*/
|
*/
|
||||||
static inline const struct mux_proto_list *conn_get_best_mux_entry(
|
static inline const struct mux_proto_list *conn_get_best_mux_entry(
|
||||||
const struct ist mux_proto,
|
const struct ist mux_proto,
|
||||||
int proto_side, int proto_is_quic, int proto_mode)
|
int proto_side, int proto_mode)
|
||||||
{
|
{
|
||||||
struct mux_proto_list *item;
|
struct mux_proto_list *item;
|
||||||
struct mux_proto_list *fallback = NULL;
|
struct mux_proto_list *fallback = NULL;
|
||||||
|
|
||||||
list_for_each_entry(item, &mux_proto_list.list, list) {
|
list_for_each_entry(item, &mux_proto_list.list, list) {
|
||||||
if (!(item->side & proto_side) || !(item->mode & proto_mode) || (proto_is_quic && !(item->mux->flags & MX_FL_FRAMED)))
|
if (!(item->side & proto_side) || !(item->mode & proto_mode))
|
||||||
continue;
|
continue;
|
||||||
if (istlen(mux_proto) && isteq(mux_proto, item->token))
|
if (istlen(mux_proto) && isteq(mux_proto, item->token))
|
||||||
return item;
|
return item;
|
||||||
@ -641,7 +633,7 @@ static inline const struct mux_ops *conn_get_best_mux(struct connection *conn,
|
|||||||
{
|
{
|
||||||
const struct mux_proto_list *item;
|
const struct mux_proto_list *item;
|
||||||
|
|
||||||
item = conn_get_best_mux_entry(mux_proto, proto_side, proto_is_quic(conn->ctrl), proto_mode);
|
item = conn_get_best_mux_entry(mux_proto, proto_side, proto_mode);
|
||||||
|
|
||||||
return item ? item->mux : NULL;
|
return item ? item->mux : NULL;
|
||||||
}
|
}
|
||||||
@ -691,12 +683,6 @@ static inline int conn_is_ssl(struct connection *conn)
|
|||||||
return !!conn_get_ssl_sock_ctx(conn);
|
return !!conn_get_ssl_sock_ctx(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if connection runs over QUIC. */
|
|
||||||
static inline int conn_is_quic(const struct connection *conn)
|
|
||||||
{
|
|
||||||
return conn->flags & CO_FL_FDLESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if connection must be reversed. */
|
/* Returns true if connection must be reversed. */
|
||||||
static inline int conn_is_reverse(const struct connection *conn)
|
static inline int conn_is_reverse(const struct connection *conn)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -185,29 +185,6 @@ struct be_counters {
|
|||||||
} p; /* protocol-specific stats */
|
} p; /* protocol-specific stats */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* extra counters that are registered at boot by various modules */
|
|
||||||
enum counters_type {
|
|
||||||
COUNTERS_FE = 0,
|
|
||||||
COUNTERS_BE,
|
|
||||||
COUNTERS_SV,
|
|
||||||
COUNTERS_LI,
|
|
||||||
COUNTERS_RSLV,
|
|
||||||
|
|
||||||
COUNTERS_OFF_END /* must always be last */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct extra_counters {
|
|
||||||
char **datap; /* points to pointer to heap containing counters allocated in a linear fashion */
|
|
||||||
size_t size; /* size of allocated data */
|
|
||||||
size_t tgrp_step; /* distance in words between two datap for consecutive tgroups, 0 for single */
|
|
||||||
uint nbtgrp; /* number of thread groups accessing these counters */
|
|
||||||
enum counters_type type; /* type of object containing the counters */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define EXTRA_COUNTERS(name) \
|
|
||||||
struct extra_counters *name
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_COUNTERS_T_H */
|
#endif /* _HAPROXY_COUNTERS_T_H */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -26,9 +26,6 @@
|
|||||||
|
|
||||||
#include <haproxy/counters-t.h>
|
#include <haproxy/counters-t.h>
|
||||||
#include <haproxy/guid-t.h>
|
#include <haproxy/guid-t.h>
|
||||||
#include <haproxy/global.h>
|
|
||||||
|
|
||||||
extern THREAD_LOCAL void *trash_counters;
|
|
||||||
|
|
||||||
int counters_fe_shared_prepare(struct fe_counters_shared *counters, const struct guid_node *guid, char **errmsg);
|
int counters_fe_shared_prepare(struct fe_counters_shared *counters, const struct guid_node *guid, char **errmsg);
|
||||||
int counters_be_shared_prepare(struct be_counters_shared *counters, const struct guid_node *guid, char **errmsg);
|
int counters_be_shared_prepare(struct be_counters_shared *counters, const struct guid_node *guid, char **errmsg);
|
||||||
@ -104,106 +101,4 @@ void counters_be_shared_drop(struct be_counters_shared *counters);
|
|||||||
__ret; \
|
__ret; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define COUNTERS_UPDATE_MAX(counter, count) \
|
|
||||||
do { \
|
|
||||||
if (!(global.tune.options & GTUNE_NO_MAX_COUNTER)) \
|
|
||||||
HA_ATOMIC_UPDATE_MAX(counter, count); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Manipulation of extra_counters, for boot-time registrable modules */
|
|
||||||
/* retrieve the base storage of extra counters (first tgroup if any) */
|
|
||||||
#define EXTRA_COUNTERS_BASE(counters, mod) \
|
|
||||||
(likely(counters) ? \
|
|
||||||
((void *)(*(counters)->datap + (mod)->counters_off[(counters)->type])) : \
|
|
||||||
(trash_counters))
|
|
||||||
|
|
||||||
/* retrieve the pointer to the extra counters storage for module <mod> for the
|
|
||||||
* current TGID.
|
|
||||||
*/
|
|
||||||
#define EXTRA_COUNTERS_GET(counters, mod) \
|
|
||||||
(likely(counters) ? \
|
|
||||||
((void *)(counters)->datap[(counters)->tgrp_step * (tgid - 1)] + \
|
|
||||||
(mod)->counters_off[(counters)->type]) : \
|
|
||||||
(trash_counters))
|
|
||||||
|
|
||||||
#define EXTRA_COUNTERS_REGISTER(counters, ctype, alloc_failed_label, storage, step) \
|
|
||||||
do { \
|
|
||||||
typeof(*counters) _ctr; \
|
|
||||||
_ctr = calloc(1, sizeof(*_ctr)); \
|
|
||||||
if (!_ctr) \
|
|
||||||
goto alloc_failed_label; \
|
|
||||||
_ctr->type = (ctype); \
|
|
||||||
_ctr->tgrp_step = (step); \
|
|
||||||
_ctr->datap = (storage); \
|
|
||||||
*(counters) = _ctr; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define EXTRA_COUNTERS_ADD(mod, counters, new_counters, csize) \
|
|
||||||
do { \
|
|
||||||
typeof(counters) _ctr = (counters); \
|
|
||||||
(mod)->counters_off[_ctr->type] = _ctr->size; \
|
|
||||||
_ctr->size += (csize); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define EXTRA_COUNTERS_ALLOC(counters, alloc_failed_label, nbtg) \
|
|
||||||
do { \
|
|
||||||
typeof(counters) _ctr = (counters); \
|
|
||||||
char **datap = _ctr->datap; \
|
|
||||||
uint tgrp; \
|
|
||||||
_ctr->nbtgrp = _ctr->tgrp_step ? (nbtg) : 1; \
|
|
||||||
for (tgrp = 0; tgrp < _ctr->nbtgrp; tgrp++) { \
|
|
||||||
*datap = malloc((_ctr)->size); \
|
|
||||||
if (!*_ctr->datap) \
|
|
||||||
goto alloc_failed_label; \
|
|
||||||
datap += _ctr->tgrp_step; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define EXTRA_COUNTERS_INIT(counters, mod, init_counters, init_counters_size) \
|
|
||||||
do { \
|
|
||||||
typeof(counters) _ctr = (counters); \
|
|
||||||
char **datap = _ctr->datap; \
|
|
||||||
uint tgrp; \
|
|
||||||
for (tgrp = 0; tgrp < _ctr->nbtgrp; tgrp++) { \
|
|
||||||
memcpy(*datap + mod->counters_off[_ctr->type], \
|
|
||||||
(init_counters), (init_counters_size)); \
|
|
||||||
datap += _ctr->tgrp_step; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define EXTRA_COUNTERS_FREE(counters) \
|
|
||||||
do { \
|
|
||||||
typeof(counters) _ctr = (counters); \
|
|
||||||
if (_ctr) { \
|
|
||||||
char **datap = _ctr->datap; \
|
|
||||||
uint tgrp; \
|
|
||||||
for (tgrp = 0; tgrp < _ctr->nbtgrp; tgrp++) { \
|
|
||||||
ha_free(datap); \
|
|
||||||
datap += _ctr->tgrp_step; \
|
|
||||||
} \
|
|
||||||
free(_ctr); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* aggregate all values of <metricp> over the thread groups handled by
|
|
||||||
* <counters>. <metricp> MUST correspond to an entry of the first tgrp of
|
|
||||||
* <counters>. The number of groups and the step are found in <counters>. The
|
|
||||||
* type of the return value is the same as <metricp>, and must be a scalar so
|
|
||||||
* that values are summed before being returned.
|
|
||||||
*/
|
|
||||||
#define EXTRA_COUNTERS_AGGR(counters, metricp) \
|
|
||||||
({ \
|
|
||||||
typeof(counters) _ctr = (counters); \
|
|
||||||
typeof(metricp) *valp, _ret = 0; \
|
|
||||||
if (_ctr) { \
|
|
||||||
size_t ofs = (char *)&metricp - _ctr->datap[0]; \
|
|
||||||
uint tgrp; \
|
|
||||||
for (tgrp = 0; tgrp < _ctr->nbtgrp; tgrp++) { \
|
|
||||||
valp = (typeof(valp))(_ctr->datap[tgrp * (counters)->tgrp_step] + ofs); \
|
|
||||||
_ret += HA_ATOMIC_LOAD(valp); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
_ret; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_COUNTERS_H */
|
#endif /* _HAPROXY_COUNTERS_H */
|
||||||
|
|||||||
@ -536,11 +536,6 @@
|
|||||||
#define TIME_STATS_SAMPLES 512
|
#define TIME_STATS_SAMPLES 512
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* number of samples used to measure the load in the run queue */
|
|
||||||
#ifndef RQ_LOAD_SAMPLES
|
|
||||||
#define RQ_LOAD_SAMPLES 512
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* max ocsp cert id asn1 encoded length */
|
/* max ocsp cert id asn1 encoded length */
|
||||||
#ifndef OCSP_MAX_CERTID_ASN1_LENGTH
|
#ifndef OCSP_MAX_CERTID_ASN1_LENGTH
|
||||||
#define OCSP_MAX_CERTID_ASN1_LENGTH 128
|
#define OCSP_MAX_CERTID_ASN1_LENGTH 128
|
||||||
@ -606,7 +601,7 @@
|
|||||||
* store stats.
|
* store stats.
|
||||||
*/
|
*/
|
||||||
#ifndef MEMPROF_HASH_BITS
|
#ifndef MEMPROF_HASH_BITS
|
||||||
# define MEMPROF_HASH_BITS 12
|
# define MEMPROF_HASH_BITS 10
|
||||||
#endif
|
#endif
|
||||||
#define MEMPROF_HASH_BUCKETS (1U << MEMPROF_HASH_BITS)
|
#define MEMPROF_HASH_BUCKETS (1U << MEMPROF_HASH_BITS)
|
||||||
|
|
||||||
|
|||||||
@ -24,12 +24,12 @@
|
|||||||
|
|
||||||
#include <import/ebtree-t.h>
|
#include <import/ebtree-t.h>
|
||||||
|
|
||||||
#include <haproxy/buf-t.h>
|
|
||||||
#include <haproxy/connection-t.h>
|
#include <haproxy/connection-t.h>
|
||||||
#include <haproxy/counters-t.h>
|
#include <haproxy/buf-t.h>
|
||||||
#include <haproxy/dgram-t.h>
|
#include <haproxy/dgram-t.h>
|
||||||
#include <haproxy/dns_ring-t.h>
|
#include <haproxy/dns_ring-t.h>
|
||||||
#include <haproxy/obj_type-t.h>
|
#include <haproxy/obj_type-t.h>
|
||||||
|
#include <haproxy/stats-t.h>
|
||||||
#include <haproxy/task-t.h>
|
#include <haproxy/task-t.h>
|
||||||
#include <haproxy/thread.h>
|
#include <haproxy/thread.h>
|
||||||
|
|
||||||
@ -152,7 +152,6 @@ struct dns_nameserver {
|
|||||||
struct dns_stream_server *stream; /* used for tcp dns */
|
struct dns_stream_server *stream; /* used for tcp dns */
|
||||||
|
|
||||||
EXTRA_COUNTERS(extra_counters);
|
EXTRA_COUNTERS(extra_counters);
|
||||||
char *extra_counters_storage; /* storage used for extra_counters above */
|
|
||||||
struct dns_counters *counters;
|
struct dns_counters *counters;
|
||||||
|
|
||||||
struct list list; /* nameserver chained list */
|
struct list list; /* nameserver chained list */
|
||||||
|
|||||||
@ -37,7 +37,6 @@
|
|||||||
|
|
||||||
extern struct pool_head *pool_head_buffer;
|
extern struct pool_head *pool_head_buffer;
|
||||||
extern struct pool_head *pool_head_large_buffer;
|
extern struct pool_head *pool_head_large_buffer;
|
||||||
extern struct pool_head *pool_head_small_buffer;
|
|
||||||
|
|
||||||
int init_buffer(void);
|
int init_buffer(void);
|
||||||
void buffer_dump(FILE *o, struct buffer *b, int from, int to);
|
void buffer_dump(FILE *o, struct buffer *b, int from, int to);
|
||||||
@ -67,12 +66,6 @@ static inline int b_is_large_sz(size_t sz)
|
|||||||
return (pool_head_large_buffer && sz == pool_head_large_buffer->size);
|
return (pool_head_large_buffer && sz == pool_head_large_buffer->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return 1 if <sz> is the size of a small buffer */
|
|
||||||
static inline int b_is_small_sz(size_t sz)
|
|
||||||
{
|
|
||||||
return (pool_head_small_buffer && sz == pool_head_small_buffer->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return 1 if <bug> is a default buffer */
|
/* Return 1 if <bug> is a default buffer */
|
||||||
static inline int b_is_default(struct buffer *buf)
|
static inline int b_is_default(struct buffer *buf)
|
||||||
{
|
{
|
||||||
@ -85,12 +78,6 @@ static inline int b_is_large(struct buffer *buf)
|
|||||||
return b_is_large_sz(b_size(buf));
|
return b_is_large_sz(b_size(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return 1 if <buf> is a small buffer */
|
|
||||||
static inline int b_is_small(struct buffer *buf)
|
|
||||||
{
|
|
||||||
return b_is_small_sz(b_size(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
/* Functions below are used for buffer allocation */
|
/* Functions below are used for buffer allocation */
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
@ -185,8 +172,6 @@ static inline char *__b_get_emergency_buf(void)
|
|||||||
* than the default buffers */ \
|
* than the default buffers */ \
|
||||||
if (unlikely(b_is_large_sz(sz))) \
|
if (unlikely(b_is_large_sz(sz))) \
|
||||||
pool_free(pool_head_large_buffer, area); \
|
pool_free(pool_head_large_buffer, area); \
|
||||||
else if (unlikely(b_is_small_sz(sz))) \
|
|
||||||
pool_free(pool_head_small_buffer, area); \
|
|
||||||
else if (th_ctx->emergency_bufs_left < global.tune.reserved_bufs) \
|
else if (th_ctx->emergency_bufs_left < global.tune.reserved_bufs) \
|
||||||
th_ctx->emergency_bufs[th_ctx->emergency_bufs_left++] = area; \
|
th_ctx->emergency_bufs[th_ctx->emergency_bufs_left++] = area; \
|
||||||
else \
|
else \
|
||||||
@ -200,35 +185,6 @@ static inline char *__b_get_emergency_buf(void)
|
|||||||
__b_free((_buf)); \
|
__b_free((_buf)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
static inline struct buffer *b_alloc_small(struct buffer *buf)
|
|
||||||
{
|
|
||||||
char *area = NULL;
|
|
||||||
|
|
||||||
if (!buf->size) {
|
|
||||||
area = pool_alloc(pool_head_small_buffer);
|
|
||||||
if (!area)
|
|
||||||
return NULL;
|
|
||||||
buf->area = area;
|
|
||||||
buf->size = global.tune.bufsize_small;
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct buffer *b_alloc_large(struct buffer *buf)
|
|
||||||
{
|
|
||||||
char *area = NULL;
|
|
||||||
|
|
||||||
if (!buf->size) {
|
|
||||||
area = pool_alloc(pool_head_large_buffer);
|
|
||||||
if (!area)
|
|
||||||
return NULL;
|
|
||||||
buf->area = area;
|
|
||||||
buf->size = global.tune.bufsize_large;
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Offer one or multiple buffer currently belonging to target <from> to whoever
|
/* Offer one or multiple buffer currently belonging to target <from> to whoever
|
||||||
* needs one. Any pointer is valid for <from>, including NULL. Its purpose is
|
* needs one. Any pointer is valid for <from>, including NULL. Its purpose is
|
||||||
* to avoid passing a buffer to oneself in case of failed allocations (e.g.
|
* to avoid passing a buffer to oneself in case of failed allocations (e.g.
|
||||||
|
|||||||
@ -28,9 +28,7 @@
|
|||||||
#include <haproxy/stream-t.h>
|
#include <haproxy/stream-t.h>
|
||||||
|
|
||||||
extern const char *trace_flt_id;
|
extern const char *trace_flt_id;
|
||||||
extern const char *http_comp_req_flt_id;
|
extern const char *http_comp_flt_id;
|
||||||
extern const char *http_comp_res_flt_id;
|
|
||||||
|
|
||||||
extern const char *cache_store_flt_id;
|
extern const char *cache_store_flt_id;
|
||||||
extern const char *spoe_filter_id;
|
extern const char *spoe_filter_id;
|
||||||
extern const char *fcgi_flt_id;
|
extern const char *fcgi_flt_id;
|
||||||
|
|||||||
@ -403,25 +403,6 @@ static inline uint swrate_add_scaled_opportunistic(uint *sum, uint n, uint v, ui
|
|||||||
return new_sum;
|
return new_sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Like swrate_add() except that if <v> is beyond the current average, the
|
|
||||||
* average is replaced by the peak. This is essentially used to measure peak
|
|
||||||
* loads in the scheduler, reason why it is provided as a local variant that
|
|
||||||
* does not involve atomic operations.
|
|
||||||
*/
|
|
||||||
static inline uint swrate_add_peak_local(uint *sum, uint n, uint v)
|
|
||||||
{
|
|
||||||
uint old_sum, new_sum;
|
|
||||||
|
|
||||||
old_sum = *sum;
|
|
||||||
if (v * n > old_sum)
|
|
||||||
new_sum = v * n;
|
|
||||||
else
|
|
||||||
new_sum = old_sum - (old_sum + n - 1) / n + v;
|
|
||||||
|
|
||||||
*sum = new_sum;
|
|
||||||
return new_sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the average sample value for the sum <sum> over a sliding window of
|
/* Returns the average sample value for the sum <sum> over a sliding window of
|
||||||
* <n> samples. Better if <n> is a power of two. It must be the same <n> as the
|
* <n> samples. Better if <n> is a power of two. It must be the same <n> as the
|
||||||
* one used above in all additions.
|
* one used above in all additions.
|
||||||
|
|||||||
@ -79,14 +79,13 @@
|
|||||||
#define GTUNE_DISABLE_H2_WEBSOCKET (1<<21)
|
#define GTUNE_DISABLE_H2_WEBSOCKET (1<<21)
|
||||||
#define GTUNE_DISABLE_ACTIVE_CLOSE (1<<22)
|
#define GTUNE_DISABLE_ACTIVE_CLOSE (1<<22)
|
||||||
#define GTUNE_QUICK_EXIT (1<<23)
|
#define GTUNE_QUICK_EXIT (1<<23)
|
||||||
#define GTUNE_COLLECT_LIBS (1<<24)
|
/* (1<<24) unused */
|
||||||
/* (1<<25) unused */
|
/* (1<<25) unused */
|
||||||
#define GTUNE_USE_FAST_FWD (1<<26)
|
#define GTUNE_USE_FAST_FWD (1<<26)
|
||||||
#define GTUNE_LISTENER_MQ_FAIR (1<<27)
|
#define GTUNE_LISTENER_MQ_FAIR (1<<27)
|
||||||
#define GTUNE_LISTENER_MQ_OPT (1<<28)
|
#define GTUNE_LISTENER_MQ_OPT (1<<28)
|
||||||
#define GTUNE_LISTENER_MQ_ANY (GTUNE_LISTENER_MQ_FAIR | GTUNE_LISTENER_MQ_OPT)
|
#define GTUNE_LISTENER_MQ_ANY (GTUNE_LISTENER_MQ_FAIR | GTUNE_LISTENER_MQ_OPT)
|
||||||
#define GTUNE_NO_KTLS (1<<29)
|
#define GTUNE_NO_KTLS (1<<29)
|
||||||
#define GTUNE_NO_MAX_COUNTER (1<<30)
|
|
||||||
|
|
||||||
/* subsystem-specific debugging options for tune.debug */
|
/* subsystem-specific debugging options for tune.debug */
|
||||||
#define GDBG_CPU_AFFINITY (1U<< 0)
|
#define GDBG_CPU_AFFINITY (1U<< 0)
|
||||||
|
|||||||
@ -58,10 +58,6 @@ extern int devnullfd;
|
|||||||
extern int fileless_mode;
|
extern int fileless_mode;
|
||||||
extern struct cfgfile fileless_cfg;
|
extern struct cfgfile fileless_cfg;
|
||||||
|
|
||||||
/* storage for collected libs */
|
|
||||||
extern void *lib_storage;
|
|
||||||
extern size_t lib_size;
|
|
||||||
|
|
||||||
struct proxy;
|
struct proxy;
|
||||||
struct server;
|
struct server;
|
||||||
int main(int argc, char **argv);
|
int main(int argc, char **argv);
|
||||||
|
|||||||
@ -99,7 +99,7 @@ enum h1m_state {
|
|||||||
#define H1_MF_TE_CHUNKED 0x00010000 // T-E "chunked"
|
#define H1_MF_TE_CHUNKED 0x00010000 // T-E "chunked"
|
||||||
#define H1_MF_TE_OTHER 0x00020000 // T-E other than supported ones found (only "chunked" is supported for now)
|
#define H1_MF_TE_OTHER 0x00020000 // T-E other than supported ones found (only "chunked" is supported for now)
|
||||||
#define H1_MF_UPG_H2C 0x00040000 // "h2c" or "h2" used as upgrade token
|
#define H1_MF_UPG_H2C 0x00040000 // "h2c" or "h2" used as upgrade token
|
||||||
#define H1_MF_NOT_HTTP 0x00080000 // Not an HTTP message (e.g "RTSP", only possible if invalid message are accepted)
|
|
||||||
/* Mask to use to reset H1M flags when we restart headers parsing.
|
/* Mask to use to reset H1M flags when we restart headers parsing.
|
||||||
*
|
*
|
||||||
* WARNING: Don't forget to update it if a new flag must be preserved when
|
* WARNING: Don't forget to update it if a new flag must be preserved when
|
||||||
|
|||||||
@ -222,7 +222,6 @@ struct hlua_proxy_list {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct hlua_proxy_list_iterator_context {
|
struct hlua_proxy_list_iterator_context {
|
||||||
struct watcher px_watch; /* watcher to automatically update next pointer on backend deletion */
|
|
||||||
struct proxy *next;
|
struct proxy *next;
|
||||||
char capabilities;
|
char capabilities;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include <haproxy/hstream-t.h>
|
#include <haproxy/hstream-t.h>
|
||||||
|
|
||||||
struct task *sc_hstream_io_cb(struct task *t, void *ctx, unsigned int state);
|
struct task *sc_hstream_io_cb(struct task *t, void *ctx, unsigned int state);
|
||||||
|
int hstream_wake(struct stconn *sc);
|
||||||
void hstream_shutdown(struct stconn *sc);
|
void hstream_shutdown(struct stconn *sc);
|
||||||
void *hstream_new(struct session *sess, struct stconn *sc, struct buffer *input);
|
void *hstream_new(struct session *sess, struct stconn *sc, struct buffer *input);
|
||||||
|
|
||||||
|
|||||||
@ -290,36 +290,6 @@ static inline int http_status_matches(const long *array, uint status)
|
|||||||
return ha_bit_test(status - 100, array);
|
return ha_bit_test(status - 100, array);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function returns 1 if the header is one of the immutable headers.
|
|
||||||
* Forbidden headers are the ones that must not be rewritten. Function returns
|
|
||||||
* 0 if a header can be rewritten
|
|
||||||
*/
|
|
||||||
static inline int is_immutable_header(struct ist hdr)
|
|
||||||
{
|
|
||||||
switch (hdr.len) {
|
|
||||||
case 6:
|
|
||||||
return isteqi(hdr, ist("expect"));
|
|
||||||
case 7:
|
|
||||||
return isteqi(hdr, ist("trailer")) ||
|
|
||||||
isteqi(hdr, ist("upgrade"));
|
|
||||||
case 10:
|
|
||||||
return isteqi(hdr, ist("connection")) ||
|
|
||||||
isteqi(hdr, ist("keep-alive"));
|
|
||||||
case 14:
|
|
||||||
return isteqi(hdr, ist("content-length"));
|
|
||||||
case 16:
|
|
||||||
return isteqi(hdr, ist("proxy-connection"));
|
|
||||||
case 17:
|
|
||||||
return isteqi(hdr, ist("transfer-encoding"));
|
|
||||||
case 18:
|
|
||||||
return isteqi(hdr, ist("proxy-authenticate"));
|
|
||||||
case 19:
|
|
||||||
return isteqi(hdr, ist("proxy-authorization"));
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_HTTP_H */
|
#endif /* _HAPROXY_HTTP_H */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -228,8 +228,7 @@ enum h1_state {
|
|||||||
*/
|
*/
|
||||||
struct http_msg {
|
struct http_msg {
|
||||||
enum h1_state msg_state; /* where we are in the current message parsing */
|
enum h1_state msg_state; /* where we are in the current message parsing */
|
||||||
unsigned char vsn; /* HTTP version, 4 bits per digit */
|
/* 3 bytes unused here */
|
||||||
/* 2 bytes unused here */
|
|
||||||
unsigned int flags; /* flags describing the message (HTTP version, ...) */
|
unsigned int flags; /* flags describing the message (HTTP version, ...) */
|
||||||
struct channel *chn; /* pointer to the channel transporting the message */
|
struct channel *chn; /* pointer to the channel transporting the message */
|
||||||
};
|
};
|
||||||
|
|||||||
@ -93,22 +93,4 @@ struct http_errors {
|
|||||||
struct list list; /* http-errors list */
|
struct list list; /* http-errors list */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Indicates the keyword origin of an http-error definition. This is used in
|
|
||||||
* <conf_errors> type to indicate which part of the internal union should be
|
|
||||||
* manipulated.
|
|
||||||
*/
|
|
||||||
enum http_err_directive {
|
|
||||||
HTTP_ERR_DIRECTIVE_SECTION = 0, /* "errorfiles" keyword referencing a http-errors section */
|
|
||||||
HTTP_ERR_DIRECTIVE_INLINE, /* "errorfile" keyword with inline error definition */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Used with "errorfiles" directives. It indicates for each known HTTP error
|
|
||||||
* status codes if they are defined in the target http-errors section.
|
|
||||||
*/
|
|
||||||
enum http_err_import {
|
|
||||||
HTTP_ERR_IMPORT_NO = 0,
|
|
||||||
HTTP_ERR_IMPORT_IMPLICIT, /* import every errcode defined in a section */
|
|
||||||
HTTP_ERR_IMPORT_EXPLICIT, /* import a specific errcode from a section */
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_HTTP_HTX_T_H */
|
#endif /* _HAPROXY_HTTP_HTX_T_H */
|
||||||
|
|||||||
@ -78,7 +78,6 @@ struct buffer *http_load_errorfile(const char *file, char **errmsg);
|
|||||||
struct buffer *http_load_errormsg(const char *key, const struct ist msg, char **errmsg);
|
struct buffer *http_load_errormsg(const char *key, const struct ist msg, char **errmsg);
|
||||||
struct buffer *http_parse_errorfile(int status, const char *file, char **errmsg);
|
struct buffer *http_parse_errorfile(int status, const char *file, char **errmsg);
|
||||||
struct buffer *http_parse_errorloc(int errloc, int status, const char *url, char **errmsg);
|
struct buffer *http_parse_errorloc(int errloc, int status, const char *url, char **errmsg);
|
||||||
int proxy_check_http_errors(struct proxy *px);
|
|
||||||
int proxy_dup_default_conf_errors(struct proxy *curpx, const struct proxy *defpx, char **errmsg);
|
int proxy_dup_default_conf_errors(struct proxy *curpx, const struct proxy *defpx, char **errmsg);
|
||||||
void proxy_release_conf_errors(struct proxy *px);
|
void proxy_release_conf_errors(struct proxy *px);
|
||||||
|
|
||||||
|
|||||||
@ -141,7 +141,6 @@
|
|||||||
#define HTX_SL_F_NORMALIZED_URI 0x00000800 /* The received URI is normalized (an implicit absolute-uri form) */
|
#define HTX_SL_F_NORMALIZED_URI 0x00000800 /* The received URI is normalized (an implicit absolute-uri form) */
|
||||||
#define HTX_SL_F_CONN_UPG 0x00001000 /* The message contains "connection: upgrade" header */
|
#define HTX_SL_F_CONN_UPG 0x00001000 /* The message contains "connection: upgrade" header */
|
||||||
#define HTX_SL_F_BODYLESS_RESP 0x00002000 /* The response to this message is bodyloess (only for reqyest) */
|
#define HTX_SL_F_BODYLESS_RESP 0x00002000 /* The response to this message is bodyloess (only for reqyest) */
|
||||||
#define HTX_SL_F_NOT_HTTP 0x00004000 /* Not an HTTP message (e.g "RTSP", only possible if invalid message are accepted) */
|
|
||||||
|
|
||||||
/* This function is used to report flags in debugging tools. Please reflect
|
/* This function is used to report flags in debugging tools. Please reflect
|
||||||
* below any single-bit flag addition above in the same order via the
|
* below any single-bit flag addition above in the same order via the
|
||||||
|
|||||||
@ -37,7 +37,6 @@ struct htx_blk *htx_add_blk(struct htx *htx, enum htx_blk_type type, uint32_t bl
|
|||||||
struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk);
|
struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk);
|
||||||
struct htx_ret htx_find_offset(struct htx *htx, uint32_t offset);
|
struct htx_ret htx_find_offset(struct htx *htx, uint32_t offset);
|
||||||
void htx_truncate(struct htx *htx, uint32_t offset);
|
void htx_truncate(struct htx *htx, uint32_t offset);
|
||||||
void htx_truncate_blk(struct htx *htx, struct htx_blk *blk);
|
|
||||||
struct htx_ret htx_drain(struct htx *htx, uint32_t max);
|
struct htx_ret htx_drain(struct htx *htx, uint32_t max);
|
||||||
|
|
||||||
struct htx_blk *htx_replace_blk_value(struct htx *htx, struct htx_blk *blk,
|
struct htx_blk *htx_replace_blk_value(struct htx *htx, struct htx_blk *blk,
|
||||||
@ -57,16 +56,6 @@ size_t htx_add_data(struct htx *htx, const struct ist data);
|
|||||||
struct htx_blk *htx_add_last_data(struct htx *htx, struct ist data);
|
struct htx_blk *htx_add_last_data(struct htx *htx, struct ist data);
|
||||||
void htx_move_blk_before(struct htx *htx, struct htx_blk **blk, struct htx_blk **ref);
|
void htx_move_blk_before(struct htx *htx, struct htx_blk **blk, struct htx_blk **ref);
|
||||||
int htx_append_msg(struct htx *dst, const struct htx *src);
|
int htx_append_msg(struct htx *dst, const struct htx *src);
|
||||||
struct buffer *htx_move_to_small_buffer(struct buffer *dst, struct buffer *src);
|
|
||||||
struct buffer *htx_move_to_large_buffer(struct buffer *dst, struct buffer *src);
|
|
||||||
struct buffer *htx_copy_to_small_buffer(struct buffer *dst, struct buffer *src);
|
|
||||||
struct buffer *htx_copy_to_large_buffer(struct buffer *dst, struct buffer *src);
|
|
||||||
|
|
||||||
#define HTX_XFER_DEFAULT 0x00000000 /* Default XFER: no partial xfer / remove blocks from source */
|
|
||||||
#define HTX_XFER_KEEP_SRC_BLKS 0x00000001 /* Don't remove xfer blocks from source messages during xfer */
|
|
||||||
#define HTX_XFER_PARTIAL_HDRS_COPY 0x00000002 /* Allow partial copy of headers and trailers part */
|
|
||||||
#define HTX_XFER_HDRS_ONLY 0x00000003 /* Only Transfer header blocks (start-line, header and EOH) */
|
|
||||||
size_t htx_xfer(struct htx *dst, struct htx *src, size_t count, unsigned int flags);
|
|
||||||
|
|
||||||
/* Functions and macros to get parts of the start-line or length of these
|
/* Functions and macros to get parts of the start-line or length of these
|
||||||
* parts. Request and response start-lines are both composed of 3 parts.
|
* parts. Request and response start-lines are both composed of 3 parts.
|
||||||
@ -109,11 +98,6 @@ static inline struct ist htx_sl_p3(const struct htx_sl *sl)
|
|||||||
return ist2(HTX_SL_P3_PTR(sl), HTX_SL_P3_LEN(sl));
|
return ist2(HTX_SL_P3_PTR(sl), HTX_SL_P3_LEN(sl));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct ist htx_sl_vsn(const struct htx_sl *sl)
|
|
||||||
{
|
|
||||||
return ((sl->flags & HTX_SL_F_IS_RESP) ? htx_sl_p1(sl) : htx_sl_p3(sl));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct ist htx_sl_req_meth(const struct htx_sl *sl)
|
static inline struct ist htx_sl_req_meth(const struct htx_sl *sl)
|
||||||
{
|
{
|
||||||
return htx_sl_p1(sl);
|
return htx_sl_p1(sl);
|
||||||
|
|||||||
@ -20,11 +20,6 @@ extern struct list server_deinit_list;
|
|||||||
extern struct list per_thread_free_list;
|
extern struct list per_thread_free_list;
|
||||||
extern struct list per_thread_deinit_list;
|
extern struct list per_thread_deinit_list;
|
||||||
|
|
||||||
/* initcall caller location */
|
|
||||||
extern const struct initcall *caller_initcall;
|
|
||||||
extern const char *caller_file;
|
|
||||||
extern int caller_line;
|
|
||||||
|
|
||||||
void hap_register_pre_check(int (*fct)());
|
void hap_register_pre_check(int (*fct)());
|
||||||
void hap_register_post_check(int (*fct)());
|
void hap_register_post_check(int (*fct)());
|
||||||
void hap_register_post_proxy_check(int (*fct)(struct proxy *));
|
void hap_register_post_proxy_check(int (*fct)(struct proxy *));
|
||||||
|
|||||||
@ -77,8 +77,6 @@ struct initcall {
|
|||||||
void *arg1;
|
void *arg1;
|
||||||
void *arg2;
|
void *arg2;
|
||||||
void *arg3;
|
void *arg3;
|
||||||
const char *loc_file; /* file where the call is declared, or NULL */
|
|
||||||
int loc_line; /* line where the call is declared, or NULL */
|
|
||||||
#if defined(USE_OBSOLETE_LINKER)
|
#if defined(USE_OBSOLETE_LINKER)
|
||||||
void *next;
|
void *next;
|
||||||
#endif
|
#endif
|
||||||
@ -109,8 +107,6 @@ struct initcall {
|
|||||||
.arg1 = (void *)(a1), \
|
.arg1 = (void *)(a1), \
|
||||||
.arg2 = (void *)(a2), \
|
.arg2 = (void *)(a2), \
|
||||||
.arg3 = (void *)(a3), \
|
.arg3 = (void *)(a3), \
|
||||||
.loc_file = __FILE__, \
|
|
||||||
.loc_line = linenum, \
|
|
||||||
} : NULL
|
} : NULL
|
||||||
|
|
||||||
|
|
||||||
@ -135,8 +131,6 @@ __attribute__((constructor)) static void __initcb_##linenum() \
|
|||||||
.arg1 = (void *)(a1), \
|
.arg1 = (void *)(a1), \
|
||||||
.arg2 = (void *)(a2), \
|
.arg2 = (void *)(a2), \
|
||||||
.arg3 = (void *)(a3), \
|
.arg3 = (void *)(a3), \
|
||||||
.loc_file = __FILE__, \
|
|
||||||
.loc_line = linenum, \
|
|
||||||
}; \
|
}; \
|
||||||
if (stg < STG_SIZE) { \
|
if (stg < STG_SIZE) { \
|
||||||
entry.next = __initstg[stg]; \
|
entry.next = __initstg[stg]; \
|
||||||
@ -235,15 +229,8 @@ extern struct initcall *__initstg[STG_SIZE];
|
|||||||
const struct initcall **ptr; \
|
const struct initcall **ptr; \
|
||||||
if (stg >= STG_SIZE) \
|
if (stg >= STG_SIZE) \
|
||||||
break; \
|
break; \
|
||||||
FOREACH_INITCALL(ptr, stg) { \
|
FOREACH_INITCALL(ptr, stg) \
|
||||||
caller_initcall = *ptr; \
|
|
||||||
caller_file = (*ptr)->loc_file; \
|
|
||||||
caller_line = (*ptr)->loc_line; \
|
|
||||||
(*ptr)->fct((*ptr)->arg1, (*ptr)->arg2, (*ptr)->arg3); \
|
(*ptr)->fct((*ptr)->arg1, (*ptr)->arg2, (*ptr)->arg3); \
|
||||||
caller_initcall = NULL; \
|
|
||||||
caller_file = NULL; \
|
|
||||||
caller_line = 0; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#else // USE_OBSOLETE_LINKER
|
#else // USE_OBSOLETE_LINKER
|
||||||
@ -256,15 +243,8 @@ extern struct initcall *__initstg[STG_SIZE];
|
|||||||
const struct initcall *ptr; \
|
const struct initcall *ptr; \
|
||||||
if (stg >= STG_SIZE) \
|
if (stg >= STG_SIZE) \
|
||||||
break; \
|
break; \
|
||||||
FOREACH_INITCALL(ptr, stg) { \
|
FOREACH_INITCALL(ptr, stg) \
|
||||||
caller_initcall = ptr; \
|
|
||||||
caller_file = (ptr)->loc_file; \
|
|
||||||
caller_line = (ptr)->loc_line; \
|
|
||||||
(ptr)->fct((ptr)->arg1, (ptr)->arg2, (ptr)->arg3); \
|
(ptr)->fct((ptr)->arg1, (ptr)->arg2, (ptr)->arg3); \
|
||||||
caller_initcall = NULL; \
|
|
||||||
caller_file = NULL; \
|
|
||||||
caller_line = 0; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#endif // USE_OBSOLETE_LINKER
|
#endif // USE_OBSOLETE_LINKER
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef USE_OPENSSL
|
#ifdef USE_OPENSSL
|
||||||
enum jwt_alg jwt_parse_alg(const char *alg_str, unsigned int alg_len);
|
enum jwt_alg jwt_parse_alg(const char *alg_str, unsigned int alg_len);
|
||||||
int jwt_tokenize(const struct buffer *jwt, struct jwt_item *items, unsigned int item_num);
|
int jwt_tokenize(const struct buffer *jwt, struct jwt_item *items, unsigned int *item_num);
|
||||||
int jwt_tree_load_cert(char *path, int pathlen, int tryload_cert, const char *file, int line, char **err);
|
int jwt_tree_load_cert(char *path, int pathlen, int tryload_cert, const char *file, int line, char **err);
|
||||||
|
|
||||||
enum jwt_vrfy_status jwt_verify(const struct buffer *token, const struct buffer *alg,
|
enum jwt_vrfy_status jwt_verify(const struct buffer *token, const struct buffer *alg,
|
||||||
|
|||||||
@ -28,13 +28,13 @@
|
|||||||
#include <import/ebtree-t.h>
|
#include <import/ebtree-t.h>
|
||||||
|
|
||||||
#include <haproxy/api-t.h>
|
#include <haproxy/api-t.h>
|
||||||
#include <haproxy/counters-t.h>
|
|
||||||
#include <haproxy/guid-t.h>
|
#include <haproxy/guid-t.h>
|
||||||
#include <haproxy/obj_type-t.h>
|
#include <haproxy/obj_type-t.h>
|
||||||
#include <haproxy/quic_cc-t.h>
|
#include <haproxy/quic_cc-t.h>
|
||||||
#include <haproxy/quic_sock-t.h>
|
#include <haproxy/quic_sock-t.h>
|
||||||
#include <haproxy/quic_tp-t.h>
|
#include <haproxy/quic_tp-t.h>
|
||||||
#include <haproxy/receiver-t.h>
|
#include <haproxy/receiver-t.h>
|
||||||
|
#include <haproxy/stats-t.h>
|
||||||
#include <haproxy/thread.h>
|
#include <haproxy/thread.h>
|
||||||
|
|
||||||
/* Some pointer types reference below */
|
/* Some pointer types reference below */
|
||||||
@ -263,7 +263,6 @@ struct listener {
|
|||||||
|
|
||||||
struct li_per_thread *per_thr; /* per-thread fields (one per thread in the group) */
|
struct li_per_thread *per_thr; /* per-thread fields (one per thread in the group) */
|
||||||
|
|
||||||
char *extra_counters_storage; /* storage for extra_counters */
|
|
||||||
EXTRA_COUNTERS(extra_counters);
|
EXTRA_COUNTERS(extra_counters);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -42,8 +42,6 @@ extern char clf_tcp_log_format[];
|
|||||||
extern char default_http_log_format[];
|
extern char default_http_log_format[];
|
||||||
extern char clf_http_log_format[];
|
extern char clf_http_log_format[];
|
||||||
extern char default_https_log_format[];
|
extern char default_https_log_format[];
|
||||||
extern char keylog_format_fc[];
|
|
||||||
extern char keylog_format_bc[];
|
|
||||||
|
|
||||||
extern char default_rfc5424_sd_log_format[];
|
extern char default_rfc5424_sd_log_format[];
|
||||||
|
|
||||||
|
|||||||
@ -81,19 +81,9 @@ struct qcc {
|
|||||||
struct quic_fctl fc; /* stream flow control applied on sending */
|
struct quic_fctl fc; /* stream flow control applied on sending */
|
||||||
uint64_t buf_in_flight; /* sum of currently allocated Tx buffer sizes */
|
uint64_t buf_in_flight; /* sum of currently allocated Tx buffer sizes */
|
||||||
struct list frms; /* list of STREAM frames ready for sent */
|
struct list frms; /* list of STREAM frames ready for sent */
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
/* quic */
|
|
||||||
struct quic_pacer pacer; /* engine used to pace emission */
|
struct quic_pacer pacer; /* engine used to pace emission */
|
||||||
int paced_sent_ctr; /* counter for when emission is interrupted due to pacing */
|
int paced_sent_ctr; /* counter for when emission is interrupted due to pacing */
|
||||||
};
|
|
||||||
/* qstrm */
|
|
||||||
struct buffer qstrm_buf;
|
|
||||||
};
|
|
||||||
} tx;
|
} tx;
|
||||||
struct {
|
|
||||||
struct buffer qstrm_buf;
|
|
||||||
} rx;
|
|
||||||
|
|
||||||
uint64_t largest_bidi_r; /* largest remote bidi stream ID opened. */
|
uint64_t largest_bidi_r; /* largest remote bidi stream ID opened. */
|
||||||
uint64_t largest_uni_r; /* largest remote uni stream ID opened. */
|
uint64_t largest_uni_r; /* largest remote uni stream ID opened. */
|
||||||
@ -174,16 +164,13 @@ struct qcs {
|
|||||||
struct bdata_ctr data; /* data utilization counter. Note that <tot> is now used for now as accounting may be difficult with ncbuf. */
|
struct bdata_ctr data; /* data utilization counter. Note that <tot> is now used for now as accounting may be difficult with ncbuf. */
|
||||||
} rx;
|
} rx;
|
||||||
struct {
|
struct {
|
||||||
union {
|
|
||||||
struct qc_stream_desc *stream; /* quic */
|
|
||||||
struct buffer qstrm_buf; /* qstrm */
|
|
||||||
};
|
|
||||||
struct quic_fctl fc; /* stream flow control applied on sending */
|
struct quic_fctl fc; /* stream flow control applied on sending */
|
||||||
struct quic_frame *msd_frm; /* MAX_STREAM_DATA frame prepared */
|
struct quic_frame *msd_frm; /* MAX_STREAM_DATA frame prepared */
|
||||||
} tx;
|
} tx;
|
||||||
|
|
||||||
struct eb64_node by_id;
|
struct eb64_node by_id;
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
|
struct qc_stream_desc *stream;
|
||||||
|
|
||||||
struct list el_recv; /* element of qcc.recv_list */
|
struct list el_recv; /* element of qcc.recv_list */
|
||||||
struct list el_send; /* element of qcc.send_list */
|
struct list el_send; /* element of qcc.send_list */
|
||||||
@ -213,8 +200,6 @@ enum qcc_app_ops_close_side {
|
|||||||
|
|
||||||
/* QUIC application layer operations */
|
/* QUIC application layer operations */
|
||||||
struct qcc_app_ops {
|
struct qcc_app_ops {
|
||||||
const char *alpn;
|
|
||||||
|
|
||||||
/* Initialize <qcc> connection app context. */
|
/* Initialize <qcc> connection app context. */
|
||||||
int (*init)(struct qcc *qcc);
|
int (*init)(struct qcc *qcc);
|
||||||
/* Finish connection initialization if prelude required. */
|
/* Finish connection initialization if prelude required. */
|
||||||
@ -247,9 +232,6 @@ struct qcc_app_ops {
|
|||||||
void (*inc_err_cnt)(void *ctx, int err_code);
|
void (*inc_err_cnt)(void *ctx, int err_code);
|
||||||
/* Set QCC error code as suspicious activity has been detected. */
|
/* Set QCC error code as suspicious activity has been detected. */
|
||||||
void (*report_susp)(void *ctx);
|
void (*report_susp)(void *ctx);
|
||||||
|
|
||||||
/* Free function to close a stream after MUX layer shutdown. */
|
|
||||||
int (*strm_reject)(struct list *out, uint64_t id);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* USE_QUIC */
|
#endif /* USE_QUIC */
|
||||||
|
|||||||
@ -12,9 +12,6 @@
|
|||||||
#include <haproxy/mux_quic-t.h>
|
#include <haproxy/mux_quic-t.h>
|
||||||
#include <haproxy/stconn.h>
|
#include <haproxy/stconn.h>
|
||||||
|
|
||||||
#include <haproxy/h3.h>
|
|
||||||
#include <haproxy/hq_interop.h>
|
|
||||||
|
|
||||||
#define qcc_report_glitch(qcc, inc, ...) ({ \
|
#define qcc_report_glitch(qcc, inc, ...) ({ \
|
||||||
COUNT_GLITCH(__VA_ARGS__); \
|
COUNT_GLITCH(__VA_ARGS__); \
|
||||||
_qcc_report_glitch(qcc, inc); \
|
_qcc_report_glitch(qcc, inc); \
|
||||||
@ -91,7 +88,7 @@ static inline char *qcs_st_to_str(enum qcs_state st)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int qcc_install_app_ops(struct qcc *qcc);
|
int qcc_install_app_ops(struct qcc *qcc, const struct qcc_app_ops *app_ops);
|
||||||
|
|
||||||
/* Register <qcs> stream for http-request timeout. If the stream is not yet
|
/* Register <qcs> stream for http-request timeout. If the stream is not yet
|
||||||
* attached in the configured delay, qcc timeout task will be triggered. This
|
* attached in the configured delay, qcc timeout task will be triggered. This
|
||||||
@ -118,16 +115,6 @@ void qcc_show_quic(struct qcc *qcc);
|
|||||||
|
|
||||||
void qcc_wakeup(struct qcc *qcc);
|
void qcc_wakeup(struct qcc *qcc);
|
||||||
|
|
||||||
static inline const struct qcc_app_ops *quic_alpn_to_app_ops(const char *alpn, int alpn_len)
|
|
||||||
{
|
|
||||||
if (alpn_len >= 2 && memcmp(alpn, "h3", 2) == 0)
|
|
||||||
return &h3_ops;
|
|
||||||
else if (alpn_len >= 10 && memcmp(alpn, "hq-interop", 10) == 0)
|
|
||||||
return &hq_interop_ops;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* USE_QUIC */
|
#endif /* USE_QUIC */
|
||||||
|
|
||||||
#endif /* _HAPROXY_MUX_QUIC_H */
|
#endif /* _HAPROXY_MUX_QUIC_H */
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
#ifndef _HAPROXY_MUX_QUIC_PRIV_H
|
|
||||||
#define _HAPROXY_MUX_QUIC_PRIV_H
|
|
||||||
|
|
||||||
/* This header file should only be used by QUIC-MUX layer internally. */
|
|
||||||
|
|
||||||
#include <haproxy/mux_quic-t.h>
|
|
||||||
|
|
||||||
void qcs_idle_open(struct qcs *qcs);
|
|
||||||
void qcs_close_local(struct qcs *qcs);
|
|
||||||
int qcs_is_completed(struct qcs *qcs);
|
|
||||||
|
|
||||||
uint64_t qcs_prep_bytes(const struct qcs *qcs);
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_MUX_QUIC_PRIV_H */
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
#ifndef _HAPROXY_MUX_QUIC_QSTRM_H
|
|
||||||
#define _HAPROXY_MUX_QUIC_QSTRM_H
|
|
||||||
|
|
||||||
#include <haproxy/mux_quic.h>
|
|
||||||
|
|
||||||
int qcc_qstrm_recv(struct qcc *qcc);
|
|
||||||
|
|
||||||
int qcc_qstrm_send_frames(struct qcc *qcc, struct list *frms);
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_MUX_QUIC_QSTRM_H */
|
|
||||||
@ -47,7 +47,6 @@ enum obj_type {
|
|||||||
OBJ_TYPE_DGRAM, /* object is a struct quic_dgram */
|
OBJ_TYPE_DGRAM, /* object is a struct quic_dgram */
|
||||||
#endif
|
#endif
|
||||||
OBJ_TYPE_HATERM, /* object is a struct hstream */
|
OBJ_TYPE_HATERM, /* object is a struct hstream */
|
||||||
OBJ_TYPE_ACME_RSLV, /* object is a struct acme_rslv */
|
|
||||||
OBJ_TYPE_ENTRIES /* last one : number of entries */
|
OBJ_TYPE_ENTRIES /* last one : number of entries */
|
||||||
} __attribute__((packed)) ;
|
} __attribute__((packed)) ;
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
#ifndef _HAPROXY_OBJ_TYPE_H
|
#ifndef _HAPROXY_OBJ_TYPE_H
|
||||||
#define _HAPROXY_OBJ_TYPE_H
|
#define _HAPROXY_OBJ_TYPE_H
|
||||||
|
|
||||||
#include <haproxy/acme_resolvers-t.h>
|
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/applet-t.h>
|
#include <haproxy/applet-t.h>
|
||||||
#include <haproxy/check-t.h>
|
#include <haproxy/check-t.h>
|
||||||
@ -57,7 +56,6 @@ static inline const char *obj_type_name(const enum obj_type *t)
|
|||||||
case OBJ_TYPE_SC: return "SC";
|
case OBJ_TYPE_SC: return "SC";
|
||||||
case OBJ_TYPE_STREAM: return "STREAM";
|
case OBJ_TYPE_STREAM: return "STREAM";
|
||||||
case OBJ_TYPE_CHECK: return "CHECK";
|
case OBJ_TYPE_CHECK: return "CHECK";
|
||||||
case OBJ_TYPE_ACME_RSLV: return "ACME_RSLV";
|
|
||||||
#ifdef USE_QUIC
|
#ifdef USE_QUIC
|
||||||
case OBJ_TYPE_DGRAM: return "DGRAM";
|
case OBJ_TYPE_DGRAM: return "DGRAM";
|
||||||
#endif
|
#endif
|
||||||
@ -205,18 +203,6 @@ static inline struct hstream *objt_hstream(enum obj_type *t)
|
|||||||
return __objt_hstream(t);
|
return __objt_hstream(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct acme_rslv *__objt_acme_rslv(enum obj_type *t)
|
|
||||||
{
|
|
||||||
return container_of(t, struct acme_rslv, obj_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct acme_rslv *objt_acme_rslv(enum obj_type *t)
|
|
||||||
{
|
|
||||||
if (!t || *t != OBJ_TYPE_ACME_RSLV)
|
|
||||||
return NULL;
|
|
||||||
return __objt_acme_rslv(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_QUIC
|
#ifdef USE_QUIC
|
||||||
static inline struct quic_dgram *__objt_dgram(enum obj_type *t)
|
static inline struct quic_dgram *__objt_dgram(enum obj_type *t)
|
||||||
{
|
{
|
||||||
@ -245,7 +231,6 @@ static inline void *obj_base_ptr(enum obj_type *t)
|
|||||||
case OBJ_TYPE_SC: return __objt_sc(t);
|
case OBJ_TYPE_SC: return __objt_sc(t);
|
||||||
case OBJ_TYPE_STREAM: return __objt_stream(t);
|
case OBJ_TYPE_STREAM: return __objt_stream(t);
|
||||||
case OBJ_TYPE_CHECK: return __objt_check(t);
|
case OBJ_TYPE_CHECK: return __objt_check(t);
|
||||||
case OBJ_TYPE_ACME_RSLV: return __objt_acme_rslv(t);
|
|
||||||
#ifdef USE_QUIC
|
#ifdef USE_QUIC
|
||||||
case OBJ_TYPE_DGRAM: return __objt_dgram(t);
|
case OBJ_TYPE_DGRAM: return __objt_dgram(t);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -394,12 +394,6 @@ static inline unsigned long ERR_peek_error_func(const char **func)
|
|||||||
#define __OPENSSL_110_CONST__
|
#define __OPENSSL_110_CONST__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (HA_OPENSSL_VERSION_NUMBER >= 0x40000000L) && (!defined(USE_OPENSSL_WOLFSSL))
|
|
||||||
#define __X509_NAME_CONST__ const
|
|
||||||
#else
|
|
||||||
#define __X509_NAME_CONST__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ERR_remove_state() was deprecated in 1.0.0 in favor of
|
/* ERR_remove_state() was deprecated in 1.0.0 in favor of
|
||||||
* ERR_remove_thread_state(), which was in turn deprecated in
|
* ERR_remove_thread_state(), which was in turn deprecated in
|
||||||
* 1.1.0 and does nothing anymore. Let's simply silently kill
|
* 1.1.0 and does nothing anymore. Let's simply silently kill
|
||||||
|
|||||||
@ -124,12 +124,6 @@ static inline int real_family(int ss_family)
|
|||||||
return fam ? fam->real_family : AF_UNSPEC;
|
return fam ? fam->real_family : AF_UNSPEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int proto_is_quic(const struct protocol *proto)
|
|
||||||
{
|
|
||||||
return (proto->proto_type == PROTO_TYPE_DGRAM &&
|
|
||||||
proto->xprt_type == PROTO_TYPE_STREAM);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_PROTOCOL_H */
|
#endif /* _HAPROXY_PROTOCOL_H */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -38,6 +38,7 @@
|
|||||||
#include <haproxy/obj_type-t.h>
|
#include <haproxy/obj_type-t.h>
|
||||||
#include <haproxy/queue-t.h>
|
#include <haproxy/queue-t.h>
|
||||||
#include <haproxy/server-t.h>
|
#include <haproxy/server-t.h>
|
||||||
|
#include <haproxy/stats-t.h>
|
||||||
#include <haproxy/tcpcheck-t.h>
|
#include <haproxy/tcpcheck-t.h>
|
||||||
#include <haproxy/thread-t.h>
|
#include <haproxy/thread-t.h>
|
||||||
#include <haproxy/tools-t.h>
|
#include <haproxy/tools-t.h>
|
||||||
@ -117,9 +118,10 @@ enum PR_SRV_STATE_FILE {
|
|||||||
#define PR_O_HTTP_DROP_REQ_TRLS 0x04000000 /* Drop the request trailers when forwarding to the server */
|
#define PR_O_HTTP_DROP_REQ_TRLS 0x04000000 /* Drop the request trailers when forwarding to the server */
|
||||||
#define PR_O_HTTP_DROP_RES_TRLS 0x08000000 /* Drop response trailers when forwarding to the client */
|
#define PR_O_HTTP_DROP_RES_TRLS 0x08000000 /* Drop response trailers when forwarding to the client */
|
||||||
|
|
||||||
/* unused: 0x10000000 */
|
#define PR_O_TCPCHK_SSL 0x10000000 /* at least one TCPCHECK connect rule requires SSL */
|
||||||
#define PR_O_CONTSTATS 0x20000000 /* continuous counters */
|
#define PR_O_CONTSTATS 0x20000000 /* continuous counters */
|
||||||
/* unused: 0x40000000..0x80000000 */
|
#define PR_O_DISABLE404 0x40000000 /* Disable a server on a 404 response to a health-check */
|
||||||
|
/* unused: 0x80000000 */
|
||||||
|
|
||||||
/* bits for proxy->options2 */
|
/* bits for proxy->options2 */
|
||||||
#define PR_O2_SPLIC_REQ 0x00000001 /* transfer requests using linux kernel's splice() */
|
#define PR_O2_SPLIC_REQ 0x00000001 /* transfer requests using linux kernel's splice() */
|
||||||
@ -144,7 +146,7 @@ enum PR_SRV_STATE_FILE {
|
|||||||
|
|
||||||
#define PR_O2_NODELAY 0x00020000 /* fully interactive mode, never delay outgoing data */
|
#define PR_O2_NODELAY 0x00020000 /* fully interactive mode, never delay outgoing data */
|
||||||
#define PR_O2_USE_PXHDR 0x00040000 /* use Proxy-Connection for proxy requests */
|
#define PR_O2_USE_PXHDR 0x00040000 /* use Proxy-Connection for proxy requests */
|
||||||
/* unused: 0x00080000 */
|
#define PR_O2_CHK_SNDST 0x00080000 /* send the state of each server along with HTTP health checks */
|
||||||
|
|
||||||
#define PR_O2_SRC_ADDR 0x00100000 /* get the source ip and port for logs */
|
#define PR_O2_SRC_ADDR 0x00100000 /* get the source ip and port for logs */
|
||||||
|
|
||||||
@ -155,17 +157,14 @@ enum PR_SRV_STATE_FILE {
|
|||||||
#define PR_O2_RSTRICT_REQ_HDR_NAMES_NOOP 0x01000000 /* preserve request header names containing chars outside of [0-9a-zA-Z-] charset */
|
#define PR_O2_RSTRICT_REQ_HDR_NAMES_NOOP 0x01000000 /* preserve request header names containing chars outside of [0-9a-zA-Z-] charset */
|
||||||
#define PR_O2_RSTRICT_REQ_HDR_NAMES_MASK 0x01c00000 /* mask for restrict-http-header-names option */
|
#define PR_O2_RSTRICT_REQ_HDR_NAMES_MASK 0x01c00000 /* mask for restrict-http-header-names option */
|
||||||
|
|
||||||
|
/* unused : 0x02000000 ... 0x08000000 */
|
||||||
|
|
||||||
/* server health checks */
|
/* server health checks */
|
||||||
#define PR_O2_CHK_NONE 0x00000000 /* no L7 health checks configured (TCP by default) */
|
#define PR_O2_CHK_NONE 0x00000000 /* no L7 health checks configured (TCP by default) */
|
||||||
#define PR_O2_TCPCHK_CHK 0x02000000 /* use TCPCHK check for server health */
|
#define PR_O2_TCPCHK_CHK 0x90000000 /* use TCPCHK check for server health */
|
||||||
#define PR_O2_EXT_CHK 0x04000000 /* use external command for server health */
|
#define PR_O2_EXT_CHK 0xA0000000 /* use external command for server health */
|
||||||
#define PR_O2_CHK_ANY 0x06000000 /* Mask to cover any check */
|
/* unused: 0xB0000000 to 0xF000000, reserved for health checks */
|
||||||
|
#define PR_O2_CHK_ANY 0xF0000000 /* Mask to cover any check */
|
||||||
#define PR_O2_USE_SBUF_QUEUE 0x08000000 /* use small buffer for request when stream are queued*/
|
|
||||||
#define PR_O2_USE_SBUF_L7_RETRY 0x10000000 /* use small buffer for request when L7 retires are enabled */
|
|
||||||
#define PR_O2_USE_SBUF_CHECK 0x20000000 /* use small buffer for request's healthchecks */
|
|
||||||
#define PR_O2_USE_SBUF_ALL 0x38000000 /* all flags for use-large-buffer option */
|
|
||||||
/* unused : 0x40000000 ... 0x80000000 */
|
|
||||||
/* end of proxy->options2 */
|
/* end of proxy->options2 */
|
||||||
|
|
||||||
/* bits for proxy->options3 */
|
/* bits for proxy->options3 */
|
||||||
@ -241,16 +240,14 @@ enum PR_SRV_STATE_FILE {
|
|||||||
#define PR_RE_JUNK_REQUEST 0x00020000 /* We received an incomplete or garbage response */
|
#define PR_RE_JUNK_REQUEST 0x00020000 /* We received an incomplete or garbage response */
|
||||||
|
|
||||||
/* Proxy flags */
|
/* Proxy flags */
|
||||||
#define PR_FL_DISABLED 0x00000001 /* The proxy was disabled in the configuration (not at runtime) */
|
#define PR_FL_DISABLED 0x01 /* The proxy was disabled in the configuration (not at runtime) */
|
||||||
#define PR_FL_STOPPED 0x00000002 /* The proxy was stopped */
|
#define PR_FL_STOPPED 0x02 /* The proxy was stopped */
|
||||||
#define PR_FL_DEF_EXPLICIT_MODE 0x00000004 /* Proxy mode is explicitly defined - only used for defaults instance */
|
#define PR_FL_DEF_EXPLICIT_MODE 0x04 /* Proxy mode is explicitely defined - only used for defaults instance */
|
||||||
#define PR_FL_EXPLICIT_REF 0x00000008 /* The default proxy is explicitly referenced by another proxy */
|
#define PR_FL_EXPLICIT_REF 0x08 /* The default proxy is explicitly referenced by another proxy */
|
||||||
#define PR_FL_IMPLICIT_REF 0x00000010 /* The default proxy is implicitly referenced by another proxy */
|
#define PR_FL_IMPLICIT_REF 0x10 /* The default proxy is implicitly referenced by another proxy */
|
||||||
#define PR_FL_PAUSED 0x00000020 /* The proxy was paused at run time (reversible) */
|
#define PR_FL_PAUSED 0x20 /* The proxy was paused at run time (reversible) */
|
||||||
#define PR_FL_CHECKED 0x00000040 /* The proxy configuration was fully checked (including postparsing checks) */
|
#define PR_FL_CHECKED 0x40 /* The proxy configuration was fully checked (including postparsing checks) */
|
||||||
#define PR_FL_BE_UNPUBLISHED 0x00000080 /* The proxy cannot be targeted by content switching rules */
|
#define PR_FL_BE_UNPUBLISHED 0x80 /* The proxy cannot be targetted by content switching rules */
|
||||||
#define PR_FL_DELETED 0x00000100 /* Proxy has been deleted and must be manipulated with care */
|
|
||||||
#define PR_FL_NON_PURGEABLE 0x00000200 /* Proxy referenced by config elements which prevent its runtime removal. */
|
|
||||||
|
|
||||||
struct stream;
|
struct stream;
|
||||||
|
|
||||||
@ -309,16 +306,13 @@ struct error_snapshot {
|
|||||||
struct proxy_per_tgroup {
|
struct proxy_per_tgroup {
|
||||||
struct queue queue;
|
struct queue queue;
|
||||||
struct lbprm_per_tgrp lbprm;
|
struct lbprm_per_tgrp lbprm;
|
||||||
char *extra_counters_fe_storage; /* storage for extra_counters_fe */
|
|
||||||
char *extra_counters_be_storage; /* storage for extra_counters_be */
|
|
||||||
} THREAD_ALIGNED();
|
} THREAD_ALIGNED();
|
||||||
|
|
||||||
struct proxy {
|
struct proxy {
|
||||||
enum obj_type obj_type; /* object type == OBJ_TYPE_PROXY */
|
enum obj_type obj_type; /* object type == OBJ_TYPE_PROXY */
|
||||||
|
char flags; /* bit field PR_FL_* */
|
||||||
enum pr_mode mode; /* mode = PR_MODE_TCP, PR_MODE_HTTP, ... */
|
enum pr_mode mode; /* mode = PR_MODE_TCP, PR_MODE_HTTP, ... */
|
||||||
char cap; /* supported capabilities (PR_CAP_*) */
|
char cap; /* supported capabilities (PR_CAP_*) */
|
||||||
/* 1 byte hole */
|
|
||||||
unsigned int flags; /* bit field PR_FL_* */
|
|
||||||
int to_log; /* things to be logged (LW_*), special value LW_LOGSTEPS == follow log-steps */
|
int to_log; /* things to be logged (LW_*), special value LW_LOGSTEPS == follow log-steps */
|
||||||
unsigned long last_change; /* internal use only: last time the proxy state was changed */
|
unsigned long last_change; /* internal use only: last time the proxy state was changed */
|
||||||
|
|
||||||
@ -444,7 +438,7 @@ struct proxy {
|
|||||||
struct stktable *table; /* table for storing sticking streams */
|
struct stktable *table; /* table for storing sticking streams */
|
||||||
|
|
||||||
struct task *task; /* the associated task, mandatory to manage rate limiting, stopping and resource shortage, NULL if disabled */
|
struct task *task; /* the associated task, mandatory to manage rate limiting, stopping and resource shortage, NULL if disabled */
|
||||||
struct tcpcheck tcpcheck; /* tcp-check to use to perform a health-check */
|
struct tcpcheck_rules tcpcheck_rules; /* tcp-check send / expect rules */
|
||||||
char *check_command; /* Command to use for external agent checks */
|
char *check_command; /* Command to use for external agent checks */
|
||||||
char *check_path; /* PATH environment to use for external agent checks */
|
char *check_path; /* PATH environment to use for external agent checks */
|
||||||
struct http_reply *replies[HTTP_ERR_SIZE]; /* HTTP replies for known errors */
|
struct http_reply *replies[HTTP_ERR_SIZE]; /* HTTP replies for known errors */
|
||||||
@ -482,7 +476,7 @@ struct proxy {
|
|||||||
struct log_steps log_steps; /* bitfield of log origins where log should be generated during request handling */
|
struct log_steps log_steps; /* bitfield of log origins where log should be generated during request handling */
|
||||||
const char *file_prev; /* file of the previous instance found with the same name, or NULL */
|
const char *file_prev; /* file of the previous instance found with the same name, or NULL */
|
||||||
int line_prev; /* line of the previous instance found with the same name, or 0 */
|
int line_prev; /* line of the previous instance found with the same name, or 0 */
|
||||||
unsigned int def_ref; /* default proxy only refcount */
|
unsigned int refcount; /* refcount on this proxy (only used for default proxy for now) */
|
||||||
} conf; /* config information */
|
} conf; /* config information */
|
||||||
struct http_ext *http_ext; /* http ext options */
|
struct http_ext *http_ext; /* http ext options */
|
||||||
struct ceb_root *used_server_addr; /* list of server addresses in use */
|
struct ceb_root *used_server_addr; /* list of server addresses in use */
|
||||||
@ -511,8 +505,6 @@ struct proxy {
|
|||||||
struct list filter_configs; /* list of the filters that are declared on this proxy */
|
struct list filter_configs; /* list of the filters that are declared on this proxy */
|
||||||
|
|
||||||
struct guid_node guid; /* GUID global tree node */
|
struct guid_node guid; /* GUID global tree node */
|
||||||
struct mt_list watcher_list; /* list of elems which currently references this proxy instance (currently only used with backends) */
|
|
||||||
uint refcount; /* refcount to keep proxy from being deleted during runtime */
|
|
||||||
|
|
||||||
EXTRA_COUNTERS(extra_counters_fe);
|
EXTRA_COUNTERS(extra_counters_fe);
|
||||||
EXTRA_COUNTERS(extra_counters_be);
|
EXTRA_COUNTERS(extra_counters_be);
|
||||||
|
|||||||
@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/applet-t.h>
|
#include <haproxy/applet-t.h>
|
||||||
#include <haproxy/counters.h>
|
|
||||||
#include <haproxy/freq_ctr.h>
|
#include <haproxy/freq_ctr.h>
|
||||||
#include <haproxy/list.h>
|
#include <haproxy/list.h>
|
||||||
#include <haproxy/listener-t.h>
|
#include <haproxy/listener-t.h>
|
||||||
@ -59,7 +58,7 @@ void stop_proxy(struct proxy *p);
|
|||||||
int stream_set_backend(struct stream *s, struct proxy *be);
|
int stream_set_backend(struct stream *s, struct proxy *be);
|
||||||
|
|
||||||
void deinit_proxy(struct proxy *p);
|
void deinit_proxy(struct proxy *p);
|
||||||
void proxy_drop(struct proxy *p);
|
void free_proxy(struct proxy *p);
|
||||||
const char *proxy_cap_str(int cap);
|
const char *proxy_cap_str(int cap);
|
||||||
const char *proxy_mode_str(int mode);
|
const char *proxy_mode_str(int mode);
|
||||||
enum pr_mode str_to_proxy_mode(const char *mode);
|
enum pr_mode str_to_proxy_mode(const char *mode);
|
||||||
@ -83,7 +82,6 @@ void proxy_unref_defaults(struct proxy *px);
|
|||||||
int setup_new_proxy(struct proxy *px, const char *name, unsigned int cap, char **errmsg);
|
int setup_new_proxy(struct proxy *px, const char *name, unsigned int cap, char **errmsg);
|
||||||
struct proxy *alloc_new_proxy(const char *name, unsigned int cap,
|
struct proxy *alloc_new_proxy(const char *name, unsigned int cap,
|
||||||
char **errmsg);
|
char **errmsg);
|
||||||
void proxy_take(struct proxy *px);
|
|
||||||
struct proxy *parse_new_proxy(const char *name, unsigned int cap,
|
struct proxy *parse_new_proxy(const char *name, unsigned int cap,
|
||||||
const char *file, int linenum,
|
const char *file, int linenum,
|
||||||
const struct proxy *defproxy);
|
const struct proxy *defproxy);
|
||||||
@ -103,8 +101,6 @@ void free_server_rules(struct list *srules);
|
|||||||
int proxy_init_per_thr(struct proxy *px);
|
int proxy_init_per_thr(struct proxy *px);
|
||||||
int proxy_finalize(struct proxy *px, int *err_code);
|
int proxy_finalize(struct proxy *px, int *err_code);
|
||||||
|
|
||||||
int be_check_for_deletion(const char *bename, struct proxy **pb, const char **pm);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function returns a string containing the type of the proxy in a format
|
* This function returns a string containing the type of the proxy in a format
|
||||||
* suitable for error messages, from its capabilities.
|
* suitable for error messages, from its capabilities.
|
||||||
@ -182,7 +178,7 @@ static inline void proxy_inc_fe_conn_ctr(struct listener *l, struct proxy *fe)
|
|||||||
}
|
}
|
||||||
if (l && l->counters && l->counters->shared.tg)
|
if (l && l->counters && l->counters->shared.tg)
|
||||||
_HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->cum_conn);
|
_HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->cum_conn);
|
||||||
COUNTERS_UPDATE_MAX(&fe->fe_counters.cps_max,
|
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.cps_max,
|
||||||
update_freq_ctr(&fe->fe_counters._conn_per_sec, 1));
|
update_freq_ctr(&fe->fe_counters._conn_per_sec, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +191,7 @@ static inline void proxy_inc_fe_sess_ctr(struct listener *l, struct proxy *fe)
|
|||||||
}
|
}
|
||||||
if (l && l->counters && l->counters->shared.tg)
|
if (l && l->counters && l->counters->shared.tg)
|
||||||
_HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->cum_sess);
|
_HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->cum_sess);
|
||||||
COUNTERS_UPDATE_MAX(&fe->fe_counters.sps_max,
|
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.sps_max,
|
||||||
update_freq_ctr(&fe->fe_counters._sess_per_sec, 1));
|
update_freq_ctr(&fe->fe_counters._sess_per_sec, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +218,7 @@ static inline void proxy_inc_be_ctr(struct proxy *be)
|
|||||||
_HA_ATOMIC_INC(&be->be_counters.shared.tg[tgid - 1]->cum_sess);
|
_HA_ATOMIC_INC(&be->be_counters.shared.tg[tgid - 1]->cum_sess);
|
||||||
update_freq_ctr(&be->be_counters.shared.tg[tgid - 1]->sess_per_sec, 1);
|
update_freq_ctr(&be->be_counters.shared.tg[tgid - 1]->sess_per_sec, 1);
|
||||||
}
|
}
|
||||||
COUNTERS_UPDATE_MAX(&be->be_counters.sps_max,
|
HA_ATOMIC_UPDATE_MAX(&be->be_counters.sps_max,
|
||||||
update_freq_ctr(&be->be_counters._sess_per_sec, 1));
|
update_freq_ctr(&be->be_counters._sess_per_sec, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +238,7 @@ static inline void proxy_inc_fe_req_ctr(struct listener *l, struct proxy *fe,
|
|||||||
}
|
}
|
||||||
if (l && l->counters && l->counters->shared.tg)
|
if (l && l->counters && l->counters->shared.tg)
|
||||||
_HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->p.http.cum_req[http_ver]);
|
_HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->p.http.cum_req[http_ver]);
|
||||||
COUNTERS_UPDATE_MAX(&fe->fe_counters.p.http.rps_max,
|
HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.p.http.rps_max,
|
||||||
update_freq_ctr(&fe->fe_counters.p.http._req_per_sec, 1));
|
update_freq_ctr(&fe->fe_counters.p.http._req_per_sec, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,7 @@
|
|||||||
#include <haproxy/quic_cc-t.h>
|
#include <haproxy/quic_cc-t.h>
|
||||||
#include <haproxy/quic_frame-t.h>
|
#include <haproxy/quic_frame-t.h>
|
||||||
#include <haproxy/quic_openssl_compat-t.h>
|
#include <haproxy/quic_openssl_compat-t.h>
|
||||||
|
#include <haproxy/quic_stats-t.h>
|
||||||
#include <haproxy/quic_tls-t.h>
|
#include <haproxy/quic_tls-t.h>
|
||||||
#include <haproxy/quic_tp-t.h>
|
#include <haproxy/quic_tp-t.h>
|
||||||
#include <haproxy/show_flags-t.h>
|
#include <haproxy/show_flags-t.h>
|
||||||
@ -400,8 +401,6 @@ struct quic_conn {
|
|||||||
|
|
||||||
struct eb_root streams_by_id; /* qc_stream_desc tree */
|
struct eb_root streams_by_id; /* qc_stream_desc tree */
|
||||||
|
|
||||||
const char *alpn;
|
|
||||||
|
|
||||||
/* MUX */
|
/* MUX */
|
||||||
struct qcc *qcc;
|
struct qcc *qcc;
|
||||||
struct task *timer_task;
|
struct task *timer_task;
|
||||||
@ -410,9 +409,7 @@ struct quic_conn {
|
|||||||
/* Handshake expiration date */
|
/* Handshake expiration date */
|
||||||
unsigned int hs_expire;
|
unsigned int hs_expire;
|
||||||
|
|
||||||
/* Callback to close any stream after MUX closure - set by the MUX itself */
|
const struct qcc_app_ops *app_ops;
|
||||||
int (*strm_reject)(struct list *out, uint64_t stream_id);
|
|
||||||
|
|
||||||
/* Proxy counters */
|
/* Proxy counters */
|
||||||
struct quic_counters *prx_counters;
|
struct quic_counters *prx_counters;
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,6 @@
|
|||||||
#include <import/eb64tree.h>
|
#include <import/eb64tree.h>
|
||||||
#include <import/ebmbtree.h>
|
#include <import/ebmbtree.h>
|
||||||
|
|
||||||
#include <haproxy/counters.h>
|
|
||||||
#include <haproxy/chunk.h>
|
#include <haproxy/chunk.h>
|
||||||
#include <haproxy/dynbuf.h>
|
#include <haproxy/dynbuf.h>
|
||||||
#include <haproxy/ncbmbuf.h>
|
#include <haproxy/ncbmbuf.h>
|
||||||
@ -84,7 +83,7 @@ void qc_check_close_on_released_mux(struct quic_conn *qc);
|
|||||||
int quic_stateless_reset_token_cpy(unsigned char *pos, size_t len,
|
int quic_stateless_reset_token_cpy(unsigned char *pos, size_t len,
|
||||||
const unsigned char *salt, size_t saltlen);
|
const unsigned char *salt, size_t saltlen);
|
||||||
int quic_reuse_srv_params(struct quic_conn *qc,
|
int quic_reuse_srv_params(struct quic_conn *qc,
|
||||||
const char *alpn,
|
const unsigned char *alpn,
|
||||||
const struct quic_early_transport_params *etps);
|
const struct quic_early_transport_params *etps);
|
||||||
|
|
||||||
/* Returns true if <qc> is used on the backed side (as a client). */
|
/* Returns true if <qc> is used on the backed side (as a client). */
|
||||||
@ -194,17 +193,13 @@ static inline void *qc_counters(enum obj_type *o, const struct stats_module *m)
|
|||||||
p = l ? l->bind_conf->frontend :
|
p = l ? l->bind_conf->frontend :
|
||||||
s ? s->proxy : NULL;
|
s ? s->proxy : NULL;
|
||||||
|
|
||||||
if (l && p)
|
return p ? EXTRA_COUNTERS_GET(p->extra_counters_fe, m) : NULL;
|
||||||
return EXTRA_COUNTERS_GET(p->extra_counters_fe, m);
|
|
||||||
else if (s && p)
|
|
||||||
return EXTRA_COUNTERS_GET(p->extra_counters_be, m);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void chunk_frm_appendf(struct buffer *buf, const struct quic_frame *frm);
|
void chunk_frm_appendf(struct buffer *buf, const struct quic_frame *frm);
|
||||||
void quic_set_connection_close(struct quic_conn *qc, const struct quic_err err);
|
void quic_set_connection_close(struct quic_conn *qc, const struct quic_err err);
|
||||||
void quic_set_tls_alert(struct quic_conn *qc, int alert);
|
void quic_set_tls_alert(struct quic_conn *qc, int alert);
|
||||||
int qc_register_alpn(struct quic_conn *qc, const char *alpn, int alpn_len);
|
int quic_set_app_ops(struct quic_conn *qc, const unsigned char *alpn, size_t alpn_len);
|
||||||
int qc_check_dcid(struct quic_conn *qc, unsigned char *dcid, size_t dcid_len);
|
int qc_check_dcid(struct quic_conn *qc, unsigned char *dcid, size_t dcid_len);
|
||||||
|
|
||||||
void qc_notify_err(struct quic_conn *qc);
|
void qc_notify_err(struct quic_conn *qc);
|
||||||
|
|||||||
@ -32,6 +32,7 @@
|
|||||||
#include <import/ebtree-t.h>
|
#include <import/ebtree-t.h>
|
||||||
#include <haproxy/buf-t.h>
|
#include <haproxy/buf-t.h>
|
||||||
#include <haproxy/list.h>
|
#include <haproxy/list.h>
|
||||||
|
#include <haproxy/quic_stream-t.h>
|
||||||
#include <haproxy/quic_token.h>
|
#include <haproxy/quic_token.h>
|
||||||
|
|
||||||
extern struct pool_head *pool_head_quic_frame;
|
extern struct pool_head *pool_head_quic_frame;
|
||||||
@ -86,7 +87,6 @@ enum quic_frame_type {
|
|||||||
* defined in quic_frame.c. Do not forget to complete the associated function
|
* defined in quic_frame.c. Do not forget to complete the associated function
|
||||||
* quic_frame_type_is_known() and both qf_builder()/qf_parser().
|
* quic_frame_type_is_known() and both qf_builder()/qf_parser().
|
||||||
*/
|
*/
|
||||||
extern const uint64_t QUIC_FT_QX_TRANSPORT_PARAMETERS;
|
|
||||||
|
|
||||||
#define QUIC_FT_PKT_TYPE_I_BITMASK (1 << QUIC_PACKET_TYPE_INITIAL)
|
#define QUIC_FT_PKT_TYPE_I_BITMASK (1 << QUIC_PACKET_TYPE_INITIAL)
|
||||||
#define QUIC_FT_PKT_TYPE_0_BITMASK (1 << QUIC_PACKET_TYPE_0RTT)
|
#define QUIC_FT_PKT_TYPE_0_BITMASK (1 << QUIC_PACKET_TYPE_0RTT)
|
||||||
@ -169,7 +169,7 @@ struct qf_new_token {
|
|||||||
|
|
||||||
struct qf_stream {
|
struct qf_stream {
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
void *stream;
|
struct qc_stream_desc *stream;
|
||||||
|
|
||||||
/* used only on TX when constructing frames.
|
/* used only on TX when constructing frames.
|
||||||
* Data cleared when processing ACK related to this STREAM frame.
|
* Data cleared when processing ACK related to this STREAM frame.
|
||||||
@ -252,10 +252,6 @@ struct qf_connection_close_app {
|
|||||||
unsigned char reason_phrase[QUIC_CC_REASON_PHRASE_MAXLEN];
|
unsigned char reason_phrase[QUIC_CC_REASON_PHRASE_MAXLEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qf_qx_transport_parameters {
|
|
||||||
struct quic_transport_params params;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct quic_frame {
|
struct quic_frame {
|
||||||
struct list list; /* List elem from parent elem (typically a Tx packet instance, a PKTNS or a MUX element). */
|
struct list list; /* List elem from parent elem (typically a Tx packet instance, a PKTNS or a MUX element). */
|
||||||
struct quic_tx_packet *pkt; /* Last Tx packet used to send the frame. */
|
struct quic_tx_packet *pkt; /* Last Tx packet used to send the frame. */
|
||||||
@ -283,7 +279,6 @@ struct quic_frame {
|
|||||||
struct qf_path_challenge_response path_challenge_response;
|
struct qf_path_challenge_response path_challenge_response;
|
||||||
struct qf_connection_close connection_close;
|
struct qf_connection_close connection_close;
|
||||||
struct qf_connection_close_app connection_close_app;
|
struct qf_connection_close_app connection_close_app;
|
||||||
struct qf_qx_transport_parameters qmux_transport_params;
|
|
||||||
};
|
};
|
||||||
struct quic_frame *origin; /* Parent frame. Set if frame is a duplicate (used for retransmission). */
|
struct quic_frame *origin; /* Parent frame. Set if frame is a duplicate (used for retransmission). */
|
||||||
struct list reflist; /* List head containing duplicated children frames. */
|
struct list reflist; /* List head containing duplicated children frames. */
|
||||||
|
|||||||
@ -34,25 +34,14 @@
|
|||||||
|
|
||||||
const char *quic_frame_type_string(enum quic_frame_type ft);
|
const char *quic_frame_type_string(enum quic_frame_type ft);
|
||||||
|
|
||||||
int qc_build_frm(struct quic_frame *frm,
|
int qc_build_frm(unsigned char **pos, const unsigned char *end,
|
||||||
unsigned char **pos, const unsigned char *end,
|
struct quic_frame *frm, struct quic_tx_packet *pkt,
|
||||||
struct quic_conn *conn);
|
struct quic_conn *conn);
|
||||||
|
|
||||||
int qc_build_frm_pkt(struct quic_frame *frm, struct quic_tx_packet *pkt,
|
int qc_parse_frm(struct quic_frame *frm, struct quic_rx_packet *pkt,
|
||||||
unsigned char **pos, const unsigned char *end,
|
|
||||||
struct quic_conn *qc);
|
|
||||||
|
|
||||||
int qc_parse_frm_type(struct quic_frame *frm,
|
|
||||||
const unsigned char **pos, const unsigned char *end,
|
const unsigned char **pos, const unsigned char *end,
|
||||||
struct quic_conn *conn);
|
struct quic_conn *conn);
|
||||||
|
|
||||||
int qc_parse_frm_pkt(const struct quic_frame *frm,
|
|
||||||
const struct quic_rx_packet *pkt, int *flags);
|
|
||||||
|
|
||||||
int qc_parse_frm_payload(struct quic_frame *frm,
|
|
||||||
const unsigned char **pos, const unsigned char *end,
|
|
||||||
struct quic_conn *qc);
|
|
||||||
|
|
||||||
void qc_release_frm(struct quic_conn *qc, struct quic_frame *frm);
|
void qc_release_frm(struct quic_conn *qc, struct quic_frame *frm);
|
||||||
|
|
||||||
/* Return the length of <frm> frame if succeeded, -1 if not (unknown frames
|
/* Return the length of <frm> frame if succeeded, -1 if not (unknown frames
|
||||||
|
|||||||
@ -6,6 +6,8 @@
|
|||||||
#error "Must define USE_OPENSSL"
|
#error "Must define USE_OPENSSL"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern struct stats_module quic_stats_module;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
QUIC_ST_RXBUF_FULL,
|
QUIC_ST_RXBUF_FULL,
|
||||||
QUIC_ST_DROPPED_PACKET,
|
QUIC_ST_DROPPED_PACKET,
|
||||||
@ -50,7 +52,6 @@ enum {
|
|||||||
QUIC_ST_STREAM_DATA_BLOCKED,
|
QUIC_ST_STREAM_DATA_BLOCKED,
|
||||||
QUIC_ST_STREAMS_BLOCKED_BIDI,
|
QUIC_ST_STREAMS_BLOCKED_BIDI,
|
||||||
QUIC_ST_STREAMS_BLOCKED_UNI,
|
QUIC_ST_STREAMS_BLOCKED_UNI,
|
||||||
QUIC_ST_NCBUF_GAP_LIMIT,
|
|
||||||
QUIC_STATS_COUNT /* must be the last */
|
QUIC_STATS_COUNT /* must be the last */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -98,7 +99,6 @@ struct quic_counters {
|
|||||||
long long stream_data_blocked; /* total number of times STREAM_DATA_BLOCKED frame was received */
|
long long stream_data_blocked; /* total number of times STREAM_DATA_BLOCKED frame was received */
|
||||||
long long streams_blocked_bidi; /* total number of times STREAMS_BLOCKED_BIDI frame was received */
|
long long streams_blocked_bidi; /* total number of times STREAMS_BLOCKED_BIDI frame was received */
|
||||||
long long streams_blocked_uni; /* total number of times STREAMS_BLOCKED_UNI frame was received */
|
long long streams_blocked_uni; /* total number of times STREAMS_BLOCKED_UNI frame was received */
|
||||||
long long ncbuf_gap_limit; /* total number of times we failed to add data to ncbuf due to gap size limit */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* USE_QUIC */
|
#endif /* USE_QUIC */
|
||||||
|
|||||||
@ -7,9 +7,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <haproxy/quic_stats-t.h>
|
#include <haproxy/quic_stats-t.h>
|
||||||
#include <haproxy/stats-t.h>
|
|
||||||
|
|
||||||
extern struct stats_module quic_stats_module;
|
|
||||||
void quic_stats_transp_err_count_inc(struct quic_counters *ctrs, int error_code);
|
void quic_stats_transp_err_count_inc(struct quic_counters *ctrs, int error_code);
|
||||||
|
|
||||||
#endif /* USE_QUIC */
|
#endif /* USE_QUIC */
|
||||||
|
|||||||
@ -124,5 +124,12 @@ struct quic_early_transport_params {
|
|||||||
uint64_t initial_max_streams_uni;
|
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 */
|
||||||
|
QUIC_TP_DEC_ERR_INVAL, /* invalid value as per RFC 9000 */
|
||||||
|
QUIC_TP_DEC_ERR_TRUNC, /* field encoding too small or too large */
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* USE_QUIC */
|
#endif /* USE_QUIC */
|
||||||
#endif /* _HAPROXY_QUIC_TP_T_H */
|
#endif /* _HAPROXY_QUIC_TP_T_H */
|
||||||
|
|||||||
@ -129,12 +129,6 @@ static inline void quic_transport_params_dump(struct buffer *b,
|
|||||||
quic_tp_version_info_dump(b, &p->version_information, local);
|
quic_tp_version_info_dump(b, &p->version_information, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
int quic_transport_param_enc_int(unsigned char **buf,
|
|
||||||
const unsigned char *end,
|
|
||||||
uint64_t type, uint64_t val);
|
|
||||||
int quic_transport_params_decode(struct quic_transport_params *p, int server,
|
|
||||||
const unsigned char *buf, const unsigned char *end);
|
|
||||||
|
|
||||||
static inline void quic_early_transport_params_dump(struct buffer *b,
|
static inline void quic_early_transport_params_dump(struct buffer *b,
|
||||||
const struct quic_conn *qc,
|
const struct quic_conn *qc,
|
||||||
const struct quic_early_transport_params *p)
|
const struct quic_early_transport_params *p)
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
#include <haproxy/connection-t.h>
|
#include <haproxy/connection-t.h>
|
||||||
#include <haproxy/dns-t.h>
|
#include <haproxy/dns-t.h>
|
||||||
#include <haproxy/obj_type-t.h>
|
#include <haproxy/obj_type-t.h>
|
||||||
|
#include <haproxy/stats-t.h>
|
||||||
#include <haproxy/task-t.h>
|
#include <haproxy/task-t.h>
|
||||||
#include <haproxy/thread.h>
|
#include <haproxy/thread.h>
|
||||||
|
|
||||||
@ -72,7 +73,6 @@ extern struct pool_head *resolv_requester_pool;
|
|||||||
/* dns record types (non exhaustive list) */
|
/* dns record types (non exhaustive list) */
|
||||||
#define DNS_RTYPE_A 1 /* IPv4 address */
|
#define DNS_RTYPE_A 1 /* IPv4 address */
|
||||||
#define DNS_RTYPE_CNAME 5 /* canonical name */
|
#define DNS_RTYPE_CNAME 5 /* canonical name */
|
||||||
#define DNS_RTYPE_TXT 16 /* TXT */
|
|
||||||
#define DNS_RTYPE_AAAA 28 /* IPv6 address */
|
#define DNS_RTYPE_AAAA 28 /* IPv6 address */
|
||||||
#define DNS_RTYPE_SRV 33 /* SRV record */
|
#define DNS_RTYPE_SRV 33 /* SRV record */
|
||||||
#define DNS_RTYPE_OPT 41 /* OPT */
|
#define DNS_RTYPE_OPT 41 /* OPT */
|
||||||
|
|||||||
@ -24,7 +24,6 @@
|
|||||||
#define _HAPROXY_SAMPLE_T_H
|
#define _HAPROXY_SAMPLE_T_H
|
||||||
|
|
||||||
#include <haproxy/api-t.h>
|
#include <haproxy/api-t.h>
|
||||||
#include <haproxy/tinfo-t.h>
|
|
||||||
#include <haproxy/sample_data-t.h>
|
#include <haproxy/sample_data-t.h>
|
||||||
|
|
||||||
/* input and output sample types
|
/* input and output sample types
|
||||||
@ -266,7 +265,6 @@ struct sample_conv {
|
|||||||
unsigned int in_type; /* expected input sample type */
|
unsigned int in_type; /* expected input sample type */
|
||||||
unsigned int out_type; /* output sample type */
|
unsigned int out_type; /* output sample type */
|
||||||
void *private; /* private values. only used by maps and Lua */
|
void *private; /* private values. only used by maps and Lua */
|
||||||
struct thread_exec_ctx exec_ctx; /* execution context */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* sample conversion expression */
|
/* sample conversion expression */
|
||||||
@ -290,7 +288,6 @@ struct sample_fetch {
|
|||||||
unsigned int use; /* fetch source (SMP_USE_*) */
|
unsigned int use; /* fetch source (SMP_USE_*) */
|
||||||
unsigned int val; /* fetch validity (SMP_VAL_*) */
|
unsigned int val; /* fetch validity (SMP_VAL_*) */
|
||||||
void *private; /* private values. only used by Lua */
|
void *private; /* private values. only used by Lua */
|
||||||
struct thread_exec_ctx exec_ctx; /* execution context */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* sample expression */
|
/* sample expression */
|
||||||
|
|||||||
@ -36,10 +36,6 @@
|
|||||||
void sc_update_rx(struct stconn *sc);
|
void sc_update_rx(struct stconn *sc);
|
||||||
void sc_update_tx(struct stconn *sc);
|
void sc_update_tx(struct stconn *sc);
|
||||||
|
|
||||||
void sc_abort(struct stconn *sc);
|
|
||||||
void sc_shutdown(struct stconn *sc);
|
|
||||||
void sc_chk_rcv(struct stconn *sc);
|
|
||||||
|
|
||||||
struct task *sc_conn_io_cb(struct task *t, void *ctx, unsigned int state);
|
struct task *sc_conn_io_cb(struct task *t, void *ctx, unsigned int state);
|
||||||
int sc_conn_sync_recv(struct stconn *sc);
|
int sc_conn_sync_recv(struct stconn *sc);
|
||||||
int sc_conn_sync_send(struct stconn *sc);
|
int sc_conn_sync_send(struct stconn *sc);
|
||||||
@ -364,6 +360,38 @@ static inline int sc_is_recv_allowed(const struct stconn *sc)
|
|||||||
return !(sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM));
|
return !(sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is to be used after making some room available in a channel. It will
|
||||||
|
* return without doing anything if the stream connector's RX path is blocked.
|
||||||
|
* It will automatically mark the stream connector as busy processing the end
|
||||||
|
* point in order to avoid useless repeated wakeups.
|
||||||
|
* It will then call ->chk_rcv() to enable receipt of new data.
|
||||||
|
*/
|
||||||
|
static inline void sc_chk_rcv(struct stconn *sc)
|
||||||
|
{
|
||||||
|
if (sc_ep_test(sc, SE_FL_APPLET_NEED_CONN) &&
|
||||||
|
sc_state_in(sc_opposite(sc)->state, SC_SB_RDY|SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) {
|
||||||
|
sc_ep_clr(sc, SE_FL_APPLET_NEED_CONN);
|
||||||
|
sc_ep_report_read_activity(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sc_is_recv_allowed(sc))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!sc_state_in(sc->state, SC_SB_RDY|SC_SB_EST))
|
||||||
|
return;
|
||||||
|
|
||||||
|
sc_ep_set(sc, SE_FL_HAVE_NO_DATA);
|
||||||
|
if (likely(sc->app_ops->chk_rcv))
|
||||||
|
sc->app_ops->chk_rcv(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calls chk_snd on the endpoint using the data layer */
|
||||||
|
static inline void sc_chk_snd(struct stconn *sc)
|
||||||
|
{
|
||||||
|
if (likely(sc->app_ops->chk_snd))
|
||||||
|
sc->app_ops->chk_snd(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Perform a synchronous receive using the right version, depending the endpoing
|
/* Perform a synchronous receive using the right version, depending the endpoing
|
||||||
* is a connection or an applet.
|
* is a connection or an applet.
|
||||||
@ -508,10 +536,24 @@ static inline void sc_schedule_abort(struct stconn *sc)
|
|||||||
sc->flags |= SC_FL_ABRT_WANTED;
|
sc->flags |= SC_FL_ABRT_WANTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Abort the SC and notify the endpoint using the data layer */
|
||||||
|
static inline void sc_abort(struct stconn *sc)
|
||||||
|
{
|
||||||
|
if (likely(sc->app_ops->abort))
|
||||||
|
sc->app_ops->abort(sc);
|
||||||
|
}
|
||||||
|
|
||||||
/* Schedule a shutdown for the SC */
|
/* Schedule a shutdown for the SC */
|
||||||
static inline void sc_schedule_shutdown(struct stconn *sc)
|
static inline void sc_schedule_shutdown(struct stconn *sc)
|
||||||
{
|
{
|
||||||
sc->flags |= SC_FL_SHUT_WANTED;
|
sc->flags |= SC_FL_SHUT_WANTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Shutdown the SC and notify the endpoint using the data layer */
|
||||||
|
static inline void sc_shutdown(struct stconn *sc)
|
||||||
|
{
|
||||||
|
if (likely(sc->app_ops->shutdown))
|
||||||
|
sc->app_ops->shutdown(sc);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _HAPROXY_SC_STRM_H */
|
#endif /* _HAPROXY_SC_STRM_H */
|
||||||
|
|||||||
@ -286,7 +286,6 @@ struct srv_per_tgroup {
|
|||||||
struct queue queue; /* pending connections */
|
struct queue queue; /* pending connections */
|
||||||
struct server *server; /* pointer to the corresponding server */
|
struct server *server; /* pointer to the corresponding server */
|
||||||
struct eb32_node lb_node; /* node used for tree-based load balancing */
|
struct eb32_node lb_node; /* node used for tree-based load balancing */
|
||||||
char *extra_counters_storage; /* storage for extra_counters */
|
|
||||||
struct server *next_full; /* next server in the temporary full list */
|
struct server *next_full; /* next server in the temporary full list */
|
||||||
unsigned int last_other_tgrp_served; /* Last other tgrp we dequeued from */
|
unsigned int last_other_tgrp_served; /* Last other tgrp we dequeued from */
|
||||||
unsigned int self_served; /* Number of connection we dequeued from our own queue */
|
unsigned int self_served; /* Number of connection we dequeued from our own queue */
|
||||||
|
|||||||
@ -29,7 +29,6 @@
|
|||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/applet-t.h>
|
#include <haproxy/applet-t.h>
|
||||||
#include <haproxy/arg-t.h>
|
#include <haproxy/arg-t.h>
|
||||||
#include <haproxy/counters.h>
|
|
||||||
#include <haproxy/freq_ctr.h>
|
#include <haproxy/freq_ctr.h>
|
||||||
#include <haproxy/proxy-t.h>
|
#include <haproxy/proxy-t.h>
|
||||||
#include <haproxy/resolvers-t.h>
|
#include <haproxy/resolvers-t.h>
|
||||||
@ -56,7 +55,6 @@ int srv_update_addr(struct server *s, void *ip, int ip_sin_family, struct server
|
|||||||
struct sample_expr *_parse_srv_expr(char *expr, struct arg_list *args_px,
|
struct sample_expr *_parse_srv_expr(char *expr, struct arg_list *args_px,
|
||||||
const char *file, int linenum, char **err);
|
const char *file, int linenum, char **err);
|
||||||
int server_parse_exprs(struct server *srv, struct proxy *px, char **err);
|
int server_parse_exprs(struct server *srv, struct proxy *px, char **err);
|
||||||
int srv_configure_auto_sni(struct server *srv, int *err_code, char **err);
|
|
||||||
int server_set_inetaddr(struct server *s, const struct server_inetaddr *inetaddr, struct server_inetaddr_updater updater, struct buffer *msg);
|
int server_set_inetaddr(struct server *s, const struct server_inetaddr *inetaddr, struct server_inetaddr_updater updater, struct buffer *msg);
|
||||||
int server_set_inetaddr_warn(struct server *s, const struct server_inetaddr *inetaddr, struct server_inetaddr_updater updater);
|
int server_set_inetaddr_warn(struct server *s, const struct server_inetaddr *inetaddr, struct server_inetaddr_updater updater);
|
||||||
void server_get_inetaddr(struct server *s, struct server_inetaddr *inetaddr);
|
void server_get_inetaddr(struct server *s, struct server_inetaddr *inetaddr);
|
||||||
@ -213,19 +211,15 @@ static inline void srv_inc_sess_ctr(struct server *s)
|
|||||||
_HA_ATOMIC_INC(&s->counters.shared.tg[tgid - 1]->cum_sess);
|
_HA_ATOMIC_INC(&s->counters.shared.tg[tgid - 1]->cum_sess);
|
||||||
update_freq_ctr(&s->counters.shared.tg[tgid - 1]->sess_per_sec, 1);
|
update_freq_ctr(&s->counters.shared.tg[tgid - 1]->sess_per_sec, 1);
|
||||||
}
|
}
|
||||||
COUNTERS_UPDATE_MAX(&s->counters.sps_max,
|
HA_ATOMIC_UPDATE_MAX(&s->counters.sps_max,
|
||||||
update_freq_ctr(&s->counters._sess_per_sec, 1));
|
update_freq_ctr(&s->counters._sess_per_sec, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the time of last session on the designated server */
|
/* set the time of last session on the designated server */
|
||||||
static inline void srv_set_sess_last(struct server *s)
|
static inline void srv_set_sess_last(struct server *s)
|
||||||
{
|
{
|
||||||
if (s->counters.shared.tg) {
|
if (s->counters.shared.tg)
|
||||||
uint now_sec = ns_to_sec(now_ms);
|
HA_ATOMIC_STORE(&s->counters.shared.tg[tgid - 1]->last_sess, ns_to_sec(now_ns));
|
||||||
|
|
||||||
if (HA_ATOMIC_LOAD(&s->counters.shared.tg[tgid - 1]->last_sess) != now_sec)
|
|
||||||
HA_ATOMIC_STORE(&s->counters.shared.tg[tgid - 1]->last_sess, now_sec);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns the current server throttle rate between 0 and 100% */
|
/* returns the current server throttle rate between 0 and 100% */
|
||||||
@ -355,26 +349,28 @@ static inline int srv_is_transparent(const struct server *srv)
|
|||||||
(srv->flags & SRV_F_MAPPORTS);
|
(srv->flags & SRV_F_MAPPORTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detach <srv> server from its parent proxy list.
|
/* Detach server from proxy list. It is supported to call this
|
||||||
*
|
* even if the server is not yet in the list
|
||||||
* Must be called under thread isolation.
|
* Must be called under thread isolation or when it is safe to assume
|
||||||
|
* that the parent proxy doesn't is not skimming through the server list
|
||||||
*/
|
*/
|
||||||
static inline void srv_detach(struct server *srv)
|
static inline void srv_detach(struct server *srv)
|
||||||
{
|
{
|
||||||
struct proxy *px = srv->proxy;
|
struct proxy *px = srv->proxy;
|
||||||
|
|
||||||
|
if (px->srv == srv)
|
||||||
|
px->srv = srv->next;
|
||||||
|
else {
|
||||||
struct server *prev;
|
struct server *prev;
|
||||||
|
|
||||||
if (px->srv == srv) {
|
|
||||||
px->srv = srv->next;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (prev = px->srv; prev && prev->next != srv; prev = prev->next)
|
for (prev = px->srv; prev && prev->next != srv; prev = prev->next)
|
||||||
;
|
;
|
||||||
BUG_ON(!prev); /* Server instance not found in proxy list ? */
|
|
||||||
|
BUG_ON(!prev);
|
||||||
|
|
||||||
prev->next = srv->next;
|
prev->next = srv->next;
|
||||||
}
|
}
|
||||||
|
/* reset the proxy's ready_srv if it was this one */
|
||||||
/* Reset the proxy's ready_srv if it was this one. */
|
|
||||||
HA_ATOMIC_CAS(&px->ready_srv, &srv, NULL);
|
HA_ATOMIC_CAS(&px->ready_srv, &srv, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -339,7 +339,7 @@ struct global_ssl {
|
|||||||
char **passphrase_cmd;
|
char **passphrase_cmd;
|
||||||
int passphrase_cmd_args_cnt;
|
int passphrase_cmd_args_cnt;
|
||||||
|
|
||||||
unsigned int certificate_compression:1; /* allow to explicitly disable certificate compression */
|
unsigned int certificate_compression:1; /* allow to explicitely disable certificate compression */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The order here matters for picking a default context,
|
/* The order here matters for picking a default context,
|
||||||
|
|||||||
@ -25,13 +25,12 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <haproxy/connection.h>
|
#include <haproxy/connection.h>
|
||||||
#include <haproxy/counters.h>
|
|
||||||
#include <haproxy/openssl-compat.h>
|
#include <haproxy/openssl-compat.h>
|
||||||
#include <haproxy/pool-t.h>
|
#include <haproxy/pool-t.h>
|
||||||
#include <haproxy/proxy-t.h>
|
#include <haproxy/proxy-t.h>
|
||||||
#include <haproxy/quic_conn-t.h>
|
#include <haproxy/quic_conn-t.h>
|
||||||
#include <haproxy/ssl_sock-t.h>
|
#include <haproxy/ssl_sock-t.h>
|
||||||
#include <haproxy/stats-t.h>
|
#include <haproxy/stats.h>
|
||||||
#include <haproxy/thread.h>
|
#include <haproxy/thread.h>
|
||||||
|
|
||||||
extern struct list tlskeys_reference;
|
extern struct list tlskeys_reference;
|
||||||
@ -74,7 +73,7 @@ int ssl_sock_get_alpn(const struct connection *conn, void *xprt_ctx,
|
|||||||
const char **str, int *len);
|
const char **str, int *len);
|
||||||
int ssl_bio_and_sess_init(struct connection *conn, SSL_CTX *ssl_ctx,
|
int ssl_bio_and_sess_init(struct connection *conn, SSL_CTX *ssl_ctx,
|
||||||
SSL **ssl, BIO **bio, BIO_METHOD *bio_meth, void *ctx);
|
SSL **ssl, BIO **bio, BIO_METHOD *bio_meth, void *ctx);
|
||||||
void ssl_sock_srv_try_reuse_sess(struct ssl_sock_ctx *ctx, struct server *srv);
|
int 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_sni(struct connection *conn);
|
||||||
const char *ssl_sock_get_cert_sig(struct connection *conn);
|
const char *ssl_sock_get_cert_sig(struct connection *conn);
|
||||||
const char *ssl_sock_get_cipher_name(struct connection *conn);
|
const char *ssl_sock_get_cipher_name(struct connection *conn);
|
||||||
|
|||||||
@ -34,10 +34,10 @@ int cert_get_pkey_algo(X509 *crt, struct buffer *out);
|
|||||||
int ssl_sock_get_serial(X509 *crt, struct buffer *out);
|
int ssl_sock_get_serial(X509 *crt, struct buffer *out);
|
||||||
int ssl_sock_crt2der(X509 *crt, struct buffer *out);
|
int ssl_sock_crt2der(X509 *crt, struct buffer *out);
|
||||||
int ssl_sock_get_time(ASN1_TIME *tm, struct buffer *out);
|
int ssl_sock_get_time(ASN1_TIME *tm, struct buffer *out);
|
||||||
int ssl_sock_get_dn_entry(__X509_NAME_CONST__ X509_NAME *a, const struct buffer *entry, int pos,
|
int ssl_sock_get_dn_entry(X509_NAME *a, const struct buffer *entry, int pos,
|
||||||
struct buffer *out);
|
struct buffer *out);
|
||||||
int ssl_sock_get_dn_formatted(__X509_NAME_CONST__ X509_NAME *a, const struct buffer *format, struct buffer *out);
|
int ssl_sock_get_dn_formatted(X509_NAME *a, const struct buffer *format, struct buffer *out);
|
||||||
int ssl_sock_get_dn_oneline(__X509_NAME_CONST__ X509_NAME *a, struct buffer *out);
|
int ssl_sock_get_dn_oneline(X509_NAME *a, struct buffer *out);
|
||||||
X509* ssl_sock_get_peer_certificate(SSL *ssl);
|
X509* ssl_sock_get_peer_certificate(SSL *ssl);
|
||||||
X509* ssl_sock_get_verified_chain_root(SSL *ssl);
|
X509* ssl_sock_get_verified_chain_root(SSL *ssl);
|
||||||
unsigned int openssl_version_parser(const char *version);
|
unsigned int openssl_version_parser(const char *version);
|
||||||
|
|||||||
@ -36,7 +36,7 @@ struct shm_stats_file_hdr {
|
|||||||
/* 2 bytes hole */
|
/* 2 bytes hole */
|
||||||
uint global_now_ms; /* global monotonic date (ms) common to all processes using the shm */
|
uint global_now_ms; /* global monotonic date (ms) common to all processes using the shm */
|
||||||
ullong global_now_ns; /* global monotonic date (ns) common to all processes using the shm */
|
ullong global_now_ns; /* global monotonic date (ns) common to all processes using the shm */
|
||||||
ALWAYS_PAD(8); // 8 bytes hole
|
llong now_offset; /* offset applied to global monotonic date on startup */
|
||||||
/* each process uses one slot and is identified using its pid, max 64 in order
|
/* each process uses one slot and is identified using its pid, max 64 in order
|
||||||
* to be able to use bitmask to refer to a process and then look its pid in the
|
* to be able to use bitmask to refer to a process and then look its pid in the
|
||||||
* "slots.pid" map
|
* "slots.pid" map
|
||||||
|
|||||||
@ -25,7 +25,6 @@
|
|||||||
#include <import/ebtree-t.h>
|
#include <import/ebtree-t.h>
|
||||||
#include <haproxy/api-t.h>
|
#include <haproxy/api-t.h>
|
||||||
#include <haproxy/buf-t.h>
|
#include <haproxy/buf-t.h>
|
||||||
#include <haproxy/counters-t.h>
|
|
||||||
|
|
||||||
/* Flags for applet.ctx.stats.flags */
|
/* Flags for applet.ctx.stats.flags */
|
||||||
#define STAT_F_FMT_HTML 0x00000001 /* dump the stats in HTML format */
|
#define STAT_F_FMT_HTML 0x00000001 /* dump the stats in HTML format */
|
||||||
@ -37,7 +36,7 @@
|
|||||||
#define STAT_F_CHUNKED 0x00000040 /* use chunked encoding (HTTP/1.1) */
|
#define STAT_F_CHUNKED 0x00000040 /* use chunked encoding (HTTP/1.1) */
|
||||||
#define STAT_F_JSON_SCHM 0x00000080 /* dump the json schema */
|
#define STAT_F_JSON_SCHM 0x00000080 /* dump the json schema */
|
||||||
|
|
||||||
#define STAT_F_SHOWVER 0x00000100 /* conf: report the version and reldate */
|
#define STAT_F_HIDEVER 0x00000100 /* conf: do not report the version and reldate */
|
||||||
#define STAT_F_SHNODE 0x00000200 /* conf: show node name */
|
#define STAT_F_SHNODE 0x00000200 /* conf: show node name */
|
||||||
#define STAT_F_SHDESC 0x00000400 /* conf: show description */
|
#define STAT_F_SHDESC 0x00000400 /* conf: show description */
|
||||||
#define STAT_F_SHLGNDS 0x00000800 /* conf: show legends */
|
#define STAT_F_SHLGNDS 0x00000800 /* conf: show legends */
|
||||||
@ -516,13 +515,23 @@ struct field {
|
|||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum counters_type {
|
||||||
|
COUNTERS_FE = 0,
|
||||||
|
COUNTERS_BE,
|
||||||
|
COUNTERS_SV,
|
||||||
|
COUNTERS_LI,
|
||||||
|
COUNTERS_RSLV,
|
||||||
|
|
||||||
|
COUNTERS_OFF_END
|
||||||
|
};
|
||||||
|
|
||||||
/* Entity used to generate statistics on an HAProxy component */
|
/* Entity used to generate statistics on an HAProxy component */
|
||||||
struct stats_module {
|
struct stats_module {
|
||||||
struct list list;
|
struct list list;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
/* function used to generate the stats module using counters provided through data parameter */
|
/* functor used to generate the stats module using counters provided through data parameter */
|
||||||
int (*fill_stats)(struct stats_module *, struct extra_counters *, struct field *, unsigned int *);
|
int (*fill_stats)(void *data, struct field *, unsigned int *);
|
||||||
|
|
||||||
struct stat_col *stats; /* statistics provided by the module */
|
struct stat_col *stats; /* statistics provided by the module */
|
||||||
void *counters; /* initial values of allocated counters */
|
void *counters; /* initial values of allocated counters */
|
||||||
@ -534,6 +543,12 @@ struct stats_module {
|
|||||||
char clearable; /* reset on a clear counters */
|
char clearable; /* reset on a clear counters */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct extra_counters {
|
||||||
|
char *data; /* heap containing counters allocated in a linear fashion */
|
||||||
|
size_t size; /* size of allocated data */
|
||||||
|
enum counters_type type; /* type of object containing the counters */
|
||||||
|
};
|
||||||
|
|
||||||
/* stats_domain is used in a flag as a 1 byte field */
|
/* stats_domain is used in a flag as a 1 byte field */
|
||||||
enum stats_domain {
|
enum stats_domain {
|
||||||
STATS_DOMAIN_PROXY = 0,
|
STATS_DOMAIN_PROXY = 0,
|
||||||
@ -578,9 +593,58 @@ struct show_stat_ctx {
|
|||||||
int iid, type, sid; /* proxy id, type and service id if bounding of stats is enabled */
|
int iid, type, sid; /* proxy id, type and service id if bounding of stats is enabled */
|
||||||
int st_code; /* the status code returned by an action */
|
int st_code; /* the status code returned by an action */
|
||||||
struct buffer chunk; /* temporary buffer which holds a single-line output */
|
struct buffer chunk; /* temporary buffer which holds a single-line output */
|
||||||
struct watcher px_watch; /* watcher to automatically update obj1 on backend deletion */
|
|
||||||
struct watcher srv_watch; /* watcher to automatically update obj2 on server deletion */
|
struct watcher srv_watch; /* watcher to automatically update obj2 on server deletion */
|
||||||
enum stat_state state; /* phase of output production */
|
enum stat_state state; /* phase of output production */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern THREAD_LOCAL void *trash_counters;
|
||||||
|
|
||||||
|
#define EXTRA_COUNTERS(name) \
|
||||||
|
struct extra_counters *name
|
||||||
|
|
||||||
|
#define EXTRA_COUNTERS_GET(counters, mod) \
|
||||||
|
(likely(counters) ? \
|
||||||
|
((void *)((counters)->data + (mod)->counters_off[(counters)->type])) : \
|
||||||
|
(trash_counters))
|
||||||
|
|
||||||
|
#define EXTRA_COUNTERS_REGISTER(counters, ctype, alloc_failed_label) \
|
||||||
|
do { \
|
||||||
|
typeof(*counters) _ctr; \
|
||||||
|
_ctr = calloc(1, sizeof(*_ctr)); \
|
||||||
|
if (!_ctr) \
|
||||||
|
goto alloc_failed_label; \
|
||||||
|
_ctr->type = (ctype); \
|
||||||
|
*(counters) = _ctr; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EXTRA_COUNTERS_ADD(mod, counters, new_counters, csize) \
|
||||||
|
do { \
|
||||||
|
typeof(counters) _ctr = (counters); \
|
||||||
|
(mod)->counters_off[_ctr->type] = _ctr->size; \
|
||||||
|
_ctr->size += (csize); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EXTRA_COUNTERS_ALLOC(counters, alloc_failed_label) \
|
||||||
|
do { \
|
||||||
|
typeof(counters) _ctr = (counters); \
|
||||||
|
_ctr->data = malloc((_ctr)->size); \
|
||||||
|
if (!_ctr->data) \
|
||||||
|
goto alloc_failed_label; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EXTRA_COUNTERS_INIT(counters, mod, init_counters, init_counters_size) \
|
||||||
|
do { \
|
||||||
|
typeof(counters) _ctr = (counters); \
|
||||||
|
memcpy(_ctr->data + mod->counters_off[_ctr->type], \
|
||||||
|
(init_counters), (init_counters_size)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EXTRA_COUNTERS_FREE(counters) \
|
||||||
|
do { \
|
||||||
|
if (counters) { \
|
||||||
|
free((counters)->data); \
|
||||||
|
free(counters); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif /* _HAPROXY_STATS_T_H */
|
#endif /* _HAPROXY_STATS_T_H */
|
||||||
|
|||||||
@ -24,7 +24,6 @@
|
|||||||
#define _HAPROXY_STATS_H
|
#define _HAPROXY_STATS_H
|
||||||
|
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/counters.h>
|
|
||||||
#include <haproxy/listener-t.h>
|
#include <haproxy/listener-t.h>
|
||||||
#include <haproxy/stats-t.h>
|
#include <haproxy/stats-t.h>
|
||||||
#include <haproxy/tools-t.h>
|
#include <haproxy/tools-t.h>
|
||||||
@ -168,8 +167,7 @@ static inline enum stats_domain_px_cap stats_px_get_cap(uint32_t domain)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int stats_allocate_proxy_counters_internal(struct extra_counters **counters,
|
int stats_allocate_proxy_counters_internal(struct extra_counters **counters,
|
||||||
int type, int px_cap,
|
int type, int px_cap);
|
||||||
char **storage, size_t step);
|
|
||||||
int stats_allocate_proxy_counters(struct proxy *px);
|
int stats_allocate_proxy_counters(struct proxy *px);
|
||||||
|
|
||||||
void stats_register_module(struct stats_module *m);
|
void stats_register_module(struct stats_module *m);
|
||||||
|
|||||||
@ -73,9 +73,7 @@ enum se_flags {
|
|||||||
SE_FL_DETACHED = 0x00000010, /* The endpoint is detached (no mux/no applet) */
|
SE_FL_DETACHED = 0x00000010, /* The endpoint is detached (no mux/no applet) */
|
||||||
SE_FL_ORPHAN = 0x00000020, /* The endpoint is orphan (no stream connector) */
|
SE_FL_ORPHAN = 0x00000020, /* The endpoint is orphan (no stream connector) */
|
||||||
|
|
||||||
SE_FL_APP_STARTED= 0x00000040, /* the application layer has really started */
|
/* unused: 0x00000040 .. 0x00000080 */
|
||||||
|
|
||||||
/* unused: 0x00000080 */
|
|
||||||
|
|
||||||
SE_FL_SHRD = 0x00000100, /* read shut, draining extra data */
|
SE_FL_SHRD = 0x00000100, /* read shut, draining extra data */
|
||||||
SE_FL_SHRR = 0x00000200, /* read shut, resetting extra data */
|
SE_FL_SHRR = 0x00000200, /* read shut, resetting extra data */
|
||||||
@ -137,12 +135,12 @@ static forceinline char *se_show_flags(char *buf, size_t len, const char *delim,
|
|||||||
_(0);
|
_(0);
|
||||||
/* flags */
|
/* flags */
|
||||||
_(SE_FL_T_MUX, _(SE_FL_T_APPLET, _(SE_FL_DETACHED, _(SE_FL_ORPHAN,
|
_(SE_FL_T_MUX, _(SE_FL_T_APPLET, _(SE_FL_DETACHED, _(SE_FL_ORPHAN,
|
||||||
_(SE_FL_APP_STARTED, _(SE_FL_SHRD, _(SE_FL_SHRR, _(SE_FL_SHWN, _(SE_FL_SHWS,
|
_(SE_FL_SHRD, _(SE_FL_SHRR, _(SE_FL_SHWN, _(SE_FL_SHWS,
|
||||||
_(SE_FL_NOT_FIRST, _(SE_FL_WEBSOCKET, _(SE_FL_EOI, _(SE_FL_EOS,
|
_(SE_FL_NOT_FIRST, _(SE_FL_WEBSOCKET, _(SE_FL_EOI, _(SE_FL_EOS,
|
||||||
_(SE_FL_ERROR, _(SE_FL_ERR_PENDING, _(SE_FL_RCV_MORE,
|
_(SE_FL_ERROR, _(SE_FL_ERR_PENDING, _(SE_FL_RCV_MORE,
|
||||||
_(SE_FL_WANT_ROOM, _(SE_FL_EXP_NO_DATA, _(SE_FL_MAY_FASTFWD_PROD, _(SE_FL_MAY_FASTFWD_CONS,
|
_(SE_FL_WANT_ROOM, _(SE_FL_EXP_NO_DATA, _(SE_FL_MAY_FASTFWD_PROD, _(SE_FL_MAY_FASTFWD_CONS,
|
||||||
_(SE_FL_WAIT_FOR_HS, _(SE_FL_KILL_CONN, _(SE_FL_WAIT_DATA,
|
_(SE_FL_WAIT_FOR_HS, _(SE_FL_KILL_CONN, _(SE_FL_WAIT_DATA,
|
||||||
_(SE_FL_WONT_CONSUME, _(SE_FL_HAVE_NO_DATA, _(SE_FL_APPLET_NEED_CONN))))))))))))))))))))))))));
|
_(SE_FL_WONT_CONSUME, _(SE_FL_HAVE_NO_DATA, _(SE_FL_APPLET_NEED_CONN)))))))))))))))))))))))));
|
||||||
/* epilogue */
|
/* epilogue */
|
||||||
_(~0U);
|
_(~0U);
|
||||||
return buf;
|
return buf;
|
||||||
@ -351,6 +349,19 @@ struct sedesc {
|
|||||||
unsigned long long kop; /* Known outgoing payload length (see above) */
|
unsigned long long kop; /* Known outgoing payload length (see above) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* sc_app_ops describes the application layer's operations and notification
|
||||||
|
* callbacks when I/O activity is reported and to use to perform shutr/shutw.
|
||||||
|
* There are very few combinations in practice (strm/chk <-> none/mux/applet).
|
||||||
|
*/
|
||||||
|
struct sc_app_ops {
|
||||||
|
void (*chk_rcv)(struct stconn *); /* chk_rcv function, may not be null */
|
||||||
|
void (*chk_snd)(struct stconn *); /* chk_snd function, may not be null */
|
||||||
|
void (*abort)(struct stconn *); /* abort function, may not be null */
|
||||||
|
void (*shutdown)(struct stconn *); /* shutdown function, may not be null */
|
||||||
|
int (*wake)(struct stconn *); /* data-layer callback to report activity */
|
||||||
|
char name[8]; /* data layer name, zero-terminated */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This structure describes the elements of a connection relevant to a stream
|
* This structure describes the elements of a connection relevant to a stream
|
||||||
*/
|
*/
|
||||||
@ -372,6 +383,7 @@ struct stconn {
|
|||||||
struct wait_event wait_event; /* We're in a wait list */
|
struct wait_event wait_event; /* We're in a wait list */
|
||||||
struct sedesc *sedesc; /* points to the stream endpoint descriptor */
|
struct sedesc *sedesc; /* points to the stream endpoint descriptor */
|
||||||
enum obj_type *app; /* points to the applicative point (stream or check) */
|
enum obj_type *app; /* points to the applicative point (stream or check) */
|
||||||
|
const struct sc_app_ops *app_ops; /* general operations used at the app layer */
|
||||||
struct sockaddr_storage *src; /* source address (pool), when known, otherwise NULL */
|
struct sockaddr_storage *src; /* source address (pool), when known, otherwise NULL */
|
||||||
struct sockaddr_storage *dst; /* destination address (pool), when known, otherwise NULL */
|
struct sockaddr_storage *dst; /* destination address (pool), when known, otherwise NULL */
|
||||||
};
|
};
|
||||||
|
|||||||
@ -45,7 +45,8 @@ void se_shutdown(struct sedesc *sedesc, enum se_shut_mode mode);
|
|||||||
|
|
||||||
struct stconn *sc_new_from_endp(struct sedesc *sedesc, struct session *sess, struct buffer *input);
|
struct stconn *sc_new_from_endp(struct sedesc *sedesc, struct session *sess, struct buffer *input);
|
||||||
struct stconn *sc_new_from_strm(struct stream *strm, unsigned int flags);
|
struct stconn *sc_new_from_strm(struct stream *strm, unsigned int flags);
|
||||||
struct stconn *sc_new_from_check(struct check *check);
|
struct stconn *sc_new_from_check(struct check *check, unsigned int flags);
|
||||||
|
struct stconn *sc_new_from_haterm(struct sedesc *sd, struct session *sess, struct buffer *input);
|
||||||
void sc_free(struct stconn *sc);
|
void sc_free(struct stconn *sc);
|
||||||
|
|
||||||
int sc_attach_mux(struct stconn *sc, void *target, void *ctx);
|
int sc_attach_mux(struct stconn *sc, void *target, void *ctx);
|
||||||
@ -56,8 +57,6 @@ void sc_destroy(struct stconn *sc);
|
|||||||
int sc_reset_endp(struct stconn *sc);
|
int sc_reset_endp(struct stconn *sc);
|
||||||
|
|
||||||
struct appctx *sc_applet_create(struct stconn *sc, struct applet *app);
|
struct appctx *sc_applet_create(struct stconn *sc, struct applet *app);
|
||||||
int sc_applet_process(struct stconn *sc);
|
|
||||||
int sc_conn_process(struct stconn *sc);
|
|
||||||
|
|
||||||
void sc_conn_prepare_endp_upgrade(struct stconn *sc);
|
void sc_conn_prepare_endp_upgrade(struct stconn *sc);
|
||||||
void sc_conn_abort_endp_upgrade(struct stconn *sc);
|
void sc_conn_abort_endp_upgrade(struct stconn *sc);
|
||||||
@ -350,6 +349,16 @@ static inline struct hstream *sc_hstream(const struct stconn *sc)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns the name of the application layer's name for the stconn,
|
||||||
|
* or "NONE" when none is attached.
|
||||||
|
*/
|
||||||
|
static inline const char *sc_get_data_name(const struct stconn *sc)
|
||||||
|
{
|
||||||
|
if (!sc->app_ops)
|
||||||
|
return "NONE";
|
||||||
|
return sc->app_ops->name;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns non-zero if the stream connector's Rx path is blocked because of
|
/* Returns non-zero if the stream connector's Rx path is blocked because of
|
||||||
* lack of room in the input buffer. This usually happens after applets failed
|
* lack of room in the input buffer. This usually happens after applets failed
|
||||||
* to deliver data into the channel's buffer and reported it via sc_need_room().
|
* to deliver data into the channel's buffer and reported it via sc_need_room().
|
||||||
@ -451,7 +460,7 @@ static inline size_t se_nego_ff(struct sedesc *se, struct buffer *input, size_t
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = CALL_MUX_WITH_RET(mux, nego_fastfwd(se->sc, input, count, flags));
|
ret = mux->nego_fastfwd(se->sc, input, count, flags);
|
||||||
if (se->iobuf.flags & IOBUF_FL_FF_BLOCKED) {
|
if (se->iobuf.flags & IOBUF_FL_FF_BLOCKED) {
|
||||||
sc_ep_report_blocked_send(se->sc, 0);
|
sc_ep_report_blocked_send(se->sc, 0);
|
||||||
|
|
||||||
@ -484,7 +493,7 @@ static inline size_t se_done_ff(struct sedesc *se)
|
|||||||
size_t to_send = se_ff_data(se);
|
size_t to_send = se_ff_data(se);
|
||||||
|
|
||||||
BUG_ON(!mux->done_fastfwd);
|
BUG_ON(!mux->done_fastfwd);
|
||||||
ret = CALL_MUX_WITH_RET(mux, done_fastfwd(se->sc));
|
ret = mux->done_fastfwd(se->sc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/* Something was forwarded, unblock the zero-copy forwarding.
|
/* Something was forwarded, unblock the zero-copy forwarding.
|
||||||
* If all data was sent, report and send activity.
|
* If all data was sent, report and send activity.
|
||||||
@ -516,7 +525,7 @@ static inline size_t se_done_ff(struct sedesc *se)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
se->sc->bytes_out += ret;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -180,7 +180,6 @@ enum {
|
|||||||
STRM_EVT_SHUT_SRV_DOWN = 0x00000004, /* Must be shut because the selected server became available */
|
STRM_EVT_SHUT_SRV_DOWN = 0x00000004, /* Must be shut because the selected server became available */
|
||||||
STRM_EVT_SHUT_SRV_UP = 0x00000008, /* Must be shut because a preferred server became available */
|
STRM_EVT_SHUT_SRV_UP = 0x00000008, /* Must be shut because a preferred server became available */
|
||||||
STRM_EVT_KILLED = 0x00000010, /* Must be shut for external reason */
|
STRM_EVT_KILLED = 0x00000010, /* Must be shut for external reason */
|
||||||
STRM_EVT_RES = 0x00000020, /* A requested resource is available (a buffer, a conn_slot...) */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This function is used to report flags in debugging tools. Please reflect
|
/* This function is used to report flags in debugging tools. Please reflect
|
||||||
|
|||||||
@ -412,7 +412,6 @@ static inline void stream_shutdown(struct stream *s, int why)
|
|||||||
static inline unsigned int stream_map_task_state(unsigned int state)
|
static inline unsigned int stream_map_task_state(unsigned int state)
|
||||||
{
|
{
|
||||||
return ((state & TASK_WOKEN_TIMER) ? STRM_EVT_TIMER : 0) |
|
return ((state & TASK_WOKEN_TIMER) ? STRM_EVT_TIMER : 0) |
|
||||||
((state & TASK_WOKEN_RES) ? STRM_EVT_RES : 0) |
|
|
||||||
((state & TASK_WOKEN_MSG) ? STRM_EVT_MSG : 0) |
|
((state & TASK_WOKEN_MSG) ? STRM_EVT_MSG : 0) |
|
||||||
((state & TASK_F_UEVT1) ? STRM_EVT_SHUT_SRV_DOWN : 0) |
|
((state & TASK_F_UEVT1) ? STRM_EVT_SHUT_SRV_DOWN : 0) |
|
||||||
((state & TASK_F_UEVT3) ? STRM_EVT_SHUT_SRV_UP : 0) |
|
((state & TASK_F_UEVT3) ? STRM_EVT_SHUT_SRV_UP : 0) |
|
||||||
|
|||||||
@ -130,6 +130,7 @@ struct notification {
|
|||||||
* on return.
|
* on return.
|
||||||
*/
|
*/
|
||||||
#define TASK_COMMON \
|
#define TASK_COMMON \
|
||||||
|
struct { \
|
||||||
unsigned int state; /* task state : bitfield of TASK_ */ \
|
unsigned int state; /* task state : bitfield of TASK_ */ \
|
||||||
int tid; /* tid of task/tasklet. <0 = local for tasklet, unbound for task */ \
|
int tid; /* tid of task/tasklet. <0 = local for tasklet, unbound for task */ \
|
||||||
struct task *(*process)(struct task *t, void *ctx, unsigned int state); /* the function which processes the task */ \
|
struct task *(*process)(struct task *t, void *ctx, unsigned int state); /* the function which processes the task */ \
|
||||||
@ -138,14 +139,11 @@ struct notification {
|
|||||||
uint32_t wake_date; /* date of the last task wakeup */ \
|
uint32_t wake_date; /* date of the last task wakeup */ \
|
||||||
unsigned int calls; /* number of times process was called */ \
|
unsigned int calls; /* number of times process was called */ \
|
||||||
TASK_DEBUG_STORAGE; \
|
TASK_DEBUG_STORAGE; \
|
||||||
short last_run; /* 16-bit now_ms of last run */
|
}
|
||||||
/* a 16- or 48-bit hole remains here and is used by task */
|
|
||||||
|
|
||||||
/* The base for all tasks */
|
/* The base for all tasks */
|
||||||
struct task {
|
struct task {
|
||||||
TASK_COMMON; /* must be at the beginning! */
|
TASK_COMMON; /* must be at the beginning! */
|
||||||
short nice; /* task prio from -1024 to +1024 */
|
|
||||||
int expire; /* next expiration date for this task, in ticks */
|
|
||||||
struct eb32_node rq; /* ebtree node used to hold the task in the run queue */
|
struct eb32_node rq; /* ebtree node used to hold the task in the run queue */
|
||||||
/* WARNING: the struct task is often aliased as a struct tasklet when
|
/* WARNING: the struct task is often aliased as a struct tasklet when
|
||||||
* it is NOT in the run queue. The tasklet has its struct list here
|
* it is NOT in the run queue. The tasklet has its struct list here
|
||||||
@ -153,12 +151,14 @@ struct task {
|
|||||||
* ever reorder these fields without taking this into account!
|
* ever reorder these fields without taking this into account!
|
||||||
*/
|
*/
|
||||||
struct eb32_node wq; /* ebtree node used to hold the task in the wait queue */
|
struct eb32_node wq; /* ebtree node used to hold the task in the wait queue */
|
||||||
|
int expire; /* next expiration date for this task, in ticks */
|
||||||
|
short nice; /* task prio from -1024 to +1024 */
|
||||||
|
/* 16-bit hole here */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* lightweight tasks, without priority, mainly used for I/Os */
|
/* lightweight tasks, without priority, mainly used for I/Os */
|
||||||
struct tasklet {
|
struct tasklet {
|
||||||
TASK_COMMON; /* must be at the beginning! */
|
TASK_COMMON; /* must be at the beginning! */
|
||||||
/* 48-bit hole here */
|
|
||||||
struct list list;
|
struct list list;
|
||||||
/* WARNING: the struct task is often aliased as a struct tasklet when
|
/* WARNING: the struct task is often aliased as a struct tasklet when
|
||||||
* it is not in the run queue. The task has its struct rq here where
|
* it is not in the run queue. The task has its struct rq here where
|
||||||
|
|||||||
@ -104,15 +104,10 @@ enum tcpcheck_rule_type {
|
|||||||
TCPCHK_ACT_ACTION_KW, /* custom registered action_kw rule. */
|
TCPCHK_ACT_ACTION_KW, /* custom registered action_kw rule. */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TCPCHK_FL_NONE 0x00000000
|
|
||||||
#define TCPCHK_FL_UNUSED_TCP_RS 0x00000001 /* An unused tcp-check ruleset exists for the current proxy */
|
|
||||||
#define TCPCHK_FL_UNUSED_HTTP_RS 0x00000002 /* An unused http-check ruleset exists for the current proxy */
|
|
||||||
#define TCPCHK_FL_UNUSED_RS 0x00000003 /* Mask for unused ruleset */
|
|
||||||
#define TCPCHK_FL_USE_SSL 0x00000004 /* tcp-check uses SSL connection */
|
|
||||||
|
|
||||||
#define TCPCHK_RULES_NONE 0x00000000
|
#define TCPCHK_RULES_NONE 0x00000000
|
||||||
#define TCPCHK_RULES_DISABLE404 0x00000001 /* Disable a server on a 404 response wht HTTP health checks */
|
#define TCPCHK_RULES_UNUSED_TCP_RS 0x00000001 /* An unused tcp-check ruleset exists */
|
||||||
#define TCPCHK_RULES_SNDST 0x00000002 /* send the state of each server along with HTTP health checks */
|
#define TCPCHK_RULES_UNUSED_HTTP_RS 0x00000002 /* An unused http-check ruleset exists */
|
||||||
|
#define TCPCHK_RULES_UNUSED_RS 0x00000003 /* Mask for unused ruleset */
|
||||||
|
|
||||||
#define TCPCHK_RULES_PGSQL_CHK 0x00000010
|
#define TCPCHK_RULES_PGSQL_CHK 0x00000010
|
||||||
#define TCPCHK_RULES_REDIS_CHK 0x00000020
|
#define TCPCHK_RULES_REDIS_CHK 0x00000020
|
||||||
@ -126,7 +121,6 @@ enum tcpcheck_rule_type {
|
|||||||
/* Unused 0x000000A0..0x00000FF0 (reserved for future proto) */
|
/* Unused 0x000000A0..0x00000FF0 (reserved for future proto) */
|
||||||
#define TCPCHK_RULES_TCP_CHK 0x00000FF0
|
#define TCPCHK_RULES_TCP_CHK 0x00000FF0
|
||||||
#define TCPCHK_RULES_PROTO_CHK 0x00000FF0 /* Mask to cover protocol check */
|
#define TCPCHK_RULES_PROTO_CHK 0x00000FF0 /* Mask to cover protocol check */
|
||||||
#define TCPCHK_RULES_MAY_USE_SBUF 0x00001000 /* checks may try to use small buffers if possible for the request */
|
|
||||||
|
|
||||||
struct check;
|
struct check;
|
||||||
struct tcpcheck_connect {
|
struct tcpcheck_connect {
|
||||||
@ -233,24 +227,18 @@ struct tcpcheck_var {
|
|||||||
struct list list; /* element to chain tcp-check vars */
|
struct list list; /* element to chain tcp-check vars */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* a list of tcp-check rules */
|
||||||
|
struct tcpcheck_rules {
|
||||||
|
unsigned int flags; /* flags applied to the rules */
|
||||||
|
struct list *list; /* the list of tcpcheck_rules */
|
||||||
|
struct list preset_vars; /* The list of variable to preset before executing the ruleset */
|
||||||
|
};
|
||||||
|
|
||||||
/* A list of tcp-check rules with a name */
|
/* A list of tcp-check rules with a name */
|
||||||
struct tcpcheck_ruleset {
|
struct tcpcheck_ruleset {
|
||||||
struct list rules; /* the list of tcpcheck_rule */
|
struct list rules; /* the list of tcpcheck_rule */
|
||||||
unsigned int flags; /* flags applied to the rules */
|
|
||||||
struct ebpt_node node; /* node in the shared tree */
|
struct ebpt_node node; /* node in the shared tree */
|
||||||
struct {
|
|
||||||
struct list preset_vars; /* The list of variable to preset for healthcheck sections */
|
|
||||||
unsigned int flags; /* TCPCHECK_FL_* for healthcheck sections */
|
|
||||||
const char *file; /* file where the section appears */
|
|
||||||
int line; /* line where the section appears */
|
|
||||||
} conf; /* config information */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tcpcheck {
|
|
||||||
struct tcpcheck_ruleset *rs; /* The tcp-check ruleset to use */
|
|
||||||
char *healthcheck; /* name of the healthcheck section (NULL if not used) */
|
|
||||||
struct list preset_vars; /* The list of variable to preset before executing the ruleset */
|
|
||||||
unsigned int flags; /* TCPCHECK_FL_* */
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_CHECKS_T_H */
|
#endif /* _HAPROXY_CHECKS_T_H */
|
||||||
|
|||||||
@ -36,7 +36,7 @@ extern struct action_kw_list tcp_check_keywords;
|
|||||||
extern struct pool_head *pool_head_tcpcheck_rule;
|
extern struct pool_head *pool_head_tcpcheck_rule;
|
||||||
|
|
||||||
int tcpcheck_get_step_id(const struct check *check, const struct tcpcheck_rule *rule);
|
int tcpcheck_get_step_id(const struct check *check, const struct tcpcheck_rule *rule);
|
||||||
struct tcpcheck_rule *get_first_tcpcheck_rule(const struct tcpcheck_ruleset *rs);
|
struct tcpcheck_rule *get_first_tcpcheck_rule(const struct tcpcheck_rules *rules);
|
||||||
|
|
||||||
struct tcpcheck_ruleset *create_tcpcheck_ruleset(const char *name);
|
struct tcpcheck_ruleset *create_tcpcheck_ruleset(const char *name);
|
||||||
struct tcpcheck_ruleset *find_tcpcheck_ruleset(const char *name);
|
struct tcpcheck_ruleset *find_tcpcheck_ruleset(const char *name);
|
||||||
@ -50,9 +50,9 @@ void free_tcpcheck_var(struct tcpcheck_var *var);
|
|||||||
int dup_tcpcheck_vars(struct list *dst, const struct list *src);
|
int dup_tcpcheck_vars(struct list *dst, const struct list *src);
|
||||||
void free_tcpcheck_vars(struct list *vars);
|
void free_tcpcheck_vars(struct list *vars);
|
||||||
|
|
||||||
int add_tcpcheck_expect_str(struct tcpcheck_ruleset *rs, const char *str);
|
int add_tcpcheck_expect_str(struct tcpcheck_rules *rules, const char *str);
|
||||||
int add_tcpcheck_send_strs(struct tcpcheck_ruleset *rs, const char * const *strs);
|
int add_tcpcheck_send_strs(struct tcpcheck_rules *rules, const char * const *strs);
|
||||||
int tcpcheck_add_http_rule(struct tcpcheck_rule *chk, struct tcpcheck_ruleset *rs, char **errmsg);
|
int tcpcheck_add_http_rule(struct tcpcheck_rule *chk, struct tcpcheck_rules *rules, char **errmsg);
|
||||||
|
|
||||||
void free_tcpcheck_http_hdr(struct tcpcheck_http_hdr *hdr);
|
void free_tcpcheck_http_hdr(struct tcpcheck_http_hdr *hdr);
|
||||||
|
|
||||||
@ -83,6 +83,10 @@ struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, struct pro
|
|||||||
struct list *rules, unsigned int proto,
|
struct list *rules, unsigned int proto,
|
||||||
const char *file, int line, char **errmsg);
|
const char *file, int line, char **errmsg);
|
||||||
|
|
||||||
|
int proxy_parse_tcpcheck(char **args, int section, struct proxy *curpx,
|
||||||
|
const struct proxy *defpx, const char *file, int line,
|
||||||
|
char **errmsg);
|
||||||
|
|
||||||
int proxy_parse_tcp_check_opt(char **args, int cur_arg, struct proxy *curpx, const struct proxy *defpx,
|
int proxy_parse_tcp_check_opt(char **args, int cur_arg, struct proxy *curpx, const struct proxy *defpx,
|
||||||
const char *file, int line);
|
const char *file, int line);
|
||||||
int proxy_parse_redis_check_opt(char **args, int cur_arg, struct proxy *curpx, const struct proxy *defpx,
|
int proxy_parse_redis_check_opt(char **args, int cur_arg, struct proxy *curpx, const struct proxy *defpx,
|
||||||
@ -102,8 +106,6 @@ int proxy_parse_spop_check_opt(char **args, int cur_arg, struct proxy *curpx, co
|
|||||||
int proxy_parse_httpchk_opt(char **args, int cur_arg, struct proxy *curpx, const struct proxy *defpx,
|
int proxy_parse_httpchk_opt(char **args, int cur_arg, struct proxy *curpx, const struct proxy *defpx,
|
||||||
const char *file, int line);
|
const char *file, int line);
|
||||||
|
|
||||||
int check_server_tcpcheck(struct server *srv);
|
|
||||||
|
|
||||||
void tcp_check_keywords_register(struct action_kw_list *kw_list);
|
void tcp_check_keywords_register(struct action_kw_list *kw_list);
|
||||||
|
|
||||||
/* Return the struct action_kw associated to a keyword */
|
/* Return the struct action_kw associated to a keyword */
|
||||||
@ -131,22 +133,6 @@ static inline int tcpchk_rules_type_to_proto_mode(int tcpchk_rules_type)
|
|||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char *tcpcheck_ruleset_type_to_str(struct tcpcheck_ruleset *rs)
|
|
||||||
{
|
|
||||||
switch (rs->flags & TCPCHK_RULES_PROTO_CHK) {
|
|
||||||
case TCPCHK_RULES_PGSQL_CHK: return "PGSQL"; break;
|
|
||||||
case TCPCHK_RULES_REDIS_CHK: return "REDIS"; break;
|
|
||||||
case TCPCHK_RULES_SMTP_CHK: return "SMTP"; break;
|
|
||||||
case TCPCHK_RULES_HTTP_CHK: return "HTTP"; break;
|
|
||||||
case TCPCHK_RULES_MYSQL_CHK: return "MYSQL"; break;
|
|
||||||
case TCPCHK_RULES_LDAP_CHK: return "LDAP"; break;
|
|
||||||
case TCPCHK_RULES_SSL3_CHK: return "SSL3"; break;
|
|
||||||
case TCPCHK_RULES_AGENT_CHK: return "AGENT"; break;
|
|
||||||
case TCPCHK_RULES_SPOP_CHK: return "SPOP"; break;
|
|
||||||
case TCPCHK_RULES_TCP_CHK: return "TCP"; break;
|
|
||||||
default: return "???"; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* _HAPROXY_TCPCHECK_H */
|
#endif /* _HAPROXY_TCPCHECK_H */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -217,7 +217,6 @@ enum lock_label {
|
|||||||
QC_CID_LOCK,
|
QC_CID_LOCK,
|
||||||
CACHE_LOCK,
|
CACHE_LOCK,
|
||||||
GUID_LOCK,
|
GUID_LOCK,
|
||||||
PROXIES_DEL_LOCK,
|
|
||||||
OTHER_LOCK,
|
OTHER_LOCK,
|
||||||
/* WT: make sure never to use these ones outside of development,
|
/* WT: make sure never to use these ones outside of development,
|
||||||
* we need them for lock profiling!
|
* we need them for lock profiling!
|
||||||
|
|||||||
@ -75,41 +75,6 @@ enum {
|
|||||||
/* we have 4 buffer-wait queues, in highest to lowest emergency order */
|
/* we have 4 buffer-wait queues, in highest to lowest emergency order */
|
||||||
#define DYNBUF_NBQ 4
|
#define DYNBUF_NBQ 4
|
||||||
|
|
||||||
/* execution context, for tracing resource usage or warning origins */
|
|
||||||
enum thread_exec_ctx_type {
|
|
||||||
TH_EX_CTX_NONE = 0, /* context not filled */
|
|
||||||
TH_EX_CTX_OTHER, /* context only known by a generic pointer */
|
|
||||||
TH_EX_CTX_INITCALL, /* the pointer is an initcall providing file:line */
|
|
||||||
TH_EX_CTX_CALLER, /* the pointer is an ha_caller of the caller providing file:line etc */
|
|
||||||
TH_EX_CTX_SMPF, /* directly registered sample fetch function, using .smpf_kwl */
|
|
||||||
TH_EX_CTX_CONV, /* directly registered converter function, using .conv_kwl */
|
|
||||||
TH_EX_CTX_FUNC, /* hopefully recognizable function/callback, using .pointer */
|
|
||||||
TH_EX_CTX_ACTION, /* directly registered action function, using .action_kwl */
|
|
||||||
TH_EX_CTX_FLT, /* filter whose config is in .flt_conf */
|
|
||||||
TH_EX_CTX_MUX, /* mux whose mux_ops is in .mux_ops */
|
|
||||||
TH_EX_CTX_TASK, /* task or tasklet whose function is in .task */
|
|
||||||
TH_EX_CTX_APPLET, /* applet whose applet is in .applet */
|
|
||||||
TH_EX_CTX_CLI_KWL, /* CLI keyword list, using .cli_kwl */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct thread_exec_ctx {
|
|
||||||
enum thread_exec_ctx_type type;
|
|
||||||
/* 32-bit hole here on 64-bit platforms */
|
|
||||||
union {
|
|
||||||
const void *pointer; /* generic pointer (for other) */
|
|
||||||
const struct initcall *initcall; /* used with TH_EX_CTX_INITCALL */
|
|
||||||
const struct ha_caller *ha_caller; /* used with TH_EX_CTX_CALLER */
|
|
||||||
const struct sample_fetch_kw_list *smpf_kwl; /* used with TH_EX_CTX_SMPF */
|
|
||||||
const struct sample_conv_kw_list *conv_kwl; /* used with TH_EX_CTX_CONV */
|
|
||||||
const struct action_kw_list *action_kwl; /* used with TH_EX_CTX_ACTION */
|
|
||||||
const struct flt_conf *flt_conf; /* used with TH_EX_CTX_FLTCONF */
|
|
||||||
const struct mux_ops *mux_ops; /* used with TH_EX_CTX_MUX */
|
|
||||||
const struct task *(*task)(struct task *, void *, unsigned int); /* used with TH_EX_CTX_TASK */
|
|
||||||
const struct applet *applet; /* used with TH_EX_CTX_APPLET */
|
|
||||||
const struct cli_kw_list *cli_kwl; /* used with TH_EX_CTX_CLI_KWL */
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Thread group information. This defines a base and a count of global thread
|
/* Thread group information. This defines a base and a count of global thread
|
||||||
* IDs which belong to it, and which can be looked up into thread_info/ctx. It
|
* IDs which belong to it, and which can be looked up into thread_info/ctx. It
|
||||||
* is set up during parsing and is stable during operation. Thread groups start
|
* is set up during parsing and is stable during operation. Thread groups start
|
||||||
@ -207,7 +172,8 @@ struct thread_ctx {
|
|||||||
uint64_t curr_mono_time; /* latest system wide monotonic time (leaving poll) */
|
uint64_t curr_mono_time; /* latest system wide monotonic time (leaving poll) */
|
||||||
|
|
||||||
ulong lock_history; /* history of used locks, see thread.h for more details */
|
ulong lock_history; /* history of used locks, see thread.h for more details */
|
||||||
struct thread_exec_ctx exec_ctx; /* current execution context when known, or NULL */
|
|
||||||
|
/* around 56 unused bytes here */
|
||||||
|
|
||||||
// fourth cache line here on 64 bits: accessed mostly using atomic ops
|
// fourth cache line here on 64 bits: accessed mostly using atomic ops
|
||||||
ALWAYS_ALIGN(64);
|
ALWAYS_ALIGN(64);
|
||||||
@ -233,7 +199,6 @@ struct thread_ctx {
|
|||||||
struct buffer *last_dump_buffer; /* Copy of last buffer used for a dump; may be NULL or invalid; for post-mortem only */
|
struct buffer *last_dump_buffer; /* Copy of last buffer used for a dump; may be NULL or invalid; for post-mortem only */
|
||||||
unsigned long long total_streams; /* Total number of streams created on this thread */
|
unsigned long long total_streams; /* Total number of streams created on this thread */
|
||||||
unsigned int stream_cnt; /* Number of streams attached to this thread */
|
unsigned int stream_cnt; /* Number of streams attached to this thread */
|
||||||
unsigned int rq_tot_peak; /* total run queue size last call */
|
|
||||||
|
|
||||||
// around 68 bytes here for shared variables
|
// around 68 bytes here for shared variables
|
||||||
|
|
||||||
|
|||||||
@ -117,42 +117,4 @@ static inline void thread_set_pin_grp1(struct thread_set *ts, ulong mask)
|
|||||||
ts->rel[i] = 0;
|
ts->rel[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* switches the current execution context to <ctx> and returns the previous one
|
|
||||||
* so that this may even be used to save and restore. Setting EXEC_CTX_NONE
|
|
||||||
* resets it. It's efficient because it uses a pair of registers on input and
|
|
||||||
* output.
|
|
||||||
*/
|
|
||||||
static inline struct thread_exec_ctx switch_exec_ctx(const struct thread_exec_ctx ctx)
|
|
||||||
{
|
|
||||||
const struct thread_exec_ctx prev = th_ctx->exec_ctx;
|
|
||||||
|
|
||||||
th_ctx->exec_ctx = ctx;
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* used to reset the execution context */
|
|
||||||
#define EXEC_CTX_NONE ((struct thread_exec_ctx){ .type = 0, .pointer = NULL })
|
|
||||||
|
|
||||||
/* make an execution context from a type and a pointer */
|
|
||||||
#define EXEC_CTX_MAKE(_type, _pointer) ((struct thread_exec_ctx){ .type = (_type), .pointer = (_pointer) })
|
|
||||||
|
|
||||||
/* execute expression <expr> under context <new_ctx> then restore the previous
|
|
||||||
* one, and return the expression's return value.
|
|
||||||
*/
|
|
||||||
#define EXEC_CTX_WITH_RET(new_ctx, expr) ({ \
|
|
||||||
const struct thread_exec_ctx __prev_ctx = switch_exec_ctx(new_ctx); \
|
|
||||||
typeof(expr) __ret = (expr); \
|
|
||||||
switch_exec_ctx(__prev_ctx); \
|
|
||||||
__ret; \
|
|
||||||
})
|
|
||||||
|
|
||||||
/* execute expression <expr> under context <new_ctx> then restore the previous
|
|
||||||
* one. This one has no return value.
|
|
||||||
*/
|
|
||||||
#define EXEC_CTX_NO_RET(new_ctx, expr) do { \
|
|
||||||
const struct thread_exec_ctx __prev_ctx = switch_exec_ctx(new_ctx); \
|
|
||||||
do { expr; } while (0); \
|
|
||||||
switch_exec_ctx(__prev_ctx); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_TINFO_H */
|
#endif /* _HAPROXY_TINFO_H */
|
||||||
|
|||||||
@ -1147,13 +1147,10 @@ void dump_hex(struct buffer *out, const char *pfx, const void *buf, int len, int
|
|||||||
int may_access(const void *ptr);
|
int may_access(const void *ptr);
|
||||||
const void *resolve_sym_name(struct buffer *buf, const char *pfx, const void *addr);
|
const void *resolve_sym_name(struct buffer *buf, const char *pfx, const void *addr);
|
||||||
const void *resolve_dso_name(struct buffer *buf, const char *pfx, const void *addr);
|
const void *resolve_dso_name(struct buffer *buf, const char *pfx, const void *addr);
|
||||||
void make_tar_header(char *output, const char *pfx, const char *fname, const char *link, size_t size, mode_t mode);
|
|
||||||
int load_file_into_tar(char **storage, size_t *size, const char *pfx, const char *fname, const char *input, const char *link);
|
|
||||||
const char *get_exec_path(void);
|
const char *get_exec_path(void);
|
||||||
void *get_sym_curr_addr(const char *name);
|
void *get_sym_curr_addr(const char *name);
|
||||||
void *get_sym_next_addr(const char *name);
|
void *get_sym_next_addr(const char *name);
|
||||||
int dump_libs(struct buffer *output, int with_addr);
|
int dump_libs(struct buffer *output, int with_addr);
|
||||||
void collect_libs(void);
|
|
||||||
|
|
||||||
/* Note that this may result in opening libgcc() on first call, so it may need
|
/* Note that this may result in opening libgcc() on first call, so it may need
|
||||||
* to have been called once before chrooting.
|
* to have been called once before chrooting.
|
||||||
@ -1327,62 +1324,6 @@ static inline uint statistical_prng_range(uint range)
|
|||||||
return mul32hi(statistical_prng(), range ? range - 1 : 0);
|
return mul32hi(statistical_prng(), range ? range - 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The functions below are used to hash one or two pointers together and reduce
|
|
||||||
* the result to fit into a given number of bits. The first part is made of a
|
|
||||||
* multiplication (and possibly an addition) by one or two prime numbers giving
|
|
||||||
* a 64-bit number whose center bits are the most distributed, and the second
|
|
||||||
* part will reuse this value and return a mix of the most variable bits that
|
|
||||||
* fits in the requested size. The most convenient approach is to directly
|
|
||||||
* call ptr_hash() / ptr2_hash(), though for some specific use cases where a
|
|
||||||
* second value could be useful, one may prefer to call the lower level
|
|
||||||
* operations instead.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* reduce a 64-bit pointer hash to <bits> bits */
|
|
||||||
static forceinline uint _ptr_hash_reduce(unsigned long long x, const int bits)
|
|
||||||
{
|
|
||||||
if (!bits)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (sizeof(long) == 4)
|
|
||||||
x ^= x >> 32;
|
|
||||||
else
|
|
||||||
x >>= 31 - (bits + 1) / 2;
|
|
||||||
return x & (~0U >> (-bits & 31));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* single-pointer version, low-level, use ptr_hash() instead */
|
|
||||||
static forceinline ullong _ptr_hash(const void *p)
|
|
||||||
{
|
|
||||||
unsigned long long x = (unsigned long)p;
|
|
||||||
|
|
||||||
x *= 0xacd1be85U;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* two-pointer version, low-level, use ptr2_hash() instead */
|
|
||||||
static forceinline ullong _ptr2_hash(const void *p1, const void *p2)
|
|
||||||
{
|
|
||||||
unsigned long long x = (unsigned long)p1;
|
|
||||||
unsigned long long y = (unsigned long)p2;
|
|
||||||
|
|
||||||
x *= 0xacd1be85U;
|
|
||||||
y *= 0x9d28e4e9U;
|
|
||||||
return x ^ y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* two-pointer plus arg version, low-level, use ptr2_hash_arg() instead */
|
|
||||||
static forceinline ullong _ptr2_hash_arg(const void *p1, const void *p2, ulong arg)
|
|
||||||
{
|
|
||||||
unsigned long long x = (unsigned long)p1;
|
|
||||||
unsigned long long y = (unsigned long)p2;
|
|
||||||
|
|
||||||
x *= 0xacd1be85U;
|
|
||||||
x += arg;
|
|
||||||
y *= 0x9d28e4e9U;
|
|
||||||
return x ^ y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns a hash on <bits> bits of pointer <p> that is suitable for being used
|
/* returns a hash on <bits> bits of pointer <p> that is suitable for being used
|
||||||
* to compute statistic buckets, in that it's fast and reasonably distributed
|
* to compute statistic buckets, in that it's fast and reasonably distributed
|
||||||
* thanks to mixing the bits via a multiplication by a prime number and using
|
* thanks to mixing the bits via a multiplication by a prime number and using
|
||||||
@ -1396,7 +1337,17 @@ static forceinline ullong _ptr2_hash_arg(const void *p1, const void *p2, ulong a
|
|||||||
*/
|
*/
|
||||||
static forceinline uint ptr_hash(const void *p, const int bits)
|
static forceinline uint ptr_hash(const void *p, const int bits)
|
||||||
{
|
{
|
||||||
return _ptr_hash_reduce(_ptr_hash(p), bits);
|
unsigned long long x = (unsigned long)p;
|
||||||
|
|
||||||
|
if (!bits)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
x *= 0xacd1be85U;
|
||||||
|
if (sizeof(long) == 4)
|
||||||
|
x ^= x >> 32;
|
||||||
|
else
|
||||||
|
x >>= 31 - (bits + 1) / 2;
|
||||||
|
return x & (~0U >> (-bits & 31));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same as above but works on two pointers. It will return the same values
|
/* Same as above but works on two pointers. It will return the same values
|
||||||
@ -1404,15 +1355,20 @@ static forceinline uint ptr_hash(const void *p, const int bits)
|
|||||||
*/
|
*/
|
||||||
static forceinline uint ptr2_hash(const void *p1, const void *p2, const int bits)
|
static forceinline uint ptr2_hash(const void *p1, const void *p2, const int bits)
|
||||||
{
|
{
|
||||||
return _ptr_hash_reduce(_ptr2_hash(p1, p2), bits);
|
unsigned long long x = (unsigned long)p1;
|
||||||
}
|
unsigned long long y = (unsigned long)p2;
|
||||||
|
|
||||||
/* Same as above but works on two pointers and a long argument. It will return
|
if (!bits)
|
||||||
* the same values if the second pointer is NULL.
|
return 0;
|
||||||
*/
|
|
||||||
static forceinline uint ptr2_hash_arg(const void *p1, const void *p2, ulong arg, const int bits)
|
x *= 0xacd1be85U;
|
||||||
{
|
y *= 0x9d28e4e9U;
|
||||||
return _ptr_hash_reduce(_ptr2_hash_arg(p1, p2, arg), bits);
|
x ^= y;
|
||||||
|
if (sizeof(long) == 4)
|
||||||
|
x ^= x >> 32;
|
||||||
|
else
|
||||||
|
x >>= 33 - bits / 2;
|
||||||
|
return x & (~0U >> (-bits & 31));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1543,6 +1499,4 @@ void ha_freearray(char ***array);
|
|||||||
|
|
||||||
void ha_memset_s(void *s, int c, size_t n);
|
void ha_memset_s(void *s, int c, size_t n);
|
||||||
|
|
||||||
void chunk_append_thread_ctx(struct buffer *output, const struct thread_exec_ctx *ctx, const char *pfx, const char *sfx);
|
|
||||||
|
|
||||||
#endif /* _HAPROXY_TOOLS_H */
|
#endif /* _HAPROXY_TOOLS_H */
|
||||||
|
|||||||
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