Hello community,

here is the log from the commit of package haproxy for openSUSE:Factory checked 
in at 2018-05-08 13:38:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/haproxy (Old)
 and      /work/SRC/openSUSE:Factory/.haproxy.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "haproxy"

Tue May  8 13:38:45 2018 rev:60 rq:605117 version:1.8.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/haproxy/haproxy.changes  2018-03-28 
10:30:01.491972780 +0200
+++ /work/SRC/openSUSE:Factory/.haproxy.new/haproxy.changes     2018-05-08 
13:38:45.978464236 +0200
@@ -1,0 +2,44 @@
+Mon May 07 12:57:54 UTC 2018 - kgronl...@suse.com
+
+- Update to version 1.8.8:
+  * BUG/CRITICAL: h2: fix incorrect frame length check (VUL-0) (bsc#1089837)
+  * MINOR: cli: Ensure the CLI always outputs an error when it should
+  * BUG/MINOR: cli: Guard against NULL messages when using CLI_ST_PRINT_FREE
+  * BUG/MEDIUM: kqueue: When adding new events, provide an output to get 
errors.
+  * BUG/MINOR: http: Return an error in proxy mode when url2sa fails
+  * BUG/MEDIUM: connection: Make sure we have a mux before calling detach().
+  * BUG/MEDIUM: threads: Fix the max/min calculation because of name clashes
+
+-------------------------------------------------------------------
+Sat Apr 07 00:15:13 UTC 2018 - mrueck...@suse.de
+
+- Update to version 1.8.7:
+  * [RELEASE] Released version 1.8.7
+  * MINOR: servers: Support alphanumeric characters for the server templates 
names
+  * BUG/MAJOR: cache: always initialize newly created objects
+  * [RELEASE] Released version 1.8.6
+  * BUG/MINOR: spoe: Don't release the context buffer in .check_timeouts 
callbaclk
+  * BUG/MINOR: spoe: Initialize variables used during conf parsing before any 
check
+  * BUG/MAJOR: cache: fix random crashes caused by incorrect delete() on 
non-first blocks
+  * BUG/MINOR: fd: Don't clear the update_mask in fd_insert.
+  * BUG/MINOR: cache: fix "show cache" output
+  * BUG/MINOR: email-alert: Set the mailer port during alert initialization
+  * BUG/MINOR: checks: check the conn_stream's readiness and not the connection
+  * BUG/MEDIUM: h2: always add a stream to the send or fctl list when blocked
+  * BUILD/MINOR: threads: always export thread_sync_io_handler()
+  * BUG/MEDIUM: h2: don't consider pending data on detach if connection is in 
error
+  * BUG/MEDIUM: h2/threads: never release the task outside of the task handler
+  * MINOR: h2: fuse h2s_detach() and h2s_free() into h2s_destroy()
+  * MINOR: h2: always call h2s_detach() in h2_detach()
+  * BUG/MAJOR: h2: remove orphaned streams from the send list before closing
+  * MINOR: h2: provide and use h2s_detach() and h2s_free()
+  * CLEANUP: h2: rename misleading h2c_stream_close() to h2s_close()
+  * BUG/MINOR: hpack: fix harmless use of uninitialized value in 
hpack_dht_insert
+  * BUILD/MINOR: cli: fix a build warning introduced by last commit
+  * MINOR: cli: make "show fd" report the mux and mux_ctx pointers when 
available
+  * MINOR: cli/threads: make "show fd" report thread_sync_io_handler instead 
of "unknown"
+  * BUILD/MINOR: fix build when USE_THREAD is not defined
+  * BUG/MINOR: lua funtion hlua_socket_settimeout don't check negative values
+  * BUG/MINOR: lua: the function returns anything
+
+-------------------------------------------------------------------

Old:
----
  haproxy-1.8.5.tar.gz

New:
----
  haproxy-1.8.8.tar.gz

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

Other differences:
------------------
++++++ haproxy.spec ++++++
--- /var/tmp/diff_new_pack.PwITkv/_old  2018-05-08 13:38:46.746436516 +0200
+++ /var/tmp/diff_new_pack.PwITkv/_new  2018-05-08 13:38:46.750436372 +0200
@@ -40,7 +40,7 @@
 %bcond_without  apparmor
 
 Name:           haproxy
-Version:        1.8.5
+Version:        1.8.8
 Release:        0
 #
 #

++++++ _service ++++++
--- /var/tmp/diff_new_pack.PwITkv/_old  2018-05-08 13:38:46.790434928 +0200
+++ /var/tmp/diff_new_pack.PwITkv/_new  2018-05-08 13:38:46.790434928 +0200
@@ -3,8 +3,8 @@
     <param name="url">http://git.haproxy.org/git/haproxy-1.8.git</param>
     <param name="scm">git</param>
     <param name="filename">haproxy</param>
-    <param name="versionformat">1.8.5</param>
-    <param name="revision">v1.8.5</param>
+    <param name="versionformat">1.8.8</param>
+    <param name="revision">v1.8.8</param>
     <param name="changesgenerate">enable</param>
   </service>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.PwITkv/_old  2018-05-08 13:38:46.814434062 +0200
+++ /var/tmp/diff_new_pack.PwITkv/_new  2018-05-08 13:38:46.818433918 +0200
@@ -5,4 +5,4 @@
             <param 
name="url">http://git.haproxy.org/git/haproxy-1.7.git</param>
           <param 
name="changesrevision">640d526f8cdad00f7f5043b51f6a34f3f6ebb49f</param></service><service
 name="tar_scm">
                 <param 
name="url">http://git.haproxy.org/git/haproxy-1.8.git</param>
-              <param 
name="changesrevision">9a083d1428b655c0079b4355d764cc08d66757f2</param></service></servicedata>
\ No newline at end of file
+              <param 
name="changesrevision">cd117685f0cff4f2f5577ef6a21eaae96ebd9f28</param></service></servicedata>
\ No newline at end of file

++++++ haproxy-1.8.5.tar.gz -> haproxy-1.8.8.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/CHANGELOG new/haproxy-1.8.8/CHANGELOG
--- old/haproxy-1.8.5/CHANGELOG 2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/CHANGELOG 2018-04-19 17:20:31.000000000 +0200
@@ -1,6 +1,45 @@
 ChangeLog :
 ===========
 
+2018/04/19 : 1.8.8
+    - BUG/MEDIUM: threads: Fix the max/min calculation because of name clashes
+    - BUG/MEDIUM: connection: Make sure we have a mux before calling detach().
+    - BUG/MINOR: http: Return an error in proxy mode when url2sa fails
+    - BUG/MEDIUM: kqueue: When adding new events, provide an output to get 
errors.
+    - BUG/MINOR: cli: Guard against NULL messages when using CLI_ST_PRINT_FREE
+    - MINOR: cli: Ensure the CLI always outputs an error when it should
+    - DOC: lua: update the links to the config and Lua API
+    - BUG/CRITICAL: h2: fix incorrect frame length check
+
+2018/04/07 : 1.8.7
+    - BUG/MAJOR: cache: always initialize newly created objects
+    - MINOR: servers: Support alphanumeric characters for the server templates 
names
+
+2018/04/05 : 1.8.6
+    - BUG/MINOR: lua: the function returns anything
+    - BUG/MINOR: lua funtion hlua_socket_settimeout don't check negative values
+    - BUILD/MINOR: fix build when USE_THREAD is not defined
+    - MINOR: cli/threads: make "show fd" report thread_sync_io_handler instead 
of "unknown"
+    - MINOR: cli: make "show fd" report the mux and mux_ctx pointers when 
available
+    - BUILD/MINOR: cli: fix a build warning introduced by last commit
+    - BUG/MINOR: hpack: fix harmless use of uninitialized value in 
hpack_dht_insert
+    - CLEANUP: h2: rename misleading h2c_stream_close() to h2s_close()
+    - MINOR: h2: provide and use h2s_detach() and h2s_free()
+    - BUG/MAJOR: h2: remove orphaned streams from the send list before closing
+    - MINOR: h2: always call h2s_detach() in h2_detach()
+    - MINOR: h2: fuse h2s_detach() and h2s_free() into h2s_destroy()
+    - BUG/MEDIUM: h2/threads: never release the task outside of the task 
handler
+    - BUG/MEDIUM: h2: don't consider pending data on detach if connection is 
in error
+    - BUILD/MINOR: threads: always export thread_sync_io_handler()
+    - BUG/MEDIUM: h2: always add a stream to the send or fctl list when blocked
+    - BUG/MINOR: checks: check the conn_stream's readiness and not the 
connection
+    - BUG/MINOR: email-alert: Set the mailer port during alert initialization
+    - BUG/MINOR: cache: fix "show cache" output
+    - BUG/MINOR: fd: Don't clear the update_mask in fd_insert.
+    - BUG/MAJOR: cache: fix random crashes caused by incorrect delete() on 
non-first blocks
+    - BUG/MINOR: spoe: Initialize variables used during conf parsing before 
any check
+    - BUG/MINOR: spoe: Don't release the context buffer in .check_timeouts 
callbaclk
+
 2018/03/23 : 1.8.5
     - BUG/MINOR: threads: fix missing thread lock labels for 1.8
     - BUG/MEDIUM: ssl: Don't always treat SSL_ERROR_SYSCALL as unrecovarable.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/README new/haproxy-1.8.8/README
--- old/haproxy-1.8.5/README    2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/README    2018-04-19 17:20:31.000000000 +0200
@@ -3,7 +3,7 @@
                          ----------------------
                               version 1.8
                              willy tarreau
-                               2018/03/23
+                               2018/04/19
 
 
 1) How to build it
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/VERDATE new/haproxy-1.8.8/VERDATE
--- old/haproxy-1.8.5/VERDATE   2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/VERDATE   2018-04-19 17:20:31.000000000 +0200
@@ -1,2 +1,2 @@
 $Format:%ci$
