Hello community,

here is the log from the commit of package haproxy for openSUSE:Factory checked 
in at 2017-04-11 09:45:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/haproxy (Old)
 and      /work/SRC/openSUSE:Factory/.haproxy.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "haproxy"

Tue Apr 11 09:45:35 2017 rev:48 rq:485839 version:1.7.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/haproxy/haproxy.changes  2017-03-02 
19:38:35.568961394 +0100
+++ /work/SRC/openSUSE:Factory/.haproxy.new/haproxy.changes     2017-04-11 
09:45:41.884547411 +0200
@@ -1,0 +2,32 @@
+Wed Mar 29 11:53:23 UTC 2017 - kgronl...@suse.com
+
+- Update to version 1.7.4:
+  * MINOR: config: warn when some HTTP rules are used in a TCP proxy
+  * BUG/MINOR: spoe: Fix soft stop handler using a specific id for spoe filters
+  * BUG/MINOR: spoe: Fix parsing of arguments in spoe-message section
+  * BUG/MEDIUM: ssl: Clear OpenSSL error stack after trying to parse OCSP file
+  * BUG/MEDIUM: cli: Prevent double free in CLI ACL lookup
+  * BUG/MINOR: Fix "get map <map> <value>" CLI command
+  * BUG/MAJOR: connection: update CO_FL_CONNECTED before calling the data layer
+  * BUG/MEDIUM: ssl: switchctx should not return SSL_TLSEXT_ERR_ALERT_WARNING
+  * BUG/MINOR: checks: attempt clean shutw for SSL check
+  * BUG/MEDIUM: listener: do not try to rebind another process' socket
+  * BUG/MEDIUM: filters: Fix channels synchronization in flt_end_analyze
+  * BUG/MAJOR: stream-int: do not depend on connection flags to detect 
connection
+  * BUG/MEDIUM: connection: ensure to always report the end of handshakes
+  * BUG: payload: fix payload not retrieving arbitrary lengths
+  * BUG/MAJOR: http: fix typo in http_apply_redirect_rule
+  * BUG/MEDIUM: stream: fix client-fin/server-fin handling
+  * MINOR: fd: add a new flag HAP_POLL_F_RDHUP to struct poller
+  * BUG/MINOR: raw_sock: always perfom the last recv if RDHUP is not available
+  * DOC/MINOR: Fix typos in proxy protocol doc
+  * DOC: Protocol doc: add checksum, TLV type ranges
+  * DOC: Protocol doc: add SSL TLVs, rename CHECKSUM
+  * DOC: Protocol doc: add noop TLV
+  * MEDIUM: global: add a 'hard-stop-after' option to cap the soft-stop time
+  * BUG/MINOR: cfgparse: loop in tracked servers lists not detected by 
check_config_validity().
+  * MINOR: server: irrelevant error message with 'default-server' config file 
keyword.
+  * MINOR: doc: fix use-server example (imap vs mail)
+  * BUG/MEDIUM: tcp: don't require privileges to bind to device
+
+-------------------------------------------------------------------

Old:
----
  haproxy-1.7.3.tar.gz

New:
----
  haproxy-1.7.4.tar.gz

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

Other differences:
------------------
++++++ haproxy.spec ++++++
--- /var/tmp/diff_new_pack.GbiHO8/_old  2017-04-11 09:45:42.824414642 +0200
+++ /var/tmp/diff_new_pack.GbiHO8/_new  2017-04-11 09:45:42.828414077 +0200
@@ -41,7 +41,7 @@
 %bcond_without  apparmor
 
 Name:           haproxy
-Version:        1.7.3
+Version:        1.7.4
 Release:        0
 #
 #

++++++ _service ++++++
--- /var/tmp/diff_new_pack.GbiHO8/_old  2017-04-11 09:45:42.860409557 +0200
+++ /var/tmp/diff_new_pack.GbiHO8/_new  2017-04-11 09:45:42.864408992 +0200
@@ -3,8 +3,8 @@
     <param name="url">http://git.haproxy.org/git/haproxy-1.7.git</param>
     <param name="scm">git</param>
     <param name="filename">haproxy</param>
-    <param name="versionformat">1.7.3</param>
-    <param name="revision">v1.7.3</param>
+    <param name="versionformat">1.7.4</param>
+    <param name="revision">v1.7.4</param>
     <param name="changesgenerate">enable</param>
   </service>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.GbiHO8/_old  2017-04-11 09:45:42.884406167 +0200
+++ /var/tmp/diff_new_pack.GbiHO8/_new  2017-04-11 09:45:42.888405602 +0200
@@ -3,4 +3,4 @@
             <param 
name="url">http://git.haproxy.org/git/haproxy-1.6.git</param>
           <param 
name="changesrevision">864bf78c3b6898eb12ece5f0a44032090f26f57f</param></service><service
 name="tar_scm">
             <param 
name="url">http://git.haproxy.org/git/haproxy-1.7.git</param>
-          <param 
name="changesrevision">9cb532a34ae190b350cdeb8bbbae25d524b10949</param></service></servicedata>
\ No newline at end of file
+          <param 
name="changesrevision">f9eae1ec92742a0185db00fbcfa566ba09b7e3a2</param></service></servicedata>
\ No newline at end of file

++++++ haproxy-1.7.3.tar.gz -> haproxy-1.7.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/CHANGELOG new/haproxy-1.7.4/CHANGELOG
--- old/haproxy-1.7.3/CHANGELOG 2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/CHANGELOG 2017-03-27 23:37:58.000000000 +0200
@@ -1,6 +1,44 @@
 ChangeLog :
 ===========
 
+2017/03/27 : 1.7.4
+    - MINOR: config: warn when some HTTP rules are used in a TCP proxy
+    - BUG/MINOR: spoe: Fix soft stop handler using a specific id for spoe 
filters
+    - BUG/MINOR: spoe: Fix parsing of arguments in spoe-message section
+    - BUG/MEDIUM: ssl: Clear OpenSSL error stack after trying to parse OCSP 
file
+    - BUG/MEDIUM: cli: Prevent double free in CLI ACL lookup
+    - BUG/MINOR: Fix "get map <map> <value>" CLI command
+    - BUG/MAJOR: connection: update CO_FL_CONNECTED before calling the data 
layer
+    - BUG/MEDIUM: ssl: switchctx should not return SSL_TLSEXT_ERR_ALERT_WARNING
+    - BUG/MINOR: checks: attempt clean shutw for SSL check
+    - CONTRIB: tcploop: add limits.h to fix build issue with some compilers
+    - CONTRIB: tcploop: make it build on FreeBSD
+    - CONTRIB: tcploop: fix time format to silence build warnings
+    - CONTRIB: tcploop: report action 'K' (kill) in usage message
+    - CONTRIB: tcploop: fix connect's address length
+    - CONTRIB: tcploop: use the trash instead of NULL for recv()
+    - BUG/MEDIUM: listener: do not try to rebind another process' socket
+    - BUG/MEDIUM: filters: Fix channels synchronization in flt_end_analyze
+    - BUG/MAJOR: stream-int: do not depend on connection flags to detect 
connection
+    - BUG/MEDIUM: connection: ensure to always report the end of handshakes
+    - BUG: payload: fix payload not retrieving arbitrary lengths
+    - BUG/MAJOR: http: fix typo in http_apply_redirect_rule
+    - MINOR: doc: 2.4. Examples should be 2.5. Examples
+    - BUG/MEDIUM: stream: fix client-fin/server-fin handling
+    - MINOR: fd: add a new flag HAP_POLL_F_RDHUP to struct poller
+    - BUG/MINOR: raw_sock: always perfom the last recv if RDHUP is not 
available
+    - DOC/MINOR: Fix typos in proxy protocol doc
+    - DOC: Protocol doc: add checksum, TLV type ranges
+    - DOC: Protocol doc: add SSL TLVs, rename CHECKSUM
+    - DOC: Protocol doc: add noop TLV
+    - MEDIUM: global: add a 'hard-stop-after' option to cap the soft-stop time
+    - BUG/MINOR: cfgparse: loop in tracked servers lists not detected by 
check_config_validity().
+    - MINOR: server: irrelevant error message with 'default-server' config 
file keyword.
+    - MINOR: doc: fix use-server example (imap vs mail)
+    - BUG/MEDIUM: tcp: don't require privileges to bind to device
+    - BUILD: make the release script use shortlog for the final changelog
+    - BUILD: scripts: fix typo in announce-release error message
+
 2017/02/28 : 1.7.3
     - BUG/MINOR: stream: Fix how backend-specific analyzers are set on a stream
     - BUILD: ssl: fix build on OpenSSL 1.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/README new/haproxy-1.7.4/README
