Hello community,

here is the log from the commit of package haproxy for openSUSE:Factory checked 
in at 2019-10-14 12:31:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/haproxy (Old)
 and      /work/SRC/openSUSE:Factory/.haproxy.new.2352 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "haproxy"

Mon Oct 14 12:31:19 2019 rev:75 rq:735634 version:2.0.7+git0.1909aa1e

Changes:
--------
--- /work/SRC/openSUSE:Factory/haproxy/haproxy.changes  2019-09-25 
01:50:25.085600808 +0200
+++ /work/SRC/openSUSE:Factory/.haproxy.new.2352/haproxy.changes        
2019-10-14 12:31:21.864290315 +0200
@@ -1,0 +2,26 @@
+Mon Oct 07 08:05:46 UTC 2019 - [email protected]
+
+- Update to version 2.0.7+git0.1909aa1e:
+  * [RELEASE] Released version 2.0.7
+  * BUG/MEDIUM: namespace: fix fd leak in master-worker mode
+  * DOC: Fix documentation about the cli command to get resolver stats
+  * BUG/MINOR: contrib/prometheus-exporter: Return the time averages in seconds
+  * MINOR: stats: Add the support of float fields in stats
+  * MINOR: spoe: Support the async mode with several threads
+  * MINOR: spoe: Improve generation of the engine-id
+  * BUG/MEDIUM: spoe: Use a different engine-id per process
+  * BUG/MINOR: mux-h1: Do h2 upgrade only on the first request
+  * BUG/MAJOR: mux_h2: Don't consume more payload than received for skipped 
frames
+  * BUG/MINOR: mux-h2: Use the dummy error when decoding headers for a closed 
stream
+  * BUG/MEDIUM: mux-h2: don't reject valid frames on closed streams
+  * BUG/MEDIUM: namespace: close open namespaces during soft shutdown
+  * BUG/MINOR: mux-h2: do not wake up blocked streams before the mux is ready
+  * BUG/MEDIUM: checks: make sure the connection is ready before trying to recv
+  * BUG/MEDIUM: stream-int: Process connection/CS errors during synchronous 
sends
+  * BUG/MINOR: stream-int: Process connection/CS errors first in si_cs_send()
+  * BUG/MEDIUM: check/threads: make external checks run exclusively on thread 1
+  * BUG/MAJOR: mux-h2: Handle HEADERS frames received after a RST_STREAM frame
+  * BUG/MINOR: mux-h2: Be sure to have a connection to unsubcribe
+  * BUG/MEDIUM: stick-table: Properly handle "show table" with a data type 
argument
+
+-------------------------------------------------------------------

Old:
----
  haproxy-2.0.6+git0.58706ab4.tar.gz

New:
----
  haproxy-2.0.7+git0.1909aa1e.tar.gz

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

Other differences:
------------------
++++++ haproxy.spec ++++++
--- /var/tmp/diff_new_pack.cvrGzE/_old  2019-10-14 12:31:22.872287688 +0200
+++ /var/tmp/diff_new_pack.cvrGzE/_new  2019-10-14 12:31:22.888287646 +0200
@@ -47,7 +47,7 @@
 %endif
 
 Name:           haproxy
-Version:        2.0.6+git0.58706ab4
+Version:        2.0.7+git0.1909aa1e
 Release:        0
 #
 #

++++++ _service ++++++
--- /var/tmp/diff_new_pack.cvrGzE/_old  2019-10-14 12:31:23.004287344 +0200
+++ /var/tmp/diff_new_pack.cvrGzE/_new  2019-10-14 12:31:23.008287334 +0200
@@ -6,7 +6,7 @@
     <param name="versionformat">@PARENT_TAG@+git@TAG_OFFSET@.%h</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="versionrewrite-replacement">\1</param>
-    <param name="revision">v2.0.6</param>
+    <param name="revision">v2.0.7</param>
     <param name="changesgenerate">enable</param>
   </service>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.cvrGzE/_old  2019-10-14 12:31:23.088287125 +0200
+++ /var/tmp/diff_new_pack.cvrGzE/_new  2019-10-14 12:31:23.092287115 +0200
@@ -1,6 +1,6 @@
 <servicedata>
   <service name="tar_scm">
     <param name="url">http://git.haproxy.org/git/haproxy-2.0.git</param>
-    <param 
name="changesrevision">58706ab4bdbea3468253eddf07f2d58db43bfcb4</param>
+    <param 
name="changesrevision">1909aa1e2f34dc8aaa86c279553eec2c99c14f2e</param>
   </service>
 </servicedata>
\ No newline at end of file

