Monitoring system wide IPv4 and IPv6 data usage. 96/139796/1
authorNishant Chaprana <n.chaprana@samsung.com>
Thu, 20 Jul 2017 10:53:51 +0000 (16:23 +0530)
committerNishant Chaprana <n.chaprana@samsung.com>
Thu, 20 Jul 2017 10:53:51 +0000 (16:23 +0530)
Change-Id: I66e8b7af58f7e4fc79b4cbf94581738218726311
Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
12 files changed:
include/stc-manager-util.h
include/stc-manager.h
packaging/stc-manager.spec
src/database/tables/table-statistics.c
src/helper/helper-cgroup.c
src/helper/helper-cgroup.h
src/helper/helper-net-cls.c
src/helper/helper-nfacct-rule.c
src/helper/helper-nfacct-rule.h
src/helper/helper-restriction.c [deleted file]
src/helper/helper-restriction.h [deleted file]
src/monitor/stc-monitor.c

index 7a19fcb..d5ee410 100755 (executable)
@@ -337,17 +337,15 @@ static inline bool strstart_with(const char *str, const char *with)
  */
 enum stc_reserved_classid {
        STC_UNKNOWN_CLASSID,
-       STC_ALL_APP_CLASSID,            /**< kernel expects 1 for
-                                         handling restriction for all
-                                         applications  */
-       STC_TETHERING_APP_CLASSID,      /**< it uses in user space logic
-                                         for counting tethering traffic */
-       STC_FOREGROUND_APP_CLASSID,     /* it will used for special cgroup,
-                                          blocked cgroup */
-       STC_BACKGROUND_APP_CLASSID,
-       STC_TOTAL_DATACALL_CLASSID,
-       STC_TOTAL_WIFI_CLASSID,
+       STC_ALL_APP_CLASSID,            /**< kernel expects 1 for handling restriction for all applications */
+       STC_TETHERING_APP_CLASSID,      /**< it uses in user space logic for counting tethering traffic */
+       STC_FOREGROUND_APP_CLASSID,     /**< it will used for special cgroup, blocked cgroup */
+       STC_BACKGROUND_APP_CLASSID,     /**< background data monitoring */
+       STC_TOTAL_DATACALL_CLASSID,     /**< Cellular data monitoring */
+       STC_TOTAL_WIFI_CLASSID,         /**< Wi-Fi data monitoring */
        STC_TOTAL_BLUETOOTH_CLASSID,
+       STC_TOTAL_IPV4_CLASSID,         /**< IPV4 data monitoring */
+       STC_TOTAL_IPV6_CLASSID,         /**< IPV6 data monitoring */
        STC_NETWORK_RESTRICTION_APP_CLASSID,
        STC_RESERVED_CLASSID_MAX,
 };
index c82c3af..160da59 100755 (executable)
@@ -28,6 +28,8 @@
 #define STC_TOTAL_DATACALL "TOTAL_DATACALL"
 #define STC_TOTAL_WIFI "TOTAL_WIFI"
 #define STC_TOTAL_BLUETOOTH "TOTAL_BLUETOOTH"
