Re: Wrong http_err_rate on standby peer

2016-07-20 Thread Frederic Lecaille

Hi Kay,

On 07/20/2016 11:27 AM, Willy Tarreau wrote:

Hi Kay,

On Wed, Jul 20, 2016 at 11:17:57AM +0200, Kay Fuchs wrote:

Hi!

2016-07-19 11:26 GMT+02:00 Kay Fuchs :

i'm using a stick-table with HAProxy 1.6.7 on an active/standby
configuration like this:

 stick-table type ipv6 size 500k expire 60s peers hacluster store
gpc0,conn_cur,http_req_rate(10s),http_err_rate(10s)
 http-request track-sc0

On the standby peer the table obviously shows wrong http_err_rates:

 0xe6ce10: key=xxx use=0 exp=59598 gpc0=0 conn_cur=1
http_req_rate(1)=1 http_err_rate(1)=346
 0xe3ed80: key=xxx use=0 exp=58440 gpc0=0 conn_cur=1
http_req_rate(1)=27 http_err_rate(1)=38841809

The active peer seems to behave as expected and shows very low error rates.

I'm no programmer, but i think it has to do with "frqp->curr_tick" in
"peers.c" which seems to have the value "0" if the very first error
appears. This leads to sending "now_ms" to the peer. If i check
"frqp->curr_tick" before the encoding like

 if (frqp->curr_tick == 0)
   frqp->curr_tick = now_ms;

the error rates seems reasonable on the standby peer.


I think either the function "intencode" or "intdecode" in "peers.c"
seems not to return the expected values. I've made a simple loop to
compare the input for "intencode" with the outputs of "intdecode" for
the encoded message. The first wrong encoded/decoded range of integers
are 4336-4351.


I confirm that 4336-4351 is the first range impacted by the bug I found 
yesterday in intdecode().


Here are the encoded values for this range:

4336  --> enc. value: 0xf08001
4337  --> enc. value: 0xf18001
4338  --> enc. value: 0xf28001
4339  --> enc. value: 0xf38001
4340  --> enc. value: 0xf48001
4341  --> enc. value: 0xf58001
4342  --> enc. value: 0xf68001
4343  --> enc. value: 0xf78001
4344  --> enc. value: 0xf88001
4345  --> enc. value: 0xf98001
4346  --> enc. value: 0xfa8001
4347  --> enc. value: 0xfb8001
4348  --> enc. value: 0xfc8001
4349  --> enc. value: 0xfd8001
4350  --> enc. value: 0xfe8001
4351  --> enc. value: 0xff8001

indecode() stops decoding as soon as it finds a byte less than or equal 
to 0x80 (128), from high to low byte.


Each impacted range decoded value is 0x8f0-0x8ff (2288-2303).



That might explain
http://thread.gmane.org/gmane.comp.web.haproxy/27168 in combination
with the sending of large integer "now_ms" reported above.


Very interesting. Yesterday Fred (in CC) found a bug there and we concluded
that it could explain such random issues that we were not able to reproduce
(possibly because we didn't face the exact faulty value). I think we'll have
a patch shortly for this.

Thanks for your feedback,
Willy






BUG/MINOR: peers: Fix a peer stick-tables synchronization issue.

2016-10-12 Thread Frederic Lecaille

Everything is in the attached patch file.

Please note that this patch has already been reviewed by Emeric Brun who 
is the peers protocol maintener.


Regards.

Fred.
>From d1e7b23187db580fe2445e80ff1abefecfcf2241 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Wed, 12 Oct 2016 17:30:30 +0200
Subject: [PATCH] BUG/MINOR: peers: Fix a peer stick-tables synchronization
 issue.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

During the stick-table teaching process which occurs at reloading/restart time,
expiration dates of stick-tables entries were not synchronized between peers.

This patch adds two new stick-table messages to provide such a synchronization feature.

As these new messages are not supported by older haproxy peers protocol versions,
this patch increments peers protol version, from 2.0 to 2.1, to help in detecting/supporting
such older peers protocol implementations so that new versions might still be able
to transparently communicate with a newer one.
---
 include/proto/stick_table.h |   4 ++
 src/peers.c | 136 +---
 src/stick_table.c   |  30 +-
 3 files changed, 149 insertions(+), 21 deletions(-)

diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h
index 8c97f73..941e2ff 100644
--- a/include/proto/stick_table.h
+++ b/include/proto/stick_table.h
@@ -42,6 +42,10 @@ int stktable_init(struct stktable *t);
 int stktable_parse_type(char **args, int *idx, unsigned long *type, size_t *key_size);
 struct stksess *stktable_get_entry(struct stktable *table, struct stktable_key *key);
 struct stksess *stktable_store(struct stktable *t, struct stksess *ts, int local);
+struct stksess *stktable_store_with_exp(struct stktable *t, struct stksess *ts,
+int local, int expire);
+struct stksess *stktable_touch_with_exp(struct stktable *t, struct stksess *ts,
+int local, int expire);
 struct stksess *stktable_touch(struct stktable *t, struct stksess *ts, int local);
 struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts);
 struct stksess *stktable_lookup_key(struct stktable *t, struct stktable_key *key);
diff --git a/src/peers.c b/src/peers.c
index 6f88c19..d11792f 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -80,6 +81,7 @@
 #define	PEER_F_TEACH_COMPLETE		0x0010 /* All that we know already taught to current peer, used only for a local peer */
 #define	PEER_F_LEARN_ASSIGN		0x0100 /* Current peer was assigned for a lesson */
 #define	PEER_F_LEARN_NOTUP2DATE		0x0200 /* Learn from peer finished but peer is not up to date */
+#define	PEER_F_DWNGRD		0x8000 /* When this flag is enabled, we must downgrade the supported version announced during peer sessions. */
 
 #define	PEER_TEACH_RESET		~(PEER_F_TEACH_PROCESS|PEER_F_TEACH_FINISHED) /* PEER_F_TEACH_COMPLETE should never be reset */
 #define	PEER_LEARN_RESET		~(PEER_F_LEARN_ASSIGN|PEER_F_LEARN_NOTUP2DATE)
@@ -124,6 +126,8 @@ enum {
 	PEER_MSG_STKT_DEFINE,
 	PEER_MSG_STKT_SWITCH,
 	PEER_MSG_STKT_ACK,
+	PEER_MSG_STKT_UPDATE_TIMED,
+	PEER_MSG_STKT_INCUPDATE_TIMED,
 };
 
 /**/
@@ -163,6 +167,9 @@ enum {
 #define	PEER_SESS_SC_ERRPEER		504 /* unknown peer */
 
 #define PEER_SESSION_PROTO_NAME "HAProxyS"
+#define PEER_MAJOR_VER2
+#define PEER_MINOR_VER1
+#define PEER_DWNGRD_MINOR_VER 0
 
 struct peers *peers = NULL;
 static void peer_session_forceshutdown(struct stream * stream);
@@ -230,6 +237,26 @@ uint64_t intdecode(char **str, char *end) {
 	return i;
 }
 
+/* Set the stick-table UPDATE message type byte at  address,
+ * depending on  and  boolean parameters.
+ * Always successful.
+ */
+static inline void peer_set_update_msg_type(char *msg_type, int use_identifier, int use_timed)
+{
+	if (use_timed) {
+		if (use_identifier)
+			*msg_type = PEER_MSG_STKT_UPDATE_TIMED;
+		else
+			*msg_type = PEER_MSG_STKT_INCUPDATE_TIMED;
+	}
+	else {
+		if (use_identifier)
+			*msg_type = PEER_MSG_STKT_UPDATE;
+		else
+			*msg_type = PEER_MSG_STKT_INCUPDATE;
+	}
+
+}
 /*
  * This prepare the data update message on the stick session ,  is the considered
  * stick table.
@@ -237,7 +264,7 @@ uint64_t intdecode(char **str, char *end) {
  * If function returns 0, the caller should consider we were unable to encode this message (TODO:
  * check size)
  */
-static int peer_prepare_updatemsg(struct stksess *ts, struct shared_table *st, char *msg, size_t size, int use_identifier)
+static int peer_prepare_updatemsg(struct stksess *ts, struct shared_table *st, char *msg, size_t size, int use_identifier, int use_timed)
 {
 	uint32_t netinteger;
 	unsigned short datalen;
@@ -261,6 +288,12 @@ static int peer_prepare_updatemsg(struct stksess *ts, struct shared_table *st, c

Re: All "server" settings supported on "default-server" lines

2017-03-23 Thread Frederic Lecaille

On 03/21/2017 07:54 PM, Frederic Lecaille wrote:

Hello HAProxy ML,

I am starting this new thread to publish a serie of patches to make
all "server" settings be supported on "default-server" lines.

This is a preliminary work for "server templates" feature.

New boolean settings have been added to disable others. Most of them
have "no-" as prefix.


[snipped]


So, from now on, all server "settings" are supported by "default-server"
except "id" which is only supported on "server" lines.


Before all theses patches, if an unknown "foo" keyword was provided on 
"default-server" or "server" lines, such error messages were displayed:


[ALERT] 081/110011 (11626) : parsing [haproxy.cfg:97] : 'server srv1' 
unknown keyword 'foo'. Registered keywords :

[ ALL] id 
[ TCP] tcp-ut 
[ SSL] ca-file 
.
.
etc.

[ALERT] 081/110011 (11626) : Error(s) found in configuration file : 
haproxy.cfg

[ALERT] 081/110011 (11626) : Fatal errors found in configuration.

Only registered by srv_register_keywords() in 'srv_kwst list keywords 
were displayed.


Most of this thread patches register new keywords in this lists.

So now, the new error messages are:

[ALERT] 081/111458 (12190) : parsing [haproxy.cfg:97] : 'server srv1' 
unknown keyword 'foo'. Registered keywords :

[ SSL] ca-file  [dflt_ok]
[ SSL] check-ssl [dflt_ok]
[ SSL] ciphers  [dflt_ok]
[ SSL] crl-file  [dflt_ok]
[ SSL] crt  [dflt_ok]
[ SSL] force-sslv3 [dflt_ok]
[ SSL] force-tlsv10 [dflt_ok]
.
.
[snipped]
.
[ ALL] id 
[ ALL] namespace  [dflt_ok]
[ ALL] no-agent-check [dflt_ok]
[ ALL] no-backup [dflt_ok]

From my point of view, this is not acceptable to flag all these 
settings as supported on "default-server" lines.


At this time, as "id" remains as unique setting supported by "server", 
the patch attached to this mail now produces these error messages:


[ALERT] 081/111458 (12190) : parsing [haproxy.cfg:97] : 'server srv1' 
unknown keyword 'foo'. Registered keywords :

[ SSL] ca-file 
[ SSL] check-ssl
[ SSL] ciphers 
[ SSL] crl-file 
[ SSL] crt 
[ SSL] force-sslv3
[ SSL] force-tlsv10
.
.
[snipped]
.
[ ALL] id  [server_only]
[ ALL] namespace 
[ ALL] no-agent-check
[ ALL] no-backup [dflt_ok]


It does not make sens to backport this patch. It is only supposed to be
used to fix the boring error messages this thread patches introduced.


>From 94f81538cc6b9f042800b47bb57cc5e1e4a9ee24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Thu, 23 Mar 2017 11:39:10 +0100
Subject: [PATCH] MINOR: server: Display only server keywords which are only
 supported on "server" lines.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.01, version=1.2.4

When displaying error messages when parsing unknown "server" keywords,
in place of flagging keywords which are also supported on "default-server" lines,,
and as in the future almost all "server" setting will be supported by "default-server",
this patch make the error message handlers flag only keywords which are only
supported on server lines.

Does not make sense to be backported.
---
 src/server.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/server.c b/src/server.c
index 5589723..1b02ee5 100644
--- a/src/server.c
+++ b/src/server.c
@@ -206,7 +206,7 @@ void srv_dump_kws(char **out)
   kwl->scope,
   kwl->kw[index].kw,
   kwl->kw[index].skip ? " " : "",
-  kwl->kw[index].default_ok ? " [dflt_ok]" : "",
+  kwl->kw[index].default_ok ? "" : " [server_only]",
   kwl->kw[index].parse ? "" : " (not supported)");
 			}
 		}
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-23 Thread Frederic Lecaille

On 03/23/2017 12:03 PM, Frederic Lecaille wrote:

On 03/21/2017 07:54 PM, Frederic Lecaille wrote:


[snipped]


At this time, as "id" remains as unique setting supported by "server",
the patch attached to this mail now produces these error messages:

[ALERT] 081/111458 (12190) : parsing [haproxy.cfg:97] : 'server srv1'
unknown keyword 'foo'. Registered keywords :
[ SSL] ca-file 
[ SSL] check-ssl
[ SSL] ciphers 
[ SSL] crl-file 
[ SSL] crt 
[ SSL] force-sslv3
[ SSL] force-tlsv10
.
.
[snipped]
.
[ ALL] id  [server_only]
[ ALL] namespace 
[ ALL] no-agent-check
[ ALL] no-backup [dflt_ok]


ooop! wrong copy and paste... well remove this previous line...




Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 39d6ba95c1c1cf2b33d916c15c40f8d6f223e60b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 13 Mar 2017 13:41:16 +0100
Subject: [PATCH 14/31] MINOR: server: Make 'default-server' support 'verify'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directive support 'verify' keyword.
---
 src/server.c   | 4 
 src/ssl_sock.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/server.c b/src/server.c
index ddb2842..b69d1d1 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1295,6 +1295,10 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			newsrv->dns_opts.pref_net_nb = curproxy->defsrv.dns_opts.pref_net_nb;
 			newsrv->init_addr_methods = curproxy->defsrv.init_addr_methods;
 			newsrv->init_addr = curproxy->defsrv.init_addr;
+#if defined(USE_OPENSSL)
+			/* SSL config. */
+			newsrv->ssl_ctx.verify = curproxy->defsrv.ssl_ctx.verify;
+#endif
 
 			cur_arg = 3;
 		} else {
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 802f0a0..5285e24 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -7517,7 +7517,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
 	{ "tlsv11",  srv_parse_tlsv11,0, 1 }, /* enable TLSv11 */
 	{ "tlsv12",  srv_parse_tlsv12,0, 1 }, /* enable TLSv12 */
 	{ "tls-tickets", srv_parse_tls_tickets,   0, 1 }, /* enable session resumption tickets */
-	{ "verify",  srv_parse_verify,1, 0 }, /* set SSL verify method */
+	{ "verify",  srv_parse_verify,1, 1 }, /* set SSL verify method */
 	{ "verifyhost",  srv_parse_verifyhost,1, 0 }, /* require that SSL cert verifies for hostname */
 	{ NULL, NULL, 0, 0 },
 }};
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 984c811ffcf50df6e400ff7e4f774d96e401924a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 13 Mar 2017 13:10:59 +0100
Subject: [PATCH 13/31] CLEANUP: server: code alignement.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

