Hello community,
here is the log from the commit of package haproxy for openSUSE:Factory checked in at 2019-09-25 01:50:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/haproxy (Old)
and /work/SRC/openSUSE:Factory/.haproxy.new.7948 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "haproxy"
Wed Sep 25 01:50:23 2019 rev:74 rq:731949 version:2.0.6+git0.58706ab4
Changes:
--------
--- /work/SRC/openSUSE:Factory/haproxy/haproxy.changes 2019-09-07 11:26:29.438486292 +0200
+++ /work/SRC/openSUSE:Factory/.haproxy.new.7948/haproxy.changes 2019-09-25 01:50:25.085600808 +0200
@@ -1,0 +2,49 @@
+Tue Sep 17 15:41:39 UTC 2019 - kgronlund@suse.com
+
+- Update to version 2.0.6+git0.58706ab4:
+ * [RELEASE] Released version 2.0.6
+ * MINOR: sample: Add UUID-fetch
+ * BUG/MINOR: Missing stat_field_names (since f21d17bb)
+ * BUG/MINOR: backend: Fix a possible null pointer dereference
+ * BUG/MINOR: acl: Fix memory leaks when an ACL expression is parsed
+ * BUG/MINOR: filters: Properly set the HTTP status code on analysis error
+ * BUG/MEDIUM: http: also reject messages where "chunked" is missing from transfer-enoding
+ * BUG/MINOR: ssl: always check for ssl connection before getting its XPRT context
+ * BUG/MINOR: listener: Fix a possible null pointer dereference
+ * MINOR: stats: report the number of idle connections for each server
+ * BUG/MEDIUM: connection: don't keep more idle connections than ever needed
+ * BUG/MAJOR: ssl: ssl_sock was not fully initialized.
+ * BUG/MINOR: lb/leastconn: ignore the server weights for empty servers
+ * MINOR: contrib/prometheus-exporter: Report DRAIN/MAINT/NOLB status for servers
+ * BUG/MINOR: checks: do not uselessly poll for reads before the connection is up
+ * BUG/MINOR: checks: make __event_chk_srv_r() report success before closing
+ * BUG/MINOR: checks: start sending the request right after connect()
+ * BUG/MINOR: checks: stop polling for write when we have nothing left to send
+ * BUG/MEDIUM: cache: Don't cache objects if the size of headers is too big
+ * BUG/MEDIUM: cache: Properly copy headers splitted on several shctx blocks
+ * BUG/MINOR: mux-h1: Be sure to update the count before adding EOM after trailers
+ * BUG/MINOR: mux-h1: Don't stop anymore input processing when the max is reached
+ * BUG/MINOR: mux-h1: Fix size evaluation of HTX messages after headers parsing
+ * BUG/MINOR: h1: Properly reset h1m when parsing is restarted
+ * BUG/MINOR: http-ana: Reset response flags when 1xx messages are handled
+ * BUG/MEDIUM: peers: local peer socket not bound.
+ * BUG/MEDIUM: proto-http: Always start the parsing if there is no outgoing data
+ * BUG/MEDIUM: url32 does not take the path part into account in the returned hash.
+ * BUG/MEDIUM: listener/threads: fix an AB/BA locking issue in delete_listener()
+ * BUG/MINOR: mworker: disable SIGPROF on re-exec
+ * DOC: fixed typo in management.txt
+ * BUG/MEDIUM: mux-h1: do not report errors on transfers ending on buffer full
+ * BUG/MEDIUM: mux-h1: do not truncate trailing 0CRLF on buffer boundary
+ * MEDIUM: debug: make the thread dump code show Lua backtraces
+ * MINOR: lua: export applet and task handlers
+ * MINOR: tools: add append_prefixed_str()
+ * MINOR: debug: indicate the applet name when the task is task_run_applet()
+
+-------------------------------------------------------------------
+Thu Aug 22 11:23:04 CEST 2019 - kukuk@suse.de
+
+- Use %license instead of %doc [bsc#1082318]
+- Recommend apparmor, it's not required to work (make haproxy
+ useable in a container)
+
+-------------------------------------------------------------------
Old:
----
haproxy-2.0.5+git0.d905f49a.tar.gz
New:
----
haproxy-2.0.6+git0.58706ab4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ haproxy.spec ++++++
--- /var/tmp/diff_new_pack.FBSw9i/_old 2019-09-25 01:50:25.969600795 +0200
+++ /var/tmp/diff_new_pack.FBSw9i/_new 2019-09-25 01:50:25.973600795 +0200
@@ -1,7 +1,7 @@
#
# spec file for package haproxy
#
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -47,7 +47,7 @@
%endif
Name: haproxy
-Version: 2.0.5+git0.d905f49a
+Version: 2.0.6+git0.58706ab4
Release: 0
#
#
@@ -55,10 +55,10 @@
%if %{with apparmor}
%if 0%{?suse_version} <= 1315
BuildRequires: apparmor-profiles
-Requires: apparmor-profiles
+Recommends: apparmor-profiles
%else
BuildRequires: apparmor-abstractions
-Requires: apparmor-abstractions
+Recommends: apparmor-abstractions
%endif
%if %{with apparmor_reload}
BuildRequires: apparmor-rpm-macros
@@ -230,7 +230,8 @@
%files
%defattr(-,root,root,-)
-%doc CHANGELOG README LICENSE
+%license LICENSE
+%doc CHANGELOG README
%doc ROADMAP doc/* examples/
%doc contrib/netsnmp-perl/ contrib/selinux/
%dir %attr(-,root,haproxy) %{_sysconfdir}/%{pkg_name}
++++++ _service ++++++
--- /var/tmp/diff_new_pack.FBSw9i/_old 2019-09-25 01:50:26.009600795 +0200
+++ /var/tmp/diff_new_pack.FBSw9i/_new 2019-09-25 01:50:26.009600795 +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.5</param>
+ <param name="revision">v2.0.6</param>
<param name="changesgenerate">enable</param>
</service>
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.FBSw9i/_old 2019-09-25 01:50:26.025600794 +0200
+++ /var/tmp/diff_new_pack.FBSw9i/_new 2019-09-25 01:50:26.025600794 +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">d905f49a0dbf78b69f24ee69df10b873680b92ea</param>
+ <param name="changesrevision">58706ab4bdbea3468253eddf07f2d58db43bfcb4</param>
</service>
</servicedata>
\ No newline at end of file
++++++ haproxy-2.0.5+git0.d905f49a.tar.gz -> haproxy-2.0.6+git0.58706ab4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/CHANGELOG new/haproxy-2.0.6+git0.58706ab4/CHANGELOG
--- old/haproxy-2.0.5+git0.d905f49a/CHANGELOG 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/CHANGELOG 2019-09-13 13:46:44.000000000 +0200
@@ -1,6 +1,44 @@
ChangeLog :
===========
+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()
+ - MINOR: lua: export applet and task handlers
+ - MEDIUM: debug: make the thread dump code show Lua backtraces
+ - BUG/MEDIUM: mux-h1: do not truncate trailing 0CRLF on buffer boundary
+ - BUG/MEDIUM: mux-h1: do not report errors on transfers ending on buffer full
+ - DOC: fixed typo in management.txt
+ - BUG/MINOR: mworker: disable SIGPROF on re-exec
+ - BUG/MEDIUM: listener/threads: fix an AB/BA locking issue in delete_listener()
+ - BUG/MEDIUM: url32 does not take the path part into account in the returned hash.
+ - BUG/MEDIUM: proto-http: Always start the parsing if there is no outgoing data
+ - BUG/MEDIUM: peers: local peer socket not bound.
+ - BUG/MINOR: http-ana: Reset response flags when 1xx messages are handled
+ - BUG/MINOR: h1: Properly reset h1m when parsing is restarted
+ - BUG/MINOR: mux-h1: Fix size evaluation of HTX messages after headers parsing
+ - BUG/MINOR: mux-h1: Don't stop anymore input processing when the max is reached
+ - BUG/MINOR: mux-h1: Be sure to update the count before adding EOM after trailers
+ - BUG/MEDIUM: cache: Properly copy headers splitted on several shctx blocks
+ - BUG/MEDIUM: cache: Don't cache objects if the size of headers is too big
+ - BUG/MINOR: checks: stop polling for write when we have nothing left to send
+ - BUG/MINOR: checks: start sending the request right after connect()
+ - BUG/MINOR: checks: make __event_chk_srv_r() report success before closing
+ - BUG/MINOR: checks: do not uselessly poll for reads before the connection is up
+ - MINOR: contrib/prometheus-exporter: Report DRAIN/MAINT/NOLB status for servers
+ - BUG/MINOR: lb/leastconn: ignore the server weights for empty servers
+ - BUG/MAJOR: ssl: ssl_sock was not fully initialized.
+ - BUG/MEDIUM: connection: don't keep more idle connections than ever needed
+ - MINOR: stats: report the number of idle connections for each server
+ - BUG/MINOR: listener: Fix a possible null pointer dereference
+ - BUG/MINOR: ssl: always check for ssl connection before getting its XPRT context
+ - BUG/MEDIUM: http: also reject messages where "chunked" is missing from transfer-enoding
+ - BUG/MINOR: filters: Properly set the HTTP status code on analysis error
+ - BUG/MINOR: acl: Fix memory leaks when an ACL expression is parsed
+ - BUG/MINOR: backend: Fix a possible null pointer dereference
+ - BUG/MINOR: Missing stat_field_names (since f21d17bb)
+ - MINOR: sample: Add UUID-fetch
+
2019/08/16 : 2.0.5
- BUG/MEDIUM: stick-table: Wrong stick-table backends parsing.
- BUG/MINOR: ssl: fix 0-RTT for BoringSSL
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/VERDATE new/haproxy-2.0.6+git0.58706ab4/VERDATE
--- old/haproxy-2.0.5+git0.d905f49a/VERDATE 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/VERDATE 2019-09-13 13:46:44.000000000 +0200
@@ -1,2 +1,2 @@
$Format:%ci$
-2019/08/16
+2019/09/13
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/VERSION new/haproxy-2.0.6+git0.58706ab4/VERSION
--- old/haproxy-2.0.5+git0.d905f49a/VERSION 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/VERSION 2019-09-13 13:46:44.000000000 +0200
@@ -1 +1 @@
-2.0.5
+2.0.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/contrib/prometheus-exporter/service-prometheus.c new/haproxy-2.0.6+git0.58706ab4/contrib/prometheus-exporter/service-prometheus.c
--- old/haproxy-2.0.5+git0.d905f49a/contrib/prometheus-exporter/service-prometheus.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/contrib/prometheus-exporter/service-prometheus.c 2019-09-13 13:46:44.000000000 +0200
@@ -659,7 +659,7 @@
[ST_F_ERESP] = IST("Total number of response errors."),
[ST_F_WRETR] = IST("Total number of retry warnings."),
[ST_F_WREDIS] = IST("Total number of redispatch warnings."),
- [ST_F_STATUS] = IST("Current status of the service (frontend: 0=STOP, 1=UP, 2=FULL - backend/server: 0=DOWN, 1=UP)."),
+ [ST_F_STATUS] = IST("Current status of the service (frontend: 0=STOP, 1=UP, 2=FULL - backend: 0=DOWN, 1=UP - server: 0=DOWN, 1=UP, 2=MAINT, 3=DRAIN, 4=NOLB)."),
[ST_F_WEIGHT] = IST("Service weight."),
[ST_F_ACT] = IST("Current number of active servers."),
[ST_F_BCK] = IST("Current number of backup servers."),
@@ -1044,25 +1044,21 @@
[ST_F_CACHE_HITS] = IST("counter"),
};
-/* Return the server status: 1=UP and 0=DOWN. */
+/* Return the server status: 0=DOWN, 1=UP, 2=MAINT, 3=DRAIN, 4=NOLB. */
static int promex_srv_status(struct server *sv)
{
- struct server *via, *ref;
int state = 0;
- /* we have "via" which is the tracked server as described in the configuration,
- * and "ref" which is the checked server and the end of the chain.
- */
- via = sv->track ? sv->track : sv;
- ref = via;
- while (ref->track)
- ref = ref->track;
-
if (sv->cur_state == SRV_ST_RUNNING || sv->cur_state == SRV_ST_STARTING) {
state = 1;
if (sv->cur_admin & SRV_ADMF_DRAIN)
- state = 0;
+ state = 3;
}
+ else if (sv->cur_state == SRV_ST_STOPPING)
+ state = 4;
+
+ if (sv->cur_admin & SRV_ADMF_MAINT)
+ state = 2;
return state;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/doc/configuration.txt new/haproxy-2.0.6+git0.58706ab4/doc/configuration.txt
--- old/haproxy-2.0.5+git0.d905f49a/doc/configuration.txt 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/doc/configuration.txt 2019-09-13 13:46:44.000000000 +0200
@@ -4,7 +4,7 @@
----------------------
version 2.0
willy tarreau
- 2019/08/16
+ 2019/09/13
This document covers the configuration language as implemented in the version
@@ -14770,6 +14770,11 @@
needed to take some routing decisions for example, or just for debugging
purposes. This random must not be used for security purposes.
+uuid([<version>]) : string
+ Returns a UUID following the RFC4122 standard. If the version is not
+ specified, a UUID version 4 (fully random) is returned.
+ Currently, only version 4 is supported.
+
srv_conn([<backend>/]<server>) : integer
Returns an integer value corresponding to the number of currently established
connections on the designated server, possibly including the connection being
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/doc/management.txt new/haproxy-2.0.6+git0.58706ab4/doc/management.txt
--- old/haproxy-2.0.5+git0.d905f49a/doc/management.txt 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/doc/management.txt 2019-09-13 13:46:44.000000000 +0200
@@ -1549,8 +1549,8 @@
level "admin".
enable dynamic-cookie backend <backend>
- Enable the generation of dynamic cookies fot the backend <backend>
- A secret key must also be provided
+ Enable the generation of dynamic cookies for the backend <backend>.
+ A secret key must also be provided.
enable frontend <frontend>
Resume a frontend which was temporarily stopped. It is possible that some of
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/include/common/standard.h new/haproxy-2.0.6+git0.58706ab4/include/common/standard.h
--- old/haproxy-2.0.5+git0.d905f49a/include/common/standard.h 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/include/common/standard.h 2019-09-13 13:46:44.000000000 +0200
@@ -1238,6 +1238,7 @@
* free(err);
*/
char *indent_msg(char **out, int level);
+int append_prefixed_str(struct buffer *out, const char *in, const char *pfx, char eol, int first);
/* removes environment variable <name> from the environment as found in
* environ. This is only provided as an alternative for systems without
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/include/proto/hlua.h new/haproxy-2.0.6+git0.58706ab4/include/proto/hlua.h
--- old/haproxy-2.0.5+git0.d905f49a/include/proto/hlua.h 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/include/proto/hlua.h 2019-09-13 13:46:44.000000000 +0200
@@ -27,6 +27,9 @@
void hlua_ctx_destroy(struct hlua *lua);
void hlua_init();
int hlua_post_init();
+void hlua_applet_tcp_fct(struct appctx *ctx);
+void hlua_applet_http_fct(struct appctx *ctx);
+struct task *hlua_process_task(struct task *task, void *context, unsigned short state);
#else /* USE_LUA */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/include/proto/server.h new/haproxy-2.0.6+git0.58706ab4/include/proto/server.h
--- old/haproxy-2.0.5+git0.d905f49a/include/proto/server.h 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/include/proto/server.h 2019-09-13 13:46:44.000000000 +0200
@@ -249,6 +249,7 @@
{
if (srv && srv->pool_purge_delay > 0 &&
(srv->max_idle_conns == -1 || srv->max_idle_conns > srv->curr_idle_conns) &&
+ (srv->cur_sess + srv->curr_idle_conns <= srv->counters.cur_sess_max) &&
!(conn->flags & CO_FL_PRIVATE) &&
((srv->proxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) &&
!conn->mux->used_streams(conn) && conn->mux->avail_streams(conn) &&
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/include/types/stats.h new/haproxy-2.0.6+git0.58706ab4/include/types/stats.h
--- old/haproxy-2.0.5+git0.d905f49a/include/types/stats.h 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/include/types/stats.h 2019-09-13 13:46:44.000000000 +0200
@@ -415,6 +415,8 @@
ST_F_REUSE,
ST_F_CACHE_LOOKUPS,
ST_F_CACHE_HITS,
+ ST_F_SRV_ICUR,
+ ST_F_SRV_ILIM,
/* must always be the last one */
ST_F_TOTAL_FIELDS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/acl.c new/haproxy-2.0.6+git0.58706ab4/src/acl.c
--- old/haproxy-2.0.5+git0.d905f49a/src/acl.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/acl.c 2019-09-13 13:46:44.000000000 +0200
@@ -342,6 +342,8 @@
goto out_free_smp;
}
}
+ free(ckw);
+ ckw = NULL;
}
else {
/* This is not an ACL keyword, so we hope this is a sample fetch
@@ -360,7 +362,7 @@
expr = calloc(1, sizeof(*expr));
if (!expr) {
memprintf(err, "out of memory when parsing ACL expression");
- goto out_return;
+ goto out_free_smp;
}
pattern_init_head(&expr->pat);
@@ -678,8 +680,8 @@
out_free_expr:
prune_acl_expr(expr);
free(expr);
- free(ckw);
out_free_smp:
+ free(ckw);
free(smp);
out_return:
return NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/backend.c new/haproxy-2.0.6+git0.58706ab4/src/backend.c
--- old/haproxy-2.0.5+git0.d905f49a/src/backend.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/backend.c 2019-09-13 13:46:44.000000000 +0200
@@ -1337,7 +1337,7 @@
}
}
if (((!reuse || (srv_conn && !(srv_conn->flags & CO_FL_CONNECTED)))
- && ha_used_fds > global.tune.pool_high_count) && srv->idle_orphan_conns) {
+ && ha_used_fds > global.tune.pool_high_count) && srv && srv->idle_orphan_conns) {
struct connection *tokill_conn;
/* We can't reuse a connection, and e have more FDs than deemd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/cache.c new/haproxy-2.0.6+git0.58706ab4/src/cache.c
--- old/haproxy-2.0.5+git0.d905f49a/src/cache.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/cache.c 2019-09-13 13:46:44.000000000 +0200
@@ -721,6 +721,7 @@
if (IS_HTX_STRM(s)) {
struct htx *htx = htxbuf(&s->res.buf);
struct http_hdr_ctx ctx;
+ size_t hdrs_len = 0;
int32_t pos;
/* Do not cache too big objects. */
@@ -755,11 +756,17 @@
enum htx_blk_type type = htx_get_blk_type(blk);
uint32_t sz = htx_get_blksz(blk);
+ hdrs_len += sizeof(*blk) + sz;
chunk_memcat(&trash, (char *)&blk->info, sizeof(blk->info));
chunk_memcat(&trash, htx_get_blk_ptr(htx, blk), sz);
if (type == HTX_BLK_EOH)
break;
}
+
+ /* Do not cache objects if the headers are too big. */
+ if (hdrs_len > htx->size - global.tune.maxrewrite)
+ goto out;
+
}
else {
struct hdr_ctx ctx;
@@ -789,6 +796,10 @@
}
http_remove_header2(msg, &txn->hdr_idx, &ctx);
}
+
+ /* Do not cache objects if the headers are too big. */
+ if (msg->sov > c_size(txn->rsp.chn) - global.tune.maxrewrite)
+ goto out;
}
shctx_lock(shctx);
@@ -899,6 +910,7 @@
struct cache_flt_conf *cconf = appctx->rule->arg.act.p[0];
struct shared_context *shctx = shctx_ptr(cconf->c.cache);
struct htx_blk *blk;
+ char *ptr;
unsigned int max, total;
uint32_t blksz;
@@ -917,12 +929,14 @@
blk->info = info;
total = 4;
+ ptr = htx_get_blk_ptr(htx, blk);
while (blksz) {
max = MIN(blksz, shctx->block_size - offset);
- memcpy(htx_get_blk_ptr(htx, blk), (const char *)shblk->data + offset, max);
+ memcpy(ptr, (const char *)shblk->data + offset, max);
offset += max;
blksz -= max;
total += max;
+ ptr += max;
if (blksz || offset == shctx->block_size) {
shblk = LIST_NEXT(&shblk->list, typeof(shblk), list);
offset = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/cfgparse.c new/haproxy-2.0.6+git0.58706ab4/src/cfgparse.c
--- old/haproxy-2.0.5+git0.d905f49a/src/cfgparse.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/cfgparse.c 2019-09-13 13:46:44.000000000 +0200
@@ -2747,6 +2747,10 @@
mrule->table.t = target;
stktable_alloc_data_type(target, STKTABLE_DT_SERVER_ID, NULL);
stktable_alloc_data_type(target, STKTABLE_DT_SERVER_NAME, NULL);
+ if (!in_proxies_list(target->proxies_list, curproxy)) {
+ curproxy->next_stkt_ref = target->proxies_list;
+ target->proxies_list = curproxy;
+ }
}
}
@@ -2781,6 +2785,10 @@
mrule->table.t = target;
stktable_alloc_data_type(target, STKTABLE_DT_SERVER_ID, NULL);
stktable_alloc_data_type(target, STKTABLE_DT_SERVER_NAME, NULL);
+ if (!in_proxies_list(target->proxies_list, curproxy)) {
+ curproxy->next_stkt_ref = target->proxies_list;
+ target->proxies_list = curproxy;
+ }
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/checks.c new/haproxy-2.0.6+git0.58706ab4/src/checks.c
--- old/haproxy-2.0.5+git0.d905f49a/src/checks.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/checks.c 2019-09-13 13:46:44.000000000 +0200
@@ -791,6 +791,9 @@
}
}
+ if (!b_data(&check->bo))
+ conn_xprt_stop_send(conn);
+
/* full request sent, we allow up to if nonzero for a response */
if (s->proxy->timeout.check) {
t->expire = tick_add_ifset(now_ms, s->proxy->timeout.check);
@@ -1375,7 +1378,13 @@
}
default:
- /* for other checks (eg: pure TCP), delegate to the main task */
+ /* good connection is enough for pure TCP check */
+ if ((conn->flags & CO_FL_CONNECTED) && !check->type) {
+ if (check->use_ssl)
+ set_server_check_status(check, HCHK_STATUS_L6OK, NULL);
+ else
+ set_server_check_status(check, HCHK_STATUS_L4OK, NULL);
+ }
break;
} /* switch */
@@ -1438,8 +1447,12 @@
ret = tcpcheck_main(check);
cs = check->cs;
conn = cs->conn;
- } else if (!(check->wait_list.events & SUB_RETRY_SEND))
- __event_srv_chk_w(cs);
+ } else {
+ if (!(check->wait_list.events & SUB_RETRY_SEND))
+ __event_srv_chk_w(cs);
+ if (!(check->wait_list.events & SUB_RETRY_RECV))
+ __event_srv_chk_r(cs);
+ }
if (unlikely(conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)) {
/* We may get error reports bypassing the I/O handlers, typically
@@ -2243,8 +2256,16 @@
t->expire = tick_first(t->expire, t_con);
}
- if (check->type)
- __event_srv_chk_r(cs);
+ if (check->type) {
+ /* send the request if we have one. We avoid receiving
+ * if not connected, unless we didn't subscribe for
+ * sending since otherwise we won't be woken up.
+ */
+ __event_srv_chk_w(cs);
+ if (!(conn->flags & CO_FL_WAIT_L4_CONN) ||
+ !(check->wait_list.events & SUB_RETRY_SEND))
+ __event_srv_chk_r(cs);
+ }
task_set_affinity(t, tid_bit);
goto reschedule;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/debug.c new/haproxy-2.0.6+git0.58706ab4/src/debug.c
--- old/haproxy-2.0.5+git0.d905f49a/src/debug.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/debug.c 2019-09-13 13:46:44.000000000 +0200
@@ -26,6 +26,7 @@
#include
#include
+#include
#include
#include
@@ -90,6 +91,8 @@
void ha_task_dump(struct buffer *buf, const struct task *task, const char *pfx)
{
const struct stream *s = NULL;
+ const struct appctx __maybe_unused *appctx = NULL;
+ struct hlua __maybe_unused *hlua = NULL;
if (!task) {
chunk_appendf(buf, "0\n");
@@ -110,15 +113,23 @@
task->call_date ? " ns ago" : "");
chunk_appendf(buf, "%s"
- " fct=%p (%s) ctx=%p\n",
+ " fct=%p (%s) ctx=%p",
pfx,
task->process,
task->process == process_stream ? "process_stream" :
task->process == task_run_applet ? "task_run_applet" :
task->process == si_cs_io_cb ? "si_cs_io_cb" :
+#ifdef USE_LUA
+ task->process == hlua_process_task ? "hlua_process_task" :
+#endif
"?",
task->context);
+ if (task->process == task_run_applet && (appctx = task->context))
+ chunk_appendf(buf, "(%s)\n", appctx->applet->name);
+ else
+ chunk_appendf(buf, "\n");
+
if (task->process == process_stream && task->context)
s = (struct stream *)task->context;
else if (task->process == task_run_applet && task->context)
@@ -128,6 +139,30 @@
if (s)
stream_dump(buf, s, pfx, '\n');
+
+#ifdef USE_LUA
+ hlua = NULL;
+ if (s && (hlua = s->hlua)) {
+ chunk_appendf(buf, "%sCurrent executing Lua from a stream analyser -- ", pfx);
+ }
+ else if (task->process == hlua_process_task && (hlua = task->context)) {
+ chunk_appendf(buf, "%sCurrent executing a Lua task -- ", pfx);
+ }
+ else if (task->process == task_run_applet && (appctx = task->context) &&
+ (appctx->applet->fct == hlua_applet_tcp_fct && (hlua = appctx->ctx.hlua_apptcp.hlua))) {
+ chunk_appendf(buf, "%sCurrent executing a Lua TCP service -- ", pfx);
+ }
+ else if (task->process == task_run_applet && (appctx = task->context) &&
+ (appctx->applet->fct == hlua_applet_http_fct && (hlua = appctx->ctx.hlua_apphttp.hlua))) {
+ chunk_appendf(buf, "%sCurrent executing a Lua HTTP service -- ", pfx);
+ }
+
+ if (hlua) {
+ luaL_traceback(hlua->T, hlua->T, NULL, 0);
+ if (!append_prefixed_str(buf, lua_tostring(hlua->T, -1), pfx, '\n', 1))
+ b_putchr(buf, '\n');
+ }
+#endif
}
/* This function dumps all profiling settings. It returns 0 if the output
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/filters.c new/haproxy-2.0.6+git0.58706ab4/src/filters.c
--- old/haproxy-2.0.5+git0.d905f49a/src/filters.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/filters.c 2019-09-13 13:46:44.000000000 +0200
@@ -1190,6 +1190,7 @@
unsigned int an_bit, int ret)
{
int finst;
+ int status = 0;
if (ret < 0)
goto return_bad_req;
@@ -1211,21 +1212,23 @@
if (!(chn->flags & CF_ISRESP)) {
s->req.analysers &= AN_REQ_FLT_END;
finst = SF_FINST_R;
+ status = 400;
/* FIXME: incr counters */
}
else {
s->res.analysers &= AN_RES_FLT_END;
finst = SF_FINST_H;
+ status = 502;
/* FIXME: incr counters */
}
if (s->txn) {
/* Do not do that when we are waiting for the next request */
- if (s->txn->status)
+ if (s->txn->status > 0)
http_reply_and_close(s, s->txn->status, NULL);
else {
- s->txn->status = 400;
- http_reply_and_close(s, 400, http_error_message(s));
+ s->txn->status = status;
+ http_reply_and_close(s, status, http_error_message(s));
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/h1.c new/haproxy-2.0.6+git0.58706ab4/src/h1.c
--- old/haproxy-2.0.5+git0.d905f49a/src/h1.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/h1.c 2019-09-13 13:46:44.000000000 +0200
@@ -935,7 +935,8 @@
return -2;
restart:
- h1m->next = 0;
+ h1m->flags &= ~(H1_MF_VER_11|H1_MF_CLEN|H1_MF_XFER_ENC|H1_MF_CHNK|H1_MF_CONN_KAL|H1_MF_CONN_CLO|H1_MF_CONN_UPG);
+ h1m->curr_len = h1m->body_len = h1m->next = 0;
if (h1m->flags & H1_MF_RESP)
h1m->state = H1_MSG_RPBEFORE;
else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/haproxy.c new/haproxy-2.0.6+git0.58706ab4/src/haproxy.c
--- old/haproxy-2.0.5+git0.d905f49a/src/haproxy.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/haproxy.c 2019-09-13 13:46:44.000000000 +0200
@@ -695,6 +695,7 @@
}
ha_warning("Reexecuting Master process\n");
+ signal(SIGPROF, SIG_IGN);
execvp(next_argv[0], next_argv);
ha_warning("Failed to reexecute the master process [%d]: %s\n", pid, strerror(errno));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/hlua.c new/haproxy-2.0.6+git0.58706ab4/src/hlua.c
--- old/haproxy-2.0.5+git0.d905f49a/src/hlua.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/hlua.c 2019-09-13 13:46:44.000000000 +0200
@@ -6237,7 +6237,7 @@
* Task wrapper are longjmp safe because the only one Lua code
* executed is the safe hlua_ctx_resume();
*/
-static struct task *hlua_process_task(struct task *task, void *context, unsigned short state)
+struct task *hlua_process_task(struct task *task, void *context, unsigned short state)
{
struct hlua *hlua = context;
enum hlua_exec status;
@@ -7045,7 +7045,7 @@
return 1;
}
-static void hlua_applet_tcp_fct(struct appctx *ctx)
+void hlua_applet_tcp_fct(struct appctx *ctx)
{
struct stream_interface *si = ctx->owner;
struct stream *strm = si_strm(si);
@@ -7417,7 +7417,7 @@
goto done;
}
-static void hlua_applet_http_fct(struct appctx *ctx)
+void hlua_applet_http_fct(struct appctx *ctx)
{
struct stream_interface *si = ctx->owner;
struct stream *strm = si_strm(si);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/http_fetch.c new/haproxy-2.0.6+git0.58706ab4/src/http_fetch.c
--- old/haproxy-2.0.5+git0.d905f49a/src/http_fetch.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/http_fetch.c 2019-09-13 13:46:44.000000000 +0200
@@ -2735,10 +2735,6 @@
/* now retrieve the path */
sl = http_get_stline(htx);
path = http_get_path(htx_sl_req_uri(sl));
- while (path.len > 0 && *(path.ptr) != '?') {
- path.ptr++;
- path.len--;
- }
if (path.len && *(path.ptr) == '/') {
while (path.len--)
hash = *(path.ptr++) + (hash << 6) + (hash << 16) - hash;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/lb_fwlc.c new/haproxy-2.0.6+git0.58706ab4/src/lb_fwlc.c
--- old/haproxy-2.0.5+git0.d905f49a/src/lb_fwlc.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/lb_fwlc.c 2019-09-13 13:46:44.000000000 +0200
@@ -48,13 +48,15 @@
* for using #conns+1 is to sort by weights in case the server is picked
* and not before it is picked. This provides a better load accuracy for
* low connection counts when weights differ and makes sure the round-robin
- * applies between servers of highest weight first.
+ * applies between servers of highest weight first. However servers with no
+ * connection are always picked first so that under low loads, it's not
+ * always the single server with the highest weight that gets picked.
*
* The server's lock and the lbprm's lock must be held.
*/
static inline void fwlc_queue_srv(struct server *s)
{
- s->lb_node.key = (s->served + 1) * SRV_EWGHT_MAX / s->next_eweight;
+ s->lb_node.key = s->served ? (s->served + 1) * SRV_EWGHT_MAX / s->next_eweight : 0;
eb32_insert(s->lb_tree, &s->lb_node);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/listener.c new/haproxy-2.0.6+git0.58706ab4/src/listener.c
--- old/haproxy-2.0.5+git0.d905f49a/src/listener.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/listener.c 2019-09-13 13:46:44.000000000 +0200
@@ -595,17 +595,17 @@
*/
void delete_listener(struct listener *listener)
{
+ HA_SPIN_LOCK(PROTO_LOCK, &proto_lock);
HA_SPIN_LOCK(LISTENER_LOCK, &listener->lock);
if (listener->state == LI_ASSIGNED) {
listener->state = LI_INIT;
- HA_SPIN_LOCK(PROTO_LOCK, &proto_lock);
LIST_DEL(&listener->proto_list);
listener->proto->nb_listeners--;
- HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
_HA_ATOMIC_SUB(&jobs, 1);
_HA_ATOMIC_SUB(&listeners, 1);
}
HA_SPIN_UNLOCK(LISTENER_LOCK, &listener->lock);
+ HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
}
/* Returns a suitable value for a listener's backlog. It uses the listener's,
@@ -1065,7 +1065,7 @@
if (!LIST_ISEMPTY(&global_listener_queue))
dequeue_all_listeners(&global_listener_queue);
- if (!LIST_ISEMPTY(&p->listener_queue) &&
+ if (p && !LIST_ISEMPTY(&p->listener_queue) &&
(!p->fe_sps_lim || freq_ctr_remain(&p->fe_sess_per_sec, p->fe_sps_lim, 0) > 0))
dequeue_all_listeners(&p->listener_queue);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/mux_h1.c new/haproxy-2.0.6+git0.58706ab4/src/mux_h1.c
--- old/haproxy-2.0.5+git0.d905f49a/src/mux_h1.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/mux_h1.c 2019-09-13 13:46:44.000000000 +0200
@@ -67,7 +67,8 @@
#define H1S_F_BUF_FLUSH 0x00000100 /* Flush input buffer and don't read more data */
#define H1S_F_SPLICED_DATA 0x00000200 /* Set when the kernel splicing is in used */
#define H1S_F_HAVE_I_TLR 0x00000800 /* Set during input process to know the trailers were processed */
-/* 0x00001000 .. 0x00002000 unused */
+#define H1S_F_APPEND_EOM 0x00001000 /* Send EOM to the HTX buffer */
+/* 0x00002000 .. 0x00002000 unused */
#define H1S_F_HAVE_O_CONN 0x00004000 /* Set during output process to know connection mode was processed */
/* H1 connection descriptor */
@@ -930,7 +931,7 @@
size_t sz;
/* size of the HTX start-line */
- sz = sizeof(struct htx_sl) + h1sl->rq.m.len + h1sl->rq.u.len + h1sl->rq.v.len;
+ sz = sizeof(struct htx_blk) + sizeof(struct htx_sl) + h1sl->rq.m.len + h1sl->rq.u.len + h1sl->rq.v.len;
sz += h1_eval_htx_hdrs_size(hdrs);
return sz;
}
@@ -941,7 +942,7 @@
size_t sz;
/* size of the HTX start-line */
- sz = sizeof(struct htx_sl) + h1sl->st.v.len + h1sl->st.c.len + h1sl->st.r.len;
+ sz = sizeof(struct htx_blk) + sizeof(struct htx_sl) + h1sl->st.v.len + h1sl->st.c.len + h1sl->st.r.len;
sz += h1_eval_htx_hdrs_size(hdrs);
return sz;
}
@@ -954,9 +955,12 @@
*/
static size_t h1_process_eom(struct h1s *h1s, struct h1m *h1m, struct htx *htx, size_t max)
{
- if (max < sizeof(struct htx_blk) + 1 || !htx_add_endof(htx, HTX_BLK_EOM))
+ if (max < sizeof(struct htx_blk) + 1 || !htx_add_endof(htx, HTX_BLK_EOM)) {
+ h1s->flags |= H1S_F_APPEND_EOM;
return 0;
+ }
+ h1s->flags &= ~H1S_F_APPEND_EOM;
h1m->state = H1_MSG_DONE;
h1s->cs->flags |= CS_FL_EOI;
return (sizeof(struct htx_blk) + 1);
@@ -995,10 +999,11 @@
ret = h1_headers_to_hdr_list(b_peek(buf, *ofs), b_tail(buf),
hdrs, sizeof(hdrs)/sizeof(hdrs[0]), h1m, &h1sl);
if (ret <= 0) {
- /* Incomplete or invalid message. If the buffer is full, it's an
- * error because headers are too large to be handled by the
- * parser. */
- if (ret < 0 || (!ret && !buf_room_for_htx_data(buf)))
+ /* Incomplete or invalid message. If the input buffer only
+ * contains headers and is full, which is detected by it being
+ * full and the offset to be zero, it's an error because
+ * headers are too large to be handled by the parser. */
+ if (ret < 0 || (!ret && !*ofs && !buf_room_for_htx_data(buf)))
goto error;
goto end;
}
@@ -1339,10 +1344,11 @@
ret = h1_headers_to_hdr_list(b_peek(buf, *ofs), b_tail(buf),
hdrs, sizeof(hdrs)/sizeof(hdrs[0]), &tlr_h1m, NULL);
if (ret <= 0) {
- /* Incomplete or invalid trailers. If the buffer is full, it's
- * an error because traliers are too large to be handled by the
- * parser. */
- if (ret < 0 || (!ret && !buf_room_for_htx_data(buf)))
+ /* Incomplete or invalid trailers. If the input buffer only
+ * contains trailers and is full, which is detected by it being
+ * full and the offset to be zero, it's an error because
+ * trailers are too large to be handled by the parser. */
+ if (ret < 0 || (!ret && !*ofs && !buf_room_for_htx_data(buf)))
goto error;
goto end;
}
@@ -1428,7 +1434,7 @@
if (!ret)
break;
}
- if (!h1_process_eom(h1s, h1m, htx, count))
+ else if (!h1_process_eom(h1s, h1m, htx, count))
break;
}
else if (h1m->state == H1_MSG_DONE) {
@@ -1448,7 +1454,7 @@
}
count -= htx_used_space(htx) - used;
- } while (!(h1s->flags & errflag) && count);
+ } while (!(h1s->flags & errflag));
if (h1s->flags & errflag)
goto parsing_err;
@@ -1470,7 +1476,8 @@
else if (h1s_data_pending(h1s) && !htx_is_empty(htx))
h1s->cs->flags |= CS_FL_RCV_MORE | CS_FL_WANT_ROOM;
- if ((h1s->flags & H1S_F_REOS) && (!h1s_data_pending(h1s) || htx_is_empty(htx))) {
+ if (((h1s->flags & (H1S_F_REOS|H1S_F_APPEND_EOM)) == H1S_F_REOS) &&
+ (!h1s_data_pending(h1s) || htx_is_empty(htx))) {
h1s->cs->flags |= CS_FL_EOS;
if (h1m->state > H1_MSG_LAST_LF && h1m->state < H1_MSG_DONE)
h1s->cs->flags |= CS_FL_ERROR;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/proto_http.c new/haproxy-2.0.6+git0.58706ab4/src/proto_http.c
--- old/haproxy-2.0.5+git0.d905f49a/src/proto_http.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/proto_http.c 2019-09-13 13:46:44.000000000 +0200
@@ -598,7 +598,7 @@
*/
if (c_data(req) && msg->msg_state < HTTP_MSG_ERROR) {
if (txn->flags & TX_NOT_FIRST) {
- if (unlikely(!channel_is_rewritable(req))) {
+ if (unlikely(!channel_is_rewritable(req) && co_data(req))) {
if (req->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_WRITE_ERROR|CF_WRITE_TIMEOUT))
goto failed_keep_alive;
/* some data has still not left the buffer, wake us once that's done */
@@ -1073,6 +1073,10 @@
}
}
+ /* "chunked" mandatory if transfer-encoding is used */
+ if (ctx.idx && !(msg->flags & HTTP_MSGF_TE_CHNK))
+ goto return_bad_req;
+
/* Chunked requests must have their content-length removed */
ctx.idx = 0;
if (msg->flags & HTTP_MSGF_TE_CHNK) {
@@ -4230,7 +4234,7 @@
* data later, which is much more complicated.
*/
if (c_data(rep) && msg->msg_state < HTTP_MSG_ERROR) {
- if (unlikely(!channel_is_rewritable(rep))) {
+ if (unlikely(!channel_is_rewritable(rep) && co_data(rep))) {
/* some data has still not left the buffer, wake us once that's done */
if (rep->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_WRITE_ERROR|CF_WRITE_TIMEOUT))
goto abort_response;
@@ -4696,6 +4700,12 @@
}
}
+ /* "chunked" mandatory if transfer-encoding is used */
+ if (ctx.idx && !(msg->flags & HTTP_MSGF_TE_CHNK)) {
+ use_close_only = 1;
+ msg->flags &= ~(HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
+ }
+
/* Chunked responses must have their content-length removed */
ctx.idx = 0;
if (use_close_only || (msg->flags & HTTP_MSGF_TE_CHNK)) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/proto_htx.c new/haproxy-2.0.6+git0.58706ab4/src/proto_htx.c
--- old/haproxy-2.0.5+git0.d905f49a/src/proto_htx.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/proto_htx.c 2019-09-13 13:46:44.000000000 +0200
@@ -1634,7 +1634,6 @@
* response which at least looks like HTTP. We have an indicator
* of each header's length, so we can parse them quickly.
*/
-
msg->msg_state = HTTP_MSG_BODY;
BUG_ON(htx_get_first_type(htx) != HTX_BLK_RES_SL);
sl = http_get_stline(htx);
@@ -1710,6 +1709,7 @@
FLT_STRM_CB(s, flt_http_reset(s, msg));
htx->first = channel_htx_fwd_headers(rep, htx);
msg->msg_state = HTTP_MSG_RPBEFORE;
+ msg->flags = 0;
txn->status = 0;
s->logs.t_data = -1; /* was not a response yet */
goto next_one;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/sample.c new/haproxy-2.0.6+git0.58706ab4/src/sample.c
--- old/haproxy-2.0.5+git0.d905f49a/src/sample.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/sample.c 2019-09-13 13:46:44.000000000 +0200
@@ -3132,6 +3132,60 @@
return 1;
}
+// This function checks the "uuid" sample's arguments.
+// Function won't get called when no parameter is specified (maybe a bug?)
+static int smp_check_uuid(struct arg *args, char **err)
+{
+ if (!args[0].type) {
+ args[0].type = ARGT_SINT;
+ args[0].data.sint = 4;
+ }
+ else if (args[0].data.sint != 4) {
+ memprintf(err, "Unsupported UUID version: '%lld'", args[0].data.sint);
+ return 0;
+ }
+
+ return 1;
+}
+
+// Generate a RFC4122 UUID (default is v4 = fully random)
+static int smp_fetch_uuid(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+ if (args[0].data.sint == 4 || !args[0].type) {
+ 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);
+
+ while (byte < 4) {
+ while (bits < 32) {
+ last |= (uint64_t)random() << bits;
+ bits += rand_max_bits;
+ }
+ rnd[byte++] = last;
+ last >>= 32u;
+ bits -= 32;
+ }
+
+ chunk_printf(&trash, "%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
+ );
+
+ smp->data.type = SMP_T_STR;
+ smp->flags = SMP_F_VOL_TEST | SMP_F_MAY_CHANGE;
+ smp->data.u.str = trash;
+ return 1;
+ }
+
+ // more implementations of other uuid formats possible here
+ return 0;
+}
+
/* Note: must not be declared <const> as its list will be overwritten.
* Note: fetches that may return multiple types must be declared as the lowest
* common denominator, the type that can be casted into all other ones. For
@@ -3150,6 +3204,7 @@
{ "rand", smp_fetch_rand, ARG1(0,SINT), NULL, SMP_T_SINT, SMP_USE_INTRN },
{ "stopping", smp_fetch_stopping, 0, NULL, SMP_T_BOOL, SMP_USE_INTRN },
{ "stopping", smp_fetch_stopping, 0, NULL, SMP_T_BOOL, SMP_USE_INTRN },
+ { "uuid", smp_fetch_uuid, ARG1(0, SINT), smp_check_uuid, SMP_T_STR, SMP_USE_INTRN },
{ "cpu_calls", smp_fetch_cpu_calls, 0, NULL, SMP_T_SINT, SMP_USE_INTRN },
{ "cpu_ns_avg", smp_fetch_cpu_ns_avg, 0, NULL, SMP_T_SINT, SMP_USE_INTRN },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/ssl_sock.c new/haproxy-2.0.6+git0.58706ab4/src/ssl_sock.c
--- old/haproxy-2.0.5+git0.d905f49a/src/ssl_sock.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/ssl_sock.c 2019-09-13 13:46:44.000000000 +0200
@@ -5124,6 +5124,8 @@
ctx->conn = conn;
ctx->send_wait = NULL;
ctx->recv_wait = NULL;
+ ctx->xprt_st = 0;
+ ctx->xprt_ctx = NULL;
/* Only work with sockets for now, this should be adapted when we'll
* add QUIC support.
@@ -6091,7 +6093,7 @@
/* used for ppv2 pkey alog (can be used for logging) */
int ssl_sock_get_pkey_algo(struct connection *conn, struct buffer *out)
{
- struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ struct ssl_sock_ctx *ctx;
struct pkey_info *pkinfo;
int bits = 0;
int sig = TLSEXT_signature_anonymous;
@@ -6099,7 +6101,7 @@
if (!ssl_sock_is_ssl(conn))
return 0;
-
+ ctx = conn->xprt_ctx;
pkinfo = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ctx->ssl), ssl_pkey_info_index);
if (pkinfo) {
sig = pkinfo->sig;
@@ -6150,13 +6152,14 @@
/* used for ppv2 cert signature (can be used for logging) */
const char *ssl_sock_get_cert_sig(struct connection *conn)
{
- struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ struct ssl_sock_ctx *ctx;
__OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
X509 *crt;
if (!ssl_sock_is_ssl(conn))
return NULL;
+ ctx = conn->xprt_ctx;
crt = SSL_get_certificate(ctx->ssl);
if (!crt)
return NULL;
@@ -6168,10 +6171,11 @@
const char *ssl_sock_get_sni(struct connection *conn)
{
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
- struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ struct ssl_sock_ctx *ctx;
if (!ssl_sock_is_ssl(conn))
return NULL;
+ ctx = conn->xprt_ctx;
return SSL_get_servername(ctx->ssl, TLSEXT_NAMETYPE_host_name);
#else
return NULL;
@@ -6181,22 +6185,22 @@
/* used for logging/ppv2, may be changed for a sample fetch later */
const char *ssl_sock_get_cipher_name(struct connection *conn)
{
- struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ struct ssl_sock_ctx *ctx;
if (!ssl_sock_is_ssl(conn))
return NULL;
-
+ ctx = conn->xprt_ctx;
return SSL_get_cipher_name(ctx->ssl);
}
/* used for logging/ppv2, may be changed for a sample fetch later */
const char *ssl_sock_get_proto_version(struct connection *conn)
{
- struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ struct ssl_sock_ctx *ctx;
if (!ssl_sock_is_ssl(conn))
return NULL;
-
+ ctx = conn->xprt_ctx;
return SSL_get_version(ctx->ssl);
}
@@ -6402,11 +6406,11 @@
void ssl_sock_set_alpn(struct connection *conn, const unsigned char *alpn, int len)
{
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
- struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ struct ssl_sock_ctx *ctx;
if (!ssl_sock_is_ssl(conn))
return;
-
+ ctx = conn->xprt_ctx;
SSL_set_alpn_protos(ctx->ssl, alpn, len);
#endif
}
@@ -6417,12 +6421,13 @@
void ssl_sock_set_servername(struct connection *conn, const char *hostname)
{
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
- struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ struct ssl_sock_ctx *ctx;
char *prev_name;
if (!ssl_sock_is_ssl(conn))
return;
+ ctx = conn->xprt_ctx;
/* if the SNI changes, we must destroy the reusable context so that a
* new connection will present a new SNI. As an optimization we could
@@ -6447,7 +6452,7 @@
int ssl_sock_get_remote_common_name(struct connection *conn,
struct buffer *dest)
{
- struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ struct ssl_sock_ctx *ctx;
X509 *crt = NULL;
X509_NAME *name;
const char find_cn[] = "CN";
@@ -6459,6 +6464,7 @@
if (!ssl_sock_is_ssl(conn))
goto out;
+ ctx = conn->xprt_ctx;
/* SSL_get_peer_certificate, it increase X509 * ref count */
crt = SSL_get_peer_certificate(ctx->ssl);
@@ -6480,11 +6486,12 @@
/* returns 1 if client passed a certificate for this session, 0 if not */
int ssl_sock_get_cert_used_sess(struct connection *conn)
{
- struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ struct ssl_sock_ctx *ctx;
X509 *crt = NULL;
if (!ssl_sock_is_ssl(conn))
return 0;
+ ctx = conn->xprt_ctx;
/* SSL_get_peer_certificate, it increase X509 * ref count */
crt = SSL_get_peer_certificate(ctx->ssl);
@@ -6498,22 +6505,22 @@
/* returns 1 if client passed a certificate for this connection, 0 if not */
int ssl_sock_get_cert_used_conn(struct connection *conn)
{
- struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ struct ssl_sock_ctx *ctx;
if (!ssl_sock_is_ssl(conn))
return 0;
-
+ ctx = conn->xprt_ctx;
return SSL_SOCK_ST_FL_VERIFY_DONE & ctx->xprt_st ? 1 : 0;
}
/* returns result from SSL verify */
unsigned int ssl_sock_get_verify_result(struct connection *conn)
{
- struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+ struct ssl_sock_ctx *ctx;
if (!ssl_sock_is_ssl(conn))
return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
-
+ ctx = conn->xprt_ctx;
return (unsigned int)SSL_get_verify_result(ctx->ssl);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/standard.c new/haproxy-2.0.6+git0.58706ab4/src/standard.c
--- old/haproxy-2.0.5+git0.d905f49a/src/standard.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/standard.c 2019-09-13 13:46:44.000000000 +0200
@@ -3709,6 +3709,41 @@
return ret;
}
+/* makes a copy of message <in> into <out>, with each line prefixed with <pfx>
+ * and end of lines replaced with <eol> if not 0. The first line to indent has
+ * to be indicated in <first> (starts at zero), so that it is possible to skip
+ * indenting the first line if it has to be appended after an existing message.
+ * Empty strings are never indented, and NULL strings are considered empty both
+ * for <in> and <pfx>. It returns non-zero if an EOL was appended as the last
+ * character, non-zero otherwise.
+ */
+int append_prefixed_str(struct buffer *out, const char *in, const char *pfx, char eol, int first)
+{
+ int bol, lf;
+ int pfxlen = pfx ? strlen(pfx) : 0;
+
+ if (!in)
+ return 0;
+
+ bol = 1;
+ lf = 0;
+ while (*in) {
+ if (bol && pfxlen) {
+ if (first > 0)
+ first--;
+ else
+ b_putblk(out, pfx, pfxlen);
+ bol = 0;
+ }
+
+ lf = (*in == '\n');
+ bol |= lf;
+ b_putchr(out, (lf && eol) ? eol : *in);
+ in++;
+ }
+ return lf;
+}
+
/* removes environment variable <name> from the environment as found in
* environ. This is only provided as an alternative for systems without
* unsetenv() (old Solaris and AIX versions). THIS IS NOT THREAD SAFE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-2.0.5+git0.d905f49a/src/stats.c new/haproxy-2.0.6+git0.58706ab4/src/stats.c
--- old/haproxy-2.0.5+git0.d905f49a/src/stats.c 2019-08-16 16:52:47.000000000 +0200
+++ new/haproxy-2.0.6+git0.58706ab4/src/stats.c 2019-09-13 13:46:44.000000000 +0200
@@ -245,6 +245,8 @@
[ST_F_REUSE] = "reuse",
[ST_F_CACHE_LOOKUPS] = "cache_lookups",
[ST_F_CACHE_HITS] = "cache_hits",
+ [ST_F_SRV_ICUR] = "srv_icur",
+ [ST_F_SRV_ILIM] = "src_ilim"
};
/* one line of info */
@@ -983,11 +985,23 @@
chunk_appendf(out,
/* sessions: current, max, limit, total */
- "<td>%s</td><td>%s</td><td>%s</td>"
+ "<td><u>%s<div class=tips>"
+ "<table class=det>"
+ "<tr><th>Current active connections:</th><td>%s</td></tr>"
+ "<tr><th>Current idle connections:</th><td>%s</td></tr>"
+ "<tr><th>Active connections limit:</th><td>%s</td></tr>"
+ "<tr><th>Idle connections limit:</th><td>%s</td></tr>"
+ "</table></div></u>"
+ "</td><td>%s</td><td>%s</td>"
"<td><u>%s<div class=tips><table class=det>"
"<tr><th>Cum. sessions:</th><td>%s</td></tr>"
"",
- U2H(stats[ST_F_SCUR].u.u32), U2H(stats[ST_F_SMAX].u.u32), LIM2A(stats[ST_F_SLIM].u.u32, "-"),
+ U2H(stats[ST_F_SCUR].u.u32),
+ U2H(stats[ST_F_SCUR].u.u32),
+ U2H(stats[ST_F_SRV_ICUR].u.u32),
+ LIM2A(stats[ST_F_SLIM].u.u32, "-"),
+ stats[ST_F_SRV_ILIM].type ? U2H(stats[ST_F_SRV_ILIM].u.u32) : "-",
+ U2H(stats[ST_F_SMAX].u.u32), LIM2A(stats[ST_F_SLIM].u.u32, "-"),
U2H(stats[ST_F_STOT].u.u64),
U2H(stats[ST_F_STOT].u.u64));
@@ -1650,6 +1664,10 @@
if (sv->maxconn)
stats[ST_F_SLIM] = mkf_u32(FO_CONFIG|FN_LIMIT, sv->maxconn);
+ stats[ST_F_SRV_ICUR] = mkf_u32(0, sv->curr_idle_conns);
+ if (sv->max_idle_conns != -1)
+ stats[ST_F_SRV_ILIM] = mkf_u32(FO_CONFIG|FN_LIMIT, sv->max_idle_conns);
+
stats[ST_F_STOT] = mkf_u64(FN_COUNTER, sv->counters.cum_sess);
stats[ST_F_BIN] = mkf_u64(FN_COUNTER, sv->counters.bytes_in);
stats[ST_F_BOUT] = mkf_u64(FN_COUNTER, sv->counters.bytes_out);