--- old/haproxy-1.7.3/README    2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/README    2017-03-27 23:37:58.000000000 +0200
@@ -3,7 +3,7 @@
                          ----------------------
                               version 1.7
                              willy tarreau
-                               2017/02/28
+                               2017/03/27
 
 
 1) How to build it
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/VERDATE new/haproxy-1.7.4/VERDATE
--- old/haproxy-1.7.3/VERDATE   2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/VERDATE   2017-03-27 23:37:58.000000000 +0200
@@ -1,2 +1,2 @@
 $Format:%ci$
-2017/02/28
+2017/03/27
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/VERSION new/haproxy-1.7.4/VERSION
--- old/haproxy-1.7.3/VERSION   2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/VERSION   2017-03-27 23:37:58.000000000 +0200
@@ -1 +1 @@
-1.7.3
+1.7.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/contrib/tcploop/tcploop.c 
new/haproxy-1.7.4/contrib/tcploop/tcploop.c
--- old/haproxy-1.7.3/contrib/tcploop/tcploop.c 2017-02-28 09:59:23.000000000 
+0100
+++ new/haproxy-1.7.4/contrib/tcploop/tcploop.c 2017-03-27 23:37:58.000000000 
+0200
@@ -39,6 +39,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <limits.h>
 #include <netdb.h>
 #include <poll.h>
 #include <signal.h>
@@ -49,6 +50,13 @@
 #include <time.h>
 #include <unistd.h>
 
+#ifndef SOL_TCP
+#define SOL_TCP IPPROTO_TCP
+#endif
+
+#ifndef MSG_MORE
+#define MSG_MORE 0
+#endif
 
 struct err_msg {
        int size;
@@ -100,6 +108,7 @@
            "  A[<count>]   : Accepts <count> incoming sockets and closes 
count-1\n"
            "                 Note: fd=accept(fd)\n"
            "  J            : Jump back to oldest post-fork/post-accept 
action\n"
+           "  K            : kill the connection and go on with next 
operation\n"
            "  G            : disable lingering\n"
            "  T            : set TCP_NODELAY\n"
            "  Q            : disable TCP Quick-ack\n"
@@ -163,10 +172,10 @@
                                tv.tv_sec = 0;
                                tv.tv_usec = 0;
                        }
-                       fprintf(stderr, "[%d.%06d] ", tv.tv_sec, tv.tv_usec);
+                       fprintf(stderr, "[%d.%06d] ", (int)tv.tv_sec, 
(int)tv.tv_usec);
                        break;
                default: // [sec.usec] absolute
-                       fprintf(stderr, "[%d.%06d] ", date.tv_sec, 
date.tv_usec);
+                       fprintf(stderr, "[%d.%06d] ", (int)date.tv_sec, 
(int)date.tv_usec);
                        break;
                }
        }
@@ -308,8 +317,12 @@
 
 int tcp_set_noquickack(int sock, const char *arg)
 {
+#ifdef TCP_QUICKACK
        /* warning: do not use during connect if nothing is to be sent! */
        return setsockopt(sock, SOL_TCP, TCP_QUICKACK, &zero, sizeof(zero));
+#else
+       return 0;
+#endif
 }
 
 /* Try to listen to address <sa>. Return the fd or -1 in case of error */
@@ -411,7 +424,7 @@
        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1)
                goto fail;
 
