Added logic to monitor and restrict data usage per interface 82/135882/7
authorhyunuktak <hyunuk.tak@samsung.com>
Tue, 27 Jun 2017 07:33:14 +0000 (16:33 +0900)
committerhyunuktak <hyunuk.tak@samsung.com>
Fri, 30 Jun 2017 05:20:20 +0000 (14:20 +0900)
Change-Id: I597acaa133cec9cd322309201ebf724582810cc4
Signed-off-by: hyunuktak <hyunuk.tak@samsung.com>
include/stc-manager-util.h
include/stc-manager.h
packaging/stc-manager.spec
src/database/tables/table-statistics.c
src/helper/helper-net-cls.c
src/helper/helper-net-cls.h
src/helper/helper-nfacct-rule.c
src/monitor/stc-monitor.c
src/stc-manager.c

index 1f8af9a..7a19fcb 100755 (executable)
@@ -345,6 +345,9 @@ enum stc_reserved_classid {
        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_TOTAL_BLUETOOTH_CLASSID,
        STC_NETWORK_RESTRICTION_APP_CLASSID,
        STC_RESERVED_CLASSID_MAX,
 };
index 73b7370..ac8ecb4 100755 (executable)
@@ -24,6 +24,9 @@
 #define NET_CLS_SUBSYS "net_cls"
 
 #define STC_BACKGROUND_APP_SUFFIX "_BACKGROUND"
+#define STC_TOTAL_DATACALL "TOTAL_DATACALL"
+#define STC_TOTAL_WIFI "TOTAL_WIFI"
+#define STC_TOTAL_BLUETOOTH "TOTAL_BLUETOOTH"
 
 typedef enum {
        STC_CANCEL = 0,    /**< cancel */
index f9ff828..cfd59dd 100644 (file)
@@ -1,6 +1,6 @@
 Name:       stc-manager
 Summary:    STC(Smart Traffic Control) manager
-Version:    0.0.17
+Version:    0.0.19
 Release:    0
 Group:      Network & Connectivity/Other
 License:    Apache-2.0
index e16059a..b31d4af 100755 (executable)
 /* SELECT statements */
 #define SELECT_FOR_PERIOD "select binpath, hw_net_protocol_type, " \
        "is_roaming, sum(received) as received, " \
-       "sum(sent) as sent, imsi, ground from statistics " \
+       "sum(sent) as sent, imsi, ground, iftype, ifname from statistics " \
        "where time_stamp between ? and ? " \
        "group by binpath, is_roaming, imsi order by received desc"
 
 #define SELECT_FOR_PERIOD_IFACE "select binpath, hw_net_protocol_type, " \
        "is_roaming, sum(received) as received, " \
-       "sum(sent) as sent, imsi, ground from statistics " \
+       "sum(sent) as sent, imsi, ground, iftype, ifname from statistics " \
        "where time_stamp between ? and ? " \
        "and iftype=? group by binpath, is_roaming, imsi order by received desc"
 
 #define SELECT_CHUNKS "select binpath, hw_net_protocol_type, " \
        "is_roaming, sum(received) as received, " \
-       "sum(sent) as sent, time_stamp - time_stamp % ? as time_stamp, imsi, " \
-       "ground " \
+       "sum(sent) as sent, imsi, ground, iftype, ifname, " \
+       "time_stamp - time_stamp % ? as time_stamp " \
        "from statistics where time_stamp between ? and ? " \
        "group by binpath, time_stamp, imsi order by time_stamp"
 
 #define SELECT_CHUNKS_IFACE "select binpath, hw_net_protocol_type, " \
        "is_roaming, sum(received) as received, " \
-       "sum(sent) as sent, imsi, ground, " \
+       "sum(sent) as sent, imsi, ground, iftype, ifname, " \
        "time_stamp - time_stamp % ? as time_stamp " \
        "from statistics where time_stamp between ? and ? and iftype=?" \
        "group by binpath, time_stamp, imsi order by time_stamp"
 #define SELECT_TOTAL "select iftype, hw_net_protocol_type, " \
        "is_roaming, sum(received) as received, sum(sent) as sent, " \
        "ifname, imsi, ground from statistics " \
-       " where (time_stamp between ? and ?) " \
+       " where (time_stamp between ? and ?) and binpath != 'TOTAL_DATACALL' " \
+       "and binpath != 'TOTAL_WIFI' and binpath != 'TOTAL_BLUETOOTH' " \
        "group by iftype, ifname, imsi, hw_net_protocol_type, is_roaming " \
        "order by time_stamp, iftype, ifname, imsi, hw_net_protocol_type, " \
        "is_roaming"
@@ -469,12 +470,15 @@ stc_error_e table_statistics_foreach_app(const table_statistics_select_rule *rul
                        data.app_id = (char *)sqlite3_column_text(stmt, 0);
                        data.hw_net_protocol_type = sqlite3_column_int(stmt, 1);
                        data.roaming = sqlite3_column_int(stmt, 2);
-                       data.ground = sqlite3_column_int(stmt, 6);
                        data.cnt.in_bytes = sqlite3_column_int64(stmt, 3);
                        data.cnt.out_bytes = sqlite3_column_int64(stmt, 4);
                        data.imsi = (char *)sqlite3_column_text(stmt, 5);
+                       data.ground = sqlite3_column_int(stmt, 6);
+                       data.iftype = sqlite3_column_int(stmt, 7);
+                       data.ifname = (char *)sqlite3_column_text(stmt, 8);
+
                        if (rule->granularity) {
-                               interval.from = sqlite3_column_int64(stmt, 7);
+                               interval.from = sqlite3_column_int64(stmt, 9);
                                interval.to = interval.from + rule->granularity;
                        }
 
index 8f3f5d0..ba30745 100755 (executable)
@@ -94,6 +94,15 @@ uint32_t get_classid_by_app_id(const char *app_id, int create)
                return STC_UNKNOWN_CLASSID;
        }
 
+       if (!strcmp(app_id, STC_TOTAL_DATACALL))
+               return STC_TOTAL_DATACALL_CLASSID;
+
+       if (!strcmp(app_id, STC_TOTAL_WIFI))
+               return STC_TOTAL_WIFI_CLASSID;
+
+       if (!strcmp(app_id, STC_TOTAL_BLUETOOTH))
+               return STC_TOTAL_BLUETOOTH_CLASSID;
+
        if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX))
                path_to_net_cgroup_dir = BACKGROUND_CGROUP_NETWORK;
        else
