dea93eae33d852853c1563d464fd64a2b4bd1e0e
[rahunas] / src / rh-server.c
1 /**
2  * RahuNAS server
3  * Author: Neutron Soutmun <neo.neutron@gmail.com>
4  * Date:   2009-03-24
5  */
6 #include <stdio.h>
7 #include "rahunasd.h"
8 #include "rh-server.h"
9 #include "rh-utils.h"
10
11 struct vserver *vserver_exists(GList *vserver_list, int vserver_id, 
12                    const char *vserver_name)
13 {
14   GList *runner = g_list_first(vserver_list);
15   struct vserver *lvserver = NULL;
16
17   while (runner != NULL) {
18     lvserver = (struct vserver *)runner->data;
19    
20     if (lvserver->vserver_config->vserver_id == vserver_id)
21       return lvserver; 
22
23     if (strcmp(lvserver->vserver_config->vserver_name, vserver_name) == 0)
24       return lvserver;
25
26     runner = g_list_next(runner); 
27   } 
28   return NULL;
29 }
30
31 struct vserver *vserver_get_by_id(struct main_server *ms, int search_id)
32 {
33   GList *runner = g_list_first(ms->vserver_list);
34   struct vserver *lvserver = NULL;
35
36   while (runner != NULL) {
37     lvserver = (struct vserver *)runner->data;
38    
39     if (lvserver->vserver_config->vserver_id == search_id) {
40       return lvserver;
41     }
42
43     runner = g_list_next(runner); 
44   } 
45   return NULL;
46 }
47
48 int vserver_cleanup(struct vserver *vs)
49 {
50   if (vs == NULL)
51     return 0;
52
53   if (vs->vserver_config != NULL)
54     cleanup_vserver_config(vs->vserver_config);  
55
56   return 0;
57 }
58
59 int mainserver_cleanup(struct main_server *ms)
60 {
61   if (ms == NULL)
62     return 0;
63
64   if (ms->main_config != NULL)
65     cleanup_mainserver_config(ms->main_config);  
66
67   return 0;
68 }
69
70 int register_vserver(struct main_server *ms, const char *vserver_cfg_file)
71 {
72   GList *vserver_list = ms->vserver_list;
73   GList *chk = NULL;
74   GList *node = NULL;
75   FILE  *cfg_file = NULL;
76   
77   union rahunas_config *cfg_get = NULL;
78   struct rahunas_vserver_config *vserver_config = NULL;
79   struct vserver *new_vserver = NULL;
80   struct vserver *old_vserver = NULL;
81
82   union rahunas_config config = {
83     .rh_vserver.vserver_name = NULL,
84     .rh_vserver.vserver_id = VSERVER_ID,
85     .rh_vserver.init_flag = VS_INIT,
86     .rh_vserver.dev_external = NULL,
87     .rh_vserver.dev_internal = NULL,
88     .rh_vserver.vlan = NULL,
89     .rh_vserver.vlan_raw_dev_external = NULL,
90     .rh_vserver.vlan_raw_dev_internal = NULL,
91     .rh_vserver.bridge = NULL,
92     .rh_vserver.masquerade = NULL,
93     .rh_vserver.ignore_mac = NULL,
94     .rh_vserver.vserver_ip = NULL, 
95     .rh_vserver.vserver_fqdn = NULL,
96     .rh_vserver.vserver_ports_allow = NULL,
97     .rh_vserver.vserver_ports_intercept = NULL,
98     .rh_vserver.clients = NULL,
99     .rh_vserver.excluded = NULL,
100     .rh_vserver.idle_timeout = IDLE_TIMEOUT,
101     .rh_vserver.dns = NULL,
102     .rh_vserver.ssh = NULL,
103     .rh_vserver.proxy = NULL,
104     .rh_vserver.proxy_host = NULL,
105     .rh_vserver.proxy_port = NULL,
106     .rh_vserver.bittorrent = NULL,
107     .rh_vserver.bittorrent_allow = NULL,
108     .rh_vserver.radius_host = NULL,
109     .rh_vserver.radius_secret = NULL,
110     .rh_vserver.radius_encrypt = NULL,
111     .rh_vserver.radius_auth_port = NULL,
112     .rh_vserver.radius_account_port = NULL,
113     .rh_vserver.nas_identifier = NULL,
114     .rh_vserver.nas_port = NULL,
115     .rh_vserver.nas_login_title = NULL,
116     .rh_vserver.nas_default_redirect = NULL,
117     .rh_vserver.nas_default_language = NULL,
118     .rh_vserver.nas_weblogin_template = NULL,
119   };
120
121   cfg_file = fopen(vserver_cfg_file, "r");
122   if (cfg_file == NULL)
123     return -1;
124
125   if (get_config(vserver_cfg_file, &config) == 0) {
126     old_vserver = vserver_exists(vserver_list, config.rh_vserver.vserver_id, 
127                     config.rh_vserver.vserver_name);
128
129     if (old_vserver != NULL) {
130       if (old_vserver->dummy_config != NULL) {
131         DP("Cleanup old dummy config");
132         rh_free(&old_vserver->dummy_config);
133       }
134
135       old_vserver->dummy_config = 
136         (struct rahunas_vserver_config *) rh_malloc(sizeof(struct rahunas_vserver_config));
137
138       if (old_vserver->dummy_config == NULL)
139         return -1;
140
141       memset(old_vserver->dummy_config, 0, 
142         sizeof(struct rahunas_vserver_config));
143       memcpy(old_vserver->dummy_config, &config, 
144         sizeof(struct rahunas_vserver_config));
145
146       if (strncmp(config.rh_vserver.vserver_name, 
147             old_vserver->vserver_config->vserver_name, 32) != 0 || 
148           strncmp(config.rh_vserver.clients, 
149             old_vserver->vserver_config->clients, 18) != 0) {
150         old_vserver->vserver_config->init_flag = VS_RESET;
151       } else {
152         old_vserver->vserver_config->init_flag = VS_RELOAD;  
153       }
154       return 1;
155     }
156   } else {
157     return -1;
158   }
159
160   vserver_config = (struct rahunas_vserver_config *) rh_malloc(sizeof(struct rahunas_vserver_config));
161
162   if (vserver_config == NULL)
163     return -1;
164
165   memset(vserver_config, 0, sizeof(struct rahunas_vserver_config));
166
167   memcpy(vserver_config, &config, sizeof(struct rahunas_vserver_config));
168
169   new_vserver = (struct vserver *) rh_malloc(sizeof(struct vserver));
170
171   if (new_vserver == NULL)
172     return -1;
173
174   memset(new_vserver, 0, sizeof(struct vserver));
175
176   new_vserver->vserver_config = vserver_config;
177
178   new_vserver->vserver_config->init_flag = VS_INIT;
179   ms->vserver_list = g_list_append(ms->vserver_list, new_vserver);
180   return 0; 
181 }
182
183 int unregister_vserver(struct main_server *ms, int vserver_id)
184 {
185   GList *vserver_list = ms->vserver_list;
186   GList *runner = g_list_first(vserver_list);
187   struct vserver *lvserver = NULL;
188
189   while (runner != NULL) {
190     lvserver = (struct vserver *)runner->data;
191     if (lvserver->vserver_config->vserver_id == vserver_id) {
192       vserver_cleanup(lvserver);
193
194       ms->vserver_list = g_list_delete_link(ms->vserver_list, runner);
195       break;
196     } else {
197       runner = g_list_next(runner);
198     }
199   }
200   return 0;
201 }
202
203 int unregister_vserver_all(struct main_server *ms)
204 {
205   GList *vserver_list = ms->vserver_list;
206   GList *runner = g_list_first(vserver_list);
207   GList *deleting = NULL;
208   struct vserver *lvserver = NULL;
209
210   while (runner != NULL) {
211     lvserver = (struct vserver *)runner->data;
212     vserver_cleanup(lvserver);
213     deleting = runner;
214     runner = g_list_next(runner);
215
216     cleanup_vserver_config(lvserver->vserver_config);
217     ms->vserver_list = g_list_delete_link(ms->vserver_list, deleting);
218   }
219   
220   return 0;
221 }
222
223 int walk_through_vserver(int (*callback)(void *, void *), struct main_server *ms)
224 {
225   GList *vserver_list = ms->vserver_list;
226   GList *runner = g_list_first(vserver_list);
227   struct vserver *vs = NULL;
228
229   while (runner != NULL) {
230     vs = (struct vserver *)runner->data;
231
232     (*callback)(ms, vs);
233
234     runner = g_list_next(runner); 
235   } 
236
237   return 0;
238 }
239
240 void vserver_init_done(struct main_server *ms, struct vserver *vs)
241 {
242   if (vs != NULL) {
243     vs->vserver_config->init_flag = VS_DONE;
244     DP("Virtual Sever (%s) - Configured", vs->vserver_config->vserver_name);
245   }
246 }
247
248 void vserver_reload(struct main_server *ms, struct vserver *vs)
249 {
250   if (vs->vserver_config->init_flag == VS_DONE) {
251     // Indicate the unused virtual server
252     vs->vserver_config->init_flag = VS_NONE;
253     return;
254   }
255
256   while (vs->vserver_config->init_flag != VS_DONE) {
257     if (vs->vserver_config->init_flag == VS_INIT) {
258       logmsg(RH_LOG_NORMAL, "[%s] - Config init",
259              vs->vserver_config->vserver_name);
260
261       rh_task_init(ms, vs); 
262       vs->vserver_config->init_flag = VS_DONE;
263     } else if (vs->vserver_config->init_flag == VS_RELOAD) {
264       logmsg(RH_LOG_NORMAL, "[%s] - Config reload",
265              vs->vserver_config->vserver_name);
266
267       rh_task_cleanup(ms, vs);
268
269       if (vs->dummy_config != NULL) {
270         cleanup_vserver_config(vs->vserver_config);
271         memcpy(vs->vserver_config, vs->dummy_config, 
272           sizeof(struct rahunas_vserver_config));
273       }
274
275       vs->vserver_config->init_flag = VS_RELOAD;
276       rh_task_init(ms, vs); 
277       vs->vserver_config->init_flag = VS_DONE;
278     } else if (vs->vserver_config->init_flag == VS_RESET) {
279       logmsg(RH_LOG_NORMAL, "[%s] - Config reset",
280              vs->vserver_config->vserver_name);
281
282       rh_task_cleanup(ms, vs);
283
284       if (vs->dummy_config != NULL) {
285         cleanup_vserver_config(vs->vserver_config);
286         memcpy(vs->vserver_config, vs->dummy_config, 
287           sizeof(struct rahunas_vserver_config));
288         rh_free(&vs->dummy_config);
289       }
290
291       vs->vserver_config->init_flag = VS_INIT;
292     } else {
293       /* Prevent infinite loop */
294       vs->vserver_config->init_flag = VS_DONE;
295     }
296   } 
297 }
298
299
300 void vserver_unused_cleanup(struct main_server *ms)
301 {
302   GList *vserver_list = ms->vserver_list;
303   GList *runner = g_list_first(vserver_list);
304   struct vserver *lvserver = NULL;
305
306   while (runner != NULL) {
307     lvserver = (struct vserver *)runner->data;
308     if (lvserver->vserver_config->init_flag == VS_NONE) {
309       logmsg(RH_LOG_NORMAL, "[%s] - Config removed",
310              lvserver->vserver_config->vserver_name);
311       rh_task_cleanup(ms, lvserver);
312       unregister_vserver(ms, lvserver->vserver_config->vserver_id);
313
314       // Set runner to the first of list due to unregister may delete head
315       runner = g_list_first(ms->vserver_list);
316     } else {
317       runner = g_list_next(runner);
318     }
319   }
320   
321   return 0;
322 }