++++++ haproxy-2.0.6+git0.58706ab4.tar.gz -> haproxy-2.0.7+git0.1909aa1e.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/CHANGELOG 
new/haproxy-2.0.7+git0.1909aa1e/CHANGELOG
--- old/haproxy-2.0.6+git0.58706ab4/CHANGELOG   2019-09-13 13:46:44.000000000 
+0200
+++ new/haproxy-2.0.7+git0.1909aa1e/CHANGELOG   2019-09-27 14:17:42.000000000 
+0200
@@ -1,6 +1,28 @@
 ChangeLog :
 ===========
 
+2019/09/27 : 2.0.7
+    - BUG/MEDIUM: stick-table: Properly handle "show table" with a data type 
argument
+    - BUG/MINOR: mux-h2: Be sure to have a connection to unsubcribe
+    - BUG/MAJOR: mux-h2: Handle HEADERS frames received after a RST_STREAM 
frame
+    - BUG/MEDIUM: check/threads: make external checks run exclusively on 
thread 1
+    - BUG/MINOR: stream-int: Process connection/CS errors first in si_cs_send()
+    - BUG/MEDIUM: stream-int: Process connection/CS errors during synchronous 
sends
+    - BUG/MEDIUM: checks: make sure the connection is ready before trying to 
recv
+    - BUG/MINOR: mux-h2: do not wake up blocked streams before the mux is ready
+    - BUG/MEDIUM: namespace: close open namespaces during soft shutdown
+    - BUG/MEDIUM: mux-h2: don't reject valid frames on closed streams
+    - BUG/MINOR: mux-h2: Use the dummy error when decoding headers for a 
closed stream
+    - BUG/MAJOR: mux_h2: Don't consume more payload than received for skipped 
frames
+    - BUG/MINOR: mux-h1: Do h2 upgrade only on the first request
+    - BUG/MEDIUM: spoe: Use a different engine-id per process
+    - MINOR: spoe: Improve generation of the engine-id
+    - MINOR: spoe: Support the async mode with several threads
+    - MINOR: stats: Add the support of float fields in stats
+    - BUG/MINOR: contrib/prometheus-exporter: Return the time averages in 
seconds
+    - DOC: Fix documentation about the cli command to get resolver stats
+    - BUG/MEDIUM: namespace: fix fd leak in master-worker mode
+
 2019/09/13 : 2.0.6
     - MINOR: debug: indicate the applet name when the task is task_run_applet()
     - MINOR: tools: add append_prefixed_str()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/VERDATE 
new/haproxy-2.0.7+git0.1909aa1e/VERDATE
--- old/haproxy-2.0.6+git0.58706ab4/VERDATE     2019-09-13 13:46:44.000000000 
+0200
+++ new/haproxy-2.0.7+git0.1909aa1e/VERDATE     2019-09-27 14:17:42.000000000 
+0200
@@ -1,2 +1,2 @@
 $Format:%ci$
-2019/09/13
+2019/09/27
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/VERSION 
new/haproxy-2.0.7+git0.1909aa1e/VERSION
--- old/haproxy-2.0.6+git0.58706ab4/VERSION     2019-09-13 13:46:44.000000000 
+0200
+++ new/haproxy-2.0.7+git0.1909aa1e/VERSION     2019-09-27 14:17:42.000000000 
+0200
@@ -1 +1 @@
-2.0.6
+2.0.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-2.0.6+git0.58706ab4/contrib/prometheus-exporter/service-prometheus.c
 
new/haproxy-2.0.7+git0.1909aa1e/contrib/prometheus-exporter/service-prometheus.c
--- 
old/haproxy-2.0.6+git0.58706ab4/contrib/prometheus-exporter/service-prometheus.c
    2019-09-13 13:46:44.000000000 +0200
+++ 
new/haproxy-2.0.7+git0.1909aa1e/contrib/prometheus-exporter/service-prometheus.c
    2019-09-27 14:17:42.000000000 +0200
@@ -1079,6 +1079,7 @@
                case FF_U32:   ret = chunk_appendf(out, "%u\n", f->u.u32); 
break;
                case FF_S64:   ret = chunk_appendf(out, "%lld\n", (long 
long)f->u.s64); break;
                case FF_U64:   ret = chunk_appendf(out, "%llu\n", (unsigned 
long long)f->u.u64); break;
+               case FF_FLT:   ret = chunk_appendf(out, "%f\n", f->u.flt); 
break;
                case FF_STR:   ret = chunk_strcat(out,  "Nan\n"); break;
                default:       ret = chunk_strcat(out,  "Nan\n"); break;
        }
@@ -1607,6 +1608,7 @@
        size_t max = htx_get_max_blksz(htx, channel_htx_recv_max(chn, htx));
        int ret = 1;
        uint32_t weight;
