Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package haproxy for openSUSE:Factory checked 
in at 2021-07-12 01:24:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/haproxy (Old)
 and      /work/SRC/openSUSE:Factory/.haproxy.new.2625 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "haproxy"

Mon Jul 12 01:24:40 2021 rev:105 rq:904653 version:2.4.2+git0.553dee326

Changes:
--------
--- /work/SRC/openSUSE:Factory/haproxy/haproxy.changes  2021-06-24 
18:22:01.524879691 +0200
+++ /work/SRC/openSUSE:Factory/.haproxy.new.2625/haproxy.changes        
2021-07-12 01:24:44.757365380 +0200
@@ -1,0 +2,41 @@
+Wed Jul 07 23:30:56 UTC 2021 - mrueck...@suse.de
+
+- Update to version 2.4.2+git0.553dee326:
+  * [RELEASE] Released version 2.4.2
+  * REGTESTS: add http scheme-based normalization test
+  * MEDIUM: h2: apply scheme-based normalization on h2 requests
+  * MEDIUM: h1-htx: apply scheme-based normalization on h1 requests
+  * MEDIUM: http: implement scheme-based normalization
+  * MINOR: http: implement http_get_scheme
+  * Revert "MINOR: tcp-act: Add set-src/set-src-port for "tcp-request content" 
rules"
+  * BUG/MINOR: cli: fix server name output in "show fd"
+  * BUG/MEDIUM: sock: make sure to never miss early connection failures
+  * DOC: stick-table: add missing documentation about gpt0 stored type
+  * BUG/MINOR: peers: fix data_type bit computation more than 32 data_types
+  * BUG/MINOR: stick-table: fix several printf sign errors dumping tables
+  * DOC: config: use CREATE USER for mysql-check
+  * BUG/MEDIUM: resolvers: Make 1st server of a template take part to SRV 
resolution
+  * BUG/MINOR: mqtt: Support empty client ID in CONNECT message
+  * BUG/MINOR: mqtt: Fix parser for string with more than 127 characters
+  * BUG/MINOR: tcpcheck: Fix numbering of implicit HTTP send/expect rules
+  * BUILD: Makefile: fix linkage for Haiku.
+  * BUG/MINOR: checks: return correct error code for srv_parse_agent_check
+  * MINOR: resolvers: Reset server IP on error in resolv_get_ip_from_response()
+  * BUG/MINOR: resolvers: Reset server IP when no ip is found in the response
+  * BUG/MINOR: resolvers: Always attach server on matching record on resolution
+  * CLEANUP: dns: Remove a forgotten debug message
+  * DOC: config: Add missing actions in "tcp-request session" documentation
+  * MINOR: tcp-act: Add set-src/set-src-port for "tcp-request content" rules
+  * REGTESTS: fix maxconn update with agent-check
+  * BUG/MAJOR: server: fix deadlock when changing maxconn via agent-check
+  * BUG/MINOR: cache: Correctly handle existing-but-empty 'accept-encoding' 
header
+  * BUG/MINOR: server/cli: Fix locking in function processing "set server" 
command
+  * BUG/MINOR: resolvers: Use resolver's lock in resolv_srvrq_expire_task()
+  * BUG/MEDIUM: resolvers: Add a task on servers to check SRV resolution status
+  * MINOR: resolvers: Remove server from named_servers tree when removing a 
SRV item
+  * MINOR: resolvers: Clean server in a dedicated function when removing a SRV 
item
+  * BUG/MEDIUM: server/cli: Fix ABBA deadlock when fqdn is set from the CLI
+  * BUG/MINOR: server: Forbid to set fqdn on the CLI if SRV resolution is 
enabled
+  * BUG/MINOR: server-state: load SRV resolution only if params match the 
config
+
+-------------------------------------------------------------------

Old:
----
  haproxy-2.4.1+git0.1ce7d4925.tar.gz

New:
----
  haproxy-2.4.2+git0.553dee326.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ haproxy.spec ++++++
--- /var/tmp/diff_new_pack.Q43BK3/_old  2021-07-12 01:24:45.357360767 +0200
+++ /var/tmp/diff_new_pack.Q43BK3/_new  2021-07-12 01:24:45.357360767 +0200
@@ -53,7 +53,7 @@
 %endif
 
 Name:           haproxy
-Version:        2.4.1+git0.1ce7d4925
+Version:        2.4.2+git0.553dee326
 Release:        0
 #
 #

++++++ _service ++++++
--- /var/tmp/diff_new_pack.Q43BK3/_old  2021-07-12 01:24:45.385360551 +0200
+++ /var/tmp/diff_new_pack.Q43BK3/_new  2021-07-12 01:24:45.385360551 +0200
@@ -6,7 +6,7 @@
     <param name="versionformat">@PARENT_TAG@+git@TAG_OFFSET@.%h</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="versionrewrite-replacement">\1</param>
-    <param name="revision">v2.4.1</param>
+    <param name="revision">v2.4.2</param>
     <param name="changesgenerate">enable</param>
   </service>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.Q43BK3/_old  2021-07-12 01:24:45.401360428 +0200
+++ /var/tmp/diff_new_pack.Q43BK3/_new  2021-07-12 01:24:45.401360428 +0200
@@ -1,6 +1,6 @@
 <servicedata>
   <service name="tar_scm">
     <param name="url">http://git.haproxy.org/git/haproxy-2.4.git</param>
-    <param 
name="changesrevision">1ce7d49252b1b9c767ab676bd178cccc35929d28</param>
+    <param 
name="changesrevision">553dee32630347e78cc3a33001c40d26d4245d23</param>
   </service>
 </servicedata>
\ No newline at end of file