Code alignement again.
---
 src/ssl_sock.c | 66 +-
 1 file changed, 33 insertions(+), 33 deletions(-)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 41b967e..802f0a0 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -7484,41 +7484,41 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
  * not enabled.
  */
 static struct srv_kw_list srv_kws = { "SSL", { }, {
-	{ "ca-file",   srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
-	{ "check-ssl", srv_parse_check_ssl,   0, 1 }, /* enable SSL for health checks */
-	{ "ciphers",   srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
-	{ "crl-file",  srv_parse_crl_file,1, 0 }, /* set certificate revocation list file use on server cert verify */
-	{ "crt",   srv_parse_crt, 1, 0 }, /* set client certificate */
-	{ "force-sslv3",   srv_parse_force_sslv3, 0, 1 }, /* force SSLv3 */
-	{ "force-tlsv10",  srv_parse_force_tlsv10,0, 1 }, /* force TLSv10 */
-	{ "force-tlsv11",  srv_parse_force_tlsv11,0, 1 }, /* force TLSv11 */
-	{ "force-tlsv12",  srv_parse_force_tlsv12,0, 1 }, /* force TLSv12 */
-	{ "no-check-ssl",  srv_parse_no_check_ssl,0, 1 }, /* disable SSL for health checks */
-	{ "no-force-sslv3",srv_parse_no_force_sslv3,  0, 1 }, /* do not force SSLv3 */
-	{ "no-force-tlsv10",   srv_parse_no_force_tlsv10, 0, 1 }, /* do not force TLSv10 */
-	{ "no-force-tlsv11",   srv_parse_no_force_tlsv11, 0, 1 }, /* do not force TLSv11 */
-	{ "no-force-tlsv12",   srv_parse_no_force_tlsv12, 0, 1 }, /* do not force TLSv12 */
+	{ "ca-file", srv_parse_ca_file,   1, 0 }, /* set CAfile to process verify server cert */
+	{ "check-ssl",   srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
+	{ "ciphers", srv_parse_ciphers,   1, 0 }, /* select the cipher suite */
+	{ "crl-file",srv_parse_crl_file,  1, 0 }, /* set certificate revocation list file use on server cert verify */
+	{ "crt", srv_parse_crt,   1, 0 }, /* set client certificate */
+	{ "force-sslv3", srv_parse_force_sslv3,   0, 1 }, /* force SSLv3 */
+	{ "force-tlsv10",srv_parse_force_tlsv10,  0, 1 }, /* force TLSv10 */
+	{ "force-tlsv11",srv_parse_force_tlsv11,  0, 1 }, /* force TLSv11 */
+	{ "force-tlsv12",srv_parse_force_tlsv12,  0, 1 }, /* force TLSv12 */
+	{ "no-check-ssl",srv_parse_no_check_ssl,  0, 1 }, /* disable SSL for health checks */
+	{ "no-force-sslv3",  srv_parse_no_force_sslv3,0, 1 }, /* do not force SSLv3 */
+	{ "no-force-tlsv10", srv_parse_no_force_tlsv10,   0, 1 }, /* do not force TLSv10 */
+	{ "no-force-tlsv11", srv_parse_no_force_tlsv11,   0, 1 }, /* do not force TLSv11 */
+	{ "no-force-tlsv12", srv_parse_no_force_tlsv12,   0, 1 }, /* do not force TLSv12 */
 	{ "no-send-proxy-v2-ssl",srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
 	{ "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn,  0, 1 }, /* do not send PROXY protocol header v2 with CN */
-	{ "no-ssl",srv_parse_no_ssl,  0, 1 }, /* disable SSL processing */
-	{ "no-ssl-reuse",  srv_parse_no_ssl_reuse,0, 1 }, /* disable session reuse */
-	{ "no-sslv3",  srv_parse_no_sslv3,0, 1 }, /* disable SSLv3 */
-	{ "no-tlsv10", srv_parse_no_tlsv10,   0, 1 }, /* disable TLSv10 */
-	{ "no-tlsv11", srv_parse_no_tlsv11,   0, 1 }, /* disable TLSv11 */
-	{ "no-tlsv12", srv_parse_no_tlsv12,   0, 1 }, /* disable TLSv12 */
-	{ "no-tls-tickets",srv_parse_no_tls_tickets,  0, 1 }, /* disable session resumption tickets */
-	{ "send-proxy-v2-ssl", srv_parse_send_proxy_ssl,  0, 1 }, /* send PROXY protocol header v2 with SSL info */
-	{ "send-proxy-v2-ssl-cn",  srv_parse_send_proxy_cn,   0, 1 }, /* send PROXY protocol header v2 with CN */
-	{ "sni",   srv_parse_sni, 1, 0 }, /* send SNI extension */
-	{ "ssl",   srv_parse_ssl, 0, 1 }, /* enable SSL processing */
-	{ "ssl-reuse", srv_parse_ssl_reuse,   0, 1 }, /* enable session reuse */
-	{ "sslv3", srv_parse_sslv3,   0, 1 }, /* enable SSLv3 */
-	{ "tlsv10",srv_parse_tlsv10,  0, 1 }, /* enable TLSv10 */
-	{ "tlsv11",   

Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 70b9d6c0246b1c3e28ded68f1617497aed1dd2d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 13 Mar 2017 12:08:01 +0100
Subject: [PATCH 12/31] MINOR: server: Make 'default-server' support
 'send-proxy-v2-ssl*' keywords.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directive support 'send-proxy-v2-ssl'
(resp. 'send-proxy-v2-ssl-cn') setting.
A new keyword 'no-send-proxy-v2-ssl' (resp. 'no-send-proxy-v2-ssl-cn') has been
added to disable 'send-proxy-v2-ssl' (resp. 'send-proxy-v2-ssl-cn') setting both
in 'server' and 'default-server' directives.
---
 src/ssl_sock.c | 23 +--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 3d1e444..41b967e 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -6588,6 +6588,23 @@ static int srv_parse_no_force_tlsv12(char **args, int *cur_arg, struct proxy *px
 #endif
 }
 
+/* parse the "no-send-proxy-v2-ssl" server keyword */
+static int srv_parse_no_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+	newsrv->pp_opts &= ~SRV_PP_V2;
+	newsrv->pp_opts &= ~SRV_PP_V2_SSL;
+	return 0;
+}
+
+/* parse the "no-send-proxy-v2-ssl-cn" server keyword */
+static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+	newsrv->pp_opts &= ~SRV_PP_V2;
+	newsrv->pp_opts &= ~SRV_PP_V2_SSL;
+	newsrv->pp_opts &= ~SRV_PP_V2_SSL_CN;
+	return 0;
+}
+
 /* parse the "no-ssl" server keyword */
 static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
 {
@@ -7481,6 +7498,8 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
 	{ "no-force-tlsv10",   srv_parse_no_force_tlsv10, 0, 1 }, /* do not force TLSv10 */
 	{ "no-force-tlsv11",   srv_parse_no_force_tlsv11, 0, 1 }, /* do not force TLSv11 */
 	{ "no-force-tlsv12",   srv_parse_no_force_tlsv12, 0, 1 }, /* do not force TLSv12 */
+	{ "no-send-proxy-v2-ssl",srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
+	{ "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn,  0, 1 }, /* do not send PROXY protocol header v2 with CN */
 	{ "no-ssl",srv_parse_no_ssl,  0, 1 }, /* disable SSL processing */
 	{ "no-ssl-reuse",  srv_parse_no_ssl_reuse,0, 1 }, /* disable session reuse */
 	{ "no-sslv3",  srv_parse_no_sslv3,0, 1 }, /* disable SSLv3 */
@@ -7488,8 +7507,8 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
 	{ "no-tlsv11", srv_parse_no_tlsv11,   0, 1 }, /* disable TLSv11 */
 	{ "no-tlsv12", srv_parse_no_tlsv12,   0, 1 }, /* disable TLSv12 */
 	{ "no-tls-tickets",srv_parse_no_tls_tickets,  0, 1 }, /* disable session resumption tickets */
-	{ "send-proxy-v2-ssl", srv_parse_send_proxy_ssl,  0, 0 }, /* send PROXY protocol header v2 with SSL info */
-	{ "send-proxy-v2-ssl-cn",  srv_parse_send_proxy_cn,   0, 0 }, /* send PROXY protocol header v2 with CN */
+	{ "send-proxy-v2-ssl", srv_parse_send_proxy_ssl,  0, 1 }, /* send PROXY protocol header v2 with SSL info */
+	{ "send-proxy-v2-ssl-cn",  srv_parse_send_proxy_cn,   0, 1 }, /* send PROXY protocol header v2 with CN */
 	{ "sni",   srv_parse_sni, 1, 0 }, /* send SNI extension */
 	{ "ssl",   srv_parse_ssl, 0, 1 }, /* enable SSL processing */
 	{ "ssl-reuse", srv_parse_ssl_reuse,   0, 1 }, /* enable session reuse */
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 83766d4697f3af4626506a6af8b186028b565fe8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Fri, 10 Mar 2017 15:50:49 +0100
Subject: [PATCH 05/31] MINOR: server: Make 'default-server' support
 'non-stick' keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directive support 'non-stick' setting.
A new keyword 'stick' has been added so that to disable
'non-stick' setting both in 'server' and 'default-server' directives.
---
 src/server.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/src/server.c b/src/server.c
index 09f196b..c5a4d31 100644
--- a/src/server.c
+++ b/src/server.c
@@ -277,6 +277,22 @@ static int srv_parse_no_check_send_proxy(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Parse the "non-stick" server keyword */
+static int srv_parse_non_stick(char **args, int *cur_arg,
+   struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	newsrv->flags |= SRV_F_NON_STICK;
+	return 0;
+}
+
+/* Parse the "stick" server keyword */
+static int srv_parse_stick(char **args, int *cur_arg,
+   struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	newsrv->flags &= ~SRV_F_NON_STICK;
+	return 0;
+}
+
 /* Shutdown all connections of a server. The caller must pass a termination
  * code in , which must be one of SF_ERR_* indicating the reason for the
  * shutdown.
@@ -891,6 +907,8 @@ static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "id",  srv_parse_id,  1,  0 }, /* set id# of server */
 	{ "no-backup",   srv_parse_no_backup,   0,  1 }, /* Flag as non-backup server */
 	{ "no-check-send-proxy", srv_parse_no_check_send_proxy, 0,  1 }, /* disable PROXY protol for health checks */
+	{ "non-stick",   srv_parse_non_stick,   0,  1 }, /* Disable stick-table persistence */
+	{ "stick",   srv_parse_stick,   0,  1 }, /* Enable stick-table persistence */
 	{ NULL, NULL, 0 },
 }};
 
@@ -1542,10 +1560,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->flags |= SRV_F_CHECKPORT;
 cur_arg += 2;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "non-stick")) {
-newsrv->flags |= SRV_F_NON_STICK;
-cur_arg ++;
-			}
 			else if (!defsrv && !strcmp(args[cur_arg], "send-proxy")) {
 newsrv->pp_opts |= SRV_PP_V1;
 cur_arg ++;
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From c39ce3eba31d37c2e790426c8127d131d6ec9072 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Fri, 10 Mar 2017 15:36:14 +0100
Subject: [PATCH 04/31] CLEANUP: server: code alignement.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.010097, version=1.2.4

Code alignement.
---
 src/server.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/server.c b/src/server.c
index 796ff51..09f196b 100644
--- a/src/server.c
+++ b/src/server.c
@@ -886,10 +886,10 @@ void srv_compute_all_admin_states(struct proxy *px)
  * not enabled.
  */
 static struct srv_kw_list srv_kws = { "ALL", { }, {
-	{ "backup",   srv_parse_backup,   0,  1 }, /* Flag as backup server */
+	{ "backup",  srv_parse_backup,  0,  1 }, /* Flag as backup server */
 	{ "check-send-proxy",srv_parse_check_send_proxy,0,  1 }, /* enable PROXY protocol for health checks */
-	{ "id",   srv_parse_id,   1,  0 }, /* set id# of server */
-	{ "no-backup",srv_parse_no_backup,0,  1 }, /* Flag as non-backup server */
+	{ "id",  srv_parse_id,  1,  0 }, /* set id# of server */
+	{ "no-backup",   srv_parse_no_backup,   0,  1 }, /* Flag as non-backup server */
 	{ "no-check-send-proxy", srv_parse_no_check_send_proxy, 0,  1 }, /* disable PROXY protol for health checks */
 	{ NULL, NULL, 0 },
 }};
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From bed0db831d2cd504f3d66df21fd53c92dc4be52a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 13 Mar 2017 11:02:01 +0100
Subject: [PATCH 09/31] CLEANUP: server: code alignement.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

Code alignement.
---
 src/ssl_sock.c | 44 ++--
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 925d0a5..2e7ae4b 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -7416,32 +7416,32 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
  * not enabled.
  */
 static struct srv_kw_list srv_kws = { "SSL", { }, {
-	{ "ca-file",   srv_parse_ca_file,1, 0 }, /* set CAfile to process verify server cert */
-	{ "check-ssl", srv_parse_check_ssl,  0, 1 }, /* enable SSL for health checks */
-	{ "ciphers",   srv_parse_ciphers,1, 0 }, /* select the cipher suite */
-	{ "crl-file",  srv_parse_crl_file,   1, 0 }, /* set certificate revocation list file use on server cert verify */
-	{ "crt",   srv_parse_crt,1, 0 }, /* set client certificate */
-	{ "force-sslv3",   srv_parse_force_sslv3,0, 1 }, /* force SSLv3 */
-	{ "force-tlsv10",  srv_parse_force_tlsv10,   0, 1 }, /* force TLSv10 */
-	{ "force-tlsv11",  srv_parse_force_tlsv11,   0, 1 }, /* force TLSv11 */
-	{ "force-tlsv12",  srv_parse_force_tlsv12,   0, 1 }, /* force TLSv12 */
-	{ "no-check-ssl",  srv_parse_no_check_ssl,   0, 1 }, /* disable SSL for health checks */
+	{ "ca-file",   srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
+	{ "check-ssl", srv_parse_check_ssl,   0, 1 }, /* enable SSL for health checks */
+	{ "ciphers",   srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
+	{ "crl-file",  srv_parse_crl_file,1, 0 }, /* set certificate revocation list file use on server cert verify */
+	{ "crt",   srv_parse_crt, 1, 0 }, /* set client certificate */
+	{ "force-sslv3",   srv_parse_force_sslv3, 0, 1 }, /* force SSLv3 */
+	{ "force-tlsv10",  srv_parse_force_tlsv10,0, 1 }, /* force TLSv10 */
+	{ "force-tlsv11",  srv_parse_force_tlsv11,0, 1 }, /* force TLSv11 */
+	{ "force-tlsv12",  srv_parse_force_tlsv12,0, 1 }, /* force TLSv12 */
+	{ "no-check-ssl",  srv_parse_no_check_ssl,0, 1 }, /* disable SSL for health checks */
 	{ "no-force-sslv3",srv_parse_no_force_sslv3,  0, 1 }, /* do not force SSLv3 */
 	{ "no-force-tlsv10",   srv_parse_no_force_tlsv10, 0, 1 }, /* do not force TLSv10 */
 	{ "no-force-tlsv11",   srv_parse_no_force_tlsv11, 0, 1 }, /* do not force TLSv11 */
 	{ "no-force-tlsv12",   srv_parse_no_force_tlsv12, 0, 1 }, /* do not force TLSv12 */
-	{ "no-ssl-reuse",  srv_parse_no_ssl_reuse,   0, 0 }, /* disable session reuse */
-	{ "no-sslv3",  srv_parse_no_sslv3,   0, 0 }, /* disable SSLv3 */
-	{ "no-tlsv10", srv_parse_no_tlsv10,  0, 0 }, /* disable TLSv10 */
-	{ "no-tlsv11", srv_parse_no_tlsv11,  0, 0 }, /* disable TLSv11 */
-	{ "no-tlsv12", srv_parse_no_tlsv12,  0, 0 }, /* disable TLSv12 */
-	{ "no-tls-tickets",srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
-	{ "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
-	{ "send-proxy-v2-ssl-cn",  srv_parse_send_proxy_cn,  0, 0 }, /* send PROXY protocol header v2 with CN */
-	{ "sni",   srv_parse_sni,1, 0 }, /* send SNI extension */
-	{ "ssl",   srv_parse_ssl,0, 0 }, /* enable SSL processing */
-	{ "verify",srv_parse_verify, 1, 0 }, /* set SSL verify method */
-	{ "verifyhost",srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
+	{ "no-ssl-reuse",  srv_parse_no_ssl_reuse,0, 0 }, /* disable session reuse */
+	{ "no-sslv3",  srv_parse_no_sslv3,0, 0 }, /* disable SSLv3 */
+	{ "no-tlsv10", srv_parse_no_tlsv10,   0, 0 }, /* disable TLSv10 */
+	{ "no-tlsv11", srv_parse_no_tlsv11,   0, 0 }, /* disable TLSv11 */
+	{ "no-tlsv12", srv_parse_no_tlsv12,   0, 0 }, /* disable TLSv12 */
+	{ "no-tls-tickets",srv_parse_no_tls_tickets,  0, 0 }, /* disable session resumption tickets */
+	{ "send-proxy-v2-ssl", srv_parse_send_proxy_ssl,  0, 0 }, /* send PROXY protocol header v2 with SSL info */
+	{ "send-proxy-v2-ssl-cn",  srv_parse_send_proxy_cn,   0, 0 }, /* send PROXY protocol header v2 with CN */
+	{ "sni",   srv_parse_sni, 1, 0 }, /* send SNI extension */
+	{ "ssl", 

Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From e6118524a2aaee921971a6be9020b75775507b52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 13 Mar 2017 11:54:17 +0100
Subject: [PATCH 11/31]  MINOR: server: Make 'default-server' support 'ssl'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

 This patch makes 'default-server' directive support 'ssl' setting.
 A new keyword 'no-ssl' has been added to disable this setting both
 in 'server' and 'default-server' directives.
---
 src/ssl_sock.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 2066e30..3d1e444 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -6588,6 +6588,15 @@ static int srv_parse_no_force_tlsv12(char **args, int *cur_arg, struct proxy *px
 #endif
 }
 
+/* parse the "no-ssl" server keyword */
+static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+	newsrv->use_ssl = 0;
+	free(newsrv->ssl_ctx.ciphers);
+	newsrv->ssl_ctx.ciphers = NULL;
+	return 0;
+}
+
 /* parse the "no-ssl-reuse" server keyword */
 static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
 {
@@ -7472,6 +7481,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
 	{ "no-force-tlsv10",   srv_parse_no_force_tlsv10, 0, 1 }, /* do not force TLSv10 */
 	{ "no-force-tlsv11",   srv_parse_no_force_tlsv11, 0, 1 }, /* do not force TLSv11 */
 	{ "no-force-tlsv12",   srv_parse_no_force_tlsv12, 0, 1 }, /* do not force TLSv12 */
+	{ "no-ssl",srv_parse_no_ssl,  0, 1 }, /* disable SSL processing */
 	{ "no-ssl-reuse",  srv_parse_no_ssl_reuse,0, 1 }, /* disable session reuse */
 	{ "no-sslv3",  srv_parse_no_sslv3,0, 1 }, /* disable SSLv3 */
 	{ "no-tlsv10", srv_parse_no_tlsv10,   0, 1 }, /* disable TLSv10 */
@@ -7481,7 +7491,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
 	{ "send-proxy-v2-ssl", srv_parse_send_proxy_ssl,  0, 0 }, /* send PROXY protocol header v2 with SSL info */
 	{ "send-proxy-v2-ssl-cn",  srv_parse_send_proxy_cn,   0, 0 }, /* send PROXY protocol header v2 with CN */
 	{ "sni",   srv_parse_sni, 1, 0 }, /* send SNI extension */
-	{ "ssl",   srv_parse_ssl, 0, 0 }, /* enable SSL processing */
+	{ "ssl",   srv_parse_ssl, 0, 1 }, /* enable SSL processing */
 	{ "ssl-reuse", srv_parse_ssl_reuse,   0, 1 }, /* enable session reuse */
 	{ "sslv3", srv_parse_sslv3,   0, 1 }, /* enable SSLv3 */
 	{ "tlsv10",srv_parse_tlsv10,  0, 1 }, /* enable TLSv10 */
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 1e0bb327696daf9f2b39beff1f981767fd047cc0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 13 Mar 2017 11:32:20 +0100
Subject: [PATCH 10/31] MINOR: server: Make 'default-server' support 'no-ssl*'
 and 'no-tlsv*' keywo rds.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directive support 'no-sslv3' (resp. 'no-ssl-reuse',
'no-tlsv10', 'no-tlsv11', 'no-tlsv12', and 'no-tls-tickets') setting.
New keywords 'sslv3' (resp. 'ssl-reuse', 'tlsv10', 'tlsv11', 'tlsv12', and
'tls-no-tickets') have been added to disable these settings both in 'server' and
'default-server' directives.
---
 src/ssl_sock.c | 60 --
 1 file changed, 54 insertions(+), 6 deletions(-)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 2e7ae4b..2066e30 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -6692,6 +6692,48 @@ static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct ser
 	return 0;
 }
 
+/* parse the "ssl-reuse" server keyword */
+static int srv_parse_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+	newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_REUSE;
+	return 0;
+}
+
+/* parse the "sslv3" server keyword */
+static int srv_parse_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+	newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_SSLV3;
+	return 0;
+}
+
+/* parse the "tlsv10" server keyword */
+static int srv_parse_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+	newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLSV10;
+	return 0;
+}
+
+/* parse the "tlsv11" server keyword */
+static int srv_parse_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+	newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLSV11;
+	return 0;
+}
+
+/* parse the "tlsv12" server keyword */
+static int srv_parse_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+	newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLSV12;
+	return 0;
+}
+
+/* parse the "tls-tickets" server keyword */
+static int srv_parse_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+	newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLS_TICKETS;
+	return 0;
+}
+
 /* parse the "verify" server keyword */
 static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
 {
@@ -7430,16 +7472,22 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
 	{ "no-force-tlsv10",   srv_parse_no_force_tlsv10, 0, 1 }, /* do not force TLSv10 */
 	{ "no-force-tlsv11",   srv_parse_no_force_tlsv11, 0, 1 }, /* do not force TLSv11 */
 	{ "no-force-tlsv12",   srv_parse_no_force_tlsv12, 0, 1 }, /* do not force TLSv12 */
-	{ "no-ssl-reuse",  srv_parse_no_ssl_reuse,0, 0 }, /* disable session reuse */
-	{ "no-sslv3",  srv_parse_no_sslv3,0, 0 }, /* disable SSLv3 */
-	{ "no-tlsv10", srv_parse_no_tlsv10,   0, 0 }, /* disable TLSv10 */
-	{ "no-tlsv11", srv_parse_no_tlsv11,   0, 0 }, /* disable TLSv11 */
-	{ "no-tlsv12", srv_parse_no_tlsv12,   0, 0 }, /* disable TLSv12 */
-	{ "no-tls-tickets",srv_parse_no_tls_tickets,  0, 0 }, /* disable session resumption tickets */
+	{ "no-ssl-reuse",  srv_parse_no_ssl_reuse,0, 1 }, /* disable session reuse */
+	{ "no-sslv3",  srv_parse_no_sslv3,0, 1 }, /* disable SSLv3 */
+	{ "no-tlsv10", srv_parse_no_tlsv10,   0, 1 }, /* disable TLSv10 */
+	{ "no-tlsv11", srv_parse_no_tlsv11,   0, 1 }, /* disable TLSv11 */
+	{ "no-tlsv12", srv_parse_no_tlsv12,   0, 1 }, /* disable TLSv12 */
+	{ "no-tls-tickets",srv_parse_no_tls_tickets,  0, 1 }, /* disable session resumption tickets */
 	{ "send-proxy-v2-ssl", srv_parse_send_proxy_ssl,  0, 0 }, /* send PROXY protocol header v2 with SSL info */
 	{ "send-proxy-v2-ssl-cn",  srv_parse_send_proxy_cn,   0, 0 }, /* send PROXY protocol header v2 with CN */
 	{ "sni",   srv_parse_sni, 1, 0 }, /* send SNI extension */
 	{ "ssl",   srv_parse_ssl, 0, 0 }, /* enable SSL processing */
+	{ "ssl-reuse", srv_parse_ssl_reuse,   0, 1 }, /* enable session reuse */
+	{ "sslv3", srv_parse_sslv3,   0, 1 }, /* enable SSLv3 */
+	{ "tlsv10",srv_parse_tlsv10,  0, 1 }, /* enable TLSv10 */
+	{ "tlsv11",srv_parse_tlsv11,  0, 1 }, /* enable TLSv11 */
+	{ "tlsv12",srv_parse_tlsv12,  0, 1 }, /* enable TLSv12 */
+	{ "tls-tickets",   srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
 	{ "verify",srv_parse_verify,  1, 0 }, /* set 

Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 94220ddfed21228e15f09dd73a5357f0245c13ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 13 Mar 2017 10:54:52 +0100
Subject: [PATCH 08/31] MINOR: server: Make 'default-server' support
 'force-sslv3' and 'force-tlsv1[0-2]' keywords.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directive support 'force-sslv3'
and 'force-tlsv1[0-2]' settings.
New keywords 'no-force-sslv3' (resp. 'no-tlsv1[0-2]') have been added
to disable 'force-sslv3' (resp. 'force-tlsv1[0-2]') setting both in 'server' and
'default-server' directives.
---
 src/ssl_sock.c | 58 ++
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index ff3f6c6..925d0a5 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -6542,6 +6542,52 @@ static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, s
 	return 0;
 }
 
+/* parse the "no-force-sslv3" server keyword */
+static int srv_parse_no_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+#ifndef OPENSSL_NO_SSL3
+	newsrv->ssl_ctx.options &= ~SRV_SSL_O_USE_SSLV3;
+	return 0;
+#else
+	if (err)
+		memprintf(err, "'%s' : library does not support protocol SSLv3", args[*cur_arg]);
+	return ERR_ALERT | ERR_FATAL;
+#endif
+}
+
+/* parse the "no-force-tlsv10" server keyword */
+static int srv_parse_no_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+	newsrv->ssl_ctx.options &= ~SRV_SSL_O_USE_TLSV10;
+	return 0;
+}
+
+/* parse the "no-force-tlsv11" server keyword */
+static int srv_parse_no_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+#if SSL_OP_NO_TLSv1_1
+	newsrv->ssl_ctx.options &= ~SRV_SSL_O_USE_TLSV11;
+	return 0;
+#else
+	if (err)
+		memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
+	return ERR_ALERT | ERR_FATAL;
+#endif
+}
+
+/* parse the "no-force-tlsv12" server keyword */
+static int srv_parse_no_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+#if SSL_OP_NO_TLSv1_2
+	newsrv->ssl_ctx.options &= ~SRV_SSL_O_USE_TLSV12;
+	return 0;
+#else
+	if (err)
+		memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
+	return ERR_ALERT | ERR_FATAL;
+#endif
+}
+
 /* parse the "no-ssl-reuse" server keyword */
 static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
 {
@@ -7375,11 +7421,15 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
 	{ "ciphers",   srv_parse_ciphers,1, 0 }, /* select the cipher suite */
 	{ "crl-file",  srv_parse_crl_file,   1, 0 }, /* set certificate revocation list file use on server cert verify */
 	{ "crt",   srv_parse_crt,1, 0 }, /* set client certificate */
-	{ "force-sslv3",   srv_parse_force_sslv3,0, 0 }, /* force SSLv3 */
-	{ "force-tlsv10",  srv_parse_force_tlsv10,   0, 0 }, /* force TLSv10 */
-	{ "force-tlsv11",  srv_parse_force_tlsv11,   0, 0 }, /* force TLSv11 */
-	{ "force-tlsv12",  srv_parse_force_tlsv12,   0, 0 }, /* force TLSv12 */
+	{ "force-sslv3",   srv_parse_force_sslv3,0, 1 }, /* force SSLv3 */
+	{ "force-tlsv10",  srv_parse_force_tlsv10,   0, 1 }, /* force TLSv10 */
+	{ "force-tlsv11",  srv_parse_force_tlsv11,   0, 1 }, /* force TLSv11 */
+	{ "force-tlsv12",  srv_parse_force_tlsv12,   0, 1 }, /* force TLSv12 */
 	{ "no-check-ssl",  srv_parse_no_check_ssl,   0, 1 }, /* disable SSL for health checks */
+	{ "no-force-sslv3",srv_parse_no_force_sslv3,  0, 1 }, /* do not force SSLv3 */
+	{ "no-force-tlsv10",   srv_parse_no_force_tlsv10, 0, 1 }, /* do not force TLSv10 */
+	{ "no-force-tlsv11",   srv_parse_no_force_tlsv11, 0, 1 }, /* do not force TLSv11 */
+	{ "no-force-tlsv12",   srv_parse_no_force_tlsv12, 0, 1 }, /* do not force TLSv12 */
 	{ "no-ssl-reuse",  srv_parse_no_ssl_reuse,   0, 0 }, /* disable session reuse */
 	{ "no-sslv3",  srv_parse_no_sslv3,   0, 0 }, /* disable SSLv3 */
 	{ "no-tlsv10", srv_parse_no_tlsv10,  0, 0 }, /* disable TLSv10 */
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 324ec06ee477cce5f9b2ba7b031e87d62c333826 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Wed, 15 Mar 2017 16:20:02 +0100
Subject: [PATCH 23/31] MINOR: server: Make 'default-server' support 'ciphers'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directive support 'ciphers' setting.
---
 src/server.c   | 2 ++
 src/ssl_sock.c | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/server.c b/src/server.c
index 79dcca7..a9cfac3 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1431,6 +1431,8 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			newsrv->ssl_ctx.verify = curproxy->defsrv.ssl_ctx.verify;
 			if (curproxy->defsrv.ssl_ctx.verify_host != NULL)
 newsrv->ssl_ctx.verify_host = strdup(curproxy->defsrv.ssl_ctx.verify_host);
+			if (curproxy->defsrv.ssl_ctx.ciphers != NULL)
+newsrv->ssl_ctx.ciphers = strdup(curproxy->defsrv.ssl_ctx.ciphers);
 #endif
 
 			cur_arg = 3;
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 72b3259..9d85eac 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -7487,7 +7487,7 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
 static struct srv_kw_list srv_kws = { "SSL", { }, {
 	{ "ca-file", srv_parse_ca_file,   1, 1 }, /* set CAfile to process verify server cert */
 	{ "check-ssl",   srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
-	{ "ciphers", srv_parse_ciphers,   1, 0 }, /* select the cipher suite */
+	{ "ciphers", srv_parse_ciphers,   1, 1 }, /* select the cipher suite */
 	{ "crl-file",srv_parse_crl_file,  1, 1 }, /* set certificate revocation list file use on server cert verify */
 	{ "crt", srv_parse_crt,   1, 1 }, /* set client certificate */
 	{ "force-sslv3", srv_parse_force_sslv3,   0, 1 }, /* force SSLv3 */
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From e47f6ab5d8a8fb61888b165adf6f7e12f07c10b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Thu, 16 Mar 2017 17:17:36 +0100
Subject: [PATCH 25/31] MINOR: server: Make 'default-server' support
 'namespace' keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

Before this patch, 'namespace' setting was only supported by 'server' directive.
This patch makes 'default-server' directive support this setting.
---
 src/server.c | 68 ++--
 1 file changed, 43 insertions(+), 25 deletions(-)

diff --git a/src/server.c b/src/server.c
index 7654211..cab0772 100644
--- a/src/server.c
+++ b/src/server.c
@@ -289,6 +289,48 @@ static int srv_parse_id(char **args, int *cur_arg, struct proxy *curproxy, struc
 	return 0;
 }
 
+/* Parse the "namespace" server keyword */
+static int srv_parse_namespace(char **args, int *cur_arg,
+   struct proxy *curproxy, struct server *newsrv, char **err)
+{
+#ifdef CONFIG_HAP_NS
+	char *arg;
+
+	arg = args[*cur_arg + 1];
+	if (!*arg) {
+		memprintf(err, "'%s' : expects  as argument", args[*cur_arg]);
+		return ERR_ALERT | ERR_FATAL;
+	}
+
+	if (!strcmp(arg, "*")) {
+		/* Use the namespace associated with the connection (if present). */
+		newsrv->flags |= SRV_F_USE_NS_FROM_PP;
+		return 0;
+	}
+
+	/*
+	 * As this parser may be called several times for the same 'default-server'
+	 * object, or for a new 'server' instance deriving from a 'default-server'
+	 * one with SRV_F_USE_NS_FROM_PP flag enabled, let's reset it.
+	 */
+	newsrv->flags &= ~SRV_F_USE_NS_FROM_PP;
+
+	newsrv->netns = netns_store_lookup(arg, strlen(arg));
+	if (!newsrv->netns)
+		newsrv->netns = netns_store_insert(arg);
+
+	if (!newsrv->netns) {
+		memprintf(err, "Cannot open namespace '%s'", arg);
+		return ERR_ALERT | ERR_FATAL;
+	}
+
+	return 0;
+#else
+	memprintf(err, "'%s': '%s' option not implemented", args[0], args[*cur_arg]);
+	return ERR_ALERT | ERR_FATAL;
+#endif
+}
+
 /* Parse the "no-backup" server keyword */
 static int srv_parse_no_backup(char **args, int *cur_arg,
struct proxy *curproxy, struct server *newsrv, char **err)
@@ -1058,6 +1100,7 @@ static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "check-send-proxy",srv_parse_check_send_proxy,0,  1 }, /* enable PROXY protocol for health checks */
 	{ "cookie",  srv_parse_cookie,  1,  1 }, /* Assign a cookie to the server */
 	{ "id",  srv_parse_id,  1,  0 }, /* set id# of server */
+	{ "namespace",   srv_parse_namespace,   1,  1 }, /* Namespace the server socket belongs to (if supported) */
 	{ "no-backup",   srv_parse_no_backup,   0,  1 }, /* Flag as non-backup server */
 	{ "no-check",srv_parse_no_check,0,  1 }, /* disable health checks */
 	{ "no-check-send-proxy", srv_parse_no_check_send_proxy, 0,  1 }, /* disable PROXY protol for health checks */
@@ -2025,31 +2068,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 err_code |= ERR_ALERT | ERR_FATAL;
 goto out;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "namespace")) {
-#ifdef CONFIG_HAP_NS
-char *arg = args[cur_arg + 1];
-if (!strcmp(arg, "*")) {
-	newsrv->flags |= SRV_F_USE_NS_FROM_PP;
-} else {
-	newsrv->netns = netns_store_lookup(arg, strlen(arg));
-
-	if (newsrv->netns == NULL)
-		newsrv->netns = netns_store_insert(arg);
-
-	if (newsrv->netns == NULL) {
-		Alert("Cannot open namespace '%s'.\n", args[cur_arg + 1]);
-		err_code |= ERR_ALERT | ERR_FATAL;
-		goto out;
-	}
-}
-#else
-Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
-  file, linenum, args[0], args[cur_arg]);
-err_code |= ERR_ALERT | ERR_FATAL;
-goto out;
-#endif
-cur_arg += 2;
-			}
 			else {
 static int srv_dumped;
 struct srv_kw *kw;
-- 
2.1.4



All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille

Hello HAProxy ML,

I am starting this new thread to publish a serie of patches to make
all "server" settings be supported on "default-server" lines.

This is a preliminary work for "server templates" feature.

New boolean settings have been added to disable others. Most of them
have "no-" as prefix.

Here is an exhaustive list:

"enabled" disable "disabled" setting,
"no-agent-check" disables "agent-check",
"no-backup" disables "backup",
"no-check" disables "check",
"no-check-ssl" disables "check-ssl",
"no-force-sslv3" disables "force-sslv3",
"no-force-tlsv10" disables "force-tlsv10",
"no-force-tlsv11" disables "force-tlsv11",
"no-force-tlsv12" disables "force-tlsv12,
"no-send-proxy" disables "send-proxy",
"no-send-proxy-v2" disables "send-proxy-v2",
"no-send-proxy-v2-ssl" disables "send-proxy-v2-ssl",
"no-send-proxy-v2-ssl-cn" disables "send-proxy-v2-ssl-cn",
"no-ssl" disables "ssl",
"no-verifyhost" disables "verifyhost",
"sslv2" disables "no-sslv3",
"ssl-reuse" disables "no-ssl-reuse",
"stick" disables "non-stick",
"tlsv10" disables "no-tlsv10",
"tlsv11" disables "no-tlsv11",
"tlsv12" disables "no-tlsv12",
"tls-tickets" disables "no-tls-tickets".

Furthemore, some settings with arguments are from now supported by 
"default-server" directive:


"addr", "ca-file", "ciphers", "crl-file", "crt", "cookie", "namespace", 
"observe", "redir", "sni", "source", "tcp-ut" and "track".


The documentation have been consequently updated.

So, from now on, all server "settings" are supported by "default-server" 
except "id" which is only supported on "server" lines.






Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From bd77e21eab9aa777962ae94ce7dbff2224b1b295 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Fri, 10 Mar 2017 16:40:00 +0100
Subject: [PATCH 06/31] MINOR: server: Make 'default-server' support
 'send-proxy' and 'send-proxy-v2 keywords.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directive support 'send-proxy'
(resp. 'send-proxy-v2') setting.
A new keyword 'no-send-proxy' (resp. 'no-send-proxy-v2') has been added
to disable 'send-proxy' (resp. 'send-proxy-v2') setting both in 'server' and
'default-server' directives.
---
 src/server.c | 55 +++
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/src/server.c b/src/server.c
index c5a4d31..ddb2842 100644
--- a/src/server.c
+++ b/src/server.c
@@ -277,6 +277,27 @@ static int srv_parse_no_check_send_proxy(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Disable server PROXY protocol flags. */
+static int inline srv_disable_pp_flags(struct server *srv, unsigned int flags)
+{
+	srv->pp_opts &= ~flags;
+	return 0;
+}
+
+/* Parse the "no-send-proxy" server keyword */
+static int srv_parse_no_send_proxy(char **args, int *cur_arg,
+   struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	return srv_disable_pp_flags(newsrv, SRV_PP_V1);
+}
+
+/* Parse the "no-send-proxy-v2" server keyword */
+static int srv_parse_no_send_proxy_v2(char **args, int *cur_arg,
+  struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	return srv_disable_pp_flags(newsrv, SRV_PP_V2);
+}
+
 /* Parse the "non-stick" server keyword */
 static int srv_parse_non_stick(char **args, int *cur_arg,
struct proxy *curproxy, struct server *newsrv, char **err)
@@ -285,6 +306,27 @@ static int srv_parse_non_stick(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Enable server PROXY protocol flags. */
+static int inline srv_enable_pp_flags(struct server *srv, unsigned int flags)
+{
+	srv->pp_opts |= flags;
+	return 0;
+}
+
+/* Parse the "send-proxy" server keyword */
+static int srv_parse_send_proxy(char **args, int *cur_arg,
+struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	return srv_enable_pp_flags(newsrv, SRV_PP_V1);
+}
+
+/* Parse the "send-proxy-v2" server keyword */
+static int srv_parse_send_proxy_v2(char **args, int *cur_arg,
+   struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	return srv_enable_pp_flags(newsrv, SRV_PP_V2);
+}
+
 /* Parse the "stick" server keyword */
 static int srv_parse_stick(char **args, int *cur_arg,
struct proxy *curproxy, struct server *newsrv, char **err)
@@ -907,7 +949,11 @@ static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "id",  srv_parse_id,  1,  0 }, /* set id# of server */
 	{ "no-backup",   srv_parse_no_backup,   0,  1 }, /* Flag as non-backup server */
 	{ "no-check-send-proxy", srv_parse_no_check_send_proxy, 0,  1 }, /* disable PROXY protol for health checks */
+	{ "no-send-proxy",   srv_parse_no_send_proxy,   0,  1 }, /* Disable use of PROXY V1 protocol */
+	{ "no-send-proxy-v2",srv_parse_no_send_proxy_v2,0,  1 }, /* Disable use of PROXY V2 protocol */
 	{ "non-stick",   srv_parse_non_stick,   0,  1 }, /* Disable stick-table persistence */
+	{ "send-proxy",  srv_parse_send_proxy,  0,  1 }, /* Enforce use of PROXY V1 protocol */
+	{ "send-proxy-v2",   srv_parse_send_proxy_v2,   0,  1 }, /* Enforce use of PROXY V2 protocol */
 	{ "stick",   srv_parse_stick,   0,  1 }, /* Enable stick-table persistence */
 	{ NULL, NULL, 0 },
 }};
@@ -1196,6 +1242,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 goto out;
 			}
 
+			newsrv->pp_opts		= curproxy->defsrv.pp_opts;
 			newsrv->use_ssl		= curproxy->defsrv.use_ssl;
 			newsrv->check.use_ssl	= curproxy->defsrv.check.use_ssl;
 			newsrv->check.port	= curproxy->defsrv.check.port;
@@ -1560,14 +1607,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->flags |= SRV_F_CHECKPORT;
 cur_arg += 2;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "send-proxy")) {
-newsrv->pp_opts |= SRV_PP_V1;
-cur_arg ++;
-			}
-			else if (!defsrv && !strcmp(args[cur_arg], "send-proxy-v2")) {
-newsrv->pp_opts |= SRV_PP_V2;
-cur_arg ++;
-			}
 			else if (!strcmp(args[cur_arg], "weight")) {
 int w;
 w = atol(args[cur_arg + 1]);
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 17f461d5878f902e34a113d462218a661c747d4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 13 Mar 2017 10:38:04 +0100
Subject: [PATCH 07/31]  MINOR: server: Make 'default-server' support
 'check-ssl' keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directive support 'check-ssl' setting
to enable SSL for health checks.
A new keyword 'no-check-ssl' has been added to disable this setting both in
'server' and 'default-server' directives.
---
 src/ssl_sock.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 1e63c57..ff3f6c6 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -6532,6 +6532,16 @@ static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, s
 #endif
 }
 
+/* parse the "no-check-ssl" server keyword */
+static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+	newsrv->check.use_ssl = 0;
+	free(newsrv->ssl_ctx.ciphers);
+	newsrv->ssl_ctx.ciphers = NULL;
+	newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
+	return 0;
+}
+
 /* parse the "no-ssl-reuse" server keyword */
 static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
 {
@@ -7361,7 +7371,7 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
  */
 static struct srv_kw_list srv_kws = { "SSL", { }, {
 	{ "ca-file",   srv_parse_ca_file,1, 0 }, /* set CAfile to process verify server cert */
-	{ "check-ssl", srv_parse_check_ssl,  0, 0 }, /* enable SSL for health checks */
+	{ "check-ssl", srv_parse_check_ssl,  0, 1 }, /* enable SSL for health checks */
 	{ "ciphers",   srv_parse_ciphers,1, 0 }, /* select the cipher suite */
 	{ "crl-file",  srv_parse_crl_file,   1, 0 }, /* set certificate revocation list file use on server cert verify */
 	{ "crt",   srv_parse_crt,1, 0 }, /* set client certificate */
@@ -7369,6 +7379,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
 	{ "force-tlsv10",  srv_parse_force_tlsv10,   0, 0 }, /* force TLSv10 */
 	{ "force-tlsv11",  srv_parse_force_tlsv11,   0, 0 }, /* force TLSv11 */
 	{ "force-tlsv12",  srv_parse_force_tlsv12,   0, 0 }, /* force TLSv12 */
+	{ "no-check-ssl",  srv_parse_no_check_ssl,   0, 1 }, /* disable SSL for health checks */
 	{ "no-ssl-reuse",  srv_parse_no_ssl_reuse,   0, 0 }, /* disable session reuse */
 	{ "no-sslv3",  srv_parse_no_sslv3,   0, 0 }, /* disable SSLv3 */
 	{ "no-tlsv10", srv_parse_no_tlsv10,  0, 0 }, /* disable TLSv10 */
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 78c8279eb296b4a70eecb7eff599e2851749b3c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 20 Mar 2017 14:54:41 +0100
Subject: [PATCH 27/31] MINOR: server: Make 'default-server' support 'sni'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directives support 'sni' settings.
A field 'sni_expr' has been added to 'struct server' to temporary
stores SNI expressions as strings during both 'default-server' and 'server'
lines parsing. So, to duplicate SNI expressions from 'default-server' 'sni' setting
for new 'server' instances we only have to "strdup" these strings as this is
often done for most of the 'server' settings.
Then, sample expressions are computed calling sample_parse_expr() (only for 'server'
instances).
A new function has been added to produce the same error output as before in case
of any error during 'sni' settings parsing (display_parser_err()).
Should not break anything.
---
 include/types/server.h |  1 +
 src/server.c   | 75 +-
 src/ssl_sock.c | 27 --
 3 files changed, 75 insertions(+), 28 deletions(-)

diff --git a/include/types/server.h b/include/types/server.h
index c973d69..781a889 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -254,6 +254,7 @@ struct server {
 
 	int use_ssl;/* ssl enabled  */
 #ifdef USE_OPENSSL
+	char *sni_expr; /* Temporary variable to store a sample expression for SNI */
 	struct {
 		SSL_CTX *ctx;
 		SSL_SESSION *reused_sess;
diff --git a/src/server.c b/src/server.c
index 51c5ee6..404c0b1 100644
--- a/src/server.c
+++ b/src/server.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1438,6 +1439,53 @@ const char *server_parse_maxconn_change_request(struct server *sv,
 	return NULL;
 }
 
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+static int server_parse_sni_expr(struct server *newsrv, struct proxy *px, char **err)
+{
+	int idx;
+	struct sample_expr *expr;
+	const char *args[] = {
+		newsrv->sni_expr,
+		NULL,
+	};
+
+	idx = 0;
+	proxy->conf.args.ctx = ARGC_SRV;
+
+	expr = sample_parse_expr((char **)args, , px->conf.file, px->conf.line,
+	 err, >conf.args);
+	if (!expr) {
+		memprintf(err, "error detected while parsing sni expression : %s", *err);
+		return ERR_ALERT | ERR_FATAL;
+	}
+
+	if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
+		memprintf(err, "error detected while parsing sni expression : "
+		  " fetch method '%s' extracts information from '%s', "
+		  "none of which is available here.\n",
+		  args[0], sample_src_names(expr->fetch->use));
+		return ERR_ALERT | ERR_FATAL;
+	}
+
+	px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
+	release_sample_expr(newsrv->ssl_ctx.sni);
+	newsrv->ssl_ctx.sni = expr;
+
+	return 0;
+}
+#endif
+
+static void display_parser_err(const char *file, int linenum, char **args, int cur_arg, char **err)
+{
+	if (err && *err) {
+		indent_msg(err, 2);
+		Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], *err);
+	}
+	else
+		Alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
+		  file, linenum, args[0], args[1], args[cur_arg]);
+}
+
 int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy)
 {
 	struct server *newsrv = NULL;
@@ -1688,6 +1736,8 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->ssl_ctx.verify_host = strdup(curproxy->defsrv.ssl_ctx.verify_host);
 			if (curproxy->defsrv.ssl_ctx.ciphers != NULL)
 newsrv->ssl_ctx.ciphers = strdup(curproxy->defsrv.ssl_ctx.ciphers);
+			if (curproxy->defsrv.sni_expr != NULL)
+newsrv->sni_expr = strdup(curproxy->defsrv.sni_expr);
 #endif
 
 #ifdef TCP_USER_TIMEOUT
@@ -2135,13 +2185,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 	err_code |= code;
 
 	if (code) {
-		if (err && *err) {
-			indent_msg(, 2);
-			Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
-		}
-		else
-			Alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
-			  file, linenum, args[0], args[1], args[cur_arg]);
+		display_parser_err(file, linenum, args, cur_arg, );
 		if (code & ERR_FATAL) {
 			free(err);
 			cur_arg += 1 + kw->skip;
@@ -2270,6 +2314,23 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 
 			srv_lb_commit_status(newsrv);
 		}
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+		if (!defsrv && newsrv->sni_expr) {
+			int code;
+			char *err;
+
+			err = NULL;
+
+			code = server_parse_sni_expr(newsrv, curproxy, );
+			err_code |= code;
+			if (code) {
+display_parser_err(file, linenum, args, cur_arg, );
+free(err);
+

Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 57d54d2e1f1b200c2c44cbe135c2c74900b83d36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Fri, 17 Mar 2017 15:33:50 +0100
Subject: [PATCH 26/31] MINOR: server: Make 'default-server' support 'source'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

Before this patch, only 'server' directives could support 'source' setting.
This patch makes also 'default-server' directives support this setting.

To do so, we had to extract the code responsible of parsing 'source' setting
arguments from parse_server() function and make it callable both
as 'default-server' and 'server' 'source' setting parser. So, the code is mostly
the same as before except that before allocating anything for 'struct conn_src'
members, we must free the memory previously allocated.

Should not break anything.
---
 src/server.c | 385 ---
 1 file changed, 211 insertions(+), 174 deletions(-)

diff --git a/src/server.c b/src/server.c
index cab0772..51c5ee6 100644
--- a/src/server.c
+++ b/src/server.c
@@ -460,6 +460,180 @@ static int srv_parse_send_proxy_v2(char **args, int *cur_arg,
 	return srv_enable_pp_flags(newsrv, SRV_PP_V2);
 }
 
+
+/* Parse the "source" server keyword */
+static int srv_parse_source(char **args, int *cur_arg,
+struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	char *errmsg;
+	int port_low, port_high;
+	struct sockaddr_storage *sk;
+	struct protocol *proto;
+
+	errmsg = NULL;
+
+	if (!*args[*cur_arg + 1]) {
+		memprintf(err, "'%s' expects [:[-]], and optionally '%s' , "
+		   "and '%s'  as argument.\n", args[*cur_arg], "usesrc", "interface");
+		goto err;
+	}
+
+	/* 'sk' is statically allocated (no need to be freed). */
+	sk = str2sa_range(args[*cur_arg + 1], NULL, _low, _high, , NULL, NULL, 1);
+	if (!sk) {
+		memprintf(err, "'%s %s' : %s\n", args[*cur_arg], args[*cur_arg + 1], errmsg);
+		goto err;
+	}
+
+	proto = protocol_by_family(sk->ss_family);
+	if (!proto || !proto->connect) {
+		Alert("'%s %s' : connect() not supported for this address family.\n",
+		  args[*cur_arg], args[*cur_arg + 1]);
+		goto err;
+	}
+
+	newsrv->conn_src.opts |= CO_SRC_BIND;
+	newsrv->conn_src.source_addr = *sk;
+
+	if (port_low != port_high) {
+		int i;
+
+		if (!port_low || !port_high) {
+			Alert("'%s' does not support port offsets (found '%s').\n",
+			  args[*cur_arg], args[*cur_arg + 1]);
+			goto err;
+		}
+
+		if (port_low  <= 0 || port_low  > 65535 ||
+			port_high <= 0 || port_high > 65535 ||
+			port_low > port_high) {
+			Alert("'%s': invalid source port range %d-%d.\n", args[*cur_arg], port_low, port_high);
+			goto err;
+		}
+		newsrv->conn_src.sport_range = port_range_alloc_range(port_high - port_low + 1);
+		for (i = 0; i < newsrv->conn_src.sport_range->size; i++)
+			newsrv->conn_src.sport_range->ports[i] = port_low + i;
+	}
+
+	*cur_arg += 2;
+	while (*(args[*cur_arg])) {
+		if (!strcmp(args[*cur_arg], "usesrc")) {  /* address to use outside */
+#if defined(CONFIG_HAP_TRANSPARENT)
+			if (!*args[*cur_arg + 1]) {
+Alert("'usesrc' expects [:], 'client', 'clientip', "
+  "or 'hdr_ip(name,#)' as argument.\n");
+goto err;
+			}
+			if (!strcmp(args[*cur_arg + 1], "client")) {
+newsrv->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
+newsrv->conn_src.opts |= CO_SRC_TPROXY_CLI;
+			}
+			else if (!strcmp(args[*cur_arg + 1], "clientip")) {
+newsrv->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
+newsrv->conn_src.opts |= CO_SRC_TPROXY_CIP;
+			}
+			else if (!strncmp(args[*cur_arg + 1], "hdr_ip(", 7)) {
+char *name, *end;
+
+name = args[*cur_arg + 1] + 7;
+while (isspace(*name))
+	name++;
+
+end = name;
+while (*end && !isspace(*end) && *end != ',' && *end != ')')
+	end++;
+
+newsrv->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
+newsrv->conn_src.opts |= CO_SRC_TPROXY_DYN;
+free(newsrv->conn_src.bind_hdr_name);
+newsrv->conn_src.bind_hdr_name = calloc(1, end - name + 1);
+newsrv->conn_src.bind_hdr_len = end - name;
+memcpy(newsrv->conn_src.bind_hdr_name, name, end - name);
+newsrv->conn_src.bind_hdr_name[end - name] = '\0';
+newsrv->conn_src.bind_hdr_occ = -1;
+
+/* now look for an occurrence number */
+while (isspace(*end))
+	end++;
+if (*end == ',') {
+	end++;
+	name = end;
+	if (*end == '-')
+		end++;
+	while (isdigit((int)*end))
+		end++;
+	newsrv->conn_src.bind_hdr_occ = strl2ic(name, end - name);
+}
+
+if (newsrv->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
+	Alert("usesrc hdr_ip(name,num) does not support negative"
+	  " occurrences values smaller than %d.\n", MAX_HDR_HISTORY);
+	goto err;
+}
+			}
+			else {
+struct sockaddr_storage *sk;
+int port1, port2;
+
+/* 'sk' is statically allocated (no need to be freed). */
+sk = str2sa_range(args[*cur_arg + 1], NULL, , , , 

Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 57c710d9866bd06837b6aeb7ff5b45e7891b5f0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 20 Mar 2017 16:30:18 +0100
Subject: [PATCH 28/31] MINOR: server: Make 'default-server' support 'addr'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' support 'addr' setting.
The code which was responsible of parsing 'server' 'addr' setting
has moved from parse_server() to implement a new parser
callable both as 'default-server' and 'server' 'addr' setting parser.

Should not break anything.
---
 src/server.c | 82 
 1 file changed, 49 insertions(+), 33 deletions(-)

diff --git a/src/server.c b/src/server.c
index 404c0b1..83a7052 100644
--- a/src/server.c
+++ b/src/server.c
@@ -215,6 +215,53 @@ void srv_dump_kws(char **out)
 	}
 }
 
+/* Parse the "addr" server keyword */
+static int srv_parse_addr(char **args, int *cur_arg,
+  struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	char *errmsg, *arg;
+	struct sockaddr_storage *sk;
+	int port1, port2;
+	struct protocol *proto;
+
+	errmsg = NULL;
+	arg = args[*cur_arg + 1];
+
+	if (!*arg) {
+		memprintf(err, "'%s' expects  as argument.\n", args[*cur_arg]);
+		goto err;
+	}
+
+	sk = str2sa_range(arg, NULL, , , , NULL, NULL, 1);
+	if (!sk) {
+		memprintf(err, "'%s' : %s", args[*cur_arg], errmsg);
+		goto err;
+	}
+
+	proto = protocol_by_family(sk->ss_family);
+	if (!proto || !proto->connect) {
+		memprintf(err, "'%s %s' : connect() not supported for this address family.\n",
+		  args[*cur_arg], arg);
+		goto err;
+	}
+
+	if (port1 != port2) {
+		memprintf(err, "'%s' : port ranges and offsets are not allowed in '%s'\n",
+		  args[*cur_arg], arg);
+		goto err;
+	}
+
+	newsrv->check.addr = newsrv->agent.addr = *sk;
+	newsrv->flags |= SRV_F_CHECKADDR;
+	newsrv->flags |= SRV_F_AGENTADDR;
+
+	return 0;
+
+ err:
+	free(errmsg);
+	return ERR_ALERT | ERR_FATAL;
+}
+
 /* Parse the "backup" server keyword */
 static int srv_parse_backup(char **args, int *cur_arg,
 struct proxy *curproxy, struct server *newsrv, char **err)
@@ -1271,6 +1318,7 @@ void srv_compute_all_admin_states(struct proxy *px)
  * not enabled.
  */
 static struct srv_kw_list srv_kws = { "ALL", { }, {
+	{ "addr",srv_parse_addr,1,  1 }, /* IP address to send health to or to probe from agent-check */
 	{ "backup",  srv_parse_backup,  0,  1 }, /* Flag as backup server */
 	{ "check",   srv_parse_check,   0,  1 }, /* enable health checks */
 	{ "check-send-proxy",srv_parse_check_send_proxy,0,  1 }, /* enable PROXY protocol for health checks */
@@ -1668,6 +1716,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->cklen = curproxy->defsrv.cklen;
 			}
 			newsrv->use_ssl		= curproxy->defsrv.use_ssl;
+			newsrv->check.addr = newsrv->agent.addr = curproxy->defsrv.check.addr;
 			newsrv->check.use_ssl	= curproxy->defsrv.check.use_ssl;
 			newsrv->check.port	= curproxy->defsrv.check.port;
 			/* Note: 'flags' field has potentially been already initialized. */
@@ -2006,39 +2055,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->check.downinter = val;
 cur_arg += 2;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "addr")) {
-struct sockaddr_storage *sk;
-int port1, port2;
-struct protocol *proto;
-
-sk = str2sa_range(args[cur_arg + 1], NULL, , , , NULL, NULL, 1);
-if (!sk) {
-	Alert("parsing [%s:%d] : '%s' : %s\n",
-	  file, linenum, args[cur_arg], errmsg);
-	err_code |= ERR_ALERT | ERR_FATAL;
-	goto out;
-}
-
-proto = protocol_by_family(sk->ss_family);
-if (!proto || !proto->connect) {
-	Alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
-	  file, linenum, args[cur_arg], args[cur_arg + 1]);
-	err_code |= ERR_ALERT | ERR_FATAL;
-	goto out;
-}
-
-if (port1 != port2) {
-	Alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
-	  file, linenum, args[cur_arg], args[cur_arg + 1]);
-	err_code |= ERR_ALERT | ERR_FATAL;
-	goto out;
-}
-
-newsrv->check.addr = newsrv->agent.addr = *sk;
-newsrv->flags |= SRV_F_CHECKADDR;
-newsrv->flags |= SRV_F_AGENTADDR;
-cur_arg += 2;
-			}
 			else if (!strcmp(args[cur_arg], "port")) {
 newsrv->check.port = atol(args[cur_arg + 1]);
 newsrv->flags |= SRV_F_CHECKPORT;
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From a7f6425b24e7855259b6b858e8a322fde0d2bd39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Fri, 10 Mar 2017 14:04:31 +0100
Subject: [PATCH 03/31] MINOR: server: Make 'default-server' support
 'check-send-proxy' keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directive support 'check-send-proxy' setting.
A new keyword 'no-check-send-proxy' has been added so that to disable
'check-send-proxy' setting both in 'server' and 'default-server' directives.
---
 src/server.c | 23 +++
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/server.c b/src/server.c
index 2b0a5da..796ff51 100644
--- a/src/server.c
+++ b/src/server.c
@@ -221,6 +221,14 @@ static int srv_parse_backup(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Parse the "check-send-proxy" server keyword */
+static int srv_parse_check_send_proxy(char **args, int *cur_arg,
+  struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	newsrv->check.send_proxy = 1;
+	return 0;
+}
+
 /* parse the "id" server keyword */
 static int srv_parse_id(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err)
 {
@@ -261,6 +269,14 @@ static int srv_parse_no_backup(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Parse the "no-check-send-proxy" server keyword */
+static int srv_parse_no_check_send_proxy(char **args, int *cur_arg,
+ struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	newsrv->check.send_proxy = 0;
+	return 0;
+}
+
 /* Shutdown all connections of a server. The caller must pass a termination
  * code in , which must be one of SF_ERR_* indicating the reason for the
  * shutdown.
@@ -871,8 +887,10 @@ void srv_compute_all_admin_states(struct proxy *px)
  */
 static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "backup",   srv_parse_backup,   0,  1 }, /* Flag as backup server */
+	{ "check-send-proxy",srv_parse_check_send_proxy,0,  1 }, /* enable PROXY protocol for health checks */
 	{ "id",   srv_parse_id,   1,  0 }, /* set id# of server */
 	{ "no-backup",srv_parse_no_backup,0,  1 }, /* Flag as non-backup server */
+	{ "no-check-send-proxy", srv_parse_no_check_send_proxy, 0,  1 }, /* disable PROXY protol for health checks */
 	{ NULL, NULL, 0 },
 }};
 
@@ -1191,6 +1209,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 		= curproxy->defsrv.iweight;
 
 			newsrv->check.status	= HCHK_STATUS_INI;
+			newsrv->check.send_proxy = curproxy->defsrv.check.send_proxy;
 			newsrv->check.rise	= curproxy->defsrv.check.rise;
 			newsrv->check.fall	= curproxy->defsrv.check.fall;
 			newsrv->check.health	= newsrv->check.rise;	/* up, but will fall down at first failure */
@@ -1535,10 +1554,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->pp_opts |= SRV_PP_V2;
 cur_arg ++;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "check-send-proxy")) {
-newsrv->check.send_proxy = 1;
-cur_arg ++;
-			}
 			else if (!strcmp(args[cur_arg], "weight")) {
 int w;
 w = atol(args[cur_arg + 1]);
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From ff5d557c972a9953073773103e4fccad9bc32638 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Fri, 10 Mar 2017 11:51:05 +0100
Subject: [PATCH 02/31] MINOR: server: Make 'default-server' support 'backup'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

At this time, only 'server' supported 'backup' keyword.
This patch makes also 'default-server' directive support this keyword.
A new keyword 'no-backup' has been added so that to disable 'backup' setting
both in 'server' and 'default-server' directives.

For instance, provided the following sequence of directives:

default-server backup
server srv1
server srv2 no-backup

default-server no-backup
server srv3
server srv4 backup

srv1 and srv4 are declared as backup servers,
srv2 and srv3 are declared as non-backup servers.
---
 src/server.c | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/server.c b/src/server.c
index 563d38d..2b0a5da 100644
--- a/src/server.c
+++ b/src/server.c
@@ -213,6 +213,14 @@ void srv_dump_kws(char **out)
 	}
 }
 
+/* Parse the "backup" server keyword */
+static int srv_parse_backup(char **args, int *cur_arg,
+struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	newsrv->flags |= SRV_F_BACKUP;
+	return 0;
+}
+
 /* parse the "id" server keyword */
 static int srv_parse_id(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err)
 {
@@ -245,6 +253,14 @@ static int srv_parse_id(char **args, int *cur_arg, struct proxy *curproxy, struc
 	return 0;
 }
 
+/* Parse the "no-backup" server keyword */
+static int srv_parse_no_backup(char **args, int *cur_arg,
+   struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	newsrv->flags &= ~SRV_F_BACKUP;
+	return 0;
+}
+
 /* Shutdown all connections of a server. The caller must pass a termination
  * code in , which must be one of SF_ERR_* indicating the reason for the
  * shutdown.
@@ -854,7 +870,9 @@ void srv_compute_all_admin_states(struct proxy *px)
  * not enabled.
  */
 static struct srv_kw_list srv_kws = { "ALL", { }, {
+	{ "backup",   srv_parse_backup,   0,  1 }, /* Flag as backup server */
 	{ "id",   srv_parse_id,   1,  0 }, /* set id# of server */
+	{ "no-backup",srv_parse_no_backup,0,  1 }, /* Flag as non-backup server */
 	{ NULL, NULL, 0 },
 }};
 
@@ -1145,6 +1163,8 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			newsrv->use_ssl		= curproxy->defsrv.use_ssl;
 			newsrv->check.use_ssl	= curproxy->defsrv.check.use_ssl;
 			newsrv->check.port	= curproxy->defsrv.check.port;
+			/* Note: 'flags' field has potentially been already initialized. */
+			newsrv->flags   |= curproxy->defsrv.flags;
 			if (newsrv->check.port)
 newsrv->flags |= SRV_F_CHECKPORT;
 			newsrv->check.inter	= curproxy->defsrv.check.inter;
@@ -1503,10 +1523,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->flags |= SRV_F_CHECKPORT;
 cur_arg += 2;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "backup")) {
-newsrv->flags |= SRV_F_BACKUP;
-cur_arg ++;
-			}
 			else if (!defsrv && !strcmp(args[cur_arg], "non-stick")) {
 newsrv->flags |= SRV_F_NON_STICK;
 cur_arg ++;
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 0f1fc0c3325bd15d97fc9005a72b2094c170c609 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Wed, 15 Mar 2017 08:55:39 +0100
Subject: [PATCH 21/31] MINOR: server: Make 'default-server' support 'observe'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

Before this path, 'observe' setting was only supported by 'server' directives.
This patch makes 'default-server' directives also support 'observe' setting.
Should not break anything.
---
 src/server.c | 59 ---
 1 file changed, 36 insertions(+), 23 deletions(-)

diff --git a/src/server.c b/src/server.c
index 1fc10c5..b855b1b 100644
--- a/src/server.c
+++ b/src/server.c
@@ -331,6 +331,40 @@ static int inline srv_enable_pp_flags(struct server *srv, unsigned int flags)
 	return 0;
 }
 
+/* Parse the "observe" server keyword */
+static int srv_parse_observe(char **args, int *cur_arg,
+ struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	char *arg;
+
+	arg = args[*cur_arg + 1];
+	if (!*arg) {
+		memprintf(err, "'%s' expects  as argument.\n", args[*cur_arg]);
+		return ERR_ALERT | ERR_FATAL;
+	}
+
+	if (!strcmp(arg, "none")) {
+		newsrv->observe = HANA_OBS_NONE;
+	}
+	else if (!strcmp(arg, "layer4")) {
+		newsrv->observe = HANA_OBS_LAYER4;
+	}
+	else if (!strcmp(arg, "layer7")) {
+		if (curproxy->mode != PR_MODE_HTTP) {
+			memprintf(err, "'%s' can only be used in http proxies.\n", arg);
+			return ERR_ALERT;
+		}
+		newsrv->observe = HANA_OBS_LAYER7;
+	}
+	else {
+		memprintf(err, "'%s' expects one of 'none', 'layer4', 'layer7' "
+		   "but got '%s'\n", args[*cur_arg], arg);
+		return ERR_ALERT | ERR_FATAL;
+	}
+
+	return 0;
+}
+
 /* Parse the "redir" server keyword */
 static int srv_parse_redir(char **args, int *cur_arg,
struct proxy *curproxy, struct server *newsrv, char **err)
@@ -1009,6 +1043,7 @@ static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "no-send-proxy",   srv_parse_no_send_proxy,   0,  1 }, /* Disable use of PROXY V1 protocol */
 	{ "no-send-proxy-v2",srv_parse_no_send_proxy_v2,0,  1 }, /* Disable use of PROXY V2 protocol */
 	{ "non-stick",   srv_parse_non_stick,   0,  1 }, /* Disable stick-table persistence */
+	{ "observe", srv_parse_observe, 1,  1 }, /* Enables health adjusting based on observing communication with the server */
 	{ "redir",   srv_parse_redir,   1,  1 }, /* Enable redirection mode */
 	{ "send-proxy",  srv_parse_send_proxy,  0,  1 }, /* Enforce use of PROXY V1 protocol */
 	{ "send-proxy-v2",   srv_parse_send_proxy_v2,   0,  1 }, /* Enforce use of PROXY V2 protocol */
@@ -1328,6 +1363,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			newsrv->minconn		= curproxy->defsrv.minconn;
 			newsrv->maxconn		= curproxy->defsrv.maxconn;
 			newsrv->slowstart	= curproxy->defsrv.slowstart;
+			newsrv->observe = curproxy->defsrv.observe;
 			newsrv->onerror		= curproxy->defsrv.onerror;
 			newsrv->onmarkeddown= curproxy->defsrv.onmarkeddown;
 			newsrv->onmarkedup  = curproxy->defsrv.onmarkedup;
@@ -1723,29 +1759,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->check.health = 0;
 cur_arg += 1;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "observe")) {
-if (!strcmp(args[cur_arg + 1], "none"))
-	newsrv->observe = HANA_OBS_NONE;
-else if (!strcmp(args[cur_arg + 1], "layer4"))
-	newsrv->observe = HANA_OBS_LAYER4;
-else if (!strcmp(args[cur_arg + 1], "layer7")) {
-	if (curproxy->mode != PR_MODE_HTTP) {
-		Alert("parsing [%s:%d]: '%s' can only be used in http proxies.\n",
-			file, linenum, args[cur_arg + 1]);
-		err_code |= ERR_ALERT;
-	}
-	newsrv->observe = HANA_OBS_LAYER7;
-}
-else {
-	Alert("parsing [%s:%d]: '%s' expects one of 'none', "
-		"'layer4', 'layer7' but got '%s'\n",
-		file, linenum, args[cur_arg], args[cur_arg + 1]);
-	err_code |= ERR_ALERT | ERR_FATAL;
-	goto out;
-}
-
-cur_arg += 2;
-			}
 			else if (!strcmp(args[cur_arg], "on-error")) {
 if (!strcmp(args[cur_arg + 1], "fastinter"))
 	newsrv->onerror = HANA_ONERR_FASTINTER;
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 617a66ec167fd7b780028a7a58b44546dba3e810 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 14 Mar 2017 16:42:49 +0100
Subject: [PATCH 20/31] MINOR: server: Make 'default-server' support 'redir'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

Before this patch only 'server' directives could support 'redir' setting.
This patch makes also 'default-server' directives support 'redir' setting.
Should not break anything.
---
 src/server.c | 29 -
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/src/server.c b/src/server.c
index c94e5dc..1fc10c5 100644
--- a/src/server.c
+++ b/src/server.c
@@ -331,6 +331,25 @@ static int inline srv_enable_pp_flags(struct server *srv, unsigned int flags)
 	return 0;
 }
 
