Merge ~lucaskanashiro/ubuntu/+source/haproxy:jammy-mre into ubuntu/+source/haproxy:ubuntu/jammy-devel
- Git
- lp:~lucaskanashiro/ubuntu/+source/haproxy
- jammy-mre
- Merge into ubuntu/jammy-devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | git-ubuntu bot | ||||
Approved revision: | not available | ||||
Merge reported by: | Lucas Kanashiro | ||||
Merged at revision: | 72681649158930cfa0da398b0215df767debd077 | ||||
Proposed branch: | ~lucaskanashiro/ubuntu/+source/haproxy:jammy-mre | ||||
Merge into: | ubuntu/+source/haproxy:ubuntu/jammy-devel | ||||
Diff against target: |
7019 lines (+2604/-830) 120 files modified
.cirrus.yml (+1/-1) .github/matrix.py (+10/-7) .github/workflows/compliance.yml (+2/-2) .github/workflows/cross-zoo.yml (+110/-0) .github/workflows/vtest.yml (+5/-2) .github/workflows/windows.yml (+2/-1) CHANGELOG (+190/-0) Makefile (+7/-3) SUBVERS (+1/-1) VERDATE (+2/-2) VERSION (+1/-1) addons/promex/README (+2/-0) addons/promex/service-prometheus.c (+30/-1) addons/wurfl/dummy/wurfl/wurfl.h (+10/-5) debian/changelog (+24/-0) debian/patches/haproxy.service-start-after-syslog.patch (+0/-2) debian/patches/reproducible.patch (+1/-3) debian/patches/series (+0/-3) debian/tests/control (+8/-0) debian/tests/proxy-localhost (+4/-9) debian/tests/proxy-ssl-pass-through (+59/-0) debian/tests/proxy-ssl-termination (+48/-0) debian/tests/utils (+58/-0) dev/null (+0/-145) doc/configuration.txt (+282/-224) doc/intro.txt (+1/-1) doc/management.txt (+4/-0) doc/proxy-protocol.txt (+1/-1) include/haproxy/buf.h (+1/-1) include/haproxy/bug.h (+2/-0) include/haproxy/http.h (+2/-0) include/haproxy/listener-t.h (+11/-2) include/haproxy/listener.h (+11/-5) include/haproxy/peers-t.h (+1/-0) include/haproxy/pool.h (+2/-2) include/haproxy/server.h (+9/-5) include/haproxy/sink.h (+2/-0) include/haproxy/ssl_sock-t.h (+11/-7) include/haproxy/ssl_sock.h (+23/-0) include/haproxy/stats-t.h (+2/-0) include/haproxy/stream.h (+1/-1) include/haproxy/task.h (+2/-1) include/haproxy/tcpcheck-t.h (+1/-0) include/haproxy/tools.h (+3/-2) include/import/ebmbtree.h (+53/-0) reg-tests/cache/if-modified-since.vtc (+4/-1) reg-tests/cache/if-none-match.vtc (+4/-0) reg-tests/checks/4be_1srv_smtpchk_httpchk_layer47errors.vtc (+8/-3) reg-tests/checks/pgsql-check.vtc (+16/-0) reg-tests/checks/smtp-check.vtc (+6/-2) reg-tests/contrib/prometheus.vtc (+4/-3) reg-tests/converter/digest.vtc (+1/-1) reg-tests/converter/hmac.vtc (+1/-1) reg-tests/converter/iif.vtc (+1/-1) reg-tests/converter/json_query.vtc (+1/-1) reg-tests/http-messaging/h1_host_normalization.vtc (+276/-0) reg-tests/http-messaging/http_request_buffer.vtc (+18/-1) reg-tests/http-rules/restrict_req_hdr_names.vtc (+62/-0) reg-tests/log/log_forward.vtc (+57/-0) reg-tests/mailers/healthcheckmail.vtc (+1/-1) reg-tests/ssl/log_forward_ssl.vtc (+60/-0) reg-tests/startup/automatic_maxconn.vtc (+102/-0) reg-tests/startup/common.pem (+117/-0) scripts/announce-release (+12/-11) src/backend.c (+0/-1) src/cache.c (+17/-17) src/cfgparse-listen.c (+4/-2) src/cfgparse-ssl.c (+7/-7) src/cfgparse.c (+52/-5) src/check.c (+7/-0) src/dns.c (+1/-1) src/ev_epoll.c (+2/-2) src/ev_evports.c (+2/-4) src/ev_kqueue.c (+2/-2) src/ev_poll.c (+2/-1) src/fcgi-app.c (+1/-1) src/fcgi.c (+6/-2) src/fd.c (+3/-3) src/flt_http_comp.c (+21/-21) src/flt_spoe.c (+22/-9) src/h1.c (+92/-15) src/h1_htx.c (+3/-0) src/haproxy.c (+10/-2) src/hlua.c (+8/-3) src/hlua_fcn.c (+3/-0) src/hpack-dec.c (+10/-0) src/http.c (+32/-0) src/http_act.c (+2/-0) src/http_ana.c (+20/-14) src/http_fetch.c (+6/-5) src/http_htx.c (+14/-25) src/listener.c (+45/-16) src/log.c (+11/-5) src/mux_fcgi.c (+14/-8) src/mux_h1.c (+26/-13) src/mux_h2.c (+24/-10) src/mworker.c (+4/-2) src/pattern.c (+6/-6) src/peers.c (+41/-25) src/pool.c (+12/-12) src/proto_tcp.c (+9/-6) src/proto_udp.c (+8/-5) src/protocol.c (+3/-3) src/proxy.c (+32/-16) src/regex.c (+9/-5) src/resolvers.c (+29/-10) src/ring.c (+11/-1) src/server.c (+5/-6) src/signal.c (+3/-0) src/sink.c (+46/-15) src/ssl_crtlist.c (+5/-0) src/ssl_sample.c (+3/-0) src/ssl_sock.c (+17/-11) src/stats.c (+20/-5) src/stick_table.c (+29/-17) src/stream.c (+22/-12) src/stream_interface.c (+28/-4) src/tcpcheck.c (+37/-6) src/time.c (+1/-0) src/tools.c (+4/-3) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
git-ubuntu bot | Approve | ||
Andreas Hasenack | Approve | ||
Canonical Server Reporter | Pending | ||
Review via email: mp+439426@code.launchpad.net |
Commit message
Description of the change
MRE update to version 2.4.22 (LP: #2012557). Some patches were removed (applied by upstream) and others refreshed.
the proposed package is available in this PPA:
https:/
autopkgtest summary:
autopkgtest [18:37:20]: @@@@@@@
cli PASS
proxy-localhost PASS
Andreas Hasenack (ahasenack) wrote : | # |
Andreas Hasenack (ahasenack) : | # |
Lucas Kanashiro (lucaskanashiro) : | # |
Lucas Kanashiro (lucaskanashiro) wrote : | # |
Fixed. Up for review again.
Andreas Hasenack (ahasenack) wrote : | # |
One inline question about the version, and another question here: have you thought about pulling in the new kinetic DEP8 tests? After all, both jammy and kinetic are receiving the same haproxy upstream version after this. Considering these are MREs, I think it would be nice to have those tests here too, unless it's too involved.
- 6944eb2... by Lucas Kanashiro
-
Backport DEP-8 tests from lunar
Lucas Kanashiro (lucaskanashiro) wrote : | # |
I fixed the version string as we discussed in the other MP and backported the DEP-8 tests as you suggested, all tests passed:
autopkgtest [16:59:13]: @@@@@@@
cli PASS
proxy-localhost PASS
proxy-ssl-
proxy-ssl-
Andreas Hasenack (ahasenack) wrote : | # |
haha, gotta love version strings :)
And thanks for bringing in the DEP8 tests
+1
git-ubuntu bot (git-ubuntu-bot) wrote : | # |
Approvers: lucaskanashiro, ahasenack
Uploaders: lucaskanashiro, ahasenack
MP auto-approved
Lucas Kanashiro (lucaskanashiro) wrote : | # |
Thanks Andreas. Package uploaded:
Uploading haproxy_
Uploading haproxy_
Uploading haproxy_
Uploading haproxy_
Preview Diff
1 | diff --git a/.cirrus.yml b/.cirrus.yml | |||
2 | index e754f83..deace96 100644 | |||
3 | --- a/.cirrus.yml | |||
4 | +++ b/.cirrus.yml | |||
5 | @@ -1,7 +1,7 @@ | |||
6 | 1 | FreeBSD_task: | 1 | FreeBSD_task: |
7 | 2 | freebsd_instance: | 2 | freebsd_instance: |
8 | 3 | matrix: | 3 | matrix: |
10 | 4 | image_family: freebsd-13-0 | 4 | image_family: freebsd-13-1 |
11 | 5 | only_if: $CIRRUS_BRANCH =~ 'master|next' | 5 | only_if: $CIRRUS_BRANCH =~ 'master|next' |
12 | 6 | install_script: | 6 | install_script: |
13 | 7 | - pkg update -f && pkg upgrade -y && pkg install -y openssl git gmake lua53 socat pcre | 7 | - pkg update -f && pkg upgrade -y && pkg install -y openssl git gmake lua53 socat pcre |
14 | diff --git a/.github/matrix.py b/.github/matrix.py | |||
15 | index 264a3d2..abd6caf 100644 | |||
16 | --- a/.github/matrix.py | |||
17 | +++ b/.github/matrix.py | |||
18 | @@ -10,6 +10,7 @@ import json | |||
19 | 10 | import sys | 10 | import sys |
20 | 11 | import urllib.request | 11 | import urllib.request |
21 | 12 | import re | 12 | import re |
22 | 13 | from os import environ | ||
23 | 13 | 14 | ||
24 | 14 | if len(sys.argv) == 2: | 15 | if len(sys.argv) == 2: |
25 | 15 | build_type = sys.argv[1] | 16 | build_type = sys.argv[1] |
26 | @@ -40,7 +41,7 @@ def determine_latest_openssl(ssl): | |||
27 | 40 | if "openssl-" in name: | 41 | if "openssl-" in name: |
28 | 41 | if name > latest_tag: | 42 | if name > latest_tag: |
29 | 42 | latest_tag = name | 43 | latest_tag = name |
31 | 43 | return "OPENSSL={}".format(latest_tag[8:]) | 44 | return "OPENSSL_VERSION={}".format(latest_tag[8:]) |
32 | 44 | 45 | ||
33 | 45 | def determine_latest_libressl(ssl): | 46 | def determine_latest_libressl(ssl): |
34 | 46 | libressl_download_list = urllib.request.urlopen("http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/") | 47 | libressl_download_list = urllib.request.urlopen("http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/") |
35 | @@ -48,7 +49,7 @@ def determine_latest_libressl(ssl): | |||
36 | 48 | decoded_line = line.decode("utf-8") | 49 | decoded_line = line.decode("utf-8") |
37 | 49 | if "libressl-" in decoded_line and ".tar.gz.asc" in decoded_line: | 50 | if "libressl-" in decoded_line and ".tar.gz.asc" in decoded_line: |
38 | 50 | l = re.split("libressl-|.tar.gz.asc", decoded_line)[1] | 51 | l = re.split("libressl-|.tar.gz.asc", decoded_line)[1] |
40 | 51 | return "LIBRESSL={}".format(l) | 52 | return "LIBRESSL_VERSION={}".format(l) |
41 | 52 | 53 | ||
42 | 53 | def clean_compression(compression): | 54 | def clean_compression(compression): |
43 | 54 | return compression.replace("USE_", "").lower() | 55 | return compression.replace("USE_", "").lower() |
44 | @@ -67,7 +68,7 @@ matrix = [] | |||
45 | 67 | 68 | ||
46 | 68 | # Ubuntu | 69 | # Ubuntu |
47 | 69 | 70 | ||
49 | 70 | os = "ubuntu-latest" | 71 | os = "ubuntu-20.04" |
50 | 71 | TARGET = "linux-glibc" | 72 | TARGET = "linux-glibc" |
51 | 72 | for CC in ["gcc", "clang"]: | 73 | for CC in ["gcc", "clang"]: |
52 | 73 | matrix.append( | 74 | matrix.append( |
53 | @@ -125,8 +126,8 @@ for CC in ["gcc", "clang"]: | |||
54 | 125 | for ssl in [ | 126 | for ssl in [ |
55 | 126 | "stock", | 127 | "stock", |
56 | 127 | "OPENSSL_VERSION=1.0.2u", | 128 | "OPENSSL_VERSION=1.0.2u", |
59 | 128 | "OPENSSL_VERSION=latest", | 129 | "OPENSSL_VERSION=3.0.2", |
60 | 129 | "LIBRESSL_VERSION=latest", | 130 | "LIBRESSL_VERSION=3.5.3", |
61 | 130 | # "BORINGSSL=yes", | 131 | # "BORINGSSL=yes", |
62 | 131 | ]: | 132 | ]: |
63 | 132 | flags = ["USE_OPENSSL=1"] | 133 | flags = ["USE_OPENSSL=1"] |
64 | @@ -155,7 +156,7 @@ for CC in ["gcc", "clang"]: | |||
65 | 155 | 156 | ||
66 | 156 | # ASAN | 157 | # ASAN |
67 | 157 | 158 | ||
69 | 158 | os = "ubuntu-latest" | 159 | os = "ubuntu-20.04" |
70 | 159 | TARGET = "linux-glibc" | 160 | TARGET = "linux-glibc" |
71 | 160 | for CC in ["gcc","clang"]: | 161 | for CC in ["gcc","clang"]: |
72 | 161 | matrix.append( | 162 | matrix.append( |
73 | @@ -207,4 +208,6 @@ for CC in ["clang"]: | |||
74 | 207 | 208 | ||
75 | 208 | print(json.dumps(matrix, indent=4, sort_keys=True)) | 209 | print(json.dumps(matrix, indent=4, sort_keys=True)) |
76 | 209 | 210 | ||
78 | 210 | print("::set-output name=matrix::{}".format(json.dumps({"include": matrix}))) | 211 | if environ.get('GITHUB_OUTPUT') is not None: |
79 | 212 | with open(environ.get('GITHUB_OUTPUT'), 'a') as f: | ||
80 | 213 | print("matrix={}".format(json.dumps({"include": matrix})), file=f) | ||
81 | diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml | |||
82 | index 66bc154..a11f0fa 100644 | |||
83 | --- a/.github/workflows/compliance.yml | |||
84 | +++ b/.github/workflows/compliance.yml | |||
85 | @@ -24,7 +24,7 @@ jobs: | |||
86 | 24 | curl -fsSL https://github.com/summerwind/h2spec/releases/download/${H2SPEC_VERSION}/h2spec_linux_amd64.tar.gz -o h2spec.tar.gz | 24 | curl -fsSL https://github.com/summerwind/h2spec/releases/download/${H2SPEC_VERSION}/h2spec_linux_amd64.tar.gz -o h2spec.tar.gz |
87 | 25 | tar xvf h2spec.tar.gz | 25 | tar xvf h2spec.tar.gz |
88 | 26 | sudo install -m755 h2spec /usr/local/bin/h2spec | 26 | sudo install -m755 h2spec /usr/local/bin/h2spec |
90 | 27 | echo "::set-output name=version::${H2SPEC_VERSION}" | 27 | echo "version=${H2SPEC_VERSION}" >> $GITHUB_OUTPUT |
91 | 28 | - name: Compile HAProxy with ${{ matrix.CC }} | 28 | - name: Compile HAProxy with ${{ matrix.CC }} |
92 | 29 | run: | | 29 | run: | |
93 | 30 | make -j$(nproc) all \ | 30 | make -j$(nproc) all \ |
94 | @@ -47,7 +47,7 @@ jobs: | |||
95 | 47 | fi | 47 | fi |
96 | 48 | echo "::endgroup::" | 48 | echo "::endgroup::" |
97 | 49 | haproxy -vv | 49 | haproxy -vv |
99 | 50 | echo "::set-output name=version::$(haproxy -v |awk 'NR==1{print $3}')" | 50 | echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT |
100 | 51 | - name: Launch HAProxy ${{ steps.show-version.outputs.version }} | 51 | - name: Launch HAProxy ${{ steps.show-version.outputs.version }} |
101 | 52 | run: haproxy -f .github/h2spec.config -D | 52 | run: haproxy -f .github/h2spec.config -D |
102 | 53 | - name: Run h2spec ${{ steps.install-h2spec.outputs.version }} | 53 | - name: Run h2spec ${{ steps.install-h2spec.outputs.version }} |
103 | diff --git a/.github/workflows/cross-zoo.yml b/.github/workflows/cross-zoo.yml | |||
104 | 54 | new file mode 100644 | 54 | new file mode 100644 |
105 | index 0000000..e2a5816 | |||
106 | --- /dev/null | |||
107 | +++ b/.github/workflows/cross-zoo.yml | |||
108 | @@ -0,0 +1,110 @@ | |||
109 | 1 | # | ||
110 | 2 | # this is naamed "zoo" after OpenSSL "cross zoo pipeline" | ||
111 | 3 | # | ||
112 | 4 | name: Cross Compile | ||
113 | 5 | |||
114 | 6 | on: | ||
115 | 7 | schedule: | ||
116 | 8 | - cron: "0 0 21 * *" | ||
117 | 9 | |||
118 | 10 | permissions: | ||
119 | 11 | contents: read | ||
120 | 12 | |||
121 | 13 | jobs: | ||
122 | 14 | cross-compilation: | ||
123 | 15 | strategy: | ||
124 | 16 | matrix: | ||
125 | 17 | platform: [ | ||
126 | 18 | { | ||
127 | 19 | arch: aarch64-linux-gnu, | ||
128 | 20 | libs: libc6-dev-arm64-cross, | ||
129 | 21 | target: linux-aarch64 | ||
130 | 22 | }, { | ||
131 | 23 | arch: alpha-linux-gnu, | ||
132 | 24 | libs: libc6.1-dev-alpha-cross, | ||
133 | 25 | target: linux-alpha-gcc | ||
134 | 26 | }, { | ||
135 | 27 | arch: arm-linux-gnueabi, | ||
136 | 28 | libs: libc6-dev-armel-cross, | ||
137 | 29 | target: linux-armv4 | ||
138 | 30 | }, { | ||
139 | 31 | arch: arm-linux-gnueabihf, | ||
140 | 32 | libs: libc6-dev-armhf-cross, | ||
141 | 33 | target: linux-armv4 | ||
142 | 34 | }, { | ||
143 | 35 | arch: hppa-linux-gnu, | ||
144 | 36 | libs: libc6-dev-hppa-cross, | ||
145 | 37 | target: -static linux-generic32 | ||
146 | 38 | }, { | ||
147 | 39 | arch: m68k-linux-gnu, | ||
148 | 40 | libs: libc6-dev-m68k-cross, | ||
149 | 41 | target: -static -m68040 linux-latomic | ||
150 | 42 | }, { | ||
151 | 43 | arch: mips-linux-gnu, | ||
152 | 44 | libs: libc6-dev-mips-cross, | ||
153 | 45 | target: -static linux-mips32 | ||
154 | 46 | }, { | ||
155 | 47 | arch: mips64-linux-gnuabi64, | ||
156 | 48 | libs: libc6-dev-mips64-cross, | ||
157 | 49 | target: -static linux64-mips64 | ||
158 | 50 | }, { | ||
159 | 51 | arch: mipsel-linux-gnu, | ||
160 | 52 | libs: libc6-dev-mipsel-cross, | ||
161 | 53 | target: linux-mips32 | ||
162 | 54 | }, { | ||
163 | 55 | arch: powerpc64le-linux-gnu, | ||
164 | 56 | libs: libc6-dev-ppc64el-cross, | ||
165 | 57 | target: linux-ppc64le | ||
166 | 58 | }, { | ||
167 | 59 | arch: riscv64-linux-gnu, | ||
168 | 60 | libs: libc6-dev-riscv64-cross, | ||
169 | 61 | target: linux64-riscv64 | ||
170 | 62 | }, { | ||
171 | 63 | arch: s390x-linux-gnu, | ||
172 | 64 | libs: libc6-dev-s390x-cross, | ||
173 | 65 | target: linux64-s390x | ||
174 | 66 | }, { | ||
175 | 67 | arch: sh4-linux-gnu, | ||
176 | 68 | libs: libc6-dev-sh4-cross, | ||
177 | 69 | target: no-async linux-latomic | ||
178 | 70 | }, { | ||
179 | 71 | arch: hppa-linux-gnu, | ||
180 | 72 | libs: libc6-dev-hppa-cross, | ||
181 | 73 | target: linux-generic32, | ||
182 | 74 | }, { | ||
183 | 75 | arch: m68k-linux-gnu, | ||
184 | 76 | libs: libc6-dev-m68k-cross, | ||
185 | 77 | target: -mcfv4e linux-latomic | ||
186 | 78 | }, { | ||
187 | 79 | arch: mips-linux-gnu, | ||
188 | 80 | libs: libc6-dev-mips-cross, | ||
189 | 81 | target: linux-mips32 | ||
190 | 82 | }, { | ||
191 | 83 | arch: mips64-linux-gnuabi64, | ||
192 | 84 | libs: libc6-dev-mips64-cross, | ||
193 | 85 | target: linux64-mips64 | ||
194 | 86 | }, { | ||
195 | 87 | arch: sparc64-linux-gnu, | ||
196 | 88 | libs: libc6-dev-sparc64-cross, | ||
197 | 89 | target: linux64-sparcv9 | ||
198 | 90 | } | ||
199 | 91 | ] | ||
200 | 92 | runs-on: ubuntu-latest | ||
201 | 93 | steps: | ||
202 | 94 | - name: install packages | ||
203 | 95 | run: | | ||
204 | 96 | sudo apt-get update | ||
205 | 97 | sudo apt-get -yq --force-yes install \ | ||
206 | 98 | gcc-${{ matrix.platform.arch }} \ | ||
207 | 99 | ${{ matrix.platform.libs }} | ||
208 | 100 | - uses: actions/checkout@v2 | ||
209 | 101 | |||
210 | 102 | |||
211 | 103 | - name: install quictls | ||
212 | 104 | run: | | ||
213 | 105 | QUICTLS_EXTRA_ARGS="--cross-compile-prefix=${{ matrix.platform.arch }}- ${{ matrix.platform.target }}" QUICTLS=yes scripts/build-ssl.sh | ||
214 | 106 | |||
215 | 107 | - name: Build | ||
216 | 108 | run: | | ||
217 | 109 | make ERR=1 CC=${{ matrix.platform.arch }}-gcc TARGET=linux-glibc USE_LIBCRYPT= USE_OPENSSL=1 USE_QUIC=1 USE_PROMEX=1 SSL_LIB=${HOME}/opt/lib SSL_INC=${HOME}/opt/include ADDLIB="-Wl,-rpath,${HOME}/opt/lib" | ||
218 | 110 | |||
219 | diff --git a/.github/workflows/vtest.yml b/.github/workflows/vtest.yml | |||
220 | index ea39662..781a2b3 100644 | |||
221 | --- a/.github/workflows/vtest.yml | |||
222 | +++ b/.github/workflows/vtest.yml | |||
223 | @@ -50,7 +50,7 @@ jobs: | |||
224 | 50 | - name: Generate cache key | 50 | - name: Generate cache key |
225 | 51 | id: generate-cache-key | 51 | id: generate-cache-key |
226 | 52 | run: | | 52 | run: | |
228 | 53 | echo "::set-output name=key::$(echo ${{ matrix.name }} | sha256sum | awk '{print $1}')" | 53 | echo "key=$(echo ${{ matrix.name }} | sha256sum | awk '{print $1}')" >> $GITHUB_OUTPUT |
229 | 54 | 54 | ||
230 | 55 | - name: Cache SSL libs | 55 | - name: Cache SSL libs |
231 | 56 | if: ${{ matrix.ssl && matrix.ssl != 'stock' && matrix.ssl != 'BORINGSSL=yes' && matrix.ssl != 'QUICTLS=yes' }} | 56 | if: ${{ matrix.ssl && matrix.ssl != 'stock' && matrix.ssl != 'BORINGSSL=yes' && matrix.ssl != 'QUICTLS=yes' }} |
232 | @@ -114,6 +114,9 @@ jobs: | |||
233 | 114 | run: make -C addons/wurfl/dummy | 114 | run: make -C addons/wurfl/dummy |
234 | 115 | - name: Compile HAProxy with ${{ matrix.CC }} | 115 | - name: Compile HAProxy with ${{ matrix.CC }} |
235 | 116 | run: | | 116 | run: | |
236 | 117 | echo "::group::Show compiler's version" | ||
237 | 118 | echo | ${{ matrix.CC }} -v | ||
238 | 119 | echo "::endgroup::" | ||
239 | 117 | echo "::group::Show platform specific defines" | 120 | echo "::group::Show platform specific defines" |
240 | 118 | echo | ${{ matrix.CC }} -dM -xc -E - | 121 | echo | ${{ matrix.CC }} -dM -xc -E - |
241 | 119 | echo "::endgroup::" | 122 | echo "::endgroup::" |
242 | @@ -138,7 +141,7 @@ jobs: | |||
243 | 138 | fi | 141 | fi |
244 | 139 | echo "::endgroup::" | 142 | echo "::endgroup::" |
245 | 140 | haproxy -vv | 143 | haproxy -vv |
247 | 141 | echo "::set-output name=version::$(haproxy -v |awk 'NR==1{print $3}')" | 144 | echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT |
248 | 142 | - name: Install problem matcher for VTest | 145 | - name: Install problem matcher for VTest |
249 | 143 | # This allows one to more easily see which tests fail. | 146 | # This allows one to more easily see which tests fail. |
250 | 144 | run: echo "::add-matcher::.github/vtest.json" | 147 | run: echo "::add-matcher::.github/vtest.json" |
251 | diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml | |||
252 | index 58283ff..022c7f6 100644 | |||
253 | --- a/.github/workflows/windows.yml | |||
254 | +++ b/.github/workflows/windows.yml | |||
255 | @@ -56,9 +56,10 @@ jobs: | |||
256 | 56 | TARGET=${{ matrix.TARGET }} \ | 56 | TARGET=${{ matrix.TARGET }} \ |
257 | 57 | CC=${{ matrix.CC }} \ | 57 | CC=${{ matrix.CC }} \ |
258 | 58 | DEBUG="-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS -DDEBUG_POOL_INTEGRITY" \ | 58 | DEBUG="-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS -DDEBUG_POOL_INTEGRITY" \ |
259 | 59 | DEBUG_CFLAGS="-g -Wno-deprecated-declarations" \ | ||
260 | 59 | ${{ join(matrix.FLAGS, ' ') }} | 60 | ${{ join(matrix.FLAGS, ' ') }} |
261 | 60 | - name: Show HAProxy version | 61 | - name: Show HAProxy version |
262 | 61 | id: show-version | 62 | id: show-version |
263 | 62 | run: | | 63 | run: | |
264 | 63 | ./haproxy -vv | 64 | ./haproxy -vv |
266 | 64 | echo "::set-output name=version::$(./haproxy -v |awk 'NR==1{print $3}')" | 65 | echo "version=$(./haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT |
267 | diff --git a/CHANGELOG b/CHANGELOG | |||
268 | index f9eec74..d59309f 100644 | |||
269 | --- a/CHANGELOG | |||
270 | +++ b/CHANGELOG | |||
271 | @@ -1,6 +1,196 @@ | |||
272 | 1 | ChangeLog : | 1 | ChangeLog : |
273 | 2 | =========== | 2 | =========== |
274 | 3 | 3 | ||
275 | 4 | 2023/02/14 : 2.4.22 | ||
276 | 5 | - BUG/MINOR: fcgi-app: prevent 'use-fcgi-app' in default section | ||
277 | 6 | - BUG/MEDIUM: ssl: wrong eviction from the session cache tree | ||
278 | 7 | - BUG/MINOR: ssl/crt-list: warn when a line is malformated | ||
279 | 8 | - BUG/MEDIUM: stick-table: do not leave entries in end of window during purge | ||
280 | 9 | - BUG/MEDIUM: cache: use the correct time reference when comparing dates | ||
281 | 10 | - DOC: config: fix option spop-check proxy compatibility | ||
282 | 11 | - DOC: config: 'http-send-name-header' option may be used in default section | ||
283 | 12 | - DOC: proxy-protocol: fix wrong byte in provided example | ||
284 | 13 | - BUG/MEDIUM: stconn: Schedule a shutw on shutr if data must be sent first | ||
285 | 14 | - CI: github: don't warn on deprecated openssl functions on windows | ||
286 | 15 | - BUG/CRITICAL: http: properly reject empty http header field names | ||
287 | 16 | |||
288 | 17 | 2023/01/27 : 2.4.21 | ||
289 | 18 | - BUG/MINOR: http-htx: Don't consider an URI as normalized after a set-uri action | ||
290 | 19 | - BUG/MEDIIM: stconn: Flush output data before forwarding close to write side | ||
291 | 20 | - CI: github: change "ubuntu-latest" to "ubuntu-20.04" | ||
292 | 21 | - BUILD: peers: peers-t.h depends on stick-table-t.h | ||
293 | 22 | - BUG/MINOR: resolvers: Don't wait periodic resolution on healthcheck failure | ||
294 | 23 | - BUG/MEDIUM: ssl: Verify error codes can exceed 63 | ||
295 | 24 | - BUG/MINOR: ssl: Fix potential overflow | ||
296 | 25 | - BUG/MEDIUM: mworker: fix segv in early failure of mworker mode with peers | ||
297 | 26 | - BUG/MINOR: promex: create haproxy_backend_agg_server_status | ||
298 | 27 | - MINOR: promex: introduce haproxy_backend_agg_check_status | ||
299 | 28 | - DOC: promex: Add missing backend metrics | ||
300 | 29 | - BUG/MAJOR: fcgi: Fix uninitialized reserved bytes | ||
301 | 30 | - REGTESTS: fix the race conditions in iff.vtc | ||
302 | 31 | - REGTESTS: startup: check maxconn computation | ||
303 | 32 | - BUG/MEDIUM: resolvers: Use tick_first() to update the resolvers task timeout | ||
304 | 33 | - LICENSE: wurfl: clarify the dummy library license. | ||
305 | 34 | - BUG/MINOR: ssl: Fix memory leak of find_chain in ssl_sock_load_cert_chain | ||
306 | 35 | - BUG/MEDIUM: mux-h2: Refuse interim responses with end-stream flag set | ||
307 | 36 | - BUG/MINOR: pool/stats: Use ullong to report total pool usage in bytes in stats | ||
308 | 37 | - BUILD: makefile: build the features list dynamically | ||
309 | 38 | - BUILD: makefile: sort the features list | ||
310 | 39 | - BUG/MINOR: http-fetch: Only fill txn status during prefetch if not already set | ||
311 | 40 | - BUG/MAJOR: buf: Fix copy of wrapping output data when a buffer is realigned | ||
312 | 41 | - REGTEST: fix the race conditions in json_query.vtc | ||
313 | 42 | - REGTEST: fix the race conditions in digest.vtc | ||
314 | 43 | - REGTEST: fix the race conditions in hmac.vtc | ||
315 | 44 | - BUG/MINOR: http: Memory leak of http redirect rules' format string | ||
316 | 45 | - CLEANUP: htx: fix a typo in an error message of http_str_to_htx | ||
317 | 46 | - BUG/MINOR: h1-htx: Remove flags about protocol upgrade on non-101 responses | ||
318 | 47 | - BUG/MINOR: resolvers: Wait the resolution execution for a do_resolv action | ||
319 | 48 | - BUG/MINOR: promex: Don't forget to consume the request on error | ||
320 | 49 | - BUG/MINOR: http-ana: Report SF_FINST_R flag on error waiting the request body | ||
321 | 50 | - BUG/MINOR: http-fetch: Don't block HTTP sample fetch eval in HTTP_MSG_ERROR state | ||
322 | 51 | - BUG/MINOR: http-ana: make set-status also update txn->status | ||
323 | 52 | - BUG/MINOR: listeners: fix suspend/resume of inherited FDs | ||
324 | 53 | - DOC: config: fix wrong section number for "protocol prefixes" | ||
325 | 54 | - DOC: config: fix aliases for protocol prefixes "udp4@" and "udp6@" | ||
326 | 55 | - BUG/MINOR: mux-fcgi: Correctly set pathinfo | ||
327 | 56 | - DOC: config: fix "Address formats" chapter syntax | ||
328 | 57 | - BUG/MINOR: listener: close tiny race between resume_listener() and stopping | ||
329 | 58 | - BUG/MINOR: mux-h2: add missing traces on failed headers decoding | ||
330 | 59 | - BUILD: hpack: include global.h for the trash that is needed in debug mode | ||
331 | 60 | - BUG/MINOR: sink: free the forwarding task on exit | ||
332 | 61 | |||
333 | 62 | 2022/12/09 : 2.4.20 | ||
334 | 63 | - BUG/MINOR: checks: update pgsql regex on auth packet | ||
335 | 64 | - DOC: config: Fix pgsql-check documentation to make user param mandatory | ||
336 | 65 | - BUG/MEDIUM: lua: Don't crash in hlua_lua2arg_check on failure | ||
337 | 66 | - BUG/MEDIUM: lua: handle stick table implicit arguments right. | ||
338 | 67 | - BUILD: h1: silence an initiialized warning with gcc-4.7 and -Os | ||
339 | 68 | - BUG/MINOR: http-fetch: Update method after a prefetch in smp_fetch_meth() | ||
340 | 69 | - BUILD: http_fetch: silence an uninitiialized warning with gcc-4/5/6 at -Os | ||
341 | 70 | - BUG/MINOR: mux-h1: Account consumed output data on synchronous connection error | ||
342 | 71 | - MINOR: smtpchk: Update expect rule to fully match replies to EHLO commands | ||
343 | 72 | - BUG/MINOR: smtpchk: SMTP Service check should gracefully close SMTP transaction | ||
344 | 73 | - BUG/MINOR: backend: only enforce turn-around state when not redispatching | ||
345 | 74 | - DOC: configuration: missing 'if' in tcp-request content example | ||
346 | 75 | - BUG/MAJOR: stick-tables: do not try to index a server name for applets | ||
347 | 76 | - BUG/MINOR: server: make sure "show servers state" hides private bits | ||
348 | 77 | - CI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in matrix.py | ||
349 | 78 | - CI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in workflow definition | ||
350 | 79 | - BUG/MINOR: log: Preserve message facility when the log target is a ring buffer | ||
351 | 80 | - BUG/MINOR: ring: Properly parse connect timeout | ||
352 | 81 | - BUG/MEDIUM: compression: handle rewrite errors when updating response headers | ||
353 | 82 | - BUG/MINOR: sink: Only use backend capability for the sink proxies | ||
354 | 83 | - BUG/MINOR: sink: Set default connect/server timeout for implicit ring buffers | ||
355 | 84 | - CI: SSL: use proper version generating when "latest" semantic is used | ||
356 | 85 | - CI: SSL: temporarily stick to LibreSSL=3.5.3 | ||
357 | 86 | - BUG/MINOR: stick-table: Use server_id instead of std_t_sint in process_store_rules() | ||
358 | 87 | - DOC: management: add forgotten "show startup-logs" | ||
359 | 88 | - BUG/MAJOR: stick-table: don't process store-response rules for applets | ||
360 | 89 | - BUG/MEDIUM: stick-table: fix a race condition when updating the expiration task | ||
361 | 90 | - BUG/MINOR: log: fixing bug in tcp syslog_io_handler Octet-Counting | ||
362 | 91 | - CI: add monthly gcc cross compile jobs | ||
363 | 92 | - BUG/MINOR: ssl: Memory leak of AUTHORITY_KEYID struct when loading issuer | ||
364 | 93 | - BUG/MINOR: ssl: ocsp structure not freed properly in case of error | ||
365 | 94 | - CI: switch to the "latest" LibreSSL | ||
366 | 95 | - CI: emit the compiler's version in the build reports | ||
367 | 96 | - BUG/MEDIUM: wdt/clock: properly handle early task hangs | ||
368 | 97 | - BUG/MINOR: http-htx: Fix error handling during parsing http replies | ||
369 | 98 | - BUG/MINOR: resolvers: Set port before IP address when processing SRV records | ||
370 | 99 | - BUG/MINOR: mux-fcgi: Be sure to send empty STDING record in case of zero-copy | ||
371 | 100 | - BUG/MEDIUM: mux-fcgi: Avoid value length overflow when it doesn't fit at once | ||
372 | 101 | - BUG/MINOR: mux-h1: Do not send a last null chunk on body-less answers | ||
373 | 102 | - REG-TESTS: cache: Remove T-E header for 304-Not-Modified responses | ||
374 | 103 | - DOC: config: fix alphabetical ordering of global section | ||
375 | 104 | - BUG/MEDIUM: ring: fix creation of server in uninitialized ring | ||
376 | 105 | - BUG/MINOR: pool/cli: use ullong to report total pool usage in bytes | ||
377 | 106 | - BUG/MEDIUM: listener: Fix race condition when updating the global mngmt task | ||
378 | 107 | - BUG/MINOR: http_ana/txn: don't re-initialize txn and req var lists | ||
379 | 108 | - BUG/MINOR: ssl: don't initialize the keylog callback when not required | ||
380 | 109 | - BUG/MEDIUM: peers: messages about unkown tables not correctly ignored | ||
381 | 110 | - BUILD: peers: Remove unused variables | ||
382 | 111 | - BUG/MINOR: server/idle: at least use atomic stores when updating max_used_conns | ||
383 | 112 | - BUILD: listener: fix build warning on global_listener_rwlock without threads | ||
384 | 113 | - BUG/MINOR: cfgparse-listen: fix ebpt_next_dup pointer dereference on proxy "from" inheritance | ||
385 | 114 | - BUG/MINOR: log: fix parse_log_message rfc5424 size check | ||
386 | 115 | - BUG/MINOR: http-htx: Don't consider an URI as normalized after a set-uri action | ||
387 | 116 | - BUILD: http-htx: Silent build error about a possible NULL start-line | ||
388 | 117 | - BUG/MINOR: mux-h1: Fix handling of 408-Request-Time-Out | ||
389 | 118 | - Revert "BUG/MINOR: http-htx: Don't consider an URI as normalized after a set-uri action" | ||
390 | 119 | - DOC: config: provide some configuration hints for "http-reuse" | ||
391 | 120 | - DOC: config: clarify the fact that SNI should not be used in HTTP scenarios | ||
392 | 121 | - DOC: config: mention that a single monitor-uri rule is supported | ||
393 | 122 | - DOC: config: explain how default matching method for ACL works | ||
394 | 123 | - DOC: config: clarify the fact that "retries" is not just for connections | ||
395 | 124 | - DOC: config: clarify the -m dir and -m dom pattern matching methods | ||
396 | 125 | - SCRIPTS: announce-release: add a link to the data plane API | ||
397 | 126 | - Revert "CI: switch to the "latest" LibreSSL" | ||
398 | 127 | - Revert "CI: determine actual OpenSSL version dynamically" | ||
399 | 128 | |||
400 | 129 | 2022/09/28 : 2.4.19 | ||
401 | 130 | - BUG/MEDIUM: mworker: use default maxconn in wait mode | ||
402 | 131 | - MINOR: http: Add function to get port part of a host | ||
403 | 132 | - MINOR: http: Add function to detect default port | ||
404 | 133 | - BUG/MEDIUM: h1: Improve authority validation for CONNCET request | ||
405 | 134 | - MINOR: http-htx: Use new HTTP functions for the scheme based normalization | ||
406 | 135 | - MINOR: ebtree: add ebmb_lookup_shorter() to pursue lookups | ||
407 | 136 | - BUG/MEDIUM: pattern: only visit equivalent nodes when skipping versions | ||
408 | 137 | - MINOR: peers: Use a dedicated reconnect timeout when stopping the local peer | ||
409 | 138 | - BUG/MEDIUM: peers: limit reconnect attempts of the old process on reload | ||
410 | 139 | - BUG/MINOR: peers: Use right channel flag to consider the peer as connected | ||
411 | 140 | - BUG/MEDIUM: dns: Properly initialize new DNS session | ||
412 | 141 | - MINOR: server: Constify source server to copy its settings | ||
413 | 142 | - REORG: server: Export srv_settings_cpy() function | ||
414 | 143 | - BUG/MEDIUM: proxy: Perform a custom copy for default server settings | ||
415 | 144 | - BUG/MINOR: ring/cli: fix a race condition between the writer and the reader | ||
416 | 145 | - BUG/MINOR: sink: fix a race condition between the writer and the reader | ||
417 | 146 | - BUILD: cfgparse: always defined _GNU_SOURCE for sched.h and crypt.h | ||
418 | 147 | - BUG/MEDIUM: poller: use fd_delete() to release the poller pipes | ||
419 | 148 | - BUG/MEDIUM: task: relax one thread consistency check in task_unlink_wq() | ||
420 | 149 | - BUILD: debug: silence warning on gcc-5 | ||
421 | 150 | - BUG/MEDIUM: ring: fix too lax 'size' parser | ||
422 | 151 | - BUILD: http: silence an uninitialized warning affecting gcc-5 | ||
423 | 152 | - BUG/MEDIUM: http-ana: fix crash or wrong header deletion by http-restrict-req-hdr-names | ||
424 | 153 | - BUG/MEDIUM: mux-h2: do not fiddle with ->dsi to indicate demux is idle | ||
425 | 154 | - BUG/MAJOR: log-forward: Fix log-forward proxies not fully initialized | ||
426 | 155 | - BUG/MAJOR: mworker: fix infinite loop on master with no proxies. | ||
427 | 156 | - BUG/MINOR: resolvers: return the correct value in resolvers_finalize_config() | ||
428 | 157 | - BUG/MINOR: tcpcheck: Disable QUICKACK only if data should be sent after connect | ||
429 | 158 | - REGTESTS: Fix prometheus script to perform HTTP health-checks | ||
430 | 159 | - DOC: configuration: do-resolve doesn't work with a port in the string | ||
431 | 160 | - BUG/MEDIUM: spoe: Properly update streams waiting for a ACK in async mode | ||
432 | 161 | - BUG/MEDIUM: peers: Add connect and server timeut to peers proxy | ||
433 | 162 | - BUG/MEDIUM: peers: Don't use resync timer when local resync is in progress | ||
434 | 163 | - BUG/MEDIUM: peers: Don't start resync on reload if local peer is not up-to-date | ||
435 | 164 | - BUG/MINOR: hlua: Rely on CF_EOI to detect end of message in HTTP applets | ||
436 | 165 | - BUG/MINOR: tcpcheck: Disable QUICKACK for default tcp-check (with no rule) | ||
437 | 166 | - BUG/MEDIUM: mux-h1: do not refrain from signaling errors after end of input | ||
438 | 167 | - REGTESTS: http_request_buffer: Add a barrier to not mix up log messages | ||
439 | 168 | - BUG/MEDIUM: mux-h1: always use RST to kill idle connections in pools | ||
440 | 169 | - BUG/MINOR: mux-h2: fix the "show fd" dest buffer for the subscriber | ||
441 | 170 | - BUG/MINOR: mux-h1: fix the "show fd" dest buffer for the subscriber | ||
442 | 171 | - BUG/MINOR: mux-fcgi: fix the "show fd" dest buffer for the subscriber | ||
443 | 172 | - BUG/MINOR: regex: Properly handle PCRE2 lib compiled without JIT support | ||
444 | 173 | - BUILD: makefile: enable crypt(3) for NetBSD | ||
445 | 174 | - BUG/MINOR: h1: Support headers case adjustment for TCP proxies | ||
446 | 175 | - BUG/MINOR: task: always reset a new tasklet's call date | ||
447 | 176 | - BUG/MINOR: signals/poller: set the poller timeout to 0 when there are signals | ||
448 | 177 | - BUG/MINOR: signals/poller: ensure wakeup from signals | ||
449 | 178 | - CI: cirrus-ci: bump FreeBSD image to 13-1 | ||
450 | 179 | - BUG/MEDIUM: proxy: ensure pause_proxy() and resume_proxy() own PROXY_LOCK | ||
451 | 180 | - MINOR: listener: small API change | ||
452 | 181 | - BUG/MINOR: stats: fixing stat shows disabled frontend status as 'OPEN' | ||
453 | 182 | - REGTESTS: healthcheckmail: Relax matching on the healthcheck log message | ||
454 | 183 | - REGTESTS: log: test the log-forward feature | ||
455 | 184 | - BUG/MEDIUM: sink: bad init sequence on tcp sink from a ring. | ||
456 | 185 | - REGTESTS: ssl/log: test the log-forward with SSL | ||
457 | 186 | - DOC: fix TOC in starter guide for subsection 3.3.8. Statistics | ||
458 | 187 | - BUG/MEDIUM: captures: free() an error capture out of the proxy lock | ||
459 | 188 | - BUILD: fd: fix a build warning on the DWCAS | ||
460 | 189 | - SCRIPTS: announce-release: update some URLs to https | ||
461 | 190 | - BUG/MINOR: log: improper behavior when escaping log data | ||
462 | 191 | - REGTESTS: 4be_1srv_smtpchk_httpchk_layer47errors: Return valid SMTP replies | ||
463 | 192 | - BUG/MEDIUM: resolvers: Remove aborted resolutions from query_ids tree | ||
464 | 193 | |||
465 | 4 | 2022/07/27 : 2.4.18 | 194 | 2022/07/27 : 2.4.18 |
466 | 5 | - CI: determine actual LibreSSL version dynamically | 195 | - CI: determine actual LibreSSL version dynamically |
467 | 6 | - MEDIUM: http-ana: Add a proxy option to restrict chars in request header names | 196 | - MEDIUM: http-ana: Add a proxy option to restrict chars in request header names |
468 | diff --git a/Makefile b/Makefile | |||
469 | index c0a6a27..40c2b10 100644 | |||
470 | --- a/Makefile | |||
471 | +++ b/Makefile | |||
472 | @@ -423,8 +423,8 @@ endif | |||
473 | 423 | # NetBSD 8 and above | 423 | # NetBSD 8 and above |
474 | 424 | ifeq ($(TARGET),netbsd) | 424 | ifeq ($(TARGET),netbsd) |
475 | 425 | set_target_defaults = $(call default_opts, \ | 425 | set_target_defaults = $(call default_opts, \ |
478 | 426 | USE_POLL USE_TPROXY USE_THREAD USE_KQUEUE USE_ACCEPT4 USE_CLOSEFROM \ | 426 | USE_POLL USE_TPROXY USE_LIBCRYPT USE_THREAD USE_KQUEUE USE_ACCEPT4 \ |
479 | 427 | USE_GETADDRINFO) | 427 | USE_CLOSEFROM USE_GETADDRINFO) |
480 | 428 | endif | 428 | endif |
481 | 429 | 429 | ||
482 | 430 | # AIX 5.1 only | 430 | # AIX 5.1 only |
483 | @@ -524,7 +524,11 @@ ignore_implicit = $(if $(subst environment,,$(origin $(1))), \ | |||
484 | 524 | # is used to report a list of all flags which were used to build this version. | 524 | # is used to report a list of all flags which were used to build this version. |
485 | 525 | # Do not assign anything to it. | 525 | # Do not assign anything to it. |
486 | 526 | BUILD_OPTIONS := $(foreach opt,$(use_opts),$(call ignore_implicit,$(opt))) | 526 | BUILD_OPTIONS := $(foreach opt,$(use_opts),$(call ignore_implicit,$(opt))) |
488 | 527 | BUILD_FEATURES := $(foreach opt,$(patsubst USE_%,%,$(use_opts)),$(if $(USE_$(opt)),+$(opt),-$(opt))) | 527 | |
489 | 528 | # Make a list of all known features with +/- prepended depending on their | ||
490 | 529 | # activation status. Must be a macro so that dynamically enabled ones are | ||
491 | 530 | # evaluated with their current status. | ||
492 | 531 | BUILD_FEATURES = $(foreach opt,$(patsubst USE_%,%,$(sort $(use_opts))),$(if $(USE_$(opt)),+$(opt),-$(opt))) | ||
493 | 528 | 532 | ||
494 | 529 | # All USE_* options have their equivalent macro defined in the code (some might | 533 | # All USE_* options have their equivalent macro defined in the code (some might |
495 | 530 | # possibly be unused though) | 534 | # possibly be unused though) |
496 | diff --git a/SUBVERS b/SUBVERS | |||
497 | index 994ee02..f042fd0 100644 | |||
498 | --- a/SUBVERS | |||
499 | +++ b/SUBVERS | |||
500 | @@ -1,2 +1,2 @@ | |||
502 | 1 | -1d80f18 | 1 | -f8e3218 |
503 | 2 | 2 | ||
504 | diff --git a/VERDATE b/VERDATE | |||
505 | index 6a4d254..d8a3372 100644 | |||
506 | --- a/VERDATE | |||
507 | +++ b/VERDATE | |||
508 | @@ -1,2 +1,2 @@ | |||
511 | 1 | 2022-07-27 15:10:44 +0200 | 1 | 2023-02-14 16:57:13 +0100 |
512 | 2 | 2022/07/27 | 2 | 2023/02/14 |
513 | diff --git a/VERSION b/VERSION | |||
514 | index cc2ff5a..76cb51e 100644 | |||
515 | --- a/VERSION | |||
516 | +++ b/VERSION | |||
517 | @@ -1 +1 @@ | |||
519 | 1 | 2.4.18 | 1 | 2.4.22 |
520 | diff --git a/addons/promex/README b/addons/promex/README | |||
521 | index e41ebdc..4e29e23 100644 | |||
522 | --- a/addons/promex/README | |||
523 | +++ b/addons/promex/README | |||
524 | @@ -286,6 +286,8 @@ See prometheus export for the description of each field. | |||
525 | 286 | | haproxy_backend_max_total_time_seconds | | 286 | | haproxy_backend_max_total_time_seconds | |
526 | 287 | | haproxy_backend_internal_errors_total | | 287 | | haproxy_backend_internal_errors_total | |
527 | 288 | | haproxy_backend_uweight | | 288 | | haproxy_backend_uweight | |
528 | 289 | | haproxy_backend_agg_server_status | | ||
529 | 290 | | haproxy_backend_agg_check_status | | ||
530 | 289 | +-----------------------------------------------------+ | 291 | +-----------------------------------------------------+ |
531 | 290 | 292 | ||
532 | 291 | * Server metrics | 293 | * Server metrics |
533 | diff --git a/addons/promex/service-prometheus.c b/addons/promex/service-prometheus.c | |||
534 | index b267f98..d31b666 100644 | |||
535 | --- a/addons/promex/service-prometheus.c | |||
536 | +++ b/addons/promex/service-prometheus.c | |||
537 | @@ -289,6 +289,8 @@ const struct promex_metric promex_st_metrics[ST_F_TOTAL_FIELDS] = { | |||
538 | 289 | [ST_F_NEED_CONN_EST] = { .n = IST("need_connections_current"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, | 289 | [ST_F_NEED_CONN_EST] = { .n = IST("need_connections_current"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, |
539 | 290 | [ST_F_UWEIGHT] = { .n = IST("uweight"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, | 290 | [ST_F_UWEIGHT] = { .n = IST("uweight"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, |
540 | 291 | [ST_F_AGG_SRV_CHECK_STATUS] = { .n = IST("agg_server_check_status"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, | 291 | [ST_F_AGG_SRV_CHECK_STATUS] = { .n = IST("agg_server_check_status"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, |
541 | 292 | [ST_F_AGG_SRV_STATUS ] = { .n = IST("agg_server_status"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, | ||
542 | 293 | [ST_F_AGG_CHECK_STATUS] = { .n = IST("agg_check_status"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, | ||
543 | 292 | }; | 294 | }; |
544 | 293 | 295 | ||
545 | 294 | /* Description of overridden stats fields */ | 296 | /* Description of overridden stats fields */ |
546 | @@ -792,6 +794,7 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx) | |||
547 | 792 | double secs; | 794 | double secs; |
548 | 793 | enum promex_back_state bkd_state; | 795 | enum promex_back_state bkd_state; |
549 | 794 | enum promex_srv_state srv_state; | 796 | enum promex_srv_state srv_state; |
550 | 797 | enum healthcheck_status srv_check_status; | ||
551 | 795 | 798 | ||
552 | 796 | for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) { | 799 | for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) { |
553 | 797 | if (!(promex_st_metrics[appctx->st2].flags & appctx->ctx.stats.flags)) | 800 | if (!(promex_st_metrics[appctx->st2].flags & appctx->ctx.stats.flags)) |
554 | @@ -800,6 +803,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx) | |||
555 | 800 | while (appctx->ctx.stats.obj1) { | 803 | while (appctx->ctx.stats.obj1) { |
556 | 801 | struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; | 804 | struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; |
557 | 802 | unsigned int srv_state_count[PROMEX_SRV_STATE_COUNT] = { 0 }; | 805 | unsigned int srv_state_count[PROMEX_SRV_STATE_COUNT] = { 0 }; |
558 | 806 | unsigned int srv_check_count[HCHK_STATUS_SIZE] = { 0 }; | ||
559 | 807 | const char *check_state; | ||
560 | 803 | 808 | ||
561 | 804 | px = appctx->ctx.stats.obj1; | 809 | px = appctx->ctx.stats.obj1; |
562 | 805 | 810 | ||
563 | @@ -814,7 +819,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx) | |||
564 | 814 | return -1; | 819 | return -1; |
565 | 815 | 820 | ||
566 | 816 | switch (appctx->st2) { | 821 | switch (appctx->st2) { |
568 | 817 | case ST_F_AGG_SRV_CHECK_STATUS: | 822 | case ST_F_AGG_SRV_CHECK_STATUS: // DEPRECATED |
569 | 823 | case ST_F_AGG_SRV_STATUS: | ||
570 | 818 | if (!px->srv) | 824 | if (!px->srv) |
571 | 819 | goto next_px; | 825 | goto next_px; |
572 | 820 | sv = px->srv; | 826 | sv = px->srv; |
573 | @@ -833,6 +839,28 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx) | |||
574 | 833 | } | 839 | } |
575 | 834 | appctx->ctx.stats.st_code = 0; | 840 | appctx->ctx.stats.st_code = 0; |
576 | 835 | goto next_px; | 841 | goto next_px; |
577 | 842 | case ST_F_AGG_CHECK_STATUS: | ||
578 | 843 | if (!px->srv) | ||
579 | 844 | goto next_px; | ||
580 | 845 | sv = px->srv; | ||
581 | 846 | while (sv) { | ||
582 | 847 | srv_check_status = sv->check.status; | ||
583 | 848 | srv_check_count[srv_check_status] += 1; | ||
584 | 849 | sv = sv->next; | ||
585 | 850 | } | ||
586 | 851 | for (; appctx->ctx.stats.st_code < HCHK_STATUS_SIZE; appctx->ctx.stats.st_code++) { | ||
587 | 852 | if (get_check_status_result(appctx->ctx.stats.st_code) < CHK_RES_FAILED) | ||
588 | 853 | continue; | ||
589 | 854 | val = mkf_u32(FO_STATUS, srv_check_count[appctx->ctx.stats.st_code]); | ||
590 | 855 | check_state = get_check_status_info(appctx->ctx.stats.st_code); | ||
591 | 856 | labels[1].name = ist("state"); | ||
592 | 857 | labels[1].value = ist(check_state); | ||
593 | 858 | if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2], | ||
594 | 859 | &val, labels, &out, max)) | ||
595 | 860 | goto full; | ||
596 | 861 | } | ||
597 | 862 | appctx->ctx.stats.st_code = 0; | ||
598 | 863 | goto next_px; | ||
599 | 836 | case ST_F_STATUS: | 864 | case ST_F_STATUS: |
600 | 837 | bkd_state = ((px->lbprm.tot_weight > 0 || !px->srv) ? 1 : 0); | 865 | bkd_state = ((px->lbprm.tot_weight > 0 || !px->srv) ? 1 : 0); |
601 | 838 | for (; appctx->ctx.stats.st_code < PROMEX_BACK_STATE_COUNT; appctx->ctx.stats.st_code++) { | 866 | for (; appctx->ctx.stats.st_code < PROMEX_BACK_STATE_COUNT; appctx->ctx.stats.st_code++) { |
602 | @@ -1547,6 +1575,7 @@ static void promex_appctx_handle_io(struct appctx *appctx) | |||
603 | 1547 | res->flags |= CF_READ_NULL; | 1575 | res->flags |= CF_READ_NULL; |
604 | 1548 | si_shutr(si); | 1576 | si_shutr(si); |
605 | 1549 | si_shutw(si); | 1577 | si_shutw(si); |
606 | 1578 | goto out; | ||
607 | 1550 | } | 1579 | } |
608 | 1551 | 1580 | ||
609 | 1552 | struct applet promex_applet = { | 1581 | struct applet promex_applet = { |
610 | diff --git a/addons/wurfl/dummy/wurfl/wurfl.h b/addons/wurfl/dummy/wurfl/wurfl.h | |||
611 | index 3b450fc..7659561 100644 | |||
612 | --- a/addons/wurfl/dummy/wurfl/wurfl.h | |||
613 | +++ b/addons/wurfl/dummy/wurfl/wurfl.h | |||
614 | @@ -4,11 +4,16 @@ | |||
615 | 4 | * Copyright (c) ScientiaMobile, Inc. | 4 | * Copyright (c) ScientiaMobile, Inc. |
616 | 5 | * http://www.scientiamobile.com | 5 | * http://www.scientiamobile.com |
617 | 6 | * | 6 | * |
623 | 7 | * This software package is the property of ScientiaMobile Inc. and is licensed | 7 | * This software package is the property of ScientiaMobile Inc. and is distributed under |
624 | 8 | * commercially according to a contract between the Licensee and ScientiaMobile Inc. (Licensor). | 8 | * a dual licensing scheme: |
625 | 9 | * If you represent the Licensee, please refer to the licensing agreement which has been signed | 9 | * |
626 | 10 | * between the two parties. If you do not represent the Licensee, you are not authorized to use | 10 | * 1) commercially according to a contract between the Licensee and ScientiaMobile Inc. (Licensor). |
627 | 11 | * this software in any way. | 11 | * If you represent the Licensee, please refer to the licensing agreement which has been signed |
628 | 12 | * between the two parties. If you do not represent the Licensee, you are not authorized to use | ||
629 | 13 | * this software in any way. | ||
630 | 14 | * | ||
631 | 15 | * 2) LGPL when used in the context of the HAProxy project with the purpose of testing compatibility | ||
632 | 16 | * of HAProxy with ScientiaMobile software. | ||
633 | 12 | * | 17 | * |
634 | 13 | */ | 18 | */ |
635 | 14 | 19 | ||
636 | diff --git a/debian/changelog b/debian/changelog | |||
637 | index e96c035..738a16f 100644 | |||
638 | --- a/debian/changelog | |||
639 | +++ b/debian/changelog | |||
640 | @@ -1,3 +1,27 @@ | |||
641 | 1 | haproxy (2.4.22-0ubuntu0.22.04.1) jammy; urgency=medium | ||
642 | 2 | |||
643 | 3 | * New upstream release (LP: #2012557). | ||
644 | 4 | - Major and critical bug fixes according to the upstream changelog: | ||
645 | 5 | + BUG/MAJOR: log-forward: Fix log-forward proxies not fully initialized | ||
646 | 6 | + BUG/MAJOR: mworker: fix infinite loop on master with no proxies. | ||
647 | 7 | + BUG/MAJOR: stick-tables: do not try to index a server name for applets | ||
648 | 8 | + BUG/MAJOR: stick-table: don't process store-response rules for applets | ||
649 | 9 | + BUG/MAJOR: fcgi: Fix uninitialized reserved bytes | ||
650 | 10 | + BUG/MAJOR: buf: Fix copy of wrapping output data when a buffer is realigned | ||
651 | 11 | + BUG/CRITICAL: http: properly reject empty http header field names | ||
652 | 12 | - Remove patches applied by upstream in debian/patches: | ||
653 | 13 | + CVE-2023-0056.patch | ||
654 | 14 | + CVE-2023-25725.patch | ||
655 | 15 | + CVE-2023-0836.patch | ||
656 | 16 | - Refresh existing patches in debian/patches: | ||
657 | 17 | + haproxy.service-start-after-syslog.patch | ||
658 | 18 | + reproducible.patch | ||
659 | 19 | * Backport DEP-8 tests from Lunar: | ||
660 | 20 | - d/t/proxy-ssl-termination | ||
661 | 21 | - d/t/proxy-ssl-pass-through | ||
662 | 22 | |||
663 | 23 | -- Lucas Kanashiro <kanashiro@ubuntu.com> Wed, 22 Mar 2023 18:18:54 -0300 | ||
664 | 24 | |||
665 | 1 | haproxy (2.4.18-0ubuntu1.3) jammy-security; urgency=medium | 25 | haproxy (2.4.18-0ubuntu1.3) jammy-security; urgency=medium |
666 | 2 | 26 | ||
667 | 3 | * SECURITY UPDATE: information leak via uninitialized bytes | 27 | * SECURITY UPDATE: information leak via uninitialized bytes |
668 | diff --git a/debian/patches/CVE-2023-0056.patch b/debian/patches/CVE-2023-0056.patch | |||
669 | 4 | deleted file mode 100644 | 28 | deleted file mode 100644 |
670 | index dd8b02d..0000000 | |||
671 | --- a/debian/patches/CVE-2023-0056.patch | |||
672 | +++ /dev/null | |||
673 | @@ -1,38 +0,0 @@ | |||
674 | 1 | From 827a6299e6995c5c3ba620d8b7cbacdaef67f2c4 Mon Sep 17 00:00:00 2001 | ||
675 | 2 | From: Christopher Faulet <cfaulet@haproxy.com> | ||
676 | 3 | Date: Thu, 22 Dec 2022 09:47:01 +0100 | ||
677 | 4 | Subject: [PATCH] BUG/MEDIUM: mux-h2: Refuse interim responses with end-stream | ||
678 | 5 | flag set | ||
679 | 6 | |||
680 | 7 | As state in RFC9113#8.1, HEADERS frame with the ES flag set that carries an | ||
681 | 8 | informational status code is malformed. However, there is no test on this | ||
682 | 9 | condition. | ||
683 | 10 | |||
684 | 11 | On 2.4 and higher, it is hard to predict consequences of this bug because | ||
685 | 12 | end of the message is only reported with a flag. But on 2.2 and lower, it | ||
686 | 13 | leads to a crash because there is an unexpected extra EOM block at the end | ||
687 | 14 | of an interim response. | ||
688 | 15 | |||
689 | 16 | Now, when a ES flag is detected on a HEADERS frame for an interim message, a | ||
690 | 17 | stream error is sent (RST_STREAM/PROTOCOL_ERROR). | ||
691 | 18 | |||
692 | 19 | This patch should solve the issue #1972. It should be backported as far as | ||
693 | 20 | 2.0. | ||
694 | 21 | --- | ||
695 | 22 | src/mux_h2.c | 5 +++++ | ||
696 | 23 | 1 file changed, 5 insertions(+) | ||
697 | 24 | |||
698 | 25 | --- a/src/mux_h2.c | ||
699 | 26 | +++ b/src/mux_h2.c | ||
700 | 27 | @@ -4940,6 +4940,11 @@ next_frame: | ||
701 | 28 | *flags |= H2_SF_HEADERS_RCVD; | ||
702 | 29 | |||
703 | 30 | if (h2c->dff & H2_F_HEADERS_END_STREAM) { | ||
704 | 31 | + if (msgf & H2_MSGF_RSP_1XX) { | ||
705 | 32 | + /* RFC9113#8.1 : HEADERS frame with the ES flag set that carries an informational status code is malformed */ | ||
706 | 33 | + TRACE_STATE("invalid interim response with ES flag!", H2_EV_RX_FRAME|H2_EV_RX_HDR|H2_EV_H2C_ERR|H2_EV_PROTO_ERR, h2c->conn); | ||
707 | 34 | + goto fail; | ||
708 | 35 | + } | ||
709 | 36 | /* no more data are expected for this message */ | ||
710 | 37 | htx->flags |= HTX_FL_EOM; | ||
711 | 38 | } | ||
712 | diff --git a/debian/patches/CVE-2023-0836.patch b/debian/patches/CVE-2023-0836.patch | |||
713 | 39 | deleted file mode 100644 | 0 | deleted file mode 100644 |
714 | index f708696..0000000 | |||
715 | --- a/debian/patches/CVE-2023-0836.patch | |||
716 | +++ /dev/null | |||
717 | @@ -1,47 +0,0 @@ | |||
718 | 1 | From f988992d16f45ef03d5bbb024a1042ed8123e4c5 Mon Sep 17 00:00:00 2001 | ||
719 | 2 | From: Youfu Zhang <zhangyoufu@gmail.com> | ||
720 | 3 | Date: Fri, 9 Dec 2022 19:15:48 +0800 | ||
721 | 4 | Subject: [PATCH] BUG/MAJOR: fcgi: Fix uninitialized reserved bytes | ||
722 | 5 | |||
723 | 6 | The output buffer is not zero-initialized. If we don't clear reserved | ||
724 | 7 | bytes, fcgi requests sent to backend will leak sensitive data. | ||
725 | 8 | |||
726 | 9 | This patch must be backported as far as 2.2. | ||
727 | 10 | |||
728 | 11 | (cherry picked from commit 2e6bf0a2722866ae0128a4392fa2375bd1f03ff8) | ||
729 | 12 | Signed-off-by: Christopher Faulet <cfaulet@haproxy.com> | ||
730 | 13 | (cherry picked from commit db03179fee55c60a92ce6b86a0f04dbb9ba0328b) | ||
731 | 14 | Signed-off-by: Christopher Faulet <cfaulet@haproxy.com> | ||
732 | 15 | --- | ||
733 | 16 | src/fcgi.c | 8 ++++++-- | ||
734 | 17 | 1 file changed, 6 insertions(+), 2 deletions(-) | ||
735 | 18 | |||
736 | 19 | diff --git a/src/fcgi.c b/src/fcgi.c | ||
737 | 20 | index dcf2db2..1d1a82b 100644 | ||
738 | 21 | --- a/src/fcgi.c | ||
739 | 22 | +++ b/src/fcgi.c | ||
740 | 23 | @@ -47,7 +47,7 @@ int fcgi_encode_record_hdr(struct buffer *out, const struct fcgi_header *h) | ||
741 | 24 | out->area[len++] = ((h->len >> 8) & 0xff); | ||
742 | 25 | out->area[len++] = (h->len & 0xff); | ||
743 | 26 | out->area[len++] = h->padding; | ||
744 | 27 | - len++; /* rsv */ | ||
745 | 28 | + out->area[len++] = 0; /* rsv */ | ||
746 | 29 | |||
747 | 30 | out->data = len; | ||
748 | 31 | return 1; | ||
749 | 32 | @@ -94,7 +94,11 @@ int fcgi_encode_begin_request(struct buffer *out, const struct fcgi_begin_reques | ||
750 | 33 | out->area[len++] = ((r->role >> 8) & 0xff); | ||
751 | 34 | out->area[len++] = (r->role & 0xff); | ||
752 | 35 | out->area[len++] = r->flags; | ||
753 | 36 | - len += 5; /* rsv */ | ||
754 | 37 | + out->area[len++] = 0; /* rsv */ | ||
755 | 38 | + out->area[len++] = 0; | ||
756 | 39 | + out->area[len++] = 0; | ||
757 | 40 | + out->area[len++] = 0; | ||
758 | 41 | + out->area[len++] = 0; | ||
759 | 42 | |||
760 | 43 | out->data = len; | ||
761 | 44 | return 1; | ||
762 | 45 | -- | ||
763 | 46 | 1.7.10.4 | ||
764 | 47 | |||
765 | diff --git a/debian/patches/CVE-2023-25725.patch b/debian/patches/CVE-2023-25725.patch | |||
766 | 48 | deleted file mode 100644 | 0 | deleted file mode 100644 |
767 | index 1897223..0000000 | |||
768 | --- a/debian/patches/CVE-2023-25725.patch | |||
769 | +++ /dev/null | |||
770 | @@ -1,145 +0,0 @@ | |||
771 | 1 | From a6c7ac9d51248a641f456906549120d3f6387049 Mon Sep 17 00:00:00 2001 | ||
772 | 2 | From: Willy Tarreau <w@1wt.eu> | ||
773 | 3 | Date: Thu, 9 Feb 2023 21:36:54 +0100 | ||
774 | 4 | Subject: BUG/CRITICAL: http: properly reject empty http header field names | ||
775 | 5 | |||
776 | 6 | The HTTP header parsers surprizingly accepts empty header field names, | ||
777 | 7 | and this is a leftover from the original code that was agnostic to this. | ||
778 | 8 | |||
779 | 9 | When muxes were introduced, for H2 first, the HPACK decompressor needed | ||
780 | 10 | to feed headers lists, and since empty header names were strictly | ||
781 | 11 | forbidden by the protocol, the lists of headers were purposely designed | ||
782 | 12 | to be terminated by an empty header field name (a principle that is | ||
783 | 13 | similar to H1's empty line termination). This principle was preserved | ||
784 | 14 | and generalized to other protocols migrated to muxes (H1/FCGI/H3 etc) | ||
785 | 15 | without anyone ever noticing that the H1 parser was still able to deliver | ||
786 | 16 | empty header field names to this list. In addition to this it turns out | ||
787 | 17 | that the HPACK decompressor, despite a comment in the code, may | ||
788 | 18 | successfully decompress an empty header field name, and this mistake | ||
789 | 19 | was propagated to the QPACK decompressor as well. | ||
790 | 20 | |||
791 | 21 | The impact is that an empty header field name may be used to truncate | ||
792 | 22 | the list of headers and thus make some headers disappear. While for | ||
793 | 23 | H2/H3 the impact is limited as haproxy sees a request with missing | ||
794 | 24 | headers, and headers are not used to delimit messages, in the case of | ||
795 | 25 | HTTP/1, the impact is significant because the presence (and sometimes | ||
796 | 26 | contents) of certain sensitive headers is detected during the parsing. | ||
797 | 27 | Thus, some of these headers may be seen, marked as present, their value | ||
798 | 28 | extracted, but never delivered to upper layers and obviously not | ||
799 | 29 | forwarded to the other side either. This can have for consequence that | ||
800 | 30 | certain important header fields such as Connection, Upgrade, Host, | ||
801 | 31 | Content-length, Transfer-Encoding etc are possibly seen as different | ||
802 | 32 | between what haproxy uses to parse/forward/route and what is observed | ||
803 | 33 | in http-request rules and of course, forwarded. One direct consequence | ||
804 | 34 | is that it is possible to exploit this property in HTTP/1 to make | ||
805 | 35 | affected versions of haproxy forward more data than is advertised on | ||
806 | 36 | the other side, and bypass some access controls or routing rules by | ||
807 | 37 | crafting extraneous requests. Note, however, that responses to such | ||
808 | 38 | requests will normally not be passed back to the client, but this can | ||
809 | 39 | still cause some harm. | ||
810 | 40 | |||
811 | 41 | This specific risk can be mostly worked around in configuration using | ||
812 | 42 | the following rule that will rely on the bug's impact to precisely | ||
813 | 43 | detect the inconsistency between the known body size and the one | ||
814 | 44 | expected to be advertised to the server (the rule works from 2.0 to | ||
815 | 45 | 2.8-dev): | ||
816 | 46 | |||
817 | 47 | http-request deny if { fc_http_major 1 } !{ req.body_size 0 } !{ req.hdr(content-length) -m found } !{ req.hdr(transfer-encoding) -m found } !{ method CONNECT } | ||
818 | 48 | |||
819 | 49 | This will exclusively block such carefully crafted requests delivered | ||
820 | 50 | over HTTP/1. HTTP/2 and HTTP/3 do not need content-length, and a body | ||
821 | 51 | that arrives without being announced with a content-length will be | ||
822 | 52 | forwarded using transfer-encoding, hence will not cause discrepancies. | ||
823 | 53 | In HAProxy 2.0 in legacy mode ("no option http-use-htx"), this rule will | ||
824 | 54 | simply have no effect but will not cause trouble either. | ||
825 | 55 | |||
826 | 56 | A clean solution would consist in modifying the loops iterating over | ||
827 | 57 | these headers lists to check the header name's pointer instead of its | ||
828 | 58 | length (since both are zero at the end of the list), but this requires | ||
829 | 59 | to touch tens of places and it's very easy to miss one. Functions such | ||
830 | 60 | as htx_add_header(), htx_add_trailer(), htx_add_all_headers() would be | ||
831 | 61 | good starting points for such a possible future change. | ||
832 | 62 | |||
833 | 63 | Instead the current fix focuses on blocking empty headers where they | ||
834 | 64 | are first inserted, hence in the H1/HPACK/QPACK decoders. One benefit | ||
835 | 65 | of the current solution (for H1) is that it allows "show errors" to | ||
836 | 66 | report a precise diagnostic when facing such invalid HTTP/1 requests, | ||
837 | 67 | with the exact location of the problem and the originating address: | ||
838 | 68 | |||
839 | 69 | $ printf "GET / HTTP/1.1\r\nHost: localhost\r\n:empty header\r\n\r\n" | nc 0 8001 | ||
840 | 70 | HTTP/1.1 400 Bad request | ||
841 | 71 | Content-length: 90 | ||
842 | 72 | Cache-Control: no-cache | ||
843 | 73 | Connection: close | ||
844 | 74 | Content-Type: text/html | ||
845 | 75 | |||
846 | 76 | <html><body><h1>400 Bad request</h1> | ||
847 | 77 | Your browser sent an invalid request. | ||
848 | 78 | </body></html> | ||
849 | 79 | |||
850 | 80 | $ socat /var/run/haproxy.stat <<< "show errors" | ||
851 | 81 | Total events captured on [10/Feb/2023:16:29:37.530] : 1 | ||
852 | 82 | |||
853 | 83 | [10/Feb/2023:16:29:34.155] frontend decrypt (#2): invalid request | ||
854 | 84 | backend <NONE> (#-1), server <NONE> (#-1), event #0, src 127.0.0.1:31092 | ||
855 | 85 | buffer starts at 0 (including 0 out), 16334 free, | ||
856 | 86 | len 50, wraps at 16336, error at position 33 | ||
857 | 87 | H1 connection flags 0x00000000, H1 stream flags 0x00000810 | ||
858 | 88 | H1 msg state MSG_HDR_NAME(17), H1 msg flags 0x00001410 | ||
859 | 89 | H1 chunk len 0 bytes, H1 body len 0 bytes : | ||
860 | 90 | |||
861 | 91 | 00000 GET / HTTP/1.1\r\n | ||
862 | 92 | 00016 Host: localhost\r\n | ||
863 | 93 | 00033 :empty header\r\n | ||
864 | 94 | 00048 \r\n | ||
865 | 95 | |||
866 | 96 | I want to address sincere and warm thanks for their great work to the | ||
867 | 97 | team composed of the following security researchers who found the issue | ||
868 | 98 | together and reported it: Bahruz Jabiyev, Anthony Gavazzi, and Engin | ||
869 | 99 | Kirda from Northeastern University, Kaan Onarlioglu from Akamai | ||
870 | 100 | Technologies, Adi Peleg and Harvey Tuch from Google. And kudos to Amaury | ||
871 | 101 | Denoyelle from HAProxy Technologies for spotting that the HPACK and | ||
872 | 102 | QPACK decoders would let this pass despite the comment explicitly | ||
873 | 103 | saying otherwise. | ||
874 | 104 | |||
875 | 105 | This fix must be backported as far as 2.0. The QPACK changes can be | ||
876 | 106 | dropped before 2.6. In 2.0 there is also the equivalent code for legacy | ||
877 | 107 | mode, which doesn't suffer from the list truncation, but it would better | ||
878 | 108 | be fixed regardless. | ||
879 | 109 | --- | ||
880 | 110 | src/h1.c | 4 ++++ | ||
881 | 111 | src/hpack-dec.c | 9 +++++++++ | ||
882 | 112 | src/qpack-dec.c | 9 +++++++++ | ||
883 | 113 | 3 files changed, 22 insertions(+) | ||
884 | 114 | |||
885 | 115 | --- a/src/h1.c | ||
886 | 116 | +++ b/src/h1.c | ||
887 | 117 | @@ -706,6 +706,10 @@ int h1_headers_to_hdr_list(char *start, | ||
888 | 118 | |||
889 | 119 | if (likely(*ptr == ':')) { | ||
890 | 120 | col = ptr - start; | ||
891 | 121 | + if (col <= sol) { | ||
892 | 122 | + state = H1_MSG_HDR_NAME; | ||
893 | 123 | + goto http_msg_invalid; | ||
894 | 124 | + } | ||
895 | 125 | EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_hdr_l1_sp, http_msg_ood, state, H1_MSG_HDR_L1_SP); | ||
896 | 126 | } | ||
897 | 127 | |||
898 | 128 | --- a/src/hpack-dec.c | ||
899 | 129 | +++ b/src/hpack-dec.c | ||
900 | 130 | @@ -419,6 +419,15 @@ int hpack_decode_frame(struct hpack_dht | ||
901 | 131 | /* <name> and <value> are correctly filled here */ | ||
902 | 132 | } | ||
903 | 133 | |||
904 | 134 | + /* We must not accept empty header names (forbidden by the spec and used | ||
905 | 135 | + * as a list termination). | ||
906 | 136 | + */ | ||
907 | 137 | + if (!name.len) { | ||
908 | 138 | + hpack_debug_printf("##ERR@%d##\n", __LINE__); | ||
909 | 139 | + ret = -HPACK_ERR_INVALID_ARGUMENT; | ||
910 | 140 | + goto leave; | ||
911 | 141 | + } | ||
912 | 142 | + | ||
913 | 143 | /* here's what we have here : | ||
914 | 144 | * - name.len > 0 | ||
915 | 145 | * - value is filled with either const data or data allocated from tmp | ||
916 | diff --git a/debian/patches/haproxy.service-start-after-syslog.patch b/debian/patches/haproxy.service-start-after-syslog.patch | |||
917 | index 14577bd..af62681 100644 | |||
918 | --- a/debian/patches/haproxy.service-start-after-syslog.patch | |||
919 | +++ b/debian/patches/haproxy.service-start-after-syslog.patch | |||
920 | @@ -13,8 +13,6 @@ Last-Update: 2017-12-01 | |||
921 | 13 | admin/systemd/haproxy.service.in | 2 +- | 13 | admin/systemd/haproxy.service.in | 2 +- |
922 | 14 | 1 file changed, 1 insertion(+), 1 deletion(-) | 14 | 1 file changed, 1 insertion(+), 1 deletion(-) |
923 | 15 | 15 | ||
924 | 16 | diff --git a/admin/systemd/haproxy.service.in b/admin/systemd/haproxy.service.in | ||
925 | 17 | index 74e66e3..243acf2 100644 | ||
926 | 18 | --- a/admin/systemd/haproxy.service.in | 16 | --- a/admin/systemd/haproxy.service.in |
927 | 19 | +++ b/admin/systemd/haproxy.service.in | 17 | +++ b/admin/systemd/haproxy.service.in |
928 | 20 | @@ -1,6 +1,6 @@ | 18 | @@ -1,6 +1,6 @@ |
929 | diff --git a/debian/patches/reproducible.patch b/debian/patches/reproducible.patch | |||
930 | index bbc95b8..e499a79 100644 | |||
931 | --- a/debian/patches/reproducible.patch | |||
932 | +++ b/debian/patches/reproducible.patch | |||
933 | @@ -1,8 +1,6 @@ | |||
934 | 1 | diff --git a/Makefile b/Makefile | ||
935 | 2 | index 566bdb26a3e7..8603dea25c21 100644 | ||
936 | 3 | --- a/Makefile | 1 | --- a/Makefile |
937 | 4 | +++ b/Makefile | 2 | +++ b/Makefile |
939 | 5 | @@ -975,7 +975,7 @@ src/haproxy.o: src/haproxy.c $(DEP) | 3 | @@ -995,7 +995,7 @@ |
940 | 6 | -DBUILD_ARCH='"$(strip $(ARCH))"' \ | 4 | -DBUILD_ARCH='"$(strip $(ARCH))"' \ |
941 | 7 | -DBUILD_CPU='"$(strip $(CPU))"' \ | 5 | -DBUILD_CPU='"$(strip $(CPU))"' \ |
942 | 8 | -DBUILD_CC='"$(strip $(CC))"' \ | 6 | -DBUILD_CC='"$(strip $(CC))"' \ |
943 | diff --git a/debian/patches/series b/debian/patches/series | |||
944 | index 25260a8..276b0d5 100644 | |||
945 | --- a/debian/patches/series | |||
946 | +++ b/debian/patches/series | |||
947 | @@ -4,6 +4,3 @@ haproxy.service-add-documentation.patch | |||
948 | 4 | # applied during the build process: | 4 | # applied during the build process: |
949 | 5 | # debianize-dconv.patch | 5 | # debianize-dconv.patch |
950 | 6 | reproducible.patch | 6 | reproducible.patch |
951 | 7 | CVE-2023-0056.patch | ||
952 | 8 | CVE-2023-25725.patch | ||
953 | 9 | CVE-2023-0836.patch | ||
954 | diff --git a/debian/tests/control b/debian/tests/control | |||
955 | index 70649e3..ccc2b53 100644 | |||
956 | --- a/debian/tests/control | |||
957 | +++ b/debian/tests/control | |||
958 | @@ -5,3 +5,11 @@ Restrictions: needs-root | |||
959 | 5 | Tests: proxy-localhost | 5 | Tests: proxy-localhost |
960 | 6 | Depends: haproxy, wget, apache2 | 6 | Depends: haproxy, wget, apache2 |
961 | 7 | Restrictions: needs-root, allow-stderr, isolation-container | 7 | Restrictions: needs-root, allow-stderr, isolation-container |
962 | 8 | |||
963 | 9 | Tests: proxy-ssl-termination | ||
964 | 10 | Depends: haproxy, wget, apache2, gnutls-bin, ssl-cert | ||
965 | 11 | Restrictions: needs-root, allow-stderr, isolation-container | ||
966 | 12 | |||
967 | 13 | Tests: proxy-ssl-pass-through | ||
968 | 14 | Depends: haproxy, wget, apache2, gnutls-bin, ssl-cert | ||
969 | 15 | Restrictions: needs-root, allow-stderr, isolation-container | ||
970 | diff --git a/debian/tests/proxy-localhost b/debian/tests/proxy-localhost | |||
971 | index 8f33d4f..0736985 100644 | |||
972 | --- a/debian/tests/proxy-localhost | |||
973 | +++ b/debian/tests/proxy-localhost | |||
974 | @@ -2,6 +2,9 @@ | |||
975 | 2 | 2 | ||
976 | 3 | set -eux | 3 | set -eux |
977 | 4 | 4 | ||
978 | 5 | WDIR=$(dirname "$0") | ||
979 | 6 | . "${WDIR}/utils" | ||
980 | 7 | |||
981 | 5 | cat > /etc/haproxy/haproxy.cfg <<EOF | 8 | cat > /etc/haproxy/haproxy.cfg <<EOF |
982 | 6 | global | 9 | global |
983 | 7 | chroot /var/lib/haproxy | 10 | chroot /var/lib/haproxy |
984 | @@ -36,14 +39,6 @@ EOF | |||
985 | 36 | service haproxy restart | 39 | service haproxy restart |
986 | 37 | sleep 2 # Apache 2 could be still starting... See #976997. | 40 | sleep 2 # Apache 2 could be still starting... See #976997. |
987 | 38 | 41 | ||
997 | 39 | # index.html is shipped with apache2 | 42 | check_index_file "http://localhost:8080" |
989 | 40 | # Download it via haproxy and compare | ||
990 | 41 | if wget -t1 http://localhost:8080 -O- | cmp /var/www/html/index.html -; then | ||
991 | 42 | echo "OK: index.html downloaded via haproxy matches the source file." | ||
992 | 43 | else | ||
993 | 44 | echo "FAIL: downloaded index.html via haproxy is different from the" | ||
994 | 45 | echo " file delivered by apache." | ||
995 | 46 | exit 1 | ||
996 | 47 | fi | ||
998 | 48 | 43 | ||
999 | 49 | exit 0 | 44 | exit 0 |
1000 | diff --git a/debian/tests/proxy-ssl-pass-through b/debian/tests/proxy-ssl-pass-through | |||
1001 | 50 | new file mode 100644 | 45 | new file mode 100644 |
1002 | index 0000000..aa0bd2c | |||
1003 | --- /dev/null | |||
1004 | +++ b/debian/tests/proxy-ssl-pass-through | |||
1005 | @@ -0,0 +1,59 @@ | |||
1006 | 1 | #!/bin/sh | ||
1007 | 2 | |||
1008 | 3 | set -eux | ||
1009 | 4 | |||
1010 | 5 | WDIR=$(dirname "$0") | ||
1011 | 6 | . "${WDIR}/utils" | ||
1012 | 7 | |||
1013 | 8 | CERT_DIR=/etc/ssl/localhost | ||
1014 | 9 | APACHE2_CONFIG=/etc/apache2/sites-available/default-ssl.conf | ||
1015 | 10 | |||
1016 | 11 | create_ca | ||
1017 | 12 | create_selfsigned_cert ${CERT_DIR} | ||
1018 | 13 | |||
1019 | 14 | # Use the self-signed certificate in apache2 config | ||
1020 | 15 | sed -i "s#/etc/ssl/certs/ssl-cert-snakeoil.pem#${CERT_DIR}/localhost_cert.pem#" ${APACHE2_CONFIG} | ||
1021 | 16 | sed -i "s#/etc/ssl/private/ssl-cert-snakeoil.key#${CERT_DIR}/localhost_key.pem#" ${APACHE2_CONFIG} | ||
1022 | 17 | |||
1023 | 18 | cat > /etc/haproxy/haproxy.cfg <<EOF | ||
1024 | 19 | global | ||
1025 | 20 | chroot /var/lib/haproxy | ||
1026 | 21 | user haproxy | ||
1027 | 22 | group haproxy | ||
1028 | 23 | daemon | ||
1029 | 24 | maxconn 4096 | ||
1030 | 25 | |||
1031 | 26 | defaults | ||
1032 | 27 | log global | ||
1033 | 28 | option dontlognull | ||
1034 | 29 | option redispatch | ||
1035 | 30 | retries 3 | ||
1036 | 31 | timeout client 50s | ||
1037 | 32 | timeout connect 10s | ||
1038 | 33 | timeout http-request 5s | ||
1039 | 34 | timeout server 50s | ||
1040 | 35 | maxconn 4096 | ||
1041 | 36 | |||
1042 | 37 | frontend test-front | ||
1043 | 38 | bind *:4433 | ||
1044 | 39 | mode tcp | ||
1045 | 40 | option tcplog | ||
1046 | 41 | default_backend test-back | ||
1047 | 42 | |||
1048 | 43 | backend test-back | ||
1049 | 44 | mode tcp | ||
1050 | 45 | stick store-request src | ||
1051 | 46 | stick-table type ip size 256k expire 30m | ||
1052 | 47 | option ssl-hello-chk | ||
1053 | 48 | server test-1 localhost:443 check | ||
1054 | 49 | EOF | ||
1055 | 50 | |||
1056 | 51 | systemctl restart haproxy | ||
1057 | 52 | a2enmod ssl | ||
1058 | 53 | a2ensite default-ssl | ||
1059 | 54 | systemctl restart apache2 | ||
1060 | 55 | sleep 5 # Apache 2 could be still starting... See #976997. It needs some extra seconds because of SSL | ||
1061 | 56 | |||
1062 | 57 | check_index_file "https://localhost:4433" | ||
1063 | 58 | |||
1064 | 59 | exit 0 | ||
1065 | diff --git a/debian/tests/proxy-ssl-termination b/debian/tests/proxy-ssl-termination | |||
1066 | 0 | new file mode 100644 | 60 | new file mode 100644 |
1067 | index 0000000..6cc1bcc | |||
1068 | --- /dev/null | |||
1069 | +++ b/debian/tests/proxy-ssl-termination | |||
1070 | @@ -0,0 +1,48 @@ | |||
1071 | 1 | #!/bin/sh | ||
1072 | 2 | |||
1073 | 3 | set -eux | ||
1074 | 4 | |||
1075 | 5 | WDIR=$(dirname "$0") | ||
1076 | 6 | . "${WDIR}/utils" | ||
1077 | 7 | |||
1078 | 8 | CERT_DIR=/etc/ssl/localhost | ||
1079 | 9 | create_ca | ||
1080 | 10 | create_selfsigned_cert ${CERT_DIR} | ||
1081 | 11 | |||
1082 | 12 | cat > /etc/haproxy/haproxy.cfg <<EOF | ||
1083 | 13 | global | ||
1084 | 14 | chroot /var/lib/haproxy | ||
1085 | 15 | user haproxy | ||
1086 | 16 | group haproxy | ||
1087 | 17 | daemon | ||
1088 | 18 | maxconn 4096 | ||
1089 | 19 | ssl-default-bind-options ssl-min-ver SSLv3 | ||
1090 | 20 | |||
1091 | 21 | defaults | ||
1092 | 22 | log global | ||
1093 | 23 | option dontlognull | ||
1094 | 24 | option redispatch | ||
1095 | 25 | retries 3 | ||
1096 | 26 | timeout client 50s | ||
1097 | 27 | timeout connect 10s | ||
1098 | 28 | timeout http-request 5s | ||
1099 | 29 | timeout server 50s | ||
1100 | 30 | maxconn 4096 | ||
1101 | 31 | |||
1102 | 32 | frontend test-front | ||
1103 | 33 | bind *:443 ssl crt ${CERT_DIR}/localhost.pem | ||
1104 | 34 | default_backend test-back | ||
1105 | 35 | |||
1106 | 36 | backend test-back | ||
1107 | 37 | mode http | ||
1108 | 38 | stick store-request src | ||
1109 | 39 | stick-table type ip size 256k expire 30m | ||
1110 | 40 | server test-1 localhost:80 check | ||
1111 | 41 | EOF | ||
1112 | 42 | |||
1113 | 43 | systemctl restart haproxy | ||
1114 | 44 | sleep 2 # Apache 2 could be still starting... See #976997. | ||
1115 | 45 | |||
1116 | 46 | check_index_file "https://localhost" | ||
1117 | 47 | |||
1118 | 48 | exit 0 | ||
1119 | diff --git a/debian/tests/utils b/debian/tests/utils | |||
1120 | 0 | new file mode 100644 | 49 | new file mode 100644 |
1121 | index 0000000..df11b55 | |||
1122 | --- /dev/null | |||
1123 | +++ b/debian/tests/utils | |||
1124 | @@ -0,0 +1,58 @@ | |||
1125 | 1 | |||
1126 | 2 | create_ca() { | ||
1127 | 3 | certtool --generate-privkey --bits 4096 --outfile /etc/ssl/private/mycakey.pem | ||
1128 | 4 | |||
1129 | 5 | cat <<EOF > /etc/ssl/ca.info | ||
1130 | 6 | cn = Example Company | ||
1131 | 7 | ca | ||
1132 | 8 | cert_signing_key | ||
1133 | 9 | expiration_days = 3650 | ||
1134 | 10 | EOF | ||
1135 | 11 | |||
1136 | 12 | certtool --generate-self-signed \ | ||
1137 | 13 | --load-privkey /etc/ssl/private/mycakey.pem \ | ||
1138 | 14 | --template /etc/ssl/ca.info \ | ||
1139 | 15 | --outfile /usr/local/share/ca-certificates/mycacert.crt | ||
1140 | 16 | |||
1141 | 17 | update-ca-certificates | ||
1142 | 18 | } | ||
1143 | 19 | |||
1144 | 20 | create_selfsigned_cert() { | ||
1145 | 21 | dir="$1" | ||
1146 | 22 | mkdir -p "${dir}" | ||
1147 | 23 | |||
1148 | 24 | certtool --generate-privkey --bits 2048 --outfile "${dir}/localhost_key.pem" | ||
1149 | 25 | |||
1150 | 26 | cat <<EOF > "${dir}/localhost.info" | ||
1151 | 27 | organization = Example Company | ||
1152 | 28 | cn = localhost | ||
1153 | 29 | tls_www_server | ||
1154 | 30 | encryption_key | ||
1155 | 31 | signing_key | ||
1156 | 32 | expiration_days = 365 | ||
1157 | 33 | EOF | ||
1158 | 34 | |||
1159 | 35 | certtool --generate-certificate \ | ||
1160 | 36 | --load-privkey "${dir}/localhost_key.pem" \ | ||
1161 | 37 | --load-ca-certificate /etc/ssl/certs/mycacert.pem \ | ||
1162 | 38 | --load-ca-privkey /etc/ssl/private/mycakey.pem \ | ||
1163 | 39 | --template "${dir}/localhost.info" \ | ||
1164 | 40 | --outfile "${dir}/localhost_cert.pem" | ||
1165 | 41 | |||
1166 | 42 | cat "${dir}/localhost_cert.pem" "${dir}/localhost_key.pem" | tee "${dir}/localhost.pem" | ||
1167 | 43 | chgrp haproxy "${dir}/localhost_key.pem" "${dir}/localhost.pem" | ||
1168 | 44 | chmod 0640 "${dir}/localhost_key.pem" "${dir}/localhost.pem" | ||
1169 | 45 | } | ||
1170 | 46 | |||
1171 | 47 | check_index_file() { | ||
1172 | 48 | haproxy_url="$1" | ||
1173 | 49 | # index.html is shipped with apache2 | ||
1174 | 50 | # Download it via haproxy and compare | ||
1175 | 51 | if wget -t1 "${haproxy_url}" -O- | cmp /var/www/html/index.html -; then | ||
1176 | 52 | echo "OK: index.html downloaded via haproxy matches the source file." | ||
1177 | 53 | else | ||
1178 | 54 | echo "FAIL: downloaded index.html via haproxy is different from the" | ||
1179 | 55 | echo " file delivered by apache." | ||
1180 | 56 | exit 1 | ||
1181 | 57 | fi | ||
1182 | 58 | } | ||
1183 | diff --git a/doc/configuration.txt b/doc/configuration.txt | |||
1184 | index 5d4c052..0c23dd1 100644 | |||
1185 | --- a/doc/configuration.txt | |||
1186 | +++ b/doc/configuration.txt | |||
1187 | @@ -3,7 +3,7 @@ | |||
1188 | 3 | Configuration Manual | 3 | Configuration Manual |
1189 | 4 | ---------------------- | 4 | ---------------------- |
1190 | 5 | version 2.4 | 5 | version 2.4 |
1192 | 6 | 2022/07/27 | 6 | 2023/02/14 |
1193 | 7 | 7 | ||
1194 | 8 | 8 | ||
1195 | 9 | This document covers the configuration language as implemented in the version | 9 | This document covers the configuration language as implemented in the version |
1196 | @@ -965,32 +965,36 @@ of them have command-line equivalents. | |||
1197 | 965 | The following keywords are supported in the "global" section : | 965 | The following keywords are supported in the "global" section : |
1198 | 966 | 966 | ||
1199 | 967 | * Process management and security | 967 | * Process management and security |
1200 | 968 | - 51degrees-cache-size | ||
1201 | 969 | - 51degrees-data-file | ||
1202 | 970 | - 51degrees-property-name-list | ||
1203 | 971 | - 51degrees-property-separator | ||
1204 | 968 | - ca-base | 972 | - ca-base |
1205 | 969 | - chroot | 973 | - chroot |
1206 | 970 | - crt-base | ||
1207 | 971 | - cpu-map | 974 | - cpu-map |
1208 | 975 | - crt-base | ||
1209 | 972 | - daemon | 976 | - daemon |
1210 | 973 | - default-path | 977 | - default-path |
1211 | 974 | - description | 978 | - description |
1212 | 975 | - deviceatlas-json-file | 979 | - deviceatlas-json-file |
1213 | 976 | - deviceatlas-log-level | 980 | - deviceatlas-log-level |
1214 | 977 | - deviceatlas-separator | ||
1215 | 978 | - deviceatlas-properties-cookie | 981 | - deviceatlas-properties-cookie |
1216 | 982 | - deviceatlas-separator | ||
1217 | 979 | - expose-experimental-directives | 983 | - expose-experimental-directives |
1218 | 980 | - external-check | 984 | - external-check |
1219 | 981 | - gid | 985 | - gid |
1220 | 982 | - group | 986 | - group |
1221 | 983 | - hard-stop-after | ||
1222 | 984 | - h1-case-adjust | 987 | - h1-case-adjust |
1223 | 985 | - h1-case-adjust-file | 988 | - h1-case-adjust-file |
1224 | 989 | - h2-workaround-bogus-websocket-clients | ||
1225 | 990 | - hard-stop-after | ||
1226 | 986 | - insecure-fork-wanted | 991 | - insecure-fork-wanted |
1227 | 987 | - insecure-setuid-wanted | 992 | - insecure-setuid-wanted |
1228 | 988 | - issuers-chain-path | 993 | - issuers-chain-path |
1229 | 989 | - h2-workaround-bogus-websocket-clients | ||
1230 | 990 | - localpeer | 994 | - localpeer |
1231 | 991 | - log | 995 | - log |
1232 | 992 | - log-tag | ||
1233 | 993 | - log-send-hostname | 996 | - log-send-hostname |
1234 | 997 | - log-tag | ||
1235 | 994 | - lua-load | 998 | - lua-load |
1236 | 995 | - lua-load-per-thread | 999 | - lua-load-per-thread |
1237 | 996 | - lua-prepend-path | 1000 | - lua-prepend-path |
1238 | @@ -1003,13 +1007,9 @@ The following keywords are supported in the "global" section : | |||
1239 | 1003 | - pp2-never-send-local | 1007 | - pp2-never-send-local |
1240 | 1004 | - presetenv | 1008 | - presetenv |
1241 | 1005 | - resetenv | 1009 | - resetenv |
1242 | 1006 | - uid | ||
1243 | 1007 | - ulimit-n | ||
1244 | 1008 | - user | ||
1245 | 1009 | - set-dumpable | 1010 | - set-dumpable |
1246 | 1010 | - set-var | 1011 | - set-var |
1247 | 1011 | - setenv | 1012 | - setenv |
1248 | 1012 | - stats | ||
1249 | 1013 | - ssl-default-bind-ciphers | 1013 | - ssl-default-bind-ciphers |
1250 | 1014 | - ssl-default-bind-ciphersuites | 1014 | - ssl-default-bind-ciphersuites |
1251 | 1015 | - ssl-default-bind-curves | 1015 | - ssl-default-bind-curves |
1252 | @@ -1020,25 +1020,25 @@ The following keywords are supported in the "global" section : | |||
1253 | 1020 | - ssl-dh-param-file | 1020 | - ssl-dh-param-file |
1254 | 1021 | - ssl-server-verify | 1021 | - ssl-server-verify |
1255 | 1022 | - ssl-skip-self-issued-ca | 1022 | - ssl-skip-self-issued-ca |
1256 | 1023 | - stats | ||
1257 | 1024 | - strict-limits | ||
1258 | 1025 | - uid | ||
1259 | 1026 | - ulimit-n | ||
1260 | 1023 | - unix-bind | 1027 | - unix-bind |
1261 | 1024 | - unsetenv | 1028 | - unsetenv |
1266 | 1025 | - 51degrees-data-file | 1029 | - user |
1267 | 1026 | - 51degrees-property-name-list | 1030 | - wurfl-cache-size |
1264 | 1027 | - 51degrees-property-separator | ||
1265 | 1028 | - 51degrees-cache-size | ||
1268 | 1029 | - wurfl-data-file | 1031 | - wurfl-data-file |
1269 | 1030 | - wurfl-information-list | 1032 | - wurfl-information-list |
1270 | 1031 | - wurfl-information-list-separator | 1033 | - wurfl-information-list-separator |
1271 | 1032 | - wurfl-cache-size | ||
1272 | 1033 | - strict-limits | ||
1273 | 1034 | 1034 | ||
1274 | 1035 | * Performance tuning | 1035 | * Performance tuning |
1275 | 1036 | - busy-polling | 1036 | - busy-polling |
1276 | 1037 | - max-spread-checks | 1037 | - max-spread-checks |
1277 | 1038 | - maxcompcpuusage | ||
1278 | 1039 | - maxcomprate | ||
1279 | 1038 | - maxconn | 1040 | - maxconn |
1280 | 1039 | - maxconnrate | 1041 | - maxconnrate |
1281 | 1040 | - maxcomprate | ||
1282 | 1041 | - maxcompcpuusage | ||
1283 | 1042 | - maxpipes | 1042 | - maxpipes |
1284 | 1043 | - maxsessrate | 1043 | - maxsessrate |
1285 | 1044 | - maxsslconn | 1044 | - maxsslconn |
1286 | @@ -1046,16 +1046,16 @@ The following keywords are supported in the "global" section : | |||
1287 | 1046 | - maxzlibmem | 1046 | - maxzlibmem |
1288 | 1047 | - no-memory-trimming | 1047 | - no-memory-trimming |
1289 | 1048 | - noepoll | 1048 | - noepoll |
1290 | 1049 | - nokqueue | ||
1291 | 1050 | - noevports | 1049 | - noevports |
1292 | 1051 | - nopoll | ||
1293 | 1052 | - nosplice | ||
1294 | 1053 | - nogetaddrinfo | 1050 | - nogetaddrinfo |
1295 | 1051 | - nokqueue | ||
1296 | 1052 | - nopoll | ||
1297 | 1054 | - noreuseport | 1053 | - noreuseport |
1298 | 1054 | - nosplice | ||
1299 | 1055 | - profiling.tasks | 1055 | - profiling.tasks |
1300 | 1056 | - spread-checks | ||
1301 | 1057 | - server-state-base | 1056 | - server-state-base |
1302 | 1058 | - server-state-file | 1057 | - server-state-file |
1303 | 1058 | - spread-checks | ||
1304 | 1059 | - ssl-engine | 1059 | - ssl-engine |
1305 | 1060 | - ssl-mode-async | 1060 | - ssl-mode-async |
1306 | 1061 | - tune.buffers.limit | 1061 | - tune.buffers.limit |
1307 | @@ -1074,9 +1074,9 @@ The following keywords are supported in the "global" section : | |||
1308 | 1074 | - tune.idletimer | 1074 | - tune.idletimer |
1309 | 1075 | - tune.lua.forced-yield | 1075 | - tune.lua.forced-yield |
1310 | 1076 | - tune.lua.maxmem | 1076 | - tune.lua.maxmem |
1311 | 1077 | - tune.lua.service-timeout | ||
1312 | 1077 | - tune.lua.session-timeout | 1078 | - tune.lua.session-timeout |
1313 | 1078 | - tune.lua.task-timeout | 1079 | - tune.lua.task-timeout |
1314 | 1079 | - tune.lua.service-timeout | ||
1315 | 1080 | - tune.maxaccept | 1080 | - tune.maxaccept |
1316 | 1081 | - tune.maxpollevents | 1081 | - tune.maxpollevents |
1317 | 1082 | - tune.maxrewrite | 1082 | - tune.maxrewrite |
1318 | @@ -1092,13 +1092,13 @@ The following keywords are supported in the "global" section : | |||
1319 | 1092 | - tune.sndbuf.client | 1092 | - tune.sndbuf.client |
1320 | 1093 | - tune.sndbuf.server | 1093 | - tune.sndbuf.server |
1321 | 1094 | - tune.ssl.cachesize | 1094 | - tune.ssl.cachesize |
1322 | 1095 | - tune.ssl.capture-cipherlist-size | ||
1323 | 1096 | - tune.ssl.default-dh-param | ||
1324 | 1097 | - tune.ssl.force-private-cache | ||
1325 | 1095 | - tune.ssl.keylog | 1098 | - tune.ssl.keylog |
1326 | 1096 | - tune.ssl.lifetime | 1099 | - tune.ssl.lifetime |
1327 | 1097 | - tune.ssl.force-private-cache | ||
1328 | 1098 | - tune.ssl.maxrecord | 1100 | - tune.ssl.maxrecord |
1329 | 1099 | - tune.ssl.default-dh-param | ||
1330 | 1100 | - tune.ssl.ssl-ctx-cache-size | 1101 | - tune.ssl.ssl-ctx-cache-size |
1331 | 1101 | - tune.ssl.capture-cipherlist-size | ||
1332 | 1102 | - tune.vars.global-max-size | 1102 | - tune.vars.global-max-size |
1333 | 1103 | - tune.vars.proc-max-size | 1103 | - tune.vars.proc-max-size |
1334 | 1104 | - tune.vars.reqres-max-size | 1104 | - tune.vars.reqres-max-size |
1335 | @@ -1115,6 +1115,36 @@ The following keywords are supported in the "global" section : | |||
1336 | 1115 | 3.1. Process management and security | 1115 | 3.1. Process management and security |
1337 | 1116 | ------------------------------------ | 1116 | ------------------------------------ |
1338 | 1117 | 1117 | ||
1339 | 1118 | 51degrees-data-file <file path> | ||
1340 | 1119 | The path of the 51Degrees data file to provide device detection services. The | ||
1341 | 1120 | file should be unzipped and accessible by HAProxy with relevant permissions. | ||
1342 | 1121 | |||
1343 | 1122 | Please note that this option is only available when HAProxy has been | ||
1344 | 1123 | compiled with USE_51DEGREES. | ||
1345 | 1124 | |||
1346 | 1125 | 51degrees-property-name-list [<string> ...] | ||
1347 | 1126 | A list of 51Degrees property names to be load from the dataset. A full list | ||
1348 | 1127 | of names is available on the 51Degrees website: | ||
1349 | 1128 | https://51degrees.com/resources/property-dictionary | ||
1350 | 1129 | |||
1351 | 1130 | Please note that this option is only available when HAProxy has been | ||
1352 | 1131 | compiled with USE_51DEGREES. | ||
1353 | 1132 | |||
1354 | 1133 | 51degrees-property-separator <char> | ||
1355 | 1134 | A char that will be appended to every property value in a response header | ||
1356 | 1135 | containing 51Degrees results. If not set that will be set as ','. | ||
1357 | 1136 | |||
1358 | 1137 | Please note that this option is only available when HAProxy has been | ||
1359 | 1138 | compiled with USE_51DEGREES. | ||
1360 | 1139 | |||
1361 | 1140 | 51degrees-cache-size <number> | ||
1362 | 1141 | Sets the size of the 51Degrees converter cache to <number> entries. This | ||
1363 | 1142 | is an LRU cache which reminds previous device detections and their results. | ||
1364 | 1143 | By default, this cache is disabled. | ||
1365 | 1144 | |||
1366 | 1145 | Please note that this option is only available when HAProxy has been | ||
1367 | 1146 | compiled with USE_51DEGREES. | ||
1368 | 1147 | |||
1369 | 1118 | ca-base <dir> | 1148 | ca-base <dir> |
1370 | 1119 | Assigns a default directory to fetch SSL CA certificates and CRLs from when a | 1149 | Assigns a default directory to fetch SSL CA certificates and CRLs from when a |
1371 | 1120 | relative path is used with "ca-file", "ca-verify-file" or "crl-file" | 1150 | relative path is used with "ca-file", "ca-verify-file" or "crl-file" |
1372 | @@ -1267,6 +1297,13 @@ default-path { current | config | parent | origin <path> } | |||
1373 | 1267 | paths. A robust approach could consist in prefixing all files names with | 1297 | paths. A robust approach could consist in prefixing all files names with |
1374 | 1268 | their respective site name, or in doing so at the directory level. | 1298 | their respective site name, or in doing so at the directory level. |
1375 | 1269 | 1299 | ||
1376 | 1300 | description <text> | ||
1377 | 1301 | Add a text that describes the instance. | ||
1378 | 1302 | |||
1379 | 1303 | Please note that it is required to escape certain characters (# for example) | ||
1380 | 1304 | and this text is inserted into a html page so you should avoid using | ||
1381 | 1305 | "<" and ">" characters. | ||
1382 | 1306 | |||
1383 | 1270 | deviceatlas-json-file <path> | 1307 | deviceatlas-json-file <path> |
1384 | 1271 | Sets the path of the DeviceAtlas JSON data file to be loaded by the API. | 1308 | Sets the path of the DeviceAtlas JSON data file to be loaded by the API. |
1385 | 1272 | The path must be a valid JSON data file and accessible by HAProxy process. | 1309 | The path must be a valid JSON data file and accessible by HAProxy process. |
1386 | @@ -1275,15 +1312,15 @@ deviceatlas-log-level <value> | |||
1387 | 1275 | Sets the level of information returned by the API. This directive is | 1312 | Sets the level of information returned by the API. This directive is |
1388 | 1276 | optional and set to 0 by default if not set. | 1313 | optional and set to 0 by default if not set. |
1389 | 1277 | 1314 | ||
1390 | 1278 | deviceatlas-separator <char> | ||
1391 | 1279 | Sets the character separator for the API properties results. This directive | ||
1392 | 1280 | is optional and set to | by default if not set. | ||
1393 | 1281 | |||
1394 | 1282 | deviceatlas-properties-cookie <name> | 1315 | deviceatlas-properties-cookie <name> |
1395 | 1283 | Sets the client cookie's name used for the detection if the DeviceAtlas | 1316 | Sets the client cookie's name used for the detection if the DeviceAtlas |
1396 | 1284 | Client-side component was used during the request. This directive is optional | 1317 | Client-side component was used during the request. This directive is optional |
1397 | 1285 | and set to DAPROPS by default if not set. | 1318 | and set to DAPROPS by default if not set. |
1398 | 1286 | 1319 | ||
1399 | 1320 | deviceatlas-separator <char> | ||
1400 | 1321 | Sets the character separator for the API properties results. This directive | ||
1401 | 1322 | is optional and set to | by default if not set. | ||
1402 | 1323 | |||
1403 | 1287 | expose-experimental-directives | 1324 | expose-experimental-directives |
1404 | 1288 | This statement must appear before using directives tagged as experimental or | 1325 | This statement must appear before using directives tagged as experimental or |
1405 | 1289 | the config file will be rejected. | 1326 | the config file will be rejected. |
1406 | @@ -1309,22 +1346,6 @@ group <group name> | |||
1407 | 1309 | Similar to "gid" but uses the GID of group name <group name> from /etc/group. | 1346 | Similar to "gid" but uses the GID of group name <group name> from /etc/group. |
1408 | 1310 | See also "gid" and "user". | 1347 | See also "gid" and "user". |
1409 | 1311 | 1348 | ||
1410 | 1312 | hard-stop-after <time> | ||
1411 | 1313 | Defines the maximum time allowed to perform a clean soft-stop. | ||
1412 | 1314 | |||
1413 | 1315 | Arguments : | ||
1414 | 1316 | <time> is the maximum time (by default in milliseconds) for which the | ||
1415 | 1317 | instance will remain alive when a soft-stop is received via the | ||
1416 | 1318 | SIGUSR1 signal. | ||
1417 | 1319 | |||
1418 | 1320 | This may be used to ensure that the instance will quit even if connections | ||
1419 | 1321 | remain opened during a soft-stop (for example with long timeouts for a proxy | ||
1420 | 1322 | in tcp mode). It applies both in TCP and HTTP mode. | ||
1421 | 1323 | |||
1422 | 1324 | Example: | ||
1423 | 1325 | global | ||
1424 | 1326 | hard-stop-after 30s | ||
1425 | 1327 | |||
1426 | 1328 | h1-case-adjust <from> <to> | 1349 | h1-case-adjust <from> <to> |
1427 | 1329 | Defines the case adjustment to apply, when enabled, to the header name | 1350 | Defines the case adjustment to apply, when enabled, to the header name |
1428 | 1330 | <from>, to change it to <to> before sending it to HTTP/1 clients or | 1351 | <from>, to change it to <to> before sending it to HTTP/1 clients or |
1429 | @@ -1374,6 +1395,33 @@ h1-case-adjust-file <hdrs-file> | |||
1430 | 1374 | See "h1-case-adjust", "option h1-case-adjust-bogus-client" and | 1395 | See "h1-case-adjust", "option h1-case-adjust-bogus-client" and |
1431 | 1375 | "option h1-case-adjust-bogus-server". | 1396 | "option h1-case-adjust-bogus-server". |
1432 | 1376 | 1397 | ||
1433 | 1398 | h2-workaround-bogus-websocket-clients | ||
1434 | 1399 | This disables the announcement of the support for h2 websockets to clients. | ||
1435 | 1400 | This can be use to overcome clients which have issues when implementing the | ||
1436 | 1401 | relatively fresh RFC8441, such as Firefox 88. To allow clients to | ||
1437 | 1402 | automatically downgrade to http/1.1 for the websocket tunnel, specify h2 | ||
1438 | 1403 | support on the bind line using "alpn" without an explicit "proto" keyword. If | ||
1439 | 1404 | this statement was previously activated, this can be disabled by prefixing | ||
1440 | 1405 | the keyword with "no'. | ||
1441 | 1406 | |||
1442 | 1407 | hard-stop-after <time> | ||
1443 | 1408 | Defines the maximum time allowed to perform a clean soft-stop. | ||
1444 | 1409 | |||
1445 | 1410 | Arguments : | ||
1446 | 1411 | <time> is the maximum time (by default in milliseconds) for which the | ||
1447 | 1412 | instance will remain alive when a soft-stop is received via the | ||
1448 | 1413 | SIGUSR1 signal. | ||
1449 | 1414 | |||
1450 | 1415 | This may be used to ensure that the instance will quit even if connections | ||
1451 | 1416 | remain opened during a soft-stop (for example with long timeouts for a proxy | ||
1452 | 1417 | in tcp mode). It applies both in TCP and HTTP mode. | ||
1453 | 1418 | |||
1454 | 1419 | Example: | ||
1455 | 1420 | global | ||
1456 | 1421 | hard-stop-after 30s | ||
1457 | 1422 | |||
1458 | 1423 | See also: grace | ||
1459 | 1424 | |||
1460 | 1377 | insecure-fork-wanted | 1425 | insecure-fork-wanted |
1461 | 1378 | By default HAProxy tries hard to prevent any thread and process creation | 1426 | By default HAProxy tries hard to prevent any thread and process creation |
1462 | 1379 | after it starts. Doing so is particularly important when using Lua files of | 1427 | after it starts. Doing so is particularly important when using Lua files of |
1463 | @@ -1421,15 +1469,6 @@ issuers-chain-path <dir> | |||
1464 | 1421 | "issuers-chain-path" directory. All other certificates with the same issuer | 1469 | "issuers-chain-path" directory. All other certificates with the same issuer |
1465 | 1422 | will share the chain in memory. | 1470 | will share the chain in memory. |
1466 | 1423 | 1471 | ||
1467 | 1424 | h2-workaround-bogus-websocket-clients | ||
1468 | 1425 | This disables the announcement of the support for h2 websockets to clients. | ||
1469 | 1426 | This can be use to overcome clients which have issues when implementing the | ||
1470 | 1427 | relatively fresh RFC8441, such as Firefox 88. To allow clients to | ||
1471 | 1428 | automatically downgrade to http/1.1 for the websocket tunnel, specify h2 | ||
1472 | 1429 | support on the bind line using "alpn" without an explicit "proto" keyword. If | ||
1473 | 1430 | this statement was previously activated, this can be disabled by prefixing | ||
1474 | 1431 | the keyword with "no'. | ||
1475 | 1432 | |||
1476 | 1433 | localpeer <name> | 1472 | localpeer <name> |
1477 | 1434 | Sets the local instance's peer name. It will be ignored if the "-L" | 1473 | Sets the local instance's peer name. It will be ignored if the "-L" |
1478 | 1435 | command line argument is specified or if used after "peers" section | 1474 | command line argument is specified or if used after "peers" section |
1479 | @@ -1762,6 +1801,26 @@ server-state-file <file> | |||
1480 | 1762 | configuration. See also "server-state-base" and "show servers state", | 1801 | configuration. See also "server-state-base" and "show servers state", |
1481 | 1763 | "load-server-state-from-file" and "server-state-file-name" | 1802 | "load-server-state-from-file" and "server-state-file-name" |
1482 | 1764 | 1803 | ||
1483 | 1804 | set-dumpable | ||
1484 | 1805 | This option is better left disabled by default and enabled only upon a | ||
1485 | 1806 | developer's request. If it has been enabled, it may still be forcibly | ||
1486 | 1807 | disabled by prefixing it with the "no" keyword. It has no impact on | ||
1487 | 1808 | performance nor stability but will try hard to re-enable core dumps that were | ||
1488 | 1809 | possibly disabled by file size limitations (ulimit -f), core size limitations | ||
1489 | 1810 | (ulimit -c), or "dumpability" of a process after changing its UID/GID (such | ||
1490 | 1811 | as /proc/sys/fs/suid_dumpable on Linux). Core dumps might still be limited by | ||
1491 | 1812 | the current directory's permissions (check what directory the file is started | ||
1492 | 1813 | from), the chroot directory's permission (it may be needed to temporarily | ||
1493 | 1814 | disable the chroot directive or to move it to a dedicated writable location), | ||
1494 | 1815 | or any other system-specific constraint. For example, some Linux flavours are | ||
1495 | 1816 | notorious for replacing the default core file with a path to an executable | ||
1496 | 1817 | not even installed on the system (check /proc/sys/kernel/core_pattern). Often, | ||
1497 | 1818 | simply writing "core", "core.%p" or "/var/log/core/core.%p" addresses the | ||
1498 | 1819 | issue. When trying to enable this option waiting for a rare issue to | ||
1499 | 1820 | re-appear, it's often a good idea to first try to obtain such a dump by | ||
1500 | 1821 | issuing, for example, "kill -11" to the "haproxy" process and verify that it | ||
1501 | 1822 | leaves a core where expected when dying. | ||
1502 | 1823 | |||
1503 | 1765 | set-var <var-name> <expr> | 1824 | set-var <var-name> <expr> |
1504 | 1766 | Sets the process-wide variable '<var-name>' to the result of the evaluation | 1825 | Sets the process-wide variable '<var-name>' to the result of the evaluation |
1505 | 1767 | of the sample expression <expr>. The variable '<var-name>' may only be a | 1826 | of the sample expression <expr>. The variable '<var-name>' may only be a |
1506 | @@ -1785,26 +1844,6 @@ setenv <name> <value> | |||
1507 | 1785 | the configuration file sees the new value. See also "presetenv", "resetenv", | 1844 | the configuration file sees the new value. See also "presetenv", "resetenv", |
1508 | 1786 | and "unsetenv". | 1845 | and "unsetenv". |
1509 | 1787 | 1846 | ||
1510 | 1788 | set-dumpable | ||
1511 | 1789 | This option is better left disabled by default and enabled only upon a | ||
1512 | 1790 | developer's request. If it has been enabled, it may still be forcibly | ||
1513 | 1791 | disabled by prefixing it with the "no" keyword. It has no impact on | ||
1514 | 1792 | performance nor stability but will try hard to re-enable core dumps that were | ||
1515 | 1793 | possibly disabled by file size limitations (ulimit -f), core size limitations | ||
1516 | 1794 | (ulimit -c), or "dumpability" of a process after changing its UID/GID (such | ||
1517 | 1795 | as /proc/sys/fs/suid_dumpable on Linux). Core dumps might still be limited by | ||
1518 | 1796 | the current directory's permissions (check what directory the file is started | ||
1519 | 1797 | from), the chroot directory's permission (it may be needed to temporarily | ||
1520 | 1798 | disable the chroot directive or to move it to a dedicated writable location), | ||
1521 | 1799 | or any other system-specific constraint. For example, some Linux flavours are | ||
1522 | 1800 | notorious for replacing the default core file with a path to an executable | ||
1523 | 1801 | not even installed on the system (check /proc/sys/kernel/core_pattern). Often, | ||
1524 | 1802 | simply writing "core", "core.%p" or "/var/log/core/core.%p" addresses the | ||
1525 | 1803 | issue. When trying to enable this option waiting for a rare issue to | ||
1526 | 1804 | re-appear, it's often a good idea to first try to obtain such a dump by | ||
1527 | 1805 | issuing, for example, "kill -11" to the "haproxy" process and verify that it | ||
1528 | 1806 | leaves a core where expected when dying. | ||
1529 | 1807 | |||
1530 | 1808 | ssl-default-bind-ciphers <ciphers> | 1847 | ssl-default-bind-ciphers <ciphers> |
1531 | 1809 | This setting is only available when support for OpenSSL was built in. It sets | 1848 | This setting is only available when support for OpenSSL was built in. It sets |
1532 | 1810 | the default string describing the list of cipher algorithms ("cipher suite") | 1849 | the default string describing the list of cipher algorithms ("cipher suite") |
1533 | @@ -1995,6 +2034,10 @@ ssl-skip-self-issued-ca | |||
1534 | 1995 | certificates. It's useless for BoringSSL, .issuer is ignored because ocsp | 2034 | certificates. It's useless for BoringSSL, .issuer is ignored because ocsp |
1535 | 1996 | bits does not need it. Requires at least OpenSSL 1.0.2. | 2035 | bits does not need it. Requires at least OpenSSL 1.0.2. |
1536 | 1997 | 2036 | ||
1537 | 2037 | stats maxconn <connections> | ||
1538 | 2038 | By default, the stats socket is limited to 10 concurrent connections. It is | ||
1539 | 2039 | possible to change this value with "stats maxconn". | ||
1540 | 2040 | |||
1541 | 1998 | stats socket [<address:port>|<path>] [param*] | 2041 | stats socket [<address:port>|<path>] [param*] |
1542 | 1999 | Binds a UNIX socket to <path> or a TCPv4/v6 address to <address:port>. | 2042 | Binds a UNIX socket to <path> or a TCPv4/v6 address to <address:port>. |
1543 | 2000 | Connections to this socket will return various statistics outputs and even | 2043 | Connections to this socket will return various statistics outputs and even |
1544 | @@ -2011,9 +2054,12 @@ stats timeout <timeout, in milliseconds> | |||
1545 | 2011 | to change this value with "stats timeout". The value must be passed in | 2054 | to change this value with "stats timeout". The value must be passed in |
1546 | 2012 | milliseconds, or be suffixed by a time unit among { us, ms, s, m, h, d }. | 2055 | milliseconds, or be suffixed by a time unit among { us, ms, s, m, h, d }. |
1547 | 2013 | 2056 | ||
1551 | 2014 | stats maxconn <connections> | 2057 | strict-limits |
1552 | 2015 | By default, the stats socket is limited to 10 concurrent connections. It is | 2058 | Makes process fail at startup when a setrlimit fails. HAProxy tries to set the |
1553 | 2016 | possible to change this value with "stats maxconn". | 2059 | best setrlimit according to what has been calculated. If it fails, it will |
1554 | 2060 | emit a warning. This option is here to guarantee an explicit failure of | ||
1555 | 2061 | HAProxy when those limits fail. It is enabled by default. It may still be | ||
1556 | 2062 | forcibly disabled by prefixing it with the "no" keyword. | ||
1557 | 2017 | 2063 | ||
1558 | 2018 | uid <number> | 2064 | uid <number> |
1559 | 2019 | Changes the process's user ID to <number>. It is recommended that the user ID | 2065 | Changes the process's user ID to <number>. It is recommended that the user ID |
1560 | @@ -2061,42 +2107,14 @@ node <name> | |||
1561 | 2061 | nodes, it becomes easy to immediately spot what server is handling the | 2107 | nodes, it becomes easy to immediately spot what server is handling the |
1562 | 2062 | traffic. | 2108 | traffic. |
1563 | 2063 | 2109 | ||
1597 | 2064 | description <text> | 2110 | wurfl-cache-size <size> |
1598 | 2065 | Add a text that describes the instance. | 2111 | Sets the WURFL Useragent cache size. For faster lookups, already processed user |
1599 | 2066 | 2112 | agents are kept in a LRU cache : | |
1600 | 2067 | Please note that it is required to escape certain characters (# for example) | 2113 | - "0" : no cache is used. |
1601 | 2068 | and this text is inserted into a html page so you should avoid using | 2114 | - <size> : size of lru cache in elements. |
1569 | 2069 | "<" and ">" characters. | ||
1570 | 2070 | |||
1571 | 2071 | 51degrees-data-file <file path> | ||
1572 | 2072 | The path of the 51Degrees data file to provide device detection services. The | ||
1573 | 2073 | file should be unzipped and accessible by HAProxy with relevant permissions. | ||
1574 | 2074 | |||
1575 | 2075 | Please note that this option is only available when HAProxy has been | ||
1576 | 2076 | compiled with USE_51DEGREES. | ||
1577 | 2077 | |||
1578 | 2078 | 51degrees-property-name-list [<string> ...] | ||
1579 | 2079 | A list of 51Degrees property names to be load from the dataset. A full list | ||
1580 | 2080 | of names is available on the 51Degrees website: | ||
1581 | 2081 | https://51degrees.com/resources/property-dictionary | ||
1582 | 2082 | |||
1583 | 2083 | Please note that this option is only available when HAProxy has been | ||
1584 | 2084 | compiled with USE_51DEGREES. | ||
1585 | 2085 | |||
1586 | 2086 | 51degrees-property-separator <char> | ||
1587 | 2087 | A char that will be appended to every property value in a response header | ||
1588 | 2088 | containing 51Degrees results. If not set that will be set as ','. | ||
1589 | 2089 | |||
1590 | 2090 | Please note that this option is only available when HAProxy has been | ||
1591 | 2091 | compiled with USE_51DEGREES. | ||
1592 | 2092 | |||
1593 | 2093 | 51degrees-cache-size <number> | ||
1594 | 2094 | Sets the size of the 51Degrees converter cache to <number> entries. This | ||
1595 | 2095 | is an LRU cache which reminds previous device detections and their results. | ||
1596 | 2096 | By default, this cache is disabled. | ||
1602 | 2097 | 2115 | ||
1605 | 2098 | Please note that this option is only available when HAProxy has been | 2116 | Please note that this option is only available when HAProxy has been compiled |
1606 | 2099 | compiled with USE_51DEGREES. | 2117 | with USE_WURFL=1. |
1607 | 2100 | 2118 | ||
1608 | 2101 | wurfl-data-file <file path> | 2119 | wurfl-data-file <file path> |
1609 | 2102 | The path of the WURFL data file to provide device detection services. The | 2120 | The path of the WURFL data file to provide device detection services. The |
1610 | @@ -2152,22 +2170,6 @@ wurfl-patch-file [<file path>] | |||
1611 | 2152 | Please note that this option is only available when HAProxy has been compiled | 2170 | Please note that this option is only available when HAProxy has been compiled |
1612 | 2153 | with USE_WURFL=1. | 2171 | with USE_WURFL=1. |
1613 | 2154 | 2172 | ||
1614 | 2155 | wurfl-cache-size <size> | ||
1615 | 2156 | Sets the WURFL Useragent cache size. For faster lookups, already processed user | ||
1616 | 2157 | agents are kept in a LRU cache : | ||
1617 | 2158 | - "0" : no cache is used. | ||
1618 | 2159 | - <size> : size of lru cache in elements. | ||
1619 | 2160 | |||
1620 | 2161 | Please note that this option is only available when HAProxy has been compiled | ||
1621 | 2162 | with USE_WURFL=1. | ||
1622 | 2163 | |||
1623 | 2164 | strict-limits | ||
1624 | 2165 | Makes process fail at startup when a setrlimit fails. HAProxy tries to set the | ||
1625 | 2166 | best setrlimit according to what has been calculated. If it fails, it will | ||
1626 | 2167 | emit a warning. This option is here to guarantee an explicit failure of | ||
1627 | 2168 | HAProxy when those limits fail. It is enabled by default. It may still be | ||
1628 | 2169 | forcibly disabled by prefixing it with the "no" keyword. | ||
1629 | 2170 | |||
1630 | 2171 | 3.2. Performance tuning | 2173 | 3.2. Performance tuning |
1631 | 2172 | ----------------------- | 2174 | ----------------------- |
1632 | 2173 | 2175 | ||
1633 | @@ -2204,6 +2206,24 @@ max-spread-checks <delay in milliseconds> | |||
1634 | 2204 | even if the servers' check intervals are larger. When servers run with | 2206 | even if the servers' check intervals are larger. When servers run with |
1635 | 2205 | shorter intervals, their intervals will be respected though. | 2207 | shorter intervals, their intervals will be respected though. |
1636 | 2206 | 2208 | ||
1637 | 2209 | maxcompcpuusage <number> | ||
1638 | 2210 | Sets the maximum CPU usage HAProxy can reach before stopping the compression | ||
1639 | 2211 | for new requests or decreasing the compression level of current requests. | ||
1640 | 2212 | It works like 'maxcomprate' but measures CPU usage instead of incoming data | ||
1641 | 2213 | bandwidth. The value is expressed in percent of the CPU used by HAProxy. A | ||
1642 | 2214 | value of 100 disable the limit. The default value is 100. Setting a lower | ||
1643 | 2215 | value will prevent the compression work from slowing the whole process down | ||
1644 | 2216 | and from introducing high latencies. | ||
1645 | 2217 | |||
1646 | 2218 | maxcomprate <number> | ||
1647 | 2219 | Sets the maximum per-process input compression rate to <number> kilobytes | ||
1648 | 2220 | per second. For each session, if the maximum is reached, the compression | ||
1649 | 2221 | level will be decreased during the session. If the maximum is reached at the | ||
1650 | 2222 | beginning of a session, the session will not compress at all. If the maximum | ||
1651 | 2223 | is not reached, the compression level will be increased up to | ||
1652 | 2224 | tune.comp.maxlevel. A value of zero means there is no limit, this is the | ||
1653 | 2225 | default value. | ||
1654 | 2226 | |||
1655 | 2207 | maxconn <number> | 2227 | maxconn <number> |
1656 | 2208 | Sets the maximum per-process number of concurrent connections to <number>. It | 2228 | Sets the maximum per-process number of concurrent connections to <number>. It |
1657 | 2209 | is equivalent to the command-line argument "-n". Proxies will stop accepting | 2229 | is equivalent to the command-line argument "-n". Proxies will stop accepting |
1658 | @@ -2229,25 +2249,6 @@ maxconnrate <number> | |||
1659 | 2229 | value close to its expected share. Also, lowering tune.maxaccept can improve | 2249 | value close to its expected share. Also, lowering tune.maxaccept can improve |
1660 | 2230 | fairness. | 2250 | fairness. |
1661 | 2231 | 2251 | ||
1662 | 2232 | maxcomprate <number> | ||
1663 | 2233 | Sets the maximum per-process input compression rate to <number> kilobytes | ||
1664 | 2234 | per second. For each session, if the maximum is reached, the compression | ||
1665 | 2235 | level will be decreased during the session. If the maximum is reached at the | ||
1666 | 2236 | beginning of a session, the session will not compress at all. If the maximum | ||
1667 | 2237 | is not reached, the compression level will be increased up to | ||
1668 | 2238 | tune.comp.maxlevel. A value of zero means there is no limit, this is the | ||
1669 | 2239 | default value. | ||
1670 | 2240 | |||
1671 | 2241 | maxcompcpuusage <number> | ||
1672 | 2242 | Sets the maximum CPU usage HAProxy can reach before stopping the compression | ||
1673 | 2243 | for new requests or decreasing the compression level of current requests. | ||
1674 | 2244 | It works like 'maxcomprate' but measures CPU usage instead of incoming data | ||
1675 | 2245 | bandwidth. The value is expressed in percent of the CPU used by HAProxy. In | ||
1676 | 2246 | case of multiple processes (nbproc > 1), each process manages its individual | ||
1677 | 2247 | usage. A value of 100 disable the limit. The default value is 100. Setting | ||
1678 | 2248 | a lower value will prevent the compression work from slowing the whole | ||
1679 | 2249 | process down and from introducing high latencies. | ||
1680 | 2250 | |||
1681 | 2251 | maxpipes <number> | 2252 | maxpipes <number> |
1682 | 2252 | Sets the maximum per-process number of pipes to <number>. Currently, pipes | 2253 | Sets the maximum per-process number of pipes to <number>. Currently, pipes |
1683 | 2253 | are only used by kernel-based tcp splicing. Since a pipe contains two file | 2254 | are only used by kernel-based tcp splicing. Since a pipe contains two file |
1684 | @@ -2323,17 +2324,21 @@ noepoll | |||
1685 | 2323 | equivalent to the command-line argument "-de". The next polling system | 2324 | equivalent to the command-line argument "-de". The next polling system |
1686 | 2324 | used will generally be "poll". See also "nopoll". | 2325 | used will generally be "poll". See also "nopoll". |
1687 | 2325 | 2326 | ||
1688 | 2326 | nokqueue | ||
1689 | 2327 | Disables the use of the "kqueue" event polling system on BSD. It is | ||
1690 | 2328 | equivalent to the command-line argument "-dk". The next polling system | ||
1691 | 2329 | used will generally be "poll". See also "nopoll". | ||
1692 | 2330 | |||
1693 | 2331 | noevports | 2327 | noevports |
1694 | 2332 | Disables the use of the event ports event polling system on SunOS systems | 2328 | Disables the use of the event ports event polling system on SunOS systems |
1695 | 2333 | derived from Solaris 10 and later. It is equivalent to the command-line | 2329 | derived from Solaris 10 and later. It is equivalent to the command-line |
1696 | 2334 | argument "-dv". The next polling system used will generally be "poll". See | 2330 | argument "-dv". The next polling system used will generally be "poll". See |
1697 | 2335 | also "nopoll". | 2331 | also "nopoll". |
1698 | 2336 | 2332 | ||
1699 | 2333 | nogetaddrinfo | ||
1700 | 2334 | Disables the use of getaddrinfo(3) for name resolving. It is equivalent to | ||
1701 | 2335 | the command line argument "-dG". Deprecated gethostbyname(3) will be used. | ||
1702 | 2336 | |||
1703 | 2337 | nokqueue | ||
1704 | 2338 | Disables the use of the "kqueue" event polling system on BSD. It is | ||
1705 | 2339 | equivalent to the command-line argument "-dk". The next polling system | ||
1706 | 2340 | used will generally be "poll". See also "nopoll". | ||
1707 | 2341 | |||
1708 | 2337 | nopoll | 2342 | nopoll |
1709 | 2338 | Disables the use of the "poll" event polling system. It is equivalent to the | 2343 | Disables the use of the "poll" event polling system. It is equivalent to the |
1710 | 2339 | command-line argument "-dp". The next polling system used will be "select". | 2344 | command-line argument "-dp". The next polling system used will be "select". |
1711 | @@ -2341,6 +2346,10 @@ nopoll | |||
1712 | 2341 | platforms supported by HAProxy. See also "nokqueue", "noepoll" and | 2346 | platforms supported by HAProxy. See also "nokqueue", "noepoll" and |
1713 | 2342 | "noevports". | 2347 | "noevports". |
1714 | 2343 | 2348 | ||
1715 | 2349 | noreuseport | ||
1716 | 2350 | Disables the use of SO_REUSEPORT - see socket(7). It is equivalent to the | ||
1717 | 2351 | command line argument "-dR". | ||
1718 | 2352 | |||
1719 | 2344 | nosplice | 2353 | nosplice |
1720 | 2345 | Disables the use of kernel tcp splicing between sockets on Linux. It is | 2354 | Disables the use of kernel tcp splicing between sockets on Linux. It is |
1721 | 2346 | equivalent to the command line argument "-dS". Data will then be copied | 2355 | equivalent to the command line argument "-dS". Data will then be copied |
1722 | @@ -2351,14 +2360,6 @@ nosplice | |||
1723 | 2351 | case of doubt. See also "option splice-auto", "option splice-request" and | 2360 | case of doubt. See also "option splice-auto", "option splice-request" and |
1724 | 2352 | "option splice-response". | 2361 | "option splice-response". |
1725 | 2353 | 2362 | ||
1726 | 2354 | nogetaddrinfo | ||
1727 | 2355 | Disables the use of getaddrinfo(3) for name resolving. It is equivalent to | ||
1728 | 2356 | the command line argument "-dG". Deprecated gethostbyname(3) will be used. | ||
1729 | 2357 | |||
1730 | 2358 | noreuseport | ||
1731 | 2359 | Disables the use of SO_REUSEPORT - see socket(7). It is equivalent to the | ||
1732 | 2360 | command line argument "-dR". | ||
1733 | 2361 | |||
1734 | 2362 | profiling.memory { on | off } | 2363 | profiling.memory { on | off } |
1735 | 2363 | Enables ('on') or disables ('off') per-function memory profiling. This will | 2364 | Enables ('on') or disables ('off') per-function memory profiling. This will |
1736 | 2364 | keep usage statistics of malloc/calloc/realloc/free calls anywhere in the | 2365 | keep usage statistics of malloc/calloc/realloc/free calls anywhere in the |
1737 | @@ -2604,18 +2605,18 @@ tune.lua.session-timeout <timeout> | |||
1738 | 2604 | counts only the pure Lua runtime. If the Lua does a sleep, the sleep is | 2605 | counts only the pure Lua runtime. If the Lua does a sleep, the sleep is |
1739 | 2605 | not taken in account. The default timeout is 4s. | 2606 | not taken in account. The default timeout is 4s. |
1740 | 2606 | 2607 | ||
1741 | 2607 | tune.lua.task-timeout <timeout> | ||
1742 | 2608 | Purpose is the same as "tune.lua.session-timeout", but this timeout is | ||
1743 | 2609 | dedicated to the tasks. By default, this timeout isn't set because a task may | ||
1744 | 2610 | remain alive during of the lifetime of HAProxy. For example, a task used to | ||
1745 | 2611 | check servers. | ||
1746 | 2612 | |||
1747 | 2613 | tune.lua.service-timeout <timeout> | 2608 | tune.lua.service-timeout <timeout> |
1748 | 2614 | This is the execution timeout for the Lua services. This is useful for | 2609 | This is the execution timeout for the Lua services. This is useful for |
1749 | 2615 | preventing infinite loops or spending too much time in Lua. This timeout | 2610 | preventing infinite loops or spending too much time in Lua. This timeout |
1750 | 2616 | counts only the pure Lua runtime. If the Lua does a sleep, the sleep is | 2611 | counts only the pure Lua runtime. If the Lua does a sleep, the sleep is |
1751 | 2617 | not taken in account. The default timeout is 4s. | 2612 | not taken in account. The default timeout is 4s. |
1752 | 2618 | 2613 | ||
1753 | 2614 | tune.lua.task-timeout <timeout> | ||
1754 | 2615 | Purpose is the same as "tune.lua.session-timeout", but this timeout is | ||
1755 | 2616 | dedicated to the tasks. By default, this timeout isn't set because a task may | ||
1756 | 2617 | remain alive during of the lifetime of HAProxy. For example, a task used to | ||
1757 | 2618 | check servers. | ||
1758 | 2619 | |||
1759 | 2619 | tune.maxaccept <number> | 2620 | tune.maxaccept <number> |
1760 | 2620 | Sets the maximum number of consecutive connections a process may accept in a | 2621 | Sets the maximum number of consecutive connections a process may accept in a |
1761 | 2621 | row before switching to other work. In single process mode, higher numbers | 2622 | row before switching to other work. In single process mode, higher numbers |
1762 | @@ -2756,6 +2757,26 @@ tune.ssl.cachesize <number> | |||
1763 | 2756 | pre-allocated upon startup and are shared between all processes if "nbproc" | 2757 | pre-allocated upon startup and are shared between all processes if "nbproc" |
1764 | 2757 | is greater than 1. Setting this value to 0 disables the SSL session cache. | 2758 | is greater than 1. Setting this value to 0 disables the SSL session cache. |
1765 | 2758 | 2759 | ||
1766 | 2760 | tune.ssl.capture-cipherlist-size <number> | ||
1767 | 2761 | Sets the maximum size of the buffer used for capturing client hello cipher | ||
1768 | 2762 | list, extensions list, elliptic curves list and elliptic curve point | ||
1769 | 2763 | formats. If the value is 0 (default value) the capture is disabled, | ||
1770 | 2764 | otherwise a buffer is allocated for each SSL/TLS connection. | ||
1771 | 2765 | |||
1772 | 2766 | tune.ssl.default-dh-param <number> | ||
1773 | 2767 | Sets the maximum size of the Diffie-Hellman parameters used for generating | ||
1774 | 2768 | the ephemeral/temporary Diffie-Hellman key in case of DHE key exchange. The | ||
1775 | 2769 | final size will try to match the size of the server's RSA (or DSA) key (e.g, | ||
1776 | 2770 | a 2048 bits temporary DH key for a 2048 bits RSA key), but will not exceed | ||
1777 | 2771 | this maximum value. Only 1024 or higher values are allowed. Higher values | ||
1778 | 2772 | will increase the CPU load, and values greater than 1024 bits are not | ||
1779 | 2773 | supported by Java 7 and earlier clients. This value is not used if static | ||
1780 | 2774 | Diffie-Hellman parameters are supplied either directly in the certificate | ||
1781 | 2775 | file or by using the ssl-dh-param-file parameter. | ||
1782 | 2776 | If there is neither a default-dh-param nor a ssl-dh-param-file defined, and | ||
1783 | 2777 | if the server's PEM file of a given frontend does not specify its own DH | ||
1784 | 2778 | parameters, then DHE ciphers will be unavailable for this frontend. | ||
1785 | 2779 | |||
1786 | 2759 | tune.ssl.force-private-cache | 2780 | tune.ssl.force-private-cache |
1787 | 2760 | This option disables SSL session cache sharing between all processes. It | 2781 | This option disables SSL session cache sharing between all processes. It |
1788 | 2761 | should normally not be used since it will force many renegotiations due to | 2782 | should normally not be used since it will force many renegotiations due to |
1789 | @@ -2824,28 +2845,12 @@ tune.ssl.maxrecord <number> | |||
1790 | 2824 | best value. HAProxy will automatically switch to this setting after an idle | 2845 | best value. HAProxy will automatically switch to this setting after an idle |
1791 | 2825 | stream has been detected (see tune.idletimer above). | 2846 | stream has been detected (see tune.idletimer above). |
1792 | 2826 | 2847 | ||
1793 | 2827 | tune.ssl.default-dh-param <number> | ||
1794 | 2828 | Sets the maximum size of the Diffie-Hellman parameters used for generating | ||
1795 | 2829 | the ephemeral/temporary Diffie-Hellman key in case of DHE key exchange. The | ||
1796 | 2830 | final size will try to match the size of the server's RSA (or DSA) key (e.g, | ||
1797 | 2831 | a 2048 bits temporary DH key for a 2048 bits RSA key), but will not exceed | ||
1798 | 2832 | this maximum value. Default value if 2048. Only 1024 or higher values are | ||
1799 | 2833 | allowed. Higher values will increase the CPU load, and values greater than | ||
1800 | 2834 | 1024 bits are not supported by Java 7 and earlier clients. This value is not | ||
1801 | 2835 | used if static Diffie-Hellman parameters are supplied either directly | ||
1802 | 2836 | in the certificate file or by using the ssl-dh-param-file parameter. | ||
1803 | 2837 | |||
1804 | 2838 | tune.ssl.ssl-ctx-cache-size <number> | 2848 | tune.ssl.ssl-ctx-cache-size <number> |
1805 | 2839 | Sets the size of the cache used to store generated certificates to <number> | 2849 | Sets the size of the cache used to store generated certificates to <number> |
1806 | 2840 | entries. This is a LRU cache. Because generating a SSL certificate | 2850 | entries. This is a LRU cache. Because generating a SSL certificate |
1807 | 2841 | dynamically is expensive, they are cached. The default cache size is set to | 2851 | dynamically is expensive, they are cached. The default cache size is set to |
1808 | 2842 | 1000 entries. | 2852 | 1000 entries. |
1809 | 2843 | 2853 | ||
1810 | 2844 | tune.ssl.capture-cipherlist-size <number> | ||
1811 | 2845 | Sets the maximum size of the buffer used for capturing client-hello cipher | ||
1812 | 2846 | list. If the value is 0 (default value) the capture is disabled, otherwise | ||
1813 | 2847 | a buffer is allocated for each SSL/TLS connection. | ||
1814 | 2848 | |||
1815 | 2849 | tune.vars.global-max-size <size> | 2854 | tune.vars.global-max-size <size> |
1816 | 2850 | tune.vars.proc-max-size <size> | 2855 | tune.vars.proc-max-size <size> |
1817 | 2851 | tune.vars.reqres-max-size <size> | 2856 | tune.vars.reqres-max-size <size> |
1818 | @@ -3619,7 +3624,7 @@ http-error X X X X | |||
1819 | 3619 | http-request - X X X | 3624 | http-request - X X X |
1820 | 3620 | http-response - X X X | 3625 | http-response - X X X |
1821 | 3621 | http-reuse X - X X | 3626 | http-reuse X - X X |
1823 | 3622 | http-send-name-header - - X X | 3627 | http-send-name-header X - X X |
1824 | 3623 | id - X X X | 3628 | id - X X X |
1825 | 3624 | ignore-persist - - X X | 3629 | ignore-persist - - X X |
1826 | 3625 | load-server-state-from-file X - X X | 3630 | load-server-state-from-file X - X X |
1827 | @@ -3677,7 +3682,7 @@ option socket-stats (*) X X X - | |||
1828 | 3677 | option splice-auto (*) X X X X | 3682 | option splice-auto (*) X X X X |
1829 | 3678 | option splice-request (*) X X X X | 3683 | option splice-request (*) X X X X |
1830 | 3679 | option splice-response (*) X X X X | 3684 | option splice-response (*) X X X X |
1832 | 3680 | option spop-check - - - X | 3685 | option spop-check X - X X |
1833 | 3681 | option srvtcpka (*) X - X X | 3686 | option srvtcpka (*) X - X X |
1834 | 3682 | option ssl-hello-chk X - X X | 3687 | option ssl-hello-chk X - X X |
1835 | 3683 | -- keyword -------------------------- defaults - frontend - listen -- backend - | 3688 | -- keyword -------------------------- defaults - frontend - listen -- backend - |
1836 | @@ -6162,7 +6167,8 @@ http-request do-resolve(<var>,<resolvers>,[ipv4,ipv6]) <expr> : | |||
1837 | 6162 | based on information found in the request (IE a Host header). | 6167 | based on information found in the request (IE a Host header). |
1838 | 6163 | If this action is used to find the server's IP address (using the | 6168 | If this action is used to find the server's IP address (using the |
1839 | 6164 | "set-dst" action), then the server IP address in the backend must be set | 6169 | "set-dst" action), then the server IP address in the backend must be set |
1841 | 6165 | to 0.0.0.0. | 6170 | to 0.0.0.0. The do-resolve action takes an host-only parameter, any port must |
1842 | 6171 | be removed from the string. | ||
1843 | 6166 | 6172 | ||
1844 | 6167 | Example: | 6173 | Example: |
1845 | 6168 | resolvers mydns | 6174 | resolvers mydns |
1846 | @@ -6177,7 +6183,7 @@ http-request do-resolve(<var>,<resolvers>,[ipv4,ipv6]) <expr> : | |||
1847 | 6177 | 6183 | ||
1848 | 6178 | frontend fe | 6184 | frontend fe |
1849 | 6179 | bind 10.42.0.1:80 | 6185 | bind 10.42.0.1:80 |
1851 | 6180 | http-request do-resolve(txn.myip,mydns,ipv4) hdr(Host),lower | 6186 | http-request do-resolve(txn.myip,mydns,ipv4) hdr(Host),lower,regsub(:[0-9]*$,) |
1852 | 6181 | http-request capture var(txn.myip) len 40 | 6187 | http-request capture var(txn.myip) len 40 |
1853 | 6182 | 6188 | ||
1854 | 6183 | # return 503 when the variable is not set, | 6189 | # return 503 when the variable is not set, |
1855 | @@ -6814,9 +6820,11 @@ http-request set-uri <fmt> [ { if | unless } <condition> ] | |||
1856 | 6814 | 6820 | ||
1857 | 6815 | This rewrites the request URI with the result of the evaluation of format | 6821 | This rewrites the request URI with the result of the evaluation of format |
1858 | 6816 | string <fmt>. The scheme, authority, path and query string are all replaced | 6822 | string <fmt>. The scheme, authority, path and query string are all replaced |
1862 | 6817 | at once. This can be used to rewrite hosts in front of proxies, or to | 6823 | at once. This can be used to rewrite hosts in front of proxies, or to perform |
1863 | 6818 | perform complex modifications to the URI such as moving parts between the | 6824 | complex modifications to the URI such as moving parts between the path and |
1864 | 6819 | path and the query string. | 6825 | the query string. If an absolute URI is set, it will be sent as is to |
1865 | 6826 | HTTP/1.1 servers. If it is not the desired behavior, the host, the path | ||
1866 | 6827 | and/or the query string should be set separately. | ||
1867 | 6820 | See also "http-request set-path" and "http-request set-query". | 6828 | See also "http-request set-path" and "http-request set-query". |
1868 | 6821 | 6829 | ||
1869 | 6822 | http-request set-var(<var-name>) <expr> [ { if | unless } <condition> ] | 6830 | http-request set-var(<var-name>) <expr> [ { if | unless } <condition> ] |
1870 | @@ -7541,7 +7549,26 @@ http-reuse { never | safe | aggressive | always } | |||
1871 | 7541 | because almost no new connection will be established while idle connections | 7549 | because almost no new connection will be established while idle connections |
1872 | 7542 | remain available. This is particularly true with the "always" strategy. | 7550 | remain available. This is particularly true with the "always" strategy. |
1873 | 7543 | 7551 | ||
1875 | 7544 | See also : "option http-keep-alive", "server maxconn" | 7552 | The rules to decide to keep an idle connection opened or to close it after |
1876 | 7553 | processing are also governed by the "tune.pool-low-fd-ratio" (default: 20%) | ||
1877 | 7554 | and "tune.pool-high-fd-ratio" (default: 25%). These correspond to the | ||
1878 | 7555 | percentage of total file descriptors spent in idle connections above which | ||
1879 | 7556 | haproxy will respectively refrain from keeping a connection opened after a | ||
1880 | 7557 | response, and actively kill idle connections. Some setups using a very high | ||
1881 | 7558 | ratio of idle connections, either because of too low a global "maxconn", or | ||
1882 | 7559 | due to a lot of HTTP/2 or HTTP/3 traffic on the frontend (few connections) | ||
1883 | 7560 | but HTTP/1 connections on the backend, may observe a lower reuse rate because | ||
1884 | 7561 | too few connections are kept open. It may be desirable in this case to adjust | ||
1885 | 7562 | such thresholds or simply to increase the global "maxconn" value. | ||
1886 | 7563 | |||
1887 | 7564 | Similarly, when thread groups are explicitly enabled, it is important to | ||
1888 | 7565 | understand that idle connections are only usable between threads from a same | ||
1889 | 7566 | group. As such it may happen that unfair load between groups leads to more | ||
1890 | 7567 | idle connections being needed, causing a lower reuse rate. The same solution | ||
1891 | 7568 | may then be applied (increase global "maxconn" or increase pool ratios). | ||
1892 | 7569 | |||
1893 | 7570 | See also : "option http-keep-alive", "server maxconn", "thread-groups", | ||
1894 | 7571 | "tune.pool-high-fd-ratio", "tune.pool-low-fd-ratio" | ||
1895 | 7545 | 7572 | ||
1896 | 7546 | 7573 | ||
1897 | 7547 | http-send-name-header [<header>] | 7574 | http-send-name-header [<header>] |
1898 | @@ -8073,7 +8100,9 @@ monitor-uri <uri> | |||
1899 | 8073 | Monitor requests are processed very early, just after the request is parsed | 8100 | Monitor requests are processed very early, just after the request is parsed |
1900 | 8074 | and even before any "http-request". The only rulesets applied before are the | 8101 | and even before any "http-request". The only rulesets applied before are the |
1901 | 8075 | tcp-request ones. They cannot be logged either, and it is the intended | 8102 | tcp-request ones. They cannot be logged either, and it is the intended |
1903 | 8076 | purpose. They are only used to report HAProxy's health to an upper component, | 8103 | purpose. Only one URI may be configured for monitoring; when multiple |
1904 | 8104 | "monitor-uri" statements are present, the last one will define the URI to | ||
1905 | 8105 | be used. They are only used to report HAProxy's health to an upper component, | ||
1906 | 8077 | nothing more. However, it is possible to add any number of conditions using | 8106 | nothing more. However, it is possible to add any number of conditions using |
1907 | 8078 | "monitor fail" and ACLs so that the result can be adjusted to whatever check | 8107 | "monitor fail" and ACLs so that the result can be adjusted to whatever check |
1908 | 8079 | can be imagined (most often the number of available servers in a backend). | 8108 | can be imagined (most often the number of available servers in a backend). |
1909 | @@ -9350,7 +9379,7 @@ no option persist | |||
1910 | 9350 | See also : "option redispatch", "retries", "force-persist" | 9379 | See also : "option redispatch", "retries", "force-persist" |
1911 | 9351 | 9380 | ||
1912 | 9352 | 9381 | ||
1914 | 9353 | option pgsql-check [ user <username> ] | 9382 | option pgsql-check user <username> |
1915 | 9354 | Use PostgreSQL health checks for server testing | 9383 | Use PostgreSQL health checks for server testing |
1916 | 9355 | May be used in sections : defaults | frontend | listen | backend | 9384 | May be used in sections : defaults | frontend | listen | backend |
1917 | 9356 | yes | no | yes | yes | 9385 | yes | no | yes | yes |
1918 | @@ -9610,7 +9639,7 @@ no option splice-response | |||
1919 | 9610 | option spop-check | 9639 | option spop-check |
1920 | 9611 | Use SPOP health checks for server testing | 9640 | Use SPOP health checks for server testing |
1921 | 9612 | May be used in sections : defaults | frontend | listen | backend | 9641 | May be used in sections : defaults | frontend | listen | backend |
1923 | 9613 | no | no | no | yes | 9642 | yes | no | yes | yes |
1924 | 9614 | Arguments : none | 9643 | Arguments : none |
1925 | 9615 | 9644 | ||
1926 | 9616 | It is possible to test that the server correctly talks SPOP protocol instead | 9645 | It is possible to test that the server correctly talks SPOP protocol instead |
1927 | @@ -10175,24 +10204,26 @@ redirect scheme <sch> [code <code>] <option> [{if | unless} <condition>] | |||
1928 | 10175 | 10204 | ||
1929 | 10176 | 10205 | ||
1930 | 10177 | retries <value> | 10206 | retries <value> |
1932 | 10178 | Set the number of retries to perform on a server after a connection failure | 10207 | Set the number of retries to perform on a server after a failure |
1933 | 10179 | May be used in sections: defaults | frontend | listen | backend | 10208 | May be used in sections: defaults | frontend | listen | backend |
1934 | 10180 | yes | no | yes | yes | 10209 | yes | no | yes | yes |
1935 | 10181 | Arguments : | 10210 | Arguments : |
1939 | 10182 | <value> is the number of times a connection attempt should be retried on | 10211 | <value> is the number of times a request or connection attempt should be |
1940 | 10183 | a server when a connection either is refused or times out. The | 10212 | retried on a server after a failure. |
1938 | 10184 | default value is 3. | ||
1941 | 10185 | 10213 | ||
1945 | 10186 | It is important to understand that this value applies to the number of | 10214 | By default, retries apply only to new connection attempts. However, when |
1946 | 10187 | connection attempts, not full requests. When a connection has effectively | 10215 | the "retry-on" directive is used, other conditions might trigger a retry |
1947 | 10188 | been established to a server, there will be no more retry. | 10216 | (e.g. empty response, undesired status code), and each of them will count |
1948 | 10217 | one attempt, and when the total number attempts reaches the value here, an | ||
1949 | 10218 | error will be returned. | ||
1950 | 10189 | 10219 | ||
1951 | 10190 | In order to avoid immediate reconnections to a server which is restarting, | 10220 | In order to avoid immediate reconnections to a server which is restarting, |
1952 | 10191 | a turn-around timer of min("timeout connect", one second) is applied before | 10221 | a turn-around timer of min("timeout connect", one second) is applied before |
1954 | 10192 | a retry occurs. | 10222 | a retry occurs on the same server. |
1955 | 10193 | 10223 | ||
1958 | 10194 | When "option redispatch" is set, the last retry may be performed on another | 10224 | When "option redispatch" is set, some retries may be performed on another |
1959 | 10195 | server even if a cookie references a different server. | 10225 | server even if a cookie references a different server. By default this will |
1960 | 10226 | only be the last retry unless an argument is passed to "option redispatch". | ||
1961 | 10196 | 10227 | ||
1962 | 10197 | See also : "option redispatch" | 10228 | See also : "option redispatch" |
1963 | 10198 | 10229 | ||
1964 | @@ -12423,7 +12454,7 @@ tcp-request content <action> [{if | unless} <condition>] | |||
1965 | 12423 | evaluated. | 12454 | evaluated. |
1966 | 12424 | 12455 | ||
1967 | 12425 | Example: | 12456 | Example: |
1969 | 12426 | tcp-request content use-service lua.deny { src -f /etc/haproxy/blacklist.lst } | 12457 | tcp-request content use-service lua.deny if { src -f /etc/haproxy/blacklist.lst } |
1970 | 12427 | 12458 | ||
1971 | 12428 | Example: | 12459 | Example: |
1972 | 12429 | 12460 | ||
1973 | @@ -14986,8 +15017,10 @@ sni <expression> | |||
1974 | 14986 | The "sni" parameter evaluates the sample fetch expression, converts it to a | 15017 | The "sni" parameter evaluates the sample fetch expression, converts it to a |
1975 | 14987 | string and uses the result as the host name sent in the SNI TLS extension to | 15018 | string and uses the result as the host name sent in the SNI TLS extension to |
1976 | 14988 | the server. A typical use case is to send the SNI received from the client in | 15019 | the server. A typical use case is to send the SNI received from the client in |
1979 | 14989 | a bridged HTTPS scenario, using the "ssl_fc_sni" sample fetch for the | 15020 | a bridged TCP/SSL scenario, using the "ssl_fc_sni" sample fetch for the |
1980 | 14990 | expression, though alternatives such as req.hdr(host) can also make sense. If | 15021 | expression. THIS MUST NOT BE USED FOR HTTPS, where req.hdr(host) should be |
1981 | 15022 | used instead, since SNI in HTTPS must always match the Host field and clients | ||
1982 | 15023 | are allowed to use different host names over the same connection). If | ||
1983 | 14991 | "verify required" is set (which is the recommended setting), the resulting | 15024 | "verify required" is set (which is the recommended setting), the resulting |
1984 | 14992 | name will also be matched against the server certificate's names. See the | 15025 | name will also be matched against the server certificate's names. See the |
1985 | 14993 | "verify" directive for more details. If you want to set a SNI for health | 15026 | "verify" directive for more details. If you want to set a SNI for health |
1986 | @@ -15679,7 +15712,11 @@ possible to convert the sample to lowercase before matching, like this : | |||
1987 | 15679 | All ACL-specific criteria imply a default matching method. Most often, these | 15712 | All ACL-specific criteria imply a default matching method. Most often, these |
1988 | 15680 | criteria are composed by concatenating the name of the original sample fetch | 15713 | criteria are composed by concatenating the name of the original sample fetch |
1989 | 15681 | method and the matching method. For example, "hdr_beg" applies the "beg" match | 15714 | method and the matching method. For example, "hdr_beg" applies the "beg" match |
1991 | 15682 | to samples retrieved using the "hdr" fetch method. Since all ACL-specific | 15715 | to samples retrieved using the "hdr" fetch method. This matching method is only |
1992 | 15716 | usable when the keyword is used alone, without any converter. In case any such | ||
1993 | 15717 | converter were to be applied after such an ACL keyword, the default matching | ||
1994 | 15718 | method from the ACL keyword is simply ignored since what will matter for the | ||
1995 | 15719 | matching is the output type of the last converter. Since all ACL-specific | ||
1996 | 15683 | criteria rely on a sample fetch method, it is always possible instead to use | 15720 | criteria rely on a sample fetch method, it is always possible instead to use |
1997 | 15684 | the original sample fetch method and the explicit matching method using "-m". | 15721 | the original sample fetch method and the explicit matching method using "-m". |
1998 | 15685 | 15722 | ||
1999 | @@ -15805,13 +15842,24 @@ different forms : | |||
2000 | 15805 | - suffix match (-m end) : the patterns are compared with the end of the | 15842 | - suffix match (-m end) : the patterns are compared with the end of the |
2001 | 15806 | extracted string, and the ACL matches if any of them matches. | 15843 | extracted string, and the ACL matches if any of them matches. |
2002 | 15807 | 15844 | ||
2010 | 15808 | - subdir match (-m dir) : the patterns are looked up inside the extracted | 15845 | - subdir match (-m dir) : the patterns are looked up anywhere inside the |
2011 | 15809 | string, delimited with slashes ("/"), and the ACL matches if any of them | 15846 | extracted string, delimited with slashes ("/"), the beginning or the end |
2012 | 15810 | matches. | 15847 | of the string. The ACL matches if any of them matches. As such, the string |
2013 | 15811 | 15848 | "/images/png/logo/32x32.png", would match "/images", "/images/png", | |
2014 | 15812 | - domain match (-m dom) : the patterns are looked up inside the extracted | 15849 | "images/png", "/png/logo", "logo/32x32.png" or "32x32.png" but not "png" |
2015 | 15813 | string, delimited with dots ("."), and the ACL matches if any of them | 15850 | nor "32x32". |
2016 | 15814 | matches. | 15851 | |
2017 | 15852 | - domain match (-m dom) : the patterns are looked up anywhere inside the | ||
2018 | 15853 | extracted string, delimited with dots ("."), colons (":"), slashes ("/"), | ||
2019 | 15854 | question marks ("?"), the beginning or the end of the string. This is made | ||
2020 | 15855 | to be used with URLs. Leading and trailing delimiters in the pattern are | ||
2021 | 15856 | ignored. The ACL matches if any of them matches. As such, in the example | ||
2022 | 15857 | string "http://www1.dc-eu.example.com:80/blah", the patterns "http", | ||
2023 | 15858 | "www1", ".www1", "dc-eu", "example", "com", "80", "dc-eu.example", | ||
2024 | 15859 | "blah", ":www1:", "dc-eu.example:80" would match, but not "eu" nor "dc". | ||
2025 | 15860 | Using it to match domain suffixes for filtering or routing is generally | ||
2026 | 15861 | not a good idea, as the routing could easily be fooled by prepending the | ||
2027 | 15862 | matching prefix in front of another domain for example. | ||
2028 | 15815 | 15863 | ||
2029 | 15816 | String matching applies to verbatim strings as they are passed, with the | 15864 | String matching applies to verbatim strings as they are passed, with the |
2030 | 15817 | exception of the backslash ("\") which makes it possible to escape some | 15865 | exception of the backslash ("\") which makes it possible to escape some |
2031 | @@ -18860,6 +18908,16 @@ ssl_fc_sni : string | |||
2032 | 18860 | requires that the SSL library is built with support for TLS extensions | 18908 | requires that the SSL library is built with support for TLS extensions |
2033 | 18861 | enabled (check haproxy -vv). | 18909 | enabled (check haproxy -vv). |
2034 | 18862 | 18910 | ||
2035 | 18911 | CAUTION! Except under very specific conditions, it is normally not correct to | ||
2036 | 18912 | use this field as a substitute for the HTTP "Host" header field. For example, | ||
2037 | 18913 | when forwarding an HTTPS connection to a server, the SNI field must be set | ||
2038 | 18914 | from the HTTP Host header field using "req.hdr(host)" and not from the front | ||
2039 | 18915 | SNI value. The reason is that SNI is solely used to select the certificate | ||
2040 | 18916 | the server side will present, and that clients are then allowed to send | ||
2041 | 18917 | requests with different Host values as long as they match the names in the | ||
2042 | 18918 | certificate. As such, "ssl_fc_sni" should normally not be used as an argument | ||
2043 | 18919 | to the "sni" server keyword, unless the backend works in TCP mode. | ||
2044 | 18920 | |||
2045 | 18863 | ACL derivatives : | 18921 | ACL derivatives : |
2046 | 18864 | ssl_fc_sni_end : suffix match | 18922 | ssl_fc_sni_end : suffix match |
2047 | 18865 | ssl_fc_sni_reg : regex match | 18923 | ssl_fc_sni_reg : regex match |
2048 | @@ -22093,8 +22151,8 @@ Optionally, a prefix could be used to force the address family and/or the | |||
2049 | 22093 | socket type and the transport method. | 22151 | socket type and the transport method. |
2050 | 22094 | 22152 | ||
2051 | 22095 | 22153 | ||
2054 | 22096 | 11.1 Address family prefixes | 22154 | 11.1. Address family prefixes |
2055 | 22097 | ---------------------------- | 22155 | ----------------------------- |
2056 | 22098 | 22156 | ||
2057 | 22099 | 'abns@<name>' following <name> is an abstract namespace (Linux only). | 22157 | 'abns@<name>' following <name> is an abstract namespace (Linux only). |
2058 | 22100 | 22158 | ||
2059 | @@ -22129,8 +22187,8 @@ socket type and the transport method. | |||
2060 | 22129 | start by slash '/'. | 22187 | start by slash '/'. |
2061 | 22130 | 22188 | ||
2062 | 22131 | 22189 | ||
2065 | 22132 | 11.2 Socket type prefixes | 22190 | 11.2. Socket type prefixes |
2066 | 22133 | ------------------------- | 22191 | -------------------------- |
2067 | 22134 | 22192 | ||
2068 | 22135 | Previous "Address family prefixes" can also be prefixed to force the socket | 22193 | Previous "Address family prefixes" can also be prefixed to force the socket |
2069 | 22136 | type and the transport method. The default depends of the statement using | 22194 | type and the transport method. The default depends of the statement using |
2070 | @@ -22139,7 +22197,7 @@ This is the case for "log" statement where the default is syslog over UDP | |||
2071 | 22139 | but we could force to use syslog over TCP. | 22197 | but we could force to use syslog over TCP. |
2072 | 22140 | 22198 | ||
2073 | 22141 | Those prefixes were designed for internal purpose and users should | 22199 | Those prefixes were designed for internal purpose and users should |
2075 | 22142 | instead use aliases of the next section "11.5.3 Protocol prefixes". | 22200 | instead use aliases of the next section "11.3 Protocol prefixes". |
2076 | 22143 | 22201 | ||
2077 | 22144 | If users need one those prefixes to perform what they expect because | 22202 | If users need one those prefixes to perform what they expect because |
2078 | 22145 | they can not configure the same using the protocol prefixes, they should | 22203 | they can not configure the same using the protocol prefixes, they should |
2079 | @@ -22152,8 +22210,8 @@ report this to the maintainers. | |||
2080 | 22152 | to "datagram". | 22210 | to "datagram". |
2081 | 22153 | 22211 | ||
2082 | 22154 | 22212 | ||
2085 | 22155 | 11.3 Protocol prefixes | 22213 | 11.3. Protocol prefixes |
2086 | 22156 | ---------------------- | 22214 | ----------------------- |
2087 | 22157 | 22215 | ||
2088 | 22158 | 'tcp@<address>[:port1[-port2]]' following <address> is considered as an IPv4 | 22216 | 'tcp@<address>[:port1[-port2]]' following <address> is considered as an IPv4 |
2089 | 22159 | or IPv6 address depending of the syntax but | 22217 | or IPv6 address depending of the syntax but |
2090 | @@ -22190,14 +22248,14 @@ report this to the maintainers. | |||
2091 | 22190 | method is forced to "datagram". Depending on | 22248 | method is forced to "datagram". Depending on |
2092 | 22191 | the statement using this address, a port or | 22249 | the statement using this address, a port or |
2093 | 22192 | port range can or must be specified. | 22250 | port range can or must be specified. |
2095 | 22193 | It is considered as an alias of 'stream+ipv4@'. | 22251 | It is considered as an alias of 'dgram+ipv4@'. |
2096 | 22194 | 22252 | ||
2097 | 22195 | 'udp6@<address>[:port1[-port2]]' following <address> is always considered as | 22253 | 'udp6@<address>[:port1[-port2]]' following <address> is always considered as |
2098 | 22196 | an IPv6 address but socket type and transport | 22254 | an IPv6 address but socket type and transport |
2099 | 22197 | method is forced to "datagram". Depending on | 22255 | method is forced to "datagram". Depending on |
2100 | 22198 | the statement using this address, a port or | 22256 | the statement using this address, a port or |
2101 | 22199 | port range can or must be specified. | 22257 | port range can or must be specified. |
2103 | 22200 | It is considered as an alias of 'stream+ipv4@'. | 22258 | It is considered as an alias of 'dgram+ipv4@'. |
2104 | 22201 | 22259 | ||
2105 | 22202 | 'uxdg@<path>' following string is considered as a unix socket <path> but | 22260 | 'uxdg@<path>' following string is considered as a unix socket <path> but |
2106 | 22203 | transport method is forced to "datagram". It is considered as | 22261 | transport method is forced to "datagram". It is considered as |
2107 | diff --git a/doc/intro.txt b/doc/intro.txt | |||
2108 | index 325ba76..d6e8648 100644 | |||
2109 | --- a/doc/intro.txt | |||
2110 | +++ b/doc/intro.txt | |||
2111 | @@ -41,6 +41,7 @@ Summary | |||
2112 | 41 | 3.3.5. Load balancing | 41 | 3.3.5. Load balancing |
2113 | 42 | 3.3.6. Stickiness | 42 | 3.3.6. Stickiness |
2114 | 43 | 3.3.7. Logging | 43 | 3.3.7. Logging |
2115 | 44 | 3.3.8. Statistics | ||
2116 | 44 | 3.4. Standard features | 45 | 3.4. Standard features |
2117 | 45 | 3.4.1. Sampling and converting information | 46 | 3.4.1. Sampling and converting information |
2118 | 46 | 3.4.2. Maps | 47 | 3.4.2. Maps |
2119 | @@ -50,7 +51,6 @@ Summary | |||
2120 | 50 | 3.4.6. Formatted strings | 51 | 3.4.6. Formatted strings |
2121 | 51 | 3.4.7. HTTP rewriting and redirection | 52 | 3.4.7. HTTP rewriting and redirection |
2122 | 52 | 3.4.8. Server protection | 53 | 3.4.8. Server protection |
2123 | 53 | 3.4.9. Statistics | ||
2124 | 54 | 3.5. Advanced features | 54 | 3.5. Advanced features |
2125 | 55 | 3.5.1. Management | 55 | 3.5.1. Management |
2126 | 56 | 3.5.2. System-specific capabilities | 56 | 3.5.2. System-specific capabilities |
2127 | diff --git a/doc/management.txt b/doc/management.txt | |||
2128 | index 56e4f66..56f119e 100644 | |||
2129 | --- a/doc/management.txt | |||
2130 | +++ b/doc/management.txt | |||
2131 | @@ -2919,6 +2919,10 @@ show ssl crt-list [-n] [<filename>] | |||
2132 | 2919 | ecdsa.pem:3 [verify none allow-0rtt ssl-min-ver TLSv1.0 ssl-max-ver TLSv1.3] localhost !www.test1.com | 2919 | ecdsa.pem:3 [verify none allow-0rtt ssl-min-ver TLSv1.0 ssl-max-ver TLSv1.3] localhost !www.test1.com |
2133 | 2920 | ecdsa.pem:4 [verify none allow-0rtt ssl-min-ver TLSv1.0 ssl-max-ver TLSv1.3] | 2920 | ecdsa.pem:4 [verify none allow-0rtt ssl-min-ver TLSv1.0 ssl-max-ver TLSv1.3] |
2134 | 2921 | 2921 | ||
2135 | 2922 | show startup-logs | ||
2136 | 2923 | Dump all messages emitted during the startup of the current haproxy process, | ||
2137 | 2924 | each startup-logs buffer is unique to its haproxy worker. | ||
2138 | 2925 | |||
2139 | 2922 | show table | 2926 | show table |
2140 | 2923 | Dump general information on all known stick-tables. Their name is returned | 2927 | Dump general information on all known stick-tables. Their name is returned |
2141 | 2924 | (the name of the proxy which holds them), their type (currently zero, always | 2928 | (the name of the proxy which holds them), their type (currently zero, always |
2142 | diff --git a/doc/proxy-protocol.txt b/doc/proxy-protocol.txt | |||
2143 | index 4d49d5c..fac0331 100644 | |||
2144 | --- a/doc/proxy-protocol.txt | |||
2145 | +++ b/doc/proxy-protocol.txt | |||
2146 | @@ -500,7 +500,7 @@ protocol. Identifying the protocol version is easy : | |||
2147 | 500 | - if the incoming byte count is 16 or above and the 13 first bytes match | 500 | - if the incoming byte count is 16 or above and the 13 first bytes match |
2148 | 501 | the protocol signature block followed by the protocol version 2 : | 501 | the protocol signature block followed by the protocol version 2 : |
2149 | 502 | 502 | ||
2151 | 503 | \x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x02 | 503 | \x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x20 |
2152 | 504 | 504 | ||
2153 | 505 | - otherwise, if the incoming byte count is 8 or above, and the 5 first | 505 | - otherwise, if the incoming byte count is 8 or above, and the 5 first |
2154 | 506 | characters match the US-ASCII representation of "PROXY" then the protocol | 506 | characters match the US-ASCII representation of "PROXY" then the protocol |
2155 | diff --git a/include/haproxy/buf.h b/include/haproxy/buf.h | |||
2156 | index 6cfd9d3..fc7b6fb 100644 | |||
2157 | --- a/include/haproxy/buf.h | |||
2158 | +++ b/include/haproxy/buf.h | |||
2159 | @@ -445,7 +445,7 @@ static inline void b_slow_realign(struct buffer *b, char *swap, size_t output) | |||
2160 | 445 | 445 | ||
2161 | 446 | /* process output data in two steps to cover wrapping */ | 446 | /* process output data in two steps to cover wrapping */ |
2162 | 447 | if (block1 > b_size(b) - b_head_ofs(b)) { | 447 | if (block1 > b_size(b) - b_head_ofs(b)) { |
2164 | 448 | block2 = b_size(b) - b_head_ofs(b); | 448 | block2 = b_peek_ofs(b, block1); |
2165 | 449 | block1 -= block2; | 449 | block1 -= block2; |
2166 | 450 | } | 450 | } |
2167 | 451 | memcpy(swap + b_size(b) - output, b_head(b), block1); | 451 | memcpy(swap + b_size(b) - output, b_head(b), block1); |
2168 | diff --git a/include/haproxy/bug.h b/include/haproxy/bug.h | |||
2169 | index a2a9f6d..445dd7c 100644 | |||
2170 | --- a/include/haproxy/bug.h | |||
2171 | +++ b/include/haproxy/bug.h | |||
2172 | @@ -42,8 +42,10 @@ static inline __attribute((always_inline)) void ha_crash_now(void) | |||
2173 | 42 | #if __GNUC_PREREQ__(5, 0) | 42 | #if __GNUC_PREREQ__(5, 0) |
2174 | 43 | #pragma GCC diagnostic push | 43 | #pragma GCC diagnostic push |
2175 | 44 | #pragma GCC diagnostic ignored "-Warray-bounds" | 44 | #pragma GCC diagnostic ignored "-Warray-bounds" |
2176 | 45 | #if __GNUC_PREREQ__(6, 0) | ||
2177 | 45 | #pragma GCC diagnostic ignored "-Wnull-dereference" | 46 | #pragma GCC diagnostic ignored "-Wnull-dereference" |
2178 | 46 | #endif | 47 | #endif |
2179 | 48 | #endif | ||
2180 | 47 | *(volatile char *)1 = 0; | 49 | *(volatile char *)1 = 0; |
2181 | 48 | #if __GNUC_PREREQ__(5, 0) | 50 | #if __GNUC_PREREQ__(5, 0) |
2182 | 49 | #pragma GCC diagnostic pop | 51 | #pragma GCC diagnostic pop |
2183 | diff --git a/include/haproxy/http.h b/include/haproxy/http.h | |||
2184 | index d0f3fd2..8a86cb6 100644 | |||
2185 | --- a/include/haproxy/http.h | |||
2186 | +++ b/include/haproxy/http.h | |||
2187 | @@ -36,6 +36,8 @@ extern const uint8_t http_char_classes[256]; | |||
2188 | 36 | enum http_meth_t find_http_meth(const char *str, const int len); | 36 | enum http_meth_t find_http_meth(const char *str, const int len); |
2189 | 37 | int http_get_status_idx(unsigned int status); | 37 | int http_get_status_idx(unsigned int status); |
2190 | 38 | const char *http_get_reason(unsigned int status); | 38 | const char *http_get_reason(unsigned int status); |
2191 | 39 | struct ist http_get_host_port(const struct ist host); | ||
2192 | 40 | int http_is_default_port(const struct ist schm, const struct ist port); | ||
2193 | 39 | int http_validate_scheme(const struct ist schm); | 41 | int http_validate_scheme(const struct ist schm); |
2194 | 40 | struct ist http_get_scheme(const struct ist uri); | 42 | struct ist http_get_scheme(const struct ist uri); |
2195 | 41 | struct ist http_get_authority(const struct ist uri, int no_userinfo); | 43 | struct ist http_get_authority(const struct ist uri, int no_userinfo); |
2196 | diff --git a/include/haproxy/listener-t.h b/include/haproxy/listener-t.h | |||
2197 | index c350290..476e65a 100644 | |||
2198 | --- a/include/haproxy/listener-t.h | |||
2199 | +++ b/include/haproxy/listener-t.h | |||
2200 | @@ -156,12 +156,21 @@ struct ssl_bind_conf { | |||
2201 | 156 | #endif | 156 | #endif |
2202 | 157 | }; | 157 | }; |
2203 | 158 | 158 | ||
2204 | 159 | /* | ||
2205 | 160 | * In OpenSSL 3.0.0, the biggest verify error code's value is 94 and on the | ||
2206 | 161 | * latest 1.1.1 it already reaches 79 so we need to size the ca/crt-ignore-err | ||
2207 | 162 | * arrays accordingly. If the max error code increases, the arrays might need to | ||
2208 | 163 | * be resized. | ||
2209 | 164 | */ | ||
2210 | 165 | #define SSL_MAX_VFY_ERROR_CODE 94 | ||
2211 | 166 | #define IGNERR_BF_SIZE ((SSL_MAX_VFY_ERROR_CODE >> 6) + 1) | ||
2212 | 167 | |||
2213 | 159 | /* "bind" line settings */ | 168 | /* "bind" line settings */ |
2214 | 160 | struct bind_conf { | 169 | struct bind_conf { |
2215 | 161 | #ifdef USE_OPENSSL | 170 | #ifdef USE_OPENSSL |
2216 | 162 | struct ssl_bind_conf ssl_conf; /* ssl conf for ctx setting */ | 171 | struct ssl_bind_conf ssl_conf; /* ssl conf for ctx setting */ |
2219 | 163 | unsigned long long ca_ignerr; /* ignored verify errors in handshake if depth > 0 */ | 172 | unsigned long long ca_ignerr_bitfield[IGNERR_BF_SIZE]; /* ignored verify errors in handshake if depth > 0 */ |
2220 | 164 | unsigned long long crt_ignerr; /* ignored verify errors in handshake if depth == 0 */ | 173 | unsigned long long crt_ignerr_bitfield[IGNERR_BF_SIZE]; /* ignored verify errors in handshake if depth == 0 */ |
2221 | 165 | SSL_CTX *initial_ctx; /* SSL context for initial negotiation */ | 174 | SSL_CTX *initial_ctx; /* SSL context for initial negotiation */ |
2222 | 166 | SSL_CTX *default_ctx; /* SSL context of first/default certificate */ | 175 | SSL_CTX *default_ctx; /* SSL context of first/default certificate */ |
2223 | 167 | struct ssl_bind_conf *default_ssl_conf; /* custom SSL conf of default_ctx */ | 176 | struct ssl_bind_conf *default_ssl_conf; /* custom SSL conf of default_ctx */ |
2224 | diff --git a/include/haproxy/listener.h b/include/haproxy/listener.h | |||
2225 | index 3fb078f..bb502c6 100644 | |||
2226 | --- a/include/haproxy/listener.h | |||
2227 | +++ b/include/haproxy/listener.h | |||
2228 | @@ -39,23 +39,29 @@ void listener_set_state(struct listener *l, enum li_state st); | |||
2229 | 39 | * closes upon SHUT_WR and refuses to rebind. So a common validation path | 39 | * closes upon SHUT_WR and refuses to rebind. So a common validation path |
2230 | 40 | * involves SHUT_WR && listen && SHUT_RD. In case of success, the FD's polling | 40 | * involves SHUT_WR && listen && SHUT_RD. In case of success, the FD's polling |
2231 | 41 | * is disabled. It normally returns non-zero, unless an error is reported. | 41 | * is disabled. It normally returns non-zero, unless an error is reported. |
2232 | 42 | * It will need to operate under the proxy's lock. The caller is | ||
2233 | 43 | * responsible for indicating in lpx whether the proxy locks is | ||
2234 | 44 | * already held (non-zero) or not (zero) so that the function picks it. | ||
2235 | 42 | */ | 45 | */ |
2237 | 43 | int pause_listener(struct listener *l); | 46 | int pause_listener(struct listener *l, int lpx); |
2238 | 44 | 47 | ||
2239 | 45 | /* This function tries to resume a temporarily disabled listener. | 48 | /* This function tries to resume a temporarily disabled listener. |
2240 | 46 | * The resulting state will either be LI_READY or LI_FULL. 0 is returned | 49 | * The resulting state will either be LI_READY or LI_FULL. 0 is returned |
2241 | 47 | * in case of failure to resume (eg: dead socket). | 50 | * in case of failure to resume (eg: dead socket). |
2242 | 51 | * It will need to operate under the proxy's lock. The caller is | ||
2243 | 52 | * responsible for indicating in lpx whether the proxy locks is | ||
2244 | 53 | * already held (non-zero) or not (zero) so that the function picks it. | ||
2245 | 48 | */ | 54 | */ |
2247 | 49 | int resume_listener(struct listener *l); | 55 | int resume_listener(struct listener *l, int lpx); |
2248 | 50 | 56 | ||
2249 | 51 | /* | 57 | /* |
2250 | 52 | * This function completely stops a listener. It will need to operate under the | 58 | * This function completely stops a listener. It will need to operate under the |
2253 | 53 | * proxy's lock, the protocol's lock, and the listener's lock. The caller is | 59 | * proxy's lock and the protocol's lock. The caller is |
2254 | 54 | * responsible for indicating in lpx, lpr, lli whether the respective locks are | 60 | * responsible for indicating in lpx, lpr whether the respective locks are |
2255 | 55 | * already held (non-zero) or not (zero) so that the function picks the missing | 61 | * already held (non-zero) or not (zero) so that the function picks the missing |
2256 | 56 | * ones, in this order. | 62 | * ones, in this order. |
2257 | 57 | */ | 63 | */ |
2259 | 58 | void stop_listener(struct listener *l, int lpx, int lpr, int lli); | 64 | void stop_listener(struct listener *l, int lpx, int lpr); |
2260 | 59 | 65 | ||
2261 | 60 | /* This function adds the specified listener's file descriptor to the polling | 66 | /* This function adds the specified listener's file descriptor to the polling |
2262 | 61 | * lists if it is in the LI_LISTEN state. The listener enters LI_READY or | 67 | * lists if it is in the LI_LISTEN state. The listener enters LI_READY or |
2263 | diff --git a/include/haproxy/peers-t.h b/include/haproxy/peers-t.h | |||
2264 | index ee9d905..93920fd 100644 | |||
2265 | --- a/include/haproxy/peers-t.h | |||
2266 | +++ b/include/haproxy/peers-t.h | |||
2267 | @@ -31,6 +31,7 @@ | |||
2268 | 31 | 31 | ||
2269 | 32 | #include <haproxy/api-t.h> | 32 | #include <haproxy/api-t.h> |
2270 | 33 | #include <haproxy/dict-t.h> | 33 | #include <haproxy/dict-t.h> |
2271 | 34 | #include <haproxy/stick_table-t.h> | ||
2272 | 34 | #include <haproxy/thread-t.h> | 35 | #include <haproxy/thread-t.h> |
2273 | 35 | 36 | ||
2274 | 36 | 37 | ||
2275 | diff --git a/include/haproxy/pool.h b/include/haproxy/pool.h | |||
2276 | index 9264998..0547dcb 100644 | |||
2277 | --- a/include/haproxy/pool.h | |||
2278 | +++ b/include/haproxy/pool.h | |||
2279 | @@ -55,8 +55,8 @@ void pool_free_nocache(struct pool_head *pool, void *ptr); | |||
2280 | 55 | void dump_pools_to_trash(); | 55 | void dump_pools_to_trash(); |
2281 | 56 | void dump_pools(void); | 56 | void dump_pools(void); |
2282 | 57 | int pool_total_failures(); | 57 | int pool_total_failures(); |
2285 | 58 | unsigned long pool_total_allocated(); | 58 | unsigned long long pool_total_allocated(); |
2286 | 59 | unsigned long pool_total_used(); | 59 | unsigned long long pool_total_used(); |
2287 | 60 | void pool_flush(struct pool_head *pool); | 60 | void pool_flush(struct pool_head *pool); |
2288 | 61 | void pool_gc(struct pool_head *pool_ctx); | 61 | void pool_gc(struct pool_head *pool_ctx); |
2289 | 62 | struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags); | 62 | struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags); |
2290 | diff --git a/include/haproxy/server.h b/include/haproxy/server.h | |||
2291 | index c927de3..fdb285c 100644 | |||
2292 | --- a/include/haproxy/server.h | |||
2293 | +++ b/include/haproxy/server.h | |||
2294 | @@ -45,6 +45,7 @@ extern struct dict server_key_dict; | |||
2295 | 45 | int srv_downtime(const struct server *s); | 45 | int srv_downtime(const struct server *s); |
2296 | 46 | int srv_lastsession(const struct server *s); | 46 | int srv_lastsession(const struct server *s); |
2297 | 47 | int srv_getinter(const struct check *check); | 47 | int srv_getinter(const struct check *check); |
2298 | 48 | void srv_settings_cpy(struct server *srv, const struct server *src, int srv_tmpl); | ||
2299 | 48 | int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, const struct proxy *defproxy, int parse_flags); | 49 | int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, const struct proxy *defproxy, int parse_flags); |
2300 | 49 | int srv_update_addr(struct server *s, void *ip, int ip_sin_family, const char *updater); | 50 | int srv_update_addr(struct server *s, void *ip, int ip_sin_family, const char *updater); |
2301 | 50 | const char *srv_update_addr_port(struct server *s, const char *addr, const char *port, char *updater); | 51 | const char *srv_update_addr_port(struct server *s, const char *addr, const char *port, char *updater); |
2302 | @@ -254,18 +255,21 @@ static inline enum srv_initaddr srv_get_next_initaddr(unsigned int *list) | |||
2303 | 254 | 255 | ||
2304 | 255 | static inline void srv_use_conn(struct server *srv, struct connection *conn) | 256 | static inline void srv_use_conn(struct server *srv, struct connection *conn) |
2305 | 256 | { | 257 | { |
2307 | 257 | unsigned int curr; | 258 | unsigned int curr, prev; |
2308 | 258 | 259 | ||
2309 | 259 | curr = _HA_ATOMIC_ADD_FETCH(&srv->curr_used_conns, 1); | 260 | curr = _HA_ATOMIC_ADD_FETCH(&srv->curr_used_conns, 1); |
2310 | 260 | 261 | ||
2311 | 262 | |||
2312 | 261 | /* It's ok not to do that atomically, we don't need an | 263 | /* It's ok not to do that atomically, we don't need an |
2313 | 262 | * exact max. | 264 | * exact max. |
2314 | 263 | */ | 265 | */ |
2317 | 264 | if (srv->max_used_conns < curr) | 266 | prev = HA_ATOMIC_LOAD(&srv->max_used_conns); |
2318 | 265 | srv->max_used_conns = curr; | 267 | if (prev < curr) |
2319 | 268 | HA_ATOMIC_STORE(&srv->max_used_conns, curr); | ||
2320 | 266 | 269 | ||
2323 | 267 | if (srv->est_need_conns < curr) | 270 | prev = HA_ATOMIC_LOAD(&srv->est_need_conns); |
2324 | 268 | srv->est_need_conns = curr; | 271 | if (prev < curr) |
2325 | 272 | HA_ATOMIC_STORE(&srv->est_need_conns, curr); | ||
2326 | 269 | } | 273 | } |
2327 | 270 | 274 | ||
2328 | 271 | static inline void conn_delete_from_tree(struct ebmb_node *node) | 275 | static inline void conn_delete_from_tree(struct ebmb_node *node) |
2329 | diff --git a/include/haproxy/sink.h b/include/haproxy/sink.h | |||
2330 | index 51d507c..a9f8099 100644 | |||
2331 | --- a/include/haproxy/sink.h | |||
2332 | +++ b/include/haproxy/sink.h | |||
2333 | @@ -28,6 +28,8 @@ | |||
2334 | 28 | 28 | ||
2335 | 29 | extern struct list sink_list; | 29 | extern struct list sink_list; |
2336 | 30 | 30 | ||
2337 | 31 | extern struct proxy *sink_proxies_list; | ||
2338 | 32 | |||
2339 | 31 | struct sink *sink_find(const char *name); | 33 | struct sink *sink_find(const char *name); |
2340 | 32 | struct sink *sink_new_fd(const char *name, const char *desc, enum log_fmt, int fd); | 34 | struct sink *sink_new_fd(const char *name, const char *desc, enum log_fmt, int fd); |
2341 | 33 | ssize_t __sink_write(struct sink *sink, const struct ist msg[], size_t nmsg, | 35 | ssize_t __sink_write(struct sink *sink, const struct ist msg[], size_t nmsg, |
2342 | diff --git a/include/haproxy/ssl_sock-t.h b/include/haproxy/ssl_sock-t.h | |||
2343 | index 974b836..35270ca 100644 | |||
2344 | --- a/include/haproxy/ssl_sock-t.h | |||
2345 | +++ b/include/haproxy/ssl_sock-t.h | |||
2346 | @@ -52,16 +52,20 @@ | |||
2347 | 52 | #define SSL_SOCK_SEND_UNLIMITED 0x00000004 | 52 | #define SSL_SOCK_SEND_UNLIMITED 0x00000004 |
2348 | 53 | #define SSL_SOCK_RECV_HEARTBEAT 0x00000008 | 53 | #define SSL_SOCK_RECV_HEARTBEAT 0x00000008 |
2349 | 54 | 54 | ||
2351 | 55 | /* bits 0xFFFF0000 are reserved to store verify errors */ | 55 | /* bits 0xFFFFFF00 are reserved to store verify errors. |
2352 | 56 | * The CA en CRT error codes will be stored on 7 bits each | ||
2353 | 57 | * (since the max verify error code does not exceed 127) | ||
2354 | 58 | * and the CA error depth will be stored on 4 bits. | ||
2355 | 59 | */ | ||
2356 | 56 | 60 | ||
2357 | 57 | /* Verify errors macros */ | 61 | /* Verify errors macros */ |
2361 | 58 | #define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16)) | 62 | #define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 127) ? 127 : e) << (8)) |
2362 | 59 | #define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16)) | 63 | #define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (7+8)) |
2363 | 60 | #define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16)) | 64 | #define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 127) ? 127 : e) << (4+7+8)) |
2364 | 61 | 65 | ||
2368 | 62 | #define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63) | 66 | #define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (8)) & 127) |
2369 | 63 | #define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15) | 67 | #define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (7+8)) & 15) |
2370 | 64 | #define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63) | 68 | #define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+7+8)) & 127) |
2371 | 65 | 69 | ||
2372 | 66 | /* ssl_methods flags for ssl options */ | 70 | /* ssl_methods flags for ssl options */ |
2373 | 67 | #define MC_SSL_O_ALL 0x0000 | 71 | #define MC_SSL_O_ALL 0x0000 |
2374 | diff --git a/include/haproxy/ssl_sock.h b/include/haproxy/ssl_sock.h | |||
2375 | index c68425a..9db4ec4 100644 | |||
2376 | --- a/include/haproxy/ssl_sock.h | |||
2377 | +++ b/include/haproxy/ssl_sock.h | |||
2378 | @@ -149,6 +149,29 @@ int ssl_sock_is_ssl(struct connection *conn) | |||
2379 | 149 | return 1; | 149 | return 1; |
2380 | 150 | } | 150 | } |
2381 | 151 | 151 | ||
2382 | 152 | static inline int cert_ignerr_bitfield_get(const unsigned long long *bitfield, int bit_index) | ||
2383 | 153 | { | ||
2384 | 154 | int byte_index = bit_index >> 6; | ||
2385 | 155 | int val = 0; | ||
2386 | 156 | |||
2387 | 157 | if (byte_index < IGNERR_BF_SIZE) | ||
2388 | 158 | val = bitfield[byte_index] & (1ULL << (bit_index & 0x3F)); | ||
2389 | 159 | |||
2390 | 160 | return val != 0; | ||
2391 | 161 | } | ||
2392 | 162 | |||
2393 | 163 | static inline void cert_ignerr_bitfield_set(unsigned long long *bitfield, int bit_index) | ||
2394 | 164 | { | ||
2395 | 165 | int byte_index = bit_index >> 6; | ||
2396 | 166 | |||
2397 | 167 | if (byte_index < IGNERR_BF_SIZE) | ||
2398 | 168 | bitfield[byte_index] |= (1ULL << (bit_index & 0x3F)); | ||
2399 | 169 | } | ||
2400 | 170 | |||
2401 | 171 | static inline void cert_ignerr_bitfield_set_all(unsigned long long *bitfield) | ||
2402 | 172 | { | ||
2403 | 173 | memset(bitfield, -1, IGNERR_BF_SIZE*sizeof(*bitfield)); | ||
2404 | 174 | } | ||
2405 | 152 | 175 | ||
2406 | 153 | #endif /* USE_OPENSSL */ | 176 | #endif /* USE_OPENSSL */ |
2407 | 154 | #endif /* _HAPROXY_SSL_SOCK_H */ | 177 | #endif /* _HAPROXY_SSL_SOCK_H */ |
2408 | diff --git a/include/haproxy/stats-t.h b/include/haproxy/stats-t.h | |||
2409 | index 17641f5..920a311 100644 | |||
2410 | --- a/include/haproxy/stats-t.h | |||
2411 | +++ b/include/haproxy/stats-t.h | |||
2412 | @@ -443,7 +443,9 @@ enum stat_field { | |||
2413 | 443 | ST_F_USED_CONN_CUR, | 443 | ST_F_USED_CONN_CUR, |
2414 | 444 | ST_F_NEED_CONN_EST, | 444 | ST_F_NEED_CONN_EST, |
2415 | 445 | ST_F_UWEIGHT, | 445 | ST_F_UWEIGHT, |
2416 | 446 | ST_F_AGG_SRV_STATUS, | ||
2417 | 446 | ST_F_AGG_SRV_CHECK_STATUS, | 447 | ST_F_AGG_SRV_CHECK_STATUS, |
2418 | 448 | ST_F_AGG_CHECK_STATUS, | ||
2419 | 447 | 449 | ||
2420 | 448 | /* must always be the last one */ | 450 | /* must always be the last one */ |
2421 | 449 | ST_F_TOTAL_FIELDS | 451 | ST_F_TOTAL_FIELDS |
2422 | diff --git a/include/haproxy/stream.h b/include/haproxy/stream.h | |||
2423 | index 1ec87b1..5a61c20 100644 | |||
2424 | --- a/include/haproxy/stream.h | |||
2425 | +++ b/include/haproxy/stream.h | |||
2426 | @@ -337,7 +337,7 @@ static inline void stream_choose_redispatch(struct stream *s) | |||
2427 | 337 | ((s->be->conn_retries - si->conn_retries) % | 337 | ((s->be->conn_retries - si->conn_retries) % |
2428 | 338 | (s->be->conn_retries + 1 + s->be->redispatch_after) == 0))) || | 338 | (s->be->conn_retries + 1 + s->be->redispatch_after) == 0))) || |
2429 | 339 | (!(s->flags & SF_DIRECT) && s->be->srv_act > 1 && | 339 | (!(s->flags & SF_DIRECT) && s->be->srv_act > 1 && |
2431 | 340 | ((s->be->lbprm.algo & BE_LB_KIND) == BE_LB_KIND_RR)))) { | 340 | ((s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI)))) { |
2432 | 341 | sess_change_server(s, NULL); | 341 | sess_change_server(s, NULL); |
2433 | 342 | if (may_dequeue_tasks(objt_server(s->target), s->be)) | 342 | if (may_dequeue_tasks(objt_server(s->target), s->be)) |
2434 | 343 | process_srv_queue(objt_server(s->target), 0); | 343 | process_srv_queue(objt_server(s->target), 0); |
2435 | diff --git a/include/haproxy/task.h b/include/haproxy/task.h | |||
2436 | index d31c893..b3ffdf2 100644 | |||
2437 | --- a/include/haproxy/task.h | |||
2438 | +++ b/include/haproxy/task.h | |||
2439 | @@ -281,7 +281,7 @@ static inline struct task *task_unlink_wq(struct task *t) | |||
2440 | 281 | 281 | ||
2441 | 282 | if (likely(task_in_wq(t))) { | 282 | if (likely(task_in_wq(t))) { |
2442 | 283 | locked = t->state & TASK_SHARED_WQ; | 283 | locked = t->state & TASK_SHARED_WQ; |
2444 | 284 | BUG_ON(!locked && t->thread_mask != tid_bit); | 284 | BUG_ON(!locked && t->thread_mask != tid_bit && !(global.mode & MODE_STOPPING)); |
2445 | 285 | if (locked) | 285 | if (locked) |
2446 | 286 | HA_RWLOCK_WRLOCK(TASK_WQ_LOCK, &wq_lock); | 286 | HA_RWLOCK_WRLOCK(TASK_WQ_LOCK, &wq_lock); |
2447 | 287 | __task_unlink_wq(t); | 287 | __task_unlink_wq(t); |
2448 | @@ -526,6 +526,7 @@ static inline void tasklet_init(struct tasklet *t) | |||
2449 | 526 | t->process = NULL; | 526 | t->process = NULL; |
2450 | 527 | t->tid = -1; | 527 | t->tid = -1; |
2451 | 528 | #ifdef DEBUG_TASK | 528 | #ifdef DEBUG_TASK |
2452 | 529 | t->call_date = 0; | ||
2453 | 529 | t->debug.caller_idx = 0; | 530 | t->debug.caller_idx = 0; |
2454 | 530 | #endif | 531 | #endif |
2455 | 531 | LIST_INIT(&t->list); | 532 | LIST_INIT(&t->list); |
2456 | diff --git a/include/haproxy/tcpcheck-t.h b/include/haproxy/tcpcheck-t.h | |||
2457 | index 29cb4cc..439fe18 100644 | |||
2458 | --- a/include/haproxy/tcpcheck-t.h | |||
2459 | +++ b/include/haproxy/tcpcheck-t.h | |||
2460 | @@ -35,6 +35,7 @@ | |||
2461 | 35 | #define TCPCHK_OPT_DEFAULT_CONNECT 0x0008 /* Do a connect using server params */ | 35 | #define TCPCHK_OPT_DEFAULT_CONNECT 0x0008 /* Do a connect using server params */ |
2462 | 36 | #define TCPCHK_OPT_IMPLICIT 0x0010 /* Implicit connect */ | 36 | #define TCPCHK_OPT_IMPLICIT 0x0010 /* Implicit connect */ |
2463 | 37 | #define TCPCHK_OPT_SOCKS4 0x0020 /* check the connection via socks4 proxy */ | 37 | #define TCPCHK_OPT_SOCKS4 0x0020 /* check the connection via socks4 proxy */ |
2464 | 38 | #define TCPCHK_OPT_HAS_DATA 0x0040 /* data should be sent after conncetion */ | ||
2465 | 38 | 39 | ||
2466 | 39 | enum tcpcheck_send_type { | 40 | enum tcpcheck_send_type { |
2467 | 40 | TCPCHK_SEND_UNDEF = 0, /* Send is not parsed. */ | 41 | TCPCHK_SEND_UNDEF = 0, /* Send is not parsed. */ |
2468 | diff --git a/include/haproxy/tools.h b/include/haproxy/tools.h | |||
2469 | index a95844a..30b6bfa 100644 | |||
2470 | --- a/include/haproxy/tools.h | |||
2471 | +++ b/include/haproxy/tools.h | |||
2472 | @@ -406,7 +406,8 @@ char *encode_chunk(char *start, char *stop, | |||
2473 | 406 | 406 | ||
2474 | 407 | /* | 407 | /* |
2475 | 408 | * Tries to prefix characters tagged in the <map> with the <escape> | 408 | * Tries to prefix characters tagged in the <map> with the <escape> |
2477 | 409 | * character. The input <string> must be zero-terminated. The result will | 409 | * character. The input <string> is processed until string_stop |
2478 | 410 | * is reached or NULL-byte is encountered. The result will | ||
2479 | 410 | * be stored between <start> (included) and <stop> (excluded). This | 411 | * be stored between <start> (included) and <stop> (excluded). This |
2480 | 411 | * function will always try to terminate the resulting string with a '\0' | 412 | * function will always try to terminate the resulting string with a '\0' |
2481 | 412 | * before <stop>, and will return its position if the conversion | 413 | * before <stop>, and will return its position if the conversion |
2482 | @@ -414,7 +415,7 @@ char *encode_chunk(char *start, char *stop, | |||
2483 | 414 | */ | 415 | */ |
2484 | 415 | char *escape_string(char *start, char *stop, | 416 | char *escape_string(char *start, char *stop, |
2485 | 416 | const char escape, const long *map, | 417 | const char escape, const long *map, |
2487 | 417 | const char *string); | 418 | const char *string, const char *string_stop); |
2488 | 418 | 419 | ||
2489 | 419 | /* | 420 | /* |
2490 | 420 | * Tries to prefix characters tagged in the <map> with the <escape> | 421 | * Tries to prefix characters tagged in the <map> with the <escape> |
2491 | diff --git a/include/import/ebmbtree.h b/include/import/ebmbtree.h | |||
2492 | index f99c16b..2d63ed1 100644 | |||
2493 | --- a/include/import/ebmbtree.h | |||
2494 | +++ b/include/import/ebmbtree.h | |||
2495 | @@ -118,6 +118,59 @@ struct ebmb_node *ebmb_lookup_longest(struct eb_root *root, const void *x); | |||
2496 | 118 | struct ebmb_node *ebmb_lookup_prefix(struct eb_root *root, const void *x, unsigned int pfx); | 118 | struct ebmb_node *ebmb_lookup_prefix(struct eb_root *root, const void *x, unsigned int pfx); |
2497 | 119 | struct ebmb_node *ebmb_insert_prefix(struct eb_root *root, struct ebmb_node *new, unsigned int len); | 119 | struct ebmb_node *ebmb_insert_prefix(struct eb_root *root, struct ebmb_node *new, unsigned int len); |
2498 | 120 | 120 | ||
2499 | 121 | /* start from a valid leaf and find the next matching prefix that's either a | ||
2500 | 122 | * duplicate, or immediately shorter than the node's current one and still | ||
2501 | 123 | * matches it. The purpose is to permit a caller that is not satisfied with a | ||
2502 | 124 | * result provided by ebmb_lookup_longest() to evaluate the next matching | ||
2503 | 125 | * entry. Given that shorter keys are necessarily attached to nodes located | ||
2504 | 126 | * above the current one, it's sufficient to restart from the current leaf and | ||
2505 | 127 | * go up until we find a shorter prefix, or a non-matching one. | ||
2506 | 128 | */ | ||
2507 | 129 | static inline struct ebmb_node *ebmb_lookup_shorter(struct ebmb_node *start) | ||
2508 | 130 | { | ||
2509 | 131 | eb_troot_t *t = start->node.leaf_p; | ||
2510 | 132 | struct ebmb_node *node; | ||
2511 | 133 | |||
2512 | 134 | /* first, chcek for duplicates */ | ||
2513 | 135 | node = ebmb_next_dup(start); | ||
2514 | 136 | if (node) | ||
2515 | 137 | return node; | ||
2516 | 138 | |||
2517 | 139 | while (1) { | ||
2518 | 140 | if (eb_gettag(t) == EB_LEFT) { | ||
2519 | 141 | /* Walking up from left branch. We must ensure that we never | ||
2520 | 142 | * walk beyond root. | ||
2521 | 143 | */ | ||
2522 | 144 | if (unlikely(eb_clrtag((eb_untag(t, EB_LEFT))->b[EB_RGHT]) == NULL)) | ||
2523 | 145 | return NULL; | ||
2524 | 146 | node = container_of(eb_root_to_node(eb_untag(t, EB_LEFT)), struct ebmb_node, node); | ||
2525 | 147 | } else { | ||
2526 | 148 | /* Walking up from right branch, so we cannot be below | ||
2527 | 149 | * root. However, if we end up on a node with an even | ||
2528 | 150 | * and positive bit, this is a cover node, which mandates | ||
2529 | 151 | * that the left branch only contains cover values, so we | ||
2530 | 152 | * must descend it. | ||
2531 | 153 | */ | ||
2532 | 154 | node = container_of(eb_root_to_node(eb_untag(t, EB_RGHT)), struct ebmb_node, node); | ||
2533 | 155 | if (node->node.bit > 0 && !(node->node.bit & 1)) | ||
2534 | 156 | return ebmb_entry(eb_walk_down(t, EB_LEFT), struct ebmb_node, node); | ||
2535 | 157 | } | ||
2536 | 158 | |||
2537 | 159 | /* Note that <t> cannot be NULL at this stage */ | ||
2538 | 160 | t = node->node.node_p; | ||
2539 | 161 | |||
2540 | 162 | /* this is a node attached to a deeper (and possibly different) | ||
2541 | 163 | * leaf, not interesting for us. | ||
2542 | 164 | */ | ||
2543 | 165 | if (node->node.pfx >= start->node.pfx) | ||
2544 | 166 | continue; | ||
2545 | 167 | |||
2546 | 168 | if (check_bits(start->key, node->key, 0, node->node.pfx) == 0) | ||
2547 | 169 | break; | ||
2548 | 170 | } | ||
2549 | 171 | return node; | ||
2550 | 172 | } | ||
2551 | 173 | |||
2552 | 121 | /* The following functions are less likely to be used directly, because their | 174 | /* The following functions are less likely to be used directly, because their |
2553 | 122 | * code is larger. The non-inlined version is preferred. | 175 | * code is larger. The non-inlined version is preferred. |
2554 | 123 | */ | 176 | */ |
2555 | diff --git a/reg-tests/cache/if-modified-since.vtc b/reg-tests/cache/if-modified-since.vtc | |||
2556 | index 8ae1cce..387fc7e 100644 | |||
2557 | --- a/reg-tests/cache/if-modified-since.vtc | |||
2558 | +++ b/reg-tests/cache/if-modified-since.vtc | |||
2559 | @@ -62,6 +62,10 @@ haproxy h1 -conf { | |||
2560 | 62 | server www ${s1_addr}:${s1_port} | 62 | server www ${s1_addr}:${s1_port} |
2561 | 63 | http-response cache-store my_cache | 63 | http-response cache-store my_cache |
2562 | 64 | 64 | ||
2563 | 65 | # Remove Transfer-Encoding header because of a vtest issue with | ||
2564 | 66 | # 304-Not-Modified responses | ||
2565 | 67 | http-after-response del-header transfer-encoding if { status eq 304 } | ||
2566 | 68 | |||
2567 | 65 | cache my_cache | 69 | cache my_cache |
2568 | 66 | total-max-size 3 | 70 | total-max-size 3 |
2569 | 67 | max-age 20 | 71 | max-age 20 |
2570 | @@ -149,4 +153,3 @@ client c1 -connect ${h1_fe_sock} { | |||
2571 | 149 | expect resp.bodylen == 0 | 153 | expect resp.bodylen == 0 |
2572 | 150 | 154 | ||
2573 | 151 | } -run | 155 | } -run |
2574 | 152 | |||
2575 | diff --git a/reg-tests/cache/if-none-match.vtc b/reg-tests/cache/if-none-match.vtc | |||
2576 | index ba3336a..bc7d67b 100644 | |||
2577 | --- a/reg-tests/cache/if-none-match.vtc | |||
2578 | +++ b/reg-tests/cache/if-none-match.vtc | |||
2579 | @@ -47,6 +47,10 @@ haproxy h1 -conf { | |||
2580 | 47 | server www ${s1_addr}:${s1_port} | 47 | server www ${s1_addr}:${s1_port} |
2581 | 48 | http-response cache-store my_cache | 48 | http-response cache-store my_cache |
2582 | 49 | 49 | ||
2583 | 50 | # Remove Transfer-Encoding header because of a vtest issue with | ||
2584 | 51 | # 304-Not-Modified responses | ||
2585 | 52 | http-after-response del-header transfer-encoding if { status eq 304 } | ||
2586 | 53 | |||
2587 | 50 | cache my_cache | 54 | cache my_cache |
2588 | 51 | total-max-size 3 | 55 | total-max-size 3 |
2589 | 52 | max-age 20 | 56 | max-age 20 |
2590 | diff --git a/reg-tests/checks/4be_1srv_smtpchk_httpchk_layer47errors.vtc b/reg-tests/checks/4be_1srv_smtpchk_httpchk_layer47errors.vtc | |||
2591 | index f9f37a1..ea72701 100644 | |||
2592 | --- a/reg-tests/checks/4be_1srv_smtpchk_httpchk_layer47errors.vtc | |||
2593 | +++ b/reg-tests/checks/4be_1srv_smtpchk_httpchk_layer47errors.vtc | |||
2594 | @@ -8,7 +8,7 @@ barrier b cond 3 | |||
2595 | 8 | 8 | ||
2596 | 9 | syslog S1 -level notice { | 9 | syslog S1 -level notice { |
2597 | 10 | recv | 10 | recv |
2599 | 11 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv1 succeeded.+reason: Layer7 check passed.+code: 2(20|48).+check duration: [[:digit:]]+ms.+status: 1/1 UP." | 11 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv1 succeeded.+reason: Layer7 check passed.+code: 221.+check duration: [[:digit:]]+ms.+status: 1/1 UP." |
2600 | 12 | barrier b sync | 12 | barrier b sync |
2601 | 13 | recv | 13 | recv |
2602 | 14 | expect ~ "Health check for server be1/srv1 failed.+reason: Layer7 timeout.+check duration: [[:digit:]]+ms.+status: 0/1 DOWN" | 14 | expect ~ "Health check for server be1/srv1 failed.+reason: Layer7 timeout.+check duration: [[:digit:]]+ms.+status: 0/1 DOWN" |
2603 | @@ -36,12 +36,17 @@ server s1 { | |||
2604 | 36 | send "2" | 36 | send "2" |
2605 | 37 | send "2" | 37 | send "2" |
2606 | 38 | send "0" | 38 | send "0" |
2608 | 39 | send "\r\n\r\n" | 39 | send "\r\n" |
2609 | 40 | recv 16 | 40 | recv 16 |
2610 | 41 | send "2" | 41 | send "2" |
2611 | 42 | send "4" | 42 | send "4" |
2612 | 43 | send "8" | 43 | send "8" |
2614 | 44 | send "\r\n\r\n" | 44 | send "\r\n" |
2615 | 45 | recv 6 | ||
2616 | 46 | send "2" | ||
2617 | 47 | send "2" | ||
2618 | 48 | send "1" | ||
2619 | 49 | send " ok\r\n" | ||
2620 | 45 | } -start | 50 | } -start |
2621 | 46 | 51 | ||
2622 | 47 | server s2 { | 52 | server s2 { |
2623 | diff --git a/reg-tests/checks/pgsql-check.vtc b/reg-tests/checks/pgsql-check.vtc | |||
2624 | index 968a18c..05c5a71 100644 | |||
2625 | --- a/reg-tests/checks/pgsql-check.vtc | |||
2626 | +++ b/reg-tests/checks/pgsql-check.vtc | |||
2627 | @@ -23,6 +23,11 @@ server s3 { | |||
2628 | 23 | send "Not a PostgreSQL response" | 23 | send "Not a PostgreSQL response" |
2629 | 24 | } -start | 24 | } -start |
2630 | 25 | 25 | ||
2631 | 26 | server s4 { | ||
2632 | 27 | recv 23 | ||
2633 | 28 | sendhex "52000000170000000A534352414D2D5348412D3235360000" | ||
2634 | 29 | } -start | ||
2635 | 30 | |||
2636 | 26 | syslog S1 -level notice { | 31 | syslog S1 -level notice { |
2637 | 27 | recv | 32 | recv |
2638 | 28 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+info: \"PostgreSQL server is ok\".+check duration: [[:digit:]]+ms, status: 1/1 UP." | 33 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+info: \"PostgreSQL server is ok\".+check duration: [[:digit:]]+ms, status: 1/1 UP." |
2639 | @@ -38,6 +43,10 @@ syslog S3 -level notice { | |||
2640 | 38 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv failed, reason: Layer7 wrong status.+info: \"PostgreSQL unknown error\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." | 43 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv failed, reason: Layer7 wrong status.+info: \"PostgreSQL unknown error\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." |
2641 | 39 | } -start | 44 | } -start |
2642 | 40 | 45 | ||
2643 | 46 | syslog S4 -level notice { | ||
2644 | 47 | recv | ||
2645 | 48 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be4/srv succeeded, reason: Layer7 check passed.+info: \"PostgreSQL server is ok\".+check duration: [[:digit:]]+ms, status: 1/1 UP." | ||
2646 | 49 | } -start | ||
2647 | 41 | 50 | ||
2648 | 42 | haproxy h1 -conf { | 51 | haproxy h1 -conf { |
2649 | 43 | defaults | 52 | defaults |
2650 | @@ -64,6 +73,12 @@ haproxy h1 -conf { | |||
2651 | 64 | option pgsql-check user postgres | 73 | option pgsql-check user postgres |
2652 | 65 | server srv ${s3_addr}:${s3_port} check inter 1s rise 1 fall 1 | 74 | server srv ${s3_addr}:${s3_port} check inter 1s rise 1 fall 1 |
2653 | 66 | 75 | ||
2654 | 76 | backend be4 | ||
2655 | 77 | log ${S4_addr}:${S4_port} daemon | ||
2656 | 78 | option log-health-checks | ||
2657 | 79 | option pgsql-check user postgres | ||
2658 | 80 | server srv ${s4_addr}:${s4_port} check inter 1s rise 1 fall 1 | ||
2659 | 81 | |||
2660 | 67 | listen pgsql1 | 82 | listen pgsql1 |
2661 | 68 | bind "fd@${pgsql}" | 83 | bind "fd@${pgsql}" |
2662 | 69 | tcp-request inspect-delay 100ms | 84 | tcp-request inspect-delay 100ms |
2663 | @@ -75,3 +90,4 @@ haproxy h1 -conf { | |||
2664 | 75 | syslog S1 -wait | 90 | syslog S1 -wait |
2665 | 76 | syslog S2 -wait | 91 | syslog S2 -wait |
2666 | 77 | syslog S3 -wait | 92 | syslog S3 -wait |
2667 | 93 | syslog S4 -wait | ||
2668 | diff --git a/reg-tests/checks/smtp-check.vtc b/reg-tests/checks/smtp-check.vtc | |||
2669 | index 29d0ddb..9d8bb8a 100644 | |||
2670 | --- a/reg-tests/checks/smtp-check.vtc | |||
2671 | +++ b/reg-tests/checks/smtp-check.vtc | |||
2672 | @@ -10,6 +10,8 @@ server s1 { | |||
2673 | 10 | send "220 smtp-check.vtc SMTP Server\r\n" | 10 | send "220 smtp-check.vtc SMTP Server\r\n" |
2674 | 11 | recv 16 | 11 | recv 16 |
2675 | 12 | send "250 smtp-check.vtc\r\n" | 12 | send "250 smtp-check.vtc\r\n" |
2676 | 13 | recv 6 | ||
2677 | 14 | send "221 smtp-check.vtc closing\r\n" | ||
2678 | 13 | } -start | 15 | } -start |
2679 | 14 | 16 | ||
2680 | 15 | server s2 { | 17 | server s2 { |
2681 | @@ -18,6 +20,8 @@ server s2 { | |||
2682 | 18 | send "250-smtp-check.vtc\r\n" | 20 | send "250-smtp-check.vtc\r\n" |
2683 | 19 | send "250-KEYWORD\r\n" | 21 | send "250-KEYWORD\r\n" |
2684 | 20 | send "250 LAST KEYWORD\r\n" | 22 | send "250 LAST KEYWORD\r\n" |
2685 | 23 | recv 6 | ||
2686 | 24 | send "221 smtp-check.vtc closing\r\n" | ||
2687 | 21 | } -start | 25 | } -start |
2688 | 22 | 26 | ||
2689 | 23 | server s3 { | 27 | server s3 { |
2690 | @@ -36,12 +40,12 @@ server s5 { | |||
2691 | 36 | 40 | ||
2692 | 37 | syslog S1 -level notice { | 41 | syslog S1 -level notice { |
2693 | 38 | recv | 42 | recv |
2695 | 39 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+code: 250.+info: \"smtp-check.vtc\".+check duration: [[:digit:]]+ms, status: 1/1 UP." | 43 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+code: 221.+info: \"smtp-check.vtc closing\".+check duration: [[:digit:]]+ms, status: 1/1 UP." |
2696 | 40 | } -start | 44 | } -start |
2697 | 41 | 45 | ||
2698 | 42 | syslog S2 -level notice { | 46 | syslog S2 -level notice { |
2699 | 43 | recv | 47 | recv |
2701 | 44 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv succeeded, reason: Layer7 check passed.+code: 250.+info: \"smtp-check.vtc\".+check duration: [[:digit:]]+ms, status: 1/1 UP." | 48 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv succeeded, reason: Layer7 check passed.+code: 221.+info: \"smtp-check.vtc closing\".+check duration: [[:digit:]]+ms, status: 1/1 UP." |
2702 | 45 | } -start | 49 | } -start |
2703 | 46 | 50 | ||
2704 | 47 | syslog S3 -level notice { | 51 | syslog S3 -level notice { |
2705 | diff --git a/reg-tests/contrib/prometheus.vtc b/reg-tests/contrib/prometheus.vtc | |||
2706 | index ebe0b87..766db47 100644 | |||
2707 | --- a/reg-tests/contrib/prometheus.vtc | |||
2708 | +++ b/reg-tests/contrib/prometheus.vtc | |||
2709 | @@ -8,12 +8,12 @@ feature ignore_unknown_macro | |||
2710 | 8 | server s1 { | 8 | server s1 { |
2711 | 9 | rxreq | 9 | rxreq |
2712 | 10 | txresp | 10 | txresp |
2714 | 11 | } -repeat 2 -start | 11 | } -start |
2715 | 12 | 12 | ||
2716 | 13 | server s2 { | 13 | server s2 { |
2717 | 14 | rxreq | 14 | rxreq |
2718 | 15 | txresp | 15 | txresp |
2720 | 16 | } -repeat 2 -start | 16 | } -start |
2721 | 17 | 17 | ||
2722 | 18 | haproxy h1 -conf { | 18 | haproxy h1 -conf { |
2723 | 19 | defaults | 19 | defaults |
2724 | @@ -33,8 +33,9 @@ haproxy h1 -conf { | |||
2725 | 33 | 33 | ||
2726 | 34 | backend be | 34 | backend be |
2727 | 35 | stick-table type ip size 1m expire 10s store http_req_rate(10s) | 35 | stick-table type ip size 1m expire 10s store http_req_rate(10s) |
2728 | 36 | option httpchk | ||
2729 | 36 | server s1 ${s1_addr}:${s1_port} | 37 | server s1 ${s1_addr}:${s1_port} |
2731 | 37 | server s2 ${s2_addr}:${s2_port} check maxqueue 10 maxconn 12 pool-max-conn 42 | 38 | server s2 ${s2_addr}:${s2_port} check inter 5s maxqueue 10 maxconn 12 pool-max-conn 42 |
2732 | 38 | } -start | 39 | } -start |
2733 | 39 | 40 | ||
2734 | 40 | client c1 -connect ${h1_stats_sock} { | 41 | client c1 -connect ${h1_stats_sock} { |
2735 | diff --git a/reg-tests/converter/digest.vtc b/reg-tests/converter/digest.vtc | |||
2736 | index a14f1cc..511daca 100644 | |||
2737 | --- a/reg-tests/converter/digest.vtc | |||
2738 | +++ b/reg-tests/converter/digest.vtc | |||
2739 | @@ -7,7 +7,7 @@ feature ignore_unknown_macro | |||
2740 | 7 | 7 | ||
2741 | 8 | server s1 { | 8 | server s1 { |
2742 | 9 | rxreq | 9 | rxreq |
2744 | 10 | txresp | 10 | txresp -hdr "Connection: close" |
2745 | 11 | } -repeat 2 -start | 11 | } -repeat 2 -start |
2746 | 12 | 12 | ||
2747 | 13 | haproxy h1 -conf { | 13 | haproxy h1 -conf { |
2748 | diff --git a/reg-tests/converter/hmac.vtc b/reg-tests/converter/hmac.vtc | |||
2749 | index f9d9d35..391e04a 100644 | |||
2750 | --- a/reg-tests/converter/hmac.vtc | |||
2751 | +++ b/reg-tests/converter/hmac.vtc | |||
2752 | @@ -7,7 +7,7 @@ feature ignore_unknown_macro | |||
2753 | 7 | 7 | ||
2754 | 8 | server s1 { | 8 | server s1 { |
2755 | 9 | rxreq | 9 | rxreq |
2757 | 10 | txresp | 10 | txresp -hdr "Connection: close" |
2758 | 11 | } -repeat 2 -start | 11 | } -repeat 2 -start |
2759 | 12 | 12 | ||
2760 | 13 | haproxy h1 -conf { | 13 | haproxy h1 -conf { |
2761 | diff --git a/reg-tests/converter/iif.vtc b/reg-tests/converter/iif.vtc | |||
2762 | index 22414e0..3a6d6a6 100644 | |||
2763 | --- a/reg-tests/converter/iif.vtc | |||
2764 | +++ b/reg-tests/converter/iif.vtc | |||
2765 | @@ -5,7 +5,7 @@ feature ignore_unknown_macro | |||
2766 | 5 | 5 | ||
2767 | 6 | server s1 { | 6 | server s1 { |
2768 | 7 | rxreq | 7 | rxreq |
2770 | 8 | txresp | 8 | txresp -hdr "Connection: close" |
2771 | 9 | } -repeat 3 -start | 9 | } -repeat 3 -start |
2772 | 10 | 10 | ||
2773 | 11 | haproxy h1 -conf { | 11 | haproxy h1 -conf { |
2774 | diff --git a/reg-tests/converter/json_query.vtc b/reg-tests/converter/json_query.vtc | |||
2775 | index b420942..9db77eb 100644 | |||
2776 | --- a/reg-tests/converter/json_query.vtc | |||
2777 | +++ b/reg-tests/converter/json_query.vtc | |||
2778 | @@ -5,7 +5,7 @@ feature ignore_unknown_macro | |||
2779 | 5 | 5 | ||
2780 | 6 | server s1 { | 6 | server s1 { |
2781 | 7 | rxreq | 7 | rxreq |
2783 | 8 | txresp | 8 | txresp -hdr "Connection: close" |
2784 | 9 | } -repeat 8 -start | 9 | } -repeat 8 -start |
2785 | 10 | 10 | ||
2786 | 11 | haproxy h1 -conf { | 11 | haproxy h1 -conf { |
2787 | diff --git a/reg-tests/http-messaging/h1_host_normalization.vtc b/reg-tests/http-messaging/h1_host_normalization.vtc | |||
2788 | 12 | new file mode 100644 | 12 | new file mode 100644 |
2789 | index 0000000..6ea32d2 | |||
2790 | --- /dev/null | |||
2791 | +++ b/reg-tests/http-messaging/h1_host_normalization.vtc | |||
2792 | @@ -0,0 +1,276 @@ | |||
2793 | 1 | varnishtest "H1 authority validation and host normalizarion based on the scheme (rfc3982 6.3.2) or the method (connect)" | ||
2794 | 2 | |||
2795 | 3 | #REQUIRE_VERSION=2.4 | ||
2796 | 4 | feature ignore_unknown_macro | ||
2797 | 5 | |||
2798 | 6 | syslog S1 -level info { | ||
2799 | 7 | # C1 | ||
2800 | 8 | recv | ||
2801 | 9 | expect ~ "^.* uri: GET http://toto:poue@hostname/c1 HTTP/1.1; host: {hostname}$" | ||
2802 | 10 | |||
2803 | 11 | # C2 | ||
2804 | 12 | recv | ||
2805 | 13 | expect ~ "^.* uri: GET http://hostname:8080/c2 HTTP/1.1; host: {hostname:8080}$" | ||
2806 | 14 | |||
2807 | 15 | # C3 | ||
2808 | 16 | recv | ||
2809 | 17 | expect ~ "^.* uri: GET https://hostname/c3 HTTP/1.1; host: {hostname}$" | ||
2810 | 18 | |||
2811 | 19 | # C4 | ||
2812 | 20 | recv | ||
2813 | 21 | expect ~ "^.* uri: GET https://hostname:80/c4 HTTP/1.1; host: {hostname:80}$" | ||
2814 | 22 | |||
2815 | 23 | # C5 | ||
2816 | 24 | recv | ||
2817 | 25 | expect ~ "^.* uri: CONNECT hostname:80 HTTP/1.1; host: {hostname}$" | ||
2818 | 26 | recv | ||
2819 | 27 | expect ~ "^.* uri: CONNECT hostname:80 HTTP/1.1; host: {hostname}$" | ||
2820 | 28 | |||
2821 | 29 | # C6 | ||
2822 | 30 | recv | ||
2823 | 31 | expect ~ "^.* uri: CONNECT hostname:443 HTTP/1.1; host: {hostname}$" | ||
2824 | 32 | recv | ||
2825 | 33 | expect ~ "^.* uri: CONNECT hostname:443 HTTP/1.1; host: {hostname}$" | ||
2826 | 34 | |||
2827 | 35 | recv | ||
2828 | 36 | expect ~ "^.* uri: CONNECT hostname:8443 HTTP/1.1; host: {hostname:8443}$" | ||
2829 | 37 | } -start | ||
2830 | 38 | |||
2831 | 39 | haproxy h1 -conf { | ||
2832 | 40 | defaults | ||
2833 | 41 | mode http | ||
2834 | 42 | timeout connect 1s | ||
2835 | 43 | timeout client 1s | ||
2836 | 44 | timeout server 1s | ||
2837 | 45 | |||
2838 | 46 | frontend fe | ||
2839 | 47 | bind "fd@${fe}" | ||
2840 | 48 | |||
2841 | 49 | http-request capture req.hdr(host) len 512 | ||
2842 | 50 | log-format "uri: %r; host: %hr" | ||
2843 | 51 | log ${S1_addr}:${S1_port} len 2048 local0 debug err | ||
2844 | 52 | |||
2845 | 53 | http-request return status 200 | ||
2846 | 54 | } -start | ||
2847 | 55 | |||
2848 | 56 | # default port 80 with http scheme => should be normalized | ||
2849 | 57 | # Be sure userinfo are skipped | ||
2850 | 58 | client c1 -connect ${h1_fe_sock} { | ||
2851 | 59 | txreq \ | ||
2852 | 60 | -req "GET" \ | ||
2853 | 61 | -url "http://toto:poue@hostname:80/c1" \ | ||
2854 | 62 | -hdr "host: hostname:80" | ||
2855 | 63 | |||
2856 | 64 | rxresp | ||
2857 | 65 | expect resp.status == 200 | ||
2858 | 66 | } -run | ||
2859 | 67 | |||
2860 | 68 | # port 8080 with http scheme => no normalization | ||
2861 | 69 | client c2 -connect ${h1_fe_sock} { | ||
2862 | 70 | txreq \ | ||
2863 | 71 | -req "GET" \ | ||
2864 | 72 | -url "http://hostname:8080/c2" \ | ||
2865 | 73 | -hdr "host: hostname:8080" | ||
2866 | 74 | |||
2867 | 75 | rxresp | ||
2868 | 76 | expect resp.status == 200 | ||
2869 | 77 | } -run | ||
2870 | 78 | |||
2871 | 79 | # default port 443 with https scheme => should be normalized | ||
2872 | 80 | client c3 -connect ${h1_fe_sock} { | ||
2873 | 81 | txreq \ | ||
2874 | 82 | -req "GET" \ | ||
2875 | 83 | -url "https://hostname:443/c3" \ | ||
2876 | 84 | -hdr "host: hostname:443" | ||
2877 | 85 | |||
2878 | 86 | rxresp | ||
2879 | 87 | expect resp.status == 200 | ||
2880 | 88 | } -run | ||
2881 | 89 | |||
2882 | 90 | # port 80 with https scheme => no normalization | ||
2883 | 91 | client c4 -connect ${h1_fe_sock} { | ||
2884 | 92 | txreq \ | ||
2885 | 93 | -req "GET" \ | ||
2886 | 94 | -url "https://hostname:80/c4" \ | ||
2887 | 95 | -hdr "host: hostname:80" | ||
2888 | 96 | |||
2889 | 97 | rxresp | ||
2890 | 98 | expect resp.status == 200 | ||
2891 | 99 | } -run | ||
2892 | 100 | |||
2893 | 101 | # CONNECT on port 80 => should be normalized | ||
2894 | 102 | client c5 -connect ${h1_fe_sock} { | ||
2895 | 103 | txreq \ | ||
2896 | 104 | -req "CONNECT" \ | ||
2897 | 105 | -url "hostname:80" \ | ||
2898 | 106 | -hdr "host: hostname:80" | ||
2899 | 107 | |||
2900 | 108 | rxresp | ||
2901 | 109 | expect resp.status == 200 | ||
2902 | 110 | } -run | ||
2903 | 111 | client c5 -connect ${h1_fe_sock} { | ||
2904 | 112 | |||
2905 | 113 | txreq \ | ||
2906 | 114 | -req "CONNECT" \ | ||
2907 | 115 | -url "hostname:80" \ | ||
2908 | 116 | -hdr "host: hostname" | ||
2909 | 117 | |||
2910 | 118 | rxresp | ||
2911 | 119 | expect resp.status == 200 | ||
2912 | 120 | } -run | ||
2913 | 121 | |||
2914 | 122 | # CONNECT on port 443 => should be normalized | ||
2915 | 123 | client c6 -connect ${h1_fe_sock} { | ||
2916 | 124 | txreq \ | ||
2917 | 125 | -req "CONNECT" \ | ||
2918 | 126 | -url "hostname:443" \ | ||
2919 | 127 | -hdr "host: hostname:443" | ||
2920 | 128 | |||
2921 | 129 | rxresp | ||
2922 | 130 | expect resp.status == 200 | ||
2923 | 131 | } -run | ||
2924 | 132 | client c6 -connect ${h1_fe_sock} { | ||
2925 | 133 | txreq \ | ||
2926 | 134 | -req "CONNECT" \ | ||
2927 | 135 | -url "hostname:443" \ | ||
2928 | 136 | -hdr "host: hostname" | ||
2929 | 137 | |||
2930 | 138 | rxresp | ||
2931 | 139 | expect resp.status == 200 | ||
2932 | 140 | } -run | ||
2933 | 141 | |||
2934 | 142 | # CONNECT on port non-default port => no normalization | ||
2935 | 143 | client c7 -connect ${h1_fe_sock} { | ||
2936 | 144 | txreq \ | ||
2937 | 145 | -req "CONNECT" \ | ||
2938 | 146 | -url "hostname:8443" \ | ||
2939 | 147 | -hdr "host: hostname:8443" | ||
2940 | 148 | |||
2941 | 149 | rxresp | ||
2942 | 150 | expect resp.status == 200 | ||
2943 | 151 | } -run | ||
2944 | 152 | |||
2945 | 153 | # host miss-match => error | ||
2946 | 154 | client c8 -connect ${h1_fe_sock} { | ||
2947 | 155 | txreq \ | ||
2948 | 156 | -req "GET" \ | ||
2949 | 157 | -url "http://hostname1/" \ | ||
2950 | 158 | -hdr "host: hostname2" | ||
2951 | 159 | |||
2952 | 160 | rxresp | ||
2953 | 161 | expect resp.status == 400 | ||
2954 | 162 | } -run | ||
2955 | 163 | |||
2956 | 164 | # port miss-match => error | ||
2957 | 165 | client c9 -connect ${h1_fe_sock} { | ||
2958 | 166 | txreq \ | ||
2959 | 167 | -req "GET" \ | ||
2960 | 168 | -url "http://hostname:80/" \ | ||
2961 | 169 | -hdr "host: hostname:81" | ||
2962 | 170 | |||
2963 | 171 | rxresp | ||
2964 | 172 | expect resp.status == 400 | ||
2965 | 173 | } -run | ||
2966 | 174 | |||
2967 | 175 | # no host port with a non-default port in abs-uri => error | ||
2968 | 176 | client c10 -connect ${h1_fe_sock} { | ||
2969 | 177 | txreq \ | ||
2970 | 178 | -req "GET" \ | ||
2971 | 179 | -url "http://hostname:8080/" \ | ||
2972 | 180 | -hdr "host: hostname" | ||
2973 | 181 | |||
2974 | 182 | rxresp | ||
2975 | 183 | expect resp.status == 400 | ||
2976 | 184 | } -run | ||
2977 | 185 | |||
2978 | 186 | # non-default host port with a default in abs-uri => error | ||
2979 | 187 | client c11 -connect ${h1_fe_sock} { | ||
2980 | 188 | txreq \ | ||
2981 | 189 | -req "GET" \ | ||
2982 | 190 | -url "http://hostname/" \ | ||
2983 | 191 | -hdr "host: hostname:81" | ||
2984 | 192 | |||
2985 | 193 | rxresp | ||
2986 | 194 | expect resp.status == 400 | ||
2987 | 195 | } -run | ||
2988 | 196 | |||
2989 | 197 | # miss-match between host headers => error | ||
2990 | 198 | client c12 -connect ${h1_fe_sock} { | ||
2991 | 199 | txreq \ | ||
2992 | 200 | -req "GET" \ | ||
2993 | 201 | -url "http://hostname1/" \ | ||
2994 | 202 | -hdr "host: hostname1" \ | ||
2995 | 203 | -hdr "host: hostname2" | ||
2996 | 204 | |||
2997 | 205 | rxresp | ||
2998 | 206 | expect resp.status == 400 | ||
2999 | 207 | } -run | ||
3000 | 208 | |||
3001 | 209 | # miss-match between host headers but with a normalization => error | ||
3002 | 210 | client c13 -connect ${h1_fe_sock} { | ||
3003 | 211 | txreq \ | ||
3004 | 212 | -req "GET" \ | ||
3005 | 213 | -url "http://hostname1/" \ | ||
3006 | 214 | -hdr "host: hostname1:80" \ | ||
3007 | 215 | -hdr "host: hostname1" | ||
3008 | 216 | |||
3009 | 217 | rxresp | ||
3010 | 218 | expect resp.status == 400 | ||
3011 | 219 | } -run | ||
3012 | 220 | |||
3013 | 221 | # CONNECT authoriy without port => error | ||
3014 | 222 | client c14 -connect ${h1_fe_sock} { | ||
3015 | 223 | txreq \ | ||
3016 | 224 | -req "CONNECT" \ | ||
3017 | 225 | -url "hostname" \ | ||
3018 | 226 | -hdr "host: hostname" | ||
3019 | 227 | |||
3020 | 228 | rxresp | ||
3021 | 229 | expect resp.status == 400 | ||
3022 | 230 | } -run | ||
3023 | 231 | |||
3024 | 232 | # host miss-match with CONNECT => error | ||
3025 | 233 | client c15 -connect ${h1_fe_sock} { | ||
3026 | 234 | txreq \ | ||
3027 | 235 | -req "CONNECT" \ | ||
3028 | 236 | -url "hostname1:80" \ | ||
3029 | 237 | -hdr "host: hostname2:80" | ||
3030 | 238 | |||
3031 | 239 | rxresp | ||
3032 | 240 | expect resp.status == 400 | ||
3033 | 241 | } -run | ||
3034 | 242 | |||
3035 | 243 | # port miss-match with CONNECT => error | ||
3036 | 244 | client c16 -connect ${h1_fe_sock} { | ||
3037 | 245 | txreq \ | ||
3038 | 246 | -req "CONNECT" \ | ||
3039 | 247 | -url "hostname:80" \ | ||
3040 | 248 | -hdr "host: hostname:443" | ||
3041 | 249 | |||
3042 | 250 | rxresp | ||
3043 | 251 | expect resp.status == 400 | ||
3044 | 252 | } -run | ||
3045 | 253 | |||
3046 | 254 | # no host port with non-default port in CONNECT authority => error | ||
3047 | 255 | client c17 -connect ${h1_fe_sock} { | ||
3048 | 256 | txreq \ | ||
3049 | 257 | -req "CONNECT" \ | ||
3050 | 258 | -url "hostname:8080" \ | ||
3051 | 259 | -hdr "host: hostname" | ||
3052 | 260 | |||
3053 | 261 | rxresp | ||
3054 | 262 | expect resp.status == 400 | ||
3055 | 263 | } -run | ||
3056 | 264 | |||
3057 | 265 | # no authority => error | ||
3058 | 266 | client c18 -connect ${h1_fe_sock} { | ||
3059 | 267 | txreq \ | ||
3060 | 268 | -req "CONNECT" \ | ||
3061 | 269 | -url "/" \ | ||
3062 | 270 | -hdr "host: hostname" | ||
3063 | 271 | |||
3064 | 272 | rxresp | ||
3065 | 273 | expect resp.status == 400 | ||
3066 | 274 | } -run | ||
3067 | 275 | |||
3068 | 276 | syslog S1 -wait | ||
3069 | diff --git a/reg-tests/http-messaging/http_request_buffer.vtc b/reg-tests/http-messaging/http_request_buffer.vtc | |||
3070 | index f1cec1a..e712e32 100644 | |||
3071 | --- a/reg-tests/http-messaging/http_request_buffer.vtc | |||
3072 | +++ b/reg-tests/http-messaging/http_request_buffer.vtc | |||
3073 | @@ -9,6 +9,8 @@ feature ignore_unknown_macro | |||
3074 | 9 | # thanks to "http-buffer-request". If this was the case, c2 client | 9 | # thanks to "http-buffer-request". If this was the case, c2 client |
3075 | 10 | # could not connect to s1 server and this would lead to make this test fail. | 10 | # could not connect to s1 server and this would lead to make this test fail. |
3076 | 11 | 11 | ||
3077 | 12 | barrier b1 cond 2 -cyclic | ||
3078 | 13 | |||
3079 | 12 | server s1 { | 14 | server s1 { |
3080 | 13 | rxreq | 15 | rxreq |
3081 | 14 | expect req.bodylen == 257 | 16 | expect req.bodylen == 257 |
3082 | @@ -23,11 +25,17 @@ server s1 { | |||
3083 | 23 | 25 | ||
3084 | 24 | syslog S -level info { | 26 | syslog S -level info { |
3085 | 25 | recv | 27 | recv |
3087 | 26 | expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 fe1/<NOSRV> .* 408 .* - - cD-- .* .* \"GET /this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url HTTP/1\\.1\"" | 28 | expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 fe1/<NOSRV> .* 408 .* - - cR-- .* .* \"GET /this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url HTTP/1\\.1\"" |
3088 | 29 | barrier b1 sync | ||
3089 | 30 | |||
3090 | 27 | recv | 31 | recv |
3091 | 28 | expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 be1/srv1 [0-9]*/[0-9]*/[0-9]*/[0-9]*/[0-9]* 200 .* - - ---- .* .* \"GET / HTTP/1\\.1\"" | 32 | expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 be1/srv1 [0-9]*/[0-9]*/[0-9]*/[0-9]*/[0-9]* 200 .* - - ---- .* .* \"GET / HTTP/1\\.1\"" |
3092 | 33 | barrier b1 sync | ||
3093 | 34 | |||
3094 | 29 | recv | 35 | recv |
3095 | 30 | expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe2 be1/srv1 [0-9]*/[0-9]*/[0-9]*/[0-9]*/[0-9]* 200 .* - - ---- .* .* \"POST /1 HTTP/1\\.1\"" | 36 | expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe2 be1/srv1 [0-9]*/[0-9]*/[0-9]*/[0-9]*/[0-9]* 200 .* - - ---- .* .* \"POST /1 HTTP/1\\.1\"" |
3096 | 37 | barrier b1 sync | ||
3097 | 38 | |||
3098 | 31 | recv | 39 | recv |
3099 | 32 | expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe2 be1/<NOSRV> [0-9]*/-1/-1/-1/[0-9]* -1 .* - - CR-- .* .* \"POST /2 HTTP/1\\.1\"" | 40 | expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe2 be1/<NOSRV> [0-9]*/-1/-1/-1/[0-9]* -1 .* - - CR-- .* .* \"POST /2 HTTP/1\\.1\"" |
3100 | 33 | } -start | 41 | } -start |
3101 | @@ -88,6 +96,9 @@ client c1 -connect ${h1_fe1_sock} { | |||
3102 | 88 | expect resp.status == 408 | 96 | expect resp.status == 408 |
3103 | 89 | } -run | 97 | } -run |
3104 | 90 | 98 | ||
3105 | 99 | # Wait matching on log message | ||
3106 | 100 | barrier b1 sync | ||
3107 | 101 | |||
3108 | 91 | # Payload is fully sent | 102 | # Payload is fully sent |
3109 | 92 | # ==> Request must be sent to the server. A 200 must be received | 103 | # ==> Request must be sent to the server. A 200 must be received |
3110 | 93 | client c2 -connect ${h1_fe1_sock} { | 104 | client c2 -connect ${h1_fe1_sock} { |
3111 | @@ -96,6 +107,9 @@ client c2 -connect ${h1_fe1_sock} { | |||
3112 | 96 | expect resp.status == 200 | 107 | expect resp.status == 200 |
3113 | 97 | } -run | 108 | } -run |
3114 | 98 | 109 | ||
3115 | 110 | # Wait matching on log message | ||
3116 | 111 | barrier b1 sync | ||
3117 | 112 | |||
3118 | 99 | # Payload is fully sent in 2 steps (with a small delay, smaller than the client | 113 | # Payload is fully sent in 2 steps (with a small delay, smaller than the client |
3119 | 100 | # timeout) and splitted on a chunk size. | 114 | # timeout) and splitted on a chunk size. |
3120 | 101 | # ==> Request must be sent to the server. A 200 must be received | 115 | # ==> Request must be sent to the server. A 200 must be received |
3121 | @@ -107,6 +121,9 @@ client c3 -connect ${h1_fe2_sock} { | |||
3122 | 107 | expect resp.status == 200 | 121 | expect resp.status == 200 |
3123 | 108 | } -run | 122 | } -run |
3124 | 109 | 123 | ||
3125 | 124 | # Wait matching on log message | ||
3126 | 125 | barrier b1 sync | ||
3127 | 126 | |||
3128 | 110 | # Last CRLF of the request payload is missing but payload is sent in 2 steps | 127 | # Last CRLF of the request payload is missing but payload is sent in 2 steps |
3129 | 111 | # (with a small delay, smaller than the client timeout) and splitted on a chunk | 128 | # (with a small delay, smaller than the client timeout) and splitted on a chunk |
3130 | 112 | # size. The client aborts before sending the last CRLF. | 129 | # size. The client aborts before sending the last CRLF. |
3131 | diff --git a/reg-tests/http-rules/restrict_req_hdr_names.vtc b/reg-tests/http-rules/restrict_req_hdr_names.vtc | |||
3132 | index 57bc7e1..b493c84 100644 | |||
3133 | --- a/reg-tests/http-rules/restrict_req_hdr_names.vtc | |||
3134 | +++ b/reg-tests/http-rules/restrict_req_hdr_names.vtc | |||
3135 | @@ -35,6 +35,32 @@ server s5 { | |||
3136 | 35 | txresp | 35 | txresp |
3137 | 36 | } -start | 36 | } -start |
3138 | 37 | 37 | ||
3139 | 38 | server s6 { | ||
3140 | 39 | rxreq | ||
3141 | 40 | expect req.http.x_my_hdr_with_lots_of_underscores == <undef> | ||
3142 | 41 | txresp | ||
3143 | 42 | } -start | ||
3144 | 43 | |||
3145 | 44 | server s7 { | ||
3146 | 45 | rxreq | ||
3147 | 46 | expect req.http.x_my_hdr-1 == <undef> | ||
3148 | 47 | expect req.http.x-my-hdr-2 == on | ||
3149 | 48 | txresp | ||
3150 | 49 | } -start | ||
3151 | 50 | |||
3152 | 51 | server s8 { | ||
3153 | 52 | rxreq | ||
3154 | 53 | expect req.http.x-my_hdr-1 == <undef> | ||
3155 | 54 | expect req.http.x-my_hdr-2 == <undef> | ||
3156 | 55 | txresp | ||
3157 | 56 | } -start | ||
3158 | 57 | |||
3159 | 58 | server s9 { | ||
3160 | 59 | rxreq | ||
3161 | 60 | expect req.http.x-my-hdr-with-trailing-underscore_ == <undef> | ||
3162 | 61 | txresp | ||
3163 | 62 | } -start | ||
3164 | 63 | |||
3165 | 38 | haproxy h1 -conf { | 64 | haproxy h1 -conf { |
3166 | 39 | defaults | 65 | defaults |
3167 | 40 | mode http | 66 | mode http |
3168 | @@ -50,6 +76,10 @@ haproxy h1 -conf { | |||
3169 | 50 | use_backend be-fcgi1 if { path /req4 } | 76 | use_backend be-fcgi1 if { path /req4 } |
3170 | 51 | use_backend be-fcgi2 if { path /req5 } | 77 | use_backend be-fcgi2 if { path /req5 } |
3171 | 52 | use_backend be-fcgi3 if { path /req6 } | 78 | use_backend be-fcgi3 if { path /req6 } |
3172 | 79 | use_backend be-http4 if { path /req7 } | ||
3173 | 80 | use_backend be-http5 if { path /req8 } | ||
3174 | 81 | use_backend be-http6 if { path /req9 } | ||
3175 | 82 | use_backend be-http7 if { path /req10 } | ||
3176 | 53 | 83 | ||
3177 | 54 | backend be-http1 | 84 | backend be-http1 |
3178 | 55 | server s1 ${s1_addr}:${s1_port} | 85 | server s1 ${s1_addr}:${s1_port} |
3179 | @@ -72,6 +102,22 @@ haproxy h1 -conf { | |||
3180 | 72 | backend be-fcgi3 | 102 | backend be-fcgi3 |
3181 | 73 | option http-restrict-req-hdr-names reject | 103 | option http-restrict-req-hdr-names reject |
3182 | 74 | 104 | ||
3183 | 105 | backend be-http4 | ||
3184 | 106 | option http-restrict-req-hdr-names delete | ||
3185 | 107 | server s6 ${s6_addr}:${s6_port} | ||
3186 | 108 | |||
3187 | 109 | backend be-http5 | ||
3188 | 110 | option http-restrict-req-hdr-names delete | ||
3189 | 111 | server s7 ${s7_addr}:${s7_port} | ||
3190 | 112 | |||
3191 | 113 | backend be-http6 | ||
3192 | 114 | option http-restrict-req-hdr-names delete | ||
3193 | 115 | server s8 ${s8_addr}:${s8_port} | ||
3194 | 116 | |||
3195 | 117 | backend be-http7 | ||
3196 | 118 | option http-restrict-req-hdr-names delete | ||
3197 | 119 | server s9 ${s9_addr}:${s9_port} | ||
3198 | 120 | |||
3199 | 75 | defaults | 121 | defaults |
3200 | 76 | mode http | 122 | mode http |
3201 | 77 | timeout connect 1s | 123 | timeout connect 1s |
3202 | @@ -114,6 +160,22 @@ client c1 -connect ${h1_fe1_sock} { | |||
3203 | 114 | txreq -req GET -url /req6 -hdr "X-my_hdr: on" | 160 | txreq -req GET -url /req6 -hdr "X-my_hdr: on" |
3204 | 115 | rxresp | 161 | rxresp |
3205 | 116 | expect resp.status == 403 | 162 | expect resp.status == 403 |
3206 | 163 | |||
3207 | 164 | txreq -req GET -url /req7 -hdr "X_my_hdr_with_lots_of_underscores: on" | ||
3208 | 165 | rxresp | ||
3209 | 166 | expect resp.status == 200 | ||
3210 | 167 | |||
3211 | 168 | txreq -req GET -url /req8 -hdr "X_my_hdr-1: on" -hdr "X-my-hdr-2: on" | ||
3212 | 169 | rxresp | ||
3213 | 170 | expect resp.status == 200 | ||
3214 | 171 | |||
3215 | 172 | txreq -req GET -url /req9 -hdr "X-my_hdr-1: on" -hdr "X-my_hdr-2: on" | ||
3216 | 173 | rxresp | ||
3217 | 174 | expect resp.status == 200 | ||
3218 | 175 | |||
3219 | 176 | txreq -req GET -url /req10 -hdr "X-my-hdr-with-trailing-underscore_: on" | ||
3220 | 177 | rxresp | ||
3221 | 178 | expect resp.status == 200 | ||
3222 | 117 | } -run | 179 | } -run |
3223 | 118 | 180 | ||
3224 | 119 | client c2 -connect ${h1_fe2_sock} { | 181 | client c2 -connect ${h1_fe2_sock} { |
3225 | diff --git a/reg-tests/log/log_forward.vtc b/reg-tests/log/log_forward.vtc | |||
3226 | 120 | new file mode 100644 | 182 | new file mode 100644 |
3227 | index 0000000..3977f4c | |||
3228 | --- /dev/null | |||
3229 | +++ b/reg-tests/log/log_forward.vtc | |||
3230 | @@ -0,0 +1,57 @@ | |||
3231 | 1 | varnishtest "Test the TCP load-forward" | ||
3232 | 2 | feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.3-dev1)'" | ||
3233 | 3 | feature ignore_unknown_macro | ||
3234 | 4 | |||
3235 | 5 | server s1 { | ||
3236 | 6 | rxreq | ||
3237 | 7 | txresp | ||
3238 | 8 | } -repeat 500 -start | ||
3239 | 9 | |||
3240 | 10 | syslog Slg1 -level info { | ||
3241 | 11 | recv | ||
3242 | 12 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* \"GET /client_c1 HTTP/1.1\"" | ||
3243 | 13 | } -repeat 50 -start | ||
3244 | 14 | |||
3245 | 15 | haproxy h1 -conf { | ||
3246 | 16 | defaults | ||
3247 | 17 | mode http | ||
3248 | 18 | option httplog | ||
3249 | 19 | timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" | ||
3250 | 20 | timeout client "${HAPROXY_TEST_TIMEOUT-5s}" | ||
3251 | 21 | timeout server "${HAPROXY_TEST_TIMEOUT-5s}" | ||
3252 | 22 | |||
3253 | 23 | frontend fe1 | ||
3254 | 24 | bind "fd@${fe_1}" | ||
3255 | 25 | log 127.0.0.1:1514 local0 | ||
3256 | 26 | # log ${Slg1_addr}:${Slg1_port} local0 | ||
3257 | 27 | default_backend be | ||
3258 | 28 | |||
3259 | 29 | backend be | ||
3260 | 30 | server app1 ${s1_addr}:${s1_port} | ||
3261 | 31 | |||
3262 | 32 | ring myring | ||
3263 | 33 | description "My local buffer" | ||
3264 | 34 | format rfc5424 | ||
3265 | 35 | maxlen 1200 | ||
3266 | 36 | size 32764 | ||
3267 | 37 | timeout connect 5s | ||
3268 | 38 | timeout server 10s | ||
3269 | 39 | # syslog tcp server | ||
3270 | 40 | server mysyslogsrv 127.0.0.1:2514 | ||
3271 | 41 | |||
3272 | 42 | log-forward syslog2tcp | ||
3273 | 43 | dgram-bind 127.0.0.1:1514 | ||
3274 | 44 | log ring@myring local0 # To TCP log | ||
3275 | 45 | |||
3276 | 46 | log-forward syslog2local | ||
3277 | 47 | bind 127.0.0.1:2514 | ||
3278 | 48 | log ${Slg1_addr}:${Slg1_port} local0 # To VTest syslog | ||
3279 | 49 | } -start | ||
3280 | 50 | |||
3281 | 51 | client c1 -connect ${h1_fe_1_sock} { | ||
3282 | 52 | txreq -url "/client_c1" | ||
3283 | 53 | rxresp | ||
3284 | 54 | expect resp.status == 200 | ||
3285 | 55 | } -repeat 50 -start | ||
3286 | 56 | |||
3287 | 57 | syslog Slg1 -wait | ||
3288 | diff --git a/reg-tests/mailers/healthcheckmail.vtc b/reg-tests/mailers/healthcheckmail.vtc | |||
3289 | index 43bf588..d36a0d3 100644 | |||
3290 | --- a/reg-tests/mailers/healthcheckmail.vtc | |||
3291 | +++ b/reg-tests/mailers/healthcheckmail.vtc | |||
3292 | @@ -5,7 +5,7 @@ feature ignore_unknown_macro | |||
3293 | 5 | 5 | ||
3294 | 6 | syslog S1 -level notice { | 6 | syslog S1 -level notice { |
3295 | 7 | recv | 7 | recv |
3297 | 8 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv1 failed.+reason: Socket error.+info: \".+\".+check duration: [[:digit:]]+ms.+status: 0/1 DOWN." | 8 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv1 failed.+check duration: [[:digit:]]+ms.+status: 0/1 DOWN." |
3298 | 9 | recv info | 9 | recv info |
3299 | 10 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Result=SUCCESS Bytes=[[:digit:]]+" | 10 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Result=SUCCESS Bytes=[[:digit:]]+" |
3300 | 11 | } -start | 11 | } -start |
3301 | diff --git a/reg-tests/ssl/log_forward_ssl.vtc b/reg-tests/ssl/log_forward_ssl.vtc | |||
3302 | 12 | new file mode 100644 | 12 | new file mode 100644 |
3303 | index 0000000..6b7515b | |||
3304 | --- /dev/null | |||
3305 | +++ b/reg-tests/ssl/log_forward_ssl.vtc | |||
3306 | @@ -0,0 +1,60 @@ | |||
3307 | 1 | varnishtest "Test the TCP+SSL load-forward" | ||
3308 | 2 | feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.3-dev1)'" | ||
3309 | 3 | feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" | ||
3310 | 4 | feature ignore_unknown_macro | ||
3311 | 5 | |||
3312 | 6 | server s1 { | ||
3313 | 7 | rxreq | ||
3314 | 8 | txresp | ||
3315 | 9 | } -repeat 500 -start | ||
3316 | 10 | |||
3317 | 11 | syslog Slg1 -level info { | ||
3318 | 12 | recv | ||
3319 | 13 | expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* \"GET /client_c1 HTTP/1.1\"" | ||
3320 | 14 | } -repeat 50 -start | ||
3321 | 15 | |||
3322 | 16 | haproxy h1 -conf { | ||
3323 | 17 | global | ||
3324 | 18 | insecure-fork-wanted | ||
3325 | 19 | defaults | ||
3326 | 20 | mode http | ||
3327 | 21 | option httplog | ||
3328 | 22 | timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" | ||
3329 | 23 | timeout client "${HAPROXY_TEST_TIMEOUT-5s}" | ||
3330 | 24 | timeout server "${HAPROXY_TEST_TIMEOUT-5s}" | ||
3331 | 25 | |||
3332 | 26 | frontend fe1 | ||
3333 | 27 | bind "fd@${fe_1}" | ||
3334 | 28 | log 127.0.0.1:1514 local0 | ||
3335 | 29 | # log ${Slg1_addr}:${Slg1_port} local0 | ||
3336 | 30 | default_backend be | ||
3337 | 31 | |||
3338 | 32 | backend be | ||
3339 | 33 | server app1 ${s1_addr}:${s1_port} | ||
3340 | 34 | |||
3341 | 35 | ring myring | ||
3342 | 36 | description "My local buffer" | ||
3343 | 37 | format rfc5424 | ||
3344 | 38 | maxlen 1200 | ||
3345 | 39 | size 32764 | ||
3346 | 40 | timeout connect 5s | ||
3347 | 41 | timeout server 10s | ||
3348 | 42 | # syslog tcp server | ||
3349 | 43 | server mysyslogsrv 127.0.0.1:2514 ssl verify none | ||
3350 | 44 | |||
3351 | 45 | log-forward syslog2tcp | ||
3352 | 46 | dgram-bind 127.0.0.1:1514 | ||
3353 | 47 | log ring@myring local0 # To TCP log | ||
3354 | 48 | |||
3355 | 49 | log-forward syslog2local | ||
3356 | 50 | bind 127.0.0.1:2514 ssl crt ${testdir}/common.pem | ||
3357 | 51 | log ${Slg1_addr}:${Slg1_port} local0 # To VTest syslog | ||
3358 | 52 | } -start | ||
3359 | 53 | |||
3360 | 54 | client c1 -connect ${h1_fe_1_sock} { | ||
3361 | 55 | txreq -url "/client_c1" | ||
3362 | 56 | rxresp | ||
3363 | 57 | expect resp.status == 200 | ||
3364 | 58 | } -repeat 50 -start | ||
3365 | 59 | |||
3366 | 60 | syslog Slg1 -wait | ||
3367 | diff --git a/reg-tests/startup/automatic_maxconn.vtc b/reg-tests/startup/automatic_maxconn.vtc | |||
3368 | 0 | new file mode 100644 | 61 | new file mode 100644 |
3369 | index 0000000..686a5c5 | |||
3370 | --- /dev/null | |||
3371 | +++ b/reg-tests/startup/automatic_maxconn.vtc | |||
3372 | @@ -0,0 +1,102 @@ | |||
3373 | 1 | #REGTEST_TYPE=broken | ||
3374 | 2 | #REQUIRE_VERSION=2.2 | ||
3375 | 3 | #REQUIRE_OPTION=OPENSSL | ||
3376 | 4 | |||
3377 | 5 | # Check the maxconn computation with the -m parameter | ||
3378 | 6 | # Broken because it can't work with ASAN. | ||
3379 | 7 | |||
3380 | 8 | varnishtest "Automatic maxconn computation" | ||
3381 | 9 | |||
3382 | 10 | |||
3383 | 11 | feature ignore_unknown_macro | ||
3384 | 12 | |||
3385 | 13 | server s1 { | ||
3386 | 14 | rxreq | ||
3387 | 15 | txresp | ||
3388 | 16 | } -start | ||
3389 | 17 | |||
3390 | 18 | |||
3391 | 19 | haproxy h1 -arg "-m 1024" -conf { | ||
3392 | 20 | } -start | ||
3393 | 21 | |||
3394 | 22 | haproxy h1 -cli { | ||
3395 | 23 | send "show info" | ||
3396 | 24 | expect ~ ".*Maxconn: 29000\n.*" | ||
3397 | 25 | } | ||
3398 | 26 | |||
3399 | 27 | haproxy h2 -arg "-m 384" -conf { | ||
3400 | 28 | } -start | ||
3401 | 29 | |||
3402 | 30 | haproxy h2 -cli { | ||
3403 | 31 | send "show info" | ||
3404 | 32 | expect ~ ".*Maxconn: 10000\n.*" | ||
3405 | 33 | } | ||
3406 | 34 | |||
3407 | 35 | haproxy h3 -arg "-m 256" -conf { | ||
3408 | 36 | } -start | ||
3409 | 37 | |||
3410 | 38 | haproxy h3 -cli { | ||
3411 | 39 | send "show info" | ||
3412 | 40 | expect ~ ".*Maxconn: 7300\n.*" | ||
3413 | 41 | } | ||
3414 | 42 | |||
3415 | 43 | # 1 SSL front but no back | ||
3416 | 44 | |||
3417 | 45 | haproxy h4 -arg "-m 256" -conf { | ||
3418 | 46 | defaults | ||
3419 | 47 | mode http | ||
3420 | 48 | timeout connect 1s | ||
3421 | 49 | timeout client 1s | ||
3422 | 50 | timeout server 1s | ||
3423 | 51 | |||
3424 | 52 | frontend fe1 | ||
3425 | 53 | bind "fd@${fe1}" ssl crt ${testdir}/common.pem | ||
3426 | 54 | |||
3427 | 55 | } -start | ||
3428 | 56 | |||
3429 | 57 | haproxy h4 -cli { | ||
3430 | 58 | send "show info" | ||
3431 | 59 | expect ~ ".*Maxconn: 1900\n.*" | ||
3432 | 60 | } | ||
3433 | 61 | |||
3434 | 62 | # 1 SSL back but not front | ||
3435 | 63 | |||
3436 | 64 | haproxy h5 -arg "-m 256" -conf { | ||
3437 | 65 | defaults | ||
3438 | 66 | mode http | ||
3439 | 67 | timeout connect 1s | ||
3440 | 68 | timeout client 1s | ||
3441 | 69 | timeout server 1s | ||
3442 | 70 | |||
3443 | 71 | listen li2 | ||
3444 | 72 | bind "fd@${li2}" | ||
3445 | 73 | server ssl "${s1_addr}:${s1_port}" ssl verify none | ||
3446 | 74 | |||
3447 | 75 | } -start | ||
3448 | 76 | |||
3449 | 77 | haproxy h5 -cli { | ||
3450 | 78 | send "show info" | ||
3451 | 79 | expect ~ ".*Maxconn: 1900\n.*" | ||
3452 | 80 | } | ||
3453 | 81 | |||
3454 | 82 | |||
3455 | 83 | # 1 SSL front and 1 back | ||
3456 | 84 | |||
3457 | 85 | haproxy h6 -arg "-m 256" -conf { | ||
3458 | 86 | defaults | ||
3459 | 87 | mode http | ||
3460 | 88 | timeout connect 1s | ||
3461 | 89 | timeout client 1s | ||
3462 | 90 | timeout server 1s | ||
3463 | 91 | |||
3464 | 92 | listen li3 | ||
3465 | 93 | bind "fd@${li3}" ssl crt ${testdir}/common.pem | ||
3466 | 94 | server ssl "${s1_addr}:${s1_port}" ssl verify none | ||
3467 | 95 | |||
3468 | 96 | } -start | ||
3469 | 97 | |||
3470 | 98 | haproxy h6 -cli { | ||
3471 | 99 | send "show info" | ||
3472 | 100 | expect ~ ".*Maxconn: 1700\n.*" | ||
3473 | 101 | } | ||
3474 | 102 | |||
3475 | diff --git a/reg-tests/startup/common.pem b/reg-tests/startup/common.pem | |||
3476 | 0 | new file mode 100644 | 103 | new file mode 100644 |
3477 | index 0000000..206e417 | |||
3478 | --- /dev/null | |||
3479 | +++ b/reg-tests/startup/common.pem | |||
3480 | @@ -0,0 +1,117 @@ | |||
3481 | 1 | -----BEGIN RSA PRIVATE KEY----- | ||
3482 | 2 | MIIEpAIBAAKCAQEAnb0BDF7FsqzslakNg7u/n/JQkq6nheuKwvyTqECfpc9y7uSB | ||
3483 | 3 | e/vrEFqBaDSLQagJxuZdL5geFeVtRbdAoB97N1/LZa6vecjjgGSP0Aag/gS/ocnM | ||
3484 | 4 | RIyvlVWWT9MrD46OG3qZY1ORU1ltrVL0NKttJP8xME7j3bTwIDElx/hNI0n7L+yS | ||
3485 | 5 | kAe2xb/7CbZRfoOhjTVAcGv4aSLVc/Hi8k6VkIzdOEtH6TcghXmuGcuqvLNH9Buo | ||
3486 | 6 | syngKTcQ8zg6J+e64aVvC+e7vi94uil9Qu+JHm0pkDzAZ2WluNsuXlrJToPirWyj | ||
3487 | 7 | 6/YdN6xgSI1hbZkBmUPAebgYuxBt6huvfyQd3wIDAQABAoIBABojc8UE/2W4WgwC | ||
3488 | 8 | 04Z82ig7Ezb7Ui9S9M+S4zUCYHItijIkE4DkIfO3y7Hk4x6iJdyb191HK9UdC5p9 | ||
3489 | 9 | 32upS9XFPgM/izx3GZvxDhO+xXbSep7ovbyuQ3pPkHTx3TTavpm3GyvmcTKKoy4R | ||
3490 | 10 | jP4dWhzDXPdQW1ol3ZS4EDau4rlyClY6oi1mq9aBEX3MqVjB/nO7s2AbdgclAgP2 | ||
3491 | 11 | OZMhTzWYR1k5tYySHCXh3ggGMCikyvHU0+SsGyrstYzP1VYi/n3f0VgqW/5ZjG8x | ||
3492 | 12 | 6SHpe04unErPF3HuSun2ZMCFdBxaTFZ8FENb8evrSXe3nQOc9W21RQdRRrNNUbjl | ||
3493 | 13 | JYI4veECgYEA0ATYKMS1VCUYRZoQ49b5GTg7avUYqfW4bEo4fSfBue8NrnKR3Wu8 | ||
3494 | 14 | PPBiCTuIYq1vSF+60B7Vu+hW0A8OuQ2UuMxLpYcQ7lKfNad/+yAfoWWafIqCqNU9 | ||
3495 | 15 | at0QMdbW6A69d6jZt7OrXtleBsphCnN58jTz4ch4PIa2Oyq46NUXCvUCgYEAwh8t | ||
3496 | 16 | G6BOHOs3yRNI2s9Y9EEfwoil2uIKrZhqiL3AwdIpu5uNIMuPnbaEpXvRX6jv/qtL | ||
3497 | 17 | 321i8vZLc31aM7zfxQ6B4ReQFJfYC80FJsWvcLwT9hB9mTJpLS4sIu5tzQc87O6w | ||
3498 | 18 | RtjFMom+5ns5hfPB4Eccy0EtbQWVY4nCzUeO6QMCgYBSvqqRRPXwG7VU8lznlHqP | ||
3499 | 19 | upuABzChYrnScY+Y0TixUlL54l79Wb6N6vzEOWceAWkzu8iewrU4QspNhr/PgoR3 | ||
3500 | 20 | IeSxWlG0yy7Dc/ZnmTabx8O06I/iwrfkizzG5nOj6UEamRLJjPGNEB/jyZriQl7u | ||
3501 | 21 | pnugg1K4mMliLbNSAnlhBQKBgQCmYepbv260Qrex1KGhSg9Ia3k5V74weYYFfJnz | ||
3502 | 22 | UhChD+1NK+ourcsOtp3C6PlwMHBjq5aAjlU9QfUxq8NgjQaO8/xGXdfUjsFSfAtq | ||
3503 | 23 | TA4vZkUFpuTAJgEYBHc4CXx7OzTxLzRPxQRgaMgC7KNFOMR34vu/CsJQq3R7uFwL | ||
3504 | 24 | bsYC2QKBgQCtEmg1uDZVdByX9zyUMuRxz5Tq/vDcp+A5lJj2mha1+bUMaKX2+lxQ | ||
3505 | 25 | vPxY55Vaw/ukWkJirRrpGv6IytBn0dLAFSlKZworZGBaxsm8OGTFJ5Oe9+kZTjI9 | ||
3506 | 26 | hvjpClOA1otbmj2F2uZAbuIjxQGDNUkLoifN5yDYCC8JPujHuHmULw== | ||
3507 | 27 | -----END RSA PRIVATE KEY----- | ||
3508 | 28 | -----BEGIN CERTIFICATE----- | ||
3509 | 29 | MIIGeTCCBGGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJGUjEW | ||
3510 | 30 | MBQGA1UECBMNSWxlLWRlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoT | ||
3511 | 31 | B296b24uaW8xFTATBgNVBAMTDE96b24gVGVzdCBDQTEeMBwGCSqGSIb3DQEJARYP | ||
3512 | 32 | c3VwcG9ydEBvem9uLmlvMB4XDTE2MDExNzIzMDIzOFoXDTE4MDExNjIzMDIzOFow | ||
3513 | 33 | gb4xCzAJBgNVBAYTAkZSMRYwFAYDVQQIEw1JbGUtZGUtRnJhbmNlMRowGAYDVQQH | ||
3514 | 34 | ExFOZXVpbGx5LXN1ci1TZWluZTEYMBYGA1UEChMPVE9BRCBDb25zdWx0aW5nMRcw | ||
3515 | 35 | FQYDVQQLEw5lUGFyYXBoZXIgVGVhbTEWMBQGA1UEAxMNd3d3LnRlc3QxLmNvbTEw | ||
3516 | 36 | MC4GCSqGSIb3DQEJARYhYXJuYXVsdC5taWNoZWxAdG9hZC1jb25zdWx0aW5nLmZy | ||
3517 | 37 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnb0BDF7FsqzslakNg7u/ | ||
3518 | 38 | n/JQkq6nheuKwvyTqECfpc9y7uSBe/vrEFqBaDSLQagJxuZdL5geFeVtRbdAoB97 | ||
3519 | 39 | N1/LZa6vecjjgGSP0Aag/gS/ocnMRIyvlVWWT9MrD46OG3qZY1ORU1ltrVL0NKtt | ||
3520 | 40 | JP8xME7j3bTwIDElx/hNI0n7L+ySkAe2xb/7CbZRfoOhjTVAcGv4aSLVc/Hi8k6V | ||
3521 | 41 | kIzdOEtH6TcghXmuGcuqvLNH9BuosyngKTcQ8zg6J+e64aVvC+e7vi94uil9Qu+J | ||
3522 | 42 | Hm0pkDzAZ2WluNsuXlrJToPirWyj6/YdN6xgSI1hbZkBmUPAebgYuxBt6huvfyQd | ||
3523 | 43 | 3wIDAQABo4IBvzCCAbswCwYDVR0PBAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUFBwMB | ||
3524 | 44 | MB0GA1UdDgQWBBTIihFNVNgOseQnsWEcAQxAbIKE4TCBsgYDVR0jBIGqMIGngBRv | ||
3525 | 45 | G9At9gzk2MW5Z7JVey1LtPIZ8KGBg6SBgDB+MQswCQYDVQQGEwJGUjEWMBQGA1UE | ||
3526 | 46 | CBMNSWxlLWRlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoTB296b24u | ||
3527 | 47 | aW8xFTATBgNVBAMTDE96b24gVGVzdCBDQTEeMBwGCSqGSIb3DQEJARYPc3VwcG9y | ||
3528 | 48 | dEBvem9uLmlvggkA15FtIaGcrk8wDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg9j | ||
3529 | 49 | b21tb25OYW1lOmNvcHkwCQYDVR0SBAIwADBIBgNVHR8EQTA/MD2gO6A5hjdodHRw | ||
3530 | 50 | Oi8vb3BlbnNzbGNhLnRvYWQtY29uc3VsdGluZy5jb20vb3BlbnZwbi9MYXRlc3Qu | ||
3531 | 51 | Y3JsMBEGCWCGSAGG+EIBAQQEAwIGQDAxBglghkgBhvhCAQ0EJBYiVE9BRC1Db25z | ||
3532 | 52 | dWx0aW5nIHNlcnZlciBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAgEAewDa | ||
3533 | 53 | 9BukGNJMex8gsXmmdaczTr8yh9Uvw4NJcZS38I+26o//2g+d6i7wxcQg8hIm62Hj | ||
3534 | 54 | 0TblGU3+RsJo4uzcWxxA5YUYlVszbHNBRpQengEE5pjwHvoXVMNES6Bt8xP04+Vj | ||
3535 | 55 | 0qVnA8gUaDMk9lN5anK7tF/mbHOIJwHJZYCa2t3y95dIOVEXFwOIzzbSbaprjkLN | ||
3536 | 56 | w0BgR5paJz7NZWNqo4sZHUUz94uH2bPEd01SqHO0dJwEVxadgxuPnD05I9gqGpGX | ||
3537 | 57 | Zf3Rn7EQylvUtX9mpPaulQPXc3emefewLUSSAdnZrVikZK2J/B4lSi9FpUwl4iQH | ||
3538 | 58 | pZoE0QLQHtB1SBKacnOAddGSTLSdFvpzjErjjWSpMukF0vutmrP86GG3xtshWVhI | ||
3539 | 59 | u+yLfDJVm/pXfaeDtWMXpxIT/U1i0avpk5MZtFMRC0MTaxEWBTnnJm+/yiaAXQYg | ||
3540 | 60 | E1ZIP0mkZkiUojIawTR7JTjHGhIraP9UVPNceVy0DLfETHEou3vhwBn7PFOz7piJ | ||
3541 | 61 | wjp3A47DStJD4fapaX6B1fqM+n34CMD9ZAiJFgQEIQfObAWC9hyr4m+pqkp1Qfuw | ||
3542 | 62 | vsAP/ZoS1CBirJfm3i+Gshh+VeH+TAmO/NBBYCfzBdgkNz4tJCkOc7CUT/NQTR/L | ||
3543 | 63 | N2OskR/Fkge149RJi7hHvE3gk/mtGtNmHJPuQ+s= | ||
3544 | 64 | -----END CERTIFICATE----- | ||
3545 | 65 | -----BEGIN CERTIFICATE----- | ||
3546 | 66 | MIIJazCCBVOgAwIBAgIUWHoc5e2FUECgyCvyVf8wCtt8gTYwDQYJKoZIhvcNAQEL | ||
3547 | 67 | BQAwRTELMAkGA1UEBhMCRlIxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM | ||
3548 | 68 | GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA4MDQxODU4MTZaFw0yMDA5 | ||
3549 | 69 | MDMxODU4MTZaMEUxCzAJBgNVBAYTAkZSMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw | ||
3550 | 70 | HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggQiMA0GCSqGSIb3DQEB | ||
3551 | 71 | AQUAA4IEDwAwggQKAoIEAQDARiuHkhrnf38Md1nxGDSneJfwv/QksdNNMNTJBdjg | ||
3552 | 72 | OVmaRCIAyz43oefTWDQ/TebbSwB+Lg9pud1zadGWhlZRhCgBPP8JDMhIKH4eXIRk | ||
3553 | 73 | 5IIa8WD08EwvSlqJL0r4gsMtVsxy7BZHAkka/2Ket9pyGt4kG5n75RFdc6BI80/8 | ||
3554 | 74 | RwJt/MDxPrcVBAT7LnCluxQpyya9mZCabj7l+9a2yU2hgWS6QqfZJ133krkP/MMh | ||
3555 | 75 | AEQkSoA4mmBwWk9yPqXmUqiOi7v6iLkIUEh5SgYVPRk9BtU/kDaUdSwuqRrpCZo4 | ||
3556 | 76 | SsWZWFLxBmLHkSh+G+BWjCVYMQr2ye7e+VMT/20+5xAfq4fj9n5BsPcx3QcVuTof | ||
3557 | 77 | RAc/Oygnt4MYnIcUb7zRFvCAvgpUHL7BnEn6nhyXjHJGqGDchsg8m9t3v/Y3ohq+ | ||
3558 | 78 | qmrSzdeuylE1n3W5aWJlbFmyXegNP45MJ0xicesVrXEWF7YD/ir9mGJ8bQYr4blf | ||
3559 | 79 | 77PrbF02komC6AzVPKOJa0jR+eW1wErzYlkYgez6ylBWCiHJd1dhEHlK3h2rXdYa | ||
3560 | 80 | Gnb45ILCLpEDjNEUrHifLLNXwqJpgZQsJU6BgMgk7ZgBfAKrCfTeg0rkCqCAPeVb | ||
3561 | 81 | 8eSLf7FBF7YBRJ5P6u8qXc4RtgEu607GaWV0gIMfyVBY52oV+OaNsEdFetrJnp3c | ||
3562 | 82 | friG8vJ+7jdq6zjUCGgnfUIHoViJPh3JuFfhA3jT0gQDKW5PeI7dxhrNvlqdYfHI | ||
3563 | 83 | fxX7Y1/J6cTQkqJ1cai2f0bwJIJiTAThNbG+zrtjJ7fZ3wJ4udyU/IKrwShqtmTb | ||
3564 | 84 | 1Ofj0tJDdwOH8i84vIySLUvR9aAb7ClFlnsx6rzwOxG90W7C0LA2M0EHm4FezJm/ | ||
3565 | 85 | FfujnZwEWr1T9Wki6qE0MHCbdN/TTDws//EKkkE44FC+amL96w0IQl70vpE37j2A | ||
3566 | 86 | zlDWvFFID95SIxfmpkwWDvXDKv6gr1GMLeysCl2fgpY05Xidw5cEo9/tEkuWn/dG | ||
3567 | 87 | x/D9hnLBGeroA0251ES12jemqDjI2U0tfaeHakjwSsoWElf94Qmuh2iPZ+1zIxQs | ||
3568 | 88 | 7o6nAWN8X9hfsmrDTTHlww0TEfrjlbzG5Yh+0ZRxmejgiUyOCXck+eh/ZXMXvfWh | ||
3569 | 89 | y3CorIIuWgkRjm80PYkdaRDJdZuyP6R7tXfTXNVzAiSQf0Qx9ru2KB2Fs/XZPamH | ||
3570 | 90 | KjItAU5Q6msIVvaRMS0muQgV+b6hqSEBzqXqJfAlpVLHXr5FqK+U7EB9y02B6piB | ||
3571 | 91 | tAmxqXP8OOCoQql6/vgIcrDFUOo6KtGBW36ef74XE3KCUVaIzVJZSIt6i/Vi0bZj | ||
3572 | 92 | bAjsJUQ3qDlHdorv9TRVOhnC1GUz7SuYnpEOyiXmyx3LAgMBAAGjUzBRMB0GA1Ud | ||
3573 | 93 | DgQWBBQ62csZcH/meQcENHhNbqz9LMzwjjAfBgNVHSMEGDAWgBQ62csZcH/meQcE | ||
3574 | 94 | NHhNbqz9LMzwjjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IEAQBA | ||
3575 | 95 | wLsGf3R1+/I2zQE+lsj7RasZtA/Cos92iEGDAPvFbx9e+roG8Gg8KBsEJu/HN0JH | ||
3576 | 96 | lMMiQ8dDRHSBMvRBENL5/57oOOhmqc+1u5sazLuANhzAYPZG17Klib7YpEwWoXar | ||
3577 | 97 | FDDiJYtCyLW0oNLpCswYopWK9GC0RJNucB0NFvOxehJ2sP2/fxGBQMB09L6mjKjd | ||
3578 | 98 | 4KsOzyd3dNf0VYS6jB+/1pcKSHKQUo9HRHB5FK04PsYHoh4AtmEHvmYQKcWWidgU | ||
3579 | 99 | v26ftlH00ERzuW2juqBbz9mghlNRqXi0IyZ9b4tSj29dxW+WWFzo7j2zEPaD6z2W | ||
3580 | 100 | DEHq7zvON+g+q6qLgWeszqMgJzjvWjMj00E/t06PoHPiz/cAnDKEqp+ZzxCIFrxj | ||
3581 | 101 | /qneChpogDWyLbawhyyzbZvbirx5znOSbWjPZgydqaNEFViqbxwinBx4Xxabo6XN | ||
3582 | 102 | TU020FuMWmgfbIcvtgjKgyKqc97l7JMNNm7LQV9+9W0U5zdIqQKLZ9MMrd2w3xh4 | ||
3583 | 103 | MAB8NKnwzHReK0TWwUU9HSgFAGdEX6HnyZ3bQ13ijg+sNBRMEi0gBHaqZKDdyoft | ||
3584 | 104 | B2u2uasSwioV48dbSIcHl+rTBKxiMh5XQ7ENnaGOJkjsIqTVzizqnPHU8eMBnSbb | ||
3585 | 105 | dsXlamROYII44+j3Ku6OGt51w86eGk4VxI3tmaECcJKqTkwUFD8AcNDrkjtmLuxK | ||
3586 | 106 | 12yjnoM+u1cclfqQ5NOtRc6MJZ27jCobfBBhVdKVDp4X1WNyqGlbsU5adDAzknuI | ||
3587 | 107 | GT7MJO7lGjkZX2n54BNPSfrSknYMOVYcZqL0Dbcrhx5IyEmg+iOlOu1HO1tdnZop | ||
3588 | 108 | ej4vT+1V2w9Sa4Wo3UCo84jcm5v/4z7jCYh4BRQ60CFb7GLxZoqXIslcGSPool3n | ||
3589 | 109 | jl8JWoaLXrJUPfZGXo1iAlayJ5EiMyZl4eB/TBUf6TMm8vLvsPiUT+CEsjLppOdS | ||
3590 | 110 | eYppZAZ6H1JrJGs5kKBdOJHGn6Pkp5QsHIswOBd1HqHrBbYbZmDaDLRHduILWLrM | ||
3591 | 111 | e0/IfDdeXB/bKfmZoEpT8xRiauw15p0AHLumiK7KISAehfgBqUnxx+YmgGoZ7EWX | ||
3592 | 112 | KnMYAfCuC6oJ1DL0gp4Z9yMK1eu+GV1sLxPq9ZruEHW1R+H+4sGyiA5Gso2tgB6/ | ||
3593 | 113 | XW//wxKclNp5LZR7hqfs/kGuh5asrJrnEbMwWn2+tr/LqfYtYh1D6nHfIXpT0o1d | ||
3594 | 114 | rNy/HrsKnRDMWxjm03r4hCViuNVD3Zb9anAF/NSPDVu8ATM5JbJNrCYX4eipz6ZE | ||
3595 | 115 | aQBkwIBkTPgtgP4r8v2G+uMYDw8nq7xh72FK107aeTTwc6MgU5jfeFNMr2XJisJd | ||
3596 | 116 | lSem1ngKYQSEzjVsTE4c | ||
3597 | 117 | -----END CERTIFICATE----- | ||
3598 | diff --git a/scripts/announce-release b/scripts/announce-release | |||
3599 | index 37e2ac4..c990821 100755 | |||
3600 | --- a/scripts/announce-release | |||
3601 | +++ b/scripts/announce-release | |||
3602 | @@ -210,20 +210,21 @@ else | |||
3603 | 210 | fi | 210 | fi |
3604 | 211 | 211 | ||
3605 | 212 | (echo "Please find the usual URLs below :" | 212 | (echo "Please find the usual URLs below :" |
3608 | 213 | echo " Site index : http://www.haproxy.org/" | 213 | echo " Site index : https://www.haproxy.org/" |
3609 | 214 | echo " Documentation : http://docs.haproxy.org/" | 214 | echo " Documentation : https://docs.haproxy.org/" |
3610 | 215 | echo " Wiki : https://github.com/haproxy/wiki/wiki" | 215 | echo " Wiki : https://github.com/haproxy/wiki/wiki" |
3612 | 216 | echo " Discourse : http://discourse.haproxy.org/" | 216 | echo " Discourse : https://discourse.haproxy.org/" |
3613 | 217 | echo " Slack channel : https://slack.haproxy.org/" | 217 | echo " Slack channel : https://slack.haproxy.org/" |
3614 | 218 | echo " Issue tracker : https://github.com/haproxy/haproxy/issues" | 218 | echo " Issue tracker : https://github.com/haproxy/haproxy/issues" |
3623 | 219 | echo " Sources : http://www.haproxy.org/download/${BRANCH}/src/" | 219 | echo " Sources : https://www.haproxy.org/download/${BRANCH}/src/" |
3624 | 220 | echo " Git repository : http://git.haproxy.org/git/${gitdir}/" | 220 | echo " Git repository : https://git.haproxy.org/git/${gitdir}/" |
3625 | 221 | echo " Git Web browsing : http://git.haproxy.org/?p=${gitdir}" | 221 | echo " Git Web browsing : https://git.haproxy.org/?p=${gitdir}" |
3626 | 222 | echo " Changelog : http://www.haproxy.org/download/${BRANCH}/src/CHANGELOG" | 222 | echo " Changelog : https://www.haproxy.org/download/${BRANCH}/src/CHANGELOG" |
3627 | 223 | echo " Pending bugs : http://www.haproxy.org/l/pending-bugs" | 223 | echo " Dataplane API : https://github.com/haproxytech/dataplaneapi/releases/latest" |
3628 | 224 | echo " Reviewed bugs : http://www.haproxy.org/l/reviewed-bugs" | 224 | echo " Pending bugs : https://www.haproxy.org/l/pending-bugs" |
3629 | 225 | echo " Code reports : http://www.haproxy.org/l/code-reports" | 225 | echo " Reviewed bugs : https://www.haproxy.org/l/reviewed-bugs" |
3630 | 226 | echo " Latest builds : http://www.haproxy.org/l/dev-packages" | 226 | echo " Code reports : https://www.haproxy.org/l/code-reports" |
3631 | 227 | echo " Latest builds : https://www.haproxy.org/l/dev-packages" | ||
3632 | 227 | ) >> "$OUTPUT" | 228 | ) >> "$OUTPUT" |
3633 | 228 | 229 | ||
3634 | 229 | # sign | 230 | # sign |
3635 | diff --git a/src/backend.c b/src/backend.c | |||
3636 | index 6f2cc05..64780e4 100644 | |||
3637 | --- a/src/backend.c | |||
3638 | +++ b/src/backend.c | |||
3639 | @@ -2326,7 +2326,6 @@ void back_handle_st_cer(struct stream *s) | |||
3640 | 2326 | 2326 | ||
3641 | 2327 | /* only wait when we're retrying on the same server */ | 2327 | /* only wait when we're retrying on the same server */ |
3642 | 2328 | if ((si->state == SI_ST_ASS || | 2328 | if ((si->state == SI_ST_ASS || |
3643 | 2329 | (s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_RR || | ||
3644 | 2330 | (s->be->srv_act <= 1)) && !reused) { | 2329 | (s->be->srv_act <= 1)) && !reused) { |
3645 | 2331 | si->state = SI_ST_TAR; | 2330 | si->state = SI_ST_TAR; |
3646 | 2332 | si->exp = tick_add(now_ms, MS_TO_TICKS(delay)); | 2331 | si->exp = tick_add(now_ms, MS_TO_TICKS(delay)); |
3647 | diff --git a/src/cache.c b/src/cache.c | |||
3648 | index ad4e715..ecf62fb 100644 | |||
3649 | --- a/src/cache.c | |||
3650 | +++ b/src/cache.c | |||
3651 | @@ -136,7 +136,7 @@ struct cache_st { | |||
3652 | 136 | struct cache_entry { | 136 | struct cache_entry { |
3653 | 137 | unsigned int complete; /* An entry won't be valid until complete is not null. */ | 137 | unsigned int complete; /* An entry won't be valid until complete is not null. */ |
3654 | 138 | unsigned int latest_validation; /* latest validation date */ | 138 | unsigned int latest_validation; /* latest validation date */ |
3656 | 139 | unsigned int expire; /* expiration date */ | 139 | unsigned int expire; /* expiration date (wall clock time) */ |
3657 | 140 | unsigned int age; /* Origin server "Age" header value */ | 140 | unsigned int age; /* Origin server "Age" header value */ |
3658 | 141 | 141 | ||
3659 | 142 | struct eb32_node eb; /* ebtree node used to hold the cache object */ | 142 | struct eb32_node eb; /* ebtree node used to hold the cache object */ |
3660 | @@ -188,7 +188,7 @@ struct cache_entry *entry_exist(struct cache *cache, char *hash) | |||
3661 | 188 | if (memcmp(entry->hash, hash, sizeof(entry->hash))) | 188 | if (memcmp(entry->hash, hash, sizeof(entry->hash))) |
3662 | 189 | return NULL; | 189 | return NULL; |
3663 | 190 | 190 | ||
3665 | 191 | if (entry->expire > now.tv_sec) { | 191 | if (entry->expire > date.tv_sec) { |
3666 | 192 | return entry; | 192 | return entry; |
3667 | 193 | } else { | 193 | } else { |
3668 | 194 | delete_entry(entry); | 194 | delete_entry(entry); |
3669 | @@ -249,7 +249,7 @@ struct cache_entry *secondary_entry_exist(struct cache *cache, struct cache_entr | |||
3670 | 249 | * when we find them. Calling delete_entry would be too costly | 249 | * when we find them. Calling delete_entry would be too costly |
3671 | 250 | * so we simply call eb32_delete. The secondary_entry count will | 250 | * so we simply call eb32_delete. The secondary_entry count will |
3672 | 251 | * be updated when we try to insert a new entry to this list. */ | 251 | * be updated when we try to insert a new entry to this list. */ |
3674 | 252 | if (entry->expire <= now.tv_sec) { | 252 | if (entry->expire <= date.tv_sec) { |
3675 | 253 | eb32_delete(&entry->eb); | 253 | eb32_delete(&entry->eb); |
3676 | 254 | entry->eb.key = 0; | 254 | entry->eb.key = 0; |
3677 | 255 | } | 255 | } |
3678 | @@ -258,7 +258,7 @@ struct cache_entry *secondary_entry_exist(struct cache *cache, struct cache_entr | |||
3679 | 258 | } | 258 | } |
3680 | 259 | 259 | ||
3681 | 260 | /* Expired entry */ | 260 | /* Expired entry */ |
3683 | 261 | if (entry && entry->expire <= now.tv_sec) { | 261 | if (entry && entry->expire <= date.tv_sec) { |
3684 | 262 | eb32_delete(&entry->eb); | 262 | eb32_delete(&entry->eb); |
3685 | 263 | entry->eb.key = 0; | 263 | entry->eb.key = 0; |
3686 | 264 | entry = NULL; | 264 | entry = NULL; |
3687 | @@ -283,7 +283,7 @@ static unsigned int clear_expired_duplicates(struct eb32_node **dup_tail) | |||
3688 | 283 | while (prev) { | 283 | while (prev) { |
3689 | 284 | entry = container_of(prev, struct cache_entry, eb); | 284 | entry = container_of(prev, struct cache_entry, eb); |
3690 | 285 | prev = eb32_prev_dup(prev); | 285 | prev = eb32_prev_dup(prev); |
3692 | 286 | if (entry->expire <= now.tv_sec) { | 286 | if (entry->expire <= date.tv_sec) { |
3693 | 287 | eb32_delete(&entry->eb); | 287 | eb32_delete(&entry->eb); |
3694 | 288 | entry->eb.key = 0; | 288 | entry->eb.key = 0; |
3695 | 289 | } | 289 | } |
3696 | @@ -315,7 +315,7 @@ static struct eb32_node *insert_entry(struct cache *cache, struct cache_entry *n | |||
3697 | 315 | struct eb32_node *prev = NULL; | 315 | struct eb32_node *prev = NULL; |
3698 | 316 | struct cache_entry *entry = NULL; | 316 | struct cache_entry *entry = NULL; |
3699 | 317 | unsigned int entry_count = 0; | 317 | unsigned int entry_count = 0; |
3701 | 318 | unsigned int last_clear_ts = now.tv_sec; | 318 | unsigned int last_clear_ts = date.tv_sec; |
3702 | 319 | 319 | ||
3703 | 320 | struct eb32_node *node = eb32_insert(&cache->entries, &new_entry->eb); | 320 | struct eb32_node *node = eb32_insert(&cache->entries, &new_entry->eb); |
3704 | 321 | 321 | ||
3705 | @@ -338,7 +338,7 @@ static struct eb32_node *insert_entry(struct cache *cache, struct cache_entry *n | |||
3706 | 338 | * space. In order to avoid going over the same list too | 338 | * space. In order to avoid going over the same list too |
3707 | 339 | * often, we first check the timestamp of the last check | 339 | * often, we first check the timestamp of the last check |
3708 | 340 | * performed. */ | 340 | * performed. */ |
3710 | 341 | if (last_clear_ts == now.tv_sec) { | 341 | if (last_clear_ts == date.tv_sec) { |
3711 | 342 | /* Too many entries for this primary key, clear the | 342 | /* Too many entries for this primary key, clear the |
3712 | 343 | * one that was inserted. */ | 343 | * one that was inserted. */ |
3713 | 344 | eb32_delete(node); | 344 | eb32_delete(node); |
3714 | @@ -351,7 +351,7 @@ static struct eb32_node *insert_entry(struct cache *cache, struct cache_entry *n | |||
3715 | 351 | /* Still too many entries for this primary key, delete | 351 | /* Still too many entries for this primary key, delete |
3716 | 352 | * the newly inserted one. */ | 352 | * the newly inserted one. */ |
3717 | 353 | entry = container_of(prev, struct cache_entry, eb); | 353 | entry = container_of(prev, struct cache_entry, eb); |
3719 | 354 | entry->last_clear_ts = now.tv_sec; | 354 | entry->last_clear_ts = date.tv_sec; |
3720 | 355 | eb32_delete(node); | 355 | eb32_delete(node); |
3721 | 356 | node->key = 0; | 356 | node->key = 0; |
3722 | 357 | return NULL; | 357 | return NULL; |
3723 | @@ -811,8 +811,8 @@ int http_calc_maxage(struct stream *s, struct cache *cache, int *true_maxage) | |||
3724 | 811 | /* A request having an expiring date earlier | 811 | /* A request having an expiring date earlier |
3725 | 812 | * than the current date should be considered as | 812 | * than the current date should be considered as |
3726 | 813 | * stale. */ | 813 | * stale. */ |
3729 | 814 | expires = (expires_val >= now.tv_sec) ? | 814 | expires = (expires_val >= date.tv_sec) ? |
3730 | 815 | (expires_val - now.tv_sec) : 0; | 815 | (expires_val - date.tv_sec) : 0; |
3731 | 816 | } | 816 | } |
3732 | 817 | else { | 817 | else { |
3733 | 818 | /* Following RFC 7234#5.3, an invalid date | 818 | /* Following RFC 7234#5.3, an invalid date |
3734 | @@ -886,7 +886,7 @@ static time_t get_last_modified_time(struct htx *htx) | |||
3735 | 886 | /* Fallback on the current time if no "Last-Modified" or "Date" header | 886 | /* Fallback on the current time if no "Last-Modified" or "Date" header |
3736 | 887 | * was found. */ | 887 | * was found. */ |
3737 | 888 | if (!last_modified) | 888 | if (!last_modified) |
3739 | 889 | last_modified = now.tv_sec; | 889 | last_modified = date.tv_sec; |
3740 | 890 | 890 | ||
3741 | 891 | return last_modified; | 891 | return last_modified; |
3742 | 892 | } | 892 | } |
3743 | @@ -1120,7 +1120,7 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px, | |||
3744 | 1120 | * is set by the end of this function (in case of concurrent accesses to | 1120 | * is set by the end of this function (in case of concurrent accesses to |
3745 | 1121 | * the same resource). This way the second access will find an existing | 1121 | * the same resource). This way the second access will find an existing |
3746 | 1122 | * but not yet usable entry in the tree and will avoid storing its data. */ | 1122 | * but not yet usable entry in the tree and will avoid storing its data. */ |
3748 | 1123 | object->expire = now.tv_sec + 2; | 1123 | object->expire = date.tv_sec + 2; |
3749 | 1124 | 1124 | ||
3750 | 1125 | memcpy(object->hash, txn->cache_hash, sizeof(object->hash)); | 1125 | memcpy(object->hash, txn->cache_hash, sizeof(object->hash)); |
3751 | 1126 | if (vary_signature) | 1126 | if (vary_signature) |
3752 | @@ -1224,8 +1224,8 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px, | |||
3753 | 1224 | if (cache_ctx) { | 1224 | if (cache_ctx) { |
3754 | 1225 | cache_ctx->first_block = first; | 1225 | cache_ctx->first_block = first; |
3755 | 1226 | /* store latest value and expiration time */ | 1226 | /* store latest value and expiration time */ |
3758 | 1227 | object->latest_validation = now.tv_sec; | 1227 | object->latest_validation = date.tv_sec; |
3759 | 1228 | object->expire = now.tv_sec + effective_maxage; | 1228 | object->expire = date.tv_sec + effective_maxage; |
3760 | 1229 | return ACT_RET_CONT; | 1229 | return ACT_RET_CONT; |
3761 | 1230 | } | 1230 | } |
3762 | 1231 | 1231 | ||
3763 | @@ -1416,7 +1416,7 @@ static int htx_cache_add_age_hdr(struct appctx *appctx, struct htx *htx) | |||
3764 | 1416 | char *end; | 1416 | char *end; |
3765 | 1417 | 1417 | ||
3766 | 1418 | chunk_reset(&trash); | 1418 | chunk_reset(&trash); |
3768 | 1419 | age = MAX(0, (int)(now.tv_sec - cache_ptr->latest_validation)) + cache_ptr->age; | 1419 | age = MAX(0, (int)(date.tv_sec - cache_ptr->latest_validation)) + cache_ptr->age; |
3769 | 1420 | if (unlikely(age > CACHE_ENTRY_MAX_AGE)) | 1420 | if (unlikely(age > CACHE_ENTRY_MAX_AGE)) |
3770 | 1421 | age = CACHE_ENTRY_MAX_AGE; | 1421 | age = CACHE_ENTRY_MAX_AGE; |
3771 | 1422 | end = ultoa_o(age, b_head(&trash), b_size(&trash)); | 1422 | end = ultoa_o(age, b_head(&trash), b_size(&trash)); |
3772 | @@ -2602,13 +2602,13 @@ static int cli_io_handler_show_cache(struct appctx *appctx) | |||
3773 | 2602 | entry = container_of(node, struct cache_entry, eb); | 2602 | entry = container_of(node, struct cache_entry, eb); |
3774 | 2603 | next_key = node->key + 1; | 2603 | next_key = node->key + 1; |
3775 | 2604 | 2604 | ||
3777 | 2605 | if (entry->expire > now.tv_sec) { | 2605 | if (entry->expire > date.tv_sec) { |
3778 | 2606 | chunk_printf(&trash, "%p hash:%u vary:0x", entry, read_u32(entry->hash)); | 2606 | chunk_printf(&trash, "%p hash:%u vary:0x", entry, read_u32(entry->hash)); |
3779 | 2607 | for (i = 0; i < HTTP_CACHE_SEC_KEY_LEN; ++i) | 2607 | for (i = 0; i < HTTP_CACHE_SEC_KEY_LEN; ++i) |
3780 | 2608 | chunk_appendf(&trash, "%02x", (unsigned char)entry->secondary_key[i]); | 2608 | chunk_appendf(&trash, "%02x", (unsigned char)entry->secondary_key[i]); |
3781 | 2609 | chunk_appendf(&trash, " size:%u (%u blocks), refcount:%u, expire:%d\n", | 2609 | chunk_appendf(&trash, " size:%u (%u blocks), refcount:%u, expire:%d\n", |
3782 | 2610 | block_ptr(entry)->len, block_ptr(entry)->block_count, | 2610 | block_ptr(entry)->len, block_ptr(entry)->block_count, |
3784 | 2611 | block_ptr(entry)->refcount, entry->expire - (int)now.tv_sec); | 2611 | block_ptr(entry)->refcount, entry->expire - (int)date.tv_sec); |
3785 | 2612 | } else { | 2612 | } else { |
3786 | 2613 | /* time to remove that one */ | 2613 | /* time to remove that one */ |
3787 | 2614 | delete_entry(entry); | 2614 | delete_entry(entry); |
3788 | diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c | |||
3789 | index 4603376..35bd498 100644 | |||
3790 | --- a/src/cfgparse-listen.c | |||
3791 | +++ b/src/cfgparse-listen.c | |||
3792 | @@ -292,6 +292,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) | |||
3793 | 292 | curr_defproxy = last_defproxy; | 292 | curr_defproxy = last_defproxy; |
3794 | 293 | 293 | ||
3795 | 294 | if (strcmp(args[arg], "from") == 0) { | 294 | if (strcmp(args[arg], "from") == 0) { |
3796 | 295 | struct ebpt_node *next_by_name; | ||
3797 | 296 | |||
3798 | 295 | curr_defproxy = proxy_find_by_name(args[arg+1], PR_CAP_DEF, 0); | 297 | curr_defproxy = proxy_find_by_name(args[arg+1], PR_CAP_DEF, 0); |
3799 | 296 | 298 | ||
3800 | 297 | if (!curr_defproxy) { | 299 | if (!curr_defproxy) { |
3801 | @@ -300,8 +302,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) | |||
3802 | 300 | goto out; | 302 | goto out; |
3803 | 301 | } | 303 | } |
3804 | 302 | 304 | ||
3807 | 303 | if (ebpt_next_dup(&curr_defproxy->conf.by_name)) { | 305 | if ((next_by_name = ebpt_next_dup(&curr_defproxy->conf.by_name))) { |
3808 | 304 | struct proxy *px2 = container_of(ebpt_next_dup(&curr_defproxy->conf.by_name), struct proxy, conf.by_name); | 306 | struct proxy *px2 = container_of(next_by_name, struct proxy, conf.by_name); |
3809 | 305 | 307 | ||
3810 | 306 | ha_alert("parsing [%s:%d] : ambiguous defaults section name '%s' referenced by %s '%s' exists at least at %s:%d and %s:%d.\n", | 308 | ha_alert("parsing [%s:%d] : ambiguous defaults section name '%s' referenced by %s '%s' exists at least at %s:%d and %s:%d.\n", |
3811 | 307 | file, linenum, args[arg+1], proxy_cap_str(rc), name, | 309 | file, linenum, args[arg+1], proxy_cap_str(rc), name, |
3812 | diff --git a/src/cfgparse-ssl.c b/src/cfgparse-ssl.c | |||
3813 | index 654b020..fcd0416 100644 | |||
3814 | --- a/src/cfgparse-ssl.c | |||
3815 | +++ b/src/cfgparse-ssl.c | |||
3816 | @@ -758,7 +758,7 @@ static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, str | |||
3817 | 758 | { | 758 | { |
3818 | 759 | int code; | 759 | int code; |
3819 | 760 | char *p = args[cur_arg + 1]; | 760 | char *p = args[cur_arg + 1]; |
3821 | 761 | unsigned long long *ignerr = &conf->crt_ignerr; | 761 | unsigned long long *ignerr = conf->crt_ignerr_bitfield; |
3822 | 762 | 762 | ||
3823 | 763 | if (!*p) { | 763 | if (!*p) { |
3824 | 764 | memprintf(err, "'%s' : missing error IDs list", args[cur_arg]); | 764 | memprintf(err, "'%s' : missing error IDs list", args[cur_arg]); |
3825 | @@ -766,21 +766,21 @@ static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, str | |||
3826 | 766 | } | 766 | } |
3827 | 767 | 767 | ||
3828 | 768 | if (strcmp(args[cur_arg], "ca-ignore-err") == 0) | 768 | if (strcmp(args[cur_arg], "ca-ignore-err") == 0) |
3830 | 769 | ignerr = &conf->ca_ignerr; | 769 | ignerr = conf->ca_ignerr_bitfield; |
3831 | 770 | 770 | ||
3832 | 771 | if (strcmp(p, "all") == 0) { | 771 | if (strcmp(p, "all") == 0) { |
3834 | 772 | *ignerr = ~0ULL; | 772 | cert_ignerr_bitfield_set_all(ignerr); |
3835 | 773 | return 0; | 773 | return 0; |
3836 | 774 | } | 774 | } |
3837 | 775 | 775 | ||
3838 | 776 | while (p) { | 776 | while (p) { |
3839 | 777 | code = atoi(p); | 777 | code = atoi(p); |
3843 | 778 | if ((code <= 0) || (code > 63)) { | 778 | if ((code <= 0) || (code > SSL_MAX_VFY_ERROR_CODE)) { |
3844 | 779 | memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'", | 779 | memprintf(err, "'%s' : ID '%d' out of range (1..%d) in error IDs list '%s'", |
3845 | 780 | args[cur_arg], code, args[cur_arg + 1]); | 780 | args[cur_arg], code, SSL_MAX_VFY_ERROR_CODE, args[cur_arg + 1]); |
3846 | 781 | return ERR_ALERT | ERR_FATAL; | 781 | return ERR_ALERT | ERR_FATAL; |
3847 | 782 | } | 782 | } |
3849 | 783 | *ignerr |= 1ULL << code; | 783 | cert_ignerr_bitfield_set(ignerr, code); |
3850 | 784 | p = strchr(p, ','); | 784 | p = strchr(p, ','); |
3851 | 785 | if (p) | 785 | if (p) |
3852 | 786 | p++; | 786 | p++; |
3853 | diff --git a/src/cfgparse.c b/src/cfgparse.c | |||
3854 | index 4b42ec0..27bab1d 100644 | |||
3855 | --- a/src/cfgparse.c | |||
3856 | +++ b/src/cfgparse.c | |||
3857 | @@ -10,10 +10,10 @@ | |||
3858 | 10 | * | 10 | * |
3859 | 11 | */ | 11 | */ |
3860 | 12 | 12 | ||
3863 | 13 | #ifdef USE_LIBCRYPT | 13 | /* This is to have crypt() and sched_setaffinity() defined on Linux */ |
3862 | 14 | /* This is to have crypt() defined on Linux */ | ||
3864 | 15 | #define _GNU_SOURCE | 14 | #define _GNU_SOURCE |
3865 | 16 | 15 | ||
3866 | 16 | #ifdef USE_LIBCRYPT | ||
3867 | 17 | #ifdef USE_CRYPT_H | 17 | #ifdef USE_CRYPT_H |
3868 | 18 | /* some platforms such as Solaris need this */ | 18 | /* some platforms such as Solaris need this */ |
3869 | 19 | #include <crypt.h> | 19 | #include <crypt.h> |
3870 | @@ -29,6 +29,9 @@ | |||
3871 | 29 | #include <pwd.h> | 29 | #include <pwd.h> |
3872 | 30 | #include <grp.h> | 30 | #include <grp.h> |
3873 | 31 | #include <errno.h> | 31 | #include <errno.h> |
3874 | 32 | #ifdef USE_CPU_AFFINITY | ||
3875 | 33 | #include <sched.h> | ||
3876 | 34 | #endif | ||
3877 | 32 | #include <sys/types.h> | 35 | #include <sys/types.h> |
3878 | 33 | #include <sys/stat.h> | 36 | #include <sys/stat.h> |
3879 | 34 | #include <fcntl.h> | 37 | #include <fcntl.h> |
3880 | @@ -62,6 +65,7 @@ | |||
3881 | 62 | #include <haproxy/lb_map.h> | 65 | #include <haproxy/lb_map.h> |
3882 | 63 | #include <haproxy/listener.h> | 66 | #include <haproxy/listener.h> |
3883 | 64 | #include <haproxy/log.h> | 67 | #include <haproxy/log.h> |
3884 | 68 | #include <haproxy/sink.h> | ||
3885 | 65 | #include <haproxy/mailers.h> | 69 | #include <haproxy/mailers.h> |
3886 | 66 | #include <haproxy/namespace.h> | 70 | #include <haproxy/namespace.h> |
3887 | 67 | #include <haproxy/obj_type-t.h> | 71 | #include <haproxy/obj_type-t.h> |
3888 | @@ -2630,6 +2634,7 @@ int check_config_validity() | |||
3889 | 2630 | { | 2634 | { |
3890 | 2631 | int cfgerr = 0; | 2635 | int cfgerr = 0; |
3891 | 2632 | struct proxy *curproxy = NULL; | 2636 | struct proxy *curproxy = NULL; |
3892 | 2637 | struct proxy *init_proxies_list = NULL; | ||
3893 | 2633 | struct stktable *t; | 2638 | struct stktable *t; |
3894 | 2634 | struct server *newsrv = NULL; | 2639 | struct server *newsrv = NULL; |
3895 | 2635 | int err_code = 0; | 2640 | int err_code = 0; |
3896 | @@ -2707,7 +2712,11 @@ int check_config_validity() | |||
3897 | 2707 | proxies_list = next; | 2712 | proxies_list = next; |
3898 | 2708 | } | 2713 | } |
3899 | 2709 | 2714 | ||
3901 | 2710 | for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) { | 2715 | /* starting to initialize the main proxies list */ |
3902 | 2716 | init_proxies_list = proxies_list; | ||
3903 | 2717 | |||
3904 | 2718 | init_proxies_list_stage1: | ||
3905 | 2719 | for (curproxy = init_proxies_list; curproxy; curproxy = curproxy->next) { | ||
3906 | 2711 | struct switching_rule *rule; | 2720 | struct switching_rule *rule; |
3907 | 2712 | struct server_rule *srule; | 2721 | struct server_rule *srule; |
3908 | 2713 | struct sticking_rule *mrule; | 2722 | struct sticking_rule *mrule; |
3909 | @@ -2837,11 +2846,16 @@ int check_config_validity() | |||
3910 | 2837 | case PR_MODE_CLI: | 2846 | case PR_MODE_CLI: |
3911 | 2838 | cfgerr += proxy_cfg_ensure_no_http(curproxy); | 2847 | cfgerr += proxy_cfg_ensure_no_http(curproxy); |
3912 | 2839 | break; | 2848 | break; |
3913 | 2849 | |||
3914 | 2840 | case PR_MODE_SYSLOG: | 2850 | case PR_MODE_SYSLOG: |
3915 | 2851 | /* this mode is initialized as the classic tcp proxy */ | ||
3916 | 2852 | cfgerr += proxy_cfg_ensure_no_http(curproxy); | ||
3917 | 2853 | break; | ||
3918 | 2854 | |||
3919 | 2841 | case PR_MODE_PEERS: | 2855 | case PR_MODE_PEERS: |
3920 | 2842 | case PR_MODES: | 2856 | case PR_MODES: |
3921 | 2843 | /* should not happen, bug gcc warn missing switch statement */ | 2857 | /* should not happen, bug gcc warn missing switch statement */ |
3923 | 2844 | ha_alert("config : %s '%s' cannot use peers or syslog mode for this proxy. NOTE: PLEASE REPORT THIS TO DEVELOPERS AS YOU'RE NOT SUPPOSED TO BE ABLE TO CREATE A CONFIGURATION TRIGGERING THIS!\n", | 2858 | ha_alert("config: %s '%s' cannot initialize this proxy mode (peers) in this way. NOTE: PLEASE REPORT THIS TO DEVELOPERS AS YOU'RE NOT SUPPOSED TO BE ABLE TO CREATE A CONFIGURATION TRIGGERING THIS!\n", |
3924 | 2845 | proxy_type_str(curproxy), curproxy->id); | 2859 | proxy_type_str(curproxy), curproxy->id); |
3925 | 2846 | cfgerr++; | 2860 | cfgerr++; |
3926 | 2847 | break; | 2861 | break; |
3927 | @@ -3966,6 +3980,24 @@ out_uri_auth_compat: | |||
3928 | 3966 | } | 3980 | } |
3929 | 3967 | } | 3981 | } |
3930 | 3968 | 3982 | ||
3931 | 3983 | /* | ||
3932 | 3984 | * We have just initialized the main proxies list | ||
3933 | 3985 | * we must also configure the log-forward proxies list | ||
3934 | 3986 | */ | ||
3935 | 3987 | if (init_proxies_list == proxies_list) { | ||
3936 | 3988 | init_proxies_list = cfg_log_forward; | ||
3937 | 3989 | /* check if list is not null to avoid infinite loop */ | ||
3938 | 3990 | if (init_proxies_list) | ||
3939 | 3991 | goto init_proxies_list_stage1; | ||
3940 | 3992 | } | ||
3941 | 3993 | |||
3942 | 3994 | if (init_proxies_list == cfg_log_forward) { | ||
3943 | 3995 | init_proxies_list = sink_proxies_list; | ||
3944 | 3996 | /* check if list is not null to avoid infinite loop */ | ||
3945 | 3997 | if (init_proxies_list) | ||
3946 | 3998 | goto init_proxies_list_stage1; | ||
3947 | 3999 | } | ||
3948 | 4000 | |||
3949 | 3969 | /***********************************************************/ | 4001 | /***********************************************************/ |
3950 | 3970 | /* At this point, target names have already been resolved. */ | 4002 | /* At this point, target names have already been resolved. */ |
3951 | 3971 | /***********************************************************/ | 4003 | /***********************************************************/ |
3952 | @@ -4087,7 +4119,11 @@ out_uri_auth_compat: | |||
3953 | 4087 | 4119 | ||
3954 | 4088 | /* perform the final checks before creating tasks */ | 4120 | /* perform the final checks before creating tasks */ |
3955 | 4089 | 4121 | ||
3957 | 4090 | for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) { | 4122 | /* starting to initialize the main proxies list */ |
3958 | 4123 | init_proxies_list = proxies_list; | ||
3959 | 4124 | |||
3960 | 4125 | init_proxies_list_stage2: | ||
3961 | 4126 | for (curproxy = init_proxies_list; curproxy; curproxy = curproxy->next) { | ||
3962 | 4091 | struct listener *listener; | 4127 | struct listener *listener; |
3963 | 4092 | unsigned int next_id; | 4128 | unsigned int next_id; |
3964 | 4093 | 4129 | ||
3965 | @@ -4209,6 +4245,17 @@ out_uri_auth_compat: | |||
3966 | 4209 | } | 4245 | } |
3967 | 4210 | 4246 | ||
3968 | 4211 | /* | 4247 | /* |
3969 | 4248 | * We have just initialized the main proxies list | ||
3970 | 4249 | * we must also configure the log-forward proxies list | ||
3971 | 4250 | */ | ||
3972 | 4251 | if (init_proxies_list == proxies_list) { | ||
3973 | 4252 | init_proxies_list = cfg_log_forward; | ||
3974 | 4253 | /* check if list is not null to avoid infinite loop */ | ||
3975 | 4254 | if (init_proxies_list) | ||
3976 | 4255 | goto init_proxies_list_stage2; | ||
3977 | 4256 | } | ||
3978 | 4257 | |||
3979 | 4258 | /* | ||
3980 | 4212 | * Recount currently required checks. | 4259 | * Recount currently required checks. |
3981 | 4213 | */ | 4260 | */ |
3982 | 4214 | 4261 | ||
3983 | diff --git a/src/check.c b/src/check.c | |||
3984 | index 1a40b6f..2205063 100644 | |||
3985 | --- a/src/check.c | |||
3986 | +++ b/src/check.c | |||
3987 | @@ -1715,6 +1715,13 @@ static int init_srv_agent_check(struct server *srv) | |||
3988 | 1715 | LIST_INSERT(srv->agent.tcpcheck_rules->list, &chk->list); | 1715 | LIST_INSERT(srv->agent.tcpcheck_rules->list, &chk->list); |
3989 | 1716 | } | 1716 | } |
3990 | 1717 | 1717 | ||
3991 | 1718 | /* <chk> is always defined here and it is a CONNECT action. If there is | ||
3992 | 1719 | * a preset variable, it means there is an agent string defined and data | ||
3993 | 1720 | * will be sent after the connect. | ||
3994 | 1721 | */ | ||
3995 | 1722 | if (!LIST_ISEMPTY(&srv->agent.tcpcheck_rules->preset_vars)) | ||
3996 | 1723 | chk->connect.options |= TCPCHK_OPT_HAS_DATA; | ||
3997 | 1724 | |||
3998 | 1718 | 1725 | ||
3999 | 1719 | err = init_check(&srv->agent, PR_O2_TCPCHK_CHK); | 1726 | err = init_check(&srv->agent, PR_O2_TCPCHK_CHK); |
4000 | 1720 | if (err) { | 1727 | if (err) { |
4001 | diff --git a/src/dns.c b/src/dns.c | |||
4002 | index 1ef5e87..c4b2af0 100644 | |||
4003 | --- a/src/dns.c | |||
4004 | +++ b/src/dns.c | |||
4005 | @@ -1023,7 +1023,7 @@ struct dns_session *dns_session_new(struct dns_stream_server *dss) | |||
4006 | 1023 | if (dss->maxconn && (dss->maxconn <= dss->cur_conns)) | 1023 | if (dss->maxconn && (dss->maxconn <= dss->cur_conns)) |
4007 | 1024 | return NULL; | 1024 | return NULL; |
4008 | 1025 | 1025 | ||
4010 | 1026 | ds = pool_alloc(dns_session_pool); | 1026 | ds = pool_zalloc(dns_session_pool); |
4011 | 1027 | if (!ds) | 1027 | if (!ds) |
4012 | 1028 | return NULL; | 1028 | return NULL; |
4013 | 1029 | 1029 | ||
4014 | diff --git a/src/ev_epoll.c b/src/ev_epoll.c | |||
4015 | index 330c38c..041d6d8 100644 | |||
4016 | --- a/src/ev_epoll.c | |||
4017 | +++ b/src/ev_epoll.c | |||
4018 | @@ -185,7 +185,7 @@ static void _do_poll(struct poller *p, int exp, int wake) | |||
4019 | 185 | 185 | ||
4020 | 186 | thread_harmless_now(); | 186 | thread_harmless_now(); |
4021 | 187 | 187 | ||
4023 | 188 | /* now let's wait for polled events */ | 188 | /* Now let's wait for polled events. */ |
4024 | 189 | wait_time = wake ? 0 : compute_poll_timeout(exp); | 189 | wait_time = wake ? 0 : compute_poll_timeout(exp); |
4025 | 190 | tv_entering_poll(); | 190 | tv_entering_poll(); |
4026 | 191 | activity_count_runtime(); | 191 | activity_count_runtime(); |
4027 | @@ -201,7 +201,7 @@ static void _do_poll(struct poller *p, int exp, int wake) | |||
4028 | 201 | } | 201 | } |
4029 | 202 | if (timeout || !wait_time) | 202 | if (timeout || !wait_time) |
4030 | 203 | break; | 203 | break; |
4032 | 204 | if (signal_queue_len || wake) | 204 | if (wake) |
4033 | 205 | break; | 205 | break; |
4034 | 206 | if (tick_isset(exp) && tick_is_expired(exp, now_ms)) | 206 | if (tick_isset(exp) && tick_is_expired(exp, now_ms)) |
4035 | 207 | break; | 207 | break; |
4036 | diff --git a/src/ev_evports.c b/src/ev_evports.c | |||
4037 | index 109e59c..e012e00 100644 | |||
4038 | --- a/src/ev_evports.c | |||
4039 | +++ b/src/ev_evports.c | |||
4040 | @@ -153,9 +153,7 @@ static void _do_poll(struct poller *p, int exp, int wake) | |||
4041 | 153 | 153 | ||
4042 | 154 | thread_harmless_now(); | 154 | thread_harmless_now(); |
4043 | 155 | 155 | ||
4047 | 156 | /* | 156 | /* Now let's wait for polled events. */ |
4045 | 157 | * Determine how long to wait for events to materialise on the port. | ||
4046 | 158 | */ | ||
4048 | 159 | wait_time = wake ? 0 : compute_poll_timeout(exp); | 157 | wait_time = wake ? 0 : compute_poll_timeout(exp); |
4049 | 160 | tv_entering_poll(); | 158 | tv_entering_poll(); |
4050 | 161 | activity_count_runtime(); | 159 | activity_count_runtime(); |
4051 | @@ -195,7 +193,7 @@ static void _do_poll(struct poller *p, int exp, int wake) | |||
4052 | 195 | break; | 193 | break; |
4053 | 196 | if (timeout || !wait_time) | 194 | if (timeout || !wait_time) |
4054 | 197 | break; | 195 | break; |
4056 | 198 | if (signal_queue_len || wake) | 196 | if (wake) |
4057 | 199 | break; | 197 | break; |
4058 | 200 | if (tick_isset(exp) && tick_is_expired(exp, now_ms)) | 198 | if (tick_isset(exp) && tick_is_expired(exp, now_ms)) |
4059 | 201 | break; | 199 | break; |
4060 | diff --git a/src/ev_kqueue.c b/src/ev_kqueue.c | |||
4061 | index d51a833..0d81d67 100644 | |||
4062 | --- a/src/ev_kqueue.c | |||
4063 | +++ b/src/ev_kqueue.c | |||
4064 | @@ -141,7 +141,7 @@ static void _do_poll(struct poller *p, int exp, int wake) | |||
4065 | 141 | } | 141 | } |
4066 | 142 | fd_nbupdt = 0; | 142 | fd_nbupdt = 0; |
4067 | 143 | 143 | ||
4069 | 144 | /* now let's wait for events */ | 144 | /* Now let's wait for polled events. */ |
4070 | 145 | wait_time = wake ? 0 : compute_poll_timeout(exp); | 145 | wait_time = wake ? 0 : compute_poll_timeout(exp); |
4071 | 146 | fd = global.tune.maxpollevents; | 146 | fd = global.tune.maxpollevents; |
4072 | 147 | tv_entering_poll(); | 147 | tv_entering_poll(); |
4073 | @@ -167,7 +167,7 @@ static void _do_poll(struct poller *p, int exp, int wake) | |||
4074 | 167 | } | 167 | } |
4075 | 168 | if (timeout || !wait_time) | 168 | if (timeout || !wait_time) |
4076 | 169 | break; | 169 | break; |
4078 | 170 | if (signal_queue_len || wake) | 170 | if (wake) |
4079 | 171 | break; | 171 | break; |
4080 | 172 | if (tick_isset(exp) && tick_is_expired(exp, now_ms)) | 172 | if (tick_isset(exp) && tick_is_expired(exp, now_ms)) |
4081 | 173 | break; | 173 | break; |
4082 | diff --git a/src/ev_poll.c b/src/ev_poll.c | |||
4083 | index c30aadb..4d136a0 100644 | |||
4084 | --- a/src/ev_poll.c | |||
4085 | +++ b/src/ev_poll.c | |||
4086 | @@ -21,6 +21,7 @@ | |||
4087 | 21 | #include <haproxy/api.h> | 21 | #include <haproxy/api.h> |
4088 | 22 | #include <haproxy/fd.h> | 22 | #include <haproxy/fd.h> |
4089 | 23 | #include <haproxy/global.h> | 23 | #include <haproxy/global.h> |
4090 | 24 | #include <haproxy/signal.h> | ||
4091 | 24 | #include <haproxy/ticks.h> | 25 | #include <haproxy/ticks.h> |
4092 | 25 | #include <haproxy/time.h> | 26 | #include <haproxy/time.h> |
4093 | 26 | 27 | ||
4094 | @@ -198,7 +199,7 @@ static void _do_poll(struct poller *p, int exp, int wake) | |||
4095 | 198 | } | 199 | } |
4096 | 199 | } | 200 | } |
4097 | 200 | 201 | ||
4099 | 201 | /* now let's wait for events */ | 202 | /* Now let's wait for polled events. */ |
4100 | 202 | wait_time = wake ? 0 : compute_poll_timeout(exp); | 203 | wait_time = wake ? 0 : compute_poll_timeout(exp); |
4101 | 203 | tv_entering_poll(); | 204 | tv_entering_poll(); |
4102 | 204 | activity_count_runtime(); | 205 | activity_count_runtime(); |
4103 | diff --git a/src/fcgi-app.c b/src/fcgi-app.c | |||
4104 | index 29a3602..8fca1e9 100644 | |||
4105 | --- a/src/fcgi-app.c | |||
4106 | +++ b/src/fcgi-app.c | |||
4107 | @@ -589,7 +589,7 @@ static int proxy_parse_use_fcgi_app(char **args, int section, struct proxy *curp | |||
4108 | 589 | struct fcgi_flt_conf *fcgi_conf = NULL; | 589 | struct fcgi_flt_conf *fcgi_conf = NULL; |
4109 | 590 | int retval = 0; | 590 | int retval = 0; |
4110 | 591 | 591 | ||
4112 | 592 | if (!(curpx->cap & PR_CAP_BE)) { | 592 | if ((curpx->cap & PR_CAP_DEF) || !(curpx->cap & PR_CAP_BE)) { |
4113 | 593 | memprintf(err, "'%s' only available in backend or listen section", args[0]); | 593 | memprintf(err, "'%s' only available in backend or listen section", args[0]); |
4114 | 594 | retval = -1; | 594 | retval = -1; |
4115 | 595 | goto end; | 595 | goto end; |
4116 | diff --git a/src/fcgi.c b/src/fcgi.c | |||
4117 | index 1c2543d..778ce9e 100644 | |||
4118 | --- a/src/fcgi.c | |||
4119 | +++ b/src/fcgi.c | |||
4120 | @@ -47,7 +47,7 @@ int fcgi_encode_record_hdr(struct buffer *out, const struct fcgi_header *h) | |||
4121 | 47 | out->area[len++] = ((h->len >> 8) & 0xff); | 47 | out->area[len++] = ((h->len >> 8) & 0xff); |
4122 | 48 | out->area[len++] = (h->len & 0xff); | 48 | out->area[len++] = (h->len & 0xff); |
4123 | 49 | out->area[len++] = h->padding; | 49 | out->area[len++] = h->padding; |
4125 | 50 | len++; /* rsv */ | 50 | out->area[len++] = 0; /* rsv */ |
4126 | 51 | 51 | ||
4127 | 52 | out->data = len; | 52 | out->data = len; |
4128 | 53 | return 1; | 53 | return 1; |
4129 | @@ -94,7 +94,11 @@ int fcgi_encode_begin_request(struct buffer *out, const struct fcgi_begin_reques | |||
4130 | 94 | out->area[len++] = ((r->role >> 8) & 0xff); | 94 | out->area[len++] = ((r->role >> 8) & 0xff); |
4131 | 95 | out->area[len++] = (r->role & 0xff); | 95 | out->area[len++] = (r->role & 0xff); |
4132 | 96 | out->area[len++] = r->flags; | 96 | out->area[len++] = r->flags; |
4134 | 97 | len += 5; /* rsv */ | 97 | out->area[len++] = 0; /* rsv */ |
4135 | 98 | out->area[len++] = 0; | ||
4136 | 99 | out->area[len++] = 0; | ||
4137 | 100 | out->area[len++] = 0; | ||
4138 | 101 | out->area[len++] = 0; | ||
4139 | 98 | 102 | ||
4140 | 99 | out->data = len; | 103 | out->data = len; |
4141 | 100 | return 1; | 104 | return 1; |
4142 | diff --git a/src/fd.c b/src/fd.c | |||
4143 | index b9c8ccc..3c9629f 100644 | |||
4144 | --- a/src/fd.c | |||
4145 | +++ b/src/fd.c | |||
4146 | @@ -206,7 +206,7 @@ lock_self: | |||
4147 | 206 | #ifdef HA_CAS_IS_8B | 206 | #ifdef HA_CAS_IS_8B |
4148 | 207 | unlikely(!_HA_ATOMIC_CAS(((uint64_t *)&_GET_NEXT(fd, off)), (uint64_t *)&cur_list.u64, next_list.u64)) | 207 | unlikely(!_HA_ATOMIC_CAS(((uint64_t *)&_GET_NEXT(fd, off)), (uint64_t *)&cur_list.u64, next_list.u64)) |
4149 | 208 | #else | 208 | #else |
4151 | 209 | unlikely(!_HA_ATOMIC_DWCAS(((long *)&_GET_NEXT(fd, off)), (uint32_t *)&cur_list.u32, &next_list.u32)) | 209 | unlikely(!_HA_ATOMIC_DWCAS(((long *)&_GET_NEXT(fd, off)), (uint32_t *)&cur_list.u32, (const uint32_t *)&next_list.u32)) |
4152 | 210 | #endif | 210 | #endif |
4153 | 211 | ); | 211 | ); |
4154 | 212 | next = cur_list.ent.next; | 212 | next = cur_list.ent.next; |
4155 | @@ -666,9 +666,9 @@ static void deinit_pollers_per_thread() | |||
4156 | 666 | /* rd and wr are init at the same place, but only rd is init to -1, so | 666 | /* rd and wr are init at the same place, but only rd is init to -1, so |
4157 | 667 | we rely to rd to close. */ | 667 | we rely to rd to close. */ |
4158 | 668 | if (poller_rd_pipe > -1) { | 668 | if (poller_rd_pipe > -1) { |
4160 | 669 | close(poller_rd_pipe); | 669 | fd_delete(poller_rd_pipe); |
4161 | 670 | poller_rd_pipe = -1; | 670 | poller_rd_pipe = -1; |
4163 | 671 | close(poller_wr_pipe[tid]); | 671 | fd_delete(poller_wr_pipe[tid]); |
4164 | 672 | poller_wr_pipe[tid] = -1; | 672 | poller_wr_pipe[tid] = -1; |
4165 | 673 | } | 673 | } |
4166 | 674 | } | 674 | } |
4167 | diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c | |||
4168 | index a9c49f5..66eb601 100644 | |||
4169 | --- a/src/flt_http_comp.c | |||
4170 | +++ b/src/flt_http_comp.c | |||
4171 | @@ -304,23 +304,18 @@ set_compression_response_header(struct comp_state *st, struct stream *s, struct | |||
4172 | 304 | struct htx_sl *sl; | 304 | struct htx_sl *sl; |
4173 | 305 | struct http_hdr_ctx ctx; | 305 | struct http_hdr_ctx ctx; |
4174 | 306 | 306 | ||
4175 | 307 | /* | ||
4176 | 308 | * Add Content-Encoding header when it's not identity encoding. | ||
4177 | 309 | * RFC 2616 : Identity encoding: This content-coding is used only in the | ||
4178 | 310 | * Accept-Encoding header, and SHOULD NOT be used in the Content-Encoding | ||
4179 | 311 | * header. | ||
4180 | 312 | */ | ||
4181 | 313 | if (st->comp_algo->cfg_name_len != 8 || memcmp(st->comp_algo->cfg_name, "identity", 8) != 0) { | ||
4182 | 314 | struct ist v = ist2(st->comp_algo->ua_name, st->comp_algo->ua_name_len); | ||
4183 | 315 | |||
4184 | 316 | if (!http_add_header(htx, ist("Content-Encoding"), v)) | ||
4185 | 317 | goto error; | ||
4186 | 318 | } | ||
4187 | 319 | |||
4188 | 320 | sl = http_get_stline(htx); | 307 | sl = http_get_stline(htx); |
4189 | 321 | if (!sl) | 308 | if (!sl) |
4190 | 322 | goto error; | 309 | goto error; |
4191 | 323 | 310 | ||
4192 | 311 | /* add "Transfer-Encoding: chunked" header */ | ||
4193 | 312 | if (!(msg->flags & HTTP_MSGF_TE_CHNK)) { | ||
4194 | 313 | if (!http_add_header(htx, ist("Transfer-Encoding"), ist("chunked"))) | ||
4195 | 314 | goto error; | ||
4196 | 315 | msg->flags |= HTTP_MSGF_TE_CHNK; | ||
4197 | 316 | sl->flags |= (HTX_SL_F_XFER_ENC|HTX_SL_F_CHNK); | ||
4198 | 317 | } | ||
4199 | 318 | |||
4200 | 324 | /* remove Content-Length header */ | 319 | /* remove Content-Length header */ |
4201 | 325 | if (msg->flags & HTTP_MSGF_CNT_LEN) { | 320 | if (msg->flags & HTTP_MSGF_CNT_LEN) { |
4202 | 326 | ctx.blk = NULL; | 321 | ctx.blk = NULL; |
4203 | @@ -330,14 +325,6 @@ set_compression_response_header(struct comp_state *st, struct stream *s, struct | |||
4204 | 330 | sl->flags &= ~HTX_SL_F_CLEN; | 325 | sl->flags &= ~HTX_SL_F_CLEN; |
4205 | 331 | } | 326 | } |
4206 | 332 | 327 | ||
4207 | 333 | /* add "Transfer-Encoding: chunked" header */ | ||
4208 | 334 | if (!(msg->flags & HTTP_MSGF_TE_CHNK)) { | ||
4209 | 335 | if (!http_add_header(htx, ist("Transfer-Encoding"), ist("chunked"))) | ||
4210 | 336 | goto error; | ||
4211 | 337 | msg->flags |= HTTP_MSGF_TE_CHNK; | ||
4212 | 338 | sl->flags |= (HTX_SL_F_XFER_ENC|HTX_SL_F_CHNK); | ||
4213 | 339 | } | ||
4214 | 340 | |||
4215 | 341 | /* convert "ETag" header to a weak ETag */ | 328 | /* convert "ETag" header to a weak ETag */ |
4216 | 342 | ctx.blk = NULL; | 329 | ctx.blk = NULL; |
4217 | 343 | if (http_find_header(htx, ist("ETag"), &ctx, 1)) { | 330 | if (http_find_header(htx, ist("ETag"), &ctx, 1)) { |
4218 | @@ -355,6 +342,19 @@ set_compression_response_header(struct comp_state *st, struct stream *s, struct | |||
4219 | 355 | if (!http_add_header(htx, ist("Vary"), ist("Accept-Encoding"))) | 342 | if (!http_add_header(htx, ist("Vary"), ist("Accept-Encoding"))) |
4220 | 356 | goto error; | 343 | goto error; |
4221 | 357 | 344 | ||
4222 | 345 | /* | ||
4223 | 346 | * Add Content-Encoding header when it's not identity encoding. | ||
4224 | 347 | * RFC 2616 : Identity encoding: This content-coding is used only in the | ||
4225 | 348 | * Accept-Encoding header, and SHOULD NOT be used in the Content-Encoding | ||
4226 | 349 | * header. | ||
4227 | 350 | */ | ||
4228 | 351 | if (st->comp_algo->cfg_name_len != 8 || memcmp(st->comp_algo->cfg_name, "identity", 8) != 0) { | ||
4229 | 352 | struct ist v = ist2(st->comp_algo->ua_name, st->comp_algo->ua_name_len); | ||
4230 | 353 | |||
4231 | 354 | if (!http_add_header(htx, ist("Content-Encoding"), v)) | ||
4232 | 355 | goto error; | ||
4233 | 356 | } | ||
4234 | 357 | |||
4235 | 358 | return 1; | 358 | return 1; |
4236 | 359 | 359 | ||
4237 | 360 | error: | 360 | error: |
4238 | diff --git a/src/flt_spoe.c b/src/flt_spoe.c | |||
4239 | index cb7eed4..4826aa0 100644 | |||
4240 | --- a/src/flt_spoe.c | |||
4241 | +++ b/src/flt_spoe.c | |||
4242 | @@ -1259,7 +1259,7 @@ spoe_release_appctx(struct appctx *appctx) | |||
4243 | 1259 | /* Destroy the task attached to this applet */ | 1259 | /* Destroy the task attached to this applet */ |
4244 | 1260 | task_destroy(spoe_appctx->task); | 1260 | task_destroy(spoe_appctx->task); |
4245 | 1261 | 1261 | ||
4247 | 1262 | /* Notify all waiting streams */ | 1262 | /* Report an error to all streams in the appctx waiting queue */ |
4248 | 1263 | list_for_each_entry_safe(ctx, back, &spoe_appctx->waiting_queue, list) { | 1263 | list_for_each_entry_safe(ctx, back, &spoe_appctx->waiting_queue, list) { |
4249 | 1264 | LIST_DELETE(&ctx->list); | 1264 | LIST_DELETE(&ctx->list); |
4250 | 1265 | LIST_INIT(&ctx->list); | 1265 | LIST_INIT(&ctx->list); |
4251 | @@ -1271,8 +1271,8 @@ spoe_release_appctx(struct appctx *appctx) | |||
4252 | 1271 | task_wakeup(ctx->strm->task, TASK_WOKEN_MSG); | 1271 | task_wakeup(ctx->strm->task, TASK_WOKEN_MSG); |
4253 | 1272 | } | 1272 | } |
4254 | 1273 | 1273 | ||
4257 | 1274 | /* If the applet was processing a fragmented frame, notify the | 1274 | /* If the applet was processing a fragmented frame, report an error to |
4258 | 1275 | * corresponding stream. */ | 1275 | * the corresponding stream. */ |
4259 | 1276 | if (spoe_appctx->frag_ctx.ctx) { | 1276 | if (spoe_appctx->frag_ctx.ctx) { |
4260 | 1277 | ctx = spoe_appctx->frag_ctx.ctx; | 1277 | ctx = spoe_appctx->frag_ctx.ctx; |
4261 | 1278 | ctx->spoe_appctx = NULL; | 1278 | ctx->spoe_appctx = NULL; |
4262 | @@ -1281,7 +1281,11 @@ spoe_release_appctx(struct appctx *appctx) | |||
4263 | 1281 | task_wakeup(ctx->strm->task, TASK_WOKEN_MSG); | 1281 | task_wakeup(ctx->strm->task, TASK_WOKEN_MSG); |
4264 | 1282 | } | 1282 | } |
4265 | 1283 | 1283 | ||
4267 | 1284 | if (!LIST_ISEMPTY(&agent->rt[tid].waiting_queue)) { | 1284 | if (!LIST_ISEMPTY(&agent->rt[tid].applets)) { |
4268 | 1285 | /* If there are still some running applets, remove reference on | ||
4269 | 1286 | * the current one from streams in the async waiting queue. In | ||
4270 | 1287 | * async mode, the ACK may be received from another appctx. | ||
4271 | 1288 | */ | ||
4272 | 1285 | list_for_each_entry_safe(ctx, back, &agent->rt[tid].waiting_queue, list) { | 1289 | list_for_each_entry_safe(ctx, back, &agent->rt[tid].waiting_queue, list) { |
4273 | 1286 | if (ctx->spoe_appctx == spoe_appctx) | 1290 | if (ctx->spoe_appctx == spoe_appctx) |
4274 | 1287 | ctx->spoe_appctx = NULL; | 1291 | ctx->spoe_appctx = NULL; |
4275 | @@ -1289,16 +1293,25 @@ spoe_release_appctx(struct appctx *appctx) | |||
4276 | 1289 | goto end; | 1293 | goto end; |
4277 | 1290 | } | 1294 | } |
4278 | 1291 | else { | 1295 | else { |
4282 | 1292 | /* It is the last running applet and the sending and waiting | 1296 | /* It is the last running applet and the sending and async |
4283 | 1293 | * queues are not empty. Try to start a new one if HAproxy is | 1297 | * waiting queues are not empty. So try to start a new applet if |
4284 | 1294 | * not stopping. | 1298 | * HAproxy is not stopping. On success, we remove reference on |
4285 | 1299 | * the current appctx from streams in the async waiting queue. | ||
4286 | 1300 | * In async mode, the ACK may be received from another appctx. | ||
4287 | 1295 | */ | 1301 | */ |
4288 | 1296 | if (!stopping && | 1302 | if (!stopping && |
4289 | 1297 | (!LIST_ISEMPTY(&agent->rt[tid].sending_queue) || !LIST_ISEMPTY(&agent->rt[tid].waiting_queue)) && | 1303 | (!LIST_ISEMPTY(&agent->rt[tid].sending_queue) || !LIST_ISEMPTY(&agent->rt[tid].waiting_queue)) && |
4291 | 1298 | spoe_create_appctx(agent->spoe_conf)) | 1304 | spoe_create_appctx(agent->spoe_conf)) { |
4292 | 1305 | list_for_each_entry_safe(ctx, back, &agent->rt[tid].waiting_queue, list) { | ||
4293 | 1306 | if (ctx->spoe_appctx == spoe_appctx) | ||
4294 | 1307 | ctx->spoe_appctx = NULL; | ||
4295 | 1308 | } | ||
4296 | 1299 | goto end; | 1309 | goto end; |
4297 | 1310 | } | ||
4298 | 1300 | 1311 | ||
4300 | 1301 | /* otherwise, notify all waiting streams */ | 1312 | /* Otherwise, report an error to all streams in the sending and |
4301 | 1313 | * async waiting queues. | ||
4302 | 1314 | */ | ||
4303 | 1302 | list_for_each_entry_safe(ctx, back, &agent->rt[tid].sending_queue, list) { | 1315 | list_for_each_entry_safe(ctx, back, &agent->rt[tid].sending_queue, list) { |
4304 | 1303 | LIST_DELETE(&ctx->list); | 1316 | LIST_DELETE(&ctx->list); |
4305 | 1304 | LIST_INIT(&ctx->list); | 1317 | LIST_INIT(&ctx->list); |
4306 | diff --git a/src/h1.c b/src/h1.c | |||
4307 | index 3a6c1c3..73de48b 100644 | |||
4308 | --- a/src/h1.c | |||
4309 | +++ b/src/h1.c | |||
4310 | @@ -130,6 +130,50 @@ void h1_parse_xfer_enc_header(struct h1m *h1m, struct ist value) | |||
4311 | 130 | } | 130 | } |
4312 | 131 | } | 131 | } |
4313 | 132 | 132 | ||
4314 | 133 | /* Validate the authority and the host header value for CONNECT method. If there | ||
4315 | 134 | * is hast header, its value is normalized. 0 is returned on success, -1 if the | ||
4316 | 135 | * authority is invalid and -2 if the host is invalid. | ||
4317 | 136 | */ | ||
4318 | 137 | static int h1_validate_connect_authority(struct ist authority, struct ist *host_hdr) | ||
4319 | 138 | { | ||
4320 | 139 | struct ist uri_host, uri_port, host, host_port; | ||
4321 | 140 | |||
4322 | 141 | if (!isttest(authority)) | ||
4323 | 142 | goto invalid_authority; | ||
4324 | 143 | uri_host = authority; | ||
4325 | 144 | uri_port = http_get_host_port(authority); | ||
4326 | 145 | if (!isttest(uri_port)) | ||
4327 | 146 | goto invalid_authority; | ||
4328 | 147 | uri_host.len -= (istlen(uri_port) + 1); | ||
4329 | 148 | |||
4330 | 149 | if (!host_hdr || !isttest(*host_hdr)) | ||
4331 | 150 | goto end; | ||
4332 | 151 | |||
4333 | 152 | /* Get the port of the host header value, if any */ | ||
4334 | 153 | host = *host_hdr; | ||
4335 | 154 | host_port = http_get_host_port(*host_hdr); | ||
4336 | 155 | if (isttest(host_port)) { | ||
4337 | 156 | host.len -= (istlen(host_port) + 1); | ||
4338 | 157 | if (!isteqi(host, uri_host) || !isteq(host_port, uri_port)) | ||
4339 | 158 | goto invalid_host; | ||
4340 | 159 | if (http_is_default_port(IST_NULL, uri_port)) | ||
4341 | 160 | *host_hdr = host; /* normalize */ | ||
4342 | 161 | } | ||
4343 | 162 | else { | ||
4344 | 163 | if (!http_is_default_port(IST_NULL, uri_port) || !isteqi(host, uri_host)) | ||
4345 | 164 | goto invalid_host; | ||
4346 | 165 | } | ||
4347 | 166 | |||
4348 | 167 | end: | ||
4349 | 168 | return 0; | ||
4350 | 169 | |||
4351 | 170 | invalid_authority: | ||
4352 | 171 | return -1; | ||
4353 | 172 | |||
4354 | 173 | invalid_host: | ||
4355 | 174 | return -2; | ||
4356 | 175 | } | ||
4357 | 176 | |||
4358 | 133 | /* Parse the Connection: header of an HTTP/1 request, looking for "close", | 177 | /* Parse the Connection: header of an HTTP/1 request, looking for "close", |
4359 | 134 | * "keep-alive", and "upgrade" values, and updating h1m->flags according to | 178 | * "keep-alive", and "upgrade" values, and updating h1m->flags according to |
4360 | 135 | * what was found there. Note that flags are only added, not removed, so the | 179 | * what was found there. Note that flags are only added, not removed, so the |
4361 | @@ -706,6 +750,10 @@ int h1_headers_to_hdr_list(char *start, const char *stop, | |||
4362 | 706 | 750 | ||
4363 | 707 | if (likely(*ptr == ':')) { | 751 | if (likely(*ptr == ':')) { |
4364 | 708 | col = ptr - start; | 752 | col = ptr - start; |
4365 | 753 | if (col <= sol) { | ||
4366 | 754 | state = H1_MSG_HDR_NAME; | ||
4367 | 755 | goto http_msg_invalid; | ||
4368 | 756 | } | ||
4369 | 709 | EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_hdr_l1_sp, http_msg_ood, state, H1_MSG_HDR_L1_SP); | 757 | EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_hdr_l1_sp, http_msg_ood, state, H1_MSG_HDR_L1_SP); |
4370 | 710 | } | 758 | } |
4371 | 711 | 759 | ||
4372 | @@ -868,22 +916,9 @@ int h1_headers_to_hdr_list(char *start, const char *stop, | |||
4373 | 868 | else if (isteqi(n, ist("upgrade"))) { | 916 | else if (isteqi(n, ist("upgrade"))) { |
4374 | 869 | h1_parse_upgrade_header(h1m, v); | 917 | h1_parse_upgrade_header(h1m, v); |
4375 | 870 | } | 918 | } |
4390 | 871 | else if (!(h1m->flags & (H1_MF_HDRS_ONLY|H1_MF_RESP)) && isteqi(n, ist("host"))) { | 919 | else if (!(h1m->flags & H1_MF_RESP) && isteqi(n, ist("host"))) { |
4391 | 872 | if (host_idx == -1) { | 920 | if (host_idx == -1) |
4378 | 873 | struct ist authority; | ||
4379 | 874 | |||
4380 | 875 | authority = http_get_authority(sl.rq.u, 1); | ||
4381 | 876 | if (authority.len && !isteqi(v, authority)) { | ||
4382 | 877 | if (h1m->err_pos < -1) { | ||
4383 | 878 | state = H1_MSG_HDR_L2_LWS; | ||
4384 | 879 | ptr = v.ptr; /* Set ptr on the error */ | ||
4385 | 880 | goto http_msg_invalid; | ||
4386 | 881 | } | ||
4387 | 882 | if (h1m->err_pos == -1) /* capture the error pointer */ | ||
4388 | 883 | h1m->err_pos = v.ptr - start + skip; /* >= 0 now */ | ||
4389 | 884 | } | ||
4392 | 885 | host_idx = hdr_count; | 921 | host_idx = hdr_count; |
4393 | 886 | } | ||
4394 | 887 | else { | 922 | else { |
4395 | 888 | if (!isteqi(v, hdr[host_idx].v)) { | 923 | if (!isteqi(v, hdr[host_idx].v)) { |
4396 | 889 | state = H1_MSG_HDR_L2_LWS; | 924 | state = H1_MSG_HDR_L2_LWS; |
4397 | @@ -934,6 +969,48 @@ int h1_headers_to_hdr_list(char *start, const char *stop, | |||
4398 | 934 | if (restarting) | 969 | if (restarting) |
4399 | 935 | goto restart; | 970 | goto restart; |
4400 | 936 | 971 | ||
4401 | 972 | |||
4402 | 973 | if (!(h1m->flags & (H1_MF_HDRS_ONLY|H1_MF_RESP))) { | ||
4403 | 974 | struct ist authority; | ||
4404 | 975 | |||
4405 | 976 | authority = http_get_authority(sl.rq.u, 1); | ||
4406 | 977 | if (sl.rq.meth == HTTP_METH_CONNECT) { | ||
4407 | 978 | struct ist *host = ((host_idx != -1) ? &hdr[host_idx].v : NULL); | ||
4408 | 979 | int ret; | ||
4409 | 980 | |||
4410 | 981 | ret = h1_validate_connect_authority(authority, host); | ||
4411 | 982 | if (ret < 0) { | ||
4412 | 983 | if (h1m->err_pos < -1) { | ||
4413 | 984 | state = H1_MSG_LAST_LF; | ||
4414 | 985 | /* WT: gcc seems to see a path where sl.rq.u.ptr was used | ||
4415 | 986 | * uninitialized, but it doesn't know that the function is | ||
4416 | 987 | * called with initial states making this impossible. | ||
4417 | 988 | */ | ||
4418 | 989 | ALREADY_CHECKED(sl.rq.u.ptr); | ||
4419 | 990 | ptr = ((ret == -1) ? sl.rq.u.ptr : host->ptr); /* Set ptr on the error */ | ||
4420 | 991 | goto http_msg_invalid; | ||
4421 | 992 | } | ||
4422 | 993 | if (h1m->err_pos == -1) /* capture the error pointer */ | ||
4423 | 994 | h1m->err_pos = ((ret == -1) ? sl.rq.u.ptr : host->ptr) - start + skip; /* >= 0 now */ | ||
4424 | 995 | } | ||
4425 | 996 | } | ||
4426 | 997 | else if (host_idx != -1 && istlen(authority)) { | ||
4427 | 998 | struct ist host = hdr[host_idx].v; | ||
4428 | 999 | |||
4429 | 1000 | /* For non-CONNECT method, the authority must match the host header value */ | ||
4430 | 1001 | if (!isteqi(authority, host)) { | ||
4431 | 1002 | if (h1m->err_pos < -1) { | ||
4432 | 1003 | state = H1_MSG_LAST_LF; | ||
4433 | 1004 | ptr = host.ptr; /* Set ptr on the error */ | ||
4434 | 1005 | goto http_msg_invalid; | ||
4435 | 1006 | } | ||
4436 | 1007 | if (h1m->err_pos == -1) /* capture the error pointer */ | ||
4437 | 1008 | h1m->err_pos = v.ptr - start + skip; /* >= 0 now */ | ||
4438 | 1009 | } | ||
4439 | 1010 | |||
4440 | 1011 | } | ||
4441 | 1012 | } | ||
4442 | 1013 | |||
4443 | 937 | state = H1_MSG_DATA; | 1014 | state = H1_MSG_DATA; |
4444 | 938 | if (h1m->flags & H1_MF_XFER_ENC) { | 1015 | if (h1m->flags & H1_MF_XFER_ENC) { |
4445 | 939 | if (h1m->flags & H1_MF_CLEN) { | 1016 | if (h1m->flags & H1_MF_CLEN) { |
4446 | diff --git a/src/h1_htx.c b/src/h1_htx.c | |||
4447 | index b6a91f2..650acba 100644 | |||
4448 | --- a/src/h1_htx.c | |||
4449 | +++ b/src/h1_htx.c | |||
4450 | @@ -279,6 +279,9 @@ static int h1_postparse_res_hdrs(struct h1m *h1m, union h1_sl *h1sl, struct htx | |||
4451 | 279 | goto output_full; | 279 | goto output_full; |
4452 | 280 | } | 280 | } |
4453 | 281 | 281 | ||
4454 | 282 | if ((h1m->flags & (H1_MF_CONN_UPG|H1_MF_UPG_WEBSOCKET)) && code != 101) | ||
4455 | 283 | h1m->flags &= ~(H1_MF_CONN_UPG|H1_MF_UPG_WEBSOCKET); | ||
4456 | 284 | |||
4457 | 282 | if (((h1m->flags & H1_MF_METH_CONNECT) && code >= 200 && code < 300) || code == 101) { | 285 | if (((h1m->flags & H1_MF_METH_CONNECT) && code >= 200 && code < 300) || code == 101) { |
4458 | 283 | h1m->flags &= ~(H1_MF_CLEN|H1_MF_CHNK); | 286 | h1m->flags &= ~(H1_MF_CLEN|H1_MF_CHNK); |
4459 | 284 | h1m->flags |= H1_MF_XFER_LEN; | 287 | h1m->flags |= H1_MF_XFER_LEN; |
4460 | diff --git a/src/haproxy.c b/src/haproxy.c | |||
4461 | index b484195..2f85293 100644 | |||
4462 | --- a/src/haproxy.c | |||
4463 | +++ b/src/haproxy.c | |||
4464 | @@ -1,6 +1,6 @@ | |||
4465 | 1 | /* | 1 | /* |
4466 | 2 | * HAProxy : High Availability-enabled HTTP/TCP proxy | 2 | * HAProxy : High Availability-enabled HTTP/TCP proxy |
4468 | 3 | * Copyright 2000-2022 Willy Tarreau <willy@haproxy.org>. | 3 | * Copyright 2000-2023 Willy Tarreau <willy@haproxy.org>. |
4469 | 4 | * | 4 | * |
4470 | 5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
4471 | 6 | * modify it under the terms of the GNU General Public License | 6 | * modify it under the terms of the GNU General Public License |
4472 | @@ -2080,6 +2080,10 @@ static void init(int argc, char **argv) | |||
4473 | 2080 | exit(1); | 2080 | exit(1); |
4474 | 2081 | } | 2081 | } |
4475 | 2082 | 2082 | ||
4476 | 2083 | /* set the default maxconn in the master, but let it be rewritable with -n */ | ||
4477 | 2084 | if (global.mode & MODE_MWORKER_WAIT) | ||
4478 | 2085 | global.maxconn = DEFAULT_MAXCONN; | ||
4479 | 2086 | |||
4480 | 2083 | if (cfg_maxconn > 0) | 2087 | if (cfg_maxconn > 0) |
4481 | 2084 | global.maxconn = cfg_maxconn; | 2088 | global.maxconn = cfg_maxconn; |
4482 | 2085 | 2089 | ||
4483 | @@ -2629,7 +2633,7 @@ void run_poll_loop() | |||
4484 | 2629 | if (killed > 1) | 2633 | if (killed > 1) |
4485 | 2630 | break; | 2634 | break; |
4486 | 2631 | 2635 | ||
4488 | 2632 | /* expire immediately if events are pending */ | 2636 | /* expire immediately if events or signals are pending */ |
4489 | 2633 | wake = 1; | 2637 | wake = 1; |
4490 | 2634 | if (thread_has_tasks()) | 2638 | if (thread_has_tasks()) |
4491 | 2635 | activity[tid].wake_tasks++; | 2639 | activity[tid].wake_tasks++; |
4492 | @@ -2639,6 +2643,10 @@ void run_poll_loop() | |||
4493 | 2639 | if (thread_has_tasks()) { | 2643 | if (thread_has_tasks()) { |
4494 | 2640 | activity[tid].wake_tasks++; | 2644 | activity[tid].wake_tasks++; |
4495 | 2641 | _HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit); | 2645 | _HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit); |
4496 | 2646 | } else if (signal_queue_len) { | ||
4497 | 2647 | /* this check is required to avoid | ||
4498 | 2648 | * a race with wakeup on signals using wake_threads() */ | ||
4499 | 2649 | _HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit); | ||
4500 | 2642 | } else | 2650 | } else |
4501 | 2643 | wake = 0; | 2651 | wake = 0; |
4502 | 2644 | } | 2652 | } |
4503 | diff --git a/src/hlua.c b/src/hlua.c | |||
4504 | index 0af3eb0..aea338f 100644 | |||
4505 | --- a/src/hlua.c | |||
4506 | +++ b/src/hlua.c | |||
4507 | @@ -738,7 +738,11 @@ __LJMP int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp, | |||
4508 | 738 | break; | 738 | break; |
4509 | 739 | 739 | ||
4510 | 740 | case ARGT_TAB: | 740 | case ARGT_TAB: |
4512 | 741 | argp[idx].data.prx = p; | 741 | if (!p->table) { |
4513 | 742 | msg = "Mandatory argument expected"; | ||
4514 | 743 | goto error; | ||
4515 | 744 | } | ||
4516 | 745 | argp[idx].data.t = p->table; | ||
4517 | 742 | argp[idx].type = ARGT_TAB; | 746 | argp[idx].type = ARGT_TAB; |
4518 | 743 | argp[idx+1].type = ARGT_STOP; | 747 | argp[idx+1].type = ARGT_STOP; |
4519 | 744 | break; | 748 | break; |
4520 | @@ -979,6 +983,7 @@ __LJMP int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp, | |||
4521 | 979 | return 0; | 983 | return 0; |
4522 | 980 | 984 | ||
4523 | 981 | error: | 985 | error: |
4524 | 986 | argp[idx].type = ARGT_STOP; | ||
4525 | 982 | for (i = 0; i < idx; i++) { | 987 | for (i = 0; i < idx; i++) { |
4526 | 983 | if (argp[i].type == ARGT_STR) | 988 | if (argp[i].type == ARGT_STR) |
4527 | 984 | chunk_destroy(&argp[i].data.str); | 989 | chunk_destroy(&argp[i].data.str); |
4528 | @@ -4421,7 +4426,7 @@ __LJMP static int hlua_applet_http_getline_yield(lua_State *L, int status, lua_K | |||
4529 | 4421 | /* The message was fully consumed and no more data are expected | 4426 | /* The message was fully consumed and no more data are expected |
4530 | 4422 | * (EOM flag set). | 4427 | * (EOM flag set). |
4531 | 4423 | */ | 4428 | */ |
4533 | 4424 | if (htx_is_empty(htx) && (htx->flags & HTX_FL_EOM)) | 4429 | if (htx_is_empty(htx) && (req->flags & CF_EOI)) |
4534 | 4425 | stop = 1; | 4430 | stop = 1; |
4535 | 4426 | 4431 | ||
4536 | 4427 | htx_to_buf(htx, &req->buf); | 4432 | htx_to_buf(htx, &req->buf); |
4537 | @@ -4513,7 +4518,7 @@ __LJMP static int hlua_applet_http_recv_yield(lua_State *L, int status, lua_KCon | |||
4538 | 4513 | /* The message was fully consumed and no more data are expected | 4518 | /* The message was fully consumed and no more data are expected |
4539 | 4514 | * (EOM flag set). | 4519 | * (EOM flag set). |
4540 | 4515 | */ | 4520 | */ |
4542 | 4516 | if (htx_is_empty(htx) && (htx->flags & HTX_FL_EOM)) | 4521 | if (htx_is_empty(htx) && (req->flags & CF_EOI)) |
4543 | 4517 | len = 0; | 4522 | len = 0; |
4544 | 4518 | 4523 | ||
4545 | 4519 | htx_to_buf(htx, &req->buf); | 4524 | htx_to_buf(htx, &req->buf); |
4546 | diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c | |||
4547 | index 26aa509..010bd13 100644 | |||
4548 | --- a/src/hlua_fcn.c | |||
4549 | +++ b/src/hlua_fcn.c | |||
4550 | @@ -1305,6 +1305,7 @@ int hlua_proxy_pause(lua_State *L) | |||
4551 | 1305 | struct proxy *px; | 1305 | struct proxy *px; |
4552 | 1306 | 1306 | ||
4553 | 1307 | px = hlua_check_proxy(L, 1); | 1307 | px = hlua_check_proxy(L, 1); |
4554 | 1308 | /* safe to call without PROXY_LOCK - pause_proxy takes it */ | ||
4555 | 1308 | pause_proxy(px); | 1309 | pause_proxy(px); |
4556 | 1309 | return 0; | 1310 | return 0; |
4557 | 1310 | } | 1311 | } |
4558 | @@ -1314,6 +1315,7 @@ int hlua_proxy_resume(lua_State *L) | |||
4559 | 1314 | struct proxy *px; | 1315 | struct proxy *px; |
4560 | 1315 | 1316 | ||
4561 | 1316 | px = hlua_check_proxy(L, 1); | 1317 | px = hlua_check_proxy(L, 1); |
4562 | 1318 | /* safe to call without PROXY_LOCK - resume_proxy takes it */ | ||
4563 | 1317 | resume_proxy(px); | 1319 | resume_proxy(px); |
4564 | 1318 | return 0; | 1320 | return 0; |
4565 | 1319 | } | 1321 | } |
4566 | @@ -1323,6 +1325,7 @@ int hlua_proxy_stop(lua_State *L) | |||
4567 | 1323 | struct proxy *px; | 1325 | struct proxy *px; |
4568 | 1324 | 1326 | ||
4569 | 1325 | px = hlua_check_proxy(L, 1); | 1327 | px = hlua_check_proxy(L, 1); |
4570 | 1328 | /* safe to call without PROXY_LOCK - stop_proxy takes it */ | ||
4571 | 1326 | stop_proxy(px); | 1329 | stop_proxy(px); |
4572 | 1327 | return 0; | 1330 | return 0; |
4573 | 1328 | } | 1331 | } |
4574 | diff --git a/src/hpack-dec.c b/src/hpack-dec.c | |||
4575 | index 4fa9bfd..ed39007 100644 | |||
4576 | --- a/src/hpack-dec.c | |||
4577 | +++ b/src/hpack-dec.c | |||
4578 | @@ -32,6 +32,7 @@ | |||
4579 | 32 | 32 | ||
4580 | 33 | #include <import/ist.h> | 33 | #include <import/ist.h> |
4581 | 34 | #include <haproxy/chunk.h> | 34 | #include <haproxy/chunk.h> |
4582 | 35 | #include <haproxy/global.h> | ||
4583 | 35 | #include <haproxy/h2.h> | 36 | #include <haproxy/h2.h> |
4584 | 36 | #include <haproxy/hpack-dec.h> | 37 | #include <haproxy/hpack-dec.h> |
4585 | 37 | #include <haproxy/hpack-huff.h> | 38 | #include <haproxy/hpack-huff.h> |
4586 | @@ -419,6 +420,15 @@ int hpack_decode_frame(struct hpack_dht *dht, const uint8_t *raw, uint32_t len, | |||
4587 | 419 | /* <name> and <value> are correctly filled here */ | 420 | /* <name> and <value> are correctly filled here */ |
4588 | 420 | } | 421 | } |
4589 | 421 | 422 | ||
4590 | 423 | /* We must not accept empty header names (forbidden by the spec and used | ||
4591 | 424 | * as a list termination). | ||
4592 | 425 | */ | ||
4593 | 426 | if (!name.len) { | ||
4594 | 427 | hpack_debug_printf("##ERR@%d##\n", __LINE__); | ||
4595 | 428 | ret = -HPACK_ERR_INVALID_ARGUMENT; | ||
4596 | 429 | goto leave; | ||
4597 | 430 | } | ||
4598 | 431 | |||
4599 | 422 | /* here's what we have here : | 432 | /* here's what we have here : |
4600 | 423 | * - name.len > 0 | 433 | * - name.len > 0 |
4601 | 424 | * - value is filled with either const data or data allocated from tmp | 434 | * - value is filled with either const data or data allocated from tmp |
4602 | diff --git a/src/http.c b/src/http.c | |||
4603 | index 0b00e47..c10b433 100644 | |||
4604 | --- a/src/http.c | |||
4605 | +++ b/src/http.c | |||
4606 | @@ -468,6 +468,38 @@ const char *http_get_reason(unsigned int status) | |||
4607 | 468 | } | 468 | } |
4608 | 469 | } | 469 | } |
4609 | 470 | 470 | ||
4610 | 471 | /* Returns the ist string corresponding to port part (without ':') in the host | ||
4611 | 472 | * <host> or IST_NULL if not found. | ||
4612 | 473 | */ | ||
4613 | 474 | struct ist http_get_host_port(const struct ist host) | ||
4614 | 475 | { | ||
4615 | 476 | char *start, *end, *ptr; | ||
4616 | 477 | |||
4617 | 478 | start = istptr(host); | ||
4618 | 479 | end = istend(host); | ||
4619 | 480 | for (ptr = end; ptr > start && isdigit((unsigned char)*--ptr);); | ||
4620 | 481 | |||
4621 | 482 | /* no port found */ | ||
4622 | 483 | if (likely(*ptr != ':' || ptr+1 == end || ptr == start)) | ||
4623 | 484 | return IST_NULL; | ||
4624 | 485 | |||
4625 | 486 | return istnext(ist2(ptr, end - ptr)); | ||
4626 | 487 | } | ||
4627 | 488 | |||
4628 | 489 | |||
4629 | 490 | /* Return non-zero if the port <port> is a default port. If the scheme <schm> is | ||
4630 | 491 | * set, it is used to detect default ports (HTTP => 80 and HTTPS => 443) | ||
4631 | 492 | * port. Otherwise, both are considered as default ports. | ||
4632 | 493 | */ | ||
4633 | 494 | int http_is_default_port(const struct ist schm, const struct ist port) | ||
4634 | 495 | { | ||
4635 | 496 | if (!isttest(schm)) | ||
4636 | 497 | return (isteq(port, ist("443")) || isteq(port, ist("80"))); | ||
4637 | 498 | else | ||
4638 | 499 | return (isteq(port, ist("443")) && isteqi(schm, ist("https://"))) || | ||
4639 | 500 | (isteq(port, ist("80")) && isteqi(schm, ist("http://"))); | ||
4640 | 501 | } | ||
4641 | 502 | |||
4642 | 471 | /* Returns non-zero if the scheme <schm> is syntactically correct according to | 503 | /* Returns non-zero if the scheme <schm> is syntactically correct according to |
4643 | 472 | * RFC3986#3.1, otherwise zero. It expects only the scheme and nothing else | 504 | * RFC3986#3.1, otherwise zero. It expects only the scheme and nothing else |
4644 | 473 | * (particularly not the following "://"). | 505 | * (particularly not the following "://"). |
4645 | diff --git a/src/http_act.c b/src/http_act.c | |||
4646 | index f88c856..59e614f 100644 | |||
4647 | --- a/src/http_act.c | |||
4648 | +++ b/src/http_act.c | |||
4649 | @@ -1877,6 +1877,8 @@ static void release_http_redir(struct act_rule *rule) | |||
4650 | 1877 | free(redir->cookie_str); | 1877 | free(redir->cookie_str); |
4651 | 1878 | list_for_each_entry_safe(lf, lfb, &redir->rdr_fmt, list) { | 1878 | list_for_each_entry_safe(lf, lfb, &redir->rdr_fmt, list) { |
4652 | 1879 | LIST_DELETE(&lf->list); | 1879 | LIST_DELETE(&lf->list); |
4653 | 1880 | release_sample_expr(lf->expr); | ||
4654 | 1881 | free(lf->arg); | ||
4655 | 1880 | free(lf); | 1882 | free(lf); |
4656 | 1881 | } | 1883 | } |
4657 | 1882 | free(redir); | 1884 | free(redir); |
4658 | diff --git a/src/http_ana.c b/src/http_ana.c | |||
4659 | index 4491ea1..2e2095b 100644 | |||
4660 | --- a/src/http_ana.c | |||
4661 | +++ b/src/http_ana.c | |||
4662 | @@ -938,9 +938,8 @@ int http_wait_for_request_body(struct stream *s, struct channel *req, int an_bit | |||
4663 | 938 | { | 938 | { |
4664 | 939 | struct session *sess = s->sess; | 939 | struct session *sess = s->sess; |
4665 | 940 | struct http_txn *txn = s->txn; | 940 | struct http_txn *txn = s->txn; |
4666 | 941 | struct http_msg *msg = &s->txn->req; | ||
4667 | 942 | 941 | ||
4669 | 943 | DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA, s, txn, msg); | 942 | DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA, s, txn, &s->txn->req); |
4670 | 944 | 943 | ||
4671 | 945 | 944 | ||
4672 | 946 | switch (http_wait_for_msg_body(s, req, s->be->timeout.httpreq, 0)) { | 945 | switch (http_wait_for_msg_body(s, req, s->be->timeout.httpreq, 0)) { |
4673 | @@ -998,7 +997,7 @@ int http_wait_for_request_body(struct stream *s, struct channel *req, int an_bit | |||
4674 | 998 | if (!(s->flags & SF_ERR_MASK)) | 997 | if (!(s->flags & SF_ERR_MASK)) |
4675 | 999 | s->flags |= SF_ERR_PRXCOND; | 998 | s->flags |= SF_ERR_PRXCOND; |
4676 | 1000 | if (!(s->flags & SF_FINST_MASK)) | 999 | if (!(s->flags & SF_FINST_MASK)) |
4678 | 1001 | s->flags |= (msg->msg_state < HTTP_MSG_DATA ? SF_FINST_R : SF_FINST_D); | 1000 | s->flags |= SF_FINST_R; |
4679 | 1002 | 1001 | ||
4680 | 1003 | req->analysers &= AN_REQ_FLT_END; | 1002 | req->analysers &= AN_REQ_FLT_END; |
4681 | 1004 | req->analyse_exp = TICK_ETERNITY; | 1003 | req->analyse_exp = TICK_ETERNITY; |
4682 | @@ -2655,17 +2654,21 @@ static enum rule_result http_req_restrict_header_names(struct stream *s, struct | |||
4683 | 2655 | 2654 | ||
4684 | 2656 | if (type == HTX_BLK_HDR) { | 2655 | if (type == HTX_BLK_HDR) { |
4685 | 2657 | struct ist n = htx_get_blk_name(htx, blk); | 2656 | struct ist n = htx_get_blk_name(htx, blk); |
4687 | 2658 | int i; | 2657 | int i, end = istlen(n); |
4688 | 2659 | 2658 | ||
4690 | 2660 | for (i = 0; i < istlen(n); i++) { | 2659 | for (i = 0; i < end; i++) { |
4691 | 2661 | if (!isalnum((unsigned char)n.ptr[i]) && n.ptr[i] != '-') { | 2660 | if (!isalnum((unsigned char)n.ptr[i]) && n.ptr[i] != '-') { |
4697 | 2662 | /* Block the request or remove the header */ | 2661 | break; |
4693 | 2663 | if (px->options2 & PR_O2_RSTRICT_REQ_HDR_NAMES_BLK) | ||
4694 | 2664 | goto block; | ||
4695 | 2665 | blk = htx_remove_blk(htx, blk); | ||
4696 | 2666 | continue; | ||
4698 | 2667 | } | 2662 | } |
4699 | 2668 | } | 2663 | } |
4700 | 2664 | |||
4701 | 2665 | if (i < end) { | ||
4702 | 2666 | /* Disallowed character found - block the request or remove the header */ | ||
4703 | 2667 | if (px->options2 & PR_O2_RSTRICT_REQ_HDR_NAMES_BLK) | ||
4704 | 2668 | goto block; | ||
4705 | 2669 | blk = htx_remove_blk(htx, blk); | ||
4706 | 2670 | continue; | ||
4707 | 2671 | } | ||
4708 | 2669 | } | 2672 | } |
4709 | 2670 | if (type == HTX_BLK_EOH) | 2673 | if (type == HTX_BLK_EOH) |
4710 | 2671 | break; | 2674 | break; |
4711 | @@ -2778,6 +2781,7 @@ int http_res_set_status(unsigned int status, struct ist reason, struct stream *s | |||
4712 | 2778 | 2781 | ||
4713 | 2779 | if (!http_replace_res_status(htx, ist2(trash.area, trash.data), reason)) | 2782 | if (!http_replace_res_status(htx, ist2(trash.area, trash.data), reason)) |
4714 | 2780 | return -1; | 2783 | return -1; |
4715 | 2784 | s->txn->status = status; | ||
4716 | 2781 | return 0; | 2785 | return 0; |
4717 | 2782 | } | 2786 | } |
4718 | 2783 | 2787 | ||
4719 | @@ -4241,7 +4245,7 @@ enum rule_result http_wait_for_msg_body(struct stream *s, struct channel *chn, | |||
4720 | 4241 | if (!(s->flags & SF_ERR_MASK)) | 4245 | if (!(s->flags & SF_ERR_MASK)) |
4721 | 4242 | s->flags |= SF_ERR_CLITO; | 4246 | s->flags |= SF_ERR_CLITO; |
4722 | 4243 | if (!(s->flags & SF_FINST_MASK)) | 4247 | if (!(s->flags & SF_FINST_MASK)) |
4724 | 4244 | s->flags |= SF_FINST_D; | 4248 | s->flags |= SF_FINST_R; |
4725 | 4245 | _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req); | 4249 | _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req); |
4726 | 4246 | if (sess->listener && sess->listener->counters) | 4250 | if (sess->listener && sess->listener->counters) |
4727 | 4247 | _HA_ATOMIC_INC(&sess->listener->counters->failed_req); | 4251 | _HA_ATOMIC_INC(&sess->listener->counters->failed_req); |
4728 | @@ -4254,7 +4258,7 @@ enum rule_result http_wait_for_msg_body(struct stream *s, struct channel *chn, | |||
4729 | 4254 | if (!(s->flags & SF_ERR_MASK)) | 4258 | if (!(s->flags & SF_ERR_MASK)) |
4730 | 4255 | s->flags |= SF_ERR_SRVTO; | 4259 | s->flags |= SF_ERR_SRVTO; |
4731 | 4256 | if (!(s->flags & SF_FINST_MASK)) | 4260 | if (!(s->flags & SF_FINST_MASK)) |
4733 | 4257 | s->flags |= SF_FINST_D; | 4261 | s->flags |= SF_FINST_R; |
4734 | 4258 | stream_inc_http_fail_ctr(s); | 4262 | stream_inc_http_fail_ctr(s); |
4735 | 4259 | http_reply_and_close(s, txn->status, http_error_message(s)); | 4263 | http_reply_and_close(s, txn->status, http_error_message(s)); |
4736 | 4260 | ret = HTTP_RULE_RES_ABRT; | 4264 | ret = HTTP_RULE_RES_ABRT; |
4737 | @@ -5205,8 +5209,10 @@ struct http_txn *http_create_txn(struct stream *s) | |||
4738 | 5205 | 5209 | ||
4739 | 5206 | txn->auth.method = HTTP_AUTH_UNKNOWN; | 5210 | txn->auth.method = HTTP_AUTH_UNKNOWN; |
4740 | 5207 | 5211 | ||
4743 | 5208 | vars_init(&s->vars_txn, SCOPE_TXN); | 5212 | /* here we don't want to re-initialize s->vars_txn and s->vars_reqres |
4744 | 5209 | vars_init(&s->vars_reqres, SCOPE_REQ); | 5213 | * variable lists, because they were already initialized upon stream |
4745 | 5214 | * creation in stream_new(), and thus may already contain some variables | ||
4746 | 5215 | */ | ||
4747 | 5210 | 5216 | ||
4748 | 5211 | return txn; | 5217 | return txn; |
4749 | 5212 | } | 5218 | } |
4750 | diff --git a/src/http_fetch.c b/src/http_fetch.c | |||
4751 | index 3950eea..6678c85 100644 | |||
4752 | --- a/src/http_fetch.c | |||
4753 | +++ b/src/http_fetch.c | |||
4754 | @@ -222,7 +222,7 @@ struct htx *smp_prefetch_htx(struct sample *smp, struct channel *chn, struct che | |||
4755 | 222 | if (IS_HTX_STRM(s)) { | 222 | if (IS_HTX_STRM(s)) { |
4756 | 223 | htx = htxbuf(&chn->buf); | 223 | htx = htxbuf(&chn->buf); |
4757 | 224 | 224 | ||
4759 | 225 | if (msg->msg_state == HTTP_MSG_ERROR || (htx->flags & HTX_FL_PARSING_ERROR)) | 225 | if (htx->flags & HTX_FL_PARSING_ERROR) |
4760 | 226 | return NULL; | 226 | return NULL; |
4761 | 227 | 227 | ||
4762 | 228 | if (msg->msg_state < HTTP_MSG_BODY) { | 228 | if (msg->msg_state < HTTP_MSG_BODY) { |
4763 | @@ -307,7 +307,7 @@ struct htx *smp_prefetch_htx(struct sample *smp, struct channel *chn, struct che | |||
4764 | 307 | if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD) | 307 | if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD) |
4765 | 308 | s->flags |= SF_REDIRECTABLE; | 308 | s->flags |= SF_REDIRECTABLE; |
4766 | 309 | } | 309 | } |
4768 | 310 | else | 310 | else if (txn->status == -1) |
4769 | 311 | txn->status = sl->info.res.status; | 311 | txn->status = sl->info.res.status; |
4770 | 312 | if (sl->flags & HTX_SL_F_VER_11) | 312 | if (sl->flags & HTX_SL_F_VER_11) |
4771 | 313 | msg->flags |= HTTP_MSGF_VER_11; | 313 | msg->flags |= HTTP_MSGF_VER_11; |
4772 | @@ -330,20 +330,21 @@ static int smp_fetch_meth(const struct arg *args, struct sample *smp, const char | |||
4773 | 330 | { | 330 | { |
4774 | 331 | struct channel *chn = SMP_REQ_CHN(smp); | 331 | struct channel *chn = SMP_REQ_CHN(smp); |
4775 | 332 | struct http_txn *txn; | 332 | struct http_txn *txn; |
4777 | 333 | struct htx *htx; | 333 | struct htx *htx = NULL; |
4778 | 334 | int meth; | 334 | int meth; |
4779 | 335 | 335 | ||
4780 | 336 | txn = (smp->strm ? smp->strm->txn : NULL); | 336 | txn = (smp->strm ? smp->strm->txn : NULL); |
4781 | 337 | if (!txn) | 337 | if (!txn) |
4782 | 338 | return 0; | 338 | return 0; |
4783 | 339 | 339 | ||
4785 | 340 | if (txn->meth == HTTP_METH_OTHER) { | 340 | meth = txn->meth; |
4786 | 341 | if (meth == HTTP_METH_OTHER) { | ||
4787 | 341 | htx = smp_prefetch_htx(smp, chn, NULL, 1); | 342 | htx = smp_prefetch_htx(smp, chn, NULL, 1); |
4788 | 342 | if (!htx) | 343 | if (!htx) |
4789 | 343 | return 0; | 344 | return 0; |
4790 | 345 | meth = txn->meth; | ||
4791 | 344 | } | 346 | } |
4792 | 345 | 347 | ||
4793 | 346 | meth = txn->meth; | ||
4794 | 347 | smp->data.type = SMP_T_METH; | 348 | smp->data.type = SMP_T_METH; |
4795 | 348 | smp->data.u.meth.meth = meth; | 349 | smp->data.u.meth.meth = meth; |
4796 | 349 | if (meth == HTTP_METH_OTHER) { | 350 | if (meth == HTTP_METH_OTHER) { |
4797 | diff --git a/src/http_htx.c b/src/http_htx.c | |||
4798 | index 6f5c1a1..60525bb 100644 | |||
4799 | --- a/src/http_htx.c | |||
4800 | +++ b/src/http_htx.c | |||
4801 | @@ -388,6 +388,9 @@ int http_replace_req_uri(struct htx *htx, const struct ist uri) | |||
4802 | 388 | goto fail; | 388 | goto fail; |
4803 | 389 | 389 | ||
4804 | 390 | sl = http_get_stline(htx); | 390 | sl = http_get_stline(htx); |
4805 | 391 | ALREADY_CHECKED(sl); /* the stline exists because http_replace_stline() succeded */ | ||
4806 | 392 | sl->flags &= ~HTX_SL_F_NORMALIZED_URI; | ||
4807 | 393 | |||
4808 | 391 | if (!http_update_host(htx, sl, uri)) | 394 | if (!http_update_host(htx, sl, uri)) |
4809 | 392 | goto fail; | 395 | goto fail; |
4810 | 393 | 396 | ||
4811 | @@ -918,7 +921,7 @@ int http_str_to_htx(struct buffer *buf, struct ist raw, char **errmsg) | |||
4812 | 918 | ret = h1_headers_to_hdr_list(raw.ptr, raw.ptr + raw.len, | 921 | ret = h1_headers_to_hdr_list(raw.ptr, raw.ptr + raw.len, |
4813 | 919 | hdrs, sizeof(hdrs)/sizeof(hdrs[0]), &h1m, &h1sl); | 922 | hdrs, sizeof(hdrs)/sizeof(hdrs[0]), &h1m, &h1sl); |
4814 | 920 | if (ret <= 0) { | 923 | if (ret <= 0) { |
4816 | 921 | memprintf(errmsg, "unabled to parse headers (error offset: %d)", h1m.err_pos); | 924 | memprintf(errmsg, "unable to parse headers (error offset: %d)", h1m.err_pos); |
4817 | 922 | goto error; | 925 | goto error; |
4818 | 923 | } | 926 | } |
4819 | 924 | 927 | ||
4820 | @@ -1565,6 +1568,7 @@ struct http_reply *http_parse_http_reply(const char **args, int *orig_arg, struc | |||
4821 | 1565 | fd = -1; | 1568 | fd = -1; |
4822 | 1566 | obj[objlen] = '\0'; | 1569 | obj[objlen] = '\0'; |
4823 | 1567 | reply->type = HTTP_REPLY_LOGFMT; | 1570 | reply->type = HTTP_REPLY_LOGFMT; |
4824 | 1571 | LIST_INIT(&reply->body.fmt); | ||
4825 | 1568 | cur_arg++; | 1572 | cur_arg++; |
4826 | 1569 | } | 1573 | } |
4827 | 1570 | else if (strcmp(args[cur_arg], "lf-string") == 0) { | 1574 | else if (strcmp(args[cur_arg], "lf-string") == 0) { |
4828 | @@ -1581,6 +1585,7 @@ struct http_reply *http_parse_http_reply(const char **args, int *orig_arg, struc | |||
4829 | 1581 | obj = strdup(args[cur_arg]); | 1585 | obj = strdup(args[cur_arg]); |
4830 | 1582 | objlen = strlen(args[cur_arg]); | 1586 | objlen = strlen(args[cur_arg]); |
4831 | 1583 | reply->type = HTTP_REPLY_LOGFMT; | 1587 | reply->type = HTTP_REPLY_LOGFMT; |
4832 | 1588 | LIST_INIT(&reply->body.fmt); | ||
4833 | 1584 | cur_arg++; | 1589 | cur_arg++; |
4834 | 1585 | } | 1590 | } |
4835 | 1586 | else if (strcmp(args[cur_arg], "hdr") == 0) { | 1591 | else if (strcmp(args[cur_arg], "hdr") == 0) { |
4836 | @@ -1721,12 +1726,6 @@ struct http_reply *http_parse_http_reply(const char **args, int *orig_arg, struc | |||
4837 | 1721 | return NULL; | 1726 | return NULL; |
4838 | 1722 | } | 1727 | } |
4839 | 1723 | 1728 | ||
4840 | 1724 | static int uri_is_default_port(const struct ist scheme, const struct ist port) | ||
4841 | 1725 | { | ||
4842 | 1726 | return (isteq(port, ist("443")) && isteqi(scheme, ist("https://"))) || | ||
4843 | 1727 | (isteq(port, ist("80")) && isteqi(scheme, ist("http://"))); | ||
4844 | 1728 | } | ||
4845 | 1729 | |||
4846 | 1730 | /* Apply schemed-based normalization as described on rfc3986 on section 6.3.2. | 1729 | /* Apply schemed-based normalization as described on rfc3986 on section 6.3.2. |
4847 | 1731 | * Returns 0 if no error has been found else non-zero. | 1730 | * Returns 0 if no error has been found else non-zero. |
4848 | 1732 | * | 1731 | * |
4849 | @@ -1741,7 +1740,6 @@ int http_scheme_based_normalize(struct htx *htx) | |||
4850 | 1741 | struct http_hdr_ctx ctx; | 1740 | struct http_hdr_ctx ctx; |
4851 | 1742 | struct htx_sl *sl; | 1741 | struct htx_sl *sl; |
4852 | 1743 | struct ist uri, scheme, authority, host, port; | 1742 | struct ist uri, scheme, authority, host, port; |
4853 | 1744 | char *start, *end, *ptr; | ||
4854 | 1745 | 1743 | ||
4855 | 1746 | sl = http_get_stline(htx); | 1744 | sl = http_get_stline(htx); |
4856 | 1747 | 1745 | ||
4857 | @@ -1755,25 +1753,16 @@ int http_scheme_based_normalize(struct htx *htx) | |||
4858 | 1755 | if (!isttest(scheme)) | 1753 | if (!isttest(scheme)) |
4859 | 1756 | return 0; | 1754 | return 0; |
4860 | 1757 | 1755 | ||
4873 | 1758 | /* Extract the port if present in authority. To properly support ipv6 | 1756 | /* Extract the port if present in authority */ |
4874 | 1759 | * hostnames, do a reverse search on the last ':' separator as long as | 1757 | authority = http_get_authority(uri, 1); |
4875 | 1760 | * digits are found. | 1758 | port = http_get_host_port(authority); |
4876 | 1761 | */ | 1759 | if (!isttest(port)) { |
4877 | 1762 | authority = http_get_authority(uri, 0); | 1760 | /* if no port found, no normalization to proceed */ |
4866 | 1763 | start = istptr(authority); | ||
4867 | 1764 | end = istend(authority); | ||
4868 | 1765 | for (ptr = end; ptr > start && isdigit((unsigned char)*--ptr); ) | ||
4869 | 1766 | ; | ||
4870 | 1767 | |||
4871 | 1768 | /* if no port found, no normalization to proceed */ | ||
4872 | 1769 | if (likely(*ptr != ':')) | ||
4878 | 1770 | return 0; | 1761 | return 0; |
4879 | 1762 | } | ||
4880 | 1763 | host = isttrim(authority, istlen(authority) - istlen(port) - 1); | ||
4881 | 1771 | 1764 | ||
4887 | 1772 | /* split host/port on the ':' separator found */ | 1765 | if (istlen(port) && http_is_default_port(scheme, port)) { |
4883 | 1773 | host = ist2(start, ptr - start); | ||
4884 | 1774 | port = istnext(ist2(ptr, end - ptr)); | ||
4885 | 1775 | |||
4886 | 1776 | if (istlen(port) && uri_is_default_port(scheme, port)) { | ||
4888 | 1777 | /* reconstruct the uri with removal of the port */ | 1766 | /* reconstruct the uri with removal of the port */ |
4889 | 1778 | struct buffer *temp = get_trash_chunk(); | 1767 | struct buffer *temp = get_trash_chunk(); |
4890 | 1779 | struct ist meth, vsn; | 1768 | struct ist meth, vsn; |
4891 | diff --git a/src/listener.c b/src/listener.c | |||
4892 | index 0ffd0fe..67616f5 100644 | |||
4893 | --- a/src/listener.c | |||
4894 | +++ b/src/listener.c | |||
4895 | @@ -45,6 +45,7 @@ static struct bind_kw_list bind_keywords = { | |||
4896 | 45 | /* list of the temporarily limited listeners because of lack of resource */ | 45 | /* list of the temporarily limited listeners because of lack of resource */ |
4897 | 46 | static struct mt_list global_listener_queue = MT_LIST_HEAD_INIT(global_listener_queue); | 46 | static struct mt_list global_listener_queue = MT_LIST_HEAD_INIT(global_listener_queue); |
4898 | 47 | static struct task *global_listener_queue_task; | 47 | static struct task *global_listener_queue_task; |
4899 | 48 | __decl_thread(static HA_RWLOCK_T global_listener_rwlock); | ||
4900 | 48 | 49 | ||
4901 | 49 | /* listener status for stats */ | 50 | /* listener status for stats */ |
4902 | 50 | const char* li_status_st[LI_STATE_COUNT] = { | 51 | const char* li_status_st[LI_STATE_COUNT] = { |
4903 | @@ -297,13 +298,14 @@ void enable_listener(struct listener *listener) | |||
4904 | 297 | 298 | ||
4905 | 298 | /* | 299 | /* |
4906 | 299 | * This function completely stops a listener. It will need to operate under the | 300 | * This function completely stops a listener. It will need to operate under the |
4911 | 300 | * proxy's lock, the protocol's lock, and the listener's lock. The caller is | 301 | * It will need to operate under the proxy's lock and the protocol's lock. |
4912 | 301 | * responsible for indicating in lpx, lpr, lli whether the respective locks are | 302 | * The caller is responsible for indicating in lpx, lpr whether the |
4913 | 302 | * already held (non-zero) or not (zero) so that the function picks the missing | 303 | * respective locks are already held (non-zero) or not (zero) so that the |
4914 | 303 | * ones, in this order. The proxy's listeners count is updated and the proxy is | 304 | * function picks the missing ones, in this order. |
4915 | 305 | * The proxy's listeners count is updated and the proxy is | ||
4916 | 304 | * disabled and woken up after the last one is gone. | 306 | * disabled and woken up after the last one is gone. |
4917 | 305 | */ | 307 | */ |
4919 | 306 | void stop_listener(struct listener *l, int lpx, int lpr, int lli) | 308 | void stop_listener(struct listener *l, int lpx, int lpr) |
4920 | 307 | { | 309 | { |
4921 | 308 | struct proxy *px = l->bind_conf->frontend; | 310 | struct proxy *px = l->bind_conf->frontend; |
4922 | 309 | 311 | ||
4923 | @@ -320,8 +322,7 @@ void stop_listener(struct listener *l, int lpx, int lpr, int lli) | |||
4924 | 320 | if (!lpr) | 322 | if (!lpr) |
4925 | 321 | HA_SPIN_LOCK(PROTO_LOCK, &proto_lock); | 323 | HA_SPIN_LOCK(PROTO_LOCK, &proto_lock); |
4926 | 322 | 324 | ||
4929 | 323 | if (!lli) | 325 | HA_RWLOCK_WRLOCK(LISTENER_LOCK, &l->lock); |
4928 | 324 | HA_RWLOCK_WRLOCK(LISTENER_LOCK, &l->lock); | ||
4930 | 325 | 326 | ||
4931 | 326 | if (l->state > LI_INIT) { | 327 | if (l->state > LI_INIT) { |
4932 | 327 | do_unbind_listener(l); | 328 | do_unbind_listener(l); |
4933 | @@ -332,8 +333,7 @@ void stop_listener(struct listener *l, int lpx, int lpr, int lli) | |||
4934 | 332 | proxy_cond_disable(px); | 333 | proxy_cond_disable(px); |
4935 | 333 | } | 334 | } |
4936 | 334 | 335 | ||
4939 | 335 | if (!lli) | 336 | HA_RWLOCK_WRUNLOCK(LISTENER_LOCK, &l->lock); |
4938 | 336 | HA_RWLOCK_WRUNLOCK(LISTENER_LOCK, &l->lock); | ||
4940 | 337 | 337 | ||
4941 | 338 | if (!lpr) | 338 | if (!lpr) |
4942 | 339 | HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock); | 339 | HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock); |
4943 | @@ -422,12 +422,18 @@ int default_resume_listener(struct listener *l) | |||
4944 | 422 | * closes upon SHUT_WR and refuses to rebind. So a common validation path | 422 | * closes upon SHUT_WR and refuses to rebind. So a common validation path |
4945 | 423 | * involves SHUT_WR && listen && SHUT_RD. In case of success, the FD's polling | 423 | * involves SHUT_WR && listen && SHUT_RD. In case of success, the FD's polling |
4946 | 424 | * is disabled. It normally returns non-zero, unless an error is reported. | 424 | * is disabled. It normally returns non-zero, unless an error is reported. |
4947 | 425 | * It will need to operate under the proxy's lock. The caller is | ||
4948 | 426 | * responsible for indicating in lpx whether the proxy locks is | ||
4949 | 427 | * already held (non-zero) or not (zero) so that the function picks it. | ||
4950 | 425 | */ | 428 | */ |
4952 | 426 | int pause_listener(struct listener *l) | 429 | int pause_listener(struct listener *l, int lpx) |
4953 | 427 | { | 430 | { |
4954 | 428 | struct proxy *px = l->bind_conf->frontend; | 431 | struct proxy *px = l->bind_conf->frontend; |
4955 | 429 | int ret = 1; | 432 | int ret = 1; |
4956 | 430 | 433 | ||
4957 | 434 | if (!lpx) | ||
4958 | 435 | HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock); | ||
4959 | 436 | |||
4960 | 431 | HA_RWLOCK_WRLOCK(LISTENER_LOCK, &l->lock); | 437 | HA_RWLOCK_WRLOCK(LISTENER_LOCK, &l->lock); |
4961 | 432 | 438 | ||
4962 | 433 | if ((global.mode & (MODE_DAEMON | MODE_MWORKER)) && | 439 | if ((global.mode & (MODE_DAEMON | MODE_MWORKER)) && |
4963 | @@ -450,6 +456,10 @@ int pause_listener(struct listener *l) | |||
4964 | 450 | } | 456 | } |
4965 | 451 | end: | 457 | end: |
4966 | 452 | HA_RWLOCK_WRUNLOCK(LISTENER_LOCK, &l->lock); | 458 | HA_RWLOCK_WRUNLOCK(LISTENER_LOCK, &l->lock); |
4967 | 459 | |||
4968 | 460 | if (!lpx) | ||
4969 | 461 | HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock); | ||
4970 | 462 | |||
4971 | 453 | return ret; | 463 | return ret; |
4972 | 454 | } | 464 | } |
4973 | 455 | 465 | ||
4974 | @@ -462,13 +472,19 @@ int pause_listener(struct listener *l) | |||
4975 | 462 | * state, it's totally rebound. This can happen if a pause() has completely | 472 | * state, it's totally rebound. This can happen if a pause() has completely |
4976 | 463 | * stopped it. If the resume fails, 0 is returned and an error might be | 473 | * stopped it. If the resume fails, 0 is returned and an error might be |
4977 | 464 | * displayed. | 474 | * displayed. |
4978 | 475 | * It will need to operate under the proxy's lock. The caller is | ||
4979 | 476 | * responsible for indicating in lpx whether the proxy locks is | ||
4980 | 477 | * already held (non-zero) or not (zero) so that the function picks it. | ||
4981 | 465 | */ | 478 | */ |
4983 | 466 | int resume_listener(struct listener *l) | 479 | int resume_listener(struct listener *l, int lpx) |
4984 | 467 | { | 480 | { |
4985 | 468 | struct proxy *px = l->bind_conf->frontend; | 481 | struct proxy *px = l->bind_conf->frontend; |
4986 | 469 | int was_paused = px && px->li_paused; | 482 | int was_paused = px && px->li_paused; |
4987 | 470 | int ret = 1; | 483 | int ret = 1; |
4988 | 471 | 484 | ||
4989 | 485 | if (!lpx) | ||
4990 | 486 | HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock); | ||
4991 | 487 | |||
4992 | 472 | HA_RWLOCK_WRLOCK(LISTENER_LOCK, &l->lock); | 488 | HA_RWLOCK_WRLOCK(LISTENER_LOCK, &l->lock); |
4993 | 473 | 489 | ||
4994 | 474 | /* check that another thread didn't to the job in parallel (e.g. at the | 490 | /* check that another thread didn't to the job in parallel (e.g. at the |
4995 | @@ -484,6 +500,10 @@ int resume_listener(struct listener *l) | |||
4996 | 484 | if (l->state == LI_READY) | 500 | if (l->state == LI_READY) |
4997 | 485 | goto end; | 501 | goto end; |
4998 | 486 | 502 | ||
4999 | 503 | /* the listener might have been stopped in parallel */ | ||
5000 | 504 | if (l->state < LI_PAUSED) |
This needs rebasing, security released 2.4.18-0ubuntu1.3