++++++ haproxy-2.4.1+git0.1ce7d4925.tar.gz -> 
haproxy-2.4.2+git0.553dee326.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/.gitignore 
new/haproxy-2.4.2+git0.553dee326/.gitignore
--- old/haproxy-2.4.1+git0.1ce7d4925/.gitignore 1970-01-01 01:00:00.000000000 
+0100
+++ new/haproxy-2.4.2+git0.553dee326/.gitignore 2021-07-07 16:46:09.000000000 
+0200
@@ -0,0 +1,53 @@
+# Below we forbid everything and only allow what we know, that's much easier
+# than blocking about 500 different test files and bug report outputs.
+/.*
+/*
+!/.cirrus.yml
+!/.gitattributes
+!/.github
+!/.gitignore
+!/.travis.yml
+!/CHANGELOG
+!/LICENSE
+!/BRANCHES
+!/Makefile
+!/README
+!/INSTALL
+!/CONTRIBUTING
+!/MAINTAINERS
+!/ROADMAP
+!/SUBVERS
+!/VERDATE
+!/VERSION
+!/addons
+!/admin
+!/dev
+!/doc
+!/ebtree
+!/examples
+!/include
+!/src
+!/tests
+!/debian
+!/scripts
+!/reg-tests
+# Reject some generic files
+*.o
+*.a
+*~
+*.rej
+*.orig
+*.bak
+# And reject some specific files
+/admin/halog/halog
+/admin/iprange/ip6range
+/admin/iprange/iprange
+/admin/systemd/haproxy.service
+dev/base64/base64rev-gen
+dev/flags/flags
+dev/poll/poll
+dev/tcploop/tcploop
+dev/hpack/decode
+dev/hpack/gen-rht
+/src/dlmalloc.c
+/tests/test_hashes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/CHANGELOG 
new/haproxy-2.4.2+git0.553dee326/CHANGELOG
--- old/haproxy-2.4.1+git0.1ce7d4925/CHANGELOG  2021-06-17 09:06:08.000000000 
+0200
+++ new/haproxy-2.4.2+git0.553dee326/CHANGELOG  2021-07-07 16:46:09.000000000 
+0200
@@ -1,6 +1,43 @@
 ChangeLog :
 ===========
 
+2021/07/07 : 2.4.2
+    - BUG/MINOR: server-state: load SRV resolution only if params match the 
config
+    - BUG/MINOR: server: Forbid to set fqdn on the CLI if SRV resolution is 
enabled
+    - BUG/MEDIUM: server/cli: Fix ABBA deadlock when fqdn is set from the CLI
+    - MINOR: resolvers: Clean server in a dedicated function when removing a 
SRV item
+    - MINOR: resolvers: Remove server from named_servers tree when removing a 
SRV item
+    - BUG/MEDIUM: resolvers: Add a task on servers to check SRV resolution 
status
+    - BUG/MINOR: resolvers: Use resolver's lock in resolv_srvrq_expire_task()
+    - BUG/MINOR: server/cli: Fix locking in function processing "set server" 
command
+    - BUG/MINOR: cache: Correctly handle existing-but-empty 'accept-encoding' 
header
+    - BUG/MAJOR: server: fix deadlock when changing maxconn via agent-check
+    - REGTESTS: fix maxconn update with agent-check
+    - MINOR: tcp-act: Add set-src/set-src-port for "tcp-request content" rules
+    - DOC: config: Add missing actions in "tcp-request session" documentation
+    - CLEANUP: dns: Remove a forgotten debug message
+    - BUG/MINOR: resolvers: Always attach server on matching record on 
resolution
+    - BUG/MINOR: resolvers: Reset server IP when no ip is found in the response
+    - MINOR: resolvers: Reset server IP on error in 
resolv_get_ip_from_response()
+    - BUG/MINOR: checks: return correct error code for srv_parse_agent_check
+    - BUILD: Makefile: fix linkage for Haiku.
+    - BUG/MINOR: tcpcheck: Fix numbering of implicit HTTP send/expect rules
+    - BUG/MINOR: mqtt: Fix parser for string with more than 127 characters
+    - BUG/MINOR: mqtt: Support empty client ID in CONNECT message
+    - BUG/MEDIUM: resolvers: Make 1st server of a template take part to SRV 
resolution
+    - DOC: config: use CREATE USER for mysql-check
+    - BUG/MINOR: stick-table: fix several printf sign errors dumping tables
+    - BUG/MINOR: peers: fix data_type bit computation more than 32 data_types
+    - DOC: stick-table: add missing documentation about gpt0 stored type
+    - BUG/MEDIUM: sock: make sure to never miss early connection failures
+    - BUG/MINOR: cli: fix server name output in "show fd"
+    - Revert "MINOR: tcp-act: Add set-src/set-src-port for "tcp-request 
content" rules"
+    - MINOR: http: implement http_get_scheme
+    - MEDIUM: http: implement scheme-based normalization
+    - MEDIUM: h1-htx: apply scheme-based normalization on h1 requests
+    - MEDIUM: h2: apply scheme-based normalization on h2 requests
+    - REGTESTS: add http scheme-based normalization test
+
 2021/06/17 : 2.4.1
     - BUG/MEDIUM: ebtree: Invalid read when looking for dup entry
     - BUG/MAJOR: server: prevent deadlock when using 'set maxconn server'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/Makefile 
new/haproxy-2.4.2+git0.553dee326/Makefile
--- old/haproxy-2.4.1+git0.1ce7d4925/Makefile   2021-06-17 09:06:08.000000000 
+0200
+++ new/haproxy-2.4.2+git0.553dee326/Makefile   2021-07-07 16:46:09.000000000 
+0200
@@ -346,7 +346,7 @@
 # Haiku
 ifeq ($(TARGET),haiku)
   TARGET_LDFLAGS = -lnetwork
-  set_target_defaults = $(call default_opts,USE_POLL USE_TPROXY)
+  set_target_defaults = $(call default_opts,USE_POLL USE_TPROXY 
USE_OBSOLETE_LINKER)
 endif
 
 # For linux >= 2.6.28 and glibc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/VERDATE 
new/haproxy-2.4.2+git0.553dee326/VERDATE
--- old/haproxy-2.4.1+git0.1ce7d4925/VERDATE    2021-06-17 09:06:08.000000000 
+0200
+++ new/haproxy-2.4.2+git0.553dee326/VERDATE    2021-07-07 16:46:09.000000000 
+0200
@@ -1,2 +1,2 @@
 $Format:%ci$
-2021/06/17
+2021/07/07
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/VERSION 
new/haproxy-2.4.2+git0.553dee326/VERSION
--- old/haproxy-2.4.1+git0.1ce7d4925/VERSION    2021-06-17 09:06:08.000000000 
+0200
+++ new/haproxy-2.4.2+git0.553dee326/VERSION    2021-07-07 16:46:09.000000000 
+0200
@@ -1 +1 @@
-2.4.1
+2.4.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/doc/configuration.txt 
new/haproxy-2.4.2+git0.553dee326/doc/configuration.txt
--- old/haproxy-2.4.1+git0.1ce7d4925/doc/configuration.txt      2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/doc/configuration.txt      2021-07-07 
16:46:09.000000000 +0200
@@ -4,7 +4,7 @@
                          ----------------------
                               version 2.4
                              willy tarreau
-                              2021/06/17
+                              2021/07/07
 
 
 This document covers the configuration language as implemented in the version
@@ -9093,12 +9093,13 @@
   one Client Authentication packet, and one QUIT packet, to correctly close
   MySQL session. We then parse the MySQL Handshake Initialization packet and/or
   Error packet. It is a basic but useful test which does not produce error nor
-  aborted connect on the server. However, it requires adding an authorization
-  in the MySQL table, like this :
-
-      USE mysql;
-      INSERT INTO user (Host,User) values ('<ip_of_haproxy>','<username>');
-      FLUSH PRIVILEGES;
+  aborted connect on the server. However, it requires an unlocked authorised
+  user without a password. To create a basic limited user in MySQL with
+  optional resource limits:
+
+      CREATE USER '<username>'@'<ip_of_haproxy|network_of_haproxy/netmask>'
+      /*!50701 WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 0 */
+      /*M!100201 MAX_STATEMENT_TIME 0.0001 */;
 
   If you don't specify a username (it is deprecated and not recommended), the
   check only consists in parsing the Mysql Handshake Initialization packet or
@@ -11311,6 +11312,11 @@
       incremented. Most of the time it will be used to measure the frequency of
       occurrence of certain events (e.g. requests to a specific URL).
 
+    - gpt0 : first General Purpose Tag. It is a positive 32-bit integer
+      integer which may be used for anything. Most of the time it will be used
+      to put a special tag on some entries, for instance to note that a
+      specific behavior was detected and must be known for future matches
+
     - conn_cnt : Connection Count. It is a positive 32-bit integer which counts
       the absolute number of connections received from clients which matched
       this entry. It does not mean the connections were accepted, just that
@@ -12621,6 +12627,10 @@
     - sc-inc-gpc0(<sc-id>)
     - sc-inc-gpc1(<sc-id>)
     - sc-set-gpt0(<sc-id>) { <int> | <expr> }
+    - set-dst <expr>
+    - set-dst-port <expr>
+    - set-src <expr>
+    - set-src-port <expr>
     - set-var(<var-name>) <expr>
     - unset-var(<var-name>)
     - silent-drop
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/include/haproxy/http.h 
new/haproxy-2.4.2+git0.553dee326/include/haproxy/http.h
--- old/haproxy-2.4.1+git0.1ce7d4925/include/haproxy/http.h     2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/include/haproxy/http.h     2021-07-07 
16:46:09.000000000 +0200
@@ -36,6 +36,7 @@
 enum http_meth_t find_http_meth(const char *str, const int len);
 int http_get_status_idx(unsigned int status);
 const char *http_get_reason(unsigned int status);
