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