• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_process_data.h"
17 
18 #include <securec.h>
19 
20 #include "softbus_adapter_crypto.h"
21 #include "softbus_adapter_mem.h"
22 #include "softbus_adapter_socket.h"
23 #include "softbus_adapter_thread.h"
24 #include "softbus_error_code.h"
25 #include "softbus_feature_config.h"
26 #include "softbus_socket.h"
27 #include "softbus_utils.h"
28 #include "trans_log.h"
29 
30 #define TDC_TLV_ELEMENT 5
31 #define TLV_TYPE_AND_LENTH 2
32 #define SLICE_HEAD_LEN 16
33 #define DATA_EXTEND_LEN (DC_DATA_HEAD_SIZE + OVERHEAD_LEN)
34 #define MIN_BUF_LEN (1024 + DATA_EXTEND_LEN)
35 #define MAGICNUM_SIZE sizeof(uint32_t)
36 #define TLVCOUNT_SIZE sizeof(uint8_t)
37 static uint32_t g_dataBufferMaxLen = 0;
38 
TransGetDataBufSize(void)39 uint32_t TransGetDataBufSize(void)
40 {
41     return MIN_BUF_LEN;
42 }
43 
TransGetTdcDataBufMaxSize(void)44 int32_t TransGetTdcDataBufMaxSize(void)
45 {
46     uint32_t maxLen = 0;
47     int32_t ret = SoftbusGetConfig(SOFTBUS_INT_MAX_BYTES_NEW_LENGTH, (unsigned char *)&maxLen, sizeof(maxLen));
48     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_CTRL, "get config err");
49     g_dataBufferMaxLen = maxLen + DATA_EXTEND_LEN + SLICE_HEAD_LEN;
50     return SOFTBUS_OK;
51 }
52 
UnPackTcpDataPacketHead(TcpDataPacketHead * data)53 static void UnPackTcpDataPacketHead(TcpDataPacketHead *data)
54 {
55     data->magicNumber = SoftBusLtoHl(data->magicNumber);
56     data->seq = (int32_t)SoftBusLtoHl((uint32_t)data->seq);
57     data->flags = SoftBusLtoHl(data->flags);
58     data->dataLen = SoftBusLtoHl(data->dataLen);
59 }
60 
TransTcpDataTlvUnpack(TcpDataTlvPacketHead * data)61 static void TransTcpDataTlvUnpack(TcpDataTlvPacketHead *data)
62 {
63     data->magicNumber = SoftBusLtoHl(data->magicNumber);
64     data->seq = (int32_t)SoftBusLtoHl((uint32_t)data->seq);
65     data->flags = SoftBusLtoHl(data->flags);
66     data->dataLen = SoftBusLtoHl(data->dataLen);
67     data->dataSeq = SoftBusLtoHl(data->dataSeq);
68 }
69 
TransResizeDataBuffer(DataBuf * oldBuf,uint32_t pkgLen)70 static int32_t TransResizeDataBuffer(DataBuf *oldBuf, uint32_t pkgLen)
71 {
72     TRANS_LOGI(TRANS_CTRL, "Resize Data Buffer channelId=%{public}d, pkgLen=%{public}d",
73         oldBuf->channelId, pkgLen);
74     char *newBuf = (char *)SoftBusCalloc(pkgLen);
75     if (newBuf == NULL) {
76         TRANS_LOGE(TRANS_CTRL, "malloc err pkgLen=%{public}u", pkgLen);
77         return SOFTBUS_MALLOC_ERR;
78     }
79     uint32_t bufLen = oldBuf->w - oldBuf->data;
80     if (memcpy_s(newBuf, pkgLen, oldBuf->data, bufLen) != EOK) {
81         SoftBusFree(newBuf);
82         return SOFTBUS_MEM_ERR;
83     }
84     SoftBusFree(oldBuf->data);
85     oldBuf->data = NULL;
86     oldBuf->data = newBuf;
87     oldBuf->size = pkgLen;
88     oldBuf->w = newBuf + bufLen;
89     TRANS_LOGI(TRANS_CTRL, "TransResizeDataBuffer ok");
90     return SOFTBUS_OK;
91 }
92 
MoveNode(int32_t channelId,DataBuf * node,uint32_t dataLen,int32_t pkgHeadSize)93 int32_t MoveNode(int32_t channelId, DataBuf *node, uint32_t dataLen, int32_t pkgHeadSize)
94 {
95     if (node == NULL) {
96         TRANS_LOGE(TRANS_CTRL, "invalid param, channelId=%{public}d", channelId);
97         return SOFTBUS_INVALID_PARAM;
98     }
99     char *end = node->data + pkgHeadSize + dataLen;
100     if (memmove_s(node->data, node->size, end, node->w - end) != EOK) {
101         TRANS_LOGE(TRANS_CTRL, "memmove fail, channelId=%{public}d, dataLen=%{public}u", channelId, dataLen);
102         return SOFTBUS_MEM_ERR;
103     }
104     node->w = node->w - pkgHeadSize - dataLen;
105     return SOFTBUS_OK;
106 }
107 
TransTdcDecrypt(const char * sessionKey,const char * in,uint32_t inLen,char * out,uint32_t * outLen)108 int32_t TransTdcDecrypt(const char *sessionKey, const char *in, uint32_t inLen, char *out, uint32_t *outLen)
109 {
110     if (sessionKey == NULL || in == NULL || out == NULL || outLen == NULL) {
111         TRANS_LOGE(TRANS_CTRL, "invalid param");
112         return SOFTBUS_INVALID_PARAM;
113     }
114     AesGcmCipherKey cipherKey = { 0 };
115     cipherKey.keyLen = SESSION_KEY_LENGTH; // 256 bit encryption
116     if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey, SESSION_KEY_LENGTH) != EOK) {
117         TRANS_LOGE(TRANS_CTRL, "memcpy key error.");
118         return SOFTBUS_MEM_ERR;
119     }
120     int32_t ret = SoftBusDecryptData(&cipherKey, (unsigned char*)in, inLen, (unsigned char*)out, outLen);
121     (void)memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey));
122     if (ret != SOFTBUS_OK) {
123         TRANS_LOGE(TRANS_CTRL, "dectypt data fail ret=%{public}d", ret);
124         return SOFTBUS_DECRYPT_ERR;
125     }
126     return SOFTBUS_OK;
127 }
128 
TransTdcRecvFirstData(int32_t channelId,char * recvBuf,int32_t * recvLen,int32_t fd,size_t len)129 int32_t TransTdcRecvFirstData(int32_t channelId, char *recvBuf, int32_t *recvLen, int32_t fd, size_t len)
130 {
131     if (recvBuf == NULL || recvLen == NULL) {
132         TRANS_LOGE(TRANS_CTRL, "invalid param");
133         return SOFTBUS_INVALID_PARAM;
134     }
135     if (len == 0 || len > g_dataBufferMaxLen) {
136         TRANS_LOGE(TRANS_CTRL,
137             "client tdc free databuf len invalid, channelId=%{public}d, len=%{public}zu", channelId, len);
138         return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
139     }
140     *recvLen = ConnRecvSocketData(fd, recvBuf, len, 0);
141     if (*recvLen < 0) {
142         int32_t socketErrCode = GetErrCodeBySocketErr(SOFTBUS_TRANS_TCP_GET_SRV_DATA_FAILED);
143         TRANS_LOGE(TRANS_CTRL, "client recv data failed, channelId=%{public}d, recvlen=%{public}d, errCode=%{public}d",
144             channelId, *recvLen, socketErrCode);
145         return socketErrCode;
146     } else if (*recvLen == 0) {
147         return SOFTBUS_DATA_NOT_ENOUGH;
148     }
149     return SOFTBUS_OK;
150 }
151 
TransTdcUnPackAllData(int32_t channelId,DataBuf * node,bool * flag)152 int32_t TransTdcUnPackAllData(int32_t channelId, DataBuf *node, bool *flag)
153 {
154     if (node == NULL || flag == NULL) {
155         TRANS_LOGE(TRANS_CTRL, "invalid param, channelId=%{public}d", channelId);
156         return SOFTBUS_INVALID_PARAM;
157     }
158     uint32_t bufLen = node->w - node->data;
159     if (bufLen == 0) {
160         *flag = true;
161         return SOFTBUS_OK;
162     }
163     if (bufLen < DC_DATA_HEAD_SIZE) {
164         TRANS_LOGW(TRANS_CTRL,"head bufLen not enough, recv biz head next time\
165             channelId=%{public}d, bufLen=%{public}u", channelId, bufLen);
166         return SOFTBUS_DATA_NOT_ENOUGH;
167     }
168     TcpDataPacketHead *pktHead = (TcpDataPacketHead *)(node->data);
169     UnPackTcpDataPacketHead(pktHead);
170     if (pktHead->magicNumber != MAGIC_NUMBER) {
171         return SOFTBUS_INVALID_DATA_HEAD;
172     }
173     if ((g_dataBufferMaxLen <= DC_DATA_HEAD_SIZE) || (pktHead->dataLen > g_dataBufferMaxLen - DC_DATA_HEAD_SIZE)
174         || (pktHead->dataLen <= OVERHEAD_LEN)) {
175         TRANS_LOGE(TRANS_CTRL, "illegal dataLen=%{public}u", pktHead->dataLen);
176         return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
177     }
178     uint32_t pkgLen = pktHead->dataLen + DC_DATA_HEAD_SIZE;
179     if (pkgLen > node->size && pkgLen <= g_dataBufferMaxLen) {
180         int32_t ret = TransResizeDataBuffer(node, pkgLen);
181         *flag = true;
182         return ret;
183     }
184     if (bufLen < pkgLen) {
185         TRANS_LOGE(TRANS_CTRL, "data bufLen not enough, recv data next time. bufLen=%{public}u", bufLen);
186         return SOFTBUS_DATA_NOT_ENOUGH;
187     }
188     return SOFTBUS_OK;
189 }
190 
TransTdcUnPackData(int32_t channelId,const char * sessionKey,char * plain,uint32_t * plainLen,DataBuf * node)191 int32_t TransTdcUnPackData(int32_t channelId, const char *sessionKey, char *plain, uint32_t *plainLen, DataBuf *node)
192 {
193     if (sessionKey == NULL || plain == NULL || plainLen == NULL || node == NULL) {
194         TRANS_LOGE(TRANS_CTRL, "invalid param, channelId=%{public}d", channelId);
195         return SOFTBUS_INVALID_PARAM;
196     }
197     TcpDataPacketHead *pktHead = (TcpDataPacketHead *)(node->data);
198     uint32_t dataLen = pktHead->dataLen;
199     TRANS_LOGI(TRANS_CTRL, "data received, channelId=%{public}d, dataLen=%{public}u, sizeof=%{public}d, seq=%{public}d",
200         channelId, dataLen, node->size, pktHead->seq);
201     int32_t ret = TransTdcDecrypt(sessionKey, node->data + DC_DATA_HEAD_SIZE, dataLen, plain, plainLen);
202     if (ret != SOFTBUS_OK) {
203         TRANS_LOGI(TRANS_CTRL, "decrypt fail, channelId=%{public}d, dataLen=%{public}u", channelId, dataLen);
204         return SOFTBUS_DECRYPT_ERR;
205     }
206     ret = MoveNode(channelId, node, dataLen, DC_DATA_HEAD_SIZE);
207     if (ret != SOFTBUS_OK) {
208         return ret;
209     }
210     return SOFTBUS_OK;
211 }
212 
CheckBufLenAndCopyData(uint32_t bufLen,uint32_t headSize,char * data,TcpDataTlvPacketHead * head)213 static int32_t CheckBufLenAndCopyData(uint32_t bufLen, uint32_t headSize, char *data, TcpDataTlvPacketHead *head)
214 {
215     if (bufLen <= headSize) {
216         TRANS_LOGE(TRANS_CTRL, "data bufLen not enough, bufLen Less than headSize. bufLen=%{public}u", bufLen);
217         return SOFTBUS_DATA_NOT_ENOUGH;
218     }
219     if (memcpy_s(&head->magicNumber, MAGICNUM_SIZE, data, MAGICNUM_SIZE) != EOK) {
220         TRANS_LOGE(TRANS_CTRL, "memcpy magicNumber failed.");
221         return SOFTBUS_MEM_ERR;
222     }
223     if (memcpy_s(&head->tlvCount, TLVCOUNT_SIZE, data + MAGICNUM_SIZE, TLVCOUNT_SIZE) != EOK) {
224         TRANS_LOGE(TRANS_CTRL, "memcpy tlvCount failed.");
225         return SOFTBUS_MEM_ERR;
226     }
227     return SOFTBUS_OK;
228 }
229 
TransTdcParseTlv(uint32_t bufLen,char * data,TcpDataTlvPacketHead * head,uint32_t * headSize)230 static int32_t TransTdcParseTlv(uint32_t bufLen, char *data, TcpDataTlvPacketHead *head, uint32_t *headSize)
231 {
232     if (data == NULL || head == NULL) {
233         TRANS_LOGE(TRANS_CTRL, "param invalid.");
234         return SOFTBUS_INVALID_PARAM;
235     }
236     errno_t ret = EOK;
237     *headSize += MAGICNUM_SIZE + TLVCOUNT_SIZE;
238     int32_t res = CheckBufLenAndCopyData(bufLen, *headSize, data, head);
239     TRANS_CHECK_AND_RETURN_RET_LOGE(res == SOFTBUS_OK, res, TRANS_CTRL, "CheckBufLenAndCopyData failed");
240     char *temp = data + MAGICNUM_SIZE + TLVCOUNT_SIZE;
241     for (int32_t index = 0; index < head->tlvCount; index++) {
242         uint8_t *type = (uint8_t *)temp;
243         if (bufLen < (*headSize + (TLV_TYPE_AND_LENTH * sizeof(uint8_t)))) {
244             TRANS_LOGE(TRANS_CTRL, "check bufLen contains tlv segment data fail, bufLen=%{public}u", bufLen);
245             return SOFTBUS_DATA_NOT_ENOUGH;
246         }
247         uint8_t *length = (uint8_t *)(temp + sizeof(uint8_t));
248         if (bufLen < (*headSize + (TLV_TYPE_AND_LENTH * sizeof(uint8_t)) + *length)) {
249             TRANS_LOGE(TRANS_CTRL, "data bufLen not enough. bufLen=%{public}u", bufLen);
250             return SOFTBUS_DATA_NOT_ENOUGH;
251         }
252         temp += (TLV_TYPE_AND_LENTH *sizeof(uint8_t));
253         switch (*type) {
254             case TLV_TYPE_INNER_SEQ:
255                 ret = memcpy_s(&head->seq, sizeof(head->seq), temp, *length);
256                 break;
257             case TLV_TYPE_DATA_SEQ:
258                 ret = memcpy_s(&head->dataSeq, sizeof(head->dataSeq), temp, *length);
259                 break;
260             case TLV_TYPE_FLAG:
261                 ret = memcpy_s(&head->flags, sizeof(head->flags), temp, *length);
262                 break;
263             case TLV_TYPE_NEED_ACK:
264                 ret = memcpy_s(&head->needAck, sizeof(head->needAck), temp, *length);
265                 break;
266             case TLV_TYPE_DATA_LEN:
267                 ret = memcpy_s(&head->dataLen, sizeof(head->dataLen), temp, *length);
268                 break;
269             default:
270                 TRANS_LOGE(TRANS_CTRL, "unknown trans tdc tlv skip, tlvType=%{public}d", *type);
271                 break;
272         }
273         temp += *length;
274         *headSize += (TLV_TYPE_AND_LENTH * sizeof(uint8_t) + *length);
275         TRANS_CHECK_AND_RETURN_RET_LOGE(ret == EOK, SOFTBUS_MEM_ERR, TRANS_CTRL,
276             "parse tlv memcpy failed, tlvType=%{public}d, ret%{public}d", *type, ret);
277     }
278     return SOFTBUS_OK;
279 }
280 
TransTdcUnPackAllTlvData(int32_t channelId,TcpDataTlvPacketHead * head,uint32_t * headSize,DataBuf * node,bool * flag)281 int32_t TransTdcUnPackAllTlvData(
282     int32_t channelId, TcpDataTlvPacketHead *head, uint32_t *headSize, DataBuf *node, bool *flag)
283 {
284     if (node == NULL || flag == NULL || head == NULL || headSize == NULL) {
285         TRANS_LOGE(TRANS_CTRL, "invalid param");
286         return SOFTBUS_INVALID_PARAM;
287     }
288     uint32_t bufLen = node->w - node->data;
289     if (bufLen == 0) {
290         *flag = true;
291         return SOFTBUS_OK;
292     }
293     int32_t ret = TransTdcParseTlv(bufLen, node->data, head, headSize);
294     if (ret != SOFTBUS_OK) {
295         return ret;
296     }
297     TransTcpDataTlvUnpack(head);
298     if (bufLen < *headSize) {
299         TRANS_LOGW(TRANS_CTRL, "head bufLen not enough, recv biz head next time\
300             channelId=%{public}d, bufLen=%{public}u", channelId, bufLen);
301         return SOFTBUS_DATA_NOT_ENOUGH;
302     }
303     if (head->magicNumber != MAGIC_NUMBER) {
304         TRANS_LOGE(TRANS_CTRL, "invalid data packet head. channelId=%{public}d", channelId);
305         return SOFTBUS_INVALID_DATA_HEAD;
306     }
307     if ((g_dataBufferMaxLen <= *headSize) || (head->dataLen > g_dataBufferMaxLen - *headSize)
308         || (head->dataLen <= OVERHEAD_LEN)) {
309         TRANS_LOGE(TRANS_CTRL, "illegal dataLen=%{public}u", head->dataLen);
310         return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
311     }
312     uint32_t pkgLen = head->dataLen + *headSize;
313     if (pkgLen > node->size && pkgLen <= g_dataBufferMaxLen) {
314         ret = TransResizeDataBuffer(node, pkgLen);
315         *flag = true;
316         return ret;
317     }
318     if (bufLen < pkgLen) {
319         TRANS_LOGE(TRANS_CTRL, "data bufLen not enough, recv data next time. bufLen=%{public}u", bufLen);
320         return SOFTBUS_DATA_NOT_ENOUGH;
321     }
322     return SOFTBUS_OK;
323 }
324 
ReleaseDataHeadResource(DataHead * pktHead)325 void ReleaseDataHeadResource(DataHead *pktHead)
326 {
327     ReleaseTlvValueBuffer(pktHead);
328     SoftBusFree(pktHead->tlvElement);
329 }
330 
TransTdcPackTlvData(DataHead * pktHead,int32_t tlvBufferSize,uint32_t dataLen)331 char *TransTdcPackTlvData(DataHead *pktHead, int32_t tlvBufferSize, uint32_t dataLen)
332 {
333     TRANS_CHECK_AND_RETURN_RET_LOGE(pktHead != NULL, NULL, TRANS_CTRL, "invalid param");
334     int32_t headSize = MAGICNUM_SIZE + TLVCOUNT_SIZE + tlvBufferSize;
335     char *buf = (char *)SoftBusCalloc(dataLen + headSize);
336     if (buf == NULL) {
337         TRANS_LOGE(TRANS_CTRL, "malloc buf failed");
338         return NULL;
339     }
340     if (memcpy_s(buf, dataLen + headSize, &pktHead->magicNum, MAGICNUM_SIZE) != EOK) {
341         SoftBusFree(buf);
342         TRANS_LOGE(TRANS_CTRL, "memcpy magicNum failed");
343         return NULL;
344     }
345 
346     if (memcpy_s(buf + MAGICNUM_SIZE, dataLen + headSize, &pktHead->tlvCount,
347         TLVCOUNT_SIZE) != EOK) {
348         SoftBusFree(buf);
349         TRANS_LOGE(TRANS_CTRL, "memcpy tlvCount failed");
350         return NULL;
351     }
352 
353     char *temp = buf + MAGICNUM_SIZE + TLVCOUNT_SIZE;
354     for (int32_t index = 0; index < pktHead->tlvCount; index++) {
355         TlvElement *ement = (TlvElement *)pktHead->tlvElement;
356 
357         if (memcpy_s(temp, dataLen + headSize, &ement->type, sizeof(ement->type)) != EOK) {
358             SoftBusFree(buf);
359             TRANS_LOGE(TRANS_CTRL, "memcpy tlvEment type failed");
360             return NULL;
361         }
362 
363         temp += sizeof(ement->type);
364         if (memcpy_s(temp, dataLen + headSize, &ement->length, sizeof(ement->length)) != EOK) {
365             SoftBusFree(buf);
366             TRANS_LOGE(TRANS_CTRL, "memcpy tlvEment length failed");
367             return NULL;
368         }
369 
370         temp += sizeof(ement->length);
371         if (memcpy_s(temp, dataLen + headSize, ement->value, ement->length) != EOK) {
372             SoftBusFree(buf);
373             TRANS_LOGE(TRANS_CTRL, "memcpy tlvEment value failed");
374             return NULL;
375         }
376         temp += ement->length;
377         pktHead->tlvElement += sizeof(TlvElement);
378     }
379     return buf;
380 }
381 
BuildNeedAckTlvData(DataHead * pktHead,bool needAck,uint32_t dataSeqs,int32_t * tlvBufferSize)382 int32_t BuildNeedAckTlvData(DataHead *pktHead, bool needAck, uint32_t dataSeqs, int32_t *tlvBufferSize)
383 {
384     if (pktHead == NULL || tlvBufferSize == NULL) {
385         TRANS_LOGE(TRANS_CTRL, "param invalid.");
386         return SOFTBUS_INVALID_PARAM;
387     }
388     uint32_t dataSeq = SoftBusHtoLl(dataSeqs);
389     int32_t ret = TransAssembleTlvData(pktHead, TLV_TYPE_NEED_ACK, (uint8_t *)&needAck, sizeof(needAck), tlvBufferSize);
390     if (ret != SOFTBUS_OK) {
391         TRANS_LOGE(TRANS_CTRL, "tcp channel assemble needAck tlv failed, ret=%{public}d", ret);
392         ReleaseDataHeadResource(pktHead);
393         return ret;
394     }
395     ret = TransAssembleTlvData(pktHead, TLV_TYPE_DATA_SEQ, (uint8_t *)&dataSeq, sizeof(dataSeq), tlvBufferSize);
396     if (ret != SOFTBUS_OK) {
397         TRANS_LOGE(TRANS_CTRL, "tcp channel assemble dataSeq tlv failed, ret=%{public}d", ret);
398         ReleaseDataHeadResource(pktHead);
399         return ret;
400     }
401     pktHead->tlvElement -= (TDC_TLV_ELEMENT * sizeof(TlvElement));
402     return SOFTBUS_OK;
403 }
404 
BuildDataHead(DataHead * pktHead,int32_t finalSeq,int32_t flags,uint32_t dataLen,int32_t * tlvBufferSize)405 int32_t BuildDataHead(DataHead *pktHead, int32_t finalSeq, int32_t flags, uint32_t dataLen,
406     int32_t *tlvBufferSize)
407 {
408     if (pktHead == NULL || tlvBufferSize == NULL) {
409         TRANS_LOGE(TRANS_CTRL, "param invalid.");
410         return SOFTBUS_INVALID_PARAM;
411     }
412     pktHead->tlvElement = (uint8_t *)SoftBusCalloc(TDC_TLV_ELEMENT * sizeof(TlvElement));
413     if (pktHead->tlvElement == NULL) {
414         TRANS_LOGE(TRANS_CTRL, "malloc tlvElement failed");
415         return SOFTBUS_MALLOC_ERR;
416     }
417     pktHead->magicNum = SoftBusHtoLl(MAGIC_NUMBER);
418     uint32_t seq = SoftBusHtoLl((uint32_t)finalSeq);
419     uint32_t flag = SoftBusHtoLl((uint32_t)flags);
420     uint32_t dataLens = SoftBusHtoLl(dataLen);
421 
422     int32_t ret = TransAssembleTlvData(pktHead, TLV_TYPE_INNER_SEQ, (uint8_t *)&seq, sizeof(seq), tlvBufferSize);
423     if (ret != SOFTBUS_OK) {
424         TRANS_LOGE(TRANS_CTRL, "tcp channel assemble seq tlv failed, ret=%{public}d", ret);
425         ReleaseDataHeadResource(pktHead);
426         return ret;
427     }
428     ret = TransAssembleTlvData(pktHead, TLV_TYPE_FLAG, (uint8_t *)&flag, sizeof(flag), tlvBufferSize);
429     if (ret != SOFTBUS_OK) {
430         TRANS_LOGE(TRANS_CTRL, "tcp channel assemble flag tlv failed, ret=%{public}d", ret);
431         ReleaseDataHeadResource(pktHead);
432         return ret;
433     }
434     ret = TransAssembleTlvData(pktHead, TLV_TYPE_DATA_LEN, (uint8_t *)&dataLens, sizeof(dataLens), tlvBufferSize);
435     if (ret != SOFTBUS_OK) {
436         TRANS_LOGE(TRANS_CTRL, "tcp channel assemble dataLen tlv failed, ret=%{public}d", ret);
437         ReleaseDataHeadResource(pktHead);
438         return ret;
439     }
440     return SOFTBUS_OK;
441 }
442 
TransTdcEncryptWithSeq(const char * sessionKey,int32_t seqNum,EncrptyInfo * info)443 int32_t TransTdcEncryptWithSeq(const char *sessionKey, int32_t seqNum, EncrptyInfo *info)
444 {
445     if (info == NULL || sessionKey == NULL) {
446         TRANS_LOGE(TRANS_CTRL, "param invalid.");
447         return SOFTBUS_INVALID_PARAM;
448     }
449     AesGcmCipherKey cipherKey = {0};
450     cipherKey.keyLen = SESSION_KEY_LENGTH;
451     if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey, SESSION_KEY_LENGTH) != EOK) {
452         TRANS_LOGE(TRANS_CTRL, "memcpy key error.");
453         return SOFTBUS_MEM_ERR;
454     }
455     int32_t ret = SoftBusEncryptDataWithSeq(&cipherKey, (unsigned char*)info->in, info->inLen,
456         (unsigned char*)info->out, info->outLen, seqNum);
457     if (memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey)) != EOK) {
458         TRANS_LOGE(TRANS_CTRL, "memset cipherKey failed.");
459         return SOFTBUS_MEM_ERR;
460     }
461     if (ret != SOFTBUS_OK || *info->outLen != info->inLen + OVERHEAD_LEN) {
462         TRANS_LOGE(TRANS_CTRL, "encrypt error, ret=%{public}d", ret);
463         return SOFTBUS_ENCRYPT_ERR;
464     }
465     return SOFTBUS_OK;
466 }
467 
PackTcpDataPacketHead(TcpDataPacketHead * data)468 static void PackTcpDataPacketHead(TcpDataPacketHead *data)
469 {
470     data->magicNumber = SoftBusHtoLl(data->magicNumber);
471     data->seq = (int32_t)SoftBusHtoLl((uint32_t)data->seq);
472     data->flags = SoftBusHtoLl(data->flags);
473     data->dataLen = SoftBusHtoLl(data->dataLen);
474 }
475 
TransPackData(uint32_t dataLen,int32_t finalSeq,int32_t flags)476 static char *TransPackData(uint32_t dataLen, int32_t finalSeq, int32_t flags)
477 {
478     TcpDataPacketHead pktHead = {
479         .magicNumber = MAGIC_NUMBER,
480         .seq = finalSeq,
481         .flags = (uint32_t)flags,
482         .dataLen = dataLen,
483     };
484     char *buf = (char *)SoftBusMalloc(dataLen + DC_DATA_HEAD_SIZE);
485     TRANS_CHECK_AND_RETURN_RET_LOGE(buf != NULL, NULL, TRANS_CTRL, "malloc failed");
486     PackTcpDataPacketHead(&pktHead);
487     if (memcpy_s(buf, DC_DATA_HEAD_SIZE, &pktHead, sizeof(TcpDataPacketHead)) != EOK) {
488         SoftBusFree(buf);
489         TRANS_LOGE(TRANS_CTRL, "memcpy_s error");
490         return NULL;
491     }
492     return buf;
493 }
494 
BuildInnerTdcSendDataInfo(EncrptyInfo * enInfo,char * finalData,uint32_t inLen,char * out,uint32_t * outLen)495 static void BuildInnerTdcSendDataInfo(EncrptyInfo *enInfo, char *finalData, uint32_t inLen, char *out, uint32_t *outLen)
496 {
497     enInfo->in = finalData;
498     enInfo->inLen = inLen;
499     enInfo->out = out;
500     enInfo->outLen = outLen;
501 }
502 
TransTdcPackAllData(TransTdcPackDataInfo * info,const char * sessionKey,const char * data,int32_t flags,DataLenInfo * lenInfo)503 char *TransTdcPackAllData(
504     TransTdcPackDataInfo *info, const char *sessionKey, const char *data, int32_t flags, DataLenInfo *lenInfo)
505 {
506     if (info == NULL || sessionKey == NULL || data == NULL || lenInfo == NULL) {
507         TRANS_LOGE(TRANS_CTRL, "param invalid.");
508         return NULL;
509     }
510     uint32_t dataLen = info->len + OVERHEAD_LEN;
511     char *finalData = (char *)data;
512     int32_t finalSeq = info->seq;
513     uint32_t tmpSeq = 0;
514     EncrptyInfo enInfo = { 0 };
515     if (flags == FLAG_ACK) {
516         finalSeq = *((int32_t *)data);
517         tmpSeq = SoftBusHtoNl((uint32_t)finalSeq);
518         finalData = (char *)(&tmpSeq);
519     }
520     if (info->supportTlv) {
521         DataHead pktHead = { 0 };
522         int32_t tlvBufferSize = 0;
523         int32_t ret = BuildDataHead(&pktHead, finalSeq, flags, dataLen, &tlvBufferSize);
524         TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, NULL, TRANS_CTRL, "build tlv dataHead failed");
525         ret = BuildNeedAckTlvData(&pktHead, info->needAck, 0, &tlvBufferSize); // sync process dataSeq must be zero.
526         TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, NULL, TRANS_CTRL, "build tlv needack failed");
527         char *buf = TransTdcPackTlvData(&pktHead, tlvBufferSize, dataLen);
528         if (buf == NULL) {
529             ReleaseDataHeadResource(&pktHead);
530             TRANS_LOGE(TRANS_CTRL, "pack tlv data fail");
531             return NULL;
532         }
533         ReleaseDataHeadResource(&pktHead);
534         lenInfo->tlvHeadLen = (uint32_t)(MAGICNUM_SIZE + TLVCOUNT_SIZE + tlvBufferSize);
535         BuildInnerTdcSendDataInfo(&enInfo, finalData, info->len, buf + lenInfo->tlvHeadLen, &lenInfo->outLen);
536         ret = TransTdcEncryptWithSeq(sessionKey, finalSeq, &enInfo);
537         if (ret != SOFTBUS_OK) {
538             SoftBusFree(buf);
539             return NULL;
540         }
541         return buf;
542     }
543     char *buf = TransPackData(dataLen, finalSeq, flags);
544     TRANS_CHECK_AND_RETURN_RET_LOGE(buf != NULL, NULL, TRANS_CTRL, "trans pack data failed");
545     BuildInnerTdcSendDataInfo(&enInfo, finalData, info->len, buf + DC_DATA_HEAD_SIZE, &lenInfo->outLen);
546     int32_t ret = TransTdcEncryptWithSeq(sessionKey, finalSeq, &enInfo);
547     if (ret != SOFTBUS_OK) {
548         SoftBusFree(buf);
549         return NULL;
550     }
551     return buf;
552 }
553 
TransTdcSendData(DataLenInfo * lenInfo,bool supportTlv,int32_t fd,uint32_t len,char * buf)554 int32_t TransTdcSendData(DataLenInfo *lenInfo, bool supportTlv, int32_t fd, uint32_t len, char *buf)
555 {
556     if (lenInfo == NULL || buf == NULL) {
557         TRANS_LOGE(TRANS_CTRL, "param invalid.");
558         return SOFTBUS_INVALID_PARAM;
559     }
560     uint32_t outLen = lenInfo->outLen;
561     if (outLen != len + OVERHEAD_LEN) {
562         TRANS_LOGE(TRANS_CTRL, "param invalid.");
563         return SOFTBUS_ENCRYPT_ERR;
564     }
565     uint32_t tmpHeadLen = DC_DATA_HEAD_SIZE;
566     if (supportTlv) {
567         TRANS_LOGD(TRANS_CTRL, "supportTlv is true");
568         tmpHeadLen = lenInfo->tlvHeadLen;
569     }
570     ssize_t ret = ConnSendSocketData(fd, buf, outLen + tmpHeadLen, 0);
571     if (ret != (ssize_t)outLen + (ssize_t)tmpHeadLen) {
572         TRANS_LOGE(TRANS_CTRL, "send bytes failed to send tcp data. channelId=%{public}d, ret=%{public}zd", fd, ret);
573         return GetErrCodeBySocketErr(SOFTBUS_TRANS_SEND_LEN_BEYOND_LIMIT);
574     }
575     return SOFTBUS_OK;
576 }
577