+struct ist http_get_scheme(const struct ist uri);
 struct ist http_get_authority(const struct ist uri, int no_userinfo);
 struct ist http_get_path(const struct ist uri);
 int http_header_match2(const char *hdr, const char *end,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-2.4.1+git0.1ce7d4925/include/haproxy/http_htx.h 
new/haproxy-2.4.2+git0.553dee326/include/haproxy/http_htx.h
--- old/haproxy-2.4.1+git0.1ce7d4925/include/haproxy/http_htx.h 2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/include/haproxy/http_htx.h 2021-07-07 
16:46:09.000000000 +0200
@@ -66,6 +66,8 @@
 struct http_reply *http_parse_http_reply(const char **args, int *orig_arg, 
struct proxy *px,
                                         int default_status, char **errmsg);
 
+int http_scheme_based_normalize(struct htx *htx);
+
 struct buffer *http_load_errorfile(const char *file, char **errmsg);
 struct buffer *http_load_errormsg(const char *key, const struct ist msg, char 
**errmsg);
 struct buffer *http_parse_errorfile(int status, const char *file, char 
**errmsg);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/include/haproxy/queue.h 
new/haproxy-2.4.2+git0.553dee326/include/haproxy/queue.h
--- old/haproxy-2.4.1+git0.1ce7d4925/include/haproxy/queue.h    2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/include/haproxy/queue.h    2021-07-07 
16:46:09.000000000 +0200
@@ -34,7 +34,7 @@
 
 struct pendconn *pendconn_add(struct stream *strm);
 int pendconn_dequeue(struct stream *strm);
-void process_srv_queue(struct server *s);
+void process_srv_queue(struct server *s, int server_locked);
 unsigned int srv_dynamic_maxconn(const struct server *s);
 int pendconn_redistribute(struct server *s);
 int pendconn_grab_from_px(struct server *s);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-2.4.1+git0.1ce7d4925/include/haproxy/server-t.h 
new/haproxy-2.4.2+git0.553dee326/include/haproxy/server-t.h
--- old/haproxy-2.4.1+git0.1ce7d4925/include/haproxy/server-t.h 2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/include/haproxy/server-t.h 2021-07-07 
16:46:09.000000000 +0200
@@ -368,6 +368,7 @@
        struct list srv_rec_item;               /* to attach server to a srv 
record item */
        struct list ip_rec_item;                /* to attach server to a A or 
AAAA record item */
        struct ebpt_node host_dn;               /* hostdn store for srvrq and 
state file matching*/
+       struct task *srvrq_check;               /* Task testing SRV record 
expiration date for this server */
        struct {
                const char *file;               /* file where the section 
appears */
                struct eb32_node id;            /* place in the tree of used 
IDs */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-2.4.1+git0.1ce7d4925/include/haproxy/stream.h 
new/haproxy-2.4.2+git0.553dee326/include/haproxy/stream.h
--- old/haproxy-2.4.1+git0.1ce7d4925/include/haproxy/stream.h   2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/include/haproxy/stream.h   2021-07-07 
16:46:09.000000000 +0200
@@ -339,7 +339,7 @@
              ((s->be->lbprm.algo & BE_LB_KIND) == BE_LB_KIND_RR)))) {
                sess_change_server(s, NULL);
                if (may_dequeue_tasks(objt_server(s->target), s->be))
-                       process_srv_queue(objt_server(s->target));
+                       process_srv_queue(objt_server(s->target), 0);
 
                s->flags &= ~(SF_DIRECT | SF_ASSIGNED | SF_ADDR_SET);
                si->state = SI_ST_REQ;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-2.4.1+git0.1ce7d4925/reg-tests/cache/vary.vtc 
new/haproxy-2.4.2+git0.553dee326/reg-tests/cache/vary.vtc
--- old/haproxy-2.4.1+git0.1ce7d4925/reg-tests/cache/vary.vtc   2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/reg-tests/cache/vary.vtc   2021-07-07 
16:46:09.000000000 +0200
@@ -108,7 +108,18 @@
                -hdr "Content-Encoding: gzip" \
               -bodylen 188
 
+       rxreq
+       expect req.url == "/empty-vs-missing"
+       txresp -hdr "Content-Encoding: gzip" \
+               -hdr "Vary: accept-encoding" \
+               -hdr "Cache-Control: max-age=5" \
+               -bodylen 234
 
+       rxreq
+       expect req.url == "/empty-vs-missing"
+       txresp -hdr "Vary: accept-encoding" \
+               -hdr "Cache-Control: max-age=5" \
+               -bodylen 256
 } -start
 
 server s2 {
@@ -345,6 +356,42 @@
        expect resp.bodylen == 188
        expect resp.http.X-Cache-Hit == 0
 
+       # A missing 'Accept-Encoding' implies that anything is acceptable,
+       # while an empty 'Accept-Encoding' implies nothing is acceptable.
+
+       # Start by caching a gzip response.
+       txreq -url "/empty-vs-missing" -hdr "Accept-Encoding: gzip"
+       rxresp
+       expect resp.status == 200
+       expect resp.bodylen == 234
+       expect resp.http.content-encoding == "gzip"
+       expect resp.http.X-Cache-Hit == 0
+
+       # Check that it is cached.
+       txreq -url "/empty-vs-missing" -hdr "Accept-Encoding: gzip"
+       rxresp
+       expect resp.status == 200
+       expect resp.bodylen == 234
+       expect resp.http.content-encoding == "gzip"
+       expect resp.http.X-Cache-Hit == 1
+
+       # Check that the cached response is returned when no accept-encoding is
+       # specified.
+       txreq -url "/empty-vs-missing"
+       rxresp
+       expect resp.status == 200
+       expect resp.bodylen == 234
+       expect resp.http.content-encoding == "gzip"
+       expect resp.http.X-Cache-Hit == 1
+
+       # Check that the cached response is not returned when an empty
+       # accept-encoding is specified.
+       txreq -url "/empty-vs-missing" -hdr "Accept-Encoding:"
+       rxresp
+       expect resp.status == 200
+       expect resp.bodylen == 256
+       expect resp.http.content-encoding == "<undef>"
+       expect resp.http.X-Cache-Hit == 0
 
        # The following requests are treated by a backend that does not cache
        # responses containing a Vary header
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-2.4.1+git0.1ce7d4925/reg-tests/checks/agent-check.vtc 
new/haproxy-2.4.2+git0.553dee326/reg-tests/checks/agent-check.vtc
--- old/haproxy-2.4.1+git0.1ce7d4925/reg-tests/checks/agent-check.vtc   
2021-06-17 09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/reg-tests/checks/agent-check.vtc   
2021-07-07 16:46:09.000000000 +0200
@@ -9,7 +9,7 @@
 server s1 {
   barrier b1 sync
   recv 5
-  send "75%,max-conn:30,maint,down\n"
+  send "75%,maxconn:30,maint,down\n"
   expect_close
   barrier b2 sync
 } -start
@@ -31,8 +31,13 @@
 haproxy h1 -cli {
     send "show servers state"
     expect ~ "be1 1 srv 127.0.0.1 2 0 100 100 [[:digit:]]+ 1 0 [[:digit:]] 0 
[[:digit:]]+ 0 0 - ${s1_port} -"
+    send "show stat"
+    expect ~ "be1,srv,0,0,0,0,,"
+
     barrier b1 sync
     barrier b2 sync
     send "show servers state"
     expect ~ "be1 1 srv 127.0.0.1 0 1 75 100 [[:digit:]]+ 1 0 [[:digit:]] 0 
[[:digit:]]+ 0 0 - ${s1_port} -"
+    send "show stat"
+    expect ~ "be1,srv,0,0,0,0,30"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-2.4.1+git0.1ce7d4925/reg-tests/converter/mqtt.vtc 
new/haproxy-2.4.2+git0.553dee326/reg-tests/converter/mqtt.vtc
--- old/haproxy-2.4.1+git0.1ce7d4925/reg-tests/converter/mqtt.vtc       
2021-06-17 09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/reg-tests/converter/mqtt.vtc       
2021-07-07 16:46:09.000000000 +0200
@@ -4,14 +4,14 @@
 feature ignore_unknown_macro
 
 server s1 {
-    # MQTT 3.1.1 CONNECT packet (id: test_sub)
-    recv 22
+    # MQTT 3.1.1 CONNECT packet (id: test_subaaaaaa... [len = 200])
+    recv 215
     sendhex "20020000"
     close
 
-    # MQTT 3.1.1 CONNECT packet (id: test_sub - username: test - passwd: 
passwd)
+    # MQTT 3.1.1 CONNECT packet (id: <empty> - username: test - passwd: passwd)
     accept
-    recv 36
+    recv 28
     sendhex "20020000"
     close
 
@@ -114,14 +114,14 @@
 
 client c1_311_1 -connect ${h1_fe1_sock} {
     # Valid MQTT 3.1.1 CONNECT packet (id: test_sub)
-    sendhex "101400044d5154540402003c0008746573745f737562"
+    sendhex 
"10d40100044d5154540402003c00c8746573745f737562616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161"
     recv 4
     expect_close
 } -run
 
 client c1_311_2 -connect ${h1_fe1_sock} {
-    # Valid MQTT 3.1.1 CONNECT packet (id: test_sub - username: test - passwd: 
passwd)
-    sendhex 
"102200044d51545404c2003c0008746573745f7375620004746573740006706173737764"
+    # Valid MQTT 3.1.1 CONNECT packet (id: <empty> - username: test - passwd: 
passwd)
+    sendhex "101a00044d51545404c2003c00000004746573740006706173737764"
     recv 4
     expect_close
 } -run
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-2.4.1+git0.1ce7d4925/reg-tests/http-messaging/scheme_based_normalize.vtc
 
new/haproxy-2.4.2+git0.553dee326/reg-tests/http-messaging/scheme_based_normalize.vtc
--- 
old/haproxy-2.4.1+git0.1ce7d4925/reg-tests/http-messaging/scheme_based_normalize.vtc
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/haproxy-2.4.2+git0.553dee326/reg-tests/http-messaging/scheme_based_normalize.vtc
        2021-07-07 16:46:09.000000000 +0200