+/* Parse the "redir" server keyword */
+static int srv_parse_redir(char **args, int *cur_arg,
+   struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	char *arg;
+
+	arg = args[*cur_arg + 1];
+	if (!*arg) {
+		memprintf(err, "'%s' expects  as argument.\n", args[*cur_arg]);
+		return ERR_ALERT | ERR_FATAL;
+	}
+
+	free(newsrv->rdr_pfx);
+	newsrv->rdr_pfx = strdup(arg);
+	newsrv->rdr_len = strlen(arg);
+
+	return 0;
+}
+
 /* Parse the "send-proxy" server keyword */
 static int srv_parse_send_proxy(char **args, int *cur_arg,
 struct proxy *curproxy, struct server *newsrv, char **err)
@@ -990,6 +1009,7 @@ static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "no-send-proxy",   srv_parse_no_send_proxy,   0,  1 }, /* Disable use of PROXY V1 protocol */
 	{ "no-send-proxy-v2",srv_parse_no_send_proxy_v2,0,  1 }, /* Disable use of PROXY V2 protocol */
 	{ "non-stick",   srv_parse_non_stick,   0,  1 }, /* Disable stick-table persistence */
+	{ "redir",   srv_parse_redir,   1,  1 }, /* Enable redirection mode */
 	{ "send-proxy",  srv_parse_send_proxy,  0,  1 }, /* Enforce use of PROXY V1 protocol */
 	{ "send-proxy-v2",   srv_parse_send_proxy_v2,   0,  1 }, /* Enforce use of PROXY V2 protocol */
 	{ "stick",   srv_parse_stick,   0,  1 }, /* Enable stick-table persistence */
@@ -1281,6 +1301,10 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			}
 
 			newsrv->pp_opts		= curproxy->defsrv.pp_opts;
+			if (curproxy->defsrv.rdr_pfx != NULL) {
+newsrv->rdr_pfx = strdup(curproxy->defsrv.rdr_pfx);
+newsrv->rdr_len = curproxy->defsrv.rdr_len;
+			}
 			newsrv->use_ssl		= curproxy->defsrv.use_ssl;
 			newsrv->check.use_ssl	= curproxy->defsrv.check.use_ssl;
 			newsrv->check.port	= curproxy->defsrv.check.port;
@@ -1454,11 +1478,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 }
 cur_arg += 2;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "redir")) {
-newsrv->rdr_pfx = strdup(args[cur_arg + 1]);
-newsrv->rdr_len = strlen(args[cur_arg + 1]);
-cur_arg += 2;
-			}
 			else if (!strcmp(args[cur_arg], "resolvers")) {
 newsrv->resolvers_id = strdup(args[cur_arg + 1]);
 cur_arg += 2;
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 6ab43989ab00ceef2b681bac8ac919f3fd25311f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Wed, 15 Mar 2017 09:13:33 +0100
Subject: [PATCH 22/31] MINOR: server: Make 'default-server' support 'cookie'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

Before this patch, 'cookie' setting was only supported by 'server' directives.
This patch makes 'default-server' directive also support 'cookie' setting.
Should not break anything.
---
 src/server.c | 30 --
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/src/server.c b/src/server.c
index b855b1b..79dcca7 100644
--- a/src/server.c
+++ b/src/server.c
@@ -237,6 +237,25 @@ static int srv_parse_check_send_proxy(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Parse the "cookie" server keyword */
+static int srv_parse_cookie(char **args, int *cur_arg,
+struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	char *arg;
+
+	arg = args[*cur_arg + 1];
+	if (!*arg) {
+		memprintf(err, "'%s' expects  as argument.\n", args[*cur_arg]);
+		return ERR_ALERT | ERR_FATAL;
+	}
+
+	free(newsrv->cookie);
+	newsrv->cookie = strdup(arg);
+	newsrv->cklen = strlen(arg);
+	newsrv->flags |= SRV_F_COOKIESET;
+	return 0;
+}
+
 /* parse the "id" server keyword */
 static int srv_parse_id(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err)
 {
@@ -1036,6 +1055,7 @@ static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "backup",  srv_parse_backup,  0,  1 }, /* Flag as backup server */
 	{ "check",   srv_parse_check,   0,  1 }, /* enable health checks */
 	{ "check-send-proxy",srv_parse_check_send_proxy,0,  1 }, /* enable PROXY protocol for health checks */
+	{ "cookie",  srv_parse_cookie,  1,  1 }, /* Assign a cookie to the server */
 	{ "id",  srv_parse_id,  1,  0 }, /* set id# of server */
 	{ "no-backup",   srv_parse_no_backup,   0,  1 }, /* Flag as non-backup server */
 	{ "no-check",srv_parse_no_check,0,  1 }, /* disable health checks */
@@ -1340,6 +1360,10 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->rdr_pfx = strdup(curproxy->defsrv.rdr_pfx);
 newsrv->rdr_len = curproxy->defsrv.rdr_len;
 			}
+			if (curproxy->defsrv.cookie != NULL) {
+newsrv->cookie = strdup(curproxy->defsrv.cookie);
+newsrv->cklen = curproxy->defsrv.cklen;
+			}
 			newsrv->use_ssl		= curproxy->defsrv.use_ssl;
 			newsrv->check.use_ssl	= curproxy->defsrv.check.use_ssl;
 			newsrv->check.port	= curproxy->defsrv.check.port;
@@ -1459,12 +1483,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 memcpy(newsrv->agent.send_string, args[cur_arg + 1], newsrv->agent.send_string_len);
 cur_arg += 2;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "cookie")) {
-newsrv->cookie = strdup(args[cur_arg + 1]);
-newsrv->cklen = strlen(args[cur_arg + 1]);
-newsrv->flags |= SRV_F_COOKIESET;
-cur_arg += 2;
-			}
 			else if (!strcmp(args[cur_arg], "init-addr")) {
 char *p, *end;
 int done;
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 93f6899637050a8c00549d8b127c19d5e7aad81a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Wed, 15 Mar 2017 16:36:09 +0100
Subject: [PATCH 24/31] MINOR: server: Make 'default-server' support 'tcp-ut'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directive support 'tcp-ut' keyword.
---
 src/proto_tcp.c | 2 +-
 src/server.c| 5 +
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 4741651..b664831 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1833,7 +1833,7 @@ static struct bind_kw_list bind_kws = { "TCP", { }, {
 
 static struct srv_kw_list srv_kws = { "TCP", { }, {
 #ifdef TCP_USER_TIMEOUT
-	{ "tcp-ut",srv_parse_tcp_ut,1,  0 }, /* set TCP user timeout on server */
+	{ "tcp-ut",srv_parse_tcp_ut,1,  1 }, /* set TCP user timeout on server */
 #endif
 	{ NULL, NULL, 0 },
 }};
diff --git a/src/server.c b/src/server.c
index a9cfac3..7654211 100644
--- a/src/server.c
+++ b/src/server.c
@@ -13,6 +13,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -1435,6 +1436,10 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->ssl_ctx.ciphers = strdup(curproxy->defsrv.ssl_ctx.ciphers);
 #endif
 
+#ifdef TCP_USER_TIMEOUT
+			newsrv->tcp_ut = curproxy->defsrv.tcp_ut;
+#endif
+
 			cur_arg = 3;
 		} else {
 			newsrv = >defsrv;
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From ffaf903ad7d5c7b9920e1e32ddc4f510365e8e5c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 13 Mar 2017 15:52:01 +0100
Subject: [PATCH 15/31] MINOR: server: Make 'default-server' support
 'verifyhost' setting.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directive support 'verifyhost' setting.
Note: there was a little memory leak when several 'verifyhost' arguments were
supplied on the same 'server' line.
---
 src/server.c   | 2 ++
 src/ssl_sock.c | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/server.c b/src/server.c
index b69d1d1..5819b75 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1298,6 +1298,8 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 #if defined(USE_OPENSSL)
 			/* SSL config. */
 			newsrv->ssl_ctx.verify = curproxy->defsrv.ssl_ctx.verify;
+			if (curproxy->defsrv.ssl_ctx.verify_host != NULL)
+newsrv->ssl_ctx.verify_host = strdup(curproxy->defsrv.ssl_ctx.verify_host);
 #endif
 
 			cur_arg = 3;
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 5285e24..34860fe 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -6792,6 +6792,7 @@ static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, str
 		return ERR_ALERT | ERR_FATAL;
 	}
 
+	free(newsrv->ssl_ctx.verify_host);
 	newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
 
 	return 0;
@@ -7518,7 +7519,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
 	{ "tlsv12",  srv_parse_tlsv12,0, 1 }, /* enable TLSv12 */
 	{ "tls-tickets", srv_parse_tls_tickets,   0, 1 }, /* enable session resumption tickets */
 	{ "verify",  srv_parse_verify,1, 1 }, /* set SSL verify method */
-	{ "verifyhost",  srv_parse_verifyhost,1, 0 }, /* require that SSL cert verifies for hostname */
+	{ "verifyhost",  srv_parse_verifyhost,1, 1 }, /* require that SSL cert verifies for hostname */
 	{ NULL, NULL, 0, 0 },
 }};
 
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 6b94e45e66da74f50c42b11cd3c087f0be991513 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 14 Mar 2017 15:21:31 +0100
Subject: [PATCH 18/31] MINOR: server: Make 'default-server' support 'track'
 setting.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

Before this patch only 'server' directives could support 'track' setting.
This patch makes 'default-server' directives also support this setting.
Should not break anything.
---
 src/server.c | 34 +-
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/src/server.c b/src/server.c
index 87d2448..988abee 100644
--- a/src/server.c
+++ b/src/server.c
@@ -353,6 +353,24 @@ static int srv_parse_stick(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Parse the "track" server keyword */
+static int srv_parse_track(char **args, int *cur_arg,
+   struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	char *arg;
+
+	arg = args[*cur_arg + 1];
+	if (!*arg) {
+		memprintf(err, "'track' expects [/] as argument.\n");
+		return ERR_ALERT | ERR_FATAL;
+	}
+
+	free(newsrv->trackit);
+	newsrv->trackit = strdup(arg);
+
+	return 0;
+}
+
 /* Shutdown all connections of a server. The caller must pass a termination
  * code in , which must be one of SF_ERR_* indicating the reason for the
  * shutdown.
@@ -975,6 +993,7 @@ static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "send-proxy",  srv_parse_send_proxy,  0,  1 }, /* Enforce use of PROXY V1 protocol */
 	{ "send-proxy-v2",   srv_parse_send_proxy_v2,   0,  1 }, /* Enforce use of PROXY V2 protocol */
 	{ "stick",   srv_parse_stick,   0,  1 }, /* Enable stick-table persistence */
+	{ "track",   srv_parse_track,   1,  1 }, /* Set the current state of the server, tracking another one */
 	{ NULL, NULL, 0 },
 }};
 
@@ -1288,6 +1307,8 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			newsrv->onerror		= curproxy->defsrv.onerror;
 			newsrv->onmarkeddown= curproxy->defsrv.onmarkeddown;
 			newsrv->onmarkedup  = curproxy->defsrv.onmarkedup;
+			if (curproxy->defsrv.trackit != NULL)
+newsrv->trackit = strdup(curproxy->defsrv.trackit);
 			newsrv->consecutive_errors_limit
 		= curproxy->defsrv.consecutive_errors_limit;
 			newsrv->uweight = newsrv->iweight
