From 1551dfc74c889b900b6967bbc76ba83a6edc4ec1 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Tue, 10 Oct 2017 14:33:38 +0900 Subject: [PATCH 01/16] Extract file name using /usr/apps keyword And ignore blank space Change-Id: I36813811a9f0ad358d591ae197de0034c326486a Signed-off-by: hyunuktak --- src/helper/helper-procfs.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/helper/helper-procfs.c b/src/helper/helper-procfs.c index ca291ac..168c34a 100755 --- a/src/helper/helper-procfs.c +++ b/src/helper/helper-procfs.c @@ -38,12 +38,16 @@ #include "stc-manager-util.h" #include "helper-procfs.h" +#define USRAPPS "/usr/apps/" + int proc_get_cmdline(pid_t pid, char *cmdline) { char buf[PROC_BUF_MAX]; char cmdline_buf[PROC_NAME_MAX]; char *filename; FILE *fp; + char *token = NULL; + char *saveptr = NULL; snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); fp = fopen(buf, "r"); @@ -56,11 +60,24 @@ int proc_get_cmdline(pid_t pid, char *cmdline) } fclose(fp); - filename = strrchr(cmdline_buf, '/'); - if (filename == NULL) - filename = cmdline_buf; - else - filename = filename + 1; + if (g_strstr_len(cmdline_buf, strlen(USRAPPS), USRAPPS) != NULL) { + /* Application */ + filename = cmdline_buf + strlen(USRAPPS); + token = strtok_r(filename, "/", &saveptr); + if (token != NULL) + filename = token; + } else { + token = strtok_r(cmdline_buf, " ", &saveptr); + if (token != NULL) + filename = strrchr(token, '/'); + else + filename = strrchr(cmdline_buf, '/'); + + if (filename == NULL) + filename = cmdline_buf; + else + filename = filename + 1; + } strncpy(cmdline, filename, PROC_NAME_MAX-1); -- 2.7.4 From f32f457577783c55aaee0a86f6cebf34f49a9362 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Tue, 10 Oct 2017 14:37:42 +0900 Subject: [PATCH 02/16] Fixed coverity issues Change-Id: I19f27469c22bc1662c8a33afc92f3bebdc2c560d Signed-off-by: hyunuktak --- src/helper/helper-nfacct-rule.c | 6 +++--- src/monitor/stc-monitor.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index aec0ef3..bd86b01 100755 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -278,15 +278,15 @@ bool recreate_counter_by_name(char *cnt_name, nfacct_rule_s *cnt) iface = get_iftype_by_name(ifname_buf); /* check first part is it datacall */ if (iface == STC_IFACE_DATACALL) { - strncpy(cnt->ifname, ifname_buf, MAX_IFACE_LENGTH); + strncpy(cnt->ifname, ifname_buf, MAX_IFACE_LENGTH - 1); cnt->iotype = NFACCT_COUNTER_IN; } else { /* +1, due : symbol and till the end of cnt_name */ - strncpy(ifname_buf, iftype_part + 1, MAX_IFACE_LENGTH); + strncpy(ifname_buf, iftype_part + 1, MAX_IFACE_LENGTH - 1); iface = get_iftype_by_name(ifname_buf); if (iface == STC_IFACE_DATACALL) { cnt->iotype = NFACCT_COUNTER_OUT; - strncpy(cnt->ifname, ifname_buf, MAX_IFACE_LENGTH); + strncpy(cnt->ifname, ifname_buf, MAX_IFACE_LENGTH - 1); } } diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index a50d65b..522a615 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -716,7 +716,7 @@ static stc_error_e __close_and_reopen_contr_sock(stc_system_s *system) /* create netlink socket for updating kernel counters */ system->contr_sock = create_netlink(NETLINK_NETFILTER, 0); - if (!(system->contr_sock)) { + if (system->contr_sock < 0) { STC_LOGE("failed to open socket"); FREE(system); return STC_ERROR_FAIL; @@ -1599,7 +1599,7 @@ stc_error_e stc_monitor_init(void) /* create netlink socket for updating kernel counters */ system->contr_sock = create_netlink(NETLINK_NETFILTER, 0); - if (!(system->contr_sock)) { + if (system->contr_sock < 0) { STC_LOGE("failed to open socket"); FREE(system); return STC_ERROR_FAIL; -- 2.7.4 From a2bb048375d5726c415de33cb5f501b569cf0105 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Tue, 10 Oct 2017 14:42:33 +0900 Subject: [PATCH 03/16] Added exceptions for system call and bracket Change-Id: Ib28764520292f29b4378620680d3391ef2308c93 Signed-off-by: hyunuktak --- data/exceptions | 22 ++++++++++++++++++++-- src/monitor/stc-app-lifecycle.c | 6 +++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/data/exceptions b/data/exceptions index 0429338..2ce70b0 100644 --- a/data/exceptions +++ b/data/exceptions @@ -17,14 +17,32 @@ sleep:inst grep:inst killall:inst systemctl:inst +xargs:inst +modprobe:inst +pkgcmd:inst +mount:inst +chmod:inst wlan.sh:script wpa_supp.sh:script +stc-manager:sys dlogutil:sys wifi-loader:sys -launchpad-loader:sys wrt-loader:sys dotnet-launcher:sys iptables:sys ip6tables:sys -modprobe:inst net-cls-release:sys +init:sys +amd:sys +launchpad-loader:sys +launchpad-process-pool:sys +deviced:sys +systemd:sys +systemd-udevd:sys +systemd-user:sys +systemd-cgroups-agent:sys +systemd-journald:sys +sdbd:sys +sdbd-user:sys +pushd:sys +dbus-daemon:sys diff --git a/src/monitor/stc-app-lifecycle.c b/src/monitor/stc-app-lifecycle.c index 09fcef0..235dc04 100755 --- a/src/monitor/stc-app-lifecycle.c +++ b/src/monitor/stc-app-lifecycle.c @@ -204,8 +204,12 @@ static void __proc_tree_remove(const proc_key_s *key) static gboolean __check_excn(char *cmdline) { - stc_error_e ret = stc_monitor_check_excn_by_cmdline(cmdline); + stc_error_e ret = STC_ERROR_NONE; + + if (cmdline[0] == '(') + return TRUE; + ret = stc_monitor_check_excn_by_cmdline(cmdline); if (ret == STC_ERROR_NO_DATA) return FALSE; else -- 2.7.4 From 754b1ad89442526794acd69a395aa08a5bfc17e1 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Tue, 10 Oct 2017 14:48:27 +0900 Subject: [PATCH 04/16] Added information config with inotify Change-Id: If6faf890e69fa7a2de05d362aada815c29778411 Signed-off-by: hyunuktak --- include/stc-manager-util.h | 13 +++ include/stc-manager.h | 2 +- packaging/stc-manager.spec | 2 +- plugin/stc-plugin.c | 4 +- src/helper/helper-cgroup.c | 21 ++-- src/helper/helper-inotify.c | 206 ++++++++++++++++++++++++++++++++++++++++ src/helper/helper-inotify.h | 32 +++++++ src/helper/helper-net-cls.c | 3 +- src/helper/helper-nfacct-rule.c | 18 ++-- src/monitor/stc-app-lifecycle.c | 33 +++---- src/monitor/stc-monitor.c | 26 ++--- src/stc-manager-util.c | 142 +++++++++++++++++++++++++++ src/stc-manager.c | 42 ++++++++ 13 files changed, 484 insertions(+), 60 deletions(-) create mode 100755 src/helper/helper-inotify.c create mode 100755 src/helper/helper-inotify.h create mode 100755 src/stc-manager-util.c diff --git a/include/stc-manager-util.h b/include/stc-manager-util.h index 708f67c..d504cf3 100755 --- a/include/stc-manager-util.h +++ b/include/stc-manager-util.h @@ -327,6 +327,10 @@ static inline bool strstart_with(const char *str, const char *with) #define CGROUP_FILE_NAME "cgroup.procs" #define UNKNOWN_APP "(unknown)" +#define INFO_STORAGE_DIR "/var/lib/stc" +#define INFO_CONFIG "info.config" +#define INFO_DEBUGLOG "debuglog" + #define MAX_PATH_LENGTH 512 #define MAX_NAME_LENGTH 256 #define MAX_IFACE_LENGTH 32 @@ -381,4 +385,13 @@ enum stc_counter_state { STC_UPDATE_REQUESTED = 1 << 5, }; +gboolean stc_util_get_config_bool(char *key); +gchar * stc_util_get_config_str(char *key); +int stc_util_get_config_int(char *key); + +void stc_util_set_debuglog(int debuglog); +int stc_util_get_debuglog(void); + +void stc_util_initialize_config(void); + #endif /* __STC_MANAGER_UTIL_H__ */ diff --git a/include/stc-manager.h b/include/stc-manager.h index 37e5d97..2766a60 100755 --- a/include/stc-manager.h +++ b/include/stc-manager.h @@ -31,7 +31,7 @@ #define STC_TOTAL_IPV4 "TOTAL_IPV4" #define STC_TOTAL_IPV6 "TOTAL_IPV6" -#define STC_DEBUG_LOG 0 +#define STC_DEBUG_LOG (stc_util_get_debuglog()) typedef enum { STC_CANCEL = 0, /**< cancel */ diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index d0e6065..cf69262 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.35 +Version: 0.0.36 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/plugin/stc-plugin.c b/plugin/stc-plugin.c index db83094..916a75e 100755 --- a/plugin/stc-plugin.c +++ b/plugin/stc-plugin.c @@ -91,11 +91,11 @@ static void __stc_gdbus_handle_aul_changestate(GDBusConnection *connection, else apptype = STC_APP_TYPE_GUI; -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) { STC_LOGD("\033[1;36mAPP STATUS\033[0;m: Pkg ID [\033[0;34m%s\033[0;m], " "App ID [\033[0;32m%s\033[0;m], PID [\033[1;33m%d\033[0;m], Status [%s], Type [%s]", pkgid, appid, pid, statstr, pkgtype); -#endif + } if (state_changed_cb) state_changed_cb(status, pid, appid, pkgid, apptype); diff --git a/src/helper/helper-cgroup.c b/src/helper/helper-cgroup.c index c636bc2..8c258a5 100755 --- a/src/helper/helper-cgroup.c +++ b/src/helper/helper-cgroup.c @@ -116,9 +116,10 @@ int cgroup_write_node_uint32(const char *cgroup_name, { char buf[MAX_PATH_LENGTH]; snprintf(buf, sizeof(buf), "%s/%s", cgroup_name, file_name); -#if STC_DEBUG_LOG - STC_LOGD("cgroup_buf %s, value %d\n", buf, value); -#endif + + if (STC_DEBUG_LOG) + STC_LOGD("cgroup_buf %s, value %d\n", buf, value); + return fwrite_uint(buf, value); } @@ -127,9 +128,10 @@ int cgroup_write_node_str(const char *cgroup_name, { char buf[MAX_PATH_LENGTH]; snprintf(buf, sizeof(buf), "%s/%s", cgroup_name, file_name); -#if STC_DEBUG_LOG - STC_LOGD("cgroup_buf %s, string %s\n", buf, string); -#endif + + if (STC_DEBUG_LOG) + STC_LOGD("cgroup_buf %s, string %s\n", buf, string); + return fwrite_str(buf, string); } @@ -140,9 +142,10 @@ int cgroup_read_node_uint32(const char *cgroup_name, int ret; snprintf(buf, sizeof(buf), "%s/%s", cgroup_name, file_name); ret = fread_uint(buf, value); -#if STC_DEBUG_LOG - STC_LOGD("cgroup_buf %s, value %d\n", buf, *value); -#endif + + if (STC_DEBUG_LOG) + STC_LOGD("cgroup_buf %s, value %d\n", buf, *value); + return ret; } diff --git a/src/helper/helper-inotify.c b/src/helper/helper-inotify.c new file mode 100755 index 0000000..71e30e2 --- /dev/null +++ b/src/helper/helper-inotify.c @@ -0,0 +1,206 @@ +/* + * 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 "helper-inotify.h" +#include "stc-manager-util.h" + +typedef struct { + GIOChannel *channel; + uint watch; + int wd; + + inotify_event_cb cb; +} stc_inotify_s; + +static GHashTable *g_inotify_hash; + +static gboolean __inotify_data(GIOChannel *channel, GIOCondition cond, + gpointer user_data) +{ + stc_inotify_s *inotify = user_data; + char buffer[sizeof(struct inotify_event) + NAME_MAX + 1]; + char *next_event; + gsize bytes_read; + GIOStatus status; + + if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { + inotify->watch = 0; + return FALSE; + } + + status = g_io_channel_read_chars(channel, buffer, + sizeof(buffer), &bytes_read, NULL); + + switch (status) { + case G_IO_STATUS_NORMAL: + break; + case G_IO_STATUS_AGAIN: + return TRUE; + default: + STC_LOGE("Reading from inotify channel failed"); + inotify->watch = 0; + return FALSE; + } + + next_event = buffer; + + while (bytes_read > 0) { + struct inotify_event *event; + gchar *ident; + gsize len; + inotify_event_cb callback = inotify->cb; + + event = (struct inotify_event *) next_event; + if (event->len) + ident = next_event + sizeof(struct inotify_event); + else + ident = NULL; + + len = sizeof(struct inotify_event) + event->len; + if (len > bytes_read) + break; + + next_event += len; + bytes_read -= len; + + (*callback)(event, ident); + } + + return TRUE; +} + +static void __remove_watch(stc_inotify_s *inotify) +{ + int fd; + + if (!inotify->channel) + return; + + if (inotify->watch > 0) + g_source_remove(inotify->watch); + + fd = g_io_channel_unix_get_fd(inotify->channel); + + if (inotify->wd >= 0) + inotify_rm_watch(fd, inotify->wd); + + g_io_channel_unref(inotify->channel); +} + +static int __create_watch(const char *path, stc_inotify_s *inotify) +{ + int fd; + + STC_LOGD("Add directory watch for [%s]", path); + + fd = inotify_init(); + if (fd < 0) + return -EIO; + + inotify->wd = inotify_add_watch(fd, path, + IN_MODIFY | IN_CREATE | IN_DELETE | + IN_MOVED_TO | IN_MOVED_FROM); + if (inotify->wd < 0) { + STC_LOGE("Creation of [%s] watch failed", path); + close(fd); + return -EIO; + } + + inotify->channel = g_io_channel_unix_new(fd); + if (!inotify->channel) { + STC_LOGE("Creation of inotify channel failed"); + inotify_rm_watch(fd, inotify->wd); + inotify->wd = 0; + + close(fd); + return -EIO; + } + + g_io_channel_set_close_on_unref(inotify->channel, TRUE); + g_io_channel_set_encoding(inotify->channel, NULL, NULL); + g_io_channel_set_buffered(inotify->channel, FALSE); + + inotify->watch = g_io_add_watch(inotify->channel, + G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR, + __inotify_data, inotify); + + return 0; +} + +static void __inotify_destroy(gpointer user_data) +{ + stc_inotify_s *inotify = user_data; + + __remove_watch(inotify); + FREE(inotify); +} + +int inotify_register(const char *path, inotify_event_cb callback) +{ + int err; + stc_inotify_s *inotify; + + if (!callback) + return -EINVAL; + + inotify = g_hash_table_lookup(g_inotify_hash, path); + if (inotify) + goto update; + + inotify = g_try_new0(stc_inotify_s, 1); + if (!inotify) + return -ENOMEM; + + inotify->wd = -1; + + err = __create_watch(path, inotify); + if (err < 0) { + FREE(inotify); + return err; + } + + g_hash_table_replace(g_inotify_hash, g_strdup(path), inotify); + +update: + inotify->cb = callback; + + return 0; +} + +void inotify_deregister(const char *path) +{ + stc_inotify_s *inotify; + + inotify = g_hash_table_lookup(g_inotify_hash, path); + if (!inotify) + return; + + g_hash_table_remove(g_inotify_hash, path); +} + +int inotify_initialize(void) +{ + g_inotify_hash = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, __inotify_destroy); + return 0; +} + +void inotify_deinitialize(void) +{ + g_hash_table_destroy(g_inotify_hash); +} diff --git a/src/helper/helper-inotify.h b/src/helper/helper-inotify.h new file mode 100755 index 0000000..1fe9d66 --- /dev/null +++ b/src/helper/helper-inotify.h @@ -0,0 +1,32 @@ +/* + * 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_HELPER_INOTIFY_H__ +#define __STC_HELPER_INOTIFY_H__ + +#include + +struct inotify_event; +typedef void (* inotify_event_cb) (struct inotify_event *event, + const char *ident); + +int inotify_register(const char *path, inotify_event_cb callback); +void inotify_deregister(const char *path); + +int inotify_initialize(void); +void inotify_deinitialize(void); + +#endif /*__STC_HELPER_INOTIFY_H__*/ diff --git a/src/helper/helper-net-cls.c b/src/helper/helper-net-cls.c index ef5e4b3..6be717a 100755 --- a/src/helper/helper-net-cls.c +++ b/src/helper/helper-net-cls.c @@ -187,7 +187,8 @@ stc_error_e place_pids_to_net_cgroup(const int pid, const char *app_id) path_to_net_cgroup_dir = FOREGROUND_CGROUP_NETWORK; if (access(child_buf, F_OK)) { - STC_LOGD("%s of %s is not existed", child_buf, app_id); + if (STC_DEBUG_LOG) + STC_LOGD("%s of %s is not existed", child_buf, app_id); return cgroup_write_pid(path_to_net_cgroup_dir, app_id, pid); } diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index bd86b01..ca3a7a9 100755 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -136,7 +136,8 @@ static stc_error_e nfacct_send_new(nfacct_rule_s *counter) prepare_netlink_msg(&req, NFNL_MSG_ACCT_NEW, NLM_F_CREATE | NLM_F_ACK); add_string_attr(&req, counter->name, NFACCT_NAME); - STC_LOGD("counter name %s", counter->name); + if (STC_DEBUG_LOG) + STC_LOGD("counter name %s", counter->name); /* padding */ add_uint64_attr(&req, 0, NFACCT_PKTS); @@ -156,9 +157,8 @@ stc_error_e nfacct_send_del(nfacct_rule_s *counter) { struct genl req; -#if STC_DEBUG_LOG - STC_LOGD("send remove request for %s", counter->name); -#endif + if (STC_DEBUG_LOG) + STC_LOGD("send remove request for %s", counter->name); prepare_netlink_msg(&req, NFNL_MSG_ACCT_DEL, NLM_F_ACK); add_string_attr(&req, counter->name, NFACCT_NAME); @@ -418,9 +418,8 @@ stc_error_e exec_iptables_cmd(const char *cmd_buf, pid_t *cmd_pid) int ret; char *save_ptr = NULL; -#if STC_DEBUG_LOG - STC_LOGD("executing iptables cmd %s in forked process", cmd_buf); -#endif + if (STC_DEBUG_LOG) + STC_LOGD("executing iptables cmd %s in forked process", cmd_buf); args[0] = "iptables"; cmd = strtok_r((char *)cmd_buf, " ", &save_ptr); @@ -464,9 +463,8 @@ stc_error_e exec_ip6tables_cmd(const char *cmd_buf, pid_t *cmd_pid) int ret; char *save_ptr = NULL; -#if STC_DEBUG_LOG - STC_LOGD("executing ip6tables cmd %s in forked process", cmd_buf); -#endif + if (STC_DEBUG_LOG) + STC_LOGD("executing ip6tables cmd %s in forked process", cmd_buf); args[0] = "ip6tables"; cmd = strtok_r((char *)cmd_buf, " ", &save_ptr); diff --git a/src/monitor/stc-app-lifecycle.c b/src/monitor/stc-app-lifecycle.c index 235dc04..eb18816 100755 --- a/src/monitor/stc-app-lifecycle.c +++ b/src/monitor/stc-app-lifecycle.c @@ -101,7 +101,6 @@ static proc_value_s * __proc_tree_lookup(const proc_key_s *key) return lookup; } -#if STC_DEBUG_LOG static gboolean __proc_tree_foreach_print(gpointer key, gpointer value, gpointer data) { @@ -119,7 +118,6 @@ static void __proc_tree_printall(void) { g_tree_foreach(proc_tree, __proc_tree_foreach_print, NULL); } -#endif static proc_value_s * __proc_tree_find_parent(proc_value_s *value) { @@ -134,14 +132,14 @@ static proc_value_s * __proc_tree_find_parent(proc_value_s *value) parent = lookup; } while (lookup); -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) { if (parent != NULL) STC_LOGD("\033[0;35mPARENT\033[0;m: tgid[\033[1;33m%s\033[0;m] pid[%s] " "ppid[\033[1;35m%s\033[0;m] cmdline[\033[0;34m%s\033[0;m] name[%s]", parent->status[PROC_STATUS_TGID], parent->status[PROC_STATUS_PID], parent->status[PROC_STATUS_PPID], parent->cmdline, parent->status[PROC_STATUS_NAME]); -#endif + } return parent; } @@ -159,12 +157,11 @@ static void __proc_tree_add(proc_key_s *key, lookup = g_tree_lookup(proc_tree, key); if (lookup) { -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) STC_LOGD("LOOKUP: tgid[\033[1;33m%s\033[0;m] pid[%s] ppid[\033[1;35m%s\033[0;m] " "cmdline[\033[0;34m%s\033[0;m] name[%s]", lookup->status[PROC_STATUS_TGID], lookup->status[PROC_STATUS_PID], lookup->status[PROC_STATUS_PPID], lookup->cmdline, lookup->status[PROC_STATUS_NAME]); -#endif return; } @@ -173,9 +170,8 @@ static void __proc_tree_add(proc_key_s *key, g_tree_insert(proc_tree, key, value); -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) __proc_tree_printall(); -#endif parent = __proc_tree_find_parent(value); if (parent != NULL) @@ -195,11 +191,11 @@ static void __proc_tree_remove(const proc_key_s *key) stc_manager_app_status_changed(STC_CMD_SET_TERMINATED, key->pid, NULL, NULL, STC_APP_TYPE_NONE); + g_tree_remove(proc_tree, key); -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) __proc_tree_printall(); -#endif } static gboolean __check_excn(char *cmdline) @@ -403,9 +399,8 @@ static void __process_event_fork(int tgid, int pid) STC_ERROR_NONE == proc_get_status(pid, status)) { if (__check_excn(cmdline)) { -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) STC_LOGD("[%s] monitoring is excepted", cmdline); -#endif return; } @@ -431,13 +426,13 @@ static void __process_event_fork(int tgid, int pid) g_strlcpy(value->status[i], status[i], sizeof(value->status[i])); g_strlcpy(value->cmdline, cmdline, sizeof(value->cmdline)); -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) { STC_LOGD("\033[1;34mFORK\033[0;m: tgid[\033[1;33m%d\033[0;m] ppid=[\033[1;35m%s\033[0;m] " "cmdline[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], cmdline, pid); STC_LOGD("STATUS: tgid[%s] pid[%s] ppid[%s] name[%s] state[%s] tracerpid[%s]", status[PROC_STATUS_TGID], status[PROC_STATUS_PID], status[PROC_STATUS_PPID], status[PROC_STATUS_NAME], status[PROC_STATUS_STATE], status[PROC_STATUS_TRACERPID]); -#endif + } __proc_tree_add(key, value); } @@ -452,9 +447,8 @@ static void __process_event_exec(int tgid, int pid) STC_ERROR_NONE == proc_get_status(pid, status)) { if (__check_excn(cmdline)) { -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) STC_LOGD("[%s] monitoring is excepted", cmdline); -#endif return; } @@ -480,13 +474,13 @@ static void __process_event_exec(int tgid, int pid) g_strlcpy(value->status[i], status[i], sizeof(value->status[i])); g_strlcpy(value->cmdline, cmdline, sizeof(value->cmdline)); -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) { STC_LOGD("\033[1;32mEXEC\033[0;m: tgid[\033[1;33m%d\033[0;m] ppid=[\033[1;35m%s\033[0;m] " "cmdline[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], cmdline, pid); STC_LOGD("STATUS: tgid[%s] pid[%s] ppid[%s] name[%s] state[%s] tracerpid[%s]", status[PROC_STATUS_TGID], status[PROC_STATUS_PID], status[PROC_STATUS_PPID], status[PROC_STATUS_NAME], status[PROC_STATUS_STATE], status[PROC_STATUS_TRACERPID]); -#endif + } __proc_tree_add(key, value); } @@ -505,10 +499,9 @@ static void __process_event_exit(int tgid, int pid, int exit_code) if (lookup == NULL) /* unmonitored process */ return; -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) STC_LOGD("\033[1;31mEXIT\033[0;m: tgid[\033[1;33m%d\033[0;m] " "pid[%d] exitcode[\033[0;31m%d\033[0;m]", tgid, pid, exit_code); -#endif __proc_tree_remove(&key); } diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 522a615..1cc0b5e 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -276,7 +276,6 @@ static void __rstns_tree_key_free(gpointer data) FREE(key); } -#if STC_DEBUG_LOG static gboolean __processes_tree_foreach_print(gpointer key, gpointer value, gpointer data) { @@ -314,7 +313,6 @@ static void __apps_tree_printall(void) { g_tree_foreach(g_system->apps, __apps_tree_foreach_print, NULL); } -#endif static gboolean __apps_tree_foreach_remove_pid(gpointer key, gpointer value, gpointer data) @@ -323,9 +321,8 @@ static gboolean __apps_tree_foreach_remove_pid(gpointer key, gpointer value, stc_app_value_s *app_value = (stc_app_value_s *)value; if (!g_tree_remove(app_value->processes, context->proc_key)) { -#if STC_DEBUG_LOG - STC_LOGD("key not found"); -#endif + if (STC_DEBUG_LOG) + STC_LOGD("key not found"); return FALSE; } @@ -966,18 +963,16 @@ static void __app_counter_update(stc_app_key_s *app_key, app_value->counter.in_bytes = context->bytes; g_system->apps_tree_updated = TRUE; -#if STC_DEBUG_LOG - __apps_tree_foreach_print(app_key, app_value, NULL); -#endif + if (STC_DEBUG_LOG) + __apps_tree_foreach_print(app_key, app_value, NULL); break; case NFACCT_COUNTER_OUT: app_value->data_usage.out_bytes += context->bytes; app_value->counter.out_bytes = context->bytes; g_system->apps_tree_updated = TRUE; -#if STC_DEBUG_LOG - __apps_tree_foreach_print(app_key, app_value, NULL); -#endif + if (STC_DEBUG_LOG) + __apps_tree_foreach_print(app_key, app_value, NULL); break; default: STC_LOGE("unknown iotype"); @@ -1036,7 +1031,8 @@ static void __fill_nfacct_result(char *cnt_name, int64_t bytes, .data_limit_reached = FALSE, }; - STC_LOGD("cnt_name %s", cnt_name); + if (STC_DEBUG_LOG) + STC_LOGD("cnt_name %s", cnt_name); if (!recreate_counter_by_name(cnt_name, &counter)) { STC_LOGE("Can't parse counter name %s", cnt_name); @@ -1780,9 +1776,8 @@ stc_error_e stc_monitor_process_add(const stc_app_key_s app_key, /* add pid to application cgroup */ place_pids_to_net_cgroup(proc_key.pid, app_key.app_id); -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) __apps_tree_printall(); -#endif return ret; } @@ -1808,9 +1803,8 @@ stc_error_e stc_monitor_process_remove(pid_t pid) if (context.entry_removed) __application_remove_if_empty(context.app_key); -#if STC_DEBUG_LOG + if (STC_DEBUG_LOG) __apps_tree_printall(); -#endif return ret; } diff --git a/src/stc-manager-util.c b/src/stc-manager-util.c new file mode 100755 index 0000000..1c97e81 --- /dev/null +++ b/src/stc-manager-util.c @@ -0,0 +1,142 @@ +/* + * 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 "stc-manager-util.h" + +static int g_debuglog = -1; + +static void __sync_file_to_disk(const char *path) +{ + FILE *fp = NULL; + fp = fopen(path, "a+"); + if (fp) { + fflush(fp); + fsync(fp->_fileno); + fclose(fp); + STC_LOGD("Sync the file to disk"); + } +} + +static GKeyFile *__load_key_file(const char *path) +{ + GKeyFile *keyfile = NULL; + GError *error = NULL; + + STC_LOGD("Loading [%s]", path); + + keyfile = g_key_file_new(); + + if (!g_key_file_load_from_file(keyfile, path, 0, &error)) { + STC_LOGD("Unable to load [%s] : %s", path, error->message); + g_clear_error(&error); + g_key_file_free(keyfile); + keyfile = NULL; + } + + return keyfile; +} + +static int __save_key_file(GKeyFile *keyfile, char *path) +{ + gchar *data = NULL; + gsize length = 0; + GError *error = NULL; + int ret = 0; + + data = g_key_file_to_data(keyfile, &length, NULL); + + if (!g_file_set_contents(path, data, length, &error)) { + STC_LOGD("Failed to save information : %s", error->message); + g_error_free(error); + ret = -EIO; + } + + __sync_file_to_disk(path); + + g_free(data); + return ret; +} + +gboolean stc_util_get_config_bool(char *key) +{ + char path[MAX_PATH_LENGTH]; + GKeyFile *keyfile; + + snprintf(path, sizeof(path), "%s/%s", INFO_STORAGE_DIR, INFO_CONFIG); + + keyfile = __load_key_file(path); + if (!keyfile) + keyfile = g_key_file_new(); + + return g_key_file_get_boolean(keyfile, path, key, NULL); +} + +gchar * stc_util_get_config_str(char *key) +{ + char path[MAX_PATH_LENGTH]; + GKeyFile *keyfile; + + snprintf(path, sizeof(path), "%s/%s", INFO_STORAGE_DIR, INFO_CONFIG); + + keyfile = __load_key_file(path); + if (!keyfile) + keyfile = g_key_file_new(); + + return g_key_file_get_string(keyfile, path, key, NULL); +} + +int stc_util_get_config_int(char *key) +{ + char path[MAX_PATH_LENGTH]; + GKeyFile *keyfile; + + snprintf(path, sizeof(path), "%s/%s", INFO_STORAGE_DIR, INFO_CONFIG); + + keyfile = __load_key_file(path); + if (!keyfile) + keyfile = g_key_file_new(); + + return g_key_file_get_integer(keyfile, path, key, NULL); +} + +API void stc_util_set_debuglog(int debuglog) +{ + g_debuglog = debuglog; +} + +API int stc_util_get_debuglog(void) +{ + if (g_debuglog == -1) + g_debuglog = stc_util_get_config_int(INFO_DEBUGLOG); + + return g_debuglog; +} + +void stc_util_initialize_config(void) +{ + char path[MAX_PATH_LENGTH]; + GKeyFile *keyfile; + + snprintf(path, sizeof(path), "%s/%s", INFO_STORAGE_DIR, INFO_CONFIG); + + keyfile = __load_key_file(path); + if (!keyfile) + keyfile = g_key_file_new(); + + g_key_file_set_integer(keyfile, path, INFO_DEBUGLOG, 0); + + __save_key_file(keyfile, path); +} diff --git a/src/stc-manager.c b/src/stc-manager.c index cfee380..d6e8521 100755 --- a/src/stc-manager.c +++ b/src/stc-manager.c @@ -23,12 +23,46 @@ #include "table-restrictions.h" #include "helper-cgroup.h" #include "helper-nfacct-rule.h" +#include "helper-inotify.h" #include "stc-monitor.h" #include "stc-manager-plugin.h" #include "stc-app-lifecycle.h" static stc_s *g_stc = NULL; +static gboolean __validate_ident(const char *ident) +{ + unsigned int i; + + if (!ident) + return FALSE; + + for (i = 0; i < strlen(ident); ++i) + if (!g_ascii_isprint(ident[i])) + return FALSE; + + return TRUE; +} + +static void __stc_inotify_handler(struct inotify_event *event, const char *ident) +{ + if (!ident) + return; + + if (!__validate_ident(ident)) { + STC_LOGE("Invalid ident [%s]", ident); + return; + } + + if (event->mask & IN_MODIFY) { + if (!g_strcmp0(ident, INFO_CONFIG)) { + int debug = 0; + debug = stc_util_get_config_int(INFO_DEBUGLOG); + stc_util_set_debuglog(debug); + } + } +} + static void __stc_manager_deinit(void) { __STC_LOG_FUNC_ENTER__; @@ -46,6 +80,9 @@ static void __stc_manager_deinit(void) stc_app_lifecycle_monitor_deinit(); stc_manager_plugin_deinit(); + inotify_deregister(INFO_STORAGE_DIR); + inotify_deinitialize(); + STC_LOGI("stc manager deinitialized"); FREE(g_stc); __STC_LOG_FUNC_EXIT__; @@ -64,6 +101,11 @@ static stc_s *__stc_manager_init(void) } g_stc = stc; + stc_util_initialize_config(); + + inotify_initialize(); + inotify_register(INFO_STORAGE_DIR, __stc_inotify_handler); + cgroup_set_release_agent(NET_CLS_SUBSYS, NET_RELEASE_AGENT); EXEC(STC_ERROR_NONE, stc_db_initialize()); -- 2.7.4 From 951a7b00437655c92d1a998c4e1ed4353010eb0b Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Wed, 11 Oct 2017 11:02:29 +0530 Subject: [PATCH 05/16] [Fix] Fetch proper app_id for creation of cgroup. Description: The app_id was not extracted properly from procfs. Some processes run with help of other daemons, for example org.tizen.browser app is execued using efl_webprocess. In this patch for resolving above issue, if /proc//attr/current file contains "User::Pkg::" wildcard string, then we extract app_id from above file. Otherwise we read /proc//cmdline and fetch process_name as app_id. Change-Id: I0eb46f4f675cec3f2323c0ab05388fec46c7781f Signed-off-by: Nishant Chaprana --- include/stc-plugin.h | 2 +- packaging/stc-manager.spec | 2 +- plugin/stc-plugin.c | 7 +-- src/helper/helper-inotify.h | 4 +- src/helper/helper-procfs.c | 124 +++++++++----------------------------- src/helper/helper-procfs.h | 19 ------ src/monitor/include/stc-monitor.h | 2 +- src/monitor/stc-app-lifecycle.c | 87 +++++++++++++++----------- src/monitor/stc-monitor.c | 4 +- 9 files changed, 91 insertions(+), 160 deletions(-) diff --git a/include/stc-plugin.h b/include/stc-plugin.h index 4d843b8..53cfaec 100755 --- a/include/stc-plugin.h +++ b/include/stc-plugin.h @@ -21,7 +21,7 @@ #include "stc-error.h" #include "stc-manager.h" -typedef stc_error_e (*stc_plugin_app_state_changed_cb)(stc_cmd_type_e cmd, +typedef stc_error_e(*stc_plugin_app_state_changed_cb) (stc_cmd_type_e cmd, pid_t pid, const gchar *app_id, const gchar *pkg_id, diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index cf69262..9500d61 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.36 +Version: 0.0.37 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/plugin/stc-plugin.c b/plugin/stc-plugin.c index 916a75e..3587db1 100755 --- a/plugin/stc-plugin.c +++ b/plugin/stc-plugin.c @@ -74,13 +74,12 @@ static void __stc_gdbus_handle_aul_changestate(GDBusConnection *connection, g_variant_get(parameters, AUL_APP_STATUS_DBUS_STATUS_CHANGE_TYPE, &pid, &appid, &pkgid, &statstr, &pkgtype); - if (!strncmp(statstr, "fg", 2)) { + if (!strncmp(statstr, "fg", 2)) status = STC_CMD_SET_FOREGRD; - } else if (!strncmp(statstr, "bg", 2)) { + else if (!strncmp(statstr, "bg", 2)) status = STC_CMD_SET_BACKGRD; - } else { + else goto out; - } if (!strncmp(pkgtype, "svc", 3)) apptype = STC_APP_TYPE_SERVICE; diff --git a/src/helper/helper-inotify.h b/src/helper/helper-inotify.h index 1fe9d66..9ee6995 100755 --- a/src/helper/helper-inotify.h +++ b/src/helper/helper-inotify.h @@ -20,8 +20,8 @@ #include struct inotify_event; -typedef void (* inotify_event_cb) (struct inotify_event *event, - const char *ident); +typedef void (*inotify_event_cb) (struct inotify_event *event, + const char *ident); int inotify_register(const char *path, inotify_event_cb callback); void inotify_deregister(const char *path); diff --git a/src/helper/helper-procfs.c b/src/helper/helper-procfs.c index 168c34a..9dcd36e 100755 --- a/src/helper/helper-procfs.c +++ b/src/helper/helper-procfs.c @@ -40,25 +40,34 @@ #define USRAPPS "/usr/apps/" +static int __proc_get_data(char *path, char *buf, int len) +{ + _cleanup_fclose_ FILE *fp = NULL; + + fp = fopen(path, "r"); + if (fp == NULL) + return STC_ERROR_FAIL; + + if (fgets(buf, len - 1, fp) == NULL) + return STC_ERROR_FAIL; + + return STC_ERROR_NONE; +} + int proc_get_cmdline(pid_t pid, char *cmdline) { - char buf[PROC_BUF_MAX]; - char cmdline_buf[PROC_NAME_MAX]; char *filename; - FILE *fp; char *token = NULL; char *saveptr = NULL; + char path_buf[PROC_BUF_MAX] = {0, }; + char cmdline_buf[PROC_NAME_MAX] = {0, }; + stc_error_e ret = STC_ERROR_NONE; - snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); - fp = fopen(buf, "r"); - if (fp == NULL) - return STC_ERROR_FAIL; + snprintf(path_buf, sizeof(path_buf), "/proc/%d/cmdline", pid); - if (fgets(cmdline_buf, PROC_NAME_MAX-1, fp) == NULL) { - fclose(fp); - return STC_ERROR_FAIL; - } - fclose(fp); + ret = __proc_get_data(path_buf, cmdline_buf, PROC_NAME_MAX); + if (ret != STC_ERROR_NONE) + return ret; if (g_strstr_len(cmdline_buf, strlen(USRAPPS), USRAPPS) != NULL) { /* Application */ @@ -80,100 +89,25 @@ int proc_get_cmdline(pid_t pid, char *cmdline) } strncpy(cmdline, filename, PROC_NAME_MAX-1); - return STC_ERROR_NONE; } -pid_t find_pid_from_cmdline(char *cmdline) -{ - pid_t pid = -1, foundpid = -1; - int ret = 0; - DIR *dp; - struct dirent *dentry; - char appname[PROC_NAME_MAX]; - - dp = opendir("/proc"); - if (!dp) { - STC_LOGE("BACKGRD MANAGE : fail to open /proc"); - return STC_ERROR_FAIL; - } - - while ((dentry = readdir(dp)) != NULL) { - if (!isdigit(dentry->d_name[0])) - continue; - - pid = atoi(dentry->d_name); - if (!pid) - continue; - ret = proc_get_cmdline(pid, appname); - if (ret == STC_ERROR_NONE) { - if (!strncmp(cmdline, appname, strlen(appname)+1)) { - foundpid = pid; - break; - } - } - } - closedir(dp); - return foundpid; -} - int proc_get_label(pid_t pid, char *label) { - char buf[PROC_BUF_MAX]; - FILE *fp; + char path_buf[PROC_BUF_MAX] = {0, }; + char label_buf[PROC_NAME_MAX] = {0, }; + stc_error_e ret = STC_ERROR_NONE; - snprintf(buf, sizeof(buf), "/proc/%d/attr/current", pid); - fp = fopen(buf, "r"); - if (fp == NULL) - return STC_ERROR_FAIL; + snprintf(path_buf, sizeof(path_buf), "/proc/%d/attr/current", pid); - if (fgets(label, PROC_NAME_MAX-1, fp) == NULL) { - fclose(fp); - return STC_ERROR_FAIL; - } - fclose(fp); - return STC_ERROR_NONE; -} + ret = __proc_get_data(path_buf, label_buf, PROC_NAME_MAX); + if (ret != STC_ERROR_NONE) + return ret; -int proc_get_exepath(pid_t pid, char *buf, int len) -{ - char path[PROC_BUF_MAX]; - int ret = 0; - - snprintf(path, sizeof(path), "/proc/%d/exe", pid); - ret = readlink(path, buf, len-1); - if (ret > 0) - buf[ret] = '\0'; - else - buf[0] = '\0'; + strncpy(label, label_buf, PROC_NAME_MAX-1); return STC_ERROR_NONE; } -static int proc_get_data(char *path, char *buf, int len) -{ - _cleanup_close_ int fd = -1; - int ret; - - fd = open(path, O_RDONLY); - if (fd < 0) - return STC_ERROR_FAIL; - - ret = read(fd, buf, len-1); - if (ret < 0) { - buf[0] = '\0'; - return STC_ERROR_FAIL; - } - buf[ret] = '\0'; - return STC_ERROR_NONE; -} - -int proc_get_raw_cmdline(pid_t pid, char *buf, int len) -{ - char path[PROC_BUF_MAX]; - snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); - return proc_get_data(path, buf, len); -} - int proc_get_status(pid_t pid, char status[][PROC_BUF_MAX]) { unsigned int i; diff --git a/src/helper/helper-procfs.h b/src/helper/helper-procfs.h index 55c6a03..c6c9b90 100755 --- a/src/helper/helper-procfs.h +++ b/src/helper/helper-procfs.h @@ -29,13 +29,6 @@ int proc_get_cmdline(pid_t pid, char *cmdline); /** - * @desc find pid with /proc/{pid}/cmdline - * it returns first entry when many pids have same cmdline - * @return negative value if error - */ -pid_t find_pid_from_cmdline(char *cmdline); - -/** * @desc get smack subject label from /proc/{pid}/attr/current * this label can indicate package name about child processes * @return negative value if error or pid doesn't exist @@ -43,18 +36,6 @@ pid_t find_pid_from_cmdline(char *cmdline); int proc_get_label(pid_t pid, char *label); /** - * @desc get command line from /proc/{pid}/cmdline without any truncation - * @return negative value if error - */ -int proc_get_raw_cmdline(pid_t pid, char *buf, int len); - -/** - * @desc get symblolic link about /proc/{pid}/exe - * @return negative value if error - */ -int proc_get_exepath(pid_t pid, char *buf, int len); - -/** * @desc get status from /proc/{pid}/status * @return negative value if error */ diff --git a/src/monitor/include/stc-monitor.h b/src/monitor/include/stc-monitor.h index 0ecce65..ee2213f 100755 --- a/src/monitor/include/stc-monitor.h +++ b/src/monitor/include/stc-monitor.h @@ -148,7 +148,7 @@ stc_error_e stc_monitor_rstns_tree_add(const table_restrictions_info *info); stc_error_e stc_monitor_rstns_tree_remove(const table_restrictions_info *info); -stc_error_e stc_monitor_check_excn_by_cmdline(char *cmdline); +stc_error_e stc_monitor_check_excn_by_app_id(char *app_id); int stc_monitor_get_counter_socket(void); diff --git a/src/monitor/stc-app-lifecycle.c b/src/monitor/stc-app-lifecycle.c index eb18816..81b976b 100755 --- a/src/monitor/stc-app-lifecycle.c +++ b/src/monitor/stc-app-lifecycle.c @@ -36,7 +36,7 @@ typedef struct { } proc_key_s; typedef struct { - char cmdline[PROC_NAME_MAX]; + char *app_id; char status[PROC_STATUS_CNT][PROC_BUF_MAX]; } proc_value_s; @@ -78,6 +78,7 @@ static void __proc_tree_value_free(gpointer data) { proc_value_s *value = (proc_value_s *)data; + FREE(value->app_id); FREE(value); } @@ -108,8 +109,8 @@ static gboolean __proc_tree_foreach_print(gpointer key, gpointer value, proc_value_s *proc_value = (proc_value_s *)value; STC_LOGD("Proc pid [\033[1;33m%d\033[0;m] ppid [\033[1;35m%s\033[0;m] " - "cmdline [\033[0;34m%s\033[0;m]", proc_key->pid, - proc_value->status[PROC_STATUS_PPID], proc_value->cmdline); + "app_id [\033[0;34m%s\033[0;m]", proc_key->pid, + proc_value->status[PROC_STATUS_PPID], proc_value->app_id); return FALSE; } @@ -135,9 +136,9 @@ static proc_value_s * __proc_tree_find_parent(proc_value_s *value) if (STC_DEBUG_LOG) { if (parent != NULL) STC_LOGD("\033[0;35mPARENT\033[0;m: tgid[\033[1;33m%s\033[0;m] pid[%s] " - "ppid[\033[1;35m%s\033[0;m] cmdline[\033[0;34m%s\033[0;m] name[%s]", + "ppid[\033[1;35m%s\033[0;m] app_id[\033[0;34m%s\033[0;m] name[%s]", parent->status[PROC_STATUS_TGID], parent->status[PROC_STATUS_PID], - parent->status[PROC_STATUS_PPID], parent->cmdline, + parent->status[PROC_STATUS_PPID], parent->app_id, parent->status[PROC_STATUS_NAME]); } @@ -159,13 +160,13 @@ static void __proc_tree_add(proc_key_s *key, if (lookup) { if (STC_DEBUG_LOG) STC_LOGD("LOOKUP: tgid[\033[1;33m%s\033[0;m] pid[%s] ppid[\033[1;35m%s\033[0;m] " - "cmdline[\033[0;34m%s\033[0;m] name[%s]", lookup->status[PROC_STATUS_TGID], + "app_id[\033[0;34m%s\033[0;m] name[%s]", lookup->status[PROC_STATUS_TGID], lookup->status[PROC_STATUS_PID], lookup->status[PROC_STATUS_PPID], - lookup->cmdline, lookup->status[PROC_STATUS_NAME]); + lookup->app_id, lookup->status[PROC_STATUS_NAME]); return; } - STC_LOGD("cmdline [%s] pid[%s] ppid[%s]", value->cmdline, + STC_LOGD("app_id [%s] pid[%s] ppid[%s]", value->app_id, value->status[PROC_STATUS_PID], value->status[PROC_STATUS_PPID]); g_tree_insert(proc_tree, key, value); @@ -176,10 +177,10 @@ static void __proc_tree_add(proc_key_s *key, parent = __proc_tree_find_parent(value); if (parent != NULL) stc_manager_app_status_changed(STC_CMD_SET_SERVICE_LAUNCHED, key->pid, - parent->cmdline, parent->cmdline, STC_APP_TYPE_SERVICE); + parent->app_id, parent->app_id, STC_APP_TYPE_SERVICE); else stc_manager_app_status_changed(STC_CMD_SET_SERVICE_LAUNCHED, key->pid, - value->cmdline, value->cmdline, STC_APP_TYPE_SERVICE); + value->app_id, value->app_id, STC_APP_TYPE_SERVICE); } static void __proc_tree_remove(const proc_key_s *key) @@ -198,14 +199,14 @@ static void __proc_tree_remove(const proc_key_s *key) __proc_tree_printall(); } -static gboolean __check_excn(char *cmdline) +static gboolean __check_excn(char *app_id) { stc_error_e ret = STC_ERROR_NONE; - if (cmdline[0] == '(') + if (app_id && app_id[0] == '(') return TRUE; - ret = stc_monitor_check_excn_by_cmdline(cmdline); + ret = stc_monitor_check_excn_by_app_id(app_id); if (ret == STC_ERROR_NO_DATA) return FALSE; else @@ -390,24 +391,41 @@ stc_error_e stc_manager_app_status_changed(stc_cmd_type_e cmd, return ret; } -static void __process_event_fork(int tgid, int pid) +static char * __process_get_app_id(int pid) { + char label[PROC_NAME_MAX] = {0, }; char cmdline[PROC_NAME_MAX] = {0, }; + char *app_id = NULL; + + if (STC_ERROR_NONE == proc_get_label(pid, label)) { + app_id = strstr(label, "User::Pkg::"); + if (app_id != NULL) + return g_strdup(app_id + 11); + } + + if (STC_ERROR_NONE == proc_get_cmdline(pid, cmdline)) + return g_strdup(cmdline); + + return NULL; +} + +static void __process_event_fork(int tgid, int pid) +{ char status[PROC_STATUS_CNT][PROC_BUF_MAX]; + char *app_id = __process_get_app_id(pid); - if (STC_ERROR_NONE == proc_get_cmdline(pid, cmdline) && - STC_ERROR_NONE == proc_get_status(pid, status)) { + if (app_id != NULL && proc_get_status(pid, status) == STC_ERROR_NONE) { - if (__check_excn(cmdline)) { + unsigned int i; + proc_key_s *key = NULL; + proc_value_s *value = NULL; + + if (__check_excn(app_id)) { if (STC_DEBUG_LOG) - STC_LOGD("[%s] monitoring is excepted", cmdline); + STC_LOGD("[%s] monitoring is excepted", app_id); return; } - unsigned int i; - proc_key_s *key; - proc_value_s *value; - key = MALLOC0(proc_key_s, 1); if (key == NULL) { STC_LOGE("memory allocation failed"); @@ -422,13 +440,13 @@ static void __process_event_fork(int tgid, int pid) } key->pid = tgid; + value->app_id = app_id; for (i = 0; i < PROC_STATUS_CNT; ++i) g_strlcpy(value->status[i], status[i], sizeof(value->status[i])); - g_strlcpy(value->cmdline, cmdline, sizeof(value->cmdline)); if (STC_DEBUG_LOG) { STC_LOGD("\033[1;34mFORK\033[0;m: tgid[\033[1;33m%d\033[0;m] ppid=[\033[1;35m%s\033[0;m] " - "cmdline[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], cmdline, pid); + "app_id[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], app_id, pid); STC_LOGD("STATUS: tgid[%s] pid[%s] ppid[%s] name[%s] state[%s] tracerpid[%s]", status[PROC_STATUS_TGID], status[PROC_STATUS_PID], status[PROC_STATUS_PPID], status[PROC_STATUS_NAME], status[PROC_STATUS_STATE], status[PROC_STATUS_TRACERPID]); @@ -440,22 +458,21 @@ static void __process_event_fork(int tgid, int pid) static void __process_event_exec(int tgid, int pid) { - char cmdline[PROC_NAME_MAX] = {0, }; char status[PROC_STATUS_CNT][PROC_BUF_MAX]; + char *app_id = __process_get_app_id(pid); - if (STC_ERROR_NONE == proc_get_cmdline(pid, cmdline) && - STC_ERROR_NONE == proc_get_status(pid, status)) { + if (app_id != NULL && proc_get_status(pid, status) == STC_ERROR_NONE) { - if (__check_excn(cmdline)) { + unsigned int i; + proc_key_s *key = NULL; + proc_value_s *value = NULL; + + if (__check_excn(app_id)) { if (STC_DEBUG_LOG) - STC_LOGD("[%s] monitoring is excepted", cmdline); + STC_LOGD("[%s] monitoring is excepted", app_id); return; } - unsigned int i; - proc_key_s *key; - proc_value_s *value; - key = MALLOC0(proc_key_s, 1); if (key == NULL) { STC_LOGE("memory allocation failed"); @@ -470,13 +487,13 @@ static void __process_event_exec(int tgid, int pid) } key->pid = tgid; + value->app_id = app_id; for (i = 0; i < PROC_STATUS_CNT; ++i) g_strlcpy(value->status[i], status[i], sizeof(value->status[i])); - g_strlcpy(value->cmdline, cmdline, sizeof(value->cmdline)); if (STC_DEBUG_LOG) { STC_LOGD("\033[1;32mEXEC\033[0;m: tgid[\033[1;33m%d\033[0;m] ppid=[\033[1;35m%s\033[0;m] " - "cmdline[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], cmdline, pid); + "app_id[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], app_id, pid); STC_LOGD("STATUS: tgid[%s] pid[%s] ppid[%s] name[%s] state[%s] tracerpid[%s]", status[PROC_STATUS_TGID], status[PROC_STATUS_PID], status[PROC_STATUS_PPID], status[PROC_STATUS_NAME], status[PROC_STATUS_STATE], status[PROC_STATUS_TRACERPID]); diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 1cc0b5e..2530dd0 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -1948,13 +1948,13 @@ stc_error_e stc_monitor_rstns_tree_remove(const table_restrictions_info *info) return ret; } -stc_error_e stc_monitor_check_excn_by_cmdline(char *cmdline) +stc_error_e stc_monitor_check_excn_by_app_id(char *app_id) { ret_value_msg_if(g_system == NULL, STC_ERROR_FAIL, "stc monitor not initialized!"); char *exe_type = NULL; - exe_type = g_hash_table_lookup(g_system->excns_hash, cmdline); + exe_type = g_hash_table_lookup(g_system->excns_hash, app_id); if (!exe_type) return STC_ERROR_NO_DATA; -- 2.7.4 From 3b547510161f3098a3af865260dbd8b306546f7d Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Tue, 3 Oct 2017 14:32:45 +0530 Subject: [PATCH 06/16] Update ground state in table while updating data usage. Change-Id: I7bd13c92fac2994f2be22fa3000896ded3a5b70a Signed-off-by: Nishant Chaprana --- src/monitor/stc-monitor.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 2530dd0..7b0558c 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -890,7 +890,15 @@ static gboolean __update_app_statistics(gpointer key, gpointer value, stat.snd_count = app_value->counter.out_bytes; stat.rcv_count = app_value->counter.in_bytes; stat.is_roaming = default_connection->roaming; - stat.ground = STC_APP_STATE_UNKNOWN; + + if (strstr(stat.app_id, "_BACKGROUND")) { + stat.ground = STC_APP_STATE_BACKGROUND; + } else { + if (strstr(stat.app_id, "TOTAL_")) + stat.ground = STC_APP_STATE_UNKNOWN; + else + stat.ground = STC_APP_STATE_FOREGROUND; + } table_statistics_insert(&stat_key, &stat, *touch_time); -- 2.7.4 From 11ea9abc4e3df7431685a10e330a4a5743868c1b Mon Sep 17 00:00:00 2001 From: taesub kim Date: Mon, 16 Oct 2017 05:31:20 +0000 Subject: [PATCH 07/16] Revert "[Fix] Fetch proper app_id for creation of cgroup." This reverts commit 951a7b00437655c92d1a998c4e1ed4353010eb0b. Change-Id: I10c8ea979a54ca189b0eab6c565e7320307e85e0 --- include/stc-plugin.h | 2 +- packaging/stc-manager.spec | 2 +- plugin/stc-plugin.c | 7 ++- src/helper/helper-inotify.h | 4 +- src/helper/helper-procfs.c | 124 +++++++++++++++++++++++++++++--------- src/helper/helper-procfs.h | 19 ++++++ src/monitor/include/stc-monitor.h | 2 +- src/monitor/stc-app-lifecycle.c | 87 +++++++++++--------------- src/monitor/stc-monitor.c | 4 +- 9 files changed, 160 insertions(+), 91 deletions(-) diff --git a/include/stc-plugin.h b/include/stc-plugin.h index 53cfaec..4d843b8 100755 --- a/include/stc-plugin.h +++ b/include/stc-plugin.h @@ -21,7 +21,7 @@ #include "stc-error.h" #include "stc-manager.h" -typedef stc_error_e(*stc_plugin_app_state_changed_cb) (stc_cmd_type_e cmd, +typedef stc_error_e (*stc_plugin_app_state_changed_cb)(stc_cmd_type_e cmd, pid_t pid, const gchar *app_id, const gchar *pkg_id, diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 9500d61..cf69262 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.37 +Version: 0.0.36 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/plugin/stc-plugin.c b/plugin/stc-plugin.c index 3587db1..916a75e 100755 --- a/plugin/stc-plugin.c +++ b/plugin/stc-plugin.c @@ -74,12 +74,13 @@ static void __stc_gdbus_handle_aul_changestate(GDBusConnection *connection, g_variant_get(parameters, AUL_APP_STATUS_DBUS_STATUS_CHANGE_TYPE, &pid, &appid, &pkgid, &statstr, &pkgtype); - if (!strncmp(statstr, "fg", 2)) + if (!strncmp(statstr, "fg", 2)) { status = STC_CMD_SET_FOREGRD; - else if (!strncmp(statstr, "bg", 2)) + } else if (!strncmp(statstr, "bg", 2)) { status = STC_CMD_SET_BACKGRD; - else + } else { goto out; + } if (!strncmp(pkgtype, "svc", 3)) apptype = STC_APP_TYPE_SERVICE; diff --git a/src/helper/helper-inotify.h b/src/helper/helper-inotify.h index 9ee6995..1fe9d66 100755 --- a/src/helper/helper-inotify.h +++ b/src/helper/helper-inotify.h @@ -20,8 +20,8 @@ #include struct inotify_event; -typedef void (*inotify_event_cb) (struct inotify_event *event, - const char *ident); +typedef void (* inotify_event_cb) (struct inotify_event *event, + const char *ident); int inotify_register(const char *path, inotify_event_cb callback); void inotify_deregister(const char *path); diff --git a/src/helper/helper-procfs.c b/src/helper/helper-procfs.c index 9dcd36e..168c34a 100755 --- a/src/helper/helper-procfs.c +++ b/src/helper/helper-procfs.c @@ -40,34 +40,25 @@ #define USRAPPS "/usr/apps/" -static int __proc_get_data(char *path, char *buf, int len) -{ - _cleanup_fclose_ FILE *fp = NULL; - - fp = fopen(path, "r"); - if (fp == NULL) - return STC_ERROR_FAIL; - - if (fgets(buf, len - 1, fp) == NULL) - return STC_ERROR_FAIL; - - return STC_ERROR_NONE; -} - int proc_get_cmdline(pid_t pid, char *cmdline) { + char buf[PROC_BUF_MAX]; + char cmdline_buf[PROC_NAME_MAX]; char *filename; + FILE *fp; char *token = NULL; char *saveptr = NULL; - char path_buf[PROC_BUF_MAX] = {0, }; - char cmdline_buf[PROC_NAME_MAX] = {0, }; - stc_error_e ret = STC_ERROR_NONE; - snprintf(path_buf, sizeof(path_buf), "/proc/%d/cmdline", pid); + snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); + fp = fopen(buf, "r"); + if (fp == NULL) + return STC_ERROR_FAIL; - ret = __proc_get_data(path_buf, cmdline_buf, PROC_NAME_MAX); - if (ret != STC_ERROR_NONE) - return ret; + if (fgets(cmdline_buf, PROC_NAME_MAX-1, fp) == NULL) { + fclose(fp); + return STC_ERROR_FAIL; + } + fclose(fp); if (g_strstr_len(cmdline_buf, strlen(USRAPPS), USRAPPS) != NULL) { /* Application */ @@ -89,25 +80,100 @@ int proc_get_cmdline(pid_t pid, char *cmdline) } strncpy(cmdline, filename, PROC_NAME_MAX-1); + return STC_ERROR_NONE; } +pid_t find_pid_from_cmdline(char *cmdline) +{ + pid_t pid = -1, foundpid = -1; + int ret = 0; + DIR *dp; + struct dirent *dentry; + char appname[PROC_NAME_MAX]; + + dp = opendir("/proc"); + if (!dp) { + STC_LOGE("BACKGRD MANAGE : fail to open /proc"); + return STC_ERROR_FAIL; + } + + while ((dentry = readdir(dp)) != NULL) { + if (!isdigit(dentry->d_name[0])) + continue; + + pid = atoi(dentry->d_name); + if (!pid) + continue; + ret = proc_get_cmdline(pid, appname); + if (ret == STC_ERROR_NONE) { + if (!strncmp(cmdline, appname, strlen(appname)+1)) { + foundpid = pid; + break; + } + } + } + closedir(dp); + return foundpid; +} + int proc_get_label(pid_t pid, char *label) { - char path_buf[PROC_BUF_MAX] = {0, }; - char label_buf[PROC_NAME_MAX] = {0, }; - stc_error_e ret = STC_ERROR_NONE; + char buf[PROC_BUF_MAX]; + FILE *fp; - snprintf(path_buf, sizeof(path_buf), "/proc/%d/attr/current", pid); + snprintf(buf, sizeof(buf), "/proc/%d/attr/current", pid); + fp = fopen(buf, "r"); + if (fp == NULL) + return STC_ERROR_FAIL; - ret = __proc_get_data(path_buf, label_buf, PROC_NAME_MAX); - if (ret != STC_ERROR_NONE) - return ret; + if (fgets(label, PROC_NAME_MAX-1, fp) == NULL) { + fclose(fp); + return STC_ERROR_FAIL; + } + fclose(fp); + return STC_ERROR_NONE; +} - strncpy(label, label_buf, PROC_NAME_MAX-1); +int proc_get_exepath(pid_t pid, char *buf, int len) +{ + char path[PROC_BUF_MAX]; + int ret = 0; + + snprintf(path, sizeof(path), "/proc/%d/exe", pid); + ret = readlink(path, buf, len-1); + if (ret > 0) + buf[ret] = '\0'; + else + buf[0] = '\0'; return STC_ERROR_NONE; } +static int proc_get_data(char *path, char *buf, int len) +{ + _cleanup_close_ int fd = -1; + int ret; + + fd = open(path, O_RDONLY); + if (fd < 0) + return STC_ERROR_FAIL; + + ret = read(fd, buf, len-1); + if (ret < 0) { + buf[0] = '\0'; + return STC_ERROR_FAIL; + } + buf[ret] = '\0'; + return STC_ERROR_NONE; +} + +int proc_get_raw_cmdline(pid_t pid, char *buf, int len) +{ + char path[PROC_BUF_MAX]; + snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); + return proc_get_data(path, buf, len); +} + int proc_get_status(pid_t pid, char status[][PROC_BUF_MAX]) { unsigned int i; diff --git a/src/helper/helper-procfs.h b/src/helper/helper-procfs.h index c6c9b90..55c6a03 100755 --- a/src/helper/helper-procfs.h +++ b/src/helper/helper-procfs.h @@ -29,6 +29,13 @@ int proc_get_cmdline(pid_t pid, char *cmdline); /** + * @desc find pid with /proc/{pid}/cmdline + * it returns first entry when many pids have same cmdline + * @return negative value if error + */ +pid_t find_pid_from_cmdline(char *cmdline); + +/** * @desc get smack subject label from /proc/{pid}/attr/current * this label can indicate package name about child processes * @return negative value if error or pid doesn't exist @@ -36,6 +43,18 @@ int proc_get_cmdline(pid_t pid, char *cmdline); int proc_get_label(pid_t pid, char *label); /** + * @desc get command line from /proc/{pid}/cmdline without any truncation + * @return negative value if error + */ +int proc_get_raw_cmdline(pid_t pid, char *buf, int len); + +/** + * @desc get symblolic link about /proc/{pid}/exe + * @return negative value if error + */ +int proc_get_exepath(pid_t pid, char *buf, int len); + +/** * @desc get status from /proc/{pid}/status * @return negative value if error */ diff --git a/src/monitor/include/stc-monitor.h b/src/monitor/include/stc-monitor.h index ee2213f..0ecce65 100755 --- a/src/monitor/include/stc-monitor.h +++ b/src/monitor/include/stc-monitor.h @@ -148,7 +148,7 @@ stc_error_e stc_monitor_rstns_tree_add(const table_restrictions_info *info); stc_error_e stc_monitor_rstns_tree_remove(const table_restrictions_info *info); -stc_error_e stc_monitor_check_excn_by_app_id(char *app_id); +stc_error_e stc_monitor_check_excn_by_cmdline(char *cmdline); int stc_monitor_get_counter_socket(void); diff --git a/src/monitor/stc-app-lifecycle.c b/src/monitor/stc-app-lifecycle.c index 81b976b..eb18816 100755 --- a/src/monitor/stc-app-lifecycle.c +++ b/src/monitor/stc-app-lifecycle.c @@ -36,7 +36,7 @@ typedef struct { } proc_key_s; typedef struct { - char *app_id; + char cmdline[PROC_NAME_MAX]; char status[PROC_STATUS_CNT][PROC_BUF_MAX]; } proc_value_s; @@ -78,7 +78,6 @@ static void __proc_tree_value_free(gpointer data) { proc_value_s *value = (proc_value_s *)data; - FREE(value->app_id); FREE(value); } @@ -109,8 +108,8 @@ static gboolean __proc_tree_foreach_print(gpointer key, gpointer value, proc_value_s *proc_value = (proc_value_s *)value; STC_LOGD("Proc pid [\033[1;33m%d\033[0;m] ppid [\033[1;35m%s\033[0;m] " - "app_id [\033[0;34m%s\033[0;m]", proc_key->pid, - proc_value->status[PROC_STATUS_PPID], proc_value->app_id); + "cmdline [\033[0;34m%s\033[0;m]", proc_key->pid, + proc_value->status[PROC_STATUS_PPID], proc_value->cmdline); return FALSE; } @@ -136,9 +135,9 @@ static proc_value_s * __proc_tree_find_parent(proc_value_s *value) if (STC_DEBUG_LOG) { if (parent != NULL) STC_LOGD("\033[0;35mPARENT\033[0;m: tgid[\033[1;33m%s\033[0;m] pid[%s] " - "ppid[\033[1;35m%s\033[0;m] app_id[\033[0;34m%s\033[0;m] name[%s]", + "ppid[\033[1;35m%s\033[0;m] cmdline[\033[0;34m%s\033[0;m] name[%s]", parent->status[PROC_STATUS_TGID], parent->status[PROC_STATUS_PID], - parent->status[PROC_STATUS_PPID], parent->app_id, + parent->status[PROC_STATUS_PPID], parent->cmdline, parent->status[PROC_STATUS_NAME]); } @@ -160,13 +159,13 @@ static void __proc_tree_add(proc_key_s *key, if (lookup) { if (STC_DEBUG_LOG) STC_LOGD("LOOKUP: tgid[\033[1;33m%s\033[0;m] pid[%s] ppid[\033[1;35m%s\033[0;m] " - "app_id[\033[0;34m%s\033[0;m] name[%s]", lookup->status[PROC_STATUS_TGID], + "cmdline[\033[0;34m%s\033[0;m] name[%s]", lookup->status[PROC_STATUS_TGID], lookup->status[PROC_STATUS_PID], lookup->status[PROC_STATUS_PPID], - lookup->app_id, lookup->status[PROC_STATUS_NAME]); + lookup->cmdline, lookup->status[PROC_STATUS_NAME]); return; } - STC_LOGD("app_id [%s] pid[%s] ppid[%s]", value->app_id, + STC_LOGD("cmdline [%s] pid[%s] ppid[%s]", value->cmdline, value->status[PROC_STATUS_PID], value->status[PROC_STATUS_PPID]); g_tree_insert(proc_tree, key, value); @@ -177,10 +176,10 @@ static void __proc_tree_add(proc_key_s *key, parent = __proc_tree_find_parent(value); if (parent != NULL) stc_manager_app_status_changed(STC_CMD_SET_SERVICE_LAUNCHED, key->pid, - parent->app_id, parent->app_id, STC_APP_TYPE_SERVICE); + parent->cmdline, parent->cmdline, STC_APP_TYPE_SERVICE); else stc_manager_app_status_changed(STC_CMD_SET_SERVICE_LAUNCHED, key->pid, - value->app_id, value->app_id, STC_APP_TYPE_SERVICE); + value->cmdline, value->cmdline, STC_APP_TYPE_SERVICE); } static void __proc_tree_remove(const proc_key_s *key) @@ -199,14 +198,14 @@ static void __proc_tree_remove(const proc_key_s *key) __proc_tree_printall(); } -static gboolean __check_excn(char *app_id) +static gboolean __check_excn(char *cmdline) { stc_error_e ret = STC_ERROR_NONE; - if (app_id && app_id[0] == '(') + if (cmdline[0] == '(') return TRUE; - ret = stc_monitor_check_excn_by_app_id(app_id); + ret = stc_monitor_check_excn_by_cmdline(cmdline); if (ret == STC_ERROR_NO_DATA) return FALSE; else @@ -391,41 +390,24 @@ stc_error_e stc_manager_app_status_changed(stc_cmd_type_e cmd, return ret; } -static char * __process_get_app_id(int pid) -{ - char label[PROC_NAME_MAX] = {0, }; - char cmdline[PROC_NAME_MAX] = {0, }; - char *app_id = NULL; - - if (STC_ERROR_NONE == proc_get_label(pid, label)) { - app_id = strstr(label, "User::Pkg::"); - if (app_id != NULL) - return g_strdup(app_id + 11); - } - - if (STC_ERROR_NONE == proc_get_cmdline(pid, cmdline)) - return g_strdup(cmdline); - - return NULL; -} - static void __process_event_fork(int tgid, int pid) { + char cmdline[PROC_NAME_MAX] = {0, }; char status[PROC_STATUS_CNT][PROC_BUF_MAX]; - char *app_id = __process_get_app_id(pid); - if (app_id != NULL && proc_get_status(pid, status) == STC_ERROR_NONE) { + if (STC_ERROR_NONE == proc_get_cmdline(pid, cmdline) && + STC_ERROR_NONE == proc_get_status(pid, status)) { - unsigned int i; - proc_key_s *key = NULL; - proc_value_s *value = NULL; - - if (__check_excn(app_id)) { + if (__check_excn(cmdline)) { if (STC_DEBUG_LOG) - STC_LOGD("[%s] monitoring is excepted", app_id); + STC_LOGD("[%s] monitoring is excepted", cmdline); return; } + unsigned int i; + proc_key_s *key; + proc_value_s *value; + key = MALLOC0(proc_key_s, 1); if (key == NULL) { STC_LOGE("memory allocation failed"); @@ -440,13 +422,13 @@ static void __process_event_fork(int tgid, int pid) } key->pid = tgid; - value->app_id = app_id; for (i = 0; i < PROC_STATUS_CNT; ++i) g_strlcpy(value->status[i], status[i], sizeof(value->status[i])); + g_strlcpy(value->cmdline, cmdline, sizeof(value->cmdline)); if (STC_DEBUG_LOG) { STC_LOGD("\033[1;34mFORK\033[0;m: tgid[\033[1;33m%d\033[0;m] ppid=[\033[1;35m%s\033[0;m] " - "app_id[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], app_id, pid); + "cmdline[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], cmdline, pid); STC_LOGD("STATUS: tgid[%s] pid[%s] ppid[%s] name[%s] state[%s] tracerpid[%s]", status[PROC_STATUS_TGID], status[PROC_STATUS_PID], status[PROC_STATUS_PPID], status[PROC_STATUS_NAME], status[PROC_STATUS_STATE], status[PROC_STATUS_TRACERPID]); @@ -458,21 +440,22 @@ static void __process_event_fork(int tgid, int pid) static void __process_event_exec(int tgid, int pid) { + char cmdline[PROC_NAME_MAX] = {0, }; char status[PROC_STATUS_CNT][PROC_BUF_MAX]; - char *app_id = __process_get_app_id(pid); - if (app_id != NULL && proc_get_status(pid, status) == STC_ERROR_NONE) { + if (STC_ERROR_NONE == proc_get_cmdline(pid, cmdline) && + STC_ERROR_NONE == proc_get_status(pid, status)) { - unsigned int i; - proc_key_s *key = NULL; - proc_value_s *value = NULL; - - if (__check_excn(app_id)) { + if (__check_excn(cmdline)) { if (STC_DEBUG_LOG) - STC_LOGD("[%s] monitoring is excepted", app_id); + STC_LOGD("[%s] monitoring is excepted", cmdline); return; } + unsigned int i; + proc_key_s *key; + proc_value_s *value; + key = MALLOC0(proc_key_s, 1); if (key == NULL) { STC_LOGE("memory allocation failed"); @@ -487,13 +470,13 @@ static void __process_event_exec(int tgid, int pid) } key->pid = tgid; - value->app_id = app_id; for (i = 0; i < PROC_STATUS_CNT; ++i) g_strlcpy(value->status[i], status[i], sizeof(value->status[i])); + g_strlcpy(value->cmdline, cmdline, sizeof(value->cmdline)); if (STC_DEBUG_LOG) { STC_LOGD("\033[1;32mEXEC\033[0;m: tgid[\033[1;33m%d\033[0;m] ppid=[\033[1;35m%s\033[0;m] " - "app_id[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], app_id, pid); + "cmdline[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], cmdline, pid); STC_LOGD("STATUS: tgid[%s] pid[%s] ppid[%s] name[%s] state[%s] tracerpid[%s]", status[PROC_STATUS_TGID], status[PROC_STATUS_PID], status[PROC_STATUS_PPID], status[PROC_STATUS_NAME], status[PROC_STATUS_STATE], status[PROC_STATUS_TRACERPID]); diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 2530dd0..1cc0b5e 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -1948,13 +1948,13 @@ stc_error_e stc_monitor_rstns_tree_remove(const table_restrictions_info *info) return ret; } -stc_error_e stc_monitor_check_excn_by_app_id(char *app_id) +stc_error_e stc_monitor_check_excn_by_cmdline(char *cmdline) { ret_value_msg_if(g_system == NULL, STC_ERROR_FAIL, "stc monitor not initialized!"); char *exe_type = NULL; - exe_type = g_hash_table_lookup(g_system->excns_hash, app_id); + exe_type = g_hash_table_lookup(g_system->excns_hash, cmdline); if (!exe_type) return STC_ERROR_NO_DATA; -- 2.7.4 From 0ea28ba451797681c1e71840148ea8ed92361a4e Mon Sep 17 00:00:00 2001 From: taesub kim Date: Mon, 16 Oct 2017 05:31:33 +0000 Subject: [PATCH 08/16] Revert "Update ground state in table while updating data usage." This reverts commit 3b547510161f3098a3af865260dbd8b306546f7d. Change-Id: Iccc7ec64a4758e8ec12e68d2b20e19339144056b --- src/monitor/stc-monitor.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 7b0558c..2530dd0 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -890,15 +890,7 @@ static gboolean __update_app_statistics(gpointer key, gpointer value, stat.snd_count = app_value->counter.out_bytes; stat.rcv_count = app_value->counter.in_bytes; stat.is_roaming = default_connection->roaming; - - if (strstr(stat.app_id, "_BACKGROUND")) { - stat.ground = STC_APP_STATE_BACKGROUND; - } else { - if (strstr(stat.app_id, "TOTAL_")) - stat.ground = STC_APP_STATE_UNKNOWN; - else - stat.ground = STC_APP_STATE_FOREGROUND; - } + stat.ground = STC_APP_STATE_UNKNOWN; table_statistics_insert(&stat_key, &stat, *touch_time); -- 2.7.4 From 4b2d1f0ff48c2d7930d68be2667d162231425d58 Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Tue, 3 Oct 2017 14:32:45 +0530 Subject: [PATCH 09/16] Update ground state in table while updating data usage. Change-Id: I3288285af6febf4ce196d9fe8d965699b01bc22e Signed-off-by: hyunuktak --- src/monitor/stc-monitor.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 1cc0b5e..2fde42c 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -890,7 +890,15 @@ static gboolean __update_app_statistics(gpointer key, gpointer value, stat.snd_count = app_value->counter.out_bytes; stat.rcv_count = app_value->counter.in_bytes; stat.is_roaming = default_connection->roaming; - stat.ground = STC_APP_STATE_UNKNOWN; + + if (strstr(stat.app_id, "_BACKGROUND")) { + stat.ground = STC_APP_STATE_BACKGROUND; + } else { + if (strstr(stat.app_id, "TOTAL_")) + stat.ground = STC_APP_STATE_UNKNOWN; + else + stat.ground = STC_APP_STATE_FOREGROUND; + } table_statistics_insert(&stat_key, &stat, *touch_time); -- 2.7.4 From 982b58fcb98e6bfd415a7dc73454e222a971f297 Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Mon, 16 Oct 2017 11:44:42 +0530 Subject: [PATCH 10/16] [Fix] Memory leak while fetching data from config file Change-Id: I2126b99837fb53c9a504ba47580c2fcfba5b5fd7 Signed-off-by: Nishant Chaprana --- packaging/stc-manager.spec | 2 +- src/stc-manager-util.c | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index cf69262..9500d61 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.36 +Version: 0.0.37 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/stc-manager-util.c b/src/stc-manager-util.c index 1c97e81..17f9d83 100755 --- a/src/stc-manager-util.c +++ b/src/stc-manager-util.c @@ -74,6 +74,7 @@ gboolean stc_util_get_config_bool(char *key) { char path[MAX_PATH_LENGTH]; GKeyFile *keyfile; + gboolean value; snprintf(path, sizeof(path), "%s/%s", INFO_STORAGE_DIR, INFO_CONFIG); @@ -81,13 +82,17 @@ gboolean stc_util_get_config_bool(char *key) if (!keyfile) keyfile = g_key_file_new(); - return g_key_file_get_boolean(keyfile, path, key, NULL); + value = g_key_file_get_boolean(keyfile, path, key, NULL); + g_key_file_free(keyfile); + + return value; } gchar * stc_util_get_config_str(char *key) { char path[MAX_PATH_LENGTH]; GKeyFile *keyfile; + gchar *value; snprintf(path, sizeof(path), "%s/%s", INFO_STORAGE_DIR, INFO_CONFIG); @@ -95,13 +100,17 @@ gchar * stc_util_get_config_str(char *key) if (!keyfile) keyfile = g_key_file_new(); - return g_key_file_get_string(keyfile, path, key, NULL); + value = g_key_file_get_string(keyfile, path, key, NULL); + g_key_file_free(keyfile); + + return value; } int stc_util_get_config_int(char *key) { char path[MAX_PATH_LENGTH]; GKeyFile *keyfile; + gint value; snprintf(path, sizeof(path), "%s/%s", INFO_STORAGE_DIR, INFO_CONFIG); @@ -109,7 +118,11 @@ int stc_util_get_config_int(char *key) if (!keyfile) keyfile = g_key_file_new(); - return g_key_file_get_integer(keyfile, path, key, NULL); + + value = g_key_file_get_integer(keyfile, path, key, NULL); + g_key_file_free(keyfile); + + return value; } API void stc_util_set_debuglog(int debuglog) -- 2.7.4 From 9a2652e780ee9483a15aa35c86c2c60fa7040418 Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Mon, 16 Oct 2017 14:46:50 +0530 Subject: [PATCH 11/16] [nfacct-rule] Use heap instead of stack, to aviod large stack usage issue. Change-Id: I5252955200603bc1c21b3b36b150e174447ce20c Signed-off-by: Nishant Chaprana --- packaging/stc-manager.spec | 2 +- src/helper/helper-nfacct-rule.c | 68 +++++++++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 9500d61..d0d5348 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.37 +Version: 0.0.38 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 ca3a7a9..952e414 100755 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -131,38 +131,53 @@ static stc_error_e send_nfacct_request(int sock, struct genl *req) static stc_error_e nfacct_send_new(nfacct_rule_s *counter) { - struct genl req; + int ret = STC_ERROR_NONE; + struct genl *req = MALLOC0(struct genl, 1); + if (req == NULL) { + STC_LOGE("Failed allocate memory to genl request message"); + return STC_ERROR_OUT_OF_MEMORY; + } - prepare_netlink_msg(&req, NFNL_MSG_ACCT_NEW, NLM_F_CREATE | NLM_F_ACK); - add_string_attr(&req, counter->name, NFACCT_NAME); + prepare_netlink_msg(req, NFNL_MSG_ACCT_NEW, NLM_F_CREATE | NLM_F_ACK); + add_string_attr(req, counter->name, NFACCT_NAME); if (STC_DEBUG_LOG) STC_LOGD("counter name %s", counter->name); /* padding */ - add_uint64_attr(&req, 0, NFACCT_PKTS); - add_uint64_attr(&req, 0, NFACCT_BYTES); + add_uint64_attr(req, 0, NFACCT_PKTS); + add_uint64_attr(req, 0, NFACCT_BYTES); if (counter->quota) { STC_LOGD("quota bytes %"PRId64, counter->quota); - add_uint32_attr(&req, htobe32(NFACCT_F_QUOTA_BYTES), + add_uint32_attr(req, htobe32(NFACCT_F_QUOTA_BYTES), NFACCT_FLAGS); - add_uint64_attr(&req, htobe64(counter->quota), NFACCT_QUOTA); + add_uint64_attr(req, htobe64(counter->quota), NFACCT_QUOTA); } - return send_nfacct_request(counter->carg->sock, &req); + ret = send_nfacct_request(counter->carg->sock, req); + FREE(req); + return ret; } stc_error_e nfacct_send_del(nfacct_rule_s *counter) { - struct genl req; + int ret = STC_ERROR_NONE; + struct genl *req = MALLOC0(struct genl, 1); + if (req == NULL) { + STC_LOGE("Failed allocate memory to genl request message"); + return STC_ERROR_OUT_OF_MEMORY; + } if (STC_DEBUG_LOG) STC_LOGD("send remove request for %s", counter->name); - prepare_netlink_msg(&req, NFNL_MSG_ACCT_DEL, NLM_F_ACK); - add_string_attr(&req, counter->name, NFACCT_NAME); - return send_nfacct_request(counter->carg->sock, &req); + prepare_netlink_msg(req, NFNL_MSG_ACCT_DEL, NLM_F_ACK); + add_string_attr(req, counter->name, NFACCT_NAME); + + ret = send_nfacct_request(counter->carg->sock, req); + FREE(req); + return ret; } #define NFACCT_F_QUOTAS (NFACCT_F_QUOTA_BYTES | NFACCT_F_QUOTA_PKTS) @@ -171,22 +186,29 @@ static stc_error_e internal_nfacct_send_get(struct counter_arg *carg, const char *name, int mask, int filter) { - struct genl req; + int ret = STC_ERROR_NONE; struct nlattr *na; int flag = !name ? NLM_F_DUMP : 0; - prepare_netlink_msg(&req, get_type, - flag); + struct genl *req = MALLOC0(struct genl, 1); + if (req == NULL) { + STC_LOGE("Failed allocate memory to genl request message"); + return STC_ERROR_OUT_OF_MEMORY; + } + + prepare_netlink_msg(req, get_type, flag); /* due we don't get counter with quota any where else, * here we will request just counters by default */ if (name) - add_string_attr(&req, name, NFACCT_NAME); - - na = start_nest_attr(&req, NFACCT_FILTER); - add_uint32_attr(&req, htonl(mask), - NFACCT_FILTER_ATTR_MASK); - add_uint32_attr(&req, htonl(filter), NFACCT_FILTER_ATTR_VALUE); - end_nest_attr(&req, na); - return send_nfacct_request(carg->sock, &req); + add_string_attr(req, name, NFACCT_NAME); + + na = start_nest_attr(req, NFACCT_FILTER); + add_uint32_attr(req, htonl(mask), NFACCT_FILTER_ATTR_MASK); + add_uint32_attr(req, htonl(filter), NFACCT_FILTER_ATTR_VALUE); + end_nest_attr(req, na); + + ret = send_nfacct_request(carg->sock, req); + FREE(req); + return ret; } stc_error_e nfacct_send_get_counters(struct counter_arg *carg, const char *name) -- 2.7.4 From e2644618210b9d01767e94e38bb92cf6415018e9 Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Tue, 17 Oct 2017 08:47:50 +0530 Subject: [PATCH 12/16] Use heap instead of stack, to aviod large stack usage issue in __process_contr_reply() Change-Id: I447c0cca6658995f355693f0923c9395cabe0468 Signed-off-by: Nishant Chaprana --- packaging/stc-manager.spec | 2 +- src/monitor/stc-monitor.c | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index d0d5348..c1914df 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.38 +Version: 0.0.39 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 2fde42c..8b18657 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -1123,12 +1123,11 @@ static gboolean __process_contr_reply(GIOChannel *source, gpointer user_data) { int sock = g_io_channel_unix_get_fd(source); - struct genl ans; + struct genl *ans; int ret; stc_s *stc = stc_get_manager(); - if ((condition & G_IO_ERR) || - (condition & G_IO_HUP) || + if ((condition & G_IO_ERR) || (condition & G_IO_HUP) || (condition & G_IO_NVAL)) { /* G_IO_ERR/G_IO_HUP/G_IO_NVAL received */ @@ -1140,23 +1139,29 @@ static gboolean __process_contr_reply(GIOChannel *source, return FALSE; } + ans = MALLOC0(struct genl, 1); + if (ans == NULL) { + STC_LOGE("Failed allocate memory to genl reply message"); + return TRUE; + } + if (stc == NULL) { STC_LOGE("Can't get stc data"); goto out; } - ret = read_netlink(sock, - &ans, sizeof(struct genl)); + ret = read_netlink(sock, ans, sizeof(struct genl)); /* STC_LOGD("Counter data received ret [%d]", ret); */ if (ret == 0) goto out; stc->carg->ans_len = ret; - __process_network_counter(&ans, stc->carg); + __process_network_counter(ans, stc->carg); g_idle_add(__flush_apps_stats_to_database, NULL); g_idle_add(__flush_rstns_counter_to_database, NULL); out: + FREE(ans); return TRUE; } -- 2.7.4 From fe9d6335ed936bf8995b34efe37ff36dacbef089 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Fri, 20 Oct 2017 13:00:04 +0900 Subject: [PATCH 13/16] Removed inotify helper Change-Id: I4de98b665307d02a75738dd8fd372eb85bfffaff Signed-off-by: hyunuktak --- packaging/stc-manager.spec | 2 +- src/helper/helper-inotify.c | 206 -------------------------------------------- src/helper/helper-inotify.h | 32 ------- src/stc-manager.c | 26 ------ 4 files changed, 1 insertion(+), 265 deletions(-) delete mode 100755 src/helper/helper-inotify.c delete mode 100755 src/helper/helper-inotify.h diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index c1914df..51f366d 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.39 +Version: 0.0.40 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/helper/helper-inotify.c b/src/helper/helper-inotify.c deleted file mode 100755 index 71e30e2..0000000 --- a/src/helper/helper-inotify.c +++ /dev/null @@ -1,206 +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. - */ - -#include - -#include "helper-inotify.h" -#include "stc-manager-util.h" - -typedef struct { - GIOChannel *channel; - uint watch; - int wd; - - inotify_event_cb cb; -} stc_inotify_s; - -static GHashTable *g_inotify_hash; - -static gboolean __inotify_data(GIOChannel *channel, GIOCondition cond, - gpointer user_data) -{ - stc_inotify_s *inotify = user_data; - char buffer[sizeof(struct inotify_event) + NAME_MAX + 1]; - char *next_event; - gsize bytes_read; - GIOStatus status; - - if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { - inotify->watch = 0; - return FALSE; - } - - status = g_io_channel_read_chars(channel, buffer, - sizeof(buffer), &bytes_read, NULL); - - switch (status) { - case G_IO_STATUS_NORMAL: - break; - case G_IO_STATUS_AGAIN: - return TRUE; - default: - STC_LOGE("Reading from inotify channel failed"); - inotify->watch = 0; - return FALSE; - } - - next_event = buffer; - - while (bytes_read > 0) { - struct inotify_event *event; - gchar *ident; - gsize len; - inotify_event_cb callback = inotify->cb; - - event = (struct inotify_event *) next_event; - if (event->len) - ident = next_event + sizeof(struct inotify_event); - else - ident = NULL; - - len = sizeof(struct inotify_event) + event->len; - if (len > bytes_read) - break; - - next_event += len; - bytes_read -= len; - - (*callback)(event, ident); - } - - return TRUE; -} - -static void __remove_watch(stc_inotify_s *inotify) -{ - int fd; - - if (!inotify->channel) - return; - - if (inotify->watch > 0) - g_source_remove(inotify->watch); - - fd = g_io_channel_unix_get_fd(inotify->channel); - - if (inotify->wd >= 0) - inotify_rm_watch(fd, inotify->wd); - - g_io_channel_unref(inotify->channel); -} - -static int __create_watch(const char *path, stc_inotify_s *inotify) -{ - int fd; - - STC_LOGD("Add directory watch for [%s]", path); - - fd = inotify_init(); - if (fd < 0) - return -EIO; - - inotify->wd = inotify_add_watch(fd, path, - IN_MODIFY | IN_CREATE | IN_DELETE | - IN_MOVED_TO | IN_MOVED_FROM); - if (inotify->wd < 0) { - STC_LOGE("Creation of [%s] watch failed", path); - close(fd); - return -EIO; - } - - inotify->channel = g_io_channel_unix_new(fd); - if (!inotify->channel) { - STC_LOGE("Creation of inotify channel failed"); - inotify_rm_watch(fd, inotify->wd); - inotify->wd = 0; - - close(fd); - return -EIO; - } - - g_io_channel_set_close_on_unref(inotify->channel, TRUE); - g_io_channel_set_encoding(inotify->channel, NULL, NULL); - g_io_channel_set_buffered(inotify->channel, FALSE); - - inotify->watch = g_io_add_watch(inotify->channel, - G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR, - __inotify_data, inotify); - - return 0; -} - -static void __inotify_destroy(gpointer user_data) -{ - stc_inotify_s *inotify = user_data; - - __remove_watch(inotify); - FREE(inotify); -} - -int inotify_register(const char *path, inotify_event_cb callback) -{ - int err; - stc_inotify_s *inotify; - - if (!callback) - return -EINVAL; - - inotify = g_hash_table_lookup(g_inotify_hash, path); - if (inotify) - goto update; - - inotify = g_try_new0(stc_inotify_s, 1); - if (!inotify) - return -ENOMEM; - - inotify->wd = -1; - - err = __create_watch(path, inotify); - if (err < 0) { - FREE(inotify); - return err; - } - - g_hash_table_replace(g_inotify_hash, g_strdup(path), inotify); - -update: - inotify->cb = callback; - - return 0; -} - -void inotify_deregister(const char *path) -{ - stc_inotify_s *inotify; - - inotify = g_hash_table_lookup(g_inotify_hash, path); - if (!inotify) - return; - - g_hash_table_remove(g_inotify_hash, path); -} - -int inotify_initialize(void) -{ - g_inotify_hash = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, __inotify_destroy); - return 0; -} - -void inotify_deinitialize(void) -{ - g_hash_table_destroy(g_inotify_hash); -} diff --git a/src/helper/helper-inotify.h b/src/helper/helper-inotify.h deleted file mode 100755 index 1fe9d66..0000000 --- a/src/helper/helper-inotify.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. - */ - -#ifndef __STC_HELPER_INOTIFY_H__ -#define __STC_HELPER_INOTIFY_H__ - -#include - -struct inotify_event; -typedef void (* inotify_event_cb) (struct inotify_event *event, - const char *ident); - -int inotify_register(const char *path, inotify_event_cb callback); -void inotify_deregister(const char *path); - -int inotify_initialize(void); -void inotify_deinitialize(void); - -#endif /*__STC_HELPER_INOTIFY_H__*/ diff --git a/src/stc-manager.c b/src/stc-manager.c index d6e8521..fb5d75a 100755 --- a/src/stc-manager.c +++ b/src/stc-manager.c @@ -23,7 +23,6 @@ #include "table-restrictions.h" #include "helper-cgroup.h" #include "helper-nfacct-rule.h" -#include "helper-inotify.h" #include "stc-monitor.h" #include "stc-manager-plugin.h" #include "stc-app-lifecycle.h" @@ -44,25 +43,6 @@ static gboolean __validate_ident(const char *ident) return TRUE; } -static void __stc_inotify_handler(struct inotify_event *event, const char *ident) -{ - if (!ident) - return; - - if (!__validate_ident(ident)) { - STC_LOGE("Invalid ident [%s]", ident); - return; - } - - if (event->mask & IN_MODIFY) { - if (!g_strcmp0(ident, INFO_CONFIG)) { - int debug = 0; - debug = stc_util_get_config_int(INFO_DEBUGLOG); - stc_util_set_debuglog(debug); - } - } -} - static void __stc_manager_deinit(void) { __STC_LOG_FUNC_ENTER__; @@ -80,9 +60,6 @@ static void __stc_manager_deinit(void) stc_app_lifecycle_monitor_deinit(); stc_manager_plugin_deinit(); - inotify_deregister(INFO_STORAGE_DIR); - inotify_deinitialize(); - STC_LOGI("stc manager deinitialized"); FREE(g_stc); __STC_LOG_FUNC_EXIT__; @@ -103,9 +80,6 @@ static stc_s *__stc_manager_init(void) stc_util_initialize_config(); - inotify_initialize(); - inotify_register(INFO_STORAGE_DIR, __stc_inotify_handler); - cgroup_set_release_agent(NET_CLS_SUBSYS, NET_RELEASE_AGENT); EXEC(STC_ERROR_NONE, stc_db_initialize()); -- 2.7.4 From 71f7bebb11e3b1c00959d20377225b4af46c9e36 Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Wed, 25 Oct 2017 11:16:07 +0530 Subject: [PATCH 14/16] Fetching /proc//status entry after validation. Description: This patch adds validation check before storing status entries and assignes proper index for storing value. In TM1 reference device kernel makes below entries in status file. proc entry is like below:- sh-3.2# cat /proc/373/status Name: stc-manager State: S (sleeping) Tgid: 373 Pid: 373 PPid: 1 TracerPid: 0 However in Odroid reference device, kernel makes below entries in status. sh-3.2# cat /proc/3404/status Name: stc-manager State: S (sleeping) Tgid: 3404 Ngid: 0 Pid: 3404 PPid: 1 TracerPid: 0 Odroid kernel has an extra entry "Ngid" which breaks current extraction logic. So added logic to match entry key before extracting value when reading status file. Change-Id: I393ed476919fc8c101a8ce6a11ab835230a39021 Signed-off-by: Nishant Chaprana --- include/stc-manager-util.h | 17 +++++++++++++---- packaging/stc-manager.spec | 2 +- src/helper/helper-procfs.c | 30 +++++++++++++++++++++++++++++- src/monitor/stc-app-lifecycle.c | 4 ++++ 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/include/stc-manager-util.h b/include/stc-manager-util.h index d504cf3..2275b85 100755 --- a/include/stc-manager-util.h +++ b/include/stc-manager-util.h @@ -339,14 +339,23 @@ static inline bool strstart_with(const char *str, const char *with) #define PROC_BUF_MAX 64 #define PROC_NAME_MAX 1024 -#define PROC_STATUS_CNT 6 +#define PROC_STATUS_CNT 7 #define PROC_STATUS_NAME 0 #define PROC_STATUS_STATE 1 #define PROC_STATUS_TGID 2 -#define PROC_STATUS_PID 3 -#define PROC_STATUS_PPID 4 -#define PROC_STATUS_TRACERPID 5 +#define PROC_STATUS_NGID 3 +#define PROC_STATUS_PID 4 +#define PROC_STATUS_PPID 5 +#define PROC_STATUS_TRACERPID 6 + +#define PROC_STATUS_NAME_STR "Name:" +#define PROC_STATUS_STATE_STR "State:" +#define PROC_STATUS_TGID_STR "Tgid:" +#define PROC_STATUS_NGID_STR "Ngid:" +#define PROC_STATUS_PID_STR "Pid:" +#define PROC_STATUS_PPID_STR "PPid:" +#define PROC_STATUS_TRACERPID_STR "TracerPid:" #define COMMA_DELIMETER "," diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 51f366d..b67e5ea 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.40 +Version: 0.0.41 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/helper/helper-procfs.c b/src/helper/helper-procfs.c index 168c34a..8710fa2 100755 --- a/src/helper/helper-procfs.c +++ b/src/helper/helper-procfs.c @@ -177,8 +177,10 @@ int proc_get_raw_cmdline(pid_t pid, char *buf, int len) int proc_get_status(pid_t pid, char status[][PROC_BUF_MAX]) { unsigned int i; + unsigned int index = 0; char path[PROC_BUF_MAX]; char status_buf[PROC_BUF_MAX]; + bool updated[PROC_STATUS_CNT] = {FALSE, }; FILE *fp; snprintf(path, sizeof(path), "/proc/%d/status", pid); @@ -195,13 +197,39 @@ int proc_get_status(pid_t pid, char status[][PROC_BUF_MAX]) return STC_ERROR_FAIL; } + if (!updated[PROC_STATUS_NAME] && strstr(status_buf, + PROC_STATUS_NAME_STR)) + index = PROC_STATUS_NAME; + else if (!updated[PROC_STATUS_STATE] && strstr(status_buf, + PROC_STATUS_STATE_STR)) + index = PROC_STATUS_STATE; + else if (!updated[PROC_STATUS_TGID] && strstr(status_buf, + PROC_STATUS_TGID_STR)) + index = PROC_STATUS_TGID; + else if (!updated[PROC_STATUS_NGID] && strstr(status_buf, + PROC_STATUS_NGID_STR)) + index = PROC_STATUS_NGID; + else if (!updated[PROC_STATUS_PID] && strstr(status_buf, + PROC_STATUS_PID_STR)) + index = PROC_STATUS_PID; + else if (!updated[PROC_STATUS_PPID] && strstr(status_buf, + PROC_STATUS_PPID_STR)) + index = PROC_STATUS_PPID; + else if (!updated[PROC_STATUS_TRACERPID] && strstr(status_buf, + PROC_STATUS_TRACERPID_STR)) + index = PROC_STATUS_TRACERPID; + else + continue; + token = strtok_r(status_buf, ":", &saveptr); if (token != NULL) { token = strtok_r(NULL, "\n", &saveptr); if (token != NULL) { while (isspace((unsigned char)*token)) token++; - strncpy(status[i], token, sizeof(status[i])); + strncpy(status[index], token, + sizeof(status[index])); + updated[index] = TRUE; } } } diff --git a/src/monitor/stc-app-lifecycle.c b/src/monitor/stc-app-lifecycle.c index eb18816..1cd8e9d 100755 --- a/src/monitor/stc-app-lifecycle.c +++ b/src/monitor/stc-app-lifecycle.c @@ -395,6 +395,8 @@ static void __process_event_fork(int tgid, int pid) char cmdline[PROC_NAME_MAX] = {0, }; char status[PROC_STATUS_CNT][PROC_BUF_MAX]; + memset(status, 0x0, sizeof(status)); + if (STC_ERROR_NONE == proc_get_cmdline(pid, cmdline) && STC_ERROR_NONE == proc_get_status(pid, status)) { @@ -443,6 +445,8 @@ static void __process_event_exec(int tgid, int pid) char cmdline[PROC_NAME_MAX] = {0, }; char status[PROC_STATUS_CNT][PROC_BUF_MAX]; + memset(status, 0x0, sizeof(status)); + if (STC_ERROR_NONE == proc_get_cmdline(pid, cmdline) && STC_ERROR_NONE == proc_get_status(pid, status)) { -- 2.7.4 From aadaee0ba3ac7ddc866bf9f3327bcd209e4b203a Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Fri, 1 Dec 2017 15:34:56 +0530 Subject: [PATCH 15/16] Replaces fork() and execv() calls with stc-iptables dbus method calls Change-Id: Iea3e6236e39c6747152e91965b785ceb6bc20023 Signed-off-by: Nishant Chaprana --- src/helper/helper-iptables.c | 231 ++++++++++++++++++++++++++++++++++ src/helper/helper-iptables.h | 40 ++++++ src/helper/helper-nfacct-rule.c | 271 +++++++++------------------------------- src/helper/helper-nfacct-rule.h | 1 + src/stc-manager.c | 2 + 5 files changed, 332 insertions(+), 213 deletions(-) create mode 100755 src/helper/helper-iptables.c create mode 100755 src/helper/helper-iptables.h diff --git a/src/helper/helper-iptables.c b/src/helper/helper-iptables.c new file mode 100755 index 0000000..42fa6f6 --- /dev/null +++ b/src/helper/helper-iptables.c @@ -0,0 +1,231 @@ +/* + * 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 "stc-manager-gdbus.h" +#include "helper-iptables.h" + +#define STC_IPTABLES_DBUS_SERVICE "net.stc.iptables" +#define STC_IPTABLES_DBUS_RULE_INTERFACE STC_IPTABLES_DBUS_SERVICE ".rule" +#define STC_IPTABLES_DBUS_CHAIN_INTERFACE STC_IPTABLES_DBUS_SERVICE ".chain" +#define STC_IPTABLES_DBUS_RULE_PATH "/net/stc/iptables/rule" +#define STC_IPTABLES_DBUS_CHAIN_PATH "/net/stc/iptables/chain" +#define STC_IPTABLES_DBUS_METHOD_IPT_ADD_CHAIN "IptAddChain" +#define STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_CHAIN "IptRemoveChain" +#define STC_IPTABLES_DBUS_METHOD_IP6T_ADD_CHAIN "Ip6tAddChain" +#define STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_CHAIN "Ip6tRemoveChain" +#define STC_IPTABLES_DBUS_METHOD_IPT_ADD_RULE "IptAddRule" +#define STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_RULE "IptRemoveRule" +#define STC_IPTABLES_DBUS_METHOD_IP6T_ADD_RULE "Ip6tAddRule" +#define STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_RULE "Ip6tRemoveRule" + +#define RULE_CHAIN "chain" +#define RULE_TYPE "type" +#define RULE_IFNAME "ifname" +#define RULE_CGROUP "cgroup" +#define RULE_NFACCT "nfacct" +#define RULE_TARGET "target" + +static void __add_rule_info_to_builder(GVariantBuilder *builder, + iptables_rule_s *rule) +{ + if (builder == NULL || rule == NULL) + return; + + g_variant_builder_add(builder, "{sv}", RULE_CHAIN, + g_variant_new_string(rule->chain)); + + g_variant_builder_add(builder, "{sv}", RULE_TYPE, + g_variant_new_uint32(rule->direction)); + + if (rule->ifname) + g_variant_builder_add(builder, "{sv}", RULE_IFNAME, + g_variant_new_string(rule->ifname)); + + if (rule->classid > 0) + g_variant_builder_add(builder, "{sv}", RULE_CGROUP, + g_variant_new_uint32(rule->classid)); + + if (rule->nfacct_name) + g_variant_builder_add(builder, "{sv}", RULE_NFACCT, + g_variant_new_string(rule->nfacct_name)); + + if (rule->target) + g_variant_builder_add(builder, "{sv}", RULE_TARGET, + g_variant_new_string(rule->target)); + +} + +static int __iptables_rule_add(GDBusConnection *connection, + iptables_rule_s *rule) +{ + int result = 0; + GVariantBuilder *builder = NULL; + GVariant *params = NULL; + GVariant *message = NULL; + + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + __add_rule_info_to_builder(builder, rule); + params = g_variant_new("(a{sv})", builder); + g_variant_builder_unref(builder); + + message = stc_manager_gdbus_call_sync(connection, + STC_IPTABLES_DBUS_SERVICE, + STC_IPTABLES_DBUS_RULE_PATH, + STC_IPTABLES_DBUS_RULE_INTERFACE, + STC_IPTABLES_DBUS_METHOD_IPT_ADD_RULE, + params); + + if (message == NULL) { + STC_LOGE("Failed to invoke dbus method"); + return STC_ERROR_FAIL; + } + + g_variant_get(message, "(i)", &result); + STC_LOGD("Successfully Add Rule [%d]", result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __iptables_rule_remove(GDBusConnection *connection, + iptables_rule_s *rule) +{ + int result = 0; + GVariantBuilder *builder = NULL; + GVariant *params = NULL; + GVariant *message = NULL; + + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + __add_rule_info_to_builder(builder, rule); + params = g_variant_new("(a{sv})", builder); + g_variant_builder_unref(builder); + + message = stc_manager_gdbus_call_sync(connection, + STC_IPTABLES_DBUS_SERVICE, + STC_IPTABLES_DBUS_RULE_PATH, + STC_IPTABLES_DBUS_RULE_INTERFACE, + STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_RULE, + params); + + if (message == NULL) { + STC_LOGE("Failed to invoke dbus method"); + return STC_ERROR_FAIL; + } + + g_variant_get(message, "(i)", &result); + STC_LOGD("Successfully Remove Rule [%d]", result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __ip6tables_rule_add(GDBusConnection *connection, + iptables_rule_s *rule) +{ + int result = 0; + GVariantBuilder *builder = NULL; + GVariant *params = NULL; + GVariant *message = NULL; + + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + __add_rule_info_to_builder(builder, rule); + params = g_variant_new("(a{sv})", builder); + g_variant_builder_unref(builder); + + message = stc_manager_gdbus_call_sync(connection, + STC_IPTABLES_DBUS_SERVICE, + STC_IPTABLES_DBUS_RULE_PATH, + STC_IPTABLES_DBUS_RULE_INTERFACE, + STC_IPTABLES_DBUS_METHOD_IP6T_ADD_RULE, + params); + + if (message == NULL) { + STC_LOGE("Failed to invoke dbus method"); + return STC_ERROR_FAIL; + } + + g_variant_get(message, "(i)", &result); + STC_LOGD("Successfully Add 6 Rule [%d]", result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __ip6tables_rule_remove(GDBusConnection *connection, + iptables_rule_s *rule) +{ + int result = 0; + GVariantBuilder *builder = NULL; + GVariant *params = NULL; + GVariant *message = NULL; + + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + __add_rule_info_to_builder(builder, rule); + params = g_variant_new("(a{sv})", builder); + g_variant_builder_unref(builder); + + message = stc_manager_gdbus_call_sync(connection, + STC_IPTABLES_DBUS_SERVICE, + STC_IPTABLES_DBUS_RULE_PATH, + STC_IPTABLES_DBUS_RULE_INTERFACE, + STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_RULE, + params); + + if (message == NULL) { + STC_LOGE("Failed to invoke dbus method"); + return STC_ERROR_FAIL; + } + + g_variant_get(message, "(i)", &result); + STC_LOGD("Successfully Remove 6 Rule [%d]", result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +stc_error_e iptables_add(iptables_rule_s *rule) +{ + stc_error_e ret = STC_ERROR_NONE; + stc_s *stc = stc_get_manager(); + + if (!stc || !stc->connection) + return STC_ERROR_INVALID_PARAMETER; + + ret = __iptables_rule_add(stc->connection, rule); + if (ret != STC_ERROR_NONE) + goto done; + + ret = __ip6tables_rule_add(stc->connection, rule); +done: + return ret; +} + +stc_error_e iptables_remove(iptables_rule_s *rule) +{ + stc_error_e ret = STC_ERROR_NONE; + stc_s *stc = stc_get_manager(); + + if (!stc || !stc->connection) + return STC_ERROR_INVALID_PARAMETER; + + ret = __iptables_rule_remove(stc->connection, rule); + if (ret != STC_ERROR_NONE) + goto done; + + ret = __ip6tables_rule_remove(stc->connection, rule); +done: + return ret; +} diff --git a/src/helper/helper-iptables.h b/src/helper/helper-iptables.h new file mode 100755 index 0000000..fed7650 --- /dev/null +++ b/src/helper/helper-iptables.h @@ -0,0 +1,40 @@ +/* + * 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_HELPER_IPTABLES_H__ +#define __STC_HELPER_IPTABLES_H__ + +#include "stc-manager.h" +#include "stc-error.h" + +typedef enum { + IPTABLES_DIRECTION_IN, + IPTABLES_DIRECTION_OUT +} iptables_rule_direction_e; + +typedef struct { + char *chain; + char *ifname; + char *nfacct_name; + char *target; + iptables_rule_direction_e direction; + uint32_t classid; +} iptables_rule_s; + +stc_error_e iptables_add(iptables_rule_s *rule); +stc_error_e iptables_remove(iptables_rule_s *rule); + +#endif /*__STC_HELPER_IPTABLES_H__*/ diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index 952e414..5b2cde4 100755 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -26,6 +26,7 @@ #include "counter.h" #include "helper-nfacct-rule.h" +#include "helper-iptables.h" #include "configure_stub.h" @@ -37,8 +38,8 @@ #define INSERT "-I" #define NFACCT_NAME_MOD " -m nfacct --nfacct-name %s" -#define REJECT_RULE " -j REJECT" -#define ACCEPT_RULE " -j ACCEPT" +#define REJECT_RULE "REJECT" +#define ACCEPT_RULE "ACCEPT" #define OUT_RULE "OUTPUT" #define IN_RULE "INPUT" #define FORWARD_RULE "FORWARD" @@ -394,192 +395,6 @@ netlink_create_command(struct netlink_serialization_params *params) return &command; } -static unsigned int get_args_number(const char *cmd_buf) -{ - char *str; - unsigned int count = 0; - - for (str = (char *)cmd_buf; *str != '\0'; ++str) { - if (*str == ' ') - ++count; - } - return count; -} - -static void wait_for_rule_cmd(pid_t pid) -{ - int status; - pid_t ret_pid; - - if (!pid || pid == -1) { - STC_LOGD("no need to wait"); - return; - } - - ret_pid = waitpid(pid, &status, 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)); - } -} - -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; - char *args[args_number + 2]; - int ret; - char *save_ptr = NULL; - - if (STC_DEBUG_LOG) - STC_LOGD("executing iptables cmd %s in forked process", cmd_buf); - - args[0] = "iptables"; - cmd = strtok_r((char *)cmd_buf, " ", &save_ptr); - if (cmd == NULL) { - STC_LOGE("no arguments"); - exit(-EINVAL); - } - - for (i = 1; i <= args_number; ++i) - args[i] = strtok_r(NULL, " ", &save_ptr); - - args[i] = NULL; - - ret = execv(cmd, args); - 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); - } - - *cmd_pid = pid; - return STC_ERROR_NONE; -} - -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; - char *args[args_number + 2]; - int ret; - char *save_ptr = NULL; - - if (STC_DEBUG_LOG) - STC_LOGD("executing ip6tables cmd %s in forked process", cmd_buf); - - args[0] = "ip6tables"; - cmd = strtok_r((char *)cmd_buf, " ", &save_ptr); - if (cmd == NULL) { - STC_LOGE("no arguments"); - exit(-EINVAL); - } - - for (i = 1; i <= args_number; ++i) - args[i] = strtok_r(NULL, " ", &save_ptr); - - args[i] = NULL; - - ret = execv(cmd, args); - 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); - } - - *cmd_pid = pid; - return STC_ERROR_NONE; -} - -static char *choose_iftype_name(nfacct_rule_s *rule) -{ - return strlen(rule->ifname) != 0 ? rule->ifname : - get_iftype_name(rule->iftype); -} - -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, 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"); - - if (iptype == NFACCT_TYPE_IPV6) - iptables_type = IP6TABLES; - - 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"); - - if (iptype == NFACCT_TYPE_IPV6) - exec_ip6tables_cmd(block_buf, pid); - else - exec_iptables_cmd(block_buf, pid); - - wait_for_rule_cmd(*pid); - - 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, 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"); - - if (iptype == NFACCT_TYPE_IPV6) - iptables_type = IP6TABLES; - - 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"); - - if (iptype == NFACCT_TYPE_IPV6) - exec_ip6tables_cmd(block_buf, pid); - else - exec_iptables_cmd(block_buf, pid); - - wait_for_rule_cmd(*pid); - - return STC_ERROR_NONE; -} - static char *get_iptables_cmd(const nfacct_rule_action action) { if (action == NFACCT_ACTION_APPEND) @@ -598,6 +413,8 @@ static char *get_iptables_chain(const nfacct_rule_direction iotype) return IN_RULE; else if (iotype == NFACCT_COUNTER_OUT) return OUT_RULE; + else if (iotype == NFACCT_COUNTER_FORWARD) + return FORWARD_RULE; return ""; } @@ -612,6 +429,41 @@ static char *get_iptables_jump(const nfacct_rule_jump jump) return ""; } +static char *choose_iftype_name(nfacct_rule_s *rule) +{ + return strlen(rule->ifname) != 0 ? rule->ifname : + get_iftype_name(rule->iftype); +} + +static stc_error_e exec_iptables_cmd(nfacct_rule_s *rule) +{ + stc_error_e ret = STC_ERROR_NONE; + iptables_rule_s iptables_rule; + memset(&iptables_rule, 0, sizeof(iptables_rule_s)); + + iptables_rule.nfacct_name = g_strdup(rule->name); + iptables_rule.ifname = g_strdup(rule->ifname); + iptables_rule.target = g_strdup(get_iptables_jump(rule->jump)); + iptables_rule.chain = g_strdup(get_iptables_chain(rule->iotype)); + iptables_rule.classid = rule->classid; + iptables_rule.direction = (rule->iotype & NFACCT_COUNTER_IN) ? 0 : 1; + + if (rule->action == NFACCT_ACTION_DELETE) { + /* delete interface rule */ + ret = iptables_remove(&iptables_rule); + } else { + /* add interface rule */ + ret = iptables_add(&iptables_rule); + } + + g_free(iptables_rule.nfacct_name); + g_free(iptables_rule.ifname); + g_free(iptables_rule.target); + g_free(iptables_rule.chain); + + return ret; +} + static stc_error_e produce_app_rule(nfacct_rule_s *rule) { if (rule == NULL) @@ -622,7 +474,6 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule) 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 (rule->iotype & NFACCT_COUNTER_IN) { @@ -651,9 +502,7 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule) ret_value_msg_if(ret > sizeof(nfacct_buf) || ret < 0, STC_ERROR_FAIL, "Not enought buffer"); - ret = exec_app_cmd(RULE_APP_IN, set_cmd, nfacct_buf, jump_cmd, - rule->classid, choose_iftype_name(rule), - &pid, rule->iptype); + ret = exec_iptables_cmd(rule); 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", @@ -696,13 +545,12 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule) ret_value_msg_if(ret > sizeof(nfacct_buf) || ret < 0, STC_ERROR_FAIL, "Not enought buffer"); - ret = exec_app_cmd(RULE_APP_OUT, set_cmd, nfacct_buf, jump_cmd, - rule->classid, choose_iftype_name(rule), - &pid, rule->iptype); + ret = exec_iptables_cmd(rule); 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 (rule->action == NFACCT_ACTION_DELETE) { rule->iptables_rule = nfacct_send_del; /* not effective, it's better to replace @@ -729,7 +577,8 @@ static stc_error_e produce_iface_rule(nfacct_rule_s *rule) char nfacct_buf[sizeof(NFACCT_NAME_MOD) + 3*MAX_DEC_SIZE(int) + 4]; stc_error_e ret; - pid_t pid = 0; + + rule->classid = 0; if (rule->iotype & NFACCT_COUNTER_IN) { /* income part */ @@ -756,11 +605,7 @@ 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 enought buffer"); - ret = exec_iface_cmd(RULE_IFACE_IN, set_cmd, - get_iptables_chain(rule->iotype), - nfacct_buf, jump_cmd, - choose_iftype_name(rule), &pid, - rule->iptype); + ret = exec_iptables_cmd(rule); 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", @@ -770,10 +615,11 @@ 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 */ - ret = exec_iface_cmd(RULE_IFACE_IN, set_cmd, - FORWARD_RULE, nfacct_buf, jump_cmd, - choose_iftype_name(rule), &pid, - rule->iptype); + nfacct_rule_direction temp_iotype = rule->iotype; + + rule->iotype = NFACCT_COUNTER_FORWARD; + ret = exec_iptables_cmd(rule); + rule->iotype = temp_iotype; 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", @@ -816,21 +662,20 @@ 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"); - ret = exec_iface_cmd(RULE_IFACE_OUT, set_cmd, OUT_RULE, - nfacct_buf, jump_cmd, - choose_iftype_name(rule), &pid, - rule->iptype); + ret = exec_iptables_cmd(rule); 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", rule->iftype, set_cmd, jump_cmd); + /* for tethering */ if (rule->intend == NFACCT_WARN || rule->intend == NFACCT_BLOCK) { - ret = exec_iface_cmd(RULE_IFACE_OUT, set_cmd, - FORWARD_RULE, nfacct_buf, jump_cmd, - choose_iftype_name(rule), &pid, - rule->iptype); + nfacct_rule_direction temp_iotype = rule->iotype; + + rule->iotype = NFACCT_COUNTER_OUT; + ret = exec_iptables_cmd(rule); + rule->iotype = temp_iotype; 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", diff --git a/src/helper/helper-nfacct-rule.h b/src/helper/helper-nfacct-rule.h index 89eb27c..88b33ad 100755 --- a/src/helper/helper-nfacct-rule.h +++ b/src/helper/helper-nfacct-rule.h @@ -31,6 +31,7 @@ typedef enum { NFACCT_COUNTER_UNKNOWN, NFACCT_COUNTER_IN = (1 << 1), NFACCT_COUNTER_OUT = (1 << 2), + NFACCT_COUNTER_FORWARD = (1 << 3), NFACCT_COUNTER_LAST_ELEM } nfacct_rule_direction; diff --git a/src/stc-manager.c b/src/stc-manager.c index fb5d75a..0e6eb8c 100755 --- a/src/stc-manager.c +++ b/src/stc-manager.c @@ -29,6 +29,7 @@ static stc_s *g_stc = NULL; +/* static gboolean __validate_ident(const char *ident) { unsigned int i; @@ -42,6 +43,7 @@ static gboolean __validate_ident(const char *ident) return TRUE; } +*/ static void __stc_manager_deinit(void) { -- 2.7.4 From 1ef4eafbdedb92720445e0a9e38912a0c46cabaf Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Fri, 8 Dec 2017 16:08:24 +0530 Subject: [PATCH 16/16] Creating seperate chains[STC_IN, STC_OUT, STC_FRWD] for STC Framework's rules. Change-Id: I74b9ce4d13fb9122c4e0ea05226a22a925d1a585 Signed-off-by: Nishant Chaprana --- packaging/stc-manager.spec | 2 +- src/helper/helper-iptables.c | 333 ++++++++++++++++++++++++++++++++++++++-- src/helper/helper-iptables.h | 7 + src/helper/helper-nfacct-rule.c | 6 +- src/monitor/stc-monitor.c | 11 ++ src/stc-manager-gdbus.c | 2 + src/stc-manager.c | 2 + 7 files changed, 350 insertions(+), 13 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index b67e5ea..bd37172 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.41 +Version: 0.0.42 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/helper/helper-iptables.c b/src/helper/helper-iptables.c index 42fa6f6..96eacb8 100755 --- a/src/helper/helper-iptables.c +++ b/src/helper/helper-iptables.c @@ -17,17 +17,19 @@ #include "stc-manager-gdbus.h" #include "helper-iptables.h" -#define STC_IPTABLES_DBUS_SERVICE "net.stc.iptables" -#define STC_IPTABLES_DBUS_RULE_INTERFACE STC_IPTABLES_DBUS_SERVICE ".rule" -#define STC_IPTABLES_DBUS_CHAIN_INTERFACE STC_IPTABLES_DBUS_SERVICE ".chain" -#define STC_IPTABLES_DBUS_RULE_PATH "/net/stc/iptables/rule" -#define STC_IPTABLES_DBUS_CHAIN_PATH "/net/stc/iptables/chain" -#define STC_IPTABLES_DBUS_METHOD_IPT_ADD_CHAIN "IptAddChain" -#define STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_CHAIN "IptRemoveChain" +#define STC_IPTABLES_DBUS_SERVICE "net.stc.iptables" +#define STC_IPTABLES_DBUS_RULE_INTERFACE STC_IPTABLES_DBUS_SERVICE ".rule" +#define STC_IPTABLES_DBUS_CHAIN_INTERFACE STC_IPTABLES_DBUS_SERVICE ".chain" +#define STC_IPTABLES_DBUS_RULE_PATH "/net/stc/iptables/rule" +#define STC_IPTABLES_DBUS_CHAIN_PATH "/net/stc/iptables/chain" +#define STC_IPTABLES_DBUS_METHOD_IPT_ADD_CHAIN "IptAddChain" +#define STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_CHAIN "IptRemoveChain" +#define STC_IPTABLES_DBUS_METHOD_IPT_FLUSH_CHAIN "IptFlushChain" #define STC_IPTABLES_DBUS_METHOD_IP6T_ADD_CHAIN "Ip6tAddChain" #define STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_CHAIN "Ip6tRemoveChain" -#define STC_IPTABLES_DBUS_METHOD_IPT_ADD_RULE "IptAddRule" -#define STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_RULE "IptRemoveRule" +#define STC_IPTABLES_DBUS_METHOD_IP6T_FLUSH_CHAIN "Ip6tFlushChain" +#define STC_IPTABLES_DBUS_METHOD_IPT_ADD_RULE "IptAddRule" +#define STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_RULE "IptRemoveRule" #define STC_IPTABLES_DBUS_METHOD_IP6T_ADD_RULE "Ip6tAddRule" #define STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_RULE "Ip6tRemoveRule" @@ -196,6 +198,174 @@ static int __ip6tables_rule_remove(GDBusConnection *connection, return STC_ERROR_NONE; } +static int __iptables_add_chain(GDBusConnection *connection, + const char *chain) +{ + int result = 0; + GVariant *message = NULL; + + message = stc_manager_gdbus_call_sync(connection, + STC_IPTABLES_DBUS_SERVICE, + STC_IPTABLES_DBUS_CHAIN_PATH, + STC_IPTABLES_DBUS_CHAIN_INTERFACE, + STC_IPTABLES_DBUS_METHOD_IPT_ADD_CHAIN, + g_variant_new("(s)", chain)); + + if (message == NULL) { + STC_LOGE("Failed to invoke dbus method"); + return STC_ERROR_FAIL; + } + + g_variant_get(message, "(i)", &result); + STC_LOGD("Successfully added ipv4 chain [%d]", result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __ip6tables_add_chain(GDBusConnection *connection, + const char *chain) +{ + int result = 0; + GVariant *message = NULL; + + message = stc_manager_gdbus_call_sync(connection, + STC_IPTABLES_DBUS_SERVICE, + STC_IPTABLES_DBUS_CHAIN_PATH, + STC_IPTABLES_DBUS_CHAIN_INTERFACE, + STC_IPTABLES_DBUS_METHOD_IP6T_ADD_CHAIN, + g_variant_new("(s)", chain)); + + if (message == NULL) { + STC_LOGE("Failed to invoke dbus method"); + return STC_ERROR_FAIL; + } + + g_variant_get(message, "(i)", &result); + STC_LOGD("Successfully added ipv6 chain [%d]", result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __iptables_remove_chain(GDBusConnection *connection, + const char *chain) +{ + int result = 0; + GVariant *message = NULL; + + message = stc_manager_gdbus_call_sync(connection, + STC_IPTABLES_DBUS_SERVICE, + STC_IPTABLES_DBUS_CHAIN_PATH, + STC_IPTABLES_DBUS_CHAIN_INTERFACE, + STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_CHAIN, + g_variant_new("(s)", chain)); + + if (message == NULL) { + STC_LOGE("Failed to invoke dbus method"); + return STC_ERROR_FAIL; + } + + g_variant_get(message, "(i)", &result); + STC_LOGD("Successfully removed ipv4 chain [%d]", result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __ip6tables_remove_chain(GDBusConnection *connection, + const char *chain) +{ + int result = 0; + GVariant *message = NULL; + + message = stc_manager_gdbus_call_sync(connection, + STC_IPTABLES_DBUS_SERVICE, + STC_IPTABLES_DBUS_CHAIN_PATH, + STC_IPTABLES_DBUS_CHAIN_INTERFACE, + STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_CHAIN, + g_variant_new("(s)", chain)); + + if (message == NULL) { + STC_LOGE("Failed to invoke dbus method"); + return STC_ERROR_FAIL; + } + + g_variant_get(message, "(i)", &result); + STC_LOGD("Successfully removed ipv6 chain [%d]", result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __iptables_flush_chain(GDBusConnection *connection, + const char *chain) +{ + int result = 0; + GVariant *message = NULL; + + message = stc_manager_gdbus_call_sync(connection, + STC_IPTABLES_DBUS_SERVICE, + STC_IPTABLES_DBUS_CHAIN_PATH, + STC_IPTABLES_DBUS_CHAIN_INTERFACE, + STC_IPTABLES_DBUS_METHOD_IPT_FLUSH_CHAIN, + g_variant_new("(s)", chain)); + + if (message == NULL) { + STC_LOGE("Failed to invoke dbus method"); + return STC_ERROR_FAIL; + } + + g_variant_get(message, "(i)", &result); + STC_LOGD("Successfully flushed ipv4 chain [%d]", result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __ip6tables_flush_chain(GDBusConnection *connection, + const char *chain) +{ + int result = 0; + GVariant *message = NULL; + + message = stc_manager_gdbus_call_sync(connection, + STC_IPTABLES_DBUS_SERVICE, + STC_IPTABLES_DBUS_CHAIN_PATH, + STC_IPTABLES_DBUS_CHAIN_INTERFACE, + STC_IPTABLES_DBUS_METHOD_IP6T_FLUSH_CHAIN, + g_variant_new("(s)", chain)); + + if (message == NULL) { + STC_LOGE("Failed to invoke dbus method"); + return STC_ERROR_FAIL; + } + + g_variant_get(message, "(i)", &result); + STC_LOGD("Successfully flushed ipv6 chain [%d]", result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __iptables_add_chain_jump_rule(const char *chain, + const char *target) +{ + stc_error_e ret = STC_ERROR_NONE; + iptables_rule_s iptables_rule; + memset(&iptables_rule, 0, sizeof(iptables_rule_s)); + + iptables_rule.target = g_strdup(target); + iptables_rule.chain = g_strdup(chain); + + ret = iptables_add(&iptables_rule); + + g_free(iptables_rule.target); + g_free(iptables_rule.chain); + + return ret; +} + stc_error_e iptables_add(iptables_rule_s *rule) { stc_error_e ret = STC_ERROR_NONE; @@ -229,3 +399,148 @@ stc_error_e iptables_remove(iptables_rule_s *rule) done: return ret; } + +stc_error_e iptables_flush_chains(void) +{ + stc_error_e ret = STC_ERROR_NONE; + stc_s *stc = stc_get_manager(); + + if (!stc || !stc->connection) + return STC_ERROR_INVALID_PARAMETER; + + ret = __iptables_flush_chain(stc->connection, STC_IN_CHAIN); + if (ret != STC_ERROR_NONE) + goto done; + + ret = __iptables_flush_chain(stc->connection, STC_OUT_CHAIN); + if (ret != STC_ERROR_NONE) + goto done; + + ret = __iptables_flush_chain(stc->connection, STC_FRWD_CHAIN); + if (ret != STC_ERROR_NONE) + goto done; + + ret = __ip6tables_flush_chain(stc->connection, STC_IN_CHAIN); + if (ret != STC_ERROR_NONE) + goto done; + + ret = __ip6tables_flush_chain(stc->connection, STC_OUT_CHAIN); + if (ret != STC_ERROR_NONE) + goto done; + + ret = __ip6tables_flush_chain(stc->connection, STC_FRWD_CHAIN); +done: + return ret; +} + +stc_error_e iptables_init(void) +{ + __STC_LOG_FUNC_ENTER__; + + stc_error_e ret = STC_ERROR_NONE; + stc_s *stc = stc_get_manager(); + + if (!stc || !stc->connection) { + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_INVALID_PARAMETER; + } + + ret = __iptables_add_chain(stc->connection, STC_IN_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __iptables_add_chain(stc->connection, STC_OUT_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __iptables_add_chain(stc->connection, STC_FRWD_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __ip6tables_add_chain(stc->connection, STC_IN_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __ip6tables_add_chain(stc->connection, STC_OUT_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __ip6tables_add_chain(stc->connection, STC_FRWD_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __iptables_add_chain_jump_rule("INPUT", STC_IN_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __iptables_add_chain_jump_rule("OUTPUT", STC_OUT_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __iptables_add_chain_jump_rule("FORWARD", STC_FRWD_CHAIN); +done: + return ret; +} + +stc_error_e iptables_deinit(void) +{ + __STC_LOG_FUNC_ENTER__; + + stc_error_e ret = STC_ERROR_NONE; + stc_s *stc = stc_get_manager(); + + if (!stc || !stc->connection) { + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_INVALID_PARAMETER; + } + + ret = __iptables_remove_chain(stc->connection, STC_IN_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __iptables_remove_chain(stc->connection, STC_OUT_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __iptables_remove_chain(stc->connection, STC_FRWD_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __ip6tables_remove_chain(stc->connection, STC_IN_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __ip6tables_remove_chain(stc->connection, STC_OUT_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } + + ret = __ip6tables_remove_chain(stc->connection, STC_FRWD_CHAIN); +done: + return ret; +} diff --git a/src/helper/helper-iptables.h b/src/helper/helper-iptables.h index fed7650..bdfedb1 100755 --- a/src/helper/helper-iptables.h +++ b/src/helper/helper-iptables.h @@ -20,6 +20,10 @@ #include "stc-manager.h" #include "stc-error.h" +#define STC_IN_CHAIN "STC_IN" +#define STC_OUT_CHAIN "STC_OUT" +#define STC_FRWD_CHAIN "STC_FRWD" + typedef enum { IPTABLES_DIRECTION_IN, IPTABLES_DIRECTION_OUT @@ -36,5 +40,8 @@ typedef struct { stc_error_e iptables_add(iptables_rule_s *rule); stc_error_e iptables_remove(iptables_rule_s *rule); +stc_error_e iptables_flush_chains(void); +stc_error_e iptables_init(void); +stc_error_e iptables_deinit(void); #endif /*__STC_HELPER_IPTABLES_H__*/ diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index 5b2cde4..374090a 100755 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -410,11 +410,11 @@ static char *get_iptables_cmd(const nfacct_rule_action action) static char *get_iptables_chain(const nfacct_rule_direction iotype) { if (iotype == NFACCT_COUNTER_IN) - return IN_RULE; + return STC_IN_CHAIN; else if (iotype == NFACCT_COUNTER_OUT) - return OUT_RULE; + return STC_OUT_CHAIN; else if (iotype == NFACCT_COUNTER_FORWARD) - return FORWARD_RULE; + return STC_FRWD_CHAIN; return ""; } diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 8b18657..268c5cf 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -23,6 +23,7 @@ #include "helper-nfacct-rule.h" #include "helper-net-cls.h" #include "helper-cgroup.h" +#include "helper-iptables.h" #include "counter.h" #include "table-statistics.h" #include "table-counters.h" @@ -526,6 +527,10 @@ static void __process_restriction(enum traffic_restriction_type rst_type, char *default_ifname = stc_default_connection_get_ifname(); struct nfacct_rule counter; stc_s *stc = stc_get_manager(); + if (!stc) { + g_free(default_ifname); + return; + } if (!stc->carg) { stc->carg = MALLOC0(counter_arg_s, 1); @@ -568,6 +573,10 @@ static void __process_restriction(enum traffic_restriction_type rst_type, char *default_ifname = stc_default_connection_get_ifname(); struct nfacct_rule counter; stc_s *stc = stc_get_manager(); + if (!stc) { + g_free(default_ifname); + return; + } if (!stc->carg) { stc->carg = MALLOC0(counter_arg_s, 1); @@ -1870,6 +1879,8 @@ void stc_monitor_update_rstn_by_default_connection(void *data) g_tree_foreach(g_system->rstns, __remove_restriction, (gpointer)&old_connection); + + iptables_flush_chains(); } FREE(old_connection.path); diff --git a/src/stc-manager-gdbus.c b/src/stc-manager-gdbus.c index aee4c9e..bf556e6 100755 --- a/src/stc-manager-gdbus.c +++ b/src/stc-manager-gdbus.c @@ -20,6 +20,7 @@ #include "stc-default-connection.h" #include "stc-manager-plugin.h" #include "stc-app-lifecycle.h" +#include "helper-iptables.h" static gboolean __stc_manager_gdbus_statistics_init(stc_s *stc) { @@ -154,6 +155,7 @@ static void __stc_manager_gdbus_on_bus_acquired(GDBusConnection *connection, g_dbus_object_manager_server_set_connection(stc->obj_mgr, stc->connection); + iptables_init(); stc_default_connection_monitor_init(stc); stc_register_state_changed_cb(stc, stc_manager_app_status_changed, NULL); diff --git a/src/stc-manager.c b/src/stc-manager.c index 0e6eb8c..5e7ddd6 100755 --- a/src/stc-manager.c +++ b/src/stc-manager.c @@ -23,6 +23,7 @@ #include "table-restrictions.h" #include "helper-cgroup.h" #include "helper-nfacct-rule.h" +#include "helper-iptables.h" #include "stc-monitor.h" #include "stc-manager-plugin.h" #include "stc-app-lifecycle.h" @@ -58,6 +59,7 @@ static void __stc_manager_deinit(void) stc_deinit_db_guard(); stc_db_deinitialize(); + iptables_deinit(); stc_manager_gdbus_deinit((gpointer)g_stc); stc_app_lifecycle_monitor_deinit(); stc_manager_plugin_deinit(); -- 2.7.4