@@ -0,0 +1,125 @@
+varnishtest "scheme based normalization (rfc3982 6.3.2)"
+#REQUIRE_VERSION=2.5
+
+feature ignore_unknown_macro
+
+syslog S1 -level info {
+       recv
+       expect ~ "^.* uri: GET http://hostname/ HTTP/2.0; host: {hostname}$"
+
+       recv
+       expect ~ "^.* uri: GET http://hostname:8080/ HTTP/2.0; host: 
{hostname:8080}$"
+
+       recv
+       expect ~ "^.* uri: GET https://hostname/ HTTP/2.0; host: {hostname}$"
+
+       recv
+       expect ~ "^.* uri: GET https://hostname:80/ HTTP/2.0; host: 
{hostname:80}$"
+} -start
+
+haproxy h1 -conf {
+       defaults
+               mode http
+               timeout connect 5s
+               timeout client  5s
+               timeout server  5s
+
+       frontend fe
+               bind "fd@${fe}" proto h2
+
+               http-request capture req.hdr(host) len 512
+               log-format "uri: %r; host: %hr"
+               log ${S1_addr}:${S1_port} len 2048 local0 debug err
+
+               http-request return status 200
+} -start
+
+# default port 80 with http scheme => should be normalized
+client c1 -connect ${h1_fe_sock} {
+       txpri
+       stream 0 {
+               txsettings
+               rxsettings
+               txsettings -ack
+               rxsettings
+               expect settings.ack == true
+       } -run
+
+       stream 1 {
+               txreq \
+                 -req "GET" \
+                 -scheme "http" \
+                 -url "/" \
+                 -hdr ":authority" "hostname:80"
+               rxhdrs
+               expect resp.status == 200
+       } -run
+} -run
+
+# port 8080 with http scheme => no normalization
+client c2 -connect ${h1_fe_sock} {
+       txpri
+       stream 0 {
+               txsettings
+               rxsettings
+               txsettings -ack
+               rxsettings
+               expect settings.ack == true
+       } -run
+
+       stream 1 {
+               txreq \
+                 -req "GET" \
+                 -scheme "http" \
+                 -url "/" \
+                 -hdr ":authority" "hostname:8080"
+               rxhdrs
+               expect resp.status == 200
+       } -run
+} -run
+
+# default port 443 with https scheme => should be normalized
+client c3 -connect ${h1_fe_sock} {
+       txpri
+       stream 0 {
+               txsettings
+               rxsettings
+               txsettings -ack
+               rxsettings
+               expect settings.ack == true
+       } -run
+
+       stream 1 {
+               txreq \
+                 -req "GET" \
+                 -scheme "https" \
+                 -url "/" \
+                 -hdr ":authority" "hostname:443"
+               rxhdrs
+               expect resp.status == 200
+       } -run
+} -run
+
+# port 80 with https scheme => no normalization
+client c4 -connect ${h1_fe_sock} {
+       txpri
+       stream 0 {
+               txsettings
+               rxsettings
+               txsettings -ack
+               rxsettings
+               expect settings.ack == true
+       } -run
+
+       stream 1 {
+               txreq \
+                 -req "GET" \
+                 -scheme "https" \
+                 -url "/" \
+                 -hdr ":authority" "hostname:80"
+               rxhdrs
+               expect resp.status == 200
+       } -run
+} -run
+
+syslog S1 -wait
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-2.4.1+git0.1ce7d4925/reg-tests/server/cli_set_fdqn.vtc 
new/haproxy-2.4.2+git0.553dee326/reg-tests/server/cli_set_fdqn.vtc
--- old/haproxy-2.4.1+git0.1ce7d4925/reg-tests/server/cli_set_fdqn.vtc  
2021-06-17 09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/reg-tests/server/cli_set_fdqn.vtc  
2021-07-07 16:46:09.000000000 +0200
@@ -28,7 +28,7 @@
 
 haproxy h1 -cli {
     send "set server test/www1 fqdn foo.fqdn"
-    expect ~ "could not update test/www1 FQDN by 'stats socket command'"
+    expect ~ "set server <b>/<s> fqdn failed because no resolution is 
configured."
     send "show servers state test"
     expect ~ "test 1 www1 ${s1_addr} .* - ${s1_port}"
 } -wait
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/backend.c 
new/haproxy-2.4.2+git0.553dee326/src/backend.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/backend.c      2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/backend.c      2021-07-07 
16:46:09.000000000 +0200
@@ -819,7 +819,7 @@
                        sess_change_server(s, srv);
                } else {
                        if (may_dequeue_tasks(conn_slot, s->be))
-                               process_srv_queue(conn_slot);
+                               process_srv_queue(conn_slot, 0);
                }
        }
 
@@ -1835,7 +1835,7 @@
 
                /* release other streams waiting for this server */
                if (may_dequeue_tasks(srv, s->be))
-                       process_srv_queue(srv);
+                       process_srv_queue(srv, 0);
                return 1;
        }
        /* if we get here, it's because we got SRV_STATUS_OK, which also
@@ -1911,7 +1911,7 @@
                        /* release other streams waiting for this server */
                        sess_change_server(s, NULL);
                        if (may_dequeue_tasks(srv, s->be))
-                               process_srv_queue(srv);
+                               process_srv_queue(srv, 0);
 
                        /* Failed and not retryable. */
                        si_shutr(si);
@@ -2239,7 +2239,7 @@
                _HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
                sess_change_server(s, NULL);
                if (may_dequeue_tasks(objt_server(s->target), s->be))
-                       process_srv_queue(objt_server(s->target));
+                       process_srv_queue(objt_server(s->target), 0);
 
                /* shutw is enough so stop a connecting socket */
                si_shutw(si);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/cache.c 
new/haproxy-2.4.2+git0.553dee326/src/cache.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/cache.c        2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/cache.c        2021-07-07 
16:46:09.000000000 +0200
@@ -2280,6 +2280,19 @@
        /* Iterate over all the ACCEPT_ENCODING_MAX_ENTRIES first 
accept-encoding
         * values that might span acrosse multiple accept-encoding headers. */
        while (http_find_header(htx, hdr_name, &ctx, 0) && count < 
ACCEPT_ENCODING_MAX_ENTRIES) {
+               count++;
+
+               /* As per RFC7231#5.3.4, "An Accept-Encoding header field with a
+                * combined field-value that is empty implies that the user 
agent
+                * does not want any content-coding in response."
+                *
+                * We must (and did) count the existence of this empty header 
to not
+                * hit the `count == 0` case below, but must ignore the value 
to not
+                * include VARY_ENCODING_OTHER into the final bitmap.
+                */
+               if (istlen(ctx.value) == 0)
+                       continue;
+
                /* Turn accept-encoding value to lower case */
                ist2bin_lc(istptr(ctx.value), ctx.value);
 
@@ -2294,8 +2307,6 @@
                        /* Unknown encoding */
                        encoding_bitmap |= VARY_ENCODING_OTHER;
                }
-
-               count++;
        }
 
        /* If a "*" was found in the accepted encodings (without a null weight),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/check.c 
new/haproxy-2.4.2+git0.553dee326/src/check.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/check.c        2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/check.c        2021-07-07 
16:46:09.000000000 +0200
@@ -1897,7 +1897,7 @@
        srv->do_agent = 1;
 
   out:
-       return 0;
+       return err_code;
 
   error:
        deinit_srv_agent_check(srv);
@@ -2155,7 +2155,6 @@
        deinit_srv_agent_check(srv);
        err_code |= ERR_ALERT | ERR_FATAL;
        goto out;
-       return 0;
 }
 
 /* Parse the "fall" server keyword */
@@ -2182,7 +2181,6 @@
        deinit_srv_agent_check(srv);
        err_code |= ERR_ALERT | ERR_FATAL;
        goto out;
-       return 0;
 }
 
 /* Parse the "inter" server keyword */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/cli.c 
new/haproxy-2.4.2+git0.553dee326/src/cli.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/cli.c  2021-06-17 09:06:08.000000000 
+0200
+++ new/haproxy-2.4.2+git0.553dee326/src/cli.c  2021-07-07 16:46:09.000000000 
+0200
@@ -1281,7 +1281,7 @@
                        if (px)
                                chunk_appendf(&trash, " px=%s", px->id);
                        else if (sv)
-                               chunk_appendf(&trash, " sv=%s/%s", sv->id, 
sv->proxy->id);
+                               chunk_appendf(&trash, " sv=%s/%s", 
sv->proxy->id, sv->id);
                        else if (li)
                                chunk_appendf(&trash, " fe=%s", 
li->bind_conf->frontend->id);
 
@@ -2580,7 +2580,7 @@
                                
HA_ATOMIC_DEC(&__objt_server(s->target)->cur_sess);
                        }
                        if (may_dequeue_tasks(__objt_server(s->target), be))
-                               process_srv_queue(__objt_server(s->target));
+                               process_srv_queue(__objt_server(s->target), 0);
                }
 
                s->target = NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/dns.c 
new/haproxy-2.4.2+git0.553dee326/src/dns.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/dns.c  2021-06-17 09:06:08.000000000 
+0200
+++ new/haproxy-2.4.2+git0.553dee326/src/dns.c  2021-07-07 16:46:09.000000000 
+0200
@@ -170,7 +170,6 @@
 
                if (!LIST_ISEMPTY(&dss->wait_sess)) {
                        ds = LIST_NEXT(&dss->wait_sess, struct dns_session *, 
waiter);
-                       fprintf(stderr, "ds: %p\n", ds);
                        ret = ds->rx_msg.len < size ? ds->rx_msg.len : size;
                        memcpy(data, ds->rx_msg.area, ret);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/h1_htx.c 
new/haproxy-2.4.2+git0.553dee326/src/h1_htx.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/h1_htx.c       2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/h1_htx.c       2021-07-07 
16:46:09.000000000 +0200
@@ -16,6 +16,7 @@
 #include <haproxy/h1.h>
 #include <haproxy/h1_htx.h>
 #include <haproxy/http.h>
+#include <haproxy/http_htx.h>
 #include <haproxy/htx.h>
 #include <haproxy/tools.h>
 
@@ -191,6 +192,10 @@
                sl->flags |= (HTX_SL_F_HAS_AUTHORITY|HTX_SL_F_HAS_SCHM);
                if (uri.len > 4 && (uri.ptr[0] | 0x20) == 'h')
                        sl->flags |= ((uri.ptr[4] == ':') ? HTX_SL_F_SCHM_HTTP 
: HTX_SL_F_SCHM_HTTPS);
+
+               /* absolute-form target URI present, proceed to scheme-based
+                * normalization */
+               http_scheme_based_normalize(htx);
        }
 
        /* If body length cannot be determined, set htx->extra to
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/h2.c 
new/haproxy-2.4.2+git0.553dee326/src/h2.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/h2.c   2021-06-17 09:06:08.000000000 
+0200
+++ new/haproxy-2.4.2+git0.553dee326/src/h2.c   2021-07-07 16:46:09.000000000 
+0200
@@ -31,6 +31,7 @@
 #include <haproxy/h2.h>
 #include <haproxy/http-hdr-t.h>
 #include <haproxy/http.h>
+#include <haproxy/http_htx.h>
 #include <haproxy/htx.h>
 #include <import/ist.h>
 
@@ -553,6 +554,10 @@
        if (!htx_add_endof(htx, HTX_BLK_EOH))
                goto fail;
 
+       /* proceed to scheme-based normalization on target-URI */
+       if (fields & H2_PHDR_FND_SCHM)
+               http_scheme_based_normalize(htx);
+
        ret = 1;
        return ret;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/http.c 
