1 /*
2  * Copyright (c) 2024 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 "client_trans_socket_manager.h"
17 
18 #include <securec.h>
19 
20 #include "anonymizer.h"
21 #include "client_bus_center_manager.h"
22 #include "client_trans_channel_manager.h"
23 #include "client_trans_file_listener.h"
24 #include "client_trans_proxy_file_manager.h"
25 #include "client_trans_tcp_direct_manager.h"
26 #include "client_trans_udp_manager.h"
27 #include "softbus_adapter_mem.h"
28 #include "softbus_app_info.h"
29 #include "softbus_def.h"
30 #include "softbus_errcode.h"
31 #include "softbus_socket.h"
32 #include "softbus_utils.h"
33 #include "trans_log.h"
34 #include "trans_server_proxy.h"
35 
36 #define NETWORK_ID_LEN 7
37 #define GET_ROUTE_TYPE(type) ((uint32_t)(type) & 0xff)
38 #define GET_CONN_TYPE(type) (((uint32_t)(type) >> 8) & 0xff)
39 
40 #define DISTRIBUTED_DATA_SESSION "distributeddata-default"
41 
IsValidSessionParam(const SessionParam *param)42 bool IsValidSessionParam(const SessionParam *param)
43 {
44     if ((param == NULL) ||
45         (param->sessionName == NULL) ||
46         (param->peerSessionName == NULL) ||
47         (param->peerDeviceId == NULL) ||
48         (param->groupId == NULL) ||
49         (param->attr == NULL)) {
50         return false;
51     }
52     return true;
53 }
54 
CreateNewSession(const SessionParam *param)55 SessionInfo *CreateNewSession(const SessionParam *param)
56 {
57     if (param == NULL) {
58         TRANS_LOGE(TRANS_SDK, "param is null");
59         return NULL;
60     }
61     SessionInfo *session = (SessionInfo*)SoftBusCalloc(sizeof(SessionInfo));
62     if (session == NULL) {
63         TRANS_LOGE(TRANS_SDK, "calloc failed");
64         return NULL;
65     }
66 
67     if (strcpy_s(session->info.peerSessionName, SESSION_NAME_SIZE_MAX, param->peerSessionName) != EOK ||
68         strcpy_s(session->info.peerDeviceId, DEVICE_ID_SIZE_MAX, param->peerDeviceId) != EOK ||
69         strcpy_s(session->info.groupId, GROUP_ID_SIZE_MAX, param->groupId) != EOK ||
70         memcpy_s(session->linkType, sizeof(param->attr->linkType), param->attr->linkType,
71             sizeof(param->attr->linkType)) != EOK) {
72         TRANS_LOGE(TRANS_SDK, "strcpy failed");
73         SoftBusFree(session);
74         return NULL;
75     }
76 
77     session->sessionId = INVALID_SESSION_ID;
78     session->channelId = INVALID_CHANNEL_ID;
79     session->channelType = CHANNEL_TYPE_BUTT;
80     session->isServer = false;
81     session->role = SESSION_ROLE_INIT;
82     session->enableStatus = ENABLE_STATUS_INIT;
83     session->info.flag = param->attr->dataType;
84     session->isEncrypt = true;
85     session->isAsync = false;
86     session->lifecycle.sessionState = SESSION_STATE_INIT;
87     session->actionId = param->actionId;
88     return session;
89 }
90 
CreateDestroySessionNode(SessionInfo *sessionNode, const ClientSessionServer *server)91 NO_SANITIZE("cfi") DestroySessionInfo *CreateDestroySessionNode(SessionInfo *sessionNode,
92     const ClientSessionServer *server)
93 {
94     if (sessionNode == NULL || server == NULL) {
95         TRANS_LOGE(TRANS_SDK, "invalid param.");
96         return NULL;
97     }
98     DestroySessionInfo *destroyNode = (DestroySessionInfo *)SoftBusCalloc(sizeof(DestroySessionInfo));
99     if (destroyNode == NULL) {
100         TRANS_LOGE(TRANS_SDK, "destroyList malloc fail.");
101         return NULL;
102     }
103     destroyNode->sessionId = sessionNode->sessionId;
104     destroyNode->channelId = sessionNode->channelId;
105     destroyNode->channelType = sessionNode->channelType;
106     destroyNode->isAsync = sessionNode->isAsync;
107     if (!sessionNode->lifecycle.condIsWaiting) {
108         (void)SoftBusCondDestroy(&(sessionNode->lifecycle.callbackCond));
109     } else {
110         (void)SoftBusCondSignal(&(sessionNode->lifecycle.callbackCond)); // destroy in CheckSessionEnableStatus
111         TRANS_LOGI(TRANS_SDK, "sessionId=%{public}d condition is waiting", sessionNode->sessionId);
112     }
113     if (memcpy_s(destroyNode->sessionName, SESSION_NAME_SIZE_MAX, server->sessionName, SESSION_NAME_SIZE_MAX) != EOK) {
114         TRANS_LOGE(TRANS_SDK, "memcpy_s sessionName fail.");
115         SoftBusFree(destroyNode);
116         return NULL;
117     }
118     if (memcpy_s(destroyNode->pkgName, PKG_NAME_SIZE_MAX, server->pkgName, PKG_NAME_SIZE_MAX) != EOK) {
119         TRANS_LOGE(TRANS_SDK, "memcpy_s pkgName fail.");
120         SoftBusFree(destroyNode);
121         return NULL;
122     }
123     destroyNode->OnSessionClosed = server->listener.session.OnSessionClosed;
124     destroyNode->OnShutdown = sessionNode->isServer ? server->listener.socketServer.OnShutdown :
125         server->listener.socketClient.OnShutdown;
126     return destroyNode;
127 }
128 
ClientDestroySession(const ListNode *destroyList, ShutdownReason reason)129 NO_SANITIZE("cfi") void ClientDestroySession(const ListNode *destroyList, ShutdownReason reason)
130 {
131     if (destroyList == NULL) {
132         TRANS_LOGE(TRANS_SDK, "invalid param.");
133         return;
134     }
135     if (IsListEmpty(destroyList)) {
136         TRANS_LOGD(TRANS_SDK, "destroyList is empty fail.");
137         return;
138     }
139     DestroySessionInfo *destroyNode = NULL;
140     DestroySessionInfo *destroyNodeNext = NULL;
141     TRANS_LOGD(TRANS_SDK, "enter.");
142     LIST_FOR_EACH_ENTRY_SAFE(destroyNode, destroyNodeNext, destroyList, DestroySessionInfo, node) {
143         int32_t id = destroyNode->sessionId;
144         (void)ClientDeleteRecvFileList(id);
145         (void)ClientTransCloseChannel(destroyNode->channelId, destroyNode->channelType);
146         if (destroyNode->OnSessionClosed != NULL) {
147             destroyNode->OnSessionClosed(id);
148         } else if (destroyNode->OnShutdown != NULL) {
149             destroyNode->OnShutdown(id, reason);
150             (void)TryDeleteEmptySessionServer(destroyNode->pkgName, destroyNode->sessionName);
151         }
152         ListDelete(&(destroyNode->node));
153         SoftBusFree(destroyNode);
154     }
155     TRANS_LOGD(TRANS_SDK, "ok");
156 }
157 
DestroyClientSessionServer(ClientSessionServer *server, ListNode *destroyList)158 void DestroyClientSessionServer(ClientSessionServer *server, ListNode *destroyList)
159 {
160     if (server == NULL || destroyList == NULL) {
161         TRANS_LOGW(TRANS_SDK, "invalid param");
162         return;
163     }
164 
165     if (!IsListEmpty(&(server->sessionList))) {
166         SessionInfo *sessionNode = NULL;
167         SessionInfo *sessionNodeNext = NULL;
168         LIST_FOR_EACH_ENTRY_SAFE(sessionNode, sessionNodeNext, &(server->sessionList), SessionInfo, node) {
169             DestroySessionInfo *destroyNode = CreateDestroySessionNode(sessionNode, server);
170             if (destroyNode == NULL) {
171                 continue;
172             }
173             DestroySessionId();
174             ListDelete(&sessionNode->node);
175             ListAdd(destroyList, &(destroyNode->node));
176             SoftBusFree(sessionNode);
177         }
178     }
179 
180     ListDelete(&(server->node));
181     char *tmpName = NULL;
182     Anonymize(server->sessionName, &tmpName);
183     TRANS_LOGI(TRANS_SDK, "destroy session server sessionName=%{public}s", AnonymizeWrapper(tmpName));
184     AnonymizeFree(tmpName);
185     SoftBusFree(server);
186 }
187 
GetNewSessionServer(SoftBusSecType type, const char *sessionName, const char *pkgName, const ISessionListener *listener)188 ClientSessionServer *GetNewSessionServer(SoftBusSecType type, const char *sessionName,
189     const char *pkgName, const ISessionListener *listener)
190 {
191     if (sessionName == NULL || pkgName == NULL || listener == NULL) {
192         TRANS_LOGW(TRANS_SDK, "invalid param");
193         return NULL;
194     }
195     ClientSessionServer *server = (ClientSessionServer *)SoftBusCalloc(sizeof(ClientSessionServer));
196     if (server == NULL) {
197         return NULL;
198     }
199     server->type = type;
200     if (strcpy_s(server->pkgName, sizeof(server->pkgName), pkgName) != EOK) {
201         goto EXIT_ERR;
202     }
203     if (strcpy_s(server->sessionName, sizeof(server->sessionName), sessionName) != EOK) {
204         goto EXIT_ERR;
205     }
206     if (memcpy_s(&server->listener.session, sizeof(ISessionListener), listener, sizeof(ISessionListener)) != EOK) {
207         goto EXIT_ERR;
208     }
209     server->listener.isSocketListener = false;
210     server->isSrvEncryptedRawStream = false;
211 
212     ListInit(&server->node);
213     ListInit(&server->sessionList);
214     return server;
215 
216 EXIT_ERR:
217     if (server != NULL) {
218         SoftBusFree(server);
219     }
220     return NULL;
221 }
222 
CreateNonEncryptSessionInfo(const char *sessionName)223 SessionInfo *CreateNonEncryptSessionInfo(const char *sessionName)
224 {
225     if (sessionName == NULL) {
226         TRANS_LOGW(TRANS_SDK, "Invalid param");
227         return NULL;
228     }
229     if (!IsValidString(sessionName, SESSION_NAME_SIZE_MAX - 1)) {
230         TRANS_LOGW(TRANS_SDK, "Invalid param");
231         return NULL;
232     }
233     SessionInfo *session = (SessionInfo *)SoftBusCalloc(sizeof(SessionInfo));
234     if (session == NULL) {
235         return NULL;
236     }
237     session->channelType = CHANNEL_TYPE_AUTH;
238     session->isEncrypt = false;
239     session->actionId = INVALID_ACTION_ID;
240     if (strcpy_s(session->info.peerSessionName, SESSION_NAME_SIZE_MAX, sessionName) != EOK) {
241         SoftBusFree(session);
242         return NULL;
243     }
244     return session;
245 }
246 
ClientTransGetTdcIp(int32_t channelId, char *myIp, int32_t ipLen)247 static int32_t ClientTransGetTdcIp(int32_t channelId, char *myIp, int32_t ipLen)
248 {
249     TcpDirectChannelInfo channel;
250     if (TransTdcGetInfoById(channelId, &channel) == NULL) {
251         TRANS_LOGE(TRANS_SDK, "not found Tdc channel by channelId=%{public}d", channelId);
252         return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
253     }
254 
255     if (strcpy_s(myIp, ipLen, channel.detail.myIp) != EOK) {
256         TRANS_LOGE(TRANS_SDK, "strcpy_s ip failed, len=%{public}zu", strlen(channel.detail.myIp));
257         return SOFTBUS_STRCPY_ERR;
258     }
259 
260     return SOFTBUS_OK;
261 }
262 
ClientTransGetUdpIp(int32_t channelId, char *myIp, int32_t ipLen)263 static int32_t ClientTransGetUdpIp(int32_t channelId, char *myIp, int32_t ipLen)
264 {
265     UdpChannel channel;
266     if (TransGetUdpChannel(channelId, &channel) != SOFTBUS_OK) {
267         TRANS_LOGE(TRANS_SDK, "not found Udp channel by channelId=%{public}d", channelId);
268         return SOFTBUS_TRANS_UDP_CHANNEL_NOT_FOUND;
269     }
270 
271     if (strcpy_s(myIp, ipLen, channel.info.myIp) != EOK) {
272         TRANS_LOGE(TRANS_SDK, "strcpy_s ip failed, len=%{public}zu", strlen(channel.info.myIp));
273         return SOFTBUS_STRCPY_ERR;
274     }
275 
276     return SOFTBUS_OK;
277 }
278 
279 // determine connection type based on IP
ClientTransCheckHmlIp(const char *ip)280 static bool ClientTransCheckHmlIp(const char *ip)
281 {
282     if (IsHmlIpAddr(ip)) {
283         return true;
284     }
285 
286     return false;
287 }
288 
289 // determine connection type based on IP, delete session when connection type and parameter connType are consistent
ClientTransCheckNeedDel(SessionInfo *sessionNode, int32_t routeType, int32_t connType)290 static bool ClientTransCheckNeedDel(SessionInfo *sessionNode, int32_t routeType, int32_t connType)
291 {
292     if (connType == TRANS_CONN_ALL) {
293         if (routeType != ROUTE_TYPE_ALL && sessionNode->routeType != routeType) {
294             return false;
295         }
296         return true;
297     }
298     /*
299     * only when the function OnWifiDirectDeviceOffLine is called can reach this else branch,
300     * and routeType is WIFI_P2P, the connType is hml or p2p
301     */
302     if (sessionNode->routeType != routeType) {
303         return false;
304     }
305 
306     char myIp[IP_LEN] = {0};
307     if (sessionNode->channelType == CHANNEL_TYPE_UDP) {
308         if (ClientTransGetUdpIp(sessionNode->channelId, myIp, sizeof(myIp)) != SOFTBUS_OK) {
309             return false;
310         }
311     } else if (sessionNode->channelType == CHANNEL_TYPE_TCP_DIRECT) {
312         if (ClientTransGetTdcIp(sessionNode->channelId, myIp, sizeof(myIp)) != SOFTBUS_OK) {
313             return false;
314         }
315     } else if (sessionNode->channelType == CHANNEL_TYPE_AUTH) {
316         TRANS_LOGD(TRANS_SDK, "check channelType=%{public}d", sessionNode->channelType);
317         return true;
318     } else {
319         TRANS_LOGW(TRANS_SDK, "check channelType=%{public}d", sessionNode->channelType);
320         return false;
321     }
322 
323     bool isHml = ClientTransCheckHmlIp(myIp);
324     if (connType == TRANS_CONN_HML && isHml) {
325         return true;
326     } else if (connType == TRANS_CONN_P2P && !isHml) {
327         return true;
328     }
329 
330     return false;
331 }
332 
DestroyClientSessionByNetworkId(const ClientSessionServer *server, const char *networkId, int32_t type, ListNode *destroyList)333 void DestroyClientSessionByNetworkId(const ClientSessionServer *server,
334     const char *networkId, int32_t type, ListNode *destroyList)
335 {
336     if (server == NULL || networkId == NULL || destroyList == NULL) {
337         TRANS_LOGE(TRANS_SDK, "invalid param.");
338         return;
339     }
340     SessionInfo *sessionNode = NULL;
341     SessionInfo *sessionNodeNext = NULL;
342     // connType is set only in function OnWifiDirectDeviceOffLine, others is TRANS_CONN_ALL, and routeType is WIFI_P2P
343     int32_t routeType = (int32_t)GET_ROUTE_TYPE(type);
344     int32_t connType = (int32_t)GET_CONN_TYPE(type);
345 
346     LIST_FOR_EACH_ENTRY_SAFE(sessionNode, sessionNodeNext, &(server->sessionList), SessionInfo, node) {
347         if (strcmp(sessionNode->info.peerDeviceId, networkId) != 0) {
348             continue;
349         }
350 
351         if (!ClientTransCheckNeedDel(sessionNode, routeType, connType)) {
352             continue;
353         }
354 
355         TRANS_LOGI(TRANS_SDK, "channelId=%{public}d, channelType=%{public}d, routeType=%{public}d, type=%{public}d",
356             sessionNode->channelId, sessionNode->channelType, sessionNode->routeType, type);
357         DestroySessionInfo *destroyNode = CreateDestroySessionNode(sessionNode, server);
358         if (destroyNode == NULL) {
359             continue;
360         }
361         /*
362          * When the channel type is UDP and the business type is file, trigger DFILE_ON_CLEAR_POLICY_FILE_LIST event
363          * before cleaning up sessionNode.
364          */
365         if (sessionNode->channelType == CHANNEL_TYPE_UDP && sessionNode->businessType == BUSINESS_TYPE_FILE) {
366             ClientEmitFileEvent(sessionNode->channelId);
367         }
368         DestroySessionId();
369         ListDelete(&sessionNode->node);
370         ListAdd(destroyList, &(destroyNode->node));
371         SoftBusFree(sessionNode);
372     }
373 }
374 
CreateSessionServerInfoNode(const ClientSessionServer *clientSessionServer)375 SessionServerInfo *CreateSessionServerInfoNode(const ClientSessionServer *clientSessionServer)
376 {
377     if (clientSessionServer == NULL) {
378         TRANS_LOGE(TRANS_SDK, "invalid param.");
379         return NULL;
380     }
381 
382     SessionServerInfo *infoNode = (SessionServerInfo *)SoftBusCalloc(sizeof(SessionServerInfo));
383     if (infoNode == NULL) {
384         TRANS_LOGE(TRANS_SDK, "failed to malloc SessionServerInfo.");
385         return NULL;
386     }
387 
388     if (strcpy_s(infoNode->pkgName, SESSION_NAME_SIZE_MAX, clientSessionServer->pkgName) != EOK) {
389         SoftBusFree(infoNode);
390         TRANS_LOGE(TRANS_SDK, "failed to strcpy pkgName.");
391         return NULL;
392     }
393 
394     if (strcpy_s(infoNode->sessionName, SESSION_NAME_SIZE_MAX, clientSessionServer->sessionName) != EOK) {
395         SoftBusFree(infoNode);
396         TRANS_LOGE(TRANS_SDK, "failed to strcpy sessionName.");
397         return NULL;
398     }
399 
400     return infoNode;
401 }
402 
GetNewSocketServer(SoftBusSecType type, const char *sessionName, const char *pkgName)403 ClientSessionServer *GetNewSocketServer(SoftBusSecType type, const char *sessionName, const char *pkgName)
404 {
405     if (sessionName == NULL || pkgName == NULL) {
406         TRANS_LOGE(TRANS_SDK, "invalid param.");
407         return NULL;
408     }
409     ClientSessionServer *server = (ClientSessionServer *)SoftBusCalloc(sizeof(ClientSessionServer));
410     if (server == NULL) {
411         return NULL;
412     }
413     server->type = type;
414     if (strcpy_s(server->pkgName, sizeof(server->pkgName), pkgName) != EOK) {
415         goto EXIT_ERR;
416     }
417     if (strcpy_s(server->sessionName, sizeof(server->sessionName), sessionName) != EOK) {
418         goto EXIT_ERR;
419     }
420     server->sessionAddingCnt++;
421     server->isSrvEncryptedRawStream = false;
422     ListInit(&server->node);
423     ListInit(&server->sessionList);
424     return server;
425 
426 EXIT_ERR:
427     if (server != NULL) {
428         SoftBusFree(server);
429     }
430     return NULL;
431 }
432 
IsDistributedDataSession(const char *sessionName)433 bool IsDistributedDataSession(const char *sessionName)
434 {
435     if (sessionName == NULL) {
436         TRANS_LOGE(TRANS_SDK, "invalid param.");
437         return false;
438     }
439     uint32_t distributedDataSessionLen = strlen(DISTRIBUTED_DATA_SESSION);
440     if (strlen(sessionName) < distributedDataSessionLen ||
441         strncmp(sessionName, DISTRIBUTED_DATA_SESSION, distributedDataSessionLen) != 0) {
442         return false;
443     }
444     return true;
445 }
446 
IsDifferentDataType(const SessionInfo *sessionInfo, int dataType, bool isEncyptedRawStream)447 bool IsDifferentDataType(const SessionInfo *sessionInfo, int dataType, bool isEncyptedRawStream)
448 {
449     if (sessionInfo == NULL) {
450         TRANS_LOGE(TRANS_SDK, "invalid param.");
451         return false;
452     }
453     if (sessionInfo->info.flag != dataType) {
454         return true;
455     }
456 
457     if (dataType != RAW_STREAM) {
458         return false;
459     }
460 
461     return sessionInfo->isEncyptedRawStream != isEncyptedRawStream;
462 }
463 
ClientInitSession(SessionInfo *session, const SessionParam *param)464 static void ClientInitSession(SessionInfo *session, const SessionParam *param)
465 {
466     session->sessionId = INVALID_SESSION_ID;
467     session->channelId = INVALID_CHANNEL_ID;
468     session->channelType = CHANNEL_TYPE_BUTT;
469     session->isServer = false;
470     session->role = SESSION_ROLE_INIT;
471     session->enableStatus = ENABLE_STATUS_INIT;
472     session->info.flag = param->attr->dataType;
473     session->info.streamType = param->attr->attr.streamAttr.streamType;
474     session->isEncrypt = true;
475     session->isAsync = false;
476     session->lifecycle.sessionState = SESSION_STATE_INIT;
477     session->lifecycle.condIsWaiting = false;
478     session->actionId = param->actionId;
479 }
480 
CreateNewSocketSession(const SessionParam *param)481 SessionInfo *CreateNewSocketSession(const SessionParam *param)
482 {
483     if (param == NULL) {
484         TRANS_LOGE(TRANS_SDK, "invalid param.");
485         return NULL;
486     }
487     SessionInfo *session = (SessionInfo *)SoftBusCalloc(sizeof(SessionInfo));
488     if (session == NULL) {
489         TRANS_LOGE(TRANS_SDK, "calloc failed");
490         return NULL;
491     }
492 
493     if (param->peerSessionName != NULL &&
494         strcpy_s(session->info.peerSessionName, SESSION_NAME_SIZE_MAX, param->peerSessionName) != EOK) {
495         char *anonySessionName = NULL;
496         Anonymize(param->peerSessionName, &anonySessionName);
497         TRANS_LOGI(TRANS_SDK, "strcpy peerName failed, peerName=%{public}s, peerNameLen=%{public}zu",
498             AnonymizeWrapper(anonySessionName), strlen(param->peerSessionName));
499         AnonymizeFree(anonySessionName);
500         SoftBusFree(session);
501         return NULL;
502     }
503 
504     if (param->peerDeviceId != NULL &&
505         strcpy_s(session->info.peerDeviceId, DEVICE_ID_SIZE_MAX, param->peerDeviceId) != EOK) {
506         char *anonyNetworkId = NULL;
507         Anonymize(param->peerDeviceId, &anonyNetworkId);
508         TRANS_LOGI(TRANS_SDK, "strcpy peerDeviceId failed, peerDeviceId=%{public}s, peerDeviceIdLen=%{public}zu",
509             AnonymizeWrapper(anonyNetworkId), strlen(param->peerDeviceId));
510         AnonymizeFree(anonyNetworkId);
511         SoftBusFree(session);
512         return NULL;
513     }
514 
515     if (strcpy_s(session->info.groupId, GROUP_ID_SIZE_MAX, param->groupId) != EOK ||
516         memcpy_s(session->linkType, sizeof(param->attr->linkType), param->attr->linkType,
517             sizeof(param->attr->linkType)) != EOK) {
518         TRANS_LOGE(TRANS_SDK, "strcpy failed");
519         SoftBusFree(session);
520         return NULL;
521     }
522 
523     if (SoftBusCondInit(&session->lifecycle.callbackCond) != SOFTBUS_OK) {
524         SoftBusFree(session);
525         TRANS_LOGE(TRANS_SDK, "callbackCond Init failed");
526         return NULL;
527     }
528 
529     ClientInitSession(session, param);
530     return session;
531 }
532 
CheckBindSocketInfo(const SessionInfo *session)533 int32_t CheckBindSocketInfo(const SessionInfo *session)
534 {
535     if (session == NULL) {
536         TRANS_LOGE(TRANS_SDK, "invalid param.");
537         return SOFTBUS_INVALID_PARAM;
538     }
539     if (!IsValidString(session->info.peerSessionName, SESSION_NAME_SIZE_MAX - 1) ||
540         !IsValidString(session->info.peerDeviceId, DEVICE_ID_SIZE_MAX - 1)) {
541         char *anonySessionName = NULL;
542         char *anonyNetworkId = NULL;
543         Anonymize(session->info.peerSessionName, &anonySessionName);
544         Anonymize(session->info.peerDeviceId, &anonyNetworkId);
545         TRANS_LOGI(TRANS_SDK, "invalid peerName=%{public}s, peerNameLen=%{public}zu, peerNetworkId=%{public}s, "
546             "peerNetworkIdLen=%{public}zu", AnonymizeWrapper(anonySessionName), strlen(session->info.peerSessionName),
547             AnonymizeWrapper(anonyNetworkId), strlen(session->info.peerDeviceId));
548         AnonymizeFree(anonyNetworkId);
549         AnonymizeFree(anonySessionName);
550         return SOFTBUS_INVALID_PARAM;
551     }
552 
553     if (session->info.flag < TYPE_MESSAGE || session->info.flag >= TYPE_BUTT) {
554         TRANS_LOGE(TRANS_SDK, "invalid dataType");
555         return SOFTBUS_INVALID_PARAM;
556     }
557 
558     return SOFTBUS_OK;
559 }
560 
FillSessionParam(SessionParam *param, SessionAttribute *tmpAttr, ClientSessionServer *serverNode, SessionInfo *sessionNode)561 void FillSessionParam(SessionParam *param, SessionAttribute *tmpAttr,
562     ClientSessionServer *serverNode, SessionInfo *sessionNode)
563 {
564     if (param == NULL || tmpAttr == NULL || serverNode == NULL || sessionNode == NULL) {
565         TRANS_LOGE(TRANS_SDK, "invalid param.");
566         return;
567     }
568     tmpAttr->fastTransData = NULL;
569     tmpAttr->fastTransDataSize = 0;
570     tmpAttr->dataType = sessionNode->info.flag;
571     tmpAttr->attr.streamAttr.streamType = sessionNode->info.streamType;
572     tmpAttr->linkTypeNum = 0;
573     param->sessionName = serverNode->sessionName;
574     param->peerSessionName = sessionNode->info.peerSessionName;
575     param->peerDeviceId = sessionNode->info.peerDeviceId;
576     param->groupId = "reserved";
577     param->attr = tmpAttr;
578     param->isQosLane = true;
579     param->actionId = sessionNode->actionId;
580 }
581 
ClientConvertRetVal(int32_t socket, int32_t *retOut)582 void ClientConvertRetVal(int32_t socket, int32_t *retOut)
583 {
584     if (retOut == NULL) {
585         TRANS_LOGE(TRANS_SDK, "invalid param.");
586         return;
587     }
588     SocketLifecycleData lifecycle;
589     (void)memset_s(&lifecycle, sizeof(SocketLifecycleData), 0, sizeof(SocketLifecycleData));
590     int32_t ret = GetSocketLifecycleAndSessionNameBySessionId(socket, NULL, &lifecycle);
591     if (ret != SOFTBUS_OK) {
592         TRANS_LOGE(TRANS_SDK, "get info fail, socket=%{public}d", socket);
593         return;
594     }
595 
596     if (lifecycle.bindErrCode == SOFTBUS_OK) {
597         TRANS_LOGE(TRANS_SDK, "bindErrCode is SOFTBUS_OK, socket=%{public}d", socket);
598         return;
599     }
600 
601     if (lifecycle.bindErrCode == SOFTBUS_TRANS_STOP_BIND_BY_TIMEOUT) {
602         *retOut = SOFTBUS_TRANS_REQUEST_LANE_TIMEOUT;
603         return;
604     }
605     *retOut = lifecycle.bindErrCode;
606 }
607 
ClientCleanUpIdleTimeoutSocket(const ListNode *destroyList)608 void ClientCleanUpIdleTimeoutSocket(const ListNode *destroyList)
609 {
610     if (destroyList == NULL || IsListEmpty(destroyList)) {
611         TRANS_LOGD(TRANS_SDK, "destroyList is empty.");
612         return;
613     }
614     DestroySessionInfo *destroyNode = NULL;
615     DestroySessionInfo *destroyNodeNext = NULL;
616     LIST_FOR_EACH_ENTRY_SAFE(destroyNode, destroyNodeNext, destroyList, DestroySessionInfo, node) {
617         int32_t id = destroyNode->sessionId;
618         (void)ClientDeleteRecvFileList(id);
619         (void)ClientTransCloseChannel(destroyNode->channelId, destroyNode->channelType);
620         TRANS_LOGI(TRANS_SDK, "session is idle, sessionId=%{public}d", id);
621         if (destroyNode->OnShutdown != NULL) {
622             destroyNode->OnShutdown(id, SHUTDOWN_REASON_TIMEOUT);
623             (void)TryDeleteEmptySessionServer(destroyNode->pkgName, destroyNode->sessionName);
624         }
625         ListDelete(&(destroyNode->node));
626         SoftBusFree(destroyNode);
627     }
628     TRANS_LOGD(TRANS_SDK, "ok");
629 }
630 
ClientCheckWaitTimeOut(const ClientSessionServer *serverNode, SessionInfo *sessionNode, int32_t waitOutSocket[], uint32_t capacity, uint32_t *num)631 void ClientCheckWaitTimeOut(const ClientSessionServer *serverNode, SessionInfo *sessionNode,
632     int32_t waitOutSocket[], uint32_t capacity, uint32_t *num)
633 {
634     if (sessionNode == NULL || waitOutSocket == NULL || num == NULL) {
635         TRANS_LOGE(TRANS_SDK, "invalid param.");
636         return;
637     }
638     if (sessionNode->enableStatus == ENABLE_STATUS_SUCCESS &&
639         strcmp(serverNode->sessionName, ISHARE_AUTH_SESSION) != 0) {
640         return;
641     }
642 
643     sessionNode->lifecycle.waitTime += TIMER_TIMEOUT;
644     if (sessionNode->lifecycle.maxWaitTime == 0 ||
645         sessionNode->lifecycle.waitTime <= sessionNode->lifecycle.maxWaitTime) {
646         TRANS_LOGD(TRANS_SDK, "no wait timeout, socket=%{public}d", sessionNode->sessionId);
647         return;
648     }
649 
650     TRANS_LOGW(TRANS_SDK, "bind time out socket=%{public}d", sessionNode->sessionId);
651     // stop check time out
652     sessionNode->lifecycle.maxWaitTime = 0;
653 
654     uint32_t tmpNum = *num;
655     if (tmpNum + 1 > capacity) {
656         TRANS_LOGE(TRANS_SDK, "socket num invalid tmpNum=%{public}u, capacity=%{public}u", tmpNum, capacity);
657         return;
658     }
659     waitOutSocket[tmpNum] = sessionNode->sessionId;
660     *num = tmpNum + 1;
661 }
662 
CleanUpTimeoutAuthSession(int32_t sessionId)663 static bool CleanUpTimeoutAuthSession(int32_t sessionId)
664 {
665     SocketLifecycleData lifecycle;
666     (void)memset_s(&lifecycle, sizeof(SocketLifecycleData), 0, sizeof(SocketLifecycleData));
667     char sessionName[SESSION_NAME_SIZE_MAX] = { 0 };
668     int32_t ret = GetSocketLifecycleAndSessionNameBySessionId(sessionId, sessionName, &lifecycle);
669     if (ret != SOFTBUS_OK) {
670         TRANS_LOGE(TRANS_SDK, "Get sessionId=%{public}d name failed, ret=%{public}d", sessionId, ret);
671         return false;
672     }
673 
674     if (strcmp(sessionName, ISHARE_AUTH_SESSION) != 0) {
675         return false;
676     }
677 
678     TRANS_LOGI(TRANS_SDK, "sessionId=%{public}d is idle timeout.", sessionId);
679     CloseSession(sessionId);
680     return true;
681 }
682 
ClientCleanUpWaitTimeoutSocket(int32_t waitOutSocket[], uint32_t waitOutNum)683 void ClientCleanUpWaitTimeoutSocket(int32_t waitOutSocket[], uint32_t waitOutNum)
684 {
685     if (waitOutSocket == NULL) {
686         TRANS_LOGE(TRANS_SDK, "invalid param.");
687         return;
688     }
689     bool tmpIsServer = false;
690     SessionListenerAdapter callback = { 0 };
691     for (uint32_t i = 0; i < waitOutNum; ++i) {
692         TRANS_LOGI(TRANS_SDK, "time out shutdown socket=%{public}d", waitOutSocket[i]);
693         SessionEnableStatus enableStatus = ENABLE_STATUS_INIT;
694         int32_t ret = ClientGetChannelBySessionId(waitOutSocket[i], NULL, NULL, &enableStatus);
695         if (ret != SOFTBUS_OK) {
696             TRANS_LOGI(TRANS_SDK, "socket get channel failed, socket=%{public}d", waitOutSocket[i]);
697             continue;
698         }
699         if (enableStatus == ENABLE_STATUS_SUCCESS) {
700             if (CleanUpTimeoutAuthSession(waitOutSocket[i])) {
701                 continue;
702             }
703             TRANS_LOGI(TRANS_SDK, "socket has enabled, need not shutdown, socket=%{public}d", waitOutSocket[i]);
704             continue;
705         }
706         ClientGetSessionCallbackAdapterById(waitOutSocket[i], &callback, &tmpIsServer);
707         if (callback.socketClient.OnError != NULL) {
708             (void)callback.socketClient.OnError(waitOutSocket[i], SOFTBUS_TRANS_STOP_BIND_BY_TIMEOUT);
709         }
710         ClientShutdown(waitOutSocket[i], SOFTBUS_TRANS_STOP_BIND_BY_TIMEOUT);
711     }
712 }
713 
ClientUpdateIdleTimeout(const ClientSessionServer *serverNode, SessionInfo *sessionNode, ListNode *destroyList)714 void ClientUpdateIdleTimeout(const ClientSessionServer *serverNode, SessionInfo *sessionNode, ListNode *destroyList)
715 {
716     if (serverNode == NULL || sessionNode == NULL || destroyList == NULL) {
717         TRANS_LOGE(TRANS_SDK, "invalid param.");
718         return;
719     }
720     if (sessionNode->role != SESSION_ROLE_CLIENT || sessionNode->enableStatus != ENABLE_STATUS_SUCCESS) {
721         return;
722     }
723 
724     sessionNode->timeout += TIMER_TIMEOUT;
725     if (sessionNode->maxIdleTime == 0 || sessionNode->timeout <= sessionNode->maxIdleTime) {
726         return;
727     }
728 
729     DestroySessionInfo *destroyNode = CreateDestroySessionNode(sessionNode, serverNode);
730     if (destroyNode == NULL) {
731         TRANS_LOGE(TRANS_SDK, "failed to create destory session Node, sessionId=%{public}d", sessionNode->sessionId);
732         return;
733     }
734     ListAdd(destroyList, &(destroyNode->node));
735     DestroySessionId();
736     ListDelete(&sessionNode->node);
737     SoftBusFree(sessionNode);
738 }
739 
ReCreateSessionServerToServer(ListNode *sessionServerInfoList)740 int32_t ReCreateSessionServerToServer(ListNode *sessionServerInfoList)
741 {
742     TRANS_LOGD(TRANS_SDK, "enter.");
743     if (sessionServerInfoList == NULL) {
744         TRANS_LOGE(TRANS_INIT, "session server list not init");
745         return SOFTBUS_INVALID_PARAM;
746     }
747 
748     SessionServerInfo *infoNode = NULL;
749     SessionServerInfo *infoNodeNext = NULL;
750     char *tmpName = NULL;
751     LIST_FOR_EACH_ENTRY_SAFE(infoNode, infoNodeNext, sessionServerInfoList, SessionServerInfo, node) {
752         int32_t ret = ServerIpcCreateSessionServer(infoNode->pkgName, infoNode->sessionName);
753         Anonymize(infoNode->sessionName, &tmpName);
754         TRANS_LOGI(TRANS_SDK, "sessionName=%{public}s, pkgName=%{public}s, ret=%{public}d",
755             AnonymizeWrapper(tmpName), infoNode->pkgName, ret);
756         AnonymizeFree(tmpName);
757         ListDelete(&infoNode->node);
758         SoftBusFree(infoNode);
759     }
760 
761     TRANS_LOGI(TRANS_SDK, "ok");
762     return SOFTBUS_OK;
763 }
764 
FillDfsSocketParam( SessionParam *param, SessionAttribute *tmpAttr, ClientSessionServer *serverNode, SessionInfo *sessionNode)765 void FillDfsSocketParam(
766     SessionParam *param, SessionAttribute *tmpAttr, ClientSessionServer *serverNode, SessionInfo *sessionNode)
767 {
768     if (param == NULL || tmpAttr == NULL || serverNode == NULL || sessionNode == NULL) {
769         TRANS_LOGE(TRANS_SDK, "invalid param.");
770         return;
771     }
772     tmpAttr->fastTransData = NULL;
773     tmpAttr->fastTransDataSize = 0;
774     tmpAttr->dataType = sessionNode->info.flag;
775     tmpAttr->attr.streamAttr.streamType = sessionNode->info.streamType;
776     // 2 means has two linkType
777     tmpAttr->linkTypeNum = 2;
778     tmpAttr->linkType[0] = LINK_TYPE_WIFI_WLAN_5G;
779     tmpAttr->linkType[1] = LINK_TYPE_WIFI_WLAN_2G;
780     param->sessionName = serverNode->sessionName;
781     param->peerSessionName = sessionNode->info.peerSessionName;
782     param->peerDeviceId = sessionNode->info.peerDeviceId;
783     param->groupId = "reserved";
784     param->attr = tmpAttr;
785     param->isQosLane = false;
786     param->qosCount = 0;
787     (void)memset_s(param->qos, sizeof(param->qos), 0, sizeof(param->qos));
788     param->isAsync = false;
789 }
790 
GetQosValue(const QosTV *qos, uint32_t qosCount, QosType type, int32_t *value, int32_t defVal)791 int32_t GetQosValue(const QosTV *qos, uint32_t qosCount, QosType type, int32_t *value, int32_t defVal)
792 {
793     if (!IsValidQosInfo(qos, qosCount) || value == NULL) {
794         TRANS_LOGE(TRANS_SDK, "invalid param");
795         return SOFTBUS_INVALID_PARAM;
796     }
797 
798     if (qos == NULL || qosCount == 0) {
799         TRANS_LOGW(TRANS_SDK, "no qos info, use defVal");
800         *value = defVal;
801         return SOFTBUS_OK;
802     }
803 
804     for (uint32_t i = 0; i < qosCount; i++) {
805         if (qos[i].qos != type) {
806             continue;
807         }
808         *value = qos[i].value;
809         return SOFTBUS_OK;
810     }
811     *value = defVal;
812     return SOFTBUS_OK;
813 }
814 
ClientGrantPermission(int uid, int pid, const char *busName)815 int32_t ClientGrantPermission(int uid, int pid, const char *busName)
816 {
817     if (uid < 0 || pid < 0 || busName == NULL) {
818         TRANS_LOGW(TRANS_SDK, "invalid parameter");
819         return SOFTBUS_INVALID_PARAM;
820     }
821     char *tmpName = NULL;
822     Anonymize(busName, &tmpName);
823     TRANS_LOGI(TRANS_SDK, "sessionName=%{public}s", AnonymizeWrapper(tmpName));
824     AnonymizeFree(tmpName);
825     int32_t ret = ServerIpcGrantPermission(uid, pid, busName);
826     if (ret != SOFTBUS_OK) {
827         TRANS_LOGE(TRANS_SDK, "server grant permission failed, ret=%{public}d", ret);
828     }
829     return ret;
830 }
831 
ClientRemovePermission(const char *busName)832 int32_t ClientRemovePermission(const char *busName)
833 {
834     if (busName == NULL) {
835         TRANS_LOGW(TRANS_SDK, "invalid parameter");
836         return SOFTBUS_INVALID_PARAM;
837     }
838     char *tmpName = NULL;
839     Anonymize(busName, &tmpName);
840     TRANS_LOGI(TRANS_SDK, "sessionName=%{public}s", AnonymizeWrapper(tmpName));
841     AnonymizeFree(tmpName);
842     int32_t ret = ServerIpcRemovePermission(busName);
843     if (ret != SOFTBUS_OK) {
844         TRANS_LOGE(TRANS_SDK, "server remove permission failed, ret=%{public}d", ret);
845     }
846     return ret;
847 }
848 
ClientDeleteSocketSession(int32_t sessionId)849 int32_t ClientDeleteSocketSession(int32_t sessionId)
850 {
851     if (sessionId <= 0) {
852         TRANS_LOGE(TRANS_SDK, "Invalid sessionId=%{public}d", sessionId);
853         return SOFTBUS_INVALID_PARAM;
854     }
855 
856     char pkgName[PKG_NAME_SIZE_MAX] = { 0 };
857     char sessionName[SESSION_NAME_SIZE_MAX] = { 0 };
858     int32_t ret = DeleteSocketSession(sessionId, pkgName, sessionName);
859     if (ret != SOFTBUS_OK) {
860         TRANS_LOGE(TRANS_SDK, "failed delete session");
861         return ret;
862     }
863 
864     ret = TryDeleteEmptySessionServer(pkgName, sessionName);
865     if (ret != SOFTBUS_OK) {
866         TRANS_LOGE(TRANS_SDK, "delete empty session server failed, ret=%{public}d", ret);
867         return ret;
868     }
869     return SOFTBUS_OK;
870 }
871