#include <errno.h>
#include <libcli.h>
+#include "dhcp6.h"
#include "l2tpns.h"
#include "cluster.h"
#include "util.h"
// The master just processes the payload as if it had
// received it off the tun device.
//(note: THIS ROUTINE WRITES TO pack[-6]).
-int master_forward_packet(uint8_t *data, int size, in_addr_t addr, int port)
+int master_forward_packet(uint8_t *data, int size, in_addr_t addr, uint16_t port, uint16_t indexudp)
{
uint8_t *p = data - (3 * sizeof(uint32_t));
uint8_t *psave = p;
+ uint32_t indexandport = port | ((indexudp << 16) & 0xFFFF0000);
if (!config->cluster_master_address) // No election has been held yet. Just skip it.
return -1;
LOG(4, 0, 0, "Forwarding packet from %s to master (size %d)\n", fmtaddr(addr, 0), size);
STAT(c_forwarded);
- add_type(&p, C_FORWARD, addr, (uint8_t *) &port, sizeof(port)); // ick. should be uint16_t
+ add_type(&p, C_FORWARD, addr, (uint8_t *) &indexandport, sizeof(indexandport));
return peer_send_data(config->cluster_master_address, psave, size + (3 * sizeof(uint32_t)));
}
// Failed to compress : Fall through.
}
case C_SESSION:
- add_type(p, C_SESSION, id, (uint8_t *) &session[id], sizeof(sessiont));
+ add_type(p, C_SESSION, id, (uint8_t *) &session[id], sizeof(sessiont));
break;
case C_CBUNDLE: { // Compressed C_BUNDLE
// Failed to compress : Fall through.
}
case C_TUNNEL:
- add_type(p, C_TUNNEL, id, (uint8_t *) &tunnel[id], sizeof(tunnelt));
+ add_type(p, C_TUNNEL, id, (uint8_t *) &tunnel[id], sizeof(tunnelt));
break;
default:
LOG(0, 0, 0, "Found an invalid type in heart queue! (%d)\n", type);
{
int i;
- for (i = 0 ; i < config->cluster_num_changes ; ++i)
- if ( cluster_changes[i].id == id &&
- cluster_changes[i].type == type)
- return 0; // Already marked for change.
-
- cluster_changes[i].type = type;
- cluster_changes[i].id = id;
- ++config->cluster_num_changes;
-
- if (config->cluster_num_changes > MAX_CHANGES)
- cluster_heartbeat(); // flush now
-
- return 1;
-}
-
-// The deleted session, must be before the new session
-int cluster_listinvert_session(int sidnew, int sidtodel)
-{
- int i, inew = 0;
-
for (i = 0 ; i < config->cluster_num_changes ; ++i)
{
- if ( cluster_changes[i].id == sidtodel && cluster_changes[i].type == C_CSESSION)
- return 0; // Deleted session already before the new session.
-
- if ( cluster_changes[i].id == sidnew && cluster_changes[i].type == C_CSESSION)
+ if ( cluster_changes[i].id == id && cluster_changes[i].type == type)
{
- if (session[i].tunnel != T_FREE)
- inew = i;
- else
- return 0; // This a free session no invert.
-
+ // Already marked for change, remove it
+ --config->cluster_num_changes;
+ memmove(&cluster_changes[i],
+ &cluster_changes[i+1],
+ (config->cluster_num_changes - i) * sizeof(cluster_changes[i]));
break;
}
}
- for ( ; i < config->cluster_num_changes ; ++i)
- {
- if ( cluster_changes[i].id == sidtodel && cluster_changes[i].type == C_CSESSION)
- {
- // Reverse position
- cluster_changes[i].id = sidnew;
- cluster_changes[inew].id = sidtodel;
- return 1;
- }
- }
+ cluster_changes[config->cluster_num_changes].type = type;
+ cluster_changes[config->cluster_num_changes].id = id;
+ ++config->cluster_num_changes;
- return 0;
+ if (config->cluster_num_changes > MAX_CHANGES)
+ cluster_heartbeat(); // flush now
+
+ return 1;
}
// A particular session has been changed!
int i, type;
int hb_ver = more;
-#ifdef LAC
-#if HB_VERSION != 7
-# error "need to update cluster_process_heartbeat()"
-#endif
-#else
-#if HB_VERSION != 6
+#if HB_VERSION != 8
# error "need to update cluster_process_heartbeat()"
#endif
-#endif
-
- // we handle versions 5 through 7
+ // we handle versions 5 through 8
if (hb_ver < 5 || hb_ver > HB_VERSION) {
LOG(0, 0, 0, "Received a heartbeat version that I don't support (%d)!\n", hb_ver);
return -1; // Ignore it??
break;
}
- if (size != sizeof(sessiont) ) { // Ouch! Very very bad!
- LOG(0, 0, 0, "DANGER: Received a CSESSION that didn't decompress correctly!\n");
- // Now what? Should exit! No-longer up to date!
- break;
+ if (size != sizeof(sessiont)) { // Ouch! Very very bad!
+ if ((hb_ver < HB_VERSION) && (size < sizeof(sessiont)))
+ {
+ LOG(2, 0, 0, "WARNING: Received a CSESSION from %s hb_version %d != %d current version !\n", fmtaddr(addr, 2), hb_ver, HB_VERSION);
+ // New feature not activated until the master has not been upgraded.
+ }
+ else
+ {
+ LOG(0, 0, 0, "DANGER: Received a CSESSION that didn't decompress correctly!\n");
+ // Now what? Should exit! No-longer up to date!
+ break;
+ }
}
cluster_recv_session(more, c);
size = rle_decompress((uint8_t **) &p, s, c, sizeof(c));
s -= (p - orig_p);
-#ifdef LAC
if ( ((hb_ver >= HB_VERSION) && (size != sizeof(tunnelt))) ||
((hb_ver < HB_VERSION) && (size > sizeof(tunnelt))) )
-#else
- if (size != sizeof(tunnelt) )
-#endif
{ // Ouch! Very very bad!
LOG(0, 0, 0, "DANGER: Received a CTUNNEL that didn't decompress correctly!\n");
// Now what? Should exit! No-longer up to date!
else
{
struct sockaddr_in a;
+ uint16_t indexudp;
a.sin_addr.s_addr = more;
- a.sin_port = *(int *) p;
+ a.sin_port = (*(int *) p) & 0xFFFF;
+ indexudp = ((*(int *) p) >> 16) & 0xFFFF;
s -= sizeof(int);
p += sizeof(int);
processdae(p, s, &a, sizeof(a), &local);
}
else
- processudp(p, s, &a);
+ processudp(p, s, &a, indexudp);
return 0;
}
//====================================================================================================
-int cmd_show_cluster(struct cli_def *cli, char *command, char **argv, int argc)
+int cmd_show_cluster(struct cli_def *cli, const char *command, char **argv, int argc)
{
int i;