new/haproxy-2.4.2+git0.553dee326/src/http.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/http.c 2021-06-17 09:06:08.000000000 
+0200
+++ new/haproxy-2.4.2+git0.553dee326/src/http.c 2021-07-07 16:46:09.000000000 
+0200
@@ -468,6 +468,56 @@
        }
 }
 
+/* Parse the uri and looks for the scheme. If not found, an empty ist is
+ * returned. Otherwise, the ist pointing to the scheme is returned.
+ */
+struct ist http_get_scheme(const struct ist uri)
+{
+       const char *ptr, *start, *end;
+
+       if (!uri.len)
+               goto not_found;
+
+       ptr = uri.ptr;
+       start = ptr;
+       end = ptr + uri.len;
+
+       /* RFC7230, par. 2.7 :
+        * Request-URI = "*" | absuri | abspath | authority
+        */
+
+       if (*ptr == '*' || *ptr == '/')
+               goto not_found;
+
+       if (isalpha((unsigned char)*ptr)) {
+               /* this is a scheme as described by RFC3986, par. 3.1, or only
+                * an authority (in case of a CONNECT method).
+                */
+               ptr++;
+               /* retrieve the scheme up to the suffix '://'. If the suffix is
+                * not found, this means there is no scheme and it is an
+                * authority-only uri.
+                */
+               while (ptr < end &&
+                      (isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == 
'-' || *ptr == '.'))
+                       ptr++;
+               if (ptr == end || *ptr++ != ':')
+                       goto not_found;
+               if (ptr == end || *ptr++ != '/')
+                       goto not_found;
+               if (ptr == end || *ptr++ != '/')
+                       goto not_found;
+       }
+       else {
+               goto not_found;
+       }
+
+       return ist2(start, ptr - start);
+
+ not_found:
+       return IST_NULL;
+}
+
 /* Parse the uri and looks for the authority, between the scheme and the
  * path. if no_userinfo is not zero, the part before the '@' (including it) is
  * skipped. If not found, an empty ist is returned. Otherwise, the ist pointing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/http_htx.c 
new/haproxy-2.4.2+git0.553dee326/src/http_htx.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/http_htx.c     2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/http_htx.c     2021-07-07 
16:46:09.000000000 +0200
@@ -11,6 +11,7 @@
  */
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <ctype.h>
 #include <fcntl.h>
 #include <unistd.h>
 
@@ -1718,6 +1719,95 @@
        return NULL;
 }
 