+       double secs;
 
        while (appctx->st2 && appctx->st2 < ST_F_TOTAL_FIELDS) {
                while (appctx->ctx.stats.px) {
@@ -1657,16 +1659,20 @@
                                        metric = mkf_u64(FN_COUNTER, 
px->be_counters.bytes_out);
                                        break;
                                case ST_F_QTIME:
-                                       metric = mkf_u32(FN_AVG, 
swrate_avg(px->be_counters.q_time, TIME_STATS_SAMPLES));
+                                       secs = 
(double)swrate_avg(px->be_counters.q_time, TIME_STATS_SAMPLES) / 1000.0;
+                                       metric = mkf_flt(FN_AVG, secs);
                                        break;
                                case ST_F_CTIME:
-                                       metric = mkf_u32(FN_AVG, 
swrate_avg(px->be_counters.c_time, TIME_STATS_SAMPLES));
+                                       secs = 
(double)swrate_avg(px->be_counters.c_time, TIME_STATS_SAMPLES) / 1000.0;
+                                       metric = mkf_flt(FN_AVG, secs);
                                        break;
                                case ST_F_RTIME:
-                                       metric = mkf_u32(FN_AVG, 
swrate_avg(px->be_counters.d_time, TIME_STATS_SAMPLES));
+                                       secs = 
(double)swrate_avg(px->be_counters.d_time, TIME_STATS_SAMPLES) / 1000.0;
+                                       metric = mkf_flt(FN_AVG, secs);
                                        break;
                                case ST_F_TTIME:
-                                       metric = mkf_u32(FN_AVG, 
swrate_avg(px->be_counters.t_time, TIME_STATS_SAMPLES));
+                                       secs = 
(double)swrate_avg(px->be_counters.t_time, TIME_STATS_SAMPLES) / 1000.0;
+                                       metric = mkf_flt(FN_AVG, secs);
                                        break;
                                case ST_F_DREQ:
                                        metric = mkf_u64(FN_COUNTER, 
px->be_counters.denied_req);
@@ -1828,6 +1834,7 @@
        size_t max = htx_get_max_blksz(htx, channel_htx_recv_max(chn, htx));
        int ret = 1;
        uint32_t weight;
+       double secs;
 
        while (appctx->st2 && appctx->st2 < ST_F_TOTAL_FIELDS) {
                while (appctx->ctx.stats.px) {
@@ -1878,16 +1885,20 @@
                                                metric = mkf_u64(FN_COUNTER, 
sv->counters.bytes_out);
                                                break;
                                        case ST_F_QTIME:
-                                               metric = mkf_u32(FN_AVG, 
swrate_avg(sv->counters.q_time, TIME_STATS_SAMPLES));
+                                               secs = 
(double)swrate_avg(sv->counters.q_time, TIME_STATS_SAMPLES) / 1000.0;
+                                               metric = mkf_flt(FN_AVG, secs);
                                                break;
                                        case ST_F_CTIME:
-                                               metric = mkf_u32(FN_AVG, 
swrate_avg(sv->counters.c_time, TIME_STATS_SAMPLES));
+                                               secs = 
(double)swrate_avg(sv->counters.c_time, TIME_STATS_SAMPLES) / 1000.0;
+                                               metric = mkf_flt(FN_AVG, secs);
                                                break;
                                        case ST_F_RTIME:
-                                               metric = mkf_u32(FN_AVG, 
swrate_avg(sv->counters.d_time, TIME_STATS_SAMPLES));
+                                               secs = 
(double)swrate_avg(sv->counters.d_time, TIME_STATS_SAMPLES) / 1000.0;
+                                               metric = mkf_flt(FN_AVG, secs);
                                                break;
                                        case ST_F_TTIME:
-                                               metric = mkf_u32(FN_AVG, 
swrate_avg(sv->counters.t_time, TIME_STATS_SAMPLES));
+                                               secs = 
(double)swrate_avg(sv->counters.t_time, TIME_STATS_SAMPLES) / 1000.0;
+                                               metric = mkf_flt(FN_AVG, secs);
                                                break;
                                        case ST_F_CONNECT:
                                                metric = mkf_u64(FN_COUNTER, 
sv->counters.connect);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/doc/configuration.txt 
new/haproxy-2.0.7+git0.1909aa1e/doc/configuration.txt
--- old/haproxy-2.0.6+git0.58706ab4/doc/configuration.txt       2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/doc/configuration.txt       2019-09-27 
14:17:42.000000000 +0200
@@ -4,7 +4,7 @@
                          ----------------------
                               version 2.0
                              willy tarreau
-                              2019/09/13
+                              2019/09/27
 
 
 This document covers the configuration language as implemented in the version
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/doc/management.txt 
new/haproxy-2.0.7+git0.1909aa1e/doc/management.txt
--- old/haproxy-2.0.6+git0.58706ab4/doc/management.txt  2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/doc/management.txt  2019-09-27 
14:17:42.000000000 +0200
@@ -2425,7 +2425,7 @@
   $ echo "show stat json" | socat /var/run/haproxy.sock stdio | \
     python -m json.tool
 
-show stat resolvers [<resolvers section id>]
+show resolvers [<resolvers section id>]
   Dump statistics for the given resolvers section, or all resolvers sections
   if no section is supplied.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/include/proto/stats.h 
new/haproxy-2.0.7+git0.1909aa1e/include/proto/stats.h
--- old/haproxy-2.0.6+git0.58706ab4/include/proto/stats.h       2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/include/proto/stats.h       2019-09-27 
14:17:42.000000000 +0200
@@ -84,6 +84,12 @@
        return f;
 }
 
+static inline struct field mkf_flt(uint32_t type, double value)
+{
+       struct field f = { .type = FF_FLT | type, .u.flt = value };
+       return f;
+}
+
 extern const char *stat_status_codes[];
 
 /* These two structs contains all field names according with
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/include/types/spoe.h 
new/haproxy-2.0.7+git0.1909aa1e/include/types/spoe.h
--- old/haproxy-2.0.6+git0.58706ab4/include/types/spoe.h        2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/include/types/spoe.h        2019-09-27 
14:17:42.000000000 +0200
@@ -244,7 +244,6 @@
        } timeout;
 
        /* Config info */
-       char                 *engine_id;      /* engine-id string */
        char                 *var_pfx;        /* Prefix used for vars set by 
the agent */
        char                 *var_on_error;   /* Variable to set when an error 
occurred, in the TXN scope */
        char                 *var_t_process;  /* Variable to set to report the 
processing time of the last event/group, in the TXN scope */
@@ -264,6 +263,7 @@
 
        /* running info */
        struct {
+               char           *engine_id;      /* engine-id string */
                unsigned int    frame_size;     /* current maximum frame size, 
only used to encode messages */
                unsigned int    processing;
                struct freq_ctr processing_per_sec;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/include/types/stats.h 
new/haproxy-2.0.7+git0.1909aa1e/include/types/stats.h
--- old/haproxy-2.0.6+git0.58706ab4/include/types/stats.h       2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/include/types/stats.h       2019-09-27 
14:17:42.000000000 +0200
@@ -195,6 +195,7 @@
        FF_S64      = 0x00000003,
        FF_U64      = 0x00000004,
        FF_STR      = 0x00000005,
+       FF_FLT      = 0x00000006,
        FF_MASK     = 0x000000FF,
 };
 
@@ -242,6 +243,7 @@
                uint32_t    u32; /* FF_U32 */
                int64_t     s64; /* FF_S64 */
                uint64_t    u64; /* FF_U64 */
+               double      flt; /* FF_FLT */
                const char *str; /* FF_STR */
        } u;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/src/checks.c 
new/haproxy-2.0.7+git0.1909aa1e/src/checks.c
--- old/haproxy-2.0.6+git0.58706ab4/src/checks.c        2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/src/checks.c        2019-09-27 
14:17:42.000000000 +0200
@@ -875,6 +875,9 @@
                }
        }
 