@@ -1669,19 +1690,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->slowstart = (val + 999) / 1000;
 cur_arg += 2;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "track")) {
-
-if (!*args[cur_arg + 1]) {
-	Alert("parsing [%s:%d]: 'track' expects [/] as argument.\n",
-		file, linenum);
-	err_code |= ERR_ALERT | ERR_FATAL;
-	goto out;
-}
-
-newsrv->trackit = strdup(args[cur_arg + 1]);
-
-cur_arg += 2;
-			}
 			else if (!defsrv && !strcmp(args[cur_arg], "disabled")) {
 newsrv->admin |= SRV_ADMF_CMAINT;
 newsrv->admin |= SRV_ADMF_FMAINT;
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 174406c72eae257d07e2239a9aea6284a644017a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 14 Mar 2017 11:20:13 +0100
Subject: [PATCH 16/31] MINOR: server: Make 'default-server' support 'check'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

Before this patch 'check' setting was only supported by 'server' directives.
This patch makes also 'default-server' directives support this setting.
A new 'no-check' keyword parser has been implemented to disable this setting both
in 'default-server' and 'server' directives.
Should not break anything.
---
 include/types/server.h |  1 +
 src/server.c   | 33 +
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/include/types/server.h b/include/types/server.h
index feede6d..c973d69 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -240,6 +240,7 @@ struct server {
 	int puid;/* proxy-unique server ID, used for SNMP, and "first" LB algo */
 	int tcp_ut; /* for TCP, user timeout */
 
+	int do_check;   /* temporary variable used during parsing to denote if health checks must be enabled */
 	struct check check; /* health-check specific configuration */
 	struct check agent; /* agent specific configuration */
 
diff --git a/src/server.c b/src/server.c
index 5819b75..87d2448 100644
--- a/src/server.c
+++ b/src/server.c
@@ -221,6 +221,14 @@ static int srv_parse_backup(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Parse the "check" server keyword */
+static int srv_parse_check(char **args, int *cur_arg,
+   struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	newsrv->do_check = 1;
+	return 0;
+}
+
 /* Parse the "check-send-proxy" server keyword */
 static int srv_parse_check_send_proxy(char **args, int *cur_arg,
   struct proxy *curproxy, struct server *newsrv, char **err)
@@ -269,6 +277,16 @@ static int srv_parse_no_backup(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Parse the "no-check" server keyword */
+static int srv_parse_no_check(char **args, int *cur_arg,
+  struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	free_check(>check);
+	newsrv->check.state &= ~CHK_ST_CONFIGURED | ~CHK_ST_ENABLED;
+	newsrv->do_check = 0;
+	return 0;
+}
+
 /* Parse the "no-check-send-proxy" server keyword */
 static int srv_parse_no_check_send_proxy(char **args, int *cur_arg,
  struct proxy *curproxy, struct server *newsrv, char **err)
@@ -945,9 +963,11 @@ void srv_compute_all_admin_states(struct proxy *px)
  */
 static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "backup",  srv_parse_backup,  0,  1 }, /* Flag as backup server */
+	{ "check",   srv_parse_check,   0,  1 }, /* enable health checks */
 	{ "check-send-proxy",srv_parse_check_send_proxy,0,  1 }, /* enable PROXY protocol for health checks */
 	{ "id",  srv_parse_id,  1,  0 }, /* set id# of server */
 	{ "no-backup",   srv_parse_no_backup,   0,  1 }, /* Flag as non-backup server */
+	{ "no-check",srv_parse_no_check,0,  1 }, /* disable health checks */
 	{ "no-check-send-proxy", srv_parse_no_check_send_proxy, 0,  1 }, /* disable PROXY protol for health checks */
 	{ "no-send-proxy",   srv_parse_no_send_proxy,   0,  1 }, /* Disable use of PROXY V1 protocol */
 	{ "no-send-proxy-v2",srv_parse_no_send_proxy_v2,0,  1 }, /* Disable use of PROXY V2 protocol */
@@ -1110,7 +1130,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 
 	if (!strcmp(args[0], "server") || !strcmp(args[0], "default-server")) {  /* server address */
 		int cur_arg;
-		int do_agent = 0, do_check = 0, defsrv = (*args[0] == 'd');
+		int do_agent = 0, defsrv = (*args[0] == 'd');
 
 		if (!defsrv && curproxy == defproxy) {
 			Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
@@ -1160,7 +1180,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			LIST_INIT(>priv_conns);
 			LIST_INIT(>idle_conns);
 			LIST_INIT(>safe_conns);
-			do_check = 0;
 			do_agent = 0;
 			newsrv->flags = 0;
 			newsrv->admin = 0;
@@ -1248,6 +1267,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			newsrv->check.port	= curproxy->defsrv.check.port;
 			/* Note: 'flags' field has potentially been already initialized. */
 			newsrv->flags   |= curproxy->defsrv.flags;
+			newsrv->do_check= curproxy->defsrv.do_check;
 			if (newsrv->check.port)
 newsrv->flags |= SRV_F_CHECKPORT;
 			newsrv->check.inter	= curproxy->defsrv.check.inter;
@@ -1662,11 +1682,6 @@ int parse_server(const 

Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 72440786d18c7e6141bf655287ce3d0c90aafc08 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 14 Mar 2017 14:32:17 +0100
Subject: [PATCH 17/31] BUG/MINOR: cfgparse: loop in tracked servers lists not
 detected by check_config_validity().
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

There is a silly case where a loop is not detected in tracked servers lists:
when a server tracks itself.

Ex:
   server srv1 127.0.0.1:8000 track srv1

Well, this never happens and this does not prevent haproxy from working.

But with this next following configuration:

   server srv1 127.0.0.1:8000 track srv2
   server srv2 127.0.0.1:8000 track srv2
   server srv3 127.0.0.1:8000 track srv2

the code in charge of detecting such loops never returns (without any error message).
haproxy becomes stuck in an infinite loop because of this statement found
in check_config_validity():

for (loop = srv->track; loop && loop != newsrv; loop = loop->track);

Again, such a configuration is never accidentally used I guess.
This latter example seems silly, but as several 'default-server' directives may be used
in the same proxy section, and as 'default-server' settings are not resetted each a
new 'default-server' line is created, it will match the following configuration, in the future,
when 'track' setting will be supported by 'default-server':

   default-server track srv3
   server srv1 127.0.0.1:8000
   server srv2 127.0.0.1:8000
   .
   .
   .
   default-server check
   server srv3 127.0.0.1:8000
---
 src/cfgparse.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/cfgparse.c b/src/cfgparse.c
index 2eb25ed..b03a821 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -8396,11 +8396,12 @@ out_uri_auth_compat:
 
 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
 
-if (loop) {
+if (newsrv == srv || loop) {
 	Alert("config : %s '%s', server '%s': unable to track %s/%s as it "
 	  "belongs to a tracking chain looping back to %s/%s.\n",
 	  proxy_type_str(curproxy), curproxy->id,
-	  newsrv->id, px->id, srv->id, px->id, loop->id);
+	  newsrv->id, px->id, srv->id, px->id,
+	  newsrv == srv ? srv->id : loop->id);
 	cfgerr++;
 	goto next_srv;
 }
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From 9da661d95b42cac3c65be783b4c8c71e900366e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 14 Mar 2017 15:52:04 +0100
Subject: [PATCH 19/31] MINOR: server: Make 'default-server' support 'ca-file',
 'crl-file' and 'crt' settings.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directives support 'ca-file', 'crl-file' and
'crt' settings.
---
 src/server.c   | 6 ++
 src/ssl_sock.c | 6 +++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/server.c b/src/server.c
index 988abee..c94e5dc 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1338,6 +1338,12 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			newsrv->init_addr = curproxy->defsrv.init_addr;
 #if defined(USE_OPENSSL)
 			/* SSL config. */
+			if (curproxy->defsrv.ssl_ctx.ca_file != NULL)
+newsrv->ssl_ctx.ca_file = strdup(curproxy->defsrv.ssl_ctx.ca_file);
+			if (curproxy->defsrv.ssl_ctx.crl_file != NULL)
+newsrv->ssl_ctx.crl_file = strdup(curproxy->defsrv.ssl_ctx.crl_file);
+			if (curproxy->defsrv.ssl_ctx.client_crt != NULL)
+newsrv->ssl_ctx.client_crt = strdup(curproxy->defsrv.ssl_ctx.crl_file);
 			newsrv->ssl_ctx.verify = curproxy->defsrv.ssl_ctx.verify;
 			if (curproxy->defsrv.ssl_ctx.verify_host != NULL)
 newsrv->ssl_ctx.verify_host = strdup(curproxy->defsrv.ssl_ctx.verify_host);
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 34860fe..72b3259 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -7485,11 +7485,11 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
  * not enabled.
  */
 static struct srv_kw_list srv_kws = { "SSL", { }, {
-	{ "ca-file", srv_parse_ca_file,   1, 0 }, /* set CAfile to process verify server cert */
+	{ "ca-file", srv_parse_ca_file,   1, 1 }, /* set CAfile to process verify server cert */
 	{ "check-ssl",   srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
 	{ "ciphers", srv_parse_ciphers,   1, 0 }, /* select the cipher suite */
-	{ "crl-file",srv_parse_crl_file,  1, 0 }, /* set certificate revocation list file use on server cert verify */
-	{ "crt", srv_parse_crt,   1, 0 }, /* set client certificate */
+	{ "crl-file",srv_parse_crl_file,  1, 1 }, /* set certificate revocation list file use on server cert verify */
+	{ "crt", srv_parse_crt,   1, 1 }, /* set client certificate */
 	{ "force-sslv3", srv_parse_force_sslv3,   0, 1 }, /* force SSLv3 */
 	{ "force-tlsv10",srv_parse_force_tlsv10,  0, 1 }, /* force TLSv10 */
 	{ "force-tlsv11",srv_parse_force_tlsv11,  0, 1 }, /* force TLSv11 */
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From b2b7b543da9c46b23c27672ed567d77df254848f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 21 Mar 2017 18:52:12 +0100
Subject: [PATCH 31/31] DOC: server: Add docs for "server" and "default-server"
 new "no-*" and other settings.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

New boolean settings have been added to disable others. Most of them have "no-" as prefix.

"enabled" disables "disabled" setting,
"no-agent-check" disables "agent-check",
"no-backup" disables "backup",
"no-check" disables "check",
"no-check-ssl" disables "check-ssl",
"no-force-sslv3" disables "force-sslv3",
"no-force-tlsv10" disables "force-tlsv10",
"no-force-tlsv11" disables "force-tlsv11",
"no-force-tlsv12" disables "force-tlsv12,
"no-send-proxy" disables "send-proxy",
"no-send-proxy-v2" disables "send-proxy-v2",
"no-send-proxy-v2-ssl" disables "send-proxy-v2-ssl",
"no-send-proxy-v2-ssl-cn" disables "send-proxy-v2-ssl-cn",
"no-ssl" disables "ssl",
"no-verifyhost" disables "verifyhost",
"sslv2" disables "no-sslv3",
"ssl-reuse" disables "no-ssl-reuse",
"stick" disables "non-stick",
"tlsv10" disables "no-tlsv10",
"tlsv11" disables "no-tlsv11",
"tlsv12" disables "no-tlsv12",
"tls-tickets" disables "no-tls-tickets".

Settings with arguments are now supported on "default-server" lines:

"addr", "ca-file", "ciphers", "crl-file", "crt", "cookie", "namespace", "observe",
"redir", "sni", "source", "tcp-ut" and "track".

>From now on, all server "settings" including the new ones above are supported by
"default-server" except "id" which is only supported on "server" lines.
---
 doc/configuration.txt | 306 +-
 1 file changed, 181 insertions(+), 125 deletions(-)
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 73a4f4b..0241ab1 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -10639,6 +10639,9 @@ address if they are used:
   server  [:port] [settings ...]
   default-server [settings ...]
 
+Note that all these settings are supported both by "server" and "default-server"
+keywords, except "id" which is only supported by "server".
+
 The currently supported settings are the following ones.
 
 addr 
@@ -10649,8 +10652,6 @@ addr 
   This parameter is ignored if the "check" parameter is not set. See also the
   "port" parameter.
 
-  Supported in default-server: No
-
 agent-check
   Enable an auxiliary agent check which is run independently of a regular
   health check. An agent health check is performed by making a TCP connection
@@ -10710,9 +10711,7 @@ agent-check
   force an agent's result in order to work around a bogus agent if needed.
 
   Requires the "agent-port" parameter to be set. See also the "agent-inter"
-  parameter.
-
-  Supported in default-server: No
+  and "no-agent-check" parameters.
 
 agent-send 
   If this option is specified, haproxy will send the given string (verbatim)
@@ -10737,8 +10736,6 @@ agent-inter 
 
   See also the "agent-check" and "agent-port" parameters.
 
-  Supported in default-server: Yes
-
 agent-addr 
   The "agent-addr" parameter sets address for agent check.
 
@@ -10752,25 +10749,19 @@ agent-port 
 
   See also the "agent-check" and "agent-inter" parameters.
 
-  Supported in default-server: Yes
-
 backup
   When "backup" is present on a server line, the server is only used in load
   balancing when all other non-backup servers are unavailable. Requests coming
   with a persistence cookie referencing the server will always be served
   though. By default, only the first operational backup server is used, unless
-  the "allbackups" option is set in the backend. See also the "allbackups"
-  option.
-
-  Supported in default-server: No
+  the "allbackups" option is set in the backend. See also the "no-backup" and
+  "allbackups" options.
 
 ca-file 
   This setting is only available when support for OpenSSL was built in. It
   designates a PEM file from which to load CA certificates used to verify
   server's certificate.
 
-  Supported in default-server: No
-
 check
   This option enables health checks on the server. By default, a server is
   always considered available. If "check" is set, the server is available when
@@ -10782,9 +10773,8 @@ check
   address, and the interval and timers using the "inter", "rise" and "fall"
   parameters. The request method is define in the backend using the "httpchk",
   "smtpchk", "mysql-check", "pgsql-check" and "ssl-hello-chk" options. Please
-  refer to those options and parameters for more information.
-
-  Supported in default-server: No
+  refer to those options and parameters for more information. See also
+  "no-check" option.
 
 check-send-proxy
   This option forces emission of a PROXY protocol line with outgoing health
@@ -10795,8 +10785,6 @@ check-send-proxy
   "check-send-proxy" option needs to be 

Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From d42d42d4d105320248277fb8fba040da02302c24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 21 Mar 2017 16:39:15 +0100
Subject: [PATCH 30/31] MINOR: server: Add 'no-agent-check' server keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch adds 'no-agent-check' setting supported both by 'default-server'
and 'server' directives to disable an agent check for a specific server which would
have 'agent-check' set as default value (inherited from 'default-server'
'agent-check' setting), or, on 'default-server' lines, to disable 'agent-check' setting
as default value for any further 'server' declarations.

For instance, provided this configuration:

default-server agent-check
server srv1
server srv2 no-agent-check
server srv3
default-server no-agent-check
server srv4

srv1 and srv3 would have an agent check enabled contrary to srv2 and srv4.

We do not allocate anymore anything when parsing 'default-server' 'agent-check'
setting.
---
 include/types/server.h |  1 +
 src/checks.c   |  3 +++
 src/server.c   | 35 +++
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/include/types/server.h b/include/types/server.h
index 781a889..bfaa941 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -241,6 +241,7 @@ struct server {
 	int tcp_ut; /* for TCP, user timeout */
 
 	int do_check;   /* temporary variable used during parsing to denote if health checks must be enabled */
+	int do_agent;   /* temporary variable used during parsing to denote if an auxiliary agent check must be enabled */
 	struct check check; /* health-check specific configuration */
 	struct check agent; /* agent specific configuration */
 
diff --git a/src/checks.c b/src/checks.c
index 77d57dc..778fc6a 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -3082,8 +3082,11 @@ const char *init_check(struct check *check, int type)
 void free_check(struct check *check)
 {
 	free(check->bi);
+	check->bi = NULL;
 	free(check->bo);
+	check->bo = NULL;
 	free(check->conn);
+	check->conn = NULL;
 }
 
 void email_alert_free(struct email_alert *alert)
diff --git a/src/server.c b/src/server.c
index 0274d84..6614a22 100644
--- a/src/server.c
+++ b/src/server.c
@@ -262,6 +262,14 @@ static int srv_parse_addr(char **args, int *cur_arg,
 	return ERR_ALERT | ERR_FATAL;
 }
 
+/* Parse the "agent-check" server keyword */
+static int srv_parse_agent_check(char **args, int *cur_arg,
+ struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	newsrv->do_agent = 1;
+	return 0;
+}
+
 /* Parse the "backup" server keyword */
 static int srv_parse_backup(char **args, int *cur_arg,
 struct proxy *curproxy, struct server *newsrv, char **err)
@@ -401,6 +409,18 @@ static int srv_parse_namespace(char **args, int *cur_arg,
 #endif
 }
 
+/* Parse the "no-agent-check" server keyword */
+static int srv_parse_no_agent_check(char **args, int *cur_arg,
+ struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	free_check(>agent);
+	newsrv->agent.inter = 0;
+	newsrv->agent.port = 0;
+	newsrv->agent.state &= ~CHK_ST_CONFIGURED & ~CHK_ST_ENABLED & ~CHK_ST_AGENT;
+	newsrv->do_agent = 0;
+	return 0;
+}
+
 /* Parse the "no-backup" server keyword */
 static int srv_parse_no_backup(char **args, int *cur_arg,
struct proxy *curproxy, struct server *newsrv, char **err)
@@ -1341,6 +1361,7 @@ void srv_compute_all_admin_states(struct proxy *px)
  */
 static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "addr",srv_parse_addr,1,  1 }, /* IP address to send health to or to probe from agent-check */
+	{ "agent-check", srv_parse_agent_check, 0,  1 }, /* Enable an auxiliary agent check */
 	{ "backup",  srv_parse_backup,  0,  1 }, /* Flag as backup server */
 	{ "check",   srv_parse_check,   0,  1 }, /* enable health checks */
 	{ "check-send-proxy",srv_parse_check_send_proxy,0,  1 }, /* enable PROXY protocol for health checks */
@@ -1349,6 +1370,7 @@ static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "enabled", srv_parse_enabled, 0,  1 }, /* Start the server in 'enabled' state */
 	{ "id",  srv_parse_id,  1,  0 }, /* set id# of server */
 	{ "namespace",   srv_parse_namespace,   1,  1 }, /* Namespace the server socket belongs to (if supported) */
+	{ "no-agent-check",  srv_parse_no_agent_check,  0,  1 }, /* Do not enable any auxiliary agent check */
 	{ "no-backup",   srv_parse_no_backup,   0,  1 }, /* Flag as non-backup server */
 	{ "no-check",

Re: All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille


>From d749c16ea9a94354998b853233b7558007bff4fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 21 Mar 2017 11:53:54 +0100
Subject: [PATCH 29/31] MINOR: server: Make 'default-server' support 'disabled'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

Before this patch, only 'server' directives could support 'disabled' setting.
This patch makes also 'default-server' directives support this setting.
It is used to disable a list of servers declared after a 'defaut-server' directive.
'enabled' new keyword has been added, both supported as 'default-server' and
'server' setting, to enable again a list of servers (so, declared after a
'default-server enabled' directive) or to explicitly enable a specific server declared
after a 'default-server disabled' directive.

For instance provided this configuration:

default-server disabled
server srv1...
server srv2...
server srv3... enabled
server srv4... enabled

srv1 and srv2 are disabled and srv3 and srv4 enabled.

This is equivalent to this configuration:

default-server disabled
server srv1...
server srv2...
default-server enabled
server srv3...
server srv4...

even if it would have been preferable/shorter to declare:

server srv3...
server srv4...
default-server disabled
server srv1...
server srv2...

as 'enabled' is the default server state.
---
 src/server.c | 39 +++
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/src/server.c b/src/server.c
index 83a7052..0274d84 100644
--- a/src/server.c
+++ b/src/server.c
@@ -305,6 +305,28 @@ static int srv_parse_cookie(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Parse the "disabled" server keyword */
+static int srv_parse_disabled(char **args, int *cur_arg,
+  struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	newsrv->admin |= SRV_ADMF_CMAINT | SRV_ADMF_FMAINT;
+	newsrv->state = SRV_ST_STOPPED;
+	newsrv->check.state |= CHK_ST_PAUSED;
+	newsrv->check.health = 0;
+	return 0;
+}
+
+/* Parse the "enabled" server keyword */
+static int srv_parse_enabled(char **args, int *cur_arg,
+ struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	newsrv->admin &= ~SRV_ADMF_CMAINT & ~SRV_ADMF_FMAINT;
+	newsrv->state = SRV_ST_RUNNING;
+	newsrv->check.state &= ~CHK_ST_PAUSED;
+	newsrv->check.health = newsrv->check.rise;
+	return 0;
+}
+
 /* parse the "id" server keyword */
 static int srv_parse_id(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err)
 {
@@ -1323,6 +1345,8 @@ static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "check",   srv_parse_check,   0,  1 }, /* enable health checks */
 	{ "check-send-proxy",srv_parse_check_send_proxy,0,  1 }, /* enable PROXY protocol for health checks */
 	{ "cookie",  srv_parse_cookie,  1,  1 }, /* Assign a cookie to the server */
+	{ "disabled",srv_parse_disabled,0,  1 }, /* Start the server in 'disabled' state */
+	{ "enabled", srv_parse_enabled, 0,  1 }, /* Start the server in 'enabled' state */
 	{ "id",  srv_parse_id,  1,  0 }, /* set id# of server */
 	{ "namespace",   srv_parse_namespace,   1,  1 }, /* Namespace the server socket belongs to (if supported) */
 	{ "no-backup",   srv_parse_no_backup,   0,  1 }, /* Flag as non-backup server */
@@ -1755,6 +1779,13 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			newsrv->check.rise	= curproxy->defsrv.check.rise;
 			newsrv->check.fall	= curproxy->defsrv.check.fall;
 			newsrv->check.health	= newsrv->check.rise;	/* up, but will fall down at first failure */
+			/* Here we check if 'disabled' is the default server state */
+			if (curproxy->defsrv.admin & (SRV_ADMF_CMAINT | SRV_ADMF_FMAINT)) {
+newsrv->admin |= SRV_ADMF_CMAINT | SRV_ADMF_FMAINT;
+newsrv->state = SRV_ST_STOPPED;
+newsrv->check.state |= CHK_ST_PAUSED;
+newsrv->check.health = 0;
+			}
 			newsrv->check.server	= newsrv;
 			newsrv->check.tcpcheck_rules	= >tcpcheck_rules;
 
@@ -2096,14 +2127,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 newsrv->slowstart = (val + 999) / 1000;
 cur_arg += 2;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "disabled")) {
-newsrv->admin |= SRV_ADMF_CMAINT;
-newsrv->admin |= SRV_ADMF_FMAINT;
-newsrv->state = SRV_ST_STOPPED;
-newsrv->check.state |= CHK_ST_PAUSED;
-newsrv->check.health = 0;
-cur_arg += 1;
-			}
 			else if (!strcmp(args[cur_arg], "on-error")) {
 if (!strcmp(args[cur_arg + 1], "fastinter"))
 	newsrv->onerror = HANA_ONERR_FASTINTER;
-- 
2.1.4



Re: All "server" settings supported on "default-server" lines

2017-03-22 Thread Frederic Lecaille

On 03/21/2017 11:14 PM, Willy Tarreau wrote:

Hi Fred!


Hello Willy,


On Tue, Mar 21, 2017 at 07:54:30PM +0100, Frederic Lecaille wrote:

Hello HAProxy ML,

I am starting this new thread to publish a serie of patches to make
all "server" settings be supported on "default-server" lines.

This is a preliminary work for "server templates" feature.

New boolean settings have been added to disable others. Most of them
have "no-" as prefix.

(...)

Wow I didn't realize you had already done all this! That's really cool!


Here is an exhaustive list:

(...)

"sslv2" disables "no-sslv3",
"ssl-reuse" disables "no-ssl-reuse",
"stick" disables "non-stick",
"tlsv10" disables "no-tlsv10",
"tlsv11" disables "no-tlsv11",
"tlsv12" disables "no-tlsv12",
"tls-tickets" disables "no-tls-tickets".


Hmmm I hadn't thought about these ones, I suspect they'll cause more
confusion than anything else, especially given that the "tlsv11" above
cancelling "no-tlsv11" is not the same as "force-tlsv11". We need to
discuss this with Emeric, he's already scratching his head around these
ones without these double negations, he will hate us now :-)



Yes I agree. I should have asked about this before posting. But from my 
point of view this is only a naming issue which may easily fixed.


Why no adding synonyms prefixed by "disallow-" for the existing 
"no(n)-*" options, and rename my silly new options to "allow-*"?


Or with "forbid(permit)-*" prefix (suffix)?

Anything else?

"no-force-*" is not very English, even for me ;)
Could be replaced by "do-not-force-*" but it's quite long.





Re: All "server" settings supported on "default-server" lines

2017-03-22 Thread Frederic Lecaille

On 03/22/2017 05:30 PM, Emmanuel Hocdet wrote:

Hi Fred,


Hi Emmanuel,


Le 21 mars 2017 à 23:14, Willy Tarreau <w...@1wt.eu> a écrit :
On Tue, Mar 21, 2017 at 07:54:30PM +0100, Frederic Lecaille wrote:

Hello HAProxy ML,

I am starting this new thread to publish a serie of patches to make
all "server" settings be supported on "default-server" lines.

This is a preliminary work for "server templates" feature.

New boolean settings have been added to disable others. Most of them
have "no-" as prefix.

(...)

Wow I didn't realize you had already done all this! That's really cool!



I agree :)


Here is an exhaustive list:

(...)

"sslv2" disables "no-sslv3",
"ssl-reuse" disables "no-ssl-reuse",
"stick" disables "non-stick",
"tlsv10" disables "no-tlsv10",
"tlsv11" disables "no-tlsv11",
"tlsv12" disables "no-tlsv12",
"tls-tickets" disables "no-tls-tickets".


Hmmm I hadn't thought about these ones, I suspect they'll cause more
confusion than anything else, especially given that the "tlsv11" above
cancelling "no-tlsv11" is not the same as "force-tlsv11". We need to
discuss this with Emeric, he's already scratching his head around these
ones without these double negations, he will hate us now :-)


I have patches sent in the ML who change the internal implementation of 
no/force-tlsxx and add min/max-tlsxx (who can replace no/force usage).
It could simplify (or not)  what you want to do, but there will be an impact on 
your patches if they are accepted.

++
Manu



Ok. Thank your for these information Emmanuel,

Fred





Re: BUG FIX: All "server" settings supported on "default-server" lines

2017-03-29 Thread Frederic Lecaille

On 03/29/2017 02:35 PM, Frederic Lecaille wrote:

Hello Willy,

As I began to work on server template feature, I found a bug in patch
#0019 (due to a copy and paste again).

Here is a new patch.

Sorry for this one.

Fred


Here is a patch which fixes this bug, to be merged with current haproxy 
sources.
>From 779867f29c5ca6c2e22e352811c0dbc99a2a96fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Wed, 29 Mar 2017 14:58:09 +0200
Subject: [PATCH] BUG/MEDIUM: server: Wrong server default CRT filenames
 initialization.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch fixes a bug which came with 5e57643 commit where server
default CRT filenames were initialized to the same value as server
default CRL filenames.
---
 src/server.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/server.c b/src/server.c
index eedd878..0795e25 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1832,7 +1832,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			if (curproxy->defsrv.ssl_ctx.crl_file != NULL)
 newsrv->ssl_ctx.crl_file = strdup(curproxy->defsrv.ssl_ctx.crl_file);
 			if (curproxy->defsrv.ssl_ctx.client_crt != NULL)
-newsrv->ssl_ctx.client_crt = strdup(curproxy->defsrv.ssl_ctx.crl_file);
+newsrv->ssl_ctx.client_crt = strdup(curproxy->defsrv.ssl_ctx.client_crt);
 			newsrv->ssl_ctx.verify = curproxy->defsrv.ssl_ctx.verify;
 			if (curproxy->defsrv.ssl_ctx.verify_host != NULL)
 newsrv->ssl_ctx.verify_host = strdup(curproxy->defsrv.ssl_ctx.verify_host);
-- 
2.1.4



Re: BUG FIX: All "server" settings supported on "default-server" lines

2017-03-29 Thread Frederic Lecaille


Hello Willy,

As I began to work on server template feature, I found a bug in patch 
#0019 (due to a copy and paste again).


Here is a new patch.

Sorry for this one.

Fred

>From 9da661d95b42cac3c65be783b4c8c71e900366e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 14 Mar 2017 15:52:04 +0100
Subject: [PATCH 19/31] MINOR: server: Make 'default-server' support 'ca-file',
 'crl-file' and 'crt' settings.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

This patch makes 'default-server' directives support 'ca-file', 'crl-file' and
'crt' settings.
---
 src/server.c   | 6 ++
 src/ssl_sock.c | 6 +++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/server.c b/src/server.c
index 988abee..c94e5dc 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1338,6 +1338,12 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			newsrv->init_addr = curproxy->defsrv.init_addr;
 #if defined(USE_OPENSSL)
 			/* SSL config. */
+			if (curproxy->defsrv.ssl_ctx.ca_file != NULL)
+newsrv->ssl_ctx.ca_file = strdup(curproxy->defsrv.ssl_ctx.ca_file);
+			if (curproxy->defsrv.ssl_ctx.crl_file != NULL)
+newsrv->ssl_ctx.crl_file = strdup(curproxy->defsrv.ssl_ctx.crl_file);
+			if (curproxy->defsrv.ssl_ctx.client_crt != NULL)
+newsrv->ssl_ctx.client_crt = strdup(curproxy->defsrv.ssl_ctx.client_crt);
 			newsrv->ssl_ctx.verify = curproxy->defsrv.ssl_ctx.verify;
 			if (curproxy->defsrv.ssl_ctx.verify_host != NULL)
 newsrv->ssl_ctx.verify_host = strdup(curproxy->defsrv.ssl_ctx.verify_host);
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 34860fe..72b3259 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -7485,11 +7485,11 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
  * not enabled.
  */
 static struct srv_kw_list srv_kws = { "SSL", { }, {
-	{ "ca-file", srv_parse_ca_file,   1, 0 }, /* set CAfile to process verify server cert */
+	{ "ca-file", srv_parse_ca_file,   1, 1 }, /* set CAfile to process verify server cert */
 	{ "check-ssl",   srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
 	{ "ciphers", srv_parse_ciphers,   1, 0 }, /* select the cipher suite */
-	{ "crl-file",srv_parse_crl_file,  1, 0 }, /* set certificate revocation list file use on server cert verify */
-	{ "crt", srv_parse_crt,   1, 0 }, /* set client certificate */
+	{ "crl-file",srv_parse_crl_file,  1, 1 }, /* set certificate revocation list file use on server cert verify */
+	{ "crt", srv_parse_crt,   1, 1 }, /* set client certificate */
 	{ "force-sslv3", srv_parse_force_sslv3,   0, 1 }, /* force SSLv3 */
 	{ "force-tlsv10",srv_parse_force_tlsv10,  0, 1 }, /* force TLSv10 */
 	{ "force-tlsv11",srv_parse_force_tlsv11,  0, 1 }, /* force TLSv11 */
-- 
2.1.4




Re: BUG FIX : All "server" settings supported on "default-server" lines

2017-03-21 Thread Frederic Lecaille

This is an updated 0016 patch which fixes a typo.



>From 8ebde4a9d6931ed1fc2c9b6b8a93e3a69fd5d53a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 14 Mar 2017 11:20:13 +0100
Subject: [PATCH 16/31] MINOR: server: Make 'default-server' support 'check'
 keyword.
X-Bogosity: Ham, tests=bogofilter, spamicity=0.00, version=1.2.4

Before this patch 'check' setting was only supported by 'server' directives.
This patch makes also 'default-server' directives support this setting.
A new 'no-check' keyword parser has been implemented to disable this setting both
in 'default-server' and 'server' directives.
Should not break anything.
---
 include/types/server.h |  1 +
 src/server.c   | 33 +
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/include/types/server.h b/include/types/server.h
index feede6d..c973d69 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -240,6 +240,7 @@ struct server {
 	int puid;/* proxy-unique server ID, used for SNMP, and "first" LB algo */
 	int tcp_ut; /* for TCP, user timeout */
 
+	int do_check;   /* temporary variable used during parsing to denote if health checks must be enabled */
 	struct check check; /* health-check specific configuration */
 	struct check agent; /* agent specific configuration */
 
diff --git a/src/server.c b/src/server.c
index 5819b75..e3a5b25 100644
--- a/src/server.c
+++ b/src/server.c
@@ -221,6 +221,14 @@ static int srv_parse_backup(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Parse the "check" server keyword */
+static int srv_parse_check(char **args, int *cur_arg,
+   struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	newsrv->do_check = 1;
+	return 0;
+}
+
 /* Parse the "check-send-proxy" server keyword */
 static int srv_parse_check_send_proxy(char **args, int *cur_arg,
   struct proxy *curproxy, struct server *newsrv, char **err)
@@ -269,6 +277,16 @@ static int srv_parse_no_backup(char **args, int *cur_arg,
 	return 0;
 }
 
+/* Parse the "no-check" server keyword */
+static int srv_parse_no_check(char **args, int *cur_arg,
+  struct proxy *curproxy, struct server *newsrv, char **err)
+{
+	free_check(>check);
+	newsrv->check.state &= ~CHK_ST_CONFIGURED & ~CHK_ST_ENABLED;
+	newsrv->do_check = 0;
+	return 0;
+}
+
 /* Parse the "no-check-send-proxy" server keyword */
 static int srv_parse_no_check_send_proxy(char **args, int *cur_arg,
  struct proxy *curproxy, struct server *newsrv, char **err)
@@ -945,9 +963,11 @@ void srv_compute_all_admin_states(struct proxy *px)
  */
 static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "backup",  srv_parse_backup,  0,  1 }, /* Flag as backup server */
+	{ "check",   srv_parse_check,   0,  1 }, /* enable health checks */
 	{ "check-send-proxy",srv_parse_check_send_proxy,0,  1 }, /* enable PROXY protocol for health checks */
 	{ "id",  srv_parse_id,  1,  0 }, /* set id# of server */
 	{ "no-backup",   srv_parse_no_backup,   0,  1 }, /* Flag as non-backup server */
+	{ "no-check",srv_parse_no_check,0,  1 }, /* disable health checks */
 	{ "no-check-send-proxy", srv_parse_no_check_send_proxy, 0,  1 }, /* disable PROXY protol for health checks */
 	{ "no-send-proxy",   srv_parse_no_send_proxy,   0,  1 }, /* Disable use of PROXY V1 protocol */
 	{ "no-send-proxy-v2",srv_parse_no_send_proxy_v2,0,  1 }, /* Disable use of PROXY V2 protocol */
@@ -1110,7 +1130,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 
 	if (!strcmp(args[0], "server") || !strcmp(args[0], "default-server")) {  /* server address */
 		int cur_arg;
-		int do_agent = 0, do_check = 0, defsrv = (*args[0] == 'd');
+		int do_agent = 0, defsrv = (*args[0] == 'd');
 
 		if (!defsrv && curproxy == defproxy) {
 			Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
@@ -1160,7 +1180,6 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			LIST_INIT(>priv_conns);
 			LIST_INIT(>idle_conns);
 			LIST_INIT(>safe_conns);
-			do_check = 0;
 			do_agent = 0;
 			newsrv->flags = 0;
 			newsrv->admin = 0;
@@ -1248,6 +1267,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			newsrv->check.port	= curproxy->defsrv.check.port;
 			/* Note: 'flags' field has potentially been already initialized. */
 			newsrv->flags   |= curproxy->defsrv.flags;
+			newsrv->do_check= curproxy->defsrv.do_check;
 			if (newsrv->check.port)
 newsrv->flags |= SRV_F_CHECKPORT;
 			newsrv->check.inter	= 

server templates

2017-04-07 Thread Frederic Lecaille

Hello Haproxy ML,

Here are patches attached to this mail to add "server templates" feature 
to haproxy.


The two first patches consist in moving code to be reused both during 
'server' lines parsing and during and server templates initializations.

A new CLI command has also been added (see "init server-templates backend).

Third patch adds server_templates_init() function to be called to 
initialize server templates attached to a proxy server list.


The remaining patch adds support for 'server-templates' configuration 
file new keyword and updates the documentation.


Feel free to review/test/comment upon these patches. Any suggestion, are 
welcome.


Regards,

Fred.
>From 423489c434f9152b26ed3f6bde61bbb1db8cde5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Thu, 30 Mar 2017 14:18:30 +0200
Subject: [PATCH 1/4] MINOR: server: Extract the code responsible of copying
 default-server settings.

This patch moves the code responsible of copying default server settings
to a new server instance from parse_server() function to new defsrv_*_cpy()
functions which may be used both during server lines parsing and during server
templates initializations to come.

These defsrv_*_cpy() do not make any reference to anything else than default
server settings.
---
 src/server.c | 325 ++-
 1 file changed, 187 insertions(+), 138 deletions(-)

diff --git a/src/server.c b/src/server.c
index 23343d8..897b8c0 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1580,6 +1580,189 @@ static void display_parser_err(const char *file, int linenum, char **args, int c
 		  file, linenum, args[0], args[1], args[cur_arg]);
 }
 
+static void defsrv_conn_src_sport_range_cpy(struct server *srv,
+struct server *defsrv)
+{
+	int range_sz;
+
+	range_sz = defsrv->conn_src.sport_range->size;
+	if (range_sz > 0) {
+		srv->conn_src.sport_range = port_range_alloc_range(range_sz);
+		if (srv->conn_src.sport_range != NULL) {
+			int i;
+
+			for (i = 0; i < range_sz; i++) {
+srv->conn_src.sport_range->ports[i] =
+	defsrv->conn_src.sport_range->ports[i];
+			}
+		}
+	}
+}
+
+/*
+ * Copy  connection source settings to  server object connection
+ * allocating everything needed.
+ */
+static void defsrv_conn_src_cpy(struct server *srv, struct server *defsrv)
+{
+	srv->conn_src.opts = defsrv->conn_src.opts;
+	srv->conn_src.source_addr = defsrv->conn_src.source_addr;
+
+	/* Source port range copy. */
+	if (defsrv->conn_src.sport_range != NULL)
+		defsrv_conn_src_sport_range_cpy(srv, defsrv);
+
+	if (defsrv->conn_src.bind_hdr_name != NULL) {
+		srv->conn_src.bind_hdr_name = strdup(defsrv->conn_src.bind_hdr_name);
+		srv->conn_src.bind_hdr_len = strlen(defsrv->conn_src.bind_hdr_name);
+	}
+	srv->conn_src.bind_hdr_occ = defsrv->conn_src.bind_hdr_occ;
+	srv->conn_src.tproxy_addr  = defsrv->conn_src.tproxy_addr;
+	if (defsrv->conn_src.iface_name != NULL)
+		srv->conn_src.iface_name = strdup(defsrv->conn_src.iface_name);
+}
+
+/*
+ * Copy  server SSL settings to  server allocating
+ * everything needed.
+ */
+#if defined(USE_OPENSSL)
+static void defsrv_ssl_settings_cpy(struct server *srv, struct server *defsrv)
+{
+	if (defsrv->ssl_ctx.ca_file != NULL)
+		srv->ssl_ctx.ca_file = strdup(defsrv->ssl_ctx.ca_file);
+	if (defsrv->ssl_ctx.crl_file != NULL)
+		srv->ssl_ctx.crl_file = strdup(defsrv->ssl_ctx.crl_file);
+	if (defsrv->ssl_ctx.client_crt != NULL)
+		srv->ssl_ctx.client_crt = strdup(defsrv->ssl_ctx.client_crt);
+
+	srv->ssl_ctx.verify = defsrv->ssl_ctx.verify;
+
+	if (defsrv->ssl_ctx.verify_host != NULL)
+		srv->ssl_ctx.verify_host = strdup(defsrv->ssl_ctx.verify_host);
+	if (defsrv->ssl_ctx.ciphers != NULL)
+		srv->ssl_ctx.ciphers = strdup(defsrv->ssl_ctx.ciphers);
+	if (defsrv->sni_expr != NULL)
+		srv->sni_expr = strdup(defsrv->sni_expr);
+}
+#endif
+
+/*
+ * Copy  server settings to  server allocating
+ * everything needed.
+ */
+static void defsrv_settings_cpy(struct server *srv, struct server *defsrv)
+{
+	/* Connection source settings copy */
+	defsrv_conn_src_cpy(srv, defsrv);
+
+	srv->pp_opts = defsrv->pp_opts;
+	if (defsrv->rdr_pfx != NULL) {
+		srv->rdr_pfx = strdup(defsrv->rdr_pfx);
+		srv->rdr_len = defsrv->rdr_len;
+	}
+	if (defsrv->cookie != NULL) {
+		srv->cookie = strdup(defsrv->cookie);
+		srv->cklen  = defsrv->cklen;
+	}
+	srv->use_ssl  = defsrv->use_ssl;
+	srv->check.addr = srv->agent.addr = defsrv->check.addr;
+	srv->check.use_ssl= defsrv->check.use_ssl;
+	srv->check.port   = defsrv->check.port;
+	/* Note: 'flags' field has potentially been already initialized. */
+	srv->flags   |= defsrv->flags;
+	srv->do_check = defsrv->do_check;
+	srv->do_agent = defsrv->do_agent;
+	if (srv->check.port)
+		srv->flags |= SRV_F_CHECKPORT;
+	srv->check.inter  = defsrv->check.inter;
+	

Re: server templates

2017-04-10 Thread Frederic Lecaille

On 04/08/2017 01:27 AM, Aleksandar Lazic wrote:

Hi Frederic


Hi Aleksandar,


Am 07-04-2017 15:00, schrieb Frederic Lecaille:

Hello Haproxy ML,

Here are patches attached to this mail to add "server templates"
feature to haproxy.


Please can you explain a little bit more the use case, thanks.
I'm sure there is a valid use case but I don't understand it.


haproxy allocates as much as possible everything required before 
starting doing its job. This is the case for 'server' objects. A static 
predefined list of servers, written in configuration files, is 
potentially allocated for each backend during configuration files parsing.


With server templates, haproxy could preallocate 'server' objects which 
would derive from 'default-server' (with same settings as default server 
settings), but with remaining parameters which are unknown at parsing 
time (for instance their names, addresses, anything else). In fact here, 
names or addresses are particular settings: a default server has not any 
default name or default address.


With server templates, haproxy would not have to allocate any 'server' 
after having parsed its configuration files. It could use an already 
allocated server template and set its remaining settings which were 
unknown at configuration files parsing time.


This may be useful to instantiate servers which are discovered after 
having parsed any configuration files.



The two first patches consist in moving code to be reused both during
'server' lines parsing and during and server templates
initializations.

A new CLI command has also been added (see "init server-templates
backend).



I think this is a more general request which could be discussed in 
another thread. From my point of view, regarding server templates, as 
they are more dynamic than 'server's, they are not supposed to be saved, 
because potentially different between two different haproxy runs.



Regards,

Fred.




Re: IPv6 resolvers seems not works

2017-04-11 Thread Frederic Lecaille

On 04/10/2017 04:17 PM, Frederic Lecaille wrote:

On 04/10/2017 01:42 PM, Павел Знаменский wrote:

Hello,


Hello,


I'm trying to add IPv6 address as a nameserver to able resolve addresses
in IPv6-only environment:

resolvers google_dns_10m
nameserver google_dns1 2001:4860:4860:::53
nameserver google_dns2 2001:4860:4860::8844:53
hold valid 10m
resolve_retries 2

But I getting error:
[ALERT] 099/133733 (10412) : Starting [google_dns_10m/google_dns1]
nameserver: can't connect socket.

As I understood resolver uses AF_INET when connecting to the nameserver
and that's why IPv6 doesn't work.


In fact, the address families used during socket() and connect() syscall
are different.

This is revealed by strace:

socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 4
connect(4, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6,
"2001:4860:4860::8844", _addr), sin6_flowinfo=0, sin6_scope_id=0},
28) = -1 EAFNOSUPPORT (Address family not supported by protocol)

should be:

socket(PF_INET6, ...)


This patch fixes the issue.



>From 09fbee7c67dea87761165c35e8a1c0450575504c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Tue, 11 Apr 2017 08:46:37 +0200
Subject: [PATCH] MINOR: dns: Wrong address family used when creating IPv6
 sockets.

AF_INET address family was always used to create sockets to connect
to name servers. This prevented any connection over IPv6 from working.
---
 src/dns.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/dns.c b/src/dns.c
index 075a701..a118598 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -1022,7 +1022,7 @@ int dns_init_resolvers(int close_socket)
 			dgram->data = _dgram_cb;
 
 			/* create network UDP socket for this nameserver */
-			if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
+			if ((fd = socket(curnameserver->addr.ss_family, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
 Alert("Starting [%s/%s] nameserver: can't create socket.\n", curr_resolvers->id,
 		curnameserver->id);
 free(dgram);
-- 
2.1.4



Re: IPv6 resolvers seems not works

2017-04-10 Thread Frederic Lecaille

On 04/10/2017 01:42 PM, Павел Знаменский wrote:

Hello,


Hello,


I'm trying to add IPv6 address as a nameserver to able resolve addresses
in IPv6-only environment:

resolvers google_dns_10m
nameserver google_dns1 2001:4860:4860:::53
nameserver google_dns2 2001:4860:4860::8844:53
hold valid 10m
resolve_retries 2

But I getting error:
[ALERT] 099/133733 (10412) : Starting [google_dns_10m/google_dns1]
nameserver: can't connect socket.

As I understood resolver uses AF_INET when connecting to the nameserver
and that's why IPv6 doesn't work.


Indeed, the address families used during socket() and connect() syscall 
are different.


This is revealed by strace:

socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 4
connect(4, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6, 
"2001:4860:4860::8844", _addr), sin6_flowinfo=0, sin6_scope_id=0}, 
28) = -1 EAFNOSUPPORT (Address family not supported by protocol)


should be:

socket(PF_INET6, ...)



Is it possible to add IPv6 support for resolvers?

Thanks.





Re: server templates

2017-04-21 Thread Frederic Lecaille

On 04/21/2017 09:45 AM, Frederic Lecaille wrote:

On 04/21/2017 09:15 AM, Jarno Huuskonen wrote:

Hi,

On Thu, Apr 20, Frederic Lecaille wrote:

+server-template   [:] [params*]
+  Set a template for this backend to initialize servers with shared
parameters.
+  This server names are built from  and 
parameters.
+  May be used in sections :   defaults | frontend | listen | backend
+ no|no|   yes  |   yes
+
+  Arguments:
+  a prefix for the server names to be built.
+
+
+  If  is provided, this template initializes 
servers
+  with 1 upto  as server name suffixes. A range
-


s/upto/up to/
"A range" -> "A range of" and "may also been" -> "may also be"
(perhaps native English speakers can check this).


+  may also been used to use  upto  as
server name


s/upto/up to/


+  suffixes.


nb (netblock, number) ? I assume number, so maybe
for example  and - is easier to understand ?


+  Examples:
+# Initializes 5 servers with srv_1, srv_2 and srv_3 as names,


5 servers (s/5/3/) ?

-Jarno



Here is an updated #0006 patch.


Well... wrong patch...
This one should be better.

Regards.


>From 39a6e77c3ba2200ca3bca85a4295c20258f9b5d1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Thu, 20 Apr 2017 13:36:25 +0200
Subject: [PATCH 6/6] DOC: Add documentation for new "server-template" keyword.

---
 doc/configuration.txt | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index e6ea2cf..d574cb6 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1969,6 +1969,7 @@ rspirep   -  X X X
 rsprep-  X X X
 server-  - X X
 server-state-file-nameX  - X X
+server-template   -  - X X
 sourceX  - X X
 srvtimeout  (deprecated)  X  - X X
 stats admin   -  X X X
@@ -7521,6 +7522,44 @@ server-state-file-name []
   See also: "server-state-file-base", "load-server-state-from-file", and
   "show servers state"
 
+server-template   [:] [params*]
+  Set a template to initialize servers with shared parameters.
+  The names of these servers are built from  and  parameters.
+  May be used in sections :   defaults | frontend | listen | backend
+ no|no|   yes  |   yes
+
+  Arguments:
+  A prefix for the server names to be built.
+
+
+  If  is provided, this template initializes  servers
+  with 1 up to  as server name suffixes. A range of numbers
+  - may also be used to use  up to
+   as server name suffixes.
+
+A FQDN for all the servers this template initializes.
+
+Same meaning as "server"  argument (see "server" keyword).
+
+<params*>
+  Remaining server parameters among all those supported by "server"
+  keyword.
+
+  Examples:
+# Initializes 3 servers with srv1, srv2 and srv3 as names,
+# google.com as FQDN, and health-check enabled.
+server-template srv 1-3 google.com:80 check
+
+# or
+server-template srv 3 google.com:80 check
+
+# would be equivalent to:
+server srv1 google.com:80 check
+server srv2 google.com:80 check
+server srv3 google.com:80 check
+
+
+
 source [:] [usesrc { [:] | client | clientip } ]
 source [:] [usesrc { [:] | hdr_ip([,]) } ]
 source [:] [interface ]
-- 
2.1.4



Re: server templates

2017-04-21 Thread Frederic Lecaille

On 04/21/2017 09:15 AM, Jarno Huuskonen wrote:

Hi,

On Thu, Apr 20, Frederic Lecaille wrote:

+server-template   [:] [params*]
+  Set a template for this backend to initialize servers with shared parameters.
+  This server names are built from  and  parameters.
+  May be used in sections :   defaults | frontend | listen | backend
+ no|no|   yes  |   yes
+
+  Arguments:
+  a prefix for the server names to be built.
+
+
+  If  is provided, this template initializes  servers
+  with 1 upto  as server name suffixes. A range 
-


s/upto/up to/
"A range" -> "A range of" and "may also been" -> "may also be"
(perhaps native English speakers can check this).


+  may also been used to use  upto  as server name


s/upto/up to/


+  suffixes.


nb (netblock, number) ? I assume number, so maybe
for example  and - is easier to understand ?


+  Examples:
+# Initializes 5 servers with srv_1, srv_2 and srv_3 as names,


5 servers (s/5/3/) ?


Also note: s/_//


-Jarno



Thank you a lot Jarno for all these remarks. In fact I have published 
#0006 patch without double checking. I have already sent an updated 
patch to Willy (in private). I am going to redo this ugly patch taking 
into an account your remarks too.


Regards.



Re: server templates

2017-04-21 Thread Frederic Lecaille

On 04/21/2017 09:15 AM, Jarno Huuskonen wrote:

Hi,

On Thu, Apr 20, Frederic Lecaille wrote:

+server-template   [:] [params*]
+  Set a template for this backend to initialize servers with shared parameters.
+  This server names are built from  and  parameters.
+  May be used in sections :   defaults | frontend | listen | backend
+ no|no|   yes  |   yes
+
+  Arguments:
+  a prefix for the server names to be built.
+
+
+  If  is provided, this template initializes  servers
+  with 1 upto  as server name suffixes. A range 
-


s/upto/up to/
"A range" -> "A range of" and "may also been" -> "may also be"
(perhaps native English speakers can check this).


+  may also been used to use  upto  as server name


s/upto/up to/


+  suffixes.


nb (netblock, number) ? I assume number, so maybe
for example  and - is easier to understand ?


+  Examples:
+# Initializes 5 servers with srv_1, srv_2 and srv_3 as names,


5 servers (s/5/3/) ?

-Jarno



Here is an updated #0006 patch.

Thank again Jarno.

Regards.


>From 12c6f08c84daa7803bc83696798b2dbf2c80acfe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Thu, 20 Apr 2017 13:36:25 +0200
Subject: [PATCH 6/6] DOC: Add documentation for new "server-template" keyword.

---
 doc/configuration.txt | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index e6ea2cf..a755948 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1969,6 +1969,7 @@ rspirep   -  X X X
 rsprep-  X X X
 server-  - X X
 server-state-file-nameX  - X X
+server-template   -  - X X
 sourceX  - X X
 srvtimeout  (deprecated)  X  - X X
 stats admin   -  X X X
@@ -7521,6 +7522,44 @@ server-state-file-name []
   See also: "server-state-file-base", "load-server-state-from-file", and
   "show servers state"
 
+server-template   [:] [params*]
+  Set a template to initialize servers with shared parameters.
+  The names of these servers are built from  and  parameters.
+  May be used in sections :   defaults | frontend | listen | backend
+ no|no|   yes  |   yes
+
+  Arguments:
+  A prefix for the server names to be built.
+
+
+  If  is provided, this template initializes  servers
+  with 1 upto  as server name suffixes. A range -
+  may also been used to use  upto  as server name
+  suffixes.
+
+A FQDN for all the servers this template initializes.
+
+Same meaning as "server"  argument (see "server" keyword).
+
+<params*>
+  Remaining server parameters among all those supported by "server"
+  keyword.
+
+  Examples:
+# Initializes 5 servers with srv1, srv2 and srv3 as names,
+# google.com as FQDN, and health-check enabled.
+server-template srv 1-3 google.com:80 check
+
+# or
+server-template srv 3 google.com:80 check
+
+# would be equivalent to:
+server srv1 google.com:80 check
+server srv2 google.com:80 check
+server srv3 google.com:80 check
+
+
+
 source [:] [usesrc { [:] | client | clientip } ]
 source [:] [usesrc { [:] | hdr_ip([,]) } ]
 source [:] [interface ]
-- 
2.1.4



Re: Propagating agent-check weight change to tracking servers

2017-04-13 Thread Frederic Lecaille

Hello Michal,

On 04/11/2017 04:41 PM, Michał wrote:

Hello Willy,

So I'm fighting with dba97077 made by Frédéric Lécaille - it broke many
things.


This patch broke haproxy non-transparent builds. Thanks to Steven 
Davidovitz, Pavlos Parissis and David Carlier for having promptly helped 
in fixing this.


Excepted this building issue, AFAIK this patch may break only server  or 
default server 'source' setting parsing. How much other things did it break?


Do not forgive that as far as your configuration files do not use any 
'default-server' line with new supported settings (I agree they are 
numerous), they should be parsed as before.


So, if you want to have more chances not to be impacted by my 
"default-server patches", please do not use any 'default-server' new 
supported setting as a first workaround, or no 'default-server' line at 
all as a second workaround. This should help you to continue and develop 
your features.



E.g. you can't use "source", because that patch broke it. I'm curious how
many other stuff got broken with those patches around default-server.



[snipped rude/useless/unproductive published anonymous comments, 
especially towards my colleagues]




In attachment there is patch fixed after your (Willy) review. Sorry for
loop,
I was focused on fixing all those problems with Frédérics patch I just
didn't
think how to replace do..while (which obviously works) with this cleaner
version - thanks for this. The patch got even simpler.


As Willy wrote before, please feel free to contact me to fix asap any 
issue I alone am responsible. I am keeping an eye on HAproxy ML, and I 
would still be glad to help you and consequently any other haproxy users.


Regards,
Fred.




BUG/MINOR : wrong error message during 'default-server' lines

2017-04-14 Thread Frederic Lecaille

Hello,

This patch fixes a minor bug, a wrong error message during 'usesrc' 
keyword parsing on 'default-server' lines.


'usesrc' was displayed as unknown if not used after 'source' keyword.

Regards,
Fred
>From a9d8045bbc3858607aa0f5d8ab5e1c4c353cce14 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Fri, 14 Apr 2017 15:19:56 +0200
Subject: [PATCH] BUG/MINOR: server: Fix a wrong error message during 'usesrc'
 keyword parsing.

'usesrc' setting is not permitted on 'server' lines if not provided after
'source' setting. This is now also the case on 'default-server' lines.
Without this patch parse_server() parser displayed that 'usersrc' is
an unknown keyword.

Should have come with dba9707 commit.
---
 src/server.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/server.c b/src/server.c
index b5d8890..40a8d7f 100644
--- a/src/server.c
+++ b/src/server.c
@@ -2207,7 +2207,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 }
 cur_arg += 2;
 			}
-			else if (!defsrv && !strcmp(args[cur_arg], "usesrc")) {  /* address to use outside: needs "source" first */
+			else if (!strcmp(args[cur_arg], "usesrc")) {  /* address to use outside: needs "source" first */
 Alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
   file, linenum, "usesrc", "source");
 err_code |= ERR_ALERT | ERR_FATAL;
-- 
2.1.4



Re: server templates

2017-04-20 Thread Frederic Lecaille

Hello HAProxy ML,

On 04/10/2017 05:00 PM, Baptiste wrote:



On Mon, Apr 10, 2017 at 2:30 PM, Willy Tarreau <w...@1wt.eu
<mailto:w...@1wt.eu>> wrote:

On Mon, Apr 10, 2017 at 10:02:29AM +0200, Frederic Lecaille wrote:
> With server templates, haproxy could preallocate 'server' objects which
> would derive from 'default-server' (with same settings as default server
> settings), but with remaining parameters which are unknown at parsing time
> (for instance their names, addresses, anything else). In fact here, names 
or
> addresses are particular settings: a default server has not any default 
name
> or default address.

Absolutely. And this combined with the recent features of dynamic
consistent
cookies and with Baptiste's upcoming DNS patches will easily result
in pretty
dynamic backends!

Willy


I just had a look at the implementation of server-templates. To make it
work with DNS resolution, we need to find a way to provide a fqdn to
 the default-server directive. This might not be too complicated.
After this, the magic will happen


After this first patches for server template new feature, here is a new 
set attached to this mail which takes into an account what have been 
discussed with Baptiste and Willy.


#0001 patch fixes a minor bug which may be backported to haproxy 1.7 and 
1.6.


#0002 upto #0005 patches implement server template feature.

"server-template" new keyword is added and supported in "backend" and 
"listen" sections.


Its syntax:
  server-temlate   [:port] <params*>

This may be used to initialize a list of servers with the same 
parameters, especially the same FQDN as requested by Baptiste.


#0006 patch updates the documentation.

Fill free to review/comment/test as needed.

Regards,

Fred.


>From ceeb3a4e39242924dd061438f0be27ed58d648a3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Thu, 20 Apr 2017 13:36:25 +0200
Subject: [PATCH 6/6] DOC: Add documentation for new "server-template" keyword.

---
 doc/configuration.txt | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index e6ea2cf..488d8e2 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1969,6 +1969,7 @@ rspirep   -  X X X
 rsprep-  X X X
 server-  - X X
 server-state-file-nameX  - X X
+server-template   -  - X X
 sourceX  - X X
 srvtimeout  (deprecated)  X  - X X
 stats admin   -  X X X
@@ -7521,6 +7522,44 @@ server-state-file-name []
   See also: "server-state-file-base", "load-server-state-from-file", and
   "show servers state"
 
+server-template   [:] [params*]
+  Set a template for this backend to initialize servers with shared parameters.
+  This server names are built from  and  parameters.
+  May be used in sections :   defaults | frontend | listen | backend
+ no|no|   yes  |   yes
+
+  Arguments:
+  a prefix for the server names to be built.
+
+
+  If  is provided, this template initializes  servers
+  with 1 upto  as server name suffixes. A range -
+  may also been used to use  upto  as server name
+  suffixes.
+
+A FQDN for all the servers this template initializes.
+
+Same meaning as "server"  argument (see "server" keyword).
+
+<params*>
+  Remaining server parameter among all those supported by "server"
+  keyword.
+
+  Examples:
+# Initializes 5 servers with srv_1, srv_2 and srv_3 as names,
+# google.com as FQDN, and health-check enabled.
+server-template srv 1-3 google.com:80 check
+
+# or
+server-template srv 3 google.com:80 check
+
+# would be equivalent to:
+server srv1 google.com:80 check
+server srv2 google.com:80 check
+server srv3 google.com:80 check
+
+
+
 source [:] [usesrc { [:] | client | clientip } ]
 source [:] [usesrc { [:] | hdr_ip([,]) } ]
 source [:] [interface ]
-- 
2.1.4

>From 960693685da4d73f7c3c4ee6065aa7f5ae7134aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Fri, 14 Apr 2017 13:28:00 +0200
Subject: [PATCH 5/6] MINOR: server: Add server_template_init() function to
 initialize servers from a templates.

This patch adds server_te

Re: Propagating agent-check weight change to tracking servers

2017-04-16 Thread Frederic Lecaille

Hello Willy,

On 04/15/2017 04:43 PM, Willy Tarreau wrote:

On Sat, Apr 15, 2017 at 02:24:41PM +0200, Michal wrote:

Hi,
Maybe my email wasn't nice enough, but breaking compilation


You were the first one to experience the build breakage, it worked for
most of us, but you didn't even give the smallest hints about the error(s)
you met, making it much harder to fix the problem. Fortunately others were
much more constructive and reported it the normal way.


and simplest
config with server using "source" got me very angry. I didn't send any
reproducer, because even simple
"server name 1.1.1.1:80 source 1.2.3.4 track other"
wasn't parsing.


Indeed, in fact this is any keyword provided *after* 'source' keyword 
which could not be parsed anymore. The first keyword ('track' here) was 
skipped leading to this error message: 'other' unknown keyword.


I agree that I have not tested such cases.

srv_parse_source() 'source' keyword parser updates 'cur_arg' variable 
(the index in the line of the current argument to be parsed). It is its 
job because 'source' keyword number of variable arguments.  So, in this 
case we should not update 'cur_arg' variable anymore outside of 
srv_parse_souce() parser.


The patch attached to this mail fixes this major bug.

Note that all such added lines 'if (kw->skip == -1)' may be removed,
but I am not sure it is a good thing.


Regards,
Fred.
>From 6febf2ca609d62dd3b7408f7488d82682853a845 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Sun, 16 Apr 2017 17:14:14 +0200
Subject: [PATCH] BUG/MAJOR: Broken parsing for valid keywords provided after
 'source' setting.

Any valid keyword could not be parsed anymore if provided after 'source' keyword.
This was due to the fact that 'source' number of arguments is variable.
So, as its parser srv_parse_source() is the only one who may know how many arguments
was provided after 'source' keyword, it updates 'cur_arg' variable (the index
in the line of the current arg to be parsed), this is a good thing.
This variable is also incremented by one (to skip the 'source' keyword).
This patch disable this behavior.

Should have come with dba9707 commit.
---
 src/server.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/server.c b/src/server.c
index b5d8890..0f12dbd 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1357,6 +1357,7 @@ void srv_compute_all_admin_states(struct proxy *px)
  * Optional keywords are also declared with a NULL ->parse() function so that
  * the config parser can report an appropriate error when a known keyword was
  * not enabled.
+ * Note: -1 as ->skip value means that the number of arguments are variable.
  */
 static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "addr",srv_parse_addr,1,  1 }, /* IP address to send health to or to probe from agent-check */
@@ -1380,12 +1381,7 @@ static struct srv_kw_list srv_kws = { "ALL", { }, {
 	{ "redir",   srv_parse_redir,   1,  1 }, /* Enable redirection mode */
 	{ "send-proxy",  srv_parse_send_proxy,  0,  1 }, /* Enforce use of PROXY V1 protocol */
 	{ "send-proxy-v2",   srv_parse_send_proxy_v2,   0,  1 }, /* Enforce use of PROXY V2 protocol */
-	/*
-	 * Note: the following 'skip' field value is 0.
-	 * Here this does not mean that "source" setting does not need any argument.
-	 * This means that the number of argument is variable.
-	 */
-	{ "source",  srv_parse_source,  0,  1 }, /* Set the source address to be used to connect to the server */
+	{ "source",  srv_parse_source, -1,  1 }, /* Set the source address to be used to connect to the server */
 	{ "stick",   srv_parse_stick,   0,  1 }, /* Enable stick-table persistence */
 	{ "track",   srv_parse_track,   1,  1 }, /* Set the current state of the server, tracking another one */
 	{ NULL, NULL, 0 },
@@ -2226,7 +,8 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 	if (!kw->parse) {
 		Alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
 		  file, linenum, args[0], args[1], args[cur_arg]);
-		cur_arg += 1 + kw->skip ;
+		if (kw->skip != -1)
+			cur_arg += 1 + kw->skip ;
 		err_code |= ERR_ALERT | ERR_FATAL;
 		goto out;
 	}
@@ -2234,7 +2231,8 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 	if (defsrv && !kw->default_ok) {
 		Alert("parsing [%s:%d] : '%s %s' : '%s' option is not accepted in default-server sections.\n",
 		  file, linenum, args[0], args[1], args[cur_arg]);
-		cur_arg += 1 + kw->skip ;
+		if (kw->skip != -1)
+			cur_arg += 1 + kw->skip ;
 		err_code |= ERR_ALERT;
 		continue;
 	}
@@ -2246,12 +2244,14 @@ int parse_server(const 

Re: BUG/MINOR : wrong error message during 'default-server' lines

2017-04-16 Thread Frederic Lecaille

On 04/15/2017 12:13 AM, Aleksandar Lazic wrote:

Hi.


Hello Aleksandar,


Am 14-04-2017 15:59, schrieb Frederic Lecaille:

Hello,

This patch fixes a minor bug, a wrong error message during 'usesrc'
keyword parsing on 'default-server' lines.

'usesrc' was displayed as unknown if not used after 'source' keyword.


When I take a look into the docs I see that the source and therefore the
usesrc is not supported in default-server

http://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.2-source

---
Supported in default-server: No
---


This is the current doc. Indeed both 'source' and 'usesrc' keywords are 
not supported by haprox 1.7.



But when I look into the "Alphabetically sorted keywords reference" then
it is supported on the default server.

http://cbonte.github.io/haproxy-dconv/1.7/configuration.html#source%20%28Alphabetically%20sorted%20keywords%20reference%29


supported in *defaults* sections... this is what I see, or have I missed 
something?




What's true?


Regards,
Fred


Regards
Aleks


Regards,
Fred.



Re: BUG/MINOR : wrong error message during 'default-server' lines

2017-04-16 Thread Frederic Lecaille

On 04/16/2017 05:40 PM, Frederic Lecaille wrote:

On 04/15/2017 12:13 AM, Aleksandar Lazic wrote:

Hi.


Hello Aleksandar,


Am 14-04-2017 15:59, schrieb Frederic Lecaille:

Hello,

This patch fixes a minor bug, a wrong error message during 'usesrc'
keyword parsing on 'default-server' lines.

'usesrc' was displayed as unknown if not used after 'source' keyword.


When I take a look into the docs I see that the source and therefore the
usesrc is not supported in default-server

http://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.2-source

---
Supported in default-server: No
---


This is the current doc. Indeed both 'source' and 'usesrc' keywords are
not supported by haprox 1.7.


I meant not supported on 'default-server' lines ;)




peers synchronization issue

2017-07-13 Thread Frederic Lecaille

Hello,

I have noticed that when several stick-table backends are attached to 
several peers sections, only the stick-tables attached to the last peer 
section could be synchronized ;) .


This patch fixes this issue.

Regards,

Fred.
>From 53908a325155836ddb8b0c8a1b8c56e1fa13139d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Thu, 13 Jul 2017 09:07:09 +0200
Subject: [PATCH] BUG/MINOR: peers: peer synchronization issue (with several
 peers sections).

When several stick-tables were configured with several peers sections,
only a part of them could be synchronized: the ones attached to the last
parsed 'peers' section. This was due to the fact that, at least, the peer I/O handler
refered to the wrong peer section list, in fact always the same: the last one parsed.

The fact that the global peer section list was named "struct peers *peers"
lead to this issue. This variable name is dangerous ;).

So this patch renames global 'peers' variable to 'cfg_peers' to ensure that
no such wrong references are still in use, then all the functions wich used
old 'peers' variable have been modified to refer to the correct peer list.

Must be backported to 1.6 and 1.7.
---
 include/types/peers.h |  2 +-
 src/cfgparse.c| 18 +-
 src/haproxy.c | 10 +-
 src/peers.c   | 40 
 src/proxy.c   |  6 +++---
 5 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/include/types/peers.h b/include/types/peers.h
index 105dffb..a77a094 100644
--- a/include/types/peers.h
+++ b/include/types/peers.h
@@ -91,7 +91,7 @@ struct peers {
 };
 
 
-extern struct peers *peers;
+extern struct peers *cfg_peers;
 
 #endif /* _TYPES_PEERS_H */
 
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 600f273..ecd4c9f 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1941,7 +1941,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
 			goto out;
 		}
 
-		for (curpeers = peers; curpeers != NULL; curpeers = curpeers->next) {
+		for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
 			/*
 			 * If there are two proxies with the same name only following
 			 * combinations are allowed:
@@ -1959,8 +1959,8 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
 			goto out;
 		}
 
-		curpeers->next = peers;
-		peers = curpeers;
+		curpeers->next = cfg_peers;
+		cfg_peers = curpeers;
 		curpeers->conf.file = strdup(file);
 		curpeers->conf.line = linenum;
 		curpeers->last_change = now.tv_sec;
@@ -2040,7 +2040,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
 		if (strcmp(newpeer->id, localpeer) == 0) {
 			/* Current is local peer, it define a frontend */
 			newpeer->local = 1;
-			peers->local = newpeer;
+			cfg_peers->local = newpeer;
 
 			if (!curpeers->peers_fe) {
 if ((curpeers->peers_fe  = calloc(1, sizeof(struct proxy))) == NULL) {
@@ -8087,9 +8087,9 @@ int check_config_validity()
 		}
 
 		if (curproxy->table.peers.name) {
-			struct peers *curpeers = peers;
+			struct peers *curpeers;
 
-			for (curpeers = peers; curpeers; curpeers = curpeers->next) {
+			for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
 	free((void *)curproxy->table.peers.name);
 	curproxy->table.peers.p = curpeers;
@@ -9108,15 +9108,15 @@ out_uri_auth_compat:
 		if (curproxy->table.peers.p)
 			curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
 
-	if (peers) {
-		struct peers *curpeers = peers, **last;
+	if (cfg_peers) {
+		struct peers *curpeers = cfg_peers, **last;
 		struct peer *p, *pb;
 
 		/* Remove all peers sections which don't have a valid listener,
 		 * which are not used by any table, or which are bound to more
 		 * than one process.
 		 */
-		last = 
+		last = _peers;
 		while (*last) {
 			curpeers = *last;
 
diff --git a/src/haproxy.c b/src/haproxy.c
index a425744..2316100 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -1448,7 +1448,7 @@ static void init(int argc, char **argv)
 		struct peers *pr;
 		struct proxy *px;
 
-		for (pr = peers; pr; pr = pr->next)
+		for (pr = cfg_peers; pr; pr = pr->next)
 			if (pr->peers_fe)
 break;
 
@@ -1662,11 +1662,11 @@ static void init(int argc, char **argv)
 	if (global.stats_fe)
 		global.maxsock += global.stats_fe->maxconn;
 
-	if (peers) {
+	if (cfg_peers) {
 		/* peers also need to bypass global maxconn */
-		struct peers *p = peers;
+		struct peers *p = cfg_peers;
 
-		for (p = peers; p; p = p->next)
+		for (p = cfg_peers; p; p = p->next)
 			if (p->peers_fe)
 global.maxsock += p->peers_fe->maxconn;
 	}
@@ -2653,7 +2653,7 @@ int main(int argc, char **argv)
 		}
 
 		/* we might have to unbind some peers sections from some processes */
-		for (curpeers = peers; curpeers; curpeers = curpeers->next) {
+		for (curpeers = cfg_peers; curpeers; curpeers 

peers - add additional information to stick-table definition message

2017-07-06 Thread Frederic Lecaille

Hello,

Here is a simple patch to add remaining information to peer stick-table 
definition message useful for external applications to discover haproxy 
peer stick-table configurations.


Regards,

Fred.
>From 733ecc558cc47b9c4d94ef2b316c6e7b3bf067a3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Thu, 6 Jul 2017 15:02:16 +0200
Subject: [PATCH] MINOR: peers: Add additional information to stick-table
 definition messages.

With this patch additional information are added to stick-table definition
messages so that to make external application capable of learning peer
stick-table configurations. First stick-table entries duration is added
followed by the frequency counters type IDs and values.

May be backported to 1.7 and 1.6.
---
 src/peers.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/src/peers.c b/src/peers.c
index 643b8c5..1ac3bad 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -422,6 +422,25 @@ static int peer_prepare_switchmsg(struct shared_table *st, char *msg, size_t siz
 	}
 	intencode(data, );
 
+	/* Encode stick-table entries duration. */
+	intencode(st->table->expire, );
+
+	/* Encode the frequency counters periods. */
+	for (data_type = 0 ; data_type < STKTABLE_DATA_TYPES ; data_type++) {
+		if (st->table->data_ofs[data_type]) {
+			switch (stktable_data_types[data_type].std_type) {
+case STD_T_SINT:
+case STD_T_UINT:
+case STD_T_ULL:
+	continue;
+case STD_T_FRQP:
+	intencode(data_type, );
+	intencode(st->table->data_arg[data_type].u, );
+	break;
+			}
+		}
+	}
+
 	/* Compute datalen */
 	datalen = (cursor - datamsg);
 
-- 
2.1.4



Re: server FQDN changes from stats socket + server-state file

2017-04-27 Thread Frederic Lecaille

On 04/27/2017 12:43 PM, Baptiste wrote:



On Thu, Apr 27, 2017 at 11:22 AM, Frederic Lecaille
<flecai...@haproxy.com <mailto:flecai...@haproxy.com>> wrote:

On 04/27/2017 10:47 AM, Frederic Lecaille wrote:

Hello HAProxy ML,

Please find attached to this mail a patch proposal which allows
server FQDNs changes from stats socket.

These FQDNs are also added to server-state file.

Regards,

Fred.


A new version of this patch which fixes a memleak (server hostname
was strdup() both in srv_set_fqdn() and srv_alloc_dns_resolution()).



Hi Fred,


Hi Baptiste,


I did a quick read of the patch and I noticed the following points:

- in update_server_fqdn(), I don't think it's relevant to perform the
name resolution validation (the call to str2ip2)
  First, str2ip2 uses libc resolver, which may be different from the
runtime resolver of HAProxy and second, it's up to the
admin/devops/script which performs this change to ensure he is not
messing up...


Ok but will the new FQDN be resolved in any case after any update from 
stats socket to match with the server IP address or is this something 
the operator must also take care of (provide new FQDNs which may resolve 
to the current IP address???)?



- in srv_alloc_dns_resolution(), if strdup (or any alloc function)
fails, then we should report an error to the function caller and display
a message on the CLI.


Ok.


Baptiste






Re: server FQDN changes from stats socket + server-state file

2017-04-27 Thread Frederic Lecaille

On 04/27/2017 03:20 PM, Frederic Lecaille wrote:

On 04/27/2017 02:56 PM, Baptiste wrote:



On Thu, Apr 27, 2017 at 2:44 PM, Frederic Lecaille
<flecai...@haproxy.com <mailto:flecai...@haproxy.com>> wrote:

On 04/27/2017 12:43 PM, Baptiste wrote:



On Thu, Apr 27, 2017 at 11:22 AM, Frederic Lecaille
<flecai...@haproxy.com <mailto:flecai...@haproxy.com>
<mailto:flecai...@haproxy.com <mailto:flecai...@haproxy.com>>>
wrote:

    On 04/27/2017 10:47 AM, Frederic Lecaille wrote:

Hello HAProxy ML,

Please find attached to this mail a patch proposal which
allows
server FQDNs changes from stats socket.

These FQDNs are also added to server-state file.

Regards,

Fred.


A new version of this patch which fixes a memleak (server
hostname
was strdup() both in srv_set_fqdn() and
srv_alloc_dns_resolution()).



Hi Fred,


Hi Baptiste,

I did a quick read of the patch and I noticed the following
points:

- in update_server_fqdn(), I don't think it's relevant to
perform the
name resolution validation (the call to str2ip2)
  First, str2ip2 uses libc resolver, which may be different
from the
runtime resolver of HAProxy and second, it's up to the
admin/devops/script which performs this change to ensure he is
not
messing up...


Ok but will the new FQDN be resolved in any case after any update
from stats socket to match with the server IP address or is this
something the operator must also take care of (provide new FQDNs
which may resolve to the current IP address???)?


From my point of view, if no runtime resolution is configured, then
changing the fqdn through the CLI should have no impact (since this is
HAProxy's behavior since the beginning). Unless I misunderstood the
purpose of this feature...
By the way, I think that the call to getaddrinfo() in str2ip2 is
blocking... Hence, if I'm not wrong about getaddrinfo, it's a definitive
no-go to call str2ip2 at runtime.


I do not know all the internals of haproxy but I agree that if str2ip2()
may make any haproxy internal processing block I have definitively to
remove this call to str2ip2(). ;)

And modify two lines which launch another call 2 str2ip2() (see the
comment: /* Reset lastaddr value. etc. */).

Thank you Baptiste.


Here is a new patch version which takes into an account Baptiste remarks.

Thank you again Baptiste.




>From 54ce2b25e74c4b95a86d3da87b5bea261a7183c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Wed, 26 Apr 2017 11:24:02 +0200
Subject: [PATCH] MINOR: server: cli: Add server FQDNs to server-state file and
 stats socket.

This patch adds a new stats socket command to modify server
FQDNs at run time.
Its syntax:
  set server / fqdn 
This patch also adds FQDNs to server state file at the end
of each line for backward compatibility ("-" if not present).
---
 doc/management.txt |   7 +++
 include/types/server.h |  22 +++-
 src/proxy.c|   4 +-
 src/server.c   | 148 +
 4 files changed, 167 insertions(+), 14 deletions(-)

diff --git a/doc/management.txt b/doc/management.txt
index 3368277..d1ea1f6 100644
--- a/doc/management.txt
+++ b/doc/management.txt
@@ -1650,6 +1650,9 @@ set server / weight [%]
   Change a server's weight to the value passed in argument. This is the exact
   equivalent of the "set weight" command below.
 
+set server / fqdn 
+  Change a server's FQDN to the value passed in argument.
+
 set ssl ocsp-response 
   This command is used to update an OCSP Response for a certificate (see "crt"
   on "bind" lines). Same controls are performed as during the initial loading of
@@ -1962,6 +1965,9 @@ show servers state []
 0x20 = SRV_ADMF_RMAINT
   The server is in maintenance because of an
   IP address resolution failure.
+0x40 = SRV_ADMF_HMAINT
+  The server FQDN was set from stats socket.
+
  srv_uweight: User visible server's weight.
  srv_iweight: Server's initial weight.
  srv_time_since_last_change:  Time since last operational change.
@@ -2003,6 +2009,7 @@ show servers state []
   configuration.
  srv_f_forced_id: Flag to know if the server's ID is forced by
   configuration.
+ srv_fqdn:Server FQDN.
 
 show sess
   Dump all known sessions. Avoid doing this on slow connections as this can
diff --git a/include/types/server.

Re: server FQDN changes from stats socket + server-state file

2017-04-27 Thread Frederic Lecaille

On 04/27/2017 10:47 AM, Frederic Lecaille wrote:

Hello HAProxy ML,

Please find attached to this mail a patch proposal which allows
server FQDNs changes from stats socket.

These FQDNs are also added to server-state file.

Regards,

Fred.


A new version of this patch which fixes a memleak (server hostname
was strdup() both in srv_set_fqdn() and srv_alloc_dns_resolution()).




>From f6adc66337655cf81a29a519dff6c40d3d24013d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Wed, 26 Apr 2017 11:24:02 +0200
Subject: [PATCH] MINOR: server: cli: Add server FQDNs to server-state file and
 stats socket.

This patch adds a new stats socket command to modify server
FQDNs at run time.
Its syntax:
  set server / fqdn 
This patch also adds FQDNs to server state file at the end
of each line for backward compatibility ("-" if not present).
---
 doc/management.txt |   7 +++
 include/types/server.h |  22 +++-
 src/proxy.c|   4 +-
 src/server.c   | 144 ++---
 4 files changed, 166 insertions(+), 11 deletions(-)

diff --git a/doc/management.txt b/doc/management.txt
index 3368277..d1ea1f6 100644
--- a/doc/management.txt
+++ b/doc/management.txt
@@ -1650,6 +1650,9 @@ set server / weight [%]
   Change a server's weight to the value passed in argument. This is the exact
   equivalent of the "set weight" command below.
 
+set server / fqdn 
+  Change a server's FQDN to the value passed in argument.
+
 set ssl ocsp-response 
   This command is used to update an OCSP Response for a certificate (see "crt"
   on "bind" lines). Same controls are performed as during the initial loading of
@@ -1962,6 +1965,9 @@ show servers state []
 0x20 = SRV_ADMF_RMAINT
   The server is in maintenance because of an
   IP address resolution failure.
+0x40 = SRV_ADMF_HMAINT
+  The server FQDN was set from stats socket.
+
  srv_uweight: User visible server's weight.
  srv_iweight: Server's initial weight.
  srv_time_since_last_change:  Time since last operational change.
@@ -2003,6 +2009,7 @@ show servers state []
   configuration.
  srv_f_forced_id: Flag to know if the server's ID is forced by
   configuration.
+ srv_fqdn:Server FQDN.
 
 show sess
   Dump all known sessions. Avoid doing this on slow connections as this can
diff --git a/include/types/server.h b/include/types/server.h
index 8d68dcb..83b1e80 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -82,6 +82,7 @@ enum srv_admin {
 	SRV_ADMF_IDRAIN= 0x10,/* the server has inherited the drain status from a tracked server */
 	SRV_ADMF_DRAIN = 0x18,/* mask to check if any drain flag is present */
 	SRV_ADMF_RMAINT= 0x20,/* the server is down because of an IP address resolution failure */
+	SRV_ADMF_HMAINT= 0x40,/* the server FQDN has been set from socket stats */
 };
 
 /* options for servers' "init-addr" parameter
@@ -103,7 +104,26 @@ enum srv_initaddr {
 #define SRV_STATE_FILE_VERSION 1
 #define SRV_STATE_FILE_VERSION_MIN 1
 #define SRV_STATE_FILE_VERSION_MAX 1
-#define SRV_STATE_FILE_FIELD_NAMES "be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id"
+#define SRV_STATE_FILE_FIELD_NAMES \
+"be_id "  \
+"be_name "\
+"srv_id " \
+"srv_name "   \
+"srv_addr "   \
+"srv_op_state "   \
+"srv_admin_state "\
+"srv_uweight "\
+"srv_iweight "\
+"srv_time_since_last_change " \
+"srv_check_status "   \
+"srv_check_result "   \
+"srv_check_health "   \
+"srv_check_state "\
+"srv_agent_state "\
+"bk_f_forced_id " \
+"srv_f_forced_id "\
+"srv_fqdn"
+
 #define SRV_STATE_FILE_MAX_FIELDS 18
 #define SRV_STATE_FILE_NB_FIELDS_VERSION_1 18
 #define SRV_STATE_LINE_MAXLEN 512
diff --git a/src/proxy.c b/src/proxy.c
index dc70213..f6a3214 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -1458,13 +1458,13 @@ static int dump_servers_state(struct stream_interface *si, struct chunk *buf)
 "%d %s

server FQDN changes from stats socket + server-state file

2017-04-27 Thread Frederic Lecaille

Hello HAProxy ML,

Please find attached to this mail a patch proposal which allows
server FQDNs changes from stats socket.

These FQDNs are also added to server-state file.

Regards,

Fred.
>From f9c1001175d406a15414e893f11d6120cf22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Wed, 26 Apr 2017 11:24:02 +0200
Subject: [PATCH] MINOR: server: cli: Add server FQDNs to server-state file and
 stats socket.

This patch adds a new stats socket command to modify server
FQDNs at run time.
Its syntax:
  set server / fqdn 
This patch also adds FQDNs to server state file at the end
of each line for backward compatibility ("-" if not present).
---
 doc/management.txt |   7 +++
 include/types/server.h |  22 +++-
 src/proxy.c|   4 +-
 src/server.c   | 145 ++---
 4 files changed, 167 insertions(+), 11 deletions(-)

diff --git a/doc/management.txt b/doc/management.txt
index 3368277..d1ea1f6 100644
--- a/doc/management.txt
+++ b/doc/management.txt
@@ -1650,6 +1650,9 @@ set server / weight [%]
   Change a server's weight to the value passed in argument. This is the exact
   equivalent of the "set weight" command below.
 
+set server / fqdn 
+  Change a server's FQDN to the value passed in argument.
+
 set ssl ocsp-response 
   This command is used to update an OCSP Response for a certificate (see "crt"
   on "bind" lines). Same controls are performed as during the initial loading of
@@ -1962,6 +1965,9 @@ show servers state []
 0x20 = SRV_ADMF_RMAINT
   The server is in maintenance because of an
   IP address resolution failure.
+0x40 = SRV_ADMF_HMAINT
+  The server FQDN was set from stats socket.
+
  srv_uweight: User visible server's weight.
  srv_iweight: Server's initial weight.
  srv_time_since_last_change:  Time since last operational change.
@@ -2003,6 +2009,7 @@ show servers state []
   configuration.
  srv_f_forced_id: Flag to know if the server's ID is forced by
   configuration.
+ srv_fqdn:Server FQDN.
 
 show sess
   Dump all known sessions. Avoid doing this on slow connections as this can
diff --git a/include/types/server.h b/include/types/server.h
index 8d68dcb..83b1e80 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -82,6 +82,7 @@ enum srv_admin {
 	SRV_ADMF_IDRAIN= 0x10,/* the server has inherited the drain status from a tracked server */
 	SRV_ADMF_DRAIN = 0x18,/* mask to check if any drain flag is present */
 	SRV_ADMF_RMAINT= 0x20,/* the server is down because of an IP address resolution failure */
+	SRV_ADMF_HMAINT= 0x40,/* the server FQDN has been set from socket stats */
 };
 
 /* options for servers' "init-addr" parameter
@@ -103,7 +104,26 @@ enum srv_initaddr {
 #define SRV_STATE_FILE_VERSION 1
 #define SRV_STATE_FILE_VERSION_MIN 1
 #define SRV_STATE_FILE_VERSION_MAX 1
-#define SRV_STATE_FILE_FIELD_NAMES "be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id"
+#define SRV_STATE_FILE_FIELD_NAMES \
+"be_id "  \
+"be_name "\
+"srv_id " \
+"srv_name "   \
+"srv_addr "   \
+"srv_op_state "   \
+"srv_admin_state "\
+"srv_uweight "\
+"srv_iweight "\
+"srv_time_since_last_change " \
+"srv_check_status "   \
+"srv_check_result "   \
+"srv_check_health "   \
+"srv_check_state "\
+"srv_agent_state "\
+"bk_f_forced_id " \
+"srv_f_forced_id "\
+"srv_fqdn"
+
 #define SRV_STATE_FILE_MAX_FIELDS 18
 #define SRV_STATE_FILE_NB_FIELDS_VERSION_1 18
 #define SRV_STATE_LINE_MAXLEN 512
diff --git a/src/proxy.c b/src/proxy.c
index dc70213..f6a3214 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -1458,13 +1458,13 @@ static int dump_servers_state(struct stream_interface *si, struct chunk *buf)
 "%d %s %s "
 "%d %d %d %d %ld "
 "%d %d %d %d %d "
-"%d %d"
+"%d %d %s"
 "\n",
 px->uuid, px->id,
 srv->puid, srv->id, srv_addr,
 srv->state, srv->admin, srv->uweight, srv->iweight, (long int)srv_time_since_last_change,
 srv->check.status, srv->check.result, srv->check.health, srv->check.state, srv->agent.state,
-bk_f_forced_id, srv_f_forced_id);
+bk_f_forced_id, srv_f_forced_id, srv->hostname ? 

Re: server FQDN changes from stats socket + server-state file

2017-04-27 Thread Frederic Lecaille

On 04/27/2017 02:56 PM, Baptiste wrote:



On Thu, Apr 27, 2017 at 2:44 PM, Frederic Lecaille
<flecai...@haproxy.com <mailto:flecai...@haproxy.com>> wrote:

On 04/27/2017 12:43 PM, Baptiste wrote:



On Thu, Apr 27, 2017 at 11:22 AM, Frederic Lecaille
<flecai...@haproxy.com <mailto:flecai...@haproxy.com>
<mailto:flecai...@haproxy.com <mailto:flecai...@haproxy.com>>>
wrote:

    On 04/27/2017 10:47 AM, Frederic Lecaille wrote:

Hello HAProxy ML,

Please find attached to this mail a patch proposal which
allows
server FQDNs changes from stats socket.

These FQDNs are also added to server-state file.

Regards,

Fred.


A new version of this patch which fixes a memleak (server
hostname
was strdup() both in srv_set_fqdn() and
srv_alloc_dns_resolution()).



Hi Fred,


Hi Baptiste,

I did a quick read of the patch and I noticed the following points:

- in update_server_fqdn(), I don't think it's relevant to
perform the
name resolution validation (the call to str2ip2)
  First, str2ip2 uses libc resolver, which may be different from the
runtime resolver of HAProxy and second, it's up to the
admin/devops/script which performs this change to ensure he is not
messing up...


Ok but will the new FQDN be resolved in any case after any update
from stats socket to match with the server IP address or is this
something the operator must also take care of (provide new FQDNs
which may resolve to the current IP address???)?


From my point of view, if no runtime resolution is configured, then
changing the fqdn through the CLI should have no impact (since this is
HAProxy's behavior since the beginning). Unless I misunderstood the
purpose of this feature...
By the way, I think that the call to getaddrinfo() in str2ip2 is
blocking... Hence, if I'm not wrong about getaddrinfo, it's a definitive
no-go to call str2ip2 at runtime.


I do not know all the internals of haproxy but I agree that if str2ip2() 
may make any haproxy internal processing block I have definitively to 
remove this call to str2ip2(). ;)


And modify two lines which launch another call 2 str2ip2() (see the 
comment: /* Reset lastaddr value. etc. */).


Thank you Baptiste.







server ports - server state file

2017-08-01 Thread Frederic Lecaille

Hello Haproxy ML,

Here is a simple patch to add server ports to server state file.

Regards,

Fred.

>From eff80e502338618ea991ecb0fac11fd25dec19b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 1 Aug 2017 08:47:19 +0200
Subject: [PATCH] MINOR: Add server port field to server state file.

This patch adds server ports to server state file at the end of each line
for backward compatibility.
---
 doc/management.txt |  1 +
 include/types/server.h |  5 +++--
 src/proxy.c|  4 ++--
 src/server.c   | 17 +
 4 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/doc/management.txt b/doc/management.txt
index dd604ae..c4e76ed 100644
--- a/doc/management.txt
+++ b/doc/management.txt
@@ -2042,6 +2042,7 @@ show servers state []
  srv_f_forced_id: Flag to know if the server's ID is forced by
   configuration.
  srv_fqdn:Server FQDN.
+ srv_port:Server port.
 
 show sess
   Dump all known sessions. Avoid doing this on slow connections as this can
diff --git a/include/types/server.h b/include/types/server.h
index 8fb6f2e..724d496 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -123,9 +123,10 @@ enum srv_initaddr {
 "srv_agent_state "\
 "bk_f_forced_id " \
 "srv_f_forced_id "\
-"srv_fqdn"
+"srv_fqdn "   \
+"srv_port"
 
-#define SRV_STATE_FILE_MAX_FIELDS 18
+#define SRV_STATE_FILE_MAX_FIELDS 19
 #define SRV_STATE_FILE_NB_FIELDS_VERSION_1 18
 #define SRV_STATE_LINE_MAXLEN 512
 
diff --git a/src/proxy.c b/src/proxy.c
index 1481089..641d4fa 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -1458,13 +1458,13 @@ static int dump_servers_state(struct stream_interface *si, struct chunk *buf)
 "%d %s %s "
 "%d %d %d %d %ld "
 "%d %d %d %d %d "
-"%d %d %s"
+"%d %d %s %u"
 "\n",
 px->uuid, px->id,
 srv->puid, srv->id, srv_addr,
 srv->state, srv->admin, srv->uweight, srv->iweight, (long int)srv_time_since_last_change,
 srv->check.status, srv->check.result, srv->check.health, srv->check.state, srv->agent.state,
-bk_f_forced_id, srv_f_forced_id, srv->hostname ? srv->hostname : "-");
+bk_f_forced_id, srv_f_forced_id, srv->hostname ? srv->hostname : "-", srv->svc_port);
 		if (bi_putchk(si_ic(si), ) == -1) {
 			si_applet_cant_put(si);
 			return 0;
diff --git a/src/server.c b/src/server.c
index 008bafa..f457d55 100644
--- a/src/server.c
+++ b/src/server.c
@@ -2892,8 +2892,11 @@ static void srv_update_state(struct server *srv, int version, char **params)
 	int srv_f_forced_id;
 	int fqdn_set_by_cli;
 	const char *fqdn;
+	const char *port_str;
+	unsigned int port;
 
 	fqdn = NULL;
+	port = 0;
 	msg = get_trash_chunk();
 	switch (version) {
 		case 1:
@@ -2913,6 +2916,7 @@ static void srv_update_state(struct server *srv, int version, char **params)
 			 * bk_f_forced_id:   params[11]
 			 * srv_f_forced_id:  params[12]
 			 * srv_fqdn: params[13]
+			 * srv_port: params[14]
 			 */
 
 			/* validating srv_op_state */
@@ -3036,6 +3040,15 @@ static void srv_update_state(struct server *srv, int version, char **params)
 fqdn = NULL;
 			}
 
+			port_str = params[14];
+			if (port_str) {
+port = strl2uic(port_str, strlen(port_str));
+if (port > USHRT_MAX) {
+	chunk_appendf(msg, ", invalid srv_port value '%s'", port_str);
+	port_str = NULL;
+}
+			}
+
 			/* don't apply anything if one error has been detected */
 			if (msg->len)
 goto out;
@@ -3167,6 +3180,9 @@ static void srv_update_state(struct server *srv, int version, char **params)
 }
 			}
 
+			if (port_str)
+srv->svc_port = port;
+
 			break;
 		default:
 			chunk_appendf(msg, ", version '%d' not supported", version);
@@ -3416,6 +3432,7 @@ void apply_server_state(void)
 			 * bk_f_forced_id:   params[15] => srv_params[11]
 			 * srv_f_forced_id:  params[16] => srv_params[12]
 			 * srv_fqdn: params[17] => srv_params[13]
+			 * srv_port: params[18] => srv_params[14]
 			 */
 			if (arg >= 4) {
 srv_params[srv_arg] = cur;
-- 
2.1.4



Re: Bug: DNS changes in 1.7.3+ break UNIX socket stats in daemon mode with resolvers on FreeBSD

2017-05-12 Thread Frederic Lecaille

On 05/12/2017 09:37 AM, Willy Tarreau wrote:

On Fri, May 12, 2017 at 08:58:56AM +0200, Lukas Tribus wrote:

Hi,


Am 11.05.2017 um 21:13 schrieb Jim Pingle:

On 05/11/2017 01:58 PM, Frederic Lecaille wrote:

I have reproduced (at home) the stats socket issue within a FreeBSD 9.3 VM.

Replacing your call to close() by fd_delete() which removes the fd from
the fd set used by kevent *and close it* seems to fix at least the stats
socket issue. I do not know if there are remaining ones.

I did not reproduced the kevent issue revealed by Lukas traces. But I
had other ones : ERR#57 'Socket is not connected' during sendto().

I attached a temporary patch to be validated and to let you perhaps
provide a better one as I have not double check everything.

Fred,

That seems to have fixed the problem for me. With that patch applied,
web traffic passes and the UNIX socket responds.


Confirmed, works for me too. Baptiste? Willy? Is this an acceptable fix?


Yes definitely, not only an acceptable one, but the right fix. I understand
why it happens to work on linux, by default close() unregisters FDs from
epoll so it passed below the radar.


Ok so Willy I will send a well-formed patch asap.





Re: Bug: DNS changes in 1.7.3+ break UNIX socket stats in daemon mode with resolvers on FreeBSD

2017-05-12 Thread Frederic Lecaille

On 05/12/2017 09:52 AM, Willy Tarreau wrote:

On Fri, May 12, 2017 at 09:48:56AM +0200, Frederic Lecaille wrote:

On 05/12/2017 09:37 AM, Willy Tarreau wrote:

On Fri, May 12, 2017 at 08:58:56AM +0200, Lukas Tribus wrote:

Hi,


Am 11.05.2017 um 21:13 schrieb Jim Pingle:

On 05/11/2017 01:58 PM, Frederic Lecaille wrote:

I have reproduced (at home) the stats socket issue within a FreeBSD 9.3 VM.

Replacing your call to close() by fd_delete() which removes the fd from
the fd set used by kevent *and close it* seems to fix at least the stats
socket issue. I do not know if there are remaining ones.

I did not reproduced the kevent issue revealed by Lukas traces. But I
had other ones : ERR#57 'Socket is not connected' during sendto().

I attached a temporary patch to be validated and to let you perhaps
provide a better one as I have not double check everything.

Fred,

That seems to have fixed the problem for me. With that patch applied,
web traffic passes and the UNIX socket responds.


Confirmed, works for me too. Baptiste? Willy? Is this an acceptable fix?


Yes definitely, not only an acceptable one, but the right fix. I understand
why it happens to work on linux, by default close() unregisters FDs from
epoll so it passed below the radar.


Ok so Willy I will send a well-formed patch asap.


Thanks Fred!
Willy


Here is a more well-formed patch.
Feel free to amend the commit message if not enough clear ;)

Regards,

Fred.

>From e6c4a93bbc8838046ab9737bbd5d4be075a72393 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Fri, 12 May 2017 09:57:15 +0200
Subject: [PATCH] BUG/MAJOR: dns: Broken kqueue events handling (BSD systems).

Some DNS related network sockets were closed without unregistering their file
descriptors from their underlying kqueue event sets. This patch replaces calls to
close() by fd_delete() calls to that to delete such events attached to DNS
network sockets from the kqueue before closing the sockets.
---
 src/dns.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/dns.c b/src/dns.c
index a118598..cb0a9a9 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -1004,7 +1004,7 @@ int dns_init_resolvers(int close_socket)
 
 			if (close_socket == 1) {
 if (curnameserver->dgram) {
-	close(curnameserver->dgram->t.sock.fd);
+	fd_delete(curnameserver->dgram->t.sock.fd);
 	memset(curnameserver->dgram, '\0', sizeof(*dgram));
 	dgram = curnameserver->dgram;
 }
-- 
2.1.4



Re: Bug: DNS changes in 1.7.3+ break UNIX socket stats in daemon mode with resolvers on FreeBSD

2017-05-11 Thread Frederic Lecaille

Hi,

On 05/11/2017 09:51 AM, Baptiste wrote:

Hi Lukas,

Thanks a lot!

So, after the fork(), HAProxy closes the UDP socket (4) and open a new
one (1) as expected, that said, the scheduler still points to the old one.
Obviously, this behavior doesn't happen on Linux.


socket #4 has been closed() but not removed from kevent fd set...


I'll see how I can reproduce the issue and then fix it. That said, I'm
running a bit out of time for now.


I have reproduced (at home) the stats socket issue within a FreeBSD 9.3 VM.

Replacing your call to close() by fd_delete() which removes the fd from 
the fd set used by kevent *and close it* seems to fix at least the stats 
socket issue. I do not know if there are remaining ones.


I did not reproduced the kevent issue revealed by Lukas traces. But I 
had other ones : ERR#57 'Socket is not connected' during sendto().


I attached a temporary patch to be validated and to let you perhaps 
provide a better one as I have not double check everything.


I hope this will help.

Regards,

Fred.
diff --git a/src/dns.c b/src/dns.c
index a118598..cb0a9a9 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -1004,7 +1004,7 @@ int dns_init_resolvers(int close_socket)
 
 			if (close_socket == 1) {
 if (curnameserver->dgram) {
-	close(curnameserver->dgram->t.sock.fd);
+	fd_delete(curnameserver->dgram->t.sock.fd);
 	memset(curnameserver->dgram, '\0', sizeof(*dgram));
 	dgram = curnameserver->dgram;
 }


Re: HAProxy won't shut down

2017-05-29 Thread Frederic Lecaille


Hi Patrick,

First thank you for this nice and helpful report.

Would it be possible to have an output of this command the next time you 
reproduce such an issue please?


echo "show sess" | socat stdio 

I have only one question (see below).

On 05/24/2017 10:40 AM, Willy Tarreau wrote:

Hi Patrick,

On Tue, May 23, 2017 at 01:49:42PM -0400, Patrick Hemmer wrote:
(...)

haproxy 28856 root1u IPv4  420797940  0t0TCP 
10.0.33.145:35754->10.0.33.147:1029 (CLOSE_WAIT)
haproxy 28856 root2u IPv4  420266351  0t0TCP 
10.0.33.145:52898->10.0.33.147:1029 (CLOSE_WAIT)
haproxy 28856 root3r  REG0,30 4026531956 net
haproxy 28856 root4u IPv4  422150834  0t0TCP 
10.0.33.145:38874->10.0.33.147:1029 (CLOSE_WAIT)


These ones are very interesting.


These traces also seem interesting to me.

# strace -p 28856
Process 28856 attached
epoll_wait(0, {}, 200, 319) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 362) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 114) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 203) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 331) = 0
epoll_wait(0, {}, 200, 0)


Were such "epoll_wait(0, 0, 200, 0)" calls infinitively displayed?


In fact I am wondering if it is normal to have so much epoll_wait(0, {}, 
200, 0) calls for a haproxy process which has shut down.


I suspect they are in relation with peer tasks (obviously which has 
expired).


If this is the case, and with configurations with only peer tasks, 
haproxy would definitively hang consuming a lot of CPU resources.


So, I had a look at the peer struct task 'expire' member handling code, 
and I have just found a situation where pollers in relation with peer 
tasks are often called with an expired timeout leading haproxy to 
consume a lot of CPU resources. In fact this happens each time the peer 
task has expired during a fraction of second.


It is easy to reproduce this issue with a sort of peer simulator ;):

strace -ttf socat TCP4-LISTEN:,reuseaddr,fork SYSTEM:"echo 
200;sleep 10"


This peer must be started *before* the other remote haproxy process with 
only peers as backends.


strace is here only to have an idea of the moment where the remote 
haproxy peer has just connected.


The sleep command is here to have enough time to block (ctrl + s) our 
peer simulator process after the haproxy peer has just connected.


So this peer accepts any remote peer sessions sending "200" status 
messages (and that's all).


A haproxy peer which connects to such a peer which does not reply to a 
synchronization request would endlessly consume high CPU ressources 
until you unblock (ctrl + q) the peer simulator process.


*Unhappily, I do not see any relation between this bug and the 
"CLOSE_WAIT peer state issue" which prevents haproxy from correctly 
shutting down.*


I have attached a patch to this mail which fixes this issue.

Regards,

Fred.






>From 855635c42b89e25a52255dd5edc8c872e888656e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 29 May 2017 13:47:16 +0200
Subject: [PATCH] BUG/MINOR: Wrong peer task expiration handling during
 synchronization processing.

When a peer task has sent a synchronization request to remote peers
its next expiration date was updated based on a resynchronization timeout
value which itself may have already expired leading the underlying
poller to wait for 0ms during a fraction of second (consuming high CPU
resources).

With this patch we update such peer task expiration dates only if
the resynchronization timeout is not already expired.

Thanks to Patrick Hemmer who reported an issue with nice traces
which helped in finding this one.

This patch may be backported to 1.7 and 1.6.
---
 src/peers.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/peers.c b/src/peers.c
index 0c8861f..0ebc040 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -1957,8 +1957,9 @@ static struct task *process_peer_sync(struct task * task)
 
 		if ((peers->flags & PEERS_RESYNC_STATEMASK) != PEERS_RESYNC_FINISHED) {
 			/* Resync not finished*/
-			/* reschedule task to resync timeout, to ended resync if needed */
-			task->expire = tick_first(task->expire, peers->resync_timeout);
+			/* reschedule task to resync timeout if not expired, to ended resync if needed */
+			if (!tick_is_expired(peers->resync_timeout, now_ms))
+task->expire = tick_first(task->expire, peers->resync_timeout);
 		}
 	} /* !stopping */
 	else {
-- 
2.1.4



Re: HAProxy won't shut down

2017-05-29 Thread Frederic Lecaille

On 05/29/2017 06:12 PM, Patrick Hemmer wrote:


On 2017/5/29 08:22, Frederic Lecaille wrote:


Hi Patrick,

First thank you for this nice and helpful report.

Would it be possible to have an output of this command the next time
you reproduce such an issue please?

echo "show sess" | socat stdio 


Unfortunately this would not be possible. When the issue occurs, the
haproxy process has stopped accepting connections on all sockets. If I
were to run this command, it would be sent to the new process, not the
one that won't shut down.



If you send a SIGHUP to haproxy-systemd-wrapper it asks the old process 
to graceful stop.


Please have a look to this documentation:

https://cbonte.github.io/haproxy-dconv/1.7/management.html#4

So you are true, if everything goes well no more connection are 
accept()'ed by the old process (the sockets have been unbound). But in 
your reported case the peers sockets are not closed because still in 
CLOSE_WAIT state, so are still being processed, so stats information are 
still available from the socket stats.


If I have missed something please does not hesitate to yell at me ;) .

I have been told that "show sess *all*" give more information.



I have only one question (see below).

On 05/24/2017 10:40 AM, Willy Tarreau wrote:

Hi Patrick,

On Tue, May 23, 2017 at 01:49:42PM -0400, Patrick Hemmer wrote:
(...)

haproxy 28856 root1u IPv4  420797940  0t0
TCP 10.0.33.145:35754->10.0.33.147:1029 (CLOSE_WAIT)
haproxy 28856 root2u IPv4  420266351  0t0
TCP 10.0.33.145:52898->10.0.33.147:1029 (CLOSE_WAIT)
haproxy 28856 root3r  REG0,30
4026531956 net
haproxy 28856 root4u IPv4  422150834  0t0
TCP 10.0.33.145:38874->10.0.33.147:1029 (CLOSE_WAIT)


These ones are very interesting.


These traces also seem interesting to me.

# strace -p 28856
Process 28856 attached
epoll_wait(0, {}, 200, 319) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 362) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 114) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 203) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 331) = 0
epoll_wait(0, {}, 200, 0)


Were such "epoll_wait(0, 0, 200, 0)" calls infinitively displayed?

Yes




In fact I am wondering if it is normal to have so much epoll_wait(0,
{}, 200, 0) calls for a haproxy process which has shut down.

I suspect they are in relation with peer tasks (obviously which has
expired).

If this is the case, and with configurations with only peer tasks,
haproxy would definitively hang consuming a lot of CPU resources.

HAProxy was not consuming high CPU. Note that in every other call to
`epoll_wait`, the 4th value was >0. If every single timeout value were
0, then yes, it would spin consuming CPU.



agreed... but perhaps your configuration does not use only peer tasks, 
contrary to my configuration... this is your traces which lead me to 
check how the peer task expiration is handled with configurations with 
only peers as backends.


In my case with only two peers I see such following traces, after a peer 
has sent a synchronization request:


epoll_wait(0, {}, 200, 1000}
epoll_wait(0, {}, 200, 1000}
epoll_wait(0, {}, 200, 1000}
epoll_wait(0, {}, 200, 1000}
epoll_wait(0, {}, 200, X}# with X < 1000

followed by a big loop of

epoll_wait(0, {}, 200, 0}# so consuming high CPU resources 
during a fraction of second


then:

shutdown(SHUT_WR)# FIN TCP segment at about 5s after 
the first epoll_wait(0, 0, 200, 1000} above.


then again:

epoll_wait(0, {}, 200, 0}

until the remote peer, which is in CLOSE_WAIT state shuts down its socket.

I have not told you that a synchronization request is the first thing a 
peer launches: the peers of the new process try to synchronize with old 
process peers.


With the fix I provided the process epoll_wait(0, {}, 200, *1000*} after
having shutdown(SHUT_WR} its socket... but it concerns only peers which 
are remote from each others.





So, I had a look at the peer struct task 'expire' member handling
code, and I have just found a situation where pollers in relation with
peer tasks are often called with an expired timeout leading haproxy to
consume a lot of CPU resources. In fact this happens each time the
peer task has expired during a fraction of second.

It is easy to reproduce this issue with a sort of peer simulator ;):

strace -ttf socat TCP4-LISTEN:,reuseaddr,fork SYSTEM:"echo
200;sleep 10"

This peer must be started *before* the other remote haproxy process
with only peers as backends.

strace is here only to have an idea of the moment where the remote
haproxy peer has just connected.

The sleep command is here to have enough time to block (ctrl + s) our
peer simulator

Re: BUG: Seg fault when reloading from saved state after config change

2017-06-15 Thread Frederic Lecaille

On 06/14/2017 11:02 PM, Shelley Shostak wrote:

Aha.  The problem is that the new haproxy.cfg file has hosts that are
not in the stat file.  If there is no state file, the haproxy.cfg file
is perfectly valid.

I've attached a self-contained config file and state file that will
reproduce the seg fault.  Also the output of haproxy -c using those
files.  Drop them into /tmp/haproxy for them to work.


Hello Shelley,

Thank you a lot for these files.

In fact there are several servers in .cfg file which are not listed in 
the state file.


The first hole is here in .cfg file (I have removed useless parameters).

  server upload3124.lv7.box.net
  server upload3125.lv7.box.net
  server upload3127.lv7.box.net

upload3126 is missing.

As there is no hole in the state file, and because the state file parser 
try to match servers arriving from .cfg first by id, then by name, 
*upload3126* server states will be applied to upload3127 server (they 
have the same id), then upload3127 states will be applied again to 
updload3127.


As there is at least one inconsistency between these two servers 
parameters which are not verified I guess this will make haproxy crash.


In fact such server lines in state files which do not match the 
configuration must be ignored.


The patch attached fixes this issue.

Regards,

Fred.
>From 95ef7cd2e01614cbe68b62ff0b0dcec1edb5c4a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Thu, 15 Jun 2017 14:09:10 +0200
Subject: [PATCH] BUG/MAJOR: server: Segfault after parsing server state file.

This patch makes the server state file parser ignore servers wich are
not present in the configuration file.
---
 src/server.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/server.c b/src/server.c
index 74450a1..008bafa 100644
--- a/src/server.c
+++ b/src/server.c
@@ -3479,10 +3479,12 @@ void apply_server_state(void)
 			else if (diff & PR_FBM_MISMATCH_ID) {
 Warning("In backend '%s' (id: '%d'): server ID mismatch: from server state file: '%s', from running config %d\n", bk->id, bk->uuid, params[2], srv->puid);
 send_log(bk, LOG_NOTICE, "In backend '%s' (id: %d): server ID mismatch: from server state file: '%s', from running config %d\n", bk->id, bk->uuid, params[2], srv->puid);
+continue;
 			}
 			else if (diff & PR_FBM_MISMATCH_NAME) {
 Warning("In backend '%s' (id: %d): server name mismatch: from server state file: '%s', from running config '%s'\n", bk->id, bk->uuid, params[3], srv->id);
 send_log(bk, LOG_NOTICE, "In backend '%s' (id: %d): server name mismatch: from server state file: '%s', from running config '%s'\n", bk->id, bk->uuid, params[3], srv->id);
+continue;
 			}
 
 			/* now we can proceed with server's state update */
-- 
2.1.4



Re: HAProxy won't shut down

2017-06-15 Thread Frederic Lecaille

On 06/14/2017 06:47 PM, Aleksandar Lazic wrote:

Hi Frederic & Willy.


Hi Aleksandar,


As this link is mentioned in the patch

https://engineeringblog.yelp.com/2015/04/true-zero-downtime-haproxy-reloads.html

yelps new solution for this topic looks interesting.

https://engineeringblog.yelp.com/2017/05/taking-zero-downtime-load-balancing-even-further.html


Thanks a lot for this new link to this new very interesting Yelp blog post.

Fred.




Re: HAProxy won't shut down

2017-06-13 Thread Frederic Lecaille

Hello Patrick,

Sorry for this late reply. I preferred focusing on how to reproduce your 
peer CLOSE_WAIT issue.


See my answers below.

On 05/30/2017 05:29 PM, Patrick Hemmer wrote:



On 2017/5/29 16:04, Frederic Lecaille wrote:

On 05/29/2017 06:12 PM, Patrick Hemmer wrote:


On 2017/5/29 08:22, Frederic Lecaille wrote:


Hi Patrick,

First thank you for this nice and helpful report.

Would it be possible to have an output of this command the next time
you reproduce such an issue please?

echo "show sess" | socat stdio 


Unfortunately this would not be possible. When the issue occurs, the
haproxy process has stopped accepting connections on all sockets. If I
were to run this command, it would be sent to the new process, not the
one that won't shut down.



If you send a SIGHUP to haproxy-systemd-wrapper it asks the old
process to graceful stop.

Yes, that is what my issue report is about. When sent a SIGHUP, the new
process comes up, but the old process won't shut down.



Please have a look to this documentation:

https://cbonte.github.io/haproxy-dconv/1.7/management.html#4

So you are true, if everything goes well no more connection are
accept()'ed by the old process (the sockets have been unbound). But in
your reported case the peers sockets are not closed because still in
CLOSE_WAIT state, so are still being processed, so stats information
are still available from the socket stats.

The information might still be tracked within the process, but there is
no way to query the information because the process is no longer
accepting new connections. The new process has taken over control of the
admin socket.


Of course but the new process may use another stats socket.

Here is an example of peer TCP session in CLOSE_WAIT state which will 
never be closed:


0x82ff420: [13/Jun/2017:13:15:18.527593] id=0 proto=tcpv4
  flags=0x23006, conn_retries=0, srv_conn=(nil), pend_pos=(nil)
  frontend=hostB (id=4294967295 mode=tcp), listener=? (id=0)
  backend= (id=-1 mode=-) addr=127.0.0.1:51488
  server= (id=-1) addr=127.0.0.10:1
  task=0x82ff3c8 (state=0x08 nice=0 calls=2 exp= age=12m11s)
  si[0]=0x82ff570 (state=CLO flags=0x4040 endp0=APPCTX:0x8303bd0 
exp=, et=0x000)
  si[1]=0x82ff58c (state=CON flags=0x50 endp1=CONN:0x8303a88 
exp=, et=0x020)

  app0=0x8303bd0 st0=11 st1=0 st2=0 applet=
  co1=0x8303a88 ctrl=tcpv4 xprt=RAW data=STRM target=PROXY:0x82b8288
  flags=0x0020b310 fd=1 fd.state=22 fd.cache=0 updt=0
  req=0x82ff42c (f=0x80a020 an=0x0 pipe=0 tofwd=0 total=0)
  an_exp= rex= wex=
  buf=0x81562a8 data=0x81562b8 o=0 p=0 req.next=0 i=0 size=0
  res=0x82ff460 (f=0x80402020 an=0x0 pipe=0 tofwd=0 total=0)
  an_exp= rex= wex=
  buf=0x81562a8 data=0x81562b8 o=0 p=0 rsp.next=0 i=0 size=0



If I have missed something please does not hesitate to yell at me ;) .

I have been told that "show sess *all*" give more information.



I have only one question (see below).

On 05/24/2017 10:40 AM, Willy Tarreau wrote:

Hi Patrick,

On Tue, May 23, 2017 at 01:49:42PM -0400, Patrick Hemmer wrote:
(...)

haproxy 28856 root1u IPv4  420797940  0t0
TCP 10.0.33.145:35754->10.0.33.147:1029 (CLOSE_WAIT)
haproxy 28856 root2u IPv4  420266351  0t0
TCP 10.0.33.145:52898->10.0.33.147:1029 (CLOSE_WAIT)
haproxy 28856 root3r  REG0,30
4026531956 net
haproxy 28856 root4u IPv4  422150834  0t0
TCP 10.0.33.145:38874->10.0.33.147:1029 (CLOSE_WAIT)


These ones are very interesting.


These traces also seem interesting to me.

# strace -p 28856
Process 28856 attached
epoll_wait(0, {}, 200, 319) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 362) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 114) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 203) = 0
epoll_wait(0, {}, 200, 0)   = 0
epoll_wait(0, {}, 200, 331) = 0
epoll_wait(0, {}, 200, 0)