-       if (connect(sock, (const struct sockaddr *)sa, sizeof(*sa)) < 0) {
+       if (connect(sock, (const struct sockaddr *)sa, sizeof(struct 
sockaddr_in)) < 0) {
                if (errno != EINPROGRESS)
                        goto fail;
        }
@@ -431,6 +444,7 @@
 {
        int count = -1; // stop at first read
        int ret;
+       int max;
 
        if (arg[1]) {
                count = atoi(arg + 1);
@@ -441,7 +455,10 @@
        }
 
        while (1) {
-               ret = recv(sock, NULL, (count > 0) ? count : INT_MAX, 
MSG_NOSIGNAL | MSG_TRUNC);
+               max = (count > 0) ? count : INT_MAX;
+               if (max > sizeof(trash))
+                       max = sizeof(trash);
+               ret = recv(sock, trash, max, MSG_NOSIGNAL | MSG_TRUNC);
                if (ret < 0) {
                        if (errno == EINTR)
                                continue;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/doc/configuration.txt 
new/haproxy-1.7.4/doc/configuration.txt
--- old/haproxy-1.7.3/doc/configuration.txt     2017-02-28 09:59:23.000000000 
+0100
+++ new/haproxy-1.7.4/doc/configuration.txt     2017-03-27 23:37:58.000000000 
+0200
@@ -4,7 +4,7 @@
                          ----------------------
                               version 1.7
                              willy tarreau
-                              2017/02/28
+                              2017/03/27
 
 
 This document covers the configuration language as implemented in the version
@@ -467,7 +467,7 @@
   - d  : days.    1d = 24h = 1440m = 86400s = 86400000ms
 
 
-2.4. Examples
+2.5. Examples
 -------------
 
     # Simple configuration for an HTTP proxy listening on port 80 on all
@@ -536,6 +536,7 @@
    - external-check
    - gid
    - group
+   - hard-stop-after
    - log
    - log-tag
    - log-send-hostname
@@ -702,6 +703,22 @@
   will only be able to drop these groups if started with superuser privileges.
   See also "group" and "uid".
 
+hard-stop-after <time>
+  Defines the maximum time allowed to perform a clean soft-stop.
+
+  Arguments :
+    <time>  is the maximum time (by default in milliseconds) for which the
+            instance will remain alive when a soft-stop is received via the
+            SIGUSR1 signal.
+
+  This may be used to ensure that the instance will quit even if connections
+  remain opened during a soft-stop (for example with long timeouts for a proxy
+  in tcp mode). It applies both in TCP and HTTP mode.
+
+  Example:
+    global
+      hard-stop-after 30s
+
 group <group name>
   Similar to "gid" but uses the GID of group name <group name> from /etc/group.
   See also "gid" and "user".
@@ -10024,7 +10041,7 @@
      use-server mail if { req_ssl_sni -i mail.example.com }
      server     mail 192.168.0.1:587 weight 0
      use-server imap if { req_ssl_sni -i imap.example.com }
-     server     mail 192.168.0.1:993 weight 0
+     server     imap 192.168.0.1:993 weight 0
      # all the rest is forwarded to this server
      server  default 192.168.0.2:443 check
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/doc/proxy-protocol.txt 
new/haproxy-1.7.4/doc/proxy-protocol.txt
--- old/haproxy-1.7.3/doc/proxy-protocol.txt    2017-02-28 09:59:23.000000000 
+0100
+++ new/haproxy-1.7.4/doc/proxy-protocol.txt    2017-03-27 23:37:58.000000000 
+0200
@@ -1,4 +1,4 @@
-2015/08/24                                                        Willy Tarreau
+2017/03/10                                                        Willy Tarreau
                                                            HAProxy Technologies
                                The PROXY protocol
                                  Versions 1 & 2
@@ -23,6 +23,10 @@
    2014/06/14 - fix v2 header check in example code, and update Forwarded spec
    2014/07/12 - update list of implementations (add Squid)
    2015/05/02 - update list of implementations and format of the TLV add-ons
+   2017/03/10 - added the checksum, noop and more SSL-related TLV types,
+                reserved TLV type ranges, added TLV documentation, clarified
+                string encoding. With contributions from Andriy Palamarchuk
+                (Amazon.com).
 
 
 1. Background
@@ -73,7 +77,7 @@
 solution could be to improve the patch to make it support keep-alive and parse
 all forwarded data, whether they're announced with a Content-Length or with a
 Transfer-Encoding, taking care of special methods such as HEAD which announce
-data without transfering them, etc... In fact, it would require implementing a
+data without transferring them, etc... In fact, it would require implementing a
 full HTTP stack in Stunnel. It would then become a lot more complex, a lot less
 reliable and would not anymore be the "dumb proxy" that fits every purposes.
 
@@ -190,9 +194,9 @@
 2.1. Human-readable header format (Version 1)
 
 This is the format specified in version 1 of the protocol. It consists in one
-line of ASCII text matching exactly the following block, sent immediately and
-at once upon the connection establishment and prepended before any data flowing
-from the sender to the receiver :
+line of US-ASCII text matching exactly the following block, sent immediately
+and at once upon the connection establishment and prepended before any data
+flowing from the sender to the receiver :
 
   - a string identifying the protocol : "PROXY" ( \x50 \x52 \x4F \x58 \x59 )
     Seeing this string indicates that this is version 1 of the protocol.
@@ -378,7 +382,7 @@
   - other values are unspecified and must not be emitted in version 2 of this
     protocol and must be rejected as invalid by receivers.
 
-The transport protocol is specified in the lowest 4 bits of the the 14th byte :
+The transport protocol is specified in the lowest 4 bits of the 14th byte :
 
   - 0x0 : UNSPEC : the connection is forwarded for an unknown, unspecified
     or unsupported protocol. The sender should use this family when sending
@@ -428,11 +432,12 @@
     AF_UNIX protocol family. Address length is 2*108 = 216 bytes.
 
 
-Only the UNSPEC protocol byte (\x00) is mandatory. A receiver is not required
-to implement other ones, provided that it automatically falls back to the
-UNSPEC mode for the valid combinations above that it does not support.
+Only the UNSPEC protocol byte (\x00) is mandatory to implement on the receiver.
+A receiver is not required to implement other ones, provided that it
+automatically falls back to the UNSPEC mode for the valid combinations above
+that it does not support.
 
-The 15th and 16th bytes is the address length in bytes in network endien order.
+The 15th and 16th bytes is the address length in bytes in network endian order.
 It is used so that the receiver knows how many address bytes to skip even when
 it does not implement the presented protocol. Thus the length of the protocol
 header in bytes is always exactly 16 + this value. When a sender presents a
@@ -497,7 +502,7 @@
            \x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x02
 
     - otherwise, if the incoming byte count is 8 or above, and the 5 first
-      characters match the ASCII representation of "PROXY" then the protocol
+      characters match the US-ASCII representation of "PROXY" then the protocol
       must be parsed as version 1 :
 
            \x50\x52\x4F\x58\x59
@@ -523,19 +528,83 @@
             uint8_t value[0];
         };
 
+A receiver may choose to skip over and ignore the TLVs he is not interested in
+or he does not understand. Senders can generate the TLVs only for
+the information they choose to publish.
+
 The following types have already been registered for the <type> field :
 
         #define PP2_TYPE_ALPN           0x01
         #define PP2_TYPE_AUTHORITY      0x02
+        #define PP2_TYPE_CRC32C         0x03
+        #define PP2_TYPE_NOOP           0x04
         #define PP2_TYPE_SSL            0x20
         #define PP2_SUBTYPE_SSL_VERSION 0x21
         #define PP2_SUBTYPE_SSL_CN      0x22
+        #define PP2_SUBTYPE_SSL_CIPHER  0x23
+        #define PP2_SUBTYPE_SSL_SIG_ALG 0x24
+        #define PP2_SUBTYPE_SSL_KEY_ALG 0x25
         #define PP2_TYPE_NETNS          0x30
 
 
-2.2.1. The PP2_TYPE_SSL type and subtypes
+2.2.1 PP2_TYPE_ALPN
+
+Application-Layer Protocol Negotiation (ALPN). It is a byte sequence defining
+the upper layer protocol in use over the connection. The most common use case
+will be to pass the exact copy of the ALPN extension of the Transport Layer
+Security (TLS) protocol as defined by RFC7301 [9].
+
+
+2.2.2 PP2_TYPE_AUTHORITY
+
+Contains the host name value passed by the client, as an UTF8-encoded string.
+In case of TLS being used on the client connection, this is the exact copy of
+the "server_name" extension as defined by RFC3546 [10], section 3.1, often
+referred to as "SNI". There are probably other situations where an authority
+can be mentionned on a connection without TLS being involved at all.
+
+
+2.2.3. PP2_TYPE_CRC32C
+
+The value of the type PP2_TYPE_CRC32C is a 32-bit number storing the CRC32c
+checksum of the PROXY protocol header.
+
+When the checksum is supported by the sender after constructing the header
+the sender MUST:
+
+ - initialize the checksum field to '0's.
+
+ - calculate the CRC32c checksum of the PROXY header as described in RFC4960,
+   Appendix B [8].
+
+ - put the resultant value into the checksum field, and leave the rest of
+   the bits unchanged.
+
+If the checksum is provided as part of the PROXY header and the checksum
+functionality is supported by the receiver, the receiver MUST:
+
+ - store the received CRC32c checksum value aside.
+
+ - replace the 32 bits of the checksum field in the received PROXY header with
+   all '0's and calculate a CRC32c checksum value of the whole PROXY header.
+
+ - verify that the calculated CRC32c checksum is the same as the received
+   CRC32c checksum. If it is not, the receiver MUST treat the TCP connection
+   providing the header as invalid.
+
+The default procedure for handling an invalid TCP connection is to abort it.
 
-For the type PP2_TYPE_SSL, the value is itselv a defined like this :
+
+2.2.4. PP2_TYPE_NOOP
+
+The TLV of this type should be ignored when parsed. The value is zero or more
+bytes. Can be used for data padding or alignment. Note that it can be used
+to align only by 3 or more bytes because a TLV can not be smaller than that.
+
+
+2.2.5. The PP2_TYPE_SSL type and subtypes
+
+For the type PP2_TYPE_SSL, the value is itself a defined like this :
 
         struct pp2_tlv_ssl {
                 uint8_t  client;
@@ -559,22 +628,60 @@
 TLV will reflect this.
 
 The PP2_CLIENT_SSL flag indicates that the client connected over SSL/TLS. When
-this field is present, the string representation of the TLS version is appended
-at the end of the field in the TLV format using the type 
PP2_SUBTYPE_SSL_VERSION.
+this field is present, the US-ASCII string representation of the TLS version is
+appended at the end of the field in the TLV format using the type
+PP2_SUBTYPE_SSL_VERSION.
 
 PP2_CLIENT_CERT_CONN indicates that the client provided a certificate over the
 current connection. PP2_CLIENT_CERT_SESS indicates that the client provided a
 certificate at least once over the TLS session this connection belongs to.
 
+The second level TLV PP2_SUBTYPE_SSL_CIPHER provides the US-ASCII string name
+of the used cipher, for example "ECDHE-RSA-AES128-GCM-SHA256".
+
+The second level TLV PP2_SUBTYPE_SSL_SIG_ALG provides the US-ASCII string name
+of the algorithm used to sign the certificate presented by the frontend when
+the incoming connection was made over an SSL/TLS transport layer, for example
+"SHA256".
+
+The second level TLV PP2_SUBTYPE_SSL_KEY_ALG provides the US-ASCII string name
+of the algorithm used to generate the key of the certificate presented by the
+frontend when the incoming connection was made over an SSL/TLS transport layer,
+for example "RSA2048".
+
 In all cases, the string representation (in UTF8) of the Common Name field
-(OID: 2.5.4.3) of the client certificate's DistinguishedName, is appended
-using the TLV format and the type PP2_SUBTYPE_SSL_CN.
+(OID: 2.5.4.3) of the client certificate's Distinguished Name, is appended
+using the TLV format and the type PP2_SUBTYPE_SSL_CN. E.g. "example.com".
+
 
+2.2.6. The PP2_TYPE_NETNS type
 
-2.2.2. The PP2_TYPE_NETNS type
+The type PP2_TYPE_NETNS defines the value as the US-ASCII string representation
+of the namespace's name.
 
-The type PP2_TYPE_NETNS defines the value as the string representation of the
-namespace's name.
+
+2.2.7. Reserved type ranges
+
+The following range of 16 type values is reserved for application-specific
+data and will be never used by the PROXY Protocol. If you need more values
+consider extending the range with a type field in your TLVs.
+
+        #define PP2_TYPE_MIN_CUSTOM    0xE0
+        #define PP2_TYPE_MAX_CUSTOM    0xEF
+
+This range of 8 values is reserved for temporary experimental use by
+application developers and protocol designers. The values from the range will
+never be used by the PROXY protocol and should not be used by production
+functionality.
+
+        #define PP2_TYPE_MIN_EXPERIMENT 0xF0
+        #define PP2_TYPE_MAX_EXPERIMENT 0xF7
+
+The following range of 8 values is reserved for future use, potentially to
+extend the protocol with multibyte type values.
+
+        #define PP2_TYPE_MIN_FUTURE    0xF8
+        #define PP2_TYPE_MAX_FUTURE    0xFF
 
 
 3. Implementations
@@ -670,7 +777,7 @@
 
 The protocol also eases IPv4 and IPv6 integration : if only the first layer
 (FW1 and PX1) is IPv6-capable, it is still possible to present the original
-client's IPv6 address to the target server eventhough the whole chain is only
+client's IPv6 address to the target server even though the whole chain is only
 connected via IPv4.
 
 
@@ -741,7 +848,7 @@
 
 The version 2 protocol signature has been sent to a wide variety of protocols
 and implementations including old ones. The following protocol and products
-have been tested to ensure the best possible behaviour when the signature was
+have been tested to ensure the best possible behavior when the signature was
 presented, even with minimal implementations :
 
   - HTTP :
@@ -784,7 +891,7 @@
 information such as the incoming network interface, or the origin addresses in
 case of network address translation happening before the first proxy, but this
 is not identified as a requirement right now. Some deep thinking has been spent
-on this and it appears that trying to add a few more information open a pandora
+on this and it appears that trying to add a few more information open a Pandora
 box with many information from MAC addresses to SSL client certificates, which
 would make the protocol much more complex. So at this point it is not planned.
 Suggestions on improvements are welcome.
@@ -803,7 +910,9 @@
 [5] https://github.com/bumptech/stud/pull/81
 [6] https://www.varnish-cache.org/docs/trunk/phk/ssl_again.html
 [7] http://wiki.squid-cache.org/Squid-3.5
-
+[8] https://tools.ietf.org/html/rfc4960#appendix-B
+[9] https://tools.ietf.org/rfc/rfc7301.txt
+[10] https://www.ietf.org/rfc/rfc3546.txt
 
 9. Sample code
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/examples/haproxy.spec 
new/haproxy-1.7.4/examples/haproxy.spec
--- old/haproxy-1.7.3/examples/haproxy.spec     2017-02-28 09:59:23.000000000 
+0100
+++ new/haproxy-1.7.4/examples/haproxy.spec     2017-03-27 23:37:58.000000000 
+0200
@@ -1,6 +1,6 @@
 Summary: HA-Proxy is a TCP/HTTP reverse proxy for high availability 
environments
 Name: haproxy
-Version: 1.7.3
+Version: 1.7.4
 Release: 1
 License: GPL
 Group: System Environment/Daemons
@@ -74,6 +74,9 @@
 %attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
 
 %changelog
+* Mon Mar 27 2017 Willy Tarreau <w...@1wt.eu>
+- updated to 1.7.4
+
 * Tue Feb 28 2017 Willy Tarreau <w...@1wt.eu>
 - updated to 1.7.3
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/include/types/channel.h 
new/haproxy-1.7.4/include/types/channel.h
--- old/haproxy-1.7.3/include/types/channel.h   2017-02-28 09:59:23.000000000 
+0100
+++ new/haproxy-1.7.4/include/types/channel.h   2017-03-27 23:37:58.000000000 
+0200
@@ -116,7 +116,8 @@
 #define CF_NEVER_WAIT     0x08000000  /* never wait for sending data 
(permanent) */
 
 #define CF_WAKE_ONCE      0x10000000  /* pretend there is activity on this 
channel (one-shoot) */
-/* unused: 0x20000000, 0x40000000 */
+#define CF_FLT_ANALYZE    0x20000000  /* at least one filter is still 
analyzing this channel */
+/* unused: 0x40000000 */
 #define CF_ISRESP         0x80000000  /* 0 = request channel, 1 = response 
channel */
 
 /* Masks which define input events for stream analysers */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/include/types/connection.h 
new/haproxy-1.7.4/include/types/connection.h
--- old/haproxy-1.7.3/include/types/connection.h        2017-02-28 
09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/include/types/connection.h        2017-03-27 
23:37:58.000000000 +0200
@@ -95,15 +95,15 @@
        CO_FL_SOCK_RD_SH    = 0x00040000,  /* SOCK layer was notified about 
shutr/read0 */
        CO_FL_SOCK_WR_SH    = 0x00080000,  /* SOCK layer asked for shutw */
 
-       /* flags used to report connection status and errors */
+       /* flags used to report connection errors or other closing conditions */
        CO_FL_ERROR         = 0x00100000,  /* a fatal error was reported     */
-       CO_FL_CONNECTED     = 0x00200000,  /* the connection is now established 
*/
+       CO_FL_NOTIFY_DATA   = 0x001F0000,  /* any shut/error flags above needs 
to be reported */
+
+       /* flags used to report connection status updates */
+       CO_FL_CONNECTED     = 0x00200000,  /* L4+L6 now ready ; extra 
handshakes may or may not exist */
        CO_FL_WAIT_L4_CONN  = 0x00400000,  /* waiting for L4 to be connected */
        CO_FL_WAIT_L6_CONN  = 0x00800000,  /* waiting for L6 to be connected 
(eg: SSL) */
 
-       /* synthesis of the flags above */
-       CO_FL_CONN_STATE    = 0x00FF0000,  /* all shut/connected flags */
-
        /*** All the flags below are used for connection handshakes. Any new
         * handshake should be added after this point, and CO_FL_HANDSHAKE
         * should be updated.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/include/types/fd.h 
new/haproxy-1.7.4/include/types/fd.h
--- old/haproxy-1.7.3/include/types/fd.h        2017-02-28 09:59:23.000000000 
+0100
+++ new/haproxy-1.7.4/include/types/fd.h        2017-03-27 23:37:58.000000000 
+0200
@@ -120,7 +120,11 @@
  *    the term() function.
  *  - clo() should be used to do indicate the poller that fd will be closed.
  *  - poll() calls the poller, expiring at <exp>
+ *  - flags indicate what the poller supports (HAP_POLL_F_*)
  */
+
+#define HAP_POLL_F_RDHUP 0x00000001                          /* the poller 
notifies of HUP with reads */
+
 struct poller {
        void   *private;                                     /* any private 
data for the poller */
        void REGPRM1   (*clo)(const int fd);                 /* mark <fd> as 
closed */
@@ -130,6 +134,7 @@
        int  REGPRM1   (*test)(struct poller *p);            /* pre-init check 
of the poller */
        int  REGPRM1   (*fork)(struct poller *p);            /* post-fork 
re-opening */
        const char   *name;                                  /* poller name */
+       unsigned int flags;                                  /* HAP_POLL_F_* */
        int    pref;                                         /* try pollers 
with higher preference first */
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/include/types/global.h 
new/haproxy-1.7.4/include/types/global.h
--- old/haproxy-1.7.3/include/types/global.h    2017-02-28 09:59:23.000000000 
+0100
+++ new/haproxy-1.7.4/include/types/global.h    2017-03-27 23:37:58.000000000 
+0200
@@ -89,6 +89,7 @@
        int gid;
        int external_check;
        int nbproc;
+       unsigned int hard_stop_after;   /* maximum time allowed to perform a 
soft-stop */
        int maxconn, hardmaxconn;
        int maxsslconn;
        int ssl_session_max_cost;   /* how many bytes an SSL session may cost */
@@ -240,6 +241,7 @@
 extern const int one;
 extern const struct linger nolinger;
 extern int stopping;   /* non zero means stopping in progress */
+extern int killed;     /* non zero means a hard-stop is triggered */
 extern char hostname[MAX_HOSTNAME_LEN];
 extern char localpeer[MAX_HOSTNAME_LEN];
 extern struct list global_listener_queue; /* list of the temporarily limited 
listeners */
@@ -264,6 +266,8 @@
        return 0;
 }
 
+void deinit(void);
+
 #endif /* _TYPES_GLOBAL_H */
 
 /*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/include/types/proto_http.h 
new/haproxy-1.7.4/include/types/proto_http.h
--- old/haproxy-1.7.3/include/types/proto_http.h        2017-02-28 
09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/include/types/proto_http.h        2017-03-27 
23:37:58.000000000 +0200
@@ -68,7 +68,12 @@
 #define TX_CACHE_COOK  0x00002000      /* a cookie in the response is 
cacheable */
 #define TX_CACHE_SHIFT 12              /* bit shift */
 
-/* Unused: 0x4000, 0x8000, 0x10000, 0x20000, 0x80000 */
+/* Unused: 0x4000, 0x8000 */
+
+#define TX_WAIT_CLEANUP        0x0010000       /* this transaction is waiting 
for a clean up */
+
+/* Unused: 0x20000, 0x80000 */
+
 
 /* indicate how we *want* the connection to behave, regardless of what is in
  * the headers. We have 4 possible values right now :
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/include/types/stream_interface.h 
new/haproxy-1.7.4/include/types/stream_interface.h
--- old/haproxy-1.7.3/include/types/stream_interface.h  2017-02-28 
09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/include/types/stream_interface.h  2017-03-27 
23:37:58.000000000 +0200
@@ -99,6 +99,7 @@
        /* struct members below are the "remote" part, as seen from the buffer 
side */
        unsigned int err_type;  /* first error detected, one of SI_ET_* */
        int conn_retries;       /* number of connect retries left */
+       unsigned int hcto;      /* half-closed timeout (0 = unset) */
 };
 
 /* operations available on a stream-interface */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/scripts/announce-release 
new/haproxy-1.7.4/scripts/announce-release
--- old/haproxy-1.7.3/scripts/announce-release  2017-02-28 09:59:23.000000000 
+0100
+++ new/haproxy-1.7.4/scripts/announce-release  2017-03-27 23:37:58.000000000 
+0200
@@ -79,7 +79,7 @@
 fi
 
 if ! git show-ref --tags "v$NEW" >/dev/null; then
-       die "git tag v$NEW already exist, did you create the release ?"
+       die "git tag v$NEW doesn't exist, did you create the release ?"
 fi
 
 if [ -z "$OLD" ]; then
@@ -169,7 +169,7 @@
 
 (echo "---"
  echo "Complete changelog :"
- git log --oneline --reverse --format="  - %s" "v$OLD".."v$NEW^"
+ git shortlog "v$OLD".."v$NEW^"
  echo "---"
 ) >> "$OUTPUT"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/cfgparse.c 
new/haproxy-1.7.4/src/cfgparse.c
--- old/haproxy-1.7.3/src/cfgparse.c    2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/cfgparse.c    2017-03-27 23:37:58.000000000 +0200
@@ -8552,11 +8552,12 @@
 
                                for (loop = srv->track; loop && loop != newsrv; 
loop = loop->track);
 
-                               if (loop) {
+                               if (newsrv == srv || loop) {
                                        Alert("config : %s '%s', server '%s': 
unable to track %s/%s as it "
                                              "belongs to a tracking chain 
looping back to %s/%s.\n",
                                              proxy_type_str(curproxy), 
curproxy->id,
-                                             newsrv->id, px->id, srv->id, 
px->id, loop->id);
+                                             newsrv->id, px->id, srv->id, 
px->id,
+                                             newsrv == srv ? srv->id : 
loop->id);
                                        cfgerr++;
                                        goto next_srv;
                                }
@@ -8681,6 +8682,36 @@
                                curproxy->uri_auth = NULL;
                        }
 
+                       if (curproxy->capture_name) {
+                               Warning("config : 'capture' statement ignored 
for %s '%s' as it requires HTTP mode.\n",
+                                       proxy_type_str(curproxy), curproxy->id);
+                               err_code |= ERR_WARN;
+                       }
+
+                       if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
+                               Warning("config : 'http-request' rules ignored 
for %s '%s' as they require HTTP mode.\n",
+                                       proxy_type_str(curproxy), curproxy->id);
+                               err_code |= ERR_WARN;
+                       }
+
+                       if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
+                               Warning("config : 'http-response' rules ignored 
for %s '%s' as they require HTTP mode.\n",
+                                       proxy_type_str(curproxy), curproxy->id);
+                               err_code |= ERR_WARN;
+                       }
+
+                       if (!LIST_ISEMPTY(&curproxy->block_rules)) {
+                               Warning("config : 'block' rules ignored for %s 
'%s' as they require HTTP mode.\n",
+                                       proxy_type_str(curproxy), curproxy->id);
+                               err_code |= ERR_WARN;
+                       }
+
+                       if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
+                               Warning("config : 'redirect' rules ignored for 
%s '%s' as they require HTTP mode.\n",
+                                       proxy_type_str(curproxy), curproxy->id);
+                               err_code |= ERR_WARN;
+                       }
+
                        if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) 
{
                                Warning("config : 'option %s' ignored for %s 
'%s' as it requires HTTP mode.\n",
                                        "forwardfor", proxy_type_str(curproxy), 
curproxy->id);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/checks.c 
new/haproxy-1.7.4/src/checks.c
--- old/haproxy-1.7.3/src/checks.c      2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/checks.c      2017-03-27 23:37:58.000000000 +0200
@@ -1355,14 +1355,15 @@
        *check->bi->data = '\0';
        check->bi->i = 0;
 
-       /* Close the connection... We absolutely want to perform a hard close
-        * and reset the connection if some data are pending, otherwise we end
-        * up with many TIME_WAITs and eat all the source port range quickly.
-        * To avoid sending RSTs all the time, we first try to drain pending
-        * data.
+       /* Close the connection... We still attempt to nicely close if,
+        * for instance, SSL needs to send a "close notify." Later, we perform
+        * a hard close and reset the connection if some data are pending,
+        * otherwise we end up with many TIME_WAITs and eat all the source port
+        * range quickly.  To avoid sending RSTs all the time, we first try to
+        * drain pending data.
         */
        __conn_data_stop_both(conn);
-       conn_data_shutw_hard(conn);
+       conn_data_shutw(conn);
 
        /* OK, let's not stay here forever */
        if (check->result == CHK_RES_FAILED)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/connection.c 
new/haproxy-1.7.4/src/connection.c
--- old/haproxy-1.7.3/src/connection.c  2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/connection.c  2017-03-27 23:37:58.000000000 +0200
@@ -99,19 +99,21 @@
         */
        if (conn->xprt && fd_recv_ready(fd) &&
            ((conn->flags & 
(CO_FL_DATA_RD_ENA|CO_FL_WAIT_ROOM|CO_FL_ERROR|CO_FL_HANDSHAKE)) == 
CO_FL_DATA_RD_ENA)) {
-               /* force detection of a flag change : it's impossible to have 
both
-                * CONNECTED and WAIT_CONN so we're certain to trigger a change.
+               /* force reporting of activity by clearing the previous flags :
+                * we'll have at least ERROR or CONNECTED at the end of an I/O,
+                * both of which will be detected below.
                 */
-               flags = CO_FL_WAIT_L4_CONN | CO_FL_CONNECTED;
+               flags = 0;
                conn->data->recv(conn);
        }
 
        if (conn->xprt && fd_send_ready(fd) &&
            ((conn->flags & 
(CO_FL_DATA_WR_ENA|CO_FL_WAIT_DATA|CO_FL_ERROR|CO_FL_HANDSHAKE)) == 
CO_FL_DATA_WR_ENA)) {
-               /* force detection of a flag change : it's impossible to have 
both
-                * CONNECTED and WAIT_CONN so we're certain to trigger a change.
+               /* force reporting of activity by clearing the previous flags :
+                * we'll have at least ERROR or CONNECTED at the end of an I/O,
+                * both of which will be detected below.
                 */
-               flags = CO_FL_WAIT_L4_CONN | CO_FL_CONNECTED;
+               flags = 0;
                conn->data->send(conn);
        }
 
@@ -129,21 +131,33 @@
                if (!tcp_connect_probe(conn))
                        goto leave;
        }
