Add the tasks list concept
authorNeutron Soutmun <neo.neutron@gmail.com>
Fri, 12 Sep 2008 11:56:30 +0000 (18:56 +0700)
committerNeutron Soutmun <neo.neutron@gmail.com>
Sun, 2 Nov 2008 19:43:11 +0000 (02:43 +0700)
2008-09-12  Neutron Soutmun <neo.neutron@gmail.com>

* +src/rh-task-*.{h,c}:
- Add the tasks concept of the workers. eg. memset, ipset,
    dbset and etc.
  - Each tasks provide the function to handle each events,
eg. init, start and stop service, start and stop session.
* src/rahunas.{h,c}, src/rh-ipset.{h,c}, src/rh-utils.{h,c},
  src/rh-xmlrpc-server.c:
  Change respectively to new tasks concept and do code beautifier.
* +src/rh-config.h: Move the configuration definitions from rahunasd.h.
* src/Makefile.am: Change respectively to properly build the tasks concept.
* AUTHORS: Add Suriya Soutmun to the author team.

19 files changed:
AUTHORS
ChangeLog
src/Makefile.am
src/rahunasd.c
src/rahunasd.h
src/rh-config.h [new file with mode: 0644]
src/rh-ipset.c
src/rh-ipset.h
src/rh-task-dbset.c [new file with mode: 0644]
src/rh-task-dbset.h [new file with mode: 0644]
src/rh-task-ipset.c [new file with mode: 0644]
src/rh-task-ipset.h [new file with mode: 0644]
src/rh-task-memset.c [new file with mode: 0644]
src/rh-task-memset.h [new file with mode: 0644]
src/rh-task.c [new file with mode: 0644]
src/rh-task.h [new file with mode: 0644]
src/rh-utils.c
src/rh-utils.h
src/rh-xmlrpc-server.c

diff --git a/AUTHORS b/AUTHORS
index b51df76..d1520e7 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1 +1,2 @@
 Neutron Soutmun <neo.neutron@gmail.com>
+Suriya Soutmun <darksolar@gmail.com>
index 15a53db..1e60ca2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2008-09-12  Neutron Soutmun <neo.neutron@gmail.com>
+
+       * +src/rh-task-*.{h,c}: 
+               - Add the tasks concept of the workers. eg. memset, ipset,
+           dbset and etc. 
+         - Each tasks provide the function to handle each events, 
+                       eg. init, start and stop service, start and stop session.
+       * src/rahunas.{h,c}, src/rh-ipset.{h,c}, src/rh-utils.{h,c},
+         src/rh-xmlrpc-server.c: 
+         Change respectively to new tasks concept and do code beautifier. 
+       * +src/rh-config.h: Move the configuration definitions from rahunasd.h.
+       * src/Makefile.am: Change respectively to properly build the tasks concept.
+       * AUTHORS: Add Suriya Soutmun to the author team.
+
 2008-09-03  Neutron Soutmun <neo.neutron@gmail.com>
 
        * src/rahunasd.{h,c}: 
index faecf59..83118c9 100644 (file)
@@ -9,7 +9,10 @@ rahunasd_SOURCES = rahunasd.c \
        rh-xmlrpc-server.c \
        rh-xmlrpc-cmd.c \
   rh-ipset.c \
-       rh-utils.c
+       rh-utils.c \
+       rh-task.c \
+       rh-task-ipset.c \
+       rh-task-memset.c
 
 rahunasd_LDADD =  \
        $(top_builddir)/xmlrpc/libgnetxmlrpc.a \
index c7fa638..af22ed7 100644 (file)
@@ -14,7 +14,6 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <unistd.h>
-#include <time.h>
 #include <signal.h>
 #include <syslog.h>
 
 #include "rh-xmlrpc-cmd.h"
 #include "rh-ipset.h"
 #include "rh-utils.h"
+#include "rh-task.h"
 
 /* Abstract functions */
 int logmsg(int priority, const char *msg, ...); 
 int getline(int fd, char *buf, size_t size);
-int finish();
-int ipset_flush();
 
-struct rahunas_map* rh_init_map();
-int rh_init_members(struct rahunas_map *map);
-
-int walk_through_set (int (*callback)(void *));
 size_t expired_check(void *data);
-size_t nas_reboot(void *data);
 
 /* Declaration */
 struct rahunas_map *map = NULL;
@@ -162,7 +155,6 @@ void rh_sighandler(int sig)
     case SIGTERM:
     case SIGKILL:
       if (pid == 0) {
-        walk_through_set(&nas_reboot);
         rh_exit();
         exit(EXIT_SUCCESS);
       }
@@ -175,40 +167,6 @@ void rh_sighandler(int sig)
   }
 }
 
-int ipset_flush()
-{
-  syslog(LOG_NOTICE, "Flushing IPSET...");
-  set_flush(SET_NAME);
-}
-
-int finish()
-{
-  char *exitmsg = "Exit Gracefully";
-       struct rahunas_member *members = NULL;
-       int i;
-  int end;
-
-  if (map) {
-    if (map->members) {
-      members = map->members;
-      end = map->size;
-    } else {
-      end = 0;
-    }  
-
-         for (i=0; i < end; i++) {
-                         rh_free_member(&members[i]);
-               }
-
-               rh_free(&(map->members));
-               rh_free(&map);
-       }
-
-  rh_free(&rahunas_set);
-       syslog(LOG_INFO, exitmsg);
-  return 0;
-}
-
 int getline(int fd, char *buf, size_t size)
 {
   char cbuf;
@@ -232,37 +190,6 @@ int getline(int fd, char *buf, size_t size)
        return (current - buf);
 }
 