Were such "epoll_wait(0, 0, 200, 0)" calls infinitively displayed?

Yes




In fact I am wondering if it is normal to have so much epoll_wait(0,
{}, 200, 0) calls for a haproxy process which has shut down.

I suspect they are in relation with peer tasks (obviously which has
expired).

If this is the case, and with configurations with only peer tasks,
haproxy would definitively hang consuming a lot of CPU resources.

HAProxy was not consuming high CPU. Note that in every other call to
`epoll_wait`, the 4th value was >0. If every single timeout value were
0, then yes, it would spin consuming CPU.



agreed... but perhaps your configuration does not use only peer tasks,
contrary to my configuration... this is your traces which lead me to
check how the peer task expiration is handled with configurations with
only peers as backends.

In my case with only two peers I see such following traces, after

Re: HAProxy won't shut down

2017-06-14 Thread Frederic Lecaille

On 06/14/2017 01:43 PM, Willy Tarreau wrote:

Hi Fred,

On Tue, Jun 13, 2017 at 09:16:33PM +0200, Frederic Lecaille wrote:
(...)

So I have compiled haproxy with the little src/plug_qdisc.c source file
(attached to this mail) highly inspired from libnl-utils package sources and
managed to make a haproxy peer block and unblock incoming connections from
another remote peer calling plug_qdisc_release_indefinite_buffer() and
plug_qdisc_plug_buffer() at the right places and only on one peer side, the
CLOSE_WAIT issue happening on the remote side.


