From 4e3d0cd1ba80062dc637503cc36a6d13f423d1eb Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Wed, 21 Jun 2017 15:48:07 +0900 Subject: [PATCH 01/16] Added check emulator environment Change-Id: Ied3e0a4abe59f93445aa46c8a44868f52c82876c Signed-off-by: hyunuktak --- packaging/stc-manager.spec | 3 +- src/CMakeLists.txt | 1 + src/monitor/include/stc-application-lifecycle.h | 0 src/monitor/include/stc-default-connection.h | 0 src/monitor/include/stc-emulator.h | 25 +++++++++++ src/monitor/include/stc-monitor.h | 0 src/monitor/stc-emulator.c | 57 +++++++++++++++++++++++++ src/monitor/stc-monitor.c | 4 +- src/stc-manager.c | 17 +++++--- 9 files changed, 98 insertions(+), 9 deletions(-) mode change 100644 => 100755 src/monitor/include/stc-application-lifecycle.h mode change 100644 => 100755 src/monitor/include/stc-default-connection.h create mode 100755 src/monitor/include/stc-emulator.h mode change 100644 => 100755 src/monitor/include/stc-monitor.h create mode 100755 src/monitor/stc-emulator.c diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 7247da5..f9ff828 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.16 +Version: 0.0.17 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 @@ -19,6 +19,7 @@ BuildRequires: pkgconfig(gio-unix-2.0) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(capi-system-info) %if %{?enable_database} == YES BuildRequires: pkgconfig(sqlite3) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4173f82..736cec3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,7 @@ SET(REQUIRES_LIST ${REQUIRES_LIST} gio-unix-2.0 dlog vconf + capi-system-info ) IF("${ENABLE_DATABASE}" STREQUAL "YES") diff --git a/src/monitor/include/stc-application-lifecycle.h b/src/monitor/include/stc-application-lifecycle.h old mode 100644 new mode 100755 diff --git a/src/monitor/include/stc-default-connection.h b/src/monitor/include/stc-default-connection.h old mode 100644 new mode 100755 diff --git a/src/monitor/include/stc-emulator.h b/src/monitor/include/stc-emulator.h new file mode 100755 index 0000000..8e06f7c --- /dev/null +++ b/src/monitor/include/stc-emulator.h @@ -0,0 +1,25 @@ +/* + * 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. + */ + +#ifndef __STC_EMULATOR_H__ +#define __STC_EMULATOR_H__ + +#include + +gboolean stc_emulator_is_emulated(void); +void stc_emulator_check_environment(void); + +#endif /* __STC_EMULATOR_H__ */ diff --git a/src/monitor/include/stc-monitor.h b/src/monitor/include/stc-monitor.h old mode 100644 new mode 100755 diff --git a/src/monitor/stc-emulator.c b/src/monitor/stc-emulator.c new file mode 100755 index 0000000..80bc170 --- /dev/null +++ b/src/monitor/stc-emulator.c @@ -0,0 +1,57 @@ +/* + * 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. + */ + +#include +#include + +#include "stc-emulator.h" +#include "stc-manager-util.h" + +static gboolean stc_is_emulated = FALSE; + +static gboolean __stc_emulator_check_env(void) +{ + int ret; + char *model = NULL; + + ret = system_info_get_platform_string("tizen.org/system/model_name", &model); + if (ret != SYSTEM_INFO_ERROR_NONE) { + STC_LOGE("Failed to get system information(%d)", ret); + return FALSE; + } + + if (model && strncmp(model, "Emulator", strlen("Emulator")) == 0) { + g_free(model); + return TRUE; + } + + g_free(model); + return FALSE; +} + +gboolean stc_emulator_is_emulated(void) +{ + return stc_is_emulated; +} + +void stc_emulator_check_environment(void) +{ + stc_is_emulated = __stc_emulator_check_env(); + + STC_LOGD("Emulation environment : %s", + stc_is_emulated ? "It's emulated" : "Not emulated"); +} + diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 32d2a8a..835e29f 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -895,7 +895,7 @@ static gboolean __process_contr_reply(GIOChannel *source, ret = read_netlink(sock, &ans, sizeof(struct genl)); - STC_LOGD("Counter data received ret [%d]", ret); + /* STC_LOGD("Counter data received ret [%d]", ret); */ if (ret == 0) goto out; @@ -918,7 +918,7 @@ static gboolean __update_contr_cb(void *user_data) stc->carg->sock = stc_monitor_get_counter_socket(); } - STC_LOGD("Get all counters"); + /* STC_LOGD("Get all counters"); */ nfacct_send_get_all(stc->carg); /* we need to continue the timer */ diff --git a/src/stc-manager.c b/src/stc-manager.c index 69349ae..6af6b7b 100755 --- a/src/stc-manager.c +++ b/src/stc-manager.c @@ -15,6 +15,7 @@ */ #include "stc-manager.h" +#include "stc-emulator.h" #include "stc-statistics.h" #include "stc-restriction.h" #include "stc-manager-gdbus.h" @@ -98,13 +99,16 @@ gint32 main(gint32 argc, gchar *argv[]) g_type_init(); #endif - g_stc = __stc_manager_init(); - if (!g_stc) - goto fail; - /* Crate the GLIB main loop */ main_loop = g_main_loop_new(NULL, FALSE); - g_stc->main_loop = main_loop; + + stc_emulator_check_environment(); + if (stc_emulator_is_emulated() == FALSE) { + g_stc = __stc_manager_init(); + if (!g_stc) + goto fail; + g_stc->main_loop = main_loop; + } /* Run the main loop */ g_main_loop_run(main_loop); @@ -112,7 +116,8 @@ gint32 main(gint32 argc, gchar *argv[]) ret = 0; fail: - __stc_manager_deinit(); + if (stc_emulator_is_emulated() == FALSE) + __stc_manager_deinit(); if (main_loop) g_main_loop_unref(main_loop); -- 2.7.4 From 086cdb8b95c7e336335f31fcdba1f7283805a2c3 Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Tue, 27 Jun 2017 14:19:33 +0530 Subject: [PATCH 02/16] Ignoring SIGCHLD signal as exit status if child process is not required. Description: This patch ignores the SIGCHLD event, so that kernel can reap the child process automatically so that process table is properly updated. Change-Id: I09283dbee630359a5daa5c2d25f97a65ac6dda3e Signed-off-by: Nishant Chaprana --- packaging/stc-manager.spec | 2 +- src/stc-manager.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index f9ff828..d9ab976 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.17 +Version: 0.0.18 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/stc-manager.c b/src/stc-manager.c index 6af6b7b..a732b72 100755 --- a/src/stc-manager.c +++ b/src/stc-manager.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #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) -- 2.7.4 From 2113c9539100f68efcdbd0266084f62e9aca3e6a Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Wed, 28 Jun 2017 16:45:39 +0530 Subject: [PATCH 03/16] Reopening socket if G_IO error is received and updated debug logs. Change-Id: I58ee40fe4b3349dd26117907347893d892fd0a63 Signed-off-by: Nishant Chaprana --- packaging/stc-manager.spec | 2 +- src/database/tables/table-statistics.c | 2 +- src/helper/helper-net-cls.c | 2 +- src/helper/helper-nfacct-rule.c | 2 +- src/monitor/stc-default-connection.c | 2 +- src/monitor/stc-monitor.c | 56 +++++++++++++++++++++++++++++----- src/stc-manager.c | 6 +++- 7 files changed, 59 insertions(+), 13 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index d9ab976..cfd59dd 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.18 +Version: 0.0.19 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/database/tables/table-statistics.c b/src/database/tables/table-statistics.c index e16059a..73c298d 100755 --- a/src/database/tables/table-statistics.c +++ b/src/database/tables/table-statistics.c @@ -619,7 +619,7 @@ stc_error_e table_statistics_insert(stc_db_classid_iftype_key *stat_key, goto handle_error; } - STC_LOGE("App stat recorded [%s]", stat->app_id); + STC_LOGD("App stat recorded [%s]", stat->app_id); handle_error: sqlite3_reset(stmt); diff --git a/src/helper/helper-net-cls.c b/src/helper/helper-net-cls.c index 8f3f5d0..826ff7d 100755 --- a/src/helper/helper-net-cls.c +++ b/src/helper/helper-net-cls.c @@ -37,7 +37,7 @@ static uint32_t __produce_classid(check_classid_used_cb check_classid_cb) int classid_test_count = 0; int ret = fread_uint(CUR_CLASSID_PATH, &classid); if (ret < 0) - STC_LOGE("Can not read current classid"); + STC_LOGI("Can not read current classid"); classid += 1; if (check_classid_cb) for (classid_test_count = 0; classid_test_count < INT32_MAX; diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index 1eb140b..315a465 100755 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -126,7 +126,7 @@ static stc_error_e send_nfacct_request(int sock, struct genl *req) int ret = sendto(sock, (char *)(&req->n), req->n.nlmsg_len, 0, (struct sockaddr *)&nladdr, sizeof(nladdr)); ret_value_msg_if(ret < 0, STC_ERROR_FAIL, - "Failed to send command to get outgoing traffic"); + "Failed to send nfacct request, error [%d]", ret); return STC_ERROR_NONE; } diff --git a/src/monitor/stc-default-connection.c b/src/monitor/stc-default-connection.c index 9aad6fb..ad9b74f 100755 --- a/src/monitor/stc-default-connection.c +++ b/src/monitor/stc-default-connection.c @@ -140,7 +140,7 @@ static void __get_default_connection_info(GDBusConnection *connection, gchar *key = NULL; if (object_path == NULL) { - STC_LOGE("Object path is NULL"); + STC_LOGI("Object path is NULL, so information not available."); return; } diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 835e29f..31dadf6 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -540,19 +540,57 @@ static stc_error_e __close_contr_sock(stc_system_s *system) ret_value_msg_if(system == NULL, STC_ERROR_INVALID_PARAMETER, "invalid parameter"); /* close netlink socket for updating kernel counters */ - if (g_system->contr_sock != -1) { - close(g_system->contr_sock); - g_system->contr_sock = -1; + if (system->contr_sock != -1) { + close(system->contr_sock); + system->contr_sock = -1; } - if (g_system->contr_gsource_id != 0) { - g_source_remove(g_system->contr_gsource_id); - g_system->contr_gsource_id = 0; + if (system->contr_gsource_id != 0) { + g_source_remove(system->contr_gsource_id); + system->contr_gsource_id = 0; } return STC_ERROR_NONE; } +static gboolean __process_contr_reply(GIOChannel *source, + GIOCondition condition, + gpointer user_data); + +static stc_error_e __close_and_reopen_contr_sock(stc_system_s *system) +{ + GIOChannel *gio = NULL; + ret_value_msg_if(system == NULL, STC_ERROR_INVALID_PARAMETER, "invalid parameter"); + + /* close netlink socket for updating kernel counters */ + if (system->contr_sock != -1) { + close(system->contr_sock); + system->contr_sock = -1; + } + + if (system->contr_gsource_id != 0) { + g_source_remove(system->contr_gsource_id); + system->contr_gsource_id = 0; + } + + /* create netlink socket for updating kernel counters */ + system->contr_sock = create_netlink(NETLINK_NETFILTER, 0); + if (!(system->contr_sock)) { + STC_LOGE("failed to open socket"); + FREE(system); + return STC_ERROR_FAIL; + } + + gio = g_io_channel_unix_new(system->contr_sock); + system->contr_gsource_id = + g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP, + (GIOFunc) __process_contr_reply, + NULL); + g_io_channel_unref(gio); + + return STC_ERROR_NONE; +} + static gboolean __rstn_counter_update_foreach_classid(gpointer key, gpointer value, gpointer data) @@ -884,7 +922,11 @@ static gboolean __process_contr_reply(GIOChannel *source, (condition & G_IO_NVAL)) { /* G_IO_ERR/G_IO_HUP/G_IO_NVAL received */ - __close_contr_sock(g_system); + STC_LOGE("Counter socket received G_IO event, closing socket." + "G_IO_ERR [%d], G_IO_HUP [%d], G_IO_NVAL [%s]", + (condition & G_IO_ERR), (condition & G_IO_HUP), + (condition & G_IO_NVAL)); + __close_and_reopen_contr_sock(g_system); return FALSE; } diff --git a/src/stc-manager.c b/src/stc-manager.c index a732b72..1f856ef 100755 --- a/src/stc-manager.c +++ b/src/stc-manager.c @@ -54,6 +54,7 @@ static stc_s *__stc_manager_init(void) { __STC_LOG_FUNC_ENTER__; stc_s *stc; + stc_error_e err = STC_ERROR_NONE; stc = MALLOC0(stc_s, 1); if (!stc) { @@ -66,7 +67,10 @@ static stc_s *__stc_manager_init(void) EXEC(STC_ERROR_NONE, stc_db_initialize()); - stc_monitor_init(); + err = stc_monitor_init(); + if (err != STC_ERROR_NONE) + goto handle_error; + stc_manager_gdbus_init((gpointer)stc); stc_manager_plugin_init(); -- 2.7.4 From 887245fd8e34706dee927d150baf9fcaa59420d7 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Tue, 27 Jun 2017 16:33:14 +0900 Subject: [PATCH 04/16] Added logic to monitor and restrict data usage per interface Change-Id: I597acaa133cec9cd322309201ebf724582810cc4 Signed-off-by: hyunuktak --- include/stc-manager-util.h | 3 + include/stc-manager.h | 3 + packaging/stc-manager.spec | 2 +- src/database/tables/table-statistics.c | 20 ++-- src/helper/helper-net-cls.c | 9 ++ src/helper/helper-net-cls.h | 9 -- src/helper/helper-nfacct-rule.c | 5 +- src/monitor/stc-monitor.c | 161 +++++++++++++++++++++++++-------- src/stc-manager.c | 3 + 9 files changed, 160 insertions(+), 55 deletions(-) diff --git a/include/stc-manager-util.h b/include/stc-manager-util.h index 1f8af9a..7a19fcb 100755 --- a/include/stc-manager-util.h +++ b/include/stc-manager-util.h @@ -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, }; diff --git a/include/stc-manager.h b/include/stc-manager.h index 73b7370..ac8ecb4 100755 --- a/include/stc-manager.h +++ b/include/stc-manager.h @@ -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 */ diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index f9ff828..cfd59dd 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -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 diff --git a/src/database/tables/table-statistics.c b/src/database/tables/table-statistics.c index e16059a..b31d4af 100755 --- a/src/database/tables/table-statistics.c +++ b/src/database/tables/table-statistics.c @@ -42,26 +42,26 @@ /* 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" @@ -103,7 +103,8 @@ #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; } diff --git a/src/helper/helper-net-cls.c b/src/helper/helper-net-cls.c index 8f3f5d0..ba30745 100755 --- a/src/helper/helper-net-cls.c +++ b/src/helper/helper-net-cls.c @@ -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 diff --git a/src/helper/helper-net-cls.h b/src/helper/helper-net-cls.h index b809716..24cd993 100755 --- a/src/helper/helper-net-cls.h +++ b/src/helper/helper-net-cls.h @@ -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__*/ diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index 1eb140b..8ad3a17 100755 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -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 diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 835e29f..f06d679 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -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); diff --git a/src/stc-manager.c b/src/stc-manager.c index 6af6b7b..a732b72 100755 --- a/src/stc-manager.c +++ b/src/stc-manager.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #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) -- 2.7.4 From 65144a1894772f20aea0721241933bda62fa398a Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Fri, 30 Jun 2017 10:47:29 +0530 Subject: [PATCH 05/16] Fixed restriction update logic, when user data limit of a restriction. Change-Id: I1784d6ad9485f2ebc21c26cc1e3941594b12ca04 Signed-off-by: Nishant Chaprana --- packaging/stc-manager.spec | 2 +- src/database/tables/table-restrictions.c | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index cfd59dd..0470c0c 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.19 +Version: 0.0.20 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/database/tables/table-restrictions.c b/src/database/tables/table-restrictions.c index a5cb108..e1e7256 100755 --- a/src/database/tables/table-restrictions.c +++ b/src/database/tables/table-restrictions.c @@ -49,7 +49,6 @@ #define SELECT_RESTRICTION_ID "SELECT restriction_id FROM restrictions " \ " WHERE binpath = ? AND iftype = ? AND imsi = ? AND " \ - " data_limit = ? AND data_warn_limit = ? AND " \ " rst_state = ? AND roaming = ? AND ifname = ?" /* UPDATE statement */ @@ -476,11 +475,9 @@ stc_error_e __get_restriction_id(table_restrictions_info *info) DB_ACTION(sqlite3_bind_int(stmt, 2, info->iftype)); DB_ACTION(sqlite3_bind_text(stmt, 3, info->imsi ? info->imsi : "", -1, SQLITE_TRANSIENT)); - DB_ACTION(sqlite3_bind_int64(stmt, 4, info->data_limit)); - DB_ACTION(sqlite3_bind_int64(stmt, 5, info->data_warn_limit)); - DB_ACTION(sqlite3_bind_int(stmt, 6, info->rst_state)); - DB_ACTION(sqlite3_bind_int(stmt, 7, info->roaming)); - DB_ACTION(sqlite3_bind_text(stmt, 8, info->ifname ? info->ifname : "", + DB_ACTION(sqlite3_bind_int(stmt, 4, info->rst_state)); + DB_ACTION(sqlite3_bind_int(stmt, 5, info->roaming)); + DB_ACTION(sqlite3_bind_text(stmt, 6, info->ifname ? info->ifname : "", -1, SQLITE_TRANSIENT)); rc = sqlite3_step(stmt); @@ -514,6 +511,7 @@ stc_error_e table_restrictions_update(table_restrictions_info *info) goto handle_error; } + __get_restriction_id(info); if (info->restriction_id) stmt = update_net_restrictions; @@ -530,7 +528,7 @@ stc_error_e table_restrictions_update(table_restrictions_info *info) DB_ACTION(sqlite3_bind_int64(stmt, 8, info->data_warn_limit)); if (info->restriction_id) - DB_ACTION(sqlite3_bind_int64(stmt, 11, info->restriction_id)); + DB_ACTION(sqlite3_bind_int64(stmt, 9, info->restriction_id)); if (sqlite3_step(stmt) != SQLITE_DONE) { STC_LOGE("Failed to set network restriction: %s\n", -- 2.7.4 From 0e4036f2ae7a28b65e7341eb67b3275ac15dab9a Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Mon, 3 Jul 2017 15:59:26 +0900 Subject: [PATCH 06/16] Called appropriately waitpid() function to wait for the child process to terminate. Change-Id: I01778a0270026c0779f3484d31870278a7cd4a58 Signed-off-by: hyunuktak --- packaging/stc-manager.spec | 2 +- src/helper/helper-nfacct-rule.c | 19 ++++++++++--------- src/stc-manager.c | 2 -- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 0470c0c..7801d1c 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.20 +Version: 0.0.21 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index 3dcde84..5a677f7 100755 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -539,13 +539,17 @@ static stc_error_e exec_iface_cmd(const char *pattern, const char *cmd, 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); /* ip6tables rule */ ret = snprintf(block_buf, sizeof(block_buf), pattern, IP6TABLES, cmd, chain, iftype_name, nfacct, jump); ret_value_msg_if(ret > sizeof(block_buf), STC_ERROR_FAIL, "Not enough buffer"); - return exec_ip6tables_cmd(block_buf, pid); + ret = exec_ip6tables_cmd(block_buf, pid); + wait_for_rule_cmd(*pid); + + return ret; } static stc_error_e exec_app_cmd(const char *pattern, const char *cmd, @@ -564,13 +568,17 @@ static stc_error_e exec_app_cmd(const char *pattern, const char *cmd, 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); /* ip6tables rules */ ret = snprintf(block_buf, sizeof(block_buf), pattern, IP6TABLES, cmd, iftype_name, classid, nfacct, jump); ret_value_msg_if(ret > sizeof(block_buf), STC_ERROR_FAIL, "Not enough buffer"); - return exec_ip6tables_cmd(block_buf, pid); + ret = exec_ip6tables_cmd(block_buf, pid); + wait_for_rule_cmd(*pid); + + return ret; } static char *get_iptables_cmd(const nfacct_rule_action action) @@ -661,7 +669,6 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule, * set new counter with that value, but it's minor issue, * due it's not clear when actual counters was stored, * and based on which value settings made such decition */ - wait_for_rule_cmd(pid); rule->iptables_rule = nfacct_send_del; set_finalize_flag(rule); nfacct_send_get(rule); @@ -700,7 +707,6 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule, " traffic, for classid %u, cmd %s, j %s", rule->classid, set_cmd, jump_cmd); if (action == NFACCT_ACTION_DELETE) { - wait_for_rule_cmd(pid); rule->iptables_rule = nfacct_send_del; /* not effective, it's better to replace * set_finalize_flag by set_property, @@ -768,7 +774,6 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule, if (rule->intend == NFACCT_WARN || rule->intend == NFACCT_BLOCK) { /* RULE_IFACE_OUT is not a misprint here */ - wait_for_rule_cmd(pid); ret = exec_iface_cmd(RULE_IFACE_IN, set_cmd, FORWARD_RULE, nfacct_buf, jump_cmd, choose_iftype_name(rule), &pid); @@ -780,7 +785,6 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule, /* tethering */ if (action == NFACCT_ACTION_DELETE) { - wait_for_rule_cmd(pid); rule->iptables_rule = nfacct_send_del; set_finalize_flag(rule); nfacct_send_get(rule); @@ -815,7 +819,6 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule, ret_value_msg_if(ret > sizeof(nfacct_buf) || ret < 0, STC_ERROR_FAIL, "Not enough buffer"); - wait_for_rule_cmd(pid); ret = exec_iface_cmd(RULE_IFACE_OUT, set_cmd, OUT_RULE, nfacct_buf, jump_cmd, choose_iftype_name(rule), &pid); @@ -826,7 +829,6 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule, /* for tethering */ if (rule->intend == NFACCT_WARN || rule->intend == NFACCT_BLOCK) { - wait_for_rule_cmd(pid); ret = exec_iface_cmd(RULE_IFACE_OUT, set_cmd, FORWARD_RULE, nfacct_buf, jump_cmd, choose_iftype_name(rule), &pid); @@ -838,7 +840,6 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule, /* tethering */ if (action == NFACCT_ACTION_DELETE) { - wait_for_rule_cmd(pid); rule->iptables_rule = nfacct_send_del; set_finalize_flag(rule); nfacct_send_get(rule); diff --git a/src/stc-manager.c b/src/stc-manager.c index 1f856ef..dc923ff 100755 --- a/src/stc-manager.c +++ b/src/stc-manager.c @@ -94,8 +94,6 @@ 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) -- 2.7.4 From dbba5d72cbf60aa30b9f54e3ef558a89206d9f41 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Mon, 3 Jul 2017 16:59:16 +0900 Subject: [PATCH 07/16] Removed dbus activation Change-Id: I14f1ffb8979540b4c5829f1e071647adb36cea56 Signed-off-by: hyunuktak --- packaging/stc-manager.spec | 2 +- resources/dbus/net.stc.service | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 7801d1c..4cbbf5e 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.21 +Version: 0.0.22 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/resources/dbus/net.stc.service b/resources/dbus/net.stc.service index 68d4a0b..13f4097 100755 --- a/resources/dbus/net.stc.service +++ b/resources/dbus/net.stc.service @@ -1,4 +1,5 @@ [D-BUS Service] Name=net.stc -Exec=/usr/bin/stc-manager +Exec=/bin/false User=root +SystemdService=stc-manager.service -- 2.7.4 From 9769c7dd261c757c4b4bd2f6a9c320c1fa550b0b Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Mon, 3 Jul 2017 18:36:09 +0900 Subject: [PATCH 08/16] Removed dbus service file Change-Id: I2f05e6b55b263448f6881906df4bd949e3c6e352 Signed-off-by: hyunuktak --- packaging/stc-manager.spec | 6 +----- resources/dbus/net.stc.service | 5 ----- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100755 resources/dbus/net.stc.service diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 4cbbf5e..e82aec1 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.22 +Version: 0.0.23 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 @@ -78,9 +78,6 @@ cp resources/systemd/stc-manager.service %{buildroot}%{_libdir}/systemd/system/s mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/ ln -s ../stc-manager.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/stc-manager.service -mkdir -p %{buildroot}%{_datadir}/dbus-1/system-services/ -cp resources/dbus/net.stc.service %{buildroot}%{_datadir}/dbus-1/system-services/ - #DBus DAC (stc-manager.manifest enables DBus SMACK) mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d cp resources/dbus/stc-manager.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/stc-manager.conf @@ -96,7 +93,6 @@ cp resources/dbus/stc-manager.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/st #DBus DAC %attr(644,root,root) %{_sysconfdir}/dbus-1/system.d/* -%attr(644,-,-) %{_datadir}/dbus-1/system-services/*.service %if %{?enable_database} == YES %config(noreplace) %attr(660, root, root) %{database_full_path} diff --git a/resources/dbus/net.stc.service b/resources/dbus/net.stc.service deleted file mode 100755 index 13f4097..0000000 --- a/resources/dbus/net.stc.service +++ /dev/null @@ -1,5 +0,0 @@ -[D-BUS Service] -Name=net.stc -Exec=/bin/false -User=root -SystemdService=stc-manager.service -- 2.7.4 From d662fe34a1c0a678ac4dd1e83f0d9361f539744d Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Mon, 3 Jul 2017 16:06:06 +0530 Subject: [PATCH 09/16] Corrected and optimized usage of fork and waitpid. The patch fixes below things:- 1. Do not call fork when arguments not present. 2. Do not call waitpid when fork returned pid as -1 from fork. 3. Corrected wrong english usage in function name by changing name of is_rule_exists => is_rule_present. Change-Id: Ic42233a846df91cc1b7871a52b830fd59433a970 Signed-off-by: Nishant Chaprana --- packaging/stc-manager.spec | 2 +- src/helper/helper-nfacct-rule.c | 46 +++++++++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 4cbbf5e..292e5c5 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.22 +Version: 0.0.23 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index 5a677f7..b46b3a4 100755 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -390,10 +390,11 @@ static void wait_for_rule_cmd(pid_t pid) pid_t ret_pid; char buf[BUF_SIZE_FOR_ERR] = { 0 }; - if (!pid) { + if (!pid || pid == -1) { STC_LOGD("no need to wait"); return; } + ret_pid = waitpid(pid, &status, 0); if (ret_pid < 0) STC_LOGD("can't wait for a pid %d %d %s", pid, status, @@ -409,7 +410,7 @@ static char* get_cmd_pos(const char *cmd_buf) return cmd_pos; } -static bool is_rule_exists(const char *cmd_buf) +static bool is_rule_present(const char *cmd_buf) { size_t buf_len; char *exec_buf; @@ -436,12 +437,16 @@ static bool is_rule_exists(const char *cmd_buf) stc_error_e exec_iptables_cmd(const char *cmd_buf, pid_t *cmd_pid) { + const size_t args_number = get_args_number(cmd_buf); + *cmd_pid = 0; + + ret_value_msg_if(args_number == 0, STC_ERROR_FAIL, "no arguments"); + pid_t pid = fork(); if (pid == 0) { char *cmd; unsigned int i; - const size_t args_number = get_args_number(cmd_buf); char *args[args_number + 2]; int ret; char *save_ptr = NULL; @@ -450,15 +455,18 @@ stc_error_e exec_iptables_cmd(const char *cmd_buf, pid_t *cmd_pid) STC_LOGD("executing iptables cmd %s in forked process", cmd_buf); - ret_value_msg_if(args_number == 0, STC_ERROR_FAIL, "no arguments"); - - if (is_rule_exists(cmd_buf)) { - STC_LOGD("Rule %s already exists", cmd_buf); + if (is_rule_present(cmd_buf)) { + STC_LOGD("Rule %s already present", cmd_buf); exit(0); } + args[0] = "iptables"; cmd = strtok_r((char *)cmd_buf, " ", &save_ptr); - ret_value_msg_if(cmd == NULL, STC_ERROR_FAIL, "no arguments"); + if (cmd == NULL) { + STC_LOGE("no arguments"); + exit(-EINVAL); + } + for (i = 1; i <= args_number; ++i) args[i] = strtok_r(NULL, " ", &save_ptr); @@ -467,7 +475,8 @@ stc_error_e exec_iptables_cmd(const char *cmd_buf, pid_t *cmd_pid) ret = execv(cmd, args); if (ret) 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); } @@ -477,12 +486,16 @@ stc_error_e exec_iptables_cmd(const char *cmd_buf, pid_t *cmd_pid) stc_error_e exec_ip6tables_cmd(const char *cmd_buf, pid_t *cmd_pid) { + const size_t args_number = get_args_number(cmd_buf); + *cmd_pid = 0; + + ret_value_msg_if(args_number == 0, STC_ERROR_FAIL, "no arguments"); + pid_t pid = fork(); if (pid == 0) { char *cmd; unsigned int i; - const size_t args_number = get_args_number(cmd_buf); char *args[args_number + 2]; int ret; char *save_ptr = NULL; @@ -491,15 +504,18 @@ stc_error_e exec_ip6tables_cmd(const char *cmd_buf, pid_t *cmd_pid) STC_LOGD("executing ip6tables cmd %s in forked process", cmd_buf); - ret_value_msg_if(args_number == 0, STC_ERROR_FAIL, "no arguments"); - - if (is_rule_exists(cmd_buf)) { - STC_LOGD("Rule %s already exists", cmd_buf); + if (is_rule_present(cmd_buf)) { + STC_LOGD("Rule %s already present", cmd_buf); exit(0); } + args[0] = "ip6tables"; cmd = strtok_r((char *)cmd_buf, " ", &save_ptr); - ret_value_msg_if(cmd == NULL, STC_ERROR_FAIL, "no arguments"); + if (cmd == NULL) { + STC_LOGE("no arguments"); + exit(-EINVAL); + } + for (i = 1; i <= args_number; ++i) args[i] = strtok_r(NULL, " ", &save_ptr); -- 2.7.4 From ff13ab088da23745b48825037e92fae637f03427 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Wed, 12 Jul 2017 13:53:50 +0900 Subject: [PATCH 10/16] Added background restriction for data saver Change-Id: I8bb5ae5c54affe6cf1c6bd35e4952b45cac04173 Signed-off-by: hyunuktak --- include/stc-manager.h | 1 + include/stc-restriction.h | 2 +- interfaces/stcmanager-iface-restriction.xml | 2 +- src/helper/helper-cgroup.c | 5 ++ src/helper/helper-cgroup.h | 8 +- src/helper/helper-net-cls.c | 7 +- src/monitor/include/stc-monitor.h | 1 + src/monitor/stc-application-lifecycle.c | 4 +- src/monitor/stc-monitor.c | 110 +++++++++++++++++++++++++--- src/stc-manager-gdbus.c | 4 +- src/stc-restriction.c | 2 +- 11 files changed, 126 insertions(+), 20 deletions(-) diff --git a/include/stc-manager.h b/include/stc-manager.h index ac8ecb4..c82c3af 100755 --- a/include/stc-manager.h +++ b/include/stc-manager.h @@ -24,6 +24,7 @@ #define NET_CLS_SUBSYS "net_cls" #define STC_BACKGROUND_APP_SUFFIX "_BACKGROUND" +#define STC_BACKGROUND_APP_ID "BACKGROUND" #define STC_TOTAL_DATACALL "TOTAL_DATACALL" #define STC_TOTAL_WIFI "TOTAL_WIFI" #define STC_TOTAL_BLUETOOTH "TOTAL_BLUETOOTH" diff --git a/include/stc-restriction.h b/include/stc-restriction.h index 219dad8..acd4eab 100755 --- a/include/stc-restriction.h +++ b/include/stc-restriction.h @@ -67,7 +67,7 @@ gboolean handle_restriction_get_state(StcRestriction *object, int iftype, void *user_data); -gboolean handle_restriction_remove(StcRestriction *object, +gboolean handle_restriction_unset(StcRestriction *object, GDBusMethodInvocation *invocation, GVariant *parameters, void *user_data); diff --git a/interfaces/stcmanager-iface-restriction.xml b/interfaces/stcmanager-iface-restriction.xml index 6ccc381..f4baf76 100644 --- a/interfaces/stcmanager-iface-restriction.xml +++ b/interfaces/stcmanager-iface-restriction.xml @@ -28,7 +28,7 @@ - + diff --git a/src/helper/helper-cgroup.c b/src/helper/helper-cgroup.c index a725dcc..af9f1f1 100755 --- a/src/helper/helper-cgroup.c +++ b/src/helper/helper-cgroup.c @@ -20,6 +20,8 @@ #define NOTIFY_ON_RELEASE "notify_on_release" #define CGROUP_FILE_NAME "cgroup.procs" +#define CLASSID_FILE_NAME "net_cls.classid" + #define MAX_PATH_LENGTH 512 static int read_uint(FILE *handler, uint32_t *out) @@ -283,6 +285,9 @@ void cgroup_init(void) cgroup_make_subdir(STC_CGROUP_NETWORK, STC_BACKGROUND_CGROUP_NAME, NULL); + cgroup_write_node_uint32(BACKGROUND_CGROUP_NETWORK, + CLASSID_FILE_NAME, STC_BACKGROUND_APP_CLASSID); + /* create foreground cgroup directory */ cgroup_make_subdir(STC_CGROUP_NETWORK, STC_FOREGROUND_CGROUP_NAME, NULL); diff --git a/src/helper/helper-cgroup.h b/src/helper/helper-cgroup.h index a358066..273036c 100755 --- a/src/helper/helper-cgroup.h +++ b/src/helper/helper-cgroup.h @@ -31,12 +31,12 @@ #define DEFAULT_CGROUP "/sys/fs/cgroup" #define CGROUP_NETWORK DEFAULT_CGROUP "/net_cls" #define STC_CGROUP_NETWORK CGROUP_NETWORK "/stc" -#define BACKGROUND_CGROUP_NETWORK STC_CGROUP_NETWORK "/background" -#define FOREGROUND_CGROUP_NETWORK STC_CGROUP_NETWORK "/foreground" +#define BACKGROUND_CGROUP_NETWORK STC_CGROUP_NETWORK "/BACKGROUND" +#define FOREGROUND_CGROUP_NETWORK STC_CGROUP_NETWORK "/FOREGROUND" #define PROC_TASK_CHILDREN "/proc/%d/task/%d/children" #define STC_CGROUP_NAME "stc" -#define STC_BACKGROUND_CGROUP_NAME "background" -#define STC_FOREGROUND_CGROUP_NAME "foreground" +#define STC_BACKGROUND_CGROUP_NAME "BACKGROUND" +#define STC_FOREGROUND_CGROUP_NAME "FOREGROUND" /** * @desc Get one unsigned int32 value from cgroup diff --git a/src/helper/helper-net-cls.c b/src/helper/helper-net-cls.c index 5f653fc..1c22608 100755 --- a/src/helper/helper-net-cls.c +++ b/src/helper/helper-net-cls.c @@ -94,6 +94,9 @@ uint32_t get_classid_by_app_id(const char *app_id, int create) return STC_UNKNOWN_CLASSID; } + if (!strcmp(app_id, STC_BACKGROUND_APP_ID)) + return STC_BACKGROUND_APP_CLASSID; + if (!strcmp(app_id, STC_TOTAL_DATACALL)) return STC_TOTAL_DATACALL_CLASSID; @@ -150,7 +153,9 @@ stc_error_e place_pids_to_net_cgroup(const int pid, const char *app_id) return STC_ERROR_INVALID_PARAMETER; } - if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX)) + if (!strcmp(app_id, STC_BACKGROUND_APP_ID)) + path_to_net_cgroup_dir = STC_CGROUP_NETWORK; + else if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX)) path_to_net_cgroup_dir = BACKGROUND_CGROUP_NETWORK; else path_to_net_cgroup_dir = FOREGROUND_CGROUP_NETWORK; diff --git a/src/monitor/include/stc-monitor.h b/src/monitor/include/stc-monitor.h index 09871d5..56d87e2 100755 --- a/src/monitor/include/stc-monitor.h +++ b/src/monitor/include/stc-monitor.h @@ -100,6 +100,7 @@ typedef struct { gboolean rstns_tree_updated; GTree *apps; /**< monitored applications */ gboolean apps_tree_updated; + guint background_state; } stc_system_s; /** diff --git a/src/monitor/stc-application-lifecycle.c b/src/monitor/stc-application-lifecycle.c index a0fb931..ee82320 100755 --- a/src/monitor/stc-application-lifecycle.c +++ b/src/monitor/stc-application-lifecycle.c @@ -91,6 +91,7 @@ static stc_error_e __stc_manager_app_status_changed(stc_cmd_type_e cmd, stc_monitor_process_add(app_key, proc_key, proc_value); stc_monitor_process_update_ground(app_key, proc_key, STC_APP_STATE_FOREGROUND); + FREE(app_key.pkg_id); FREE(app_key.app_id); break; @@ -108,7 +109,8 @@ static stc_error_e __stc_manager_app_status_changed(stc_cmd_type_e cmd, memset(&proc_value, 0, sizeof(stc_process_value_s)); app_key.pkg_id = g_strdup(pkg_id); - app_key.app_id = g_strdup(app_id); + app_key.app_id = g_strconcat(app_id, STC_BACKGROUND_APP_SUFFIX, + NULL); app_value.type = app_type; app_value.processes = NULL; diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index a65f6d2..2bb1777 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -15,6 +15,8 @@ */ #include +#include +#include #include "stc-default-connection.h" #include "helper-nl.h" @@ -28,6 +30,7 @@ #include "stc-manager-plugin.h" #define MAX_INT_LENGTH 128 +#define VCONFKEY_STC_BACKGROUND_STATE "db/stc/background_state" typedef struct { stc_app_key_s *app_key; @@ -1259,7 +1262,7 @@ static void __add_rstns_for_application(gchar *app_id) app_id); } -static void __stc_monitor_add_application_by_interface(const char *app_id) +static void __add_application_by_interface(const char *app_id) { stc_app_key_s app_key; stc_app_value_s app_value; @@ -1284,6 +1287,78 @@ static void __stc_monitor_add_application_by_interface(const char *app_id) FREE(app_key.app_id); } +static int __vconf_get_int(const char *key, int *value) +{ + int ret = 0; + + ret = vconf_get_int(key, value); + if (ret != VCONF_OK) { + STC_LOGE("Failed to get vconfkey [%s] value", key); + return -1; + } + + return 0; +} + +static int __vconf_set_int(const char *key, int value) +{ + int ret = 0; + + ret = vconf_set_int(key, value); + if (ret != VCONF_OK) { + STC_LOGE("Failed to set vconfkey [%s] value", key); + return -1; + } + + return 0; +} + +static guint __get_background_state(void) +{ + return g_system->background_state;; +} + +static void __set_background_state(guint state) +{ + g_system->background_state = state; +} + +static gboolean __processes_tree_foreach_background(gpointer key, gpointer value, + gpointer data) +{ + stc_process_key_s *proc_key = (stc_process_key_s *)key; + stc_process_value_s *proc_value = (stc_process_value_s *)value; + stc_app_key_s *app_key = (stc_app_key_s *)data; + + if (g_system->background_state) + place_pids_to_net_cgroup(proc_key->pid, STC_BACKGROUND_APP_ID); + else + place_pids_to_net_cgroup(proc_key->pid, app_key->app_id); + + return FALSE; +} + +static gboolean __apps_tree_foreach_background(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; + + if (strstr(app_key->app_id, STC_BACKGROUND_APP_SUFFIX)) + g_tree_foreach(app_value->processes, __processes_tree_foreach_background, app_key); + + return FALSE; +} + +static stc_error_e __process_update_background(void) +{ + ret_value_msg_if(g_system == NULL, STC_ERROR_FAIL, "stc monitor not initialized!"); + + g_tree_foreach(g_system->apps, __apps_tree_foreach_background, NULL); + + return STC_ERROR_NONE; +} + stc_error_e stc_monitor_init(void) { stc_system_s *system = MALLOC0(stc_system_s, 1); @@ -1320,9 +1395,9 @@ 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); + __add_application_by_interface(STC_TOTAL_DATACALL); + __add_application_by_interface(STC_TOTAL_WIFI); + __add_application_by_interface(STC_TOTAL_BLUETOOTH); /* creating restriction rules tree */ __update_contr_cb(NULL); @@ -1337,6 +1412,8 @@ stc_error_e stc_monitor_init(void) return STC_ERROR_FAIL; } + __vconf_get_int(VCONFKEY_STC_BACKGROUND_STATE, &g_system->background_state); + __fill_restritions_list(); return STC_ERROR_NONE; @@ -1519,11 +1596,14 @@ stc_error_e stc_monitor_process_update_ground(const stc_app_key_s app_key, proc_lookup->ground = ground; if (ground == STC_APP_STATE_BACKGROUND) { - char *background_app_id = g_strconcat(app_key.app_id, - STC_BACKGROUND_APP_SUFFIX, - NULL); - place_pids_to_net_cgroup(proc_key.pid, background_app_id); - g_free(background_app_id); + if (__get_background_state()) { + place_pids_to_net_cgroup(proc_key.pid, STC_BACKGROUND_APP_ID); + } else { + char *background_app_id = g_strconcat(app_key.app_id, + STC_BACKGROUND_APP_SUFFIX, NULL); + place_pids_to_net_cgroup(proc_key.pid, background_app_id); + g_free(background_app_id); + } } else { place_pids_to_net_cgroup(proc_key.pid, app_key.app_id); } @@ -1594,6 +1674,12 @@ stc_error_e stc_monitor_rstns_tree_add(const table_restrictions_info *info) else value.classid = STC_UNKNOWN_CLASSID; + if (value.classid == STC_BACKGROUND_APP_CLASSID) { + __set_background_state(TRUE); + __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, g_system->background_state); + __process_update_background(); + } + value.data_limit = info->data_limit; value.data_warn_limit = info->data_warn_limit; @@ -1617,6 +1703,12 @@ stc_error_e stc_monitor_rstns_tree_remove(const table_restrictions_info *info) .roaming = info->roaming, }; + if (!strcmp(key.app_id, STC_BACKGROUND_APP_ID)) { + __set_background_state(FALSE); + __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, g_system->background_state); + __process_update_background(); + } + ret = __rstn_tree_remove(&key); FREE(key.app_id); diff --git a/src/stc-manager-gdbus.c b/src/stc-manager-gdbus.c index 5b3cc71..3bd6659 100755 --- a/src/stc-manager-gdbus.c +++ b/src/stc-manager-gdbus.c @@ -113,8 +113,8 @@ static gboolean __stc_manager_gdbus_restriction_init(stc_s *stc) G_CALLBACK(handle_restriction_get_state), stc); - g_signal_connect(restriction, "handle-remove", - G_CALLBACK(handle_restriction_remove), stc); + g_signal_connect(restriction, "handle-unset", + G_CALLBACK(handle_restriction_unset), stc); /* Export the object (@manager takes its own reference to @object) */ g_dbus_object_manager_server_export(stc->obj_mgr, diff --git a/src/stc-restriction.c b/src/stc-restriction.c index aa8ed4e..8550e41 100755 --- a/src/stc-restriction.c +++ b/src/stc-restriction.c @@ -295,7 +295,7 @@ gboolean handle_restriction_exclude(StcRestriction *object, return TRUE; } -gboolean handle_restriction_remove(StcRestriction *object, +gboolean handle_restriction_unset(StcRestriction *object, GDBusMethodInvocation *invocation, GVariant *parameters, void *user_data) -- 2.7.4 From ba0534e9b40f4899e6acc0b76c1456ab6ed024ce Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Thu, 20 Jul 2017 10:42:45 +0530 Subject: [PATCH 11/16] Added default sim's IMSI fetch logic. Change-Id: I9040fb2bec433e828c4289e3ce7841a901989dc8 Signed-off-by: Nishant Chaprana --- packaging/stc-manager.spec | 2 +- src/monitor/include/stc-default-connection.h | 17 ++- src/monitor/stc-default-connection.c | 150 ++++++++++++++++++++++++--- src/monitor/stc-monitor.c | 45 ++++++-- 4 files changed, 183 insertions(+), 31 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index e82aec1..4c005ca 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.23 +Version: 0.0.24 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/monitor/include/stc-default-connection.h b/src/monitor/include/stc-default-connection.h index ec5b2dc..861e58d 100755 --- a/src/monitor/include/stc-default-connection.h +++ b/src/monitor/include/stc-default-connection.h @@ -23,24 +23,33 @@ #include "stc-manager-gdbus.h" #include "stc-manager-util.h" +#define IMSI_LENGTH 16 + /** * @brief default connection information will be fetched from net-config */ typedef struct { - gchar *path; /* to identify each connection uniquely */ + /* to identify each connection uniquely */ + gchar *path; /* profile info */ stc_iface_type_e type; gchar *ifname; - gboolean roaming; /* cellular profile only else it is always false */ + + /* cellular profile only else it is always false */ + gboolean roaming; + + /* only present when default profile is cellular */ + char imsi[IMSI_LENGTH]; + + /* hardware network protocol type */ + stc_hw_net_protocol_type_e hw_net_protocol_type; } default_connection_s; stc_error_e stc_default_connection_monitor_init(stc_s *stc); stc_error_e stc_default_connection_monitor_deinit(stc_s *stc); -stc_iface_type_e stc_default_connection_get_type(void); gchar *stc_default_connection_get_ifname(void); -gboolean stc_default_connection_get_roaming(void); default_connection_s *stc_get_default_connection(void); #endif /* __STC_DEFAULT_CONNECTION_H__ */ diff --git a/src/monitor/stc-default-connection.c b/src/monitor/stc-default-connection.c index ad9b74f..8b32a3e 100755 --- a/src/monitor/stc-default-connection.c +++ b/src/monitor/stc-default-connection.c @@ -14,9 +14,12 @@ * limitations under the License. */ +#include + #include "stc-monitor.h" #include "stc-default-connection.h" +/* connman service dbus details */ #define CONNMAN_SERVICE "net.connman" #define CONNMAN_PATH "/net/connman" @@ -31,9 +34,132 @@ #define CONNMAN_SIGNAL_PROPERTY_CHANGED "PropertyChanged" +/* telephony service dbus details */ +#define TELEPHONY_SERVICE "org.tizen.telephony" +#define TELEPHONY_DEFAULT_PATH "/org/tizen/telephony" + +#define TELEPHONY_SERVICE_MANAGER TELEPHONY_SERVICE".Manager" +#define TELEPHONY_SIM_INTERFACE TELEPHONY_SERVICE".Sim" + +#define TELEPHONY_GET_MODEMS "GetModems" +#define TELEPHONY_GET_IMSI "GetIMSI" + +#define SIM_SLOT_SINGLE 1 + +#define VCONF_TELEPHONY_DEFAULT_DATA_SERVICE "db/telephony/dualsim/default_data_service" + default_connection_s g_default_connection; guint g_default_connection_sub_id = 0; +static int __telephony_get_current_sim(void) +{ + int sim_slot_count = 0; + int current_sim = 0; + + if (vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT_COUNT, &sim_slot_count) != 0) { + STC_LOGD("failed to get sim slot count"); + return -1; + } + + if (sim_slot_count == SIM_SLOT_SINGLE) { + STC_LOGD("It's single sim model"); + return current_sim; + } + + if (vconf_get_int(VCONF_TELEPHONY_DEFAULT_DATA_SERVICE, ¤t_sim) != 0) { + STC_LOGD("failed to get default data service = %d\n", + current_sim); + return -1; + } + + return current_sim; +} + +static void __telephony_get_modem_imsi(GDBusConnection *connection, + const char *default_modem_name) +{ + GVariant *message = NULL; + char tel_path[MAX_PATH_LENGTH]; + const char *plmn = NULL; + int plmn_len = 0; + const char *msin = NULL; + int msin_len = 0; + + snprintf(tel_path, sizeof(tel_path), "%s/%s", TELEPHONY_DEFAULT_PATH, + default_modem_name); + message = stc_manager_gdbus_call_sync(connection, + TELEPHONY_SERVICE, + tel_path, + TELEPHONY_SIM_INTERFACE, + TELEPHONY_GET_IMSI, + NULL); + if (message == NULL) { + STC_LOGE("Failed to get services informations"); + goto done; + } + + DEBUG_PARAMS(message); + DEBUG_PARAM_TYPE(message); + g_variant_get(message, "(&s&s)", &plmn, &msin); + plmn_len = strlen(plmn); + msin_len = strlen(msin); + + if (msin_len + plmn_len >= IMSI_LENGTH) { + STC_LOGD("Incorrect length of mobile subscriber identifier + net id"); + goto done; + } + + snprintf(g_default_connection.imsi, IMSI_LENGTH, "%s%s", plmn, msin); + +done: + g_variant_unref(message); + return; +} + +static void __telephony_update_default_modem_imsi(GDBusConnection *connection) +{ + GVariant *message = NULL; + GVariantIter *iter = NULL; + gchar *default_modem_name = NULL; + gchar *modem_name = NULL; + int current_sim = __telephony_get_current_sim(); + + if (current_sim < 0) { + STC_LOGI("Sim not found"); + return; + } + + message = stc_manager_gdbus_call_sync(connection, + TELEPHONY_SERVICE, + TELEPHONY_DEFAULT_PATH, + TELEPHONY_SERVICE_MANAGER, + TELEPHONY_GET_MODEMS, + NULL); + if (message == NULL) { + STC_LOGE("Failed to get services informations"); + return; + } + + g_variant_get(message, "(as)", &iter); + DEBUG_PARAMS(message); + DEBUG_PARAM_TYPE(message); + while (g_variant_iter_loop(iter, "s", &modem_name)) { + if (current_sim == 0) { + default_modem_name = g_strdup(modem_name); + FREE(modem_name); + break; + } + current_sim--; + } + + __telephony_get_modem_imsi(connection, default_modem_name); + + FREE(default_modem_name); + g_variant_iter_free(iter); + g_variant_unref(message); + return; +} + static void __print_default_connection_info(void) { STC_LOGI("============= default connection info ============"); @@ -41,6 +167,8 @@ static void __print_default_connection_info(void) STC_LOGI("type [%d]", g_default_connection.type); STC_LOGI("ifname [%s]", g_default_connection.ifname); STC_LOGI("roaming [%u]", g_default_connection.roaming ? TRUE : FALSE); + if (g_default_connection.type == STC_IFACE_DATACALL) + STC_LOGI("imsi [%s]", g_default_connection.imsi); STC_LOGI("=================================================="); } @@ -247,16 +375,18 @@ static stc_error_e __get_default_profile(GDBusConnection *connection) g_variant_iter_free(iter); g_variant_unref(message); - if (__is_cellular_profile(g_default_connection.path)) + if (__is_cellular_profile(g_default_connection.path)) { g_default_connection.type = STC_IFACE_DATACALL; - else if (__is_wifi_profile(g_default_connection.path)) + __telephony_update_default_modem_imsi(connection); + } else if (__is_wifi_profile(g_default_connection.path)) { g_default_connection.type = STC_IFACE_WIFI; - else if (__is_ethernet_profile(g_default_connection.path)) + } else if (__is_ethernet_profile(g_default_connection.path)) { g_default_connection.type = STC_IFACE_WIRED; - else if (__is_bluetooth_profile(g_default_connection.path)) + } else if (__is_bluetooth_profile(g_default_connection.path)) { g_default_connection.type = STC_IFACE_BLUETOOTH; - else + } else { g_default_connection.type = STC_IFACE_UNKNOWN; + } __get_default_connection_info(connection, g_default_connection.path); @@ -357,21 +487,11 @@ stc_error_e stc_default_connection_monitor_deinit(stc_s *stc) return STC_ERROR_NONE; } -stc_iface_type_e stc_default_connection_get_type(void) -{ - return g_default_connection.type; -} - gchar *stc_default_connection_get_ifname(void) { return g_strdup(g_default_connection.ifname); } -gboolean stc_default_connection_get_roaming(void) -{ - return g_default_connection.roaming; -} - default_connection_s *stc_get_default_connection(void) { return &g_default_connection; diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 2bb1777..5ff6adb 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -289,6 +289,9 @@ static gboolean __add_application_monitor(gpointer key, gpointer value, if (!stc->carg) { stc->carg = MALLOC0(counter_arg_s, 1); + if (stc->carg == NULL) + return FALSE; + stc->carg->sock = stc_monitor_get_counter_socket(); } @@ -319,6 +322,9 @@ static gboolean __remove_application_monitor(gpointer key, gpointer value, if (!stc->carg) { stc->carg = MALLOC0(counter_arg_s, 1); + if (stc->carg == NULL) + return FALSE; + stc->carg->sock = stc_monitor_get_counter_socket(); } @@ -419,6 +425,11 @@ static void __process_restriction(enum traffic_restriction_type rst_type, if (!stc->carg) { stc->carg = MALLOC0(counter_arg_s, 1); + if (stc->carg == NULL) { + g_free(default_ifname); + return; + } + stc->carg->sock = stc_monitor_get_counter_socket(); } @@ -452,6 +463,11 @@ static void __process_restriction(enum traffic_restriction_type rst_type, if (!stc->carg) { stc->carg = MALLOC0(counter_arg_s, 1); + if (stc->carg == NULL) { + g_free(default_ifname); + return; + } + stc->carg->sock = stc_monitor_get_counter_socket(); } @@ -737,23 +753,26 @@ static gboolean __update_app_statistics(gpointer key, gpointer value, time_t *touch_time = (time_t *)data; stc_db_classid_iftype_key stat_key; stc_db_app_stats stat; - char *default_ifname = stc_default_connection_get_ifname(); + default_connection_s *default_connection = stc_get_default_connection(); memset(&stat_key, 0, sizeof(stc_db_classid_iftype_key)); memset(&stat, 0 , sizeof(stc_db_app_stats)); stat_key.classid = app_value->classid; - stat_key.iftype = stc_default_connection_get_type(); + stat_key.iftype = default_connection->type; + if (STC_IFACE_DATACALL == stat_key.iftype) - stat_key.imsi = g_strdup("unknown"); + stat_key.imsi = g_strdup(default_connection->imsi); else stat_key.imsi = g_strdup("noneimsi"); - g_strlcpy(stat_key.ifname, default_ifname, MAX_IFACE_LENGTH); + + g_strlcpy(stat_key.ifname, default_connection->ifname, + MAX_IFACE_LENGTH); stat.app_id = g_strdup(app_key->app_id); stat.snd_count = app_value->counter.out_bytes; stat.rcv_count = app_value->counter.in_bytes; - stat.is_roaming = stc_default_connection_get_roaming(); + stat.is_roaming = default_connection->roaming; stat.ground = STC_APP_STATE_UNKNOWN; table_statistics_insert(&stat_key, &stat, *touch_time); @@ -763,7 +782,6 @@ static gboolean __update_app_statistics(gpointer key, gpointer value, FREE(stat.app_id); FREE(stat_key.imsi); - FREE(default_ifname); return FALSE; } @@ -1020,6 +1038,9 @@ static gboolean __update_contr_cb(void *user_data) ret_value_msg_if(stc == NULL, STC_ERROR_FAIL, "Can't get stc data"); if (!stc->carg) { stc->carg = MALLOC0(counter_arg_s, 1); + if (stc->carg == NULL) + return TRUE; /* we need to continue the timer */ + stc->carg->sock = stc_monitor_get_counter_socket(); } @@ -1323,11 +1344,11 @@ static void __set_background_state(guint state) g_system->background_state = state; } -static gboolean __processes_tree_foreach_background(gpointer key, gpointer value, - gpointer data) +static gboolean __processes_tree_foreach_background(gpointer key, + gpointer value, + gpointer data) { stc_process_key_s *proc_key = (stc_process_key_s *)key; - stc_process_value_s *proc_value = (stc_process_value_s *)value; stc_app_key_s *app_key = (stc_app_key_s *)data; if (g_system->background_state) @@ -1345,7 +1366,8 @@ static gboolean __apps_tree_foreach_background(gpointer key, gpointer value, stc_app_value_s *app_value = (stc_app_value_s *)value; if (strstr(app_key->app_id, STC_BACKGROUND_APP_SUFFIX)) - g_tree_foreach(app_value->processes, __processes_tree_foreach_background, app_key); + g_tree_foreach(app_value->processes, + __processes_tree_foreach_background, app_key); return FALSE; } @@ -1412,7 +1434,8 @@ stc_error_e stc_monitor_init(void) return STC_ERROR_FAIL; } - __vconf_get_int(VCONFKEY_STC_BACKGROUND_STATE, &g_system->background_state); + __vconf_get_int(VCONFKEY_STC_BACKGROUND_STATE, + (int *)&g_system->background_state); __fill_restritions_list(); -- 2.7.4 From f599780803f66fa9be773d8ea1c4f1278a9cb695 Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Thu, 20 Jul 2017 11:47:43 +0530 Subject: [PATCH 12/16] Fix: Extra "_BACKGROUND" was added in background cgroups. Description: An extra "_BACKGROUN" keywork was added when any update in ground status was performed. Change-Id: Ib297853b08c7516483d88674535b032f1ccd932c Signed-off-by: Nishant Chaprana --- packaging/stc-manager.spec | 2 +- src/monitor/stc-monitor.c | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 4c005ca..8f96ff2 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.24 +Version: 0.0.25 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 5ff6adb..19e4b90 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -1618,18 +1618,10 @@ stc_error_e stc_monitor_process_update_ground(const stc_app_key_s app_key, if (proc_lookup->ground != ground) proc_lookup->ground = ground; - if (ground == STC_APP_STATE_BACKGROUND) { - if (__get_background_state()) { - place_pids_to_net_cgroup(proc_key.pid, STC_BACKGROUND_APP_ID); - } else { - char *background_app_id = g_strconcat(app_key.app_id, - STC_BACKGROUND_APP_SUFFIX, NULL); - place_pids_to_net_cgroup(proc_key.pid, background_app_id); - g_free(background_app_id); - } - } else { + if (ground == STC_APP_STATE_BACKGROUND && __get_background_state()) + place_pids_to_net_cgroup(proc_key.pid, STC_BACKGROUND_APP_ID); + else place_pids_to_net_cgroup(proc_key.pid, app_key.app_id); - } return ret; } -- 2.7.4 From 1e43de3cef3def735d5bf304900d34154f3cf2bc Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Thu, 20 Jul 2017 16:23:51 +0530 Subject: [PATCH 13/16] Monitoring system wide IPv4 and IPv6 data usage. Change-Id: I66e8b7af58f7e4fc79b4cbf94581738218726311 Signed-off-by: Nishant Chaprana --- include/stc-manager-util.h | 18 ++-- include/stc-manager.h | 4 + packaging/stc-manager.spec | 2 +- src/database/tables/table-statistics.c | 1 + src/helper/helper-cgroup.c | 65 ----------- src/helper/helper-cgroup.h | 7 -- src/helper/helper-net-cls.c | 15 ++- src/helper/helper-nfacct-rule.c | 174 +++++++++++++++--------------- src/helper/helper-nfacct-rule.h | 33 +++--- src/helper/helper-restriction.c | 39 ------- src/helper/helper-restriction.h | 32 ------ src/monitor/stc-monitor.c | 192 ++++++++++++++++++++++++++------- 12 files changed, 285 insertions(+), 297 deletions(-) delete mode 100755 src/helper/helper-restriction.c delete mode 100755 src/helper/helper-restriction.h diff --git a/include/stc-manager-util.h b/include/stc-manager-util.h index 7a19fcb..d5ee410 100755 --- a/include/stc-manager-util.h +++ b/include/stc-manager-util.h @@ -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, }; diff --git a/include/stc-manager.h b/include/stc-manager.h index c82c3af..160da59 100755 --- a/include/stc-manager.h +++ b/include/stc-manager.h @@ -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; diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 8f96ff2..4668ee5 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -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 diff --git a/src/database/tables/table-statistics.c b/src/database/tables/table-statistics.c index d28ec86..0f5db95 100755 --- a/src/database/tables/table-statistics.c +++ b/src/database/tables/table-statistics.c @@ -105,6 +105,7 @@ "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" diff --git a/src/helper/helper-cgroup.c b/src/helper/helper-cgroup.c index af9f1f1..aa01d16 100755 --- a/src/helper/helper-cgroup.c +++ b/src/helper/helper-cgroup.c @@ -24,26 +24,6 @@ #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) { diff --git a/src/helper/helper-cgroup.h b/src/helper/helper-cgroup.h index 273036c..725cad4 100755 --- a/src/helper/helper-cgroup.h +++ b/src/helper/helper-cgroup.h @@ -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); diff --git a/src/helper/helper-net-cls.c b/src/helper/helper-net-cls.c index 1c22608..0f2ae30 100755 --- a/src/helper/helper-net-cls.c +++ b/src/helper/helper-net-cls.c @@ -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 diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index b46b3a4..3c365ee 100755 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -47,13 +47,11 @@ #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; } diff --git a/src/helper/helper-nfacct-rule.h b/src/helper/helper-nfacct-rule.h index 2220868..89eb27c 100755 --- a/src/helper/helper-nfacct-rule.h +++ b/src/helper/helper-nfacct-rule.h @@ -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 index fb15856..0000000 --- a/src/helper/helper-restriction.c +++ /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 index 51b959e..0000000 --- a/src/helper/helper-restriction.h +++ /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__ */ diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 19e4b90..08f1065 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -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); -- 2.7.4 From d4e3bde7ecdff26045d9e11c4e1aa4b2022d7bbd Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Tue, 25 Jul 2017 19:01:31 +0530 Subject: [PATCH 14/16] Fix: Fetching granularized data usage issue. Description: This patch fixes the scenario where multiple entries are sent to upper layer because of granularity, also this patch fixes faulty fill operation when data is fetched from database. Change-Id: Ifbd7fcd646f461277bdd8bc90379f452032b05fe Signed-off-by: Nishant Chaprana --- interfaces/stcmanager-iface-statistics.xml | 2 +- packaging/stc-manager.spec | 2 +- src/database/tables/table-statistics.c | 11 ++++++----- src/stc-statistics.c | 20 +++++++++++++------- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/interfaces/stcmanager-iface-statistics.xml b/interfaces/stcmanager-iface-statistics.xml index 42b5c80..825da54 100644 --- a/interfaces/stcmanager-iface-statistics.xml +++ b/interfaces/stcmanager-iface-statistics.xml @@ -12,7 +12,7 @@ - + diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 4668ee5..fafa1dd 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.26 +Version: 0.0.27 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/database/tables/table-statistics.c b/src/database/tables/table-statistics.c index 0f5db95..9564d8e 100755 --- a/src/database/tables/table-statistics.c +++ b/src/database/tables/table-statistics.c @@ -55,16 +55,16 @@ #define SELECT_CHUNKS "select binpath, hw_net_protocol_type, " \ "is_roaming, sum(received) as received, " \ "sum(sent) as sent, imsi, ground, iftype, ifname, " \ - "time_stamp - time_stamp % ? as time_stamp " \ + "time_stamp - time_stamp % ? as timestamp " \ "from statistics where time_stamp between ? and ? " \ - "group by binpath, time_stamp, imsi order by time_stamp" + "group by binpath, timestamp, imsi order by timestamp" #define SELECT_CHUNKS_IFACE "select binpath, hw_net_protocol_type, " \ "is_roaming, sum(received) as received, " \ "sum(sent) as sent, imsi, ground, iftype, ifname, " \ - "time_stamp - time_stamp % ? as time_stamp " \ + "time_stamp - time_stamp % ? as timestamp " \ "from statistics where time_stamp between ? and ? and iftype=?" \ - "group by binpath, time_stamp, imsi order by time_stamp" + "group by binpath, timestamp, imsi order by timestamp" #define SELECT_APP_DETAILS "select iftype, hw_net_protocol_type, " \ "is_roaming, sum(received) as received, sum(sent) as sent, " \ @@ -557,9 +557,10 @@ stc_error_e table_statistics_per_app(const char *app_id, data.cnt.out_bytes = sqlite3_column_int64(stmt, 4); data.ifname = (char *)sqlite3_column_text(stmt, 5); data.imsi = (char *)sqlite3_column_text(stmt, 6); + data.ground = sqlite3_column_int(stmt, 7); if (rule->granularity) { - interval.from = sqlite3_column_int64(stmt, 7); + interval.from = sqlite3_column_int64(stmt, 8); interval.to = interval.from + rule->granularity; } diff --git a/src/stc-statistics.c b/src/stc-statistics.c index ec52aeb..b20e3bb 100755 --- a/src/stc-statistics.c +++ b/src/stc-statistics.c @@ -167,11 +167,13 @@ void __stc_statistics_app_info_builder_add(GVariantBuilder *builder, return; } - g_variant_builder_add(builder, "{sv}", "app_id", - g_variant_new_string(info->app_id)); + if (info->app_id) + g_variant_builder_add(builder, "{sv}", "app_id", + g_variant_new_string(info->app_id)); - g_variant_builder_add(builder, "{sv}", "ifname", - g_variant_new_string(info->ifname)); + if (info->ifname) + g_variant_builder_add(builder, "{sv}", "ifname", + g_variant_new_string(info->ifname)); g_variant_builder_add(builder, "{sv}", "imsi", g_variant_new_string(info->imsi)); @@ -232,14 +234,18 @@ stc_cb_ret_e __table_statistics_per_app_cb(const table_statistics_info *info, { __STC_LOG_FUNC_ENTER__; GVariantBuilder *builder = (GVariantBuilder *)user_data; + GVariantBuilder sub_builder; if (!info || !builder) { __STC_LOG_FUNC_EXIT__; return STC_CANCEL; } - __stc_statistics_app_info_builder_add(builder, info); + g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}")); + __stc_statistics_app_info_builder_add(&sub_builder, info); __stc_statistics_print_app_info(info); + g_variant_builder_add_value(builder, + g_variant_builder_end(&sub_builder)); __STC_LOG_FUNC_EXIT__; return STC_CONTINUE; @@ -346,7 +352,7 @@ gboolean handle_statistics_get(StcStatistics *object, STC_LOGD("No selection rule, using default selection rule."); } - builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}")); ret = table_statistics_per_app(app_id, &rule, __table_statistics_per_app_cb, @@ -358,7 +364,7 @@ gboolean handle_statistics_get(StcStatistics *object, return TRUE; } - return_parameters = g_variant_new("(ia{sv})", STC_ERROR_NONE, builder); + return_parameters = g_variant_new("(iaa{sv})", STC_ERROR_NONE, builder); g_variant_builder_unref(builder); DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); -- 2.7.4 From c570781b44cc2e72ee0c770769ce01d51f7d9361 Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Wed, 26 Jul 2017 10:31:13 +0530 Subject: [PATCH 15/16] Ignoring values of TOTAL_* details when fetching interface data. Description: When fetching interface related data and chunk data TOTAL_IPV4, TOTAL_IPV6, TOTAL_WIFI, TOTAL_BLUETOOTH, TOTAL_DATACALL app_id were increasing redundant data in fetch query. Change-Id: Icc074219dfd9e83832d7f193040969fd23a30d43 Signed-off-by: Nishant Chaprana --- packaging/stc-manager.spec | 2 +- src/database/tables/table-statistics.c | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index fafa1dd..a15bc75 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -1,6 +1,6 @@ Name: stc-manager Summary: STC(Smart Traffic Control) manager -Version: 0.0.27 +Version: 0.0.28 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/database/tables/table-statistics.c b/src/database/tables/table-statistics.c index 9564d8e..1b6d288 100755 --- a/src/database/tables/table-statistics.c +++ b/src/database/tables/table-statistics.c @@ -103,9 +103,8 @@ #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 ?) and binpath != 'TOTAL_DATACALL' " \ - "and binpath != 'TOTAL_WIFI' and binpath != 'TOTAL_BLUETOOTH' " \ - "and binpath != 'TOTAL_IPV4' and binpath != 'TOTAL_IPV6' " \ + "where (time_stamp between ? and ?) " \ + "and binpath NOT LIKE 'TOTAL_%' " \ "group by iftype, ifname, imsi, hw_net_protocol_type, is_roaming " \ "order by time_stamp, iftype, ifname, imsi, hw_net_protocol_type, " \ "is_roaming" @@ -113,8 +112,8 @@ #define SELECT_TOTAL_IFACE "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 ?) " \ - "and iftype=? " \ + "where (time_stamp between ? and ?) and iftype=? " \ + "and binpath NOT LIKE 'TOTAL_%' " \ "group by hw_net_protocol_type, is_roaming, " \ "iftype, ifname, imsi " \ "order by time_stamp, iftype, ifname, imsi, hw_net_protocol_type, " \ @@ -124,6 +123,7 @@ "is_roaming, sum(received) as received, sum(sent) as sent, " \ "ifname, imsi, ground, time_stamp - time_stamp % ? as time_stamp " \ "from statistics where time_stamp between ? and ? " \ + "and binpath NOT LIKE 'TOTAL_%' " \ "group by time_stamp, iftype, ifname, imsi, hw_net_protocol_type, " \ "is_roaming " \ "order by time_stamp, iftype, ifname, imsi, hw_net_protocol_type, " \ @@ -134,6 +134,7 @@ "ifname, imsi, ground, time_stamp - time_stamp % ? as time_stamp " \ "from statistics where time_stamp between ? and ? " \ "and iftype = ? " \ + "and binpath NOT LIKE 'TOTAL_%' " \ "group by time_stamp, hw_net_protocol_type, is_roaming, iftype, ifname, imsi " \ "order by time_stamp, hw_net_protocol_type, is_roaming, iftype, " \ "ifname, imsi" -- 2.7.4 From fd6810bf5dfc73e813a4c56f2b22a71c643bd5c5 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Tue, 8 Aug 2017 14:37:56 +0900 Subject: [PATCH 16/16] Fixed a issue for using heap after free Change-Id: I6d79e47857211945aa29de2de71072dc98835bd4 Signed-off-by: hyunuktak --- src/database/db-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/database/db-common.c b/src/database/db-common.c index d2ad1ea..3895e12 100755 --- a/src/database/db-common.c +++ b/src/database/db-common.c @@ -75,6 +75,7 @@ stc_error_e stc_db_initialize_once(void) STC_LOGE("Can't set locking mode %s, skip set busy handler.", sqlite3_errmsg(database)); sqlite3_close(database); + database = NULL; __STC_LOG_FUNC_EXIT__; return STC_ERROR_DB_FAILED; } -- 2.7.4