Merge ~ahasenack/ubuntu/+source/haproxy:disco-haproxy-1.8.19 into ubuntu/+source/haproxy:ubuntu/devel

Proposed by Andreas Hasenack
Status: Superseded
Proposed branch: ~ahasenack/ubuntu/+source/haproxy:disco-haproxy-1.8.19
Merge into: ubuntu/+source/haproxy:ubuntu/devel
Diff against target: 1551 lines (+501/-163) (has conflicts)
35 files modified
CHANGELOG (+52/-0)
README (+1/-1)
VERDATE (+1/-1)
VERSION (+1/-1)
debian/changelog (+36/-0)
debian/control (+2/-1)
debian/tests/proxy-localhost (+4/-0)
doc/configuration.txt (+57/-43)
examples/haproxy.spec (+7/-1)
include/common/h2.h (+33/-0)
include/common/hpack-tbl.h (+1/-0)
include/common/xref.h (+5/-0)
include/proto/session.h (+2/-1)
include/proto/stream.h (+4/-2)
include/proto/stream_interface.h (+6/-0)
include/types/connection.h (+1/-0)
include/types/stream_interface.h (+19/-17)
scripts/announce-release (+2/-0)
src/action.c (+5/-0)
src/backend.c (+10/-8)
src/cache.c (+6/-2)
src/cfgparse.c (+52/-8)
src/checks.c (+4/-3)
src/flt_spoe.c (+42/-25)
src/haproxy.c (+1/-0)
src/hlua.c (+3/-3)
src/hpack-dec.c (+6/-0)
src/mux_h2.c (+48/-18)
src/proto_http.c (+4/-1)
src/sample.c (+7/-0)
src/server.c (+22/-26)
src/ssl_sock.c (+41/-0)
src/stream.c (+5/-1)
src/stream_interface.c (+8/-0)
src/tcp_rules.c (+3/-0)
Conflict in debian/changelog
Conflict in debian/tests/proxy-localhost
Reviewer Review Type Date Requested Status
Canonical Server Pending
Review via email: mp+363424@code.launchpad.net

Description of the change