-
  leave:
-       /* The wake callback may be used to process a critical error and abort 
the
-        * connection. If so, we don't want to go further as the connection will
-        * have been released and the FD destroyed.
+       /* Verify if the connection just established. */
+       if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | 
CO_FL_CONNECTED))))
+               conn->flags |= CO_FL_CONNECTED;
+
+       /* The wake callback is normally used to notify the data layer about
+        * data layer activity (successful send/recv), connection establishment,
+        * shutdown and fatal errors. We need to consider the following
+        * situations to wake up the data layer :
+        *  - change among the CO_FL_NOTIFY_DATA flags :
+        *      {DATA,SOCK}_{RD,WR}_SH, ERROR,
+        *  - absence of any of {L4,L6}_CONN and CONNECTED, indicating the
+        *    end of handshake and transition to CONNECTED
+        *  - raise of CONNECTED with HANDSHAKE down
+        *  - end of HANDSHAKE with CONNECTED set
+        *  - regular data layer activity
+        *
+        * Note that the wake callback is allowed to release the connection and
+        * the fd (and return < 0 in this case).
         */
        if ((conn->flags & CO_FL_WAKE_DATA) &&
-           ((conn->flags ^ flags) & CO_FL_CONN_STATE) &&
+           (((conn->flags ^ flags) & CO_FL_NOTIFY_DATA) ||
+            ((flags & (CO_FL_CONNECTED|CO_FL_HANDSHAKE)) != CO_FL_CONNECTED &&
+             (conn->flags & (CO_FL_CONNECTED|CO_FL_HANDSHAKE)) == 
CO_FL_CONNECTED)) &&
            conn->data->wake(conn) < 0)
                return;
 
