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

2016-10-17 Thread Willy Tarreau
Hi Fred,

On Wed, Oct 12, 2016 at 06:11:04PM +0200, Frederic Lecaille wrote:
> 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.

Thank you very much for taking care of this one. I'd say it's a design
bug and not an implementation bug. And the fact that you were forced to
upgrade the protocol reflects this. For this reason, I think in a first
time I'll only merge it into 1.7, and maybe later after some observation
period *and* if there is a strong insisting demand we could consider
backporting it. But in general I'd rather keep protocol 2.0 for v1.6 and
protocol 2.1 for v1.7 as it's easier to track for users.

Oh I forgot to say, your patch looks good.

Cheers,
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
 		cur