-* Sat May 21 2005 Brendan O'Dea <bod@optusnet.com.au> 2.0.21
+* Sun May 22 2005 Brendan O'Dea <bod@optusnet.com.au> 2.0.21
- Cluster changes from Michael, intended to prevent a stray master
from trashing a cluster:
+ Ignore heartbeats from peers claiming to be the master before the
+ Keep probing the master for late heartbeats.
+ Drop BGP as soon as we become master with peers (TODO: pre-emptively
drop routes if the master is late and we are the best candidate).
- + A slave (presumably a recently restarted master) receiving a
- LASTSEEN message sends a zero basetime ping (as sent by the master
- on clean shutdown).
+ + Any PING seen from a master forces an election (rather than just
+ where basetime is zero).
+ + A slave which receives a LASTSEEN message (presumably a restarted
+ master) sends back a ping, indicating that it's not the master.
* Mon May 16 2005 Brendan O'Dea <bod@optusnet.com.au> 2.0.20
- Add handling of "throttle=N" RADIUS attributes.
// L2TPNS Clustering Stuff
-char const *cvs_id_cluster = "$Id: cluster.c,v 1.26.2.6 2005/05/21 13:05:36 bodea Exp $";
+char const *cvs_id_cluster = "$Id: cluster.c,v 1.26.2.7 2005/05/22 04:15:32 bodea Exp $";
#include <stdio.h>
#include <stdlib.h>
}
//
-// Send an 'i am alive' message to every machine in the cluster.
+// Send an 'i am alive' message to every machine in the cluster, or to a single peer
//
-void cluster_send_ping(time_t basetime)
+static void send_ping(time_t basetime, in_addr_t peer)
{
char buff[100 + sizeof(pingt)];
char *p = buff;
if (config->cluster_iam_master && basetime) // We're heartbeating so no need to ping.
return;
- LOG(5, 0, 0, "Sending cluster ping...\n");
-
x.ver = 1;
x.addr = config->bind_address;
x.undef = config->cluster_undefined_sessions + config->cluster_undefined_tunnels;
x.basetime = basetime;
add_type(&p, C_PING, basetime, (char *) &x, sizeof(x));
- cluster_send_data(buff, (p-buff) );
+
+ if (peer)
+ peer_send_data(peer, buff, (p-buff));
+ else
+ cluster_send_data(buff, (p-buff) );
+}
+
+void cluster_send_ping(time_t basetime)
+{
+ LOG(5, 0, 0, "Sending cluster ping...\n");
+ send_ping(0, basetime);
+}
+
+void peer_send_ping(in_addr_t peer, time_t basetime)
+{
+ LOG(5, 0, 0, "Sending unicast ping to %s...\n", fmtaddr(peer, 0));
+ send_ping(peer, basetime);
}
//
LOG(1, 0, 0, "Slave %s sent LASTSEEN with seq %d\n", fmtaddr(slave, 0), seq);
if (!config->cluster_iam_master) {
- LOG(1, 0, 0, "Got LASTSEEN but I'm not a master! Sending a null PING.\n");
- // Send a ping to the stray slave saying that we're a master that's
- // just shutdown. This should force the slave to listen for the real
- // master.
- peer_send_message(slave, C_PING, 0, NULL, 0);
+ LOG(1, 0, 0, "Got LASTSEEN but I'm not a master! Sending a PING.\n");
+ // Send a ping to the slave so they know we're no longer a master
+ peer_send_ping(slave, basetime);
return 0;
}
}
// Is this the master shutting down??
- if (peer == config->cluster_master_address && !basetime) {
- LOG(3, 0, 0, "Master %s shutting down...\n", fmtaddr(config->cluster_master_address, 0));
+ if (peer == config->cluster_master_address) {
+ LOG(3, 0, 0, "Master %s %s\n", fmtaddr(config->cluster_master_address, 0),
+ basetime ? "has restarted!" : "shutting down...");
+
config->cluster_master_address = 0;
config->cluster_last_hb = 0; // Force an election.
cluster_check_master();