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 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
ClientTransTdcOnChannelOpened(const char * sessionName,const ChannelInfo * channel)179 int32_t ClientTransTdcOnChannelOpened(const char *sessionName, const ChannelInfo *channel)
180 {
181 if (sessionName == NULL || channel == NULL) {
182 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[%s] param invalid", __func__);
183 return SOFTBUS_ERR;
184 }
185 if (ClientTransCheckTdcChannelExist(channel->channelId) != SOFTBUS_OK) {
186 return SOFTBUS_ERR;
187 }
188 if (SoftBusMutexLock(&g_tcpDirectChannelInfoList->lock) != SOFTBUS_OK) {
189 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[%s] lock failed.", __func__);
190 return SOFTBUS_ERR;
191 }
192 TcpDirectChannelInfo *item = TransGetNewTcpChannel(channel);
193 if (item == NULL) {
194 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get new channel[%d] err.", channel->channelId);
195 goto EXIT_ERR;
196 }
197
198 if (TransAddDataBufNode(channel->channelId, channel->fd) != SOFTBUS_OK) {
199 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR,
200 "add cId[%d] fd[%d] data buf node fail.", channel->channelId, channel->fd);
201 SoftBusFree(item);
202 goto EXIT_ERR;
203 }
204 if (TransTdcCreateListener(channel->fd) != SOFTBUS_OK) {
205 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "trans tdc fd[%d] create listener failed.", channel->fd);
206 TransDelDataBufNode(channel->channelId);
207 SoftBusFree(item);
208 goto EXIT_ERR;
209 }
210 if (ConnSetTcpKeepAlive(channel->fd, HEART_TIME) != SOFTBUS_OK) {
211 TransDelDataBufNode(channel->channelId);
212 SoftBusFree(item);
213 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ConnSetTcpKeepAlive failed, fd[%d].", channel->fd);
214 goto EXIT_ERR;
215 }
216 if (ConnSetTcpUserTimeOut(channel->fd, USER_TIME_OUT) != SOFTBUS_OK) {
217 TransDelDataBufNode(channel->channelId);
218 SoftBusFree(item);
219 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ConnSetTcpUserTimeOut failed, fd[%d].", channel->fd);
220 goto EXIT_ERR;
221 }
222 ListAdd(&g_tcpDirectChannelInfoList->list, &item->node);
223 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
224
225 if (ClientTransTdcOnSessionOpened(sessionName, channel) != SOFTBUS_OK) {
226 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "notify on session opened err.");
227 return SOFTBUS_ERR;
228 }
229 return SOFTBUS_OK;
230 EXIT_ERR:
231 (void)SoftBusMutexUnlock(&g_tcpDirectChannelInfoList->lock);
232 return SOFTBUS_ERR;
233 }
234
TransTdcManagerInit(const IClientSessionCallBack * cb)235 int32_t TransTdcManagerInit(const IClientSessionCallBack *cb)
236 {
237 g_tcpDirectChannelInfoList = CreateSoftBusList();
238 if (g_tcpDirectChannelInfoList == NULL || TransDataListInit() != SOFTBUS_OK) {
239 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "init tcp direct channel fail.");
240 return SOFTBUS_ERR;
241 }
242 if (ClientTransTdcSetCallBack(cb) != SOFTBUS_OK) {
243 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "ClientTransTdcSetCallBack fail.");
244 return SOFTBUS_ERR;
245 }
246 if (PendingInit(PENDING_TYPE_DIRECT) == SOFTBUS_ERR) {
247 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "trans direct pending init failed.");
248 return SOFTBUS_ERR;
249 }
250 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "init tcp direct channel success.");
251 return SOFTBUS_OK;
252 }
253
TransTdcManagerDeinit(void)254 void TransTdcManagerDeinit(void)
255 {
256 if (g_tcpDirectChannelInfoList == NULL) {
257 return;
258 }
259
260 TransDataListDeinit();
261 DestroySoftBusList(g_tcpDirectChannelInfoList);
262 g_tcpDirectChannelInfoList = NULL;
263 PendingDeinit(PENDING_TYPE_DIRECT);
264 }
265
ClientTransTdcOnChannelOpenFailed(int32_t channelId,int32_t errCode)266 int32_t ClientTransTdcOnChannelOpenFailed(int32_t channelId, int32_t errCode)
267 {
268 return ClientTransTdcOnSessionOpenFailed(channelId, errCode);
269 }
270
TransTdcGetSessionKey(int32_t channelId,char * key,unsigned int len)271 int32_t TransTdcGetSessionKey(int32_t channelId, char *key, unsigned int len)
272 {
273 if (key == NULL) {
274 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s invalid param.", __func__);
275 return SOFTBUS_INVALID_PARAM;
276 }
277 TcpDirectChannelInfo channel;
278 if (TransTdcGetInfoById(channelId, &channel) == NULL) {
279 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get tdc channel[%d] info failed.", channelId);
280 return SOFTBUS_ERR;
281 }
282 if (memcpy_s(key, len, channel.detail.sessionKey, SESSION_KEY_LENGTH) != EOK) {
283 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "copy session key failed.");
284 return SOFTBUS_MEM_ERR;
285 }
286 return SOFTBUS_OK;
287 }
288
TransTdcGetHandle(int32_t channelId,int * handle)289 int32_t TransTdcGetHandle(int32_t channelId, int *handle)
290 {
291 if (handle == NULL) {
292 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s invalid param.", __func__);
293 return SOFTBUS_INVALID_PARAM;
294 }
295 TcpDirectChannelInfo channel;
296 if (TransTdcGetInfoById(channelId, &channel) == NULL) {
297 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get tdc channel[%d] info failed.", channelId);
298 return SOFTBUS_ERR;
299 }
300 *handle = channel.detail.fd;
301 return SOFTBUS_OK;
302 }
303
TransDisableSessionListener(int32_t channelId)304 int32_t TransDisableSessionListener(int32_t channelId)
305 {
306 TcpDirectChannelInfo channel;
307 if (TransTdcGetInfoById(channelId, &channel) == NULL) {
308 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get tdc channel[%d] info failed.", channelId);
309 return SOFTBUS_ERR;
310 }
311 if (channel.detail.fd < 0) {
312 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "invalid handle.");
313 return SOFTBUS_ERR;
314 }
315 return TransTdcStopRead(channel.detail.fd);
316 }
317