+       /* the rest of the code below expects the connection to be ready! */
+       if (!(conn->flags & CO_FL_CONNECTED) && !done)
+               goto wait_more_data;
 
        /* Intermediate or complete response received.
         * Terminate string in b_head(&check->bi) buffer.
@@ -2175,7 +2178,7 @@
                        /* a success was detected */
                        check_notify_success(check);
                }
-               task_set_affinity(t, MAX_THREADS_MASK);
+               task_set_affinity(t, 1);
                check->state &= ~CHK_ST_INPROGRESS;
 
                pid_list_del(check->curpid);
@@ -2423,8 +2426,13 @@
                            int nbcheck, int srvpos)
 {
        struct task *t;
+       unsigned long thread_mask = MAX_THREADS_MASK;
+
+       if (check->type == PR_O2_EXT_CHK)
+               thread_mask = 1;
+
        /* task for the check */
-       if ((t = task_new(MAX_THREADS_MASK)) == NULL) {
+       if ((t = task_new(thread_mask)) == NULL) {
                ha_alert("Starting [%s:%s] check: out of memory.\n",
                         check->server->proxy->id, check->server->id);
                return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/src/flt_spoe.c 
new/haproxy-2.0.7+git0.1909aa1e/src/flt_spoe.c
--- old/haproxy-2.0.6+git0.58706ab4/src/flt_spoe.c      2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/src/flt_spoe.c      2019-09-27 
14:17:42.000000000 +0200
@@ -172,7 +172,6 @@
        free(agent->id);
        free(agent->conf.file);
        free(agent->var_pfx);
-       free(agent->engine_id);
        free(agent->var_on_error);
        free(agent->var_t_process);
        free(agent->var_t_total);
@@ -185,8 +184,10 @@
                spoe_release_group(grp);
        }
        if (agent->rt) {
-               for (i = 0; i < global.nbthread; ++i)
+               for (i = 0; i < global.nbthread; ++i) {
+                       free(agent->rt[i].engine_id);
                        HA_SPIN_DESTROY(&agent->rt[i].lock);
+               }
        }
        free(agent->rt);
        free(agent);
@@ -256,30 +257,32 @@
 static char *
 generate_pseudo_uuid()
 {
-       static int init = 0;
-
-       const char uuid_fmt[] = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
-       const char uuid_chr[] = "0123456789ABCDEF-";
        char *uuid;
-       int i;
+       uint32_t rnd[4] = { 0, 0, 0, 0 };
+       uint64_t last = 0;
+       int byte = 0;
+       uint8_t bits = 0;
+       unsigned int rand_max_bits = my_flsl(RAND_MAX);
 
-       if ((uuid = calloc(1, sizeof(uuid_fmt))) == NULL)
+       if ((uuid = calloc(1, 37)) == NULL)
                return NULL;
 
-       if (!init) {
-               srand(now_ms);
-               init = 1;
-       }
-
-       for (i = 0; i < sizeof(uuid_fmt)-1; i++) {
-               int r = rand () % 16;
-
-               switch (uuid_fmt[i]) {
-                       case 'x' : uuid[i] = uuid_chr[r]; break;
-                       case 'y' : uuid[i] = uuid_chr[(r & 0x03) | 0x08]; break;
-                       default  : uuid[i] = uuid_fmt[i]; break;
-               }
-       }
+       while (byte < 4) {
+               while (bits < 32) {
+                       last |= (uint64_t)random() << bits;
+                       bits += rand_max_bits;
+               }
+               rnd[byte++] = last;
+               last >>= 32u;
+               bits  -= 32;
+       }
+       snprintf(uuid, 36, "%8.8x-%4.4x-%4.4x-%4.4x-%12.12llx",
+                            rnd[0],
+                            rnd[1] & 0xFFFF,
+                            ((rnd[1] >> 16u) & 0xFFF) | 0x4000,  // highest 4 
bits indicate the uuid version
+                            (rnd[2] & 0x3FFF) | 0x8000,  // the highest 2 bits 
indicate the UUID variant (10),
+                            (long long)((rnd[2] >> 14u) | ((uint64_t) rnd[3] 
<< 18u)) & 0xFFFFFFFFFFFFull
+                       );
        return uuid;
 }
 
@@ -458,14 +461,14 @@
                goto too_big;
 
        /* (optionnal) "engine-id" K/V item, if present */
-       if (agent != NULL && agent->engine_id != NULL) {
+       if (agent != NULL && agent->rt[tid].engine_id != NULL) {
                sz = SLEN(ENGINE_ID_KEY);
                if (spoe_encode_buffer(ENGINE_ID_KEY, sz, &p, end) == -1)
                        goto too_big;
 
                *p++ = SPOE_DATA_T_STR;
-               sz = strlen(agent->engine_id);
-               if (spoe_encode_buffer(agent->engine_id, sz, &p, end) == -1)
+               sz = strlen(agent->rt[tid].engine_id);
+               if (spoe_encode_buffer(agent->rt[tid].engine_id, sz, &p, end) 
== -1)
                        goto too_big;
        }
 
@@ -3087,16 +3090,13 @@
                return 1;
        }
 
-       /* finish per-thread agent initialization */
-       if (global.nbthread == 1)
-               conf->agent->flags |= SPOE_FL_ASYNC;
-
        if ((conf->agent->rt = calloc(global.nbthread, 
sizeof(*conf->agent->rt))) == NULL) {
                ha_alert("Proxy %s : out of memory initializing SPOE agent '%s' 
declared at %s:%d.\n",
                         px->id, conf->agent->id, conf->agent->conf.file, 
conf->agent->conf.line);
                return 1;
        }
        for (i = 0; i < global.nbthread; ++i) {
+               conf->agent->rt[i].engine_id    = NULL;
                conf->agent->rt[i].frame_size   = conf->agent->max_frame_size;
                conf->agent->rt[i].processing   = 0;
                LIST_INIT(&conf->agent->rt[i].applets);
@@ -3111,6 +3111,24 @@
        return 0;
 }
 
+/* Initializes the SPOE filter for a proxy for a specific thread.
+ * Returns a negative value if an error occurs. */
+static int
+spoe_init_per_thread(struct proxy *p, struct flt_conf *fconf)
+{
+       struct spoe_config *conf = fconf->conf;
+       struct spoe_agent *agent = conf->agent;
+
+       /* Use a != seed per process */
+       if (relative_pid > 1 && tid == 0)
+               srandom(now_ms * pid);
+
+       agent->rt[tid].engine_id = generate_pseudo_uuid();
+       if (agent->rt[tid].engine_id == NULL)
+               return -1;
+       return 0;
+}
+
 /**************************************************************************
  * Hooks attached to a stream
  *************************************************************************/
@@ -3309,6 +3327,7 @@
        .init   = spoe_init,
        .deinit = spoe_deinit,
        .check  = spoe_check,
+       .init_per_thread = spoe_init_per_thread,
 
        /* Handle start/stop of SPOE */
        .attach         = spoe_start,
@@ -3374,12 +3393,11 @@
                curagent->timeout.idle       = TICK_ETERNITY;
                curagent->timeout.processing = TICK_ETERNITY;
 
-               curagent->engine_id      = NULL;
                curagent->var_pfx        = NULL;
                curagent->var_on_error   = NULL;
                curagent->var_t_process  = NULL;
                curagent->var_t_total    = NULL;
-               curagent->flags          = (SPOE_FL_PIPELINING | 
SPOE_FL_SND_FRAGMENTATION);
+               curagent->flags          = (SPOE_FL_ASYNC | SPOE_FL_PIPELINING 
| SPOE_FL_SND_FRAGMENTATION);
                curagent->cps_max        = 0;
                curagent->eps_max        = 0;
                curagent->max_frame_size = MAX_FRAME_SIZE;
@@ -3524,15 +3542,8 @@
                                goto out;
                        if (kwm == 1)
                                curagent->flags &= ~SPOE_FL_ASYNC;
-                       else {
-                               if (global.nbthread == 1)
-                                       curagent->flags |= SPOE_FL_ASYNC;
-                               else {
-                                       ha_warning("parsing [%s:%d] Async 
option is not supported with threads.\n",
-                                                  file, linenum);
-                                       err_code |= ERR_WARN;
-                               }
-                       }
+                       else
+                               curagent->flags |= SPOE_FL_ASYNC;
                        goto out;
                }
                else if (!strcmp(args[1], "send-frag-payload")) {
@@ -4177,8 +4188,6 @@
                }
                curagent->var_pfx = strdup(curagent->id);
        }