-       /* Last check, verify if the connection just established */
-       if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | 
CO_FL_CONNECTED))))
-               conn->flags |= CO_FL_CONNECTED;
-
        /* remove the events before leaving */
        fdtab[fd].ev &= FD_POLL_STICKY;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/ev_epoll.c 
new/haproxy-1.7.4/src/ev_epoll.c
--- old/haproxy-1.7.3/src/ev_epoll.c    2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/ev_epoll.c    2017-03-27 23:37:58.000000000 +0200
@@ -154,8 +154,10 @@
                }
 
                /* always remap RDHUP to HUP as they're used similarly */
-               if (e & EPOLLRDHUP)
+               if (e & EPOLLRDHUP) {
+                       cur_poller.flags |= HAP_POLL_F_RDHUP;
                        n |= FD_POLL_HUP;
+               }
 
                fdtab[fd].ev |= n;
                if (n & (FD_POLL_IN | FD_POLL_HUP | FD_POLL_ERR))
@@ -263,6 +265,7 @@
 
        p->name = "epoll";
        p->pref = 300;
+       p->flags = 0;
        p->private = NULL;
 
        p->clo  = __fd_clo;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/ev_kqueue.c 
new/haproxy-1.7.4/src/ev_kqueue.c
--- old/haproxy-1.7.3/src/ev_kqueue.c   2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/ev_kqueue.c   2017-03-27 23:37:58.000000000 +0200
@@ -234,6 +234,7 @@
 
        p->name = "kqueue";
        p->pref = 300;
