Released version 1.7.2 with the following main changes : - BUG/MEDIUM: lua: In some case, the return of sample-fetches is ignored (2) - SCRIPTS: git-show-backports: fix a harmless typo - SCRIPTS: git-show-backports: add -H to use the hash of the commit message - BUG/MINOR: stream-int: automatically release SI_FL_WAIT_DATA on SHUTW_NOW - DOC: lua: documentation about time parser functions - DOC: lua: section declared twice - BUG/MINOR: lua/cli: bad error message - DOC: fix small typo in fe_id (backend instead of frontend) - BUG/MINOR: Fix the sending function in Lua's cosocket - BUG/MINOR: lua: memory leak executing tasks - BUG/MINOR: lua: bad return code - BUG/MEDIUM: ssl: properly reset the reused_sess during a forced handshake - BUG/MEDIUM: ssl: avoid double free when releasing bind_confs - BUG/MINOR: stats: fix be/sessions/current out in typed stats - BUG/MINOR: backend: nbsrv() should return 0 if backend is disabled - BUG/MEDIUM: ssl: for a handshake when server-side SNI changes - BUG/MINOR: systemd: potential zombie processes - DOC: Add timings events schemas - BUILD: lua: build failed on FreeBSD. - BUG/MINOR: option prefer-last-server must be ignored in some case - MINOR: stats: Support "select all" for backend actions - BUG/MINOR: sample-fetches/stick-tables: bad type for the sample fetches sc*_get_gpt0 - BUG/MAJOR: channel: Fix the definition order of channel analyzers - BUG/MINOR: http: report real parser state in error captures - BUILD: scripts: automatically update the branch in version.h when releasing - BUG/MAJOR: http: fix risk of getting invalid reports of bad requests - MINOR: http: custom status reason. - MINOR: connection: add sample fetch "fc_rcvd_proxy" - BUG/MINOR: config: emit a warning if http-reuse is enabled with incompatible options - BUG/MINOR: tools: fix off-by-one in port size check - BUG/MEDIUM: server: consider AF_UNSPEC as a valid address family - MEDIUM: server: split the address and the port into two different fields - MINOR: tools: make str2sa_range() return the port in a separate argument - MINOR: server: take the destination port from the port field, not the addr - MEDIUM: server: disable protocol validations when the server doesn't resolve - BUG/MEDIUM: tools: do not force an unresolved address to AF_INET:0.0.0.0 - BUG/MINOR: ssl: EVP_PKEY must be freed after X509_get_pubkey usage - MINOR: proto_http.c 502 error txt typo. - DOC: add deprecation notice to "block" - BUG/MINOR: Reset errno variable before calling strtol(3) Signed-off-by: heil <heil@terminal-consulting.de>lilik-openwrt-22.03
@ -1,268 +0,0 @@ | |||
From bf583640ff69104e228b5f04e149b800ebc9e7d8 Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <thierry.fournier@ozon.io> | |||
Date: Tue, 13 Dec 2016 13:06:23 +0100 | |||
Subject: [PATCH 01/19] BUG/MEDIUM: lua: In some case, the return of | |||
sample-fetches is ignored (2) | |||
This problem is already detected here: | |||
8dc7316a6fa8cc6f3a60456376c8a13a6902a5be | |||
Another case raises. Now HAProxy sends a final message (typically | |||
with "http-request deny"). Once the the message is sent, the response | |||
channel flags are not modified. | |||
HAProxy executes a Lua sample-fecthes for building logs, and the | |||
result is ignored because the response flag remains set to the value | |||
HTTP_MSG_RPBEFORE. So the Lua function hlua_check_proto() want to | |||
guarantee the valid state of the buffer and ask for aborting the | |||
request. | |||
The function check_proto() is not the good way to ensure request | |||
consistency. The real question is not "Are the message valid ?", but | |||
"Are the validity of message unchanged ?" | |||
This patch memorize the parser state before entering int the Lua | |||
code, and perform a check when it go out of the Lua code. If the parser | |||
state change for down, the request is aborted because the HTTP message | |||
is degraded. | |||
This patch should be backported in version 1.6 and 1.7 | |||
(cherry picked from commit 11cfb3daecd789416103837001e30e9644b4c722) | |||
--- | |||
include/types/hlua.h | 17 ++++++++++ | |||
src/hlua.c | 96 ++++++++++++++++++++++++++++++++++++---------------- | |||
2 files changed, 83 insertions(+), 30 deletions(-) | |||
diff --git a/include/types/hlua.h b/include/types/hlua.h | |||
index d2aaa4a..7a7c37f 100644 | |||
--- a/include/types/hlua.h | |||
+++ b/include/types/hlua.h | |||
@@ -49,6 +49,22 @@ enum hlua_exec { | |||
HLUA_E_ERR, /* LUA stack execution failed without error message. */ | |||
}; | |||
+/* This struct is use for storing HAProxy parsers state | |||
+ * before executing some Lua code. The goal is we can | |||
+ * check and compare the parser state a the end of Lua | |||
+ * execution. If the state is changed by Lua towards | |||
+ * an unexpected state, we can abort the transaction. | |||
+ */ | |||
+struct hlua_consistency { | |||
+ enum pr_mode mode; | |||
+ union { | |||
+ struct { | |||
+ int dir; | |||
+ enum ht_state state; | |||
+ } http; | |||
+ } data; | |||
+}; | |||
+ | |||
struct hlua { | |||
lua_State *T; /* The LUA stack. */ | |||
int Tref; /* The reference of the stack in coroutine case. | |||
@@ -65,6 +81,7 @@ struct hlua { | |||
We must wake this task to continue the task execution */ | |||
struct list com; /* The list head of the signals attached to this task. */ | |||
struct ebpt_node node; | |||
+ struct hlua_consistency cons; /* Store data consistency check. */ | |||
}; | |||
struct hlua_com { | |||
diff --git a/src/hlua.c b/src/hlua.c | |||
index 6889f2f..b91414b 100644 | |||
--- a/src/hlua.c | |||
+++ b/src/hlua.c | |||
@@ -2397,33 +2397,49 @@ static void hlua_resynchonize_proto(struct stream *stream, int dir) | |||
} | |||
} | |||
-/* Check the protocole integrity after the Lua manipulations. Close the stream | |||
- * and returns 0 if fails, otherwise returns 1. The direction is set using dir, | |||
- * which equals either SMP_OPT_DIR_REQ or SMP_OPT_DIR_RES. | |||
+/* This function is called before the Lua execution. It stores | |||
+ * the differents parsers state before executing some Lua code. | |||
*/ | |||
-static int hlua_check_proto(struct stream *stream, int dir) | |||
+static inline void consistency_set(struct stream *stream, int opt, struct hlua_consistency *c) | |||
+{ | |||
+ c->mode = stream->be->mode; | |||
+ switch (c->mode) { | |||
+ case PR_MODE_HTTP: | |||
+ c->data.http.dir = opt & SMP_OPT_DIR; | |||
+ if (c->data.http.dir == SMP_OPT_DIR_REQ) | |||
+ c->data.http.state = stream->txn->req.msg_state; | |||
+ else | |||
+ c->data.http.state = stream->txn->rsp.msg_state; | |||
+ break; | |||
+ default: | |||
+ break; | |||
+ } | |||
+} | |||
+ | |||
+/* This function is called after the Lua execution. it | |||
+ * returns true if the parser state is consistent, otherwise, | |||
+ * it return false. | |||
+ * | |||
+ * In HTTP mode, the parser state must be in the same state | |||
+ * or greater when we exit the function. Even if we do a | |||
+ * control yield. This prevent to break the HTTP message | |||
+ * from the Lua code. | |||
+ */ | |||
+static inline int consistency_check(struct stream *stream, int opt, struct hlua_consistency *c) | |||
{ | |||
- const struct chunk msg = { .len = 0 }; | |||
+ if (c->mode != stream->be->mode) | |||
+ return 0; | |||
- /* Protocol HTTP. The message parsing state must match the request or | |||
- * response state. The problem that may happen is that Lua modifies | |||
- * the request or response message *after* it was parsed, and corrupted | |||
- * it so that it could not be processed anymore. We just need to verify | |||
- * if the parser is still expected to run or not. | |||
- */ | |||
- if (stream->be->mode == PR_MODE_HTTP) { | |||
- if (dir == SMP_OPT_DIR_REQ && | |||
- !(stream->req.analysers & AN_REQ_WAIT_HTTP) && | |||
- stream->txn->req.msg_state < HTTP_MSG_ERROR) { | |||
- stream_int_retnclose(&stream->si[0], &msg); | |||
- return 0; | |||
- } | |||
- else if (dir == SMP_OPT_DIR_RES && | |||
- !(stream->res.analysers & AN_RES_WAIT_HTTP) && | |||
- stream->txn->rsp.msg_state < HTTP_MSG_ERROR) { | |||
- stream_int_retnclose(&stream->si[0], &msg); | |||
+ switch (c->mode) { | |||
+ case PR_MODE_HTTP: | |||
+ if (c->data.http.dir != (opt & SMP_OPT_DIR)) | |||
return 0; | |||
- } | |||
+ if (c->data.http.dir == SMP_OPT_DIR_REQ) | |||
+ return stream->txn->req.msg_state >= c->data.http.state; | |||
+ else | |||
+ return stream->txn->rsp.msg_state >= c->data.http.state; | |||
+ default: | |||
+ return 1; | |||
} | |||
return 1; | |||
} | |||
@@ -5324,6 +5340,7 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp | |||
struct hlua_function *fcn = private; | |||
struct stream *stream = smp->strm; | |||
const char *error; | |||
+ const struct chunk msg = { .len = 0 }; | |||
if (!stream) | |||
return 0; | |||
@@ -5338,6 +5355,8 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp | |||
return 0; | |||
} | |||
+ consistency_set(stream, smp->opt, &stream->hlua.cons); | |||
+ | |||
/* If it is the first run, initialize the data for the call. */ | |||
if (!HLUA_IS_RUNNING(&stream->hlua)) { | |||
@@ -5393,8 +5412,10 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp | |||
switch (hlua_ctx_resume(&stream->hlua, 0)) { | |||
/* finished. */ | |||
case HLUA_E_OK: | |||
- if (!hlua_check_proto(stream, (smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES)) | |||
+ if (!consistency_check(stream, smp->opt, &stream->hlua.cons)) { | |||
+ stream_int_retnclose(&stream->si[0], &msg); | |||
return 0; | |||
+ } | |||
/* Convert the returned value in sample. */ | |||
hlua_lua2smp(stream->hlua.T, -1, smp); | |||
lua_pop(stream->hlua.T, 1); | |||
@@ -5405,13 +5426,15 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp | |||
/* yield. */ | |||
case HLUA_E_AGAIN: | |||
- hlua_check_proto(stream, (smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES); | |||
+ if (!consistency_check(stream, smp->opt, &stream->hlua.cons)) | |||
+ stream_int_retnclose(&stream->si[0], &msg); | |||
SEND_ERR(smp->px, "Lua sample-fetch '%s': cannot use yielded functions.\n", fcn->name); | |||
return 0; | |||
/* finished with error. */ | |||
case HLUA_E_ERRMSG: | |||
- hlua_check_proto(stream, (smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES); | |||
+ if (!consistency_check(stream, smp->opt, &stream->hlua.cons)) | |||
+ stream_int_retnclose(&stream->si[0], &msg); | |||
/* Display log. */ | |||
SEND_ERR(smp->px, "Lua sample-fetch '%s': %s.\n", | |||
fcn->name, lua_tostring(stream->hlua.T, -1)); | |||
@@ -5419,7 +5442,8 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp | |||
return 0; | |||
case HLUA_E_ERR: | |||
- hlua_check_proto(stream, (smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES); | |||
+ if (!consistency_check(stream, smp->opt, &stream->hlua.cons)) | |||
+ stream_int_retnclose(&stream->si[0], &msg); | |||
/* Display log. */ | |||
SEND_ERR(smp->px, "Lua sample-fetch '%s' returns an unknown error.\n", fcn->name); | |||
@@ -5556,6 +5580,7 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px, | |||
unsigned int analyzer; | |||
int dir; | |||
const char *error; | |||
+ const struct chunk msg = { .len = 0 }; | |||
switch (rule->from) { | |||
case ACT_F_TCP_REQ_CNT: analyzer = AN_REQ_INSPECT_FE ; dir = SMP_OPT_DIR_REQ; break; | |||
@@ -5567,6 +5592,8 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px, | |||
return ACT_RET_CONT; | |||
} | |||
+ consistency_set(s, dir, &s->hlua.cons); | |||
+ | |||
/* In the execution wrappers linked with a stream, the | |||
* Lua context can be not initialized. This behavior | |||
* permits to save performances because a systematic | |||
@@ -5635,8 +5662,10 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px, | |||
switch (hlua_ctx_resume(&s->hlua, !(flags & ACT_FLAG_FINAL))) { | |||
/* finished. */ | |||
case HLUA_E_OK: | |||
- if (!hlua_check_proto(s, dir)) | |||
+ if (!consistency_check(s, dir, &s->hlua.cons)) { | |||
+ stream_int_retnclose(&s->si[0], &msg); | |||
return ACT_RET_ERR; | |||
+ } | |||
if (s->hlua.flags & HLUA_STOP) | |||
return ACT_RET_STOP; | |||
return ACT_RET_CONT; | |||
@@ -5661,12 +5690,17 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px, | |||
} | |||
if (HLUA_IS_WAKEREQWR(&s->hlua)) | |||
s->req.flags |= CF_WAKE_WRITE; | |||
+ /* We can quit the fcuntion without consistency check | |||
+ * because HAProxy is not able to manipulate data, it | |||
+ * is only allowed to call me again. */ | |||
return ACT_RET_YIELD; | |||
/* finished with error. */ | |||
case HLUA_E_ERRMSG: | |||
- if (!hlua_check_proto(s, dir)) | |||
+ if (!consistency_check(s, dir, &s->hlua.cons)) { | |||
+ stream_int_retnclose(&s->si[0], &msg); | |||
return ACT_RET_ERR; | |||
+ } | |||
/* Display log. */ | |||
SEND_ERR(px, "Lua function '%s': %s.\n", | |||
rule->arg.hlua_rule->fcn.name, lua_tostring(s->hlua.T, -1)); | |||
@@ -5674,8 +5708,10 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px, | |||
return ACT_RET_CONT; | |||
case HLUA_E_ERR: | |||
- if (!hlua_check_proto(s, dir)) | |||
+ if (!consistency_check(s, dir, &s->hlua.cons)) { | |||
+ stream_int_retnclose(&s->si[0], &msg); | |||
return ACT_RET_ERR; | |||
+ } | |||
/* Display log. */ | |||
SEND_ERR(px, "Lua function '%s' return an unknown error.\n", | |||
rule->arg.hlua_rule->fcn.name); | |||
-- | |||
2.10.2 | |||
@ -0,0 +1,36 @@ | |||
From 7a03968243dbad8cab1a3bdd75794c4d7cc18d96 Mon Sep 17 00:00:00 2001 | |||
From: Christopher Faulet <cfaulet@haproxy.com> | |||
Date: Mon, 9 Jan 2017 16:33:19 +0100 | |||
Subject: [PATCH] BUG/MINOR: stream: Fix how backend-specific analyzers are set | |||
on a stream | |||
When the stream's backend was defined, the request's analyzers flag was always | |||
set to 0 if the stream had no listener. This bug was introduced with the filter | |||
API but never triggered (I think so). | |||
Because of the commit 5820a366, it is now possible to encountered it. For | |||
example, this happens when the trace filter is enabled on a SPOE backend. The | |||
fix is pretty trivial. | |||
This fix must be backported to 1.7. | |||
(cherry picked from commit 70e2f272127a931a7b245a95e3a022879145e1dd) | |||
--- | |||
src/proxy.c | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/src/proxy.c b/src/proxy.c | |||
index fec2555..a84a08f 100644 | |||
--- a/src/proxy.c | |||
+++ b/src/proxy.c | |||
@@ -1156,7 +1156,7 @@ int stream_set_backend(struct stream *s, struct proxy *be) | |||
* be more reliable to store the list of analysers that have been run, | |||
* but what we do here is OK for now. | |||
*/ | |||
- s->req.analysers |= be->be_req_ana & (strm_li(s) ? ~strm_li(s)->analysers : 0); | |||
+ s->req.analysers |= be->be_req_ana & ~(strm_li(s) ? strm_li(s)->analysers : 0); | |||
/* If the target backend requires HTTP processing, we have to allocate | |||
* the HTTP transaction and hdr_idx if we did not have one. | |||
-- | |||
2.10.2 | |||
@ -1,28 +0,0 @@ | |||
From b0b4eff10d998ff6bb00d5a36478f2b3d6ee2ee0 Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Wed, 14 Dec 2016 16:43:23 +0100 | |||
Subject: [PATCH 02/19] SCRIPTS: git-show-backports: fix a harmless typo | |||
There was a double output redirection in this script while dumping the | |||
current branch's refs which could cause either an error or an empty file. | |||
(cherry picked from commit b684cd4642186fd64c9335c316aeca16cc87d9de) | |||
--- | |||
scripts/git-show-backports | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/scripts/git-show-backports b/scripts/git-show-backports | |||
index 6567b2f..ca7ad4f 100755 | |||
--- a/scripts/git-show-backports | |||
+++ b/scripts/git-show-backports | |||
@@ -183,7 +183,7 @@ mkdir -p .git/.show-backports #|| die "Can't create .git/.show-backports" | |||
WORK=.git/.show-backports | |||
rm -f "$WORK/${REF//\//_}" | |||
-git log --reverse ${LOGEXPR:+--grep $LOGEXPR} --pretty="%H %s" "$BASE".."$REF" | grep "${SUBJECT}" > "$WORK/${branch//\//_}" > "$WORK/${REF//\//_}" | |||
+git log --reverse ${LOGEXPR:+--grep $LOGEXPR} --pretty="%H %s" "$BASE".."$REF" | grep "${SUBJECT}" > "$WORK/${REF//\//_}" | |||
# for each branch, enumerate all commits and their ancestry | |||
-- | |||
2.10.2 | |||
@ -1,101 +0,0 @@ | |||
From dae8c59d08d60b32d2bddf367f3686ff87e7c87e Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Wed, 14 Dec 2016 16:44:45 +0100 | |||
Subject: [PATCH 03/19] SCRIPTS: git-show-backports: add -H to use the hash of | |||
the commit message | |||
Sometimes certain commits don't contain useful tracking information but | |||
we'd still like to be able to report them. Here we implement a hash on | |||
the author's name, e-mail and date, the subject and the body before the | |||
first s-o-b or cherry-picked line. These parts are supposed to be | |||
reasonable invariant across backports and are usable to compute an | |||
invariant hash of a given commit. When we don't find ancestry in a | |||
commit, we try this method (if -H is specified) to compare commits | |||
hashes and we can report a match. The equivalent commit is reported | |||
as "XXXX+?" to indicate that it's an apparent backport but we don't | |||
know how far it goes. | |||
(cherry picked from commit 5e637e556d12cd4d8b97b4896448ef6f3396224b) | |||
--- | |||
scripts/git-show-backports | 26 ++++++++++++++++++++++++-- | |||
1 file changed, 24 insertions(+), 2 deletions(-) | |||
diff --git a/scripts/git-show-backports b/scripts/git-show-backports | |||
index ca7ad4f..1569701 100755 | |||
--- a/scripts/git-show-backports | |||
+++ b/scripts/git-show-backports | |||
@@ -28,7 +28,7 @@ | |||
# show-backports -q -m -r hapee-r2 hapee-r1 | |||
-USAGE="Usage: ${0##*/} [-q] [-m] [-u] [-r reference] [-l logexpr] [-s subject] [-b base] {branch|range} [...]" | |||
+USAGE="Usage: ${0##*/} [-q] [-H] [-m] [-u] [-r reference] [-l logexpr] [-s subject] [-b base] {branch|range} [...]" | |||
BASES=( ) | |||
BRANCHES=( ) | |||
REF=master | |||
@@ -38,6 +38,7 @@ LOGEXPR= | |||
SUBJECT= | |||
MISSING= | |||
UPSTREAM= | |||
+BODYHASH= | |||
die() { | |||
[ "$#" -eq 0 ] || echo "$*" >&2 | |||
@@ -75,10 +76,12 @@ dump_commit_matrix() { | |||
upstream="none" | |||
missing=0 | |||
+ refbhash="" | |||
line="" | |||
for branch in "${BRANCHES[@]}"; do | |||
set -- $(grep -m 1 $ref "$WORK/${branch//\//_}") | |||
newhash=$1 ; shift | |||
+ bhash="" | |||
# count the number of cherry-picks after this one. Since we shift, | |||
# the result is in "$#" | |||
while [ -n "$1" -a "$1" != "$ref" ]; do | |||
@@ -108,6 +111,19 @@ dump_commit_matrix() { | |||
break | |||
fi | |||
done | |||
+ if [ -z "$newhash" -a -n "$BODYHASH" ]; then | |||
+ if [ -z "$refbhash" ]; then | |||
+ refbhash=$(git log -1 --pretty="%an|%ae|%at|%B" "$ref" | sed -n '/^\(Signed-off-by\|(cherry picked\)/q;p' | md5sum) | |||
+ fi | |||
+ | |||
+ | |||
+ set -- $(grep -m 1 "H$refbhash\$" "$WORK/${branch//\//_}") | |||
+ newhash=$1 ; shift | |||
+ if [ -n "$newhash" ]; then | |||
+ line="${line} $(short $newhash)+?" | |||
+ break | |||
+ fi | |||
+ fi | |||
if [ -z "$newhash" ]; then | |||
line="${line} -" | |||
missing=1 | |||
@@ -136,6 +152,7 @@ while [ -n "$1" -a -z "${1##-*}" ]; do | |||
-q) QUIET=1 ; shift ;; | |||
-m) MISSING=1 ; shift ;; | |||
-u) UPSTREAM=1 ; shift ;; | |||
+ -H) BODYHASH=1 ; shift ;; | |||
-h|--help) quit "$USAGE" ;; | |||
*) die "$USAGE" ;; | |||
esac | |||
@@ -194,8 +211,13 @@ while [ $branch_num -lt "${#BRANCHES[@]}" ]; do | |||
base="${base:-$BASE}" | |||
rm -f "$WORK/${branch//\//_}" | |||
git log --reverse --pretty="%H %s" "$base".."$branch" | grep "${SUBJECT}" | while read h subject; do | |||
- echo "$h" $(git log -1 --pretty --format=%B "$h" | \ | |||
+ echo -n "$h" $(git log -1 --pretty --format=%B "$h" | \ | |||
sed -n 's/^commit \([^)]*\) upstream\.$/\1/p;s/^(cherry picked from commit \([^)]*\))/\1/p') | |||
+ if [ -n "$BODYHASH" ]; then | |||
+ echo " H$(git log -1 --pretty="%an|%ae|%at|%B" "$h" | sed -n '/^\(Signed-off-by\|(cherry picked\)/q;p' | md5sum)" | |||
+ else | |||
+ echo | |||
+ fi | |||
done > "$WORK/${branch//\//_}" | |||
(( branch_num++ )) | |||
done | |||
-- | |||
2.10.2 | |||
@ -1,46 +0,0 @@ | |||
From ae03ce5039283b63124e069bccd2c742cd71c5fb Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Tue, 13 Dec 2016 15:21:25 +0100 | |||
Subject: [PATCH 04/19] BUG/MINOR: stream-int: automatically release | |||
SI_FL_WAIT_DATA on SHUTW_NOW | |||
While developing an experimental applet performing only one read per full | |||
line, it appeared that it would be woken up for the client's close, not | |||
read all data (missing LF), then wait for a subsequent call, and would only | |||
be woken up on client timeout to finish the read. The reason is that we | |||
preset SI_FL_WAIT_DATA in the stream-interface's flags to avoid a fast loop, | |||
but there's nothing which can remove this flag until there's a read operation. | |||
We must definitely remove it in stream_int_notify() each time we're called | |||
with CF_SHUTW_NOW because we know there will be no more subsequent read | |||
and we don't want an applet which keeps the WANT_GET flag to block on this. | |||
This fix should be backported to 1.7 and 1.6 though it's uncertain whether | |||
cli, peers, lua or spoe really are affected there. | |||
(cherry picked from commit 8cf9c8e663fa468fa2380eddecd671172ff63868) | |||
--- | |||
src/stream_interface.c | 6 +++++- | |||
1 file changed, 5 insertions(+), 1 deletion(-) | |||
diff --git a/src/stream_interface.c b/src/stream_interface.c | |||
index faeceb9..758aec7 100644 | |||
--- a/src/stream_interface.c | |||
+++ b/src/stream_interface.c | |||
@@ -455,9 +455,13 @@ void stream_int_notify(struct stream_interface *si) | |||
oc->wex = TICK_ETERNITY; | |||
} | |||
- /* indicate that we may be waiting for data from the output channel */ | |||
+ /* indicate that we may be waiting for data from the output channel or | |||
+ * we're about to close and can't expect more data if SHUTW_NOW is there. | |||
+ */ | |||
if ((oc->flags & (CF_SHUTW|CF_SHUTW_NOW)) == 0 && channel_may_recv(oc)) | |||
si->flags |= SI_FL_WAIT_DATA; | |||
+ else if ((oc->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW) | |||
+ si->flags &= ~SI_FL_WAIT_DATA; | |||
/* update OC timeouts and wake the other side up if it's waiting for room */ | |||
if (oc->flags & CF_WRITE_ACTIVITY) { | |||
-- | |||
2.10.2 | |||
@ -1,112 +0,0 @@ | |||
From 809d416ac092a42aaf1752dc789d5a828c45d42b Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <thierry.fournier@ozon.io> | |||
Date: Wed, 14 Dec 2016 19:04:41 +0100 | |||
Subject: [PATCH 05/19] DOC: lua: documentation about time parser functions | |||
This patch must be backported in version 1.7 | |||
(cherry picked from commit a78f037505c3176aef3ce80f6aaac2fdcc92ca27) | |||
--- | |||
doc/lua-api/index.rst | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++ | |||
1 file changed, 87 insertions(+) | |||
diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst | |||
index 22c0538..3cb2b4b 100644 | |||
--- a/doc/lua-api/index.rst | |||
+++ b/doc/lua-api/index.rst | |||
@@ -297,6 +297,93 @@ Core class | |||
contains the current at the epoch format, and "usec" contains the | |||
current microseconds. | |||
+.. js:function:: core.http_date(date) | |||
+ | |||
+ **context**: body, init, task, action | |||
+ | |||
+ This function take a string repsenting http date, and returns an integer | |||
+ containing the corresponding date with a epoch format. A valid http date | |||
+ me respect the format IMF, RFC850 or ASCTIME. | |||
+ | |||
+ :param string date: a date http-date formatted | |||
+ :returns: integer containing epoch date | |||
+ :see: :js:func:`core.imf_date`. | |||
+ :see: :js:func:`core.rfc850_date`. | |||
+ :see: :js:func:`core.asctime_date`. | |||
+ :see: https://tools.ietf.org/html/rfc7231#section-7.1.1.1 | |||
+ | |||
+.. js:function:: core.imf_date(date) | |||
+ | |||
+ **context**: body, init, task, action | |||
+ | |||
+ This function take a string repsenting IMF date, and returns an integer | |||
+ containing the corresponding date with a epoch format. | |||
+ | |||
+ :param string date: a date IMF formatted | |||
+ :returns: integer containing epoch date | |||
+ :see: https://tools.ietf.org/html/rfc7231#section-7.1.1.1 | |||
+ | |||
+ The IMF format is like this: | |||
+ | |||
+.. code-block:: text | |||
+ | |||
+ Sun, 06 Nov 1994 08:49:37 GMT | |||
+.. | |||
+ | |||
+.. js:function:: core.rfc850_date(date) | |||
+ | |||
+ **context**: body, init, task, action | |||
+ | |||
+ This function take a string repsenting RFC850 date, and returns an integer | |||
+ containing the corresponding date with a epoch format. | |||
+ | |||
+ :param string date: a date RFC859 formatted | |||
+ :returns: integer containing epoch date | |||
+ :see: https://tools.ietf.org/html/rfc7231#section-7.1.1.1 | |||
+ | |||
+ The RFC850 format is like this: | |||
+ | |||
+.. code-block:: text | |||
+ | |||
+ Sunday, 06-Nov-94 08:49:37 GMT | |||
+.. | |||
+ | |||
+.. js:function:: core.asctime_date(date) | |||
+ | |||
+ **context**: body, init, task, action | |||
+ | |||
+ This function take a string repsenting ASCTIME date, and returns an integer | |||
+ containing the corresponding date with a epoch format. | |||
+ | |||
+ :param string date: a date ASCTIME formatted | |||
+ :returns: integer containing epoch date | |||
+ :see: https://tools.ietf.org/html/rfc7231#section-7.1.1.1 | |||
+ | |||
+ The ASCTIME format is like this: | |||
+ | |||
+.. code-block:: text | |||
+ | |||
+ Sun Nov 6 08:49:37 1994 | |||
+.. | |||
+ | |||
+.. js:function:: core.rfc850_date(date) | |||
+ | |||
+ **context**: body, init, task, action | |||
+ | |||
+ This function take a string repsenting http date, and returns an integer | |||
+ containing the corresponding date with a epoch format. | |||
+ | |||
+ :param string date: a date http-date formatted | |||
+ | |||
+.. js:function:: core.asctime_date(date) | |||
+ | |||
+ **context**: body, init, task, action | |||
+ | |||
+ This function take a string repsenting http date, and returns an integer | |||
+ containing the corresponding date with a epoch format. | |||
+ | |||
+ :param string date: a date http-date formatted | |||
+ | |||
.. js:function:: core.msleep(milliseconds) | |||
**context**: body, init, task, action | |||
-- | |||
2.10.2 | |||
@ -1,31 +0,0 @@ | |||
From 3e94c95f577cfbd3921545bacc92dd638739859c Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <thierry.fournier@ozon.io> | |||
Date: Wed, 14 Dec 2016 19:43:08 +0100 | |||
Subject: [PATCH 06/19] DOC: lua: section declared twice | |||
This patch remove the second section. | |||
This patch should be backported in versions 1.6 and 1.7 | |||
(cherry picked from commit d7f2eb6f7eb7218b9f85fb59e24d1d414d6b9fae) | |||
--- | |||
doc/lua-api/index.rst | 4 ---- | |||
1 file changed, 4 deletions(-) | |||
diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst | |||
index 3cb2b4b..8d3bdf0 100644 | |||
--- a/doc/lua-api/index.rst | |||
+++ b/doc/lua-api/index.rst | |||
@@ -2065,10 +2065,6 @@ AppletHTTP class | |||
AppletHTTP.headers["accept"][2] = "*/*, q=0.1" | |||
.. | |||
-.. js:attribute:: AppletHTTP.headers | |||
- | |||
- Contains an array containing all the request headers. | |||
- | |||
.. js:function:: AppletHTTP.set_status(applet, code) | |||
This function sets the HTTP status code for the response. The allowed code are | |||
-- | |||
2.10.2 | |||
@ -1,29 +0,0 @@ | |||
From bd2fff07e8858d5154debd48dfabcddaf5d133e4 Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <thierry.fournier@ozon.io> | |||
Date: Fri, 16 Dec 2016 11:14:06 +0100 | |||
Subject: [PATCH 07/19] BUG/MINOR: lua/cli: bad error message | |||
Error message inherited from lua_appelet_tcp copy/paste. | |||
Should be backported in 1.7 | |||
(cherry picked from commit ffbf569edba2a10a3d2316cb6d7435944f591cce) | |||
--- | |||
src/hlua.c | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/src/hlua.c b/src/hlua.c | |||
index b91414b..cee2c1b 100644 | |||
--- a/src/hlua.c | |||
+++ b/src/hlua.c | |||
@@ -6447,7 +6447,7 @@ static int hlua_cli_parse_fct(char **args, struct appctx *appctx, void *private) | |||
*/ | |||
appctx->ctx.hlua_cli.task = task_new(); | |||
if (!appctx->ctx.hlua_cli.task) { | |||
- SEND_ERR(NULL, "Lua applet tcp '%s': out of memory.\n", fcn->name); | |||
+ SEND_ERR(NULL, "Lua cli '%s': out of memory.\n", fcn->name); | |||
return 0; | |||
} | |||
appctx->ctx.hlua_cli.task->nice = 0; | |||
-- | |||
2.10.2 | |||
@ -1,28 +0,0 @@ | |||
From ea6f0832bf3879bbc68089399bbb05d411c766d2 Mon Sep 17 00:00:00 2001 | |||
From: Marcin Deranek <marcin.deranek@booking.com> | |||
Date: Tue, 13 Dec 2016 12:40:01 +0100 | |||
Subject: [PATCH 08/19] DOC: fix small typo in fe_id (backend instead of | |||
frontend) | |||
Needs to be backported to 1.7 and 1.6 at least. | |||
(cherry picked from commit 6e413ed1ed33e65740bfa1f209383252eb472256) | |||
--- | |||
doc/configuration.txt | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/doc/configuration.txt b/doc/configuration.txt | |||
index 6795166..6596578 100644 | |||
--- a/doc/configuration.txt | |||
+++ b/doc/configuration.txt | |||
@@ -13182,7 +13182,7 @@ fc_reordering(<unit>) : integer | |||
fe_id : integer | |||
Returns an integer containing the current frontend's id. It can be used in | |||
- backends to check from which backend it was called, or to stick all users | |||
+ backends to check from which frontend it was called, or to stick all users | |||
coming via a same frontend to the same server. | |||
fe_name : string | |||
-- | |||
2.10.2 | |||
@ -1,58 +0,0 @@ | |||
From 8d570235f18eb7a6c920d674d1a057f35c6740e8 Mon Sep 17 00:00:00 2001 | |||
From: Christopher Faulet <cfaulet@haproxy.com> | |||
Date: Mon, 19 Dec 2016 09:29:06 +0100 | |||
Subject: [PATCH 09/19] BUG/MINOR: Fix the sending function in Lua's cosocket | |||
This is a regression from the commit a73e59b6901a164d19b1145e8511602d9814f28f. | |||
When data are sent from a cosocket, the action is done in the context of the | |||
applet running a lua stack and not in the context of the applet owning the | |||
cosocket. So we must take care, explicitly, that this last applet have a buffer | |||
(the req buffer of the cosocket). | |||
This patch must be backported in 1.7 | |||
(cherry picked from commit 33834b15dce4658ee98fa85668162d78abf32e18) | |||
--- | |||
src/hlua.c | 14 ++++++++------ | |||
1 file changed, 8 insertions(+), 6 deletions(-) | |||
diff --git a/src/hlua.c b/src/hlua.c | |||
index cee2c1b..e82656b 100644 | |||
--- a/src/hlua.c | |||
+++ b/src/hlua.c | |||
@@ -1884,14 +1884,19 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext | |||
* the request buffer if its not required. | |||
*/ | |||
if (socket->s->req.buf->size == 0) { | |||
- si_applet_cant_put(&socket->s->si[0]); | |||
- goto hlua_socket_write_yield_return; | |||
+ appctx = hlua->task->context; | |||
+ if (!channel_alloc_buffer(&socket->s->req, &appctx->buffer_wait)) | |||
+ goto hlua_socket_write_yield_return; | |||
} | |||
/* Check for avalaible space. */ | |||
len = buffer_total_space(socket->s->req.buf); | |||
- if (len <= 0) | |||
+ if (len <= 0) { | |||
+ appctx = objt_appctx(socket->s->si[0].end); | |||
+ if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_write)) | |||
+ WILL_LJMP(luaL_error(L, "out of memory")); | |||
goto hlua_socket_write_yield_return; | |||
+ } | |||
/* send data */ | |||
if (len < send_len) | |||
@@ -1929,9 +1934,6 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext | |||
return 1; | |||
hlua_socket_write_yield_return: | |||
- appctx = objt_appctx(socket->s->si[0].end); | |||
- if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_write)) | |||
- WILL_LJMP(luaL_error(L, "out of memory")); | |||
WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_write_yield, TICK_ETERNITY, 0)); | |||
return 0; | |||
} | |||
-- | |||
2.10.2 | |||
@ -1,44 +0,0 @@ | |||
From 4135292707ef737f8fea8b255f31648bc01e3063 Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <thierry.fournier@ozon.io> | |||
Date: Sat, 17 Dec 2016 11:46:06 +0100 | |||
Subject: [PATCH 10/19] BUG/MINOR: lua: memory leak executing tasks | |||
The struct hlua isn't freed when the task is complete. | |||
This patch should be backported in 1.6 and 1.7 | |||
(cherry picked from commit 4e7c708612730d79f4cc2ec7617fce01665ff807) | |||
--- | |||
src/hlua.c | 3 +++ | |||
1 file changed, 3 insertions(+) | |||
diff --git a/src/hlua.c b/src/hlua.c | |||
index e82656b..cdef8ed 100644 | |||
--- a/src/hlua.c | |||
+++ b/src/hlua.c | |||
@@ -5133,6 +5133,7 @@ static struct task *hlua_process_task(struct task *task) | |||
/* finished or yield */ | |||
case HLUA_E_OK: | |||
hlua_ctx_destroy(hlua); | |||
+ free(hlua); | |||
task_delete(task); | |||
task_free(task); | |||
break; | |||
@@ -5146,6 +5147,7 @@ static struct task *hlua_process_task(struct task *task) | |||
case HLUA_E_ERRMSG: | |||
SEND_ERR(NULL, "Lua task: %s.\n", lua_tostring(hlua->T, -1)); | |||
hlua_ctx_destroy(hlua); | |||
+ free(hlua); | |||
task_delete(task); | |||
task_free(task); | |||
break; | |||
@@ -5154,6 +5156,7 @@ static struct task *hlua_process_task(struct task *task) | |||
default: | |||
SEND_ERR(NULL, "Lua task: unknown error.\n"); | |||
hlua_ctx_destroy(hlua); | |||
+ free(hlua); | |||
task_delete(task); | |||
task_free(task); | |||
break; | |||
-- | |||
2.10.2 | |||
@ -1,31 +0,0 @@ | |||
From 59a34946f1b0076c1f72c8d024b991c7aca41589 Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <thierry.fournier@ozon.io> | |||
Date: Sat, 17 Dec 2016 12:05:56 +0100 | |||
Subject: [PATCH 11/19] BUG/MINOR: lua: bad return code | |||
If the lua/cli fails during initialization, it returns an ok | |||
status, an the execution continue. This will probably occur a | |||
segfault. | |||
Thiw patch should be backported in 1.7 | |||
(cherry picked from commit 33558c4a3f2521bb33fa71ebb312babbf1361c13) | |||
--- | |||
src/hlua.c | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/src/hlua.c b/src/hlua.c | |||
index cdef8ed..45e3164 100644 | |||
--- a/src/hlua.c | |||
+++ b/src/hlua.c | |||
@@ -6453,7 +6453,7 @@ static int hlua_cli_parse_fct(char **args, struct appctx *appctx, void *private) | |||
appctx->ctx.hlua_cli.task = task_new(); | |||
if (!appctx->ctx.hlua_cli.task) { | |||
SEND_ERR(NULL, "Lua cli '%s': out of memory.\n", fcn->name); | |||
- return 0; | |||
+ return 1; | |||
} | |||
appctx->ctx.hlua_cli.task->nice = 0; | |||
appctx->ctx.hlua_cli.task->context = appctx; | |||
-- | |||
2.10.2 | |||
@ -1,38 +0,0 @@ | |||
From 4d0ca6937f682998d16b94da74f463b18056cdea Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Thu, 22 Dec 2016 21:54:21 +0100 | |||
Subject: [PATCH 12/19] BUG/MEDIUM: ssl: properly reset the reused_sess during | |||
a forced handshake | |||
We have a bug when SSL reuse is disabled on the server side : we reset | |||
the context but do not set it to NULL, causing a multiple free of the | |||
same entry. It seems like this bug cannot appear as-is with the current | |||
code (or the conditions to get it are not obvious) but it did definitely | |||
strike when trying to fix another bug with the SNI which forced a new | |||
handshake. | |||
This fix should be backported to 1.7, 1.6 and 1.5. | |||
(cherry picked from commit 30fd4bd8446dd7104b7d1cae9e762c7d1405171a) | |||
--- | |||
src/ssl_sock.c | 4 +++- | |||
1 file changed, 3 insertions(+), 1 deletion(-) | |||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c | |||
index 0a06adb..322488e 100644 | |||
--- a/src/ssl_sock.c | |||
+++ b/src/ssl_sock.c | |||
@@ -3654,8 +3654,10 @@ reneg_ok: | |||
global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr; | |||
/* check if session was reused, if not store current session on server for reuse */ | |||
- if (objt_server(conn->target)->ssl_ctx.reused_sess) | |||
+ if (objt_server(conn->target)->ssl_ctx.reused_sess) { | |||
SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess); | |||
+ objt_server(conn->target)->ssl_ctx.reused_sess = NULL; | |||
+ } | |||
if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE)) | |||
objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx); | |||
-- | |||
2.10.2 | |||
@ -1,51 +0,0 @@ | |||
From 8e24409513ae20000256b0dc649cb83412ffb20e Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Thu, 22 Dec 2016 17:57:46 +0100 | |||
Subject: [PATCH 13/19] BUG/MEDIUM: ssl: avoid double free when releasing | |||
bind_confs | |||
ssl_sock functions don't mark pointers as NULL after freeing them. So | |||
if a "bind" line specifies some SSL settings without the "ssl" keyword, | |||
they will get freed at the end of check_config_validity(), then freed | |||
a second time on exit. Simply mark the pointers as NULL to fix this. | |||
This fix needs to be backported to 1.7 and 1.6. | |||
(cherry picked from commit 94ff03af84ee0c4a2b6cfb92332fcafbcdc48765) | |||
--- | |||
src/cfgparse.c | 7 +++++++ | |||
src/ssl_sock.c | 2 ++ | |||
2 files changed, 9 insertions(+) | |||
diff --git a/src/cfgparse.c b/src/cfgparse.c | |||
index ec8f6a1..63716fa 100644 | |||
--- a/src/cfgparse.c | |||
+++ b/src/cfgparse.c | |||
@@ -9050,6 +9050,13 @@ out_uri_auth_compat: | |||
LIST_DEL(&bind_conf->keys_ref->list); | |||
free(bind_conf->keys_ref); | |||
} | |||
+ bind_conf->keys_ref = NULL; | |||
+ bind_conf->crl_file = NULL; | |||
+ bind_conf->ecdhe = NULL; | |||
+ bind_conf->ciphers = NULL; | |||
+ bind_conf->ca_sign_pass = NULL; | |||
+ bind_conf->ca_sign_file = NULL; | |||
+ bind_conf->ca_file = NULL; | |||
#endif /* USE_OPENSSL */ | |||
} | |||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c | |||
index 322488e..55eaa28 100644 | |||
--- a/src/ssl_sock.c | |||
+++ b/src/ssl_sock.c | |||
@@ -3334,6 +3334,8 @@ ssl_sock_free_ca(struct bind_conf *bind_conf) | |||
EVP_PKEY_free(bind_conf->ca_sign_pkey); | |||
if (bind_conf->ca_sign_cert) | |||
X509_free(bind_conf->ca_sign_cert); | |||
+ bind_conf->ca_sign_pkey = NULL; | |||
+ bind_conf->ca_sign_cert = NULL; | |||
} | |||
/* | |||
-- | |||
2.10.2 | |||
@ -1,30 +0,0 @@ | |||
From 81c04b246e081f33a6aefa45e91a8a4306fb8211 Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <thierry.fournier@ozon.io> | |||
Date: Mon, 19 Dec 2016 16:50:42 +0100 | |||
Subject: [PATCH 14/19] BUG/MINOR: stats: fix be/sessions/current out in typed | |||
stats | |||
"scur" was typed as "limit" (FO_CONFIG) and "config value" (FN_LIMIT). | |||
The real types of "scur" are "metric" (FO_METRIC) and "gauge" | |||
(FN_GAUGE). FO_METRIC and FN_GAUGE are the value 0. | |||
(cherry picked from commit 0ff98a4758a511f573e50175992984dc5a3db050) | |||
--- | |||
src/stats.c | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/src/stats.c b/src/stats.c | |||
index 8ad983d..8eef3e8 100644 | |||
--- a/src/stats.c | |||
+++ b/src/stats.c | |||
@@ -1501,7 +1501,7 @@ int stats_fill_be_stats(struct proxy *px, int flags, struct field *stats, int le | |||
stats[ST_F_MODE] = mkf_str(FO_CONFIG|FS_SERVICE, proxy_mode_str(px->mode)); | |||
stats[ST_F_QCUR] = mkf_u32(0, px->nbpend); | |||
stats[ST_F_QMAX] = mkf_u32(FN_MAX, px->be_counters.nbpend_max); | |||
- stats[ST_F_SCUR] = mkf_u32(FO_CONFIG|FN_LIMIT, px->beconn); | |||
+ stats[ST_F_SCUR] = mkf_u32(0, px->beconn); | |||
stats[ST_F_SMAX] = mkf_u32(FN_MAX, px->be_counters.conn_max); | |||
stats[ST_F_SLIM] = mkf_u32(FO_CONFIG|FN_LIMIT, px->fullconn); | |||
stats[ST_F_STOT] = mkf_u64(FN_COUNTER, px->be_counters.cum_conn); | |||
-- | |||
2.10.2 | |||
@ -1,35 +0,0 @@ | |||
From 2558c178612254dd5d94a425627a5cb4c21aef2f Mon Sep 17 00:00:00 2001 | |||
From: Marcin Deranek <marcin.deranek@booking.com> | |||
Date: Thu, 22 Dec 2016 16:21:08 +0100 | |||
Subject: [PATCH 15/19] BUG/MINOR: backend: nbsrv() should return 0 if backend | |||
is disabled | |||
According to nbsrv() documentation this fetcher should return "an | |||
integer value corresponding to the number of usable servers". | |||
In case backend is disabled none of servers is usable, so I believe | |||
fetcher should return 0. | |||
This patch should be backported to 1.7, 1.6, 1.5. | |||
(cherry picked from commit 57b877147d726a743a038e7101b6d2e6922116c7) | |||
--- | |||
src/backend.c | 4 +++- | |||
1 file changed, 3 insertions(+), 1 deletion(-) | |||
diff --git a/src/backend.c b/src/backend.c | |||
index e0e53ff..6224a69 100644 | |||
--- a/src/backend.c | |||
+++ b/src/backend.c | |||
@@ -1608,7 +1608,9 @@ smp_fetch_nbsrv(const struct arg *args, struct sample *smp, const char *kw, void | |||
smp->data.type = SMP_T_SINT; | |||
px = args->data.prx; | |||
- if (px->srv_act) | |||
+ if (px->state == PR_STSTOPPED) | |||
+ smp->data.u.sint = 0; | |||
+ else if (px->srv_act) | |||
smp->data.u.sint = px->srv_act; | |||
else if (px->lbprm.fbck) | |||
smp->data.u.sint = 1; | |||
-- | |||
2.10.2 | |||
@ -1,66 +0,0 @@ | |||
From 5fbcf1a914507b4c73d83387fdc5e8f612d83558 Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Thu, 22 Dec 2016 21:58:38 +0100 | |||
Subject: [PATCH 16/19] BUG/MEDIUM: ssl: for a handshake when server-side SNI | |||
changes | |||
Calling SSL_set_tlsext_host_name() on the current SSL ctx has no effect | |||
if the session is being resumed because the hostname is already stored | |||
in the session and is not advertised again in subsequent connections. | |||
It's visible when enabling SNI and health checks at the same time because | |||
checks do not send an SNI and regular traffic reuses the same connection, | |||
resulting in no SNI being sent. | |||
The only short-term solution is to reset the reused session when the | |||
SNI changes compared to the previous one. It can make the server-side | |||
performance suffer when SNIs are interleaved but it will work. A better | |||
long-term solution would be to keep a small cache of a few contexts for | |||
a few SNIs. | |||
Now with SSL_set_session(ctx, NULL) it works. This needs to be double- | |||
checked though. The man says that SSL_set_session() frees any previously | |||
existing context. Some people report a bit of breakage when calling | |||
SSL_set_session(NULL) on openssl 1.1.0a (freed session not reusable at | |||
all though it's not an issue for now). | |||
This needs to be backported to 1.7 and 1.6. | |||
(cherry picked from commit 119a4084bf88418bce74d8af686576e371700c20) | |||
--- | |||
src/ssl_sock.c | 15 +++++++++++++++ | |||
1 file changed, 15 insertions(+) | |||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c | |||
index 55eaa28..77fb4b3 100644 | |||
--- a/src/ssl_sock.c | |||
+++ b/src/ssl_sock.c | |||
@@ -4143,12 +4143,27 @@ char *ssl_sock_get_version(struct connection *conn) | |||
return (char *)SSL_get_version(conn->xprt_ctx); | |||
} | |||
+/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL | |||
+ * to disable SNI. | |||
+ */ | |||
void ssl_sock_set_servername(struct connection *conn, const char *hostname) | |||
{ | |||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME | |||
+ char *prev_name; | |||
+ | |||
if (!ssl_sock_is_ssl(conn)) | |||
return; | |||
+ /* 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 | |||
+ * later imagine having a small cache of ssl_ctx to hold a few SNI per | |||
+ * server. | |||
+ */ | |||
+ prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name); | |||
+ if ((!prev_name && hostname) || | |||
+ (prev_name && (!hostname || strcmp(hostname, prev_name) != 0))) | |||
+ SSL_set_session(conn->xprt_ctx, NULL); | |||
+ | |||
SSL_set_tlsext_host_name(conn->xprt_ctx, hostname); | |||
#endif | |||
} | |||
-- | |||
2.10.2 | |||
@ -1,33 +0,0 @@ | |||
From 22e0a2295a96c30c9cd11e3aa5997e9de9083b93 Mon Sep 17 00:00:00 2001 | |||
From: William Lallemand <wlallemand@haproxy.com> | |||
Date: Fri, 23 Dec 2016 15:44:15 +0100 | |||
Subject: [PATCH 17/19] BUG/MINOR: systemd: potential zombie processes | |||
In systemd mode (-Ds), the master haproxy process is waiting for each | |||
child to exit in a specific order. If a process die when it's not his | |||
turn, it will become a zombie process until every processes exit. | |||
The master is now waiting for any process to exit in any order. | |||
This patch should be backported to 1.7, 1.6 and 1.5. | |||
(cherry picked from commit 1e4fc43630eb194f8e8dd98197cf47c7e9912371) | |||
--- | |||
src/haproxy.c | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/src/haproxy.c b/src/haproxy.c | |||
index c31ccb0..b30a351 100644 | |||
--- a/src/haproxy.c | |||
+++ b/src/haproxy.c | |||
@@ -2038,7 +2038,7 @@ int main(int argc, char **argv) | |||
/* it's OK because "-Ds -f x" is the shortest form going here */ | |||
memcpy(argv[0] + strlen(argv[0]), "-master", 8); | |||
for (proc = 0; proc < global.nbproc; proc++) | |||
- while (waitpid(children[proc], NULL, 0) == -1 && errno == EINTR); | |||
+ while (waitpid(-1, NULL, 0) == -1 && errno == EINTR); | |||
} | |||
exit(0); /* parent must leave */ | |||
} | |||
-- | |||
2.10.2 | |||
@ -1,45 +0,0 @@ | |||
From 4a87848534d3950b415619554ef4938396f45f58 Mon Sep 17 00:00:00 2001 | |||
From: Guillaume de Lafond <gdelafond@aquaray.com> | |||
Date: Fri, 23 Dec 2016 17:32:43 +0100 | |||
Subject: [PATCH 18/19] DOC: Add timings events schemas | |||
[wt: this could be backported to 1.7] | |||
(cherry picked from commit f27cddcf7d42cad6e1972b5075da348192ee4105) | |||
--- | |||
doc/configuration.txt | 20 ++++++++++++++++++++ | |||
1 file changed, 20 insertions(+) | |||
diff --git a/doc/configuration.txt b/doc/configuration.txt | |||
index 6596578..e5e6282 100644 | |||
--- a/doc/configuration.txt | |||
+++ b/doc/configuration.txt | |||
@@ -15491,6 +15491,26 @@ frontend, 3 control points are reported under the form "Tw/Tc/Tt", and in HTTP | |||
mode, 5 control points are reported under the form "TR/Tw/Tc/Tr/Ta". In | |||
addition, three other measures are provided, "Th", "Ti", and "Tq". | |||
+Timings events in HTTP mode: | |||
+ | |||
+ first request 2nd request | |||
+ |<-------------------------------->|<-------------- ... | |||
+ t tr t tr ... | |||
+ ---|----|----|----|----|----|----|----|----|-- | |||
+ : Th Ti TR Tw Tc Tr Td : Ti ... | |||
+ :<---- Tq ---->: : | |||
+ :<-------------- Tt -------------->: | |||
+ :<--------- Ta --------->: | |||
+ | |||
+Timings events in TCP mode: | |||
+ | |||
+ TCP session | |||
+ |<----------------->| | |||
+ t t | |||
+ ---|----|----|----|----|--- | |||
+ | Th Tw Tc Td | | |||
+ |<------ Tt ------->| | |||
+ | |||
- Th: total time to accept tcp connection and execute handshakes for low level | |||
protocols. Currently, these protocoles are proxy-protocol and SSL. This may | |||
only happen once during the whole connection's lifetime. A large time here | |||
-- | |||
2.10.2 | |||
@ -1,48 +0,0 @@ | |||
From 5a566e3d01273de38490527fbd378c9a2f671b2c Mon Sep 17 00:00:00 2001 | |||
From: Thierry FOURNIER <thierry.fournier@ozon.io> | |||
Date: Fri, 23 Dec 2016 17:03:25 +0100 | |||
Subject: [PATCH 19/19] BUILD: lua: build failed on FreeBSD. | |||
s6_addr* fields are not available in the userland on | |||
BSD systems in general. | |||
bug reported by David Carlier | |||
needs backport to 1.7.x | |||
(cherry picked from commit de6925eccfaba85f1402c5e5cf700c420792802a) | |||
--- | |||
src/hlua_fcn.c | 18 ++++++++++-------- | |||
1 file changed, 10 insertions(+), 8 deletions(-) | |||
diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c | |||
index 5ac533a..58905d7 100644 | |||
--- a/src/hlua_fcn.c | |||
+++ b/src/hlua_fcn.c | |||
@@ -1016,14 +1016,16 @@ int hlua_match_addr(lua_State *L) | |||
return 1; | |||
} | |||
} else { | |||
- if (((addr1->addr.v6.ip.s6_addr32[0] & addr2->addr.v6.mask.s6_addr32[0]) == | |||
- (addr2->addr.v6.ip.s6_addr32[0] & addr1->addr.v6.mask.s6_addr32[0])) && | |||
- ((addr1->addr.v6.ip.s6_addr32[1] & addr2->addr.v6.mask.s6_addr32[1]) == | |||
- (addr2->addr.v6.ip.s6_addr32[1] & addr1->addr.v6.mask.s6_addr32[1])) && | |||
- ((addr1->addr.v6.ip.s6_addr32[2] & addr2->addr.v6.mask.s6_addr32[2]) == | |||
- (addr2->addr.v6.ip.s6_addr32[2] & addr1->addr.v6.mask.s6_addr32[2])) && | |||
- ((addr1->addr.v6.ip.s6_addr32[3] & addr2->addr.v6.mask.s6_addr32[3]) == | |||
- (addr2->addr.v6.ip.s6_addr32[3] & addr1->addr.v6.mask.s6_addr32[3]))) { | |||
+ int i; | |||
+ | |||
+ for (i = 0; i < 16; i += 4) { | |||
+ if ((*(uint32_t *)&addr1->addr.v6.ip.s6_addr[i] & | |||
+ *(uint32_t *)&addr2->addr.v6.mask.s6_addr[i]) != | |||
+ (*(uint32_t *)&addr2->addr.v6.ip.s6_addr[i] & | |||
+ *(uint32_t *)&addr1->addr.v6.mask.s6_addr[i])) | |||
+ break; | |||
+ } | |||
+ if (i == 16) { | |||
lua_pushboolean(L, 1); | |||
return 1; | |||
} | |||
-- | |||
2.10.2 | |||