+static int uri_is_default_port(const struct ist scheme, const struct ist port)
+{
+       return (isteq(port, ist("443")) && isteqi(scheme, ist("https://";))) ||
+               (isteq(port, ist("80")) && isteqi(scheme, ist("http://";)));
+}
+
+/* Apply schemed-based normalization as described on rfc3986 on section 6.3.2.
+ * Returns 0 if no error has been found else non-zero.
+ *
+ * The normalization is processed on the target-uri at the condition that it is
+ * in absolute-form. In the case where the target-uri was normalized, every
+ * host headers values found are also replaced by the normalized hostname. This
+ * assumes that the target-uri and host headers were properly identify as
+ * similar before calling this function.
+ */
+int http_scheme_based_normalize(struct htx *htx)
+{
+       struct http_hdr_ctx ctx;
+       struct htx_sl *sl;
+       struct ist uri, scheme, authority, host, port;
+       char *start, *end, *ptr;
+
+       sl = http_get_stline(htx);
+
+       if (!sl || !(sl->flags & (HTX_SL_F_HAS_SCHM|HTX_SL_F_HAS_AUTHORITY)))
+               return 0;
+
+       uri = htx_sl_req_uri(sl);
+
+       scheme = http_get_scheme(uri);
+       /* if no scheme found, no normalization to proceed */
+       if (!isttest(scheme))
+               return 0;
+
+       /* Extract the port if present in authority. To properly support ipv6
+        * hostnames, do a reverse search on the last ':' separator as long as
+        * digits are found.
+        */
+       authority = http_get_authority(uri, 0);
+       start = istptr(authority);
+       end = istend(authority);
+       for (ptr = end; ptr > start && isdigit(*--ptr); )
+               ;
+
+       /* if no port found, no normalization to proceed */
+       if (likely(*ptr != ':'))
+               return 0;
+
+       /* split host/port on the ':' separator found */
+       host = ist2(start, ptr - start);
+       port = istnext(ist2(ptr, end - ptr));
+
+       if (istlen(port) && uri_is_default_port(scheme, port)) {
+               /* reconstruct the uri with removal of the port */
+               struct buffer *temp = get_trash_chunk();
+               struct ist meth, vsn, path;
+
+               /* meth */
+               chunk_memcat(temp, HTX_SL_REQ_MPTR(sl), HTX_SL_REQ_MLEN(sl));
+               meth = ist2(temp->area, HTX_SL_REQ_MLEN(sl));
+
+               /* vsn */
+               chunk_memcat(temp, HTX_SL_REQ_VPTR(sl), HTX_SL_REQ_VLEN(sl));
+               vsn = ist2(temp->area + meth.len, HTX_SL_REQ_VLEN(sl));
+
+               /* reconstruct uri without port */
+               path = http_get_path(uri);
+               chunk_istcat(temp, scheme);
+               chunk_istcat(temp, host);
+               chunk_istcat(temp, path);
+               uri = ist2(temp->area + meth.len + vsn.len,
+                          scheme.len + host.len + path.len);
+
+               http_replace_stline(htx, meth, uri, vsn);
+
+               /* replace every host headers values by the normalized host */
+               ctx.blk = NULL;
+               while (http_find_header(htx, ist("host"), &ctx, 0)) {
+                       if (!http_replace_header_value(htx, &ctx, host))
+                               goto fail;
+               }
+       }
+
+       return 0;
+
+ fail:
+       return 1;
+}
+
 /* Parses the "errorloc[302|303]" proxy keyword */
 static int proxy_parse_errorloc(char **args, int section, struct proxy *curpx,
                                  const struct proxy *defpx, const char *file, 
int line,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/mqtt.c 
new/haproxy-2.4.2+git0.553dee326/src/mqtt.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/mqtt.c 2021-06-17 09:06:08.000000000 
+0200
+++ new/haproxy-2.4.2+git0.553dee326/src/mqtt.c 2021-07-07 16:46:09.000000000 
+0200
@@ -288,15 +288,14 @@
  */
 static inline struct ist mqtt_read_string(struct ist parser, struct ist *str)
 {
-       uint16_t len;
+       uint16_t len = 0;
 
        /* read and compute the string length */
-       if (istlen(parser) <= 2)
+       if (istlen(parser) < 2)
                goto error;
 
-       len = ((uint16_t)*istptr(parser) << 8) + (uint16_t)*(istptr(parser) + 
1);
-       parser = istadv(parser, 2);
-       if (istlen(parser) < len)
+       parser = mqtt_read_2byte_int(parser, &len);
+       if (!isttest(parser) || istlen(parser) < len)
                goto error;
 
        if (str) {
@@ -863,7 +862,7 @@
         */
        /* read client identifier */
        parser = mqtt_read_string(parser, 
&mpkt->data.connect.payload.client_identifier);
-       if (!isttest(parser) || 
!istlen(mpkt->data.connect.payload.client_identifier))
+       if (!isttest(parser))
                goto end;
 
        /* read Will Properties, for MQTT v5 only
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/peers.c 
new/haproxy-2.4.2+git0.553dee326/src/peers.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/peers.c        2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/peers.c        2021-07-07 
16:46:09.000000000 +0200
@@ -845,10 +845,10 @@
                                case STD_T_UINT:
                                case STD_T_ULL:
                                case STD_T_DICT:
-                                       data |= 1 << data_type;
+                                       data |= 1ULL << data_type;
                                        break;
                                case STD_T_FRQP:
-                                       data |= 1 << data_type;
+                                       data |= 1ULL << data_type;
                                        intencode(data_type, &chunkq);
                                        
intencode(st->table->data_arg[data_type].u, &chunkq);
                                        break;
@@ -1657,7 +1657,7 @@
        for (data_type = 0 ; data_type < STKTABLE_DATA_TYPES ; data_type++) {
                uint64_t decoded_int;
 
-               if (!((1 << data_type) & st->remote_data))
+               if (!((1ULL << data_type) & st->remote_data))
                        continue;
 
                decoded_int = intdecode(msg_cur, msg_end);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/queue.c 
new/haproxy-2.4.2+git0.553dee326/src/queue.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/queue.c        2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/queue.c        2021-07-07 
16:46:09.000000000 +0200
@@ -337,14 +337,16 @@
 }
 
 /* Manages a server's connection queue. This function will try to dequeue as
- * many pending streams as possible, and wake them up.
+ * many pending streams as possible, and wake them up. <server_locked> must
+ * only be set if the caller already hold the server lock.
  */
-void process_srv_queue(struct server *s)
+void process_srv_queue(struct server *s, int server_locked)
 {
        struct proxy  *p = s->proxy;
        int maxconn;
 
-       HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
+       if (!server_locked)
+               HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
        HA_RWLOCK_WRLOCK(PROXY_LOCK,  &p->lock);
        maxconn = srv_dynamic_maxconn(s);
        while (s->served < maxconn) {
@@ -353,7 +355,8 @@
                        break;
        }
        HA_RWLOCK_WRUNLOCK(PROXY_LOCK,  &p->lock);
-       HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
+       if (!server_locked)
+               HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
 }
 
 /* Adds the stream <strm> to the pending connection queue of server <strm>->srv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/resolvers.c 
new/haproxy-2.4.2+git0.553dee326/src/resolvers.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/resolvers.c    2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/resolvers.c    2021-07-07 
16:46:09.000000000 +0200
@@ -571,6 +571,52 @@
        return 0;
 }
 
+/* Cleanup fqdn/port and address of a server attached to a SRV resolution. This
+ * happens when an SRV item is purged or when the server status is considered 
as
+ * obsolete.
+ *
+ * Must be called with the DNS lock held.
+ */
+static void resolv_srvrq_cleanup_srv(struct server *srv)
+{
+       resolv_unlink_resolution(srv->resolv_requester, 0);
+       HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
+       srvrq_update_srv_status(srv, 1);
+       ha_free(&srv->hostname);
+       ha_free(&srv->hostname_dn);
+       srv->hostname_dn_len = 0;
+       memset(&srv->addr, 0, sizeof(srv->addr));
+       srv->svc_port = 0;
+       srv->flags |= SRV_F_NO_RESOLUTION;
+
+       ebpt_delete(&srv->host_dn);
+       ha_free(&srv->host_dn.key);
+
+       HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
+       LIST_DELETE(&srv->srv_rec_item);
+       LIST_APPEND(&srv->srvrq->attached_servers, &srv->srv_rec_item);
+
+       srv->srvrq_check->expire = TICK_ETERNITY;
+}
+
+/* Takes care to cleanup a server resolution when it is outdated. This only
+ * happens for a server relying on a SRV record.
+ */
+static struct task *resolv_srvrq_expire_task(struct task *t, void *context, 
unsigned int state)
+{
+       struct server *srv = context;
+
+       if (!tick_is_expired(t->expire, now_ms))
+               goto end;
+
+       HA_SPIN_LOCK(DNS_LOCK, &srv->srvrq->resolvers->lock);
+       resolv_srvrq_cleanup_srv(srv);
+       HA_SPIN_UNLOCK(DNS_LOCK, &srv->srvrq->resolvers->lock);
+
+  end:
+       return t;
+}
+
 /* Checks for any obsolete record, also identify any SRV request, and try to
  * find a corresponding server.
 */
@@ -604,20 +650,8 @@
                        }
                        else if (item->type == DNS_RTYPE_SRV) {
                                /* Remove any associated server */
-                               list_for_each_entry_safe(srv, srvback, 
&item->attached_servers, srv_rec_item) {
-                                       
resolv_unlink_resolution(srv->resolv_requester, 0);
-                                       HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
-                                       srvrq_update_srv_status(srv, 1);
-                                       ha_free(&srv->hostname);
-                                       ha_free(&srv->hostname_dn);
-                                       srv->hostname_dn_len = 0;
-                                       memset(&srv->addr, 0, 
sizeof(srv->addr));
-                                       srv->svc_port = 0;
-                                       srv->flags |= SRV_F_NO_RESOLUTION;
-                                       HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
-                                       LIST_DELETE(&srv->srv_rec_item);
-                                       
LIST_APPEND(&srv->srvrq->attached_servers, &srv->srv_rec_item);
-                               }
+                               list_for_each_entry_safe(srv, srvback, 
&item->attached_servers, srv_rec_item)
+                                       resolv_srvrq_cleanup_srv(srv);
                        }
 
                        LIST_DELETE(&item->list);
@@ -675,7 +709,7 @@
                                                if (srv->svc_port == 
item->port) {
                                                        /* server found, we 
remove it from tree */
                                                        ebpt_delete(node);
-                                                       free(srv->host_dn.key);
+                                                       
ha_free(&srv->host_dn.key);
                                                        goto srv_found;
                                                }
 
@@ -713,6 +747,7 @@
                        if (srv) {
                                /* re-enable DNS resolution for this server by 
default */
                                srv->flags &= ~SRV_F_NO_RESOLUTION;
+                               srv->srvrq_check->expire = TICK_ETERNITY;
 
                                /* Check if an Additional Record is associated 
to this SRV record.
                                 * Perform some sanity checks too to ensure the 
record can be used.
@@ -1543,8 +1578,6 @@
                        *newip = newip6;
                        *newip_sin_family = AF_INET6;
                }
-               if (!currentip_found)
-                       goto not_found;
        }
        /* Case when the caller looks first for an IPv6 address */
        else if (family_priority == AF_INET6) {
@@ -1556,8 +1589,6 @@
                        *newip = newip4;
                        *newip_sin_family = AF_INET;
                }
-               if (!currentip_found)
-                       goto not_found;
        }
        /* Case when the caller have no preference (we prefer IPv6) */
        else if (family_priority == AF_UNSPEC) {
@@ -1569,17 +1600,11 @@
                        *newip = newip4;
                        *newip_sin_family = AF_INET;
                }
-               if (!currentip_found)
-                       goto not_found;
        }
 
-       /* No reason why we should change the server's IP address */
-       return RSLV_UPD_NO;
-
- not_found:
-
        /* the ip of this record was chosen for the server */
        if (owner && found_record) {
+               LIST_DEL_INIT(&owner->ip_rec_item);
                LIST_APPEND(&found_record->attached_servers, 
&owner->ip_rec_item);
        }
 
@@ -1590,7 +1615,8 @@
                LIST_APPEND(&r_res->answer_list, &record->list);
                break;
        }
-       return RSLV_UPD_SRVIP_NOT_FOUND;
+
+       return (currentip_found ? RSLV_UPD_NO : RSLV_UPD_SRVIP_NOT_FOUND);
 }
 
 /* Turns a domain name label into a string.
@@ -1930,20 +1956,8 @@
                list_for_each_entry_safe(item, itemback, 
&res->response.answer_list, list) {
                        if (item->type == DNS_RTYPE_SRV) {
                                list_for_each_entry_safe(srv, srvback, 
&item->attached_servers, srv_rec_item) {
-                                       if (srv->srvrq == srvrq) {
-                                               HA_SPIN_LOCK(SERVER_LOCK, 
&srv->lock);
-                                               
resolv_unlink_resolution(srv->resolv_requester, safe);
-                                               srvrq_update_srv_status(srv, 1);
-                                               ha_free(&srv->hostname);
-                                               ha_free(&srv->hostname_dn);
-                                               srv->hostname_dn_len = 0;
-                                               memset(&srv->addr, 0, 
sizeof(srv->addr));
-                                               srv->svc_port = 0;
-                                               srv->flags |= 
SRV_F_NO_RESOLUTION;
-                                               HA_SPIN_UNLOCK(SERVER_LOCK, 
&srv->lock);
-                                               LIST_DELETE(&srv->srv_rec_item);
-                                               
LIST_APPEND(&srvrq->attached_servers, &srv->srv_rec_item);
-                                       }
+                                       if (srv->srvrq == srvrq)
+                                               resolv_srvrq_cleanup_srv(srv);
                                }
                        }
                }
@@ -2426,17 +2440,30 @@
                                continue;
                        }
                        srv->resolvers = resolvers;
+                       srv->srvrq_check = NULL;
+                       if (srv->srvrq) {
+                               if (!srv->srvrq->resolvers) {
+                                       srv->srvrq->resolvers = srv->resolvers;
+                                       if (resolv_link_resolution(srv->srvrq, 
OBJ_TYPE_SRVRQ, 0) == -1) {
+                                               ha_alert("config : %s '%s' : 
unable to set DNS resolution for server '%s'.\n",
+                                                        proxy_type_str(px), 
px->id, srv->id);
+                                               err_code |= 
(ERR_ALERT|ERR_ABORT);
+                                               continue;
+                                       }
+                               }
 
-                       if (srv->srvrq && !srv->srvrq->resolvers) {
-                               srv->srvrq->resolvers = srv->resolvers;
-                               if (resolv_link_resolution(srv->srvrq, 
OBJ_TYPE_SRVRQ, 0) == -1) {
-                                       ha_alert("config : %s '%s' : unable to 
set DNS resolution for server '%s'.\n",
+                               srv->srvrq_check = task_new(MAX_THREADS_MASK);
+                               if (!srv->srvrq_check) {
+                                       ha_alert("config: %s '%s' : unable to 
create SRVRQ task for server '%s'.\n",
                                                 proxy_type_str(px), px->id, 
srv->id);
                                        err_code |= (ERR_ALERT|ERR_ABORT);
-                                       continue;
+                                       goto err;
                                }
+                               srv->srvrq_check->process = 
resolv_srvrq_expire_task;
+                               srv->srvrq_check->context = srv;
+                               srv->srvrq_check->expire = TICK_ETERNITY;
                        }
-                       if (!srv->srvrq && resolv_link_resolution(srv, 
OBJ_TYPE_SERVER, 0) == -1) {
+                       else if (resolv_link_resolution(srv, OBJ_TYPE_SERVER, 
0) == -1) {
                                ha_alert("config : %s '%s', unable to set DNS 
resolution for server '%s'.\n",
                                         proxy_type_str(px), px->id, srv->id);
                                err_code |= (ERR_ALERT|ERR_ABORT);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/server.c 
new/haproxy-2.4.2+git0.553dee326/src/server.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/server.c       2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/server.c       2021-07-07 
16:46:09.000000000 +0200
@@ -1812,16 +1812,17 @@
        else if (end[0] != '\0')
                return "Trailing garbage in maxconn string";
 
-       HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
        if (sv->maxconn == sv->minconn) { // static maxconn
                sv->maxconn = sv->minconn = v;
        } else { // dynamic maxconn
                sv->maxconn = v;
        }
-       HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
 
+       /* server_parse_maxconn_change_request requires the server lock held.
+        * Specify it to process_srv_queue to prevent a deadlock.
+        */
        if (may_dequeue_tasks(sv, sv->proxy))