-       if (curagent->engine_id == NULL)
-               curagent->engine_id = generate_pseudo_uuid();
 
        if (curagent->var_on_error) {
                struct arg arg;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/src/mux_h1.c 
new/haproxy-2.0.7+git0.1909aa1e/src/mux_h1.c
--- old/haproxy-2.0.6+git0.58706ab4/src/mux_h1.c        2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/src/mux_h1.c        2019-09-27 
14:17:42.000000000 +0200
@@ -989,7 +989,7 @@
        if (b_head(buf) + b_data(buf) > b_wrap(buf))
                b_slow_realign(buf, trash.area, 0);
 
-       if (!(h1m->flags & H1_MF_RESP)) {
+       if (!(h1s->flags & H1S_F_NOT_FIRST) && !(h1m->flags & H1_MF_RESP)) {
                /* Try to match H2 preface before parsing the request headers. 
*/
                ret = b_isteq(buf, 0, b_data(buf), ist(H2_CONN_PREFACE));
                if (ret > 0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/src/mux_h2.c 
new/haproxy-2.0.7+git0.1909aa1e/src/mux_h2.c
--- old/haproxy-2.0.6+git0.58706ab4/src/mux_h2.c        2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/src/mux_h2.c        2019-09-27 
14:17:42.000000000 +0200
@@ -677,9 +677,9 @@
                }
                if (h2c->wait_event.tasklet)
                        tasklet_free(h2c->wait_event.tasklet);
-               if (h2c->wait_event.events != 0)
+               if (conn && h2c->wait_event.events != 0)
                        conn->xprt->unsubscribe(conn, conn->xprt_ctx, 
h2c->wait_event.events,
-                           &h2c->wait_event);
+                                               &h2c->wait_event);
 
                pool_free(pool_head_h2c, h2c);
        }
@@ -2106,6 +2106,9 @@
  */
 static struct h2s *h2c_bck_handle_headers(struct h2c *h2c, struct h2s *h2s)
 {
+       struct buffer rxbuf = BUF_NULL;
+       unsigned long long body_len = 0;
+       uint32_t flags = 0;
        int error;
 
        if (!b_size(&h2c->dbuf))
@@ -2114,7 +2117,18 @@
        if (b_data(&h2c->dbuf) < h2c->dfl && !b_full(&h2c->dbuf))
                return NULL; // incomplete frame
 
-       error = h2c_decode_headers(h2c, &h2s->rxbuf, &h2s->flags, 
&h2s->body_len);
+       if (h2s->st != H2_SS_CLOSED) {
+               error = h2c_decode_headers(h2c, &h2s->rxbuf, &h2s->flags, 
&h2s->body_len);
+       }
+       else {
+               /* the connection was already killed by an RST, let's consume
+                * the data and send another RST.
+                */
+               error = h2c_decode_headers(h2c, &rxbuf, &flags, &body_len);
+               h2s = (struct h2s*)h2_error_stream;
+               h2c->st0 = H2_CS_FRAME_E;
+               goto send_rst;
+       }
 
        /* unrecoverable error ? */
        if (h2c->st0 >= H2_CS_ERROR)
@@ -2150,6 +2164,15 @@
        }
 
        return h2s;
+
+ send_rst:
+       /* make the demux send an RST for the current stream. We may only
+        * do this if we're certain that the HEADERS frame was properly
+        * decompressed so that the HPACK decoder is still kept up to date.
+        */
+       h2_release_buf(h2c, &rxbuf);
+       h2c->st0 = H2_CS_FRAME_E;
+       return h2s;
 }
 
 /* processes a DATA frame. Returns > 0 on success or zero on missing data.
@@ -2459,7 +2482,8 @@
                                goto strm_err;
                        }
 
-                       if (h2s->flags & H2_SF_RST_RCVD && h2_ft_bit(h2c->dft) 
& H2_FT_HDR_MASK) {
+                       if (h2s->flags & H2_SF_RST_RCVD &&
+                           !(h2_ft_bit(h2c->dft) & (H2_FT_HDR_MASK | 
H2_FT_RST_STREAM_BIT | H2_FT_PRIORITY_BIT | H2_FT_WINDOW_UPDATE_BIT))) {
                                /* RFC7540#5.1:closed: an endpoint that
                                 * receives any frame other than PRIORITY after
                                 * receiving a RST_STREAM MUST treat that as a
@@ -2474,6 +2498,10 @@
                                 * happen with request trailers received after 
sending an
                                 * RST_STREAM, or with header/trailers 
responses received after
                                 * sending RST_STREAM (aborted stream).
+                                *
+                                * In addition, since our CLOSED streams always 
carry the
+                                * RST_RCVD bit, we don't want to accidently 
catch valid
+                                * frames for a closed stream, i.e. RST/PRIO/WU.
                                 */
                                h2s_error(h2s, H2_ERR_STREAM_CLOSED);
                                h2c->st0 = H2_CS_FRAME_E;
