Add new iptables handle task
[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   logmsg(RH_LOG_NORMAL, "[%s] Task MEMSET initialize..",
60          vs->vserver_config->vserver_name);  
61
62   vs->v_map = (struct rahunas_map *)(rh_malloc(sizeof(struct rahunas_map)));
63   if (vs->v_map == NULL) {
64     logmsg(RH_LOG_ERROR, "[%s] Could not allocate memory...",
65            vs->vserver_config->vserver_name); 
66     exit(EXIT_FAILURE);
67   }
68
69   memset(vs->v_map, 0, sizeof(struct rahunas_map));
70
71   if (get_header_from_set(vs) < 0) {
72     syslog(LOG_ERR, "Could not fetch IPSET header");
73     exit(EXIT_FAILURE);
74   }
75 }
76
77 /* Cleanup */
78 static void cleanup (struct vserver *vs)
79 {
80   GList *runner = NULL;
81   GList *deleting = NULL;
82   struct rahunas_member *member = NULL;
83
84   logmsg(RH_LOG_NORMAL, "[%s] Task MEMSET cleanup..",
85          vs->vserver_config->vserver_name);  
86
87   if (vs->v_map != NULL) {
88
89     runner = g_list_first(vs->v_map->members);
90
91     while (runner != NULL) {
92       member = (struct rahunas_member *) runner->data; 
93
94       DP("Cleanup IP: %s", idtoip(vs->v_map, member->id));
95
96       rh_free_member(member);
97       deleting = runner;
98       runner = g_list_next(runner);
99
100       vs->v_map->members = g_list_delete_link(vs->v_map->members, deleting);
101     }
102
103     g_list_free(vs->v_map->members);
104
105     rh_free(&(vs->v_map->members));
106     rh_free(&(vs->v_map));
107   }
108
109   return 0;
110 }
111
112 /* Start session task */
113 static int startsess (struct vserver *vs, struct task_req *req)
114 {
115   uint32_t id = req->id;
116   GList *member_node = NULL;
117   struct rahunas_member *member = NULL;
118
119   member_node = member_get_node_by_id(vs, id);
120
121   if (member_node == NULL) {
122     DP("Create new member");
123     member = (struct rahunas_member *)rh_malloc(sizeof(struct rahunas_member));
124     if (member == NULL)
125       return (-1);
126
127     memset(member, 0, sizeof(struct rahunas_member));
128
129     vs->v_map->members = 
130         g_list_insert_sorted(vs->v_map->members, member, idcmp);
131
132   } else {
133     DP("Member already exists");
134     member = (struct rahunas_member *)member_node->data;
135   }
136
137   member->id = id; 
138
139   if (member->username && member->username != termstring)
140     free(member->username);
141
142   if (member->session_id && member->username != termstring)
143     free(member->session_id);
144
145   member->username   = strdup(req->username);
146   if (!member->username)
147     member->username = termstring;
148
149   member->session_id = strdup(req->session_id);
150   if (!member->session_id)
151     member->session_id = termstring;
152
153   if (req->session_start == 0) {
154     time(&(req->session_start));
155   } 
156
157   memcpy(&member->session_start, &req->session_start, sizeof(time_t));
158
159   memcpy(&member->mac_address, &req->mac_address, ETH_ALEN);
160
161   memcpy(&member->session_timeout, &req->session_timeout, 
162          sizeof(time_t));
163   member->bandwidth_max_down = req->bandwidth_max_down;
164   member->bandwidth_max_up = req->bandwidth_max_up;
165  
166   DP("Session-Timeout %d", req->session_timeout);
167   DP("Bandwidth - Down: %lu, Up: %lu", req->bandwidth_max_down, 
168        req->bandwidth_max_up);
169
170   logmsg(RH_LOG_NORMAL, "[%s] Session Start, User: %s, IP: %s, "
171                         "Session ID: %s, MAC: %s",
172                         vs->vserver_config->vserver_name,
173                         member->username, 
174                         idtoip(vs->v_map, id), 
175                         member->session_id,
176                         mac_tostring(member->mac_address)); 
177   return 0;
178 }
179
180 /* Stop session task */
181 static int stopsess  (struct vserver *vs, struct task_req *req)
182 {
183   uint32_t id = req->id;
184   GList *member_node = NULL;
185   struct rahunas_member *member = NULL;
186   char cause[16] = "";
187
188   member_node = member_get_node_by_id(vs, id);
189   if (member_node == NULL)
190     return (-1);
191
192   member = (struct rahunas_member *)member_node->data;
193
194   switch (req->req_opt) {
195     case RH_RADIUS_TERM_IDLE_TIMEOUT :
196       strcpy(cause, "idle timeout");
197       break;
198     case RH_RADIUS_TERM_SESSION_TIMEOUT :
199       strcpy(cause, "session timeout");
200       break;
201     case RH_RADIUS_TERM_USER_REQUEST :
202       strcpy(cause, "user request");
203       break;
204     case RH_RADIUS_TERM_NAS_REBOOT :
205       strcpy(cause, "nas reboot");
206       break;
207     case RH_RADIUS_TERM_ADMIN_RESET :
208       strcpy(cause, "admin reset");
209       break;
210   }
211   if (!member->username)
212     member->username = termstring;
213
214   if (!member->session_id)
215     member->session_id = termstring;
216
217   logmsg(RH_LOG_NORMAL, "[%s] Session Stop (%s), User: %s, IP: %s, "
218                         "Session ID: %s, MAC: %s",
219                         vs->vserver_config->vserver_name,
220                         cause,
221                         member->username, 
222                         idtoip(vs->v_map, id), 
223                         member->session_id,
224                         mac_tostring(member->mac_address)); 
225
226   rh_free_member(member);   
227
228   vs->v_map->members = g_list_delete_link(vs->v_map->members, member_node);
229
230   return 0;
231 }
232
233 /* Commit start session task */
234 static int commitstartsess (struct vserver *vs, struct task_req *req)
235 {
236   /* Do nothing or need to implement */
237 }
238
239 /* Commit stop session task */
240 static int commitstopsess  (struct vserver *vs, struct task_req *req)
241 {
242   /* Do nothing or need to implement */
243 }
244
245 /* Rollback start session task */
246 static int rollbackstartsess (struct vserver *vs, struct task_req *req)
247 {
248   /* Do nothing or need to implement */
249 }
250
251 /* Rollback stop session task */
252 static int rollbackstopsess  (struct vserver *vs, struct task_req *req)
253 {
254   /* Do nothing or need to implement */
255 }
256
257 static struct task task_memset = {
258   .taskname = "MEMSET",
259   .taskprio = 40,
260   .init = &init,
261   .cleanup = &cleanup,
262   .startservice = &startservice,
263   .stopservice = &stopservice,
264   .startsess = &startsess,
265   .stopsess = &stopsess,
266   .commitstartsess = &commitstartsess,
267   .commitstopsess = &commitstopsess,
268   .rollbackstartsess = &rollbackstartsess,
269   .rollbackstopsess = &rollbackstopsess,
270 };
271
272 void rh_task_memset_reg(struct main_server *ms) {
273   task_register(ms, &task_memset);
274 }