Wow, this stuff is absolutely awesome! It will definitely be very helpful
to reproduce certain classes of bugs which have already required some
stuff like tcploop.c! So please add this to contrib/ (eg: contrib/plug_qdisc
or whatever you like) with 3-5 lines of README to help a developer quickly
spot how to call it. No need for details, those who can't figure how to
build it don't need it anyway.


Ok. Here is a patch for that.


>From 0c96ce424eb4ba54e8f0afd037814fa4187673cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Wed, 14 Jun 2017 15:16:15 +0200
Subject: [PATCH 2/2] CONTRIB: plug qdiscs: Plug queuing disciplines mini
 HOWTO.

Add plug_qdisc.c source file which may help in how to programatically
use plug queueing disciplines with its README file.
Such code may be useful to reproduce painful network application bugs.
---
 contrib/plug_qdisc/README   | 59 
 contrib/plug_qdisc/plug_qdisc.c | 86 +
 2 files changed, 145 insertions(+)
 create mode 100644 contrib/plug_qdisc/README
 create mode 100644 contrib/plug_qdisc/plug_qdisc.c

diff --git a/contrib/plug_qdisc/README b/contrib/plug_qdisc/README
new file mode 100644
index 000..ccc9bd0
--- /dev/null
+++ b/contrib/plug_qdisc/README
@@ -0,0 +1,59 @@
+  ** Plug queueing disciplines **
+
+  The 'plug' qdisc type is not documented. It is even not supported
+  by traffic shaping tools like 'tc' from iproute2 package.
+
+  Such qdiscs have already been used by Yelp engineers but outside
+  of haproxy with libnl-utils tools (especially nl-qdisc-* tools)
+  to implement a workaround and make haproxy reloads work.
+
+  Indeed with such plug qdiscs coupled with iptables configurations
+  we are able to temporarily bufferize IP packets and to release them as
+  needed. So, they may be very useful to "synchronize" TCP sessions
+  or at higher level to put network applications in states approaching
+  the ones suspected to occur during bugs. Furthermore to be sure
+  to produce a correct bug fix, it may be useful to reproduce
+  as mush as needed such painful bugs. This is where plug qdiscs
+  may be useful.
+
+  To have an idea about how to use plug qdisc on the command line I highly recommend to
+  read Willy Tarreau blog here:
+
+  https://www.haproxy.com/blog/truly-seamless-reloads-with-haproxy-no-more-hacks/
+
+  which refers to this other one from Yelp:
+
+  https://engineeringblog.yelp.com/2015/04/true-zero-downtime-haproxy-reloads.html
+
+  The code found in plug_qdisc.c file already helped in fixing a painful bug hard to
+  fix because hard to reproduce. To use the API it exports this is quite easy:
+
+- First your program must call plug_disc_attach() to create if not already created
+  a plug qdisc and use it (must be done during your application own already existing
+  initializations).
+  Note that this function calls plug_qdisc_release_indefinite_buffer() so that to
+  release already buffered packets before you start your application,
+
+- then call plug_qdisc_plug_buffer() to start buffering packets incoming to your
+  plug qdisc. So they won't be delivered to your application,
+
+- then call plug_qdisc_release_indefinite_buffer() to stop buffering the packets
+  incoming to your plug qdisc and release those already buffered.
+  So, that to be deliver them to your application.
+
+  This code is short and simple. But uses several libraries especially libnl-route module
+  part of libnl library. To compile haproxy and make it use the plug_qdisc.c code we had
+  to link it against several libnl3 library modules like that:
+
+ -lnl-genl-3 -lnl-route-3 -lnl-3 -lnl-cli-3
+
+
+  - Some references:
+Libnl API documentation may be found here:
+https://www.infradead.org/~tgr/libnl/doc/api/index.html
+
+Kernel sources:
+http://elixir.free-electrons.com/linux/latest/source/net/sched/sch_plug.c
+
+Nice website about traffic shaping with queuing disciplines:
+http://wiki.linuxwall.info/doku.php/en:ressources:dossiers:networking:traffic_control
diff --git a/contrib/plug_qdisc/plug_qdisc.c b/contrib/plug_qdisc/plug_qdisc.c
new file mode 100644
index 000..294994e
--- /dev/null
+++ b/contrib/plug_qdisc/plug_qdisc.c
@@ -0,0 +1,86 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#inc

Re: HAProxy won't shut down

2017-06-14 Thread Frederic Lecaille

On 06/13/2017 09:16 PM, Frederic Lecaille wrote:

Hello Patrick,



[snipped]


I hope the pach attached to this mail will definitively fix such peer
CLOSE_WAIT issues.


A better patch which fixes the comments and commit message.



>From 5535bcd5298bbbce11385eee18ef740848d31903 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Tue, 13 Jun 2017 16:39:57 +0200
Subject: [PATCH] MINOR: peers: Peers CLOSE_WAIT issue.

A peer session which has just been created upon reconnect timeout expirations,
could be right after shutdown (at peer session level) because the remote
side peer could also righ after have connected. In such a case the underlying
TCP session was still running (connect()/accept()) and finally left in CLOSE_WAIT
state after the remote side stopped writting (shutdown(SHUT_WR)).

Now on, with this patch we never shutdown such peer sessions wich have just
been created. We leave them connect to the remote peer which is already
connected and must shutdown its own peer session.