@@ -2620,8 +2648,11 @@
                        break;
 
                if (h2c->st0 != H2_CS_FRAME_H) {
-                       b_del(&h2c->dbuf, h2c->dfl);
-                       h2c->st0 = H2_CS_FRAME_H;
+                       ret = MIN(b_data(&h2c->dbuf), h2c->dfl);
+                       b_del(&h2c->dbuf, ret);
+                       h2c->dfl -= ret;
+                       if (!h2c->dfl)
+                               h2c->st0 = H2_CS_FRAME_H;
                }
        }
 
@@ -2892,7 +2923,7 @@
        /* We're not full anymore, so we can wake any task that are waiting
         * for us.
         */
-       if (!(h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MROOM))) {
+       if (!(h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MROOM)) && h2c->st0 >= 
H2_CS_FRAME_H) {
                struct h2s *h2s;
 
                list_for_each_entry(h2s, &h2c->send_list, list) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/src/namespace.c 
new/haproxy-2.0.7+git0.1909aa1e/src/namespace.c
--- old/haproxy-2.0.6+git0.58706ab4/src/namespace.c     2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/src/namespace.c     2019-09-27 
14:17:42.000000000 +0200
@@ -15,6 +15,7 @@
 #include <common/hash.h>
 #include <common/errors.h>
 #include <proto/log.h>
+#include <proto/signal.h>
 #include <types/global.h>
 
 /* Opens the namespace <ns_name> and returns the FD or -1 in case of error
@@ -24,7 +25,7 @@
 {
        if (chunk_printf(&trash, "/var/run/netns/%s", ns_name) < 0)
                return -1;
-       return open(trash.area, O_RDONLY);
+       return open(trash.area, O_RDONLY | O_CLOEXEC);
 }
 
 static int default_namespace = -1;
@@ -33,12 +34,30 @@
 {
        if (chunk_printf(&trash, "/proc/%d/ns/net", getpid()) < 0)
                return -1;
-       default_namespace = open(trash.area, O_RDONLY);
+       default_namespace = open(trash.area, O_RDONLY | O_CLOEXEC);
        return default_namespace;
 }
 
 static struct eb_root namespace_tree_root = EB_ROOT;
 
+static void netns_sig_stop(struct sig_handler *sh)
+{
+       struct ebpt_node *node, *next;
+       struct netns_entry *entry;
+
+       /* close namespace file descriptors and remove registered namespaces 
from the
+        * tree when stopping */
+       node = ebpt_first(&namespace_tree_root);
+       while (node) {
+               next = ebpt_next(node);
+               ebpt_delete(node);
+               entry = container_of(node, struct netns_entry, node);
+               free(entry->node.key);
+               close(entry->fd);
+               node = next;
+       }
+}
+
 int netns_init(void)
 {
        int err_code = 0;
@@ -55,6 +74,8 @@
                }
        }
 