+#define STC_TOTAL_IPV4 "TOTAL_IPV4"
+#define STC_TOTAL_IPV6 "TOTAL_IPV6"
 
 typedef enum {
        STC_CANCEL = 0,    /**< cancel */
@@ -78,6 +80,8 @@ typedef enum {
        STC_IFACE_WIFI,       /**< wifi data */
        STC_IFACE_WIRED,      /**< wired interface */
        STC_IFACE_BLUETOOTH,  /**< bluetooth interface */
+       STC_IFACE_IPV4,       /**< ipv4 interface */
+       STC_IFACE_IPV6,       /**< ipv6 interface */
        STC_IFACE_ALL,        /**< enumerate all network interface types */
        STC_IFACE_LAST_ELEM
 } stc_iface_type_e;
index 8f96ff2..4668ee5 100644 (file)
@@ -1,6 +1,6 @@
 Name:       stc-manager
 Summary:    STC(Smart Traffic Control) manager
-Version:    0.0.25
+Version:    0.0.26
 Release:    0
 Group:      Network & Connectivity/Other
 License:    Apache-2.0
index d28ec86..0f5db95 100755 (executable)
        "ifname, imsi, ground from statistics " \
        " where (time_stamp between ? and ?) and binpath != 'TOTAL_DATACALL' " \
        "and binpath != 'TOTAL_WIFI' and binpath != 'TOTAL_BLUETOOTH' " \
+       "and binpath != 'TOTAL_IPV4' and binpath != 'TOTAL_IPV6' " \
        "group by iftype, ifname, imsi, hw_net_protocol_type, is_roaming " \
        "order by time_stamp, iftype, ifname, imsi, hw_net_protocol_type, " \
        "is_roaming"
index af9f1f1..aa01d16 100755 (executable)
 
 #define MAX_PATH_LENGTH 512
 
-static int read_uint(FILE *handler, uint32_t *out)
-{
-       return fscanf(handler, "%u", out);
-}
-
-static int write_uint(FILE *handler, uint32_t number)
-{
-       _cleanup_free_ char *digit_buf = NULL;
-       int ret;
-
-       ret = asprintf(&digit_buf, "%u\n", number);
-       ret_value_errno_msg_if(ret < 0, -ENOMEM, "asprintf failed\n");
-
-       ret = fputs(digit_buf, handler);
-       ret_value_errno_msg_if(ret == EOF, errno ? -errno : -EIO,
-                              "Fail to write file");
-
-       return 0;
-}
-
 static bool cgroup_is_exists(const char *cgroup_full_path)
 {
        struct stat stat_buf;
@@ -214,51 +194,6 @@ int cgroup_make_subdir(const char *parentdir, const char *cgroup_name,
        return STC_ERROR_NONE;
 }
 
-/* FIXME: tasks is not removed from tasks list */
-int cgroup_remove_pid(const char *cgroup_subsystem, const char *cgroup_name,
-                     const int pid)
-{
-       char cgroup_tasks_file_path[MAX_PATH_LENGTH];
-       FILE *handler = 0;
-       guint i = 0;
-       pid_t pid_for_read = 0;
-       GArray *pids = NULL;
-       guint pid_count = 0;;
-
-       snprintf(cgroup_tasks_file_path, sizeof(cgroup_tasks_file_path),
-                "%s/%s/tasks", cgroup_subsystem, cgroup_name);
-
-       handler = fopen(cgroup_tasks_file_path, "r");
-       if (!handler) {
-               STC_LOGE("Read file open failed");
-               return -1;
-       }
-
-       pids = g_array_new(FALSE, FALSE, sizeof(pid_t));
-
-       while (read_uint(handler, (uint32_t *)&pid_for_read) >= 0) {
-               if (pid_for_read != pid) {
-                       pids = g_array_append_val(pids, pid_for_read);
-                       ++pid_count;
-               }
-       }
-
-       fclose(handler);
-
-       handler = fopen(cgroup_tasks_file_path, "w");
-       if (!handler) {
-               STC_LOGE("Write file open failed");
-               return -1;
-       }
-
-       for (i = 0; i < pid_count; i++)
-               write_uint(handler, g_array_index(pids, pid_t, i));
-
-       fclose(handler);
-       g_array_free(pids, TRUE);
-       return 0;
-}
-
 int cgroup_set_release_agent(const char *cgroup_subsys,
                             const char *release_agent)
 {
index 273036c..725cad4 100755 (executable)
@@ -116,13 +116,6 @@ int cgroup_set_release_agent(const char *cgroup_subsys,
 int cgroup_get_pids(const char *name, GArray **pids);
 
 /**
- * @desc remove PID from a certain cgroup tasks file.
- * @return 0 if pid removed
- */
-int cgroup_remove_pid(const char *cgroup_subsystem, const char *cgroup_name,
-                     const int pid);
-
-/**
  * @desc initializes cgroups.
  */
 void cgroup_init(void);
index 1c22608..0f2ae30 100755 (executable)
@@ -34,17 +34,20 @@ typedef GArray task_classid_array;
 static uint32_t __produce_classid(check_classid_used_cb check_classid_cb)
 {
        uint32_t classid = STC_RESERVED_CLASSID_MAX;
-       int classid_test_count = 0;
        int ret = fread_uint(CUR_CLASSID_PATH, &classid);
        if (ret < 0)
                STC_LOGI("Can not read current classid");
+
        classid += 1;
-       if (check_classid_cb)
+
+       if (check_classid_cb) {
+               int classid_test_count = 0;
                for (classid_test_count = 0; classid_test_count < INT32_MAX;
                     ++classid) {
                        if (!check_classid_cb(classid))
                                break;
                }
+       }
 
        ret = fwrite_uint(CUR_CLASSID_PATH, ++classid);
        if (ret < 0)
@@ -90,7 +93,7 @@ uint32_t get_classid_by_app_id(const char *app_id, int create)
        const char *path_to_net_cgroup_dir = NULL;
 
        if (app_id == NULL) {
-               STC_LOGE("app_id  must be not empty");
+               STC_LOGE("app_id must be not empty");
                return STC_UNKNOWN_CLASSID;
        }
 
@@ -106,6 +109,12 @@ uint32_t get_classid_by_app_id(const char *app_id, int create)
        if (!strcmp(app_id, STC_TOTAL_BLUETOOTH))
                return STC_TOTAL_BLUETOOTH_CLASSID;
 
+       if (!strcmp(app_id, STC_TOTAL_IPV4))
+               return STC_TOTAL_IPV4_CLASSID;
+
+       if (!strcmp(app_id, STC_TOTAL_IPV6))
+               return STC_TOTAL_IPV6_CLASSID;
+
        if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX))
                path_to_net_cgroup_dir = BACKGROUND_CGROUP_NETWORK;
        else
index b46b3a4..3c365ee 100755 (executable)
 #define RULE_APP_OUT "%s -w %s OUTPUT -o %s -m cgroup --cgroup %u %s %s"
 #define RULE_APP_IN "%s -w %s INPUT -i %s -m cgroup --cgroup %u %s %s"
 
-
 /* iptables -w [I/A/D] [OUTPUT/FORWARD/INPUT] -o/-i iface -m nfacct --nfacct-name name -j ACCEPT/REJECT */
 
 #define RULE_IFACE_OUT "%s -w %s %s -o %s %s %s"
 #define RULE_IFACE_IN "%s -w %s %s -i %s %s  %s"
 
-
 #define NFNL_SUBSYS_ACCT                7
 #define BUF_SIZE_FOR_ERR 100
 
@@ -388,7 +386,6 @@ static void wait_for_rule_cmd(pid_t pid)
 {
        int status;
        pid_t ret_pid;
-       char buf[BUF_SIZE_FOR_ERR] = { 0 };
 
        if (!pid || pid == -1) {
                STC_LOGD("no need to wait");
@@ -396,9 +393,11 @@ static void wait_for_rule_cmd(pid_t pid)
        }
 
        ret_pid = waitpid(pid, &status, 0);
-       if (ret_pid < 0)
+       if (ret_pid < 0) {
+               char buf[BUF_SIZE_FOR_ERR] = { 0 };
                STC_LOGD("can't wait for a pid %d %d %s", pid, status,
                         strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
+       }
 }
 
 static char* get_cmd_pos(const char *cmd_buf)
@@ -450,7 +449,6 @@ stc_error_e exec_iptables_cmd(const char *cmd_buf, pid_t *cmd_pid)
                char *args[args_number + 2];
                int ret;
                char *save_ptr = NULL;
-               char buf[BUF_SIZE_FOR_ERR] = { 0 };
 
                STC_LOGD("executing iptables cmd %s in forked process",
                         cmd_buf);
@@ -473,10 +471,12 @@ stc_error_e exec_iptables_cmd(const char *cmd_buf, pid_t *cmd_pid)
                args[i] = NULL;
 
                ret = execv(cmd, args);
-               if (ret)
+               if (ret) {
+                       char buf[BUF_SIZE_FOR_ERR] = { 0 };
                        STC_LOGE("Can't execute %s: %s",
                                 cmd_buf, strerror_r(errno, buf,
                                                     BUF_SIZE_FOR_ERR));
+               }
                exit(ret);
        }
 
@@ -499,7 +499,6 @@ stc_error_e exec_ip6tables_cmd(const char *cmd_buf, pid_t *cmd_pid)
                char *args[args_number + 2];
                int ret;
                char *save_ptr = NULL;
-               char buf[BUF_SIZE_FOR_ERR] = { 0 };
 
                STC_LOGD("executing ip6tables cmd %s in forked process",
                         cmd_buf);
@@ -522,9 +521,12 @@ stc_error_e exec_ip6tables_cmd(const char *cmd_buf, pid_t *cmd_pid)
                args[i] = NULL;
 
                ret = execv(cmd, args);
-               if (ret)
+               if (ret) {
+                       char buf[BUF_SIZE_FOR_ERR] = { 0 };
                        STC_LOGE("Can't execute %s: %s",
-                                cmd_buf, strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
+                                cmd_buf, strerror_r(errno, buf,
+                                                    BUF_SIZE_FOR_ERR));
+               }
                exit(ret);
        }
 
@@ -541,60 +543,61 @@ static char *choose_iftype_name(nfacct_rule_s *rule)
 static stc_error_e exec_iface_cmd(const char *pattern, const char *cmd,
                                  const char *chain, const char *nfacct,
                                  const char *jump, char *iftype_name,
-                                 pid_t *pid)
+                                 pid_t *pid, nfacct_rule_iptype iptype)
 {
        char block_buf[MAX_PATH_LENGTH];
        int ret;
+       const char *iptables_type = IPTABLES;
 
        ret_value_msg_if(iftype_name == NULL, STC_ERROR_FAIL,
                         "Invalid network interface name argument");
 
-       /* iptables rule */
-       ret = snprintf(block_buf, sizeof(block_buf), pattern, IPTABLES, cmd, chain,
-                     iftype_name, nfacct, jump);
-       ret_value_msg_if(ret > sizeof(block_buf), STC_ERROR_FAIL,
-                        "Not enough buffer");
-       exec_iptables_cmd(block_buf, pid);
-       wait_for_rule_cmd(*pid);
+       if (iptype == NFACCT_TYPE_IPV6)
+               iptables_type = IP6TABLES;
 
-       /* ip6tables rule */
-       ret = snprintf(block_buf, sizeof(block_buf), pattern, IP6TABLES, cmd, chain,
-                     iftype_name, nfacct, jump);
+       ret = snprintf(block_buf, sizeof(block_buf), pattern, iptables_type,
+                      cmd, chain, iftype_name, nfacct, jump);
        ret_value_msg_if(ret > sizeof(block_buf), STC_ERROR_FAIL,
                         "Not enough buffer");
-       ret = exec_ip6tables_cmd(block_buf, pid);
+
+       if (iptype == NFACCT_TYPE_IPV6)
+               exec_ip6tables_cmd(block_buf, pid);
+       else
+               exec_iptables_cmd(block_buf, pid);
+
        wait_for_rule_cmd(*pid);
 
-       return ret;
+       return STC_ERROR_NONE;
 }
 
 static stc_error_e exec_app_cmd(const char *pattern, const char *cmd,
                                const char *nfacct, const char *jump,
                                const uint32_t classid, char *iftype_name,
-                               pid_t *pid)
+                               pid_t *pid, nfacct_rule_iptype iptype)
 {
        char block_buf[MAX_PATH_LENGTH];
        int ret;
+       const char *iptables_type = IPTABLES;
+
        ret_value_msg_if(iftype_name == NULL, STC_ERROR_FAIL,
                         "Invalid network interface name argument");
 
-       /* iptables rules */
-       ret = snprintf(block_buf, sizeof(block_buf), pattern, IPTABLES, cmd,
-                     iftype_name, classid, nfacct, jump);
-       ret_value_msg_if(ret > sizeof(block_buf), STC_ERROR_FAIL,
-                        "Not enough buffer");
-       exec_iptables_cmd(block_buf, pid);
-       wait_for_rule_cmd(*pid);
+       if (iptype == NFACCT_TYPE_IPV6)
+               iptables_type = IP6TABLES;
 
-       /* ip6tables rules */
-       ret = snprintf(block_buf, sizeof(block_buf), pattern, IP6TABLES, cmd,
-                     iftype_name, classid, nfacct, jump);
+       ret = snprintf(block_buf, sizeof(block_buf), pattern, iptables_type,
+                      cmd, iftype_name, classid, nfacct, jump);
        ret_value_msg_if(ret > sizeof(block_buf), STC_ERROR_FAIL,
                         "Not enough buffer");
-       ret = exec_ip6tables_cmd(block_buf, pid);
+
+       if (iptype == NFACCT_TYPE_IPV6)
+               exec_ip6tables_cmd(block_buf, pid);
+       else
+               exec_iptables_cmd(block_buf, pid);
+
        wait_for_rule_cmd(*pid);
 
-       return ret;
+       return STC_ERROR_NONE;
 }
 
 static char *get_iptables_cmd(const nfacct_rule_action action)
