Add connection tracking cutter
authorNeutron Soutmun <neo.neutron@gmail.com>
Mon, 18 Jun 2012 05:09:53 +0000 (12:09 +0700)
committerNeutron Soutmun <neo.neutron@gmail.com>
Mon, 18 Jun 2012 05:09:53 +0000 (12:09 +0700)
* configure.ac, src/Makefile.am, tools/Makefile.am:
  - Add connection tracking cutter.
* src/rh-task-connection.{h,c}:
  - Connection cut on start/stop session.
* tools/rahunas-conntrack.in:
  - Wrapper script. (requires conntrack tools from conntrack package)

configure.ac
src/Makefile.am
src/rh-task-conntrack.c [new file with mode: 0644]
src/rh-task-conntrack.h [new file with mode: 0644]
src/rh-task.c
tools/Makefile.am
tools/rahunas-conntrack.in [new file with mode: 0755]

index b8ae064..45d3fbc 100644 (file)
@@ -84,6 +84,7 @@ AC_CONFIG_FILES([
   tools/Makefile
   tools/rahunas-firewall
   tools/rahunas-bandwidth
+  tools/rahunas-conntrack
   tools/rahunas-weblogin-config-update
   netsnmp-module/Makefile
   netsnmp-module/scripts/rh-checkrad
index 465ae82..c0e8117 100644 (file)
@@ -17,6 +17,7 @@ AM_CFLAGS = \
   -DRAHUNAS_RUN_DIR=\"$(localstatedir)/run/\" \
   -DRAHUNAS_FIREWALL_WRAPPER=\"$(sbindir)/rahunas-firewall\" \
   -DRAHUNAS_BANDWIDTH_WRAPPER=\"$(sbindir)/rahunas-bandwidth\" \
+  -DRAHUNAS_CONNTRACK_WRAPPER=\"$(sbindir)/rahunas-conntrack\" \
   -D_GNU_SOURCE
 
 rahunasd_SOURCES = \
@@ -49,6 +50,8 @@ rahunasd_SOURCES = \
   rh-task-dbset.h \
   rh-task-bandwidth.c \
   rh-task-bandwidth.h \
+  rh-task-conntrack.c \
+  rh-task-conntrack.h \
   rh-task-serviceclass.c \
   rh-task-serviceclass.h \
   rh-radius.h \
diff --git a/src/rh-task-conntrack.c b/src/rh-task-conntrack.c
new file mode 100644 (file)
index 0000000..6f3f346
--- /dev/null
@@ -0,0 +1,180 @@
+/**
+ * RahuNAS task conntrack implementation
+ * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ * Date:   2012-06-17
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "rahunasd.h"
+#include "rh-task.h"
+#include "rh-utils.h"
+
+int conntrack_exec(RHVServer *vs, char *const args[])
+{
+  pid_t ws;
+  pid_t pid;
+  int status;
+  int exec_pipe[2];
+  char buffer[150];
+  char *endline = NULL;
+  int ret = 0;
+  int fd = 0;
+
+  memset(buffer, '\0', sizeof(buffer));
+
+  if (pipe(exec_pipe) == -1) {
+    logmsg(RH_LOG_ERROR, "Error: pipe()");
+    return -1;
+  }
+  DP("pipe0=%d,pipe1=%d", exec_pipe[0], exec_pipe[1]);
+
+  pid = vfork();
+  dup2(exec_pipe[1], STDOUT_FILENO);
+
+  if (pid == 0) {
+    // Child
+    execv(RAHUNAS_CONNTRACK_WRAPPER, args);
+  } else if (pid < 0) {
+    // Fork error
+    logmsg(RH_LOG_ERROR, "Error: vfork()");
+    ret = -1;
+  } else {
+    // Parent
+    ws = waitpid(pid, &status, 0);
+
+    DP("Connection Tracking: Return (%d)", WEXITSTATUS(status));
+
+    // Return message log
+    DP("Read message");
+    read(exec_pipe[0], buffer, sizeof(buffer));
+
+    if (buffer != NULL) {
+      DP("Got message: %s", buffer);
+      endline = strstr(buffer, "\n");
+      if (endline != NULL)
+        *endline = '\0';
+
+      if (vs != NULL) {
+        logmsg(RH_LOG_NORMAL, "[%s] Connection Tracking: %s",
+          vs->vserver_config->vserver_name, buffer);
+      }
+    }
+
+    if (WIFEXITED(status)) {
+      ret = WEXITSTATUS(status);
+    } else {
+      ret = -1;
+    }
+  }
+
+  if ((buffer != NULL) && (strncmp (buffer, "NOT COMPLETED", 13) == 0))
+    ret = -2;  // Not complete need to retry
+
+  close(exec_pipe[0]);
+  close(exec_pipe[1]);
+  return ret;
+}
+
+int conntrack_flush(RHVServer *vs, struct task_req *req)
+{
+  char *args[4];
+  char ip[16];
+
+  snprintf (ip, sizeof (ip), "%s", idtoip (vs->v_map, req->id));
+
+  DP("Connection Tracking: flush");
+
+  args[0] = RAHUNAS_CONNTRACK_WRAPPER;
+  args[1] = "cut";
+  args[2] = ip;
+  args[3] = (char *) 0;
+
+  return conntrack_exec(vs, args);
+}
+
+/* Start service task */
+static int startservice ()
+{
+  return 0;
+}
+
+/* Stop service task */
+static int stopservice  ()
+{
+  return 0;
+}
+
+/* Initialize */
+static void init (RHVServer *vs)
+{
+  /* Do nothing */
+}
+
+/* Cleanup */
+static void cleanup (RHVServer *vs)
+{
+  /* Do nothing */
+}
+
+/* Start session task */
+static int startsess (RHVServer *vs, struct task_req *req)
+{
+  return conntrack_flush (vs, req);
+}
+
+/* Stop session task */
+static int stopsess  (RHVServer *vs, struct task_req *req)
+{
+  return conntrack_flush (vs, req);
+}
+
+/* Commit start session task */
+static int commitstartsess (RHVServer *vs, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Commit stop session task */
+static int commitstopsess  (RHVServer *vs, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Rollback start session task */
+static int rollbackstartsess (RHVServer *vs, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+/* Rollback stop session task */
+static int rollbackstopsess  (RHVServer *vs, struct task_req *req)
+{
+  /* Do nothing or need to implement */
+}
+
+static struct task taskconntrack = {
+  .taskname = "CONNTRACK",
+  .taskprio = 21,
+  .init = &init,
+  .cleanup = &cleanup,
+  .startservice = &startservice,
+  .stopservice = &stopservice,
+  .startsess = &startsess,
+  .stopsess = &stopsess,
+  .commitstartsess = &commitstartsess,
+  .commitstopsess = &commitstopsess,
+  .rollbackstartsess = &rollbackstartsess,
+  .rollbackstopsess = &rollbackstopsess,
+};
+
+void rh_task_conntrack_reg(RHMainServer *ms) {
+  task_register(ms, &taskconntrack);
+}
diff --git a/src/rh-task-conntrack.h b/src/rh-task-conntrack.h
new file mode 100644 (file)
index 0000000..d0a2cf9
--- /dev/null
@@ -0,0 +1,13 @@
+/**
+ * RahuNAS task conntrack implementation
+ * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ * Date:   2012-06-17
+ */
+#ifndef __RH_TASK_CONNTRACK_H
+#define __RH_TASK_CONNTRACK_H
+
+#include "rh-server.h"
+
+extern void rh_task_conntrack_reg(RHMainServer *ms);
+
+#endif // __RH_TASK_CONNTRACK_H
index 90cfb15..a03d07e 100644 (file)
@@ -11,6 +11,7 @@
 #include "rh-task-ipset.h"
 #include "rh-task-dbset.h"
 #include "rh-task-bandwidth.h"
+#include "rh-task-conntrack.h"
 
 void task_register(RHMainServer *ms, struct task *task)
 {
@@ -61,6 +62,8 @@ void rh_task_register(RHMainServer *ms)
     if (ms->main_config->bandwidth_shape)
       rh_task_bandwidth_reg(ms);
 
+    rh_task_conntrack_reg(ms);
+
     rh_task_dbset_reg(ms);
     task_registered = 1;
   }
index 80ee191..9e12c88 100644 (file)
@@ -3,6 +3,7 @@ MAINTAINERCLEANFILES = Makefile.in
 dist_sbin_SCRIPTS = \
        rahunas-firewall \
        rahunas-bandwidth \
+       rahunas-conntrack \
        rahunas-weblogin-config-update
 
 bin_PROGRAMS = \
diff --git a/tools/rahunas-conntrack.in b/tools/rahunas-conntrack.in
new file mode 100755 (executable)
index 0000000..e73f859
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/sh
+# File: bandwidth.sh
+# Description: The bandwidth shaper wrapper script for RahuNAS
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:@prefix@/sbin:@prefix@/bin
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+
+CONNTRACK=/usr/sbin/conntrack
+
+MESSAGE=""
+MSG_NOT_COMPLETED="NOT COMPLETED"
+
+usage() {
+  echo "Usage: $1 cut client_ip"
+}
+
+N=$prefix/sbin/rahunas-conntrack
+
+case "$1" in
+  cut)
+    $CONNTRACK -D -s $2 > /dev/null 2>&1
+    $CONNTRACK -D -d $2 > /dev/null 2>&1
+    MESSAGE="$2 flushed"
+
+    echo $MESSAGE
+    ;;
+  *)
+    usage $N
+    exit 3
+    ;;
+esac
+
+exit 0