1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "trans_session_manager.h"
17
18 #include "anonymizer.h"
19 #include "lnn_lane_link.h"
20 #include "permission_entry.h"
21 #include "securec.h"
22 #include "softbus_adapter_mem.h"
23 #include "softbus_adapter_thread.h"
24 #include "softbus_def.h"
25 #include "softbus_errcode.h"
26 #include "softbus_utils.h"
27 #include "softbus_hidumper_trans.h"
28 #include "trans_channel_callback.h"
29 #include "trans_client_proxy.h"
30 #include "trans_log.h"
31
32 #define MAX_SESSION_SERVER_NUM 100
33 #define CMD_REGISTED_SESSION_LIST "registed_sessionlist"
34 #define GET_ROUTE_TYPE(type) ((uint32_t)(type) & 0xff)
35 #define GET_CONN_TYPE(type) (((uint32_t)(type) >> 8) & 0xff)
36
37 static SoftBusList *g_sessionServerList = NULL;
38
TransSessionForEachShowInfo(int32_t fd)39 static int32_t TransSessionForEachShowInfo(int32_t fd)
40 {
41 if (g_sessionServerList == NULL) {
42 TRANS_LOGE(TRANS_CTRL, "session server list is empty");
43 return SOFTBUS_NO_INIT;
44 }
45 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
46 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
47 return SOFTBUS_LOCK_ERR;
48 }
49
50 SessionServer *pos = NULL;
51 LIST_FOR_EACH_ENTRY(pos, &g_sessionServerList->list, SessionServer, node) {
52 SoftBusTransDumpRegisterSession(fd, pos->pkgName, pos->sessionName, pos->uid, pos->pid);
53 }
54
55 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
56 return SOFTBUS_OK;
57 }
58
TransSessionMgrInit(void)59 int32_t TransSessionMgrInit(void)
60 {
61 if (g_sessionServerList != NULL) {
62 return SOFTBUS_OK;
63 }
64 g_sessionServerList = CreateSoftBusList();
65 if (g_sessionServerList == NULL) {
66 TRANS_LOGE(TRANS_CTRL, "session manager init fail");
67 return SOFTBUS_MALLOC_ERR;
68 }
69
70 return SoftBusRegTransVarDump(CMD_REGISTED_SESSION_LIST, TransSessionForEachShowInfo);
71 }
72
TransSessionMgrDeinit(void)73 void TransSessionMgrDeinit(void)
74 {
75 if (g_sessionServerList != NULL) {
76 DestroySoftBusList(g_sessionServerList);
77 g_sessionServerList = NULL;
78 }
79 }
80
TransSessionServerIsExist(const char * sessionName)81 bool TransSessionServerIsExist(const char *sessionName)
82 {
83 if (sessionName == NULL) {
84 return false;
85 }
86 if (g_sessionServerList == NULL) {
87 TRANS_LOGE(TRANS_CTRL, "sessionServerList not init");
88 return false;
89 }
90
91 SessionServer *pos = NULL;
92 SessionServer *tmp = NULL;
93 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
94 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
95 return false;
96 }
97
98 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
99 if (strcmp(pos->sessionName, sessionName) == 0) {
100 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
101 return true;
102 }
103 }
104 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
105 char *tmpSessionName = NULL;
106 Anonymize(sessionName, &tmpSessionName);
107 TRANS_LOGE(TRANS_CTRL, "session server not exist, sessionName=%{public}s", AnonymizeWrapper(tmpSessionName));
108 AnonymizeFree(tmpSessionName);
109 return false;
110 }
111
ShowSessionServer(void)112 static void ShowSessionServer(void)
113 {
114 SessionServer *pos = NULL;
115 SessionServer *tmp = NULL;
116 int32_t count = 0;
117 char *tmpName = NULL;
118 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
119 Anonymize(pos->sessionName, &tmpName);
120 TRANS_LOGI(TRANS_CTRL,
121 "session server is exist. count=%{public}d, sessionName=%{public}s", count, tmpName);
122 AnonymizeFree(tmpName);
123 count++;
124 }
125 }
126
TransSessionServerAddItem(SessionServer * newNode)127 int32_t TransSessionServerAddItem(SessionServer *newNode)
128 {
129 TRANS_CHECK_AND_RETURN_RET_LOGE(newNode != NULL, SOFTBUS_INVALID_PARAM, TRANS_CTRL, "param invalid");
130 TRANS_CHECK_AND_RETURN_RET_LOGE(g_sessionServerList != NULL, SOFTBUS_NO_INIT, TRANS_CTRL, "not init");
131 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
132 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
133 return SOFTBUS_LOCK_ERR;
134 }
135 if (g_sessionServerList->cnt >= MAX_SESSION_SERVER_NUM) {
136 (void)ShowSessionServer();
137 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
138 TRANS_LOGE(TRANS_CTRL, "session server num reach max");
139 return SOFTBUS_INVALID_NUM;
140 }
141
142 SessionServer *pos = NULL;
143 SessionServer *tmp = NULL;
144 char *tmpName = NULL;
145 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
146 if (strcmp(pos->sessionName, newNode->sessionName) == 0) {
147 Anonymize(newNode->sessionName, &tmpName);
148 if ((pos->uid == newNode->uid) && (pos->pid == newNode->pid)) {
149 TRANS_LOGI(TRANS_CTRL, "session server is exist, sessionName=%{public}s", AnonymizeWrapper(tmpName));
150 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
151 AnonymizeFree(tmpName);
152 return SOFTBUS_SERVER_NAME_REPEATED;
153 }
154 if (CheckServiceIsRegistered(pos->pkgName, pos->pid) == SOFTBUS_OK) {
155 TRANS_LOGI(TRANS_CTRL,
156 "sessionName=%{public}s has been used by other processes, old Pid=%{public}d, new pid=%{public}d",
157 AnonymizeWrapper(tmpName), pos->pid, newNode->pid);
158 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
159 AnonymizeFree(tmpName);
160 return SOFTBUS_SERVER_NAME_USED;
161 }
162 pos->pid = newNode->pid;
163 TRANS_LOGI(TRANS_CTRL, "sessionName=%{public}s is exist. old pid=%{public}d, new pid=%{public}d",
164 AnonymizeWrapper(tmpName), pos->pid, newNode->pid);
165 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
166 AnonymizeFree(tmpName);
167 SoftBusFree(newNode);
168 return SOFTBUS_OK;
169 }
170 }
171
172 Anonymize(newNode->sessionName, &tmpName);
173 ListAdd(&(g_sessionServerList->list), &(newNode->node));
174 TRANS_LOGI(TRANS_CTRL, "add sessionName=%{public}s", AnonymizeWrapper(tmpName));
175 g_sessionServerList->cnt++;
176 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
177 AnonymizeFree(tmpName);
178 return SOFTBUS_OK;
179 }
180
TransSessionServerDelItem(const char * sessionName)181 int32_t TransSessionServerDelItem(const char *sessionName)
182 {
183 if (sessionName == NULL) {
184 return SOFTBUS_INVALID_PARAM;
185 }
186 if (g_sessionServerList == NULL) {
187 return SOFTBUS_NO_INIT;
188 }
189
190 bool isFind = false;
191 SessionServer *pos = NULL;
192 SessionServer *tmp = NULL;
193 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
194 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
195 return SOFTBUS_LOCK_ERR;
196 }
197 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
198 if (strcmp(pos->sessionName, sessionName) == 0) {
199 isFind = true;
200 break;
201 }
202 }
203 if (isFind) {
204 ListDelete(&pos->node);
205 SoftBusFree(pos);
206 g_sessionServerList->cnt--;
207 char *tmpName = NULL;
208 Anonymize(sessionName, &tmpName);
209 TRANS_LOGI(TRANS_CTRL, "destroy session server sessionName=%{public}s", tmpName);
210 AnonymizeFree(tmpName);
211 }
212 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
213 return SOFTBUS_OK;
214 }
215
CheckUidAndPid(const char * sessionName,pid_t callingUid,pid_t callingPid)216 bool CheckUidAndPid(const char *sessionName, pid_t callingUid, pid_t callingPid)
217 {
218 if (sessionName == NULL) {
219 TRANS_LOGE(TRANS_CTRL, "Parameter sessionName is empty");
220 return false;
221 }
222 if (g_sessionServerList == NULL) {
223 TRANS_LOGE(TRANS_CTRL, "sessionServer is empty");
224 return false;
225 }
226 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
227 TRANS_LOGE(TRANS_CTRL, "Lock failure");
228 return false;
229 }
230
231 SessionServer *pos = NULL;
232 LIST_FOR_EACH_ENTRY(pos, &g_sessionServerList->list, SessionServer, node) {
233 if (strcmp(pos->sessionName, sessionName) == 0 &&
234 pos->uid == callingUid && pos->pid == callingPid) {
235 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
236 return true;
237 }
238 }
239
240 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
241 return false;
242 }
243
TransDelItemByPackageName(const char * pkgName,int32_t pid)244 void TransDelItemByPackageName(const char *pkgName, int32_t pid)
245 {
246 if (pkgName == NULL || g_sessionServerList == NULL) {
247 return;
248 }
249
250 SessionServer *pos = NULL;
251 SessionServer *tmp = NULL;
252 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
253 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
254 return;
255 }
256 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
257 if ((strcmp(pos->pkgName, pkgName) == 0) && (pos->pid == pid)) {
258 if (CheckDBinder(pos->sessionName)) {
259 // Remove RPC Permission when Client Process Exit
260 (void)DeleteDynamicPermission(pos->sessionName);
261 }
262 ListDelete(&pos->node);
263 g_sessionServerList->cnt--;
264 SoftBusFree(pos);
265 pos = NULL;
266 }
267 }
268 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
269 TRANS_LOGI(TRANS_CTRL, "del pkgName=%{public}s", pkgName);
270 }
271
TransGetPkgNameBySessionName(const char * sessionName,char * pkgName,uint16_t len)272 int32_t TransGetPkgNameBySessionName(const char *sessionName, char *pkgName, uint16_t len)
273 {
274 if (sessionName == NULL || pkgName == NULL || len == 0) {
275 TRANS_LOGE(TRANS_CTRL, "param error");
276 return SOFTBUS_INVALID_PARAM;
277 }
278 if (g_sessionServerList == NULL) {
279 TRANS_LOGE(TRANS_CTRL, "session server list not init");
280 return SOFTBUS_NO_INIT;
281 }
282
283 SessionServer *pos = NULL;
284 SessionServer *tmp = NULL;
285 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
286 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
287 return SOFTBUS_LOCK_ERR;
288 }
289 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
290 if (strcmp(pos->sessionName, sessionName) == 0) {
291 int32_t ret = strcpy_s(pkgName, len, pos->pkgName);
292 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
293 if (ret != EOK) {
294 TRANS_LOGE(TRANS_CTRL, "strcpy_s error ret, ret=%{public}d", ret);
295 return SOFTBUS_STRCPY_ERR;
296 }
297 return SOFTBUS_OK;
298 }
299 }
300
301 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
302 char *tmpName = NULL;
303 Anonymize(sessionName, &tmpName);
304 TRANS_LOGE(TRANS_CTRL, "not found sessionName=%{public}s.", tmpName);
305 AnonymizeFree(tmpName);
306 return SOFTBUS_TRANS_SESSION_NAME_NO_EXIST;
307 }
308
TransGetUidAndPid(const char * sessionName,int32_t * uid,int32_t * pid)309 int32_t TransGetUidAndPid(const char *sessionName, int32_t *uid, int32_t *pid)
310 {
311 if (sessionName == NULL || uid == NULL || pid == NULL) {
312 return SOFTBUS_INVALID_PARAM;
313 }
314 if (g_sessionServerList == NULL) {
315 TRANS_LOGE(TRANS_CTRL, "not init");
316 return SOFTBUS_NO_INIT;
317 }
318
319 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
320 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
321 return SOFTBUS_LOCK_ERR;
322 }
323
324 SessionServer *pos = NULL;
325 SessionServer *tmp = NULL;
326 char *tmpName = NULL;
327 Anonymize(sessionName, &tmpName);
328 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
329 if (strcmp(pos->sessionName, sessionName) == 0) {
330 *uid = pos->uid;
331 *pid = pos->pid;
332 TRANS_LOGD(TRANS_CTRL, "sessionName=%{public}s, uid=%{public}d, pid=%{public}d",
333 tmpName, pos->uid, pos->pid);
334 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
335 AnonymizeFree(tmpName);
336 return SOFTBUS_OK;
337 }
338 }
339
340 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
341 TRANS_LOGE(TRANS_CTRL, "err: sessionName=%{public}s", tmpName);
342 AnonymizeFree(tmpName);
343 return SOFTBUS_TRANS_GET_PID_FAILED;
344 }
345
TransListDelete(ListNode * sessionServerList)346 static void TransListDelete(ListNode *sessionServerList)
347 {
348 SessionServer *pos = NULL;
349 SessionServer *tmp = NULL;
350
351 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, sessionServerList, SessionServer, node) {
352 ListDelete(&pos->node);
353 SoftBusFree(pos);
354 }
355 }
356
TransListCopy(ListNode * sessionServerList)357 static int32_t TransListCopy(ListNode *sessionServerList)
358 {
359 TRANS_LOGD(TRANS_CTRL, "enter.");
360 if (sessionServerList == NULL) {
361 return SOFTBUS_NO_INIT;
362 }
363
364 SessionServer *pos = NULL;
365 SessionServer *tmp = NULL;
366 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
367 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
368 return SOFTBUS_LOCK_ERR;
369 }
370 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
371 SessionServer *newPos = (SessionServer *)SoftBusMalloc(sizeof(SessionServer));
372 if (newPos == NULL) {
373 TransListDelete(sessionServerList);
374 TRANS_LOGE(TRANS_CTRL, "SoftBusMalloc failed");
375 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
376 return SOFTBUS_MALLOC_ERR;
377 }
378 *newPos = *pos;
379 ListAdd(sessionServerList, &newPos->node);
380 }
381 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
382 return SOFTBUS_OK;
383 }
384
TransOnLinkDown(const char * networkId,const char * uuid,const char * udid,const char * peerIp,int32_t type)385 void TransOnLinkDown(const char *networkId, const char *uuid, const char *udid, const char *peerIp, int32_t type)
386 {
387 if (networkId == NULL || g_sessionServerList == NULL) {
388 return;
389 }
390 int32_t routeType = (int32_t)GET_ROUTE_TYPE(type);
391 int32_t connType = (int32_t)GET_CONN_TYPE(type);
392 char *anonyNetworkId = NULL;
393 Anonymize(networkId, &anonyNetworkId);
394 TRANS_LOGI(TRANS_CTRL,
395 "routeType=%{public}d, networkId=%{public}s connType=%{public}d", routeType, anonyNetworkId, connType);
396 AnonymizeFree(anonyNetworkId);
397
398 ListNode sessionServerList = {0};
399 ListInit(&sessionServerList);
400 int32_t ret = TransListCopy(&sessionServerList);
401 if (ret != SOFTBUS_OK) {
402 TRANS_LOGE(TRANS_CTRL, "copy list failed");
403 return;
404 }
405
406 SessionServer *pos = NULL;
407 SessionServer *tmp = NULL;
408 LinkDownInfo info = {
409 .uuid = uuid,
410 .udid = udid,
411 .peerIp = peerIp,
412 .networkId = networkId,
413 .routeType = type
414 };
415
416 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &sessionServerList, SessionServer, node) {
417 (void)TransServerOnChannelLinkDown(pos->pkgName, pos->pid, &info);
418 }
419
420 if (routeType == WIFI_P2P) {
421 LaneDeleteP2pAddress(networkId, true);
422 }
423 TransListDelete(&sessionServerList);
424 }
425