index b809716..24cd993 100755 (executable)
@@ -51,13 +51,4 @@ typedef gboolean(*check_classid_used_cb)(guint32 classid);
 
 stc_error_e place_pids_to_net_cgroup(const int pid, const char *pkg_name);
 
-/**
- * @desc this function makes net_cls cgroup and put pids into it.
- */
-void create_net_background_cgroup(GSList *background_pid_list);
-
-void add_pid_to_background_cgroup(pid_t pid);
-
-void remove_pid_from_background_cgroup(pid_t pid);
-
 #endif /*__STC_HELPER_NET_CLS_H__*/
index 1eb140b..8ad3a17 100755 (executable)
@@ -864,7 +864,10 @@ stc_error_e produce_net_rule(nfacct_rule_s *rule,
                return STC_ERROR_NONE;
 
        if (rule->classid != STC_ALL_APP_CLASSID &&
-           rule->classid != STC_TETHERING_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);
        else
index 835e29f..f06d679 100755 (executable)
@@ -276,6 +276,11 @@ static gboolean __add_application_monitor(gpointer key, gpointer value,
        default_connection_s *connection = (default_connection_s *)data;
        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)
+               return FALSE;
+
        if (stc && connection && connection->ifname) {
                struct nfacct_rule counter;
 
@@ -289,6 +294,7 @@ static gboolean __add_application_monitor(gpointer key, gpointer value,
                counter.carg = stc->carg;
                counter.classid = app_value->classid;
                counter.intend = NFACCT_COUNTER;
+               counter.iftype = connection->type;
                g_strlcpy(counter.ifname, connection->ifname, MAX_IFACE_LENGTH);
 
                __add_iptables_in(&counter);
@@ -318,6 +324,7 @@ static gboolean __remove_application_monitor(gpointer key, gpointer value,
                counter.carg = stc->carg;
                counter.classid = app_value->classid;
                counter.intend = NFACCT_COUNTER;
+               counter.iftype = connection->type;
                g_strlcpy(counter.ifname, connection->ifname, MAX_IFACE_LENGTH);
 
                __del_iptables_in(&counter);
@@ -416,7 +423,7 @@ static void __process_restriction(enum traffic_restriction_type rst_type,
                        counter.carg = stc->carg;
                        counter.classid = rstn_value->classid;
                        counter.intend = NFACCT_BLOCK;
-                       counter.iftype = STC_IFACE_UNKNOWN;
+                       counter.iftype = rstn_key->iftype;
                        g_strlcpy(counter.ifname, default_ifname,
                                  MAX_IFACE_LENGTH);
 
@@ -449,7 +456,7 @@ static void __process_restriction(enum traffic_restriction_type rst_type,
                        counter.carg = stc->carg;
                        counter.classid = rstn_value->classid;
                        counter.intend = NFACCT_BLOCK;
-                       counter.iftype = STC_IFACE_UNKNOWN;
+                       counter.iftype = rstn_key->iftype;
                        g_strlcpy(counter.ifname, default_ifname,
                                  MAX_IFACE_LENGTH);
 
@@ -553,25 +560,10 @@ static stc_error_e __close_contr_sock(stc_system_s *system)
        return STC_ERROR_NONE;
 }
 
-static gboolean __rstn_counter_update_foreach_classid(gpointer key,
-                                                     gpointer value,
-                                                     gpointer data)
+static gboolean __rstn_counter_update(stc_rstn_key_s *rstn_key,
+                                                     stc_rstn_value_s *rstn_value,
+                                                     classid_bytes_context_s *context)
 {
-       stc_rstn_key_s *rstn_key = (stc_rstn_key_s *)key;
-       stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
-       classid_bytes_context_s *context = (classid_bytes_context_s *)data;
-
-       if (context->counter->intend != NFACCT_COUNTER)
-               goto try_next_callback;
-
-       if (rstn_value->classid != context->counter->classid)
-               goto try_next_callback;
-
-       if (rstn_value->data_limit_reached == TRUE) {
-               context->data_limit_reached = TRUE;
-               goto try_next_callback;
-       }
-
        switch (context->counter->iotype) {
        case NFACCT_COUNTER_IN:
        case NFACCT_COUNTER_OUT:
@@ -591,7 +583,7 @@ static gboolean __rstn_counter_update_foreach_classid(gpointer key,
                                                          STC_DBUS_SERVICE_RESTRICTION_PATH,
                                                          STC_DBUS_INTERFACE_RESTRICTION,
                                                          "WarnThresholdCrossed",
-                                                         g_variant_new("(s)", rstn_key->app_id));
+                                                         g_variant_new("(si)", rstn_key->app_id, rstn_key->iftype));
                        if (rv == TRUE)
                                rstn_value->warn_limit_crossed_notified = TRUE;
 
@@ -627,7 +619,7 @@ static gboolean __rstn_counter_update_foreach_classid(gpointer key,
                                                          STC_DBUS_SERVICE_RESTRICTION_PATH,
                                                          STC_DBUS_INTERFACE_RESTRICTION,
                                                          "RestrictionThresholdCrossed",
-                                                         g_variant_new("(s)", rstn_key->app_id));
+                                                         g_variant_new("(si)", rstn_key->app_id, rstn_key->iftype));
                        if (rv == TRUE)
                                rstn_value->rstn_limit_crossed_notified = TRUE;
 
@@ -645,11 +637,57 @@ static gboolean __rstn_counter_update_foreach_classid(gpointer key,
                STC_LOGE("unknown iotype");
        }
 
+       return FALSE;
+}
+
+static gboolean __interface_rstn_counter_update(stc_rstn_key_s *rstn_key,
+                                                     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->classid = rstn_value->classid;
+               return __rstn_counter_update(rstn_key, rstn_value, context);
+       }
 
-try_next_callback:
        return FALSE;
 }
 
+static gboolean __rstn_counter_update_foreach_classid(gpointer key,
+                                                     gpointer value,
+                                                     gpointer data)
+{
+       gboolean rv = FALSE;
+       stc_rstn_key_s *rstn_key = (stc_rstn_key_s *)key;
+       stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
+       classid_bytes_context_s *context = (classid_bytes_context_s *)data;
+       uint32_t classid;
+
+       if (context->counter->intend != NFACCT_COUNTER)
+               goto try_next_callback;
+
+       if (rstn_value->data_limit_reached == TRUE) {
+               context->data_limit_reached = TRUE;
+               goto try_next_callback;
+       }
+
+       classid = context->counter->classid;
+       rv = __interface_rstn_counter_update(rstn_key, rstn_value, context);
+
+       context->counter->classid = classid;
+       if (rstn_value->classid != context->counter->classid)
+               goto try_next_callback;
+
+       rv = __rstn_counter_update(rstn_key, rstn_value, context);
+
+try_next_callback:
+       return rv;
+}
+
 static gboolean __update_app_statistics(gpointer key, gpointer value,
                                        gpointer data)
 {
@@ -739,20 +777,10 @@ static gboolean __flush_rstns_counter_to_database(gpointer user_data)
        return G_SOURCE_REMOVE;
 }
 
-static gboolean __apps_counter_update_foreach_classid(gpointer key,
-                                                     gpointer value,
-                                                     gpointer 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_key_s *app_key = (stc_app_key_s *)key;
-       stc_app_value_s *app_value = (stc_app_value_s *)value;
-       classid_bytes_context_s *context = (classid_bytes_context_s *)data;
-
-       if (context->counter->intend != NFACCT_COUNTER)
-               goto try_next_callback;
-
-       if (app_value->classid != context->counter->classid)
-               goto try_next_callback;
-
        switch (context->counter->iotype) {
        case NFACCT_COUNTER_IN:
                app_value->data_usage.in_bytes += context->bytes;
@@ -771,6 +799,38 @@ static gboolean __apps_counter_update_foreach_classid(gpointer key,
        default:
                STC_LOGE("unknown iotype");
        }
+}
+
+static void __interface_counter_update(stc_app_key_s *app_key,
+                                                       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))
+               __app_counter_update(app_key, app_value, context);
+}
+
+static gboolean __apps_counter_update_foreach_classid(gpointer key,
+                                                     gpointer value,
+                                                     gpointer data)
+{
+       stc_app_key_s *app_key = (stc_app_key_s *)key;
+       stc_app_value_s *app_value = (stc_app_value_s *)value;
+       classid_bytes_context_s *context = (classid_bytes_context_s *)data;
+
+       if (context->counter->intend != NFACCT_COUNTER)
+               goto try_next_callback;
+
+       __interface_counter_update(app_key, app_value, context);
+
+       if (app_value->classid != context->counter->classid)
+               goto try_next_callback;
+
+       __app_counter_update(app_key, app_value, context);
 
 try_next_callback:
        return FALSE;
@@ -1157,6 +1217,31 @@ static void __add_rstns_for_application(gchar *app_id)
                       app_id);
 }
 
+static void __stc_monitor_add_application_by_interface(const char *app_id)
+{
+       stc_app_key_s app_key;
+       stc_app_value_s app_value;
+
+       if (app_id == NULL)
+               return;
+
+       memset(&app_key, 0, sizeof(stc_app_key_s));
+       memset(&app_value, 0, sizeof(stc_app_value_s));
+
+       app_key.pkg_id = g_strdup(app_id);
+       app_key.app_id = g_strdup(app_id);
+
+       app_value.type = STC_APP_TYPE_NONE;
+       app_value.processes = NULL;
+       app_value.counter.in_bytes = 0;
+       app_value.counter.out_bytes = 0;
+
+       stc_monitor_application_add(app_key, app_value);
+
+       FREE(app_key.pkg_id);
+       FREE(app_key.app_id);
+}
+
 stc_error_e stc_monitor_init(void)
 {
        stc_system_s *system = MALLOC0(stc_system_s, 1);
@@ -1193,6 +1278,10 @@ stc_error_e stc_monitor_init(void)
 
        g_system = system;
 
+       __stc_monitor_add_application_by_interface(STC_TOTAL_DATACALL);
+       __stc_monitor_add_application_by_interface(STC_TOTAL_WIFI);
+       __stc_monitor_add_application_by_interface(STC_TOTAL_BLUETOOTH);
+
        /* creating restriction rules tree */
        __update_contr_cb(NULL);
 
index 6af6b7b..a732b72 100755 (executable)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <signal.h>
 #include "stc-manager.h"
 #include "stc-emulator.h"
 #include "stc-statistics.h"
@@ -89,6 +90,8 @@ gint32 main(gint32 argc, gchar *argv[])
        GMainLoop *main_loop = NULL;
        gint32 ret = -1;
 
+       signal(SIGCHLD, SIG_IGN);
+
        STC_LOGI("Smart Traffic Control Manager");
 
        if (daemon(0, 0) != 0)