+       signal_register_fct(0, netns_sig_stop, 0);
+
        return err_code;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/src/stats.c 
new/haproxy-2.0.7+git0.1909aa1e/src/stats.c
--- old/haproxy-2.0.6+git0.58706ab4/src/stats.c 2019-09-13 13:46:44.000000000 
+0200
+++ new/haproxy-2.0.7+git0.1909aa1e/src/stats.c 2019-09-27 14:17:42.000000000 
+0200
@@ -341,6 +341,7 @@
        case FF_U32:   return chunk_appendf(out, "%u", f->u.u32);
        case FF_S64:   return chunk_appendf(out, "%lld", (long long)f->u.s64);
        case FF_U64:   return chunk_appendf(out, "%llu", (unsigned long 
long)f->u.u64);
+       case FF_FLT:   return chunk_appendf(out, "%f", f->u.flt);
        case FF_STR:   return csv_enc_append(field_str(f, 0), 1, out) != NULL;
        default:       return chunk_appendf(out, "[INCORRECT_FIELD_TYPE_%08x]", 
f->type);
        }
@@ -358,6 +359,7 @@
        case FF_U32:   return chunk_appendf(out, "u32:%u", f->u.u32);
        case FF_S64:   return chunk_appendf(out, "s64:%lld", (long 
long)f->u.s64);
        case FF_U64:   return chunk_appendf(out, "u64:%llu", (unsigned long 
long)f->u.u64);
+       case FF_FLT:   return chunk_appendf(out, "flt:%f", f->u.flt);
        case FF_STR:   return chunk_appendf(out, "str:%s", field_str(f, 0));
        default:       return chunk_appendf(out, "%08x:?", f->type);
        }
