2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "stc-manager.h"
20 #include "stc-plugin-monitor.h"
21 #include "stc-plugin-monitor-app.h"
22 #include "stc-plugin-monitor-rstn.h"
23 #include "stc-plugin-monitor-proc.h"
24 #include "stc-plugin-monitor-ipt.h"
25 #include "table-statistics.h"
26 #include "helper-net-cls.h"
27 #include "stc-manager-plugin-tether.h"
29 static void __print_app(gpointer key, gpointer value,
32 stc_app_value_s *app_value = (stc_app_value_s *)value;
34 STC_LOGD("PkgID[%s] AppID[\033[0;32m%s\033[0;m] "
35 "type[%d] state[%d] classid[\033[1;36m%d\033[0;m] "
36 "counter[in(%lld) out(%lld)]",
37 app_value->pkg_id, app_value->app_id,
38 app_value->type, app_value->state,
40 app_value->data_usage.in_bytes,
41 app_value->data_usage.out_bytes);
44 static void __app_update_statistics(gpointer key,
45 gpointer value, gpointer data)
47 stc_app_value_s *app_value = (stc_app_value_s *)value;
48 time_t *touch_time = (time_t *)data;
49 GSList *conn_list = stc_get_connection_list();
51 for (; conn_list != NULL; conn_list = conn_list->next) {
52 stc_connection_s *conn = conn_list->data;
53 stc_db_classid_iftype_key stat_key;
54 stc_db_app_stats stat;
56 memset(&stat_key, 0, sizeof(stc_db_classid_iftype_key));
57 memset(&stat, 0 , sizeof(stc_db_app_stats));
62 /* Do not update statistics for Tethering
63 * if tethering is in-active found */
64 if (conn && conn->tether_state == FALSE &&
65 !strcmp(app_value->app_id, STC_TOTAL_TETHERING))
68 /* Do not update statistics for Wi-Fi
69 * if tethering is active on wlan0 iface */
70 if (conn && conn->tether_state &&
71 conn->tether_iface.type == STC_IFACE_WIFI &&
72 !strcmp(app_value->app_id, STC_TOTAL_WIFI))
75 stat_key.classid = app_value->classid;
77 if (app_value->classid == STC_TETHERING_APP_CLASSID &&
78 conn->tether_state == TRUE)
79 stat_key.iftype = conn->tether_iface.type;
80 else if (g_str_has_suffix(app_value->app_id, STC_TETHERING_APP_SUFFIX))
81 stat_key.iftype = conn->tether_iface.type;
83 stat_key.iftype = conn->type;
85 if (STC_IFACE_DATACALL == stat_key.iftype)
86 stat_key.subscriber_id = g_strdup(conn->subscriber_id);
88 stat_key.subscriber_id = g_strdup(SUBSCRIBERID_NONE);
90 if (app_value->classid == STC_TETHERING_APP_CLASSID &&
91 conn->tether_state == TRUE)
92 g_strlcpy(stat_key.ifname, conn->tether_iface.ifname,
94 else if (g_str_has_suffix(app_value->app_id, STC_TETHERING_APP_SUFFIX))
95 g_strlcpy(stat_key.ifname, conn->tether_iface.ifname,
98 g_strlcpy(stat_key.ifname, conn->ifname,
101 stat.app_id = g_strdup(app_value->app_id);
102 stat.snd_count = app_value->counter.out_bytes;
103 stat.rcv_count = app_value->counter.in_bytes;
104 stat.is_roaming = (conn->roaming == TRUE) ? STC_ROAMING_ENABLE : STC_ROAMING_DISABLE;
106 if (strstr(stat.app_id, "_BACKGROUND")) {
107 stat.ground = STC_APP_STATE_BACKGROUND;
109 if (strstr(stat.app_id, "TOTAL_"))
110 stat.ground = STC_APP_STATE_UNKNOWN;
112 stat.ground = STC_APP_STATE_FOREGROUND;
115 table_statistics_insert(&stat_key, &stat, *touch_time);
117 app_value->counter.out_bytes = 0;
118 app_value->counter.in_bytes = 0;
121 FREE(stat_key.subscriber_id);
127 static gboolean __add_app_monitor_for_tethering(gpointer key,
128 gpointer value, gpointer data)
130 stc_app_value_s *app_value = (stc_app_value_s *)value;
131 stc_connection_s *connection = (stc_connection_s *)data;
132 stc_s *stc = stc_get_manager();
133 struct nfacct_rule counter;
137 STC_LOGI("Add appid(%s) classid(%d)", app_value->app_id,
140 if (stc == NULL || connection == NULL)
144 stc->carg = MALLOC0(counter_arg_s, 1);
145 if (stc->carg == NULL)
148 stc->carg->sock = stc_monitor_get_contr_sock();
151 memset(&counter, 0, sizeof(struct nfacct_rule));
153 counter.carg = stc->carg;
154 counter.classid = app_value->classid;
155 counter.intend = NFACCT_TETH_COUNTER;
157 if (connection->tether_state != TRUE ||
158 connection->tether_iface.ifname == NULL)
161 counter.iftype = connection->tether_iface.type;
162 g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
164 /* get the ip address of the station based on its mac address */
165 ret = stc_plugin_tether_get_station_ip(app_value->mac, &ipaddr);
166 if (ret != STC_ERROR_NONE)
169 /* tethering iptables rule */
170 stc_monitor_tether_add_in(&counter, ipaddr);
171 stc_monitor_tether_add_out(&counter, ipaddr);
177 static gboolean __remove_app_monitor_for_tethering(gpointer key,
178 gpointer value, gpointer data)
180 stc_app_value_s *app_value = (stc_app_value_s *)value;
181 stc_connection_s *connection = (stc_connection_s *)data;
182 stc_s *stc = stc_get_manager();
183 struct nfacct_rule counter;
187 STC_LOGI("Remove appid(%s) classid(%d)", app_value->app_id,
190 if (stc == NULL || connection == NULL)
194 stc->carg = MALLOC0(counter_arg_s, 1);
195 if (stc->carg == NULL)
198 stc->carg->sock = stc_monitor_get_contr_sock();
201 memset(&counter, 0, sizeof(struct nfacct_rule));
203 counter.carg = stc->carg;
204 counter.classid = app_value->classid;
205 counter.intend = NFACCT_TETH_COUNTER;
207 if (connection->tether_state != TRUE ||
208 connection->tether_iface.ifname == NULL)
211 counter.iftype = connection->tether_iface.type;
212 g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
214 /* get the ip address of the station based on its mac address */
215 ret = stc_plugin_tether_get_station_ip(app_value->mac, &ipaddr);
216 if (ret != STC_ERROR_NONE)
219 stc_monitor_tether_del_in(&counter, ipaddr);
220 stc_monitor_tether_del_out(&counter, ipaddr);
226 static void __app_value_destroy(gpointer data)
228 stc_app_value_s *app_value = (stc_app_value_s *)data;
230 FREE(app_value->pkg_id);
231 FREE(app_value->app_id);
232 g_hash_table_destroy(app_value->processes);
233 app_value->processes = NULL;
238 static void __check_rstn_limit_exceeded(gpointer data,
241 stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
242 int32_t *limit_exceeded = (int32_t *)user_data;
244 if (rstn_data->limit_exceeded != 0)
245 *limit_exceeded = rstn_data->limit_exceeded;
248 static void __app_update_counter(classid_bytes_context_s *context,
251 stc_app_value_s *lookup_app;
252 stc_rstn_value_s *lookup_rstn;
253 GHashTable *apps = stc_monitor_get_system_apps();
254 GHashTable *rstns = stc_monitor_get_system_rstns();
259 lookup_app = g_hash_table_lookup(apps, GUINT_TO_POINTER(classid));
261 stc_monitor_app_update_counter(lookup_app, context);
266 lookup_rstn = g_hash_table_lookup(rstns, GUINT_TO_POINTER(classid));
268 int32_t limit_exceeded = 0;
269 g_slist_foreach(lookup_rstn->rules,
270 __check_rstn_limit_exceeded, &limit_exceeded);
272 if (limit_exceeded != 0)
277 API stc_error_e stc_plugin_monitor_app_add(uint32_t classid,
280 const stc_app_value_s value)
282 stc_app_value_s *app_value;
283 stc_app_value_s *lookup_value;
285 GHashTable *apps = stc_monitor_get_system_apps();
286 GSList *conn_list = stc_get_connection_list();
289 return STC_ERROR_NO_DATA;
291 if (classid == STC_UNKNOWN_CLASSID)
292 classid = get_classid_by_app_id(app_id, TRUE);
294 lookup_value = g_hash_table_lookup(apps, GUINT_TO_POINTER(classid));
297 STC_LOGE("Already exists [\033[1;36m%d\033[0;m:"
298 "\033[0;32m%s\033[0;m]", classid, app_id);
299 return STC_ERROR_NONE;
302 app_value = MALLOC0(stc_app_value_s, 1);
305 STC_LOGE("Value allocation failed");
306 return STC_ERROR_OUT_OF_MEMORY;
309 /* create cgroup and update classid */
310 app_value->classid = classid;
312 app_value->app_id = g_strdup(app_id);
313 app_value->pkg_id = g_strdup(pkg_id);
315 app_value->type = value.type;
316 app_value->state = value.state;
317 app_value->data_usage.in_bytes = value.data_usage.in_bytes;
318 app_value->data_usage.out_bytes = value.data_usage.out_bytes;
319 g_strlcpy(app_value->mac, value.mac, MAC_ADDRESS_LEN);
321 app_value->processes = g_hash_table_new_full(g_direct_hash,
322 g_direct_equal, NULL, NULL);
324 /* update classid for tethering station based on its mac address */
325 if (g_str_has_suffix(app_id, STC_TETHERING_APP_SUFFIX) &&
326 classid != STC_TETHERING_APP_CLASSID)
327 stc_plugin_tether_set_station_classid(app_value->mac, classid);
329 g_hash_table_insert(apps, GUINT_TO_POINTER(classid), app_value);
331 for (; conn_list != NULL; conn_list = conn_list->next) {
332 stc_connection_s *conn = conn_list->data;
333 /* add nfacct rule for this classid */
334 stc_monitor_app_add_monitor(GUINT_TO_POINTER(classid),
337 if (app_value->state == STC_APP_STATE_FOREGROUND)
338 stc_monitor_app_add_accept(GUINT_TO_POINTER(classid),
342 stc_monitor_rstn_add_for_app(classid);
345 __print_app(GUINT_TO_POINTER(classid), app_value, NULL);
346 STC_LOGD("\033[1;32mApplication added\033[0;m "
347 "[\033[1;36m%d\033[0;m]", classid);
350 return STC_ERROR_NONE;
353 API stc_error_e stc_plugin_monitor_app_remove(uint32_t classid,
356 stc_app_value_s *app_lookup;
357 GHashTable *apps = stc_monitor_get_system_apps();
358 GSList *conn_list = stc_get_connection_list();
361 return STC_ERROR_NO_DATA;
363 classid = get_classid_by_app_id(app_id, FALSE);
365 app_lookup = g_hash_table_lookup(apps, GUINT_TO_POINTER(classid));
368 STC_LOGD("Application not found [\033[1;36m%d\033[0;m]", classid);
369 return STC_ERROR_FAIL;
372 for (; conn_list != NULL; conn_list = conn_list->next) {
373 stc_connection_s *conn = conn_list->data;
374 /* remove nfacct rule for this classid */
375 stc_monitor_app_remove_monitor(GUINT_TO_POINTER(classid),
378 if (app_lookup->state == STC_APP_STATE_FOREGROUND)
379 stc_monitor_app_remove_accept(GUINT_TO_POINTER(classid),
383 /* remove ristrictions if any */
384 stc_monitor_rstn_remove_for_app(classid);
387 __print_app(GUINT_TO_POINTER(classid), app_lookup, NULL);
389 /* remove app_key from the stc-manager */
390 g_hash_table_remove(apps, GUINT_TO_POINTER(classid));
392 return STC_ERROR_NONE;
395 API gboolean stc_plugin_monitor_app_lookup(uint32_t classid)
397 stc_app_value_s *lookup_value;
399 GHashTable *apps = stc_monitor_get_system_apps();
404 if (classid == STC_UNKNOWN_CLASSID)
407 lookup_value = g_hash_table_lookup(apps, GUINT_TO_POINTER(classid));
414 void stc_monitor_app_update_counter(stc_app_value_s *value,
415 classid_bytes_context_s *context)
417 switch (context->counter->iotype) {
418 case NFACCT_COUNTER_IN:
419 value->data_usage.in_bytes += context->bytes;
420 value->counter.in_bytes = context->bytes;
421 stc_monitor_set_apps_updated(TRUE);
424 case NFACCT_COUNTER_OUT:
425 value->data_usage.out_bytes += context->bytes;
426 value->counter.out_bytes = context->bytes;
427 stc_monitor_set_apps_updated(TRUE);
431 STC_LOGE("Unknown iotype");
435 void stc_monitor_app_update_iface_counter(classid_bytes_context_s *context)
437 switch (context->counter->iftype) {
438 case STC_IFACE_DATACALL:
439 __app_update_counter(context, STC_TOTAL_DATACALL_CLASSID);
442 __app_update_counter(context, STC_TOTAL_WIFI_CLASSID);
443 __app_update_counter(context, STC_TETHERING_APP_CLASSID);
445 case STC_IFACE_BLUETOOTH:
446 __app_update_counter(context, STC_TOTAL_BLUETOOTH_CLASSID);
447 __app_update_counter(context, STC_TETHERING_APP_CLASSID);
450 __app_update_counter(context, STC_TETHERING_APP_CLASSID);
453 __app_update_counter(context, STC_TETHERING_APP_CLASSID);
460 gboolean stc_monitor_app_flush_stats_to_db(gpointer user_data)
462 time_t current_time = 0;
463 stc_s *stc = stc_get_manager();
464 GHashTable *apps = stc_monitor_get_system_apps();
465 gboolean apps_updated = stc_monitor_get_apps_updated();
467 if (stc && stc->carg)
468 current_time = stc->carg->last_run_time;
470 if (apps_updated == FALSE)
471 return G_SOURCE_REMOVE;
473 stc_monitor_set_apps_updated(FALSE);
476 g_hash_table_foreach(apps,
477 __app_update_statistics,
480 STC_LOGI("Flushed app stats to database");
481 return G_SOURCE_REMOVE;
484 void stc_monitor_app_add_by_iface(const char *ifname)
486 stc_app_value_s app_value;
491 memset(&app_value, 0, sizeof(stc_app_value_s));
493 app_value.type = STC_APP_TYPE_NONE;
494 app_value.processes = NULL;
495 app_value.counter.in_bytes = 0;
496 app_value.counter.out_bytes = 0;
498 stc_plugin_monitor_app_add(STC_UNKNOWN_CLASSID, ifname, ifname, app_value);
501 void stc_monitor_app_add_monitor(gpointer key,
502 gpointer value, gpointer data)
504 stc_app_value_s *app_value = (stc_app_value_s *)value;
505 stc_connection_s *connection = (stc_connection_s *)data;
506 stc_s *stc = stc_get_manager();
508 if (app_value->classid == STC_TOTAL_DATACALL_CLASSID ||
509 app_value->classid == STC_TOTAL_WIFI_CLASSID ||
510 app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID)
513 if (stc && connection && connection->ifname) {
514 struct nfacct_rule counter;
517 stc->carg = MALLOC0(counter_arg_s, 1);
518 if (stc->carg == NULL)
521 stc->carg->sock = stc_monitor_get_contr_sock();
524 memset(&counter, 0, sizeof(struct nfacct_rule));
526 counter.carg = stc->carg;
527 counter.classid = app_value->classid;
528 counter.app_state = app_value->state;
529 counter.intend = NFACCT_COUNTER;
531 if (connection->tether_state == TRUE &&
532 connection->tether_iface.ifname != NULL &&
533 app_value->classid == STC_TETHERING_APP_CLASSID) {
534 counter.iftype = connection->tether_iface.type;
535 g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
537 counter.iftype = connection->type;
538 g_strlcpy(counter.ifname, connection->ifname, MAX_IFACE_LENGTH);
541 if (g_str_has_suffix(app_value->app_id, STC_TETHERING_APP_SUFFIX) &&
542 app_value->classid != STC_TETHERING_APP_CLASSID) {
543 __add_app_monitor_for_tethering(key, value, data);
544 } else if (app_value->classid == STC_TOTAL_IPV4_CLASSID) {
545 stc_monitor_ipt_add_in(&counter);
546 stc_monitor_ipt_add_out(&counter);
547 } else if (app_value->classid == STC_TOTAL_IPV6_CLASSID) {
548 stc_monitor_ip6t_add_in(&counter);
549 stc_monitor_ip6t_add_out(&counter);
551 stc_monitor_ipt_add_in(&counter);
552 stc_monitor_ipt_add_out(&counter);
553 stc_monitor_ip6t_add_in(&counter);
554 stc_monitor_ip6t_add_out(&counter);
560 GSList *counter_v4_list;
561 GSList *counter_v6_list;
562 stc_connection_s *connection;
563 nfacct_rule_action action;
564 nfacct_rule_intend intend;
567 static void __make_counter(stc_app_value_s *app_value,
568 nfacct_rule_direction iotype, nfacct_rule_iptype iptype,
569 counter_list_data *list_data)
571 stc_s *stc = stc_get_manager();
572 struct nfacct_rule *counter;
574 if (!stc || !list_data->connection || !list_data->connection->ifname)
578 stc->carg = MALLOC0(counter_arg_s, 1);
579 if (stc->carg == NULL)
582 stc->carg->sock = stc_monitor_get_contr_sock();
585 counter = MALLOC0(struct nfacct_rule, 1);
589 counter->carg = stc->carg;
590 counter->classid = app_value->classid;
591 counter->app_state = app_value->state;
592 counter->intend = list_data->intend;
593 counter->action = list_data->action;
594 counter->iotype = iotype;
595 counter->iftype = list_data->connection->type;
596 g_strlcpy(counter->ifname, list_data->connection->ifname, MAX_IFACE_LENGTH);
597 switch (counter->intend) {
599 case NFACCT_TETH_BLOCK:
600 counter->jump = NFACCT_JUMP_REJECT;
604 case NFACCT_TETH_ALLOW:
605 counter->jump = NFACCT_JUMP_ACCEPT;
608 counter->jump = NFACCT_JUMP_UNKNOWN;
610 counter->send_limit = 0;
611 counter->rcv_limit = 0;
613 if (iptype == NFACCT_TYPE_IPV4)
614 list_data->counter_v4_list = g_slist_append(list_data->counter_v4_list, counter);
616 list_data->counter_v6_list = g_slist_append(list_data->counter_v6_list, counter);
619 static void __make_counter_list(stc_app_value_s *app_value, counter_list_data *list_data)
621 switch (app_value->classid) {
622 case STC_TOTAL_IPV4_CLASSID:
623 __make_counter(app_value, NFACCT_COUNTER_IN, NFACCT_TYPE_IPV4, list_data);
624 __make_counter(app_value, NFACCT_COUNTER_OUT, NFACCT_TYPE_IPV4, list_data);
626 case STC_TOTAL_IPV6_CLASSID:
627 __make_counter(app_value, NFACCT_COUNTER_IN, NFACCT_TYPE_IPV6, list_data);
628 __make_counter(app_value, NFACCT_COUNTER_OUT, NFACCT_TYPE_IPV6, list_data);
631 __make_counter(app_value, NFACCT_COUNTER_IN, NFACCT_TYPE_IPV4, list_data);
632 __make_counter(app_value, NFACCT_COUNTER_OUT, NFACCT_TYPE_IPV4, list_data);
633 __make_counter(app_value, NFACCT_COUNTER_IN, NFACCT_TYPE_IPV6, list_data);
634 __make_counter(app_value, NFACCT_COUNTER_OUT, NFACCT_TYPE_IPV6, list_data);
638 static void __foreach_app_table(gpointer key, gpointer value, gpointer data)
640 stc_app_value_s *app_value = (stc_app_value_s *)value;
641 counter_list_data *list_data = (counter_list_data *)data;
643 if (app_value->classid == STC_TOTAL_DATACALL_CLASSID ||
644 app_value->classid == STC_TOTAL_WIFI_CLASSID ||
645 app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID)
648 list_data->intend = NFACCT_COUNTER;
649 __make_counter_list(app_value, list_data);
651 if (app_value->state == STC_APP_STATE_FOREGROUND) {
652 list_data->intend = NFACCT_ALLOW;
653 __make_counter_list(app_value, list_data);
657 void stc_monitor_app_add_by_connection(stc_connection_s *conn)
659 GHashTable *apps = stc_monitor_get_system_apps();
660 counter_list_data list_data = { 0, };
661 struct timespec start, end;
668 list_data.connection = conn;
669 list_data.action = NFACCT_ACTION_INSERT;
671 g_hash_table_foreach(apps, __foreach_app_table, &list_data);
673 clock_gettime(CLOCK_MONOTONIC, &start);
675 stc_monitor_ipt_add_list(list_data.counter_v4_list, NFACCT_TYPE_IPV4);
676 stc_monitor_ipt_add_list(list_data.counter_v6_list, NFACCT_TYPE_IPV6);
678 g_slist_free_full(list_data.counter_v4_list, g_free);
679 g_slist_free_full(list_data.counter_v6_list, g_free);
681 clock_gettime(CLOCK_MONOTONIC, &end);
683 sec = end.tv_sec - start.tv_sec;
684 nsec = end.tv_nsec - start.tv_nsec;
687 STC_LOGD("Added by [%s] connection [%3ld.%09ld]s", conn->ifname, sec, nsec);
690 void stc_monitor_app_add_accept(gpointer key,
691 gpointer value, gpointer data)
693 stc_app_value_s *app_value = (stc_app_value_s *)value;
694 stc_connection_s *connection = (stc_connection_s *)data;
695 stc_s *stc = stc_get_manager();
697 if (app_value->classid == STC_TOTAL_DATACALL_CLASSID ||
698 app_value->classid == STC_TOTAL_WIFI_CLASSID ||
699 app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID)
702 if (app_value->state != STC_APP_STATE_FOREGROUND)
705 if (stc && connection && connection->ifname) {
706 struct nfacct_rule counter;
709 stc->carg = MALLOC0(counter_arg_s, 1);
710 if (stc->carg == NULL)
713 stc->carg->sock = stc_monitor_get_contr_sock();
716 memset(&counter, 0, sizeof(struct nfacct_rule));
718 counter.carg = stc->carg;
719 counter.classid = app_value->classid;
720 counter.app_state = app_value->state;
721 counter.intend = NFACCT_ALLOW;
723 counter.iftype = connection->type;
724 g_strlcpy(counter.ifname, connection->ifname, MAX_IFACE_LENGTH);
726 if (app_value->classid == STC_TOTAL_IPV4_CLASSID) {
727 stc_monitor_ipt_add_in(&counter);
728 stc_monitor_ipt_add_out(&counter);
729 } else if (app_value->classid == STC_TOTAL_IPV6_CLASSID) {
730 stc_monitor_ip6t_add_in(&counter);
731 stc_monitor_ip6t_add_out(&counter);
733 stc_monitor_ipt_add_in(&counter);
734 stc_monitor_ipt_add_out(&counter);
735 stc_monitor_ip6t_add_in(&counter);
736 stc_monitor_ip6t_add_out(&counter);
741 void stc_monitor_app_remove_monitor(gpointer key,
742 gpointer value, gpointer data)
744 stc_app_value_s *app_value = (stc_app_value_s *)value;
745 stc_connection_s *connection = (stc_connection_s *)data;
746 stc_s *stc = stc_get_manager();
748 if (stc && connection && connection->ifname) {
749 struct nfacct_rule counter;
752 stc->carg = MALLOC0(counter_arg_s, 1);
753 if (stc->carg == NULL)
756 stc->carg->sock = stc_monitor_get_contr_sock();
759 memset(&counter, 0, sizeof(struct nfacct_rule));
761 counter.carg = stc->carg;
762 counter.classid = app_value->classid;
763 counter.app_state = app_value->state;
764 counter.intend = NFACCT_COUNTER;
766 if (g_str_has_suffix(app_value->app_id, STC_TETHERING_APP_SUFFIX) &&
767 app_value->classid != STC_TETHERING_APP_CLASSID) {
768 __remove_app_monitor_for_tethering(key, value, data);
770 } else if (connection->tether_state == FALSE &&
771 connection->tether_iface.ifname != NULL &&
772 app_value->classid == STC_TETHERING_APP_CLASSID) {
773 counter.iftype = connection->tether_iface.type;
774 g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
776 counter.iftype = connection->type;
777 g_strlcpy(counter.ifname, connection->ifname, MAX_IFACE_LENGTH);
780 if (app_value->classid == STC_TOTAL_IPV4_CLASSID) {
781 stc_monitor_ipt_del_in(&counter);
782 stc_monitor_ipt_del_out(&counter);
783 } else if (app_value->classid == STC_TOTAL_IPV6_CLASSID) {
784 stc_monitor_ip6t_del_in(&counter);
785 stc_monitor_ip6t_del_out(&counter);
787 stc_monitor_ipt_del_in(&counter);
788 stc_monitor_ipt_del_out(&counter);
789 stc_monitor_ip6t_del_in(&counter);
790 stc_monitor_ip6t_del_out(&counter);
797 void stc_monitor_app_remove_by_connection(stc_connection_s *conn)
799 GHashTable *apps = stc_monitor_get_system_apps();
800 counter_list_data list_data = { 0, };
801 struct timespec start, end;
808 list_data.connection = conn;
809 list_data.action = NFACCT_ACTION_DELETE;
811 g_hash_table_foreach(apps, __foreach_app_table, &list_data);
813 clock_gettime(CLOCK_MONOTONIC, &start);
815 stc_monitor_ipt_del_list(list_data.counter_v4_list, NFACCT_TYPE_IPV4);
816 stc_monitor_ipt_del_list(list_data.counter_v6_list, NFACCT_TYPE_IPV6);
818 g_slist_free_full(list_data.counter_v4_list, g_free);
819 g_slist_free_full(list_data.counter_v6_list, g_free);
821 clock_gettime(CLOCK_MONOTONIC, &end);
823 sec = end.tv_sec - start.tv_sec;
824 nsec = end.tv_nsec - start.tv_nsec;
827 STC_LOGD("Removed by [%s] connection [%3ld.%09ld]s", conn->ifname, sec, nsec);
830 void stc_monitor_app_remove_accept(gpointer key,
831 gpointer value, gpointer data)
833 stc_app_value_s *app_value = (stc_app_value_s *)value;
834 stc_connection_s *connection = (stc_connection_s *)data;
835 stc_s *stc = stc_get_manager();
837 if (app_value->classid == STC_TOTAL_DATACALL_CLASSID ||
838 app_value->classid == STC_TOTAL_WIFI_CLASSID ||
839 app_value->classid == STC_TOTAL_BLUETOOTH_CLASSID)
842 if (app_value->state != STC_APP_STATE_FOREGROUND)
845 if (stc && connection && connection->ifname) {
846 struct nfacct_rule counter;
849 stc->carg = MALLOC0(counter_arg_s, 1);
850 if (stc->carg == NULL)
853 stc->carg->sock = stc_monitor_get_contr_sock();
856 memset(&counter, 0, sizeof(struct nfacct_rule));
858 counter.carg = stc->carg;
859 counter.classid = app_value->classid;
860 counter.app_state = app_value->state;
861 counter.intend = NFACCT_ALLOW;
863 counter.iftype = connection->type;
864 g_strlcpy(counter.ifname, connection->ifname, MAX_IFACE_LENGTH);
866 if (app_value->classid == STC_TOTAL_IPV4_CLASSID) {
867 stc_monitor_ipt_del_in(&counter);
868 stc_monitor_ipt_del_out(&counter);
869 } else if (app_value->classid == STC_TOTAL_IPV6_CLASSID) {
870 stc_monitor_ip6t_del_in(&counter);
871 stc_monitor_ip6t_del_out(&counter);
873 stc_monitor_ipt_del_in(&counter);
874 stc_monitor_ipt_del_out(&counter);
875 stc_monitor_ip6t_del_in(&counter);
876 stc_monitor_ip6t_del_out(&counter);
883 GHashTable *stc_monitor_apps_init(void)
885 return g_hash_table_new_full(g_direct_hash, g_direct_equal,
886 NULL, __app_value_destroy);