1 // L2TPNS Cluster Master
2 // $Id: cluster_slave.c,v 1.4 2004-05-24 04:12:48 fred_nerk Exp $
5 #include <netinet/in.h>
12 #include <sys/socket.h>
15 #include <sys/types.h>
16 #include <arpa/inet.h>
24 extern int cluster_sockfd
;
25 extern char hostname
[1000];
26 extern ippoolt
*ip_address_pool
;
27 extern uint32_t vip_address
;
28 extern struct configt
*config
;
30 int handle_tunnel(char *buf
, int l
);
31 int handle_session(char *buf
, int l
);
32 int handle_hello_response(char *buf
, int l
);
34 int processcluster(char *buf
, int l
)
39 log_hex(4, "Cluster receive", buf
, l
);
40 if (!buf
|| l
<= sizeof(uint32_t)) return 0;
42 addr
= ntohl(*(uint32_t*)buf
);
43 buf
+= sizeof(uint32_t);
44 l
-= sizeof(uint32_t);
46 if (addr
!= vip_address
)
48 log(0, 0, 0, 0, "Received cluster message for VIP %s, which isn't ours\n", inet_toa(addr
));
51 mtype
= *buf
; buf
++; l
--;
57 case C_HELLO_RESPONSE
:
58 handle_hello_response(buf
, l
);
63 handle_tunnel(buf
, l
);
66 handle_session(buf
, l
);
74 int handle_tunnel(char *buf
, int l
)
78 // Ignore tunnel message if NOSTATEFILE exists
79 if (config
->ignore_cluster_updates
)
81 log(1, 0, 0, 0, "Discarding tunnel message from cluster master.\n");
86 log(1, 0, 0, t
, "Receiving tunnel %d from cluster master (%d bytes)\n", t
, l
);
87 buf
+= sizeof(int); l
-= sizeof(int);
91 log(0, 0, 0, t
, "Cluster master tried to send tunnel %d, which is bigger than MAXTUNNEL (%d)\n", t
, MAXTUNNEL
);
95 if (l
!= sizeof(tunnelt
))
97 log(1, 0, 0, t
, "Discarding bogus tunnel message (%d bytes instead of %d).\n", l
, sizeof(tunnelt
));
101 memcpy(&tunnel
[t
], buf
, l
);
102 log(3, 0, 0, t
, "Cluster master sent tunnel for %s\n", tunnel
[t
].hostname
);
104 tunnel
[t
].controlc
= 0;
105 tunnel
[t
].controls
= NULL
;
106 tunnel
[t
].controle
= NULL
;
110 int handle_session(char *buf
, int l
)
114 // Ignore tunnel message if NOSTATEFILE exists
115 if (config
->ignore_cluster_updates
)
117 log(1, 0, 0, 0, "Discarding session message from cluster master.\n");
122 log(1, 0, s
, 0, "Receiving session %d from cluster master (%d bytes)\n", s
, l
);
123 buf
+= sizeof(int); l
-= sizeof(int);
127 log(0, 0, s
, 0, "Cluster master tried to send session %d, which is bigger than MAXSESSION (%d)\n", s
, MAXSESSION
);
131 if (l
!= sizeof(sessiont
))
133 log(1, 0, s
, 0, "Discarding short session message (%d bytes instead of %d).\n", l
, sizeof(sessiont
));
139 session
[s
-1].next
= session
[s
].next
;
142 if (sessionfree
== s
)
144 sessionfree
= session
[s
].next
;
147 memcpy(&session
[s
], buf
, l
);
149 session
[s
].throttle
= 0;
150 if (session
[s
].opened
)
152 log(2, 0, s
, session
[s
].tunnel
, "Cluster master sent active session for user %s\n", session
[s
].user
);
153 sessionsetup(session
[s
].tunnel
, s
, 0);
154 if (session
[s
].ip
&& session
[s
].ip
!= 0xFFFFFFFE)
157 for (x
= 0; x
< MAXIPPOOL
&& ip_address_pool
[x
].address
; x
++)
159 if (ip_address_pool
[x
].address
== session
[s
].ip
)
161 ip_address_pool
[x
].assigned
= 1;
170 int handle_hello_response(char *buf
, int l
)
172 int numtunnels
, numsessions
;
174 /* The cluster master has downed the address, so send another garp */
175 send_garp(vip_address
);
181 log(1, 0, 0, 0, "Cluster master sent invalid hello response: %d bytes instead of %d\n", l
, (4 * IL
));
184 numtunnels
= *(int *)(buf
+ IL
* 0);
185 numsessions
= *(int *)(buf
+ IL
* 1);
186 if (numtunnels
== 0 && numsessions
== 0)
188 log(2, 0, 0, 0, "Cluster master has no state information for us.\n");
191 log(2, 0, 0, 0, "The cluster master will send %d tunnels and %d sessions.\n", numtunnels
, numsessions
);
195 int cluster_send_session(int s
)
200 if (!cluster_sockfd
) return 1;
202 packet
= malloc(4096);
205 len
= strlen(hostname
);
206 *(char *)packet
= len
;
207 memcpy((char *)(packet
+ 1), hostname
, len
);
211 *(int *)(packet
+ len
) = s
;
215 memcpy((char *)(packet
+ len
), &session
[s
], sizeof(sessiont
));
216 len
+= sizeof(sessiont
);
218 cluster_send_message(config
->cluster_address
, vip_address
, C_SESSION
, packet
, len
);
224 int cluster_send_tunnel(int t
)
229 packet
= malloc(4096);
232 len
= strlen(hostname
);
233 *(char *)packet
= len
;
234 memcpy((char *)(packet
+ 1), hostname
, len
);
238 *(int *)(packet
+ len
) = t
;
242 memcpy((char *)(packet
+ len
), &tunnel
[t
], sizeof(tunnelt
));
243 len
+= sizeof(tunnelt
);
245 cluster_send_message(config
->cluster_address
, vip_address
, C_TUNNEL
, packet
, len
);
251 int cluster_send_goodbye()
256 packet
= malloc(4096);
258 log(2, 0, 0, 0, "Sending goodbye to cluster master\n");
260 len
= strlen(hostname
);
261 *(char *)packet
= len
;
262 memcpy((char *)(packet
+ 1), hostname
, len
);
265 cluster_send_message(config
->cluster_address
, vip_address
, C_GOODBYE
, packet
, len
);