Check insert option when iptables commit
[platform/core/connectivity/stc-manager.git] / src / monitor / stc-monitor-proc.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "stc-monitor.h"
18 #include "stc-monitor-proc.h"
19 #include "stc-default-connection.h"
20 #include "helper-net-cls.h"
21
22 static void __print_proc(gpointer key, gpointer value,
23                                 gpointer data)
24 {
25         stc_proc_value_s *proc_value = (stc_proc_value_s *)value;
26
27         STC_LOGD("pid[\033[1;33m%d\033[0;m] ground[%d]",
28                  proc_value->pid, proc_value->ground);
29 }
30
31 static void __print_proc_all(GHashTable *procs)
32 {
33         g_hash_table_foreach(procs, __print_proc, NULL);
34 }
35
36 static void __proc_remove_pid(gpointer key, gpointer value,
37                                 gpointer data)
38 {
39         stc_app_value_s *app_value = (stc_app_value_s *)value;
40         remove_pid_context_s *context = (remove_pid_context_s *)data;
41
42         if (!g_hash_table_remove(app_value->processes, GUINT_TO_POINTER(context->pid)))
43                 return;
44
45         if (STC_DEBUG_LOG) {
46                 __print_proc_all(app_value->processes);
47                 STC_LOGD("\033[1;31mProcess removed\033[0;m "
48                         "[\033[1;33m%d\033[0;m]", context->pid);
49         }
50
51         context->entry_removed = TRUE;
52         context->app_value = app_value;
53 }
54
55 API stc_error_e stc_monitor_proc_update_ground(uint32_t classid,
56                                                 const char *app_id,
57                                                 const stc_proc_value_s value)
58 {
59         stc_error_e ret = STC_ERROR_NONE;
60         stc_app_value_s *app_lookup;
61         stc_proc_value_s *proc_lookup;
62         GHashTable *apps = stc_monitor_get_system_apps();
63
64         if (!apps)
65                 return STC_ERROR_NO_DATA;
66
67         if (classid == STC_UNKNOWN_CLASSID)
68                 classid = get_classid_by_app_id(app_id, TRUE);
69
70         app_lookup = g_hash_table_lookup(apps, GUINT_TO_POINTER(classid));
71         if (!app_lookup) {
72                 if (STC_DEBUG_LOG)
73                         STC_LOGD("Application not found [\033[1;36m%d\033[0;m]", classid);
74                 return STC_ERROR_NO_DATA;
75         }
76
77         proc_lookup = g_hash_table_lookup(app_lookup->processes,
78                                         GUINT_TO_POINTER(value.pid));
79         if (!proc_lookup) {
80                 if (STC_DEBUG_LOG)
81                         STC_LOGD("Process not found [\033[1;33m%d\033[0;m]", value.pid);
82                 return STC_ERROR_NO_DATA;
83         }
84
85         if (proc_lookup->ground != value.ground)
86                 proc_lookup->ground = value.ground;
87
88         place_pids_to_net_cgroup(value.pid, app_id);
89
90         return ret;
91 }
92
93 API stc_error_e stc_monitor_proc_add(uint32_t classid,
94                                         const char *app_id,
95                                         const stc_proc_value_s value)
96 {
97         stc_error_e ret = STC_ERROR_NONE;
98         stc_app_value_s *app_lookup;
99         stc_proc_value_s *proc_lookup;
100         stc_proc_value_s *proc_value;
101         GHashTable *apps = stc_monitor_get_system_apps();
102
103         if (!apps)
104                 return STC_ERROR_NO_DATA;
105
106         if (classid == STC_UNKNOWN_CLASSID)
107                 classid = get_classid_by_app_id(app_id, TRUE);
108
109         app_lookup = g_hash_table_lookup(apps, GUINT_TO_POINTER(classid));
110         if (!app_lookup) {
111                 if (STC_DEBUG_LOG)
112                         STC_LOGD("Application not found [\033[1;36m%d\033[0;m]", classid);
113                 return STC_ERROR_NO_DATA;
114         }
115
116         proc_lookup = g_hash_table_lookup(app_lookup->processes,
117                                         GUINT_TO_POINTER(value.pid));
118         if (proc_lookup) {
119                 if (STC_DEBUG_LOG)
120                         STC_LOGE("Already exists [\033[1;36m%d\033[0;m]", value.pid);
121                 return STC_ERROR_NONE;
122         }
123
124         proc_value = MALLOC0(stc_proc_value_s, 1);
125         if (!proc_value) {
126                 if (STC_DEBUG_LOG)
127                         STC_LOGE("Value allocation failed");
128                 return STC_ERROR_OUT_OF_MEMORY;
129         }
130
131         proc_value->pid = value.pid;
132         proc_value->ground = value.ground;
133
134         g_hash_table_insert(app_lookup->processes,
135                         GUINT_TO_POINTER(proc_value->pid),
136                         proc_value);
137
138         /* add pid to application cgroup */
139         place_pids_to_net_cgroup(proc_value->pid, app_id);
140
141         if (STC_DEBUG_LOG) {
142                 __print_proc_all(app_lookup->processes);
143                 STC_LOGD("\033[1;32mProcess added\033[0;m "
144                         "[\033[1;33m%d\033[0;m]", proc_value->pid);
145         }
146
147         return ret;
148 }
149
150 API stc_error_e stc_monitor_proc_remove(uint32_t classid,
151                                                 pid_t pid)
152 {
153         stc_error_e ret = STC_ERROR_NONE;
154         stc_app_value_s *app_lookup = NULL;
155         guint pid_count = 0;
156         GHashTable *apps = stc_monitor_get_system_apps();
157         remove_pid_context_s context = {
158                 .pid = pid,
159                 .app_value = NULL,
160                 .entry_removed = FALSE,
161         };
162
163         if (!apps)
164                 return STC_ERROR_NO_DATA;
165
166         if (classid == STC_UNKNOWN_CLASSID) {
167                 g_hash_table_foreach(apps, __proc_remove_pid, &context);
168
169                 if (context.entry_removed)
170                         app_lookup = context.app_value;
171
172                 if (!app_lookup) {
173                         if (STC_DEBUG_LOG)
174                                 STC_LOGD("Process not found [\033[1;33m%d\033[0;m]", pid);
175                         return STC_ERROR_NO_DATA;
176                 }
177         } else {
178                 app_lookup = g_hash_table_lookup(apps, GUINT_TO_POINTER(classid));
179                 if (!app_lookup) {
180                         if (STC_DEBUG_LOG)
181                                 STC_LOGD("Application not found [\033[1;36m%d\033[0;m]",
182                                                         classid);
183                         return STC_ERROR_NO_DATA;
184                 }
185
186                 if (g_hash_table_remove(app_lookup->processes, GUINT_TO_POINTER(pid))) {
187                         if (STC_DEBUG_LOG) {
188                                 __print_proc_all(app_lookup->processes);
189                                 STC_LOGD("\033[1;31mProcess removed\033[0;m "
190                                         "[\033[1;33m%d\033[0;m]", pid);
191                         }
192                 } else {
193                         STC_LOGD("Process not found [\033[1;33m%d\033[0;m]", pid);
194                 }
195         }
196
197         pid_count = g_hash_table_size(app_lookup->processes);
198
199         if (!pid_count) {
200                 /* remove nfacct rule for this classid */
201                 stc_monitor_app_remove_monitor(GUINT_TO_POINTER(classid),
202                                         app_lookup, stc_get_default_connection());
203                 stc_monitor_rstn_remove_for_app(classid);
204
205                 g_hash_table_remove(apps, GUINT_TO_POINTER(classid));
206
207                 if (STC_DEBUG_LOG)
208                         STC_LOGD("\033[1;31mApplication removed\033[0;m "
209                                 "[\033[1;36m%d\033[0;m]", classid);
210         }
211
212         return ret;
213 }