Compare commits

..

No commits in common. "master" and "v3.4-dev7" have entirely different histories.

275 changed files with 3631 additions and 10965 deletions

View File

@ -6,42 +6,27 @@ runs:
steps: steps:
- name: Setup coredumps - name: Setup coredumps
if: ${{ runner.os == 'Linux' }} if: ${{ startsWith(matrix.os, 'ubuntu-') }}
shell: sh shell: bash
run: | run: |
sudo mkdir -p /tmp/core sudo sysctl -w fs.suid_dumpable=1
sudo sysctl fs.suid_dumpable=1 sudo sysctl kernel.core_pattern=/tmp/core.%h.%e.%t
sudo sysctl kernel.core_pattern=/tmp/core/core.%h.%e.%t
- name: Setup ulimit for core dumps - name: Setup ulimit for core dumps
shell: sh shell: bash
run: | run: |
# This is required for macOS which does not actually allow to increase # This is required for macOS which does not actually allow to increase
# the '-n' soft limit to the hard limit, thus failing to run. # the '-n' soft limit to the hard limit, thus failing to run.
ulimit -n 65536 ulimit -n 65536
ulimit -c unlimited ulimit -c unlimited
- name: Get VTest latest commit SHA
id: vtest-sha
shell: sh
run: |
echo "sha=$(git ls-remote https://code.vinyl-cache.org/vtest/VTest2 HEAD | cut -f1)" >> $GITHUB_OUTPUT
- name: Cache VTest
id: cache-vtest
uses: actions/cache@v5
with:
path: ${{ github.workspace }}/vtest
key: vtest-${{ runner.os }}-${{ runner.arch }}-${{ steps.vtest-sha.outputs.sha }}
- name: Install VTest - name: Install VTest
if: ${{ steps.cache-vtest.outputs.cache-hit != 'true' }} shell: bash
shell: sh
run: | run: |
DESTDIR=${{ github.workspace }}/vtest scripts/build-vtest.sh scripts/build-vtest.sh
- name: Install problem matcher for VTest - name: Install problem matcher for VTest
shell: sh shell: bash
# This allows one to more easily see which tests fail. # This allows one to more easily see which tests fail.
run: echo "::add-matcher::.github/vtest.json" run: echo "::add-matcher::.github/vtest.json"

82
.github/matrix.py vendored
View File

@ -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
@ -34,24 +33,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):
@ -69,7 +57,7 @@ def aws_lc_version_string_to_num(version_string):
return tuple(map(int, version_string[1:].split('.'))) return tuple(map(int, version_string[1:].split('.')))
def aws_lc_version_valid(version_string): def aws_lc_version_valid(version_string):
return re.match(r'^v[0-9]+(\.[0-9]+)*$', version_string) return re.match('^v[0-9]+(\.[0-9]+)*$', version_string)
@functools.lru_cache(5) @functools.lru_cache(5)
def determine_latest_aws_lc(ssl): def determine_latest_aws_lc(ssl):
@ -77,8 +65,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:])
@ -86,16 +72,15 @@ def aws_lc_fips_version_string_to_num(version_string):
return tuple(map(int, version_string[12:].split('.'))) return tuple(map(int, version_string[12:].split('.')))
def aws_lc_fips_version_valid(version_string): def aws_lc_fips_version_valid(version_string):
return re.match(r'^AWS-LC-FIPS-[0-9]+(\.[0-9]+)*$', version_string) return re.match('^AWS-LC-FIPS-[0-9]+(\.[0-9]+)*$', 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:])
@ -103,7 +88,7 @@ def wolfssl_version_string_to_num(version_string):
return tuple(map(int, version_string[1:].removesuffix('-stable').split('.'))) return tuple(map(int, version_string[1:].removesuffix('-stable').split('.')))
def wolfssl_version_valid(version_string): def wolfssl_version_valid(version_string):
return re.match(r'^v[0-9]+(\.[0-9]+)*-stable$', version_string) return re.match('^v[0-9]+(\.[0-9]+)*-stable$', version_string)
@functools.lru_cache(5) @functools.lru_cache(5)
def determine_latest_wolfssl(ssl): def determine_latest_wolfssl(ssl):
@ -145,11 +130,9 @@ def main(ref_name):
if is_stable: if is_stable:
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
os_i686 = "ubuntu-24.04" # stable branch
else: else:
os = "ubuntu-24.04" # development branch os = "ubuntu-24.04" # development branch
os_arm = "ubuntu-24.04-arm" # development branch os_arm = "ubuntu-24.04-arm" # development branch
os_i686 = "ubuntu-24.04" # development branch
TARGET = "linux-glibc" TARGET = "linux-glibc"
for CC in ["gcc", "clang"]: for CC in ["gcc", "clang"]:
@ -207,7 +190,6 @@ def main(ref_name):
'OPT_CFLAGS="-O1"', 'OPT_CFLAGS="-O1"',
"USE_ZLIB=1", "USE_ZLIB=1",
"USE_OT=1", "USE_OT=1",
"DEBUG=-DDEBUG_STRICT=2",
"OT_INC=${HOME}/opt-ot/include", "OT_INC=${HOME}/opt-ot/include",
"OT_LIB=${HOME}/opt-ot/lib", "OT_LIB=${HOME}/opt-ot/lib",
"OT_RUNPATH=1", "OT_RUNPATH=1",
@ -312,48 +294,6 @@ def main(ref_name):
} }
) )
# Alpine / musl
matrix.append(
{
"name": "Alpine+musl, gcc",
"os": "ubuntu-latest",
"container": {
"image": "alpine:latest",
"options": "--privileged --ulimit core=-1 --security-opt seccomp=unconfined",
"volumes": ["/tmp/core:/tmp/core"],
},
"TARGET": "linux-musl",
"CC": "gcc",
"FLAGS": [
"ARCH_FLAGS='-ggdb3'",
"USE_LUA=1",
"LUA_INC=/usr/include/lua5.3",
"LUA_LIB=/usr/lib/lua5.3",
"USE_OPENSSL=1",
"USE_PCRE2=1",
"USE_PCRE2_JIT=1",
"USE_PROMEX=1",
],
}
)
# i686
matrix.append(
{
"name": "{}, i686-linux-gnu-gcc".format(os_i686),
"os": os_i686,
"TARGET": "linux-glibc",
"CC": "i686-linux-gnu-gcc",
"FLAGS": [
"USE_OPENSSL=1",
"USE_PCRE2=1",
"USE_PCRE2_JIT=1",
],
}
)
# Print matrix # Print matrix
print(json.dumps(matrix, indent=4, sort_keys=True)) print(json.dumps(matrix, indent=4, sort_keys=True))

12
.github/workflows/aws-lc-fips.yml vendored Normal file
View File

@ -0,0 +1,12 @@
name: AWS-LC-FIPS
on:
schedule:
- cron: "0 0 * * 4"
workflow_dispatch:
jobs:
test:
uses: ./.github/workflows/aws-lc-template.yml
with:
command: "from matrix import determine_latest_aws_lc_fips; print(determine_latest_aws_lc_fips(''))"

94
.github/workflows/aws-lc-template.yml vendored Normal file
View File

@ -0,0 +1,94 @@
name: AWS-LC template
on:
workflow_call:
inputs:
command:
required: true
type: string
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
steps:
- uses: actions/checkout@v5
- name: Determine latest AWS-LC release
id: get_aws_lc_release
run: |
result=$(cd .github && python3 -c "${{ inputs.command }}")
echo $result
echo "result=$result" >> $GITHUB_OUTPUT
- name: Cache AWS-LC
id: cache_aws_lc
uses: actions/cache@v4
with:
path: '~/opt/'
key: ssl-${{ steps.get_aws_lc_release.outputs.result }}-Ubuntu-latest-gcc
- name: Install apt dependencies
run: |
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
sudo apt-get --no-install-recommends -y install socat gdb jose
- name: Install AWS-LC
if: ${{ steps.cache_ssl.outputs.cache-hit != 'true' }}
run: env ${{ steps.get_aws_lc_release.outputs.result }} scripts/build-ssl.sh
- name: Compile HAProxy
run: |
make -j$(nproc) ERR=1 CC=gcc TARGET=linux-glibc \
USE_OPENSSL_AWSLC=1 USE_QUIC=1 \
SSL_LIB=${HOME}/opt/lib SSL_INC=${HOME}/opt/include \
DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" \
ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/"
sudo make install
- name: Show HAProxy version
id: show-version
run: |
ldd $(which haproxy)
haproxy -vv
echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
- uses: ./.github/actions/setup-vtest
- name: Run VTest for HAProxy
id: vtest
run: |
make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
- name: Run Unit tests
id: unittests
run: |
make unit-tests
- name: Show VTest results
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
run: |
for folder in ${TMPDIR:-/tmp}/haregtests-*/vtc.*; do
printf "::group::"
cat $folder/INFO
cat $folder/LOG
echo "::endgroup::"
done
exit 1
- name: Show coredumps
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
run: |
failed=false
shopt -s nullglob
for file in /tmp/core.*; do
failed=true
printf "::group::"
gdb -ex 'thread apply all bt full' ./haproxy $file
echo "::endgroup::"
done
if [ "$failed" = true ]; then
exit 1;
fi
- name: Show Unit-Tests results
if: ${{ failure() && steps.unittests.outcome == 'failure' }}
run: |
for result in ${TMPDIR:-/tmp}/ha-unittests-*/results/res.*; do
printf "::group::"
cat $result
echo "::endgroup::"
done
exit 1

View File

@ -5,95 +5,8 @@ on:
- cron: "0 0 * * 4" - cron: "0 0 * * 4"
workflow_dispatch: workflow_dispatch:
permissions:
contents: read
jobs: jobs:
Test: test:
name: ${{ matrix.name }} uses: ./.github/workflows/aws-lc-template.yml
runs-on: ubuntu-latest
strategy:
matrix:
include:
- name: AWS-LC
command: "from matrix import determine_latest_aws_lc; print(determine_latest_aws_lc(''))"
- name: AWS-LC (FIPS)
command: "from matrix import determine_latest_aws_lc_fips; print(determine_latest_aws_lc_fips(''))"
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
steps:
- uses: actions/checkout@v6
- name: Determine latest AWS-LC release
id: get_aws_lc_release
run: |
result=$(cd .github && python3 -c "${{ matrix.command }}")
echo $result
echo "result=$result" >> $GITHUB_OUTPUT
- name: Cache AWS-LC
id: cache_aws_lc
uses: actions/cache@v5
with: with:
path: '~/opt/' command: "from matrix import determine_latest_aws_lc; print(determine_latest_aws_lc(''))"
key: ssl-${{ steps.get_aws_lc_release.outputs.result }}-Ubuntu-latest-gcc
- name: Install apt dependencies
run: |
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
sudo apt-get --no-install-recommends -y install socat gdb jose
- name: Install AWS-LC
if: ${{ steps.cache_ssl.outputs.cache-hit != 'true' }}
run: env ${{ steps.get_aws_lc_release.outputs.result }} scripts/build-ssl.sh
- name: Compile HAProxy
run: |
make -j$(nproc) ERR=1 CC=gcc TARGET=linux-glibc \
USE_OPENSSL_AWSLC=1 USE_QUIC=1 \
SSL_LIB=${HOME}/opt/lib SSL_INC=${HOME}/opt/include \
DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" \
ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/"
sudo make install
- name: Show HAProxy version
id: show-version
run: |
ldd $(which haproxy)
haproxy -vv
echo "version=$(haproxy -vq)" >> $GITHUB_OUTPUT
- uses: ./.github/actions/setup-vtest
- name: Run VTest for HAProxy
id: vtest
run: |
make reg-tests VTEST_PROGRAM=${{ github.workspace }}/vtest/vtest REGTESTS_TYPES=default,bug,devel
- name: Run Unit tests
id: unittests
run: |
make unit-tests
- name: Show VTest results
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
run: |
for folder in ${TMPDIR:-/tmp}/haregtests-*/vtc.*; do
printf "::group::"
cat $folder/INFO
cat $folder/LOG
echo "::endgroup::"
done
exit 1
- name: Show coredumps
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
run: |
failed=false
shopt -s nullglob
for file in /tmp/core.*; do
failed=true
printf "::group::"
gdb -ex 'thread apply all bt full' ./haproxy $file
echo "::endgroup::"
done
if [ "$failed" = true ]; then
exit 1;
fi
- name: Show Unit-Tests results
if: ${{ failure() && steps.unittests.outcome == 'failure' }}
run: |
for result in ${TMPDIR:-/tmp}/ha-unittests-*/results/res.*; do
printf "::group::"
cat $result
echo "::endgroup::"
done
exit 1

View File

@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- uses: codespell-project/codespell-problem-matcher@v1.2.0 - uses: codespell-project/codespell-problem-matcher@v1.2.0
- uses: codespell-project/actions-codespell@master - uses: codespell-project/actions-codespell@master
with: with:

View File

@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- name: Install h2spec - name: Install h2spec
id: install-h2spec id: install-h2spec
run: | run: |
@ -45,7 +45,7 @@ jobs:
fi fi
echo "::endgroup::" echo "::endgroup::"
haproxy -vv haproxy -vv
echo "version=$(haproxy -vq)" >> $GITHUB_OUTPUT echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
- name: Launch HAProxy ${{ steps.show-version.outputs.version }} - name: Launch HAProxy ${{ steps.show-version.outputs.version }}
run: haproxy -f .github/h2spec.config -D run: haproxy -f .github/h2spec.config -D
- name: Run h2spec ${{ steps.install-h2spec.outputs.version }} - name: Run h2spec ${{ steps.install-h2spec.outputs.version }}

View File

@ -7,30 +7,16 @@ permissions:
contents: read contents: read
jobs: jobs:
compile: build:
name: ${{ matrix.name }} runs-on: ubuntu-latest
runs-on: ubuntu-slim
strategy:
matrix:
include:
- name: admin/halog/
targets:
- admin/halog/halog
- name: dev/flags/
targets:
- dev/flags/flags
- name: dev/haring/
targets:
- dev/haring/haring
- name: dev/hpack/
targets:
- dev/hpack/decode
- dev/hpack/gen-enc
- dev/hpack/gen-rht
- name: dev/poll/
targets:
- dev/poll/poll
fail-fast: false
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- run: make ${{ join(matrix.targets, ' ') }} - name: Compile dev/flags/flags
run: |
make dev/flags/flags
- name: Compile dev/poll/poll
run: |
make dev/poll/poll
- name: Compile dev/hpack
run: |
make dev/hpack/decode dev/hpack/gen-enc dev/hpack/gen-rht

View File

@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- name: Install apt dependencies - name: Install apt dependencies
run: | run: |
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none

View File