-               process_srv_queue(sv);
+               process_srv_queue(sv, 1);
 
        return NULL;
 }
@@ -2205,6 +2206,7 @@
 void free_server(struct server *srv)
 {
        task_destroy(srv->warmup);
+       task_destroy(srv->srvrq_check);
 
        free(srv->id);
        free(srv->cookie);
@@ -2472,6 +2474,7 @@
                                        err_code |= ERR_ALERT | ERR_FATAL;
                                        goto out;
                                }
+                               LIST_APPEND(&newsrv->srvrq->attached_servers, 
&newsrv->srv_rec_item);
                        }
                        else if (srv_prepare_for_resolution(newsrv, fqdn) == 
-1) {
                                memprintf(errmsg, "Can't create DNS resolution 
for server '%s'",
@@ -3414,9 +3417,6 @@
                case RSLV_UPD_SRVIP_NOT_FOUND:
                        goto save_ip;
 
-               case RSLV_UPD_CNAME:
-                       goto invalid;
-
                case RSLV_UPD_NO_IP_FOUND:
                        has_no_ip = 1;
                        goto update_status;
@@ -3424,9 +3424,11 @@
                case RSLV_UPD_NAME_ERROR:
                        /* update resolution status to OTHER error type */
                        resolution->status = RSLV_STATUS_OTHER;
+                       has_no_ip = 1;
                        goto update_status;
 
                default:
+                       has_no_ip = 1;
                        goto invalid;
 
        }
@@ -3442,8 +3444,8 @@
        srv_update_addr(s, firstip, firstip_sin_family, (char *) chk->area);
 
  update_status:
-
-       snr_update_srv_status(s, has_no_ip);
+       if (!snr_update_srv_status(s, has_no_ip) && has_no_ip)
+               memset(&s->addr, 0, sizeof(s->addr));
        return 1;
 
  invalid:
@@ -3451,7 +3453,8 @@
                counters->invalid++;
                goto update_status;
        }
-       snr_update_srv_status(s, has_no_ip);
+       if (!snr_update_srv_status(s, has_no_ip) && has_no_ip)
+               memset(&s->addr, 0, sizeof(s->addr));
        return 0;
 }
 
@@ -3912,14 +3915,15 @@
        if (!sv)
                return 1;
 