-2018/03/23
+2018/04/19
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/VERSION new/haproxy-1.8.8/VERSION
--- old/haproxy-1.8.5/VERSION   2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/VERSION   2018-04-19 17:20:31.000000000 +0200
@@ -1 +1 @@
-1.8.5
+1.8.8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/doc/configuration.txt 
new/haproxy-1.8.8/doc/configuration.txt
--- old/haproxy-1.8.5/doc/configuration.txt     2018-03-23 16:58:34.000000000 
+0100
+++ new/haproxy-1.8.8/doc/configuration.txt     2018-04-19 17:20:31.000000000 
+0200
@@ -4,7 +4,7 @@
                          ----------------------
                               version 1.8
                              willy tarreau
-                              2018/03/23
+                              2018/04/19
 
 
 This document covers the configuration language as implemented in the version
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/doc/lua.txt 
new/haproxy-1.8.8/doc/lua.txt
--- old/haproxy-1.8.5/doc/lua.txt       2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/doc/lua.txt       2018-04-19 17:20:31.000000000 +0200
@@ -1,6 +1,6 @@
                    Lua: Architecture and first steps
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                             version 1.0
+                             version 1.8
 
                         author: Thierry FOURNIER
                  contact: tfournier at arpalert dot org
@@ -83,9 +83,9 @@
 Reading the following documentation links is required to understand the
 current paragraph:
 
-   HAProxy doc: http://cbonte.github.io/haproxy-dconv/configuration-1.6.html
+   HAProxy doc: http://cbonte.github.io/haproxy-dconv/
    Lua API:     http://www.lua.org/manual/5.3/
-   HAProxy API: http://www.arpalert.org/src/haproxy-lua-api/1.6/index.html
+   HAProxy API: http://www.arpalert.org/src/haproxy-lua-api/1.8/index.html
    Lua guide:   http://www.lua.org/pil/
 
 more about Lua choice
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/examples/haproxy.spec 
new/haproxy-1.8.8/examples/haproxy.spec
--- old/haproxy-1.8.5/examples/haproxy.spec     2018-03-23 16:58:34.000000000 
+0100
+++ new/haproxy-1.8.8/examples/haproxy.spec     2018-04-19 17:20:31.000000000 
+0200
@@ -1,6 +1,6 @@
 Summary: HA-Proxy is a TCP/HTTP reverse proxy for high availability 
environments
 Name: haproxy
-Version: 1.8.5
+Version: 1.8.8
 Release: 1
 License: GPL
 Group: System Environment/Daemons
@@ -74,6 +74,15 @@
 %attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
 
 %changelog
+* Thu Apr 19 2018 Willy Tarreau <w...@1wt.eu>
+- updated to 1.8.8
+
+* Sat Apr  7 2018 Willy Tarreau <w...@1wt.eu>
+- updated to 1.8.7
+
+* Thu Apr  5 2018 Willy Tarreau <w...@1wt.eu>
+- updated to 1.8.6
+
 * Fri Mar 23 2018 Willy Tarreau <w...@1wt.eu>
 - updated to 1.8.5
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/include/common/hathreads.h 
new/haproxy-1.8.8/include/common/hathreads.h
--- old/haproxy-1.8.5/include/common/hathreads.h        2018-03-23 
16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/include/common/hathreads.h        2018-04-19 
17:20:31.000000000 +0200
@@ -41,26 +41,26 @@
 #define HA_ATOMIC_OR(val, flags)     ({*(val) |= (flags);})
 #define HA_ATOMIC_XCHG(val, new)                                       \
        ({                                                              \
-               typeof(*(val)) __old = *(val);                          \
+               typeof(*(val)) __old_xchg = *(val);                     \
                *(val) = new;                                           \
-               __old;                                                  \
+               __old_xchg;                                             \
        })
 #define HA_ATOMIC_STORE(val, new)    ({*(val) = new;})
 #define HA_ATOMIC_UPDATE_MAX(val, new)                                 \
        ({                                                              \
-               typeof(*(val)) __new = (new);                           \
+               typeof(*(val)) __new_max = (new);                       \
                                                                        \
-               if (*(val) < __new)                                     \
-                       *(val) = __new;                                 \
+               if (*(val) < __new_max)                                 \
+                       *(val) = __new_max;                             \
                *(val);                                                 \
        })
 
 #define HA_ATOMIC_UPDATE_MIN(val, new)                                 \
        ({                                                              \
-               typeof(*(val)) __new = (new);                           \
+               typeof(*(val)) __new_min = (new);                       \
                                                                        \
-               if (*(val) > __new)                                     \
-                       *(val) = __new;                                 \
+               if (*(val) > __new_min)                                 \
+                       *(val) = __new_min;                             \
                *(val);                                                 \
        })
 
@@ -120,38 +120,38 @@
  * but only if it differs from the expected one. If it's the same it's a race
  * thus we try again to avoid confusing a possibly sensitive caller.
  */
