1 /*
2 * Copyright (c) 2021-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 "trans_tcp_direct_listener.h"
17
18 #include <arpa/inet.h>
19 #include <securec.h>
20 #include "auth_interface.h"
21 #include "bus_center_manager.h"
22 #include "lnn_distributed_net_ledger.h"
23 #include "softbus_adapter_crypto.h"
24 #include "softbus_adapter_hitrace.h"
25 #include "softbus_adapter_mem.h"
26 #include "softbus_base_listener.h"
27 #include "softbus_def.h"
28 #include "softbus_errcode.h"
29 #include "softbus_message_open_channel.h"
30 #include "softbus_socket.h"
31 #include "trans_channel_common.h"
32 #include "trans_channel_manager.h"
33 #include "trans_event.h"
34 #include "trans_log.h"
35 #include "trans_tcp_direct_message.h"
36 #include "trans_tcp_direct_sessionconn.h"
37
38 #define ID_OFFSET (1)
39 #define OHOS_TYPE_UNKNOWN (-1)
40 #define OH_OS_TYPE 10
41 #define HO_OS_TYPE 11
42
SwitchAuthLinkTypeToFlagType(AuthLinkType type)43 uint32_t SwitchAuthLinkTypeToFlagType(AuthLinkType type)
44 {
45 switch (type) {
46 case AUTH_LINK_TYPE_BR:
47 return FLAG_BR;
48 case AUTH_LINK_TYPE_BLE:
49 return FLAG_BLE;
50 case AUTH_LINK_TYPE_P2P:
51 return FLAG_P2P;
52 case AUTH_LINK_TYPE_ENHANCED_P2P:
53 return FLAG_ENHANCE_P2P;
54 default:
55 return FLAG_WIFI;
56 }
57 }
58
GetCipherFlagByAuthId(AuthHandle authHandle,uint32_t * flag,bool * isAuthServer,bool isLegacyOs)59 int32_t GetCipherFlagByAuthId(AuthHandle authHandle, uint32_t *flag, bool *isAuthServer, bool isLegacyOs)
60 {
61 if (flag == NULL || isAuthServer == NULL) {
62 TRANS_LOGE(TRANS_CTRL, "param invalid");
63 return SOFTBUS_INVALID_PARAM;
64 }
65 AuthConnInfo info;
66 int32_t ret = AuthGetServerSide(authHandle.authId, isAuthServer);
67 if (ret != SOFTBUS_OK) {
68 TRANS_LOGE(TRANS_CTRL, "get auth server side fail authId=%{public}" PRId64, authHandle.authId);
69 return ret;
70 }
71 ret = AuthGetConnInfo(authHandle, &info);
72 if (ret != SOFTBUS_OK) {
73 TRANS_LOGE(TRANS_CTRL, "get authinfo fail authId=%{public}" PRId64, authHandle.authId);
74 return ret;
75 }
76 // In order to be compatible with legacyOs versions that only has AUTH_P2P
77 if (isLegacyOs && info.type == AUTH_LINK_TYPE_ENHANCED_P2P) {
78 *flag = FLAG_P2P;
79 TRANS_LOGW(TRANS_CTRL,
80 "peer device is legacyOs, change flag form P2P_ENHANCE to P2P flag=0x%{public}x", *flag);
81 return SOFTBUS_OK;
82 }
83 *flag = SwitchAuthLinkTypeToFlagType(info.type);
84 TRANS_LOGI(TRANS_CTRL, "get auth link type=%{public}d, flag=0x%{public}x", info.type, *flag);
85 return SOFTBUS_OK;
86 }
87
StartVerifySession(SessionConn * conn)88 static int32_t StartVerifySession(SessionConn *conn)
89 {
90 TRANS_LOGI(TRANS_CTRL, "verify enter. channelId=%{public}d, fd=%{public}d", conn->channelId, conn->appInfo.fd);
91 if (SoftBusGenerateSessionKey(conn->appInfo.sessionKey, SESSION_KEY_LENGTH) != SOFTBUS_OK) {
92 TRANS_LOGE(TRANS_CTRL,
93 "Generate SessionKey failed channelId=%{public}d, fd=%{public}d",
94 conn->channelId, conn->appInfo.fd);
95 return SOFTBUS_TRANS_TCP_GENERATE_SESSIONKEY_FAILED;
96 }
97 SetSessionKeyByChanId(conn->channelId, conn->appInfo.sessionKey, sizeof(conn->appInfo.sessionKey));
98
99 bool isAuthServer = false;
100 uint32_t cipherFlag = FLAG_WIFI;
101 bool isLegacyOs = IsPeerDeviceLegacyOs(conn->appInfo.osType);
102 if (GetCipherFlagByAuthId(conn->authHandle, &cipherFlag, &isAuthServer, isLegacyOs)) {
103 TRANS_LOGE(TRANS_CTRL,
104 "get cipher flag failed channelId=%{public}d, fd=%{public}d",
105 conn->channelId, conn->appInfo.fd);
106 return SOFTBUS_TRANS_GET_CIPHER_FAILED;
107 }
108 uint64_t seq = TransTdcGetNewSeqId();
109 if (isAuthServer) {
110 seq |= AUTH_CONN_SERVER_SIDE;
111 }
112
113 char *bytes = PackRequest(&conn->appInfo);
114 if (bytes == NULL) {
115 TRANS_LOGE(TRANS_CTRL,
116 "Pack Request failed channelId=%{public}d, fd=%{public}d",
117 conn->channelId, conn->appInfo.fd);
118 return SOFTBUS_TRANS_PACK_REQUEST_FAILED;
119 }
120 TdcPacketHead packetHead = {
121 .magicNumber = MAGIC_NUMBER,
122 .module = MODULE_SESSION,
123 .seq = seq,
124 .flags = (FLAG_REQUEST | cipherFlag),
125 .dataLen = strlen(bytes), /* reset after encrypt */
126 };
127 if (conn->isMeta) {
128 packetHead.flags |= FLAG_AUTH_META;
129 }
130 int32_t ret = TransTdcPostBytes(conn->channelId, &packetHead, bytes);
131 cJSON_free(bytes);
132 if (ret != SOFTBUS_OK) {
133 TRANS_LOGE(TRANS_CTRL,
134 "TransTdc post bytes failed channelId=%{public}d, fd=%{public}d, ret=%{public}d",
135 conn->channelId, conn->appInfo.fd, ret);
136 return ret;
137 }
138 TRANS_LOGI(TRANS_CTRL, "verify ok. channelId=%{public}d, fd=%{public}d", conn->channelId, conn->appInfo.fd);
139
140 return SOFTBUS_OK;
141 }
142
TransSetTcpDirectConnectType(int32_t * connectType,ListenerModule module)143 static void TransSetTcpDirectConnectType(int32_t *connectType, ListenerModule module)
144 {
145 if (module >= DIRECT_CHANNEL_SERVER_HML_START && module <= DIRECT_CHANNEL_SERVER_HML_END) {
146 *connectType = CONNECT_HML;
147 } else if (module == DIRECT_CHANNEL_SERVER_P2P) {
148 *connectType = CONNECT_P2P;
149 } else if (module == DIRECT_CHANNEL_SERVER_WIFI) {
150 *connectType = CONNECT_TCP;
151 }
152 }
153
CreateSessionConnNode(ListenerModule module,int fd,int32_t chanId,const ConnectOption * clientAddr)154 static int32_t CreateSessionConnNode(ListenerModule module, int fd, int32_t chanId, const ConnectOption *clientAddr)
155 {
156 SessionConn *conn = (SessionConn *)SoftBusCalloc(sizeof(SessionConn));
157 if (conn == NULL) {
158 TRANS_LOGE(TRANS_CTRL, "malloc fail in create session conn node.");
159 return SOFTBUS_MALLOC_ERR;
160 }
161 conn->appInfo.myData.apiVersion = API_V2;
162 conn->appInfo.fd = fd;
163 conn->serverSide = true;
164 conn->channelId = chanId;
165 conn->status = TCP_DIRECT_CHANNEL_STATUS_CONNECTING;
166 conn->timeout = 0;
167 conn->listenMod = module;
168 conn->authHandle.authId = AUTH_INVALID_ID;
169 conn->appInfo.routeType = (module == DIRECT_CHANNEL_SERVER_P2P) ? WIFI_P2P : WIFI_STA;
170 conn->appInfo.peerData.port = clientAddr->socketOption.port;
171 TransSetTcpDirectConnectType(&conn->appInfo.connectType, module);
172 int32_t ret =
173 LnnGetLocalStrInfo(STRING_KEY_UUID, conn->appInfo.myData.deviceId, sizeof(conn->appInfo.myData.deviceId));
174 if (ret != SOFTBUS_OK) {
175 TRANS_LOGE(TRANS_CTRL, "get local deviceId failed.");
176 SoftBusFree(conn);
177 return ret;
178 }
179
180 if (strcpy_s(conn->appInfo.peerData.addr, sizeof(conn->appInfo.peerData.addr), clientAddr->socketOption.addr) !=
181 EOK) {
182 TRANS_LOGE(TRANS_CTRL, "copy ip to app info failed.");
183 SoftBusFree(conn);
184 return SOFTBUS_STRCPY_ERR;
185 }
186 conn->appInfo.protocol = clientAddr->socketOption.protocol;
187
188 const char *authState = "";
189 if (strcpy_s(conn->appInfo.myData.authState, sizeof(conn->appInfo.myData.authState), authState) != EOK) {
190 TRANS_LOGE(TRANS_CTRL, "copy auth state to app info failed.");
191 SoftBusFree(conn);
192 return SOFTBUS_STRCPY_ERR;
193 }
194 ret = TransTdcAddSessionConn(conn);
195 if (ret != SOFTBUS_OK) {
196 TRANS_LOGE(TRANS_CTRL, "add session conn node failed.");
197 SoftBusFree(conn);
198 return ret;
199 }
200 ret = AddTrigger(module, fd, READ_TRIGGER);
201 if (ret != SOFTBUS_OK) {
202 TRANS_LOGE(TRANS_CTRL, "add trigger failed, delete session conn.");
203 TransDelSessionConnById(chanId);
204 return ret;
205 }
206
207 return SOFTBUS_OK;
208 }
209
TdcOnConnectEvent(ListenerModule module,int cfd,const ConnectOption * clientAddr)210 static int32_t TdcOnConnectEvent(ListenerModule module, int cfd, const ConnectOption *clientAddr)
211 {
212 if (cfd < 0 || clientAddr == NULL) {
213 TRANS_LOGW(TRANS_CTRL, "invalid param, cfd=%{public}d", cfd);
214 return SOFTBUS_INVALID_PARAM;
215 }
216 int32_t ret;
217 int32_t channelId = GenerateChannelId(true);
218 TransEventExtra extra = {
219 .socketName = NULL,
220 .peerNetworkId = NULL,
221 .calleePkg = NULL,
222 .callerPkg = NULL,
223 .socketFd = cfd,
224 .channelId = channelId
225 };
226 if (channelId <= INVALID_CHANNEL_ID) {
227 ret = SOFTBUS_TRANS_INVALID_CHANNEL_ID;
228 extra.result = EVENT_STAGE_RESULT_FAILED;
229 extra.errcode = ret;
230 TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL_SERVER, EVENT_STAGE_START_CONNECT, extra);
231 TRANS_LOGE(TRANS_CTRL, "channelId is invalid");
232 ConnShutdownSocket(cfd);
233 return ret;
234 }
235 ret = TransSrvAddDataBufNode(channelId, cfd); // fd != channelId
236 if (ret != SOFTBUS_OK) {
237 extra.result = EVENT_STAGE_RESULT_FAILED;
238 extra.errcode = ret;
239 TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL_SERVER, EVENT_STAGE_START_CONNECT, extra);
240 TRANS_LOGE(TRANS_CTRL, "create srv data buf node failed.");
241 ConnShutdownSocket(cfd);
242 return ret;
243 }
244
245 ret = CreateSessionConnNode(module, cfd, channelId, clientAddr);
246 if (ret != SOFTBUS_OK) {
247 extra.result = EVENT_STAGE_RESULT_FAILED;
248 extra.errcode = ret;
249 TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL_SERVER, EVENT_STAGE_START_CONNECT, extra);
250 TRANS_LOGE(TRANS_CTRL, "create session conn node fail, delete data buf node.");
251 TransSrvDelDataBufNode(channelId);
252 ConnShutdownSocket(cfd);
253 return ret;
254 }
255 extra.result = EVENT_STAGE_RESULT_OK;
256 TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL_SERVER, EVENT_STAGE_START_CONNECT, extra);
257 TRANS_LOGI(TRANS_CTRL, "tdc conn event cfd=%{public}d, channelId=%{public}d, module=%{public}d",
258 cfd, channelId, module);
259 return SOFTBUS_OK;
260 }
261
CloseTcpDirectFd(int fd)262 static void CloseTcpDirectFd(int fd)
263 {
264 #ifndef __LITEOS_M__
265 ConnCloseSocket(fd);
266 #else
267 (void)fd;
268 #endif
269 }
270
TransProcDataRes(ListenerModule module,int32_t ret,int32_t channelId,int32_t fd)271 static void TransProcDataRes(ListenerModule module, int32_t ret, int32_t channelId, int32_t fd)
272 {
273 if (ret != SOFTBUS_OK) {
274 TransEventExtra extra = {
275 .socketName = NULL,
276 .peerNetworkId = NULL,
277 .calleePkg = NULL,
278 .callerPkg = NULL,
279 .channelId = channelId,
280 .socketFd = fd,
281 .errcode = ret,
282 .result = EVENT_STAGE_RESULT_FAILED
283 };
284 SessionConn conn;
285 if (GetSessionConnById(channelId, &conn) != SOFTBUS_OK || !conn.serverSide) {
286 TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL, EVENT_STAGE_HANDSHAKE_REPLY, extra);
287 } else {
288 TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL_SERVER, EVENT_STAGE_HANDSHAKE_REPLY, extra);
289 }
290 (void)memset_s(conn.appInfo.sessionKey, sizeof(conn.appInfo.sessionKey), 0, sizeof(conn.appInfo.sessionKey));
291 DelTrigger(module, fd, READ_TRIGGER);
292 ConnShutdownSocket(fd);
293 (void)NotifyChannelOpenFailed(channelId, ret);
294 } else {
295 CloseTcpDirectFd(fd);
296 }
297 TransDelSessionConnById(channelId);
298 TransSrvDelDataBufNode(channelId);
299 }
300
ProcessSocketInEvent(SessionConn * conn,int fd)301 static int32_t ProcessSocketInEvent(SessionConn *conn, int fd)
302 {
303 int32_t ret = TransTdcSrvRecvData(conn->listenMod, conn->channelId, conn->authHandle.type);
304 if (ret == SOFTBUS_DATA_NOT_ENOUGH) {
305 return SOFTBUS_OK;
306 }
307 if (ret != SOFTBUS_OK) {
308 TRANS_LOGE(TRANS_CTRL, "Trans Srv Recv Data, ret=%{public}d.", ret);
309 }
310 TransProcDataRes(conn->listenMod, ret, conn->channelId, fd);
311 return ret;
312 }
313
ProcessSocketOutEvent(SessionConn * conn,int fd)314 static int32_t ProcessSocketOutEvent(SessionConn *conn, int fd)
315 {
316 int32_t ret = SOFTBUS_TCP_SOCKET_ERR;
317 if (conn->serverSide) {
318 return ret;
319 }
320 DelTrigger(conn->listenMod, fd, WRITE_TRIGGER);
321 if (AddTrigger(conn->listenMod, fd, READ_TRIGGER) != SOFTBUS_OK) {
322 TRANS_LOGE(TRANS_CTRL, "add trigger fail, module=%{public}d, fd=%{public}d", conn->listenMod, fd);
323 return SOFTBUS_TRANS_ADD_TRIGGER_FAILED;
324 }
325 ret = StartVerifySession(conn);
326 TransEventExtra extra = {
327 .socketName = NULL,
328 .peerNetworkId = NULL,
329 .calleePkg = NULL,
330 .callerPkg = NULL,
331 .socketFd = fd,
332 .channelId = conn->channelId,
333 .authId = conn->authHandle.authId,
334 .errcode = ret,
335 .result = (ret == SOFTBUS_OK) ? EVENT_STAGE_RESULT_OK : EVENT_STAGE_RESULT_FAILED
336 };
337 TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL, EVENT_STAGE_HANDSHAKE_START, extra);
338 if (ret != SOFTBUS_OK) {
339 TRANS_LOGE(TRANS_CTRL, "start verify session failed, ret = %{public}d", ret);
340 DelTrigger(conn->listenMod, fd, READ_TRIGGER);
341 ConnShutdownSocket(fd);
342 (void)NotifyChannelOpenFailed(conn->channelId, ret);
343 TransDelSessionConnById(conn->channelId);
344 TransSrvDelDataBufNode(conn->channelId);
345 }
346 return ret;
347 }
348
ProcessSocketExceptionEvent(SessionConn * conn,int fd)349 static void ProcessSocketExceptionEvent(SessionConn *conn, int fd)
350 {
351 TRANS_LOGE(TRANS_CTRL, "exception occurred.");
352 DelTrigger(conn->listenMod, fd, EXCEPT_TRIGGER);
353 ConnShutdownSocket(fd);
354 TransDelSessionConnById(conn->channelId);
355 TransSrvDelDataBufNode(conn->channelId);
356 }
357
TdcOnDataEvent(ListenerModule module,int events,int fd)358 static int32_t TdcOnDataEvent(ListenerModule module, int events, int fd)
359 {
360 (void)module;
361 SessionConn *conn = (SessionConn *)SoftBusCalloc(sizeof(SessionConn));
362 if (conn == NULL) {
363 TRANS_LOGE(TRANS_CTRL, "OnDataEvent malloc fail.");
364 return SOFTBUS_MALLOC_ERR;
365 }
366 if (GetSessionConnByFd(fd, conn) != SOFTBUS_OK || conn->appInfo.fd != fd) {
367 TRANS_LOGE(TRANS_CTRL, "fd is not exist tdc info. fd=%{public}d, appfd=%{public}d", fd, conn->appInfo.fd);
368 for (uint32_t i = DIRECT_CHANNEL_SERVER_P2P; i <= DIRECT_CHANNEL_SERVER_HML_END; i++) {
369 DelTrigger((ListenerModule)i, fd, READ_TRIGGER);
370 DelTrigger((ListenerModule)i, fd, WRITE_TRIGGER);
371 DelTrigger((ListenerModule)i, fd, EXCEPT_TRIGGER);
372 }
373 SoftBusFree(conn);
374 ConnShutdownSocket(fd);
375 return SOFTBUS_INVALID_FD;
376 }
377 SoftbusHitraceStart(SOFTBUS_HITRACE_ID_VALID, (uint64_t)(conn->channelId + ID_OFFSET));
378 int32_t ret = SOFTBUS_TRANS_TDC_ON_DATA_EVENT_FAILED;
379 if (events == SOFTBUS_SOCKET_IN) {
380 ret = ProcessSocketInEvent(conn, fd);
381 } else if (events == SOFTBUS_SOCKET_OUT) {
382 ret = ProcessSocketOutEvent(conn, fd);
383 } else if (events == SOFTBUS_SOCKET_EXCEPTION) {
384 ProcessSocketExceptionEvent(conn, fd);
385 }
386 (void)memset_s(conn->appInfo.sessionKey, sizeof(conn->appInfo.sessionKey), 0, sizeof(conn->appInfo.sessionKey));
387 SoftBusFree(conn);
388 return ret;
389 }
390
TransTdcStartSessionListener(ListenerModule module,const LocalListenerInfo * info)391 int32_t TransTdcStartSessionListener(ListenerModule module, const LocalListenerInfo *info)
392 {
393 if (info == NULL || (info->type != CONNECT_TCP && info->type != CONNECT_P2P && info->type != CONNECT_HML) ||
394 info->socketOption.port < 0) {
395 TRANS_LOGE(TRANS_CTRL, "Invalid para.");
396 return SOFTBUS_INVALID_PARAM;
397 }
398
399 static SoftbusBaseListener sessionListener = {
400 .onConnectEvent = TdcOnConnectEvent,
401 .onDataEvent = TdcOnDataEvent
402 };
403
404 TRANS_LOGI(TRANS_CTRL, "set listener for module=%{public}d.", module);
405 int serverPort = StartBaseListener(info, &sessionListener);
406 return serverPort;
407 }
408
TransTdcStopSessionListener(ListenerModule module)409 int32_t TransTdcStopSessionListener(ListenerModule module)
410 {
411 TransTdcStopSessionProc(module);
412 return StopBaseListener(module);
413 }