@@ -397,6 +399,8 @@
                       type = "\"u64\"";
                       snprintf(buf, sizeof(buf), "%llu",
                                (unsigned long long) f->u.u64);
+       case FF_FLT:   type = "\"flt\"";
+                      snprintf(buf, sizeof(buf), "%f", f->u.flt);
                       break;
        case FF_STR:   type = "\"str\"";
                       value = field_str(f, 0);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/src/stick_table.c 
new/haproxy-2.0.7+git0.1909aa1e/src/stick_table.c
--- old/haproxy-2.0.6+git0.58706ab4/src/stick_table.c   2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/src/stick_table.c   2019-09-27 
14:17:42.000000000 +0200
@@ -3601,8 +3601,7 @@
                return 1;
        }
 
-       if (!((struct proxy *)appctx->ctx.table.target)->table ||
-           !((struct proxy 
*)appctx->ctx.table.target)->table->data_ofs[appctx->ctx.table.data_type]) {
+       if (!((struct stktable 
*)appctx->ctx.table.target)->data_ofs[appctx->ctx.table.data_type]) {
                appctx->ctx.cli.severity = LOG_ERR;
                appctx->ctx.cli.msg = "Data type not stored in this table\n";
                appctx->st0 = CLI_ST_PRINT;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-2.0.6+git0.58706ab4/src/stream_interface.c 
new/haproxy-2.0.7+git0.1909aa1e/src/stream_interface.c
--- old/haproxy-2.0.6+git0.58706ab4/src/stream_interface.c      2019-09-13 
13:46:44.000000000 +0200
+++ new/haproxy-2.0.7+git0.1909aa1e/src/stream_interface.c      2019-09-27 
14:17:42.000000000 +0200
@@ -652,10 +652,6 @@
        int ret;
        int did_send = 0;
 
-       /* We're already waiting to be able to send, give up */
-       if (si->wait_event.events & SUB_RETRY_SEND)
-               return 0;
-
        if (conn->flags & CO_FL_ERROR || cs->flags & 
(CS_FL_ERROR|CS_FL_ERR_PENDING)) {
                /* We're probably there because the tasklet was woken up,
                 * but process_stream() ran before, detected there were an
@@ -669,6 +665,10 @@
                return 1;
        }
 
+       /* We're already waiting to be able to send, give up */
+       if (si->wait_event.events & SUB_RETRY_SEND)
+               return 0;
+
        /* we might have been called just after an asynchronous shutw */
        if (conn->flags & CO_FL_SOCK_WR_SH || oc->flags & CF_SHUTW)
                return 1;
@@ -922,12 +922,6 @@
        if (!cs)
                return;
 
-       if (cs->flags & (CS_FL_ERROR|CS_FL_ERR_PENDING))
-               return;
-
-       if (cs->conn->flags & CO_FL_ERROR)
-               return;
-
        si_cs_send(cs);
 }
 


Reply via email to