// L2TPNS Cluster Master
-// $Id: cluster_master.c,v 1.1 2003/12/16 07:07:39 fred_nerk Exp $
+// $Id: cluster_master.c,v 1.3 2004/05/24 04:12:34 fred_nerk Exp $
#include <stdio.h>
#include <netinet/in.h>
int handle_tunnel(char *buf, int l, uint32_t addr);
int handle_session(char *buf, int l, uint32_t addr);
int handle_ping(char *buf, int l, uint32_t addr);
+int handle_goodbye(char *buf, int l, uint32_t addr);
int backup_up(slave *s);
int backup_down(slave *s);
int return_state(slave *s);
slave *find_slave(uint32_t address);
#define log _log
-void _log(int level, const char *format, ...);
+void _log(int level, const char *format, ...) __attribute__((format (printf, 2, 3)));
void log_hex(int level, const char *title, const char *data, int maxsize);
/* Catch our forked processes exiting */
signal(SIGCHLD, sigchild_handler);
- log(0, "Cluster Manager $Id: cluster_master.c,v 1.1 2003/12/16 07:07:39 fred_nerk Exp $ starting\n");
+ log(0, "Cluster Manager $Id: cluster_master.c,v 1.3 2004/05/24 04:12:34 fred_nerk Exp $ starting\n");
to.tv_sec = 1;
to.tv_usec = 0;
int processmsg(char *buf, int l, struct sockaddr_in *src_addr)
{
+ slave *s;
char mtype;
uint32_t addr;
mtype = *buf; buf++; l--;
+ if (mtype != C_GOODBYE && (s = find_slave(addr)) && s->down)
+ {
+ char *hostname;
+ hostname = calloc(l + 1, 1);
+ memcpy(hostname, buf, l);
+ log(1, "Slave \"%s\" (for %s) has come back.\n", hostname, inet_toa(s->ip_address));
+ backup_down(s);
+ free(hostname);
+ }
+
switch (mtype)
{
case C_HELLO:
if (!find_slave(addr)) handle_hello((char *)(buf + 1), *(char *)buf, src_addr, addr);
handle_session(buf, l, addr);
break;
+ case C_GOODBYE:
+ if (!find_slave(addr)) break;
+ handle_goodbye(buf, l, addr);
+ break;
}
return mtype;
}
return 0;
}
+int handle_goodbye(char *buf, int l, uint32_t addr)
+{
+ int i;
+ slave *s;
+
+ // Is this a slave we have state information for?
+ if ((s = find_slave(addr)))
+ {
+ log(0, "Received goodbye for slave %s\n", s->hostname);
+ ll_delete(slaves, s);
+ for (i = 0; i < s->num_tunnels; i++)
+ if (s->tunnels[i]) free(s->tunnels[i]);
+ for (i = 0; i < s->num_sessions; i++)
+ if (s->sessions[i]) free(s->sessions[i]);
+ if (s->hostname) free(s->hostname);
+ free(s);
+ }
+
+ return 0;
+}
+