-#define HA_ATOMIC_CAS(val, old, new)                                          \
-       ({                                                                     \
-               typeof((val)) __val = (val);                                   \
-               typeof((old)) __oldp = (old);                                  \
-               typeof(*(old)) __oldv;                                         \
-               typeof((new)) __new = (new);                                   \
-               int __ret;                                                     \
-               do {                                                           \
-                       __oldv = *__val;                                       \
-                       __ret = __sync_bool_compare_and_swap(__val, *__oldp, 
__new); \
-               } while (!__ret && *__oldp == __oldv);                         \
-               if (!__ret)                                                    \
-                       *__oldp = __oldv;                                      \
-               __ret;                                                         \
+#define HA_ATOMIC_CAS(val, old, new)                                   \
+       ({                                                              \
+               typeof((val)) __val_cas = (val);                        \
+               typeof((old)) __oldp_cas = (old);                       \
+               typeof(*(old)) __oldv_cas;                              \
+               typeof((new)) __new_cas = (new);                        \
+               int __ret_cas;                                          \
+               do {                                                    \
+                       __oldv_cas = *__val_cas;                        \
+                       __ret_cas = __sync_bool_compare_and_swap(__val_cas, 
*__oldp_cas, __new_cas); \
+               } while (!__ret_cas && *__oldp_cas == __oldv_cas);      \
+               if (!__ret_cas)                                         \
+                       *__oldp_cas = __oldv_cas;                       \
+               __ret_cas;                                              \
        })
 
-#define HA_ATOMIC_XCHG(val, new)                                              \
-       ({                                                                     \
-               typeof((val)) __val = (val);                                   \
-               typeof(*(val)) __old;                                          \
-               typeof((new)) __new = (new);                                   \
-               do { __old = *__val;                                           \
-               } while (!__sync_bool_compare_and_swap(__val, __old, __new));  \
-               __old;                                                         \
+#define HA_ATOMIC_XCHG(val, new)                                       \
+       ({                                                              \
+               typeof((val)) __val_xchg = (val);                       \
+               typeof(*(val)) __old_xchg;                              \
+               typeof((new)) __new_xchg = (new);                       \
+               do { __old_xchg = *__val_xchg;                          \
+               } while (!__sync_bool_compare_and_swap(__val_xchg, __old_xchg, 
__new_xchg)); \
+               __old_xchg;                                             \
        })
-#define HA_ATOMIC_STORE(val, new)                                           \
-       ({                                                                     \
-               typeof((val)) __val = (val);                                   \
-               typeof(*(val)) __old;                                          \
-               typeof((new)) __new = (new);                                   \
-               do { __old = *__val;                                           \
-               } while (!__sync_bool_compare_and_swap(__val, __old, __new));  \
+#define HA_ATOMIC_STORE(val, new)                                      \
+       ({                                                              \
+               typeof((val)) __val_store = (val);                      \
+               typeof(*(val)) __old_store;                             \
+               typeof((new)) __new_store = (new);                      \
+               do { __old_store = *__val_store;                        \
+               } while (!__sync_bool_compare_and_swap(__val_store, 
__old_store, __new_store)); \
        })
 #else
 /* gcc >= 4.7 */
@@ -166,19 +166,21 @@
 
 #define HA_ATOMIC_UPDATE_MAX(val, new)                                 \
        ({                                                              \
-               typeof(*(val)) __old = *(val);                          \
-               typeof(*(val)) __new = (new);                           \
+               typeof(*(val)) __old_max = *(val);                      \
+               typeof(*(val)) __new_max = (new);                       \
                                                                        \
-               while (__old < __new && !HA_ATOMIC_CAS(val, &__old, __new)); \
-               (*val);                                                 \
+               while (__old_max < __new_max &&                         \
+                      !HA_ATOMIC_CAS(val, &__old_max, __new_max));     \
+               *(val);                                                 \
        })
 #define HA_ATOMIC_UPDATE_MIN(val, new)                                 \
        ({                                                              \
-               typeof((*val)) __old = *(val);                          \
-               typeof((*val)) __new = (new);                           \
+               typeof(*(val)) __old_min = *(val);                      \
+               typeof(*(val)) __new_min = (new);                       \
                                                                        \
-               while (__old > __new && !HA_ATOMIC_CAS(val, &__old, __new)); \
-               (*val);                                                 \
+               while (__old_min > __new_min &&                         \
+                      !HA_ATOMIC_CAS(val, &__old_min, __new_min));     \
+               *(val);                                                 \
        })
 
 #define HA_BARRIER() pl_barrier()
@@ -678,4 +680,7 @@
 
 #endif /* USE_THREAD */
 
+/* Dummy I/O handler used by the sync pipe.*/
+void thread_sync_io_handler(int fd);
+
 #endif /* _COMMON_HATHREADS_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/include/proto/connection.h 
new/haproxy-1.8.8/include/proto/connection.h
--- old/haproxy-1.8.5/include/proto/connection.h        2018-03-23 
16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/include/proto/connection.h        2018-04-19 
17:20:31.000000000 +0200
@@ -701,7 +701,20 @@
 /* Release a conn_stream, and kill the connection if it was the last one */
 static inline void cs_destroy(struct conn_stream *cs)
 {
-       cs->conn->mux->detach(cs);
+       if (cs->conn->mux)
+               cs->conn->mux->detach(cs);
+       else {
+               /* It's too early to have a mux, let's just destroy
+                * the connection
+                */
+               struct connection *conn = cs->conn;
+
+               conn_stop_tracking(conn);
+               conn_full_close(conn);
+               if (conn->destroy_cb)
+                       conn->destroy_cb(conn);
+               conn_free(conn);
+       }
        cs_free(cs);
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/include/proto/fd.h 
new/haproxy-1.8.8/include/proto/fd.h
--- old/haproxy-1.8.5/include/proto/fd.h        2018-03-23 16:58:34.000000000 
+0100
+++ new/haproxy-1.8.8/include/proto/fd.h        2018-04-19 17:20:31.000000000 
+0200
@@ -400,7 +400,6 @@
        HA_SPIN_LOCK(FD_LOCK, &fdtab[fd].lock);
        fdtab[fd].ev = 0;
        fdtab[fd].new = 1;
-       fdtab[fd].update_mask &= ~tid_bit;
        fdtab[fd].linger_risk = 0;
        fdtab[fd].cloned = 0;
        fdtab[fd].cache = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/cache.c 
new/haproxy-1.8.8/src/cache.c
--- old/haproxy-1.8.5/src/cache.c       2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/cache.c       2018-04-19 17:20:31.000000000 +0200
@@ -378,13 +378,11 @@
 
 static void cache_free_blocks(struct shared_block *first, struct shared_block 
*block)
 {
-       if (first == block) {
-               struct cache_entry *object = (struct cache_entry *)first->data;
-               if (object->eb.key) {
-                       eb32_delete(&object->eb);
-                       object->eb.key = 0;
-               }
-       }
+       struct cache_entry *object = (struct cache_entry *)block->data;
+
+       if (first == block && object->eb.key)
+               eb32_delete(&object->eb);
+       object->eb.key = 0;
 }
 
 /*
@@ -448,6 +446,13 @@
        }
        shctx_unlock(shctx);
 
+       /* the received memory is not initialized, we need at least to mark
+        * the object as not indexed yet.
+        */
+       object = (struct cache_entry *)first->data;
+       object->eb.node.leaf_p = NULL;
+       object->eb.key = 0;
+
        /* reserve space for the cache_entry structure */
        first->len = sizeof(struct cache_entry);
 
@@ -472,7 +477,6 @@
                                        struct cache_entry *old;
 
                                        cache_ctx->first_block = first;
-                                       object = (struct cache_entry 
*)first->data;
 
                                        object->eb.key = (*(unsigned int 
*)&txn->cache_hash);
                                        memcpy(object->hash, txn->cache_hash, 
sizeof(object->hash));
@@ -499,8 +503,6 @@
 out:
        /* if does not cache */
        if (first) {
-               object = (struct cache_entry *)first->data;
-
                shctx_lock(shctx);
                first->len = 0;
                object->eb.key = 0;
@@ -963,9 +965,6 @@
        struct cache* cache = appctx->ctx.cli.p0;
        struct stream_interface *si = appctx->owner;
 
-       chunk_reset(&trash);
-
-
        if (cache == NULL) {
                cache = LIST_ELEM((caches).n, typeof(struct cache *), list);
        }
@@ -975,9 +974,14 @@
                unsigned int next_key;
                struct cache_entry *entry;
 
-               chunk_appendf(&trash, "%p: %s (shctx:%p, available 
blocks:%d)\n", cache, cache->id, shctx_ptr(cache), shctx_ptr(cache)->nbav);
-
                next_key = appctx->ctx.cli.i0;
+               if (!next_key) {
+                       chunk_printf(&trash, "%p: %s (shctx:%p, available 
blocks:%d)\n", cache, cache->id, shctx_ptr(cache), shctx_ptr(cache)->nbav);
+                       if (ci_putchk(si_ic(si), &trash) == -1) {
+                               si_applet_cant_put(si);
+                               return 0;
+                       }
+               }
 
                appctx->ctx.cli.p0 = cache;
 
@@ -987,11 +991,12 @@
                        node = eb32_lookup_ge(&cache->entries, next_key);
                        if (!node) {
                                shctx_unlock(shctx_ptr(cache));
+                               appctx->ctx.cli.i0 = 0;
                                break;
                        }
 
                        entry = container_of(node, struct cache_entry, eb);
-                       chunk_appendf(&trash, "%p hash:%u size:%u (%u blocks), 
refcount:%u, expire:%d\n", entry, (*(unsigned int *)entry->hash), 
block_ptr(entry)->len, block_ptr(entry)->block_count, 
block_ptr(entry)->refcount, entry->expire - (int)now.tv_sec);
+                       chunk_printf(&trash, "%p hash:%u size:%u (%u blocks), 
refcount:%u, expire:%d\n", entry, (*(unsigned int *)entry->hash), 
block_ptr(entry)->len, block_ptr(entry)->block_count, 
block_ptr(entry)->refcount, entry->expire - (int)now.tv_sec);
 
                        next_key = node->key + 1;
                        appctx->ctx.cli.i0 = next_key;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/checks.c 
new/haproxy-1.8.8/src/checks.c
--- old/haproxy-1.8.5/src/checks.c      2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/checks.c      2018-04-19 17:20:31.000000000 +0200
@@ -1394,7 +1394,7 @@
                __cs_stop_both(cs);
                task_wakeup(check->task, TASK_WOKEN_IO);
        }
-       else if (!(conn->flags & 
(CO_FL_XPRT_RD_ENA|CO_FL_XPRT_WR_ENA|CO_FL_HANDSHAKE))) {
+       else if (!(conn->flags & CO_FL_HANDSHAKE) && !(cs->flags & 
(CS_FL_DATA_RD_ENA|CS_FL_DATA_WR_ENA))) {
                /* we may get here if only a connection probe was required : we
                 * don't have any data to send nor anything expected in 
response,
                 * so the completion of the connection establishment is enough.
@@ -3202,9 +3202,7 @@
 
                check->xprt = mailer->xprt;
                check->addr = mailer->addr;
-               if (!get_host_port(&mailer->addr))
-                       /* Default to submission port */
-                       check->port = 587;
+               check->port = get_host_port(&mailer->addr);
                //check->server = s;
 
                if ((t = task_new(MAX_THREADS_MASK)) == NULL) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/cli.c new/haproxy-1.8.8/src/cli.c
--- old/haproxy-1.8.5/src/cli.c 2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/cli.c 2018-04-19 17:20:31.000000000 +0200
@@ -625,14 +625,20 @@
                                else
                                        si_applet_cant_put(si);
                                break;
-                       case CLI_ST_PRINT_FREE:
-                               if (cli_output_msg(res, appctx->ctx.cli.err, 
LOG_ERR, cli_get_severity_output(appctx)) != -1) {
+                       case CLI_ST_PRINT_FREE: {
+                               const char *msg = appctx->ctx.cli.err;
+
+                               if (!msg)
+                                       msg = "Out of memory.\n";
+
+                               if (cli_output_msg(res, msg, LOG_ERR, 
cli_get_severity_output(appctx)) != -1) {
                                        free(appctx->ctx.cli.err);
                                        appctx->st0 = CLI_ST_PROMPT;
                                }
                                else
                                        si_applet_cant_put(si);
                                break;
+                       }
                        case CLI_ST_CALLBACK: /* use custom pointer */
                                if (appctx->io_handler)
                                        if (appctx->io_handler(appctx)) {
@@ -777,6 +783,8 @@
                struct listener *li = NULL;
                struct server *sv = NULL;
                struct proxy *px = NULL;
+               const struct mux_ops *mux = NULL;
+               void *ctx = NULL;
                uint32_t conn_flags = 0;
 
                fdt = fdtab[fd];
@@ -786,6 +794,8 @@
 
                if (fdt.iocb == conn_fd_handler) {
                        conn_flags = ((struct connection *)fdt.owner)->flags;
+                       mux = ((struct connection *)fdt.owner)->mux;
+                       ctx = ((struct connection *)fdt.owner)->mux_ctx;
                        li = objt_listener(((struct connection 
*)fdt.owner)->target);
                        sv = objt_server(((struct connection 
*)fdt.owner)->target);
                        px = objt_proxy(((struct connection 
*)fdt.owner)->target);
@@ -818,6 +828,7 @@
                             (fdt.iocb == conn_fd_handler)  ? "conn_fd_handler" 
:
                             (fdt.iocb == dgram_fd_handler) ? 
"dgram_fd_handler" :
                             (fdt.iocb == listener_accept)  ? "listener_accept" 
:
+                            (fdt.iocb == thread_sync_io_handler) ? 
"thread_sync_io_handler" :
                             "unknown",
                             fdt.thread_mask, fdt.update_mask);
 
@@ -829,6 +840,11 @@
                                chunk_appendf(&trash, " sv=%s/%s", sv->id, 
sv->proxy->id);
                        else if (li)
                                chunk_appendf(&trash, " fe=%s", 
li->bind_conf->frontend->id);
+
+                       if (mux)
+                               chunk_appendf(&trash, " mux=%s mux_ctx=%p", 
mux->name, ctx);
+                       else
+                               chunk_appendf(&trash, " nomux");
                }
                else if (fdt.iocb == listener_accept) {
                        chunk_appendf(&trash, " l.st=%s fe=%s",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/ev_epoll.c 
new/haproxy-1.8.8/src/ev_epoll.c
--- old/haproxy-1.8.5/src/ev_epoll.c    2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/ev_epoll.c    2018-04-19 17:20:31.000000000 +0200
@@ -74,13 +74,15 @@
        for (updt_idx = 0; updt_idx < fd_nbupdt; updt_idx++) {
                fd = fd_updt[updt_idx];
 
+               HA_SPIN_LOCK(FD_LOCK, &fdtab[fd].lock);
+               fdtab[fd].update_mask &= ~tid_bit;
+
                if (!fdtab[fd].owner) {
                        activity[tid].poll_drop++;
+                       HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock);
                        continue;
                }
 
-               HA_SPIN_LOCK(FD_LOCK, &fdtab[fd].lock);
-               fdtab[fd].update_mask &= ~tid_bit;
                fdtab[fd].new = 0;
 
                eo = fdtab[fd].state;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/ev_kqueue.c 
new/haproxy-1.8.8/src/ev_kqueue.c
--- old/haproxy-1.8.5/src/ev_kqueue.c   2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/ev_kqueue.c   2018-04-19 17:20:31.000000000 +0200
@@ -31,6 +31,7 @@
 /* private data */
 static int kqueue_fd[MAX_THREADS]; // per-thread kqueue_fd
 static THREAD_LOCAL struct kevent *kev = NULL;
+static struct kevent *kev_out = NULL; // Trash buffer for kevent() to write 
the eventlist in
 
 /*
  * kqueue() poller
@@ -43,17 +44,21 @@
        int updt_idx, en, eo;
        int changes = 0;
 
+       timeout.tv_sec  = 0;
+       timeout.tv_nsec = 0;
        /* first, scan the update list to find changes */
        for (updt_idx = 0; updt_idx < fd_nbupdt; updt_idx++) {
                fd = fd_updt[updt_idx];
 
+               HA_SPIN_LOCK(FD_LOCK, &fdtab[fd].lock);
+               fdtab[fd].update_mask &= ~tid_bit;
+
                if (!fdtab[fd].owner) {
                        activity[tid].poll_drop++;
+                       HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock);
                        continue;
                }
 
-               HA_SPIN_LOCK(FD_LOCK, &fdtab[fd].lock);
-               fdtab[fd].update_mask &= ~tid_bit;
                fdtab[fd].new = 0;
 
                eo = fdtab[fd].state;
@@ -87,13 +92,21 @@
                        HA_ATOMIC_OR(&fdtab[fd].polled_mask, tid_bit);
                }
        }
-       if (changes)
-               kevent(kqueue_fd[tid], kev, changes, NULL, 0, NULL);
+       if (changes) {
+#ifdef EV_RECEIPT
+               kev[0].flags |= EV_RECEIPT;
+#else
+               /* If EV_RECEIPT isn't defined, just add an invalid entry,
+                * so that we get an error and kevent() stops before scanning
+                * the kqueue.
+                */
+               EV_SET(&kev[changes++], -1, EVFILT_WRITE, EV_DELETE, 0, 0, 
NULL);
+#endif
+               kevent(kqueue_fd[tid], kev, changes, kev_out, changes, 
&timeout);
+       }
        fd_nbupdt = 0;
 
        delta_ms        = 0;
-       timeout.tv_sec  = 0;
-       timeout.tv_nsec = 0;
 
        if (!exp) {
                delta_ms        = MAX_DELAY_MS;
@@ -156,8 +169,12 @@
 {
        int fd;
 
-       /* we can have up to two events per fd (*/
-       kev = calloc(1, sizeof(struct kevent) * 2 * global.maxsock);
+       /* we can have up to two events per fd, so allocate enough to store
+        * 2*fd event, and an extra one, in case EV_RECEIPT isn't defined,
+        * so that we can add an invalid entry and get an error, to avoid
+        * scanning the kqueue uselessly.
+        */
+       kev = calloc(1, sizeof(struct kevent) * (2 * global.maxsock + 1));
        if (kev == NULL)
                goto fail_alloc;
 
@@ -200,6 +217,15 @@
 {
        p->private = NULL;
 
+       /* we can have up to two events per fd, so allocate enough to store
+        * 2*fd event, and an extra one, in case EV_RECEIPT isn't defined,
+        * so that we can add an invalid entry and get an error, to avoid
+        * scanning the kqueue uselessly.
+        */
+       kev_out = calloc(1, sizeof(struct kevent) * (2 * global.maxsock + 1));
+       if (!kev_out)
+               goto fail_alloc;
+
        kqueue_fd[tid] = kqueue();
        if (kqueue_fd[tid] < 0)
                goto fail_fd;
@@ -209,6 +235,9 @@
        return 1;
 
  fail_fd:
+       free(kev_out);
+       kev_out = NULL;
+fail_alloc:
        p->pref = 0;
        return 0;
 }
@@ -226,6 +255,10 @@
 
        p->private = NULL;
        p->pref = 0;
+       if (kev_out) {
+               free(kev_out);
+               kev_out = NULL;
+       }
 }
 
 /*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/ev_poll.c 
new/haproxy-1.8.8/src/ev_poll.c
--- old/haproxy-1.8.5/src/ev_poll.c     2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/ev_poll.c     2018-04-19 17:20:31.000000000 +0200
@@ -73,13 +73,15 @@
        for (updt_idx = 0; updt_idx < fd_nbupdt; updt_idx++) {
                fd = fd_updt[updt_idx];
 
+               HA_SPIN_LOCK(FD_LOCK, &fdtab[fd].lock);
+               fdtab[fd].update_mask &= ~tid_bit;
+
                if (!fdtab[fd].owner) {
                        activity[tid].poll_drop++;
+                       HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock);
                        continue;
                }
 
-               HA_SPIN_LOCK(FD_LOCK, &fdtab[fd].lock);
-               fdtab[fd].update_mask &= ~tid_bit;
                fdtab[fd].new = 0;
 
                eo = fdtab[fd].state;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/ev_select.c 
new/haproxy-1.8.8/src/ev_select.c
--- old/haproxy-1.8.5/src/ev_select.c   2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/ev_select.c   2018-04-19 17:20:31.000000000 +0200
@@ -55,13 +55,15 @@
        for (updt_idx = 0; updt_idx < fd_nbupdt; updt_idx++) {
                fd = fd_updt[updt_idx];
 
+               HA_SPIN_LOCK(FD_LOCK, &fdtab[fd].lock);
+               fdtab[fd].update_mask &= ~tid_bit;
+
                if (!fdtab[fd].owner) {
                        activity[tid].poll_drop++;
+                       HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock);
                        continue;
                }
 
-               HA_SPIN_LOCK(FD_LOCK, &fdtab[fd].lock);
-               fdtab[fd].update_mask &= ~tid_bit;
                fdtab[fd].new = 0;
 
                eo = fdtab[fd].state;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/flt_spoe.c 
new/haproxy-1.8.8/src/flt_spoe.c
--- old/haproxy-1.8.5/src/flt_spoe.c    2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/flt_spoe.c    2018-04-19 17:20:31.000000000 +0200
@@ -2988,10 +2988,8 @@
 {
        struct spoe_context *ctx = filter->ctx;
 
-       if (tick_is_expired(ctx->process_exp, now_ms)) {
+       if (tick_is_expired(ctx->process_exp, now_ms))
                s->pending_events |= TASK_WOKEN_MSG;
-               spoe_release_buffer(&ctx->buffer, &ctx->buffer_wait);
-       }
 }
 
 /* Called when we are ready to filter data on a channel */
@@ -3767,6 +3765,11 @@
        char                        *file = NULL, *engine = NULL;
        int                          ret, pos = *cur_arg + 1;
 
+       LIST_INIT(&curmsgs);
+       LIST_INIT(&curgrps);
+       LIST_INIT(&curmphs);
+       LIST_INIT(&curgphs);
+
        conf = calloc(1, sizeof(*conf));
        if (conf == NULL) {
                memprintf(err, "%s: out of memory", args[*cur_arg]);
@@ -3815,10 +3818,6 @@
        curproxy  = px;
        curagent  = NULL;
        curmsg    = NULL;
-       LIST_INIT(&curmsgs);
-       LIST_INIT(&curgrps);
-       LIST_INIT(&curmphs);
-       LIST_INIT(&curgphs);
        ret = readcfgfile(file);
        curproxy = NULL;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/hathreads.c 
new/haproxy-1.8.8/src/hathreads.c
--- old/haproxy-1.8.5/src/hathreads.c   2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/hathreads.c   2018-04-19 17:20:31.000000000 +0200
@@ -21,6 +21,11 @@
 THREAD_LOCAL unsigned int tid      = 0;
 THREAD_LOCAL unsigned long tid_bit = (1UL << 0);
 
+/* Dummy I/O handler used by the sync pipe.*/
+void thread_sync_io_handler(int fd)
+{
+}
+
 #ifdef USE_THREAD
 
 static HA_SPINLOCK_T sync_lock;
@@ -32,9 +37,6 @@
 struct lock_stat lock_stats[LOCK_LABELS];
 #endif
 
-/* Dummy I/O handler used by the sync pipe.*/
-static void thread_sync_io_handler(int fd) { }
-
 /* Initializes the sync point. It creates a pipe used by threads to wakup all
  * others when a sync is requested. It also initialize the mask of all create
  * threads. It returns 0 on success and -1 if an error occurred.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/hlua.c new/haproxy-1.8.8/src/hlua.c
--- old/haproxy-1.8.5/src/hlua.c        2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/hlua.c        2018-04-19 17:20:31.000000000 +0200
@@ -2467,6 +2467,10 @@
        socket = MAY_LJMP(hlua_checksocket(L, 1));
        tmout = MAY_LJMP(luaL_checkinteger(L, 2)) * 1000;
 
+       /* Check for negative values */
+       if (tmout < 0)
+               WILL_LJMP(luaL_error(L, "settimeout: cannot set negatives 
values"));
+
        /* Check if we run on the same thread than the xreator thread.
         * We cannot access to the socket if the thread is different.
         */
@@ -2490,6 +2494,7 @@
        s->res.wto = tmout;
        xref_unlock(&socket->xref, peer);
 
+       lua_pushinteger(L, 1);
        return 1;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/hpack-tbl.c 
new/haproxy-1.8.8/src/hpack-tbl.c
--- old/haproxy-1.8.5/src/hpack-tbl.c   2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/hpack-tbl.c   2018-04-19 17:20:31.000000000 +0200
@@ -261,15 +261,11 @@
        if (!hpack_dht_make_room(dht, name.len + value.len))
                return 0;
 
-       used = dht->used;
-       prev = head = dht->head;
-       wrap = dht->wrap;
-       tail = hpack_dht_get_tail(dht);
-
        /* Now there is enough room in the table, that's guaranteed by the
         * protocol, but not necessarily where we need it.
         */
 
+       used = dht->used;
        if (!used) {
                /* easy, the table was empty */
                dht->front = dht->head = 0;
@@ -281,6 +277,10 @@
        }
 
        /* compute the new head, used and wrap position */
+       prev = head = dht->head;
+       wrap = dht->wrap;
+       tail = hpack_dht_get_tail(dht);
+
        used++;
        head++;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/map.c new/haproxy-1.8.8/src/map.c
--- old/haproxy-1.8.5/src/map.c 2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/map.c 2018-04-19 17:20:31.000000000 +0200
@@ -726,15 +726,21 @@
                                return 1;
                        }
 
-                       /* Try to delete the entry. */
+                       /* Try to modify the entry. */
                        err = NULL;
                        HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
                        if (!pat_ref_set_by_id(appctx->ctx.map.ref, ref, 
args[4], &err)) {
                                HA_SPIN_UNLOCK(PATREF_LOCK, 
&appctx->ctx.map.ref->lock);
-                               if (err)
+                               if (err) {
                                        memprintf(&err, "%s.\n", err);
-                               appctx->ctx.cli.err = err;
-                               appctx->st0 = CLI_ST_PRINT_FREE;
+                                       appctx->ctx.cli.err = err;
+                                       appctx->st0 = CLI_ST_PRINT_FREE;
+                               }
+                               else {
+                                       appctx->ctx.cli.severity = LOG_ERR;
+                                       appctx->ctx.cli.msg = "Failed to update 
an entry.\n";
+                                       appctx->st0 = CLI_ST_PRINT;
+                               }
                                return 1;
                        }
                        HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
@@ -747,10 +753,16 @@
                        HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
                        if (!pat_ref_set(appctx->ctx.map.ref, args[3], args[4], 
&err)) {
                                HA_SPIN_UNLOCK(PATREF_LOCK, 
&appctx->ctx.map.ref->lock);
-                               if (err)
+                               if (err) {
                                        memprintf(&err, "%s.\n", err);
-                               appctx->ctx.cli.err = err;
-                               appctx->st0 = CLI_ST_PRINT_FREE;
+                                       appctx->ctx.cli.err = err;
+                                       appctx->st0 = CLI_ST_PRINT_FREE;
+                               }
+                               else {
+                                       appctx->ctx.cli.severity = LOG_ERR;
+                                       appctx->ctx.cli.msg = "Failed to update 
an entry.\n";
+                                       appctx->st0 = CLI_ST_PRINT;
+                               }
                                return 1;
                        }
                        HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
@@ -832,10 +844,16 @@
                        ret = pat_ref_add(appctx->ctx.map.ref, args[3], NULL, 
&err);
                HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
                if (!ret) {
-                       if (err)
+                       if (err) {
                                memprintf(&err, "%s.\n", err);
-                       appctx->ctx.cli.err = err;
-                       appctx->st0 = CLI_ST_PRINT_FREE;
+                               appctx->ctx.cli.err = err;
+                               appctx->st0 = CLI_ST_PRINT_FREE;
+                       }
+                       else {
+                               appctx->ctx.cli.severity = LOG_ERR;
+                               appctx->ctx.cli.msg = "Failed to add an 
entry.\n";
+                               appctx->st0 = CLI_ST_PRINT;
+                       }
                        return 1;
                }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/mux_h2.c 
new/haproxy-1.8.8/src/mux_h2.c
--- old/haproxy-1.8.5/src/mux_h2.c      2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/mux_h2.c      2018-04-19 17:20:31.000000000 +0200
@@ -484,8 +484,8 @@
                HA_SPIN_UNLOCK(BUF_WQ_LOCK, &buffer_wq_lock);
 
                if (h2c->task) {
-                       task_delete(h2c->task);
-                       task_free(h2c->task);
+                       h2c->task->context = NULL;
+                       task_wakeup(h2c->task, TASK_WOKEN_OTHER);
                        h2c->task = NULL;
                }
 
@@ -630,18 +630,27 @@
        return ret;
 }
 
-/* marks stream <h2s> as CLOSED for connection <h2c> and decrement the number
- * of active streams for this connection if the stream was not yet closed.
- * Please use this exclusively before closing a stream to ensure stream count
- * is well maintained.
+/* marks stream <h2s> as CLOSED and decrement the number of active streams for
+ * its connection if the stream was not yet closed. Please use this exclusively
+ * before closing a stream to ensure stream count is well maintained.
  */
-static inline void h2c_stream_close(struct h2c *h2c, struct h2s *h2s)
+static inline void h2s_close(struct h2s *h2s)
 {
        if (h2s->st != H2_SS_CLOSED)
                h2s->h2c->nb_streams--;
        h2s->st = H2_SS_CLOSED;
 }
 
+/* detaches an H2 stream from its H2C and releases it to the H2S pool. */
+static void h2s_destroy(struct h2s *h2s)
+{
+       h2s_close(h2s);
+       LIST_DEL(&h2s->list);
+       LIST_INIT(&h2s->list);
+       eb32_delete(&h2s->by_id);
+       pool_free(pool_head_h2s, h2s);
+}
+
 /* creates a new stream <id> on the h2c connection and returns it, or NULL in
  * case of memory allocation error.
  */
@@ -686,9 +695,7 @@
  out_free_cs:
        cs_free(cs);
  out_close:
-       h2c->nb_streams--;
-       eb32_delete(&h2s->by_id);
-       pool_free(pool_head_h2s, h2s);
+       h2s_destroy(h2s);
        h2s = NULL;
  out:
        return h2s;
@@ -924,7 +931,7 @@
 
  ignore:
        h2s->flags |= H2_SF_RST_SENT;
-       h2c_stream_close(h2c, h2s);
+       h2s_close(h2s);
        return ret;
 }
 
@@ -988,7 +995,7 @@
  ignore:
        if (h2s->st > H2_SS_IDLE && h2s->st < H2_SS_CLOSED) {
                h2s->flags |= H2_SF_RST_SENT;
-               h2c_stream_close(h2c, h2s);
+               h2s_close(h2s);
        }
 
        return ret;
@@ -1066,9 +1073,7 @@
 
                if (!h2s->cs) {
                        /* this stream was already orphaned */
-                       h2c_stream_close(h2c, h2s);
-                       eb32_delete(&h2s->by_id);
-                       pool_free(pool_head_h2s, h2s);
+                       h2s_destroy(h2s);
                        continue;
                }
 
@@ -1084,7 +1089,7 @@
                else if (flags & CS_FL_EOS && h2s->st == H2_SS_OPEN)
                        h2s->st = H2_SS_HREM;
                else if (flags & CS_FL_EOS && h2s->st == H2_SS_HLOC)
-                       h2c_stream_close(h2c, h2s);
+                       h2s_close(h2s);
        }
 }
 
@@ -1551,7 +1556,7 @@
                return 1;
 
        h2s->errcode = h2_get_n32(h2c->dbuf, 0);
-       h2c_stream_close(h2c, h2s);
+       h2s_close(h2s);
 
        if (h2s->cs) {
                h2s->cs->flags |= CS_FL_EOS | CS_FL_ERROR;
@@ -1781,7 +1786,7 @@
                                goto fail;
                        }
 
-                       if ((int)hdr.len < 0 || (int)hdr.len > h2c->mfs) {
+                       if ((int)hdr.len < 0 || (int)hdr.len > 
global.tune.bufsize) {
                                /* RFC7540#3.5: a GOAWAY frame MAY be omitted */
                                h2c_error(h2c, H2_ERR_FRAME_SIZE_ERROR);
                                h2c->st0 = H2_CS_ERROR2;
@@ -1811,7 +1816,7 @@
                        if (!h2_peek_frame_hdr(h2c->dbuf, &hdr))
                                break;
 
-                       if ((int)hdr.len < 0 || (int)hdr.len > h2c->mfs) {
+                       if ((int)hdr.len < 0 || (int)hdr.len > 
global.tune.bufsize) {
                                h2c_error(h2c, H2_ERR_FRAME_SIZE_ERROR);
                                h2c->st0 = H2_CS_ERROR;
                                break;
@@ -2099,9 +2104,7 @@
                                        h2s->cs->flags &= ~CS_FL_DATA_WR_ENA;
                                else {
                                        /* just sent the last frame for this 
orphaned stream */
-                                       h2c_stream_close(h2c, h2s);
-                                       eb32_delete(&h2s->by_id);
-                                       pool_free(pool_head_h2s, h2s);
+                                       h2s_destroy(h2s);
                                }
                        }
                }
@@ -2142,9 +2145,7 @@
                                h2s->cs->flags &= ~CS_FL_DATA_WR_ENA;
                        else {
                                /* just sent the last frame for this orphaned 
stream */
-                               h2c_stream_close(h2c, h2s);
-                               eb32_delete(&h2s->by_id);
-                               pool_free(pool_head_h2s, h2s);
+                               h2s_destroy(h2s);
                        }
                }
        }
@@ -2368,9 +2369,18 @@
        struct h2c *h2c = t->context;
        int expired = tick_is_expired(t->expire, now_ms);
 
-       if (!expired)
+       if (!expired && h2c)
                return t;
 
+       task_delete(t);
+       task_free(t);
+
+       if (!h2c) {
+               /* resources were already deleted */
+               return NULL;
+       }
+
+       h2c->task = NULL;
        h2c_error(h2c, H2_ERR_NO_ERROR);
        h2_wake_some_streams(h2c, 0, 0);
 
@@ -2387,17 +2397,12 @@
        if (h2c->mbuf->o && !(h2c->flags & H2_CF_GOAWAY_FAILED) && 
conn_xprt_ready(h2c->conn))
                h2c->conn->xprt->snd_buf(h2c->conn, h2c->mbuf, 0);
 
-       if (!eb_is_empty(&h2c->streams_by_id))
-               goto wait;
-
-       h2_release(h2c->conn);
-       return NULL;
+       /* either we can release everything now or it will be done later once
+        * the last stream closes.
+        */
+       if (eb_is_empty(&h2c->streams_by_id))
+               h2_release(h2c->conn);
 
- wait:
-       /* the streams have been notified, we must let them finish and close */
-       h2c->task = NULL;
-       task_delete(t);
-       task_free(t);
        return NULL;
 }
 
@@ -2482,12 +2487,10 @@
        /* this stream may be blocked waiting for some data to leave (possibly
         * an ES or RST frame), so orphan it in this case.
         */
-       if (h2s->flags & (H2_SF_BLK_MBUSY | H2_SF_BLK_MROOM | H2_SF_BLK_MFCTL))
+       if (!(cs->conn->flags & CO_FL_ERROR) &&
+           (h2s->flags & (H2_SF_BLK_MBUSY | H2_SF_BLK_MROOM | 
H2_SF_BLK_MFCTL)))
                return;
 
-       /* the stream could be in the send list */
-       LIST_DEL(&h2s->list);
-
        if ((h2c->flags & H2_CF_DEM_BLOCK_ANY && h2s->id == h2c->dsi) ||
            (h2c->flags & H2_CF_MUX_BLOCK_ANY && h2s->id == h2c->msi)) {
                /* unblock the connection if it was blocked on this
@@ -2499,35 +2502,30 @@
                conn_xprt_want_send(cs->conn);
        }
 
-       if (h2s->by_id.node.leaf_p) {
-               /* h2s still attached to the h2c */
-               h2c_stream_close(h2c, h2s);
-               eb32_delete(&h2s->by_id);
-
-               /* We don't want to close right now unless we're removing the
-                * last stream, and either the connection is in error, or it
-                * reached the ID already specified in a GOAWAY frame received
-                * or sent (as seen by last_sid >= 0).
-                */
-               if (eb_is_empty(&h2c->streams_by_id) &&     /* don't close if 
streams exist */
-                   ((h2c->conn->flags & CO_FL_ERROR) ||    /* errors close 
immediately */
-                    (h2c->flags & H2_CF_GOAWAY_FAILED) ||
-                    (!h2c->mbuf->o &&  /* mux buffer empty, also process clean 
events below */
-                     (conn_xprt_read0_pending(h2c->conn) ||
-                      (h2c->last_sid >= 0 && h2c->max_id >= h2c->last_sid))))) 
{
-                       /* no more stream will come, kill it now */
-                       h2_release(h2c->conn);
-               }
-               else if (h2c->task) {
-                       if (eb_is_empty(&h2c->streams_by_id) || h2c->mbuf->o) {
-                               h2c->task->expire = tick_add(now_ms, 
h2c->last_sid < 0 ? h2c->timeout : h2c->shut_timeout);
-                               task_queue(h2c->task);
-                       }
-                       else
-                               h2c->task->expire = TICK_ETERNITY;
+       h2s_destroy(h2s);
+
+       /* We don't want to close right now unless we're removing the
+        * last stream, and either the connection is in error, or it
+        * reached the ID already specified in a GOAWAY frame received
+        * or sent (as seen by last_sid >= 0).
+        */
+       if (eb_is_empty(&h2c->streams_by_id) &&     /* don't close if streams 
exist */
+           ((h2c->conn->flags & CO_FL_ERROR) ||    /* errors close immediately 
*/
+            (h2c->flags & H2_CF_GOAWAY_FAILED) ||
+            (!h2c->mbuf->o &&  /* mux buffer empty, also process clean events 
below */
+             (conn_xprt_read0_pending(h2c->conn) ||
+              (h2c->last_sid >= 0 && h2c->max_id >= h2c->last_sid))))) {
+               /* no more stream will come, kill it now */
+               h2_release(h2c->conn);
+       }
+       else if (h2c->task) {
+               if (eb_is_empty(&h2c->streams_by_id) || h2c->mbuf->o) {
+                       h2c->task->expire = tick_add(now_ms, h2c->last_sid < 0 
? h2c->timeout : h2c->shut_timeout);
+                       task_queue(h2c->task);
                }
+               else
+                       h2c->task->expire = TICK_ETERNITY;
        }
-       pool_free(pool_head_h2s, h2s);
 }
 
 static void h2_shutr(struct conn_stream *cs, enum cs_shr_mode mode)
@@ -2547,17 +2545,25 @@
         */
        if (!(h2s->flags & H2_SF_RST_SENT) &&
            h2s_send_rst_stream(h2s->h2c, h2s) <= 0)
-               return;
+               goto add_to_list;
 
        if (!(h2s->flags & H2_SF_OUTGOING_DATA) &&
            !(h2s->h2c->flags & (H2_CF_GOAWAY_SENT|H2_CF_GOAWAY_FAILED)) &&
            h2c_send_goaway_error(h2s->h2c, h2s) <= 0)
-               return;
+               goto add_to_list;
 
        if (h2s->h2c->mbuf->o && !(cs->conn->flags & CO_FL_XPRT_WR_ENA))
                conn_xprt_want_send(cs->conn);
 
-       h2c_stream_close(h2s->h2c, h2s);
+       h2s_close(h2s);
+
+ add_to_list:
+       if (LIST_ISEMPTY(&h2s->list)) {
+               if (h2s->flags & H2_SF_BLK_MFCTL)
+                       LIST_ADDQ(&h2s->h2c->fctl_list, &h2s->list);
+               else if (h2s->flags & (H2_SF_BLK_MBUSY|H2_SF_BLK_MROOM))
+                       LIST_ADDQ(&h2s->h2c->send_list, &h2s->list);
+       }
 }
 
 static void h2_shutw(struct conn_stream *cs, enum cs_shw_mode mode)
@@ -2572,10 +2578,10 @@
 
                if (!(h2s->flags & (H2_SF_ES_SENT|H2_SF_RST_SENT)) &&
                    h2_send_empty_data_es(h2s) <= 0)
-                       return;
+                       goto add_to_list;
 
                if (h2s->st == H2_SS_HREM)
-                       h2c_stream_close(h2s->h2c, h2s);
+                       h2s_close(h2s);
                else
                        h2s->st = H2_SS_HLOC;
        } else {
@@ -2586,18 +2592,26 @@
                 */
                if (!(h2s->flags & H2_SF_RST_SENT) &&
                    h2s_send_rst_stream(h2s->h2c, h2s) <= 0)
-                       return;
+                       goto add_to_list;
 
                if (!(h2s->flags & H2_SF_OUTGOING_DATA) &&
                    !(h2s->h2c->flags & 
(H2_CF_GOAWAY_SENT|H2_CF_GOAWAY_FAILED)) &&
                    h2c_send_goaway_error(h2s->h2c, h2s) <= 0)
-                       return;
+                       goto add_to_list;
 
-               h2c_stream_close(h2s->h2c, h2s);
+               h2s_close(h2s);
        }
 
        if (h2s->h2c->mbuf->o && !(cs->conn->flags & CO_FL_XPRT_WR_ENA))
                conn_xprt_want_send(cs->conn);
+
+ add_to_list:
+       if (LIST_ISEMPTY(&h2s->list)) {
+               if (h2s->flags & H2_SF_BLK_MFCTL)
+                       LIST_ADDQ(&h2s->h2c->fctl_list, &h2s->list);
+               else if (h2s->flags & (H2_SF_BLK_MBUSY|H2_SF_BLK_MROOM))
+                       LIST_ADDQ(&h2s->h2c->send_list, &h2s->list);
+       }
 }
 
 /* Decode the payload of a HEADERS frame and produce the equivalent HTTP/1
@@ -3049,7 +3063,7 @@
                if (h2s->st == H2_SS_OPEN)
                        h2s->st = H2_SS_HLOC;
                else
-                       h2c_stream_close(h2c, h2s);
+                       h2s_close(h2s);
        }
        else if (h1m->status >= 100 && h1m->status < 200) {
                /* we'll let the caller check if it has more headers to send */
@@ -3291,7 +3305,7 @@
                if (h2s->st == H2_SS_OPEN)
                        h2s->st = H2_SS_HLOC;
                else
-                       h2c_stream_close(h2c, h2s);
+                       h2s_close(h2s);
 
                if (!(h1m->flags & H1_MF_CHNK)) {
                        // trim any possibly pending data (eg: inconsistent 
content-length)
@@ -3364,7 +3378,7 @@
        if (h2s->st == H2_SS_ERROR || h2s->flags & H2_SF_RST_RCVD) {
                cs->flags |= CS_FL_ERROR;
                if (h2s_send_rst_stream(h2s->h2c, h2s) > 0)
-                       h2c_stream_close(h2s->h2c, h2s);
+                       h2s_close(h2s);
        }
 
        if (h2s->flags & H2_SF_BLK_SFCTL) {
@@ -3372,6 +3386,12 @@
                LIST_DEL(&h2s->list);
                LIST_INIT(&h2s->list);
        }
+       else if (LIST_ISEMPTY(&h2s->list)) {
+               if (h2s->flags & H2_SF_BLK_MFCTL)
+                       LIST_ADDQ(&h2s->h2c->fctl_list, &h2s->list);
+               else if (h2s->flags & (H2_SF_BLK_MBUSY|H2_SF_BLK_MROOM))
+                       LIST_ADDQ(&h2s->h2c->send_list, &h2s->list);
+       }
 
        return total;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/proto_http.c 
new/haproxy-1.8.8/src/proto_http.c
--- old/haproxy-1.8.5/src/proto_http.c  2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/proto_http.c  2018-04-19 17:20:31.000000000 +0200
@@ -3718,9 +3718,11 @@
                }
 
                path = http_get_path(txn);
-               url2sa(req->buf->p + msg->sl.rq.u,
-                      path ? path - (req->buf->p + msg->sl.rq.u) : 
msg->sl.rq.u_l,
-                      &conn->addr.to, NULL);
+               if (url2sa(req->buf->p + msg->sl.rq.u,
+                          path ? path - (req->buf->p + msg->sl.rq.u) : 
msg->sl.rq.u_l,
+                          &conn->addr.to, NULL) == -1)
+                       goto return_bad_req;
+
                /* if the path was found, we have to remove everything between
                 * req->buf->p + msg->sl.rq.u and path (excluded). If it was not
                 * found, we need to replace from req->buf->p + msg->sl.rq.u for
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/queue.c 
new/haproxy-1.8.8/src/queue.c
--- old/haproxy-1.8.5/src/queue.c       2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/queue.c       2018-04-19 17:20:31.000000000 +0200
@@ -181,7 +181,7 @@
        HA_SPIN_UNLOCK(PROXY_LOCK,  &p->lock);
 
        if (remote)
-               thread_want_sync();
+               THREAD_WANT_SYNC();
 }
 
 /* Adds the stream <strm> to the pending connection list of server <strm>->srv
@@ -269,8 +269,7 @@
        HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
 
        if (remote)
-               thread_want_sync();
-
+               THREAD_WANT_SYNC();
        return xferred;
 }
 
@@ -308,8 +307,7 @@
        HA_SPIN_UNLOCK(PROXY_LOCK, &s->proxy->lock);
 
        if (remote)
-               thread_want_sync();
-
+               THREAD_WANT_SYNC();
        return xferred;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/ssl_sock.c 
new/haproxy-1.8.8/src/ssl_sock.c
--- old/haproxy-1.8.5/src/ssl_sock.c    2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/ssl_sock.c    2018-04-19 17:20:31.000000000 +0200
@@ -8487,6 +8487,11 @@
                        appctx->ctx.cli.err = err;
                        appctx->st0 = CLI_ST_PRINT_FREE;
                }
+               else {
+                       appctx->ctx.cli.severity = LOG_ERR;
+                       appctx->ctx.cli.msg = "Failed to update OCSP 
response.\n";
+                       appctx->st0 = CLI_ST_PRINT;
+               }
                return 1;
        }
        appctx->ctx.cli.severity = LOG_INFO;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.8.5/src/standard.c 
new/haproxy-1.8.8/src/standard.c
--- old/haproxy-1.8.5/src/standard.c    2018-03-23 16:58:34.000000000 +0100
+++ new/haproxy-1.8.8/src/standard.c    2018-04-19 17:20:31.000000000 +0200
@@ -629,7 +629,7 @@
  * If everything is fine, NULL is returned.
  */
 const char *invalid_prefix_char(const char *name) {
-       return __invalid_char(name, isalpha);
+       return __invalid_char(name, isalnum);
 }
 
 /*


Reply via email to