1 // L2TPNS Cluster Master
2 // $Id: cluster_slave.c,v 1.1 2003/12/16 07:07:39 fred_nerk Exp $
5 #include <netinet/in.h>
12 #include <sys/socket.h>
15 #include <sys/types.h>
16 #include <arpa/inet.h>
22 extern int cluster_sockfd
;
23 extern tunnelt
*tunnel
;
24 extern sessiont
*session
;
25 extern uint32_t cluster_address
;
26 extern char hostname
[1000];
28 extern ippoolt
*ip_address_pool
;
29 extern uint32_t vip_address
;
30 extern tunnelidt tunnelfree
;
31 extern sessionidt sessionfree
;
33 int handle_tunnel(char *buf
, int l
);
34 int handle_session(char *buf
, int l
);
35 int handle_hello_response(char *buf
, int l
);
37 int processcluster(char *buf
, int l
)
42 log_hex(4, "Cluster receive", buf
, l
);
43 if (!buf
|| l
<= sizeof(uint32_t)) return 0;
45 addr
= ntohl(*(uint32_t*)buf
);
46 buf
+= sizeof(uint32_t);
47 l
-= sizeof(uint32_t);
49 if (addr
!= vip_address
)
51 log(0, 0, 0, 0, "Received cluster message for VIP %s, which isn't ours\n", inet_toa(addr
));
54 mtype
= *buf
; buf
++; l
--;
60 case C_HELLO_RESPONSE
:
61 handle_hello_response(buf
, l
);
66 handle_tunnel(buf
, l
);
69 handle_session(buf
, l
);
77 int handle_tunnel(char *buf
, int l
)
82 log(1, 0, 0, t
, "Receiving tunnel %d from cluster master (%d bytes)\n", t
, l
);
83 buf
+= sizeof(int); l
-= sizeof(int);
87 log(0, 0, 0, t
, "Cluster master tried to send tunnel %d, which is bigger than MAXTUNNEL (%d)\n", t
, MAXTUNNEL
);
91 if (l
!= sizeof(tunnelt
))
93 log(1, 0, 0, t
, "Discarding bogus tunnel message (%d bytes instead of %d).\n", l
, sizeof(tunnelt
));
99 tunnel
[t
-1].next
= tunnel
[t
].next
;
104 tunnelfree
= tunnel
[t
].next
;
107 memcpy(&tunnel
[t
], buf
, l
);
108 log(3, 0, 0, t
, "Cluster master sent tunnel for %s\n", tunnel
[t
].hostname
);
110 tunnel
[t
].controlc
= 0;
111 tunnel
[t
].controls
= NULL
;
112 tunnel
[t
].controle
= NULL
;
116 int handle_session(char *buf
, int l
)
121 log(1, 0, s
, 0, "Receiving session %d from cluster master (%d bytes)\n", s
, l
);
122 buf
+= sizeof(int); l
-= sizeof(int);
126 log(0, 0, s
, 0, "Cluster master tried to send session %d, which is bigger than MAXSESSION (%d)\n", s
, MAXSESSION
);
130 if (l
!= sizeof(sessiont
))
132 log(1, 0, s
, 0, "Discarding short session message (%d bytes instead of %d).\n", l
, sizeof(sessiont
));
138 session
[s
-1].next
= session
[s
].next
;
141 if (sessionfree
== s
)
143 sessionfree
= session
[s
].next
;
146 memcpy(&session
[s
], buf
, l
);
148 session
[s
].throttle
= 0;
149 if (session
[s
].opened
)
151 log(2, 0, s
, session
[s
].tunnel
, "Cluster master sent active session for user %s\n", session
[s
].user
);
152 sessionsetup(session
[s
].tunnel
, s
, 0);
153 if (session
[s
].ip
&& session
[s
].ip
!= 0xFFFFFFFE)
156 for (x
= 0; x
< MAXIPPOOL
&& ip_address_pool
[x
].address
; x
++)
158 if (ip_address_pool
[x
].address
== session
[s
].ip
)
160 ip_address_pool
[x
].assigned
= 1;
169 int handle_hello_response(char *buf
, int l
)
171 int numtunnels
, numsessions
;
173 /* The cluster master has downed the address, so send another garp */
174 send_garp(vip_address
);
180 log(1, 0, 0, 0, "Cluster master sent invalid hello response: %d bytes instead of %d\n", l
, (4 * IL
));
183 numtunnels
= *(int *)(buf
+ IL
* 0);
184 numsessions
= *(int *)(buf
+ IL
* 1);
185 if (numtunnels
== 0 && numsessions
== 0)
187 log(2, 0, 0, 0, "Cluster master has no state information for us.\n");
190 log(2, 0, 0, 0, "The cluster master will send %d tunnels and %d sessions.\n", numtunnels
, numsessions
);
194 int cluster_send_session(int s
)
199 if (!cluster_sockfd
) return 1;
201 packet
= malloc(4096);
204 len
= strlen(hostname
);
205 *(char *)packet
= len
;
206 memcpy((char *)(packet
+ 1), hostname
, len
);
210 *(int *)(packet
+ len
) = s
;
214 memcpy((char *)(packet
+ len
), &session
[s
], sizeof(sessiont
));
215 len
+= sizeof(sessiont
);
217 cluster_send_message(cluster_address
, vip_address
, C_SESSION
, packet
, len
);
223 int cluster_send_tunnel(int t
)
228 packet
= malloc(4096);
231 len
= strlen(hostname
);
232 *(char *)packet
= len
;
233 memcpy((char *)(packet
+ 1), hostname
, len
);
237 *(int *)(packet
+ len
) = t
;
241 memcpy((char *)(packet
+ len
), &tunnel
[t
], sizeof(tunnelt
));
242 len
+= sizeof(tunnelt
);
244 cluster_send_message(cluster_address
, vip_address
, C_TUNNEL
, packet
, len
);