+       p->flags = 0;
        p->private = NULL;
 
        p->clo  = NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/ev_poll.c 
new/haproxy-1.7.4/src/ev_poll.c
--- old/haproxy-1.7.3/src/ev_poll.c     2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/ev_poll.c     2017-03-27 23:37:58.000000000 +0200
@@ -235,6 +235,7 @@
 
        p->name = "poll";
        p->pref = 200;
+       p->flags = 0;
        p->private = NULL;
 
        p->clo  = __fd_clo;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/ev_select.c 
new/haproxy-1.7.4/src/ev_select.c
--- old/haproxy-1.7.3/src/ev_select.c   2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/ev_select.c   2017-03-27 23:37:58.000000000 +0200
@@ -235,6 +235,7 @@
 
        p->name = "select";
        p->pref = 150;
+       p->flags = 0;
        p->private = NULL;
 
        p->clo  = __fd_clo;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/filters.c 
new/haproxy-1.7.4/src/filters.c
--- old/haproxy-1.7.3/src/filters.c     2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/filters.c     2017-03-27 23:37:58.000000000 +0200
@@ -675,6 +675,9 @@
        /* If this function is called, this means there is at least one filter,
         * so we do not need to check the filter list's emptiness. */
 
+       /* Set flag on channel to tell that the channel is filtered */
+       chn->flags |= CF_FLT_ANALYZE;
+
        RESUME_FILTER_LOOP(s, chn) {
                if (!(chn->flags & CF_ISRESP)) {
                        if (an_bit == AN_REQ_FLT_START_BE &&
@@ -801,6 +804,11 @@
 {
        int ret = 1;
 
+       /* Check if all filters attached on the stream have finished their
+        * processing on this channel. */
+       if (!(chn->flags & CF_FLT_ANALYZE))
+               goto sync;
+
        RESUME_FILTER_LOOP(s, chn) {
                FLT_NXT(filter, chn) = 0;
                FLT_FWD(filter, chn) = 0;
@@ -813,27 +821,31 @@
                }
        } RESUME_FILTER_END;
 
-end:
-       ret = handle_analyzer_result(s, chn, an_bit, ret);
-
-       /* Check if 'channel_end_analyze' callback has been called for the
-        * request and the response. */
-       if (!(s->req.analysers & AN_REQ_FLT_END) && !(s->res.analysers & 
AN_RES_FLT_END)) {
-               /* When we are waiting for a new request, so we must reset
-                * stream analyzers. The input must not be closed the request
-                * channel, else it is useless to wait. */
-               if (s->txn && (s->txn->flags & TX_WAIT_NEXT_RQ) && 
!channel_input_closed(&s->req)) {
-                       s->req.analysers = strm_li(s) ? strm_li(s)->analysers : 
0;
-                       s->res.analysers = 0;
-
-                       /* Remove backend filters from the list */
-                       flt_stream_release(s, 1);
-               }
+ end:
+       /* We don't remove yet this analyzer because we need to synchronize the
+        * both channels. So here, we just remove the flag CF_FLT_ANALYZE. */
+       ret = handle_analyzer_result(s, chn, 0, ret);
+       if (ret)
+               chn->flags &= ~CF_FLT_ANALYZE;
+
+ sync:
+       /* Now we can check if filters have finished their work on the both
+        * channels */
+       if (!(s->req.flags & CF_FLT_ANALYZE) && !(s->res.flags & 
CF_FLT_ANALYZE)) {
+               /* Sync channels by removing this analyzer for the both 
channels */
+               s->req.analysers &= ~AN_REQ_FLT_END;
+               s->res.analysers &= ~AN_RES_FLT_END;
+
+               /* Clean up the HTTP transaction if needed */
+               if (s->txn && (s->txn->flags & TX_WAIT_CLEANUP))
+                       http_end_txn_clean_session(s);
 
+               /* Remove backend filters from the list */
+               flt_stream_release(s, 1);
        }
-       else if (ret) {
-               /* Analyzer ends only for one channel. So wake up the stream to
-                * be sure to process it for the other side as soon as
+       else {
+               /* This analyzer ends only for one channel. So wake up the
+                * stream to be sure to process it for the other side as soon as
                 * possible. */
                task_wakeup(s->task, TASK_WOKEN_MSG);
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/flt_spoe.c 
new/haproxy-1.7.4/src/flt_spoe.c
--- old/haproxy-1.7.3/src/flt_spoe.c    2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/flt_spoe.c    2017-03-27 23:37:58.000000000 +0200
@@ -235,6 +235,9 @@
        unsigned int        process_exp;  /* expiration date to process an 
event */
 };
 
+/* SPOE filter id. Used to identify SPOE filters */
+const char *spoe_filter_id = "SPOE filter";
+
 /* Set if the handle on SIGUSR1 is registered */
 static int sighandler_registered = 0;
 
@@ -2286,10 +2289,16 @@
                struct flt_conf *fconf;
 
                list_for_each_entry(fconf, &p->filter_configs, list) {
-                       struct spoe_config *conf  = fconf->conf;
-                       struct spoe_agent  *agent = conf->agent;
+                       struct spoe_config *conf;
+                       struct spoe_agent  *agent;
                        struct appctx      *appctx;
 
+                       if (fconf->id != spoe_filter_id)
+                               continue;
+
+                       conf  = fconf->conf;
+                       agent = conf->agent;
+
                        list_for_each_entry(appctx, &agent->cache, 
ctx.spoe.list) {
                                si_applet_want_get(appctx->owner);
                                si_applet_want_put(appctx->owner);
@@ -2957,8 +2966,9 @@
                                arg->name_len = delim - args[cur_arg];
                                delim++;
                        }
-
-                       arg->expr = sample_parse_expr(&delim, &idx, file, 
linenum, &errmsg, &curproxy->conf.args);
+                       arg->expr = sample_parse_expr((char*[]){delim, NULL},
+                                                     &idx, file, linenum, 
&errmsg,
+                                                     &curproxy->conf.args);
                        if (arg->expr == NULL) {
                                Alert("parsing [%s:%d] : '%s': %s.\n", file, 
linenum, args[0], errmsg);
                                err_code |= ERR_ALERT | ERR_FATAL;
@@ -3178,6 +3188,7 @@
        }
 
        *cur_arg    = pos;
+       fconf->id   = spoe_filter_id;
        fconf->ops  = &spoe_ops;
        fconf->conf = conf;
        return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/haproxy.c 
new/haproxy-1.7.4/src/haproxy.c
--- old/haproxy-1.7.3/src/haproxy.c     2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/haproxy.c     2017-03-27 23:37:58.000000000 +0200
@@ -140,6 +140,7 @@
 
 /* global options */
 struct global global = {
+       .hard_stop_after = TICK_ETERNITY,
        .nbproc = 1,
        .req_count = 0,
        .logsrvs = LIST_HEAD_INIT(global.logsrvs),
@@ -228,6 +229,7 @@
 /*********************************************************************/
 
 int stopping;  /* non zero means stopping in progress */
+int killed;    /* non zero means a hard-stop is triggered */
 int jobs = 0;   /* number of active jobs (conns, listeners, active tasks, ...) 
*/
 
 /* Here we store informations about the pids of the processes we may pause
@@ -708,6 +710,7 @@
         */
     
        totalconn = actconn = maxfd = listeners = stopping = 0;
+       killed = 0;
     
 
 #ifdef HAPROXY_MEMMAX
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/listener.c 
new/haproxy-1.7.4/src/listener.c
--- old/haproxy-1.7.3/src/listener.c    2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/listener.c    2017-03-27 23:37:58.000000000 +0200
@@ -128,6 +128,11 @@
  */
 int resume_listener(struct listener *l)
 {
+       if ((global.mode & (MODE_DAEMON | MODE_SYSTEMD)) &&
+           l->bind_conf->bind_proc &&
+           !(l->bind_conf->bind_proc & (1UL << (relative_pid - 1))))
+               return 1;
+
        if (l->state == LI_ASSIGNED) {
                char msg[100];
                int err;
@@ -145,11 +150,6 @@
        if (l->state < LI_PAUSED)
                return 0;
 
-       if ((global.mode & (MODE_DAEMON | MODE_SYSTEMD)) &&
-           l->bind_conf->bind_proc &&
-           !(l->bind_conf->bind_proc & (1UL << (relative_pid - 1))))
-               return 1;
-
        if (l->proto->sock_prot == IPPROTO_TCP &&
            l->state == LI_PAUSED &&
            listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/map.c new/haproxy-1.7.4/src/map.c
--- old/haproxy-1.7.3/src/map.c 2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/map.c 2017-03-27 23:37:58.000000000 +0200
@@ -524,7 +524,6 @@
 
        default:
                appctx->st2 = STAT_ST_FIN;
-               free(appctx->ctx.map.chunk.str);
                return 1;
        }
 }
@@ -907,7 +906,7 @@
        { { "add",   "map", NULL }, "add map        : add map entry", 
cli_parse_add_map, NULL },
        { { "clear", "map", NULL }, "clear map <id> : clear the content of this 
map", cli_parse_clear_map, NULL },
        { { "del",   "map", NULL }, "del map        : delete map entry", 
cli_parse_del_map, NULL },
-       { { "get",   "map", NULL }, "get map        : report the keys and 
values matching a sample for a map", cli_parse_get_map, NULL },
+       { { "get",   "map", NULL }, "get map        : report the keys and 
values matching a sample for a map", cli_parse_get_map, 
cli_io_handler_map_lookup, cli_release_mlook },
        { { "set",   "map", NULL }, "set map        : modify map entry", 
cli_parse_set_map, NULL },
        { { "show",  "map", NULL }, "show map [id]  : report available maps or 
dump a map's contents", cli_parse_show_map, NULL },
        { { NULL }, NULL, NULL, NULL }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/payload.c 
new/haproxy-1.7.4/src/payload.c
--- old/haproxy-1.7.3/src/payload.c     2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/payload.c     2017-03-27 23:37:58.000000000 +0200
@@ -838,7 +838,7 @@
                return 0;
 
        chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : 
&smp->strm->req;
-       if (!buf_size || buf_size > global.tune.bufsize || buf_offset + 
buf_size > global.tune.bufsize) {
+       if (buf_size > global.tune.bufsize || buf_offset + buf_size > 
global.tune.bufsize) {
                /* will never match */
                smp->flags = 0;
                return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/proto_http.c 
new/haproxy-1.7.4/src/proto_http.c
--- old/haproxy-1.7.3/src/proto_http.c  2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/proto_http.c  2017-03-27 23:37:58.000000000 +0200
@@ -4253,7 +4253,7 @@
                req->next -= req->sov;
                req->sov = 0;
                s->req.analysers = AN_REQ_HTTP_XFER_BODY | (s->req.analysers & 
AN_REQ_FLT_END);
-               s->res.analysers = AN_RES_HTTP_XFER_BODY | (s->req.analysers & 
AN_RES_FLT_END);
+               s->res.analysers = AN_RES_HTTP_XFER_BODY | (s->res.analysers & 
AN_RES_FLT_END);
                req->msg_state = HTTP_MSG_CLOSED;
                res->msg_state = HTTP_MSG_DONE;
                /* Trim any possible response */
@@ -5310,15 +5310,8 @@
                else
                        si_idle_conn(&s->si[1], &srv->idle_conns);
        }
-
-       if (HAS_FILTERS(s)) {
-               s->req.analysers &= AN_REQ_FLT_END;
-               s->res.analysers &= AN_RES_FLT_END;
-       }
-       else {
-               s->req.analysers = strm_li(s) ? strm_li(s)->analysers : 0;
-               s->res.analysers = 0;
-       }
+       s->req.analysers = strm_li(s) ? strm_li(s)->analysers : 0;
+       s->res.analysers = 0;
 }
 
 
@@ -5674,8 +5667,12 @@
                        s->req.flags |= CF_WAKE_WRITE;
                else if (channel_congested(&s->res))
                        s->res.flags |= CF_WAKE_WRITE;
-               else
-                       http_end_txn_clean_session(s);
+               else {
+                       s->req.analysers = AN_REQ_FLT_END;
+                       s->res.analysers = AN_RES_FLT_END;
+                       txn->flags |= TX_WAIT_CLEANUP;
+                       return 1;
+               }
        }
 
        return txn->req.msg_state != old_req_state ||
@@ -9007,6 +9004,7 @@
        s->res.rex = TICK_ETERNITY;
        s->res.wex = TICK_ETERNITY;
        s->res.analyse_exp = TICK_ETERNITY;
+       s->si[1].hcto = TICK_ETERNITY;
 }
 
 void free_http_res_rules(struct list *r)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/proto_tcp.c 
new/haproxy-1.7.4/src/proto_tcp.c
--- old/haproxy-1.7.3/src/proto_tcp.c   2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/proto_tcp.c   2017-03-27 23:37:58.000000000 +0200
@@ -1698,7 +1698,6 @@
                        l->interface = strdup(args[cur_arg + 1]);
        }
 
-       global.last_checks |= LSTCHK_NETADM;
        return 0;
 }
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/proxy.c 
new/haproxy-1.7.4/src/proxy.c
--- old/haproxy-1.7.3/src/proxy.c       2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/proxy.c       2017-03-27 23:37:58.000000000 +0200
@@ -913,6 +913,58 @@
 }
 
 
+static int proxy_parse_hard_stop_after(char **args, int section_type, struct 
proxy *curpx,
+                                struct proxy *defpx, const char *file, int 
line,
+                                char **err)
+{
+       const char *res;
+
+       if (!*args[1]) {
+               memprintf(err, "'%s' expects <time> as argument.\n", args[0]);
+               return -1;
+       }
+       res = parse_time_err(args[1], &global.hard_stop_after, TIME_UNIT_MS);
+       if (res) {
+               memprintf(err, "unexpected character '%c' in argument to 
<%s>.\n", *res, args[0]);
+               return -1;
+       }
+       return 0;
+}
+
+struct task *hard_stop(struct task *t)
+{
+       struct proxy *p;
+       struct stream *s;
+
+       if (killed) {
+               Warning("Some tasks resisted to hard-stop, exiting now.\n");
+               send_log(NULL, LOG_WARNING, "Some tasks resisted to hard-stop, 
exiting now.\n");
+               /* Do some cleanup and explicitely quit */
+               deinit();
+               exit(0);
+       }
+
+       Warning("soft-stop running for too long, performing a hard-stop.\n");
+       send_log(NULL, LOG_WARNING, "soft-stop running for too long, performing 
a hard-stop.\n");
+       p = proxy;
+       while (p) {
+               if ((p->cap & PR_CAP_FE) && (p->feconn > 0)) {
+                       Warning("Proxy %s hard-stopped (%d remaining conns will 
be closed).\n",
+                               p->id, p->feconn);
+                       send_log(p, LOG_WARNING, "Proxy %s hard-stopped (%d 
remaining conns will be closed).\n",
+                               p->id, p->feconn);
+               }
+               p = p->next;
+       }
+       list_for_each_entry(s, &streams, list) {
+               stream_shutdown(s, SF_ERR_KILLED);
+       }
+
+       killed = 1;
+       t->expire = tick_add(now_ms, MS_TO_TICKS(1000));
+       return t;
+}
+
 /*
  * this function disables health-check servers so that the process will 
quickly be ignored
  * by load balancers. Note that if a proxy was already in the PAUSED state, 
then its grace
@@ -922,8 +974,19 @@
 {
        struct proxy *p;
        struct peers *prs;
+       struct task *task;
 
        stopping = 1;
+       if (tick_isset(global.hard_stop_after)) {
+               task = task_new();
+               if (task) {
+                       task->process = hard_stop;
+                       task_schedule(task, tick_add(now_ms, 
global.hard_stop_after));
+               }
+               else {
+                       Alert("out of memory trying to allocate the hard-stop 
task.\n");
+               }
+       }
        p = proxy;
        tv_update_date(0,1); /* else, the old time before select will be used */
        while (p) {
@@ -1151,6 +1214,9 @@
        if (be->options2 & PR_O2_INDEPSTR)
                s->si[1].flags |= SI_FL_INDEP_STR;
 
+       if (tick_isset(be->timeout.serverfin))
+               s->si[1].hcto = be->timeout.serverfin;
+
        /* We want to enable the backend-specific analysers except those which
         * were already run as part of the frontend/listener. Note that it would
         * be more reliable to store the list of analysers that have been run,
@@ -1211,6 +1277,7 @@
 }
 
 static struct cfg_kw_list cfg_kws = {ILH, {
+       { CFG_GLOBAL, "hard-stop-after", proxy_parse_hard_stop_after },
        { CFG_LISTEN, "timeout", proxy_parse_timeout },
        { CFG_LISTEN, "clitimeout", proxy_parse_timeout },
        { CFG_LISTEN, "contimeout", proxy_parse_timeout },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/raw_sock.c 
new/haproxy-1.7.4/src/raw_sock.c
--- old/haproxy-1.7.3/src/raw_sock.c    2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/raw_sock.c    2017-03-27 23:37:58.000000000 +0200
@@ -296,13 +296,21 @@
                        if (ret < try) {
                                /* unfortunately, on level-triggered events, 
POLL_HUP
                                 * is generally delivered AFTER the system 
buffer is
-                                * empty, so this one might never match.
+                                * empty, unless the poller supports 
POLL_RDHUP. If
+                                * we know this is the case, we don't try to 
read more
+                                * as we know there's no more available. 
Similarly, if
+                                * there's no problem with lingering we don't 
even try
+                                * to read an unlikely close from the client 
since we'll
+                                * close first anyway.
                                 */
                                if (fdtab[conn->t.sock.fd].ev & FD_POLL_HUP)
                                        goto read0;
 
-                               fd_done_recv(conn->t.sock.fd);
-                               break;
+                               if ((!fdtab[conn->t.sock.fd].linger_risk) ||
+                                   (cur_poller.flags & HAP_POLL_F_RDHUP)) {
+                                       fd_done_recv(conn->t.sock.fd);
+                                       break;
+                               }
                        }
                        count -= ret;
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/server.c 
new/haproxy-1.7.4/src/server.c
--- old/haproxy-1.7.3/src/server.c      2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/server.c      2017-03-27 23:37:58.000000000 +0200
@@ -951,7 +951,7 @@
                else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, 
args[0], NULL))
                        err_code |= ERR_ALERT | ERR_FATAL;
 
-               if (!*args[2]) {
+               if (!defsrv && !*args[2]) {
                        Alert("parsing [%s:%d] : '%s' expects <name> and 
<addr>[:<port>] as arguments.\n",
                              file, linenum, args[0]);
                        err_code |= ERR_ALERT | ERR_FATAL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/ssl_sock.c 
new/haproxy-1.7.4/src/ssl_sock.c
--- old/haproxy-1.7.3/src/ssl_sock.c    2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/ssl_sock.c    2017-03-27 23:37:58.000000000 +0200
@@ -433,6 +433,8 @@
 
        ret = 0;
 out:
+       ERR_clear_error();
+
        if (bs)
                 OCSP_BASICRESP_free(bs);
 
@@ -1464,7 +1466,7 @@
                }
                return (s->strict_sni ?
                        SSL_TLSEXT_ERR_ALERT_FATAL :
-                       SSL_TLSEXT_ERR_ALERT_WARNING);
+                       SSL_TLSEXT_ERR_OK);
        }
 
        /* switch ctx */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/stream.c 
new/haproxy-1.7.4/src/stream.c
--- old/haproxy-1.7.3/src/stream.c      2017-02-28 09:59:23.000000000 +0100
+++ new/haproxy-1.7.4/src/stream.c      2017-03-27 23:37:58.000000000 +0200
@@ -168,6 +168,7 @@
        /* this part should be common with other protocols */
        si_reset(&s->si[0]);
        si_set_state(&s->si[0], SI_ST_EST);
+       s->si[0].hcto = sess->fe->timeout.clientfin;
 
        /* attach the incoming connection to the stream interface now. */
        if (conn)
@@ -182,6 +183,7 @@
         * callbacks will be initialized before attempting to connect.
         */
        si_reset(&s->si[1]);
+       s->si[1].hcto = TICK_ETERNITY;
 
        if (likely(sess->fe->options2 & PR_O2_INDEPSTR))
                s->si[1].flags |= SI_FL_INDEP_STR;
@@ -2056,10 +2058,6 @@
                if (req->flags & CF_READ_ERROR)
                        si_b->flags |= SI_FL_NOLINGER;
                si_shutw(si_b);
-               if (tick_isset(s->be->timeout.serverfin)) {
-                       res->rto = s->be->timeout.serverfin;
-                       res->rex = tick_add(now_ms, res->rto);
-               }
        }
 
        /* shutdown(write) done on server side, we must stop the client too */
@@ -2239,10 +2237,6 @@
        if (unlikely((res->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
                     channel_is_empty(res))) {
                si_shutw(si_f);
-               if (tick_isset(sess->fe->timeout.clientfin)) {
-                       req->rto = sess->fe->timeout.clientfin;
-                       req->rex = tick_add(now_ms, req->rto);
-               }
        }
 
        /* shutdown(write) done on the client side, we must stop the server too 
*/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.3/src/stream_interface.c 
new/haproxy-1.7.4/src/stream_interface.c
--- old/haproxy-1.7.3/src/stream_interface.c    2017-02-28 09:59:23.000000000 
+0100
+++ new/haproxy-1.7.4/src/stream_interface.c    2017-03-27 23:37:58.000000000 
+0200
@@ -205,6 +205,11 @@
        oc->wex = TICK_ETERNITY;
        si->flags &= ~SI_FL_WAIT_DATA;
 
+       if (tick_isset(si->hcto)) {
+               ic->rto = si->hcto;
+               ic->rex = tick_add(now_ms, ic->rto);
+       }
+
        switch (si->state) {
        case SI_ST_EST:
                /* we have to shut before closing, otherwise some short messages
@@ -563,7 +568,8 @@
        if (conn->flags & CO_FL_ERROR)
                si->flags |= SI_FL_ERR;
 
-       if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | 
CO_FL_CONNECTED)))) {
+       if ((si->state < SI_ST_EST) &&
+           (conn->flags & (CO_FL_CONNECTED | CO_FL_HANDSHAKE)) == 
CO_FL_CONNECTED) {
                si->exp = TICK_ETERNITY;
                oc->flags |= CF_WRITE_NULL;
        }
@@ -825,6 +831,11 @@
        oc->wex = TICK_ETERNITY;
        si->flags &= ~SI_FL_WAIT_DATA;
 
+       if (tick_isset(si->hcto)) {
+               ic->rto = si->hcto;
+               ic->rex = tick_add(now_ms, ic->rto);
+       }
+
        switch (si->state) {
        case SI_ST_EST:
                /* we have to shut before closing, otherwise some short messages
@@ -1440,6 +1451,11 @@
        oc->wex = TICK_ETERNITY;
        si->flags &= ~SI_FL_WAIT_DATA;
 
+       if (tick_isset(si->hcto)) {
+               ic->rto = si->hcto;
+               ic->rex = tick_add(now_ms, ic->rto);
+       }
+
        /* on shutw we always wake the applet up */
        appctx_wakeup(si_appctx(si));
 


Reply via email to