@@ -629,30 +632,28 @@ static char *get_iptables_jump(const nfacct_rule_jump jump)
        return "";
 }
 
-static stc_error_e produce_app_rule(nfacct_rule_s *rule,
-                                   const int64_t send_limit,
-                                   const int64_t rcv_limit,
-                                   const nfacct_rule_action action,
-                                   const nfacct_rule_jump jump,
-                                   const nfacct_rule_direction iotype)
+static stc_error_e produce_app_rule(nfacct_rule_s *rule)
 {
-       char *set_cmd = get_iptables_cmd(action);
-       char *jump_cmd = get_iptables_jump(jump);
+       if (rule == NULL)
+               return STC_ERROR_INVALID_PARAMETER;
+
+       char *set_cmd = get_iptables_cmd(rule->action);
+       char *jump_cmd = get_iptables_jump(rule->jump);
        char nfacct_buf[sizeof(NFACCT_NAME_MOD) +
                3*MAX_DEC_SIZE(int) + 4];
        stc_error_e ret = STC_ERROR_NONE;
        pid_t pid = 0;
 
        /* income part */
-       if (iotype & NFACCT_COUNTER_IN) {
-               rule->quota = rcv_limit;
+       if (rule->iotype & NFACCT_COUNTER_IN) {
+               rule->quota = rule->rcv_limit;
                rule->iotype = NFACCT_COUNTER_IN;
                generate_counter_name(rule);
 
                /* to support quated counter we need nfacct,
                 *      don't use it in case of just block without a limit
                 *      iow, send_limit = 0 and rcv_limit 0 */
-               if (action != NFACCT_ACTION_DELETE) {
+               if (rule->action != NFACCT_ACTION_DELETE) {
                        ret = nfacct_send_del(rule);
                        ret_value_msg_if(ret != STC_ERROR_NONE, ret,
                                         "can't del quota counter");
@@ -672,14 +673,14 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule,
 
                ret = exec_app_cmd(RULE_APP_IN, set_cmd, nfacct_buf, jump_cmd,
                                   rule->classid, choose_iftype_name(rule),
-                                  &pid);
+                                  &pid, rule->iptype);
                ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
                                 "Can't set conditional block for ingress"
                                 " traffic, for classid %u, cmd %s, j %s",
                                 rule->classid, set_cmd, jump_cmd);
 
                /* remove in any case */
-               if (action == NFACCT_ACTION_DELETE) {
+               if (rule->action == NFACCT_ACTION_DELETE) {
                        /* TODO here and everywhere should be not just a del,
                         *      here should be get counted value and than
                         *      set new counter with that value, but it's minor issue,
@@ -694,12 +695,12 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule,
                }
        }
 
-       if (iotype & NFACCT_COUNTER_OUT) {
+       if (rule->iotype & NFACCT_COUNTER_OUT) {
                /* outcome part */
                rule->iotype = NFACCT_COUNTER_OUT;
-               rule->quota = send_limit;
+               rule->quota = rule->send_limit;
                generate_counter_name(rule);
-               if (action != NFACCT_ACTION_DELETE) {
+               if (rule->action != NFACCT_ACTION_DELETE) {
                        ret = nfacct_send_del(rule);
                        ret_value_msg_if(ret != STC_ERROR_NONE, ret,
                                         "can't del quota counter");
@@ -717,12 +718,12 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule,
 
                ret = exec_app_cmd(RULE_APP_OUT, set_cmd, nfacct_buf, jump_cmd,
                                   rule->classid, choose_iftype_name(rule),
-                                  &pid);
+                                  &pid, rule->iptype);
                ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
                                 "Can't set conditional block for engress"
                                 " traffic, for classid %u, cmd %s, j %s",
                                 rule->classid, set_cmd, jump_cmd);
-               if (action == NFACCT_ACTION_DELETE) {
+               if (rule->action == NFACCT_ACTION_DELETE) {
                        rule->iptables_rule = nfacct_send_del;
                        /* not effective, it's better to replace
                         * set_finalize_flag by set_property,
@@ -738,27 +739,25 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule,
        return STC_ERROR_NONE;
 }
 
-static stc_error_e produce_iface_rule(nfacct_rule_s *rule,
-                                     const int64_t send_limit,
-                                     const int64_t rcv_limit,
-                                     const nfacct_rule_action action,
-                                     const nfacct_rule_jump jump,
-                                     const nfacct_rule_direction iotype)
+static stc_error_e produce_iface_rule(nfacct_rule_s *rule)
 {
-       char *set_cmd = get_iptables_cmd(action);
-       char *jump_cmd = get_iptables_jump(jump);
+       if (rule == NULL)
+               return STC_ERROR_INVALID_PARAMETER;
+
+       char *set_cmd = get_iptables_cmd(rule->action);
+       char *jump_cmd = get_iptables_jump(rule->jump);
        char nfacct_buf[sizeof(NFACCT_NAME_MOD) +
                3*MAX_DEC_SIZE(int) + 4];
        stc_error_e ret;
        pid_t pid = 0;
 
-       if (iotype & NFACCT_COUNTER_IN) {
+       if (rule->iotype & NFACCT_COUNTER_IN) {
                /* income part */
                rule->iotype = NFACCT_COUNTER_IN;
-               rule->quota = rcv_limit;
+               rule->quota = rule->rcv_limit;
                generate_counter_name(rule);
 
-               if (action != NFACCT_ACTION_DELETE) {
+               if (rule->action != NFACCT_ACTION_DELETE) {
                        /* send delete comman in case of creation,
                         * because nfacct doesn't reset value for nfacct quota
                         * in case of quota existing */
@@ -780,7 +779,8 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule,
                ret = exec_iface_cmd(RULE_IFACE_IN, set_cmd,
                                     get_iptables_chain(rule->iotype),
                                     nfacct_buf, jump_cmd,
-                                    choose_iftype_name(rule), &pid);
+                                    choose_iftype_name(rule), &pid,
+                                    rule->iptype);
                ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
                                 "Can't set conditional block for ingress"
                                 " traffic, for iftype %d, cmd %s, j %s",
@@ -792,7 +792,8 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule,
                        /* RULE_IFACE_OUT is not a misprint here */
                        ret = exec_iface_cmd(RULE_IFACE_IN, set_cmd,
                                             FORWARD_RULE, nfacct_buf, jump_cmd,
-                                            choose_iftype_name(rule), &pid);
+                                            choose_iftype_name(rule), &pid,
+                                            rule->iptype);
                        ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
                                         "Can't set forward rule for ingress "
                                         "traffic, for iftype %d, cmd %s, j %s",
@@ -800,7 +801,7 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule,
                }
                /* tethering */
 
-               if (action == NFACCT_ACTION_DELETE) {
+               if (rule->action == NFACCT_ACTION_DELETE) {
                        rule->iptables_rule = nfacct_send_del;
                        set_finalize_flag(rule);
                        nfacct_send_get(rule);
@@ -810,13 +811,13 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule,
                }
        }
 
-       if (iotype & NFACCT_COUNTER_OUT) {
+       if (rule->iotype & NFACCT_COUNTER_OUT) {
                /* outcome part */
                rule->iotype = NFACCT_COUNTER_OUT;
-               rule->quota = send_limit;
+               rule->quota = rule->send_limit;
                generate_counter_name(rule);
 
-               if (action != NFACCT_ACTION_DELETE) {
+               if (rule->action != NFACCT_ACTION_DELETE) {
                        /* send delete comman in case of creation,
                         * because nfacct doesn't reset value for nfacct quota
                         * in case of quota existing */
@@ -837,7 +838,8 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule,
 
                ret = exec_iface_cmd(RULE_IFACE_OUT, set_cmd, OUT_RULE,
                                     nfacct_buf, jump_cmd,
-                                    choose_iftype_name(rule), &pid);
+                                    choose_iftype_name(rule), &pid,
+                                    rule->iptype);
                ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
                                 "Can't set conditional block for "
                                 "engress traffic, for iftype %d, cmd %s, j %s",
@@ -847,7 +849,8 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule,
                    rule->intend == NFACCT_BLOCK) {
                        ret = exec_iface_cmd(RULE_IFACE_OUT, set_cmd,
                                             FORWARD_RULE, nfacct_buf, jump_cmd,
-                                            choose_iftype_name(rule), &pid);
+                                            choose_iftype_name(rule), &pid,
+                                            rule->iptype);
                        ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
                                         "Can't set forward rule for engress "
                                         "traffic, for iftype %d, cmd %s, j %s",
@@ -855,7 +858,7 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule,
                }
                /* tethering  */
 
-               if (action == NFACCT_ACTION_DELETE) {
+               if (rule->action == NFACCT_ACTION_DELETE) {
                        rule->iptables_rule = nfacct_send_del;
                        set_finalize_flag(rule);
                        nfacct_send_get(rule);
@@ -867,29 +870,28 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule,
        return STC_ERROR_NONE;
 }
 
-stc_error_e produce_net_rule(nfacct_rule_s *rule,
-                            const int64_t send_limit,
-                            const int64_t rcv_limit,
-                            const nfacct_rule_action action,
-                            const nfacct_rule_jump jump,
-                            const nfacct_rule_direction iotype)
+stc_error_e produce_net_rule(nfacct_rule_s *rule)
 {
        stc_error_e ret = STC_ERROR_NONE;
 
-       if (action == NFACCT_ACTION_APPEND && rule->intend == NFACCT_WARN
-           && !send_limit && !rcv_limit)
+       if (rule == NULL)
+               return STC_ERROR_INVALID_PARAMETER;
+
+       if (rule->action == NFACCT_ACTION_APPEND &&
+           rule->intend == NFACCT_WARN &&
+           !rule->send_limit && !rule->rcv_limit)
                return STC_ERROR_NONE;
 
        if (rule->classid != STC_ALL_APP_CLASSID &&
            rule->classid != STC_TETHERING_APP_CLASSID &&
            rule->classid != STC_TOTAL_DATACALL_CLASSID &&
            rule->classid != STC_TOTAL_WIFI_CLASSID &&
-           rule->classid != STC_TOTAL_BLUETOOTH_CLASSID)
-               ret = produce_app_rule(rule, send_limit,
-                                      rcv_limit, action, jump, iotype);
+           rule->classid != STC_TOTAL_BLUETOOTH_CLASSID &&
+           rule->classid != STC_TOTAL_IPV4_CLASSID &&
+           rule->classid != STC_TOTAL_IPV6_CLASSID)
+               ret = produce_app_rule(rule);
        else
-               ret = produce_iface_rule(rule, send_limit, rcv_limit,
-                                        action, jump, iotype);
+               ret = produce_iface_rule(rule);
 
        return ret;
 }
index 2220868..89eb27c 100755 (executable)
@@ -57,6 +57,13 @@ typedef enum {
        NFACCT_RULE_LAST_ELEM,
 } nfacct_rule_intend;
 
+typedef enum {
+       NFACCT_TYPE_UNKNOWN,
+       NFACCT_TYPE_IPV4,
+       NFACCT_TYPE_IPV6,
+       NFACCT_TYPE_LAST_ELEM
+} nfacct_rule_iptype;
+
 enum nfnl_acct_flags {
        NFACCT_F_QUOTA_PKTS     = (1 << 0),
        NFACCT_F_QUOTA_BYTES    = (1 << 1),
@@ -81,20 +88,21 @@ struct nfacct_rule {
        pid_t pid;
        uint32_t classid;
        stc_iface_type_e iftype;
+       nfacct_rule_action action;
        nfacct_rule_direction iotype;
        nfacct_rule_intend intend;
+       nfacct_rule_jump jump; /* in most cases jump is evalutation based on intend, but not always */
+       stc_restriction_state_e rst_state;
+       nfacct_rule_iptype iptype;
+
        struct counter_arg *carg;
        stc_error_e(*iptables_rule)(struct nfacct_rule *counter);
        int64_t quota;
        int quota_id;
        stc_roaming_type_e roaming;
-       stc_restriction_state_e rst_state;
 
-       /**
-        * in most cases jump is evalutation based
-        * on intend, but not always
-        */
-       nfacct_rule_jump jump;
+       int64_t send_limit;
+       int64_t rcv_limit;
 };
 
 typedef struct nfacct_rule nfacct_rule_s;
@@ -105,18 +113,7 @@ void generate_counter_name(nfacct_rule_s *counter);
 bool recreate_counter_by_name(char *cnt_name, nfacct_rule_s *counter);
 
 stc_error_e nfacct_send_get_all(struct counter_arg *carg);
-stc_error_e nfacct_send_get_counters(struct counter_arg *carg,
-                                    const char *name);
-stc_error_e nfacct_send_get(nfacct_rule_s *rule);
-stc_error_e nfacct_send_del(nfacct_rule_s *counter);
-
-stc_error_e exec_iptables_cmd(const char *cmd_buf, pid_t *pid);
-stc_error_e produce_net_rule(nfacct_rule_s *rule,
-                            const int64_t send_limit,
-                            const int64_t rcv_limit,
-                            const nfacct_rule_action action,
-                            const nfacct_rule_jump jump,
-                            const nfacct_rule_direction iotype);
+stc_error_e produce_net_rule(nfacct_rule_s *rule);
 
 netlink_serialization_command *
 netlink_create_command(struct netlink_serialization_params *params);
diff --git a/src/helper/helper-restriction.c b/src/helper/helper-restriction.c
deleted file mode 100755 (executable)
index fb15856..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @file restriction-helper.c
- * @desc Helper restriction functions
- */
-
-#include "stc-manager.h"
-#include "stc-restriction.h"
-#include "transmission.h"
-
-stc_restriction_state_e
-convert_to_restriction_state(const enum traffic_restriction_type rst_type)
-{
-       switch (rst_type) {
-       case RST_SET:
-               return STC_RESTRICTION_ACTIVATED;
-       case RST_UNSET:
-               return STC_RESTRICTION_REMOVED;
-       case RST_EXCLUDE:
-               return STC_RESTRICTION_EXCLUDED;
-       default:
-               return STC_RESTRICTION_UNKNOWN;
-       }
-}
diff --git a/src/helper/helper-restriction.h b/src/helper/helper-restriction.h
deleted file mode 100755 (executable)
index 51b959e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file helper-restriction.h
- * @desc Helper restriction functions
- */
-
-#ifndef __STC_HELPER_RESTRICTION_H__
-#define __STC_HELPER_RESTRICTION_H__
-
-#include "stc-manager.h"
-#include "stc-restriction.h"
-#include "transmission.h"
-
-stc_restriction_state_e
-convert_to_restriction_state(const enum traffic_restriction_type rst_type);
-
-#endif /* __STC_HELPER_RESTRICTION_H__ */
index 19e4b90..08f1065 100755 (executable)
@@ -58,30 +58,122 @@ static nfacct_rule_jump __get_jump_by_intend(struct nfacct_rule *counter)
 
 static stc_error_e __add_iptables_in(struct nfacct_rule *counter)
 {
-       return produce_net_rule(counter, 0, 0,
-               NFACCT_ACTION_INSERT, __get_jump_by_intend(counter),
-               NFACCT_COUNTER_IN);
+       if (counter == NULL)
+               return STC_ERROR_INVALID_PARAMETER;
+
+       counter->action = NFACCT_ACTION_INSERT;
+       counter->iotype = NFACCT_COUNTER_IN;
+       counter->jump = __get_jump_by_intend(counter);
+       counter->iptype = NFACCT_TYPE_IPV4;
+       counter->send_limit = 0;
+       counter->rcv_limit = 0;
+
+       return produce_net_rule(counter);
 }
 
 static stc_error_e __add_iptables_out(struct nfacct_rule *counter)
 {
-       return produce_net_rule(counter, 0, 0,
-               NFACCT_ACTION_INSERT, __get_jump_by_intend(counter),
-               NFACCT_COUNTER_OUT);
+       if (counter == NULL)
+               return STC_ERROR_INVALID_PARAMETER;
+
+       counter->action = NFACCT_ACTION_INSERT;
+       counter->iotype = NFACCT_COUNTER_OUT;
+       counter->jump = __get_jump_by_intend(counter);
+       counter->iptype = NFACCT_TYPE_IPV4;
+       counter->send_limit = 0;
+       counter->rcv_limit = 0;
+
+       return produce_net_rule(counter);
 }
 
 static stc_error_e __del_iptables_in(struct nfacct_rule *counter)
 {
-       return produce_net_rule(counter, 0, 0,
-               NFACCT_ACTION_DELETE, __get_jump_by_intend(counter),
-               NFACCT_COUNTER_IN);
+       if (counter == NULL)
+               return STC_ERROR_INVALID_PARAMETER;
+
+       counter->action = NFACCT_ACTION_DELETE;
+       counter->iotype = NFACCT_COUNTER_IN;
+       counter->jump = __get_jump_by_intend(counter);
+       counter->iptype = NFACCT_TYPE_IPV4;
+       counter->send_limit = 0;
+       counter->rcv_limit = 0;
+
+       return produce_net_rule(counter);
 }
 
 static stc_error_e __del_iptables_out(struct nfacct_rule *counter)
 {
-       return produce_net_rule(counter, 0, 0,
-               NFACCT_ACTION_DELETE, __get_jump_by_intend(counter),
-               NFACCT_COUNTER_OUT);
+       if (counter == NULL)
+               return STC_ERROR_INVALID_PARAMETER;
+
+       counter->action = NFACCT_ACTION_DELETE;
+       counter->iotype = NFACCT_COUNTER_OUT;
+       counter->jump = __get_jump_by_intend(counter);
+       counter->iptype = NFACCT_TYPE_IPV4;
+       counter->send_limit = 0;
+       counter->rcv_limit = 0;
+
+       return produce_net_rule(counter);
+}
+
+static stc_error_e __add_ip6tables_in(struct nfacct_rule *counter)
+{
+       if (counter == NULL)
+               return STC_ERROR_INVALID_PARAMETER;
+
+       counter->action = NFACCT_ACTION_INSERT;
+       counter->iotype = NFACCT_COUNTER_IN;
+       counter->jump = __get_jump_by_intend(counter);
+       counter->iptype = NFACCT_TYPE_IPV6;
+       counter->send_limit = 0;
+       counter->rcv_limit = 0;
+
+       return produce_net_rule(counter);
+}
+
+static stc_error_e __add_ip6tables_out(struct nfacct_rule *counter)
+{
+       if (counter == NULL)
+               return STC_ERROR_INVALID_PARAMETER;
+
+       counter->action = NFACCT_ACTION_INSERT;
+       counter->iotype = NFACCT_COUNTER_OUT;
+       counter->jump = __get_jump_by_intend(counter);
+       counter->iptype = NFACCT_TYPE_IPV6;
+       counter->send_limit = 0;
+       counter->rcv_limit = 0;
+
+       return produce_net_rule(counter);
+}
+
+static stc_error_e __del_ip6tables_in(struct nfacct_rule *counter)
+{
+       if (counter == NULL)
+               return STC_ERROR_INVALID_PARAMETER;
+
+       counter->action = NFACCT_ACTION_DELETE;
+       counter->iotype = NFACCT_COUNTER_IN;
+       counter->jump = __get_jump_by_intend(counter);
+       counter->iptype = NFACCT_TYPE_IPV6;
+       counter->send_limit = 0;
+       counter->rcv_limit = 0;
+
+       return produce_net_rule(counter);
+}
+
+static stc_error_e __del_ip6tables_out(struct nfacct_rule *counter)
+{
+       if (counter == NULL)
+               return STC_ERROR_INVALID_PARAMETER;
+
+       counter->action = NFACCT_ACTION_DELETE;
+       counter->iotype = NFACCT_COUNTER_OUT;
+       counter->jump = __get_jump_by_intend(counter);
+       counter->iptype = NFACCT_TYPE_IPV6;
+       counter->send_limit = 0;
+       counter->rcv_limit = 0;
+
+       return produce_net_rule(counter);
 }
 
 static int __processes_tree_key_compare(gconstpointer a, gconstpointer b,
@@ -280,8 +372,8 @@ static gboolean __add_application_monitor(gpointer key, gpointer value,
        stc_s *stc = stc_get_manager();
 
        if (app_value->classid == STC_TOTAL_DATACALL_CLASSID ||
-               app_value->classid == STC_TOTAL_WIFI_CLASSID ||
-               app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID)
+           app_value->classid == STC_TOTAL_WIFI_CLASSID ||
+           app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID)
                return FALSE;
 
        if (stc && connection && connection->ifname) {
@@ -303,8 +395,18 @@ static gboolean __add_application_monitor(gpointer key, gpointer value,
                counter.iftype = connection->type;
                g_strlcpy(counter.ifname, connection->ifname, MAX_IFACE_LENGTH);
 
-               __add_iptables_in(&counter);
-               __add_iptables_out(&counter);
+               if (app_value->classid == STC_TOTAL_IPV4_CLASSID) {
+                       __add_iptables_in(&counter);
+                       __add_iptables_out(&counter);
+               } else if (app_value->classid == STC_TOTAL_IPV6_CLASSID) {
+                       __add_ip6tables_in(&counter);
+                       __add_ip6tables_out(&counter);
+               } else {
+                       __add_iptables_in(&counter);
+                       __add_iptables_out(&counter);
+                       __add_ip6tables_in(&counter);
+                       __add_ip6tables_out(&counter);
+               }
        }
 
        return FALSE;
@@ -338,6 +440,8 @@ static gboolean __remove_application_monitor(gpointer key, gpointer value,
 
                __del_iptables_in(&counter);
                __del_iptables_out(&counter);
+               __del_ip6tables_in(&counter);
+               __del_ip6tables_out(&counter);
        }
 
        return FALSE;
@@ -447,6 +551,10 @@ static void __process_restriction(enum traffic_restriction_type rst_type,
                        /* iptables rule */
                        __add_iptables_in(&counter);
                        __add_iptables_out(&counter);
+
+                       /* ip6tables rule */
+                       __add_ip6tables_in(&counter);
+                       __add_ip6tables_out(&counter);
                }
 
                rstn_value->rst_state = STC_RESTRICTION_ACTIVATED;
@@ -486,6 +594,10 @@ static void __process_restriction(enum traffic_restriction_type rst_type,
                        __del_iptables_in(&counter);
                        __del_iptables_out(&counter);
 
+                       /* ip6tables rule */
+                       __del_ip6tables_in(&counter);
+                       __del_ip6tables_out(&counter);
+
                        rstn_value->rst_state = STC_RESTRICTION_REMOVED;
                        rstn_value->data_limit_reached = FALSE;
                }
@@ -618,8 +730,8 @@ static stc_error_e __close_and_reopen_contr_sock(stc_system_s *system)
 }
 
 static gboolean __rstn_counter_update(stc_rstn_key_s *rstn_key,
-                                                     stc_rstn_value_s *rstn_value,
-                                                     classid_bytes_context_s *context)
+                                     stc_rstn_value_s *rstn_value,
+                                     classid_bytes_context_s *context)
 {
        switch (context->counter->iotype) {
        case NFACCT_COUNTER_IN:
@@ -629,7 +741,7 @@ static gboolean __rstn_counter_update(stc_rstn_key_s *rstn_key,
                if (rstn_value->data_counter >= rstn_value->data_warn_limit &&
                    rstn_value->warn_limit_crossed_notified == FALSE) {
 
-                       gboolean rv = FALSE;
+                       gboolean rv;
                        char iftype[MAX_INT_LENGTH];
                        char byte[MAX_INT_LENGTH];
                        stc_s *stc = (stc_s *)stc_get_manager();
@@ -655,7 +767,7 @@ static gboolean __rstn_counter_update(stc_rstn_key_s *rstn_key,
                if (rstn_value->data_counter >= rstn_value->data_limit &&
                    rstn_value->rstn_limit_crossed_notified == FALSE) {
 
-                       gboolean rv = FALSE;
+                       gboolean rv;
                        char iftype[MAX_INT_LENGTH];
                        char byte[MAX_INT_LENGTH];
                        stc_s *stc = (stc_s *)stc_get_manager();
@@ -667,6 +779,11 @@ static gboolean __rstn_counter_update(stc_rstn_key_s *rstn_key,
                        __del_iptables_out(context->counter);
                        __add_iptables_in(context->counter);
                        __add_iptables_out(context->counter);
+
+                       __del_ip6tables_in(context->counter);
+                       __del_ip6tables_out(context->counter);
+                       __add_ip6tables_in(context->counter);
+                       __add_ip6tables_out(context->counter);
                        context->counter->intend = NFACCT_COUNTER;
 
                        rstn_value->data_limit_reached = TRUE;
@@ -698,15 +815,15 @@ static gboolean __rstn_counter_update(stc_rstn_key_s *rstn_key,
 }
 
 static gboolean __interface_rstn_counter_update(stc_rstn_key_s *rstn_key,
-                                                     stc_rstn_value_s *rstn_value,
-                                                     classid_bytes_context_s *context)
+                                               stc_rstn_value_s *rstn_value,
+                                               classid_bytes_context_s *context)
 {
        if ((rstn_value->classid == STC_TOTAL_DATACALL_CLASSID &&
-               context->counter->iftype == STC_IFACE_DATACALL) ||
-               (rstn_value->classid == STC_TOTAL_WIFI_CLASSID &&
-               context->counter->iftype == STC_IFACE_WIFI) ||
-               (rstn_value->classid == STC_TOTAL_BLUETOOTH_CLASSID &&
-               context->counter->iftype == STC_IFACE_BLUETOOTH)) {
+            context->counter->iftype == STC_IFACE_DATACALL) ||
+           (rstn_value->classid == STC_TOTAL_WIFI_CLASSID &&
+            context->counter->iftype == STC_IFACE_WIFI) ||
+           (rstn_value->classid == STC_TOTAL_BLUETOOTH_CLASSID &&
+            context->counter->iftype == STC_IFACE_BLUETOOTH)) {
                context->counter->classid = rstn_value->classid;
                return __rstn_counter_update(rstn_key, rstn_value, context);
        }
@@ -837,8 +954,8 @@ static gboolean __flush_rstns_counter_to_database(gpointer user_data)
 }
 
 static void __app_counter_update(stc_app_key_s *app_key,
-                                                       stc_app_value_s *app_value,
-                                                       classid_bytes_context_s *context)
+                                stc_app_value_s *app_value,
+                                classid_bytes_context_s *context)
 {
        switch (context->counter->iotype) {
        case NFACCT_COUNTER_IN:
@@ -861,18 +978,19 @@ static void __app_counter_update(stc_app_key_s *app_key,
 }
 
 static void __interface_counter_update(stc_app_key_s *app_key,
-                                                       stc_app_value_s *app_value,
-                                                       classid_bytes_context_s *context)
+                                      stc_app_value_s *app_value,
+                                      classid_bytes_context_s *context)
 {
        if ((app_value->classid == STC_TOTAL_DATACALL_CLASSID &&
-               context->counter->iftype == STC_IFACE_DATACALL) ||
-               (app_value->classid == STC_TOTAL_WIFI_CLASSID &&
-               context->counter->iftype == STC_IFACE_WIFI) ||
-               (app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID &&
-               context->counter->iftype == STC_IFACE_BLUETOOTH))
+            context->counter->iftype == STC_IFACE_DATACALL) ||
+           (app_value->classid == STC_TOTAL_WIFI_CLASSID &&
+            context->counter->iftype == STC_IFACE_WIFI) ||
+           (app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID &&
+            context->counter->iftype == STC_IFACE_BLUETOOTH))
                __app_counter_update(app_key, app_value, context);
 }
 
+
 static gboolean __apps_counter_update_foreach_classid(gpointer key,
                                                      gpointer value,
                                                      gpointer data)
@@ -1420,6 +1538,8 @@ stc_error_e stc_monitor_init(void)
        __add_application_by_interface(STC_TOTAL_DATACALL);
        __add_application_by_interface(STC_TOTAL_WIFI);
        __add_application_by_interface(STC_TOTAL_BLUETOOTH);
+       __add_application_by_interface(STC_TOTAL_IPV4);
+       __add_application_by_interface(STC_TOTAL_IPV6);
 
        /* creating restriction rules tree */
        __update_contr_cb(NULL);