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_message.h"
17
18 #include <arpa/inet.h>
19 #include <securec.h>
20
21 #include "client_trans_tcp_direct_callback.h"
22 #include "client_trans_tcp_direct_manager.h"
23 #include "common_list.h"
24 #include "softbus_adapter_crypto.h"
25 #include "softbus_adapter_mem.h"
26 #include "softbus_adapter_socket.h"
27 #include "softbus_def.h"
28 #include "softbus_errcode.h"
29 #include "softbus_feature_config.h"
30 #include "softbus_log.h"
31 #include "softbus_socket.h"
32 #include "softbus_tcp_socket.h"
33 #include "softbus_utils.h"
34 #include "trans_pending_pkt.h"
35
36 #define ACK_SIZE 4
37 #define DATA_EXTEND_LEN (DC_DATA_HEAD_SIZE + OVERHEAD_LEN)
38 #define MIN_BUF_LEN (1024 + DATA_EXTEND_LEN)
39
40 #define BYTE_TOS 0x60
41 #define MESSAGE_TOS 0xC0
42
43 typedef struct {
44 ListNode node;
45 int32_t channelId;
46 int32_t fd;
47 uint32_t size;
48 char *data;
49 char *w;
50 } ClientDataBuf;
51
52 static uint32_t g_dataBufferMaxLen = 0;
53 static SoftBusList *g_tcpDataList = NULL;
54
PackTcpDataPacketHead(TcpDataPacketHead * data)55 static void PackTcpDataPacketHead(TcpDataPacketHead *data)
56 {
57 data->magicNumber = SoftBusHtoLl(data->magicNumber);
58 data->seq = (int32_t)SoftBusHtoLl((uint32_t)data->seq);
59 data->flags = SoftBusHtoLl(data->flags);
60 data->dataLen = SoftBusHtoLl(data->dataLen);
61 }
62
UnpackTcpDataPacketHead(TcpDataPacketHead * data)63 static void UnpackTcpDataPacketHead(TcpDataPacketHead *data)
64 {
65 data->magicNumber = SoftBusLtoHl(data->magicNumber);
66 data->seq = (int32_t)SoftBusLtoHl((uint32_t)data->seq);
67 data->flags = SoftBusLtoHl(data->flags);
68 data->dataLen = SoftBusLtoHl(data->dataLen);
69 }
70
TransTdcDecrypt(const char * sessionKey,const char * in,uint32_t inLen,char * out,uint32_t * outLen)71 static int32_t TransTdcDecrypt(const char *sessionKey, const char *in, uint32_t inLen, char *out, uint32_t *outLen)
72 {
73 AesGcmCipherKey cipherKey = {0};
74 cipherKey.keyLen = SESSION_KEY_LENGTH; // 256 bit encryption
75 if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey, SESSION_KEY_LENGTH) != EOK) {
76 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "memcpy key error.");
77 return SOFTBUS_ERR;
78 }
79 int32_t ret = SoftBusDecryptData(&cipherKey, (unsigned char*)in, inLen, (unsigned char*)out, outLen);
80 (void)memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey));
81 if (ret != SOFTBUS_OK) {
82 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "SoftBusDecryptData fail(=%d).", ret);
83 return SOFTBUS_DECRYPT_ERR;
84 }
85 return SOFTBUS_OK;
86 }
87
TransTdcEncryptWithSeq(const char * sessionKey,int32_t seqNum,const char * in,uint32_t inLen,char * out,uint32_t * outLen)88 static int32_t TransTdcEncryptWithSeq(const char *sessionKey, int32_t seqNum, const char *in, uint32_t inLen,
89 char *out, uint32_t *outLen)
90 {
91 AesGcmCipherKey cipherKey = {0};
92 cipherKey.keyLen = SESSION_KEY_LENGTH;
93 if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey, SESSION_KEY_LENGTH) != EOK) {
94 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "memcpy key error.");
95 return SOFTBUS_ERR;
96 }
97 int ret = SoftBusEncryptDataWithSeq(&cipherKey, (unsigned char*)in, inLen, (unsigned char*)out, outLen, seqNum);
98 (void)memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey));
99 if (ret != SOFTBUS_OK || *outLen != inLen + OVERHEAD_LEN) {
100 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "encrypt error.");
101 return SOFTBUS_ENCRYPT_ERR;
102 }
103 return SOFTBUS_OK;
104 }
105
TransTdcSetPendingPacket(int32_t channelId,const char * data,uint32_t len)106 static int32_t TransTdcSetPendingPacket(int32_t channelId, const char *data, uint32_t len)
107 {
108 if (len != ACK_SIZE) {
109 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "recv invalid seq.");
110 return SOFTBUS_ERR;
111 }
112
113 int32_t seq = (int32_t)SoftBusNtoHl(*(uint32_t *)data);
114 if (SetPendingPacket(channelId, seq, PENDING_TYPE_DIRECT) != SOFTBUS_OK) {
115 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "can not match seq.[%d]", seq);
116 return SOFTBUS_ERR;
117 }
118 return SOFTBUS_OK;
119 }
120
TransTdcPackData(const TcpDirectChannelInfo * channel,const char * data,uint32_t len,int flags,uint32_t * outLen)121 static char *TransTdcPackData(const TcpDirectChannelInfo *channel, const char *data, uint32_t len, int flags,
122 uint32_t *outLen)
123 {
124 uint32_t dataLen = len + OVERHEAD_LEN;
125 char *buf = (char *)SoftBusMalloc(dataLen + DC_DATA_HEAD_SIZE);
126 if (buf == NULL) {
127 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "malloc failed.");
128 return NULL;
129 }
130
131 char *finalData = (char *)data;
132 int32_t finalSeq = channel->detail.sequence;
133 uint32_t tmpSeq;
134 if (flags == FLAG_ACK) {
135 finalSeq = *((int32_t *)data);
136 tmpSeq = SoftBusHtoNl((uint32_t)finalSeq);
137 finalData = (char *)(&tmpSeq);
138 }
139
140 TcpDataPacketHead pktHead = {
141 .magicNumber = MAGIC_NUMBER,
142 .seq = finalSeq,
143 .flags = (uint32_t)flags,
144 .dataLen = dataLen,
145 };
146 PackTcpDataPacketHead(&pktHead);
147 if (memcpy_s(buf, DC_DATA_HEAD_SIZE, &pktHead, sizeof(TcpDataPacketHead)) != EOK) {
148 SoftBusFree(buf);
149 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "memcpy_s error");
150 return NULL;
151 }
152 if (TransTdcEncryptWithSeq(channel->detail.sessionKey, finalSeq, finalData, len,
153 buf + DC_DATA_HEAD_SIZE, outLen) != SOFTBUS_OK) {
154 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "encrypt error");
155 SoftBusFree(buf);
156 return NULL;
157 }
158 return buf;
159 }
160
TransTdcProcessPostData(const TcpDirectChannelInfo * channel,const char * data,uint32_t len,int32_t flags)161 static int32_t TransTdcProcessPostData(const TcpDirectChannelInfo *channel, const char *data, uint32_t len,
162 int32_t flags)
163 {
164 uint32_t outLen;
165 char *buf = TransTdcPackData(channel, data, len, flags, &outLen);
166 if (buf == NULL) {
167 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "failed to pack bytes.");
168 return SOFTBUS_ENCRYPT_ERR;
169 }
170 if (outLen != len + OVERHEAD_LEN) {
171 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "pack bytes len error, len: %d", outLen);
172 SoftBusFree(buf);
173 return SOFTBUS_ENCRYPT_ERR;
174 }
175 uint32_t tos = (flags == FLAG_BYTES) ? BYTE_TOS : MESSAGE_TOS;
176 if (SetIpTos(channel->detail.fd, tos) != SOFTBUS_OK) {
177 SoftBusFree(buf);
178 return SOFTBUS_TCP_SOCKET_ERR;
179 }
180 ssize_t ret = ConnSendSocketData(channel->detail.fd, buf, outLen + DC_DATA_HEAD_SIZE, 0);
181 if (ret != (ssize_t)outLen + DC_DATA_HEAD_SIZE) {
182 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "failed to send tcp data. ret: %d", ret);
183 SoftBusFree(buf);
184 return SOFTBUS_ERR;
185 }
186 SoftBusFree(buf);
187 buf = NULL;
188 return SOFTBUS_OK;
189 }
190
TransTdcSendBytes(int32_t channelId,const char * data,uint32_t len)191 int32_t TransTdcSendBytes(int32_t channelId, const char *data, uint32_t len)
192 {
193 if (data == NULL || len == 0) {
194 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s cId[%d] param invalid.", __func__, channelId);
195 return SOFTBUS_INVALID_PARAM;
196 }
197 TcpDirectChannelInfo channel;
198 (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
199 if (TransTdcGetInfoByIdWithIncSeq(channelId, &channel) == NULL) {
200 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "TransTdcGetInfoByIdWithIncSeq failed, cId[%d].", channelId);
201 return SOFTBUS_ERR;
202 }
203
204 int ret = TransTdcProcessPostData(&channel, data, len, FLAG_BYTES);
205 if (ret != SOFTBUS_OK) {
206 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "cId[%d] tdc send bytes failed, ret=%d.", channelId, ret);
207 return ret;
208 }
209
210 return SOFTBUS_OK;
211 }
212
TransTdcSendMessage(int32_t channelId,const char * data,uint32_t len)213 int32_t TransTdcSendMessage(int32_t channelId, const char *data, uint32_t len)
214 {
215 if (data == NULL || len == 0) {
216 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s cId[%d] param invalid.", __func__, channelId);
217 return SOFTBUS_INVALID_PARAM;
218 }
219
220 TcpDirectChannelInfo channel;
221 (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
222 if (TransTdcGetInfoByIdWithIncSeq(channelId, &channel) == NULL) {
223 return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
224 }
225 int32_t ret = TransTdcProcessPostData(&channel, data, len, FLAG_MESSAGE);
226 if (ret != SOFTBUS_OK) {
227 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "tdc send message failed, ret=%d.", ret);
228 return ret;
229 }
230 return ProcPendingPacket(channelId, channel.detail.sequence, PENDING_TYPE_DIRECT);
231 }
232
TransTdcSendAck(const TcpDirectChannelInfo * channel,int32_t seq)233 static int32_t TransTdcSendAck(const TcpDirectChannelInfo *channel, int32_t seq)
234 {
235 if (channel == NULL) {
236 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "channel is null.");
237 return SOFTBUS_ERR;
238 }
239
240 return TransTdcProcessPostData(channel, (char*)(&seq), ACK_SIZE, FLAG_ACK);
241 }
242
TransGetDataBufSize(void)243 static uint32_t TransGetDataBufSize(void)
244 {
245 return MIN_BUF_LEN;
246 }
247
248 #define SLICE_HEAD_LEN 16
TransGetDataBufMaxSize(void)249 static int32_t TransGetDataBufMaxSize(void)
250 {
251 uint32_t maxLen;
252 if (SoftbusGetConfig(SOFTBUS_INT_MAX_BYTES_NEW_LENGTH, (unsigned char *)&maxLen, sizeof(maxLen)) != SOFTBUS_OK) {
253 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "get config err");
254 return SOFTBUS_ERR;
255 }
256 g_dataBufferMaxLen = maxLen + DATA_EXTEND_LEN + SLICE_HEAD_LEN;
257 return SOFTBUS_OK;
258 }
259
TransAddDataBufNode(int32_t channelId,int32_t fd)260 int32_t TransAddDataBufNode(int32_t channelId, int32_t fd)
261 {
262 if (g_tcpDataList == NULL) {
263 return SOFTBUS_ERR;
264 }
265 ClientDataBuf *node = (ClientDataBuf *)SoftBusCalloc(sizeof(ClientDataBuf));
266 if (node == NULL) {
267 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s calloc failed.", __func__);
268 return SOFTBUS_ERR;
269 }
270 node->channelId = channelId;
271 node->fd = fd;
272 node->size = TransGetDataBufSize();
273 node->data = (char *)SoftBusCalloc(node->size);
274 if (node->data == NULL) {
275 SoftBusFree(node);
276 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s calloc data failed.", __func__);
277 return SOFTBUS_ERR;
278 }
279 node->w = node->data;
280
281 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
282 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s lock failed.", __func__);
283 SoftBusFree(node->data);
284 SoftBusFree(node);
285 return SOFTBUS_ERR;
286 }
287 ListAdd(&g_tcpDataList->list, &node->node);
288 g_tcpDataList->cnt++;
289 SoftBusMutexUnlock(&g_tcpDataList->lock);
290 return SOFTBUS_OK;
291 }
292
TransDelDataBufNode(int32_t channelId)293 int32_t TransDelDataBufNode(int32_t channelId)
294 {
295 if (g_tcpDataList == NULL) {
296 return SOFTBUS_ERR;
297 }
298
299 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
300 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s lock failed.", __func__);
301 return SOFTBUS_ERR;
302 }
303 ClientDataBuf *item = NULL;
304 ClientDataBuf *next = NULL;
305 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_tcpDataList->list, ClientDataBuf, node) {
306 if (item->channelId == channelId) {
307 ListDelete(&item->node);
308 SoftBusFree(item->data);
309 SoftBusFree(item);
310 g_tcpDataList->cnt--;
311 break;
312 }
313 }
314 SoftBusMutexUnlock(&g_tcpDataList->lock);
315
316 return SOFTBUS_OK;
317 }
318
TransDestroyDataBuf(void)319 static int32_t TransDestroyDataBuf(void)
320 {
321 if (g_tcpDataList == NULL) {
322 return SOFTBUS_ERR;
323 }
324
325 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
326 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s lock failed.", __func__);
327 return SOFTBUS_ERR;
328 }
329 ClientDataBuf *item = NULL;
330 ClientDataBuf *next = NULL;
331 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_tcpDataList->list, ClientDataBuf, node) {
332 ListDelete(&item->node);
333 SoftBusFree(item->data);
334 SoftBusFree(item);
335 g_tcpDataList->cnt--;
336 }
337 SoftBusMutexUnlock(&g_tcpDataList->lock);
338
339 return SOFTBUS_OK;
340 }
341
TransGetDataBufNodeById(int32_t channelId)342 static ClientDataBuf *TransGetDataBufNodeById(int32_t channelId)
343 {
344 if (g_tcpDataList == NULL) {
345 return NULL;
346 }
347
348 ClientDataBuf *item = NULL;
349 LIST_FOR_EACH_ENTRY(item, &(g_tcpDataList->list), ClientDataBuf, node) {
350 if (item->channelId == channelId) {
351 return item;
352 }
353 }
354 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "tcp direct channel id[]%d not exist.", channelId);
355 return NULL;
356 }
357
TransTdcProcessDataByFlag(uint32_t flag,int32_t seqNum,const TcpDirectChannelInfo * channel,const char * plain,uint32_t plainLen)358 static int32_t TransTdcProcessDataByFlag(uint32_t flag, int32_t seqNum, const TcpDirectChannelInfo *channel,
359 const char *plain, uint32_t plainLen)
360 {
361 switch (flag) {
362 case FLAG_BYTES:
363 return ClientTransTdcOnDataReceived(channel->channelId, plain, plainLen, TRANS_SESSION_BYTES);
364 case FLAG_ACK:
365 TransTdcSetPendingPacket(channel->channelId, plain, plainLen);
366 return SOFTBUS_OK;
367 case FLAG_MESSAGE:
368 TransTdcSendAck(channel, seqNum);
369 return ClientTransTdcOnDataReceived(channel->channelId, plain, plainLen, TRANS_SESSION_MESSAGE);
370 default:
371 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "unknown flag=%d.", flag);
372 return SOFTBUS_ERR;
373 }
374 }
375
TransTdcProcessData(int32_t channelId)376 static int32_t TransTdcProcessData(int32_t channelId)
377 {
378 TcpDirectChannelInfo channel;
379 if (TransTdcGetInfoById(channelId, &channel) == NULL) {
380 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "cId[%d] get key fail.", channelId);
381 return SOFTBUS_ERR;
382 }
383
384 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
385 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s lock failed.", __func__);
386 return SOFTBUS_ERR;
387 }
388 ClientDataBuf *node = TransGetDataBufNodeById(channelId);
389 if (node == NULL) {
390 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "cId[%d] node is null.", channelId);
391 SoftBusMutexUnlock(&g_tcpDataList->lock);
392 return SOFTBUS_ERR;
393 }
394 TcpDataPacketHead *pktHead = (TcpDataPacketHead *)(node->data);
395 int32_t seqNum = pktHead->seq;
396 uint32_t flag = pktHead->flags;
397 uint32_t dataLen = pktHead->dataLen;
398 char *plain = (char *)SoftBusCalloc(dataLen - OVERHEAD_LEN);
399 if (plain == NULL) {
400 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "malloc fail.");
401 SoftBusMutexUnlock(&g_tcpDataList->lock);
402 return SOFTBUS_MALLOC_ERR;
403 }
404
405 uint32_t plainLen;
406 int ret = TransTdcDecrypt(channel.detail.sessionKey, node->data + DC_DATA_HEAD_SIZE, dataLen, plain, &plainLen);
407 if (ret != SOFTBUS_OK) {
408 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "decrypt fail.");
409 SoftBusFree(plain);
410 SoftBusMutexUnlock(&g_tcpDataList->lock);
411 return SOFTBUS_DECRYPT_ERR;
412 }
413 char *end = node->data + DC_DATA_HEAD_SIZE + dataLen;
414 if (memmove_s(node->data, node->size, end, node->w - end) != EOK) {
415 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "memmove fail.");
416 SoftBusFree(plain);
417 SoftBusMutexUnlock(&g_tcpDataList->lock);
418 return SOFTBUS_MEM_ERR;
419 }
420 node->w = node->w - DC_DATA_HEAD_SIZE - dataLen;
421 SoftBusMutexUnlock(&g_tcpDataList->lock);
422
423 ret = TransTdcProcessDataByFlag(flag, seqNum, &channel, plain, plainLen);
424 if (ret != SOFTBUS_OK) {
425 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "process data fail");
426 }
427 SoftBusFree(plain);
428 return ret;
429 }
430
TransResizeDataBuffer(ClientDataBuf * oldBuf,uint32_t pkgLen)431 static int32_t TransResizeDataBuffer(ClientDataBuf *oldBuf, uint32_t pkgLen)
432 {
433 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "TransResizeDataBuffer: channelId=%d, pkgLen=%d",
434 oldBuf->channelId, pkgLen);
435 char *newBuf = (char *)SoftBusCalloc(pkgLen);
436 if (newBuf == NULL) {
437 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "TransResizeDataBuffer malloc err(%u)", pkgLen);
438 return SOFTBUS_MEM_ERR;
439 }
440 uint32_t bufLen = oldBuf->w - oldBuf->data;
441 if (memcpy_s(newBuf, pkgLen, oldBuf->data, bufLen) != EOK) {
442 SoftBusFree(newBuf);
443 return SOFTBUS_MEM_ERR;
444 }
445 SoftBusFree(oldBuf->data);
446 oldBuf->data = NULL;
447 oldBuf->data = newBuf;
448 oldBuf->size = pkgLen;
449 oldBuf->w = newBuf + bufLen;
450 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "TransResizeDataBuffer ok");
451 return SOFTBUS_OK;
452 }
453
TransTdcProcAllData(int32_t channelId)454 static int32_t TransTdcProcAllData(int32_t channelId)
455 {
456 while (1) {
457 SoftBusMutexLock(&g_tcpDataList->lock);
458 ClientDataBuf *node = TransGetDataBufNodeById(channelId);
459 if (node == NULL) {
460 SoftBusMutexUnlock(&g_tcpDataList->lock);
461 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "cId[%d] can not find data buf node.", channelId);
462 return SOFTBUS_ERR;
463 }
464 uint32_t bufLen = node->w - node->data;
465 if (bufLen == 0) {
466 SoftBusMutexUnlock(&g_tcpDataList->lock);
467 return SOFTBUS_OK;
468 }
469 if (bufLen < DC_DATA_HEAD_SIZE) {
470 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_WARN, "head[%d] not enough, recv biz head next time.", bufLen);
471 SoftBusMutexUnlock(&g_tcpDataList->lock);
472 return SOFTBUS_DATA_NOT_ENOUGH;
473 }
474
475 TcpDataPacketHead *pktHead = (TcpDataPacketHead *)(node->data);
476 UnpackTcpDataPacketHead(pktHead);
477 if (pktHead->magicNumber != MAGIC_NUMBER) {
478 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "cId[%d] invalid data packet head.", channelId);
479 SoftBusMutexUnlock(&g_tcpDataList->lock);
480 return SOFTBUS_ERR;
481 }
482
483 if ((pktHead->dataLen > g_dataBufferMaxLen - DC_DATA_HEAD_SIZE) || (pktHead->dataLen <= OVERHEAD_LEN)) {
484 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "illegal data size[%d]", pktHead->dataLen);
485 SoftBusMutexUnlock(&g_tcpDataList->lock);
486 return SOFTBUS_ERR;
487 }
488 uint32_t pkgLen = pktHead->dataLen + DC_DATA_HEAD_SIZE;
489
490 if (pkgLen > node->size && pkgLen <= g_dataBufferMaxLen) {
491 int32_t ret = TransResizeDataBuffer(node, pkgLen);
492 SoftBusMutexUnlock(&g_tcpDataList->lock);
493 return ret;
494 }
495 SoftBusMutexUnlock(&g_tcpDataList->lock);
496
497 if (bufLen < pkgLen) {
498 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_WARN, "data[%d] not enough, recv biz data next time.", bufLen);
499 return SOFTBUS_DATA_NOT_ENOUGH;
500 }
501
502 if (TransTdcProcessData(channelId) != SOFTBUS_OK) {
503 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "data received failed");
504 return SOFTBUS_ERR;
505 }
506 }
507 }
508
TransClientGetTdcDataBufByChannel(int32_t channelId,int32_t * fd,size_t * len)509 static int32_t TransClientGetTdcDataBufByChannel(int32_t channelId, int32_t *fd, size_t *len)
510 {
511 if (fd == NULL || len == NULL) {
512 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s invalid param.", __func__);
513 return SOFTBUS_ERR;
514 }
515
516 if (g_tcpDataList == NULL) {
517 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s tdc data list empty.", __func__);
518 return SOFTBUS_ERR;
519 }
520
521 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
522 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s lock failed.", __func__);
523 return SOFTBUS_ERR;
524 }
525 ClientDataBuf *item = NULL;
526 LIST_FOR_EACH_ENTRY(item, &(g_tcpDataList->list), ClientDataBuf, node) {
527 if (item->channelId == channelId) {
528 *fd = item->fd;
529 *len = item->size - (item->w - item->data);
530 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
531 return SOFTBUS_OK;
532 }
533 }
534 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
535 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "client get tdc[%d] data buf not found.", channelId);
536 return SOFTBUS_ERR;
537 }
538
TransClientUpdateTdcDataBufWInfo(int32_t channelId,char * recvBuf,int32_t recvLen)539 static int32_t TransClientUpdateTdcDataBufWInfo(int32_t channelId, char *recvBuf, int32_t recvLen)
540 {
541 if (recvBuf == NULL) {
542 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s invalid param.", __func__);
543 return SOFTBUS_ERR;
544 }
545 if (g_tcpDataList == NULL) {
546 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s data list empty.", __func__);
547 return SOFTBUS_ERR;
548 }
549 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
550 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "[client]%s lock failed.", __func__);
551 return SOFTBUS_ERR;
552 }
553
554 ClientDataBuf *item = NULL;
555 ClientDataBuf *nextItem = NULL;
556 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &(g_tcpDataList->list), ClientDataBuf, node) {
557 if (item->channelId != channelId) {
558 continue;
559 }
560 int32_t freeLen = (int32_t)(item->size) - (item->w - item->data);
561 if (recvLen > freeLen) {
562 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
563 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR,
564 "client tdc recv=%d override free=%d.", recvLen, freeLen);
565 return SOFTBUS_ERR;
566 }
567 if (memcpy_s(item->w, recvLen, recvBuf, recvLen) != EOK) {
568 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
569 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "client tdc[%d] memcpy failed.", channelId);
570 return SOFTBUS_ERR;
571 }
572 item->w += recvLen;
573 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
574 return SOFTBUS_OK;
575 }
576 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
577 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "client update tdc[%d] data buf not found.", channelId);
578 return SOFTBUS_ERR;
579 }
580
TransTdcRecvData(int32_t channelId)581 int32_t TransTdcRecvData(int32_t channelId)
582 {
583 int32_t fd = -1;
584 size_t len = 0;
585 if (TransClientGetTdcDataBufByChannel(channelId, &fd, &len) != SOFTBUS_OK) {
586 return SOFTBUS_ERR;
587 }
588 if (len == 0 || len > g_dataBufferMaxLen) {
589 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR,
590 "client tdc[%d] free databuf len[%zu] invalid.", channelId, len);
591 return SOFTBUS_ERR;
592 }
593
594 char *recvBuf = (char*)SoftBusCalloc(len);
595 if (recvBuf == NULL) {
596 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "client tdc[%d] calloc len[%zu] failed.", channelId, len);
597 return SOFTBUS_ERR;
598 }
599
600 int32_t recvLen = ConnRecvSocketData(fd, recvBuf, len, 0);
601 if (recvLen < 0) {
602 SoftBusFree(recvBuf);
603 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "client cId[%d] recv data failed,ret=%d.", channelId, recvLen);
604 return SOFTBUS_ERR;
605 } else if (recvLen == 0) {
606 return SOFTBUS_DATA_NOT_ENOUGH;
607 }
608
609 if (TransClientUpdateTdcDataBufWInfo(channelId, recvBuf, recvLen) != SOFTBUS_OK) {
610 SoftBusFree(recvBuf);
611 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "client cId[%d] update data buf failed.", channelId);
612 return SOFTBUS_ERR;
613 }
614 SoftBusFree(recvBuf);
615
616 return TransTdcProcAllData(channelId);
617 }
618
TransDataListInit(void)619 int32_t TransDataListInit(void)
620 {
621 if (g_tcpDataList != NULL) {
622 return SOFTBUS_OK;
623 }
624 if (TransGetDataBufMaxSize() != SOFTBUS_OK) {
625 return SOFTBUS_ERR;
626 }
627 g_tcpDataList = CreateSoftBusList();
628 if (g_tcpDataList == NULL) {
629 return SOFTBUS_ERR;
630 }
631 return SOFTBUS_OK;
632 }
633
TransDataListDeinit(void)634 void TransDataListDeinit(void)
635 {
636 if (g_tcpDataList == NULL) {
637 return;
638 }
639 (void)TransDestroyDataBuf();
640 DestroySoftBusList(g_tcpDataList);
641 g_tcpDataList = NULL;
642 }
643