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