Merge from debian. Our single delta still applies, but it was already accepted by debian and should be in an upcoming release (https://salsa.debian.org/haproxy-team/haproxy/merge_requests/3).

I updated the test to use "service" instead of "systemctl" to match what was accepted by debian after my submission.

To post a comment you must log in.

Unmerged commits

9132c04... by Andreas Hasenack

update-maintainer

1044ad9... by Andreas Hasenack

reconstruct-changelog

ebda99b... by Andreas Hasenack

merge-changelogs

e44336d... by Andreas Hasenack

    - d/t/control, d/t/proxy-localhost: simple DEP8 test to actually
      generate traffic through haproxy.
      [Updated to use "service" instead of "systemctl" to match what was
      submitted to Debian.]

bd3810b... by Apollon Oikonomopoulos <email address hidden>

Import patches-unapplied version 1.8.19-1 to debian/sid

Imported using git-ubuntu import.

Changelog parent: 3b885bfb277d04831405e979d38eac423793855c

New changelog entries:
  * New upstream version 1.8.19
    - BUG/MEDIUM: spoe: initialization depending on nbthread must be done last
    - BUG/MEDIUM: server: initialize the idle conns list after parsing the
                  config
    - BUG/MAJOR: spoe: Don't try to get agent config during SPOP healthcheck
    - BUG/MAJOR: stream: avoid double free on unique_id (Closes: #921981)

3b885bf... by Vincent Bernat

Import patches-unapplied version 1.8.18-1 to debian/sid

Imported using git-ubuntu import.

Changelog parent: a1a84313d54570921ed9a0ecd52c2b23ec5e991e

New changelog entries:
  * New upstream version 1.8.18
    - BUG/MAJOR: cache: fix confusion between zero and uninitialized cache
                 key
    - BUG/MAJOR: config: verify that targets of track-sc and stick rules
                 are present
    - BUG/MAJOR: spoe: verify that backends used by SPOE cover all their
                 callers' processes

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/CHANGELOG b/CHANGELOG
2index 6a8554b..d489531 100644
3--- a/CHANGELOG
4+++ b/CHANGELOG
5@@ -1,6 +1,58 @@
6 ChangeLog :
7 ===========
8
9+2019/02/11 : 1.8.19
10+ - DOC: ssl: Clarify when pre TLSv1.3 cipher can be used
11+ - DOC: ssl: Stop documenting ciphers example to use
12+ - BUG/MINOR: spoe: do not assume agent->rt is valid on exit
13+ - BUG/MINOR: lua: initialize the correct idle conn lists for the SSL sockets
14+ - BUG/MEDIUM: spoe: initialization depending on nbthread must be done last
15+ - BUG/MEDIUM: server: initialize the idle conns list after parsing the config
16+ - BUG/MAJOR: spoe: Don't try to get agent config during SPOP healthcheck
17+ - BUG/MAJOR: stream: avoid double free on unique_id
18+ - BUG/MINOR: config: Reinforce validity check when a process number is parsed
19+
20+2019/02/06 : 1.8.18
21+ - DOC: http-request cache-use / http-response cache-store expects cache name
22+ - BUG/MAJOR: cache: fix confusion between zero and uninitialized cache key
23+ - BUG/MEDIUM: ssl: Disable anti-replay protection and set max data with 0RTT.
24+ - DOC: Be a bit more explicit about allow-0rtt security implications.
25+ - BUG/MEDIUM: ssl: missing allocation failure checks loading tls key file
26+ - BUG/MINOR: backend: don't use url_param_name as a hint for BE_LB_ALGO_PH
27+ - BUG/MINOR: backend: balance uri specific options were lost across defaults
28+ - BUG/MINOR: backend: BE_LB_LKUP_CHTREE is a value, not a bit
29+ - BUG/MINOR: stick_table: Prevent conn_cur from underflowing
30+ - BUG/MINOR: server: don't always trust srv_check_health when loading a server state
31+ - BUG/MINOR: check: Wake the check task if the check is finished in wake_srv_chk()
32+ - BUG/MEDIUM: ssl: Fix handling of TLS 1.3 KeyUpdate messages
33+ - DOC: mention the effect of nf_conntrack_tcp_loose on src/dst
34+ - MINOR: h2: add a bit-based frame type representation
35+ - MINOR: h2: declare new sets of frame types
36+ - BUG/MINOR: mux-h2: CONTINUATION in closed state must always return GOAWAY
37+ - BUG/MINOR: mux-h2: headers-type frames in HREM are always a connection error
38+ - BUG/MINOR: mux-h2: make it possible to set the error code on an already closed stream
39+ - BUG/MINOR: hpack: return a compression error on invalid table size updates
40+ - DOC: nbthread is no longer experimental.
41+ - BUG/MINOR: spoe: corrected fragmentation string size
42+ - BUG/MINOR: deinit: tcp_rep.inspect_rules not deinit, add to deinit
43+ - SCRIPTS: add the slack channel URL to the announce script
44+ - SCRIPTS: add the issue tracker URL to the announce script
45+ - BUG/MINOR: stream: don't close the front connection when facing a backend error
46+ - MINOR: xref: Add missing barriers.
47+ - BUG/MEDIUM: mux-h2: wake up flow-controlled streams on initial window update
48+ - BUG/MEDIUM: mux-h2: fix two half-closed to closed transitions
49+ - BUG/MEDIUM: mux-h2: make sure never to send GOAWAY on too old streams
50+ - BUG/MEDIUM: mux-h2: wait for the mux buffer to be empty before closing the connection
51+ - MINOR: stream-int: expand the flags to 32-bit
52+ - MINOR: stream-int: add a new flag to mention that we want the connection to be killed
53+ - MINOR: connstream: have a new flag CS_FL_KILL_CONN to kill a connection
54+ - BUG/MEDIUM: mux-h2: do not close the connection on aborted streams
55+ - BUG/MEDIUM: stream: Don't forget to free s->unique_id in stream_free().
56+ - BUG/MINOR: config: fix bind line thread mask validation
57+ - BUG/MAJOR: config: verify that targets of track-sc and stick rules are present
58+ - BUG/MAJOR: spoe: verify that backends used by SPOE cover all their callers' processes
59+ - BUG/MINOR: config: make sure to count the error on incorrect track-sc/stick rules
60+
61 2019/01/08 : 1.8.17
62 - BUG/MAJOR: stream-int: Update the stream expiration date in stream_int_notify()
63 - MINOR: mux-h2: only increase the connection window with the first update
64diff --git a/README b/README
65index 07e095a..e66b5fd 100644
66--- a/README
67+++ b/README
68@@ -3,7 +3,7 @@
69 ----------------------
70 version 1.8
71 willy tarreau
72- 2019/01/08
73+ 2019/02/11
74
75
76 1) How to build it
77diff --git a/VERDATE b/VERDATE
78index 944f490..ddc7727 100644
79--- a/VERDATE
80+++ b/VERDATE
81@@ -1,2 +1,2 @@
82 $Format:%ci$
83-2019/01/08
84+2019/02/11
85diff --git a/VERSION b/VERSION
86index f49e8ed..c8f955a 100644
87--- a/VERSION
88+++ b/VERSION
89@@ -1 +1 @@
90-1.8.17
91+1.8.19
92diff --git a/debian/changelog b/debian/changelog
93index 3f24b6e..f461719 100644
94--- a/debian/changelog
95+++ b/debian/changelog
96@@ -1,3 +1,39 @@
97+<<<<<<< debian/changelog
98+=======
99+haproxy (1.8.19-1ubuntu1) disco; urgency=medium
100+
101+ * Merge with Debian unstable. Remaining changes:
102+ - d/t/control, d/t/proxy-localhost: simple DEP8 test to actually
103+ generate traffic through haproxy.
104+ [Updated to use "service" instead of "systemctl" to match what was
105+ submitted to Debian.]
106+
107+ -- Andreas Hasenack <andreas@canonical.com> Wed, 20 Feb 2019 14:18:15 +0100
108+
109+haproxy (1.8.19-1) unstable; urgency=medium
110+
111+ * New upstream version 1.8.19
112+ - BUG/MEDIUM: spoe: initialization depending on nbthread must be done last
113+ - BUG/MEDIUM: server: initialize the idle conns list after parsing the
114+ config
115+ - BUG/MAJOR: spoe: Don't try to get agent config during SPOP healthcheck
116+ - BUG/MAJOR: stream: avoid double free on unique_id (Closes: #921981)
117+
118+ -- Apollon Oikonomopoulos <apoikos@debian.org> Tue, 12 Feb 2019 10:30:54 +0200
119+
120+haproxy (1.8.18-1) unstable; urgency=medium
121+
122+ * New upstream version 1.8.18
123+ - BUG/MAJOR: cache: fix confusion between zero and uninitialized cache
124+ key
125+ - BUG/MAJOR: config: verify that targets of track-sc and stick rules
126+ are present
127+ - BUG/MAJOR: spoe: verify that backends used by SPOE cover all their
128+ callers' processes
129+
130+ -- Vincent Bernat <bernat@debian.org> Wed, 06 Feb 2019 18:44:54 +0100
131+
132+>>>>>>> debian/changelog
133 haproxy (1.8.17-1ubuntu1) disco; urgency=medium
134
135 * d/t/control, d/t/proxy-localhost: simple DEP8 test to actually
136diff --git a/debian/control b/debian/control
137index 941d92f..a85b34f 100644
138--- a/debian/control
139+++ b/debian/control
140@@ -1,7 +1,8 @@
141 Source: haproxy
142 Section: net
143 Priority: optional
144-Maintainer: Debian HAProxy Maintainers <haproxy@tracker.debian.org>
145+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
146+XSBC-Original-Maintainer: Debian HAProxy Maintainers <haproxy@tracker.debian.org>
147 Uploaders: Apollon Oikonomopoulos <apoikos@debian.org>,
148 Prach Pongpanich <prach@debian.org>,
149 Vincent Bernat <bernat@debian.org>
150diff --git a/debian/tests/proxy-localhost b/debian/tests/proxy-localhost
151index 2824287..b7762d5 100644
152--- a/debian/tests/proxy-localhost
153+++ b/debian/tests/proxy-localhost
154@@ -33,7 +33,11 @@ backend test-back
155 server test-1 localhost:80
156 EOF
157
158+<<<<<<< debian/tests/proxy-localhost
159 systemctl restart haproxy
160+=======
161+service haproxy restart
162+>>>>>>> debian/tests/proxy-localhost
163
164 # index.html is shipped with apache2
165 # Download it via haproxy and compare
166diff --git a/doc/configuration.txt b/doc/configuration.txt
167index 4f999e2..8d75d56 100644
168--- a/doc/configuration.txt
169+++ b/doc/configuration.txt
170@@ -4,7 +4,7 @@
171 ----------------------
172 version 1.8
173 willy tarreau
174- 2019/01/08
175+ 2019/02/11
176
177
178 This document covers the configuration language as implemented in the version
179@@ -917,14 +917,14 @@ nbproc <number>
180 mode. By default, only one process is created, which is the recommended mode
181 of operation. For systems limited to small sets of file descriptors per
182 process, it may be needed to fork multiple daemons. USING MULTIPLE PROCESSES
183- IS HARDER TO DEBUG AND IS REALLY DISCOURAGED. See also "daemon".
184+ IS HARDER TO DEBUG AND IS REALLY DISCOURAGED. See also "daemon" and
185+ "nbthread".
186
187 nbthread <number>
188 This setting is only available when support for threads was built in. It
189 creates <number> threads for each created processes. It means if HAProxy is
190 started in foreground, it only creates <number> threads for the first
191- process. FOR NOW, THREADS SUPPORT IN HAPROXY IS HIGHLY EXPERIMENTAL AND IT
192- MUST BE ENABLED WITH CAUTION AND AT YOUR OWN RISK. See also "nbproc".
193+ process. See also "nbproc".
194
195 pidfile <pidfile>
196 Writes PIDs of all daemons into file <pidfile>. This option is equivalent to
197@@ -986,12 +986,14 @@ setenv <name> <value>
198 ssl-default-bind-ciphers <ciphers>
199 This setting is only available when support for OpenSSL was built in. It sets
200 the default string describing the list of cipher algorithms ("cipher suite")
201- that are negotiated during the SSL/TLS handshake except for TLSv1.3 for all
202+ that are negotiated during the SSL/TLS handshake up to TLSv1.2 for all
203 "bind" lines which do not explicitly define theirs. The format of the string
204- is defined in "man 1 ciphers" from OpenSSL man pages, and can be for instance
205- a string such as "AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH" (without quotes). For
206- TLSv1.3 cipher configuration, please check the "ssl-default-bind-ciphersuites"
207- keyword. Please check the "bind" keyword for more information.
208+ is defined in "man 1 ciphers" from OpenSSL man pages. For background
209+ information and recommendations see e.g.
210+ (https://wiki.mozilla.org/Security/Server_Side_TLS) and
211+ (https://mozilla.github.io/server-side-tls/ssl-config-generator/). For TLSv1.3
212+ cipher configuration, please check the "ssl-default-bind-ciphersuites" keyword.
213+ Please check the "bind" keyword for more information.
214
215 ssl-default-bind-ciphersuites <ciphersuites>
216 This setting is only available when support for OpenSSL was built in and
217@@ -999,11 +1001,9 @@ ssl-default-bind-ciphersuites <ciphersuites>
218 describing the list of cipher algorithms ("cipher suite") that are negotiated
219 during the TLSv1.3 handshake for all "bind" lines which do not explicitly define
220 theirs. The format of the string is defined in
221- "man 1 ciphers" from OpenSSL man pages under the section "ciphersuites", and can
222- be for instance a string such as
223- "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
224- (without quotes). For cipher configuration for TLSv1.2 and earlier, please check
225- the "ssl-default-bind-ciphers" keyword. Please check the "bind" keyword for more
226+ "man 1 ciphers" from OpenSSL man pages under the section "ciphersuites". For
227+ cipher configuration for TLSv1.2 and earlier, please check the
228+ "ssl-default-bind-ciphers" keyword. Please check the "bind" keyword for more
229 information.
230
231 ssl-default-bind-options [<option>]...
232@@ -1018,11 +1018,15 @@ ssl-default-bind-options [<option>]...
233 ssl-default-server-ciphers <ciphers>
234 This setting is only available when support for OpenSSL was built in. It
235 sets the default string describing the list of cipher algorithms that are
236- negotiated during the SSL/TLS handshake except for TLSv1.3 with the server,
237+ negotiated during the SSL/TLS handshake up to TLSv1.2 with the server,
238 for all "server" lines which do not explicitly define theirs. The format of
239- the string is defined in "man 1 ciphers". For TLSv1.3 cipher configuration,
240- please check the "ssl-default-server-ciphersuites" keyword. Please check the
241- "server" keyword for more information.
242+ the string is defined in "man 1 ciphers" from OpenSSL man pages. For background
243+ information and recommendations see e.g.
244+ (https://wiki.mozilla.org/Security/Server_Side_TLS) and
245+ (https://mozilla.github.io/server-side-tls/ssl-config-generator/).
246+ For TLSv1.3 cipher configuration, please check the
247+ "ssl-default-server-ciphersuites" keyword. Please check the "server" keyword
248+ for more information.
249
250 ssl-default-server-ciphersuites <ciphersuites>
251 This setting is only available when support for OpenSSL was built in and
252@@ -1030,9 +1034,10 @@ ssl-default-server-ciphersuites <ciphersuites>
253 string describing the list of cipher algorithms that are negotiated during
254 the TLSv1.3 handshake with the server, for all "server" lines which do not
255 explicitly define theirs. The format of the string is defined in
256- "man 1 ciphers" under the "ciphersuites" section. For cipher configuration for
257- TLSv1.2 and earlier, please check the "ssl-default-server-ciphers" keyword.
258- Please check the "server" keyword for more information.
259+ "man 1 ciphers" from OpenSSL man pages under the section "ciphersuites". For
260+ cipher configuration for TLSv1.2 and earlier, please check the
261+ "ssl-default-server-ciphers" keyword. Please check the "server" keyword for
262+ more information.
263
264 ssl-default-server-options [<option>]...
265 This setting is only available when support for OpenSSL was built in. It sets
266@@ -10483,7 +10488,10 @@ accept-proxy
267
268 allow-0rtt
269 Allow receiving early data when using TLSv1.3. This is disabled by default,
270- due to security considerations.
271+ due to security considerations. Because it is vulnerable to replay attacks,
272+ you should only allow if for requests that are safe to replay, ie requests
273+ that are idempotent. You can use the "wait-for-handshake" action for any
274+ request that wouldn't be safe with early data.
275
276 alpn <protocols>
277 This enables the TLS ALPN extension and advertises the specified protocol
278@@ -10545,11 +10553,8 @@ ca-sign-pass <passphrase>
279 ciphers <ciphers>
280 This setting is only available when support for OpenSSL was built in. It sets
281 the string describing the list of cipher algorithms ("cipher suite") that are
282- negotiated during the SSL/TLS handshake except for TLSv1.3. The format of the
283- string is defined in "man 1 ciphers" from OpenSSL man pages, and can be for
284- instance a string such as "AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH" (without
285- quotes). Depending on the compatibility and security requirements, the list
286- of suitable ciphers depends on a variety of variables. For background
287+ negotiated during the SSL/TLS handshake up to TLSv1.2. The format of the
288+ string is defined in "man 1 ciphers" from OpenSSL man pages. For background
289 information and recommendations see e.g.
290 (https://wiki.mozilla.org/Security/Server_Side_TLS) and
291 (https://mozilla.github.io/server-side-tls/ssl-config-generator/). For TLSv1.3
292@@ -10560,11 +10565,8 @@ ciphersuites <ciphersuites>
293 OpenSSL 1.1.1 or later was used to build HAProxy. It sets the string describing
294 the list of cipher algorithms ("cipher suite") that are negotiated during the
295 TLSv1.3 handshake. The format of the string is defined in "man 1 ciphers" from
296- OpenSSL man pages under the "ciphersuites" section, and can be for instance a
297- string such as
298- "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
299- (without quotes). For cipher configuration for TLSv1.2 and earlier, please check
300- the "ciphers" keyword.
301+ OpenSSL man pages under the "ciphersuites" section. For cipher configuration
302+ for TLSv1.2 and earlier, please check the "ciphers" keyword.
303
304 crl-file <crlfile>
305 This setting is only available when support for OpenSSL was built in. It
306@@ -11278,19 +11280,20 @@ ciphers <ciphers>
307 This setting is only available when support for OpenSSL was built in. This
308 option sets the string describing the list of cipher algorithms that is
309 negotiated during the SSL/TLS handshake with the server. The format of the
310- string is defined in "man 1 ciphers". When SSL is used to communicate with
311- servers on the local network, it is common to see a weaker set of algorithms
312- than what is used over the internet. Doing so reduces CPU usage on both the
313- server and haproxy while still keeping it compatible with deployed software.
314- Some algorithms such as RC4-SHA1 are reasonably cheap. If no security at all
315- is needed and just connectivity, using DES can be appropriate.
316+ string is defined in "man 1 ciphers" from OpenSSL man pages. For background
317+ information and recommendations see e.g.
318+ (https://wiki.mozilla.org/Security/Server_Side_TLS) and
319+ (https://mozilla.github.io/server-side-tls/ssl-config-generator/). For TLSv1.3
320+ cipher configuration, please check the "ciphersuites" keyword.
321
322 ciphersuites <ciphersuites>
323 This setting is only available when support for OpenSSL was built in and
324 OpenSSL 1.1.1 or later was used to build HAProxy. This option sets the string
325 describing the list of cipher algorithms that is negotiated during the TLS
326 1.3 handshake with the server. The format of the string is defined in
327- "man 1 ciphers" under the "ciphersuites" section.
328+ "man 1 ciphers" from OpenSSL man pages under the "ciphersuites" section.
329+ For cipher configuration for TLSv1.2 and earlier, please check the "ciphers"
330+ keyword.
331
332 cookie <value>
333 The "cookie" parameter sets the cookie value assigned to the server to
334@@ -13819,7 +13822,12 @@ dst : ip
335 which is the address the client connected to. It can be useful when running
336 in transparent mode. It is of type IP and works on both IPv4 and IPv6 tables.
337 On IPv6 tables, IPv4 address is mapped to its IPv6 equivalent, according to
338- RFC 4291.
339+ RFC 4291. When the incoming connection passed through address translation or
340+ redirection involving connection tracking, the original destination address
341+ before the redirection will be reported. On Linux systems, the source and
342+ destination may seldom appear reversed if the nf_conntrack_tcp_loose sysctl
343+ is set, because a late response may reopen a timed out connection and switch
344+ what is believed to be the source and the destination.
345
346 dst_conn : integer
347 Returns an integer value corresponding to the number of currently established
348@@ -14124,7 +14132,13 @@ src : ip
349 behind a proxy. However if the "accept-proxy" or "accept-netscaler-cip" bind
350 directive is used, it can be the address of a client behind another
351 PROXY-protocol compatible component for all rule sets except
352- "tcp-request connection" which sees the real address.
353+ "tcp-request connection" which sees the real address. When the incoming
354+ connection passed through address translation or redirection involving
355+ connection tracking, the original destination address before the redirection
356+ will be reported. On Linux systems, the source and destination may seldom
357+ appear reversed if the nf_conntrack_tcp_loose sysctl is set, because a late
358+ response may reopen a timed out connection and switch what is believed to be
359+ the source and the destination.
360
361 Example:
362 # add an HTTP header in requests with the originating address' country
363@@ -17157,13 +17171,13 @@ max-age <seconds>
364 10.2.2. Proxy section
365 ---------------------
366
367-http-request cache-use <name>
368+http-request cache-use <name> [ { if | unless } <condition> ]
369 Try to deliver a cached object from the cache <name>. This directive is also
370 mandatory to store the cache as it calculates the cache hash. If you want to
371 use a condition for both storage and delivering that's a good idea to put it
372 after this one.
373
374-http-response cache-store <name>
375+http-response cache-store <name> [ { if | unless } <condition> ]
376 Store an http-response within the cache. The storage of the response headers
377 is done at this step, which means you can use others http-response actions
378 to modify headers before or after the storage of the response. This action
379diff --git a/examples/haproxy.spec b/examples/haproxy.spec
380index 15f0850..aaa83c8 100644
381--- a/examples/haproxy.spec
382+++ b/examples/haproxy.spec
383@@ -1,6 +1,6 @@
384 Summary: HA-Proxy is a TCP/HTTP reverse proxy for high availability environments
385 Name: haproxy
386-Version: 1.8.17
387+Version: 1.8.19
388 Release: 1
389 License: GPL
390 Group: System Environment/Daemons
391@@ -74,6 +74,12 @@ fi
392 %attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
393
394 %changelog
395+* Mon Feb 11 2019 Willy Tarreau <w@1wt.eu>
396+- updated to 1.8.19
397+
398+* Wed Feb 6 2019 Willy Tarreau <w@1wt.eu>
399+- updated to 1.8.18
400+
401 * Tue Jan 8 2019 Willy Tarreau <w@1wt.eu>
402 - updated to 1.8.17
403
404diff --git a/include/common/h2.h b/include/common/h2.h
405index 576ed10..dec1763 100644
406--- a/include/common/h2.h
407+++ b/include/common/h2.h
408@@ -81,6 +81,30 @@ enum h2_ft {
409 H2_FT_ENTRIES /* must be last */
410 } __attribute__((packed));
411
412+/* frame types, turned to bits or bit fields */
413+enum {
414+ /* one bit per frame type */
415+ H2_FT_DATA_BIT = 1U << H2_FT_DATA,
416+ H2_FT_HEADERS_BIT = 1U << H2_FT_HEADERS,
417+ H2_FT_PRIORITY_BIT = 1U << H2_FT_PRIORITY,
418+ H2_FT_RST_STREAM_BIT = 1U << H2_FT_RST_STREAM,
419+ H2_FT_SETTINGS_BIT = 1U << H2_FT_SETTINGS,
420+ H2_FT_PUSH_PROMISE_BIT = 1U << H2_FT_PUSH_PROMISE,
421+ H2_FT_PING_BIT = 1U << H2_FT_PING,
422+ H2_FT_GOAWAY_BIT = 1U << H2_FT_GOAWAY,
423+ H2_FT_WINDOW_UPDATE_BIT = 1U << H2_FT_WINDOW_UPDATE,
424+ H2_FT_CONTINUATION_BIT = 1U << H2_FT_CONTINUATION,
425+ /* padded frames */
426+ H2_FT_PADDED_MASK = H2_FT_DATA_BIT | H2_FT_HEADERS_BIT | H2_FT_PUSH_PROMISE_BIT,
427+ /* flow controlled frames */
428+ H2_FT_FC_MASK = H2_FT_DATA_BIT,
429+ /* header frames */
430+ H2_FT_HDR_MASK = H2_FT_HEADERS_BIT | H2_FT_PUSH_PROMISE_BIT | H2_FT_CONTINUATION_BIT,
431+ /* frames allowed to arrive late on a stream */
432+ H2_FT_LATE_MASK = H2_FT_WINDOW_UPDATE_BIT | H2_FT_RST_STREAM_BIT | H2_FT_PRIORITY_BIT,
433+};
434+
435+
436 /* flags defined for each frame type */
437
438 // RFC7540 #6.1
439@@ -109,6 +133,9 @@ enum h2_ft {
440 // RFC7540 #6.8 : GOAWAY defines no flags
441 // RFC7540 #6.9 : WINDOW_UPDATE defines no flags
442
443+// PADDED is the exact same among DATA, HEADERS and PUSH_PROMISE (8)
444+#define H2_F_PADDED 0x08
445+
446 /* HTTP/2 error codes - RFC7540 #7 */
447 enum h2_err {
448 H2_ERR_NO_ERROR = 0x0,
449@@ -159,6 +186,12 @@ int h2_make_h1_request(struct http_hdr *list, char *out, int osize, unsigned int
450 * Some helpful debugging functions.
451 */
452
453+/* returns a bit corresponding to the frame type */
454+static inline unsigned int h2_ft_bit(enum h2_ft ft)
455+{
456+ return 1U << ft;
457+}
458+
459 /* returns the frame type as a string */
460 static inline const char *h2_ft_str(int type)
461 {
462diff --git a/include/common/hpack-tbl.h b/include/common/hpack-tbl.h
463index 385f386..2cbc2bf 100644
464--- a/include/common/hpack-tbl.h
465+++ b/include/common/hpack-tbl.h
466@@ -127,6 +127,7 @@ enum {
467 HPACK_ERR_MISSING_AUTHORITY, /* :authority is missing with CONNECT */
468 HPACK_ERR_SCHEME_NOT_ALLOWED, /* :scheme not allowed with CONNECT */
469 HPACK_ERR_PATH_NOT_ALLOWED, /* :path not allowed with CONNECT */
470+ HPACK_ERR_INVALID_ARGUMENT, /* an invalid argument was passed */
471 };
472
473 /* static header table as in RFC7541 Appendix A. [0] unused. */
474diff --git a/include/common/xref.h b/include/common/xref.h
475index 6dfa7b6..a6291f5 100644
476--- a/include/common/xref.h
477+++ b/include/common/xref.h
478@@ -32,6 +32,7 @@ static inline struct xref *xref_get_peer_and_lock(struct xref *xref)
479
480 /* Get the local pointer to the peer. */
481 local = HA_ATOMIC_XCHG(&xref->peer, XREF_BUSY);
482+ __ha_barrier_store();
483
484 /* If the local pointer is NULL, the peer no longer exists. */
485 if (local == NULL) {
486@@ -53,6 +54,7 @@ static inline struct xref *xref_get_peer_and_lock(struct xref *xref)
487 /* The remote lock is BUSY, We retry the process. */
488 if (remote == XREF_BUSY) {
489 xref->peer = local;
490+ __ha_barrier_store();
491 continue;
492 }
493
494@@ -66,6 +68,8 @@ static inline void xref_unlock(struct xref *xref, struct xref *peer)
495 /* Release the peer. */
496 peer->peer = xref;
497
498+ __ha_barrier_store();
499+
500 /* Release myself. */
501 xref->peer = peer;
502 }
503@@ -73,6 +77,7 @@ static inline void xref_unlock(struct xref *xref, struct xref *peer)
504 static inline void xref_disconnect(struct xref *xref, struct xref *peer)
505 {
506 peer->peer = NULL;
507+ __ha_barrier_store();
508 xref->peer = NULL;
509 }
510
511diff --git a/include/proto/session.h b/include/proto/session.h
512index f48c0d4..7265f5a 100644
513--- a/include/proto/session.h
514+++ b/include/proto/session.h
515@@ -59,7 +59,8 @@ static inline void session_store_counters(struct session *sess)
516 if (ptr) {
517 HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
518
519- stktable_data_cast(ptr, conn_cur)--;
520+ if (stktable_data_cast(ptr, conn_cur) > 0)
521+ stktable_data_cast(ptr, conn_cur)--;
522
523 HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
524
525diff --git a/include/proto/stream.h b/include/proto/stream.h
526index 8521957..c9bcac3 100644
527--- a/include/proto/stream.h
528+++ b/include/proto/stream.h
529@@ -104,7 +104,8 @@ static inline void stream_store_counters(struct stream *s)
530 if (ptr) {
531 HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
532
533- stktable_data_cast(ptr, conn_cur)--;
534+ if (stktable_data_cast(ptr, conn_cur) > 0)
535+ stktable_data_cast(ptr, conn_cur)--;
536
537 HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
538
539@@ -142,7 +143,8 @@ static inline void stream_stop_content_counters(struct stream *s)
540 if (ptr) {
541 HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
542
543- stktable_data_cast(ptr, conn_cur)--;
544+ if (stktable_data_cast(ptr, conn_cur) > 0)
545+ stktable_data_cast(ptr, conn_cur)--;
546
547 HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
548
549diff --git a/include/proto/stream_interface.h b/include/proto/stream_interface.h
550index ee1fa12..9db7920 100644
551--- a/include/proto/stream_interface.h
552+++ b/include/proto/stream_interface.h
553@@ -320,6 +320,12 @@ static inline void si_shutw(struct stream_interface *si)
554 si->ops->shutw(si);
555 }
556
557+/* Marks on the stream-interface that next shutw must kill the whole connection */
558+static inline void si_must_kill_conn(struct stream_interface *si)
559+{
560+ si->flags |= SI_FL_KILL_CONN;
561+}
562+
563 /* Updates the stream interface and timers, then updates the data layer below */
564 static inline void si_update(struct stream_interface *si)
565 {
566diff --git a/include/types/connection.h b/include/types/connection.h
567index b9e4604..c1d1b35 100644
568--- a/include/types/connection.h
569+++ b/include/types/connection.h
570@@ -70,6 +70,7 @@ enum {
571 CS_FL_ERROR = 0x00000100, /* a fatal error was reported */
572 CS_FL_RCV_MORE = 0x00000200, /* more bytes to receive but not enough room */
573 CS_FL_EOS = 0x00001000, /* End of stream */
574+ CS_FL_KILL_CONN = 0x00002000, /* must kill the connection when the CS closes */
575 };
576
577 /* cs_shutr() modes */
578diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h
579index 0c83759..c805685 100644
580--- a/include/types/stream_interface.h
581+++ b/include/types/stream_interface.h
582@@ -59,22 +59,23 @@ enum {
583 SI_ET_DATA_ABRT = 0x0400, /* data phase aborted by external cause */
584 };
585
586-/* flags set after I/O (16 bit) */
587+/* flags set after I/O (32 bit) */
588 enum {
589- SI_FL_NONE = 0x0000, /* nothing */
590- SI_FL_EXP = 0x0001, /* timeout has expired */
591- SI_FL_ERR = 0x0002, /* a non-recoverable error has occurred */
592- SI_FL_WAIT_ROOM = 0x0004, /* waiting for space to store incoming data */
593- SI_FL_WAIT_DATA = 0x0008, /* waiting for more data to send */
594- SI_FL_ISBACK = 0x0010, /* 0 for front-side SI, 1 for back-side */
595- SI_FL_DONT_WAKE = 0x0020, /* resync in progress, don't wake up */
596- SI_FL_INDEP_STR = 0x0040, /* independent streams = don't update rex on write */
597- SI_FL_NOLINGER = 0x0080, /* may close without lingering. One-shot. */
598- SI_FL_NOHALF = 0x0100, /* no half close, close both sides at once */
599- SI_FL_SRC_ADDR = 0x1000, /* get the source ip/port with getsockname */
600- SI_FL_WANT_PUT = 0x2000, /* an applet would like to put some data into the buffer */
601- SI_FL_WANT_GET = 0x4000, /* an applet would like to get some data from the buffer */
602- SI_FL_CLEAN_ABRT = 0x8000, /* SI_FL_ERR is used to report aborts, and not SHUTR */
603+ SI_FL_NONE = 0x00000000, /* nothing */
604+ SI_FL_EXP = 0x00000001, /* timeout has expired */
605+ SI_FL_ERR = 0x00000002, /* a non-recoverable error has occurred */
606+ SI_FL_WAIT_ROOM = 0x00000004, /* waiting for space to store incoming data */
607+ SI_FL_WAIT_DATA = 0x00000008, /* waiting for more data to send */
608+ SI_FL_ISBACK = 0x00000010, /* 0 for front-side SI, 1 for back-side */
609+ SI_FL_DONT_WAKE = 0x00000020, /* resync in progress, don't wake up */
610+ SI_FL_INDEP_STR = 0x00000040, /* independent streams = don't update rex on write */
611+ SI_FL_NOLINGER = 0x00000080, /* may close without lingering. One-shot. */
612+ SI_FL_NOHALF = 0x00000100, /* no half close, close both sides at once */
613+ SI_FL_SRC_ADDR = 0x00001000, /* get the source ip/port with getsockname */
614+ SI_FL_WANT_PUT = 0x00002000, /* an applet would like to put some data into the buffer */
615+ SI_FL_WANT_GET = 0x00004000, /* an applet would like to get some data from the buffer */
616+ SI_FL_CLEAN_ABRT = 0x00008000, /* SI_FL_ERR is used to report aborts, and not SHUTR */
617+ SI_FL_KILL_CONN = 0x00010000, /* next shutw must kill the whole conn, not just the stream */
618 };
619
620 /* A stream interface has 3 parts :
621@@ -92,10 +93,11 @@ struct stream_interface {
622 /* struct members used by the "buffer" side */
623 enum si_state state; /* SI_ST* */
624 enum si_state prev_state;/* SI_ST*, copy of previous state */
625- unsigned short flags; /* SI_FL_* */
626- unsigned int exp; /* wake up time for connect, queue, turn-around, ... */
627+ /* 16-bit hole here */
628+ unsigned int flags; /* SI_FL_* */
629 enum obj_type *end; /* points to the end point (connection or appctx) */
630 struct si_ops *ops; /* general operations at the stream interface layer */
631+ unsigned int exp; /* wake up time for connect, queue, turn-around, ... */
632
633 /* struct members below are the "remote" part, as seen from the buffer side */
634 unsigned int err_type; /* first error detected, one of SI_ET_* */
635diff --git a/scripts/announce-release b/scripts/announce-release
636index c4045ae..972d6ea 100755
637--- a/scripts/announce-release
638+++ b/scripts/announce-release
639@@ -155,6 +155,8 @@ fi
640 (echo "Please find the usual URLs below :"
641 echo " Site index : http://www.haproxy.org/"
642 echo " Discourse : http://discourse.haproxy.org/"
643+ echo " Slack channel : https://slack.haproxy.org/"
644+ echo " Issue tracker : https://github.com/haproxy/haproxy/issues"
645 echo " Sources : http://www.haproxy.org/download/${BRANCH}/src/"
646 echo " Git repository : http://git.haproxy.org/git/${gitdir}/"
647 echo " Git Web browsing : http://git.haproxy.org/?p=${gitdir}"
648diff --git a/src/action.c b/src/action.c
649index 54d27a0..7574fba 100644
650--- a/src/action.c
651+++ b/src/action.c
652@@ -51,6 +51,11 @@ int check_trk_action(struct act_rule *rule, struct proxy *px, char **err)
653 trk_idx(rule->action));
654 return 0;
655 }
656+ else if (px->bind_proc & ~target->bind_proc) {
657+ memprintf(err, "stick-table '%s' referenced by 'track-sc%d' rule not present on all processes covered by proxy '%s'",
658+ target->id, trk_idx(rule->action), px->id);
659+ return 0;
660+ }
661 else {
662 free(rule->arg.trk_ctr.table.n);
663 rule->arg.trk_ctr.table.t = &target->table;
664diff --git a/src/backend.c b/src/backend.c
665index 87327f1..0cf14cf 100644
666--- a/src/backend.c
667+++ b/src/backend.c
668@@ -183,7 +183,7 @@ static struct server *get_server_sh(struct proxy *px, const char *addr, int len,
669 if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
670 h = full_hash(h);
671 hash_done:
672- if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
673+ if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
674 return chash_get_server_hash(px, h, avoid);
675 else
676 return map_get_server_hash(px, h);
677@@ -236,7 +236,7 @@ static struct server *get_server_uh(struct proxy *px, char *uri, int uri_len, co
678 if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
679 hash = full_hash(hash);
680 hash_done:
681- if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
682+ if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
683 return chash_get_server_hash(px, hash, avoid);
684 else
685 return map_get_server_hash(px, hash);
686@@ -293,7 +293,7 @@ static struct server *get_server_ph(struct proxy *px, const char *uri, int uri_l
687 if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
688 hash = full_hash(hash);
689
690- if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
691+ if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
692 return chash_get_server_hash(px, hash, avoid);
693 else
694 return map_get_server_hash(px, hash);
695@@ -367,7 +367,7 @@ static struct server *get_server_ph_post(struct stream *s, const struct server *
696 if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
697 hash = full_hash(hash);
698
699- if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
700+ if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
701 return chash_get_server_hash(px, hash, avoid);
702 else
703 return map_get_server_hash(px, hash);
704@@ -463,7 +463,7 @@ static struct server *get_server_hh(struct stream *s, const struct server *avoid
705 if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
706 hash = full_hash(hash);
707 hash_done:
708- if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
709+ if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
710 return chash_get_server_hash(px, hash, avoid);
711 else
712 return map_get_server_hash(px, hash);
713@@ -507,7 +507,7 @@ static struct server *get_server_rch(struct stream *s, const struct server *avoi
714 if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
715 hash = full_hash(hash);
716 hash_done:
717- if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
718+ if ((px->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
719 return chash_get_server_hash(px, hash, avoid);
720 else
721 return map_get_server_hash(px, hash);
722@@ -615,7 +615,7 @@ int assign_server(struct stream *s)
723 case BE_LB_LKUP_CHTREE:
724 case BE_LB_LKUP_MAP:
725 if ((s->be->lbprm.algo & BE_LB_KIND) == BE_LB_KIND_RR) {
726- if (s->be->lbprm.algo & BE_LB_LKUP_CHTREE)
727+ if ((s->be->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
728 srv = chash_get_next_server(s->be, prev_srv);
729 else
730 srv = map_get_server_rr(s->be, prev_srv);
731@@ -691,7 +691,7 @@ int assign_server(struct stream *s)
732 * back to round robin on the map.
733 */
734 if (!srv) {
735- if (s->be->lbprm.algo & BE_LB_LKUP_CHTREE)
736+ if ((s->be->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_CHTREE)
737 srv = chash_get_next_server(s->be, prev_srv);
738 else
739 srv = map_get_server_rr(s->be, prev_srv);
740@@ -1516,6 +1516,8 @@ int backend_parse_balance(const char **args, char **err, struct proxy *curproxy)
741 curproxy->lbprm.algo |= BE_LB_ALGO_UH;
742
743 curproxy->uri_whole = 0;
744+ curproxy->uri_len_limit = 0;
745+ curproxy->uri_dirs_depth1 = 0;
746
747 while (*args[arg]) {
748 if (!strcmp(args[arg], "len")) {
749diff --git a/src/cache.c b/src/cache.c
750index 667cede..3d8ed24 100644
751--- a/src/cache.c
752+++ b/src/cache.c
753@@ -400,7 +400,7 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px,
754 struct cache *cache = (struct cache *)rule->arg.act.p[0];
755 struct shared_context *shctx = shctx_ptr(cache);
756 struct cache_entry *object;
757-
758+ unsigned int key = *(unsigned int *)txn->cache_hash;
759
760 /* Don't cache if the response came from a cache */
761 if ((obj_type(s->target) == OBJ_TYPE_APPLET) &&
762@@ -420,6 +420,10 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px,
763 if (txn->meth != HTTP_METH_GET)
764 goto out;
765
766+ /* cache key was not computed */
767+ if (!key)
768+ goto out;
769+
770 /* cache only 200 status code */
771 if (txn->status != 200)
772 goto out;
773@@ -478,7 +482,7 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px,
774
775 cache_ctx->first_block = first;
776
777- object->eb.key = (*(unsigned int *)&txn->cache_hash);
778+ object->eb.key = key;
779 memcpy(object->hash, txn->cache_hash, sizeof(object->hash));
780 /* Insert the node later on caching success */
781
782diff --git a/src/cfgparse.c b/src/cfgparse.c
783index 94f2963..c178538 100644
784--- a/src/cfgparse.c
785+++ b/src/cfgparse.c
786@@ -613,16 +613,20 @@ int parse_process_number(const char *arg, unsigned long *proc, int *autoinc, cha
787 else if (strcmp(arg, "even") == 0)
788 *proc |= (~0UL/3UL) << 1; /* 0xAAA...AAA */
789 else {
790- char *dash;
791+ const char *p, *dash = NULL;
792 unsigned int low, high;
793
794- if (!isdigit((int)*arg)) {
795- memprintf(err, "'%s' is not a valid number.\n", arg);
796- return -1;
797+ for (p = arg; *p; p++) {
798+ if (*p == '-' && !dash)
799+ dash = p;
800+ else if (!isdigit((int)*p)) {
801+ memprintf(err, "'%s' is not a valid number/range.", arg);
802+ return -1;
803+ }
804 }
805
806 low = high = str2uic(arg);
807- if ((dash = strchr(arg, '-')) != NULL)
808+ if (dash)
809 high = ((!*(dash+1)) ? LONGBITS : str2uic(dash + 1));
810
811 if (high < low) {
812@@ -2844,7 +2848,10 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
813
814 if (defproxy.url_param_name)
815 curproxy->url_param_name = strdup(defproxy.url_param_name);
816- curproxy->url_param_len = defproxy.url_param_len;
817+ curproxy->url_param_len = defproxy.url_param_len;
818+ curproxy->uri_whole = defproxy.uri_whole;
819+ curproxy->uri_len_limit = defproxy.uri_len_limit;
820+ curproxy->uri_dirs_depth1 = defproxy.uri_dirs_depth1;
821
822 if (defproxy.hh_name)
823 curproxy->hh_name = strdup(defproxy.hh_name);
824@@ -7648,9 +7655,9 @@ int check_config_validity()
825 /* detect and address thread affinity inconsistencies */
826 nbproc = 0;
827 if (bind_conf->bind_proc)
828- nbproc = my_ffsl(bind_conf->bind_proc);
829+ nbproc = my_ffsl(bind_conf->bind_proc) - 1;
830
831- mask = bind_conf->bind_thread[nbproc - 1];
832+ mask = bind_conf->bind_thread[nbproc];
833 if (mask && !(mask & all_threads_mask)) {
834 unsigned long new_mask = 0;
835
836@@ -7996,6 +8003,11 @@ int check_config_validity()
837 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
838 cfgerr++;
839 }
840+ else if (curproxy->bind_proc & ~target->bind_proc) {
841+ ha_alert("Proxy '%s': stick-table '%s' referenced 'stick-store' rule not present on all processes covered by proxy '%s'.\n",
842+ curproxy->id, target->id, curproxy->id);
843+ cfgerr++;
844+ }
845 else {
846 free((void *)mrule->table.name);
847 mrule->table.t = &(target->table);
848@@ -8029,6 +8041,11 @@ int check_config_validity()
849 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
850 cfgerr++;
851 }
852+ else if (curproxy->bind_proc & ~target->bind_proc) {
853+ ha_alert("Proxy '%s': stick-table '%s' referenced 'stick-store' rule not present on all processes covered by proxy '%s'.\n",
854+ curproxy->id, target->id, curproxy->id);
855+ cfgerr++;
856+ }
857 else {
858 free((void *)mrule->table.name);
859 mrule->table.t = &(target->table);
860@@ -8829,6 +8846,33 @@ out_uri_auth_compat:
861 }
862 }
863 }
864+
865+ /* initialize idle conns lists */
866+ for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
867+ int i;
868+
869+ newsrv->priv_conns = calloc(global.nbthread, sizeof(*newsrv->priv_conns));
870+ newsrv->idle_conns = calloc(global.nbthread, sizeof(*newsrv->idle_conns));
871+ newsrv->safe_conns = calloc(global.nbthread, sizeof(*newsrv->safe_conns));
872+
873+ if (!newsrv->priv_conns || !newsrv->idle_conns || !newsrv->safe_conns) {
874+ free(newsrv->safe_conns); newsrv->safe_conns = NULL;
875+ free(newsrv->idle_conns); newsrv->idle_conns = NULL;
876+ free(newsrv->priv_conns); newsrv->priv_conns = NULL;
877+ ha_alert("parsing [%s:%d] : failed to allocate idle connections for server '%s'.\n",
878+ newsrv->conf.file, newsrv->conf.line, newsrv->id);
879+ cfgerr++;
880+ continue;
881+ }
882+
883+ for (i = 0; i < global.nbthread; i++) {
884+ LIST_INIT(&newsrv->priv_conns[i]);
885+ LIST_INIT(&newsrv->idle_conns[i]);
886+ LIST_INIT(&newsrv->safe_conns[i]);
887+ }
888+
889+ LIST_INIT(&newsrv->update_status);
890+ }
891 }
892
893 /***********************************************************/
894diff --git a/src/checks.c b/src/checks.c
895index 74958b2..e04f114 100644
896--- a/src/checks.c
897+++ b/src/checks.c
898@@ -1403,12 +1403,13 @@ static int wake_srv_chk(struct conn_stream *cs)
899 }
900
901 if (check->result != CHK_RES_UNKNOWN) {
902- /* We're here because nobody wants to handle the error, so we
903- * sure want to abort the hard way.
904- */
905+ /* Check complete or aborted. If connection not yet closed do it
906+ * now and wake the check task up to be sure the result is
907+ * handled ASAP. */
908 conn_sock_drain(conn);
909 cs_close(cs);
910 ret = -1;
911+ task_wakeup(check->task, TASK_WOKEN_IO);
912 }
913
914 HA_SPIN_UNLOCK(SERVER_LOCK, &check->server->lock);
915diff --git a/src/flt_spoe.c b/src/flt_spoe.c
916index 4009c2a..e445388 100644
917--- a/src/flt_spoe.c
918+++ b/src/flt_spoe.c
919@@ -170,8 +170,10 @@ spoe_release_agent(struct spoe_agent *agent)
920 LIST_DEL(&grp->list);
921 spoe_release_group(grp);
922 }
923- for (i = 0; i < global.nbthread; ++i)
924- HA_SPIN_DESTROY(&agent->rt[i].lock);
925+ if (agent->rt) {
926+ for (i = 0; i < global.nbthread; ++i)
927+ HA_SPIN_DESTROY(&agent->rt[i].lock);
928+ }
929 free(agent->rt);
930 free(agent);
931 }
932@@ -444,7 +446,7 @@ spoe_prepare_hahello_frame(struct appctx *appctx, char *frame, size_t size)
933 if (agent != NULL && (agent->flags & SPOE_FL_RCV_FRAGMENTATION)) {
934 if (chk->len) chk->str[chk->len++] = ',';
935 memcpy(chk->str+chk->len, "fragmentation", 13);
936- chk->len += 5;
937+ chk->len += 13;
938 }
939 if (spoe_encode_buffer(chk->str, chk->len, &p, end) == -1)
940 goto too_big;
941@@ -817,10 +819,14 @@ spoe_handle_agenthello_frame(struct appctx *appctx, char *frame, size_t size)
942 SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_NO_FRAME_SIZE;
943 return -1;
944 }
945- if ((flags & SPOE_APPCTX_FL_PIPELINING) && !(agent->flags & SPOE_FL_PIPELINING))
946- flags &= ~SPOE_APPCTX_FL_PIPELINING;
947- if ((flags & SPOE_APPCTX_FL_ASYNC) && !(agent->flags & SPOE_FL_ASYNC))
948- flags &= ~SPOE_APPCTX_FL_ASYNC;
949+ if (!agent)
950+ flags &= ~(SPOE_APPCTX_FL_PIPELINING|SPOE_APPCTX_FL_ASYNC);
951+ else {
952+ if ((flags & SPOE_APPCTX_FL_PIPELINING) && !(agent->flags & SPOE_FL_PIPELINING))
953+ flags &= ~SPOE_APPCTX_FL_PIPELINING;
954+ if ((flags & SPOE_APPCTX_FL_ASYNC) && !(agent->flags & SPOE_FL_ASYNC))
955+ flags &= ~SPOE_APPCTX_FL_ASYNC;
956+ }
957
958 SPOE_APPCTX(appctx)->version = (unsigned int)vsn;
959 SPOE_APPCTX(appctx)->max_frame_size = (unsigned int)max_frame_size;
960@@ -2881,6 +2887,7 @@ spoe_check(struct proxy *px, struct flt_conf *fconf)
961 struct flt_conf *f;
962 struct spoe_config *conf = fconf->conf;
963 struct proxy *target;
964+ int i;
965
966 /* Check all SPOE filters for proxy <px> to be sure all SPOE agent names
967 * are uniq */
968@@ -2918,6 +2925,34 @@ spoe_check(struct proxy *px, struct flt_conf *fconf)
969 return 1;
970 }
971
972+ if (px->bind_proc & ~target->bind_proc) {
973+ ha_alert("Proxy %s : backend '%s' used by SPOE agent '%s' declared"
974+ " at %s:%d does not cover all of its processes.\n",
975+ px->id, target->id, conf->agent->id,
976+ conf->agent->conf.file, conf->agent->conf.line);
977+ return 1;
978+ }
979+
980+ /* finish per-thread agent initialization */
981+ if (global.nbthread == 1)
982+ conf->agent->flags |= SPOE_FL_ASYNC;
983+
984+ if ((curagent->rt = calloc(global.nbthread, sizeof(*curagent->rt))) == NULL) {
985+ ha_alert("Proxy %s : out of memory initializing SPOE agent '%s' declared at %s:%d.\n",
986+ px->id, conf->agent->id, conf->agent->conf.file, conf->agent->conf.line);
987+ return 1;
988+ }
989+ for (i = 0; i < global.nbthread; ++i) {
990+ curagent->rt[i].frame_size = curagent->max_frame_size;
991+ curagent->rt[i].applets_act = 0;
992+ curagent->rt[i].applets_idle = 0;
993+ curagent->rt[i].sending_rate = 0;
994+ LIST_INIT(&curagent->rt[i].applets);
995+ LIST_INIT(&curagent->rt[i].sending_queue);
996+ LIST_INIT(&curagent->rt[i].waiting_queue);
997+ HA_SPIN_INIT(&curagent->rt[i].lock);
998+ }
999+
1000 free(conf->agent->b.name);
1001 conf->agent->b.name = NULL;
1002 conf->agent->b.be = target;
1003@@ -3196,8 +3231,6 @@ cfg_parse_spoe_agent(const char *file, int linenum, char **args, int kwm)
1004 curagent->var_pfx = NULL;
1005 curagent->var_on_error = NULL;
1006 curagent->flags = (SPOE_FL_PIPELINING | SPOE_FL_SND_FRAGMENTATION);
1007- if (global.nbthread == 1)
1008- curagent->flags |= SPOE_FL_ASYNC;
1009 curagent->cps_max = 0;
1010 curagent->eps_max = 0;
1011 curagent->max_frame_size = MAX_FRAME_SIZE;
1012@@ -3208,22 +3241,6 @@ cfg_parse_spoe_agent(const char *file, int linenum, char **args, int kwm)
1013 LIST_INIT(&curagent->events[i]);
1014 LIST_INIT(&curagent->groups);
1015 LIST_INIT(&curagent->messages);
1016-
1017- if ((curagent->rt = calloc(global.nbthread, sizeof(*curagent->rt))) == NULL) {
1018- ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1019- err_code |= ERR_ALERT | ERR_ABORT;
1020- goto out;
1021- }
1022- for (i = 0; i < global.nbthread; ++i) {
1023- curagent->rt[i].frame_size = curagent->max_frame_size;
1024- curagent->rt[i].applets_act = 0;
1025- curagent->rt[i].applets_idle = 0;
1026- curagent->rt[i].sending_rate = 0;
1027- LIST_INIT(&curagent->rt[i].applets);
1028- LIST_INIT(&curagent->rt[i].sending_queue);
1029- LIST_INIT(&curagent->rt[i].waiting_queue);
1030- HA_SPIN_INIT(&curagent->rt[i].lock);
1031- }
1032 }
1033 else if (!strcmp(args[0], "use-backend")) {
1034 if (!*args[1]) {
1035diff --git a/src/haproxy.c b/src/haproxy.c
1036index ad6d069..6836762 100644
1037--- a/src/haproxy.c
1038+++ b/src/haproxy.c
1039@@ -2155,6 +2155,7 @@ void deinit(void)
1040 }
1041
1042 deinit_tcp_rules(&p->tcp_req.inspect_rules);
1043+ deinit_tcp_rules(&p->tcp_rep.inspect_rules);
1044 deinit_tcp_rules(&p->tcp_req.l4_rules);
1045
1046 deinit_stick_rules(&p->storersp_rules);
1047diff --git a/src/hlua.c b/src/hlua.c
1048index efeee31..93cb86d 100644
1049--- a/src/hlua.c
1050+++ b/src/hlua.c
1051@@ -7984,9 +7984,9 @@ void hlua_init(void)
1052 socket_ssl.obj_type = OBJ_TYPE_SERVER;
1053 LIST_INIT(&socket_ssl.actconns);
1054 LIST_INIT(&socket_ssl.pendconns);
1055- socket_tcp.priv_conns = NULL;
1056- socket_tcp.idle_conns = NULL;
1057- socket_tcp.safe_conns = NULL;
1058+ socket_ssl.priv_conns = NULL;
1059+ socket_ssl.idle_conns = NULL;
1060+ socket_ssl.safe_conns = NULL;
1061 socket_ssl.next_state = SRV_ST_RUNNING; /* early server setup */
1062 socket_ssl.last_change = 0;
1063 socket_ssl.id = "LUA-SSL-CONN";
1064diff --git a/src/hpack-dec.c b/src/hpack-dec.c
1065index 99d40f9..3fd4224 100644
1066--- a/src/hpack-dec.c
1067+++ b/src/hpack-dec.c
1068@@ -213,6 +213,12 @@ int hpack_decode_frame(struct hpack_dht *dht, const uint8_t *raw, uint32_t len,
1069 ret = -HPACK_ERR_TRUNCATED;
1070 goto leave;
1071 }
1072+
1073+ if (idx > dht->size) {
1074+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
1075+ ret = -HPACK_ERR_INVALID_ARGUMENT;
1076+ goto leave;
1077+ }
1078 continue;
1079 }
1080 else if (!(*raw & (*raw - 0x10))) {
1081diff --git a/src/mux_h2.c b/src/mux_h2.c
1082index b57ba6f..b2f3096 100644
1083--- a/src/mux_h2.c
1084+++ b/src/mux_h2.c
1085@@ -548,12 +548,15 @@ static inline __maybe_unused void h2c_error(struct h2c *h2c, enum h2_err err)
1086 h2c->st0 = H2_CS_ERROR;
1087 }
1088
1089-/* marks an error on the stream */
1090+/* marks an error on the stream. It may also update an already closed stream
1091+ * (e.g. to report an error after an RST was received).
1092+ */
1093 static inline __maybe_unused void h2s_error(struct h2s *h2s, enum h2_err err)
1094 {
1095- if (h2s->st > H2_SS_IDLE && h2s->st < H2_SS_ERROR) {
1096+ if (h2s->id && h2s->st != H2_SS_ERROR) {
1097 h2s->errcode = err;
1098- h2s->st = H2_SS_ERROR;
1099+ if (h2s->st < H2_SS_ERROR)
1100+ h2s->st = H2_SS_ERROR;
1101 if (h2s->cs)
1102 h2s->cs->flags |= CS_FL_ERROR;
1103 }
1104@@ -1140,6 +1143,14 @@ static void h2c_update_all_ws(struct h2c *h2c, int diff)
1105 while (node) {
1106 h2s = container_of(node, struct h2s, by_id);
1107 h2s->mws += diff;
1108+
1109+ if (h2s->mws > 0 && (h2s->flags & H2_SF_BLK_SFCTL)) {
1110+ h2s->flags &= ~H2_SF_BLK_SFCTL;
1111+ if (h2s->cs && LIST_ISEMPTY(&h2s->list) &&
1112+ (h2s->cs->flags & CS_FL_DATA_WR_ENA))
1113+ LIST_ADDQ(&h2c->send_list, &h2s->list);
1114+ }
1115+
1116 node = eb32_next(node);
1117 }
1118 }
1119@@ -1766,7 +1777,11 @@ static int h2c_frt_handle_data(struct h2c *h2c, struct h2s *h2s)
1120
1121 /* last frame */
1122 if (h2c->dff & H2_F_DATA_END_STREAM) {
1123- h2s->st = H2_SS_HREM;
1124+ if (h2s->st == H2_SS_OPEN)
1125+ h2s->st = H2_SS_HREM;
1126+ else
1127+ h2s_close(h2s);
1128+
1129 h2s->flags |= H2_SF_ES_RCVD;
1130 }
1131
1132@@ -1891,10 +1906,14 @@ static void h2_process_demux(struct h2c *h2c)
1133 if (h2s->st == H2_SS_HREM && h2c->dft != H2_FT_WINDOW_UPDATE &&
1134 h2c->dft != H2_FT_RST_STREAM && h2c->dft != H2_FT_PRIORITY) {
1135 /* RFC7540#5.1: any frame other than WU/PRIO/RST in
1136- * this state MUST be treated as a stream error
1137+ * this state MUST be treated as a stream error.
1138+ * 6.2, 6.6 and 6.10 further mandate that HEADERS/
1139+ * PUSH_PROMISE/CONTINUATION cause connection errors.
1140 */
1141- h2s_error(h2s, H2_ERR_STREAM_CLOSED);
1142- h2c->st0 = H2_CS_FRAME_E;
1143+ if (h2_ft_bit(h2c->dft) & H2_FT_HDR_MASK)
1144+ h2c_error(h2c, H2_ERR_PROTOCOL_ERROR);
1145+ else
1146+ h2s_error(h2s, H2_ERR_STREAM_CLOSED);
1147 goto strm_err;
1148 }
1149
1150@@ -1910,7 +1929,7 @@ static void h2_process_demux(struct h2c *h2c)
1151 * Some frames have to be silently ignored as well.
1152 */
1153 if (h2s->st == H2_SS_CLOSED && h2c->dsi) {
1154- if (h2c->dft == H2_FT_HEADERS || h2c->dft == H2_FT_PUSH_PROMISE) {
1155+ if (h2_ft_bit(h2c->dft) & H2_FT_HDR_MASK) {
1156 /* #5.1.1: The identifier of a newly
1157 * established stream MUST be numerically
1158 * greater than all streams that the initiating
1159@@ -1949,7 +1968,7 @@ static void h2_process_demux(struct h2c *h2c)
1160 * over which it ignores frames and treat frames that
1161 * arrive after this time as being in error.
1162 */
1163- if (!(h2s->flags & H2_SF_RST_SENT)) {
1164+ if (h2s->id && !(h2s->flags & H2_SF_RST_SENT)) {
1165 /* RFC7540#5.1:closed: any frame other than
1166 * PRIO/WU/RST in this state MUST be treated as
1167 * a connection error
1168@@ -2561,7 +2580,6 @@ static void h2_detach(struct conn_stream *cs)
1169 if (eb_is_empty(&h2c->streams_by_id) && /* don't close if streams exist */
1170 ((h2c->conn->flags & CO_FL_ERROR) || /* errors close immediately */
1171 (h2c->st0 >= H2_CS_ERROR && !h2c->task) || /* a timeout stroke earlier */
1172- (h2c->flags & (H2_CF_GOAWAY_FAILED | H2_CF_GOAWAY_SENT)) ||
1173 (!h2c->mbuf->o && /* mux buffer empty, also process clean events below */
1174 (conn_xprt_read0_pending(h2c->conn) ||
1175 (h2c->last_sid >= 0 && h2c->max_id >= h2c->last_sid))))) {
1176@@ -2588,11 +2606,17 @@ static void h2_shutr(struct conn_stream *cs, enum cs_shr_mode mode)
1177 if (h2s->st == H2_SS_HLOC || h2s->st == H2_SS_ERROR || h2s->st == H2_SS_CLOSED)
1178 return;
1179
1180- /* if no outgoing data was seen on this stream, it means it was
1181- * closed with a "tcp-request content" rule that is normally
1182- * used to kill the connection ASAP (eg: limit abuse). In this
1183- * case we send a goaway to close the connection.
1184+ /* a connstream may require us to immediately kill the whole connection
1185+ * for example because of a "tcp-request content reject" rule that is
1186+ * normally used to limit abuse. In this case we schedule a goaway to
1187+ * close the connection.
1188 */
1189+ if ((h2s->cs->flags & CS_FL_KILL_CONN) &&
1190+ !(h2s->h2c->flags & (H2_CF_GOAWAY_SENT|H2_CF_GOAWAY_FAILED))) {
1191+ h2c_error(h2s->h2c, H2_ERR_ENHANCE_YOUR_CALM);
1192+ h2s_error(h2s, H2_ERR_ENHANCE_YOUR_CALM);
1193+ }
1194+
1195 if (!(h2s->flags & H2_SF_RST_SENT) &&
1196 h2s_send_rst_stream(h2s->h2c, h2s) <= 0)
1197 goto add_to_list;
1198@@ -2635,11 +2659,17 @@ static void h2_shutw(struct conn_stream *cs, enum cs_shw_mode mode)
1199 else
1200 h2s->st = H2_SS_HLOC;
1201 } else {
1202- /* if no outgoing data was seen on this stream, it means it was
1203- * closed with a "tcp-request content" rule that is normally
1204- * used to kill the connection ASAP (eg: limit abuse). In this
1205- * case we send a goaway to close the connection.
1206+ /* a connstream may require us to immediately kill the whole connection
1207+ * for example because of a "tcp-request content reject" rule that is
1208+ * normally used to limit abuse. In this case we schedule a goaway to
1209+ * close the connection.
1210 */
1211+ if ((h2s->cs->flags & CS_FL_KILL_CONN) &&
1212+ !(h2s->h2c->flags & (H2_CF_GOAWAY_SENT|H2_CF_GOAWAY_FAILED))) {
1213+ h2c_error(h2s->h2c, H2_ERR_ENHANCE_YOUR_CALM);
1214+ h2s_error(h2s, H2_ERR_ENHANCE_YOUR_CALM);
1215+ }
1216+
1217 if (!(h2s->flags & H2_SF_RST_SENT) &&
1218 h2s_send_rst_stream(h2s->h2c, h2s) <= 0)
1219 goto add_to_list;
1220diff --git a/src/proto_http.c b/src/proto_http.c
1221index 7e4a835..efd318e 100644
1222--- a/src/proto_http.c
1223+++ b/src/proto_http.c
1224@@ -3935,7 +3935,8 @@ int http_process_request(struct stream *s, struct channel *req, int an_bit)
1225 * that parameter. This will be done in another analyser.
1226 */
1227 if (!(s->flags & (SF_ASSIGNED|SF_DIRECT)) &&
1228- s->txn->meth == HTTP_METH_POST && s->be->url_param_name != NULL &&
1229+ s->txn->meth == HTTP_METH_POST &&
1230+ (s->be->lbprm.algo & BE_LB_ALGO) == BE_LB_ALGO_PH &&
1231 (msg->flags & (HTTP_MSGF_CNT_LEN|HTTP_MSGF_TE_CHNK))) {
1232 channel_dont_connect(req);
1233 req->analysers |= AN_REQ_HTTP_BODY;
1234@@ -8210,6 +8211,7 @@ void http_init_txn(struct stream *s)
1235
1236 txn->flags = 0;
1237 txn->status = -1;
1238+ *(unsigned int *)txn->cache_hash = 0;
1239
1240 txn->cookie_first_date = 0;
1241 txn->cookie_last_date = 0;
1242@@ -12106,6 +12108,7 @@ enum act_parse_ret parse_http_set_status(const char **args, int *orig_arg, struc
1243 enum act_return http_action_reject(struct act_rule *rule, struct proxy *px,
1244 struct session *sess, struct stream *s, int flags)
1245 {
1246+ si_must_kill_conn(chn_prod(&s->req));
1247 channel_abort(&s->req);
1248 channel_abort(&s->res);
1249 s->req.analysers = 0;
1250diff --git a/src/sample.c b/src/sample.c
1251index 139d976..4c6b99d 100644
1252--- a/src/sample.c
1253+++ b/src/sample.c
1254@@ -1261,6 +1261,13 @@ int smp_resolve_args(struct proxy *p)
1255 break;
1256 }
1257
1258+ if (p->bind_proc & ~px->bind_proc) {
1259+ ha_alert("parsing [%s:%d] : stick-table '%s' not present on all processes covered by proxy '%s'.\n",
1260+ cur->file, cur->line, px->id, p->id);
1261+ cfgerr++;
1262+ break;
1263+ }
1264+
1265 free(arg->data.str.str);
1266 arg->data.str.str = NULL;
1267 arg->unresolved = 0;
1268diff --git a/src/server.c b/src/server.c
1269index a86db3d..0dded5b 100644
1270--- a/src/server.c
1271+++ b/src/server.c
1272@@ -1534,7 +1534,6 @@ static void srv_settings_cpy(struct server *srv, struct server *src, int srv_tmp
1273 static struct server *new_server(struct proxy *proxy)
1274 {
1275 struct server *srv;
1276- int i;
1277
1278 srv = calloc(1, sizeof *srv);
1279 if (!srv)
1280@@ -1545,21 +1544,6 @@ static struct server *new_server(struct proxy *proxy)
1281 LIST_INIT(&srv->actconns);
1282 LIST_INIT(&srv->pendconns);
1283
1284- if ((srv->priv_conns = calloc(global.nbthread, sizeof(*srv->priv_conns))) == NULL)
1285- goto free_srv;
1286- if ((srv->idle_conns = calloc(global.nbthread, sizeof(*srv->idle_conns))) == NULL)
1287- goto free_priv_conns;
1288- if ((srv->safe_conns = calloc(global.nbthread, sizeof(*srv->safe_conns))) == NULL)
1289- goto free_idle_conns;
1290-
1291- for (i = 0; i < global.nbthread; i++) {
1292- LIST_INIT(&srv->priv_conns[i]);
1293- LIST_INIT(&srv->idle_conns[i]);
1294- LIST_INIT(&srv->safe_conns[i]);
1295- }
1296-
1297- LIST_INIT(&srv->update_status);
1298-
1299 srv->next_state = SRV_ST_RUNNING; /* early server setup */
1300 srv->last_change = now.tv_sec;
1301
1302@@ -1572,14 +1556,6 @@ static struct server *new_server(struct proxy *proxy)
1303 srv->xprt = srv->check.xprt = srv->agent.xprt = xprt_get(XPRT_RAW);
1304
1305 return srv;
1306-
1307- free_idle_conns:
1308- free(srv->idle_conns);
1309- free_priv_conns:
1310- free(srv->priv_conns);
1311- free_srv:
1312- free(srv);
1313- return NULL;
1314 }
1315
1316 /*
1317@@ -2843,16 +2819,37 @@ static void srv_update_state(struct server *srv, int version, char **params)
1318 HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1319 /* recover operational state and apply it to this server
1320 * and all servers tracking this one */
1321+ srv->check.health = srv_check_health;
1322 switch (srv_op_state) {
1323 case SRV_ST_STOPPED:
1324 srv->check.health = 0;
1325 srv_set_stopped(srv, "changed from server-state after a reload", NULL);
1326 break;
1327 case SRV_ST_STARTING:
1328+ /* If rise == 1 there is no STARTING state, let's switch to
1329+ * RUNNING
1330+ */
1331+ if (srv->check.rise == 1) {
1332+ srv->check.health = srv->check.rise + srv->check.fall - 1;
1333+ srv_set_running(srv, "", NULL);
1334+ break;
1335+ }
1336+ if (srv->check.health < 1 || srv->check.health >= srv->check.rise)
1337+ srv->check.health = srv->check.rise - 1;
1338 srv->next_state = srv_op_state;
1339 break;
1340 case SRV_ST_STOPPING:
1341- srv->check.health = srv->check.rise + srv->check.fall - 1;
1342+ /* If fall == 1 there is no STOPPING state, let's switch to
1343+ * STOPPED
1344+ */
1345+ if (srv->check.fall == 1) {
1346+ srv->check.health = 0;
1347+ srv_set_stopped(srv, "changed from server-state after a reload", NULL);
1348+ break;
1349+ }
1350+ if (srv->check.health < srv->check.rise ||
1351+ srv->check.health > srv->check.rise + srv->check.fall - 2)
1352+ srv->check.health = srv->check.rise;
1353 srv_set_stopping(srv, "changed from server-state after a reload", NULL);
1354 break;
1355 case SRV_ST_RUNNING:
1356@@ -2906,7 +2903,6 @@ static void srv_update_state(struct server *srv, int version, char **params)
1357 srv->last_change = date.tv_sec - srv_last_time_change;
1358 srv->check.status = srv_check_status;
1359 srv->check.result = srv_check_result;
1360- srv->check.health = srv_check_health;
1361
1362 /* Only case we want to apply is removing ENABLED flag which could have been
1363 * done by the "disable health" command over the stats socket
1364diff --git a/src/ssl_sock.c b/src/ssl_sock.c
1365index 24ccc4b..7736c32 100644
1366--- a/src/ssl_sock.c
1367+++ b/src/ssl_sock.c
1368@@ -1406,6 +1406,10 @@ void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1369 BIO *write_bio;
1370 (void)ret; /* shut gcc stupid warning */
1371
1372+#ifndef SSL_OP_NO_RENEGOTIATION
1373+ /* Please note that BoringSSL defines this macro to zero so don't
1374+ * change this to #if and do not assign a default value to this macro!
1375+ */
1376 if (where & SSL_CB_HANDSHAKE_START) {
1377 /* Disable renegotiation (CVE-2009-3555) */
1378 if ((conn->flags & (CO_FL_CONNECTED | CO_FL_EARLY_SSL_HS | CO_FL_EARLY_DATA)) == CO_FL_CONNECTED) {
1379@@ -1413,6 +1417,7 @@ void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1380 conn->err_code = CO_ER_SSL_RENEG;
1381 }
1382 }
1383+#endif
1384
1385 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1386 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1387@@ -3806,6 +3811,11 @@ ssl_sock_initial_ctx(struct bind_conf *bind_conf)
1388 options |= SSL_OP_NO_TICKET;
1389 if (bind_conf->ssl_options & BC_SSL_O_PREF_CLIE_CIPH)
1390 options &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
1391+
1392+#ifdef SSL_OP_NO_RENEGOTIATION
1393+ options |= SSL_OP_NO_RENEGOTIATION;
1394+#endif
1395+
1396 SSL_CTX_set_options(ctx, options);
1397
1398 #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
1399@@ -3821,6 +3831,10 @@ ssl_sock_initial_ctx(struct bind_conf *bind_conf)
1400 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
1401 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
1402 #elif (OPENSSL_VERSION_NUMBER >= 0x10101000L)
1403+ if (bind_conf->ssl_conf.early_data) {
1404+ SSL_CTX_set_options(ctx, SSL_OP_NO_ANTI_REPLAY);
1405+ SSL_CTX_set_max_early_data(ctx, global.tune.bufsize - global.tune.maxrewrite);
1406+ }
1407 SSL_CTX_set_client_hello_cb(ctx, ssl_sock_switchctx_cbk, NULL);
1408 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
1409 #else
1410@@ -7623,15 +7637,36 @@ static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px
1411 }
1412
1413 keys_ref = malloc(sizeof(*keys_ref));
1414+ if (!keys_ref) {
1415+ if (err)
1416+ memprintf(err, "'%s' : allocation error", args[cur_arg+1]);
1417+ return ERR_ALERT | ERR_FATAL;
1418+ }
1419+
1420 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
1421+ if (!keys_ref->tlskeys) {
1422+ free(keys_ref);
1423+ if (err)
1424+ memprintf(err, "'%s' : allocation error", args[cur_arg+1]);
1425+ return ERR_ALERT | ERR_FATAL;
1426+ }
1427
1428 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
1429+ free(keys_ref->tlskeys);
1430+ free(keys_ref);
1431 if (err)
1432 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
1433 return ERR_ALERT | ERR_FATAL;
1434 }
1435
1436 keys_ref->filename = strdup(args[cur_arg + 1]);
1437+ if (!keys_ref->filename) {
1438+ free(keys_ref->tlskeys);
1439+ free(keys_ref);
1440+ if (err)
1441+ memprintf(err, "'%s' : allocation error", args[cur_arg+1]);
1442+ return ERR_ALERT | ERR_FATAL;
1443+ }
1444
1445 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1446 int len = strlen(thisline);
1447@@ -7643,6 +7678,9 @@ static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px
1448 thisline[--len] = 0;
1449
1450 if (base64dec(thisline, len, (char *) (keys_ref->tlskeys + i % TLS_TICKETS_NO), sizeof(struct tls_sess_key)) != sizeof(struct tls_sess_key)) {
1451+ free(keys_ref->filename);
1452+ free(keys_ref->tlskeys);
1453+ free(keys_ref);
1454 if (err)
1455 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
1456 fclose(f);
1457@@ -7652,6 +7690,9 @@ static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px
1458 }
1459
1460 if (i < TLS_TICKETS_NO) {
1461+ free(keys_ref->filename);
1462+ free(keys_ref->tlskeys);
1463+ free(keys_ref);
1464 if (err)
1465 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
1466 fclose(f);
1467diff --git a/src/stream.c b/src/stream.c
1468index 507cd2f..f443cc7 100644
1469--- a/src/stream.c
1470+++ b/src/stream.c
1471@@ -339,6 +339,9 @@ static void stream_free(struct stream *s)
1472 offer_buffers(NULL, tasks_run_queue + applets_active_queue);
1473 }
1474
1475+ pool_free(pool_head_uniqueid, s->unique_id);
1476+ s->unique_id = NULL;
1477+
1478 hlua_ctx_destroy(s->hlua);
1479 s->hlua = NULL;
1480 if (s->txn)
1481@@ -593,7 +596,8 @@ static int sess_update_st_con_tcp(struct stream *s)
1482 */
1483 si->state = SI_ST_EST;
1484 si->err_type = SI_ET_DATA_ERR;
1485- rep->flags |= CF_READ_ERROR | CF_WRITE_ERROR;
1486+ req->flags |= CF_WRITE_ERROR;
1487+ rep->flags |= CF_READ_ERROR;
1488 return 1;
1489 }
1490 si->exp = TICK_ETERNITY;
1491diff --git a/src/stream_interface.c b/src/stream_interface.c
1492index f17980a..47a100d 100644
1493--- a/src/stream_interface.c
1494+++ b/src/stream_interface.c
1495@@ -830,6 +830,9 @@ static void stream_int_shutr_conn(struct stream_interface *si)
1496 if (si->state != SI_ST_EST && si->state != SI_ST_CON)
1497 return;
1498
1499+ if (si->flags & SI_FL_KILL_CONN)
1500+ cs->flags |= CS_FL_KILL_CONN;
1501+
1502 if (si_oc(si)->flags & CF_SHUTW) {
1503 cs_close(cs);
1504 si->state = SI_ST_DIS;
1505@@ -880,6 +883,9 @@ static void stream_int_shutw_conn(struct stream_interface *si)
1506 * However, if SI_FL_NOLINGER is explicitly set, we know there is
1507 * no risk so we close both sides immediately.
1508 */
1509+ if (si->flags & SI_FL_KILL_CONN)
1510+ cs->flags |= CS_FL_KILL_CONN;
1511+
1512 if (si->flags & SI_FL_ERR) {
1513 /* quick close, the socket is alredy shut anyway */
1514 }
1515@@ -914,6 +920,8 @@ static void stream_int_shutw_conn(struct stream_interface *si)
1516 /* we may have to close a pending connection, and mark the
1517 * response buffer as shutr
1518 */
1519+ if (si->flags & SI_FL_KILL_CONN)
1520+ cs->flags |= CS_FL_KILL_CONN;
1521 cs_close(cs);
1522 /* fall through */
1523 case SI_ST_CER:
1524diff --git a/src/tcp_rules.c b/src/tcp_rules.c
1525index feee441..72a7015 100644
1526--- a/src/tcp_rules.c
1527+++ b/src/tcp_rules.c
1528@@ -162,6 +162,7 @@ resume_execution:
1529 break;
1530 }
1531 else if (rule->action == ACT_ACTION_DENY) {
1532+ si_must_kill_conn(chn_prod(req));
1533 channel_abort(req);
1534 channel_abort(&s->res);
1535 req->analysers = 0;
1536@@ -340,6 +341,7 @@ resume_execution:
1537 break;
1538 }
1539 else if (rule->action == ACT_ACTION_DENY) {
1540+ si_must_kill_conn(chn_prod(rep));
1541 channel_abort(rep);
1542 channel_abort(&s->req);
1543 rep->analysers = 0;
1544@@ -357,6 +359,7 @@ resume_execution:
1545 }
1546 else if (rule->action == ACT_TCP_CLOSE) {
1547 chn_prod(rep)->flags |= SI_FL_NOLINGER | SI_FL_NOHALF;
1548+ si_must_kill_conn(chn_prod(rep));
1549 si_shutr(chn_prod(rep));
1550 si_shutw(chn_prod(rep));
1551 break;

Subscribers

People subscribed via source and target branches