1 /*
2 * Copyright (c) 2021 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_tcp_direct_manager.h"
17
18 #include <securec.h>
19
20 #include "client_trans_tcp_direct_callback.h"
21 #include "client_trans_tcp_direct_listener.h"
22 #include "softbus_adapter_mem.h"
23 #include "softbus_base_listener.h"
24 #include "softbus_def.h"
25 #include "softbus_errcode.h"
26 #include "softbus_log.h"
27 #include "softbus_socket.h"
28 #include "softbus_utils.h"
29 #include "trans_pending_pkt.h"
30 #include "trans_server_proxy.h"
31
32 #define HEART_TIME 300
33 #define USER_TIME_OUT (30 * 1000)
34
35 static SoftBusList *g_tcpDirectChannelInfoList = NULL;
36
TransTdcGetInfoById(int32_t channelId,TcpDirectChannelInfo * info)37 TcpDirectChannelInfo *TransTdcGetInfoById(int32_t channelId, TcpDirectChannelInfo *info)
38 {
39 if (info == NULL) {
40 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s param invalid.", __func__);
41 return NULL;
42 }
43 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
44 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s lock failed", __func__);
45 return NULL;
46 }
47
48 TcpDirectChannelInfo *item = NULL;
49 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
50 if (item->channelId == channelId) {
51 (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
52 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
53 return item;
54 }
55 }
56
57 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
58 return NULL;
59 }
60
TransTdcGetInfoByIdWithIncSeq(int32_t channelId,TcpDirectChannelInfo * info)61 TcpDirectChannelInfo *TransTdcGetInfoByIdWithIncSeq(int32_t channelId, TcpDirectChannelInfo *info)
62 {
63 if (info == NULL) {
64 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s param invalid.", __func__);
65 return NULL;
66 }
67 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
68 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s lock failed", __func__);
69 return NULL;
70 }
71
72 TcpDirectChannelInfo *item = NULL;
73 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
74 if (item->channelId == channelId) {
75 (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
76 item->detail.sequence++;
77 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
78 return item;
79 }
80 }
81
82 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
83 return NULL;
84 }
85
TransTdcGetInfoByFd(int32_t fd,TcpDirectChannelInfo * info)86 NO_SANITIZE("cfi") TcpDirectChannelInfo *TransTdcGetInfoByFd(int32_t fd, TcpDirectChannelInfo *info)
87 {
88 if (info == NULL) {
89 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s param invalid.", __func__);
90 return NULL;
91 }
92 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
93 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s lock failed", __func__);
94 return NULL;
95 }
96
97 TcpDirectChannelInfo *item = NULL;
98 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
99 if (item->detail.fd == fd) {
100 (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo));
101 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
102 return item;
103 }
104 }
105
106 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
107 return NULL;
108 }
109
TransTdcCloseChannel(int32_t channelId)110 void TransTdcCloseChannel(int32_t channelId)
111 {
112 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "[client]TransCloseTcpDirectChannel, cId [%d].", channelId);
113 if (ServerIpcCloseChannel(channelId, CHANNEL_TYPE_TCP_DIRECT) != SOFTBUS_OK) {
114 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "[client]close server tdc channel[%d] err.", channelId);
115 }
116
117 TcpDirectChannelInfo *item = NULL;
118 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
119 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]TransTdcCloseChannel lock failed");
120 return;
121 }
122
123 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
124 if (item->channelId == channelId) {
125 TransTdcReleaseFd(item->detail.fd);
126 ListDelete(&item->node);
127 SoftBusFree(item);
128 item = NULL;
129 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
130 DelPendingPacket(channelId, PENDING_TYPE_DIRECT);
131 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "[client]Delete chanel[%d] item success.", channelId);
132 return;
133 }
134 }
135
136 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]Target channel[%d] item not exist.", channelId);
137 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
138 }
139
TransGetNewTcpChannel(const ChannelInfo * channel)140 static TcpDirectChannelInfo *TransGetNewTcpChannel(const ChannelInfo *channel)
141 {
142 if (channel == NULL) {
143 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s param invalid", __func__);
144 return NULL;
145 }
146 TcpDirectChannelInfo *item = (TcpDirectChannelInfo *)SoftBusCalloc(sizeof(TcpDirectChannelInfo));
147 if (item == NULL) {
148 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s calloc failed", __func__);
149 return NULL;
150 }
151 item->channelId = channel->channelId;
152 item->detail.fd = channel->fd;
153 item->detail.channelType = channel->channelType;
154 if (memcpy_s(item->detail.sessionKey, SESSION_KEY_LENGTH, channel->sessionKey, SESSION_KEY_LENGTH) != EOK) {
155 SoftBusFree(item);
156 return NULL;
157 }
158 return item;
159 }
160
ClientTransCheckTdcChannelExist(int32_t channelId)161 static int32_t ClientTransCheckTdcChannelExist(int32_t channelId)
162 {
163 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
164 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[%s] lock failed.", __func__);
165 return SOFTBUS_ERR;
166 }
167 TcpDirectChannelInfo *item = NULL;
168 LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
169 if (item->channelId == channelId) {
170 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "tcp direct channel[%d] already exist.", channelId);
171 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
172 return SOFTBUS_ERR;
173 }
174 }
175 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
176 return SOFTBUS_OK;
177 }
178
TransTdcDelChannelInfo(int32_t channelId)179 static void TransTdcDelChannelInfo(int32_t channelId)
180 {
181 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "[client]TransDelTcpDirectChannelInfo, cId [%d].", channelId);
182
183 TcpDirectChannelInfo *item = NULL;
184 TcpDirectChannelInfo *nextNode = NULL;
185 if (g_tcpDirectChannelInfoList == NULL) {
186 return;
187 }
188 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
189 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]TransTdcDelChannelInfo lock failed");
190 return;
191 }
192
193 LIST_FOR_EACH_ENTRY_SAFE(item, nextNode, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) {
194 if (item->channelId == channelId) {
195 TransTdcReleaseFd(item->detail.fd);
196 ListDelete(&item->node);
197 SoftBusFree(item);
198 item = NULL;
199 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
200 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO,
201 "[client]Delete Tdc chanel info[%d] item success.", channelId);
202 return;
203 }
204 }
205
206 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]Target channel info[%d] item not exist.", channelId);
207 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
208 }
209
ClientTransTdcOnChannelOpened(const char * sessionName,const ChannelInfo * channel)210 int32_t ClientTransTdcOnChannelOpened(const char *sessionName, const ChannelInfo *channel)
211 {
212 if (sessionName == NULL || channel == NULL) {
213 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[%s] param invalid", __func__);
214 return SOFTBUS_ERR;
215 }
216 if (ClientTransCheckTdcChannelExist(channel->channelId) != SOFTBUS_OK) {
217 return SOFTBUS_ERR;
218 }
219 TcpDirectChannelInfo *item = TransGetNewTcpChannel(channel);
220 if (item == NULL) {
221 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get new channel[%d] err.", channel->channelId);
222 return SOFTBUS_ERR;
223 }
224 if (TransAddDataBufNode(channel->channelId, channel->fd) != SOFTBUS_OK) {
225 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR,
226 "add cId[%d] fd[%d] data buf node fail.", channel->channelId, channel->fd);
227 SoftBusFree(item);
228 return SOFTBUS_ERR;
229 }
230 if (TransTdcCreateListener(channel->fd) != SOFTBUS_OK) {
231 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "trans tdc fd[%d] create listener failed.", channel->fd);
232 goto EXIT_ERR;
233 }
234 if (ConnSetTcpKeepAlive(channel->fd, HEART_TIME) != SOFTBUS_OK) {
235 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ConnSetTcpKeepAlive failed, fd[%d].", channel->fd);
236 goto EXIT_ERR;
237 }
238 if (ConnSetTcpUserTimeOut(channel->fd, USER_TIME_OUT) != SOFTBUS_OK) {
239 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ConnSetTcpUserTimeOut failed, fd[%d].", channel->fd);
240 goto EXIT_ERR;
241 }
242 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
243 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[%s] lock failed.", __func__);
244 goto EXIT_ERR;
245 }
246 ListAdd(&g_tcpDirectChannelInfoList->list, &item->node);
247 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
248
249 if (ClientTransTdcOnSessionOpened(sessionName, channel) != SOFTBUS_OK) {
250 TransDelDataBufNode(channel->channelId);
251 TransTdcDelChannelInfo(channel->channelId);
252 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "notify on session opened err.");
253 return SOFTBUS_ERR;
254 }
255 return SOFTBUS_OK;
256 EXIT_ERR:
257 TransDelDataBufNode(channel->channelId);
258 SoftBusFree(item);
259 return SOFTBUS_ERR;
260 }
261
TransTdcManagerInit(const IClientSessionCallBack * callback)262 int32_t TransTdcManagerInit(const IClientSessionCallBack *callback)
263 {
264 g_tcpDirectChannelInfoList = CreateSoftBusList();
265 if (g_tcpDirectChannelInfoList == NULL || TransDataListInit() != SOFTBUS_OK) {
266 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "init tcp direct channel fail.");
267 return SOFTBUS_ERR;
268 }
269 if (ClientTransTdcSetCallBack(callback) != SOFTBUS_OK) {
270 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ClientTransTdcSetCallBack fail.");
271 return SOFTBUS_ERR;
272 }
273 if (PendingInit(PENDING_TYPE_DIRECT) == SOFTBUS_ERR) {
274 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "trans direct pending init failed.");
275 return SOFTBUS_ERR;
276 }
277 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "init tcp direct channel success.");
278 return SOFTBUS_OK;
279 }
280
TransTdcManagerDeinit(void)281 void TransTdcManagerDeinit(void)
282 {
283 if (g_tcpDirectChannelInfoList == NULL) {
284 return;
285 }
286
287 TransDataListDeinit();
288 DestroySoftBusList(g_tcpDirectChannelInfoList);
289 g_tcpDirectChannelInfoList = NULL;
290 PendingDeinit(PENDING_TYPE_DIRECT);
291 }
292
ClientTransTdcOnChannelOpenFailed(int32_t channelId,int32_t errCode)293 int32_t ClientTransTdcOnChannelOpenFailed(int32_t channelId, int32_t errCode)
294 {
295 return ClientTransTdcOnSessionOpenFailed(channelId, errCode);
296 }
297
TransTdcGetSessionKey(int32_t channelId,char * key,unsigned int len)298 int32_t TransTdcGetSessionKey(int32_t channelId, char *key, unsigned int len)
299 {
300 if (key == NULL) {
301 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s invalid param.", __func__);
302 return SOFTBUS_INVALID_PARAM;
303 }
304 TcpDirectChannelInfo channel;
305 if (TransTdcGetInfoById(channelId, &channel) == NULL) {
306 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get tdc channel[%d] info failed.", channelId);
307 return SOFTBUS_ERR;
308 }
309 if (memcpy_s(key, len, channel.detail.sessionKey, SESSION_KEY_LENGTH) != EOK) {
310 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "copy session key failed.");
311 return SOFTBUS_MEM_ERR;
312 }
313 return SOFTBUS_OK;
314 }
315
TransTdcGetHandle(int32_t channelId,int * handle)316 int32_t TransTdcGetHandle(int32_t channelId, int *handle)
317 {
318 if (handle == NULL) {
319 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s invalid param.", __func__);
320 return SOFTBUS_INVALID_PARAM;
321 }
322 TcpDirectChannelInfo channel;
323 if (TransTdcGetInfoById(channelId, &channel) == NULL) {
324 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get tdc channel[%d] info failed.", channelId);
325 return SOFTBUS_ERR;
326 }
327 *handle = channel.detail.fd;
328 return SOFTBUS_OK;
329 }
330
TransDisableSessionListener(int32_t channelId)331 int32_t TransDisableSessionListener(int32_t channelId)
332 {
333 TcpDirectChannelInfo channel;
334 if (TransTdcGetInfoById(channelId, &channel) == NULL) {
335 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get tdc channel[%d] info failed.", channelId);
336 return SOFTBUS_ERR;
337 }
338 if (channel.detail.fd < 0) {
339 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "invalid handle.");
340 return SOFTBUS_ERR;
341 }
342 return TransTdcStopRead(channel.detail.fd);
343 }
344