Thanks to Patric Hemmer for reporting this issue and to Willy and Yelp blogs
which helped me in fixing this issue.
(See https://www.haproxy.com/blog/truly-seamless-reloads-with-haproxy-no-more-hacks/ and
https://engineeringblog.yelp.com/2015/04/true-zero-downtime-haproxy-reloads.htmll)
---
 src/peers.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/peers.c b/src/peers.c
index 0c8861f..0dd93ea 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -1719,7 +1719,13 @@ static void peer_session_forceshutdown(struct appctx *appctx)
 {
 	struct peer *ps;
 
-	if (!appctx)
+	/* Note that the peer sessions which have just been created
+	 * (->st0 == PEER_SESS_SC_CONNECTCODE) must not
+	 * be shutdown, if not, the TCP session will never be closed
+	 * and stay in CLOSE_WAIT state after having been closed by
+	 * the remote side.
+	 */
+	if (!appctx || appctx->st0 == PEER_SESS_SC_CONNECTCODE)
 		return;
 
 	if (appctx->applet != _applet)
-- 
2.1.4



Re: Possible regression in 1.6.12

2017-06-16 Thread Frederic Lecaille

On 06/16/2017 03:20 PM, Willy Tarreau wrote:

On Fri, Jun 16, 2017 at 03:10:56PM +0200, Willy Tarreau wrote:

Hi Veiko,

On Fri, Jun 16, 2017 at 01:41:14PM +0300, Veiko Kukk wrote:

So I have more info on this now. Veiko, first, I'm assuming that your config
was using "resolvers dns_resolvers" on the "server" line, otherwise resolvers
are not used.


My real world configs use resolvers, but timeouts happen even when resolver
was not used anywhere.


Wow then that's super strange, as by definition they are not even triggered
in this case!


I'm just realizing that it's very similar to the bug that Fred fixed here :

https://www.mail-archive.com/haproxy@formilux.org/msg26040.html


Ah, yes I remember this one. Calling close() in place of fd_delete() 
(which calls close()) puts a big mess in the fd cache for pollers. So 
not only on BSD systems ;)





Re: HAProxy won't shut down

2017-06-14 Thread Frederic Lecaille

On 06/14/2017 08:51 AM, Frederic Lecaille wrote:

On 06/13/2017 09:16 PM, Frederic Lecaille wrote:

Hello Patrick,



[snipped]


I hope the pach attached to this mail will definitively fix such peer
CLOSE_WAIT issues.


A better patch which fixes the comments and commit message.


Sorry again but when I created my patch yesterday evening from a clean 
branch I did not use the correct flag I used in another branch during my 
tests. In the bad patch PEER_SESS_ST_CONNECT was replaced by 
PEER_SESS_SC_CONNECTCODE.


Here is a new patch.
>From bc5c6a75eedb1745866cca27c4aafb67bbfdc1cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <flecai...@haproxy.com>
Date: Tue, 13 Jun 2017 16:39:57 +0200
Subject: [PATCH] MINOR: peers: Peers CLOSE_WAIT issue.

A peer session which has just been created upon reconnect timeout expirations,
could be right after shutdown (at peer session level) because the remote
side peer could also righ after have connected. In such a case the underlying
TCP session was still running (connect()/accept()) and finally left in CLOSE_WAIT
state after the remote side stopped writting (shutdown(SHUT_WR)).

Now on, with this patch we never shutdown such peer sessions wich have just
been created. We leave them connect to the remote peer which is already
connected and must shutdown its own peer session.

Thanks to Patric Hemmer for reporting this issue and to Willy and Yelp blogs
which helped me in fixing this issue.
(See https://www.haproxy.com/blog/truly-seamless-reloads-with-haproxy-no-more-hacks/ and
https://engineeringblog.yelp.com/2015/04/true-zero-downtime-haproxy-reloads.htmll)
---
 src/peers.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/peers.c b/src/peers.c
index 0c8861f..beeec96 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -1719,7 +1719,13 @@ static void peer_session_forceshutdown(struct appctx *appctx)
 {
 	struct peer *ps;
 
-	if (!appctx)
+	/* Note that the peer sessions which have just been created
+	 * (->st0 == PEER_SESS_ST_CONNECT) must not
+	 * be shutdown, if not, the TCP session will never be closed
+	 * and stay in CLOSE_WAIT state after having been closed by
+	 * the remote side.
+	 */
+	if (!appctx || appctx->st0 == PEER_SESS_ST_CONNECT)
 		return;
 
 	if (appctx->applet != _applet)
-- 
2.1.4



Re: server FQDN changes from stats socket + server-state file

2017-05-02 Thread Frederic Lecaille

On 05/02/2017 03:45 PM, Baptiste wrote:


Here is a new patch version which takes into an account Baptiste
remarks.

Thank you again Baptiste.


Hi Fred,

I gave a try to your code today and found a segfault at the next DNS
request following the fqdn change.
I attached a patch to this email to fix it, simply merge it into yours.


Here is an update of my patch which integrates your fix.

Fred.

>From 31429d2aefa16c6bd6c83ca2ab60d48cef666c60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Wed, 26 Apr 2017 11:24:02 +0200
Subject: [PATCH] MINOR: server: cli: Add server FQDNs to server-state file and
 stats socket.

This patch adds a new stats socket command to modify server
FQDNs at run time.
Its syntax:
  set server / fqdn 
This patch also adds FQDNs to server state file at the end
of each line for backward compatibility ("-" if not present).
---
 doc/management.txt |   7 +++
 include/types/server.h |  22 ++-
 src/cfgparse.c |   2 -
 src/proxy.c|   4 +-
 src/server.c   | 165 +
 5 files changed, 184 insertions(+), 16 deletions(-)

diff --git a/doc/management.txt b/doc/management.txt
index 3368277..d1ea1f6 100644
--- a/doc/management.txt
+++ b/doc/management.txt
@@ -1650,6 +1650,9 @@ set server / weight [%]
   Change a server's weight to the value passed in argument. This is the exact
   equivalent of the "set weight" command below.
 
+set server / fqdn 
+  Change a server's FQDN to the value passed in argument.
+
 set ssl ocsp-response 
   This command is used to update an OCSP Response for a certificate (see "crt"
   on "bind" lines). Same controls are performed as during the initial loading of
@@ -1962,6 +1965,9 @@ show servers state []
 0x20 = SRV_ADMF_RMAINT
   The server is in maintenance because of an
   IP address resolution failure.
+0x40 = SRV_ADMF_HMAINT
+  The server FQDN was set from stats socket.
+
  srv_uweight: User visible server's weight.
  srv_iweight: Server's initial weight.
  srv_time_since_last_change:  Time since last operational change.
@@ -2003,6 +2009,7 @@ show servers state []
   configuration.
  srv_f_forced_id: Flag to know if the server's ID is forced by
   configuration.
+ srv_fqdn:Server FQDN.
 
 show sess
   Dump all known sessions. Avoid doing this on slow connections as this can
diff --git a/include/types/server.h b/include/types/server.h
index 8d68dcb..83b1e80 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -82,6 +82,7 @@ enum srv_admin {
 	SRV_ADMF_IDRAIN= 0x10,/* the server has inherited the drain status from a tracked server */
 	SRV_ADMF_DRAIN = 0x18,/* mask to check if any drain flag is present */
 	SRV_ADMF_RMAINT= 0x20,/* the server is down because of an IP address resolution failure */
+	SRV_ADMF_HMAINT= 0x40,/* the server FQDN has been set from socket stats */
 };
 
 /* options for servers' "init-addr" parameter
@@ -103,7 +104,26 @@ enum srv_initaddr {
 #define SRV_STATE_FILE_VERSION 1
 #define SRV_STATE_FILE_VERSION_MIN 1
 #define SRV_STATE_FILE_VERSION_MAX 1
-#define SRV_STATE_FILE_FIELD_NAMES "be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id"
+#define SRV_STATE_FILE_FIELD_NAMES \
+"be_id "  \
+"be_name "\
+"srv_id " \
+"srv_name "   \
+"srv_addr "   \
+"srv_op_state "   \
+"srv_admin_state "\
+"srv_uweight "\
+"srv_iweight "\
+"srv_time_since_last_change " \
+"srv_check_status "   \
+"srv_check_result "   \
+"srv_check_health "   \
+"srv_check_state "\
+"srv_agent_state "\
+"bk_f_forced_id " \
+"srv_f_forced_id "\
+"srv_fqdn"
+
 #define SRV_STATE_FILE_MAX_FIELDS 18
 #define SRV_STATE_FILE_NB_FIELDS_VERSION_1 18
 #define SRV_STATE_LINE_MAXLEN 512
diff --git a/src/cfgparse.c b/src/cfgparse.c
index d44949a..f167321 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -8492,8 +8492,6 @@ out_uri_auth_compat:
 	newsrv->id, newsrv->resolvers_id);
 	cfgerr++;
 } else {
-	free(newsrv->resolvers_id);
-	newsrv->resolvers_id = NULL;
 	if (newsrv->resolution)
 		newsrv->resolution->resolvers = curr_resolvers;
 }
diff --git 

Re: server FQDN changes from stats socket + server-state file

2017-05-02 Thread Frederic Lecaille

On 05/02/2017 03:45 PM, Baptiste wrote:


Here is a new patch version which takes into an account Baptiste
remarks.

Thank you again Baptiste.


Hi Fred,


Hello Baptiste,


I gave a try to your code today and found a segfault at the next DNS
request following the fqdn change.
I attached a patch to this email to fix it, simply merge it into yours.



Ok I will have a look to this patch asap.


Note that my fix is temporary, since I'm reorganizing the DNS
structures. The ugly foreach loop will disapear once I'll get my patches
merged.

Baptiste



Thank you for reviewing/testing Baptiste.

Fred.



Re: Will HAProxy community supports mailers section?

2017-08-24 Thread Frederic Lecaille

On 08/24/2017 03:35 PM, Rajesh Kolli wrote:

Hi Daniel,

I have changed my config file according to you, even though i am getting
the same error.
-
haproxy.service - HAProxy Load Balancer
   Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled)
   Active: inactive (dead) since Thu 2017-08-24 19:04:14 IST; 6s ago
  Process: 7641 ExecStart=/usr/sbin/haproxy-systemd-wrapper -f
/etc/haproxy/haproxy.cfg -p /run/haproxy.pid (code=exited, status=0/SUCCESS)
 Main PID: 7641 (code=exited, status=0/SUCCESS)

Aug 24 19:04:14 DS-11-82-R7-CLST-Node1 systemd[1]: Starting HAProxy Load
Balancer...
Aug 24 19:04:14 DS-11-82-R7-CLST-Node1 systemd[1]: Started HAProxy Load
Balancer.
Aug 24 19:04:14 DS-11-82-R7-CLST-Node1 haproxy-systemd-wrapper[7641]:
[ALERT] 235/190414 (7642) : parsing [/etc/haproxy/haproxy.cfg:9]:
unknown keyword 'mailers' out of section.
Aug 24 19:04:14 DS-11-82-R7-CLST-Node1 haproxy-systemd-wrapper[7641]:
[ALERT] 235/190414 (7642) : parsing [/etc/haproxy/haproxy.cfg:10]:
unknown keyword 'mailer' out of section.
Aug 24 19:04:14 DS-11-82-R7-CLST-Node1 haproxy-systemd-wrapper[7641]:
[ALERT] 235/190414 (7642) : parsing [/etc/haproxy/haproxy.cfg:121] :
unknown keyword 'email-alert' in 'backend' section


Well I would at least say that your haproxy does not support 
"email-alert" keyword ;)


If I configure a 1.7 haproxy *without* any "mailers" section *but* with 
a "email-alert mailers mta" setting in "backend" sections the parser 
does not say it does not known "email-alert" keyword. It says: unable to 
find "mailers" mta.


So even your haproxy could support "mailers" keyword, as it does not 
support "email-alert", this would be for nothing ;)


You should try the same thing: remove/comment your "mailers" section, 
and see if you still have "unknown keyword 'email-alert' in 'backend' 
section".


AFAIK, "email-alert" may be followed by a "mailers" keyword  ;)

Or perhaps I have missed something.



Re: [PATCH]: CLEANUP

2017-08-22 Thread Frederic Lecaille

On 07/28/2017 05:23 PM, David CARLIER wrote:

Good points :-) sorry for the noise.

On 28 July 2017 at 14:07, Willy Tarreau > 
wrote:

Hi David,

On Fri, Jul 28, 2017 at 01:58:29PM +0100, David CARLIER wrote:
> Hi all,
>
> Nothing serious, just a patch proposal to silent compiler warning
about
> function parameter types.
>
> Kind regards.

> From 6ed9b28287440ca74e7a29016f9c4d081cd902d5 Mon Sep 17 00:00:00 2001
> From: David Carlier >
> Date: Fri, 28 Jul 2017 14:42:42 +0100
> Subject: [PATCH] CLEANUP: spoe: silencing compiler warning.
>
> Here we cast explicitally to silence gcc complains mismatches.
> ---
>  src/flt_spoe.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/src/flt_spoe.c b/src/flt_spoe.c
> index 5d574477..4df16ef6 100644
> --- a/src/flt_spoe.c
> +++ b/src/flt_spoe.c
> @@ -706,7 +706,7 @@ spoe_handle_agenthello_frame(struct appctx
*appctx, char *frame, size_t size)
>   SPOE_APPCTX(appctx)->status_code =
SPOE_FRM_ERR_INVALID;
>   return 0;
>   }
> - if (decode_varint(, end, ) == -1) {
> + if (decode_varint(, end, (uint64_t *))
== -1) {
(...)

I noticed these ones as well recently but I'd rather avoid to start
casting
the pointers, or sooner or later we'll regret it. And by the way
it's a real
bug, as decode_varint() takes an uint64_t* while size_t will
generally be an
uint32_t on 32-bit architectures.

We'll more generally need to slightly modify the internal prototypes
to use
either one or the other type. By experience I tend to be used to see
that
when you change one of them it can propagate far away. But it will
be safer
(and will address the issue on 32-bit).

As long as we have this warning we have a reminder that there's
something
to fix ;-)


Hello Willy, David, Christopher,

I have just had a look at this issue. In fact the required modifications 
were not that complicated.


Here is a simple patch for this issue.

Regards.


>From ca080eb5e0ed959686e7cb67cd614a570059aea1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 22 Aug 2017 10:33:14 +0200
Subject: [PATCH] BUG/MINOR: Wrong type used as argument for
 spoe_decode_buffer().
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Contrary to 64-bits libCs where size_t type size is 8, on systems with 32-bits
size of size_t is 4 (the size of a long) which does not equal to size of uint64_t type.
This was revealed by such GCC warnings on 32bits systems:

src/flt_spoe.c:2259:40: warning: passing argument 4 of ‘spoe_decode_buffer’ from
incompatible pointer type
  if (spoe_decode_buffer(, end, , ) == -1)
 ^
As the already existing code using spoe_decode_buffer() already use such pointers to
uint64_t, in place of pointer to size_t ;), most of this code is in contrib directory,
this simple patch modifies the prototype of spoe_decode_buffer() so that to use a
pointer to uint64_t in place of a pointer to size_t, uint64_t type being the type
finally required for decode_varint().
---
 include/proto/spoe.h | 7 +++
 src/flt_spoe.c   | 4 ++--
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/include/proto/spoe.h b/include/proto/spoe.h
index 1372a7d..002cf7d 100644
--- a/include/proto/spoe.h
+++ b/include/proto/spoe.h
@@ -92,7 +92,7 @@ spoe_encode_frag_buffer(const char *str, size_t len, char **buf, char *end)
  * On success, it returns the buffer length and <*buf> is moved after the
  * encoded buffer. Otherwise, it returns -1. */
 static inline int
-spoe_decode_buffer(char **buf, char *end, char **str, size_t *len)
+spoe_decode_buffer(char **buf, char *end, char **str, uint64_t *len)
 {
 	char*p = *buf;
 	uint64_t sz;
@@ -248,8 +248,7 @@ spoe_skip_data(char **buf, char *end)
 {
 	char*str, *p = *buf;
 	int  type, ret;
-	size_t   sz;
-	uint64_t v;
+	uint64_t v, sz;
 
 	if (p >= end)
 		return -1;
@@ -296,7 +295,7 @@ spoe_decode_data(char **buf, char *end, struct sample *smp)
 {
 	char  *str, *p = *buf;
 	inttype, r = 0;
-	size_t sz;
+	uint64_t sz;
 
 	if (p >= end)
 		return -1;
diff --git a/src/flt_spoe.c b/src/flt_spoe.c
index 5d57447..1a8bd2c 100644
--- a/src/flt_spoe.c
+++ b/src/flt_spoe.c
@@ -655,7 +655,7 @@ spoe_handle_agenthello_frame(struct appctx *appctx, char *frame, size_t size)
 	vsn = max_frame_size = flags = 0;
 	while (p < end) {
 		char  *str;
-		size_t sz;
+		uint64_t sz;
 		intret;
 
 		/* Decode the item key */
@@ -836,7 +836,7 @@ spoe_handle_agentdiscon_frame(struct appctx *appctx, char *frame, size_t size)
 	/* Loop on K/V 

Re: Issue with src_http_req_rate count

2017-08-30 Thread Frederic Lecaille

Hello Sikander,

Sorry for this late reply.

On 08/16/2017 01:24 PM, Sikander Dhaliwal wrote:

Dear Support,

We are using HA-Proxy version 1.8-dev1-7b67726 on four servers. To
handle the DDOS attacks, we have configured sticky-table rules.

The issue is, the same configuration is working on 3 servers but not on
one server. All the server packages,haproxy version and configuration
file  is same. But one server is showing 1/3rd requests in sticky table.
Consequently, it is not blocking any of the IPs.

However, rest of the servers showing correct count in sticky table
corresponding to the number of requests made and blocking the IPs as
well when they reach defined limit.


Could you please guide how we can eradicate the issue?  Which packages
haproxy use to count the http_req_rate?


Well, if there is a bug, it is not easy to know how to fix it as at this 
time we are not able to reproduce it.


When you are facing such a problem, would you mind issuing this command 
on the CLI to have more information about the current peer session 
states for each haproxy processes please:


  show sess all

If this command output is too big, I would be interested by the peer 
sessions information which look like this following one:


0x9a905e8: [30/Aug/2017:16:07:39.284581] id=0 proto=tcpv4
  flags=0x6, conn_retries=0, srv_conn=(nil), pend_pos=(nil)
  frontend=hostA (id=4294967295 mode=tcp), listener=? (id=0)
  backend= (id=-1 mode=-) addr=127.0.0.1:59320
  server= (id=-1) addr=127.0.0.100:8030
  task=0x9a90590 (state=0x08 nice=0 calls=2 exp=4s age=?)
  si[0]=0x9a90740 (state=EST flags=0x4048 endp0=APPCTX:0x9a907f0 
exp=, et=0x000)
  si[1]=0x9a9075c (state=EST flags=0x58 endp1=CONN:0x9a903f0 
exp=, et=0x000)


  app0=0x9a907f0 st0=7 st1=0 st2=0 *applet=*

  co1=0x9a903f0 ctrl=tcpv4 xprt=RAW data=STRM target=PROXY:0x9a52750
  flags=0x00203306 fd=1 fd.state=25 fd.cache=0 updt=0
  req=0x9a905f4 (f=0x848000 an=0x0 pipe=0 tofwd=-1 total=31)
  an_exp= rex=4s wex=
  buf=0x8187fc0 data=0x8187fd0 o=0 p=0 req.next=0 i=0 size=0
  res=0x9a90628 (f=0x80408202 an=0x0 pipe=0 tofwd=-1 total=4)
  an_exp= rex= wex=
  buf=0x9a5fc08 data=0x9a5fc18 o=0 p=0 rsp.next=0 i=0 size=16384

Note the line beginning by "app0=..." and terminated by "applet=". 
This is how you can distinguish the TCP peer sessions among others.



Regards.



Re: [BUG] haproxy 1.8-last/master-worker/peers

2017-11-28 Thread Frederic Lecaille

On 11/28/2017 02:13 PM, Willy Tarreau wrote:

On Tue, Nov 28, 2017 at 01:43:52PM +0100, Frederic Lecaille wrote:

On 11/28/2017 01:29 PM, Frederic Lecaille wrote:
There is a "/* fall through */" between PEER_SESS_ST_CONNECT and
PEER_SESS_ST_GETSTATUS cases in peer I/O handler code, so with a lock which
may be taken two times ;).


 From what I'm seeing it cannot take it twice because it only grabs the
lock when curpeer switches from null to non-null.


Yes. Wrong remark on my side.

What if peer state switched from PEER_SESS_ST_CONNECT to 
PEER_SESS_ST_GETPEER?


This may happen if the peer has just sent a hello message and just after 
received a hello message.





Re: [RFC] Wireshark dissector for SPOP

2017-11-28 Thread Frederic Lecaille

On 11/20/2017 10:16 PM, my.card@web.de wrote:

Hi Fred,


Hi Danny,

thanks for looking into this, I've fixed this issue (and introduced some 
new :-))
The attached dissector code parses all SPOP frames sent from 
contrib/spoa_sample and haproxy and handles some fragmentation scenarios.

Kind regards,
     Danny


Great job!

Why do not you send your wireshark dissector as a patch to haproxy 
mailing list?


It could be added to already existing contrib/wireshark-dissectors 
directory (let's say in contrib/wireshark-dissectors/spop directory).


Regards,

Fred.



Re: Aw: Re: [RFC] Wireshark dissector for SPOP

2017-11-19 Thread Frederic Lecaille

Hi Danny,

So I had a look at this issue which is easily reproducible.

See my answer below.

On 11/12/2017 07:43 PM, my.card@web.de wrote:

Hi,
I've figured it out, it has been a feature of the dissector code. 
Perhaps it might be useful for someone developing her own SPOA.

Kind regards,
   Danny
*Gesendet:* Donnerstag, 09. November 2017 um 16:07 Uhr
*Von:* "Frederic Lecaille" <flecai...@haproxy.com>
*An:* my.card@web.de, haproxy@formilux.org
*Betreff:* Re: [RFC] Wireshark dissector for SPOP
On 11/05/2017 09:27 AM, my.card@web.de wrote:
 > Hi all,

Hi,

 > I've implemented a very basic wireshark (https://www.wireshark.org)
 > dissector for SPOP. I've stumbled over the following issue, that I
 > couldn't figure out, yet.
 > ACTION-ARGS should be multiple TYPED-DATA items, but the data sent by
 > contrib/spoa_sample does not add type information:
 > 73335    14123.613537866    127.0.0.1    127.0.0.1    SPOP    89    ACK
 > STREAM-ID:35969 FRAME-ID:1[Malformed Packet]
 >    00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00  ..E.
 > 0010   00 4b 70 77 40 00 40 06 cc 33 7f 00 00 01 7f 00  .Kpw@.@..3..
 > 0020   00 01 30 39 cd 4c e8 1d cd f2 05 90 45 92 80 18  ..09.L..E...
 > 0030   01 5e fe 3f 00 00 01 01 08 0a 01 46 c7 f3 01 46  .^.?...F...F
 > 0040   c7 f3 67 01 00 00 00 f2 99 01 01 01 03 01 08 69  ..gi
 > 0050   70 5f 73 63 6f 72 65 03 47   p_score.G


"Malformed Packet"s are announced by wireshark when parsing ACK SPOP frames.

According to 3.4 paragraph of SPOP documentation, such frames are made 
of actions, with 3 arguments here when using ACTION-SET-VAR action only:


ACTION-SET-VAR  : byte>


The hexadecimal dump of this action here is:

01 03 01 08 69 70 5f 73 63 6f 72 65 03 47

which must be decomposed as follows:

01 -> SET-VAR
03 -> NB-ARGS
01 -> VAR-SCOPE  (1st argument)
08 69 70 5f 73 63 6f 72 65 -> VAR-NAME   (2nd argument)
 03 47 -> VAR-VALUE  (3rd argument)

Here VAR-NAME is a STRING field made of an encoded length -> 0x08 
followed by the non null terminated string -> 69 70 5f 73 63 6f 72 65 
(ip_score).


*But* note that these arguments are not 3 TYPED-DATA fields.
Only the last one VAR-VALUE argument is typed, so prefixed by a unique 
byte for the type (0x03 here -> UINT32).


So dissect_action_args() should not be made of a loop like this:

for (i=0; i<nbargs; i++)
length += dissect_typed_data(tvb, tree, offset + length);

At this time, your dissector considers VAR-SCOPE argument as a BOOL 
field (false) and VAR-NAME as a 0x69 bytes long STRING field (with 0x08 
as TYPED-DATA field ID).


I hope this will help to finalize your dissector which could be added to 
"contrib/wireshark-dissectors/spop" directory.



Regards.

Fred.



Re: [RFC] Wireshark dissector for SPOP

2017-11-09 Thread Frederic Lecaille

On 11/05/2017 09:27 AM, my.card@web.de wrote:

Hi all,


Hi,

I've implemented a very basic wireshark (https://www.wireshark.org) 
dissector for SPOP. I've stumbled over the following issue, that I 
couldn't figure out, yet.
ACTION-ARGS should be multiple TYPED-DATA items, but the data sent by 
contrib/spoa_sample does not add type information:
73335    14123.613537866    127.0.0.1    127.0.0.1    SPOP    89    ACK 
STREAM-ID:35969 FRAME-ID:1[Malformed Packet]

   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00  ..E.
0010   00 4b 70 77 40 00 40 06 cc 33 7f 00 00 01 7f 00  .Kpw@.@..3..
0020   00 01 30 39 cd 4c e8 1d cd f2 05 90 45 92 80 18  ..09.L..E...
0030   01 5e fe 3f 00 00 01 01 08 0a 01 46 c7 f3 01 46  .^.?...F...F
0040   c7 f3 67 01 00 00 00 f2 99 01 01 01 03 01 08 69  ..gi
0050   70 5f 73 63 6f 72 65 03 47   p_score.G
Is this an implementation or documentation issues? What is haproxy 
expecting here?

Kind regards,
     Danny


Thank you for sharing this code.

It could be interesting to have such a dissector in the future.

I will have a look at your code asap.

Do not hesitate to update this thread if you managed to fix some issues.

Regards,

Fred.



Re: regression testing for haproxy

2018-06-11 Thread Frederic Lecaille

On 06/09/2018 09:16 AM, Baptiste wrote:

Hi Fred,


Hi Baptiste,


Amazing work. Looking forward to write some of those :)


Yes for now on, *if possible*, it would be great to write a test file 
for each bug to come.

.
According to you, would it be compicated to automate tests on the DNS 
resolvers, the stats socket, etc...


About the CLI, as varnishtest is able to start a shell and as each 
haproxy processus starts a CLI (listening on /tmp/vtc.PID>.//stats.sock UNIX socket) it should 
be easy to write such tests.


ex:

shell {
echo "show servers state" | socat - ${tmpdir}/h1/stats.sock | grep 
-v ^#

}

with such a filtered output:

**   top   0.0 === shell {
 top   0.0 shell_cmd|exec 2>&1 ;
 top   0.0 shell_cmd|\techo "show servers state" | socat - 
/tmp/vtc.25976.1d3b8c2c/h1/stats.sock | grep -v ^#

 top   0.0 shell_out|1
 top   0.0 shell_out|2 my_https 1 cas1 1.2.3.4 2 0 1 1 0 1 0 2 7 0 0 
0 - 443
 top   0.0 shell_out|2 my_https 2 cas2 4.3.2.1 2 0 1 1 0 1 0 2 6 0 0 
0 - 443

 top   0.0 shell_out|
 top   0.0 shell_status = 0x


About DNS, I do not know what you exactly want to do? Obviously, at this 
time, varnishtest does not implement DNS protocol to speak to DNS servers.



I mean, anything which is not really HTTP?

Baptiste





regression testing for haproxy

2018-06-07 Thread Frederic Lecaille

Hi all,

We have recently worked in colloboration with Poul-Henning Kamp to use 
varnishtest regression testing (script driven) tool for Varnish HTTP 
Cache so that to modify it and make it capable of also test haproxy.


Note that here we are speaking about *regression* testing which has 
nothing to see with others classes of tests (unit, integration, 
performance etc). The aim of such tests is: to prevent old bugs from 
coming back!


A nice reference manual for varnishtest may be bound here:

https://varnish-cache.org/docs/6.0/reference/varnishtest.html

In a few words, varnishtest program is able to start HTTP clients and 
servers and put a varnish-cache processus (or several) in the middle to 
test it, making these clients and servers interact with each others. So, 
here we wanted to do the same thing for haproxy.


Of course, it will not always be possible to write a regression test 
script for each bug to come.


Please find attached to this mail a first patch to document how to use 
varnishtest regression testing tool with haproxy and help you to write 
regression test files.


We will have to discuss about how to organize the test files for these 
regressions tests.


A big thank you to Poul-Henning Kamp for having helped us during this 
interesting project.



Regards,

Fred.
   +-+
   | HAProxy regression testing with varnishtest |
   +-+


The information found in this file are a short starting guide to help you to
write VTC (Varnish Test Case) scripts (or VTC files) for haproxy regression 
testing.
Such VTC files are currently used to test Varnish cache application developed by
Poul-Henning Kamp. A very big thanks you to him for having helped you to add
our haproxy C modules to varnishtest tool.

A lot of general information about how to write VTC files may be found in 
'man/vtc.7'
manual. It is *highly* recommended to read this manual before asking. This
documentation only deals with the varnishtest support for haproxy.


varnishtest installation


To use varnishtest you will have to download and compile the recent Varnish 
cache
sources found at https://github.com/varnishcache/varnish-cache.

To compile Varnish cache :

$ ./autogen.sh
$ ./configure
$ make

The varnishtest sources may be found in 'bin/varnishtest' directory.
'bin/varnishtest/tests' is plenty of VTC files for Varnish cache. After having
compiled these sources, the varnishtest executable location is
'bin/varnishtest/varnishtest'.

varnishtest is able to search for the haproxy executable file it is supposed to
launch in the PATH environment variable. To force the executable to be used by
varnishtest, the HAPROXY_PROGRAM environment variable for varnishtest may be
typically set as follows:

 $ HAPROXY_PROGRAM=~/srcs/haproxy/haproxy varnishtest ...


varnistest exectution
-

varnishtest program comes with interesting options. The most interesting are:

-t  Timeout in seconds to abort the test if some launched program
-v  By default, varnishtest does not dump the outputs of processus it 
launched
when the test passes. With this option the outputs are dumped even
when the test passes.
-L  to always keep the temporary VTC directories.
-l  to keep the temporary VTC directories only when the test fails.

About haproxy when launched by varnishtest, -d option is enabled by default.


How to write VTC files
--

A VTC file must start with a "varnishtest" command line followed by a 
descriptive
line enclosed by double quotes. This is not specific to the VTC files for 
haproxy.

The VTC files for haproxy must also contain a "feature ignore_unknown_macro" 
line
if any macro is used for haproxy in this file. This is due to the fact that
varnishtest parser code for haproxy commands generates macros the varnishtest
parser code for varnish has no knowledge of. This line prevents varnishtest from
failing in such cases.

To make varnishtest capable of testing haproxy, two new VTC commands have been
implemented: "haproxy" and "syslog". "haproxy" is used to start haproxy 
processus.
"syslog" is used to start syslog servers (at this time, only used by haproxy).
 
As haproxy cannot work without configuration file, a VTC file for haproxy must
embed the configuration files contents for the haproxy instances it declares.
This may  be done using the following intuitive syntax construction: -conf 
{...}.
Here -conf is an argument of "haproxy" VTC command to declare the configuration
file of the haproxy instances it also declares (see "Basic HAProxy test" VTC 
file
below).

As for varnish VTC files, the parser of VTC files for haproxy automatically
generates macros for the declared frontends to be reused by the clients later
in the script, so after having written the "haproxy" command sections.
The syntax 

Re: regression testing for haproxy

2018-06-07 Thread Frederic Lecaille

On 06/07/2018 03:14 PM, Frederic Lecaille wrote:

Hi all,

We have recently worked in colloboration with Poul-Henning Kamp to use 
varnishtest regression testing (script driven) tool for Varnish HTTP 
Cache so that to modify it and make it capable of also test haproxy.


Note that here we are speaking about *regression* testing which has 
nothing to see with others classes of tests (unit, integration, 
performance etc). The aim of such tests is: to prevent old bugs from 
coming back!


A nice reference manual for varnishtest may be bound here:

https://varnish-cache.org/docs/6.0/reference/varnishtest.html

In a few words, varnishtest program is able to start HTTP clients and 
servers and put a varnish-cache processus (or several) in the middle to 
test it, making these clients and servers interact with each others. So, 
here we wanted to do the same thing for haproxy.


Of course, it will not always be possible to write a regression test 
script for each bug to come.


Please find attached to this mail a first patch to document how to use 
varnishtest regression testing tool with haproxy and help you to write 
regression test files.


We will have to discuss about how to organize the test files for these 
regressions tests.


A big thank you to Poul-Henning Kamp for having helped us during this 
interesting project.



Regards,

Fred.


Well... this is patch matching with the previous text file.

Fred
>From deb0549ad58e7a4a91a631c6b673f832ace1f428 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Thu, 7 Jun 2018 14:57:30 +0200
Subject: [PATCH] DOC: regression testing: Add a short starting guide.

This documentation describes how to write varnish test case (VTC)
files to reg test haproxy.
---
 doc/regression-testing.txt | 697 +
 1 file changed, 697 insertions(+)
 create mode 100644 doc/regression-testing.txt

diff --git a/doc/regression-testing.txt b/doc/regression-testing.txt
new file mode 100644
index 000..2df67cb
--- /dev/null
+++ b/doc/regression-testing.txt
@@ -0,0 +1,697 @@
+   +-+
+   | HAProxy regression testing with varnishtest |
+   +-+
+
+
+The information found in this file are a short starting guide to help you to
+write VTC (Varnish Test Case) scripts (or VTC files) for haproxy regression testing.
+Such VTC files are currently used to test Varnish cache application developed by
+Poul-Henning Kamp. A very big thanks you to him for having helped you to add
+our haproxy C modules to varnishtest tool.
+
+A lot of general information about how to write VTC files may be found in 'man/vtc.7'
+manual. It is *highly* recommended to read this manual before asking. This
+documentation only deals with the varnishtest support for haproxy.
+
+
+varnishtest installation
+
+
+To use varnishtest you will have to download and compile the recent Varnish cache
+sources found at https://github.com/varnishcache/varnish-cache.
+
+To compile Varnish cache :
+
+$ ./autogen.sh
+$ ./configure
+$ make
+
+The varnishtest sources may be found in 'bin/varnishtest' directory.
+'bin/varnishtest/tests' is plenty of VTC files for Varnish cache. After having
+compiled these sources, the varnishtest executable location is
+'bin/varnishtest/varnishtest'.
+
+varnishtest is able to search for the haproxy executable file it is supposed to
+launch in the PATH environment variable. To force the executable to be used by
+varnishtest, the HAPROXY_PROGRAM environment variable for varnishtest may be
+typically set as follows:
+
+ $ HAPROXY_PROGRAM=~/srcs/haproxy/haproxy varnishtest ...
+
+
+varnistest exectution
+-
+
+varnishtest program comes with interesting options. The most interesting are:
+
+-t  Timeout in seconds to abort the test if some launched program
+-v  By default, varnishtest does not dump the outputs of processus it launched
+when the test passes. With this option the outputs are dumped even
+when the test passes.
+-L  to always keep the temporary VTC directories.
+-l  to keep the temporary VTC directories only when the test fails.
+
+About haproxy when launched by varnishtest, -d option is enabled by default.
+
+
+How to write VTC files
+--
+
+A VTC file must start with a "varnishtest" command line followed by a descriptive
+line enclosed by double quotes. This is not specific to the VTC files for haproxy.
+
+The VTC files for haproxy must also contain a "feature ignore_unknown_macro" line
+if any macro is used for haproxy in this file. This is due to the fact that
+varnishtest parser code for haproxy commands generates macros the varnishtest
+parser code for varnish has no knowledge of. This line prevents varnishtest from
+failing in such cases.
+
+To make varnishtest capable of testi

[PATCH] MINOR: tests: First regression testing file.

2018-06-18 Thread Frederic Lecaille

Hello,

Here is a simple patch to add a Makefile target to run all "*.vtc" 
regression testing files found in 'reg-tests' directory.


It comes with a first VTC file in relation with f874a83 bug fix commit 
for LUA. This VTC file parent directory is 'reg-tests/lua'.


I have copied and pasted the commit log at the beginning of the vtc 
file. I think this would be a good practice so that to link the vtc 
files to the bug it is supposed to test for any regression.


Regards,

Fred.
>From e05d7a9815c2b05e596740fb780e42c77931b6f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 18 Jun 2018 19:32:10 +0200
Subject: [PATCH] MINOR: tests: First regression testing file.

Add a makefile target 'reg-tests' to run all regression testing file
found in 'reg-tests' directory.
Add reg-tests/lua/h0.vtc first regression testing file for a LUA
fixed by f874a83 commit.
---
 .gitignore   |  1 +
 Makefile |  5 
 reg-tests/lua/h0.lua |  3 ++
 reg-tests/lua/h0.vtc | 74 
 4 files changed, 83 insertions(+)
 create mode 100644 reg-tests/lua/h0.lua
 create mode 100644 reg-tests/lua/h0.vtc

diff --git a/.gitignore b/.gitignore
index 73eaeae..32a8a84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,7 @@
 !/tests
 !/debian
 !/scripts
+!/reg-tests
 # Reject some generic files
 *.o
 *~
diff --git a/Makefile b/Makefile
index 5d17004..06f8ac9 100644
--- a/Makefile
+++ b/Makefile
@@ -996,3 +996,8 @@ update-version:
 	echo "$(VERSION)" > VERSION
 	echo "$(SUBVERS)" > SUBVERS
 	echo "$(VERDATE)" > VERDATE
+
+reg-tests:
+	@find reg-tests -type f -name "*.vtc" -print0 | \
+	   xargs -0 $(VARNISHTEST_PROGRAM) -l -t5
+.PHONY: reg-tests
diff --git a/reg-tests/lua/h0.lua b/reg-tests/lua/h0.lua
new file mode 100644
index 000..d2401fa
--- /dev/null
+++ b/reg-tests/lua/h0.lua
@@ -0,0 +1,3 @@
+core.register_action("foo", { "http-req" }, function(txn)
+	txn.sc:ipmask(txn.f:src(), 24, 112)
+end)
diff --git a/reg-tests/lua/h0.vtc b/reg-tests/lua/h0.vtc
new file mode 100644
index 000..2b2ffb0
--- /dev/null
+++ b/reg-tests/lua/h0.vtc
@@ -0,0 +1,74 @@
+# commit f874a83
+# BUG/MINOR: lua: Segfaults with wrong usage of types.
+#
+# Patrick reported that this simple configuration made haproxy segfaults:
+#
+# global
+# lua-load /tmp/haproxy.lua
+#
+# frontend f1
+# mode http
+# bind :8000
+# default_backend b1
+#
+# http-request lua.foo
+#
+# backend b1
+# mode http
+# server s1 127.0.0.1:8080
+#
+# with this '/tmp/haproxy.lua' script:
+#
+# core.register_action("foo", { "http-req" }, function(txn)
+# txn.sc:ipmask(txn.f:src(), 24, 112)
+# end)
+#
+# This is due to missing initialization of the array of arguments
+# passed to hlua_lua2arg_check() which makes it enter code with
+# corrupted arguments.
+#
+# Thanks a lot to Patrick Hemmer for having reported this issue.
+
+
+varnishtest "Basic LUA test h0"
+feature ignore_unknown_macro
+
+server s1 -repeat 2 {
+rxreq
+txresp
+} -start
+
+haproxy h1 -conf {
+global
+lua-load ${testdir}/h0.lua
+
+frontend fe1
+mode http
+bind "fd@${fe1}"
+default_backend b1
+
+http-request lua.foo
+
+backend b1
+mode http
+server s1 ${s1_addr}:${s1_port}
+
+} -start
+
+client c0 -connect ${h1_fe1_sock} {
+txreq -url "/foo"
+rxresp
+expect resp.status == 200
+}
+
+client c1 -connect ${h1_fe1_sock} {
+txreq -url "/foo"
+rxresp
+expect resp.status == 200
+}
+
+client c0 -start
+client c1 -start
+
+client c0 -wait
+client c1 -wait
-- 
2.1.4



Re: BUG: segfault with lua sample converters & wrong arg types

2018-06-15 Thread Frederic Lecaille

Hello Patrick,

On 06/14/2018 11:05 PM, Patrick Hemmer wrote:

Haproxy segfaults if you pass the wrong argument type to a converter.
Example:

haproxy.cfg:
     global
         lua-load /tmp/haproxy.lua

     frontend f1
         mode http
         bind :8000
         default_backend b1

         http-request lua.foo

     backend b1
         mode http
         server s1 127.0.0.1:8080

haproxy.lua:
     core.register_action("foo", { "http-req" }, function(txn)
         txn.sc:ipmask(txn.f:src(), 24, 112)
     end)

Result:
     * thread #1, queue = 'com.apple.main-thread', stop reason = 
EXC_BAD_ACCESS (code=1, address=0x18)
     frame #0: 0x7fffc9fcbf56 
libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 182

libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell:
     ->  0x7fffc9fcbf56 <+182>: movb   (%rsi,%r8), %cl
     0x7fffc9fcbf5a <+186>: movb   %cl, (%rdi,%r8)
     0x7fffc9fcbf5e <+190>: subq   $0x1, %rdx
     0x7fffc9fcbf62 <+194>: je 0x7fffc9fcbf78    ; <+216>
     Target 0: (haproxy) stopped.
     (lldb) bt
     * thread #1, queue = 'com.apple.main-thread', stop reason = 
EXC_BAD_ACCESS (code=1, address=0x18)
   * frame #0: 0x7fffc9fcbf56 
libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 182

     frame #1: 0x7fffc9e7442e libsystem_c.dylib`__memcpy_chk + 22
     frame #2: 0x00010002ec46 
haproxy`hlua_lua2arg_check(L=0x00010120d298, first=3, 
argp=0x7fff5fbfe690, mask=196, p=0x000101817000) at hlua.c:749
     frame #3: 0x00010001fa00 
haproxy`hlua_run_sample_conv(L=0x00010120d298) at hlua.c:3393

     frame #4: 0x00010032400b haproxy`luaD_precall + 747
     frame #5: 0x0001003343c6 haproxy`luaV_execute + 3158
     frame #6: 0x000100323429 haproxy`luaD_rawrunprotected + 89
     frame #7: 0x000100324516 haproxy`lua_resume + 278
     frame #8: 0x00010001b199 
haproxy`hlua_ctx_resume(lua=0x000101205080, yield_allowed=1) at 
hlua.c:1080
     frame #9: 0x000100027de8 
haproxy`hlua_action(rule=0x00010101b180, px=0x000101817000, 
sess=0x00010120cb70, s=0x00010120cc00, flags=2) at hlua.c:6198
     frame #10: 0x000100044bcd 
haproxy`http_req_get_intercept_rule(px=0x000101817000, 
rules=0x000101817048, s=0x00010120cc00, 
deny_status=0x7fff5fbfee78) at proto_http.c:2760
     frame #11: 0x000100046182 
haproxy`http_process_req_common(s=0x00010120cc00, 
req=0x00010120cc10, an_bit=16, px=0x000101817000) at 
proto_http.c:3461
     frame #12: 0x000100094c50 
haproxy`process_stream(t=0x00010120cf40, context=0x00010120cc00, 
state=9) at stream.c:1905
     frame #13: 0x00010016179f haproxy`process_runnable_tasks at 
task.c:362
     frame #14: 0x0001000ea0eb haproxy`run_poll_loop at 
haproxy.c:2403
     frame #15: 0x0001000e7c74 
haproxy`run_thread_poll_loop(data=0x7fff5fbff3a4) at haproxy.c:2464
     frame #16: 0x0001000e4a49 haproxy`main(argc=3, 
argv=0x7fff5fbff590) at haproxy.c:3082

     frame #17: 0x7fffc9db9235 libdyld.dylib`start + 1

Issue goes away if you change the lua txn.sc:ipmask() line to:
     txn.sc:ipmask(txn.f:src(), '24', '112')

Reproduced with current master (9db0fed) and lua version 5.3.4.

-Patrick


I have reproduced the same issue with varnishtest.

Here is a linux backtrace:


Program terminated with signal SIGSEGV, Segmentation fault.
#0  __memcpy_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:33
33  ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: No such 
file or directory.

(gdb) bt
#0  __memcpy_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:33
#1  0x0041b428 in hlua_lua2arg_check (L=L@entry=0xf1b528,
first=first@entry=3, argp=argp@entry=0x7fffa27a2790, mask=196, 
p=0xee3600)

at src/hlua.c:749
#2  0x0041c6ae in hlua_run_sample_conv (L=0xf1b528) at 
src/hlua.c:3393

#3  0x00508664 in luaD_precall ()
#4  0x0051350d in luaV_execute ()
#5  0x00507ebc in luaD_rawrunprotected ()
#6  0x00508af0 in lua_resume ()
#7  0x00423dec in hlua_ctx_resume (lua=0xf1b490,
yield_allowed=yield_allowed@entry=1) at src/hlua.c:1080
#8  0x00428bb7 in hlua_action (rule=0xee51c0, px=0xee3600,
sess=, s=0xf15690, flags=2) at src/hlua.c:6198
#9  0x00438a9c in http_req_get_intercept_rule (px=0xeb8d20,
px@entry=0xee3600, rules=0xee3648, s=0xf15690, deny_status=0x726a606e,
deny_status@entry=0x7fffa27a2d6c) at src/proto_http.c:2760
#10 0x0043e216 in http_process_req_common (s=s@entry=0xf15690,
req=req@entry=0xf156a0, an_bit=an_bit@entry=16, px=0xee3600)
at src/proto_http.c:3461
#11 0x0046fcb0 in process_stream (t=, 
context=0xf15690,

state=) at src/stream.c:1905
#12 0x004efeca in process_runnable_tasks () at src/task.c:362
#13 0x004a25f4 

[PATCH] BUG/MINOR: lua: Segfaults with wrong usage of types.

2018-06-15 Thread Frederic Lecaille

On 06/15/2018 02:28 PM, Frederic Lecaille wrote:

On 06/15/2018 02:15 PM, Frederic Lecaille wrote:

On 06/14/2018 11:05 PM, Patrick Hemmer wrote:

Haproxy segfaults if you pass the wrong argument type to a converter.
Example:

haproxy.cfg:
 global
     lua-load /tmp/haproxy.lua

 frontend f1
     mode http
     bind :8000
     default_backend b1

     http-request lua.foo

 backend b1
     mode http
     server s1 127.0.0.1:8080

haproxy.lua:
 core.register_action("foo", { "http-req" }, function(txn)
     txn.sc:ipmask(txn.f:src(), 24, 112)
 end)

Result:
 * thread #1, queue = 'com.apple.main-thread', stop reason = 
EXC_BAD_ACCESS (code=1, address=0x18)
 frame #0: 0x7fffc9fcbf56 
libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 182

libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell:
 ->  0x7fffc9fcbf56 <+182>: movb   (%rsi,%r8), %cl
 0x7fffc9fcbf5a <+186>: movb   %cl, (%rdi,%r8)
 0x7fffc9fcbf5e <+190>: subq   $0x1, %rdx
 0x7fffc9fcbf62 <+194>: je 0x7fffc9fcbf78    ; <+216>
 Target 0: (haproxy) stopped.
 (lldb) bt
 * thread #1, queue = 'com.apple.main-thread', stop reason = 
EXC_BAD_ACCESS (code=1, address=0x18)
   * frame #0: 0x7fffc9fcbf56 
libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 182
 frame #1: 0x7fffc9e7442e libsystem_c.dylib`__memcpy_chk 
+ 22
 frame #2: 0x00010002ec46 
haproxy`hlua_lua2arg_check(L=0x00010120d298, first=3, 
argp=0x7fff5fbfe690, mask=196, p=0x000101817000) at hlua.c:749
 frame #3: 0x00010001fa00 
haproxy`hlua_run_sample_conv(L=0x00010120d298) at hlua.c:3393

 frame #4: 0x00010032400b haproxy`luaD_precall + 747
 frame #5: 0x0001003343c6 haproxy`luaV_execute + 3158
 frame #6: 0x000100323429 haproxy`luaD_rawrunprotected + 89
 frame #7: 0x000100324516 haproxy`lua_resume + 278
 frame #8: 0x00010001b199 
haproxy`hlua_ctx_resume(lua=0x000101205080, yield_allowed=1) at 
hlua.c:1080
 frame #9: 0x000100027de8 
haproxy`hlua_action(rule=0x00010101b180, px=0x000101817000, 
sess=0x00010120cb70, s=0x00010120cc00, flags=2) at hlua.c:6198
 frame #10: 0x000100044bcd 
haproxy`http_req_get_intercept_rule(px=0x000101817000, 
rules=0x000101817048, s=0x00010120cc00, 
deny_status=0x7fff5fbfee78) at proto_http.c:2760
 frame #11: 0x000100046182 
haproxy`http_process_req_common(s=0x00010120cc00, 
req=0x00010120cc10, an_bit=16, px=0x000101817000) at 
proto_http.c:3461
 frame #12: 0x000100094c50 
haproxy`process_stream(t=0x00010120cf40, 
context=0x00010120cc00, state=9) at stream.c:1905
 frame #13: 0x00010016179f haproxy`process_runnable_tasks 
at task.c:362
 frame #14: 0x0001000ea0eb haproxy`run_poll_loop at 
haproxy.c:2403
 frame #15: 0x0001000e7c74 
haproxy`run_thread_poll_loop(data=0x7fff5fbff3a4) at haproxy.c:2464
 frame #16: 0x0001000e4a49 haproxy`main(argc=3, 
argv=0x7fff5fbff590) at haproxy.c:3082

 frame #17: 0x7fffc9db9235 libdyld.dylib`start + 1

Issue goes away if you change the lua txn.sc:ipmask() line to:
 txn.sc:ipmask(txn.f:src(), '24', '112')

Reproduced with current master (9db0fed) and lua version 5.3.4.

-Patrick


It seems the patch attached to this mail fixes this issue. It at least 
make the varnishtest test file pass.


Must be checked by Thierry.


Should have mentionned that I could not reproduce this issue without 
compiling the thread support (USE_THREAD=1).


There is potentially the same issue in hlua_run_sample_conv(). See the 
updated patch attached to this mail.





>From e3efb02b48098aad6d4694d06bb4c3193f29e312 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Fri, 15 Jun 2018 13:56:04 +0200
Subject: [PATCH] BUG/MINOR: lua: Segfaults with wrong usage of types.

Patrick reported that this simple configuration made haproxy segfaults:

global
lua-load /tmp/haproxy.lua

frontend f1
mode http
bind :8000
default_backend b1

http-request lua.foo

backend b1
mode http
server s1 127.0.0.1:8080

with this '/tmp/haproxy.lua' script:

core.register_action("foo", { "http-req" }, function(txn)
txn.sc:ipmask(txn.f:src(), 24, 112)
end)

This is due to missing initialization of the array of arguments
passed to hlua_lua2arg_check() which makes it enter code with
corrupted arguments.

Thanks a lot to Patrick Hemmer for having reported this issue.

Must be backported to 1.8, 1.7 and 1.6.
---
 src/hlua.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/hlua.c b/src/hlua.c
index 716bd29..93ec44c 100644
--- a/src/hlua.c
+++ b/src/hlua.

Re: BUG: segfault with lua sample converters & wrong arg types

2018-06-15 Thread Frederic Lecaille

On 06/14/2018 11:05 PM, Patrick Hemmer wrote:

Haproxy segfaults if you pass the wrong argument type to a converter.
Example:

haproxy.cfg:
     global
         lua-load /tmp/haproxy.lua

     frontend f1
         mode http
         bind :8000
         default_backend b1

         http-request lua.foo

     backend b1
         mode http
         server s1 127.0.0.1:8080

haproxy.lua:
     core.register_action("foo", { "http-req" }, function(txn)
         txn.sc:ipmask(txn.f:src(), 24, 112)
     end)

Result:
     * thread #1, queue = 'com.apple.main-thread', stop reason = 
EXC_BAD_ACCESS (code=1, address=0x18)
     frame #0: 0x7fffc9fcbf56 
libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 182

libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell:
     ->  0x7fffc9fcbf56 <+182>: movb   (%rsi,%r8), %cl
     0x7fffc9fcbf5a <+186>: movb   %cl, (%rdi,%r8)
     0x7fffc9fcbf5e <+190>: subq   $0x1, %rdx
     0x7fffc9fcbf62 <+194>: je 0x7fffc9fcbf78    ; <+216>
     Target 0: (haproxy) stopped.
     (lldb) bt
     * thread #1, queue = 'com.apple.main-thread', stop reason = 
EXC_BAD_ACCESS (code=1, address=0x18)
   * frame #0: 0x7fffc9fcbf56 
libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 182

     frame #1: 0x7fffc9e7442e libsystem_c.dylib`__memcpy_chk + 22
     frame #2: 0x00010002ec46 
haproxy`hlua_lua2arg_check(L=0x00010120d298, first=3, 
argp=0x7fff5fbfe690, mask=196, p=0x000101817000) at hlua.c:749
     frame #3: 0x00010001fa00 
haproxy`hlua_run_sample_conv(L=0x00010120d298) at hlua.c:3393

     frame #4: 0x00010032400b haproxy`luaD_precall + 747
     frame #5: 0x0001003343c6 haproxy`luaV_execute + 3158
     frame #6: 0x000100323429 haproxy`luaD_rawrunprotected + 89
     frame #7: 0x000100324516 haproxy`lua_resume + 278
     frame #8: 0x00010001b199 
haproxy`hlua_ctx_resume(lua=0x000101205080, yield_allowed=1) at 
hlua.c:1080
     frame #9: 0x000100027de8 
haproxy`hlua_action(rule=0x00010101b180, px=0x000101817000, 
sess=0x00010120cb70, s=0x00010120cc00, flags=2) at hlua.c:6198
     frame #10: 0x000100044bcd 
haproxy`http_req_get_intercept_rule(px=0x000101817000, 
rules=0x000101817048, s=0x00010120cc00, 
deny_status=0x7fff5fbfee78) at proto_http.c:2760
     frame #11: 0x000100046182 
haproxy`http_process_req_common(s=0x00010120cc00, 
req=0x00010120cc10, an_bit=16, px=0x000101817000) at 
proto_http.c:3461
     frame #12: 0x000100094c50 
haproxy`process_stream(t=0x00010120cf40, context=0x00010120cc00, 
state=9) at stream.c:1905
     frame #13: 0x00010016179f haproxy`process_runnable_tasks at 
task.c:362
     frame #14: 0x0001000ea0eb haproxy`run_poll_loop at 
haproxy.c:2403
     frame #15: 0x0001000e7c74 
haproxy`run_thread_poll_loop(data=0x7fff5fbff3a4) at haproxy.c:2464
     frame #16: 0x0001000e4a49 haproxy`main(argc=3, 
argv=0x7fff5fbff590) at haproxy.c:3082

     frame #17: 0x7fffc9db9235 libdyld.dylib`start + 1

Issue goes away if you change the lua txn.sc:ipmask() line to:
     txn.sc:ipmask(txn.f:src(), '24', '112')

Reproduced with current master (9db0fed) and lua version 5.3.4.

-Patrick


It seems the patch attached to this mail fixes this issue. It at least 
make the varnishtest test file pass.


Must be checked by Thierry.


