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