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