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 char *tmpName = NULL;
101 Anonymize(sessionName, &tmpName);
102 TRANS_LOGW(TRANS_CTRL, "session server is exist. sessionName=%{public}s", tmpName);
103 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
104 AnonymizeFree(tmpName);
105 return true;
106 }
107 }
108
109 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
110 return false;
111 }
112
ShowSessionServer(void)113 static void ShowSessionServer(void)
114 {
115 SessionServer *pos = NULL;
116 SessionServer *tmp = NULL;
117 int32_t count = 0;
118 char *tmpName = NULL;
119 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
120 Anonymize(pos->sessionName, &tmpName);
121 TRANS_LOGI(TRANS_CTRL,
122 "session server is exist. count=%{public}d, sessionName=%{public}s", count, tmpName);
123 AnonymizeFree(tmpName);
124 count++;
125 }
126 }
127
TransSessionServerAddItem(SessionServer * newNode)128 int32_t TransSessionServerAddItem(SessionServer *newNode)
129 {
130 TRANS_CHECK_AND_RETURN_RET_LOGE(newNode != NULL, SOFTBUS_INVALID_PARAM, TRANS_CTRL, "param invalid");
131 TRANS_CHECK_AND_RETURN_RET_LOGE(g_sessionServerList != NULL, SOFTBUS_NO_INIT, TRANS_CTRL, "not init");
132 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
133 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
134 return SOFTBUS_LOCK_ERR;
135 }
136 if (g_sessionServerList->cnt >= MAX_SESSION_SERVER_NUM) {
137 (void)ShowSessionServer();
138 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
139 TRANS_LOGE(TRANS_CTRL, "session server num reach max");
140 return SOFTBUS_INVALID_NUM;
141 }
142
143 SessionServer *pos = NULL;
144 SessionServer *tmp = NULL;
145 char *tmpName = NULL;
146 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
147 if (strcmp(pos->sessionName, newNode->sessionName) == 0) {
148 Anonymize(newNode->sessionName, &tmpName);
149 if ((pos->uid == newNode->uid) && (pos->pid == newNode->pid)) {
150 TRANS_LOGI(TRANS_CTRL, "session server is exist, sessionName=%{public}s", AnonymizeWrapper(tmpName));
151 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
152 AnonymizeFree(tmpName);
153 return SOFTBUS_SERVER_NAME_REPEATED;
154 }
155 if (CheckServiceIsRegistered(pos->pkgName, pos->pid) == SOFTBUS_OK) {
156 TRANS_LOGI(TRANS_CTRL,
157 "sessionName=%{public}s has been used by other processes, old Pid=%{public}d, new pid=%{public}d",
158 AnonymizeWrapper(tmpName), pos->pid, newNode->pid);
159 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
160 AnonymizeFree(tmpName);
161 return SOFTBUS_SERVER_NAME_USED;
162 }
163 pos->pid = newNode->pid;
164 TRANS_LOGI(TRANS_CTRL, "sessionName=%{public}s is exist. old pid=%{public}d, new pid=%{public}d",
165 AnonymizeWrapper(tmpName), pos->pid, newNode->pid);
166 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
167 AnonymizeFree(tmpName);
168 SoftBusFree(newNode);
169 return SOFTBUS_OK;
170 }
171 }
172
173 Anonymize(newNode->sessionName, &tmpName);
174 ListAdd(&(g_sessionServerList->list), &(newNode->node));
175 TRANS_LOGI(TRANS_CTRL, "add sessionName=%{public}s", AnonymizeWrapper(tmpName));
176 g_sessionServerList->cnt++;
177 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
178 AnonymizeFree(tmpName);
179 return SOFTBUS_OK;
180 }
181
TransSessionServerDelItem(const char * sessionName)182 int32_t TransSessionServerDelItem(const char *sessionName)
183 {
184 if (sessionName == NULL) {
185 return SOFTBUS_INVALID_PARAM;
186 }
187 if (g_sessionServerList == NULL) {
188 return SOFTBUS_NO_INIT;
189 }
190
191 bool isFind = false;
192 SessionServer *pos = NULL;
193 SessionServer *tmp = NULL;
194 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
195 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
196 return SOFTBUS_LOCK_ERR;
197 }
198 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
199 if (strcmp(pos->sessionName, sessionName) == 0) {
200 isFind = true;
201 break;
202 }
203 }
204 if (isFind) {
205 ListDelete(&pos->node);
206 SoftBusFree(pos);
207 g_sessionServerList->cnt--;
208 char *tmpName = NULL;
209 Anonymize(sessionName, &tmpName);
210 TRANS_LOGI(TRANS_CTRL, "destroy session server sessionName=%{public}s", tmpName);
211 AnonymizeFree(tmpName);
212 }
213 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
214 return SOFTBUS_OK;
215 }
216
CheckUidAndPid(const char * sessionName,pid_t callingUid,pid_t callingPid)217 bool CheckUidAndPid(const char *sessionName, pid_t callingUid, pid_t callingPid)
218 {
219 if (sessionName == NULL) {
220 TRANS_LOGE(TRANS_CTRL, "Parameter sessionName is empty");
221 return false;
222 }
223 if (g_sessionServerList == NULL) {
224 TRANS_LOGE(TRANS_CTRL, "sessionServer is empty");
225 return false;
226 }
227 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
228 TRANS_LOGE(TRANS_CTRL, "Lock failure");
229 return false;
230 }
231
232 SessionServer *pos = NULL;
233 LIST_FOR_EACH_ENTRY(pos, &g_sessionServerList->list, SessionServer, node) {
234 if (strcmp(pos->sessionName, sessionName) == 0 &&
235 pos->uid == callingUid && pos->pid == callingPid) {
236 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
237 return true;
238 }
239 }
240
241 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
242 return false;
243 }
244
TransDelItemByPackageName(const char * pkgName,int32_t pid)245 void TransDelItemByPackageName(const char *pkgName, int32_t pid)
246 {
247 if (pkgName == NULL || g_sessionServerList == NULL) {
248 return;
249 }
250
251 SessionServer *pos = NULL;
252 SessionServer *tmp = NULL;
253 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
254 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
255 return;
256 }
257 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
258 if ((strcmp(pos->pkgName, pkgName) == 0) && (pos->pid == pid)) {
259 if (CheckDBinder(pos->sessionName)) {
260 // Remove RPC Permission when Client Process Exit
261 (void)DeleteDynamicPermission(pos->sessionName);
262 }
263 ListDelete(&pos->node);
264 g_sessionServerList->cnt--;
265 SoftBusFree(pos);
266 pos = NULL;
267 }
268 }
269 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
270 TRANS_LOGI(TRANS_CTRL, "del pkgName=%{public}s", pkgName);
271 }
272
TransGetPkgNameBySessionName(const char * sessionName,char * pkgName,uint16_t len)273 int32_t TransGetPkgNameBySessionName(const char *sessionName, char *pkgName, uint16_t len)
274 {
275 if (sessionName == NULL || pkgName == NULL || len == 0) {
276 TRANS_LOGE(TRANS_CTRL, "param error");
277 return SOFTBUS_INVALID_PARAM;
278 }
279 if (g_sessionServerList == NULL) {
280 TRANS_LOGE(TRANS_CTRL, "session server list not init");
281 return SOFTBUS_NO_INIT;
282 }
283
284 SessionServer *pos = NULL;
285 SessionServer *tmp = NULL;
286 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
287 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
288 return SOFTBUS_LOCK_ERR;
289 }
290 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
291 if (strcmp(pos->sessionName, sessionName) == 0) {
292 int32_t ret = strcpy_s(pkgName, len, pos->pkgName);
293 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
294 if (ret != EOK) {
295 TRANS_LOGE(TRANS_CTRL, "strcpy_s error ret, ret=%{public}d", ret);
296 return SOFTBUS_STRCPY_ERR;
297 }
298 return SOFTBUS_OK;
299 }
300 }
301
302 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
303 char *tmpName = NULL;
304 Anonymize(sessionName, &tmpName);
305 TRANS_LOGE(TRANS_CTRL, "not found sessionName=%{public}s.", tmpName);
306 AnonymizeFree(tmpName);
307 return SOFTBUS_TRANS_SESSION_NAME_NO_EXIST;
308 }
309
TransGetUidAndPid(const char * sessionName,int32_t * uid,int32_t * pid)310 int32_t TransGetUidAndPid(const char *sessionName, int32_t *uid, int32_t *pid)
311 {
312 if (sessionName == NULL || uid == NULL || pid == NULL) {
313 return SOFTBUS_INVALID_PARAM;
314 }
315 if (g_sessionServerList == NULL) {
316 TRANS_LOGE(TRANS_CTRL, "not init");
317 return SOFTBUS_NO_INIT;
318 }
319
320 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
321 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
322 return SOFTBUS_LOCK_ERR;
323 }
324
325 SessionServer *pos = NULL;
326 SessionServer *tmp = NULL;
327 char *tmpName = NULL;
328 Anonymize(sessionName, &tmpName);
329 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
330 if (strcmp(pos->sessionName, sessionName) == 0) {
331 *uid = pos->uid;
332 *pid = pos->pid;
333 TRANS_LOGD(TRANS_CTRL, "sessionName=%{public}s, uid=%{public}d, pid=%{public}d",
334 tmpName, pos->uid, pos->pid);
335 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
336 AnonymizeFree(tmpName);
337 return SOFTBUS_OK;
338 }
339 }
340
341 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
342 TRANS_LOGE(TRANS_CTRL, "err: sessionName=%{public}s", tmpName);
343 AnonymizeFree(tmpName);
344 return SOFTBUS_TRANS_GET_PID_FAILED;
345 }
346
TransListDelete(ListNode * sessionServerList)347 static void TransListDelete(ListNode *sessionServerList)
348 {
349 SessionServer *pos = NULL;
350 SessionServer *tmp = NULL;
351
352 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, sessionServerList, SessionServer, node) {
353 ListDelete(&pos->node);
354 SoftBusFree(pos);
355 }
356 }
357
TransListCopy(ListNode * sessionServerList)358 static int32_t TransListCopy(ListNode *sessionServerList)
359 {
360 TRANS_LOGD(TRANS_CTRL, "enter.");
361 if (sessionServerList == NULL) {
362 return SOFTBUS_NO_INIT;
363 }
364
365 SessionServer *pos = NULL;
366 SessionServer *tmp = NULL;
367 if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
368 TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
369 return SOFTBUS_LOCK_ERR;
370 }
371 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
372 SessionServer *newPos = (SessionServer *)SoftBusMalloc(sizeof(SessionServer));
373 if (newPos == NULL) {
374 TransListDelete(sessionServerList);
375 TRANS_LOGE(TRANS_CTRL, "SoftBusMalloc failed");
376 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
377 return SOFTBUS_MALLOC_ERR;
378 }
379 *newPos = *pos;
380 ListAdd(sessionServerList, &newPos->node);
381 }
382 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
383 return SOFTBUS_OK;
384 }
385
TransOnLinkDown(const char * networkId,const char * uuid,const char * udid,const char * peerIp,int32_t type)386 void TransOnLinkDown(const char *networkId, const char *uuid, const char *udid, const char *peerIp, int32_t type)
387 {
388 if (networkId == NULL || g_sessionServerList == NULL) {
389 return;
390 }
391 int32_t routeType = (int32_t)GET_ROUTE_TYPE(type);
392 int32_t connType = (int32_t)GET_CONN_TYPE(type);
393 char *anonyNetworkId = NULL;
394 Anonymize(networkId, &anonyNetworkId);
395 TRANS_LOGI(TRANS_CTRL,
396 "routeType=%{public}d, networkId=%{public}s connType=%{public}d", routeType, anonyNetworkId, connType);
397 AnonymizeFree(anonyNetworkId);
398
399 ListNode sessionServerList = {0};
400 ListInit(&sessionServerList);
401 int32_t ret = TransListCopy(&sessionServerList);
402 if (ret != SOFTBUS_OK) {
403 TRANS_LOGE(TRANS_CTRL, "copy list failed");
404 return;
405 }
406
407 SessionServer *pos = NULL;
408 SessionServer *tmp = NULL;
409 LinkDownInfo info = {
410 .uuid = uuid,
411 .udid = udid,
412 .peerIp = peerIp,
413 .networkId = networkId,
414 .routeType = type
415 };
416
417 LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &sessionServerList, SessionServer, node) {
418 (void)TransServerOnChannelLinkDown(pos->pkgName, pos->pid, &info);
419 }
420
421 if (routeType == WIFI_P2P) {
422 LaneDeleteP2pAddress(networkId, true);
423 }
424 TransListDelete(&sessionServerList);
425 }
426