1 /*
2  * Copyright (c) 2023-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 "string.h"
17 #include <securec.h>
18 #include "anonymizer.h"
19 #include "client_trans_session_adapter.h"
20 #include "client_trans_session_manager.h"
21 #include "client_trans_socket_manager.h"
22 #include "client_trans_socket_option.h"
23 #include "inner_socket.h"
24 #include "socket.h"
25 #include "softbus_adapter_mem.h"
26 #include "softbus_def.h"
27 #include "softbus_error_code.h"
28 #include "softbus_utils.h"
29 #include "session_ipc_adapter.h"
30 #include "trans_log.h"
31 #include "trans_server_proxy.h"
32 #include "client_trans_session_service.h"
33 
CheckSocketInfoIsValid(const SocketInfo * info)34 static int32_t CheckSocketInfoIsValid(const SocketInfo *info)
35 {
36     if (!IsValidString(info->name, SESSION_NAME_SIZE_MAX - 1) ||
37         !IsValidString(info->pkgName, PKG_NAME_SIZE_MAX - 1)) {
38         TRANS_LOGE(TRANS_SDK, "invalid name or package name of socket");
39         return SOFTBUS_INVALID_PARAM;
40     }
41 
42     if (info->peerName != NULL && !IsValidString(info->peerName, SESSION_NAME_SIZE_MAX - 1)) {
43         char *anonySessionName = NULL;
44         Anonymize(info->peerName, &anonySessionName);
45         TRANS_LOGI(TRANS_SDK, "strcpy peerName failed, peerName=%{public}s, peerNameLen=%{public}zu",
46             anonySessionName, strlen(info->peerName));
47         AnonymizeFree(anonySessionName);
48         return SOFTBUS_INVALID_PARAM;
49     }
50 
51     if (info->peerNetworkId != NULL && !IsValidString(info->peerNetworkId, DEVICE_ID_SIZE_MAX - 1)) {
52         char *anonyNetworkId = NULL;
53         Anonymize(info->peerNetworkId, &anonyNetworkId);
54         TRANS_LOGI(TRANS_SDK, "strcpy peerNetworkId failed, peerNetworkId=%{public}s, peerNetworkIdLen=%{public}zu",
55             anonyNetworkId, strlen(info->peerNetworkId));
56         AnonymizeFree(anonyNetworkId);
57         return SOFTBUS_INVALID_PARAM;
58     }
59     return SOFTBUS_OK;
60 }
61 
PrintSocketInfo(const SocketInfo * info)62 static void PrintSocketInfo(const SocketInfo *info)
63 {
64     char *tmpMyName = NULL;
65     char *tmpPeerName = NULL;
66     char *tmpPeerNetworkId = NULL;
67     char *tmpPkgName = NULL;
68     Anonymize(info->name, &tmpMyName);
69     Anonymize(info->peerName, &tmpPeerName);
70     Anonymize(info->peerNetworkId, &tmpPeerNetworkId);
71     Anonymize(info->pkgName, &tmpPkgName);
72     TRANS_LOGI(TRANS_SDK,
73         "Socket: mySessionName=%{public}s, peerSessionName=%{public}s, peerNetworkId=%{public}s, "
74         "pkgName=%{public}s, dataType=%{public}d",
75         tmpMyName, tmpPeerName, tmpPeerNetworkId, tmpPkgName, info->dataType);
76     AnonymizeFree(tmpMyName);
77     AnonymizeFree(tmpPeerName);
78     AnonymizeFree(tmpPeerNetworkId);
79     AnonymizeFree(tmpPkgName);
80 }
81 
Socket(SocketInfo info)82 int32_t Socket(SocketInfo info)
83 {
84     int32_t ret = CheckSocketInfoIsValid(&info);
85     if (ret != SOFTBUS_OK) {
86         TRANS_LOGW(TRANS_SDK, "invalid SocketInfo");
87         return ret;
88     }
89 
90     PrintSocketInfo(&info);
91     ret = CreateSocket(info.pkgName, info.name);
92     if (ret != SOFTBUS_OK) {
93         TRANS_LOGE(TRANS_SDK, "CreateSocket failed, ret=%{public}d.", ret);
94         return ret;
95     }
96 
97     int32_t socketFd = INVALID_SESSION_ID;
98     char newSessionName[SESSION_NAME_SIZE_MAX +1] = {0};
99     if (CheckIsNormalApp(info.name)) {
100         if (strncpy_s(newSessionName, SESSION_NAME_SIZE_MAX + 1, info.name, strlen(info.name)) != EOK) {
101             TRANS_LOGE(TRANS_SDK, "copy session name failed");
102             return SOFTBUS_STRCPY_ERR;
103         }
104         if (!RemoveAppIdFromSessionName(info.name, newSessionName)) {
105             TRANS_LOGE(TRANS_SDK, "invalid bundlename or appId and delete appId failed");
106             return SOFTBUS_TRANS_NOT_FIND_APPID;
107         }
108         info.name = newSessionName;
109     }
110     ret = ClientAddSocket(&info, &socketFd);
111     SocketServerStateUpdate(info.name);
112     if (ret != SOFTBUS_OK) {
113         TRANS_LOGE(TRANS_SDK, "add socket failed, ret=%{public}d.", ret);
114         return ret;
115     }
116     TRANS_LOGD(TRANS_SDK, "create socket ok, socket=%{public}d", socketFd);
117     return socketFd;
118 }
119 
Listen(int32_t socket,const QosTV qos[],uint32_t qosCount,const ISocketListener * listener)120 int32_t Listen(int32_t socket, const QosTV qos[], uint32_t qosCount, const ISocketListener *listener)
121 {
122     TRANS_LOGD(TRANS_SDK, "Listen: socket=%{public}d", socket);
123     return ClientListen(socket, qos, qosCount, listener);
124 }
125 
StartBindWaitTimer(int32_t socket,const QosTV qos[],uint32_t qosCount)126 static int32_t StartBindWaitTimer(int32_t socket, const QosTV qos[], uint32_t qosCount)
127 {
128 #define DEFAULT_MAX_WAIT_TIMEOUT 30000 // 30s
129     int32_t maxWaitTime;
130     int32_t ret = GetQosValue(qos, qosCount, QOS_TYPE_MAX_WAIT_TIMEOUT, &maxWaitTime, DEFAULT_MAX_WAIT_TIMEOUT);
131     if (ret != SOFTBUS_OK) {
132         TRANS_LOGE(TRANS_SDK, "get max wait timeout fail ret=%{public}d", ret);
133         return ret;
134     }
135 
136     if (maxWaitTime <= 0) {
137         TRANS_LOGE(TRANS_SDK, "invalid max wait timeout. maxWaitTime=%{public}d", maxWaitTime);
138         return SOFTBUS_INVALID_PARAM;
139     }
140 
141     return ClientHandleBindWaitTimer(socket, (uint32_t)maxWaitTime, TIMER_ACTION_START);
142 }
143 
Bind(int32_t socket,const QosTV qos[],uint32_t qosCount,const ISocketListener * listener)144 int32_t Bind(int32_t socket, const QosTV qos[], uint32_t qosCount, const ISocketListener *listener)
145 {
146     TRANS_LOGI(TRANS_SDK, "Bind: socket=%{public}d", socket);
147     if (IsSessionExceedLimit()) {
148         TRANS_LOGE(TRANS_SDK, "Bind failed, over session num limit");
149         return SOFTBUS_TRANS_SESSION_CNT_EXCEEDS_LIMIT;
150     }
151     int32_t ret = StartBindWaitTimer(socket, qos, qosCount);
152     if (ret == SOFTBUS_ALREADY_TRIGGERED) {
153         TRANS_LOGW(TRANS_SDK, "already success, socket=%{public}d", socket);
154         return SOFTBUS_OK;
155     } else if (ret != SOFTBUS_OK) {
156         TRANS_LOGE(TRANS_SDK, "Start timer failed, ret=%{public}d", ret);
157         return ret;
158     }
159 
160     ret = ClientBind(socket, qos, qosCount, listener, false);
161     TRANS_LOGI(TRANS_SDK, "Bind end, stop timer, socket=%{public}d", socket);
162     (void)ClientHandleBindWaitTimer(socket, 0, TIMER_ACTION_STOP);
163     if (ret != SOFTBUS_OK) {
164         (void)SetSessionStateBySessionId(socket, SESSION_STATE_INIT, 0);
165     }
166     return ret;
167 }
168 
BindAsync(int32_t socket,const QosTV qos[],uint32_t qosCount,const ISocketListener * listener)169 int32_t BindAsync(int32_t socket, const QosTV qos[], uint32_t qosCount, const ISocketListener *listener)
170 {
171     TRANS_LOGI(TRANS_SDK, "Bind async socket=%{public}d", socket);
172     if (IsSessionExceedLimit()) {
173         TRANS_LOGE(TRANS_SDK, "Bind async failed, over session num limit");
174         return SOFTBUS_TRANS_SESSION_CNT_EXCEEDS_LIMIT;
175     }
176 
177     int32_t ret = StartBindWaitTimer(socket, qos, qosCount);
178     if (ret == SOFTBUS_ALREADY_TRIGGERED) {
179         TRANS_LOGW(TRANS_SDK, "already success, socket=%{public}d", socket);
180         return SOFTBUS_OK;
181     } else if (ret != SOFTBUS_OK) {
182         TRANS_LOGE(TRANS_SDK, "Start timer failed, ret=%{public}d, socket=%{public}d", ret, socket);
183         return ret;
184     }
185 
186     ret = ClientBind(socket, qos, qosCount, listener, true);
187     if (ret != SOFTBUS_OK) {
188         TRANS_LOGE(TRANS_SDK, "BindAsync fail, stop timer, ret=%{public}d, socket=%{public}d", ret, socket);
189         (void)ClientHandleBindWaitTimer(socket, 0, TIMER_ACTION_STOP);
190         (void)SetSessionStateBySessionId(socket, SESSION_STATE_INIT, 0);
191     }
192     return ret;
193 }
194 
Shutdown(int32_t socket)195 void Shutdown(int32_t socket)
196 {
197     TRANS_LOGI(TRANS_SDK, "Shutdown: socket=%{public}d", socket);
198     (void)ClientHandleBindWaitTimer(socket, 0, TIMER_ACTION_STOP);
199     ClientShutdown(socket, SOFTBUS_TRANS_STOP_BIND_BY_CANCEL);
200 }
201 
EvaluateQos(const char * peerNetworkId,TransDataType dataType,const QosTV * qos,uint32_t qosCount)202 int32_t EvaluateQos(const char *peerNetworkId, TransDataType dataType, const QosTV *qos, uint32_t qosCount)
203 {
204     if (!IsValidString(peerNetworkId, DEVICE_ID_SIZE_MAX) || dataType >= DATA_TYPE_BUTT ||
205         (qos == NULL && qosCount != 0) || (qosCount > QOS_TYPE_BUTT)) {
206         TRANS_LOGE(TRANS_SDK, "invalid param");
207         return SOFTBUS_INVALID_PARAM;
208     }
209 
210     return ServerIpcEvaluateQos(peerNetworkId, dataType, qos, qosCount);
211 }
212 
GetMtuSize(int32_t socket,uint32_t * mtuSize)213 int32_t GetMtuSize(int32_t socket, uint32_t *mtuSize)
214 {
215     TRANS_LOGI(TRANS_SDK, "GetMtuSize: socket=%{public}d", socket);
216     return GetSocketMtuSize(socket, mtuSize);
217 }
218 
DBinderGrantPermission(int32_t uid,int32_t pid,const char * socketName)219 int32_t DBinderGrantPermission(int32_t uid, int32_t pid, const char *socketName)
220 {
221     return ClientGrantPermission(uid, pid, socketName);
222 }
223 
DBinderRemovePermission(const char * socketName)224 int32_t DBinderRemovePermission(const char *socketName)
225 {
226     return ClientRemovePermission(socketName);
227 }
228 
DfsBind(int32_t socket,const ISocketListener * listener)229 int32_t DfsBind(int32_t socket, const ISocketListener *listener)
230 {
231     return ClientDfsBind(socket, listener);
232 }
233 
CheckSocketOptParam(OptLevel level,OptType optType,void * optValue)234 static int32_t CheckSocketOptParam(OptLevel level, OptType optType, void *optValue)
235 {
236     if (level < 0 || level >= OPT_LEVEL_BUTT) {
237         TRANS_LOGE(TRANS_SDK, "invalid level.");
238         return SOFTBUS_INVALID_PARAM;
239     }
240     if (optType < 0) {
241         TRANS_LOGE(TRANS_SDK, "invalid optType.");
242         return SOFTBUS_INVALID_PARAM;
243     }
244     if (optValue == NULL) {
245         TRANS_LOGE(TRANS_SDK, "invalid optValue.");
246         return SOFTBUS_INVALID_PARAM;
247     }
248     return SOFTBUS_OK;
249 }
250 
SetSocketOpt(int32_t socket,OptLevel level,OptType optType,void * optValue,int32_t optValueSize)251 int32_t SetSocketOpt(int32_t socket, OptLevel level, OptType optType, void *optValue, int32_t optValueSize)
252 {
253     int32_t ret = CheckSocketOptParam(level, optType, optValue);
254     if (ret != SOFTBUS_OK) {
255         return ret;
256     }
257     if (optValueSize <= 0) {
258         TRANS_LOGE(TRANS_SDK, "invalid optValueSize.");
259         return SOFTBUS_INVALID_PARAM;
260     }
261     switch (optType) {
262         case OPT_TYPE_MAX_BUFFER:
263         case OPT_TYPE_FIRST_PACKAGE:
264         case OPT_TYPE_MAX_IDLE_TIMEOUT:
265             ret = SOFTBUS_NOT_IMPLEMENT;
266             break;
267         default:
268             ret = SetExtSocketOpt(socket, level, optType, optValue, optValueSize);
269             break;
270     }
271     return ret;
272 }
273 
GetSocketOpt(int32_t socket,OptLevel level,OptType optType,void * optValue,int32_t * optValueSize)274 int32_t GetSocketOpt(int32_t socket, OptLevel level, OptType optType, void *optValue, int32_t *optValueSize)
275 {
276     int32_t ret = CheckSocketOptParam(level, optType, optValue);
277     if (ret != SOFTBUS_OK) {
278         return ret;
279     }
280     if (optValueSize == NULL) {
281         TRANS_LOGE(TRANS_SDK, "invalid optValueSize.");
282         return SOFTBUS_INVALID_PARAM;
283     }
284     switch (optType) {
285         case OPT_TYPE_MAX_BUFFER:
286         case OPT_TYPE_FIRST_PACKAGE:
287         case OPT_TYPE_MAX_IDLE_TIMEOUT:
288             ret = SOFTBUS_NOT_IMPLEMENT;
289             break;
290         default:
291             ret = GetExtSocketOpt(socket, level, optType, optValue, optValueSize);
292             break;
293     }
294     return ret;
295 }