summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--include/network.h12
-rw-r--r--src/sync-ftfw.c50
-rw-r--r--src/sync-mode.c4
4 files changed, 59 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 597206a..14ba054 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -36,6 +36,7 @@ o add Mcast[Snd|Rcv]SocketBuffer clauses to tune multicast socket buffers
o add missing string.h required by strdup in config parsing
o add eventfd emulation to communicate receiver -> sender
o add best effort replication protocol (aka NOTRACK)
+o rework the HELLO logic inside FT-FW
version 0.9.6 (2008/03/08)
------------------------------
diff --git a/include/network.h b/include/network.h
index baa1eba..777be11 100644
--- a/include/network.h
+++ b/include/network.h
@@ -31,6 +31,8 @@ enum {
NET_F_NACK = (1 << 2),
NET_F_ACK = (1 << 3),
NET_F_ALIVE = (1 << 4),
+ NET_F_HELLO = (1 << 5),
+ NET_F_HELLO_BACK= (1 << 6),
};
enum {
@@ -63,6 +65,12 @@ enum {
SEQ_BEFORE,
};
+enum {
+ SAY_HELLO,
+ HELLO_BACK,
+ HELLO_DONE,
+};
+
int mcast_track_seq(uint32_t seq, uint32_t *exp_seq);
void mcast_track_update_seq(uint32_t seq);
int mcast_track_is_seq_set(void);
@@ -74,12 +82,14 @@ void mcast_buffered_destroy(void);
int mcast_buffered_send_netmsg(struct mcast_sock *m, void *data, size_t len);
ssize_t mcast_buffered_pending_netmsg(struct mcast_sock *m);
-#define IS_DATA(x) (x->flags == 0)
+#define IS_DATA(x) ((x->flags & ~(NET_F_HELLO | NET_F_HELLO_BACK)) == 0)
#define IS_ACK(x) (x->flags & NET_F_ACK)
#define IS_NACK(x) (x->flags & NET_F_NACK)
#define IS_RESYNC(x) (x->flags & NET_F_RESYNC)
#define IS_ALIVE(x) (x->flags & NET_F_ALIVE)
#define IS_CTL(x) IS_ACK(x) || IS_NACK(x) || IS_RESYNC(x) || IS_ALIVE(x)
+#define IS_HELLO(x) (x->flags & NET_F_HELLO)
+#define IS_HELLO_BACK(x)(x->flags & NET_F_HELLO_BACK)
#define HDR_NETWORK2HOST(x) \
({ \
diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c
index adfdda9..42005c4 100644
--- a/src/sync-ftfw.c
+++ b/src/sync-ftfw.c
@@ -52,6 +52,7 @@ static uint32_t window;
static uint32_t ack_from;
static int ack_from_set = 0;
static struct alarm_block alive_alarm;
+static int hello_state = SAY_HELLO;
/* XXX: alive message expiration configurable */
#define ALIVE_INT 1
@@ -97,6 +98,16 @@ static void tx_queue_add_ctlmsg(uint32_t flags, uint32_t from, uint32_t to)
.to = to,
};
+ switch(hello_state) {
+ case SAY_HELLO:
+ ack.flags |= NET_F_HELLO;
+ break;
+ case HELLO_BACK:
+ ack.flags |= NET_F_HELLO_BACK;
+ hello_state = HELLO_DONE;
+ break;
+ }
+
queue_add(tx_queue, &ack, NETHDR_ACK_SIZ);
write_evfd(STATE_SYNC(evfd));
}
@@ -315,10 +326,29 @@ static int digest_msg(const struct nethdr *net)
return MSG_BAD;
}
+static int digest_hello(const struct nethdr *net)
+{
+ int ret = 0;
+
+ if (IS_HELLO(net)) {
+ dlog(LOG_NOTICE, "The other node says HELLO");
+ hello_state = HELLO_BACK;
+ ret = 1;
+ } else if (IS_HELLO_BACK(net)) {
+ dlog(LOG_NOTICE, "The other node says HELLO BACK");
+ hello_state = HELLO_DONE;
+ }
+
+ return ret;
+}
+
static int ftfw_recv(const struct nethdr *net)
{
int ret = MSG_DATA;
+ if (digest_hello(net))
+ goto bypass;
+
switch (mcast_track_seq(net->seq, &exp_seq)) {
case SEQ_AFTER:
ret = digest_msg(net);
@@ -348,14 +378,12 @@ static int ftfw_recv(const struct nethdr *net)
/* we don't accept delayed packets */
dlog(LOG_WARNING, "Received seq=%u before expected seq=%u",
net->seq, exp_seq);
- dlog(LOG_WARNING, "Probably the other node has come back"
- "to life but you forgot to add "
- "conntrackd -r to your scripts");
ret = MSG_DROP;
break;
case SEQ_UNSET:
case SEQ_IN_SYNC:
+bypass:
ret = digest_msg(net);
if (ret == MSG_BAD) {
ret = MSG_BAD;
@@ -390,8 +418,6 @@ static void ftfw_send(struct nethdr *net, struct us_conntrack *u)
struct netpld *pld = NETHDR_DATA(net);
struct cache_ftfw *cn;
- HDR_NETWORK2HOST(net);
-
switch(ntohs(pld->query)) {
case NFCT_Q_CREATE:
case NFCT_Q_UPDATE:
@@ -404,7 +430,19 @@ static void ftfw_send(struct nethdr *net, struct us_conntrack *u)
rs_list_len--;
}
- cn->seq = net->seq;
+ switch(hello_state) {
+ case SAY_HELLO:
+ net->flags = ntohs(net->flags) | NET_F_HELLO;
+ net->flags = htons(net->flags);
+ break;
+ case HELLO_BACK:
+ net->flags = ntohs(net->flags) | NET_F_HELLO_BACK;
+ net->flags = htons(net->flags);
+ hello_state = HELLO_DONE;
+ break;
+ }
+
+ cn->seq = ntohl(net->seq);
list_add_tail(&cn->rs_list, &rs_list);
rs_list_len++;
break;
diff --git a/src/sync-mode.c b/src/sync-mode.c
index 16cc70d..4b36935 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -395,9 +395,11 @@ static void mcast_send_sync(struct us_conntrack *u, int query)
net = BUILD_NETMSG(u->ct, query);
len = prepare_send_netmsg(STATE_SYNC(mcast_client), net);
- mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net, len);
+
if (STATE_SYNC(sync)->send)
STATE_SYNC(sync)->send(net, u);
+
+ mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net, len);
}
static int purge_step(void *data1, void *data2)