Refactoring structures for monitoring and restrictions
[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         guint pid_count = 0;
42
43         if (!g_hash_table_remove(app_value->processes, GUINT_TO_POINTER(context->pid)))
44                 return;
45
46         if (STC_DEBUG_LOG) {
47                 __print_proc_all(app_value->processes);
48                 STC_LOGD("\033[1;31mProcess removed\033[0;m "
49                         "[\033[1;33m%d\033[0;m]", context->pid);
50         }
51
52         context->entry_removed = TRUE;
53         context->app_value = app_value;
54 }
55
56 API stc_error_e stc_monitor_proc_update_ground(uint32_t classid,
57                                                 const char *app_id,
58                                                 const stc_proc_value_s value)
59 {
60         stc_error_e ret = STC_ERROR_NONE;
61         stc_app_value_s *app_lookup;
62         stc_proc_value_s *proc_lookup;
63         GHashTable *apps = stc_monitor_get_system_apps();
64
65         if (!apps)
66                 return STC_ERROR_NO_DATA;
67
68         if (classid == STC_UNKNOWN_CLASSID)
69                 classid = get_classid_by_app_id(app_id, TRUE);
70
71         app_lookup = g_hash_table_lookup(apps, GUINT_TO_POINTER(classid));
72         if (!app_lookup) {
73                 if (STC_DEBUG_LOG)
74                         STC_LOGD("Application not found [\033[1;36m%d\033[0;m]", classid);
75                 return STC_ERROR_NO_DATA;
76         }
77
78         proc_lookup = g_hash_table_lookup(app_lookup->processes,
79                                         GUINT_TO_POINTER(value.pid));
80         if (!proc_lookup) {
81                 if (STC_DEBUG_LOG)
82                         STC_LOGD("Process not found [\033[1;33m%d\033[0;m]", value.pid);
83                 return STC_ERROR_NO_DATA;
84         }
85
86         if (proc_lookup->ground != value.ground)
87                 proc_lookup->ground = value.ground;
88
89         place_pids_to_net_cgroup(value.pid, app_id);
90
91         return ret;
92 }
93
94 API stc_error_e stc_monitor_proc_add(uint32_t classid,
95                                         const char *app_id,
96                                         const stc_proc_value_s value)
97 {
98         stc_error_e ret = STC_ERROR_NONE;
99         stc_app_value_s *app_lookup;
100         stc_proc_value_s *proc_lookup;
101         stc_proc_value_s *proc_value;
102         GHashTable *apps = stc_monitor_get_system_apps();
103
104         if (!apps)
105                 return STC_ERROR_NO_DATA;
106
107         if (classid == STC_UNKNOWN_CLASSID)
108                 classid = get_classid_by_app_id(app_id, TRUE);
109
110         app_lookup = g_hash_table_lookup(apps, GUINT_TO_POINTER(classid));
111         if (!app_lookup) {
112                 if (STC_DEBUG_LOG)
113                         STC_LOGD("Application not found [\033[1;36m%d\033[0;m]", classid);
114                 return STC_ERROR_NO_DATA;
115         }
116
117         proc_lookup = g_hash_table_lookup(app_lookup->processes,
118                                         GUINT_TO_POINTER(value.pid));
119         if (proc_lookup) {
120                 if (STC_DEBUG_LOG)
121                         STC_LOGE("Already exists [\033[1;36m%d\033[0;m]", value.pid);
122                 return STC_ERROR_NONE;
123         }
124
125         proc_value = MALLOC0(stc_proc_value_s, 1);
126         if (!proc_value) {
127                 if (STC_DEBUG_LOG)
128                         STC_LOGE("Value allocation failed");
129                 return STC_ERROR_OUT_OF_MEMORY;
130         }
131
132         proc_value->pid = value.pid;
133         proc_value->ground = value.ground;
134
135         g_hash_table_insert(app_lookup->processes,
136                         GUINT_TO_POINTER(proc_value->pid),
137                         proc_value);
138
139         /* add pid to application cgroup */
140         place_pids_to_net_cgroup(proc_value->pid, app_id);
141
142         if (STC_DEBUG_LOG) {
143                 __print_proc_all(app_lookup->processes);
144                 STC_LOGD("\033[1;32mProcess added\033[0;m "
145                         "[\033[1;33m%d\033[0;m]", proc_value->pid);
146         }
147
148         return ret;
149 }
150
151 API stc_error_e stc_monitor_proc_remove(uint32_t classid,
152                                                 pid_t pid)
153 {
154         stc_error_e ret = STC_ERROR_NONE;
155         stc_app_value_s *app_lookup = NULL;
156         guint pid_count = 0;
157         GHashTable *apps = stc_monitor_get_system_apps();
158         remove_pid_context_s context = {
159                 .pid = pid,
160                 .app_value = NULL,
161                 .entry_removed = FALSE,
162         };
163
164         if (!apps)
165                 return STC_ERROR_NO_DATA;
166
167         if (classid == STC_UNKNOWN_CLASSID) {
168                 g_hash_table_foreach(apps, __proc_remove_pid, &context);
169
170                 if (context.entry_removed)
171                         app_lookup = context.app_value;
172
173                 if (!app_lookup) {
174                         if (STC_DEBUG_LOG)
175                                 STC_LOGD("Process not found [\033[1;33m%d\033[0;m]", pid);
176                         return STC_ERROR_NO_DATA;
177                 }
178         } else {
179                 app_lookup = g_hash_table_lookup(apps, GUINT_TO_POINTER(classid));
180                 if (!app_lookup) {
181                         if (STC_DEBUG_LOG)
182                                 STC_LOGD("Application not found [\033[1;36m%d\033[0;m]",
183                                                         classid);
184                         return STC_ERROR_NO_DATA;
185                 }
186
187                 if (g_hash_table_remove(app_lookup->processes, GUINT_TO_POINTER(pid))) {
188                         if (STC_DEBUG_LOG) {
189                                 __print_proc_all(app_lookup->processes);
190                                 STC_LOGD("\033[1;31mProcess removed\033[0;m "
191                                         "[\033[1;33m%d\033[0;m]", pid);
192                         }
193                 } else {
194                         STC_LOGD("Process not found [\033[1;33m%d\033[0;m]", pid);
195                 }
196         }
197
198         pid_count = g_hash_table_size(app_lookup->processes);
199
200         if (!pid_count) {
201                 /* remove nfacct rule for this classid */
202                 stc_monitor_app_remove_monitor(GUINT_TO_POINTER(classid),
203                                         app_lookup, stc_get_default_connection());
204                 stc_monitor_rstn_remove_for_app(classid);
205
206                 g_hash_table_remove(apps, GUINT_TO_POINTER(classid));
207
208                 if (STC_DEBUG_LOG)
209                         STC_LOGD("\033[1;31mApplication removed\033[0;m "
210                                 "[\033[1;36m%d\033[0;m]", classid);
211         }
212
213         return ret;
214 }