-       HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
-
        if (strcmp(args[3], "weight") == 0) {
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
                warning = server_parse_weight_change_request(sv, args[4]);
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
                if (warning)
                        cli_err(appctx, warning);
        }
        else if (strcmp(args[3], "state") == 0) {
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
                if (strcmp(args[4], "ready") == 0)
                        srv_adm_set_ready(sv);
                else if (strcmp(args[4], "drain") == 0)
@@ -3928,8 +3932,10 @@
                        srv_adm_set_maint(sv);
                else
                        cli_err(appctx, "'set server <srv> state' expects 
'ready', 'drain' and 'maint'.\n");
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
        }
        else if (strcmp(args[3], "health") == 0) {
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
                if (sv->track)
                        cli_err(appctx, "cannot change health on a tracking 
server.\n");
                else if (strcmp(args[4], "up") == 0) {
@@ -3946,8 +3952,10 @@
                }
                else
                        cli_err(appctx, "'set server <srv> health' expects 
'up', 'stopping', or 'down'.\n");
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
        }
        else if (strcmp(args[3], "agent") == 0) {
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
                if (!(sv->agent.state & CHK_ST_ENABLED))
                        cli_err(appctx, "agent checks are not enabled on this 
server.\n");
                else if (strcmp(args[4], "up") == 0) {
@@ -3960,6 +3968,7 @@
                }
                else
                        cli_err(appctx, "'set server <srv> agent' expects 'up' 
or 'down'.\n");
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
        }
        else if (strcmp(args[3], "agent-addr") == 0) {
                char *addr = NULL;
@@ -3967,12 +3976,14 @@
                if (strlen(args[4]) == 0) {
                        cli_err(appctx, "set server <b>/<s> agent-addr requires"
                                        " an address and optionally a port.\n");
-                       goto out_unlock;
+                       goto out;
                }
                addr = args[4];
                if (strcmp(args[5], "port") == 0)
                        port = args[6];
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
                warning = srv_update_agent_addr_port(sv, addr, port);
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
                if (warning)
                        cli_msg(appctx, LOG_WARNING, warning);
        }
@@ -3981,20 +3992,24 @@
                if (strlen(args[4]) == 0) {
                        cli_err(appctx, "set server <b>/<s> agent-port requires"
                                        " a port.\n");
-                       goto out_unlock;
+                       goto out;
                }
                port = args[4];
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
                warning = srv_update_agent_addr_port(sv, NULL, port);
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
                if (warning)
                        cli_msg(appctx, LOG_WARNING, warning);
        }
        else if (strcmp(args[3], "agent-send") == 0) {
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
                if (!(sv->agent.state & CHK_ST_ENABLED))
                        cli_err(appctx, "agent checks are not enabled on this 
server.\n");
                else {
                        if (!set_srv_agent_send(sv, args[4]))
                                cli_err(appctx, "cannot allocate memory for new 
string.\n");
                }
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
        }
        else if (strcmp(args[3], "check-addr") == 0) {
                char *addr = NULL;
@@ -4002,12 +4017,14 @@
                if (strlen(args[4]) == 0) {
                        cli_err(appctx, "set server <b>/<s> check-addr requires"
                                        " an address and optionally a port.\n");
-                       goto out_unlock;
+                       goto out;
                }
                addr = args[4];
                if (strcmp(args[5], "port") == 0)
                        port = args[6];
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
                warning = srv_update_check_addr_port(sv, addr, port);
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
                if (warning)
                        cli_msg(appctx, LOG_WARNING, warning);
        }
@@ -4016,10 +4033,12 @@
                if (strlen(args[4]) == 0) {
                        cli_err(appctx, "set server <b>/<s> check-port requires"
                                        " a port.\n");
-                       goto out_unlock;
+                       goto out;
                }
                port = args[4];
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
                warning = srv_update_check_addr_port(sv, NULL, port);
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
                if (warning)
                        cli_msg(appctx, LOG_WARNING, warning);
        }
@@ -4028,7 +4047,7 @@
                char *port = NULL;
                if (strlen(args[4]) == 0) {
                        cli_err(appctx, "set server <b>/<s> addr requires an 
address and optionally a port.\n");
-                       goto out_unlock;
+                       goto out;
                }
                else {
                        addr = args[4];
@@ -4036,21 +4055,35 @@
                if (strcmp(args[5], "port") == 0) {
                        port = args[6];
                }
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
                warning = srv_update_addr_port(sv, addr, port, "stats socket 
command");
                if (warning)
                        cli_msg(appctx, LOG_WARNING, warning);
                srv_clr_admin_flag(sv, SRV_ADMF_RMAINT);
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
        }
        else if (strcmp(args[3], "fqdn") == 0) {
                if (!*args[4]) {
                        cli_err(appctx, "set server <b>/<s> fqdn requires a 
FQDN.\n");
-                       goto out_unlock;
+                       goto out;
+               }
+               if (!sv->resolvers) {
+                       cli_err(appctx, "set server <b>/<s> fqdn failed because 
no resolution is configured.\n");
+                       goto out;
                }
+               if (sv->srvrq) {
+                       cli_err(appctx, "set server <b>/<s> fqdn failed because 
SRV resolution is configured.\n");
+                       goto out;
+               }
+               HA_SPIN_LOCK(DNS_LOCK, &sv->resolvers->lock);
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
                /* ensure runtime resolver will process this new fqdn */
                if (sv->flags & SRV_F_NO_RESOLUTION) {
                        sv->flags &= ~SRV_F_NO_RESOLUTION;
                }
-               warning = srv_update_fqdn(sv, args[4], "stats socket command", 
0);
+               warning = srv_update_fqdn(sv, args[4], "stats socket command", 
1);
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
+               HA_SPIN_UNLOCK(DNS_LOCK, &sv->resolvers->lock);
                if (warning)
                        cli_msg(appctx, LOG_WARNING, warning);
        }
@@ -4059,16 +4092,21 @@
                if (sv->ssl_ctx.ctx == NULL) {
                        cli_err(appctx, "'set server <srv> ssl' cannot be set. "
                                        " default-server should define ssl 
settings\n");
-                       goto out_unlock;
-               } else if (strcmp(args[4], "on") == 0) {
+                       goto out;
+               }
+
+               HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
+               if (strcmp(args[4], "on") == 0) {
                        ssl_sock_set_srv(sv, 1);
                } else if (strcmp(args[4], "off") == 0) {
                        ssl_sock_set_srv(sv, 0);
                } else {
+                       HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
                        cli_err(appctx, "'set server <srv> ssl' expects 'on' or 
'off'.\n");
-                       goto out_unlock;
+                       goto out;
                }
                srv_cleanup_connections(sv);
+               HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
                cli_msg(appctx, LOG_NOTICE, "server ssl setting updated.\n");
 #else
                cli_msg(appctx, LOG_NOTICE, "server ssl setting not 
supported.\n");
@@ -4080,8 +4118,7 @@
                        "check-addr | check-port | fqdn | health | ssl | "
                        "state | weight\n");
        }
- out_unlock:
-       HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
+ out:
        return 1;
 }
 
@@ -4159,10 +4196,14 @@
        if (!sv)
                return 1;
 
+       HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
+
        warning = server_parse_maxconn_change_request(sv, args[4]);
        if (warning)
                cli_err(appctx, warning);
 
+       HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
+
        return 1;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/server_state.c 
new/haproxy-2.4.2+git0.553dee326/src/server_state.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/server_state.c 2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/server_state.c 2021-07-07 
16:46:09.000000000 +0200
@@ -397,16 +397,12 @@
                char *tmp;
 
                /* we can't apply previous state if SRV record has changed */
-               if (srv->srvrq && strcmp(srv->srvrq->name, srvrecord) != 0) {
-                       chunk_appendf(msg, ", SRV record mismatch between 
configuration ('%s') and state file ('%s) for server '%s'. Previous state not 
applied", srv->srvrq->name, srvrecord, srv->id);
+               if (!srv->srvrq) {
+                       chunk_appendf(msg, ", no SRV resolution for server 
'%s'. Previous state not applied", srv->id);
                        goto out;
                }
-
-               /* create or find a SRV resolution for this srv record */
-               if (srv->srvrq == NULL && (srv->srvrq = 
find_srvrq_by_name(srvrecord, srv->proxy)) == NULL)
-                       srv->srvrq = new_resolv_srvrq(srv, srvrecord);
-               if (srv->srvrq == NULL) {
-                       chunk_appendf(msg, ", can't create or find SRV 
resolution '%s' for server '%s'", srvrecord, srv->id);
+               if (strcmp(srv->srvrq->name, srvrecord) != 0) {
+                       chunk_appendf(msg, ", SRV record mismatch between 
configuration ('%s') and state file ('%s) for server '%s'. Previous state not 
applied", srv->srvrq->name, srvrecord, srv->id);
                        goto out;
                }
 
@@ -429,8 +425,9 @@
                for (i = 0; tmp[i]; i++)
                        tmp[i] = tolower(tmp[i]);
 
-               /* insert in tree */
+               /* insert in tree and set the srvrq expiration date */
                ebis_insert(&srv->srvrq->named_servers, &srv->host_dn);
+               task_schedule(srv->srvrq_check, tick_add(now_ms, 
srv->srvrq->resolvers->hold.timeout));
 
                /* Unset SRV_F_MAPPORTS for SRV records.
                 * SRV_F_MAPPORTS is unfortunately set by parse_server()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/sock.c 
new/haproxy-2.4.2+git0.553dee326/src/sock.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/sock.c 2021-06-17 09:06:08.000000000 
+0200
+++ new/haproxy-2.4.2+git0.553dee326/src/sock.c 2021-07-07 16:46:09.000000000 
+0200
@@ -667,7 +667,7 @@
        if (!(conn->flags & CO_FL_WAIT_L4_CONN))
                return 1; /* strange we were called while ready */
 
-       if (!fd_send_ready(fd))
+       if (!fd_send_ready(fd) && !(fdtab[fd].state & 
(FD_POLL_ERR|FD_POLL_HUP)))
                return 0;
 
        /* Here we have 2 cases :
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/stick_table.c 
new/haproxy-2.4.2+git0.553dee326/src/stick_table.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/stick_table.c  2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/stick_table.c  2021-07-07 
16:46:09.000000000 +0200
@@ -3615,7 +3615,7 @@
                if (t->data_ofs[dt] == 0)
                        continue;
                if (stktable_data_types[dt].arg_type == ARG_T_DELAY)
-                       chunk_appendf(msg, " %s(%d)=", 
stktable_data_types[dt].name, t->data_arg[dt].u);
+                       chunk_appendf(msg, " %s(%u)=", 
stktable_data_types[dt].name, t->data_arg[dt].u);
                else
                        chunk_appendf(msg, " %s=", 
stktable_data_types[dt].name);
 
@@ -3628,10 +3628,10 @@
                        chunk_appendf(msg, "%u", stktable_data_cast(ptr, 
std_t_uint));
                        break;
                case STD_T_ULL:
-                       chunk_appendf(msg, "%lld", stktable_data_cast(ptr, 
std_t_ull));
+                       chunk_appendf(msg, "%llu", stktable_data_cast(ptr, 
std_t_ull));
                        break;
                case STD_T_FRQP:
-                       chunk_appendf(msg, "%d",
+                       chunk_appendf(msg, "%u",
                                     
read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp),
                                                          t->data_arg[dt].u));
                        break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/stream.c 
new/haproxy-2.4.2+git0.553dee326/src/stream.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/stream.c       2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/stream.c       2021-07-07 
16:46:09.000000000 +0200
@@ -623,7 +623,7 @@
                        _HA_ATOMIC_DEC(&__objt_server(s->target)->cur_sess);
                }
                if (may_dequeue_tasks(objt_server(s->target), s->be))
-                       process_srv_queue(objt_server(s->target));
+                       process_srv_queue(objt_server(s->target), 0);
        }
 
        if (unlikely(s->srv_conn)) {
@@ -1815,7 +1815,7 @@
                        }
                        sess_change_server(s, NULL);
                        if (may_dequeue_tasks(srv, s->be))
-                               process_srv_queue(srv);
+                               process_srv_queue(srv, 0);
                }
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.4.1+git0.1ce7d4925/src/tcpcheck.c 
new/haproxy-2.4.2+git0.553dee326/src/tcpcheck.c
--- old/haproxy-2.4.1+git0.1ce7d4925/src/tcpcheck.c     2021-06-17 
09:06:08.000000000 +0200
+++ new/haproxy-2.4.2+git0.553dee326/src/tcpcheck.c     2021-07-07 
16:46:09.000000000 +0200
@@ -937,6 +937,9 @@
                cs += strlen("maxconn:");
 
                TRACE_DEVEL("change server maxconn", CHK_EV_TCPCHK_EXP, check);
+               /* This is safe to call server_parse_maxconn_change_request
+                * because the server lock is held during the check.
+                */
                msg = server_parse_maxconn_change_request(check->server, cs);
                if (!wrn || !*wrn)
                        wrn = msg;
@@ -3634,7 +3637,7 @@
                        if (next && next->action == TCPCHK_ACT_CONNECT) {
                                LIST_DELETE(&chk->list);
                                LIST_INSERT(&next->list, &chk->list);
-                               chk->index = next->index;
+                               chk->index = next->index + 1;
                        }
                }
 
@@ -3655,7 +3658,7 @@
                                goto out;
                        }
                        LIST_APPEND(px->tcpcheck_rules.list, &next->list);
-                       next->index = chk->index;
+                       next->index = chk->index + 1;
                }
        }
 

Reply via email to