5b9371afdcbb69fa27ab521aaa7378f1c9fc5955
[rahunas] / src / rh-task-memset.c
1 /**
2  * RahuNAS task memset implementation 
3  * Author: Neutron Soutmun <neo.neutron@gmail.com>
4  * Date:   2008-09-07
5  */
6
7 #include <stdlib.h>
8 #include <syslog.h>
9 #include <time.h>
10 #include "rahunasd.h"
11 #include "rh-radius.h"
12 #include "rh-task.h"
13 #include "rh-ipset.h"
14
15 GList *member_get_node_by_id(struct vserver *vs, uint32_t id) 
16 {
17   GList *runner = g_list_first(vs->v_map->members);
18   struct rahunas_member *member = NULL;
19
20   while (runner != NULL) {
21     member = (struct rahunas_member *) runner->data;
22
23     if (member->id == id)
24       return runner;
25
26     runner = g_list_next(runner);
27   }
28
29   return NULL;
30 }
31
32 gint idcmp(struct rahunas_member *a, struct rahunas_member *b)
33 {
34   if (a != NULL && b != NULL)
35     return (a->id - b->id);
36
37   return -1;
38 }
39
40 /* Start service task */
41 static int startservice ()
42 {
43   /* Do nothing or need to implement */
44   return 0;
45 }
46
47 /* Stop service task */
48 static int stopservice  ()
49 {
50   /* Do nothing or need to implement */
51   return 0;
52 }
53
54 /* Initialize */
55 static void init (struct vserver *vs)
56 {
57   int size;
58
59   if (vs->vserver_config->init_flag == VS_RELOAD)
60     return;
61
62   logmsg(RH_LOG_NORMAL, "[%s] Task MEMSET initialize..",
63          vs->vserver_config->vserver_name);  
64
65   vs->v_map = (struct rahunas_map *)(rh_malloc(sizeof(struct rahunas_map)));
66   if (vs->v_map == NULL) {
67     logmsg(RH_LOG_ERROR, "[%s] Could not allocate memory...",
68            vs->vserver_config->vserver_name); 
69     exit(EXIT_FAILURE);
70   }
71
72   memset(vs->v_map, 0, sizeof(struct rahunas_map));
73
74   if (get_header_from_set(vs) < 0) {
75     syslog(LOG_ERR, "Could not fetch IPSET header");
76     exit(EXIT_FAILURE);
77   }
78 }
79
80 /* Cleanup */
81 static void cleanup (struct vserver *vs)
82 {
83   GList *runner = NULL;
84   GList *deleting = NULL;
85   struct rahunas_member *member = NULL;
86
87   if (vs->vserver_config->init_flag == VS_RELOAD)
88     return;
89
90   logmsg(RH_LOG_NORMAL, "[%s] Task MEMSET cleanup..",
91          vs->vserver_config->vserver_name);  
92
93   if (vs->v_map != NULL) {
94
95     runner = g_list_first(vs->v_map->members);
96
97     while (runner != NULL) {
98       member = (struct rahunas_member *) runner->data; 
99
100       DP("Cleanup IP: %s", idtoip(vs->v_map, member->id));
101
102       rh_free_member(member);
103       deleting = runner;
104       runner = g_list_next(runner);
105
106       vs->v_map->members = g_list_delete_link(vs->v_map->members, deleting);
107     }
108
109     g_list_free(vs->v_map->members);
110
111     rh_free(&(vs->v_map->members));
112     rh_free(&(vs->v_map));
113   }
114
115   return 0;
116 }
117
118 /* Start session task */
119 static int startsess (struct vserver *vs, struct task_req *req)
120 {
121   uint32_t id = req->id;
122   GList *member_node = NULL;
123   struct rahunas_member *member = NULL;
124
125   member_node = member_get_node_by_id(vs, id);
126
127   if (member_node == NULL) {
128     DP("Create new member");
129     member = (struct rahunas_member *)rh_malloc(sizeof(struct rahunas_member));
130     if (member == NULL)
131       return (-1);
132
133     memset(member, 0, sizeof(struct rahunas_member));
134
135     vs->v_map->members = 
136         g_list_insert_sorted(vs->v_map->members, member, idcmp);
137
138   } else {
139     DP("Member already exists");
140     member = (struct rahunas_member *)member_node->data;
141   }
142
143   member->id = id; 
144
145   if (member->username && member->username != termstring)
146     free(member->username);
147
148   if (member->session_id && member->username != termstring)
149     free(member->session_id);
150
151   if (member->serviceclass_name && member->serviceclass_name != termstring)
152     free(member->serviceclass_name);
153
154   if (member->mapping_ip && member->mapping_ip != termstring)
155     free(member->mapping_ip);
156
157   member->username   = strdup(req->username);
158   if (!member->username)
159     member->username = termstring;
160
161   member->session_id = strdup(req->session_id);
162   if (!member->session_id)
163     member->session_id = termstring;
164
165   member->serviceclass_name    = NULL;
166   member->serviceclass_description = termstring;
167   member->serviceclass_slot_id = 0;
168   member->mapping_ip = termstring;
169
170   if (req->session_start == 0) {
171     time(&(req->session_start));
172   } 
173
174   memcpy(&member->session_start, &req->session_start, sizeof(time_t));
175
176   memcpy(&member->mac_address, &req->mac_address, ETH_ALEN);
177
178   memcpy(&member->session_timeout, &req->session_timeout, 
179          sizeof(time_t));
180   member->bandwidth_max_down = req->bandwidth_max_down;
181   member->bandwidth_max_up = req->bandwidth_max_up;
182  
183   DP("Session-Timeout %d", req->session_timeout);
184   DP("Bandwidth - Down: %lu, Up: %lu", req->bandwidth_max_down, 
185        req->bandwidth_max_up);
186
187   logmsg(RH_LOG_NORMAL, "[%s] Session Start, User: %s, IP: %s, "
188                         "Session ID: %s, MAC: %s",
189                         vs->vserver_config->vserver_name,
190                         member->username, 
191                         idtoip(vs->v_map, id), 
192                         member->session_id,
193                         mac_tostring(member->mac_address)); 
194   return 0;
195 }
196
197 /* Stop session task */
198 static int stopsess  (struct vserver *vs, struct task_req *req)
199 {
200   uint32_t id = req->id;
201   GList *member_node = NULL;
202   struct rahunas_member *member = NULL;
203   char cause[16] = "";
204
205   member_node = member_get_node_by_id(vs, id);
206   if (member_node == NULL)
207     return (-1);
208
209   member = (struct rahunas_member *)member_node->data;
210
211   switch (req->req_opt) {
212     case RH_RADIUS_TERM_IDLE_TIMEOUT :
213       strncpy(cause, "idle timeout", sizeof (cause));
214       break;
215     case RH_RADIUS_TERM_SESSION_TIMEOUT :
216       strncpy(cause, "session timeout", sizeof (cause));
217       break;
218     case RH_RADIUS_TERM_USER_REQUEST :
219       strncpy(cause, "user request", sizeof (cause));
220       break;
221     case RH_RADIUS_TERM_NAS_REBOOT :
222       strncpy(cause, "nas reboot", sizeof (cause));
223       break;
224     case RH_RADIUS_TERM_ADMIN_RESET :
225       strncpy(cause, "admin reset", sizeof (cause));
226       break;
227   }
228   if (!member->username)
229     member->username = termstring;
230
231   if (!member->session_id)
232     member->session_id = termstring;
233
234   logmsg(RH_LOG_NORMAL, "[%s] Session Stop (%s), User: %s, IP: %s, "
235                         "Session ID: %s, MAC: %s",
236                         vs->vserver_config->vserver_name,
237                         cause,
238                         member->username, 
239                         idtoip(vs->v_map, id), 
240                         member->session_id,
241                         mac_tostring(member->mac_address)); 
242
243   rh_free_member(member);   
244
245   vs->v_map->members = g_list_delete_link(vs->v_map->members, member_node);
246
247   return 0;
248 }
249
250 /* Commit start session task */
251 static int commitstartsess (struct vserver *vs, struct task_req *req)
252 {
253   /* Do nothing or need to implement */
254 }
255
256 /* Commit stop session task */
257 static int commitstopsess  (struct vserver *vs, struct task_req *req)
258 {
259   /* Do nothing or need to implement */
260 }
261
262 /* Rollback start session task */
263 static int rollbackstartsess (struct vserver *vs, struct task_req *req)
264 {
265   /* Do nothing or need to implement */
266 }
267
268 /* Rollback stop session task */
269 static int rollbackstopsess  (struct vserver *vs, struct task_req *req)
270 {
271   /* Do nothing or need to implement */
272 }
273
274 static struct task task_memset = {
275   .taskname = "MEMSET",
276   .taskprio = 40,
277   .init = &init,
278   .cleanup = &cleanup,
279   .startservice = &startservice,
280   .stopservice = &stopservice,
281   .startsess = &startsess,
282   .stopsess = &stopsess,
283   .commitstartsess = &commitstartsess,
284   .commitstopsess = &commitstopsess,
285   .rollbackstartsess = &rollbackstartsess,
286   .rollbackstopsess = &rollbackstopsess,
287 };
288
289 void rh_task_memset_reg(struct main_server *ms) {
290   task_register(ms, &task_memset);
291 }