Fred.
>From 245592382b46458082be1cd440603dd4b92c500b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Fri, 15 Jun 2018 13:56:04 +0200
Subject: [PATCH] BUG/MINOR: lua: Segfaults with wrong usage of types.

Patrick reported that this simple configuration made haproxy segfaults:

global
lua-load /tmp/haproxy.lua

frontend f1
mode http
bind :8000
default_backend b1

http-request lua.foo

backend b1
mode http
server s1 127.0.0.1:8080

with this '/tmp/haproxy.lua' script:

core.register_action("foo", { "http-req" }, function(txn)
txn.sc:ipmask(txn.f:src(), 24, 112)
end)

This is due to missing initialization of the array of arguments
passed to hlua_lua2arg_check() which makes it enter code with
corrupted arguments.

Thanks a lot to Patrick Hemmer for having reported this issue.

Must be backported to 1.8, 1.7 and 1.6.
---
 src/hlua.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/hlua.c b/src/hlua.c
index 716bd29..84debaf 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -3256,7 +3256,7 @@ __LJMP static int hlua_run_sample_fetch(lua_State *L)
 {
 	struct hlua_smp *hsmp;
 	struct sample_fetch *f;
-	struct arg args[ARGM_NBARGS + 1];
+	struct arg args[ARGM_NBARGS + 1] = {{0}};
 	int i;
 	struct sample smp;
 
-- 
2.1.4



Re: BUG: segfault with lua sample converters & wrong arg types

2018-06-15 Thread Frederic Lecaille

On 06/15/2018 02:15 PM, Frederic Lecaille wrote:

On 06/14/2018 11:05 PM, Patrick Hemmer wrote:

Haproxy segfaults if you pass the wrong argument type to a converter.
Example:

haproxy.cfg:
 global
     lua-load /tmp/haproxy.lua

 frontend f1
     mode http
     bind :8000
     default_backend b1

     http-request lua.foo

 backend b1
     mode http
     server s1 127.0.0.1:8080

haproxy.lua:
 core.register_action("foo", { "http-req" }, function(txn)
     txn.sc:ipmask(txn.f:src(), 24, 112)
 end)

Result:
 * thread #1, queue = 'com.apple.main-thread', stop reason = 
EXC_BAD_ACCESS (code=1, address=0x18)
 frame #0: 0x7fffc9fcbf56 
libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 182

libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell:
 ->  0x7fffc9fcbf56 <+182>: movb   (%rsi,%r8), %cl
 0x7fffc9fcbf5a <+186>: movb   %cl, (%rdi,%r8)
 0x7fffc9fcbf5e <+190>: subq   $0x1, %rdx
 0x7fffc9fcbf62 <+194>: je 0x7fffc9fcbf78    ; <+216>
 Target 0: (haproxy) stopped.
 (lldb) bt
 * thread #1, queue = 'com.apple.main-thread', stop reason = 
EXC_BAD_ACCESS (code=1, address=0x18)
   * frame #0: 0x7fffc9fcbf56 
libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 182

 frame #1: 0x7fffc9e7442e libsystem_c.dylib`__memcpy_chk + 22
 frame #2: 0x00010002ec46 
haproxy`hlua_lua2arg_check(L=0x00010120d298, first=3, 
argp=0x7fff5fbfe690, mask=196, p=0x000101817000) at hlua.c:749
 frame #3: 0x00010001fa00 
haproxy`hlua_run_sample_conv(L=0x00010120d298) at hlua.c:3393

 frame #4: 0x00010032400b haproxy`luaD_precall + 747
 frame #5: 0x0001003343c6 haproxy`luaV_execute + 3158
 frame #6: 0x000100323429 haproxy`luaD_rawrunprotected + 89
 frame #7: 0x000100324516 haproxy`lua_resume + 278
 frame #8: 0x00010001b199 
haproxy`hlua_ctx_resume(lua=0x000101205080, yield_allowed=1) at 
hlua.c:1080
 frame #9: 0x000100027de8 
haproxy`hlua_action(rule=0x00010101b180, px=0x000101817000, 
sess=0x00010120cb70, s=0x00010120cc00, flags=2) at hlua.c:6198
 frame #10: 0x000100044bcd 
haproxy`http_req_get_intercept_rule(px=0x000101817000, 
rules=0x000101817048, s=0x00010120cc00, 
deny_status=0x7fff5fbfee78) at proto_http.c:2760
 frame #11: 0x000100046182 
haproxy`http_process_req_common(s=0x00010120cc00, 
req=0x00010120cc10, an_bit=16, px=0x000101817000) at 
proto_http.c:3461
 frame #12: 0x000100094c50 
haproxy`process_stream(t=0x00010120cf40, 
context=0x00010120cc00, state=9) at stream.c:1905
 frame #13: 0x00010016179f haproxy`process_runnable_tasks 
at task.c:362
 frame #14: 0x0001000ea0eb haproxy`run_poll_loop at 
haproxy.c:2403
 frame #15: 0x0001000e7c74 
haproxy`run_thread_poll_loop(data=0x7fff5fbff3a4) at haproxy.c:2464
 frame #16: 0x0001000e4a49 haproxy`main(argc=3, 
argv=0x7fff5fbff590) at haproxy.c:3082

 frame #17: 0x7fffc9db9235 libdyld.dylib`start + 1

Issue goes away if you change the lua txn.sc:ipmask() line to:
 txn.sc:ipmask(txn.f:src(), '24', '112')

Reproduced with current master (9db0fed) and lua version 5.3.4.

-Patrick


It seems the patch attached to this mail fixes this issue. It at least 
make the varnishtest test file pass.


Must be checked by Thierry.


Should have mentionned that I could not reproduce this issue without 
compiling the thread support (USE_THREAD=1).







Re: haproxy 1.9 status update

2018-05-28 Thread Frederic Lecaille

On 05/25/2018 06:10 PM, Willy Tarreau wrote:

Hi all,


[sniped]


   - peers over SSL [Fred] : the purpose is to allow all bind options with
 peers so that peers can exchange information securely. I think I've
 seen it posted somewhere, I'll have to dig through the archives.


Here are the rebased patches for this feature.

Fred.

>From e41942d0c85dd4270a685e5db5bf8523e87ef287 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 28 May 2018 08:47:52 +0200
Subject: [PATCH 10/10] DOC: peers: Update "peers" section SSL/TLS support
 documentation.

---
 doc/configuration.txt | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index e27d666..544b697 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1833,6 +1833,12 @@ peers 
   Creates a new peer list with name . It is an independent section,
   which is referenced by one or more stick-tables.
 
+bind [param*]
+  Defines the binding parameters of the local peer of this "peers" section.
+  To avoid some redundancy, and as the  and  parameters
+  are already provided on "peer" (or "server") lines, they are not supported
+  by "bind" keyword in "peers" sections.
+
 disabled
   Disables a peers section. It disables both listening and any synchronization
   related to this section. This is provided to disable synchronization of stick
@@ -1841,7 +1847,7 @@ disabled
 enable
   This re-enables a disabled peers section which was previously disabled.
 
-peer  :
+peer  : [param*]
   Defines a peer inside a peers section.
   If  is set to the local peer name (by default hostname, or forced
   using "-L" command line option), haproxy will listen for incoming remote peer
@@ -1860,6 +1866,15 @@ peer  :
   You may want to reference some environment variables in the address
   parameter, see section 2.3 about environment variables.
 
+  Note: "peer" keyword may transparently be replaced by "server" keyword (see
+  "server" keyword explanation below).
+
+server  : [param*]
+  As previously mentionned, "peer" keyword may be replaced by "server" keyword
+  with a support for all "server" parameters found in 5.2 paragraph.
+  Some of these parameters are irrelevant for "peers" sections.
+
+
   Example:
 peers mypeers
 peer haproxy1 192.168.0.1:1024
-- 
2.1.4

>From a546f38d9e6fe980c477b91df0681ac6fa0289a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Fri, 27 Apr 2018 13:56:13 +0200
Subject: [PATCH 09/10] MINOR: peers: Make incoming connections to SSL/TLS
 local peer work.

This patch makes "bind" work in "peers" sections. All "bind" settings
are supported, excepted ip:port parameters which are provided on
"peer" (or server) line matching the local peer.
After having parsed the configuration files ->prepare_bind_conf is run
to initialize all SSL/TLS stuff for the local peer.
---
 src/cfgparse.c | 95 ++
 1 file changed, 90 insertions(+), 5 deletions(-)

diff --git a/src/cfgparse.c b/src/cfgparse.c
index 96ccc9f..90735e6 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1992,6 +1992,31 @@ static int init_peers_frontend(const char *file, int linenum,
 	return 0;
 }
 
+/* Only change ->file, ->line and ->arg struct bind_conf member values
+ * if already present.
+ */
+static struct bind_conf *bind_conf_uniq_alloc(struct proxy *p,
+  const char *file, int line,
+  const char *arg, struct xprt_ops *xprt)
+{
+	struct bind_conf *bind_conf;
+
+	if (!LIST_ISEMPTY(>conf.bind)) {
+		bind_conf = LIST_ELEM((>conf.bind)->n, typeof(bind_conf), by_fe);
+		free(bind_conf->file);
+		bind_conf->file = strdup(file);
+		bind_conf->line = line;
+		if (arg) {
+			free(bind_conf->arg);
+			bind_conf->arg = strdup(arg);
+		}
+	}
+	else {
+		bind_conf = bind_conf_alloc(p, file, line, arg, xprt);
+	}
+
+	return bind_conf;
+}
 /*
  * Parse a line in a ,  or  section.
  * Returns the error code, 0 if OK, or any combination of :
@@ -2012,7 +2037,56 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
 	int err_code = 0;
 	char *errmsg = NULL;
 
-	if (strcmp(args[0], "default-server") == 0) {
+	if (strcmp(args[0], "bind") == 0) {
+		int cur_arg;
+		static int kws_dumped;
+		struct bind_conf *bind_conf;
+		struct bind_kw *kw;
+		char *kws;
+
+		cur_arg = 1;
+
+		if (init_peers_frontend(file, linenum, NULL, curpeers) != 0) {
+			err_code |= ERR_ALERT | ERR_ABORT;
+			goto out;
+		}
+
+		bind_conf = bind_conf_uniq_alloc(curpeers->peers_fe, file, linenum,
+		 NULL, xprt_get(XPRT_RAW));
+		while (*args[cur_arg] && (kw = bind_find_kw(args[cur_arg]))) {
+			int ret;
+
+			ret = kw->parse(args, cur_arg, curpeers->peers_fe, bind_conf, );
+			err_code |= ret;
+			if (ret) {
+if (errmsg 

Re: [PATCH] REGTEST: stick-tables: Test expiration when used with table_*

2018-06-25 Thread Frederic Lecaille

On 06/21/2018 04:53 AM, Willy Tarreau wrote:

Hi Daniel,

On Wed, Jun 20, 2018 at 10:28:43AM -0400, Daniel Corbett wrote:

+shell -expect "used:0" {
+echo "show table http1" |socat ${tmpdir}/h1/stats.sock -

 ^

This is the point where it will start to require that we organize the
reg tests better. First, socat is rarely installed by default so we'll
have to mention that it's required. Second, socat introduces half a
second delay before quitting, making it impractical for the quick
automated tests that we expect developers to run frequently.

The dependency on socat makes me think we could probably put all of such
tests in a specific sub-directory. However, I predict that we will also
create a number of other ones which will be slower than average and which
will be unrelated to the CLI.

Maybe we could simply introduce levels :
   - level 1 (the default) would contain only the immediate tests that cover
 the internal state machine and HTTP compliance (the things we break the
 most often by side effets when fixing a bug in the same area). Basically
 we should expect to be able to run 100 tests in a second there and there
 should be zero excuse for not running them before committing a patch
 affecting a sensitive area.

   - level 2 would cover some extra parts requiring a bit more time (eg:
 CLI commands, horrible stuff involving tcploop) and would probably
 be needed only when trying to ensure that a fix doesn't break
 something unexpected.

   - level 3 would be the painful one that we already know nobody will dare
 to run. They would cover timeouts, health checks, etc. All the stuff
 that takes multiple seconds per test would be there. They may occasionally
 be run by a dev during lunch time, or at night by automated bots.




Then we could issue "make reg-tests" to run level 1 by default or
"make reg-tests LEVEL=" for the other ones. The idea is that I would
*really* like to encourage developers to run some basic tests before sending
patches, and we all know that none of us will accept to run them if they take
more time than what is needed to divert us (ie if you have time to switch to
reading your mails while the test runs, we won't run them because this will
create distraction).



I have attached #0003 patch for that in addition to these ones:

#0001 : as would say Olivier "Ooops, I'am an idiot etc". 
reg-tests/ssl/h0.vtc did not run any https request.


#0002 : set the default value of HAPROXY_PROGRAM environment variable.

We will have to change the class of the already existing reg test files.
>From bbbef595937170b87d0707780968d031c95ca9e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 25 Jun 2018 11:15:43 +0200
Subject: [PATCH 3/3] REGTEST/MINOR: Add levels to reg-tests target.

With this patch we can provide LEVEL environment variable when
running reg-tests Makefile targe (reg testing) to set the execution
level of the reg-tests make target to run.

LEVEL default value is 1.

LEVEL=1 is to run all h*.vtc files which are the most important
reg testing files (to test haproxy core, HTTP compliance etc).

LEVEL=2 is to run all s*.vtc files which are a bit slow tests,
for instance tests requiring external programs (curl, socat etc).

LEVEL=3 is to run all l*.vtc files which are test files with again
more slow or with little interest.
---
 Makefile | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 9ea3e80..817161f 100644
--- a/Makefile
+++ b/Makefile
@@ -1004,6 +1004,16 @@ reg-tests:
 		echo "Please make the VARNISHTEST_PROGRAM variable point to the location of the varnishtest program."; \
 		exit 1; \
 	fi
-	@find reg-tests -type f -name "*.vtc" -print0 | \
-	   HAPROXY_PROGRAM=$${HAPROXY_PROGRAM:-$$PWD/haproxy} xargs -0 $(VARNISHTEST_PROGRAM) -l -t5
+	@export LEVEL=$${LEVEL:-1}; \
+	if [ $$LEVEL = 1 ] ; then \
+	   EXPR='h*.vtc'; \
+	elif [ $$LEVEL = 2 ] ; then \
+	   EXPR='s*.vtc'; \
+	elif [ $$LEVEL = 3 ] ; then \
+	   EXPR='l*.vtc'; \
+	fi ; \
+	if [ -n "$$EXPR" ] ; then \
+	   find reg-tests -type f -name "$$EXPR" -print0 | \
+	  HAPROXY_PROGRAM=$${HAPROXY_PROGRAM:-$$PWD/haproxy} xargs -r -0 $(VARNISHTEST_PROGRAM) -l -t5 ; \
+	fi
 .PHONY: reg-tests
-- 
2.1.4

>From 820602fa642c3143c3884056775a7077bf99c2eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Mon, 25 Jun 2018 10:24:37 +0200
Subject: [PATCH 2/3] REGTEST/MINOR: Set HAPROXY_PROGRAM default value.

With this patch, we set HAPROXY_PROGRAM environment variable
default value to the haproxy executable of the current working directory.
So, if the current directory is the haproxy sources directory,
the reg-tests Makefile target may be run with this shorter command:

  $ VARNISTEST_PROGRAM=<...> make reg-tests

in place of

  $ VARNISTEST_PROGRAM=<...> HAPROXY_PROGRAM=<...> make reg-tests
---
 Makefile | 2 +-
 1 file 

[PATCH] MINOR: reg-tests: Add a few regression testing files.

2018-06-20 Thread Frederic Lecaille

On 06/19/2018 10:18 AM, Willy Tarreau wrote:

On Mon, Jun 18, 2018 at 07:50:38PM +0200, Frederic Lecaille wrote:

Hello,

Here is a simple patch to add a Makefile target to run all "*.vtc"
regression testing files found in 'reg-tests' directory.

(...)

Thank you very much for this, Fred! I hope this will ignite a long
series of such tests. It may be useful to add a README in the reg-tests
directory indicating how to install varnishtest (especially the version
compatible with haproxy), and probably suggest contributing new tests
in the CONTRIBUTING file to encourage the practice.

Willy



Here is a few more reg testing files with a special one for Olivier (see 
reg-tests/seamless-reload/h0.vtc).


Fred.
>From a95e9c2caf10e2d6393b6ba38269e0afdfc71d64 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Wed, 20 Jun 2018 07:26:44 +0200
Subject: [PATCH] MINOR: reg-tests: Add a few regression testing files.

---
 reg-tests/log/h0.vtc | 62 ++
 reg-tests/seamless-reload/h0.vtc | 43 
 reg-tests/spoe/h0.vtc| 18 ++
 reg-tests/ssl/README |  2 ++
 reg-tests/ssl/common.pem | 65 
 reg-tests/ssl/h0.vtc | 48 ++
 6 files changed, 238 insertions(+)
 create mode 100644 reg-tests/log/h0.vtc
 create mode 100644 reg-tests/seamless-reload/h0.vtc
 create mode 100644 reg-tests/spoe/h0.vtc
 create mode 100644 reg-tests/ssl/README
 create mode 100644 reg-tests/ssl/common.pem
 create mode 100644 reg-tests/ssl/h0.vtc

diff --git a/reg-tests/log/h0.vtc b/reg-tests/log/h0.vtc
new file mode 100644
index 000..f0ab7ea
--- /dev/null
+++ b/reg-tests/log/h0.vtc
@@ -0,0 +1,62 @@
+# commit d02286d
+# BUG/MINOR: log: pin the front connection when front ip/ports are logged
+#
+# Mathias Weiersmueller reported an interesting issue with logs which Lukas
+# diagnosed as dating back from commit 9b061e332 (1.5-dev9). When front
+# connection information (ip, port) are logged in TCP mode and the log is
+# emitted at the end of the connection (eg: because %B or any log tag
+# requiring LW_BYTES is set), the log is emitted after the connection is
+# closed, so the address and ports cannot be retrieved anymore.
+#
+# It could be argued that we'd make a special case of these to immediatly
+# retrieve the source and destination addresses from the connection, but it
+# seems cleaner to simply pin the front connection, marking it "tracked" by
+# adding the LW_XPRT flag to mention that we'll need some of these elements
+# at the last moment. Only LW_FRTIP and LW_CLIP are affected. Note that after
+# this change, LW_FRTIP could simply be removed as it's not used anywhere.
+#
+# Note that the problem doesn't happen when using %[src] or %[dst] since
+# all sample expressions set LW_XPRT.
+
+varnishtest "Wrong ip/port logging"
+feature ignore_unknown_macro
+
+server s1 {
+rxreq
+txresp
+} -start
+
+syslog Slg_1 -level notice {
+recv
+recv
+recv info
+expect ~ \"dip\":\"${h1_fe_1_addr}\",\"dport\":\"${h1_fe_1_port}.*\"ts\":\"cD\",\"
+} -start
+
+haproxy h1 -conf {
+global
+log ${Slg_1_addr}:${Slg_1_port} local0
+
+defaults
+log global
+timeout connect 3000
+timeout client 5
+timeout server  1
+
+frontend fe1
+bind "fd@${fe_1}"
+mode tcp
+log-format {\"dip\":\"%fi\",\"dport\":\"%fp\",\"c_ip\":\"%ci\",\"c_port\":\"%cp\",\"fe_name\":\"%ft\",\"be_name\":\"%b\",\"s_name\":\"%s\",\"ts\":\"%ts\",\"bytes_read\":\"%B\"}
+default_backendbe_app
+
+backend be_app
+server app1 ${s1_addr}:${s1_port} check
+} -start
+
+client c1 -connect ${h1_fe_1_sock} {
+txreq -url "/"
+delay 0.02
+} -run
+
+syslog Slg_1 -wait
+
diff --git a/reg-tests/seamless-reload/h0.vtc b/reg-tests/seamless-reload/h0.vtc
new file mode 100644
index 000..498e0c6
--- /dev/null
+++ b/reg-tests/seamless-reload/h0.vtc
@@ -0,0 +1,43 @@
+# commit b4dd15b
+# BUG/MINOR: unix: Make sure we can transfer abns sockets on seamless reload.
+#
+# When checking if a socket we got from the parent is suitable for a listener,
+# we just checked that the path matched sockname.tmp, however this is
+# unsuitable for abns sockets, where we don't have to create a temporary
+# file and rename it later.
+# To detect that, check that the first character of the sun_path is 0 for
+# both, and if so, that _path[1] is the same too.
+
+varnishtest "Seamless reload issue with abns sockets"
+feature ignore_unknown_macro
+
+haproxy h1 -W -conf {
+  global
+stats socket 

Re: [PATCH] MINOR: reg-tests: Add a few regression testing files.

2018-06-20 Thread Frederic Lecaille

On 06/20/2018 10:06 AM, Willy Tarreau wrote:

On Wed, Jun 20, 2018 at 09:47:25AM +0200, Frederic Lecaille wrote:

Here is a few more reg testing files with a special one for Olivier (see
reg-tests/seamless-reload/h0.vtc).


Merged, thanks Fred.

I think we should start to think about using a new tag for patches about
regtests. We already use "TESTS" from time to time for the tests directory
but it contains a bit of whatever. Maybe something short like "REGTEST"
could be easy to spot in logs ? Or feel free to suggest and use anything
else that you see fit.


Ok why not REGTEST (=> new patch for CONTRIBUTING).
>From ac705a3bcc91fcd02e4cc4497f32e9d1641d5c27 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Wed, 20 Jun 2018 10:14:01 +0200
Subject: [PATCH] DOC: Add new REGTEST tag info about reg testing.

---
 CONTRIBUTING | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/CONTRIBUTING b/CONTRIBUTING
index 9e0d625..b5ba182 100644
--- a/CONTRIBUTING
+++ b/CONTRIBUTING
@@ -566,6 +566,9 @@ patch types include :
 
   - LICENSE  licensing updates (may impact distro packagers).
 
+  - REGTEST  updates to any of the regression testing files found in reg-tests
+ directory, including README or any documentation file.
+
 
 When the patch cannot be categorized, it's best not to put any type tag, and to
 only use a risk or complexity information only as below. This is commonly the
-- 
2.1.4



Re: [PATCH] REGTEST: stick-tables: Test expiration when used with table_*

2018-06-21 Thread Frederic Lecaille

On 06/20/2018 04:28 PM, Daniel Corbett wrote:

Hello,

Thanks for adding this integration Fred.  Great job!

Attached is a new regression test to check for stick-tables expiration when
they are used with table_* converters as noted in commit id:
3e60b11100cbc812b77029ca142b83ac7a314db1


Thanks,

-- Daniel



Hello Daniel,

Thank you for this test file.

But as Christopher has just noticed, would it be possible to not use 
http redirections to https://www.haproxy.com?


I think you could use redirections to a varnishtest server.

Fred.



Re: how to run vtc files?

2018-06-21 Thread Frederic Lecaille

On 06/21/2018 04:13 AM, Willy Tarreau wrote:

On Wed, Jun 20, 2018 at 04:39:36PM -0400, Daniel Corbett wrote:

Hello,


On 06/20/2018 03:34 PM,  ??? wrote:

hi


[ilia@localhost haproxy]$ HAPROXY_PROGRAM=./haproxy varnishtest
reg-tests/ssl/h0.vtc
 top   0.0 extmacro def pwd=/home/ilia/xxx/haproxy
 top   0.0 extmacro def localhost=127.0.0.1
 top   0.0 extmacro def bad_backend=127.0.0.1 36769
 top   0.0 extmacro def bad_ip=192.0.2.255
 top   0.0 macro def tmpdir=/tmp/vtc.31222.33cfe809
*    top   0.0 TEST reg-tests/ssl/h0.vtc starting
**   top   0.0 === varnishtest "OpenSSL bug: Random crashes"
*    top   0.0 TEST OpenSSL bug: Random crashes
**   top   0.0 === feature ignore_unknown_macro
**   top   0.0 === haproxy h1 -conf {
 top   0.0 Unknown command: "haproxy"
*    top   0.0 RESETTING after reg-tests/ssl/h0.vtc
*    top   0.0 TEST reg-tests/ssl/h0.vtc FAILED
#    top  TEST reg-tests/ssl/h0.vtc FAILED (0.001) exit=2
[ilia@localhost haproxy]$


Something like this should work:

$ HAPROXY_PROGRAM=$PWD/haproxy varnishtest reg-tests/ssl/h0.vtc
#    top  TEST reg-tests/ssl/h0.vtc passed (0.147)


This just makes me think that we should probably also set HAPROXY_PROGRAM
in the "reg-tests" target in the makefile to point to the current haproxy
executable, about like the below. Fred, what do you think ?

  reg-tests:
...
+   @export HAPROXY_PROGRAM=$${HAPROXY_PROGRAM:-$$PWD/haproxy}; \
@find reg-tests ...


As ${parameter:-word} expansion is Posix, I agree ;).
Same thing for PWD shell variable.

Fred




Re: Peer tables don't synch on clear

2018-02-12 Thread Frederic Lecaille
On 02/08/2018 11:22 AM, Franks Andy (IT Technical Architecture Manager) 
wrote:

Hi all,


Hello Franks,


   Haproxy 1.6.13

   I’ve checked the documentation again but can’t see an option for this.

We sometimes clear backup path server use for individual connections and 
whilst the peers synchronisation works for new connections, it doesn’t 
clear on the secondary peer node we’re using.


Is this by design or an option I’m not seeing?


Please give us more information about your configuration. If possible, 
also provide us with the information of stick-table entries concerned 
with this issue (see "show table" CLI command).


Do not forget to obfuscate the critical data.

Regards,

Fred.




Re: Peer tables don't synch on clear

2018-02-12 Thread Frederic Lecaille
On 02/12/2018 04:28 PM, Franks Andy (IT Technical Architecture Manager) 
wrote:

Hi Fred,


Hi Franks,

Please bottom post when you reply.


   Thanks for the reply.
I have two peers synchronising (we use keepalived over the two to control which 
is live).

HAProxy config:

peers lb_replication
   peer server1 10.128.176.141:1024
   peer server2 10.128.176.142:1024

backend sourceaddr
stick-table type ip size 10240k expire 30m peers lb_replication

frontend ft_web_ssl
bind 0.0.0.0:443 name https ssl crt /etc/haproxy/certs/main.pem
mode http
option httplog

 acl is_from_outside src 192.168.110.0/24
 acl is_empty_path path /
acl is_webmail hdr(host) -i webmail
acl is_webmail_fqdn hdr(host) -i webmail.domain

redirect location /owa/ code 302 if is_webmail is_empty_path ! 
is_from_outside
redirect location /owa/ code 302 if is_webmail_fqdn is_empty_path ! 
is_from_outside
default_backend bk_web_ssl

backend bk_web_ssl
mode http
option httplog
cookie SERVERID insert nocache indirect
stick on src table sourceaddr
server server1 10.128.176.150:443 check ssl
server server2 10.51.0.150:443 check ssl backup

It's fine for new connections - it records the correct server1/server2 
information. It's hard to demonstrate, but I can see when I use haproxyctl to 
clear an entry :

Haproxyctl clear table sourceaddr key 


Haproxy stick-table are synchronized between peers but only to create or 
update entries. The deletions are not synchronized.


The stick-table synchronizations are performed thanks to peers protocol 
(see doc/peers* files). There is nothing in this protocol which 
synchronize the deletions.


So you cannot reproduce your issue with haproxyctl.

The stick-table entries are cleared when they expire (exp == 0) and when 
there is no more usage of these entries (use == 0). As the expiry values 
are synchronized,the stick-table are supposed to be purged at almost the 
same time.



.. it doesn't clear the secondary node entry. When that entry for the client 
re-presents the expiry time on the secondary updates but the entry never clears.

I can't really include pictures on these emails, but the tables are kind of 
standard:

e.g.

0x7fa8b247a4f4: key=217.40.203.34 use=0 exp=1574957 server_id=1

Thanks
Andy

-Original Message-
From: Frederic Lecaille [mailto:flecai...@haproxy.com]
Sent: 12 February 2018 12:56
To: Franks Andy (IT Technical Architecture Manager); 'haproxy@formilux.org'
Subject: Re: Peer tables don't synch on clear

On 02/08/2018 11:22 AM, Franks Andy (IT Technical Architecture Manager)
wrote:

Hi all,


Hello Franks,


    Haproxy 1.6.13

    I've checked the documentation again but can't see an option for this.

We sometimes clear backup path server use for individual connections and
whilst the peers synchronisation works for new connections, it doesn't
clear on the secondary peer node we're using.

Is this by design or an option I'm not seeing?


Please give us more information about your configuration. If possible,
also provide us with the information of stick-table entries concerned
with this issue (see "show table" CLI command).

Do not forget to obfuscate the critical data.

Regards,

Fred.








[PATCH] MINOR: reg-tests: Add reg-tests/README file.

2018-06-19 Thread Frederic Lecaille

On 06/19/2018 10:18 AM, Willy Tarreau wrote:

On Mon, Jun 18, 2018 at 07:50:38PM +0200, Frederic Lecaille wrote:

Hello,

Here is a simple patch to add a Makefile target to run all "*.vtc"
regression testing files found in 'reg-tests' directory.

(...)

Thank you very much for this, Fred! I hope this will ignite a long
series of such tests. It may be useful to add a README in the reg-tests
directory indicating how to install varnishtest (especially the version
compatible with haproxy), and probably suggest contributing new tests
in the CONTRIBUTING file to encourage the practice.


Here is a new patch to add reg-tests/README file and update CONTRIBUTING 
file.


Fred.
>From cc4ea839d4783de2e38389801d469cd908f3a469 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Tue, 19 Jun 2018 14:06:07 +0200
Subject: [PATCH] MINOR: reg-tests: Add reg-tests/README file.

Add reg-tests/README file about how to compile and use varnishtest, and
how to produce patches to add regression testing files to HAProxy sources.

Also update CONTRIBUTING file to encourage the contributors to write
regression testing files.
---
 CONTRIBUTING |  9 
 reg-tests/README | 63 
 2 files changed, 72 insertions(+)
 create mode 100644 reg-tests/README

diff --git a/CONTRIBUTING b/CONTRIBUTING
index b2c2b49..9e0d625 100644
--- a/CONTRIBUTING
+++ b/CONTRIBUTING
@@ -467,6 +467,12 @@ do not think about them anymore after a few patches.
harm when nobody is able to tell whether or not the patch needs to be
backported or can be reverted in case of regression.
 
+   When fixing a bug which is reproducible, if possible, the contributors are
+   strongly encouraged to write a regression testing VTC file for varnishtest
+   to add to reg-tests directory. More information about varnishtest may be
+   found in README file of reg-tests directory and in doc/regression-testing.txt
+   file.
+
 12) Discuss on the mailing list
 
When submitting changes, please always CC the mailing list address so that
@@ -615,6 +621,9 @@ part is being touched. The following tags are suggested but not limitative :
 
   - tests regression test files. No code is affected, no need to upgrade.
 
+  - reg-tests regression test files for varnishtest. No code is affected, no
+  need to upgrade.
+
   - init  initialization code, arguments parsing, etc...
 
   - configconfiguration parser, mostly used when adding new config keywords
diff --git a/reg-tests/README b/reg-tests/README
new file mode 100644
index 000..5427ad6
--- /dev/null
+++ b/reg-tests/README
@@ -0,0 +1,63 @@
+ * Regression testing for HAProxy with varnishtest *
+
+
+This little README file is about how to compile and run varnishtest test case files (VTC files) to test HAProxy for any regression.
+
+To do so, you will have to compile varnishtest program sources which comes with
+Varnish cache application. varnishtest is a very useful program which has been
+developed to test Varnish cache application. varnishtest has been modified in
+collaboration with Varnish cache conceptor Poul-Henning Kamp to support HAProxy in
+addition to Varnish cache.
+
+
+* varnishtest compilation *
+
+  - Clone recent Varnish cache sources which may be found in this GitHub repository
+https://github.com/varnishcache/varnish-cache:
+
+$ git clone https://github.com/varnishcache/varnish-cache
+
+  - Compile Varnish cache sources:
+
+$ cd varnish-cache && ./autogen.sh && ./configure && make
+
+  Then varnishtest program may be found in bin/varnishtest directory.
+  VTC files for Varnish cache may be found in bin/varnishtest/tests directory.
+  The Varnish cache manuals are located in 'man' directory. You will have to
+  have a look at varnishtest(7) and vtc(7) manuals.
+
+  Some information may also be found in doc/regression-testing.txt in HAProxy
+  sources.
+
+
+* varnishtest execution *
+
+  You must set HAPROXY_PROGRAM environment variable to give the location
+  of the HAProxy program to test to varnishtest:
+
+$ HAPROXY_PROGRAM= varnishtest ...
+
+  The HAProxy VTC files found in HAProxy sources may be run with the reg-tests
+  Makefile target. You must set the VARNISHTEST_PROGRAM environment variable to
+  give the location of the varnishtest program which has been previously compiled.
+
+$ VARNISHTEST_PROGRAM= HAPROXY_PROGRAM= make reg-tests
+
+  Note that varnishtest is run with -t5 and -l option. -l option is to keep
+  keep varnishtest temporary directory in case of failed test cases. core files
+  may be found in this directory (if enabled by ulimit).
+
+
+* varnishtest patches for HAProxy VTC files *
+
+  When producing a patch to add a VCT regression testing file to reg-tests directory,
+  please follow these simple rules:
+
+- Add the commit number on the first line.
+- Then, copy and paste the commit log.
+

[PATCH] BUG/MINOR: lua: Bad HTTP client request duration.

2018-08-24 Thread Frederic Lecaille
Here is a patch to fix the issue reported by Patrick in this thread 
(BUG: Tw is negative with lua sleep 
https://www.mail-archive.com/haproxy@formilux.org/msg30474.html).


Note that I provide a reg testing file to test both HTTP and TCP LUA 
applet callbacks used when registering an HTTP or TCP service.


I dit not manage to reproduce any issue similar to the one reported by 
Patrick about HTTP. Note that when we modify struct logs->tv_request 
field in src/hlua.c only %TR, %Tq and %Tw timing events may be affected, 
and among these three timing events, only %Tw is valid for TCP mode.



Fred.
>From 410ed466774f40c221afb1a8224d64bc21c4407c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Thu, 23 Aug 2018 18:06:35 +0200
Subject: [PATCH 2/2] REGEST/MINOR: Add reg testing files.

Reg testing files for a LUA bug fixed by 7b6cc527 commit.
---
 reg-tests/lua/b1.lua |  8 +
 reg-tests/lua/b1.vtc | 80 
 2 files changed, 88 insertions(+)
 create mode 100644 reg-tests/lua/b1.lua
 create mode 100644 reg-tests/lua/b1.vtc

diff --git a/reg-tests/lua/b1.lua b/reg-tests/lua/b1.lua
new file mode 100644
index ..2c2ab1dc
--- /dev/null
+++ b/reg-tests/lua/b1.lua
@@ -0,0 +1,8 @@
+core.register_service("foo.http", "http", function(applet)
+core.msleep(10)
+applet:start_response()
+end)
+
+core.register_service("foo.tcp", "tcp", function(applet)
+   applet:send("HTTP/1.1 200 OK\r\nTransfer-encoding: chunked\r\n\r\n0\r\n\r\n")
+end)
diff --git a/reg-tests/lua/b1.vtc b/reg-tests/lua/b1.vtc
new file mode 100644
index ..a7a2d699
--- /dev/null
+++ b/reg-tests/lua/b1.vtc
@@ -0,0 +1,80 @@
+# commit 7b6cc52784526c32efda44b873a4258d3ae0b8c7
+# BUG/MINOR: lua: Bad HTTP client request duration.
+#
+# HTTP LUA applet callback should not update the date on which the HTTP client requests
+# arrive. This was done just after the LUA applet has completed its job.
+#
+# This patch simply removes the affected statement. The same fixe has been applied
+# to TCP LUA applet callback.
+#
+# To reproduce this issue, as reported by Patrick Hemmer, implement an HTTP LUA applet
+# which sleeps a bit before replying:
+#
+#   core.register_service("foo", "http", function(applet)
+#   core.msleep(100)
+#   applet:set_status(200)
+#   applet:start_response()
+#   end)
+#
+# This had as a consequence to log %TR field with approximatively the same value as
+# the LUA sleep time.
+
+varnishtest "LUA bug"
+
+feature ignore_unknown_macro
+
+syslog Slog {
+recv notice
+expect ~ "haproxy\\[[0-9]*\\]: Proxy f1 started"
+
+recv notice
+expect ~ "haproxy\\[[0-9]*\\]: Proxy f2 started"
+
+recv info
+expect ~ "haproxy\\[[0-9]*\\]: Ta=[0-9]* Tc=[0-9]* Td=[0-9]* Th=[0-9]* Ti=[0-9]* Tq=[0-9]* TR=[0-9]* Tr=[0-9]* Tt=[0-9]* Tw=[0-9]*$"
+
+recv info
+expect ~ "haproxy\\[[0-9]*\\]: Tc=[0-9]* Td=[0-9]* Th=[0-9]* Tt=[0-9]* Tw=[0-9]*$"
+} -start
+
+haproxy h1 -conf {
+global
+lua-load ${testdir}/b1.lua
+
+defaults
+timeout client 1s
+timeout server 1s
+timeout connect 1s
+
+frontend f1
+mode http
+bind "fd@${f1}"
+log ${Slog_addr}:${Slog_port} daemon
+log-format Ta=%Ta\ Tc=%Tc\ Td=%Td\ Th=%Th\ Ti=%Ti\ Tq=%Tq\ TR=%TR\ Tr=%Tr\ Tt=%Tt\ Tw=%Tw
+default_backend b1
+
+backend b1
+mode http
+http-request use-service lua.foo.http
+
+frontend f2
+mode tcp
+bind "fd@${f2}"
+log ${Slog_addr}:${Slog_port} daemon
+log-format Tc=%Tc\ Td=%Td\ Th=%Th\ Tt=%Tt\ Tw=%Tw
+
+tcp-request inspect-delay 1s
+tcp-request content use-service lua.foo.tcp
+} -start
+
+client c1 -connect "${h1_f1_sock}" {
+txreq
+rxresp
+} -run
+
+client c2 -connect "${h1_f2_sock}" {
+txreq
+rxresp
+} -run
+
+syslog Slog -wait
-- 
2.11.0

>From 7b6cc52784526c32efda44b873a4258d3ae0b8c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= 
Date: Wed, 18 Jul 2018 14:25:26 +0200
Subject: [PATCH 1/2] BUG/MINOR: lua: Bad HTTP client request duration.

HTTP LUA applet callback should not update the date on which the HTTP client requests
arrive. This was done just after the LUA applet has completed its job.

This patch simply removes the affected statement. The same fixe has been applied
to TCP LUA applet callback.

To reproduce this issue, as reported by Patrick Hemmer, implement an HTTP LUA applet
which sleeps a bit before replying:

  core.register_service("foo", "http", function(applet)
  core.msleep(100)
  applet:set_status(200)
  applet:start_response()
  end)

This had as a consequence to log %TR field with approximatively the same value as
the LUA sleep time.

Thank you to Patrick Hemmer for having reported this issue.

Must be backported to 1.8, 1.7 and 1.6.
---
 src/hlua.c | 6 +-
 1 file changed, 1 insertion(+), 5 

  1   2   3   >