-struct rahunas_map* rh_init_map() {
-  struct rahunas_map *map = NULL;
-
-       map = (struct rahunas_map*)(rh_malloc(sizeof(struct rahunas_map)));
-
-  map->members = NULL;
-       map->size = 0;
-
-       return map;
-}
-
-int rh_init_members (struct rahunas_map* map)
-{
-       struct rahunas_member *members = NULL;
-       int size;
-
-  if (!map)
-         return (-1);
-       
-       size = map->size == 0 ? MAX_MEMBERS : map->size;
-
-       members = 
-    (struct rahunas_member*)(rh_malloc(sizeof(struct rahunas_member)*size));
-
-       memset(members, 0, sizeof(struct rahunas_member)*size);
-
-       map->members = members;
-
-       return 0;
-}
-
 gboolean polling(gpointer data) {
   struct rahunas_map *map = (struct rahunas_map *)data;
        DP("%s", "Start polling!");
@@ -277,9 +204,9 @@ size_t expired_check(void *data)
   size_t offset;
   struct ip_set_rahunas *table = NULL;
   struct rahunas_member *members = map->members;
+  struct task_req req;
   unsigned int i;
   char *ip = NULL;
-  ip_set_ip_t current_ip;
   int res  = 0;
 
   offset = sizeof(struct ip_set_list) + setlist->header_size;
@@ -288,171 +215,23 @@ size_t expired_check(void *data)
   DP("Map size %d", map->size);
  
   for (i = 0; i < map->size; i++) {
-    if (test_bit(IPSET_RAHUNAS_ISSET,
-          (void *)&table[i].flags)) {
-      if ((time(NULL) - table[i].timestamp) > IDLE_THRESHOLD) {
+    if (test_bit(IPSET_RAHUNAS_ISSET, (void *)&table[i].flags) && 
+          (time(NULL) - table[i].timestamp) > IDLE_THRESHOLD) {
         DP("Found IP: %s expired", idtoip(map, i));
-        current_ip = ntohl(map->first_ip) + i;
-        res = set_adtip_nb(rahunas_set, &current_ip, &table[i].ethernet,
-                           IP_SET_OP_DEL_IP);  
-        DP("set_adtip_nb() res=%d errno=%d", res, errno);
-
-        if (res == 0) {
-                           send_xmlrpc_stopacct(map, i, RH_RADIUS_TERM_IDLE_TIMEOUT);
-
-          if (!members[i].username)
-            members[i].username = termstring;
-
-          if (!members[i].session_id)
-            members[i].session_id = termstring;
-
-          logmsg(RH_LOG_NORMAL, "Session Idle-Timeout, User: %s, IP: %s, "
-                                "Session ID: %s, MAC: %s",
-                                members[i].username, 
-                                idtoip(map, i), 
-                                members[i].session_id,
-                                mac_tostring(members[i].mac_address)); 
-
-          rh_free_member(&members[i]);
-        }
-      } 
-    }
-  }
-}
-
-size_t nas_reboot(void *data)
-{
-  struct ip_set_list *setlist = (struct ip_set_list *) data;
-  struct set *set = set_list[setlist->index];
-  size_t offset;
-  struct ip_set_rahunas *table = NULL;
-  struct rahunas_member *members = map->members;
-  unsigned int i;
-  char *ip = NULL;
-  ip_set_ip_t current_ip;
-  int res  = 0;
-
-  offset = sizeof(struct ip_set_list) + setlist->header_size;
-  table = (struct ip_set_rahunas *)(data + offset);
-
-  DP("Map size %d", map->size);
-  for (i = 0; i < map->size; i++) {
-    if (test_bit(IPSET_RAHUNAS_ISSET, (void *)&table[i].flags)) {
-      DP("Found IP: %s in set, try logout", idtoip(map, i));
-      current_ip = ntohl(map->first_ip) + i;
-      res = set_adtip_nb(rahunas_set, &current_ip, &table[i].ethernet,
-                         IP_SET_OP_DEL_IP);  
-      DP("set_adtip_nb() res=%d errno=%d", res, errno);
-
-      if (res == 0) {
-                           send_xmlrpc_stopacct(map, i, RH_RADIUS_TERM_NAS_REBOOT);
-
-        if (!members[i].username)
-          members[i].username = termstring;
-
-        if (!members[i].session_id)
-          members[i].session_id = termstring;
-
-        logmsg(RH_LOG_NORMAL, "Session Stop (NAS Reboot), User: %s, IP: %s, "
-                              "Session ID: %s, MAC: %s",
-                              members[i].username, 
-                              idtoip(map, i), 
-                              members[i].session_id,
-                              mac_tostring(members[i].mac_address)); 
-
-        rh_free_member(&members[i]);
-      }
-    }
-  }
-}
-
-int get_header_from_set ()
-{
-  struct ip_set_req_rahunas_create *header = NULL;
-  void *data = NULL;
-  ip_set_id_t idx;
-  socklen_t size, req_size;
-  size_t offset;
-  int res = 0;
-       in_addr_t first_ip;
-       in_addr_t last_ip;
-
-  size = req_size = load_set_list(SET_NAME, &idx, 
-                                  IP_SET_OP_LIST_SIZE, CMD_LIST); 
-
-  DP("Get Set Size: %d", size);
-  
-  if (size) {
-    data = rh_malloc(size);
-    ((struct ip_set_req_list *) data)->op = IP_SET_OP_LIST;
-    ((struct ip_set_req_list *) data)->index = idx;
-    res = kernel_getfrom_handleerrno(data, &size);
-    DP("get_lists getsockopt() res=%d errno=%d", res, errno);
-
-    if (res != 0 || size != req_size) {
-      free(data);
-      return -EAGAIN;
-    }
-    size = 0;
-  }
-
-  offset = sizeof(struct ip_set_list);
-  header = (struct ip_set_req_rahunas_create *) (data + offset);
-
-  first_ip = htonl(header->from); 
-  last_ip = htonl(header->to); 
-  
-  memcpy(&map->first_ip, &first_ip, sizeof(in_addr_t));
-  memcpy(&map->last_ip, &last_ip, sizeof(in_addr_t));
-       map->size = ntohl(map->last_ip) - ntohl(map->first_ip) + 1;
-
-       logmsg(RH_LOG_NORMAL, "First IP: %s", ip_tostring(ntohl(map->first_ip)));
-       logmsg(RH_LOG_NORMAL, "Last  IP: %s", ip_tostring(ntohl(map->last_ip)));
-       logmsg(RH_LOG_NORMAL, "Set Size: %lu", map->size);
-
-  rh_free(&data);
-  return res;
-}
-
-int walk_through_set (int (*callback)(void *))
-{
-  void *data = NULL;
-  ip_set_id_t idx;
-  socklen_t size, req_size;
-  int res = 0;
-
-  size = req_size = load_set_list(SET_NAME, &idx, 
-                                  IP_SET_OP_LIST_SIZE, CMD_LIST); 
-
-  DP("Get Set Size: %d", size);
-  
-  if (size) {
-    data = rh_malloc(size);
-    ((struct ip_set_req_list *) data)->op = IP_SET_OP_LIST;
-    ((struct ip_set_req_list *) data)->index = idx;
-    res = kernel_getfrom_handleerrno(data, &size);
-    DP("get_lists getsockopt() res=%d errno=%d", res, errno);
-
-    if (res != 0 || size != req_size) {
-      free(data);
-      return -EAGAIN;
+        req.id = i;
+        memcpy(req.mac_address, &table[i].ethernet, ETH_ALEN);
+        req.req_opt = RH_RADIUS_TERM_IDLE_TIMEOUT;
+                         send_xmlrpc_stopacct(map, i, RH_RADIUS_TERM_IDLE_TIMEOUT);
+        res = rh_task_stopsess(map, &req);
     }
-    size = 0;
   }
-  
-  if (data != NULL)
-    (*callback)(data);
-
-  rh_free(&data);
-  return res;
 }
 
 void rh_exit()
 {
   syslog(LOG_ALERT, "Child Exiting ..");
-  ipset_flush();
-  finish();
+  rh_task_stopservice(map);
+  rh_task_cleanup();
   rh_closelog(DEFAULT_LOG);
 }
 
@@ -576,31 +355,21 @@ int main(int argc, char **argv)
 
   dup2(fd_log, STDERR_FILENO);
 
-  gnet_init();
-  main_loop = g_main_loop_new (NULL, FALSE);
-
   sprintf(version, "Starting %s - Version %s", PROGRAM, VERSION);
-
-  
        logmsg(RH_LOG_NORMAL, version);
   syslog(LOG_INFO, version);
 
-  rahunas_set = set_adt_get(SET_NAME);
-  DP("getsetname: %s", rahunas_set->name);
-  DP("getsetid: %d", rahunas_set->id);
-  DP("getsetindex: %d", rahunas_set->index);
+  rh_task_init();
 
-  map = rh_init_map();
-  get_header_from_set();
-  rh_init_members(map);
+  gnet_init();
+  main_loop = g_main_loop_new (NULL, FALSE);
 
   /* XML RPC Server */
        server = gnet_xmlrpc_server_new (addr, port);
 
        if (!server) {
     syslog(LOG_ERR, "Could not start XML-RPC server!");
-    ipset_flush();
-    finish(); 
+    rh_task_stopservice(map);
          exit (EXIT_FAILURE);
        }
 
@@ -621,6 +390,8 @@ int main(int argc, char **argv)
 
   g_timeout_add_seconds (POLLING, polling, map);
 
+  rh_task_startservice(map);
+
        g_main_loop_run(main_loop);
 
        exit(EXIT_SUCCESS);
index 1aec3f6..f228f9f 100644 (file)
@@ -7,33 +7,25 @@
 #ifndef __RAHUNASD_H
 #define __RAHUNASD_H
 
+
 #include <stdio.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <time.h>
 #include <linux/if_ether.h>
+#include <errno.h>
+
+#include "rh-config.h"
+#include "rh-utils.h"
 
 #define PROGRAM "RahuNASd"
 #define VERSION "0.1.1"
 #define MAX_MEMBERS 0x00FFFF
 
-/* Configuration */
-#define DEFAULT_LOG "/var/log/rahunas/rahunas.log"
-#define DEFAULT_PID "/var/run/rahunasd.pid"
-
-#ifdef RH_DEBUG
-#  define IDLE_THRESHOLD 30
-#  define POLLING 15 
-#else
-#  define IDLE_THRESHOLD 600
-#  define POLLING 60 
-#endif
-
-#define SET_NAME "rahunas_set"
-#define XMLSERVICE_HOST        "localhost"
-#define XMLSERVICE_PORT        8888
-#define XMLSERVICE_URL "/xmlrpc_service.php"
+extern struct rahunas_map *map;
+extern struct set *rahunas_set;
+extern const char *termstring; 
 
 enum RH_LOG {
   RH_LOG_DEBUG,
@@ -74,7 +66,7 @@ char *idtoip(struct rahunas_map *map, uint32_t id);
 
 void rh_free_member (struct rahunas_member *member);
 
-static char *timemsg()
+static const char *timemsg()
 {
   static char tmsg[32] = "";
   char tfmt[] = "%b %e %T";
diff --git a/src/rh-config.h b/src/rh-config.h
new file mode 100644 (file)
index 0000000..1bcbf3a
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * RahuNASd config file 
+ * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ * Date:   2008-08-07
+ */
+
+#ifndef __RH_CONFIG_H
+#define __RH_CONFIG_H
+
+/* Configuration */
+#define DEFAULT_LOG "/var/log/rahunas/rahunas.log"
+#define DEFAULT_PID "/var/run/rahunasd.pid"
+
+#ifdef RH_DEBUG
+#  define IDLE_THRESHOLD 30
+#  define POLLING 15 
+#else
+#  define IDLE_THRESHOLD 600
+#  define POLLING 60 
+#endif
+
+#define SET_NAME "rahunas_set"
+#define XMLSERVICE_HOST        "localhost"
+#define XMLSERVICE_PORT        8888
+#define XMLSERVICE_URL "/xmlrpc_service.php"
+
+#endif // __RH_CONFIG_H
index 60044b0..d68125c 100644 (file)
@@ -12,9 +12,6 @@
 #include "rh-ipset.h"
 #include "rh-utils.h"
 
-extern struct set **set_list;
-extern ip_set_id_t max_sets;
-
 int kernel_getsocket(void)
 {
   int sockfd = -1;
@@ -255,7 +252,6 @@ int set_adtip_nb(struct set *rahunas_set, ip_set_ip_t *adtip,
   return res;
 }
 
-
 void set_flush(const char *name)
 {
   struct ip_set_req_std req;
@@ -349,3 +345,84 @@ tryagain:
        
        return size;
 }
+
+int get_header_from_set (struct rahunas_map *map)
+{
+  struct ip_set_req_rahunas_create *header = NULL;
+  void *data = NULL;
+  ip_set_id_t idx;
+  socklen_t size, req_size;
+  size_t offset;
+  int res = 0;
+       in_addr_t first_ip;
+       in_addr_t last_ip;
+
+  size = req_size = load_set_list(SET_NAME, &idx, 
+                                  IP_SET_OP_LIST_SIZE, CMD_LIST); 
+
+  DP("Get Set Size: %d", size);
+  
+  if (size) {
+    data = rh_malloc(size);
+    ((struct ip_set_req_list *) data)->op = IP_SET_OP_LIST;
+    ((struct ip_set_req_list *) data)->index = idx;
+    res = kernel_getfrom_handleerrno(data, &size);
+    DP("get_lists getsockopt() res=%d errno=%d", res, errno);
+
+    if (res != 0 || size != req_size) {
+      free(data);
+      return -EAGAIN;
+    }
+    size = 0;
+  }
+
+  offset = sizeof(struct ip_set_list);
+  header = (struct ip_set_req_rahunas_create *) (data + offset);
+
+  first_ip = htonl(header->from); 
+  last_ip = htonl(header->to); 
+  
+  memcpy(&map->first_ip, &first_ip, sizeof(in_addr_t));
+  memcpy(&map->last_ip, &last_ip, sizeof(in_addr_t));
+       map->size = ntohl(map->last_ip) - ntohl(map->first_ip) + 1;
+
+       logmsg(RH_LOG_NORMAL, "First IP: %s", ip_tostring(ntohl(map->first_ip)));
+       logmsg(RH_LOG_NORMAL, "Last  IP: %s", ip_tostring(ntohl(map->last_ip)));
+       logmsg(RH_LOG_NORMAL, "Set Size: %lu", map->size);
+
+  rh_free(&data);
+  return res;
+}
+
+int walk_through_set (int (*callback)(void *))
+{
+  void *data = NULL;
+  ip_set_id_t idx;
+  socklen_t size, req_size;
+  int res = 0;
+
+  size = req_size = load_set_list(SET_NAME, &idx, 
+                                  IP_SET_OP_LIST_SIZE, CMD_LIST); 
+
+  DP("Get Set Size: %d", size);
+  
+  if (size) {
+    data = rh_malloc(size);
+    ((struct ip_set_req_list *) data)->op = IP_SET_OP_LIST;
+    ((struct ip_set_req_list *) data)->index = idx;
+    res = kernel_getfrom_handleerrno(data, &size);
+    DP("get_lists getsockopt() res=%d errno=%d", res, errno);
+
+    if (res != 0 || size != req_size) {
+      free(data);
+      return -EAGAIN;
+    }
+    size = 0;
+  }
+  
+  if (data != NULL)
+    (*callback)(data);
+
+  rh_free(&data);
+  return res;
+}
index c6f7388..301c277 100644 (file)
@@ -15,6 +15,9 @@
 #define GETSOCK_TRIES 5
 #define LIST_TRIES 5
 
+extern struct set **set_list;
+extern ip_set_id_t max_sets;
+
 /* The view of an ipset in userspace */
 struct set {
        char name[IP_SET_MAXNAMELEN];           /* Name of the set */
@@ -81,6 +84,10 @@ size_t load_set_list(const char name[IP_SET_MAXNAMELEN],
                            ip_set_id_t *idx,
                            unsigned op, unsigned cmd);
 
+int get_header_from_set (struct rahunas_map *map);
+
+int walk_through_set (int (*callback)(void *));
+
 void parse_ip(const char *str, ip_set_ip_t *ip);
 void parse_mac(const char *mac, unsigned char *ethernet);
 char *ip_tostring(ip_set_ip_t ip);
diff --git a/src/rh-task-dbset.c b/src/rh-task-dbset.c
new file mode 100644 (file)
index 0000000..906c1c4
--- /dev/null
@@ -0,0 +1,182 @@
+/**
+ * RahuNAS task dbset implementation 
+ * Author: Suriya  Soutmun <darksolar@gmail.com>
+ * Date:   2008-09-11
+ */
+
+#include <stdlib.h>
+#include <syslog.h>
+#include <time.h>
+#include "rahunasd.h"
+#include "rh-task.h"
+#include "rh-ipset.h"
+
+/* Initialize */
+static void init (void)
+{
+  struct rahunas_member *members = NULL;
+  int size;
+
+  logmsg(RH_LOG_NORMAL, "Task MEMSET init..");  
+  map = (struct rahunas_map*)(rh_malloc(sizeof(struct rahunas_map)));
+
+  map->members = NULL;
+  map->size = 0;
+
+  if (get_header_from_set(map) < 0) {
+    syslog(LOG_ERR, "Could not fetch IPSET header");
+    exit(EXIT_FAILURE);
+  }
+
+  size = map->size == 0 ? MAX_MEMBERS : map->size;
+
+       members = 
+    (struct rahunas_member*)(rh_malloc(sizeof(struct rahunas_member)*size));
+
+       memset(members, 0, sizeof(struct rahunas_member)*size);
+
+       map->members = members;
+}
+
+/* Cleanup */
+static void cleanup (void)
+{
+  struct rahunas_member *members = NULL;
+       int i;
+  int end;
+
+  if (map) {
+    if (map->members) {
+      members = map->members;
+      end = map->size;
+    } else {
+      end = 0;
+    }  
+
+         for (i=0; i < end; i++) {
+                         rh_free_member(&members[i]);
+               }
+
+               rh_free(&(map->members));
+               rh_free(&map);
+       }
+
+  logmsg(RH_LOG_NORMAL, "Task MEMSET cleanup..");  
+  return 0;
+}
+
+
+/* Start service task */
+static int startservice (struct rahunas_map *map)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Stop service task */
+static int stopservice  (struct rahunas_map *map)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Start session task */
+static int startsess (struct rahunas_map *map, struct task_req *req)
+{
+       struct rahunas_member *members = map->members;
+  uint32_t id = req->id;
+
+  members[id].flags = 1;
+  if (members[id].username && members[id].username != termstring)
+    free(members[id].username);
+
+  if (members[id].session_id && members[id].username != termstring)
+    free(members[id].session_id);
+
+  members[id].username   = strdup(req->username);
+  if (!members[id].username)
+    members[id].username = termstring;
+
+  members[id].session_id = strdup(req->session_id);
+  if (!members[id].session_id)
+    members[id].session_id = termstring;
+
+       time(&(members[id].session_start));
+  memcpy(&req->session_start, &members[id].session_start, sizeof(time_t));
+
+  memcpy(&members[id].mac_address, &(req->mac_address), ETH_ALEN);
+
+  logmsg(RH_LOG_NORMAL, "Session Start, User: %s, IP: %s, "
+                        "Session ID: %s, MAC: %s",
+                        members[id].username, 
+                        idtoip(map, id), 
+                        members[id].session_id,
+                        mac_tostring(members[id].mac_address)); 
+  return 0;
+}
+
+/* Stop session task */
+static int stopsess  (struct rahunas_map *map, struct task_req *req)
+{
+       struct rahunas_member *members = map->members;
+  uint32_t id = req->id;
+
+  if (!members[id].username)
+    members[id].username = termstring;
+
+  if (!members[id].session_id)
+    members[id].session_id = termstring;
+
+  logmsg(RH_LOG_NORMAL, "Session Stop, User: %s, IP: %s, "
+                        "Session ID: %s, MAC: %s",
+                        members[id].username, 
+                        idtoip(map, id), 
+                        members[id].session_id,
+                        mac_tostring(members[id].mac_address)); 
+
+  rh_free_member(&members[id]);   
+
+  return 0;
+}
+
+/* Commit start session task */
+static int commitstartsess (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Commit stop session task */
+static int commitstopsess  (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Rollback start session task */
+static int rollbackstartsess (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Rollback stop session task */
+static int rollbackstopsess  (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+static struct task task_memset = {
+  .taskname = "MEMSET",
+  .taskprio = 2,
+  .init = &init,
+  .cleanup = &cleanup,
+  .startservice = &startservice,
+  .stopservice = &stopservice,
+  .startsess = &startsess,
+  .stopsess = &stopsess,
+  .commitstartsess = &commitstartsess,
+  .commitstopsess = &commitstopsess,
+  .rollbackstartsess = &rollbackstartsess,
+  .rollbackstopsess = &rollbackstopsess,
+};
+
+void rh_task_memset_reg(void) {
+  task_register(&task_memset);
+}
diff --git a/src/rh-task-dbset.h b/src/rh-task-dbset.h
new file mode 100644 (file)
index 0000000..3063002
--- /dev/null
@@ -0,0 +1,12 @@
+/**
+ * RahuNAS task dbset implementation 
+ * Author: Suriya  Soutmun <darksoalr@gmail.com>
+ * Date:   2008-09-11
+ */
+#ifndef __RH_TASK_DBSET_H
+#define __RH_TASK_DBSET_H
+
+extern void rh_task_dbset_reg(void);
+
+#endif // __RH_TASK_MEMSET_H
+
diff --git a/src/rh-task-ipset.c b/src/rh-task-ipset.c
new file mode 100644 (file)
index 0000000..62ddf0a
--- /dev/null
@@ -0,0 +1,146 @@
+/**
+ * RahuNAS task memset implementation 
+ * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ *         Suriya Soutmun <darksolar@gmail.com>
+ * Date:   2008-09-07
+ */
+
+#include <syslog.h>
+
+#include "rahunasd.h"
+#include "rh-ipset.h"
+#include "rh-task.h"
+#include "rh-xmlrpc-cmd.h"
+
+size_t nas_stopservice(void *data)
+{
+  struct ip_set_list *setlist = (struct ip_set_list *) data;
+  struct set *set = set_list[setlist->index];
+  size_t offset;
+  struct ip_set_rahunas *table = NULL;
+  struct rahunas_member *members = map->members;
+  struct task_req req;
+  unsigned int i;
+  char *ip = NULL;
+  int res  = 0;
+
+  offset = sizeof(struct ip_set_list) + setlist->header_size;
+  table = (struct ip_set_rahunas *)(data + offset);
+
+  DP("Map size %d", map->size);
+  for (i = 0; i < map->size; i++) {
+    if (test_bit(IPSET_RAHUNAS_ISSET, (void *)&table[i].flags)) {
+      DP("Found IP: %s in set, try logout", idtoip(map, i));
+      req.id = i;
+      memcpy(req.mac_address, &table[i].ethernet, ETH_ALEN);
+      req.req_opt = RH_RADIUS_TERM_NAS_REBOOT;
+                       send_xmlrpc_stopacct(map, i, RH_RADIUS_TERM_NAS_REBOOT);
+      rh_task_stopsess(map, &req);
+    }
+  }
+}
+
+/* Initialize */
+static void init (void)
+{
+  logmsg(RH_LOG_NORMAL, "Task IPSET init..");  
+
+  rahunas_set = set_adt_get(SET_NAME);
+
+  DP("getsetname: %s", rahunas_set->name);
+  DP("getsetid: %d", rahunas_set->id);
+  DP("getsetindex: %d", rahunas_set->index);
+}
+
+/* Cleanup */
+static void cleanup (void)
+{
+  set_flush(SET_NAME);
+
+  rh_free(&rahunas_set);
+  logmsg(RH_LOG_NORMAL, "Task IPSET cleanup..");  
+}
+
+/* Start service task */
+static int startservice (struct rahunas_map *map)
+{
+  /* Ensure the set is empty */
+  set_flush(SET_NAME);
+}
+
+/* Stop service task */
+static int stopservice  (struct rahunas_map *map)
+{
+  walk_through_set(&nas_stopservice);
+
+  logmsg(RH_LOG_NORMAL, "Task IPSET stop..");  
+  return 0;
+}
+
+/* Start session task */
+static int startsess (struct rahunas_map *map, struct task_req *req)
+{
+  int res = 0;
+  ip_set_ip_t ip;
+  parse_ip(idtoip(map, req->id), &ip);
+
+  res = set_adtip_nb(rahunas_set, &ip, req->mac_address, IP_SET_OP_ADD_IP);
+
+  return res;
+}
+
+/* Stop session task */
+static int stopsess  (struct rahunas_map *map, struct task_req *req)
+{
+  int res = 0;
+  ip_set_ip_t ip;
+  parse_ip(idtoip(map, req->id), &ip);
+
+  res = set_adtip_nb(rahunas_set, &ip, req->mac_address, IP_SET_OP_DEL_IP);
+
+  return res;
+}
+
+/* Commit start session task */
+static int commitstartsess (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Commit stop session task */
+static int commitstopsess  (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Rollback start session task */
+static int rollbackstartsess (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Rollback stop session task */
+static int rollbackstopsess  (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+static struct task task_ipset = {
+  .taskname = "IPSET",
+  .taskprio = 1,
+  .init = &init,
+  .cleanup = &cleanup,
+  .startservice = &startservice,
+  .stopservice = &stopservice,
+  .startsess = &startsess,
+  .stopsess = &stopsess,
+  .commitstartsess = &commitstartsess,
+  .commitstopsess = &commitstopsess,
+  .rollbackstartsess = &rollbackstartsess,
+  .rollbackstopsess = &rollbackstopsess,
+};
+
+void rh_task_ipset_reg(void) {
+  task_register(&task_ipset);
+}
diff --git a/src/rh-task-ipset.h b/src/rh-task-ipset.h
new file mode 100644 (file)
index 0000000..d169021
--- /dev/null
@@ -0,0 +1,12 @@
+/**
+ * RahuNAS task memset implementation 
+ * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ * Date:   2008-09-07
+ */
+#ifndef __RH_TASK_MEMSET_H
+#define __RH_TASK_MEMSET_H
+
+extern void rh_task_ipset_reg(void);
+
+#endif // __RH_TASK_MEMSET_H
+
diff --git a/src/rh-task-memset.c b/src/rh-task-memset.c
new file mode 100644 (file)
index 0000000..0856919
--- /dev/null
@@ -0,0 +1,195 @@
+/**
+ * RahuNAS task memset implementation 
+ * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ * Date:   2008-09-07
+ */
+
+#include <stdlib.h>
+#include <syslog.h>
+#include <time.h>
+#include "rahunasd.h"
+#include "rh-radius.h"
+#include "rh-task.h"
+#include "rh-ipset.h"
+
+/* Initialize */
+static void init (void)
+{
+  struct rahunas_member *members = NULL;
+  int size;
+
+  logmsg(RH_LOG_NORMAL, "Task MEMSET init..");  
+  map = (struct rahunas_map*)(rh_malloc(sizeof(struct rahunas_map)));
+
+  map->members = NULL;
+  map->size = 0;
+
+  if (get_header_from_set(map) < 0) {
+    syslog(LOG_ERR, "Could not fetch IPSET header");
+    exit(EXIT_FAILURE);
+  }
+
+  size = map->size == 0 ? MAX_MEMBERS : map->size;
+
+       members = 
+    (struct rahunas_member*)(rh_malloc(sizeof(struct rahunas_member)*size));
+
+       memset(members, 0, sizeof(struct rahunas_member)*size);
+
+       map->members = members;
+}
+
+/* Cleanup */
+static void cleanup (void)
+{
+  struct rahunas_member *members = NULL;
+       int i;
+  int end;
+
+  if (map) {
+    if (map->members) {
+      members = map->members;
+      end = map->size;
+    } else {
+      end = 0;
+    }  
+
+         for (i=0; i < end; i++) {
+                         rh_free_member(&members[i]);
+               }
+
+               rh_free(&(map->members));
+               rh_free(&map);
+       }
+
+  logmsg(RH_LOG_NORMAL, "Task MEMSET cleanup..");  
+  return 0;
+}
+
+
+/* Start service task */
+static int startservice (struct rahunas_map *map)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Stop service task */
+static int stopservice  (struct rahunas_map *map)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Start session task */
+static int startsess (struct rahunas_map *map, struct task_req *req)
+{
+       struct rahunas_member *members = map->members;
+  uint32_t id = req->id;
+
+  members[id].flags = 1;
+  if (members[id].username && members[id].username != termstring)
+    free(members[id].username);
+
+  if (members[id].session_id && members[id].username != termstring)
+    free(members[id].session_id);
+
+  members[id].username   = strdup(req->username);
+  if (!members[id].username)
+    members[id].username = termstring;
+
+  members[id].session_id = strdup(req->session_id);
+  if (!members[id].session_id)
+    members[id].session_id = termstring;
+
+       time(&(members[id].session_start));
+  memcpy(&req->session_start, &members[id].session_start, sizeof(time_t));
+
+  memcpy(&members[id].mac_address, &(req->mac_address), ETH_ALEN);
+
+  logmsg(RH_LOG_NORMAL, "Session Start, User: %s, IP: %s, "
+                        "Session ID: %s, MAC: %s",
+                        members[id].username, 
+                        idtoip(map, id), 
+                        members[id].session_id,
+                        mac_tostring(members[id].mac_address)); 
+  return 0;
+}
+
+/* Stop session task */
+static int stopsess  (struct rahunas_map *map, struct task_req *req)
+{
+       struct rahunas_member *members = map->members;
+  uint32_t id = req->id;
+  char cause[16] = "";
+  switch (req->req_opt) {
+    case RH_RADIUS_TERM_IDLE_TIMEOUT :
+      strcpy(cause, "idle timeout");
+      break;
+    case RH_RADIUS_TERM_USER_REQUEST :
+      strcpy(cause, "user request");
+      break;
+    case RH_RADIUS_TERM_NAS_REBOOT :
+      strcpy(cause, "nas reboot");
+      break;
+  }
+  if (!members[id].username)
+    members[id].username = termstring;
+
+  if (!members[id].session_id)
+    members[id].session_id = termstring;
+
+  logmsg(RH_LOG_NORMAL, "Session Stop (%s), User: %s, IP: %s, "
+                        "Session ID: %s, MAC: %s",
+                        cause,
+                        members[id].username, 
+                        idtoip(map, id), 
+                        members[id].session_id,
+                        mac_tostring(members[id].mac_address)); 
+
+  rh_free_member(&members[id]);   
+
+  return 0;
+}
+
+/* Commit start session task */
+static int commitstartsess (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Commit stop session task */
+static int commitstopsess  (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Rollback start session task */
+static int rollbackstartsess (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Rollback stop session task */
+static int rollbackstopsess  (struct rahunas_map *map, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+static struct task task_memset = {
+  .taskname = "MEMSET",
+  .taskprio = 2,
+  .init = &init,
+  .cleanup = &cleanup,
+  .startservice = &startservice,
+  .stopservice = &stopservice,
+  .startsess = &startsess,
+  .stopsess = &stopsess,
+  .commitstartsess = &commitstartsess,
+  .commitstopsess = &commitstopsess,
+  .rollbackstartsess = &rollbackstartsess,
+  .rollbackstopsess = &rollbackstopsess,
+};
+
+void rh_task_memset_reg(void) {
+  task_register(&task_memset);
+}
diff --git a/src/rh-task-memset.h b/src/rh-task-memset.h
new file mode 100644 (file)
index 0000000..62c68e9
--- /dev/null
@@ -0,0 +1,12 @@
+/**
+ * RahuNAS task memset implementation 
+ * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ * Date:   2008-09-07
+ */
+#ifndef __RH_TASK_MEMSET_H
+#define __RH_TASK_MEMSET_H
+
+extern void rh_task_memset_reg(void);
+
+#endif // __RH_TASK_MEMSET_H
+
diff --git a/src/rh-task.c b/src/rh-task.c
new file mode 100644 (file)
index 0000000..ce4ea19
--- /dev/null
@@ -0,0 +1,186 @@
+/**
+ * RahuNAS task implementation
+ * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ * Date:   2008-09-07
+ */
+
+#include <syslog.h>
+#include "rh-task.h"
+#include "rh-task-memset.h"
+#include "rh-task-ipset.h"
+
+static struct task dummy;
+
+static struct task *task_find(const char *taskname)
+{
+  struct task *runner = get_task_list(); 
+  while(runner != NULL) {
+    if (strncmp(runner->taskname, taskname, RH_TASK_MAXNAMELEN) == 0)
+      return runner;
+    
+    runner = runner->next;
+  }
+
+  return NULL;
+}
+
+struct task *get_task_list ()
+{
+  if (task_list == NULL)
+    return NULL;
+  else
+    return task_list->next; /* start after dummy */
+}
+
+void task_register(struct task *task)
+{
+  struct task *chk, *prev = NULL;
+  struct task *runner = task_list;
+
+  if (task == NULL)
+     return;
+
+  DP("Registering Task: %s", task->taskname);
+
+  chk = task_find(task->taskname);
+
+  /* Already register */
+  if (chk != NULL) {
+    DP("Already registered");
+    return;
+  }
+  while (runner->next != NULL && (task->taskprio < runner->next->taskprio)) {
+    runner = runner->next;
+  }
+
+  task->next = runner->next;
+  runner->next = task;
+}
+
+static void rh_task_call_init (void)
+{
+  struct task *runner = get_task_list();
+  while(runner != NULL) {
+    (*runner->init)();
+    runner = runner->next;
+  }
+}
+
+void rh_task_init(void)
+{
+  strncpy(dummy.taskname, "DUMMY", 6);
+  dummy.taskprio = 999; /* ensure it always be head */
+  dummy.next = NULL;
+
+  task_list = &dummy;
+
+  /* Register all tasks */
+  rh_task_ipset_reg();
+  rh_task_memset_reg();
+
+  /* Call each init */
+  rh_task_call_init();
+}
+
+void rh_task_cleanup(void)
+{
+  struct task *runner = get_task_list();
+
+  DP("Task Cleanup");
+
+  if (runner == NULL)
+    return;
+
+  while (runner != NULL) {
+    (*runner->cleanup)();
+    runner = runner->next;
+  }
+}
+
+int  rh_task_startservice(struct rahunas_map *map)
+{
+  struct task *runner = get_task_list();
+
+  DP("Start service");
+
+  if (runner == NULL)
+    return 0;
+
+  while (runner != NULL) {
+    (*runner->startservice)(map);
+    runner = runner->next;
+  }
+  
+  logmsg(RH_LOG_NORMAL, "Service start");
+  return 0;
+}
+
+int  rh_task_stopservice(struct rahunas_map *map)
+{  
+  struct task *runner = get_task_list();
+
+  DP("Stop service");
+
+  if (runner == NULL)
+    return 0;
+
+  while (runner != NULL) {
+    (*runner->stopservice)(map);
+    runner = runner->next;
+  }
+}
+
+int  rh_task_startsess(struct rahunas_map *map, struct task_req *req)
+{
+  struct task *runner = get_task_list();
+
+  DP("Start session called");
+
+  if (runner == NULL)
+    return 0;
+
+  while (runner != NULL) {
+    if ((*runner->startsess)(map, req) < 0) {
+      DP("Failed, rollback");
+    }
+    runner = runner->next;
+  }
+  
+  return 0;
+}
+
+int  rh_task_stopsess(struct rahunas_map *map, struct task_req *req)
+{
+  struct task *runner = get_task_list();
+
+  DP("Stop session called");
+
+  if (runner == NULL)
+    return 0;
+
+  while (runner != NULL) {
+    if ((*runner->stopsess)(map, req) < 0) {
+      DP("Failed, rollback");
+    }
+    runner = runner->next;
+  }
+  
+  return 0;
+}
+
+int  rh_task_commitstartsess(struct rahunas_map *map, struct task_req *req)
+{
+}
+
+int  rh_task_commitstopsess(struct rahunas_map *map, struct task_req *req)
+{
+}
+
+int  rh_task_rollbackstartsess(struct rahunas_map *map, struct task_req *req)
+{
+}
+
+int  rh_task_rollbackstopsess(struct rahunas_map *map, struct task_req *req)
+{
+}
diff --git a/src/rh-task.h b/src/rh-task.h
new file mode 100644 (file)
index 0000000..e47eb2d
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * RahuNAS task header
+ * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ * Date:   2008-09-05
+ */
+#ifndef __RH_TASK_H
+#define __RH_TASK_H
+
+#include "rahunasd.h"
+
+#define RH_TASK_MAXNAMELEN 64
+
+struct task_req {
+  uint32_t id;
+  const char *username;
+  const char *session_id;
+  unsigned char mac_address[ETH_ALEN];
+       time_t session_start;
+  unsigned short req_opt;
+};
+
+struct task {
+  struct task *next;
+
+  char taskname[RH_TASK_MAXNAMELEN];
+  unsigned int taskprio;
+
+  /* Initialize */
+  void (*init) (void);
+
+  /* Cleanup */
+  void (*cleanup) (void);
+  
+  /* Start service task */
+  int (*startservice) (struct rahunas_map *map);
+
+  /* Stop service task */
+  int (*stopservice) (struct rahunas_map *map);
+
+  /* Start session task */
+  int (*startsess) (struct rahunas_map *map, struct task_req *req);
+
+  /* Stop session task */
+  int (*stopsess) (struct rahunas_map *map, struct task_req *req);
+
+  /* Commit start session task */
+  int (*commitstartsess) (struct rahunas_map *map, struct task_req *req);
+
+  /* Commit stop session task */
+  int (*commitstopsess) (struct rahunas_map *map, struct task_req *req);
+
+  /* Rollback start session task */
+  int (*rollbackstartsess) (struct rahunas_map *map, struct task_req *req);
+
+  /* Rollback stop session task */
+  int (*rollbackstopsess) (struct rahunas_map *map, struct task_req *req);
+};
+
+static struct task *task_list = NULL;
+
+extern void task_register(struct task *task);
+struct task *get_task_list ();
+
+void rh_task_init(void);
+void rh_task_cleanup(void);
+int  rh_task_startservice(struct rahunas_map *map);
+int  rh_task_stopservice(struct rahunas_map *map);
+int  rh_task_startsess(struct rahunas_map *map, struct task_req *req);
+int  rh_task_stopsess(struct rahunas_map *map, struct task_req *req);
+int  rh_task_commitstartsess(struct rahunas_map *map, struct task_req *req);
+int  rh_task_commitstopsess(struct rahunas_map *map, struct task_req *req);
+int  rh_task_rollbackstartsess(struct rahunas_map *map, struct task_req *req);
+int  rh_task_rollbackstopsess(struct rahunas_map *map, struct task_req *req);
+
+#endif // __RH_TASK_H
index e90d32a..2e26ede 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <syslog.h>
 #include <glib.h>
+#include <time.h>
 
 #include "rh-utils.h"
 
index feb8444..ad5cafe 100644 (file)
@@ -13,5 +13,4 @@ void rh_free(void **data);
 
 const char *rh_string_get_sep(const char *haystack, const char *sep, 
                               unsigned short idx);
-
 #endif // __RH_UTILS_H
index 30e1fb3..8238b62 100644 (file)
@@ -1,6 +1,7 @@
 /**
  * RahuNAS XML-RPC Server implementation
  * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ *         Suriya Soutmun <darksolar@gmail.com>
  * Date:   2008-08-07
  */
 
@@ -8,10 +9,11 @@
 #include <stdlib.h>
 #include "rahunasd.h"
 #include "rh-xmlrpc-server.h"
+#include "rh-radius.h"
 #include "rh-ipset.h"
 #include "rh-utils.h"
+#include "rh-task.h"
 
-extern struct set *rahunas_set;
 extern const char* termstring;
 
 int do_startsession(GNetXmlRpcServer *server,
@@ -23,12 +25,12 @@ int do_startsession(GNetXmlRpcServer *server,
   struct rahunas_map *map = (struct rahunas_map *)user_data;
        struct rahunas_member *members = NULL;
   unsigned char ethernet[ETH_ALEN] = {0,0,0,0,0,0};
+  struct task_req req;
        gchar *ip = NULL;
        gchar *username = NULL;
        gchar *session_id = NULL;
   gchar *mac_address = NULL;
        uint32_t id;
-  int res = 0;
 
        if (!map)
          goto out;
@@ -57,38 +59,13 @@ int do_startsession(GNetXmlRpcServer *server,
                goto cleanup;
        }
 
-  res = set_adtip(rahunas_set, ip, mac_address, IP_SET_OP_ADD_IP);
-  if (res == 0) {
-    members[id].flags = 1;
-    if (members[id].username && members[id].username != termstring)
-      free(members[id].username);
-
-    if (members[id].session_id && members[id].username != termstring)
-      free(members[id].session_id);
-
-    members[id].username   = strdup(username);
-    if (!members[id].username)
-      members[id].username = termstring;
-
-    members[id].session_id = strdup(session_id);
-    if (!members[id].session_id)
-      members[id].session_id = termstring;
-
-               time(&(members[id].session_start));
-
-    parse_mac(mac_address, &ethernet);
-    memcpy(&members[id].mac_address, &ethernet, ETH_ALEN);
+  req.id = id;
+  req.username = username;
+  req.session_id = session_id;
+  parse_mac(mac_address, &ethernet);
+  memcpy(req.mac_address, &ethernet, ETH_ALEN);
 
-    logmsg(RH_LOG_NORMAL, "Session Start, User: %s, IP: %s, "
-                          "Session ID: %s, MAC: %s",
-                          members[id].username, 
-                          idtoip(map, id), 
-                          members[id].session_id,
-                          mac_tostring(members[id].mac_address)); 
-
-  } else if (res == RH_IS_IN_SET) {
-    members[id].flags = 1;
-  }
+  rh_task_startsess(map, &req);
 
   *reply_string = g_strdup_printf("Greeting! Got: IP %s, User %s, ID %s", 
                                         ip, members[id].username, 
@@ -115,6 +92,7 @@ int do_stopsession(GNetXmlRpcServer *server,
 {
   struct rahunas_map *map = (struct rahunas_map *)user_data;
        struct rahunas_member *members;
+  struct task_req req;
        gchar *ip = NULL;
        gchar *mac_address = NULL;
        uint32_t   id;
@@ -147,27 +125,15 @@ int do_stopsession(GNetXmlRpcServer *server,
     goto cleanup;
        }
 
+  req.id = id;
+  parse_mac(mac_address, &ethernet);
+  memcpy(req.mac_address, &ethernet, ETH_ALEN);
+  req.req_opt = RH_RADIUS_TERM_USER_REQUEST;
+
        if (members[id].flags) {
-    parse_mac(mac_address, &ethernet);
     if (memcmp(&ethernet, &members[id].mac_address, ETH_ALEN) == 0) {
-      res = set_adtip(rahunas_set, idtoip(map, id), mac_address,
-                      IP_SET_OP_DEL_IP);
+      res = rh_task_stopsess(map, &req);
       if (res == 0) {
-        if (!members[id].username)
-          members[id].username = termstring;
-
-        if (!members[id].session_id)
-          members[id].session_id = termstring;
-
-        logmsg(RH_LOG_NORMAL, "Session Stop, User: %s, IP: %s, "
-                              "Session ID: %s, MAC: %s",
-                              members[id].username, 
-                              idtoip(map, id), 
-                              members[id].session_id,
-                              mac_tostring(members[id].mac_address)); 
-
-        rh_free_member(&members[id]);   
         *reply_string = g_strdup_printf("Client IP %s was removed!", 
                                                          idtoip(map, id));
       } else {