* Fri Mar 5 2004 David Parrish <david@dparrish.com> 1.1.0
[l2tpns.git] / cluster.c
1 // L2TPNS Clustering Stuff
2 // $Id: cluster.c,v 1.2 2004/03/05 00:09:03 fred_nerk Exp $ #include <stdio.h> #include <sys/file.h>
3
4 #include <sys/stat.h>
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <sys/ioctl.h>
10 #include <net/if.h>
11 #include <string.h>
12 #include <malloc.h>
13 #include <errno.h>
14 #include <stdlib.h>
15 #include <stdarg.h>
16 #include <unistd.h>
17 #include <stdio.h>
18 #include "cluster.h"
19
20 int cluster_sockfd = 0;
21 int cluster_server = 0;
22 uint32_t vip_address;
23 extern int debug;
24 void _log_hex(int level, const char *title, const char *data, int maxsize);
25 #define log_hex(a,b,c,d)
26 #ifndef log_hex
27 #define log_hex(a,b,c,d) do{if (a > debug) _log_hex(a,b,c,d);}while (0)
28 #endif
29
30 // Create a listening socket
31 int cluster_init(uint32_t bind_address, int server)
32 {
33 struct sockaddr_in addr;
34
35 vip_address = bind_address;
36 cluster_server = !!server;
37
38 cluster_sockfd = socket(AF_INET, SOCK_DGRAM, UDP);
39
40 memset(&addr, 0, sizeof(addr));
41 addr.sin_family = AF_INET;
42 addr.sin_port = htons(cluster_server ? CLUSTERPORT : CLUSTERCLIENTPORT);
43 addr.sin_addr.s_addr = INADDR_ANY;
44 setsockopt(cluster_sockfd, SOL_SOCKET, SO_REUSEADDR, &addr, sizeof(addr));
45 if (bind(cluster_sockfd, (void *) &addr, sizeof(addr)) < 0)
46 {
47 perror("bind");
48 exit(-1);
49 }
50
51 return cluster_sockfd;
52 }
53
54 int cluster_send_message(unsigned long ip_address, uint32_t vip, char type, void *data, int datalen)
55 {
56 size_t l = 1 + sizeof(uint32_t) + datalen;
57 char *buf = NULL;
58 struct sockaddr_in addr = {0};
59
60 if (!cluster_sockfd) return -1;
61 if (!ip_address) return 0;
62
63 buf = calloc(l, 1);
64 *(uint32_t *)(buf) = htonl(vip);
65 *(char *)(buf+sizeof(uint32_t)) = type;
66
67 if (data && datalen > 0)
68 memcpy((char *)(buf + sizeof(uint32_t) + 1), data, datalen);
69
70 addr.sin_addr.s_addr = ip_address;
71 addr.sin_port = htons(cluster_server ? CLUSTERCLIENTPORT : CLUSTERPORT);
72 addr.sin_family = AF_INET;
73
74 log_hex(4, "Cluster send", buf, l);
75
76 if (sendto(cluster_sockfd, buf, l, MSG_NOSIGNAL, (void *) &addr, sizeof(addr)) < 0)
77 {
78 perror("sendto");
79 free(buf);
80 return -1;
81 }
82 free(buf);
83
84 return 0;
85 }