@ -5,7 +5,7 @@ name: Cross Compile
on: on:
schedule: schedule:
- cron: "0 2 * * 1" - cron: "0 0 21 * *"
workflow_dispatch: workflow_dispatch:
permissions: permissions:
@ -17,10 +17,6 @@ jobs:
matrix: matrix:
platform: [ platform: [
{ {
arch: i686-linux-gnu,
libs: libc6-dev-i386-cross,
target: linux-x86
}, {
arch: aarch64-linux-gnu, arch: aarch64-linux-gnu,
libs: libc6-dev-arm64-cross, libs: libc6-dev-arm64-cross,
target: linux-aarch64 target: linux-aarch64
@ -103,12 +99,12 @@ jobs:
sudo apt-get -yq --force-yes install \ sudo apt-get -yq --force-yes install \
gcc-${{ matrix.platform.arch }} \ gcc-${{ matrix.platform.arch }} \
${{ matrix.platform.libs }} ${{ matrix.platform.libs }}
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- name: install quictls - name: install quictls
run: | run: |
QUICTLS_EXTRA_ARGS="--cross-compile-prefix=${{ matrix.platform.arch }}- ${{ matrix.platform.target }}" QUICTLS_VERSION=openssl-3.1.7+quic scripts/build-ssl.sh QUICTLS_EXTRA_ARGS="--cross-compile-prefix=${{ matrix.platform.arch }}- ${{ matrix.platform.target }}" QUICTLS_VERSION=OpenSSL_1_1_1w-quic1 scripts/build-ssl.sh
- name: Build - name: Build
run: | run: |

View File

@ -24,17 +24,22 @@ jobs:
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
container: container:
image: fedora:rawhide image: fedora:rawhide
options: --privileged
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- name: Install dependencies - name: Install dependencies
run: | run: |
dnf -y install awk diffutils git zlib-devel pcre2-devel 'perl(FindBin)' perl-IPC-Cmd 'perl(File::Copy)' 'perl(File::Compare)' lua-devel socat findutils systemd-devel clang openssl-devel.x86_64 procps-ng dnf -y install awk diffutils git pcre-devel zlib-devel pcre2-devel 'perl(FindBin)' perl-IPC-Cmd 'perl(File::Copy)' 'perl(File::Compare)' lua-devel socat findutils systemd-devel clang openssl-devel.x86_64
dnf -y install 'perl(FindBin)' 'perl(File::Compare)' perl-IPC-Cmd 'perl(File::Copy)' glibc-devel.i686 lua-devel.i686 lua-devel.x86_64 systemd-devel.i686 zlib-ng-compat-devel.i686 libatomic.i686 openssl-devel.i686 pcre2-devel.i686 dnf -y install 'perl(FindBin)' 'perl(File::Compare)' perl-IPC-Cmd 'perl(File::Copy)' glibc-devel.i686 lua-devel.i686 lua-devel.x86_64 systemd-devel.i686 zlib-ng-compat-devel.i686 pcre-devel.i686 libatomic.i686 openssl-devel.i686
- uses: ./.github/actions/setup-vtest - uses: ./.github/actions/setup-vtest
- name: Build contrib tools
run: |
make admin/halog/halog
make dev/flags/flags
make dev/poll/poll
make dev/hpack/decode dev/hpack/gen-enc dev/hpack/gen-rht
- name: Compile HAProxy with ${{ matrix.platform.cc }} - name: Compile HAProxy with ${{ matrix.platform.cc }}
run: | run: |
make -j3 CC=${{ matrix.platform.cc }} V=1 ERR=1 TARGET=linux-glibc DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" USE_PROMEX=1 USE_OPENSSL=1 USE_QUIC=1 USE_ZLIB=1 USE_PCRE2=1 USE_PCRE2_JIT=1 USE_LUA=1 ADDLIB="${{ matrix.platform.ADDLIB_ATOMIC }}" ARCH_FLAGS="${{ matrix.platform.ARCH_FLAGS }}" make -j3 CC=${{ matrix.platform.cc }} V=1 ERR=1 TARGET=linux-glibc DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" USE_PROMEX=1 USE_OPENSSL=1 USE_QUIC=1 USE_ZLIB=1 USE_PCRE=1 USE_PCRE_JIT=1 USE_LUA=1 ADDLIB="${{ matrix.platform.ADDLIB_ATOMIC }}" ARCH_FLAGS="${{ matrix.platform.ARCH_FLAGS }}"
make install make install
- name: Show HAProxy version - name: Show HAProxy version
id: show-version id: show-version
@ -43,7 +48,7 @@ jobs:
ldd $(command -v haproxy) ldd $(command -v haproxy)
echo "::endgroup::" echo "::endgroup::"
haproxy -vv haproxy -vv
echo "version=$(haproxy -vq)" >> $GITHUB_OUTPUT echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
# #
# TODO: review this workaround later # TODO: review this workaround later
- name: relax crypto policies - name: relax crypto policies
@ -54,7 +59,7 @@ jobs:
- name: Run VTest for HAProxy ${{ steps.show-version.outputs.version }} - name: Run VTest for HAProxy ${{ steps.show-version.outputs.version }}
id: vtest id: vtest
run: | run: |
make reg-tests VTEST_PROGRAM=${{ github.workspace }}/vtest/vtest REGTESTS_TYPES=default,bug,devel make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
- name: Show VTest results - name: Show VTest results
if: ${{ failure() && steps.vtest.outcome == 'failure' }} if: ${{ failure() && steps.vtest.outcome == 'failure' }}
run: | run: |

View File

@ -5,16 +5,15 @@ on:
- cron: "0 0 25 * *" - cron: "0 0 25 * *"
workflow_dispatch: workflow_dispatch:
permissions:
contents: read
jobs: jobs:
gcc: gcc:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
permissions:
contents: read
steps: steps:
- name: "Checkout repository" - name: "Checkout repository"
uses: actions/checkout@v6 uses: actions/checkout@v5
- name: "Build on VM" - name: "Build on VM"
uses: vmactions/solaris-vm@v1 uses: vmactions/solaris-vm@v1

76
.github/workflows/musl.yml vendored Normal file
View File

@ -0,0 +1,76 @@
name: alpine/musl
on:
push:
permissions:
contents: read
jobs:
musl:
name: gcc
runs-on: ubuntu-latest
container:
image: alpine:latest
options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined
volumes:
- /tmp/core:/tmp/core
steps:
- name: Setup coredumps
run: |
ulimit -c unlimited
echo '/tmp/core/core.%h.%e.%t' > /proc/sys/kernel/core_pattern
- uses: actions/checkout@v5
- name: Install dependencies
run: apk add gcc gdb make tar git python3 libc-dev linux-headers pcre-dev pcre2-dev openssl-dev lua5.3-dev grep socat curl musl-dbg lua5.3-dbg jose
- name: Install VTest
run: scripts/build-vtest.sh
- name: Build
run: make -j$(nproc) TARGET=linux-musl DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" ARCH_FLAGS='-ggdb3' CC=cc V=1 USE_LUA=1 LUA_INC=/usr/include/lua5.3 LUA_LIB=/usr/lib/lua5.3 USE_OPENSSL=1 USE_PCRE2=1 USE_PCRE2_JIT=1 USE_PROMEX=1
- name: Show version
run: ./haproxy -vv
- name: Show linked libraries
run: ldd haproxy
- name: Install problem matcher for VTest
# This allows one to more easily see which tests fail.
run: echo "::add-matcher::.github/vtest.json"
- name: Run VTest
id: vtest
run: make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
- name: Run Unit tests
id: unittests
run: |
make unit-tests
- name: Show coredumps
if: ${{ failure() && steps.vtest.outcome == 'failure' }}
run: |
failed=false
ls /tmp/core/
for file in /tmp/core/core.*; do
failed=true
printf "::group::"
gdb -ex 'thread apply all bt full' ./haproxy $file
echo "::endgroup::"
done
if [ "$failed" = true ]; then
exit 1;
fi
- name: Show results
if: ${{ failure() }}
run: |
for folder in /tmp/haregtests-*/vtc.*; do
printf "::group::"
cat $folder/INFO
cat $folder/LOG
echo "::endgroup::"
done
- name: Show Unit-Tests results
if: ${{ failure() && steps.unittests.outcome == 'failure' }}
run: |
for result in ${TMPDIR:-/tmp}/ha-unittests-*/results/res.*; do
printf "::group::"
cat $result
echo "::endgroup::"
done
exit 1

View File

@ -5,16 +5,15 @@ on:
- cron: "0 0 25 * *" - cron: "0 0 25 * *"
workflow_dispatch: workflow_dispatch:
permissions:
contents: read
jobs: jobs:
gcc: gcc:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
permissions:
contents: read
steps: steps:
- name: "Checkout repository" - name: "Checkout repository"
uses: actions/checkout@v6 uses: actions/checkout@v5
- name: "Build on VM" - name: "Build on VM"
uses: vmactions/netbsd-vm@v1 uses: vmactions/netbsd-vm@v1

View File

@ -13,13 +13,15 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- name: Install VTest
run: |
scripts/build-vtest.sh
- name: Install apt dependencies - name: Install apt dependencies
run: | run: |
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
sudo apt-get --no-install-recommends -y install socat gdb sudo apt-get --no-install-recommends -y install socat gdb
sudo apt-get --no-install-recommends -y install libpsl-dev sudo apt-get --no-install-recommends -y install libpsl-dev
- uses: ./.github/actions/setup-vtest
- name: Install OpenSSL+ECH - name: Install OpenSSL+ECH
run: env OPENSSL_VERSION="git-feature/ech" GIT_TYPE="branch" scripts/build-ssl.sh run: env OPENSSL_VERSION="git-feature/ech" GIT_TYPE="branch" scripts/build-ssl.sh
- name: Install curl+ECH - name: Install curl+ECH
@ -38,7 +40,7 @@ jobs:
run: | run: |
ldd $(which haproxy) ldd $(which haproxy)
haproxy -vv haproxy -vv
echo "version=$(haproxy -vq)" >> $GITHUB_OUTPUT echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
- name: Install problem matcher for VTest - name: Install problem matcher for VTest
run: echo "::add-matcher::.github/vtest.json" run: echo "::add-matcher::.github/vtest.json"
- name: Run VTest for HAProxy - name: Run VTest for HAProxy
@ -49,7 +51,7 @@ jobs:
ulimit -n 65536 ulimit -n 65536
# allow to catch coredumps # allow to catch coredumps
ulimit -c unlimited ulimit -c unlimited
make reg-tests VTEST_PROGRAM=${{ github.workspace }}/vtest/vtest REGTESTS_TYPES=default,bug,devel make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
- name: Show VTest results - name: Show VTest results
if: ${{ failure() && steps.vtest.outcome == 'failure' }} if: ${{ failure() && steps.vtest.outcome == 'failure' }}
run: | run: |

View File

@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- name: Install apt dependencies - name: Install apt dependencies
run: | run: |
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
@ -35,7 +35,7 @@ jobs:
run: | run: |
ldd $(which haproxy) ldd $(which haproxy)
haproxy -vv haproxy -vv
echo "version=$(haproxy -vq)" >> $GITHUB_OUTPUT echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
- name: Install problem matcher for VTest - name: Install problem matcher for VTest
run: echo "::add-matcher::.github/vtest.json" run: echo "::add-matcher::.github/vtest.json"
- name: Run VTest for HAProxy - name: Run VTest for HAProxy
@ -46,7 +46,7 @@ jobs:
ulimit -n 65536 ulimit -n 65536
# allow to catch coredumps # allow to catch coredumps
ulimit -c unlimited ulimit -c unlimited
make reg-tests VTEST_PROGRAM=${{ github.workspace }}/vtest/vtest REGTESTS_TYPES=default,bug,devel make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
- name: Show VTest results - name: Show VTest results
if: ${{ failure() && steps.vtest.outcome == 'failure' }} if: ${{ failure() && steps.vtest.outcome == 'failure' }}
run: | run: |

View File

@ -9,16 +9,17 @@ on:
schedule: schedule:
- cron: "0 0 * * 2" - cron: "0 0 * * 2"
permissions:
contents: read
jobs: jobs:
combined-build-and-run: combined-build-and-run:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
permissions:
contents: read
packages: write
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- name: Update Docker to the latest - name: Update Docker to the latest
uses: docker/setup-docker-action@v4 uses: docker/setup-docker-action@v4
@ -49,7 +50,7 @@ jobs:
python run.py -j result.json -l logs-ngtcp2 -r haproxy=local:aws-lc -t "handshake,transfer,longrtt,chacha20,multiplexing,retry,resumption,zerortt,http3,blackhole,keyupdate,ecn,amplificationlimit,handshakeloss,transferloss,handshakecorruption,transfercorruption,ipv6,v2" -c ngtcp2 -s haproxy python run.py -j result.json -l logs-ngtcp2 -r haproxy=local:aws-lc -t "handshake,transfer,longrtt,chacha20,multiplexing,retry,resumption,zerortt,http3,blackhole,keyupdate,ecn,amplificationlimit,handshakeloss,transferloss,handshakecorruption,transfercorruption,ipv6,v2" -c ngtcp2 -s haproxy
- name: Delete succeeded logs - name: Delete succeeded logs
if: ${{ failure() }} if: failure()
run: | run: |
for client in chrome picoquic quic-go ngtcp2; do for client in chrome picoquic quic-go ngtcp2; do
pushd quic-interop-runner/logs-${client}/haproxy_${client} pushd quic-interop-runner/logs-${client}/haproxy_${client}
@ -58,8 +59,8 @@ jobs:
done done
- name: Logs upload - name: Logs upload
if: ${{ failure() }} if: failure()
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v4
with: with:
name: logs name: logs
path: quic-interop-runner/logs*/ path: quic-interop-runner/logs*/

View File

@ -9,16 +9,17 @@ on:
schedule: schedule:
- cron: "0 0 * * 2" - cron: "0 0 * * 2"
permissions:
contents: read
jobs: jobs:
combined-build-and-run: combined-build-and-run:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
permissions:
contents: read
packages: write
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- name: Update Docker to the latest - name: Update Docker to the latest
uses: docker/setup-docker-action@v4 uses: docker/setup-docker-action@v4
@ -47,7 +48,7 @@ jobs:
python run.py -j result.json -l logs-quic-go -r haproxy=local:libressl -t "handshake,transfer,longrtt,chacha20,multiplexing,retry,http3,blackhole,amplificationlimit,transferloss,transfercorruption,v2" -c quic-go -s haproxy python run.py -j result.json -l logs-quic-go -r haproxy=local:libressl -t "handshake,transfer,longrtt,chacha20,multiplexing,retry,http3,blackhole,amplificationlimit,transferloss,transfercorruption,v2" -c quic-go -s haproxy
- name: Delete succeeded logs - name: Delete succeeded logs
if: ${{ failure() }} if: failure()
run: | run: |
for client in picoquic quic-go; do for client in picoquic quic-go; do
pushd quic-interop-runner/logs-${client}/haproxy_${client} pushd quic-interop-runner/logs-${client}/haproxy_${client}
@ -56,8 +57,8 @@ jobs:
done done
- name: Logs upload - name: Logs upload
if: ${{ failure() }} if: failure()
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v4
with: with:
name: logs name: logs
path: quic-interop-runner/logs*/ path: quic-interop-runner/logs*/

View File

@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- name: Install apt dependencies - name: Install apt dependencies
run: | run: |
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
@ -38,12 +38,12 @@ jobs:
run: | run: |
ldd $(which haproxy) ldd $(which haproxy)
haproxy -vv haproxy -vv
echo "version=$(haproxy -vq)" >> $GITHUB_OUTPUT echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
- uses: ./.github/actions/setup-vtest - uses: ./.github/actions/setup-vtest
- name: Run VTest for HAProxy - name: Run VTest for HAProxy
id: vtest id: vtest
run: | run: |
make reg-tests VTEST_PROGRAM=${{ github.workspace }}/vtest/vtest REGTESTS_TYPES=default,bug,devel make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
- name: Show VTest results - name: Show VTest results
if: ${{ failure() && steps.vtest.outcome == 'failure' }} if: ${{ failure() && steps.vtest.outcome == 'failure' }}
run: | run: |

View File

@ -19,11 +19,11 @@ jobs:
# generated by .github/matrix.py. # generated by .github/matrix.py.
generate-matrix: generate-matrix:
name: Generate Build Matrix name: Generate Build Matrix
runs-on: ubuntu-slim runs-on: ubuntu-latest
outputs: outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }} matrix: ${{ steps.set-matrix.outputs.matrix }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- name: Generate Build Matrix - name: Generate Build Matrix
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -38,14 +38,13 @@ jobs:
strategy: strategy:
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
fail-fast: false fail-fast: false
container: ${{ matrix.container }}
env: env:
# Configure a short TMPDIR to prevent failures due to long unix socket # Configure a short TMPDIR to prevent failures due to long unix socket
# paths. # paths.
TMPDIR: /tmp TMPDIR: /tmp
OT_CPP_VERSION: 1.6.0 OT_CPP_VERSION: 1.6.0
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
with: with:
fetch-depth: 100 fetch-depth: 100
@ -60,7 +59,7 @@ jobs:
- name: Cache SSL libs - name: Cache SSL libs
if: ${{ matrix.ssl && matrix.ssl != 'stock' && matrix.ssl != 'BORINGSSL=yes' && !contains(matrix.ssl, 'QUICTLS') }} if: ${{ matrix.ssl && matrix.ssl != 'stock' && matrix.ssl != 'BORINGSSL=yes' && !contains(matrix.ssl, 'QUICTLS') }}
id: cache_ssl id: cache_ssl
uses: actions/cache@v5 uses: actions/cache@v4
with: with:
path: '~/opt/' path: '~/opt/'
key: ssl-${{ steps.generate-cache-key.outputs.key }} key: ssl-${{ steps.generate-cache-key.outputs.key }}
@ -68,28 +67,21 @@ jobs:
- name: Cache OpenTracing - name: Cache OpenTracing
if: ${{ contains(matrix.FLAGS, 'USE_OT=1') }} if: ${{ contains(matrix.FLAGS, 'USE_OT=1') }}
id: cache_ot id: cache_ot
uses: actions/cache@v5 uses: actions/cache@v4
with: with:
path: '~/opt-ot/' path: '~/opt-ot/'
key: ${{ matrix.os }}-ot-${{ matrix.CC }}-${{ env.OT_CPP_VERSION }}-${{ contains(matrix.name, 'ASAN') }} key: ${{ matrix.os }}-ot-${{ matrix.CC }}-${{ env.OT_CPP_VERSION }}-${{ contains(matrix.name, 'ASAN') }}
- name: Add i386 architecture
if: ${{ matrix.CC == 'i686-linux-gnu-gcc' }}
run: sudo dpkg --add-architecture i386
- name: Install apt dependencies - name: Install apt dependencies
if: ${{ startsWith(matrix.os, 'ubuntu-') && matrix.TARGET != 'linux-musl' }} if: ${{ startsWith(matrix.os, 'ubuntu-') }}
run: | run: |
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
sudo apt-get --no-install-recommends -y install \ sudo apt-get --no-install-recommends -y install \
${{ case(contains(matrix.FLAGS, 'USE_LUA=1'), 'liblua5.4-dev', '') }} \ ${{ contains(matrix.FLAGS, 'USE_LUA=1') && 'liblua5.4-dev' || '' }} \
${{ case(contains(matrix.FLAGS, 'USE_PCRE2=1'), 'libpcre2-dev', '') }} \ ${{ contains(matrix.FLAGS, 'USE_PCRE2=1') && 'libpcre2-dev' || '' }} \
${{ case(contains(matrix.ssl, 'BORINGSSL=yes'), 'ninja-build', '') }} \ ${{ contains(matrix.ssl, 'BORINGSSL=yes') && 'ninja-build' || '' }} \
${{ case(matrix.CC == 'i686-linux-gnu-gcc', 'gcc-i686-linux-gnu libc6-dev-i386-cross libssl-dev:i386 libpcre2-dev:i386', '') }} \
socat \ socat \
gdb \ gdb \
jose jose
- name: Install apk dependencies
if: ${{ matrix.TARGET == 'linux-musl' }}
run: apk add gcc gdb make tar git python3 libc-dev linux-headers pcre-dev pcre2-dev openssl-dev lua5.3-dev grep socat curl musl-dbg lua5.3-dbg jose sudo
- name: Install brew dependencies - name: Install brew dependencies
if: ${{ startsWith(matrix.os, 'macos-') }} if: ${{ startsWith(matrix.os, 'macos-') }}
run: | run: |
@ -122,6 +114,15 @@ jobs:
${{ join(matrix.FLAGS, ' ') }} \ ${{ join(matrix.FLAGS, ' ') }} \
ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/" ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/"
sudo make install-bin sudo make install-bin
- name: Compile admin/halog/halog
run: |
make -j$(nproc) admin/halog/halog \
ERR=1 \
TARGET=${{ matrix.TARGET }} \
CC=${{ matrix.CC }} \
DEBUG="-DDEBUG_POOL_INTEGRITY -DDEBUG_UNIT" \
${{ join(matrix.FLAGS, ' ') }} \
ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/"
- name: Show HAProxy version - name: Show HAProxy version
id: show-version id: show-version
run: | run: |
@ -135,11 +136,11 @@ jobs:
fi fi
echo "::endgroup::" echo "::endgroup::"
haproxy -vv haproxy -vv
echo "version=$(haproxy -vq)" >> $GITHUB_OUTPUT echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
- name: Run VTest for HAProxy ${{ steps.show-version.outputs.version }} - name: Run VTest for HAProxy ${{ steps.show-version.outputs.version }}
id: vtest id: vtest
run: | run: |
make reg-tests VTEST_PROGRAM=${{ github.workspace }}/vtest/vtest REGTESTS_TYPES=default,bug,devel make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
- name: Show VTest results - name: Show VTest results
if: ${{ failure() && steps.vtest.outcome == 'failure' }} if: ${{ failure() && steps.vtest.outcome == 'failure' }}
run: | run: |
@ -167,7 +168,8 @@ jobs:
if: ${{ failure() && steps.vtest.outcome == 'failure' }} if: ${{ failure() && steps.vtest.outcome == 'failure' }}
run: | run: |
failed=false failed=false
for file in /tmp/core/core.*; do shopt -s nullglob
for file in /tmp/core.*; do
failed=true failed=true
printf "::group::" printf "::group::"
gdb -ex 'thread apply all bt full' ./haproxy $file gdb -ex 'thread apply all bt full' ./haproxy $file

View File

@ -36,7 +36,7 @@ jobs:
- USE_THREAD=1 - USE_THREAD=1
- USE_ZLIB=1 - USE_ZLIB=1
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- uses: msys2/setup-msys2@v2 - uses: msys2/setup-msys2@v2
with: with:
install: >- install: >-

View File

@ -13,13 +13,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }} if: ${{ github.repository_owner == 'haproxy' || github.event_name == 'workflow_dispatch' }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v5
- name: Install apt dependencies - name: Install apt dependencies
run: | run: |
sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none
sudo apt-get --no-install-recommends -y install socat gdb jose sudo apt-get --no-install-recommends -y install socat gdb jose
- name: Install WolfSSL - name: Install WolfSSL
run: env WOLFSSL_VERSION=git-master WOLFSSL_DEBUG=1 CFLAGS="-fsanitize=address -g" scripts/build-ssl.sh run: env WOLFSSL_VERSION=git-master WOLFSSL_DEBUG=1 scripts/build-ssl.sh
- name: Compile HAProxy - name: Compile HAProxy
run: | run: |
make -j$(nproc) ERR=1 CC=gcc TARGET=linux-glibc \ make -j$(nproc) ERR=1 CC=gcc TARGET=linux-glibc \
@ -34,12 +34,12 @@ jobs:
run: | run: |
ldd $(which haproxy) ldd $(which haproxy)
haproxy -vv haproxy -vv
echo "version=$(haproxy -vq)" >> $GITHUB_OUTPUT echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT
- uses: ./.github/actions/setup-vtest - uses: ./.github/actions/setup-vtest
- name: Run VTest for HAProxy - name: Run VTest for HAProxy
id: vtest id: vtest
run: | run: |
make reg-tests VTEST_PROGRAM=${{ github.workspace }}/vtest/vtest REGTESTS_TYPES=default,bug,devel make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel
- name: Run Unit tests - name: Run Unit tests
id: unittests id: unittests
run: | run: |

489
CHANGELOG
View File

@ -1,495 +1,6 @@
ChangeLog : ChangeLog :
=========== ===========
2026/04/29 : 3.4-dev10
- DOC: config: fix spelling of "max-threads-per-group" in the index
- MEDIUM: threads: change the default max-threads-per-group value to 16
- BUG/MEDIUM: mux-h2: ignore conn->owner when deciding if a connection is dead
- BUG/MINOR: task: fix uninitialised read in run_tasks_from_lists()
- MINOR: compression: prefix compression oriented functions with "comp_"
- BUG/MINOR: mux_quic: limit avail_streams() to 2^62
- MINOR: h3: simplify GOAWAY local emission
- MEDIUM: h3: prevent new streams on GOAWAY reception
- MINOR: mux-quic: release BE idle conn after GOAWAY reception
- MINOR: otel: added debug thread ID support for the OTel C wrapper library
- MINOR: otel: test: added option parsing to the speed test script
- MINOR: otel: test: replaced argument variables with positional parameters in run scripts
- CLEANUP: otel: removed insecure-fork-wanted requirement
- MINOR: otel: test: unified run scripts into a single symlinked script
- BUILD: haterm: don't pass size_t to %lu in error messages
- CI: github: merge Test and Test-musl in VTest.yml
- CI: Build halog as part of contrib.yml
- BUG/MINOR: xprt_qstrm: read record length in 64bits
- BUG/MINOR: mux_quic: convert QCC rx.rlen to 64bits
- CI: github: revert quictls version on cross-zoo.yml
- BUG/MINOR: xprt_qstrm: reduce max record length check
- CI: github: use quictls-3.1.7 for cross-zoo.yml
- BUILD: ssl/sample: potential null pointer dereference in sample_conv_aes
- CI: github: add an i686 job in cross-zoo.yml
- CI: github: run cross-zoo.yml weekly
- CI: github: add cross-zoo.yml in README.md
- BUG/MEDIUM: checks: Don't forget to set the "alt_proto" field
- CI: github: do not install pcre-devel on Fedora Rawhide build
- CI: github: fix sysctl in fedora-rawhide
- CI: github: switch to USE_PCRE2 in Fedora Rawhide build
- MINOR: acme: implement draft-ietf-acme-profiles
- MINOR: acme: allow IP SAN in certificate request
- BUG/MINOR: log: consider format expression dependencies to decide when to log
- MINOR: sample: make RQ/RS stats available everywhere
- BUG/MINOR: sample: adjust dependencies for channel output bytes counters
- MEDIUM: muxes: always set conn->owner to the session that owns the connection
- MEDIUM: session: always reset the conn->owner on backend when installing mux
- CLEANUP: mux-h1: avoid using conn->owner in uncertain areas
- CLEANUP: mux-h1: remove the unneeded test on conn->owner in h1s_finish_detach()
- BUG/MAJOR: sched: protect task->expire on 32-bit platforms
- CI: github: add an i686 job to the push job
- BUILD: config: also set DEF_MAX_THREADS_PER_GROUP when not using threads
- reg-tests/ssl/ssl_dh.vtc: fix syntax error
- ci: modernize actions/upload-artifact@v4
- BUG/MINOR: reg-tests: make shell syntax errors fatal
- MINOR: cli: Handle the paylod pattern as a pointer in the cmdline buffer
- MEDIUM: cli: Make a buffer for the command payload
- MEDIUM: cli: Add support for dynamically allocated payloads
- MEDIUM: cli: increase the payload pattern up to 64 bytes
- MINOR: stream: Move the HTTP txn in an union
- MINOR: stream: Add flags to identify the stream tansaction when allocated
- MINOR: stream: Use a pcli transaction to replace pcli_* members
- CLEANUP: applet: Remove useless shadow pointer from appctx
- REGTESTS: ssl: mark ssl_dh.vtc as broken
- BUG/MINOR: mux-h2: count a protocol error when failing to parse a trailer
- BUG/MINOR: mux-h2: count a proto error when rejecting a stream on parsing error
- BUG/MEDIUM: tasks: Make sure we don't schedule a task already running
- BUG/MAJOR: net_helper: ip.fp infinite loop on malformed tcp options
- BUG/MINOR: h2: make tune.h2.log-errors actually work
- BUG/MINOR: h2: Don't look at the exclusive bit for PRIORITY frame
- BUG/MINOR: H2: Don't forget to free shared_rx_bufs on failure
- BUG/MINOR: log: also wait for the response when logging response headers
- BUG/MINOR: mux-h1: Fix condition to send null-chunk for bodyless message
- BUG/MINOR: mux-h1: Fix test to skip trailers from chunked messages
- BUG/MINOR: http-act: fix a typo in a "del-heeaders-bin" error message
- CLEANUP: tcpcheck: Fix some typos in comments
- MINOR: tcpcheck: Rely on free_tcpcheck_ruleset() to deinit tcpchecks
- BUG/MINOR: tcpcheck: Don't release ruleset when parsing 'spop-check' ruleset
- BUG/MINOR: tcpcheck: Fix a leak on deinit by releasing ruleset's conf.file
- CLEANUP: haterm: Fix typos in comments
- CLEANUP: config: Fix warning about invalid small buffer size
- CLEANUP: htx: Fix typos in comments
- CLEANUP: chunk: Fix a typo in a comment
- CLEANUP: http-client: Fix typos in comments
- BUG/MEDIUM: tcpcheck: Release temporary small chunk when retrying on http-check
- CLEANUP: proxy: Fix typos in comments
- DOC: config: Fix a typo for "external-check" directive
- CLEANUP: cli: Fix typos in comments
- BUG/MINOR: stream: Add SF_TXN_HTTP/SF_TXN_PCLI flags in strm_show_flags()
- REGTESTS: Never reuse server connection in jwt/jws_verify.vtc
- REGTESTS: Never reuse server connection in server/cli_delete_dynamic_server.vtc
- BUG/MINOR: compression: properly disable request when setting response
- BUG/MINOR: servers: fix last_sess date calculation
- DOC: config: fix typo introduce in max-threads-per-group documentation
- BUG/MINOR: stream: add the newly added SF_TXN_* flags to strm_show_flags()
- BUG/MINOR: debug: properly mark the entire libs archive read-only
- Revert "BUG/MINOR: stream: add the newly added SF_TXN_* flags to strm_show_flags()"
- BUG/MINOR: server: fix a possible leak of an error message in dynamic servers
- BUG/MAJOR: mux-h2: detect incomplete transfers on HEADERS frames as well
- BUG/MEDIUM: mux-h1: Force close mode for bodyless message announcing a C-L
- BUG/MINOR: mux_quic: prevent crash on qc_frm_free() with QMux
- BUG/MINOR: xprt_qstrm: ensure all local TPs are allocated
- BUG/MINOR: xprt_qstrm: prevent crash if conn release on MUX wake
- BUG/MINOR: mux_quic: do not release conn on qcc_recv() for QMux
- MINOR: xprt_qstrm: remove unused subs
- MINOR: connection: document conn_create_mux()
- MINOR: xprt_qstrm: implement close callback
- MINOR: mux_quic: refactor QMux send frames function
- MINOR: mux_quic: use dynamic Tx streams buffers for QMux
- MINOR: mux_quic: use dynamic conn buffers for QMux
- MINOR: mux_quic/xprt_qstrm: simplify Rx buffer transfer
- MINOR: mux_quic: receive MAX_STREAMS_BIDI frames in QMux
- MINOR: mux_quic: handle conn errors on QMux without crash
- MINOR: mux_quic: handle incomplete QMux record read
- BUG/MINOR: tcpcheck: Allow connection reuse without prior traffic
- MINOR: sample: converter for frontend existence check
- BUG/MEDIUM: stats: fix crash on 'dump stats-file'
- BUG/MINOR: ssl: fix memory leaks on realloc failure in ssl_ckch.c
- BUG/MINOR: ssl: fix memory leaks on realloc failure in ssl_sock.c
- BUG/MINOR: ssl: fix memory leak on realloc failure in acme.ips
- DOC: config: Fix log-format example with last rule expressions
- DOC: config: Fix typo in tune.bufsize.large description
- MEDIUM: ot: emitted deprecation warning at filter init
- BUILD: ot: emitted deprecation warning at build time
- BUG/MINOR: ssl: fix double-free on failed realloc in ssl_sock.c
- BUG/MINOR: tree-wide: fix a few user-visible spelling mistakes from dev7
- CLEANUP: tree-wide: address various spelling mistakes in comments from -dev7
- BUG/MINOR: tools: my_memspn/my_memcspn wrong cast causing incorrect byte reading
- BUG/MINOR: tools: fix memory leak in indent_msg() on out of memory
- BUG/MINOR: tools: free previously allocated strings on strdup failure in backup_env()
- BUG/MINOR: sample: fix memory leak in check_when_cond() when ACL is not found
- BUG/MINOR: sample: fix memory leak in smp_resolve_args error paths
- BUG/MINOR: sample: fix NULL strm dereference in sample_conv_when
- BUG/MINOR: peers: fix logical "and" when checking for local in PEER_APP_ST_STARTING
- BUG/MINOR: peers: fix wrong flag reported twice for dump_flags
- CLEANUP: peers: fix a few user-visible spelling mistakes
- CLEANUP: tools: drop upper case check after tolower()
- CLEANUP: mux-h2: remove duplicate forward declaration of h2s_rxbuf_{head,tail}()
- CLEANUP: tree-wide: fix around 20 mistakes in comments in h2,tools,peers
- MINOR: mux_quic: return conn error code in debug string
- MINOR: mux_quic: display QCS sd on traces
- MINOR: mux_quic/h3: report termination events at connection level
- MINOR: mux_quic/h3: report termination events at stream layer
- BUG/MEDIUM: mux_h1: fix stack buffer overflow in h1_append_chunk_size()
- BUG/MINOR: http_ana: use scf to report term_evts in http_wait_for_request()
- MINOR: lb: infrastructure for declarative initialization
- MEDIUM: lb: use the LB ops tables
- MINOR: lb: cleanups
- MINOR: mux_quic: remove superfluous b_size() before b_alloc()
- BUG/MINOR: mux_quic: free frames emitted with QMux
- BUILD: 51d: fix bool definition on dummy lib v4
- CLEANUP: Reapply ist.cocci (4)
- CLEANUP: Reapply strcmp.cocci (3)
- CLEANUP: Reapply ha_free.cocci (2)
- BUG/MAJOR: http-htx: Store new host in a chunk for scheme-based normalization
- BUG/MEDIUM: http-htx: Don't use data from HTX message to update authority
- BUG/MEDIUM: http-htx: Loop on full host value during scheme based normalization
- MEDIUM: http-htx: Make authority update optional when replacing a header value
- MEDIUM: http-htx: Make authority update optional when adding a header
- BUG/MAJOR: http: forbid comma character in authority value
- BUG/MEDIUM: h1: Enforce the authority validation during H1 request parsing
- BUG/MAJOR: mux-h1: Deal with true 64-bits integer to emit chunks size
- BUG/MEDIUM: tasks: Do not loop in task_schedule() if a task is running
- BUG/MINOR: fix various typos and spelling mistakes in user-visible messages
- CLEANUP: tree-wide: fix comment typos all over the tree (~68)
- BUG/MINOR: payload: validate minimum keyshare_len in smp_fetch_ssl_keyshare_groups
- BUG/MINOR: payload: prevent integer overflow in distcc token parsing
- BUG/MINOR: net_helper: fix out-of-bounds read in tcp_fullhdr_find_opt
- BUG/MINOR: net_helper: fix out-of-bounds read in sample_conv_tcp_options_list
- BUG/MINOR: net_helper: fix incomplete decoding in sample_conv_eth_vlan
- BUG/MEDIUM: mux-fcgi: Properly handle full buffer for FCGI_PARAM record
- BUG/MINOR: http-htx: Don't normalize emtpy path for OPTIONS requests
2026/04/15 : 3.4-dev9
- DOC: config: fix ambiguous info in log-steps directive description
- MINOR: filters: add filter name to flt_conf struct
- MEDIUM: filters: add "filter-sequence" directive
- REGTESTS: add a test for "filter-sequence" directive
- Revert "CLEANUP: tcpcheck: Don't needlessly expose proxy_parse_tcpcheck()"
- MINOR: tcpcheck: reintroduce proxy_parse_tcpcheck() symbol
- BUG/MEDIUM: haterm: Move all init functions of haterm in haterm_init.c
- BUG/MEDIUM: mux-h1: Disable 0-copy forwarding when draining the request
- MINOR: servers: The right parameter for idle-pool.shared is "full"
- DOC: config: Fix two typos in the server param "healthcheck" description
- BUG/MINOR: http-act: fix a typo in the "pause" action error message
- MINOR: tcpcheck: Reject unknown keyword during parsing of healthcheck section
- BUG/MEDIUM: tcpcheck/server: Fix parsing of healthcheck param for dynamic servers
- BUG/MINOR: counters: fix unexpected 127 char GUID truncation for shm-stats-file objects
- BUG/MEDIUM: tcpcheck: Properly retrieve tcpcheck type to install the best mux
- BUG/MEDIUM: payload: validate SNI name_len in req.ssl_sni
- BUG/MEDIUM: jwe: fix NULL deref crash with empty CEK and non-dir alg
- BUG/MEDIUM: jwt: fix heap overflow in ECDSA signature DER conversion
- BUG/MEDIUM: jwe: fix memory leak in jwt_decrypt_secret with var argument
- BUG: hlua: fix stack overflow in httpclient headers conversion
- BUG/MINOR: hlua: fix stack overflow in httpclient headers conversion
- BUG/MINOR: hlua: fix format-string vulnerability in Patref error path
- BUG/MEDIUM: chunk: fix typo allocating small trash with bufsize_large
- BUG/MEDIUM: chunk: fix infinite loop in get_larger_trash_chunk()
- BUG/MINOR: peers: fix OOB heap write in dictionary cache update
- CI: VTest build with git clone + cache
- BUG/MEDIUM: connection: Wake the stconn on error when failing to create mux
- CI: github: update to cache@v5
- Revert "BUG: hlua: fix stack overflow in httpclient headers conversion"
- CI: github: fix vtest path to allow correct caching
- CI: github: add the architecture to the cache key for vtest2
- MEDIUM: connections: Really enforce mux protocol requirements
- MINOR: tools: Implement net_addr_type_is_quic()
- MEDIUM: check: Revamp the way the protocol and xprt are determined
- BUG/MAJOR: slz: always make sure to limit fixed output to less than worst case literals
- MINOR: lua: add tune.lua.openlibs to restrict loaded Lua standard libraries
- REGTESTS: lua: add tune.lua.openlibs to all Lua reg-tests
- BUG/MINOR: resolvers: fix memory leak on AAAA additional records
- BUG/MINOR: spoe: fix pointer arithmetic overflow in spoe_decode_buffer()
- BUG/MINOR: http-act: validate decoded lengths in *-headers-bin
- BUG/MINOR: haterm: Return the good start-line for 100-continue interim message
- BUG/MEDIUM: samples: Fix handling of SMP_T_METH samples
- BUG/MINOR: sample: fix info leak in regsub when exp_replace fails
- BUG/MEDIUM: mux-fcgi: prevent record-length truncation with large bufsize
- BUG/MINOR: hlua: fix use-after-free of HTTP reason string
- BUG/MINOR: mux-quic: fix potential NULL deref on qcc_release()
- BUG/MINOR: quic: increment pos pointer on QMux transport params parsing
- MINOR: xprt_qstrm: implement Rx buffering
- MINOR: xprt_qstrm/mux-quic: handle extra QMux frames after params
- MINOR: xprt_qstrm: implement Tx buffering
- MINOR: xprt_qstrm: handle connection errors
- MEDIUM: mux-quic: implement QMux record parsing
- MEDIUM: xprt_qstrm: implement QMux record parsing
- MEDIUM: mux-quic/xprt_qstrm: implement QMux record emission
- DOC: update draft link for QMux protocol
- BUG/MINOR: do not crash on QMux reception of BLOCKED frames
- Revert "BUG/MEDIUM: haterm: Move all init functions of haterm in haterm_init.c"
- BUG/MEDIUM: haterm: Properly initialize the splicing support for haterm
- BUG/MINOR: mux_quic: prevent QMux crash on qcc_io_send() error path
- BUG/MINOR: xprt_qstrm: do not parse record length on read again
- MEDIUM: otel: added OpenTelemetry filter skeleton
- MEDIUM: otel: added configuration and utility layer
- MEDIUM: otel: added configuration parser and event model
- MEDIUM: otel: added post-parse configuration check
- MEDIUM: otel: added memory pool and runtime scope layer
- MEDIUM: otel: implemented filter callbacks and event dispatcher
- MEDIUM: otel: wired OTel C wrapper library integration
- MEDIUM: otel: implemented scope execution and span management
- MEDIUM: otel: added context propagation via carrier interfaces
- MEDIUM: otel: added HTTP header operations for context propagation
- MEDIUM: otel: added HAProxy variable storage for context propagation
- MINOR: otel: added prefix-based variable scanning
- MEDIUM: otel: added CLI commands for runtime filter management
- MEDIUM: otel: added group action for rule-based scope execution
- MINOR: otel: added log-format support to the sample parser and runtime
- MINOR: otel: test: added test and benchmark suite for the OTel filter
- MINOR: otel: added span link support
- MINOR: otel: added metrics instrument support
- MINOR: otel: added log-record signal support
- MINOR: otel: test: added full-event test config
- DOC: otel: added documentation
- DOC: otel: test: added test README-* files
- DOC: otel: test: added speed test guide and benchmark results
- DOC: otel: added cross-cutting design patterns document
- MINOR: otel: added flt_otel_sample_eval and exposed flt_otel_sample_add_kv
- MINOR: otel: changed log-record attr to use sample expressions
- MINOR: otel: changed instrument attr to use sample expressions
- DOC: otel: added README.md overview document
- CLEANUP: ot: use the item API for the variables trees
- BUG/MINOR: ot: removed dead code in flt_ot_parse_cfg_str()
- BUG/MINOR: ot: fixed wrong NULL check in flt_ot_parse_cfg_group()
- BUILD: ot: removed explicit include path when building opentracing filter
- MINOR: ot: renamed the variable dbg_indent_level to flt_ot_dbg_indent_level
- CI: Drop obsolete `packages: write` permission from `quic-interop-*.yml`
- CI: Consistently add a top-level `permissions` definition to GHA workflows
- CI: Wrap all `if:` conditions in `${{ }}`
- CI: Fix regular expression escaping in matrix.py
- CI: Update to actions/checkout@v6
- CI: Simplify version extraction with `haproxy -vq`
- CI: Merge `aws-lc.yml` and `aws-lc-fips.yml` into `aws-lc.yml`
- CI: Merge `aws-lc-template.yml` into `aws-lc.yml`
- CI: Consistently set up VTest with `./.github/actions/setup-vtest`
- MINOR: mux_quic: remove duplicate QMux local transport params
- CI: github: add bash to the musl job
- BUG/MINOR: quic: do not use hardcoded values in QMux TP frame builder
- BUG/MINOR: log: Fix error message when using unavailable fetch in logfmt
- CLEANUP: log: Return `size_t` from `sess_build_logline_orig()`
- CLEANUP: stream: Explain the two-step initialization in `stream_generate_unique_id()`
- CLEANUP: stream: Reduce duplication in `stream_generate_unique_id()`
- CLEANUP: http_fetch: Use local `unique_id` variable in `smp_fetch_uniqueid()`
- CI: build WolfSSL job with asan enabled
- MINOR: tools: memvprintf(): remove <out> check that always true
- BUG/MEDIUM: cli: Properly handle too big payload on a command line
- REGTESTS: Never reuse server connection in reg-tests/jwt/jwt_decrypt.vtc
- MINOR: errors: remove excessive errmsg checks
- BUG/MINOR: haterm: preserve the pipe size margin for splicing
- MEDIUM: acme: implement dns-persist-01 challenge
- MINOR: acme: extend resolver-based DNS pre-check to dns-persist-01
- DOC: configuration: document dns-persist-01 challenge type and options
- BUG/MINOR: acme: read the wildcard flag from the authorization response
- BUG/MINOR: acme: don't pass NULL into format string
- BUG/MINOR: haterm: don't apply the default pipe size margin twice
- CLEANUP: Make `lf_expr` parameter of `sess_build_logline_orig()` const
- MINOR: Add `generate_unique_id()` helper
- MINOR: Allow inlining of `stream_generate_unique_id()`
- CLEANUP: log: Stop touching `struct stream` internals for `%ID`
- MINOR: check: Support generating a `unique_id` for checks
- MINOR: http_fetch: Add support for checks to `unique-id` fetch
- MINOR: acme: display the type of challenge in ACME_INITIAL_DELAY
- MINOR: mjson: reintroduce mjson_next()
- CI: Remove obsolete steps from musl.yml
- CI: Use `sh` in `actions/setup-vtest/action.yml`
- CI: Sync musl.yml with vtest.yml
- CI: Integrate Musl build into vtest.yml
- CI: Use `case()` function
- CI: Generate vtest.yml matrix on `ubuntu-slim`
- CI: Run contrib.yml on `ubuntu-slim`
- CI: Use `matrix:` in contrib.yml
- CI: Build `dev/haring/` as part of contrib.yml
- MINOR: htx: Add helper function to get type and size from the block info field
- BUG/MEDIUM: htx: Properly handle block modification during defragmentation
- BUG/MEDIUM: htx: Don't count delta twice when block value is replaced
- MINOR: ssl: add TLS 1.2 values in HAPROXY_KEYLOG_XX_LOG_FMT
- EXAMPLES: ssl: keylog entries are greater than 1024
- BUILD: Makefile: don't forget to also delete haterm on make clean
- MINOR: stats: report the number of thread groups in "show info"
- CLEANUP: sample: fix the comment regarding the range of the thread sample fetch
- MINOR: sample: return the number of the current thread group
- MINOR: sample: add new sample fetch functions reporting current CPU usage
- BUG/MEDIUM: peers: trash of expired entries delayed after fullresync
- DOC: remove the alpine/musl status job image
- MINOR: mux-quic: improve documentation for qcs_attach_sc()
- MINOR: mux-quic: reorganize code for app init/shutdown
- MINOR: mux-quic: perform app init in case of early shutdown
- MEDIUM: quic: implement fe.stream.max-total
- MINOR: mux-quic: close connection when reaching max-total streams
- REGTESTS: add QUIC test for max-total streams setting
- MEDIUM: threads: start threads by groups
- MINOR: acme: opportunistic DNS check for dns-persist-01 to skip challenge-ready steps
- BUG/MINOR: acme: fix fallback state after failed initial DNS check
- CLEANUP: acme: no need to reset ctx state and http_state before nextreq
- BUG/MINOR: threads: properly set the number of tgroups when non using policy
2026/04/03 : 3.4-dev8
- MINOR: log: split do_log() in do_log() + do_log_ctx()
- MINOR: log: provide a way to override logger->profile from process_send_log_ctx
- MINOR: log: support optional 'profile <log_profile_name>' argument to do-log action
- BUG/MINOR: sock: adjust accept() error messages for ENFILE and ENOMEM
- BUG/MINOR: qpack: fix 62-bit overflow and 1-byte OOB reads in decoding
- MEDIUM: sched: do not run a same task multiple times in series
- MINOR: sched: do not requeue a tasklet into the current queue
- MINOR: sched: do not punish self-waking tasklets anymore
- MEDIUM: sched: do not punish self-waking tasklets if TASK_WOKEN_ANY
- MEDIUM: sched: change scheduler budgets to lower TL_BULK
- MINOR: mux-h2: assign a limited frames processing budget
- BUILD: sched: fix leftover of debugging test in single-run changes
- BUG/MEDIUM: acme: fix multiple resource leaks in acme_x509_req()
- MINOR: http_htx: use enum for arbitrary values in conf_errors
- MINOR: http_htx: rename fields in struct conf_errors
- MINOR: http_htx: split check/init of http_errors
- MINOR/OPTIM: http_htx: lookup once http_errors section on check/init
- MEDIUM: proxy: remove http-errors limitation for dynamic backends
- BUG/MINOR: acme: leak of ext_san upon insertion error
- BUG/MINOR: acme: wrong error when checking for duplicate section
- BUG/MINOR: acme/cli: wrong argument check in 'acme renew'
- BUG/MINOR: http_htx: fix null deref in http-errors config check
- MINOR: buffers: Move small buffers management from quic to dynbuf part
- MINOR: dynbuf: Add helper functions to alloc large and small buffers
- MINOR: quic: Use b_alloc_small() to allocate a small buffer
- MINOR: config: Relax tests on the configured size of small buffers
- MINOR: config: Report the warning when invalid large buffer size is set
- MEDIUM: htx: Add htx_xfer function to replace htx_xfer_blks
- MINOR: htx: Add helper functions to xfer a message to smaller or larger one
- MINOR: http-ana: Use HTX API to move to a large buffer
- MEDIUM: chunk: Add support for small chunks
- MEDIUM: stream: Try to use a small buffer for HTTP request on queuing
- MEDIUM: stream: Try to use small buffer when TCP stream is queued
- MEDIUM: stconn: Use a small buffer if possible for L7 retries
- MEDIUM: tree-wide: Rely on htx_xfer() instead of htx_xfer_blks()
- Revert "BUG/MEDIUM: mux-h2: make sure to always report pending errors to the stream"
- MEDIUM: mux-h2: Stop dealing with HTX flags transfer in h2_rcv_buf()
- MEDIUM: tcpcheck: Use small buffer if possible for healthchecks
- MINOR: proxy: Review options flags used to configure healthchecks
- DOC: config: Fix alphabetical ordering of proxy options
- DOC: config: Fix alphabetical ordering of external-check directives
- MINOR: proxy: Add use-small-buffers option to set where to use small buffers
- DOC: config: Add missing 'status-code' param for 'http-check expect' directive
- DOC: config: Reorder params for 'tcp-check expect' directive
- BUG/MINOR: acme: NULL check on my_strndup()
- BUG/MINOR: acme: free() DER buffer on a2base64url error path
- BUG/MINOR: acme: replace atol with len-bounded __strl2uic() for retry-after
- BUG/MINOR: acme/cli: fix argument check and error in 'acme challenge_ready'
- BUILD: tools: potential null pointer dereference in dl_collect_libs_cb
- BUG/MINOR: ech: permission checks on the CLI
- BUG/MINOR: acme: permission checks on the CLI
- BUG/MEDIUM: check: Don't reuse the server xprt if we should not
- MINOR: checks: Store the protocol to be used in struct check
- MINOR: protocols: Add a new proto_is_quic() function
- MEDIUM: connections: Enforce mux protocol requirements
- MEDIUM: server: remove a useless memset() in srv_update_check_addr_port.
- BUG/MINOR: config: Warn only if warnif_cond_conflicts report a conflict
- BUG/MINOR: config: Properly test warnif_misplaced_* return values
- BUG/MINOR: http-ana: Only consider client abort for abortonclose
- BUG/MEDIUM: acme: skip doing challenge if it is already valid
- MINOR: connections: Enhance tune.idle-pool.shared
- BUG/MINOR: acme: fix task allocation leaked upon error
- BUG/MEDIUM: htx: Fix htx_xfer() to consume more data than expected
- CI: github: fix tag listing by implementing proper API pagination
- CLEANUP: fix typos and spelling in comments and documentation
- BUG/MINOR: quic: close conn on packet reception with incompatible frame
- CLEANUP: stconn: Remove usless sc_new_from_haterm() declaration
- BUG/MINOR: stconn: Always declare the SC created from healthchecks as a back SC
- MINOR: stconn: flag the stream endpoint descriptor when the app has started
- MINOR: mux-h2: report glitches on early RST_STREAM
- BUG/MINOR: net_helper: fix length controls on ip.fp tcp options parsing
- BUILD: net_helper: fix unterminated comment that broke the build
- MINOR: resolvers: basic TXT record implementation
- MINOR: acme: store the TXT record in auth->token
- MEDIUM: acme: add dns-01 DNS propagation pre-check
- MEDIUM: acme: new 'challenge-ready' option
- DOC: configuration: document challenge-ready and dns-delay options for ACME
- SCRIPTS: git-show-backports: list new commits and how to review them with -L
- BUG/MEDIUM: ssl/cli: tls-keys commands warn when accessed without admin level
- BUG/MEDIUM: ssl/ocsp: ocsp commands warn when accessed without admin level
- BUG/MEDIUM: map/cli: map/acl commands warn when accessed without admin level
- BUG/MEDIUM: ssl/cli: tls-keys commands are missing permission checks
- BUG/MEDIUM: ssl/ocsp: ocsp commands are missing permission checks
- BUG/MEDIUM: map/cli: CLI commands lack admin permission checks
- DOC: configuration: mention QUIC server support
- MEDIUM: Add set-headers-bin, add-headers-bin and del-headers-bin actions
- BUG/MEDIUM: mux-h1: Don't set MSG_MORE on bodyless responses forwarded to client
- BUG/MINOR: http_act: Properly handle decoding errors in *-headers-bin actions
- MEDIUM: stats: Hide the version by default and add stats-showversion
- MINOR: backends: Don't update last_sess if it did not change
- MINOR: servers: Don't update last_sess if it did not change
- MINOR: ssl/log: add keylog format variables and env vars
- DOC: configuration: update tune.ssl.keylog URL to IETF draft
- BUG/MINOR: http_act: Make set/add-headers-bin compatible with ACL conditions
- MINOR: action: Add a sample expression field in arguments used by HTTP actions
- MEDIUM: http_act: Rework *-headers-bin actions
- BUG/MINOR: tcpcheck: Remove unexpected flag on tcpcheck rules for httchck option
- MEDIUM: tcpcheck: Refactor how tcp-check rulesets are stored
- MINOR: tcpcheck: Deal with disable-on-404 and send-state in the tcp-check itself
- BUG/MINOR: tcpcheck: Don't enable http_needed when parsing HTTP samples
- MINOR: tcpcheck: Use tcpcheck flags to know a healthcheck uses SSL connections
- BUG/MINOR: tcpcheck: Use tcpcheck context for expressions parsing
- CLEANUP: tcpcheck: Don't needlessly expose proxy_parse_tcpcheck()
- MINOR: tcpcheck: Add a function to stringify the healthcheck type
- MEDIUM: tcpcheck: Split parsing functions to prepare healthcheck sections parsing
- MEDIUM: tcpcheck: Add parsing support for healthcheck sections
- MINOR: tcpcheck: Extract tcpheck ruleset post-config in a dedicated function
- MEDIUM: tcpcheck/server: Add healthcheck server keyword
- REGTESTS: tcpcheck: Add a script to check healthcheck section
- MINOR: acme: add 'dns-timeout' keyword for dns-01 challenge
- CLEANUP: net_helper: fix typo in comment
- MINOR: acme: set the default dns-delay to 30s
- MINOR: connection: add function to identify a QUIC connection
- MINOR: quic: refactor frame parsing
- MINOR: quic: refactor frame encoding
- BUG/MINOR: quic: fix documentation for transport params decoding
- MINOR: quic: split transport params decoding/check
- MINOR: quic: remove useless quic_tp_dec_err type
- MINOR: quic: define QMux transport parameters frame type
- MINOR: quic: implement QMux transport params frame parser/builder
- MINOR: mux-quic: move qcs stream member into tx inner struct
- MINOR: mux-quic: prepare Tx support for QMux
- MINOR: mux-quic: convert init/closure for QMux compatibility
- MINOR: mux-quic: protect qcc_io_process for QMux
- MINOR: mux-quic: prepare traces support for QMux
- MINOR: quic: abstract stream type in qf_stream frame
- MEDIUM: mux-quic: implement QMux receive
- MINOR: mux-quic: handle flow-control frame on qstream read
- MINOR: mux-quic: define Rx connection buffer for QMux
- MINOR: mux_quic: implement qstrm rx buffer realign
- MEDIUM: mux-quic: implement QMux send
- MINOR: mux-quic: implement qstream send callback
- MINOR: mux-quic: define Tx connection buffer for QMux
- MINOR: xprt_qstrm: define new xprt module for QMux protocol
- MINOR: xprt_qstrm: define callback for ALPN retrieval
- MINOR: xprt_qstrm: implement reception of transport parameters
- MINOR: xprt_qstrm: implement sending of transport parameters
- MEDIUM: ssl: load xprt_qstrm after handshake completion
- MINOR: mux-quic: use QMux transport parameters from qstrm xprt
- MAJOR: mux-quic: activate QMux for frontend side
- MAJOR: mux-quic: activate QMux on the backend side
- MINOR: acme: split the CLI wait from the resolve wait
- MEDIUM: acme: initialize the dns timer starting from the first DNS request
- DEBUG: connection/flags: add QSTRM flags for the decoder
- BUG/MINOR: mux_quic: fix uninit for QMux emission
- MINOR: acme: remove remaining CLI wait in ACME_RSLV_TRIGGER
- MEDIUM: acme: split the initial delay from the retry DNS delay
- BUG/MINOR: cfgcond: properly set the error pointer on evaluation error
- BUG/MINOR: cfgcond: always set the error string on openssl_version checks
- BUG/MINOR: cfgcond: always set the error string on awslc_api checks
- BUG/MINOR: cfgcond: fail cleanly on missing argument for "feature"
- MINOR: ssl: add the ssl_fc_crtname sample fetch
- MINOR: hasterm: Change hstream_add_data() to prepare zero-copy data forwarding
- MEDIUM: haterm: Add support for 0-copy data forwading and option to disable it
- MEDIUM: haterm: Prepare support for splicing by initializing a master pipe
- MEDIUM: haterm: Add support for splicing and option to disable it
- MINOR: haterm: Handle boolean request options as flags
- MINOR: haterm: Add an request option to disable splicing
- BUG/MINOR: ssl: fix memory leak in ssl_fc_crtname by using SSL_CTX ex_data index
2026/03/20 : 3.4-dev7 2026/03/20 : 3.4-dev7
- BUG/MINOR: stconn: Increase SC bytes_out value in se_done_ff() - 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: ssl-sample: Fix sample_conv_sha2() by checking EVP_Digest* failures

View File

@ -60,7 +60,6 @@
# USE_OBSOLETE_LINKER : use when the linker fails to emit __start_init/__stop_init # USE_OBSOLETE_LINKER : use when the linker fails to emit __start_init/__stop_init
# USE_THREAD_DUMP : use the more advanced thread state dump system. Automatic. # USE_THREAD_DUMP : use the more advanced thread state dump system. Automatic.
# USE_OT : enable the OpenTracing filter # USE_OT : enable the OpenTracing filter
# EXTRA_MAKE : space-separated list of external addons using a Makefile.inc
# USE_MEMORY_PROFILING : enable the memory profiler. Linux-glibc only. # USE_MEMORY_PROFILING : enable the memory profiler. Linux-glibc only.
# USE_LIBATOMIC : force to link with/without libatomic. Automatic. # USE_LIBATOMIC : force to link with/without libatomic. Automatic.
# USE_PTHREAD_EMULATION : replace pthread's rwlocks with ours # USE_PTHREAD_EMULATION : replace pthread's rwlocks with ours
@ -644,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=),)
@ -671,8 +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
src/mpring.o
endif endif
ifneq ($(USE_QUIC_OPENSSL_COMPAT:0=),) ifneq ($(USE_QUIC_OPENSSL_COMPAT:0=),)
@ -861,14 +859,9 @@ ifneq ($(USE_LINUX_CAP:0=),)
endif endif
ifneq ($(USE_OT:0=),) ifneq ($(USE_OT:0=),)
$(call warning, The opentracing filter was deprecated in haproxy 3.3 and will be removed in 3.5.)
include addons/ot/Makefile include addons/ot/Makefile
endif endif
ifneq ($(EXTRA_MAKE),)
include $(addsuffix /Makefile.inc,$(EXTRA_MAKE))
endif
# better keep this one close to the end, as several libs above may need it # better keep this one close to the end, as several libs above may need it
ifneq ($(USE_DL:0=),) ifneq ($(USE_DL:0=),)
DL_LDFLAGS = -ldl DL_LDFLAGS = -ldl
@ -1169,7 +1162,7 @@ uninstall:
$(Q)rm -f "$(DESTDIR)$(SBINDIR)"/haproxy $(Q)rm -f "$(DESTDIR)$(SBINDIR)"/haproxy
clean: clean:
$(Q)rm -f *.[oas] src/*.[oas] haproxy haterm test .build_opts .build_opts.new $(Q)rm -f *.[oas] src/*.[oas] haproxy test .build_opts .build_opts.new
$(Q)for dir in . src dev/* admin/* addons/* include/* doc; do rm -f $$dir/*~ $$dir/*.rej $$dir/core; done $(Q)for dir in . src dev/* admin/* addons/* include/* doc; do rm -f $$dir/*~ $$dir/*.rej $$dir/core; done
$(Q)rm -f haproxy-$(VERSION).tar.gz haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION).tar.gz $(Q)rm -f haproxy-$(VERSION).tar.gz haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION).tar.gz
$(Q)rm -f haproxy-$(VERSION) haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION) nohup.out gmon.out $(Q)rm -f haproxy-$(VERSION) haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION) nohup.out gmon.out

View File

@ -1,9 +1,9 @@
# HAProxy # HAProxy
[![alpine/musl](https://github.com/haproxy/haproxy/actions/workflows/musl.yml/badge.svg)](https://github.com/haproxy/haproxy/actions/workflows/musl.yml)
[![AWS-LC](https://github.com/haproxy/haproxy/actions/workflows/aws-lc.yml/badge.svg)](https://github.com/haproxy/haproxy/actions/workflows/aws-lc.yml) [![AWS-LC](https://github.com/haproxy/haproxy/actions/workflows/aws-lc.yml/badge.svg)](https://github.com/haproxy/haproxy/actions/workflows/aws-lc.yml)
[![Illumos](https://github.com/haproxy/haproxy/actions/workflows/illumos.yml/badge.svg)](https://github.com/haproxy/haproxy/actions/workflows/illumos.yml) [![Illumos](https://github.com/haproxy/haproxy/actions/workflows/illumos.yml/badge.svg)](https://github.com/haproxy/haproxy/actions/workflows/illumos.yml)
[![NetBSD](https://github.com/haproxy/haproxy/actions/workflows/netbsd.yml/badge.svg)](https://github.com/haproxy/haproxy/actions/workflows/netbsd.yml) [![NetBSD](https://github.com/haproxy/haproxy/actions/workflows/netbsd.yml/badge.svg)](https://github.com/haproxy/haproxy/actions/workflows/netbsd.yml)
[![CrossCompile](https://github.com/haproxy/haproxy/actions/workflows/cross-zoo.yml/badge.svg)](https://github.com/haproxy/haproxy/actions/workflows/cross-zoo.yml)
[![FreeBSD](https://api.cirrus-ci.com/github/haproxy/haproxy.svg?task=FreeBSD)](https://cirrus-ci.com/github/haproxy/haproxy/) [![FreeBSD](https://api.cirrus-ci.com/github/haproxy/haproxy.svg?task=FreeBSD)](https://cirrus-ci.com/github/haproxy/haproxy/)
[![VTest](https://github.com/haproxy/haproxy/actions/workflows/vtest.yml/badge.svg)](https://github.com/haproxy/haproxy/actions/workflows/vtest.yml) [![VTest](https://github.com/haproxy/haproxy/actions/workflows/vtest.yml/badge.svg)](https://github.com/haproxy/haproxy/actions/workflows/vtest.yml)

View File

@ -1,2 +1,2 @@
$Format:%ci$ $Format:%ci$
2026/04/29 2026/03/20

View File

@ -1 +1 @@
3.4-dev10 3.4-dev7

View File

@ -40,7 +40,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h> typedef int bool;
enum { false, true };
typedef unsigned char byte; typedef unsigned char byte;

View File

@ -70,4 +70,4 @@ OPTIONS_OBJS += \
addons/ot/src/vars.o addons/ot/src/vars.o
endif endif
OT_CFLAGS := $(OT_CFLAGS) $(OT_DEFINE) OT_CFLAGS := $(OT_CFLAGS) -Iaddons/ot/include $(OT_DEFINE)

View File

@ -48,12 +48,13 @@ Currently, tracers that support this API include Datadog, Jaeger, LightStep
and Zipkin. and Zipkin.
Note: The OpenTracing filter shouldn't be used for new designs as OpenTracing Note: The OpenTracing filter shouldn't be used for new designs as OpenTracing
itself is no longer maintained nor supported by its authors. As such itself is no longer maintained nor supported by its authors. A
OpenTracing will be deprecated in 3.3 and removed in 3.5. A replacement replacement filter base on OpenTelemetry is currently under development
filter based on OpenTelemetry is available since 3.4 with complete build and is expected to be ready around HAProxy 3.2. As such OpenTracing will
instructions currently at: be deprecated in 3.3 and removed in 3.5.
https://github.com/haproxytech/haproxy-opentelemetry/ The OT filter was primarily tested with the Jaeger tracer, while configurations
for both Datadog and Zipkin tracers were also set in the test directory.
The OT filter is a standard HAProxy filter, so what applies to others also The OT filter is a standard HAProxy filter, so what applies to others also
applies to this one (of course, by that I mean what is described in the applies to this one (of course, by that I mean what is described in the

View File

@ -35,11 +35,11 @@
do { \ do { \
if (!(l) || (flt_ot_debug.level & (1 << (l)))) \ if (!(l) || (flt_ot_debug.level & (1 << (l)))) \
(void)fprintf(stderr, FLT_OT_DBG_FMT("%.*s" f "\n"), \ (void)fprintf(stderr, FLT_OT_DBG_FMT("%.*s" f "\n"), \
flt_ot_dbg_indent_level, FLT_OT_DBG_INDENT, ##__VA_ARGS__); \ dbg_indent_level, FLT_OT_DBG_INDENT, ##__VA_ARGS__); \
} while (0) } while (0)
# define FLT_OT_FUNC(f, ...) do { FLT_OT_DBG(1, "%s(" f ") {", __func__, ##__VA_ARGS__); flt_ot_dbg_indent_level += 3; } while (0) # define FLT_OT_FUNC(f, ...) do { FLT_OT_DBG(1, "%s(" f ") {", __func__, ##__VA_ARGS__); dbg_indent_level += 3; } while (0)
# define FLT_OT_RETURN(a) do { flt_ot_dbg_indent_level -= 3; FLT_OT_DBG(1, "}"); return a; } while (0) # define FLT_OT_RETURN(a) do { dbg_indent_level -= 3; FLT_OT_DBG(1, "}"); return a; } while (0)
# define FLT_OT_RETURN_EX(a,t,f) do { flt_ot_dbg_indent_level -= 3; { t _r = (a); FLT_OT_DBG(1, "} = " f, _r); return _r; } } while (0) # define FLT_OT_RETURN_EX(a,t,f) do { dbg_indent_level -= 3; { t _r = (a); FLT_OT_DBG(1, "} = " f, _r); return _r; } } while (0)
# define FLT_OT_RETURN_INT(a) FLT_OT_RETURN_EX((a), int, "%d") # define FLT_OT_RETURN_INT(a) FLT_OT_RETURN_EX((a), int, "%d")
# define FLT_OT_RETURN_PTR(a) FLT_OT_RETURN_EX((a), void *, "%p") # define FLT_OT_RETURN_PTR(a) FLT_OT_RETURN_EX((a), void *, "%p")
# define FLT_OT_DBG_IFDEF(a,b) a # define FLT_OT_DBG_IFDEF(a,b) a
@ -54,7 +54,7 @@ struct flt_ot_debug {
}; };
extern THREAD_LOCAL int flt_ot_dbg_indent_level; extern THREAD_LOCAL int dbg_indent_level;
extern struct flt_ot_debug flt_ot_debug; extern struct flt_ot_debug flt_ot_debug;
#else #else

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
/*** /***

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
/*** /***

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
#define FLT_OT_EVENT_DEF(a,b,c,d,e,f) { AN_##b##_##a, SMP_OPT_DIR_##b, SMP_VAL_FE_##c, SMP_VAL_BE_##d, e, f }, #define FLT_OT_EVENT_DEF(a,b,c,d,e,f) { AN_##b##_##a, SMP_OPT_DIR_##b, SMP_VAL_FE_##c, SMP_VAL_BE_##d, e, f },

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
/* /*
@ -155,18 +155,12 @@ static void flt_ot_return_void(const struct filter *f, char **err)
*/ */
static int flt_ot_init(struct proxy *p, struct flt_conf *fconf) static int flt_ot_init(struct proxy *p, struct flt_conf *fconf)
{ {
static int warnings_emitted = 0;
struct flt_ot_conf *conf = FLT_OT_DEREF(fconf, conf, NULL); struct flt_ot_conf *conf = FLT_OT_DEREF(fconf, conf, NULL);
char *err = NULL; char *err = NULL;
int retval = FLT_OT_RET_ERROR; int retval = FLT_OT_RET_ERROR;
FLT_OT_FUNC("%p, %p", p, fconf); FLT_OT_FUNC("%p, %p", p, fconf);
if (!warnings_emitted && !deprecated_directives_allowed) {
warnings_emitted++;
ha_warning("The opentracing filter was deprecated in haproxy 3.3 and will be removed in 3.5.\n");
}
if (conf == NULL) if (conf == NULL)
FLT_OT_RETURN_INT(retval); FLT_OT_RETURN_INT(retval);

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
#define FLT_OT_GROUP_DEF(a,b,c) { a, b, c }, #define FLT_OT_GROUP_DEF(a,b,c) { a, b, c },

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
#ifdef DEBUG_OT #ifdef DEBUG_OT
@ -261,7 +261,7 @@ int flt_ot_http_header_set(struct channel *chn, const char *prefix, const char *
if (value == NULL) { if (value == NULL) {
/* Do nothing. */ /* Do nothing. */
} }
else if (http_add_header(htx, ist_name, ist(value), 1) == 1) { else if (http_add_header(htx, ist_name, ist(value)) == 1) {
retval = 0; retval = 0;
FLT_OT_DBG(3, "HTTP header '%s: %s' added", ist_name.ptr, value); FLT_OT_DBG(3, "HTTP header '%s: %s' added", ist_name.ptr, value);

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
static struct pool_head *pool_head_ot_span_context __read_mostly = NULL; static struct pool_head *pool_head_ot_span_context __read_mostly = NULL;

View File

@ -17,12 +17,12 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
#ifdef DEBUG_OT #ifdef DEBUG_OT
struct flt_ot_debug flt_ot_debug; struct flt_ot_debug flt_ot_debug;
THREAD_LOCAL int flt_ot_dbg_indent_level = 0; THREAD_LOCAL int dbg_indent_level = 0;
#endif #endif
#ifdef OTC_DBG_MEM #ifdef OTC_DBG_MEM
@ -359,6 +359,7 @@ static int flt_ot_parse_cfg_sample(const char *file, int linenum, char **args, s
*/ */
static int flt_ot_parse_cfg_str(const char *file, int linenum, char **args, struct list *head, char **err) static int flt_ot_parse_cfg_str(const char *file, int linenum, char **args, struct list *head, char **err)
{ {
struct flt_ot_conf_str *str = NULL;
int i, retval = ERR_NONE; int i, retval = ERR_NONE;
FLT_OT_FUNC("\"%s\", %d, %p, %p, %p:%p", file, linenum, args, head, FLT_OT_DPTR_ARGS(err)); FLT_OT_FUNC("\"%s\", %d, %p, %p, %p:%p", file, linenum, args, head, FLT_OT_DPTR_ARGS(err));
@ -367,6 +368,9 @@ static int flt_ot_parse_cfg_str(const char *file, int linenum, char **args, stru
if (flt_ot_conf_str_init(args[i], linenum, head, err) == NULL) if (flt_ot_conf_str_init(args[i], linenum, head, err) == NULL)
retval |= ERR_ABORT | ERR_ALERT; retval |= ERR_ABORT | ERR_ALERT;
if (retval & ERR_CODE)
flt_ot_conf_str_free(&str);
FLT_OT_RETURN_INT(retval); FLT_OT_RETURN_INT(retval);
} }
@ -640,7 +644,7 @@ static int flt_ot_parse_cfg_group(const char *file, int linenum, char **args, in
if (pdata->keyword == FLT_OT_PARSE_GROUP_ID) { if (pdata->keyword == FLT_OT_PARSE_GROUP_ID) {
flt_ot_current_group = flt_ot_conf_group_init(args[1], linenum, &(flt_ot_current_config->groups), &err); flt_ot_current_group = flt_ot_conf_group_init(args[1], linenum, &(flt_ot_current_config->groups), &err);
if (flt_ot_current_group == NULL) if (flt_ot_current_config == NULL)
retval |= ERR_ABORT | ERR_ALERT; retval |= ERR_ABORT | ERR_ALERT;
} }
else if (pdata->keyword == FLT_OT_PARSE_GROUP_SCOPES) { else if (pdata->keyword == FLT_OT_PARSE_GROUP_SCOPES) {

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
/*** /***

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
static struct pool_head *pool_head_ot_scope_span __read_mostly = NULL; static struct pool_head *pool_head_ot_scope_span __read_mostly = NULL;

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
#ifdef DEBUG_OT #ifdef DEBUG_OT
@ -41,7 +41,7 @@ void flt_ot_args_dump(char **args)
argc = flt_ot_args_count(args); argc = flt_ot_args_count(args);
(void)fprintf(stderr, FLT_OT_DBG_FMT("%.*sargs[%d]: { '%s' "), flt_ot_dbg_indent_level, FLT_OT_DBG_INDENT, argc, args[0]); (void)fprintf(stderr, FLT_OT_DBG_FMT("%.*sargs[%d]: { '%s' "), dbg_indent_level, FLT_OT_DBG_INDENT, argc, args[0]);
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
(void)fprintf(stderr, "'%s' ", args[i]); (void)fprintf(stderr, "'%s' ", args[i]);

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "../include/include.h" #include "include.h"
#ifdef DEBUG_OT #ifdef DEBUG_OT
@ -46,10 +46,10 @@ static void flt_ot_vars_scope_dump(struct vars *vars, const char *scope)
vars_rdlock(vars); vars_rdlock(vars);
for (i = 0; i < VAR_NAME_ROOTS; i++) { for (i = 0; i < VAR_NAME_ROOTS; i++) {
struct ceb_node *node = cebu64_imm_first(&(vars->name_root[i])); struct ceb_node *node = cebu64_first(&(vars->name_root[i]));
for ( ; node != NULL; node = cebu64_imm_next(&(vars->name_root[i]), node)) { for ( ; node != NULL; node = cebu64_next(&(vars->name_root[i]), node)) {
struct var *var = container_of(node, struct var, name_node); struct var *var = container_of(node, struct var, node);
FLT_OT_DBG(2, "'%s.%016" PRIx64 "' -> '%.*s'", scope, var->name_hash, (int)b_data(&(var->data.u.str)), b_orig(&(var->data.u.str))); FLT_OT_DBG(2, "'%s.%016" PRIx64 "' -> '%.*s'", scope, var->name_hash, (int)b_data(&(var->data.u.str)), b_orig(&(var->data.u.str)));
} }

View File

@ -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"

View File

@ -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

View File

@ -59,7 +59,7 @@ versions. It displays its usage when run without argument or wrong arguments:
-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"...) -b <keysize> : RSA key size in bits (ex: "2048", "4096"...)
-c <curves> : ECDSA curves (ex: "P-256", "P-384"...) -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 --quic-bind-opts <opts> : append options to QUIC "bind" lines
@ -134,7 +134,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

View File

@ -1,5 +1,5 @@
----------------------------------------- -----------------------------------------
Filters Guide - version 3.4 Filters Guide - version 2.9
( Last update: 2021-02-24 ) ( Last update: 2021-02-24 )
------------------------------------------ ------------------------------------------
Author : Christopher Faulet Author : Christopher Faulet
@ -738,10 +738,10 @@ For instance :
switch (an_bit) { switch (an_bit) {
case AN_REQ_WAIT_HTTP: case AN_REQ_WAIT_HTTP:
if (/* A test on received headers before any other treatment */) { if (/* A test on received headers before any other treatment */) {
msg = ((chn->flags & CF_ISRESP) ? &s->txn.http->rsp : &s->txn.http->req); msg = ((chn->flags & CF_ISRESP) ? &s->txn->rsp : &s->txn->req);
txn->status = 400; txn->status = 400;
msg->msg_state = HTTP_MSG_ERROR; msg->msg_state = HTTP_MSG_ERROR;
http_reply_and_close(s, s->txn.http->status, http_error_message(s)); http_reply_and_close(s, s->txn->status, http_error_message(s));
return -1; /* This is an error ! */ return -1; /* This is an error ! */
} }
break; break;
@ -1161,7 +1161,7 @@ Then, to finish, there are 2 informational callbacks :
if we're retrying to send the request to the server after it failed. It if we're retrying to send the request to the server after it failed. It
could be useful to reset the filter context before receiving the true could be useful to reset the filter context before receiving the true
response. response.
By checking s->txn.http->status, it is possible to know why this callback is By checking s->txn->status, it is possible to know why this callback is
called. If it's a 1xx, we're called because of an informational called. If it's a 1xx, we're called because of an informational
message. Otherwise, it is a L7 retry. message. Otherwise, it is a L7 retry.

View File

@ -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

View File

@ -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.

View File

@ -1646,20 +1646,16 @@ a payload, it needs to end with an empty line.
The payload pattern can be customized in order to change the way the payload The payload pattern can be customized in order to change the way the payload
ends. In order to end a payload with something else than an empty line, a ends. In order to end a payload with something else than an empty line, a
customized pattern can be set between '<<' and '\n'. Up to 64 characters can be customized pattern can be set between '<<' and '\n'. Only 7 characters can be
used in addition to '<<', otherwise this won't be considered a payload. It used in addiction to '<<', otherwise this won't be considered a payload.
should be enough to use random payload patterns. For example, to use a PEM file For example, to use a PEM file that contains empty lines and comments:
that contains empty lines and comments:
# echo -e "set ssl cert common.pem <<%EOF%\n$(cat common.pem)\n%EOF%\n" | \ # echo -e "set ssl cert common.pem <<%EOF%\n$(cat common.pem)\n%EOF%\n" | \
socat /var/run/haproxy.stat - socat /var/run/haproxy.stat -
Limitations do exist: The pattern "<<" must not be glued to the last word of the Limitations do exist: the length of the whole buffer passed to the CLI must
line. The length of a command line must not be greater than tune.bufsize, not be greater than tune.bfsize and the pattern "<<" must not be glued to the
including the pattern starting the payload, but excluding the payload last word of the line.
itself. The payload size is limited to 128KB by default. This can be changed by
setting "tune.cli.max-payload-size" global parameter, with some cautions. Note
the pattern marking the end of the payload is part of this limit.
When entering a payload while in interactive mode, the prompt will change from When entering a payload while in interactive mode, the prompt will change from
"> " to "+ ". "> " to "+ ".
@ -1735,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
@ -1744,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
@ -2134,7 +2133,7 @@ del backend <name>
be attached to the backend instance. be attached to the backend instance.
There is additional restrictions which prevent backend removal. First, a There is additional restrictions which prevent backend removal. First, a
backend cannot be removed if it is explicitly referenced by config elements, backend cannot be removed if it is explicitely referenced by config elements,
for example via a use_backend rule or in sample expressions. Some proxies for example via a use_backend rule or in sample expressions. Some proxies
options are also incompatible with runtime deletion. Currently, this is the options are also incompatible with runtime deletion. Currently, this is the
case when deprecated dispatch or option transparent are used. Also, a backend case when deprecated dispatch or option transparent are used. Also, a backend
@ -2142,7 +2141,7 @@ del backend <name>
impossible for now to remove a backend if QUIC servers were present in it. 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 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 for the aformentioned requisites. This also provides a methode to wait for
the final closure of the streams attached to the target backend. the final closure of the streams attached to the target backend.
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

View File

@ -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 2048
size 1M
ring keylog-bc
description "TLS session key backend log"
format raw
maxlen 2048
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 len 2048 profile keylog-fc local1
log ring@keylog-bc len 2048 profile keylog-bc local1
default_backend be1
backend be1
server s1 10.0.0.123:443 ssl verify none

View File

@ -2,30 +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
#define ACME_RDY_INITIAL_DNS 0x08
/* 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 {
@ -41,7 +28,6 @@ struct acme_cfg {
int curves; /* NID of curves */ int curves; /* NID of curves */
} key; } key;
char *challenge; /* HTTP-01, DNS-01, etc */ char *challenge; /* HTTP-01, DNS-01, etc */
char *profile; /* ACME profile */
char *vars; /* variables put in the dpapi sink */ char *vars; /* variables put in the dpapi sink */
char *provider; /* DNS provider put in the dpapi sink */ char *provider; /* DNS provider put in the dpapi sink */
struct acme_cfg *next; struct acme_cfg *next;
@ -54,13 +40,6 @@ enum acme_st {
ACME_NEWACCOUNT, ACME_NEWACCOUNT,
ACME_NEWORDER, ACME_NEWORDER,
ACME_AUTH, ACME_AUTH,
ACME_INITIAL_RSLV_TRIGGER, /* opportunistic DNS check to avoid cond_ready steps */
ACME_INITIAL_RSLV_READY,
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,
@ -79,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;
}; };
@ -107,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];
@ -126,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

View File

@ -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 */

View File

@ -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, const char *challenge_type, char **errmsg);
void acme_rslv_free(struct acme_rslv *rslv);
#endif
#endif /* _HAPROXY_ACME_RESOLVERS_H */

View File

@ -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;

View File

@ -107,7 +107,7 @@ struct appctx {
enum obj_type obj_type; /* OBJ_TYPE_APPCTX */ enum obj_type obj_type; /* OBJ_TYPE_APPCTX */
/* 3 unused bytes here */ /* 3 unused bytes here */
unsigned int st0; /* Main applet state. May be used by any applet */ unsigned int st0; /* Main applet state. May be used by any applet */
unsigned int st1; /* Applet substate. May be used by any applet */ unsigned int st1; /* Applet substate. Mau be used by any applet */
unsigned int flags; /* APPCTX_FL_* */ unsigned int flags; /* APPCTX_FL_* */
struct buffer inbuf; struct buffer inbuf;
@ -120,13 +120,13 @@ struct appctx {
struct { struct {
struct buffer *cmdline; /* used to store unfinished commands */ struct buffer *cmdline; /* used to store unfinished commands */
struct buffer payload; /* used to store the payload */
int severity_output; /* used within the cli_io_handler to format severity output of informational feedback */ int severity_output; /* used within the cli_io_handler to format severity output of informational feedback */
int level; /* the level of CLI which can be lowered dynamically */ int level; /* the level of CLI which can be lowered dynamically */
char *payload_pat; /* Pointer to the payload pattern. NULL if no payload */ char payload_pat[8]; /* Payload pattern */
uint32_t max_payload_sz;/* Max size allowed for dynamic payload. 0 if not allowed */ char *payload; /* Pointer on the payload. NULL if no payload */
uint32_t anon_key; /* the key to anonymise with the hash in cli */ uint32_t anon_key; /* the key to anonymise with the hash in cli */
/* XXX 4 unused bytes here */
int (*io_handler)(struct appctx *appctx); /* used within the cli_io_handler when st0 = CLI_ST_CALLBACK */ 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 */
@ -148,6 +148,7 @@ struct appctx {
/* here we have the service's context (CLI command, applet, etc) */ /* here we have the service's context (CLI command, applet, etc) */
void *svcctx; /* pointer to a context used by the command, e.g. <storage> below */ void *svcctx; /* pointer to a context used by the command, e.g. <storage> below */
struct { struct {
void *shadow; /* shadow of svcctx above, do not use! */
char storage[APPLET_MAX_SVCCTX]; /* storage of svcctx above */ char storage[APPLET_MAX_SVCCTX]; /* storage of svcctx above */
} svc; /* generic storage for most commands */ } svc; /* generic storage for most commands */
}; };

View File

@ -92,7 +92,6 @@ enum {
ARGC_TCK, /* tcp-check expression */ ARGC_TCK, /* tcp-check expression */
ARGC_CFG, /* configuration expression */ ARGC_CFG, /* configuration expression */
ARGC_CLI, /* CLI expression*/ ARGC_CLI, /* CLI expression*/
ARGC_OTEL, /* opentelemetry scope args */
}; };
/* flags used when compiling and executing regex */ /* flags used when compiling and executing regex */

View File

@ -150,24 +150,6 @@ struct lbprm_per_tgrp {
struct lb_fwrr_per_tgrp fwrr; struct lb_fwrr_per_tgrp fwrr;
}; };
}; };
/* Call backs for some LB actions. Any of them may be NULL (thus should be ignored).
* Those marked "srvlock" will need to be called with the server lock held.
* The other ones might take it themselves if needed.
*/
struct lb_ops {
int (*proxy_init)(struct proxy *); /* set up per-proxy LB state at config time; <0=fail */
void (*update_server_eweight)(struct server *); /* to be called after eweight change // srvlock */
void (*set_server_status_up)(struct server *); /* to be called after status changes to UP // srvlock */
void (*set_server_status_down)(struct server *); /* to be called after status changes to DOWN // srvlock */
void (*server_take_conn)(struct server *); /* to be called when connection is assigned */
void (*server_drop_conn)(struct server *); /* to be called when connection is dropped */
void (*server_requeue)(struct server *); /* function used to place the server where it must be */
void (*proxy_deinit)(struct proxy *); /* to be called when we're destroying the proxy */
void (*server_deinit)(struct server *); /* to be called when we're destroying the server */
int (*server_init)(struct server *); /* initialize a freshly added server (runtime); <0=fail. */
};
/* LB parameters for all algorithms */ /* LB parameters for all algorithms */
struct lbprm { struct lbprm {
union { /* LB parameters depending on the algo type */ union { /* LB parameters depending on the algo type */
@ -197,7 +179,20 @@ struct lbprm {
struct mt_list lb_free_list; /* LB tree elements available */ struct mt_list lb_free_list; /* LB tree elements available */
__decl_thread(HA_RWLOCK_T lock); __decl_thread(HA_RWLOCK_T lock);
struct server *fbck; /* first backup server when !PR_O_USE_ALL_BK, or NULL */ struct server *fbck; /* first backup server when !PR_O_USE_ALL_BK, or NULL */
const struct lb_ops *ops; /* algo-specific operations; NULL = no LB algo selected */
/* Call backs for some actions. Any of them may be NULL (thus should be ignored).
* Those marked "srvlock" will need to be called with the server lock held.
* The other ones might take it themselves if needed.
*/
void (*update_server_eweight)(struct server *); /* to be called after eweight change // srvlock */
void (*set_server_status_up)(struct server *); /* to be called after status changes to UP // srvlock */
void (*set_server_status_down)(struct server *); /* to be called after status changes to DOWN // srvlock */
void (*server_take_conn)(struct server *); /* to be called when connection is assigned */
void (*server_drop_conn)(struct server *); /* to be called when connection is dropped */
void (*server_requeue)(struct server *); /* function used to place the server where it must be */
void (*proxy_deinit)(struct proxy *); /* to be called when we're destroying the proxy */
void (*server_deinit)(struct server *); /* to be called when we're destroying the server */
int (*server_init)(struct server *); /* initialize a freshly added server (runtime); <0=fail. */
}; };
#endif /* _HAPROXY_BACKEND_T_H */ #endif /* _HAPROXY_BACKEND_T_H */

View File

@ -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

View File

@ -24,7 +24,6 @@
#include <haproxy/connection-t.h> #include <haproxy/connection-t.h>
#include <haproxy/dynbuf-t.h> #include <haproxy/dynbuf-t.h>
#include <haproxy/obj_type-t.h> #include <haproxy/obj_type-t.h>
#include <haproxy/tools-t.h>
#include <haproxy/vars-t.h> #include <haproxy/vars-t.h>
/* Please note: this file tends to commonly be part of circular dependencies, /* Please note: this file tends to commonly be part of circular dependencies,
@ -60,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
@ -156,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 */
@ -175,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_* */
@ -190,8 +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 net_addr_type addr_type; /* Address type (dgram/stream for both protocol and XPRT) */
int alt_proto; /* Needed to know exactly which protocol we are after */
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 */
@ -199,7 +195,6 @@ struct check {
const struct mux_proto_list *mux_proto; /* the mux to use for all outgoing connections (specified by the "proto" keyword) */ const struct mux_proto_list *mux_proto; /* the mux to use for all outgoing connections (specified by the "proto" keyword) */
struct list check_queue; /* entry in the check queue. Not empty = in queue. */ struct list check_queue; /* entry in the check queue. Not empty = in queue. */
int via_socks4; /* check the connection via socks4 proxy */ int via_socks4; /* check the connection via socks4 proxy */
struct ist unique_id; /* custom unique ID, same as in struct stream */
}; };
#endif /* _HAPROXY_CHECKS_T_H */ #endif /* _HAPROXY_CHECKS_T_H */

View File

@ -26,7 +26,6 @@
#include <haproxy/proxy-t.h> #include <haproxy/proxy-t.h>
#include <haproxy/server-t.h> #include <haproxy/server-t.h>
#include <haproxy/trace-t.h> #include <haproxy/trace-t.h>
#include <haproxy/log.h>
extern struct trace_source trace_check; extern struct trace_source trace_check;
@ -79,18 +78,8 @@ 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);
static inline struct ist check_generate_unique_id(struct check *check, struct lf_expr *format)
{
if (!isttest(check->unique_id)) {
generate_unique_id(&check->unique_id, check->sess, NULL, format);
}
return check->unique_id;
}
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);

View File

@ -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. */

View File

@ -49,7 +49,6 @@
#define APPCTX_CLI_ST1_PROMPT (1 << 4) /* display prompt */ #define APPCTX_CLI_ST1_PROMPT (1 << 4) /* display prompt */
#define APPCTX_CLI_ST1_TIMED (1 << 5) /* display timer in prompt */ #define APPCTX_CLI_ST1_TIMED (1 << 5) /* display timer in prompt */
#define APPCTX_CLI_ST1_YIELD (1 << 6) /* forced yield between commands */ #define APPCTX_CLI_ST1_YIELD (1 << 6) /* forced yield between commands */
#define APPCTX_CLI_ST1_DYN_PAYLOAD (1 << 7) /* the payload was dynamically allocated */
#define CLI_PREFIX_KW_NB 5 #define CLI_PREFIX_KW_NB 5
#define CLI_MAX_MATCHES 5 #define CLI_MAX_MATCHES 5
@ -113,13 +112,6 @@ struct cli_wait_ctx {
const char *msg; // static error message for failures if not NULL const char *msg; // static error message for failures if not NULL
}; };
struct pcli_txn {
int next_pid; /* next target PID to use for the CLI proxy */
int flags; /* flags for CLI proxy */
char payload_pat[65]; /* payload pattern for the CLI proxy, including trailing \0 */
};
struct cli_kw { struct cli_kw {
const char *str_kw[CLI_PREFIX_KW_NB]; /* keywords ended by NULL, limited to CLI_PREFIX_KW_NB const char *str_kw[CLI_PREFIX_KW_NB]; /* keywords ended by NULL, limited to CLI_PREFIX_KW_NB
separated keywords combination */ separated keywords combination */

View File

@ -47,13 +47,10 @@ int mworker_cli_global_proxy_new_listener(struct mworker_proc *proc);
void mworker_cli_proxy_stop(void); void mworker_cli_proxy_stop(void);
extern struct bind_conf *mcli_reload_bind_conf; extern struct bind_conf *mcli_reload_bind_conf;
extern struct pool_head *pool_head_pcli_txn;
/* proxy mode cli functions */ /* proxy mode cli functions */
/* analyzers */ /* analyzers */
struct pcli_txn *pcli_create_txn(struct stream *s);
void pcli_destroy_txn(struct stream *s);
int pcli_wait_for_request(struct stream *s, struct channel *req, int an_bit); int pcli_wait_for_request(struct stream *s, struct channel *req, int an_bit);
int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit); int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit);

View File

@ -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;
@ -285,8 +283,6 @@ enum {
CO_ER_SSL_FATAL, /* SSL fatal error during a SSL_read or SSL_write */ CO_ER_SSL_FATAL, /* SSL fatal error during a SSL_read or SSL_write */
CO_ER_QSTRM, /* QMux transport parameter exchange failure */
CO_ER_REVERSE, /* Error during reverse connect */ CO_ER_REVERSE, /* Error during reverse connect */
CO_ER_POLLERR, /* we only noticed POLLERR */ CO_ER_POLLERR, /* we only noticed POLLERR */
@ -349,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 */
}; };
@ -361,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 */

View File

@ -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>
@ -610,17 +609,16 @@ 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 != 0) != ((item->mux->flags & MX_FL_FRAMED) != 0))) 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;
}
else if (!istlen(item->token)) { else if (!istlen(item->token)) {
if (!fallback || (item->mode == proto_mode && fallback->mode != proto_mode)) if (!fallback || (item->mode == proto_mode && fallback->mode != proto_mode))
fallback = item; fallback = item;
@ -642,7 +640,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;
} }
@ -692,12 +690,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)
{ {

View File

@ -34,7 +34,6 @@
#define MAX_TGROUPS 1 #define MAX_TGROUPS 1
#define MAX_THREADS_PER_GROUP 1 #define MAX_THREADS_PER_GROUP 1
#define DEF_MAX_THREADS_PER_GROUP 1
#else #else
@ -50,15 +49,6 @@
#define MAX_THREADS_PER_GROUP __WORDSIZE #define MAX_THREADS_PER_GROUP __WORDSIZE
/* Default value for the maximum number of threads per group. Thread counts
* beyond this value will induce the creation of new thread groups and thus
* limit contention on highly accessed areas. The value may be changed between
* 1 and MAX_THREADS_PER_GROUP via the global "max-threads-per-group" setting.
*/
#ifndef DEF_MAX_THREADS_PER_GROUP
#define DEF_MAX_THREADS_PER_GROUP 16
#endif
/* threads enabled, max_threads defaults to long bits for 1 tgroup or 4 times /* threads enabled, max_threads defaults to long bits for 1 tgroup or 4 times
* long bits if more tgroups are enabled. * long bits if more tgroups are enabled.
*/ */

View File

@ -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.

View File

@ -143,7 +143,7 @@ struct flt_kw_list {
* otherwise. * otherwise.
* - http_reset : Called when the HTTP message is reset. It happens * - http_reset : Called when the HTTP message is reset. It happens
* either when a 100-continue response is received. * either when a 100-continue response is received.
* that can be detected if s->txn.http->status is 10X, or * that can be detected if s->txn->status is 10X, or
* if we're attempting a L7 retry. * if we're attempting a L7 retry.
* Returns nothing. * Returns nothing.
* - http_reply : Called when, at any time, HAProxy decides to stop * - http_reply : Called when, at any time, HAProxy decides to stop
@ -207,7 +207,6 @@ struct flt_ops {
* accessible from a filter when instantiated in a stream * accessible from a filter when instantiated in a stream
*/ */
struct flt_conf { struct flt_conf {
const char *name; /* The filter name (same name used to select the filter from config) */
const char *id; /* The filter id */ const char *id; /* The filter id */
struct flt_ops *ops; /* The filter callbacks */ struct flt_ops *ops; /* The filter callbacks */
void *conf; /* The filter configuration */ void *conf; /* The filter configuration */
@ -215,12 +214,6 @@ struct flt_conf {
unsigned int flags; /* FLT_CFG_FL_* */ unsigned int flags; /* FLT_CFG_FL_* */
}; };
struct filter_sequence_elt {
char *flt_name; /* filter name (set during parsing) */
struct flt_conf *flt_conf; /* associated filter conf (set after parsing) */
struct list list; /* list element */
};
/* /*
* Structure reprensenting a filter instance attached to a stream * Structure reprensenting a filter instance attached to a stream
* *

View File

@ -215,7 +215,6 @@ struct global {
int default_shards; /* default shards for listeners, or -1 (by-thread) or -2 (by-group) */ int default_shards; /* default shards for listeners, or -1 (by-thread) or -2 (by-group) */
uint max_checks_per_thread; /* if >0, no more than this concurrent checks per thread */ uint max_checks_per_thread; /* if >0, no more than this concurrent checks per thread */
uint ring_queues; /* if >0, #ring queues, otherwise equals #thread groups */ uint ring_queues; /* if >0, #ring queues, otherwise equals #thread groups */
uint cli_max_payload_sz; /* The max payload size for the CLI */
enum threadgroup_takeover tg_takeover; /* Policy for threadgroup takeover */ enum threadgroup_takeover tg_takeover; /* Policy for threadgroup takeover */
} tune; } tune;
struct { struct {

View File

@ -164,7 +164,7 @@ static inline int hpack_encode_int_status(struct buffer *out, unsigned int statu
goto fail; goto fail;
/* basic encoding of the status code */ /* basic encoding of the status code */
out->area[len - 5] = 0x48; // literal with incremental indexing, name=":status" (idx 8) out->area[len - 5] = 0x48; // indexed name -- name=":status" (idx 8)
out->area[len - 4] = 0x03; // 3 bytes status out->area[len - 4] = 0x03; // 3 bytes status
out->area[len - 3] = '0' + status / 100; out->area[len - 3] = '0' + status / 100;
out->area[len - 2] = '0' + status / 10 % 10; out->area[len - 2] = '0' + status / 10 % 10;

View File

@ -78,7 +78,7 @@ static inline const struct hpack_dte *hpack_get_dte(const struct hpack_dht *dht,
/* returns non-zero if <idx> is valid for table <dht> */ /* returns non-zero if <idx> is valid for table <dht> */
static inline int hpack_valid_idx(const struct hpack_dht *dht, uint32_t idx) static inline int hpack_valid_idx(const struct hpack_dht *dht, uint32_t idx)
{ {
return idx > 0 && idx < dht->used + HPACK_SHT_SIZE; return idx < dht->used + HPACK_SHT_SIZE;
} }
/* return a pointer to the header name for entry <dte>. */ /* return a pointer to the header name for entry <dte>. */

View File

@ -21,11 +21,15 @@ struct hstream {
int flags; int flags;
int ka; /* .0: keep-alive .1: forced .2: http/1.1, .3: was_reused */ int ka; /* .0: keep-alive .1: forced .2: http/1.1, .3: was_reused */
int req_cache;
unsigned long long req_size; /* values passed in the URI to override the server's */ unsigned long long req_size; /* values passed in the URI to override the server's */
unsigned long long req_body; /* remaining body to be consumed from the request */ unsigned long long req_body; /* remaining body to be consumed from the request */
int req_code; int req_code;
int res_wait; /* time to wait before replying in ms */ int res_wait; /* time to wait before replying in ms */
int res_time; int res_time;
int req_chunked;
int req_random;
int req_after_res; /* Drain the request body after having sent the response */
enum http_meth_t req_meth; enum http_meth_t req_meth;
}; };

View File

@ -238,11 +238,6 @@ static inline int http_path_has_forbidden_char(const struct ist ist, const char
* fall back to the slow path and decide. Brackets are used for IP-literal and * fall back to the slow path and decide. Brackets are used for IP-literal and
* deserve special case, that is better handled in the slow path. The function * deserve special case, that is better handled in the slow path. The function
* returns 0 if no forbidden char is presnet, non-zero otherwise. * returns 0 if no forbidden char is presnet, non-zero otherwise.
*
* There is a special case for the comma (','). While it is allowed, we reject
* it because the authority is higly linked with the host header. The comma is
* also the header value separator. So it is highly ambiguous to use it for the
* authority/host value.
*/ */
static inline int http_authority_has_forbidden_char(const struct ist ist) static inline int http_authority_has_forbidden_char(const struct ist ist)
{ {
@ -262,7 +257,6 @@ static inline int http_authority_has_forbidden_char(const struct ist ist)
c = p[ofs]; c = p[ofs];
if (unlikely(c < 0x21 || c > 0x7e || if (unlikely(c < 0x21 || c > 0x7e ||
c == ',' || /* Special case: forbidden because it is ambiguous for the host header value */
c == '#' || c == '/' || c == '?' || c == '@' || c == '#' || c == '/' || c == '?' || c == '@' ||
c == '[' || c == '\\' || c == ']')) { c == '[' || c == '\\' || c == ']')) {
/* all of them must be rejected, except '[' which may /* all of them must be rejected, except '[' which may
@ -296,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 */
/* /*

View File

@ -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 */

View File

@ -42,7 +42,7 @@ int http_find_pfx_header(const struct htx *htx, const struct ist prefix, struct
int http_find_sfx_header(const struct htx *htx, const struct ist suffix, struct http_hdr_ctx *ctx, int full); int http_find_sfx_header(const struct htx *htx, const struct ist suffix, struct http_hdr_ctx *ctx, int full);
int http_find_sub_header(const struct htx *htx, const struct ist sub, struct http_hdr_ctx *ctx, int full); int http_find_sub_header(const struct htx *htx, const struct ist sub, struct http_hdr_ctx *ctx, int full);
int http_match_header(const struct htx *htx, const struct my_regex *re, struct http_hdr_ctx *ctx, int full); int http_match_header(const struct htx *htx, const struct my_regex *re, struct http_hdr_ctx *ctx, int full);
int http_add_header(struct htx *htx, const struct ist n, const struct ist v, int update_authority); int http_add_header(struct htx *htx, const struct ist n, const struct ist v);
int http_replace_stline(struct htx *htx, const struct ist p1, const struct ist p2, const struct ist p3); int http_replace_stline(struct htx *htx, const struct ist p1, const struct ist p2, const struct ist p3);
int http_replace_req_meth(struct htx *htx, const struct ist meth); int http_replace_req_meth(struct htx *htx, const struct ist meth);
int http_replace_req_uri(struct htx *htx, const struct ist uri); int http_replace_req_uri(struct htx *htx, const struct ist uri);
@ -52,8 +52,8 @@ int http_replace_res_status(struct htx *htx, const struct ist status, const stru
int http_replace_res_reason(struct htx *htx, const struct ist reason); int http_replace_res_reason(struct htx *htx, const struct ist reason);
int http_append_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data); int http_append_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data);
int http_prepend_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data); int http_prepend_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data);
int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data, int update_authority); int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data);
int http_replace_header(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist name, const struct ist value, int update_authority); int http_replace_header(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist name, const struct ist value);
int http_remove_header(struct htx *htx, struct http_hdr_ctx *ctx); int http_remove_header(struct htx *htx, struct http_hdr_ctx *ctx);
int http_update_authority(struct htx *htx, struct htx_sl *sl, const struct ist host); int http_update_authority(struct htx *htx, struct htx_sl *sl, const struct ist host);
int http_update_host(struct htx *htx, struct htx_sl *sl, const struct ist uri); int http_update_host(struct htx *htx, struct htx_sl *sl, const struct ist uri);
@ -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);

View File

@ -57,16 +57,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.
@ -165,36 +155,26 @@ static inline struct htx_blk *htx_get_blk(const struct htx *htx, uint32_t pos)
return (struct htx_blk *)(htx->blocks + htx_pos_to_addr(htx, pos)); return (struct htx_blk *)(htx->blocks + htx_pos_to_addr(htx, pos));
} }
static inline enum htx_blk_type __htx_blkinfo_type(uint32_t info)
{
return (info >> 28);
}
/* Returns the type of the block <blk> */ /* Returns the type of the block <blk> */
static inline enum htx_blk_type htx_get_blk_type(const struct htx_blk *blk) static inline enum htx_blk_type htx_get_blk_type(const struct htx_blk *blk)
{ {
return __htx_blkinfo_type(blk->info); return (blk->info >> 28);
}
static inline enum htx_blk_type __htx_blkinfo_size(uint32_t info)
{
enum htx_blk_type type = __htx_blkinfo_type(info);
switch (type) {
case HTX_BLK_HDR:
case HTX_BLK_TLR:
/* name.length + value.length */
return ((info & 0xff) + ((info >> 8) & 0xfffff));
default:
/* value.length */
return (info & 0xfffffff);
}
} }
/* Returns the size of the block <blk>, depending of its type */ /* Returns the size of the block <blk>, depending of its type */
static inline uint32_t htx_get_blksz(const struct htx_blk *blk) static inline uint32_t htx_get_blksz(const struct htx_blk *blk)
{ {
return __htx_blkinfo_size(blk->info); enum htx_blk_type type = htx_get_blk_type(blk);
switch (type) {
case HTX_BLK_HDR:
case HTX_BLK_TLR:
/* name.length + value.length */
return ((blk->info & 0xff) + ((blk->info >> 8) & 0xfffff));
default:
/* value.length */
return (blk->info & 0xfffffff);
}
} }
/* Returns the position of the oldest entry (head). It returns a signed 32-bits /* Returns the position of the oldest entry (head). It returns a signed 32-bits

View File

@ -23,16 +23,14 @@
#define _HAPROXY_LB_CHASH_H #define _HAPROXY_LB_CHASH_H
#include <haproxy/api.h> #include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/lb_chash-t.h> #include <haproxy/lb_chash-t.h>
struct proxy; struct proxy;
struct server; struct server;
int chash_init_server_tree(struct proxy *p);
struct server *chash_get_next_server(struct proxy *p, struct server *srvtoavoid); struct server *chash_get_next_server(struct proxy *p, struct server *srvtoavoid);
struct server *chash_get_server_hash(struct proxy *p, unsigned int hash, const struct server *avoid); struct server *chash_get_server_hash(struct proxy *p, unsigned int hash, const struct server *avoid);
extern const struct lb_ops lb_chash_ops;
#endif /* _HAPROXY_LB_CHASH_H */ #endif /* _HAPROXY_LB_CHASH_H */
/* /*

View File

@ -23,14 +23,12 @@
#define _HAPROXY_LB_FAS_H #define _HAPROXY_LB_FAS_H
#include <haproxy/api.h> #include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/lb_fas-t.h> #include <haproxy/lb_fas-t.h>
#include <haproxy/proxy-t.h> #include <haproxy/proxy-t.h>
#include <haproxy/server-t.h> #include <haproxy/server-t.h>
struct server *fas_get_next_server(struct proxy *p, struct server *srvtoavoid); struct server *fas_get_next_server(struct proxy *p, struct server *srvtoavoid);
void fas_init_server_tree(struct proxy *p);
extern const struct lb_ops lb_fas_ops;
#endif /* _HAPROXY_LB_FAS_H */ #endif /* _HAPROXY_LB_FAS_H */

View File

@ -23,14 +23,12 @@
#define _HAPROXY_LB_FWLC_H #define _HAPROXY_LB_FWLC_H
#include <haproxy/api.h> #include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/lb_fwlc-t.h> #include <haproxy/lb_fwlc-t.h>
#include <haproxy/proxy-t.h> #include <haproxy/proxy-t.h>
#include <haproxy/server-t.h> #include <haproxy/server-t.h>
struct server *fwlc_get_next_server(struct proxy *p, struct server *srvtoavoid); struct server *fwlc_get_next_server(struct proxy *p, struct server *srvtoavoid);
void fwlc_init_server_tree(struct proxy *p);
extern const struct lb_ops lb_fwlc_ops;
#endif /* _HAPROXY_LB_FWLC_H */ #endif /* _HAPROXY_LB_FWLC_H */

View File

@ -23,15 +23,13 @@
#define _HAPROXY_LB_FWRR_H #define _HAPROXY_LB_FWRR_H
#include <haproxy/api.h> #include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/lb_fwrr-t.h> #include <haproxy/lb_fwrr-t.h>
#include <haproxy/proxy-t.h> #include <haproxy/proxy-t.h>
#include <haproxy/server-t.h> #include <haproxy/server-t.h>
void fwrr_init_server_groups(struct proxy *p);
struct server *fwrr_get_next_server(struct proxy *p, struct server *srvtoavoid); struct server *fwrr_get_next_server(struct proxy *p, struct server *srvtoavoid);
extern const struct lb_ops lb_fwrr_ops;
#endif /* _HAPROXY_LB_FWRR_H */ #endif /* _HAPROXY_LB_FWRR_H */
/* /*

View File

@ -23,15 +23,14 @@
#define _HAPROXY_LB_MAP_H #define _HAPROXY_LB_MAP_H
#include <haproxy/api.h> #include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/proxy-t.h> #include <haproxy/proxy-t.h>
#include <haproxy/server-t.h> #include <haproxy/server-t.h>
void recalc_server_map(struct proxy *px);
void init_server_map(struct proxy *p);
struct server *map_get_server_rr(struct proxy *px, struct server *srvtoavoid); struct server *map_get_server_rr(struct proxy *px, struct server *srvtoavoid);
struct server *map_get_server_hash(struct proxy *px, unsigned int hash); struct server *map_get_server_hash(struct proxy *px, unsigned int hash);
extern const struct lb_ops lb_map_ops;
#endif /* _HAPROXY_LB_MAP_H */ #endif /* _HAPROXY_LB_MAP_H */
/* /*

View File

@ -23,12 +23,11 @@
#define _HAPROXY_LB_SS_H #define _HAPROXY_LB_SS_H
#include <haproxy/api.h> #include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/proxy-t.h> #include <haproxy/proxy-t.h>
#include <haproxy/server-t.h> #include <haproxy/server-t.h>
void recalc_server_ss(struct proxy *px);
void init_server_ss(struct proxy *px);
struct server *ss_get_server(struct proxy *px); struct server *ss_get_server(struct proxy *px);
extern const struct lb_ops lb_ss_ops;
#endif /* _HAPROXY_LB_SS_H */ #endif /* _HAPROXY_LB_SS_H */

View File

@ -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[];
@ -97,12 +95,12 @@ static inline struct log_orig log_orig(enum log_orig_id id, uint16_t flags)
} }
/* build a log line for the session and an optional stream */ /* build a log line for the session and an optional stream */
size_t sess_build_logline_orig(struct session *sess, struct stream *s, char *dst, size_t maxsize, int sess_build_logline_orig(struct session *sess, struct stream *s, char *dst, size_t maxsize,
const struct lf_expr *lf_expr, struct log_orig orig); struct lf_expr *lf_expr, struct log_orig orig);
/* wrapper for sess_build_logline_orig(), uses LOG_ORIG_UNSPEC log origin */ /* wrapper for sess_build_logline_orig(), uses LOG_ORIG_UNSPEC log origin */
static inline size_t sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t maxsize, static inline int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t maxsize,
const struct lf_expr *lf_expr) struct lf_expr *lf_expr)
{ {
return sess_build_logline_orig(sess, s, dst, maxsize, lf_expr, return sess_build_logline_orig(sess, s, dst, maxsize, lf_expr,
log_orig(LOG_ORIG_UNSPEC, LOG_ORIG_FL_NONE)); log_orig(LOG_ORIG_UNSPEC, LOG_ORIG_FL_NONE));
@ -196,22 +194,11 @@ char *update_log_hdr(const time_t time);
char * get_format_pid_sep1(int format, size_t *len); char * get_format_pid_sep1(int format, size_t *len);
char * get_format_pid_sep2(int format, size_t *len); char * get_format_pid_sep2(int format, size_t *len);
void generate_unique_id(struct ist *dst, struct session *sess, struct stream *strm, struct lf_expr *format);
static inline struct ist stream_generate_unique_id(struct stream *strm, struct lf_expr *format)
{
if (!isttest(strm->unique_id)) {
generate_unique_id(&strm->unique_id, strm_sess(strm), strm, format);
}
return strm->unique_id;
}
/* /*
* Builds a log line for the stream (must be valid). * Builds a log line for the stream (must be valid).
*/ */
static inline size_t build_logline_orig(struct stream *s, char *dst, size_t maxsize, static inline int build_logline_orig(struct stream *s, char *dst, size_t maxsize,
const struct lf_expr *lf_expr, struct log_orig orig) struct lf_expr *lf_expr, struct log_orig orig)
{ {
return sess_build_logline_orig(strm_sess(s), s, dst, maxsize, lf_expr, orig); return sess_build_logline_orig(strm_sess(s), s, dst, maxsize, lf_expr, orig);
} }
@ -219,7 +206,7 @@ static inline size_t build_logline_orig(struct stream *s, char *dst, size_t maxs
/* /*
* Wrapper for build_logline_orig, uses LOG_ORIG_UNSPEC log origin * Wrapper for build_logline_orig, uses LOG_ORIG_UNSPEC log origin
*/ */
static inline size_t build_logline(struct stream *s, char *dst, size_t maxsize, const struct lf_expr *lf_expr) static inline int build_logline(struct stream *s, char *dst, size_t maxsize, struct lf_expr *lf_expr)
{ {
return build_logline_orig(s, dst, maxsize, lf_expr, return build_logline_orig(s, dst, maxsize, lf_expr,
log_orig(LOG_ORIG_UNSPEC, LOG_ORIG_FL_NONE)); log_orig(LOG_ORIG_UNSPEC, LOG_ORIG_FL_NONE));

View File

@ -1,54 +0,0 @@
/*
* MPSC byte ring buffer with variable sized entries.
*/
#ifndef _MPRING_H
#define _MPRING_H
#include <sys/types.h>
#include <haproxy/compiler.h>
struct mpring {
size_t capacity;
size_t mask;
uint8_t *buffer;
uint64_t head THREAD_ALIGNED();
uint64_t tail THREAD_ALIGNED();
};
/* Initialize the ring buffer. The size MUST be a power of 2, and bigger than
* the value of the MPRING_PAYLOAD_ALIGN macro in mpring.c (currently set to 8).
*/
void mpring_init(struct mpring *ring, void *buffer, size_t size);
/* Reserve bytes in the buffer. Returns NULL in case of failure, and otherwise
* a pointer to the buffer with enough space to write <len> bytes.
*/
void *mpring_write_reserve(struct mpring *ring, size_t len);
/* Commit data to the buffer after it was written to the pointer given by
* mpring_write_reserve(). The <ptr> and <len> parameters MUST be identical to
* the ones returned by and passed to mpring_write_reserve(), respectively.
*/
void mpring_write_commit(struct mpring *ring, void *ptr, size_t len);
/* Convenience shorthand for when we only need to write one contiguous set of
* bytes to the buffer. Returns 0 in case of failure, and a non-zero value
* otherwise.
*/
int mpring_write(struct mpring *ring, const void *data, size_t len);
/* Get the next entry to be read. Returns NULL if there is no data to be read,
* otherwise returns a pointer to that data and set the size of the entry in the
* <len> pointer.
*/
void *mpring_read_begin(struct mpring *ring, size_t *len);
/* Indicate that we are done reading an entry, and that the space can be reused
* for new entries. This MUST be called after we are done reading an entry. The
* <len> parameter MUST be equal to the length given by mpring_read_begin().
*/
void mpring_read_end(struct mpring *ring, size_t len);
#endif /* _MPRING_H */

View File

@ -46,8 +46,6 @@ struct qcc {
enum qcc_app_st app_st; /* application layer state */ enum qcc_app_st app_st; /* application layer state */
int glitches; /* total number of glitches on this connection */ int glitches; /* total number of glitches on this connection */
uint32_t term_evts_log; /* termination events log */
/* flow-control fields set by us enforced on our side. */ /* flow-control fields set by us enforced on our side. */
struct { struct {
struct list frms; /* prepared frames related to flow-control */ struct list frms; /* prepared frames related to flow-control */
@ -82,21 +80,10 @@ struct qcc {
struct { struct {
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 sending */ 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;
uint64_t rlen; /* last record length read */
} 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. */
@ -177,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 */
@ -214,12 +198,6 @@ enum qcc_app_ops_close_side {
QCC_APP_OPS_CLOSE_SIDE_WR /* Write channel closed (STOP_SENDING received). */ QCC_APP_OPS_CLOSE_SIDE_WR /* Write channel closed (STOP_SENDING received). */
}; };
enum qcc_app_ops_lclose_mode {
QCC_APP_OPS_LCLO_MODE_NORMAL,
QCC_APP_OPS_LCLO_MODE_ABORT,
QCC_APP_OPS_LCLO_MODE_KILL_CONN,
};
/* QUIC application layer operations */ /* QUIC application layer operations */
struct qcc_app_ops { struct qcc_app_ops {
const char *alpn; const char *alpn;
@ -242,10 +220,8 @@ struct qcc_app_ops {
size_t (*nego_ff)(struct qcs *qcs, size_t count); size_t (*nego_ff)(struct qcs *qcs, size_t count);
size_t (*done_ff)(struct qcs *qcs); size_t (*done_ff)(struct qcs *qcs);
/* Notify about <qcs> stream remote closure. */ /* Notify about <qcs> stream closure. */
int (*close)(struct qcs *qcs, enum qcc_app_ops_close_side side); int (*close)(struct qcs *qcs, enum qcc_app_ops_close_side side);
/* Notify about <qcs> stream upper layer closure. */
void (*lclose)(struct qcs *qcs, enum qcc_app_ops_lclose_mode mode);
/* Free <qcs> stream app context. */ /* Free <qcs> stream app context. */
void (*detach)(struct qcs *qcs); void (*detach)(struct qcs *qcs);
@ -269,7 +245,7 @@ struct qcc_app_ops {
#define QC_CF_ERRL_DONE 0x00000002 /* local error properly handled, connection can be released */ #define QC_CF_ERRL_DONE 0x00000002 /* local error properly handled, connection can be released */
#define QC_CF_IS_BACK 0x00000004 /* backend side */ #define QC_CF_IS_BACK 0x00000004 /* backend side */
#define QC_CF_CONN_FULL 0x00000008 /* no stream buffers available on connection */ #define QC_CF_CONN_FULL 0x00000008 /* no stream buffers available on connection */
#define QC_CF_CONN_SHUT 0x00000010 /* peer has initiated app layer shutdown - no new stream should be opened locally */ /* unused 0x00000010 */
#define QC_CF_ERR_CONN 0x00000020 /* fatal error reported by transport layer */ #define QC_CF_ERR_CONN 0x00000020 /* fatal error reported by transport layer */
#define QC_CF_WAIT_HS 0x00000040 /* MUX init before QUIC handshake completed (0-RTT) */ #define QC_CF_WAIT_HS 0x00000040 /* MUX init before QUIC handshake completed (0-RTT) */

View File

@ -20,8 +20,7 @@
_qcc_report_glitch(qcc, inc); \ _qcc_report_glitch(qcc, inc); \
}) })
void qcc_set_error(struct qcc *qcc, int err, int app, int tevt); void qcc_set_error(struct qcc *qcc, int err, int app);
void qcc_report_term_evt(struct qcc *qcc, enum muxc_term_event_type type);
int _qcc_report_glitch(struct qcc *qcc, int inc); int _qcc_report_glitch(struct qcc *qcc, int inc);
int qcc_fctl_avail_streams(const struct qcc *qcc, int bidi); int qcc_fctl_avail_streams(const struct qcc *qcc, int bidi);
struct qcs *qcc_init_stream_local(struct qcc *qcc, int bidi); struct qcs *qcc_init_stream_local(struct qcc *qcc, int bidi);
@ -41,10 +40,9 @@ struct buffer *qcc_realloc_stream_txbuf(struct qcs *qcs);
int qcc_realign_stream_txbuf(const struct qcs *qcs, struct buffer *out); int qcc_realign_stream_txbuf(const struct qcs *qcs, struct buffer *out);
int qcc_release_stream_txbuf(struct qcs *qcs); int qcc_release_stream_txbuf(struct qcs *qcs);
int qcc_stream_can_send(const struct qcs *qcs); int qcc_stream_can_send(const struct qcs *qcs);
void qcc_reset_stream(struct qcs *qcs, int err, int term_evt); void qcc_reset_stream(struct qcs *qcs, int err);
void qcc_send_stream(struct qcs *qcs, int urg, int count); void qcc_send_stream(struct qcs *qcs, int urg, int count);
void qcc_abort_stream_read(struct qcs *qcs); void qcc_abort_stream_read(struct qcs *qcs);
void qcc_update_shut_id(struct qcc *qcc, uint64_t val);
int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset, int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset,
char fin, char *data); char fin, char *data);
int qcc_recv_max_data(struct qcc *qcc, uint64_t max); int qcc_recv_max_data(struct qcc *qcc, uint64_t max);
@ -64,9 +62,6 @@ static inline int qmux_stream_rx_bufsz(void)
/* This bit is set for unidirectional streams */ /* This bit is set for unidirectional streams */
#define QCS_ID_DIR_BIT 0x2 #define QCS_ID_DIR_BIT 0x2
/* Maximum bidirectional stream ID that a client can open. */
#define QCS_ID_MAX_STRM_CL_BIDI (QUIC_VARINT_8_BYTE_MAX - 3)
static inline enum qcs_type qcs_id_type(uint64_t id) static inline enum qcs_type qcs_id_type(uint64_t id)
{ {
return id & QCS_ID_TYPE_MASK; return id & QCS_ID_TYPE_MASK;

View File

@ -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 */

View File

@ -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 */

View File

@ -360,7 +360,7 @@ static inline uint16_t readv_n16(const void *p1, size_t s1, const void *p2)
* <p2>. <s1> may be zero and may be larger than the type. The caller is always * <p2>. <s1> may be zero and may be larger than the type. The caller is always
* responsible for providing enough room. * responsible for providing enough room.
*/ */
static inline void writev_n16(void *p1, size_t s1, void *p2, const uint16_t u16) static inline void writev_n16(const void *p1, size_t s1, const void *p2, const uint16_t u16)
{ {
if (unlikely(s1 < 2)) { if (unlikely(s1 < 2)) {
if (s1 == 0) if (s1 == 0)

View File

@ -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)) ;

View File

@ -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

View File

@ -44,10 +44,10 @@ enum peer_app_state {
/* peer learn state */ /* peer learn state */
enum peer_learn_state { enum peer_learn_state {
PEER_LR_ST_NOTASSIGNED = 0,/* The peer is not assigned for a lesson */ PEER_LR_ST_NOTASSIGNED = 0,/* The peer is not assigned for a leason */
PEER_LR_ST_ASSIGNED, /* The peer is assigned for a lesson */ PEER_LR_ST_ASSIGNED, /* The peer is assigned for a leason */
PEER_LR_ST_PROCESSING, /* The peer has started the lesson and it is not finished */ PEER_LR_ST_PROCESSING, /* The peer has started the leason and it is not finished */
PEER_LR_ST_FINISHED, /* The peer has finished the lesson, this state must be ack by the sync task */ PEER_LR_ST_FINISHED, /* The peer has finished the leason, this state must be ack by the sync task */
}; };
/******************************/ /******************************/
@ -88,7 +88,7 @@ static forceinline char *peers_show_flags(char *buf, size_t len, const char *del
_(PEERS_F_DBG_RESYNC_LOCALABORT, _(PEERS_F_DBG_RESYNC_REMOTEABORT, _(PEERS_F_DBG_RESYNC_LOCALABORT, _(PEERS_F_DBG_RESYNC_REMOTEABORT,
_(PEERS_F_DBG_RESYNC_LOCALFINISHED, _(PEERS_F_DBG_RESYNC_REMOTEFINISHED, _(PEERS_F_DBG_RESYNC_LOCALFINISHED, _(PEERS_F_DBG_RESYNC_REMOTEFINISHED,
_(PEERS_F_DBG_RESYNC_LOCALPARTIAL, _(PEERS_F_DBG_RESYNC_REMOTEPARTIAL, _(PEERS_F_DBG_RESYNC_LOCALPARTIAL, _(PEERS_F_DBG_RESYNC_REMOTEPARTIAL,
_(PEERS_F_DBG_RESYNC_LOCALASSIGN, _(PEERS_F_DBG_RESYNC_REMOTEASSIGN))))))))))))); _(PEERS_F_DBG_RESYNC_LOCALASSIGN, _(PEERS_F_DBG_RESYNC_REMOTEABORT)))))))))))));
/* epilogue */ /* epilogue */
_(~0U); _(~0U);
return buf; return buf;

View File

@ -25,8 +25,6 @@
#include <haproxy/api-t.h> #include <haproxy/api-t.h>
#include <haproxy/thread-t.h> #include <haproxy/thread-t.h>
#define QUIC_MAX_UDP_PAYLOAD_SIZE 2048
extern struct protocol proto_quic4; extern struct protocol proto_quic4;
extern struct protocol proto_quic6; extern struct protocol proto_quic6;

View File

@ -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 */
/* /*

View File

@ -117,9 +117,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 +145,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 +156,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 streams are queued*/
#define PR_O2_USE_SBUF_L7_RETRY 0x10000000 /* use small buffer for request when L7 retries are enabled */
#define PR_O2_USE_SBUF_CHECK 0x20000000 /* use small buffer for health-check requests */
#define PR_O2_USE_SBUF_ALL 0x38000000 /* all flags for use-small-buffer option */
/* unused : 0x40000000 ... 0x80000000 */
/* end of proxy->options2 */ /* end of proxy->options2 */
/* bits for proxy->options3 */ /* bits for proxy->options3 */
@ -243,12 +241,12 @@ enum PR_SRV_STATE_FILE {
/* Proxy flags */ /* Proxy flags */
#define PR_FL_DISABLED 0x00000001 /* The proxy was disabled in the configuration (not at runtime) */ #define PR_FL_DISABLED 0x00000001 /* The proxy was disabled in the configuration (not at runtime) */
#define PR_FL_STOPPED 0x00000002 /* The proxy was stopped */ #define PR_FL_STOPPED 0x00000002 /* 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 0x00000004 /* 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 0x00000008 /* 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 0x00000010 /* 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 0x00000020 /* 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 0x00000040 /* 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 0x00000080 /* 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_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. */ #define PR_FL_NON_PURGEABLE 0x00000200 /* Proxy referenced by config elements which prevent its runtime removal. */
@ -444,7 +442,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 */
@ -509,12 +507,6 @@ struct proxy {
* name is used * name is used
*/ */
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 { /* sequence in which declared filters on the proxy should be executed
* (list of filter_sequence_elt)
*/
struct list req; /* during request handling */
struct list res; /* during response handling */
} filter_sequence;
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) */ struct mt_list watcher_list; /* list of elems which currently references this proxy instance (currently only used with backends) */

View File

@ -24,7 +24,7 @@
struct quic_arngs { struct quic_arngs {
/* ebtree of ACK ranges organized by their first value. */ /* ebtree of ACK ranges organized by their first value. */
struct eb_root root; struct eb_root root;
/* The number of ACK ranges in this tree */ /* The number of ACK ranges is this tree */
size_t sz; size_t sz;
/* The number of bytes required to encode this ACK ranges lists. */ /* The number of bytes required to encode this ACK ranges lists. */
size_t enc_sz; size_t enc_sz;
@ -36,7 +36,7 @@ struct quic_arng {
int64_t last; int64_t last;
}; };
/* Structure to hold a range of ACKs to be stored as a node in a tree of /* Structure to hold a range of ACKs to be store as a node in a tree of
* ACK ranges. * ACK ranges.
*/ */
struct quic_arng_node { struct quic_arng_node {

View File

@ -229,7 +229,7 @@ extern const struct quic_version *quic_version_2;
/* Flag the packet number space as needing probing */ /* Flag the packet number space as needing probing */
#define QUIC_FL_PKTNS_PROBE_NEEDED (1UL << 2) #define QUIC_FL_PKTNS_PROBE_NEEDED (1UL << 2)
/* Flag the packet number space as having received a packet with a new largest /* Flag the packet number space as having received a packet with a new largest
* packet number, to be acknowledged * packet number, to be acknowledege
*/ */
#define QUIC_FL_PKTNS_NEW_LARGEST_PN (1UL << 3) #define QUIC_FL_PKTNS_NEW_LARGEST_PN (1UL << 3)

View File

@ -51,7 +51,7 @@
/* Returns enough log2 of first powers of two to encode QUIC variable length /* Returns enough log2 of first powers of two to encode QUIC variable length
* integers. * integers.
* Returns -1 if <val> is out of the range of lengths supported by QUIC. * Returns -1 if <val> if out of the range of lengths supported by QUIC.
*/ */
static inline int quic_log2(unsigned int val) static inline int quic_log2(unsigned int val)
{ {
@ -109,7 +109,7 @@ static inline uint64_t quic_max_int(size_t sz)
* Note that the result is a 64-bits integer but with the less significant * Note that the result is a 64-bits integer but with the less significant
* 62 bits as relevant information. The most significant 2 remaining bits encode * 62 bits as relevant information. The most significant 2 remaining bits encode
* the length of the integer. * the length of the integer.
* Returns 1 if succeeded (there was enough data in <buf>), 0 if not. * Returns 1 if succeeded there was enough data in <buf>), 0 if not.
*/ */
static inline int quic_dec_int(uint64_t *val, static inline int quic_dec_int(uint64_t *val,
const unsigned char **buf, const unsigned char **buf,
@ -137,7 +137,7 @@ static inline int quic_dec_int(uint64_t *val,
* the length of the integer. * the length of the integer.
* Note that this function update <b> buffer when a variable-length integer * Note that this function update <b> buffer when a variable-length integer
* has successfully been parsed. * has successfully been parsed.
* Returns 1 if succeeded (there was enough data in <buf>), 0 if not. * Returns 1 and if succeeded (there was enough data in <buf>), 0 if not.
* If <retlen> is not null, increment <*retlen> by the number of bytes consumed to decode * If <retlen> is not null, increment <*retlen> by the number of bytes consumed to decode
* the varint. * the varint.
*/ */
@ -173,7 +173,7 @@ static inline size_t b_quic_dec_int(uint64_t *val, struct buffer *b, size_t *ret
/* Encode a QUIC variable-length integer from <val> into <buf> buffer with <end> as first /* Encode a QUIC variable-length integer from <val> into <buf> buffer with <end> as first
* byte address after the end of this buffer. * byte address after the end of this buffer.
* Returns 1 if succeeded (there was enough room in <buf>), 0 if not. * Returns 1 if succeeded (there was enough room in buf), 0 if not.
*/ */
static inline int quic_enc_int(unsigned char **buf, const unsigned char *end, uint64_t val) static inline int quic_enc_int(unsigned char **buf, const unsigned char *end, uint64_t val)
{ {
@ -209,7 +209,7 @@ static inline int b_quic_enc_int(struct buffer *b, uint64_t val, int width)
char *pos; char *pos;
int save_width, len; int save_width, len;
/* width can only be 0, 1, 2, 4 or 8 */ /* width can only by 0, 1, 2, 4 or 8 */
BUG_ON(width && (width > 8 || atleast2(width))); BUG_ON(width && (width > 8 || atleast2(width)));
len = quic_int_getsize(val); len = quic_int_getsize(val);
@ -279,7 +279,7 @@ static inline size_t quic_decint_size_diff(uint64_t val)
* Returns the value usable as Length field, or 0 if <room> is too small. * Returns the value usable as Length field, or 0 if <room> is too small.
* *
* Here are examples of the output returned by the function. For each inputs * Here are examples of the output returned by the function. For each inputs
* between brackets, returned value is written associated with its implicit * between charets, returned value is written associated with its implicit
* variable-length integer size : * variable-length integer size :
* *
* [64] => 63(1) [65] => 63(1) [66] => 64(2) * [64] => 63(1) [65] => 63(1) [66] => 64(2)

Some files were not shown because too many files have changed in this diff Show More