From ec67a82d1fd89d965b109b06554f5d162e67f60c Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Thu, 2 Aug 2018 12:58:01 +0530 Subject: [PATCH 01/16] Removed redundant NULL check Change-Id: Id29b2b3473715d454496c860b46f13ef3070ce0e Signed-off-by: Nishant Chaprana --- src/stc-manager-gdbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stc-manager-gdbus.c b/src/stc-manager-gdbus.c index 672909b..2e5803c 100644 --- a/src/stc-manager-gdbus.c +++ b/src/stc-manager-gdbus.c @@ -458,7 +458,7 @@ void stc_manager_gdbus_dict_foreach(GVariantIter *iter, dbus_dict_cb cb, while (g_variant_iter_loop(iter, "{sv}", &key, &value)) { /* DEBUG_GDBUS_KEY_VALUE(key, value); */ - if (key && cb) + if (key) cb(key, value, user_data); } -- 2.7.4 From ea8a61cd93110141438e5165fc3b07eb5d61b13c Mon Sep 17 00:00:00 2001 From: Milind Murhekar Date: Wed, 8 Aug 2018 17:55:21 +0530 Subject: [PATCH 02/16] [Add] tether plugin This change adds a plugin called "tether" to support data usage for tethering client stations. Change-Id: I823c832f42613f0b607b96e0d863e532fe892e63 Signed-off-by: Milind Murhekar --- include/stc-manager-plugin-tether.h | 29 +++++ packaging/stc-manager.spec | 10 ++ plugin/CMakeLists.txt | 1 + plugin/tether/CMakeLists.txt | 36 ++++++ plugin/tether/include/stc-plugin-tether.h | 46 +++++++ plugin/tether/stc-plugin-tether.c | 197 ++++++++++++++++++++++++++++++ src/CMakeLists.txt | 2 + src/stc-manager-plugin-tether.c | 67 ++++++++++ src/stc-manager.c | 3 + 9 files changed, 391 insertions(+) create mode 100644 include/stc-manager-plugin-tether.h create mode 100644 plugin/tether/CMakeLists.txt create mode 100644 plugin/tether/include/stc-plugin-tether.h create mode 100644 plugin/tether/stc-plugin-tether.c create mode 100644 src/stc-manager-plugin-tether.c diff --git a/include/stc-manager-plugin-tether.h b/include/stc-manager-plugin-tether.h new file mode 100644 index 0000000..bdee306 --- /dev/null +++ b/include/stc-manager-plugin-tether.h @@ -0,0 +1,29 @@ +/* + * 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_MANAGER_PLUGIN_TETHER_H__ +#define __STC_MANAGER_PLUGIN_TETHER_H__ + +#define STC_PLUGIN_TETHER_FILEPATH "/usr/lib/stc-plugin-tether.so" + +#include "stc-plugin-tether.h" + +int stc_plugin_tether_init(void); +int stc_plugin_tether_deinit(void); +stc_error_e stc_plugin_tether_load(void); +stc_error_e stc_plugin_tether_status_changed(void); + +#endif /* __STC_MANAGER_PLUGIN_TETHER_H__ */ diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index b227159..6b0b965 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -57,6 +57,12 @@ Summary: STC manager exception proc file system plugin %description plugin-procfs A smart traffic control manager extension for proc file system plugin +%package plugin-tether +Summary: Tethering plugin for data usage of tethering clients + +%description plugin-tether +A smart traffic control manager extension for tethering client data usage plugin + %prep %setup -q chmod 644 %{SOURCE0} @@ -144,3 +150,7 @@ cp resources/dbus/stc-manager.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/st %files plugin-procfs %manifest %{name}.manifest %attr(500,root,root) %{_libdir}/stc-plugin-procfs.so + +%files plugin-tether +%manifest %{name}.manifest +%attr(500,root,root) %{_libdir}/stc-plugin-tether.so diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index ce92a27..e591d7a 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -18,3 +18,4 @@ INCLUDE_DIRECTORIES(${MONITOR_SOURCE_DIR}/include) ADD_SUBDIRECTORY(appstatus) ADD_SUBDIRECTORY(exception) ADD_SUBDIRECTORY(procfs) +ADD_SUBDIRECTORY(tether) diff --git a/plugin/tether/CMakeLists.txt b/plugin/tether/CMakeLists.txt new file mode 100644 index 0000000..889f44a --- /dev/null +++ b/plugin/tether/CMakeLists.txt @@ -0,0 +1,36 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(stc-plugin-tether C) + +# Set required packages +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(tether_plugin REQUIRED + dlog + gio-2.0 + gio-unix-2.0 + glib-2.0 + ) + +FOREACH(flag ${tether_plugin_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -g -Werror -fvisibility=hidden") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") + +ADD_DEFINITIONS("-DUSE_DLOG") + +SET(SRCS_PLUGIN + stc-plugin-tether.c + ) + +# library build +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS_PLUGIN}) +ADD_DEPENDENCIES(${PROJECT_NAME} GENERATED_DBUS_CODE) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${tether_plugin_LDFLAGS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "" OUTPUT_NAME ${PROJECT_NAME}) + +# install +INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${LIBDIR}) diff --git a/plugin/tether/include/stc-plugin-tether.h b/plugin/tether/include/stc-plugin-tether.h new file mode 100644 index 0000000..b3d4439 --- /dev/null +++ b/plugin/tether/include/stc-plugin-tether.h @@ -0,0 +1,46 @@ +/* + * 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_PLUGIN_TETHER_H__ +#define __STC_PLUGIN_TETHER_H__ + +#include +#include "stc-error.h" +#include "stc-manager.h" + +#define TETHERING_SERVICE_INTERFACE "org.tizen.tethering" +#define SIGNAL_NAME_DHCP_STATUS "dhcp_status" +#define STATION_STR_INFO_LEN 54 +#define STATION_STR_HOSTNAME_LEN 33 + +typedef struct { + gchar *station_id; + gchar name[STATION_STR_HOSTNAME_LEN + 1]; + gchar ip[STATION_STR_INFO_LEN + 1]; + gchar mac[STATION_STR_INFO_LEN + 1]; +} tether_sta_info_s; + +typedef struct { + int (*init) (void); + void (*deinit) (void); + int (*status_changed) (void); +} stc_plugin_tether_s; + +int tether_init(void); +void tether_deinit(void); +stc_error_e tether_plugin_status_changed(void); + +#endif /* __STC_PLUGIN_TETHER_H__ */ diff --git a/plugin/tether/stc-plugin-tether.c b/plugin/tether/stc-plugin-tether.c new file mode 100644 index 0000000..ed3ccd4 --- /dev/null +++ b/plugin/tether/stc-plugin-tether.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stc-monitor.h" +#include "stc-plugin-tether.h" + +static GSList *station_list = NULL; +static GDBusConnection *connection = NULL; +static GCancellable *cancellable = NULL; +static int g_mobileap_signal_sub_id = 0; + +static int _compare_sta_by_mac_func(gconstpointer a, + gconstpointer b) +{ + tether_sta_info_s *si = (tether_sta_info_s *)a; + return g_ascii_strcasecmp(si->mac, (const char *)b); +} + +static int _get_station_info(gconstpointer data, GCompareFunc func, + tether_sta_info_s **si) +{ + GSList *list = station_list; + tether_sta_info_s *info = NULL; + + if (func == NULL || si == NULL) + return -1; + + if (!list) + return -1; + + list = g_slist_find_custom(list, data, func); + if (list == NULL) + return -1; + + info = list->data; + *si = info; + return 0; +} + +static void _remove_station_info(gconstpointer data, GCompareFunc func) +{ + GSList *list = station_list; + tether_sta_info_s *info = NULL; + if (func == NULL) + return; + + if (!list) + return; + + list = g_slist_find_custom(list, data, func); + if (list == NULL) + return; + + info = (tether_sta_info_s *)list->data; + STC_LOGI("STA-REMOVED: (%s) (%s) (%s)", info->ip, info->mac, info->name); + g_free(info->station_id); + g_free(info); + + station_list = g_slist_delete_link(station_list, list); +} + +static void _add_station_info(tether_sta_info_s *info) +{ + tether_sta_info_s *tmp = NULL; + if (info == NULL) { + STC_LOGE("info is NULL"); + return; + } + + if (_get_station_info(info->mac, _compare_sta_by_mac_func, &tmp) == 0) { + if (!g_strcmp0(tmp->name, info->name) && !g_strcmp0(tmp->ip, info->ip)) + return; + + //Remove the station if dhcp info changed. + _remove_station_info(info->mac, _compare_sta_by_mac_func); + } + + station_list = g_slist_prepend(station_list, info); + STC_LOGI("STA-ADDED: (%s) (%s) (%s)", info->ip, info->mac, info->name); + info->station_id = g_strdup_printf("%s_%s", info->mac, info->name); +} + +static void _mobileap_signal_cb(GDBusConnection *conn, + const gchar *name, const gchar *path, + const gchar *interface, const gchar *sig, + GVariant *param, gpointer user_data) +{ + int type; + int tm; + char *ip = NULL; + char *mac = NULL; + char *hostname = NULL; + char *state = NULL; + tether_sta_info_s *sta = NULL; + + ret_msg_if(sig == NULL, "signal name NULL"); + ret_msg_if(param == NULL, "param NULL"); + + STC_LOGI("%s interface(%s)", sig, interface); + + sta = (tether_sta_info_s *)g_malloc0(sizeof(tether_sta_info_s)); + if (sta == NULL) { + STC_LOGE("g_malloc0 failed"); + return; + } + + g_variant_get(param, "(susssu)", &state, &type, &ip, &mac, &hostname, &tm); + STC_LOGI("%s: ip(%s) mac(%s) name(%s) tm(%d)", state, ip, mac, hostname, tm); + + if (!g_strcmp0(state, "DhcpConnected")) { + g_strlcpy(sta->ip, ip, STATION_STR_INFO_LEN); + g_strlcpy(sta->mac, mac, STATION_STR_INFO_LEN); + g_strlcpy(sta->name, hostname, STATION_STR_HOSTNAME_LEN); + _add_station_info(sta); + } else if (!g_strcmp0(state, "DhcpLeaseDeleted")) { + _remove_station_info(mac, _compare_sta_by_mac_func); + } + + g_free(state); + g_free(ip); + g_free(mac); + g_free(hostname); +} + +stc_error_e tether_plugin_status_changed(void) +{ + return STC_ERROR_NONE; +} + +int tether_plugin_init(void) +{ + GError *error = NULL; + + if (connection) + return 0; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (!connection) { + g_error_free(error); + return -1; + } + + cancellable = g_cancellable_new(); + + g_mobileap_signal_sub_id = g_dbus_connection_signal_subscribe(connection, + NULL, + TETHERING_SERVICE_INTERFACE, + SIGNAL_NAME_DHCP_STATUS, + NULL, NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + _mobileap_signal_cb, + NULL, NULL); + + STC_LOGI("tether plugin initialised"); + return 0; +} + +void tether_plugin_deinit(void) +{ + if (!connection) + return; + + g_object_unref(connection); + g_object_unref(cancellable); + connection = NULL; + cancellable = NULL; + STC_LOGI("tether plugin deinitialised"); +} + +/* Tether Plugin APIs */ +API stc_plugin_tether_s tether_plugin = { + .init = tether_plugin_init, + .deinit = tether_plugin_deinit, + .status_changed = tether_plugin_status_changed +}; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 809897a..c845dd0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,6 +31,7 @@ SET(PLUGIN_DIR ${CMAKE_SOURCE_DIR}/plugin) SET(APPSTATUS_SOURCE_DIR ${PLUGIN_DIR}/appstatus) SET(EXCEPTION_SOURCE_DIR ${PLUGIN_DIR}/exception) SET(PROCFS_SOURCE_DIR ${PLUGIN_DIR}/procfs) +SET(TETHER_SOURCE_DIR ${PLUGIN_DIR}/tether) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/interfaces) @@ -53,6 +54,7 @@ INCLUDE_DIRECTORIES(${LIMITATION_SOURCE_DIR}/include) INCLUDE_DIRECTORIES(${APPSTATUS_SOURCE_DIR}/include) INCLUDE_DIRECTORIES(${EXCEPTION_SOURCE_DIR}/include) INCLUDE_DIRECTORIES(${PROCFS_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${TETHER_SOURCE_DIR}/include) FILE(GLOB SOURCE_SRCS ${SOURCE_DIR}/*.c) FILE(GLOB HELPER_SRCS ${HELPER_SOURCE_DIR}/*.c) diff --git a/src/stc-manager-plugin-tether.c b/src/stc-manager-plugin-tether.c new file mode 100644 index 0000000..1813e40 --- /dev/null +++ b/src/stc-manager-plugin-tether.c @@ -0,0 +1,67 @@ +/* + * 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 "stc-manager.h" +#include "stc-manager-plugin-tether.h" + +static gboolean stc_tether_plugin_enabled = FALSE; +static void *tether_plugin_handle; +static stc_plugin_tether_s *plugin; + +int stc_plugin_tether_init(void) +{ + __STC_LOG_FUNC_ENTER__; + + tether_plugin_handle = dlopen(STC_PLUGIN_TETHER_FILEPATH, RTLD_NOW); + if (!tether_plugin_handle) { + STC_LOGE("Can't load %s: %s", STC_PLUGIN_TETHER_FILEPATH, dlerror()); + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_UNINITIALIZED; + } + + plugin = dlsym(tether_plugin_handle, "tether_plugin"); + if (!plugin) { + STC_LOGE("Can't load symbol: %s", dlerror()); + dlclose(tether_plugin_handle); + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_UNINITIALIZED; + } + + plugin->init(); + stc_tether_plugin_enabled = TRUE; + + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_NONE; +} + +int stc_plugin_tether_deinit(void) +{ + __STC_LOG_FUNC_ENTER__; + + if (!stc_tether_plugin_enabled) { + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_UNINITIALIZED; + } + + plugin->deinit(); + stc_tether_plugin_enabled = FALSE; + dlclose(tether_plugin_handle); + + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_NONE; +} diff --git a/src/stc-manager.c b/src/stc-manager.c index 436ee29..58f6531 100644 --- a/src/stc-manager.c +++ b/src/stc-manager.c @@ -31,6 +31,7 @@ #include "stc-manager-plugin-appstatus.h" #include "stc-manager-plugin-exception.h" #include "stc-manager-plugin-procfs.h" +#include "stc-manager-plugin-tether.h" #define BUF_SIZE_FOR_ERR 100 @@ -89,6 +90,7 @@ static void __stc_manager_deinit(void) stc_plugin_appstatus_deinit(); stc_plugin_exception_deinit(); stc_plugin_procfs_deinit(); + stc_plugin_tether_deinit(); inotify_deregister(INFO_STORAGE_DIR); inotify_deinitialize(); @@ -123,6 +125,7 @@ static stc_s *__stc_manager_init(void) stc_plugin_appstatus_init(); stc_plugin_exception_init(); stc_plugin_procfs_init(); + stc_plugin_tether_init(); stc_firewall_init(); -- 2.7.4 From a721485553d709539ffd205bbb16142d43765bf7 Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Wed, 22 Aug 2018 09:51:42 +0530 Subject: [PATCH 03/16] Add 'ps', 'awk' and 'pgrep' to exception list Change-Id: I965daf32489804429b316455071bca3d9a55f40b Signed-off-by: Nishant Chaprana --- data/exceptions | 3 +++ packaging/stc-manager.spec | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/data/exceptions b/data/exceptions index 2ce70b0..178bd7e 100644 --- a/data/exceptions +++ b/data/exceptions @@ -15,6 +15,7 @@ rpm:inst sh:inst sleep:inst grep:inst +pgrep:inst killall:inst systemctl:inst xargs:inst @@ -22,6 +23,8 @@ modprobe:inst pkgcmd:inst mount:inst chmod:inst +awk:inst +ps:inst wlan.sh:script wpa_supp.sh:script stc-manager:sys diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index b227159..bb2f8ed 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.74 +Version: 0.0.75 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 -- 2.7.4 From 5cbfb23b9a29e26b618f72f9f81b1e16faffb783 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Wed, 22 Aug 2018 14:07:57 +0900 Subject: [PATCH 04/16] Added new vconf key for VCONFKEY_SETAPPL_DATA_RESTRICTION_INT Change-Id: I1d869718893ada6c6b2b6ff979b1460672b34524 Signed-off-by: hyunuktak --- src/monitor/include/stc-monitor.h | 5 +++ src/monitor/stc-monitor.c | 82 ++++++++++++++++++++++++++------------- 2 files changed, 60 insertions(+), 27 deletions(-) mode change 100644 => 100755 src/monitor/include/stc-monitor.h mode change 100644 => 100755 src/monitor/stc-monitor.c diff --git a/src/monitor/include/stc-monitor.h b/src/monitor/include/stc-monitor.h old mode 100644 new mode 100755 index 3414c06..0977eba --- a/src/monitor/include/stc-monitor.h +++ b/src/monitor/include/stc-monitor.h @@ -40,6 +40,11 @@ typedef enum { STC_RSTN_LIMIT_TYPE_MAX } stc_rstn_limit_type_e; +typedef enum { + STC_RSTN_STATE_INIT = -1, + STC_RSTN_STATE_UNSET, + STC_RSTN_STATE_SET, +} stc_rstn_noti_state_e; /** * @brief key for processes tree diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c old mode 100644 new mode 100755 index 2a42682..694bf5c --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -34,7 +34,14 @@ #define GRANULARITY 10 #define MAX_INT_LENGTH 128 + +#ifndef VCONFKEY_STC_BACKGROUND_STATE #define VCONFKEY_STC_BACKGROUND_STATE "db/stc/background_state" +#endif + +#ifndef VCONFKEY_SETAPPL_DATA_RESTRICTION_INT +#define VCONFKEY_SETAPPL_DATA_RESTRICTION_INT "db/setting/data_restriction" +#endif typedef struct { time_t now; @@ -58,6 +65,34 @@ typedef struct { static stc_system_s *g_system = NULL; +//LCOV_EXCL_START +static int __vconf_get_int(const char *key, int *value) +{ + int ret = 0; + + ret = vconf_get_int(key, value); + if (ret != VCONF_OK) { + STC_LOGE("Failed to get vconfkey [%s] value", key); //LCOV_EXCL_LINE + return -1; //LCOV_EXCL_LINE + } + + return 0; +} + +static int __vconf_set_int(const char *key, int value) +{ + int ret = 0; + + ret = vconf_set_int(key, value); + if (ret != VCONF_OK) { + STC_LOGE("Failed to set vconfkey [%s] value", key); //LCOV_EXCL_LINE + return -1; //LCOV_EXCL_LINE + } + + return 0; +} +//LCOV_EXCL_STOP + static nfacct_rule_jump __get_jump_by_intend(struct nfacct_rule *counter) { if (counter->intend == NFACCT_WARN) @@ -608,6 +643,22 @@ static void __del_iptables_rule(int64_t classid, nfacct_rule_intend intend, __del_ip6tables_out(&counter); } +static void __set_rstn_noti_state(int value) +{ + int state = STC_RSTN_STATE_INIT; + + if (__vconf_get_int(VCONFKEY_SETAPPL_DATA_RESTRICTION_INT, &state)) + return; + + if (state == value) { + STC_LOGI("No need to change a restriction status: %d", state); + return; + } + + vconf_set_int(VCONFKEY_SETAPPL_DATA_RESTRICTION_INT, value); + return; +} + typedef struct { time_t month_start_ts; time_t week_start_ts; @@ -753,6 +804,8 @@ static void __process_restriction(enum traffic_restriction_type rstn_type, for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) if (rstn_value->limit[i] >= 0) rstn_value->counter[i] = 0; + + __set_rstn_noti_state(STC_RSTN_STATE_UNSET); } break; default: @@ -934,6 +987,8 @@ static void __action_when_rstn_limit_exceeded(stc_rstn_limit_type_e limit_type, context->counter->intend = NFACCT_COUNTER; rstn_value->limit_exceeded |= (1 << limit_type); + + __set_rstn_noti_state(STC_RSTN_STATE_SET); } break; default: @@ -1864,33 +1919,6 @@ static void __add_application_by_interface(const char *app_id) FREE(app_key.app_id); } -static int __vconf_get_int(const char *key, int *value) -{ - int ret = 0; - - ret = vconf_get_int(key, value); - if (ret != VCONF_OK) { - STC_LOGE("Failed to get vconfkey [%s] value", key); //LCOV_EXCL_LINE - return -1; //LCOV_EXCL_LINE - } - - return 0; -} - -//LCOV_EXCL_START -static int __vconf_set_int(const char *key, int value) -{ - int ret = 0; - - ret = vconf_set_int(key, value); - if (ret != VCONF_OK) { - STC_LOGE("Failed to set vconfkey [%s] value", key); //LCOV_EXCL_LINE - return -1; //LCOV_EXCL_LINE - } - - return 0; -} - static guint __get_background_state(void) { return g_system->background_state;; -- 2.7.4 From 6b6c8c8d2a7e95589fd3e2731ff0dd5d58bccf6a Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Wed, 22 Aug 2018 18:26:19 +0900 Subject: [PATCH 05/16] Removed flag for TIZEN_DEBUG_ENABLE Change-Id: I5589bc07ded2abe496bf8fdfdc10bcc82145e0a1 Signed-off-by: hyunuktak --- packaging/stc-manager.spec | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index b227159..295754d 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -63,9 +63,8 @@ chmod 644 %{SOURCE0} %build -export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE -D_GNU_SOURCE" -export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE -D_GNU_SOURCE" -export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" +export CFLAGS="$CFLAGS -D_GNU_SOURCE" +export CXXFLAGS="$CXXFLAGS -D_GNU_SOURCE" %cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \ -DBIN_DIR=%{_bindir} \ -- 2.7.4 From 4774bacda3da28d4b0e08c7d15a04e83fd336014 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Thu, 23 Aug 2018 14:44:38 +0900 Subject: [PATCH 06/16] Add to insert firewall rule Change-Id: I873350bb260bc1ef111b2a1e3f551019c9676273 Signed-off-by: hyunuktak --- packaging/stc-manager.spec | 2 +- src/database/tables/table-firewall.c | 4 +- src/helper/helper-firewall.c | 209 +++++++++++++++++++++++++++-------- src/helper/helper-firewall.h | 7 +- src/stc-firewall.c | 4 +- 5 files changed, 171 insertions(+), 55 deletions(-) mode change 100644 => 100755 src/database/tables/table-firewall.c mode change 100644 => 100755 src/stc-firewall.c diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 295754d..38eb499 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.74 +Version: 0.0.75 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/database/tables/table-firewall.c b/src/database/tables/table-firewall.c old mode 100644 new mode 100755 index 3eac6cf..3df1f52 --- a/src/database/tables/table-firewall.c +++ b/src/database/tables/table-firewall.c @@ -368,7 +368,9 @@ stc_error_e table_firewall_get_lock(char *name, int *state) switch (rc) { case SQLITE_DONE: - break; + STC_LOGD("There is no lock state [%s]", name); + error_code = STC_ERROR_NO_DATA; + goto handle_error; case SQLITE_ROW: *state = sqlite3_column_int(stmt, 0); break; diff --git a/src/helper/helper-firewall.c b/src/helper/helper-firewall.c index 14dff41..644ab75 100755 --- a/src/helper/helper-firewall.c +++ b/src/helper/helper-firewall.c @@ -31,8 +31,10 @@ #define STC_FIREWALL6_DBUS_METHOD_FLUSH_CHAIN "Ip6tFlushChain" #define STC_FIREWALL_DBUS_METHOD_ADD_RULE "IptAddRule" +#define STC_FIREWALL_DBUS_METHOD_INSERT_RULE "IptInsertRule" #define STC_FIREWALL_DBUS_METHOD_REMOVE_RULE "IptRemoveRule" #define STC_FIREWALL6_DBUS_METHOD_ADD_RULE "Ip6tAddRule" +#define STC_FIREWALL6_DBUS_METHOD_INSERT_RULE "Ip6tInsertRule" #define STC_FIREWALL6_DBUS_METHOD_REMOVE_RULE "Ip6tRemoveRule" #define BUF_SIZE_FOR_IP 64 @@ -46,33 +48,21 @@ static void __fw_add_rule_info_to_builder(GVariantBuilder *builder, g_variant_builder_add(builder, "{sv}", RULE_CHAIN, g_variant_new_string(rule->chain)); - if (rule->direction != STC_FW_DIRECTION_NONE) + if (rule->direction != STC_FW_DIRECTION_NONE) { g_variant_builder_add(builder, "{sv}", RULE_DIRECTION, g_variant_new_uint16(rule->direction)); - if (rule->s_ip_type != STC_FW_IP_NONE) - g_variant_builder_add(builder, "{sv}", RULE_SIPTYPE, - g_variant_new_uint16(rule->s_ip_type)); - - if (rule->d_ip_type != STC_FW_IP_NONE) - g_variant_builder_add(builder, "{sv}", RULE_DIPTYPE, - g_variant_new_uint16(rule->d_ip_type)); - - if (rule->s_port_type != STC_FW_PORT_NONE) - g_variant_builder_add(builder, "{sv}", RULE_SPORTTYPE, - g_variant_new_uint16(rule->s_port_type)); - - if (rule->d_port_type != STC_FW_PORT_NONE) - g_variant_builder_add(builder, "{sv}", RULE_DPORTTYPE, - g_variant_new_uint16(rule->d_port_type)); - - if (rule->protocol != STC_FW_PROTOCOL_NONE) - g_variant_builder_add(builder, "{sv}", RULE_PROTOCOL, - g_variant_new_uint16(rule->protocol)); + if (rule->ifname && rule->ifname[0] != '\0') + g_variant_builder_add(builder, "{sv}", RULE_IFNAME, + g_variant_new_string(rule->ifname)); + } switch (rule->family) { case STC_FW_FAMILY_V4: if (rule->s_ip_type != STC_FW_IP_NONE) { + g_variant_builder_add(builder, "{sv}", RULE_SIPTYPE, + g_variant_new_uint16(rule->s_ip_type)); + if (rule->s_ip1.Ipv4.s_addr) g_variant_builder_add(builder, "{sv}", RULE_SIP1, g_variant_new_uint32(rule->s_ip1.Ipv4.s_addr)); @@ -83,6 +73,9 @@ static void __fw_add_rule_info_to_builder(GVariantBuilder *builder, } if (rule->d_ip_type != STC_FW_IP_NONE) { + g_variant_builder_add(builder, "{sv}", RULE_DIPTYPE, + g_variant_new_uint16(rule->d_ip_type)); + if (rule->d_ip1.Ipv4.s_addr) g_variant_builder_add(builder, "{sv}", RULE_DIP1, g_variant_new_uint32(rule->d_ip1.Ipv4.s_addr)); @@ -98,6 +91,9 @@ static void __fw_add_rule_info_to_builder(GVariantBuilder *builder, char buf[BUF_SIZE_FOR_IP]; if (rule->s_ip_type != STC_FW_IP_NONE) { + g_variant_builder_add(builder, "{sv}", RULE_SIPTYPE, + g_variant_new_uint16(rule->s_ip_type)); + if (rule->s_ip1.Ipv6.s6_addr32[0] || rule->s_ip1.Ipv6.s6_addr32[1] || rule->s_ip1.Ipv6.s6_addr32[2] || rule->s_ip1.Ipv6.s6_addr32[3]) { memset(buf, 0, sizeof(buf)); @@ -120,6 +116,9 @@ static void __fw_add_rule_info_to_builder(GVariantBuilder *builder, } if (rule->d_ip_type != STC_FW_IP_NONE) { + g_variant_builder_add(builder, "{sv}", RULE_DIPTYPE, + g_variant_new_uint16(rule->d_ip_type)); + if (rule->d_ip1.Ipv6.s6_addr32[0] || rule->d_ip1.Ipv6.s6_addr32[1] || rule->d_ip1.Ipv6.s6_addr32[2] || rule->d_ip1.Ipv6.s6_addr32[3]) { memset(buf, 0, sizeof(buf)); @@ -147,30 +146,35 @@ static void __fw_add_rule_info_to_builder(GVariantBuilder *builder, break; } - if (rule->s_port_type != STC_FW_PORT_NONE) { - if (rule->s_port1) - g_variant_builder_add(builder, "{sv}", RULE_SPORT1, - g_variant_new_uint32(rule->s_port1)); + if (rule->protocol != STC_FW_PROTOCOL_NONE) { + g_variant_builder_add(builder, "{sv}", RULE_PROTOCOL, + g_variant_new_uint16(rule->protocol)); - if (rule->s_port2) - g_variant_builder_add(builder, "{sv}", RULE_SPORT2, - g_variant_new_uint32(rule->s_port2)); - } + if (rule->s_port_type != STC_FW_PORT_NONE) { + g_variant_builder_add(builder, "{sv}", RULE_SPORTTYPE, + g_variant_new_uint16(rule->s_port_type)); - if (rule->s_port_type != STC_FW_PORT_NONE) { - if (rule->d_port1) - g_variant_builder_add(builder, "{sv}", RULE_DPORT1, - g_variant_new_uint32(rule->d_port1)); + if (rule->s_port1) + g_variant_builder_add(builder, "{sv}", RULE_SPORT1, + g_variant_new_uint32(rule->s_port1)); - if (rule->d_port2) - g_variant_builder_add(builder, "{sv}", RULE_DPORT2, - g_variant_new_uint32(rule->d_port2)); - } + if (rule->s_port2) + g_variant_builder_add(builder, "{sv}", RULE_SPORT2, + g_variant_new_uint32(rule->s_port2)); + } - if (rule->direction != STC_FW_DIRECTION_NONE) { - if (rule->ifname && rule->ifname[0] != '\0') - g_variant_builder_add(builder, "{sv}", RULE_IFNAME, - g_variant_new_string(rule->ifname)); + if (rule->d_port_type != STC_FW_PORT_NONE) { + g_variant_builder_add(builder, "{sv}", RULE_DPORTTYPE, + g_variant_new_uint16(rule->d_port_type)); + + if (rule->d_port1) + g_variant_builder_add(builder, "{sv}", RULE_DPORT1, + g_variant_new_uint32(rule->d_port1)); + + if (rule->d_port2) + g_variant_builder_add(builder, "{sv}", RULE_DPORT2, + g_variant_new_uint32(rule->d_port2)); + } } if (rule->target_str && rule->target_str[0] != '\0') @@ -377,7 +381,7 @@ static int __fw_set_chain(firewall_chain_s *chain) } rule.target_str = g_strdup(chain->chain); - ret = firewall_rule_add(&rule); + ret = firewall_rule_insert(&rule); g_free(rule.chain); g_free(rule.target_str); @@ -411,7 +415,7 @@ static int __fw_unset_chain(firewall_chain_s *chain) return ret; } -static int __fw_add_rule(GDBusConnection *connection, +static int __fw_append_rule(GDBusConnection *connection, firewall_rule_s *rule) { int result = 0; @@ -444,7 +448,40 @@ static int __fw_add_rule(GDBusConnection *connection, return STC_ERROR_NONE; } -static int __fw6_add_rule(GDBusConnection *connection, +static int __fw_insert_rule(GDBusConnection *connection, + firewall_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}")); + __fw_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_FIREWALL_DBUS_SERVICE, + STC_FIREWALL_DBUS_RULE_PATH, + STC_FIREWALL_DBUS_RULE_INTERFACE, + STC_FIREWALL_DBUS_METHOD_INSERT_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 inserted firewall rule [%d:%s]", + result, rule->chain); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __fw6_append_rule(GDBusConnection *connection, firewall_rule_s *rule) { int result = 0; @@ -477,6 +514,39 @@ static int __fw6_add_rule(GDBusConnection *connection, return STC_ERROR_NONE; } +static int __fw6_insert_rule(GDBusConnection *connection, + firewall_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}")); + __fw_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_FIREWALL_DBUS_SERVICE, + STC_FIREWALL_DBUS_RULE_PATH, + STC_FIREWALL_DBUS_RULE_INTERFACE, + STC_FIREWALL6_DBUS_METHOD_INSERT_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 inserted firewall6 rule [%d:%s]", + result, rule->chain); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + static int __fw_remove_rule(GDBusConnection *connection, firewall_rule_s *rule) { @@ -649,7 +719,50 @@ stc_error_e firewall_chain_unset(firewall_chain_s *chain) return ret; } -stc_error_e firewall_rule_add(firewall_rule_s *rule) +stc_error_e firewall_rule_append(firewall_rule_s *rule) +{ + stc_error_e ret = STC_ERROR_NONE; + stc_s *stc = stc_get_manager(); + + if (!stc || !stc->connection) { + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_UNINITIALIZED; + } + + switch (rule->family) { + case STC_FW_FAMILY_V4: + ret = __fw_append_rule(stc->connection, rule); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + return ret; + } + break; + case STC_FW_FAMILY_V6: + ret = __fw6_append_rule(stc->connection, rule); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + return ret; + } + break; + default: + ret = __fw_append_rule(stc->connection, rule); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + return ret; + } + + ret = __fw6_append_rule(stc->connection, rule); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + return ret; + } + break; + } + + return ret; +} + +stc_error_e firewall_rule_insert(firewall_rule_s *rule) { stc_error_e ret = STC_ERROR_NONE; stc_s *stc = stc_get_manager(); @@ -661,27 +774,27 @@ stc_error_e firewall_rule_add(firewall_rule_s *rule) switch (rule->family) { case STC_FW_FAMILY_V4: - ret = __fw_add_rule(stc->connection, rule); + ret = __fw_insert_rule(stc->connection, rule); if (ret != STC_ERROR_NONE) { __STC_LOG_FUNC_EXIT__; return ret; } break; case STC_FW_FAMILY_V6: - ret = __fw6_add_rule(stc->connection, rule); + ret = __fw6_insert_rule(stc->connection, rule); if (ret != STC_ERROR_NONE) { __STC_LOG_FUNC_EXIT__; return ret; } break; default: - ret = __fw_add_rule(stc->connection, rule); + ret = __fw_insert_rule(stc->connection, rule); if (ret != STC_ERROR_NONE) { __STC_LOG_FUNC_EXIT__; return ret; } - ret = __fw6_add_rule(stc->connection, rule); + ret = __fw6_insert_rule(stc->connection, rule); if (ret != STC_ERROR_NONE) { __STC_LOG_FUNC_EXIT__; return ret; diff --git a/src/helper/helper-firewall.h b/src/helper/helper-firewall.h index 2c779bb..4966769 100755 --- a/src/helper/helper-firewall.h +++ b/src/helper/helper-firewall.h @@ -22,8 +22,8 @@ #include "stc-manager.h" #include "stc-error.h" -#define FIREWALL_CHAIN_TARGET_IN "STC_IN" -#define FIREWALL_CHAIN_TARGET_OUT "STC_OUT" +#define FIREWALL_CHAIN_TARGET_IN "INPUT" +#define FIREWALL_CHAIN_TARGET_OUT "OUTPUT" #define FIREWALL_RULE_TARGET_ACCEPT "ACCEPT" #define FIREWALL_RULE_TARGET_DROP "DROP" @@ -111,7 +111,8 @@ stc_error_e firewall_chain_flush(firewall_chain_s *chain); stc_error_e firewall_chain_set(firewall_chain_s *chain); stc_error_e firewall_chain_unset(firewall_chain_s *chain); -stc_error_e firewall_rule_add(firewall_rule_s *rule); +stc_error_e firewall_rule_append(firewall_rule_s *rule); +stc_error_e firewall_rule_insert(firewall_rule_s *rule); stc_error_e firewall_rule_remove(firewall_rule_s *rule); #endif /*__STC_HELPER_FIREWALL_H__*/ diff --git a/src/stc-firewall.c b/src/stc-firewall.c old mode 100644 new mode 100755 index bec6c27..ec1f674 --- a/src/stc-firewall.c +++ b/src/stc-firewall.c @@ -629,7 +629,7 @@ static void __fw_rule_set_to_chain(gpointer data, gpointer user_data) break; } - firewall_rule_add(rule); + firewall_rule_append(rule); } static void __fw_rule_print_rules(gpointer data, gpointer user_data) @@ -1030,7 +1030,7 @@ static void __fw_rule_extract(const char *key, GVariant *value, } } else if (g_strcmp0(key, RULE_DPORT1) == 0) { - if (rule->s_port_type != STC_FW_PORT_NONE) { + if (rule->d_port_type != STC_FW_PORT_NONE) { rule->d_port1 = g_variant_get_uint32(value); STC_LOGD("%s: [%04x]", RULE_DPORT1, rule->d_port1); } -- 2.7.4 From 754bc0adb95b0efb54f2c7dd8e3105ff41ccc14d Mon Sep 17 00:00:00 2001 From: Milind Murhekar Date: Mon, 20 Aug 2018 17:15:05 +0530 Subject: [PATCH 07/16] [Add] tethering client monitoring This change adds the feature to monitor the data usage of connected tethering clients and saves the stats to the table counters. Change-Id: I50df631b27ad9fe483f6790877e92308b8ea760a Signed-off-by: Milind Murhekar --- include/stc-manager.h | 2 + packaging/stc-manager.spec | 2 +- plugin/tether/stc-plugin-tether.c | 53 ++++++++- src/helper/helper-cgroup.c | 4 + src/helper/helper-cgroup.h | 2 + src/helper/helper-iptables.c | 54 +++++++++ src/helper/helper-iptables.h | 15 +++ src/helper/helper-net-cls.c | 4 + src/helper/helper-nfacct-rule.c | 47 +++++++- src/helper/helper-nfacct-rule.h | 13 +++ src/monitor/include/stc-monitor.h | 7 ++ src/monitor/stc-monitor.c | 233 +++++++++++++++++++++++++++++++++++++- 12 files changed, 429 insertions(+), 7 deletions(-) diff --git a/include/stc-manager.h b/include/stc-manager.h index 898e7ae..94c57a1 100644 --- a/include/stc-manager.h +++ b/include/stc-manager.h @@ -24,6 +24,7 @@ #define NET_CLS_SUBSYS "net_cls" #define STC_BACKGROUND_APP_SUFFIX "_BACKGROUND" +#define STC_TETHERING_APP_SUFFIX "_TETHERING" #define STC_BACKGROUND_APP_ID "BACKGROUND" #define STC_TOTAL_DATACALL "TOTAL_DATACALL" #define STC_TOTAL_WIFI "TOTAL_WIFI" @@ -118,6 +119,7 @@ typedef enum { STC_APP_TYPE_GROUP, STC_APP_TYPE_WATCH, STC_APP_TYPE_WIDGET, + STC_APP_TYPE_TETHERING, STC_APP_TYPE_MAX, } stc_app_type_e; diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index 6b0b965..81d341a 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.74 +Version: 0.0.75 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/plugin/tether/stc-plugin-tether.c b/plugin/tether/stc-plugin-tether.c index ed3ccd4..629abbf 100644 --- a/plugin/tether/stc-plugin-tether.c +++ b/plugin/tether/stc-plugin-tether.c @@ -31,6 +31,51 @@ static GDBusConnection *connection = NULL; static GCancellable *cancellable = NULL; static int g_mobileap_signal_sub_id = 0; +static stc_error_e add_station_monitor(gchar *pkg_id, gchar *app_id, const char *ip) +{ + int ret; + stc_app_key_s app_key; + stc_app_value_s app_value; + + if (pkg_id == NULL || app_id == NULL || ip == NULL) { + STC_LOGE("invalid station station info"); + return STC_ERROR_INVALID_PARAMETER; + } + + memset(&app_key, 0, sizeof(stc_app_key_s)); + memset(&app_value, 0, sizeof(stc_app_value_s)); + app_key.pkg_id = g_strdup(pkg_id); + app_key.app_id = g_strconcat(app_id, STC_TETHERING_APP_SUFFIX, NULL); + app_value.type = STC_APP_TYPE_TETHERING; + app_value.processes = NULL; + g_strlcpy(app_value.ipaddr, ip, IPV4_IPADDRESS_LEN); + + ret = stc_monitor_application_add(app_key, app_value); + FREE(app_key.pkg_id); + FREE(app_key.app_id); + return ret; +} + +static stc_error_e remove_station_monitor(gchar *pkg_id, gchar *app_id) +{ + int ret; + stc_app_key_s app_key; + + if (pkg_id == NULL || app_id == NULL) { + STC_LOGE("invalid station station info"); + return STC_ERROR_INVALID_PARAMETER; + } + + memset(&app_key, 0, sizeof(stc_app_key_s)); + app_key.pkg_id = g_strdup(pkg_id); + app_key.app_id = g_strconcat(app_id, STC_TETHERING_APP_SUFFIX, NULL); + + ret = stc_monitor_application_remove(app_key); + FREE(app_key.pkg_id); + FREE(app_key.app_id); + return ret; +} + static int _compare_sta_by_mac_func(gconstpointer a, gconstpointer b) { @@ -75,6 +120,10 @@ static void _remove_station_info(gconstpointer data, GCompareFunc func) info = (tether_sta_info_s *)list->data; STC_LOGI("STA-REMOVED: (%s) (%s) (%s)", info->ip, info->mac, info->name); + + /* remove tethering client from monitoring */ + remove_station_monitor(info->mac, info->station_id); + g_free(info->station_id); g_free(info); @@ -99,7 +148,10 @@ static void _add_station_info(tether_sta_info_s *info) station_list = g_slist_prepend(station_list, info); STC_LOGI("STA-ADDED: (%s) (%s) (%s)", info->ip, info->mac, info->name); + + /* add tethering client for monitoring data usage */ info->station_id = g_strdup_printf("%s_%s", info->mac, info->name); + add_station_monitor(info->mac, info->station_id, info->ip); } static void _mobileap_signal_cb(GDBusConnection *conn, @@ -189,7 +241,6 @@ void tether_plugin_deinit(void) STC_LOGI("tether plugin deinitialised"); } -/* Tether Plugin APIs */ API stc_plugin_tether_s tether_plugin = { .init = tether_plugin_init, .deinit = tether_plugin_deinit, diff --git a/src/helper/helper-cgroup.c b/src/helper/helper-cgroup.c index 1f195ba..fa54c12 100644 --- a/src/helper/helper-cgroup.c +++ b/src/helper/helper-cgroup.c @@ -237,4 +237,8 @@ void cgroup_init(void) /* create foreground cgroup directory */ cgroup_make_subdir(STC_CGROUP_NETWORK, STC_FOREGROUND_CGROUP_NAME, NULL); + + /* create tethering cgroup directory */ + cgroup_make_subdir(STC_CGROUP_NETWORK, STC_TETHERING_CGROUP_NAME, + NULL); } diff --git a/src/helper/helper-cgroup.h b/src/helper/helper-cgroup.h index 725cad4..73abd40 100644 --- a/src/helper/helper-cgroup.h +++ b/src/helper/helper-cgroup.h @@ -33,10 +33,12 @@ #define STC_CGROUP_NETWORK CGROUP_NETWORK "/stc" #define BACKGROUND_CGROUP_NETWORK STC_CGROUP_NETWORK "/BACKGROUND" #define FOREGROUND_CGROUP_NETWORK STC_CGROUP_NETWORK "/FOREGROUND" +#define TETHERING_CGROUP_NETWORK STC_CGROUP_NETWORK "/TETHERING" #define PROC_TASK_CHILDREN "/proc/%d/task/%d/children" #define STC_CGROUP_NAME "stc" #define STC_BACKGROUND_CGROUP_NAME "BACKGROUND" #define STC_FOREGROUND_CGROUP_NAME "FOREGROUND" +#define STC_TETHERING_CGROUP_NAME "TETHERING" /** * @desc Get one unsigned int32 value from cgroup diff --git a/src/helper/helper-iptables.c b/src/helper/helper-iptables.c index 6ca96af..0914100 100644 --- a/src/helper/helper-iptables.c +++ b/src/helper/helper-iptables.c @@ -39,6 +39,13 @@ #define RULE_CGROUP "cgroup" #define RULE_NFACCT "nfacct" #define RULE_TARGET "target" +#define RULE_PROTOCOL "protocol" +#define RULE_SIPTYPE "s_ip_type" +#define RULE_SIP1 "s_ip1" +#define RULE_SIP2 "s_ip2" +#define RULE_DIPTYPE "d_ip_type" +#define RULE_DIP1 "d_ip1" +#define RULE_DIP2 "d_ip2" static void __add_rule_info_to_builder(GVariantBuilder *builder, iptables_rule_s *rule) @@ -68,6 +75,27 @@ static void __add_rule_info_to_builder(GVariantBuilder *builder, g_variant_builder_add(builder, "{sv}", RULE_TARGET, g_variant_new_string(rule->target)); + g_variant_builder_add(builder, "{sv}", RULE_SIPTYPE, + g_variant_new_uint16(rule->s_iprange_type)); + + g_variant_builder_add(builder, "{sv}", RULE_DIPTYPE, + g_variant_new_uint16(rule->d_iprange_type)); + + if (rule->s_ip1.s_addr) + g_variant_builder_add(builder, "{sv}", RULE_SIP1, + g_variant_new_uint32(rule->s_ip1.s_addr)); + + if (rule->s_ip2.s_addr) + g_variant_builder_add(builder, "{sv}", RULE_SIP2, + g_variant_new_uint32(rule->s_ip2.s_addr)); + + if (rule->d_ip1.s_addr) + g_variant_builder_add(builder, "{sv}", RULE_DIP1, + g_variant_new_uint32(rule->d_ip1.s_addr)); + + if (rule->d_ip2.s_addr) + g_variant_builder_add(builder, "{sv}", RULE_DIP2, + g_variant_new_uint32(rule->d_ip2.s_addr)); } static int __iptables_rule_add(GDBusConnection *connection, @@ -436,6 +464,10 @@ stc_error_e iptables_flush_chains(void) if (ret != STC_ERROR_NONE) goto done; //LCOV_EXCL_LINE + ret = __iptables_flush_chain(stc->connection, STC_TETHER_CHAIN); + if (ret != STC_ERROR_NONE) + goto done; //LCOV_EXCL_LINE + ret = __ip6tables_flush_chain(stc->connection, STC_IN_CHAIN); if (ret != STC_ERROR_NONE) goto done; //LCOV_EXCL_LINE @@ -479,6 +511,12 @@ stc_error_e iptables_init(void) goto done; //LCOV_EXCL_LINE } + ret = __iptables_add_chain(stc->connection, STC_TETHER_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE + goto done; //LCOV_EXCL_LINE + } + ret = __ip6tables_add_chain(stc->connection, STC_IN_CHAIN); if (ret != STC_ERROR_NONE) { __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE @@ -510,6 +548,16 @@ stc_error_e iptables_init(void) } ret = __iptables_add_chain_jump_rule("FORWARD", STC_FRWD_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE + goto done; //LCOV_EXCL_LINE + } + + ret = __iptables_add_chain_jump_rule("FORWARD", STC_TETHER_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; + goto done; + } done: return ret; } @@ -538,6 +586,12 @@ stc_error_e iptables_deinit(void) goto done; //LCOV_EXCL_LINE } + ret = __iptables_remove_chain(stc->connection, STC_TETHER_CHAIN); + if (ret != STC_ERROR_NONE) { + __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE + goto done; //LCOV_EXCL_LINE + } + ret = __iptables_remove_chain(stc->connection, STC_FRWD_CHAIN); if (ret != STC_ERROR_NONE) { __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE diff --git a/src/helper/helper-iptables.h b/src/helper/helper-iptables.h index 13db25b..71b057b 100644 --- a/src/helper/helper-iptables.h +++ b/src/helper/helper-iptables.h @@ -17,12 +17,14 @@ #ifndef __STC_HELPER_IPTABLES_H__ #define __STC_HELPER_IPTABLES_H__ +#include #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" +#define STC_TETHER_CHAIN "STC_TETHER" typedef enum { IPTABLES_DIRECTION_NONE, @@ -38,11 +40,24 @@ typedef enum { IP_TYPE_LAST_ELEM } iptables_ip_type_e; +typedef enum { + IPTABLES_IP_NONE, + IPTABLES_IP_SINGLE, + IPTABLES_IP_MASK, + IPTABLES_IP_RANGE +} iptables_iprange_type_e; + typedef struct { char *chain; char *ifname; char *nfacct_name; char *target; + iptables_iprange_type_e s_iprange_type; + iptables_iprange_type_e d_iprange_type; + struct in_addr s_ip1; + struct in_addr s_ip2; + struct in_addr d_ip1; + struct in_addr d_ip2; iptables_rule_direction_e direction; uint32_t classid; } iptables_rule_s; diff --git a/src/helper/helper-net-cls.c b/src/helper/helper-net-cls.c index 748f95f..238b7de 100644 --- a/src/helper/helper-net-cls.c +++ b/src/helper/helper-net-cls.c @@ -137,6 +137,8 @@ uint32_t get_classid_by_app_id(const char *app_id, int create) if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX)) path_to_net_cgroup_dir = BACKGROUND_CGROUP_NETWORK; + else if (strstr(app_id, STC_TETHERING_APP_SUFFIX)) + path_to_net_cgroup_dir = TETHERING_CGROUP_NETWORK; else path_to_net_cgroup_dir = FOREGROUND_CGROUP_NETWORK; @@ -186,6 +188,8 @@ stc_error_e place_pids_to_net_cgroup(const int pid, const char *app_id) path_to_net_cgroup_dir = STC_CGROUP_NETWORK; else if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX)) path_to_net_cgroup_dir = BACKGROUND_CGROUP_NETWORK; + else if (strstr(app_id, STC_TETHERING_APP_SUFFIX)) + path_to_net_cgroup_dir = TETHERING_CGROUP_NETWORK; else path_to_net_cgroup_dir = FOREGROUND_CGROUP_NETWORK; //LCOV_EXCL_LINE diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index 90364d3..70b29a5 100644 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -448,12 +448,32 @@ static stc_error_e exec_iptables_cmd(nfacct_rule_s *rule) 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)); + + /* In case of tehering use chain 'STC_TETHER' */ + if (rule->intend == NFACCT_TETH_COUNTER) + iptables_rule.chain = g_strdup(STC_TETHER_CHAIN); + else + iptables_rule.chain = g_strdup(get_iptables_chain(rule->iotype)); + iptables_rule.classid = rule->classid; iptables_rule.direction = (rule->iotype & NFACCT_COUNTER_IN) ? IPTABLES_DIRECTION_IN : IPTABLES_DIRECTION_OUT; iptype = (iptables_ip_type_e)rule->iptype; + /* specify the ip range type for source and destination */ + iptables_rule.s_iprange_type = rule->src_iprange_type; + iptables_rule.d_iprange_type = rule->dst_iprange_type; + + /* specify source and destination ip address if any */ + if (rule->src_ip1) + inet_aton(rule->src_ip1, &iptables_rule.s_ip1); + if (rule->src_ip2) + inet_aton(rule->src_ip2, &iptables_rule.s_ip2); + if (rule->dst_ip1) + inet_aton(rule->dst_ip1, &iptables_rule.d_ip1); + if (rule->dst_ip2) + inet_aton(rule->dst_ip2, &iptables_rule.d_ip2); + if (rule->action == NFACCT_ACTION_DELETE) { /* delete interface rule */ ret = iptables_remove(&iptables_rule, iptype); @@ -480,6 +500,7 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule) char nfacct_buf[sizeof(NFACCT_NAME_MOD) + 3*MAX_DEC_SIZE(int) + 4 + 1]; stc_error_e ret = STC_ERROR_NONE; + uint32_t classid = rule->classid; /* income part */ if (rule->iotype & NFACCT_COUNTER_IN) { @@ -508,7 +529,19 @@ 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"); + /* cgroup extention on FORWARD chain are not allowed + * remove classid info in case of tethering rules */ + if (rule->intend == NFACCT_TETH_COUNTER) { + classid = rule->classid; + rule->classid = 0; + } + ret = exec_iptables_cmd(rule); + + /* restore the classid info in case of tethering rule */ + if (rule->intend == NFACCT_TETH_COUNTER) + rule->classid = classid; + 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", @@ -551,7 +584,19 @@ 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"); + /* cgroup extention on FORWARD chain are not allowed + * remove classid info in case of tethering rules */ + if (rule->intend == NFACCT_TETH_COUNTER) { + classid = rule->classid; + rule->classid = 0; + } + ret = exec_iptables_cmd(rule); + + /* restore the classid info in case of tethering rule */ + if (rule->intend == NFACCT_TETH_COUNTER) + rule->classid = classid; + 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", diff --git a/src/helper/helper-nfacct-rule.h b/src/helper/helper-nfacct-rule.h index 9d80afb..52ef8f4 100644 --- a/src/helper/helper-nfacct-rule.h +++ b/src/helper/helper-nfacct-rule.h @@ -67,6 +67,13 @@ typedef enum { NFACCT_TYPE_LAST_ELEM } nfacct_rule_iptype; +typedef enum { + NFACCT_IPRANGE_TYPE_NONE, + NFACCT_IPRANGE_TYPE_SINGLE, + NFACCT_IPRANGE_TYPE_MASK, + NFACCT_IPRANGE_TYPE_RANGE, +} nfacct_rule_iprange_type; + enum nfnl_acct_flags { NFACCT_F_QUOTA_PKTS = (1 << 0), NFACCT_F_QUOTA_BYTES = (1 << 1), @@ -97,6 +104,12 @@ struct nfacct_rule { nfacct_rule_jump jump; /* in most cases jump is evalutation based on intend, but not always */ stc_rstn_state_e rstn_state; nfacct_rule_iptype iptype; + nfacct_rule_iprange_type src_iprange_type; + nfacct_rule_iprange_type dst_iprange_type; + char *src_ip1; + char *src_ip2; + char *dst_ip1; + char *dst_ip2; struct counter_arg *carg; stc_error_e(*iptables_rule)(struct nfacct_rule *counter); diff --git a/src/monitor/include/stc-monitor.h b/src/monitor/include/stc-monitor.h index 3414c06..4b5375c 100644 --- a/src/monitor/include/stc-monitor.h +++ b/src/monitor/include/stc-monitor.h @@ -27,6 +27,7 @@ /* 1 seconds */ #define CONTR_TIMER_INTERVAL 1 +#define IPV4_IPADDRESS_LEN 16 /** * @brief enumeration for data limit types @@ -72,6 +73,7 @@ typedef struct { stc_data_counter_s data_usage; stc_data_counter_s counter; GTree *processes; /**< applications instances */ + char ipaddr[IPV4_IPADDRESS_LEN+1]; /**< application ip address */ } stc_app_value_s; /** @@ -139,6 +141,11 @@ stc_error_e stc_monitor_application_add(const stc_app_key_s app_key, const stc_app_value_s app_value); /** + * @brief deletes an application entry + */ +stc_error_e stc_monitor_application_remove(const stc_app_key_s app_key); + +/** * @brief associates process to an application */ stc_error_e stc_monitor_process_add(const stc_app_key_s app_key, diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 2a42682..fbed5e3 100644 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -70,6 +70,102 @@ static nfacct_rule_jump __get_jump_by_intend(struct nfacct_rule *counter) return NFACCT_JUMP_UNKNOWN; } +static stc_error_e __add_iptables_tether_in(struct nfacct_rule *counter, + const gchar *ipaddr) +{ + int ret; + + if (counter == NULL || ipaddr == NULL) + return STC_ERROR_INVALID_PARAMETER; + + counter->action = NFACCT_ACTION_INSERT; + counter->iotype = NFACCT_COUNTER_IN; + counter->jump = __get_jump_by_intend(counter); + counter->iptype = NFACCT_TYPE_IPV4; + counter->send_limit = 0; + counter->rcv_limit = 0; + counter->src_iprange_type = NFACCT_IPRANGE_TYPE_SINGLE; + counter->src_ip1 = g_strdup(ipaddr); + + ret = produce_net_rule(counter); + + g_free(counter->src_ip1); + counter->src_iprange_type = NFACCT_IPRANGE_TYPE_NONE; + return ret; +} + +static stc_error_e __add_iptables_tether_out(struct nfacct_rule *counter, + const gchar *ipaddr) +{ + int ret; + + if (counter == NULL || ipaddr == NULL) + return STC_ERROR_INVALID_PARAMETER; + + counter->action = NFACCT_ACTION_INSERT; + counter->iotype = NFACCT_COUNTER_OUT; + counter->jump = __get_jump_by_intend(counter); + counter->iptype = NFACCT_TYPE_IPV4; + counter->send_limit = 0; + counter->rcv_limit = 0; + counter->dst_iprange_type = NFACCT_IPRANGE_TYPE_SINGLE; + counter->dst_ip1 = g_strdup(ipaddr); + + ret = produce_net_rule(counter); + + g_free(counter->dst_ip1); + counter->dst_iprange_type = NFACCT_IPRANGE_TYPE_NONE; + return ret; +} + +static stc_error_e __del_iptables_tether_in(struct nfacct_rule *counter, + const gchar *ipaddr) +{ + int ret; + + if (counter == NULL || ipaddr == NULL) + return STC_ERROR_INVALID_PARAMETER; + + counter->action = NFACCT_ACTION_DELETE; + counter->iotype = NFACCT_COUNTER_IN; + counter->jump = __get_jump_by_intend(counter); + counter->iptype = NFACCT_TYPE_IPV4; + counter->send_limit = 0; + counter->rcv_limit = 0; + counter->src_iprange_type = NFACCT_IPRANGE_TYPE_SINGLE; + counter->src_ip1 = g_strdup(ipaddr); + + ret = produce_net_rule(counter); + + g_free(counter->src_ip1); + counter->src_iprange_type = NFACCT_IPRANGE_TYPE_NONE; + return ret; +} + +static stc_error_e __del_iptables_tether_out(struct nfacct_rule *counter, + const gchar *ipaddr) +{ + int ret; + + if (counter == NULL || ipaddr == NULL) + return STC_ERROR_INVALID_PARAMETER; + + counter->action = NFACCT_ACTION_DELETE; + counter->iotype = NFACCT_COUNTER_OUT; + counter->jump = __get_jump_by_intend(counter); + counter->iptype = NFACCT_TYPE_IPV4; + counter->send_limit = 0; + counter->rcv_limit = 0; + counter->dst_iprange_type = NFACCT_IPRANGE_TYPE_SINGLE; + counter->dst_ip1 = g_strdup(ipaddr); + + ret = produce_net_rule(counter); + + g_free(counter->dst_ip1); + counter->dst_iprange_type = NFACCT_IPRANGE_TYPE_NONE; + return ret; +} + static stc_error_e __add_iptables_in(struct nfacct_rule *counter) { if (counter == NULL) @@ -384,10 +480,93 @@ static gboolean __processes_tree_check_empty(gpointer key, gpointer value, } //LCOV_EXCL_STOP +static gboolean __add_application_monitor_for_tethering(gpointer key, gpointer value, + gpointer data) +{ + stc_app_value_s *app_value = (stc_app_value_s *)value; + stc_app_key_s *app_key = (stc_app_key_s *)key; + default_connection_s *connection = (default_connection_s *)data; + stc_s *stc = stc_get_manager(); + struct nfacct_rule counter; + + STC_LOGI("add tether app (%s)", app_key->app_id); + + if (stc == NULL || connection == NULL) + return FALSE; + + if (!stc->carg) { + stc->carg = MALLOC0(counter_arg_s, 1); + if (stc->carg == NULL) + return FALSE; + + stc->carg->sock = stc_monitor_get_counter_socket(); + } + + memset(&counter, 0, sizeof(struct nfacct_rule)); + + counter.carg = stc->carg; + counter.classid = app_value->classid; + counter.intend = NFACCT_TETH_COUNTER; + + if (connection->tether_state != TRUE || + connection->tether_iface.ifname == NULL) + return FALSE; + + counter.iftype = connection->tether_iface.type; + g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH); + + __add_iptables_tether_in(&counter, app_value->ipaddr); + __add_iptables_tether_out(&counter, app_value->ipaddr); + + return FALSE; +} + +static gboolean __remove_application_monitor_for_tethering(gpointer key, gpointer value, + gpointer data) +{ + stc_app_value_s *app_value = (stc_app_value_s *)value; + stc_app_key_s *app_key = (stc_app_key_s *)key; + default_connection_s *connection = (default_connection_s *)data; + stc_s *stc = stc_get_manager(); + struct nfacct_rule counter; + + STC_LOGI("remove tether app (%s)", app_key->app_id); + + if (stc == NULL || connection == NULL) + return FALSE; + + if (!stc->carg) { + stc->carg = MALLOC0(counter_arg_s, 1); + if (stc->carg == NULL) + return FALSE; + + stc->carg->sock = stc_monitor_get_counter_socket(); + } + + memset(&counter, 0, sizeof(struct nfacct_rule)); + + counter.carg = stc->carg; + counter.classid = app_value->classid; + counter.intend = NFACCT_TETH_COUNTER; + + if (connection->tether_state != TRUE || + connection->tether_iface.ifname == NULL) + return FALSE; + + counter.iftype = connection->tether_iface.type; + g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH); + + __del_iptables_tether_in(&counter, app_value->ipaddr); + __del_iptables_tether_out(&counter, app_value->ipaddr); + + return FALSE; +} + static gboolean __add_application_monitor(gpointer key, gpointer value, gpointer data) { stc_app_value_s *app_value = (stc_app_value_s *)value; + stc_app_key_s *app_key = (stc_app_key_s *)key; default_connection_s *connection = (default_connection_s *)data; stc_s *stc = stc_get_manager(); @@ -423,7 +602,10 @@ static gboolean __add_application_monitor(gpointer key, gpointer value, g_strlcpy(counter.ifname, connection->ifname, MAX_IFACE_LENGTH); } - if (app_value->classid == STC_TOTAL_IPV4_CLASSID) { + if (g_str_has_suffix(app_key->app_id, STC_TETHERING_APP_SUFFIX) && + app_value->classid != STC_TETHERING_APP_CLASSID) { + __add_application_monitor_for_tethering(key, value, data); + } else if (app_value->classid == STC_TOTAL_IPV4_CLASSID) { __add_iptables_in(&counter); __add_iptables_out(&counter); } else if (app_value->classid == STC_TOTAL_IPV6_CLASSID) { @@ -444,6 +626,7 @@ static gboolean __remove_application_monitor(gpointer key, gpointer value, gpointer data) { stc_app_value_s *app_value = (stc_app_value_s *)value; + stc_app_key_s *app_key = (stc_app_key_s *)key; default_connection_s *connection = (default_connection_s *)data; stc_s *stc = stc_get_manager(); @@ -464,7 +647,11 @@ static gboolean __remove_application_monitor(gpointer key, gpointer value, counter.classid = app_value->classid; counter.intend = NFACCT_COUNTER; - if (connection->tether_state == FALSE && + if (g_str_has_suffix(app_key->app_id, STC_TETHERING_APP_SUFFIX) && + app_value->classid != STC_TETHERING_APP_CLASSID) { + __remove_application_monitor_for_tethering(key, value, data); + return FALSE; + } else if (connection->tether_state == FALSE && connection->tether_iface.ifname != NULL && app_value->classid == STC_TETHERING_APP_CLASSID) { counter.iftype = connection->tether_iface.type; @@ -1049,7 +1236,8 @@ static gboolean __rstn_counter_update_foreach_classid(gpointer key, classid_bytes_context_s *context = (classid_bytes_context_s *)data; uint32_t classid; - if (context->counter->intend != NFACCT_COUNTER) + if (context->counter->intend != NFACCT_COUNTER && + context->counter->intend != NFACCT_TETH_COUNTER) goto try_next_callback; if (rstn_value->limit_exceeded == TRUE) { @@ -1103,6 +1291,8 @@ static gboolean __update_app_statistics(gpointer key, gpointer value, if (app_value->classid == STC_TETHERING_APP_CLASSID && default_connection->tether_state == TRUE) stat_key.iftype = default_connection->tether_iface.type; + else if (g_str_has_suffix(app_key->app_id, STC_TETHERING_APP_SUFFIX)) + stat_key.iftype = default_connection->tether_iface.type; else stat_key.iftype = default_connection->type; @@ -1115,6 +1305,9 @@ static gboolean __update_app_statistics(gpointer key, gpointer value, default_connection->tether_state == TRUE) g_strlcpy(stat_key.ifname, default_connection->tether_iface.ifname, MAX_IFACE_LENGTH); + else if (g_str_has_suffix(app_key->app_id, STC_TETHERING_APP_SUFFIX)) + g_strlcpy(stat_key.ifname, default_connection->tether_iface.ifname, + MAX_IFACE_LENGTH); else g_strlcpy(stat_key.ifname, default_connection->ifname, MAX_IFACE_LENGTH); @@ -1266,7 +1459,8 @@ static gboolean __apps_counter_update_foreach_classid(gpointer key, stc_app_value_s *app_value = (stc_app_value_s *)value; classid_bytes_context_s *context = (classid_bytes_context_s *)data; - if (context->counter->intend != NFACCT_COUNTER) + if (context->counter->intend != NFACCT_COUNTER && + context->counter->intend != NFACCT_TETH_COUNTER) goto try_next_callback; __interface_counter_update(app_key, app_value, context); @@ -2071,6 +2265,7 @@ API stc_error_e stc_monitor_application_add(const stc_app_key_s app_key, value->type = app_value.type; value->data_usage.in_bytes = app_value.data_usage.in_bytes; value->data_usage.out_bytes = app_value.data_usage.out_bytes; + g_strlcpy(value->ipaddr, app_value.ipaddr, IPV4_IPADDRESS_LEN); value->processes = g_tree_new_full(__processes_tree_key_compare, NULL, __processes_tree_key_free, @@ -2088,6 +2283,36 @@ API stc_error_e stc_monitor_application_add(const stc_app_key_s app_key, return ret; } +API stc_error_e stc_monitor_application_remove(const stc_app_key_s app_key) +{ + stc_error_e ret = STC_ERROR_NONE; + stc_app_value_s *app_lookup; + + ret_value_msg_if(g_system == NULL, STC_ERROR_FAIL, "stc monitor not initialized!"); + + app_lookup = __application_lookup(g_system->apps, &app_key); + if (!app_lookup) { + if (STC_DEBUG_LOG) + STC_LOGD("app_key not found"); //LCOV_EXCL_LINE + return STC_ERROR_FAIL; //LCOV_EXCL_LINE + } + + /* remove nfacct rule for this classid */ + __remove_application_monitor((gpointer) &app_key, app_lookup, + stc_get_default_connection()); + + /* remove ristrictions if any */ + __remove_rstns_for_application(app_key.app_id); + + /* remove app_key from the stc-manager */ + if (!g_tree_remove(g_system->apps, &app_key)) { + ret = STC_ERROR_NO_DATA; + STC_LOGE("key not found"); + } + + return ret; +} + API stc_error_e stc_monitor_process_add(const stc_app_key_s app_key, const stc_process_key_s proc_key, const stc_process_value_s proc_value) -- 2.7.4 From a72b6122101219d7acd0ab83b7c74a90d3599596 Mon Sep 17 00:00:00 2001 From: Milind Murhekar Date: Wed, 29 Aug 2018 16:33:11 +0530 Subject: [PATCH 08/16] Add tethering client data limitation This change/feature adds the data limitaion restriction on each connected tethering clients based on its mac address, ip address and app id. Change-Id: I538450a68bb6e099d277bce0a6fe53a80d483332 Signed-off-by: Milind Murhekar --- include/stc-manager-plugin-tether.h | 5 +- packaging/stc-manager.spec | 2 +- plugin/tether/include/stc-plugin-tether.h | 21 +- plugin/tether/stc-plugin-tether.c | 80 ++++++- src/database/include/table-restrictions.h | 1 + src/helper/helper-iptables.c | 1 - src/helper/helper-nfacct-rule.c | 42 +++- src/helper/helper-nfacct-rule.h | 3 + src/monitor/include/stc-monitor.h | 5 +- src/monitor/stc-monitor.c | 380 +++++++++++++++++++++++++++--- src/stc-manager-plugin-tether.c | 66 ++++++ src/stc-restriction.c | 6 + 12 files changed, 550 insertions(+), 62 deletions(-) diff --git a/include/stc-manager-plugin-tether.h b/include/stc-manager-plugin-tether.h index bdee306..8fd874b 100644 --- a/include/stc-manager-plugin-tether.h +++ b/include/stc-manager-plugin-tether.h @@ -24,6 +24,7 @@ int stc_plugin_tether_init(void); int stc_plugin_tether_deinit(void); stc_error_e stc_plugin_tether_load(void); -stc_error_e stc_plugin_tether_status_changed(void); - +int stc_plugin_tether_get_station_ip(const char *mac, char **ipaddr); +int stc_plugin_tether_get_station_by_classid(const int classid, char **mac); +int stc_plugin_tether_set_station_classid(const char *mac, int classid); #endif /* __STC_MANAGER_PLUGIN_TETHER_H__ */ diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index b57a246..d84c351 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.75 +Version: 0.0.76 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/plugin/tether/include/stc-plugin-tether.h b/plugin/tether/include/stc-plugin-tether.h index b3d4439..f021516 100644 --- a/plugin/tether/include/stc-plugin-tether.h +++ b/plugin/tether/include/stc-plugin-tether.h @@ -18,29 +18,34 @@ #define __STC_PLUGIN_TETHER_H__ #include +#include #include "stc-error.h" #include "stc-manager.h" #define TETHERING_SERVICE_INTERFACE "org.tizen.tethering" #define SIGNAL_NAME_DHCP_STATUS "dhcp_status" -#define STATION_STR_INFO_LEN 54 +#define STATION_MAC_STR_LEN 18 #define STATION_STR_HOSTNAME_LEN 33 typedef struct { - gchar *station_id; - gchar name[STATION_STR_HOSTNAME_LEN + 1]; - gchar ip[STATION_STR_INFO_LEN + 1]; - gchar mac[STATION_STR_INFO_LEN + 1]; + gchar *station_id; /* Station unique ID (mac_hostname)*/ + int classid; /* cgroup net_cls Classid of station */ + gchar name[STATION_STR_HOSTNAME_LEN+1]; /* Station hostname */ + gchar ip[INET_ADDRSTRLEN+1]; /* Station IP address */ + gchar mac[STATION_MAC_STR_LEN+1]; /* Station MAC address */ } tether_sta_info_s; typedef struct { int (*init) (void); void (*deinit) (void); - int (*status_changed) (void); + int (*get_station_ip) (const char *mac, char *ip); + int (*get_station_by_classid) (const int classid, char *mac); + int (*set_station_classid) (const char *mac, int classid); } stc_plugin_tether_s; int tether_init(void); void tether_deinit(void); -stc_error_e tether_plugin_status_changed(void); - +stc_error_e tether_plugin_get_station_ip(const char *mac, char *ip); +stc_error_e tether_plugin_get_station_by_classid(const int classid, char *mac); +stc_error_e tether_plugin_set_station_classid(const char *mac, int classid); #endif /* __STC_PLUGIN_TETHER_H__ */ diff --git a/plugin/tether/stc-plugin-tether.c b/plugin/tether/stc-plugin-tether.c index 629abbf..2641509 100644 --- a/plugin/tether/stc-plugin-tether.c +++ b/plugin/tether/stc-plugin-tether.c @@ -31,13 +31,14 @@ static GDBusConnection *connection = NULL; static GCancellable *cancellable = NULL; static int g_mobileap_signal_sub_id = 0; -static stc_error_e add_station_monitor(gchar *pkg_id, gchar *app_id, const char *ip) +static stc_error_e add_station_monitor(gchar *pkg_id, gchar *app_id, + const char *mac) { int ret; stc_app_key_s app_key; stc_app_value_s app_value; - if (pkg_id == NULL || app_id == NULL || ip == NULL) { + if (pkg_id == NULL || app_id == NULL || mac == NULL) { STC_LOGE("invalid station station info"); return STC_ERROR_INVALID_PARAMETER; } @@ -48,7 +49,7 @@ static stc_error_e add_station_monitor(gchar *pkg_id, gchar *app_id, const char app_key.app_id = g_strconcat(app_id, STC_TETHERING_APP_SUFFIX, NULL); app_value.type = STC_APP_TYPE_TETHERING; app_value.processes = NULL; - g_strlcpy(app_value.ipaddr, ip, IPV4_IPADDRESS_LEN); + g_strlcpy(app_value.mac, mac, STATION_MAC_STR_LEN); ret = stc_monitor_application_add(app_key, app_value); FREE(app_key.pkg_id); @@ -83,6 +84,14 @@ static int _compare_sta_by_mac_func(gconstpointer a, return g_ascii_strcasecmp(si->mac, (const char *)b); } +static int _compare_sta_by_classid_func(gconstpointer a, + gconstpointer b) +{ + tether_sta_info_s *si = (tether_sta_info_s *)a; + int *classid = (int *)b; + return si->classid - *classid; +} + static int _get_station_info(gconstpointer data, GCompareFunc func, tether_sta_info_s **si) { @@ -142,7 +151,7 @@ static void _add_station_info(tether_sta_info_s *info) if (!g_strcmp0(tmp->name, info->name) && !g_strcmp0(tmp->ip, info->ip)) return; - //Remove the station if dhcp info changed. + /* Remove the station if dhcp info changed. */ _remove_station_info(info->mac, _compare_sta_by_mac_func); } @@ -151,7 +160,7 @@ static void _add_station_info(tether_sta_info_s *info) /* add tethering client for monitoring data usage */ info->station_id = g_strdup_printf("%s_%s", info->mac, info->name); - add_station_monitor(info->mac, info->station_id, info->ip); + add_station_monitor(info->mac, info->station_id, info->mac); } static void _mobileap_signal_cb(GDBusConnection *conn, @@ -182,8 +191,8 @@ static void _mobileap_signal_cb(GDBusConnection *conn, STC_LOGI("%s: ip(%s) mac(%s) name(%s) tm(%d)", state, ip, mac, hostname, tm); if (!g_strcmp0(state, "DhcpConnected")) { - g_strlcpy(sta->ip, ip, STATION_STR_INFO_LEN); - g_strlcpy(sta->mac, mac, STATION_STR_INFO_LEN); + g_strlcpy(sta->ip, ip, INET_ADDRSTRLEN); + g_strlcpy(sta->mac, mac, STATION_MAC_STR_LEN); g_strlcpy(sta->name, hostname, STATION_STR_HOSTNAME_LEN); _add_station_info(sta); } else if (!g_strcmp0(state, "DhcpLeaseDeleted")) { @@ -196,8 +205,59 @@ static void _mobileap_signal_cb(GDBusConnection *conn, g_free(hostname); } -stc_error_e tether_plugin_status_changed(void) +stc_error_e tether_plugin_get_station_ip(const char *mac, char *ip) +{ + tether_sta_info_s *tmp = NULL; + + if (mac == NULL || ip == NULL) + return STC_ERROR_FAIL; + + if (_get_station_info((gconstpointer)mac, + _compare_sta_by_mac_func, &tmp) != 0) { + STC_LOGE("mac(%s) not found", mac); + return STC_ERROR_FAIL; + } + + g_strlcpy(ip, tmp->ip, INET_ADDRSTRLEN); + return STC_ERROR_NONE; +} + +stc_error_e tether_plugin_get_station_by_classid(const int classid, char *mac) +{ + tether_sta_info_s *tmp = NULL; + int classid_value = classid; + + if (mac == NULL) + return STC_ERROR_FAIL; + + if (_get_station_info((gconstpointer)&classid_value, + _compare_sta_by_classid_func, &tmp) != 0) { + STC_LOGE("classid(%s) not found", classid); + return STC_ERROR_FAIL; + } + + g_strlcpy(mac, tmp->mac, STATION_MAC_STR_LEN); + return STC_ERROR_NONE; +} + +stc_error_e tether_plugin_set_station_classid(const char *mac, int classid) { + tether_sta_info_s *tmp = NULL; + + if (mac == NULL) { + STC_LOGE("invalid param"); + return STC_ERROR_FAIL; + } + + if (_get_station_info((gconstpointer)mac, + _compare_sta_by_mac_func, &tmp) != 0) { + STC_LOGE("mac(%s) not found", mac); + return STC_ERROR_FAIL; + } + + if (tmp) + tmp->classid = classid; + return STC_ERROR_NONE; } @@ -244,5 +304,7 @@ void tether_plugin_deinit(void) API stc_plugin_tether_s tether_plugin = { .init = tether_plugin_init, .deinit = tether_plugin_deinit, - .status_changed = tether_plugin_status_changed + .get_station_ip = tether_plugin_get_station_ip, + .get_station_by_classid = tether_plugin_get_station_by_classid, + .set_station_classid = tether_plugin_set_station_classid }; diff --git a/src/database/include/table-restrictions.h b/src/database/include/table-restrictions.h index ea36988..fb62bb9 100644 --- a/src/database/include/table-restrictions.h +++ b/src/database/include/table-restrictions.h @@ -21,6 +21,7 @@ typedef struct { char *app_id; char *ifname; char *subscriber_id; + char *mac; stc_iface_type_e iftype; stc_rstn_type_e rstn_type; stc_roaming_type_e roaming; diff --git a/src/helper/helper-iptables.c b/src/helper/helper-iptables.c index 0914100..445b627 100644 --- a/src/helper/helper-iptables.c +++ b/src/helper/helper-iptables.c @@ -39,7 +39,6 @@ #define RULE_CGROUP "cgroup" #define RULE_NFACCT "nfacct" #define RULE_TARGET "target" -#define RULE_PROTOCOL "protocol" #define RULE_SIPTYPE "s_ip_type" #define RULE_SIP1 "s_ip1" #define RULE_SIP2 "s_ip2" diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index 70b29a5..d75c3f3 100644 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -285,6 +285,14 @@ bool recreate_counter_by_name(char *cnt_name, nfacct_rule_s *cnt) STRING_SAVE_COPY(cnt->name, cnt_name); +#if 0 + /* ======================================================== + * NOTE:- + * Below parsing for tethering case is not in use + * stc-manager needs to ignore this for NFACCT_TETH_COUNTER + * this is disbaled for future use. + * =======================================================*/ + //LCOV_EXCL_START if (cnt->intend == NFACCT_TETH_COUNTER) { char ifname_buf[MAX_IFACE_LENGTH]; @@ -322,6 +330,7 @@ bool recreate_counter_by_name(char *cnt_name, nfacct_rule_s *cnt) return true; } //LCOV_EXCL_STOP +#endif io_part = strtok_r(name, "_", &save_ptr); if (io_part != NULL) @@ -449,8 +458,10 @@ static stc_error_e exec_iptables_cmd(nfacct_rule_s *rule) iptables_rule.ifname = g_strdup(rule->ifname); iptables_rule.target = g_strdup(get_iptables_jump(rule->jump)); - /* In case of tehering use chain 'STC_TETHER' */ - if (rule->intend == NFACCT_TETH_COUNTER) + /* In case of tehering rules use chain 'STC_TETHER' */ + if (rule->intend == NFACCT_TETH_COUNTER || + rule->intend == NFACCT_TETH_ALLOW || + rule->intend == NFACCT_TETH_BLOCK) iptables_rule.chain = g_strdup(STC_TETHER_CHAIN); else iptables_rule.chain = g_strdup(get_iptables_chain(rule->iotype)); @@ -531,7 +542,9 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule) /* cgroup extention on FORWARD chain are not allowed * remove classid info in case of tethering rules */ - if (rule->intend == NFACCT_TETH_COUNTER) { + if (rule->intend == NFACCT_TETH_COUNTER || + rule->intend == NFACCT_TETH_ALLOW || + rule->intend == NFACCT_TETH_BLOCK) { classid = rule->classid; rule->classid = 0; } @@ -539,7 +552,9 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule) ret = exec_iptables_cmd(rule); /* restore the classid info in case of tethering rule */ - if (rule->intend == NFACCT_TETH_COUNTER) + if (rule->intend == NFACCT_TETH_COUNTER || + rule->intend == NFACCT_TETH_ALLOW || + rule->intend == NFACCT_TETH_BLOCK) rule->classid = classid; ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL, @@ -586,7 +601,9 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule) /* cgroup extention on FORWARD chain are not allowed * remove classid info in case of tethering rules */ - if (rule->intend == NFACCT_TETH_COUNTER) { + if (rule->intend == NFACCT_TETH_COUNTER || + rule->intend == NFACCT_TETH_ALLOW || + rule->intend == NFACCT_TETH_BLOCK) { classid = rule->classid; rule->classid = 0; } @@ -594,7 +611,9 @@ static stc_error_e produce_app_rule(nfacct_rule_s *rule) ret = exec_iptables_cmd(rule); /* restore the classid info in case of tethering rule */ - if (rule->intend == NFACCT_TETH_COUNTER) + if (rule->intend == NFACCT_TETH_COUNTER || + rule->intend == NFACCT_TETH_ALLOW || + rule->intend == NFACCT_TETH_BLOCK) rule->classid = classid; ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL, @@ -795,12 +814,17 @@ void generate_counter_name(nfacct_rule_s *counter) STRING_SAVE_COPY(counter->ifname, iftype_name); } - if (counter->intend == NFACCT_WARN) + if (counter->intend == NFACCT_WARN || + counter->intend == NFACCT_TETH_WARN) warn_symbol = 'w'; - else if (counter->intend == NFACCT_BLOCK) + else if (counter->intend == NFACCT_BLOCK || + counter->intend == NFACCT_TETH_BLOCK) warn_symbol = 'r'; - else if (counter->intend == NFACCT_ALLOW) + else if (counter->intend == NFACCT_ALLOW || + counter->intend == NFACCT_TETH_ALLOW) warn_symbol = 'a'; + else if (counter->intend == NFACCT_TETH_COUNTER) + warn_symbol = 't'; snprintf(counter->name, NFACCT_NAME_MAX, "%c%d_%d_%d_%s", warn_symbol, counter->iotype, counter->iftype, counter->classid, counter->ifname); diff --git a/src/helper/helper-nfacct-rule.h b/src/helper/helper-nfacct-rule.h index 52ef8f4..7520709 100644 --- a/src/helper/helper-nfacct-rule.h +++ b/src/helper/helper-nfacct-rule.h @@ -56,6 +56,9 @@ typedef enum { NFACCT_BLOCK, NFACCT_ALLOW, NFACCT_TETH_COUNTER, + NFACCT_TETH_WARN, + NFACCT_TETH_BLOCK, + NFACCT_TETH_ALLOW, NFACCT_RULE_LAST_ELEM, } nfacct_rule_intend; diff --git a/src/monitor/include/stc-monitor.h b/src/monitor/include/stc-monitor.h index 187035f..d138cbc 100755 --- a/src/monitor/include/stc-monitor.h +++ b/src/monitor/include/stc-monitor.h @@ -27,7 +27,7 @@ /* 1 seconds */ #define CONTR_TIMER_INTERVAL 1 -#define IPV4_IPADDRESS_LEN 16 +#define MAC_ADDRESS_LEN 18 /** * @brief enumeration for data limit types @@ -78,7 +78,7 @@ typedef struct { stc_data_counter_s data_usage; stc_data_counter_s counter; GTree *processes; /**< applications instances */ - char ipaddr[IPV4_IPADDRESS_LEN+1]; /**< application ip address */ + char mac[MAC_ADDRESS_LEN+1]; /**< application mac address */ } stc_app_value_s; /** @@ -87,6 +87,7 @@ typedef struct { typedef struct { gchar *app_id; gchar *ifname; + gchar *mac; gchar *subscriber_id; stc_iface_type_e iftype; stc_roaming_type_e roaming; diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index 7f28d9c..8037c53 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -31,6 +31,7 @@ #include "stc-time.h" #include "stc-manager-plugin-appstatus.h" #include "stc-manager-plugin-exception.h" +#include "stc-manager-plugin-tether.h" #define GRANULARITY 10 #define MAX_INT_LENGTH 128 @@ -101,6 +102,10 @@ static nfacct_rule_jump __get_jump_by_intend(struct nfacct_rule *counter) return NFACCT_JUMP_REJECT; else if (counter->intend == NFACCT_ALLOW) return NFACCT_JUMP_ACCEPT; + else if (counter->intend == NFACCT_TETH_BLOCK) + return NFACCT_JUMP_REJECT; + else if (counter->intend == NFACCT_TETH_ALLOW) + return NFACCT_JUMP_ACCEPT; return NFACCT_JUMP_UNKNOWN; } @@ -124,7 +129,7 @@ static stc_error_e __add_iptables_tether_in(struct nfacct_rule *counter, ret = produce_net_rule(counter); - g_free(counter->src_ip1); + FREE(counter->src_ip1); counter->src_iprange_type = NFACCT_IPRANGE_TYPE_NONE; return ret; } @@ -148,7 +153,7 @@ static stc_error_e __add_iptables_tether_out(struct nfacct_rule *counter, ret = produce_net_rule(counter); - g_free(counter->dst_ip1); + FREE(counter->dst_ip1); counter->dst_iprange_type = NFACCT_IPRANGE_TYPE_NONE; return ret; } @@ -172,7 +177,7 @@ static stc_error_e __del_iptables_tether_in(struct nfacct_rule *counter, ret = produce_net_rule(counter); - g_free(counter->src_ip1); + FREE(counter->src_ip1); counter->src_iprange_type = NFACCT_IPRANGE_TYPE_NONE; return ret; } @@ -196,7 +201,7 @@ static stc_error_e __del_iptables_tether_out(struct nfacct_rule *counter, ret = produce_net_rule(counter); - g_free(counter->dst_ip1); + FREE(counter->dst_ip1); counter->dst_iprange_type = NFACCT_IPRANGE_TYPE_NONE; return ret; } @@ -515,16 +520,19 @@ static gboolean __processes_tree_check_empty(gpointer key, gpointer value, } //LCOV_EXCL_STOP -static gboolean __add_application_monitor_for_tethering(gpointer key, gpointer value, - gpointer data) +static gboolean __add_application_monitor_for_tethering(gpointer key, + gpointer value, gpointer data) { stc_app_value_s *app_value = (stc_app_value_s *)value; stc_app_key_s *app_key = (stc_app_key_s *)key; default_connection_s *connection = (default_connection_s *)data; stc_s *stc = stc_get_manager(); struct nfacct_rule counter; + char *ipaddr = NULL; + int ret; - STC_LOGI("add tether app (%s)", app_key->app_id); + STC_LOGI("add appid(%s) classid(%d)", app_key->app_id, + app_value->classid); if (stc == NULL || connection == NULL) return FALSE; @@ -550,9 +558,16 @@ static gboolean __add_application_monitor_for_tethering(gpointer key, gpointer v counter.iftype = connection->tether_iface.type; g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH); - __add_iptables_tether_in(&counter, app_value->ipaddr); - __add_iptables_tether_out(&counter, app_value->ipaddr); + /* get the ip address of the station based on its mac address */ + ret = stc_plugin_tether_get_station_ip(app_value->mac, &ipaddr); + if (ret != STC_ERROR_NONE) + return FALSE; + + /* tethering iptables rule */ + __add_iptables_tether_in(&counter, ipaddr); + __add_iptables_tether_out(&counter, ipaddr); + g_free(ipaddr); return FALSE; } @@ -564,8 +579,11 @@ static gboolean __remove_application_monitor_for_tethering(gpointer key, gpointe default_connection_s *connection = (default_connection_s *)data; stc_s *stc = stc_get_manager(); struct nfacct_rule counter; + char *ipaddr = NULL; + int ret; - STC_LOGI("remove tether app (%s)", app_key->app_id); + STC_LOGI("remove appid(%s) classid(%d)", app_key->app_id, + app_value->classid); if (stc == NULL || connection == NULL) return FALSE; @@ -591,9 +609,15 @@ static gboolean __remove_application_monitor_for_tethering(gpointer key, gpointe counter.iftype = connection->tether_iface.type; g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH); - __del_iptables_tether_in(&counter, app_value->ipaddr); - __del_iptables_tether_out(&counter, app_value->ipaddr); + /* get the ip address of the station based on its mac address */ + ret = stc_plugin_tether_get_station_ip(app_value->mac, &ipaddr); + if (ret != STC_ERROR_NONE) + return FALSE; + __del_iptables_tether_in(&counter, ipaddr); + __del_iptables_tether_out(&counter, ipaddr); + + g_free(ipaddr); return FALSE; } @@ -784,6 +808,96 @@ static void __add_iptables_rule(int64_t classid, nfacct_rule_intend intend, __add_ip6tables_out(&counter); } +static void __add_tethering_iptables_rule(int64_t classid, gchar *mac, + nfacct_rule_intend intend, stc_iface_type_e iftype) +{ + default_connection_s *connection = stc_get_default_connection(); + struct nfacct_rule counter; + stc_s *stc = stc_get_manager(); + char *ipaddr = NULL; + int ret; + + if (!stc || !mac) + return; + + if (!stc->carg) { + stc->carg = MALLOC0(counter_arg_s, 1); + if (stc->carg == NULL) + return; + + stc->carg->sock = stc_monitor_get_counter_socket(); + } + + memset(&counter, 0, sizeof(struct nfacct_rule)); + + counter.carg = stc->carg; + counter.classid = classid; + counter.intend = intend; + + if (connection->tether_state != TRUE || + connection->tether_iface.ifname == NULL) + return; + + counter.iftype = connection->tether_iface.type; + g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH); + + /* get connected station ip based on its mac */ + ret = stc_plugin_tether_get_station_ip(mac, &ipaddr); + if (ret != STC_ERROR_NONE) + return; + + /* tethering iptables rule */ + __add_iptables_tether_in(&counter, ipaddr); + __add_iptables_tether_out(&counter, ipaddr); + g_free(ipaddr); +} + +static void __del_tethering_iptables_rule(int64_t classid, gchar *mac, + nfacct_rule_intend intend, stc_iface_type_e iftype) +{ + default_connection_s *connection = stc_get_default_connection(); + struct nfacct_rule counter; + stc_s *stc = stc_get_manager(); + char *ipaddr = NULL; + int ret; + + if (!stc || !mac) + return; + + if (!stc->carg) { + stc->carg = MALLOC0(counter_arg_s, 1); + if (stc->carg == NULL) + return; + + stc->carg->sock = stc_monitor_get_counter_socket(); + } + + memset(&counter, 0, sizeof(struct nfacct_rule)); + + counter.carg = stc->carg; + counter.classid = classid; + counter.intend = intend; + + if (connection->tether_state != TRUE || + connection->tether_iface.ifname == NULL) + return; + + counter.iftype = connection->tether_iface.type; + g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH); + + /* get connected station ip based on its mac */ + ret = stc_plugin_tether_get_station_ip(mac, &ipaddr); + if (ret != STC_ERROR_NONE) { + STC_LOGE("Error: no IP found for station mac(%s)", mac); + return; + } + + /* tethering iptables rule */ + __del_iptables_tether_in(&counter, ipaddr); + __del_iptables_tether_out(&counter, ipaddr); + g_free(ipaddr); +} + static void __del_iptables_rule(int64_t classid, nfacct_rule_intend intend, stc_iface_type_e iftype) { @@ -872,6 +986,142 @@ static stc_cb_ret_e __statistics_info_cb(const table_statistics_info *info, return STC_CONTINUE; } +static void __process_tethering_restriction(enum traffic_restriction_type rstn_type, + stc_rstn_key_s *rstn_key, stc_rstn_value_s *rstn_value, void *data) +{ + default_connection_s *old_connection = (default_connection_s *)data; + default_connection_s *connection = NULL; + char *mac_str = NULL; + + if (old_connection != NULL) + connection = old_connection; + else + connection = stc_get_default_connection(); + + /* in case tethering is not active */ + if (connection->tether_state == FALSE) + return; + + /* rstn not applicable for this interface */ + if (rstn_key->ifname != NULL && g_strcmp0("", rstn_key->ifname) != 0 && + (g_strcmp0(connection->tether_iface.ifname, rstn_key->ifname) != 0)) + return; + + /* in case appid not a tethering app */ + if (!g_str_has_suffix(rstn_key->app_id, STC_TETHERING_APP_SUFFIX)) + return; + + /* Ignore TOTAL_TETHERING, + * Process only station appids */ + if (rstn_value->classid == STC_TETHERING_APP_CLASSID) + return; + + /* get the station mac based on classid */ + stc_plugin_tether_get_station_by_classid(rstn_value->classid, &mac_str); + if (!mac_str) { + STC_LOGE("station not found for classid(%d)", rstn_value->classid); + return; + } + + switch (rstn_type) { + case RST_SET: + { + int i; + table_counters_info info; + int64_t effective_limit[STC_RSTN_LIMIT_TYPE_MAX] = { 0, }; + + memset(&info, 0, sizeof(table_counters_info)); + rstn_value->limit_exceeded = 0; + + if ((rstn_value->counter[STC_RSTN_LIMIT_TYPE_DATA] == 0 && + rstn_value->limit[STC_RSTN_LIMIT_TYPE_DATA] >= 0) || + (rstn_value->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] == 0 && + rstn_value->limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] >= 0) || + (rstn_value->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] == 0 && + rstn_value->limit[STC_RSTN_LIMIT_TYPE_MONTHLY] >= 0) || + (rstn_value->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] == 0 && + rstn_value->limit[STC_RSTN_LIMIT_TYPE_WEEKLY] >= 0) || + (rstn_value->counter[STC_RSTN_LIMIT_TYPE_DAILY] == 0 && + rstn_value->limit[STC_RSTN_LIMIT_TYPE_DAILY] >= 0)) { + table_counters_get(rstn_value->restriction_id, &info); + + time_t current_time = 0; + cumulative_data_s stat; + table_statistics_select_rule rule; + + memset(&stat, 0, sizeof(cumulative_data_s)); + stat.month_start_ts = rstn_value->month_start_ts; + stat.week_start_ts = g_system->last_week_ts; + stat.day_start_ts = g_system->last_day_ts; + + memset(&rule, 0, sizeof(table_statistics_select_rule)); + rule.from = rstn_value->month_start_ts; + time(¤t_time); + rule.to = current_time; + rule.iftype = rstn_key->iftype; + rule.granularity = GRANULARITY; + + table_statistics_per_app(rstn_key->app_id, &rule, __statistics_info_cb, &stat); + + rstn_value->counter[STC_RSTN_LIMIT_TYPE_DATA] = info.data_counter; + rstn_value->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info.warn_counter; + rstn_value->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] = info.monthly_counter + stat.monthly_stat; + rstn_value->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] = info.weekly_counter + stat.weekly_stat; + rstn_value->counter[STC_RSTN_LIMIT_TYPE_DAILY] = info.daily_counter + stat.daily_stat; + } + + for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) { + if (rstn_value->limit[i] >= 0) { + effective_limit[i] = rstn_value->limit[i] - rstn_value->counter[i]; + + if (effective_limit[i] < 0) + rstn_value->limit_exceeded |= (1 << i); + } + } + + STC_LOGD("rstn_id [%llu], datausage [%llu] bytes", + rstn_value->restriction_id, info.data_counter); + + if (rstn_value->limit_exceeded != 0 && + rstn_value->limit_exceeded != (1 << STC_RSTN_LIMIT_TYPE_DATA_WARN)) { + __add_tethering_iptables_rule(rstn_value->classid, mac_str, + NFACCT_TETH_BLOCK, rstn_key->iftype); + } + + rstn_value->rstn_state = STC_RSTN_STATE_ACTIVATED; + } + break; + case RST_EXCLUDE: + { + __add_tethering_iptables_rule(rstn_value->classid, mac_str, + NFACCT_TETH_ALLOW, rstn_key->iftype); + + rstn_value->rstn_state = STC_RSTN_STATE_ACTIVATED; + rstn_value->limit_exceeded = 0; + rstn_value->limit_notified = 0; + } + break; + case RST_UNSET: + { + int i; + __del_tethering_iptables_rule(rstn_value->classid, mac_str, + NFACCT_TETH_BLOCK, rstn_key->iftype); + + rstn_value->rstn_state = STC_RSTN_STATE_DEACTIVATED; + rstn_value->limit_exceeded = 0; + rstn_value->limit_notified = 0; + + for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) + if (rstn_value->limit[i] >= 0) + rstn_value->counter[i] = 0; + } + break; + default: + ;//Do Nothing + } + FREE(mac_str); +} + static void __process_restriction(enum traffic_restriction_type rstn_type, stc_rstn_key_s *rstn_key, stc_rstn_value_s *rstn_value, void *data) @@ -898,6 +1148,13 @@ static void __process_restriction(enum traffic_restriction_type rstn_type, if (rstn_value->classid <= STC_UNKNOWN_CLASSID) return; + /* Do not proceed for tethering station appid if found here, + * for tethering station apps __process_tethering_restriction() call + * will handle it */ + if (g_str_has_suffix(rstn_key->app_id, STC_TETHERING_APP_SUFFIX) && + rstn_value->classid != STC_TETHERING_APP_CLASSID) + return; + switch (rstn_type) { case RST_SET: { @@ -1024,6 +1281,9 @@ static gboolean __remove_rstns_foreach_application(gpointer key, /* remove restriction from system */ __process_restriction(RST_UNSET, rstn_key, rstn_value, NULL); + /* remove tethering restriction from system*/ + __process_tethering_restriction(RST_UNSET, rstn_key, rstn_value, NULL); + __print_rstn(rstn_key, rstn_value); out: return FALSE; @@ -1125,6 +1385,36 @@ static stc_error_e __close_and_reopen_contr_sock(stc_system_s *system) return STC_ERROR_NONE; } +static void __action_when_rstn_limit_exceeded_tethering(stc_rstn_key_s *rstn_key, + stc_rstn_value_s *rstn_value, classid_bytes_context_s *context) +{ + char *mac_str = NULL; + struct nfacct_rule *counter = context->counter; + + /* get the station mac based on classid */ + stc_plugin_tether_get_station_by_classid(counter->classid, &mac_str); + if (!mac_str) { + STC_LOGE("station not found for classid(%d)", counter->classid); + return; + } + + STC_LOGI("station mac %s, classid %u, iftype %u, iotype %d, \ + intend %d, ifname %s, bytes %lld", mac_str, + counter->classid, counter->iftype, counter->iotype, + counter->intend, counter->ifname, context->bytes); + + /* Block tethering station immediately */ + counter->intend = NFACCT_TETH_BLOCK; + __del_tethering_iptables_rule(counter->classid, mac_str, + NFACCT_TETH_BLOCK, rstn_key->iftype); + + __add_tethering_iptables_rule(counter->classid, mac_str, + NFACCT_TETH_BLOCK, rstn_key->iftype); + counter->intend = NFACCT_TETH_COUNTER; + + g_free(mac_str); +} + static void __action_when_rstn_limit_exceeded(stc_rstn_limit_type_e limit_type, stc_rstn_key_s *rstn_key, stc_rstn_value_s *rstn_value, @@ -1160,18 +1450,30 @@ static void __action_when_rstn_limit_exceeded(stc_rstn_limit_type_e limit_type, net_popup_content = "restriction threshold crossed"; net_popup_type = "restriction_noti"; - /* block immediately */ - context->counter->intend = NFACCT_BLOCK; - __del_iptables_in(context->counter); - __del_iptables_out(context->counter); - __add_iptables_in(context->counter); - __add_iptables_out(context->counter); + /* Apply restriction for tethering apps if app_id is of tethering client + * otherwise do the normal iptables rule */ + if (context->counter->intend == NFACCT_TETH_COUNTER) { - __del_ip6tables_in(context->counter); - __del_ip6tables_out(context->counter); - __add_ip6tables_in(context->counter); - __add_ip6tables_out(context->counter); - context->counter->intend = NFACCT_COUNTER; + if (g_str_has_suffix(rstn_key->app_id, STC_TETHERING_APP_SUFFIX) && + rstn_value->classid != STC_TETHERING_APP_CLASSID) { + __action_when_rstn_limit_exceeded_tethering(rstn_key, rstn_value, + context); + } + + } else { + /* block immediately */ + context->counter->intend = NFACCT_BLOCK; + __del_iptables_in(context->counter); + __del_iptables_out(context->counter); + __add_iptables_in(context->counter); + __add_iptables_out(context->counter); + + __del_ip6tables_in(context->counter); + __del_ip6tables_out(context->counter); + __add_ip6tables_in(context->counter); + __add_ip6tables_out(context->counter); + context->counter->intend = NFACCT_COUNTER; + } rstn_value->limit_exceeded |= (1 << limit_type); @@ -1877,6 +2179,7 @@ static gboolean __remove_restriction(gpointer key, gpointer value, stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value; __process_restriction(RST_UNSET, rstn_key, rstn_value, data); + __process_tethering_restriction(RST_UNSET, rstn_key, rstn_value, data); __print_rstn(rstn_key, rstn_value); return FALSE; } @@ -1891,10 +2194,13 @@ static gboolean __add_restriction_debug(gpointer key, gpointer value, if (rstn_value->rstn_state == STC_RSTN_STATE_ACTIVATED) return FALSE; - if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT) + if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT) { __process_restriction(RST_EXCLUDE, rstn_key, rstn_value, data); - else + __process_tethering_restriction(RST_EXCLUDE, rstn_key, rstn_value, data); + } else { __process_restriction(RST_SET, rstn_key, rstn_value, data); + __process_tethering_restriction(RST_SET, rstn_key, rstn_value, data); + } __print_rstn(rstn_key, rstn_value); @@ -1911,10 +2217,13 @@ static gboolean __add_restriction(gpointer key, gpointer value, gpointer data) if (rstn_value->rstn_state == STC_RSTN_STATE_ACTIVATED) return FALSE; - if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT) + if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT) { __process_restriction(RST_EXCLUDE, rstn_key, rstn_value, data); - else + __process_tethering_restriction(RST_EXCLUDE, rstn_key, rstn_value, data); + } else { __process_restriction(RST_SET, rstn_key, rstn_value, data); + __process_tethering_restriction(RST_SET, rstn_key, rstn_value, data); + } return FALSE; } @@ -1971,6 +2280,7 @@ static stc_error_e __rstn_tree_add(stc_rstn_key_s *key, rstn_key->app_id = g_strdup(key->app_id); rstn_key->ifname = g_strdup(key->ifname); + rstn_key->mac = g_strdup(key->mac); rstn_key->subscriber_id = g_strdup(key->subscriber_id); rstn_key->iftype = key->iftype; rstn_key->roaming = key->roaming; @@ -2071,10 +2381,13 @@ static gboolean __add_rstn_foreach_application(gpointer key, goto out; /* add restriction to system */ - if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT) + if (rstn_value->rstn_type == STC_RSTN_TYPE_ACCEPT) { __process_restriction(RST_EXCLUDE, rstn_key, rstn_value, NULL); - else + __process_tethering_restriction(RST_EXCLUDE, rstn_key, rstn_value, NULL); + } else { __process_restriction(RST_SET, rstn_key, rstn_value, NULL); + __process_tethering_restriction(RST_SET, rstn_key, rstn_value, NULL); + } __print_rstn(rstn_key, rstn_value); out: @@ -2293,7 +2606,7 @@ API stc_error_e stc_monitor_application_add(const stc_app_key_s app_key, value->type = app_value.type; value->data_usage.in_bytes = app_value.data_usage.in_bytes; value->data_usage.out_bytes = app_value.data_usage.out_bytes; - g_strlcpy(value->ipaddr, app_value.ipaddr, IPV4_IPADDRESS_LEN); + g_strlcpy(value->mac, app_value.mac, MAC_ADDRESS_LEN); value->processes = g_tree_new_full(__processes_tree_key_compare, NULL, __processes_tree_key_free, @@ -2302,6 +2615,11 @@ API stc_error_e stc_monitor_application_add(const stc_app_key_s app_key, /* create cgroup and update classid */ value->classid = get_classid_by_app_id(app_key.app_id, TRUE); + /* update classid for tethering station based on its mac address */ + if (g_str_has_suffix(app_key.app_id, STC_TETHERING_APP_SUFFIX) && + value->classid != STC_TETHERING_APP_CLASSID) + stc_plugin_tether_set_station_classid(value->mac, value->classid); + g_tree_insert(g_system->apps, key, value); /* add nfacct rule for this classid */ @@ -2517,6 +2835,7 @@ stc_error_e stc_monitor_rstns_tree_add(const table_restrictions_info *info) key.app_id = g_strdup(info->app_id); key.ifname = g_strdup(info->ifname); + key.mac = g_strdup(info->mac); key.subscriber_id = g_strdup(info->subscriber_id); key.iftype = info->iftype; key.roaming = info->roaming; @@ -2549,6 +2868,7 @@ stc_error_e stc_monitor_rstns_tree_add(const table_restrictions_info *info) FREE(key.app_id); FREE(key.ifname); + FREE(key.mac); FREE(key.subscriber_id); return ret; } diff --git a/src/stc-manager-plugin-tether.c b/src/stc-manager-plugin-tether.c index 1813e40..afb170d 100644 --- a/src/stc-manager-plugin-tether.c +++ b/src/stc-manager-plugin-tether.c @@ -65,3 +65,69 @@ int stc_plugin_tether_deinit(void) __STC_LOG_FUNC_EXIT__; return STC_ERROR_NONE; } + +int stc_plugin_tether_get_station_ip(const char *mac, char **ipaddr) +{ + __STC_LOG_FUNC_ENTER__; + char ip[INET_ADDRSTRLEN+1]; + + if (!stc_tether_plugin_enabled || + mac == NULL || ipaddr == NULL) { + STC_LOGE("invalid args"); + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_INVALID_PARAMETER; + } + + memset(ip, 0, sizeof(ip)); + + if (plugin->get_station_ip(mac, ip) != STC_ERROR_NONE) + return STC_ERROR_FAIL; + + *ipaddr = g_strdup(ip); + STC_LOGI("station ip(%s)", *ipaddr); + + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_NONE; +} + +int stc_plugin_tether_get_station_by_classid(const int classid, char **mac) +{ + __STC_LOG_FUNC_ENTER__; + char mac_addr[STATION_MAC_STR_LEN+1]; + + if (!stc_tether_plugin_enabled || mac == NULL) { + STC_LOGE("invalid args"); + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_INVALID_PARAMETER; + } + + memset(mac_addr, 0, sizeof(mac_addr)); + + if (plugin->get_station_by_classid(classid, mac_addr) != STC_ERROR_NONE) + return STC_ERROR_FAIL; + + *mac = g_strdup(mac_addr); + STC_LOGI("station mac(%s)", *mac); + + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_NONE; +} + +int stc_plugin_tether_set_station_classid(const char *mac, int classid) +{ + __STC_LOG_FUNC_ENTER__; + + if (!stc_tether_plugin_enabled || mac == NULL) { + STC_LOGE("invalid args"); + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_INVALID_PARAMETER; + } + + if (plugin->set_station_classid(mac, classid) != STC_ERROR_NONE) + return STC_ERROR_FAIL; + + STC_LOGI("classid(%d) for station mac(%s) is set successfully", + classid, mac); + __STC_LOG_FUNC_EXIT__; + return STC_ERROR_NONE; +} diff --git a/src/stc-restriction.c b/src/stc-restriction.c index 2f44459..f4cd753 100644 --- a/src/stc-restriction.c +++ b/src/stc-restriction.c @@ -241,6 +241,12 @@ static void __stc_extract_restriction_rule(const char *key, GVariant *value, rule->rstn_type = g_variant_get_uint16(value); STC_LOGD("type: [%u]", (unsigned int) rule->rstn_type); + } else if (!g_strcmp0(key, "mac")) { + guint str_length; + const gchar *str = g_variant_get_string(value, &str_length); + rule->mac = g_strdup(str); + STC_LOGD("mac: [%s]", rule->mac); + } else { STC_LOGD("Unknown select rule"); //LCOV_EXCL_LINE } -- 2.7.4 From c8f94ac3feda779ad5ae0cdc47ebee417db6d643 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Mon, 3 Sep 2018 14:01:06 +0900 Subject: [PATCH 09/16] Fix a bug for using heap after free Change-Id: I7bb7fa02324f919bd7d6aee99a2ceb0f8090a4bc Signed-off-by: hyunuktak --- packaging/stc-manager.spec | 2 +- src/stc-manager.c | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) mode change 100644 => 100755 src/stc-manager.c diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index b57a246..d84c351 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.75 +Version: 0.0.76 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/stc-manager.c b/src/stc-manager.c old mode 100644 new mode 100755 index 58f6531..7b4876a --- a/src/stc-manager.c +++ b/src/stc-manager.c @@ -120,7 +120,11 @@ static stc_s *__stc_manager_init(void) cgroup_set_release_agent(NET_CLS_SUBSYS, NET_RELEASE_AGENT); - EXEC(STC_ERROR_NONE, stc_db_initialize()); + err = stc_db_initialize(); + if (err != STC_ERROR_NONE) { + STC_LOGD("Failed to initialize stc db"); //LCOV_EXCL_LINE + return NULL; //LCOV_EXCL_LINE + } stc_plugin_appstatus_init(); stc_plugin_exception_init(); @@ -130,8 +134,10 @@ static stc_s *__stc_manager_init(void) stc_firewall_init(); err = stc_monitor_init(); - if (err != STC_ERROR_NONE) - goto handle_error; + if (err != STC_ERROR_NONE) { + STC_LOGD("Failed to initialize stc manager"); //LCOV_EXCL_LINE + return NULL; //LCOV_EXCL_LINE + } stc_plugin_procfs_load_pid(); stc_manager_gdbus_init((gpointer)stc); @@ -139,11 +145,6 @@ static stc_s *__stc_manager_init(void) STC_LOGI("stc manager initialized"); __STC_LOG_FUNC_EXIT__; return stc; - -handle_error: - STC_LOGD("Failed to initialize stc manager"); //LCOV_EXCL_LINE - __stc_manager_deinit(); //LCOV_EXCL_LINE - return NULL; //LCOV_EXCL_LINE } stc_s *stc_get_manager(void) -- 2.7.4 From 6bd0d8efb2ad6978205f4f76832cc83ae7761a30 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Mon, 3 Sep 2018 18:26:09 +0900 Subject: [PATCH 10/16] Initialize memory for nfacct rule Change-Id: Iadc6d5a531bc14e450970f6af57672b6f2b9fe66 Signed-off-by: hyunuktak --- packaging/stc-manager.spec | 2 +- src/monitor/stc-monitor.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index d84c351..b75fff7 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.76 +Version: 0.0.77 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 7f28d9c..ebf15a5 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -760,6 +760,8 @@ static void __add_iptables_rule(int64_t classid, nfacct_rule_intend intend, stc->carg->sock = stc_monitor_get_counter_socket(); //LCOV_EXCL_LINE } + memset(&counter, 0, sizeof(struct nfacct_rule)); + counter.carg = stc->carg; counter.classid = classid; counter.intend = intend; @@ -806,6 +808,8 @@ static void __del_iptables_rule(int64_t classid, nfacct_rule_intend intend, stc->carg->sock = stc_monitor_get_counter_socket(); //LCOV_EXCL_LINE } + memset(&counter, 0, sizeof(struct nfacct_rule)); + counter.carg = stc->carg; counter.classid = classid; counter.intend = intend; @@ -1602,6 +1606,8 @@ static gboolean __reset_time_counter_foreach_rstn(gpointer key, stc_monitor_get_counter_socket(); } + memset(&counter, 0, sizeof(struct nfacct_rule)); + counter.carg = stc->carg; counter.classid = rstn_value->classid; counter.intend = NFACCT_BLOCK; -- 2.7.4 From cd1d2a991820b939ec361b9e200088fe46eedbd6 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Thu, 6 Sep 2018 10:52:44 +0900 Subject: [PATCH 11/16] Remove logic to place pids to background cgroup procs Change-Id: I5f491bc202cfd1d660370e7367858e92fe23691c Signed-off-by: hyunuktak --- packaging/stc-manager.spec | 2 +- src/helper/helper-cgroup.c | 3 --- src/monitor/stc-monitor.c | 28 ++++++---------------------- 3 files changed, 7 insertions(+), 26 deletions(-) mode change 100644 => 100755 src/helper/helper-cgroup.c diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index b75fff7..87b4095 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.77 +Version: 0.0.78 Release: 0 Group: Network & Connectivity/Other License: Apache-2.0 diff --git a/src/helper/helper-cgroup.c b/src/helper/helper-cgroup.c old mode 100644 new mode 100755 index fa54c12..ee7c282 --- a/src/helper/helper-cgroup.c +++ b/src/helper/helper-cgroup.c @@ -231,9 +231,6 @@ void cgroup_init(void) cgroup_make_subdir(STC_CGROUP_NETWORK, STC_BACKGROUND_CGROUP_NAME, NULL); - cgroup_write_node_uint32(BACKGROUND_CGROUP_NETWORK, - CLASSID_FILE_NAME, STC_BACKGROUND_APP_CLASSID); - /* create foreground cgroup directory */ cgroup_make_subdir(STC_CGROUP_NETWORK, STC_FOREGROUND_CGROUP_NAME, NULL); diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index ca7f6bf..4f1129c 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -2432,16 +2432,6 @@ static void __add_application_by_interface(const char *app_id) FREE(app_key.app_id); } -static guint __get_background_state(void) -{ - return g_system->background_state;; -} - -static void __set_background_state(guint state) -{ - g_system->background_state = state; -} - static gboolean __processes_tree_foreach_background(gpointer key, gpointer value, gpointer data) @@ -2449,10 +2439,7 @@ static gboolean __processes_tree_foreach_background(gpointer key, stc_process_key_s *proc_key = (stc_process_key_s *)key; stc_app_key_s *app_key = (stc_app_key_s *)data; - if (g_system->background_state) - place_pids_to_net_cgroup(proc_key->pid, STC_BACKGROUND_APP_ID); - else - place_pids_to_net_cgroup(proc_key->pid, app_key->app_id); + place_pids_to_net_cgroup(proc_key->pid, app_key->app_id); return FALSE; } @@ -2771,10 +2758,7 @@ API stc_error_e stc_monitor_process_update_ground(const stc_app_key_s app_key, if (proc_lookup->ground != ground) proc_lookup->ground = ground; - if (ground == STC_APP_STATE_BACKGROUND && __get_background_state()) - place_pids_to_net_cgroup(proc_key.pid, STC_BACKGROUND_APP_ID); - else - place_pids_to_net_cgroup(proc_key.pid, app_key.app_id); + place_pids_to_net_cgroup(proc_key.pid, app_key.app_id); return ret; } @@ -2856,8 +2840,8 @@ stc_error_e stc_monitor_rstns_tree_add(const table_restrictions_info *info) value.classid = STC_UNKNOWN_CLASSID; if (value.classid == STC_BACKGROUND_APP_CLASSID) { - __set_background_state(TRUE); //LCOV_EXCL_LINE - __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, g_system->background_state); //LCOV_EXCL_LINE + g_system->background_state = TRUE; //LCOV_EXCL_LINE + __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, TRUE); //LCOV_EXCL_LINE __process_update_background(); //LCOV_EXCL_LINE } @@ -2892,8 +2876,8 @@ stc_error_e stc_monitor_rstns_tree_remove(const table_restrictions_info *info) }; if (!strcmp(key.app_id, STC_BACKGROUND_APP_ID)) { - __set_background_state(FALSE); //LCOV_EXCL_LINE - __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, g_system->background_state); //LCOV_EXCL_LINE + g_system->background_state = FALSE; //LCOV_EXCL_LINE + __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, FALSE); //LCOV_EXCL_LINE __process_update_background(); //LCOV_EXCL_LINE } -- 2.7.4 From 1226449614628a71d1939fdd15c21c81ebfc60ce Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Fri, 7 Sep 2018 11:03:03 +0900 Subject: [PATCH 12/16] Modify attr for "/var/lib/stc" Change-Id: Ieec5d5ee3f217e8b021a9c175636bdcd877203a9 Signed-off-by: hyunuktak --- packaging/stc-manager.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/stc-manager.spec b/packaging/stc-manager.spec index b75fff7..ab1c360 100644 --- a/packaging/stc-manager.spec +++ b/packaging/stc-manager.spec @@ -122,7 +122,7 @@ cp resources/dbus/stc-manager.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/st %attr(644,root,root) %{_libdir}/systemd/system/stc-manager.service %attr(644,root,root) %{_libdir}/systemd/system/multi-user.target.wants/stc-manager.service -%attr(755,root,root) /%{_localstatedir}/lib/stc +%attr(755,network_fw,network_fw) /%{_localstatedir}/lib/stc %attr(600,root,root) /%{_localstatedir}/lib/stc/exceptions #DBus DAC -- 2.7.4 From 4ba9fee21db5a1911529822b5928c3f41c4e9946 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Mon, 10 Sep 2018 09:11:37 +0900 Subject: [PATCH 13/16] Fix a coverity for unchecking return value Change-Id: I5c9290ebeceb806ab1ff64ed6f0127ce09c81873 Signed-off-by: hyunuktak --- src/helper/helper-nfacct-rule.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/helper/helper-nfacct-rule.c b/src/helper/helper-nfacct-rule.c index d75c3f3..a3e4647 100644 --- a/src/helper/helper-nfacct-rule.c +++ b/src/helper/helper-nfacct-rule.c @@ -476,14 +476,22 @@ static stc_error_e exec_iptables_cmd(nfacct_rule_s *rule) iptables_rule.d_iprange_type = rule->dst_iprange_type; /* specify source and destination ip address if any */ - if (rule->src_ip1) - inet_aton(rule->src_ip1, &iptables_rule.s_ip1); - if (rule->src_ip2) - inet_aton(rule->src_ip2, &iptables_rule.s_ip2); - if (rule->dst_ip1) - inet_aton(rule->dst_ip1, &iptables_rule.d_ip1); - if (rule->dst_ip2) - inet_aton(rule->dst_ip2, &iptables_rule.d_ip2); + if (rule->src_ip1) { + if (!inet_aton(rule->src_ip1, &iptables_rule.s_ip1)) + STC_LOGE("Failed to inet aton [%s]", rule->src_ip1); + } + if (rule->src_ip2) { + if (!inet_aton(rule->src_ip2, &iptables_rule.s_ip2)) + STC_LOGE("Failed to inet aton [%s]", rule->src_ip2); + } + if (rule->dst_ip1) { + if (!inet_aton(rule->dst_ip1, &iptables_rule.d_ip1)) + STC_LOGE("Failed to inet aton [%s]", rule->dst_ip1); + } + if (rule->dst_ip2) { + if (!inet_aton(rule->dst_ip2, &iptables_rule.d_ip2)) + STC_LOGE("Failed to inet aton [%s]", rule->dst_ip2); + } if (rule->action == NFACCT_ACTION_DELETE) { /* delete interface rule */ -- 2.7.4 From e84a61cd98b1feee0503035f12fff31c7c535f69 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Tue, 11 Sep 2018 09:44:36 +0900 Subject: [PATCH 14/16] Fix a memory leak Change-Id: I1a32004a8aaea706156e9e53d304b9f149081a0d Signed-off-by: hyunuktak --- plugin/tether/stc-plugin-tether.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) mode change 100644 => 100755 plugin/tether/stc-plugin-tether.c diff --git a/plugin/tether/stc-plugin-tether.c b/plugin/tether/stc-plugin-tether.c old mode 100644 new mode 100755 index 2641509..f1278f9 --- a/plugin/tether/stc-plugin-tether.c +++ b/plugin/tether/stc-plugin-tether.c @@ -181,16 +181,16 @@ static void _mobileap_signal_cb(GDBusConnection *conn, STC_LOGI("%s interface(%s)", sig, interface); - sta = (tether_sta_info_s *)g_malloc0(sizeof(tether_sta_info_s)); - if (sta == NULL) { - STC_LOGE("g_malloc0 failed"); - return; - } - g_variant_get(param, "(susssu)", &state, &type, &ip, &mac, &hostname, &tm); STC_LOGI("%s: ip(%s) mac(%s) name(%s) tm(%d)", state, ip, mac, hostname, tm); if (!g_strcmp0(state, "DhcpConnected")) { + sta = (tether_sta_info_s *)g_malloc0(sizeof(tether_sta_info_s)); + if (sta == NULL) { + STC_LOGE("g_malloc0 failed"); + return; + } + g_strlcpy(sta->ip, ip, INET_ADDRSTRLEN); g_strlcpy(sta->mac, mac, STATION_MAC_STR_LEN); g_strlcpy(sta->name, hostname, STATION_STR_HOSTNAME_LEN); -- 2.7.4 From 7b9e9ce6289594e586c4726d32c7db72c8e5a420 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Wed, 19 Sep 2018 10:58:42 +0900 Subject: [PATCH 15/16] Fix build warning for format Change-Id: I173ee0057395eccb3cf82048428288f572d5fed5 Signed-off-by: hyunuktak --- plugin/tether/stc-plugin-tether.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/tether/stc-plugin-tether.c b/plugin/tether/stc-plugin-tether.c index f1278f9..c335f05 100755 --- a/plugin/tether/stc-plugin-tether.c +++ b/plugin/tether/stc-plugin-tether.c @@ -232,7 +232,7 @@ stc_error_e tether_plugin_get_station_by_classid(const int classid, char *mac) if (_get_station_info((gconstpointer)&classid_value, _compare_sta_by_classid_func, &tmp) != 0) { - STC_LOGE("classid(%s) not found", classid); + STC_LOGE("classid(%d) not found", classid); return STC_ERROR_FAIL; } -- 2.7.4 From 89fbda039c955a8301dba4075c7a665af6ef1e17 Mon Sep 17 00:00:00 2001 From: Abhishek Sansanwal Date: Mon, 8 Oct 2018 16:34:53 +0530 Subject: [PATCH 16/16] Firewall rule is invalid if target >= STC_FW_RULE_TARGET_MAX Signed-off-by: Abhishek Sansanwal Change-Id: I6d6b9c9e3ef5410705dc83167cda4cd7c16da7af --- src/stc-firewall.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stc-firewall.c b/src/stc-firewall.c index ec1f674..9f353ee 100755 --- a/src/stc-firewall.c +++ b/src/stc-firewall.c @@ -1157,6 +1157,11 @@ gboolean __validate_fw_rule(firewall_rule_s *rule) return FALSE; } + if (rule->target >= STC_FW_RULE_TARGET_MAX) { + __STC_LOG_FUNC_EXIT__; + return FALSE; + } + if (rule->target == STC_FW_RULE_TARGET_LOG && (rule->log_prefix == NULL || rule->log_prefix[0] == '\0')) { -- 2.7.4