1 /*
2 * Copyright (C) 2022 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 "fillp_input.h"
17 #include "opt.h"
18 #include "fillp.h"
19 #include "fillp_flow_control.h"
20 #include "log.h"
21 #include "net.h"
22 #include "fillp_common.h"
23 #include "fillp_output.h"
24 #include "fillp_mgt_msg_log.h"
25 #include "fillp_dfx.h"
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 #define FILLP_HLEN_U 12u
31 #define FILLP_INTERVAL_RATE 4
32 #define FILLP_FACTOR_PAR 15
33 #define FILLP_JITTER_PAR 16
34
FillpCalRecvJitter(struct FtSocket * sock,FILLP_LLONG arrival,FILLP_LLONG receiveTransmit)35 static void FillpCalRecvJitter(struct FtSocket *sock, FILLP_LLONG arrival, FILLP_LLONG receiveTransmit)
36 {
37 FILLP_LLONG transmit = arrival - receiveTransmit;
38 FILLP_LLONG delta = transmit - sock->transmit;
39 double factor;
40 double factorJitter;
41
42 /* init the sock->transmit by current transmit when recv the fist data packet */
43 if ((sock->transmit == 0) && (sock->jitter == 0)) {
44 sock->transmit = transmit;
45 return;
46 }
47
48 sock->transmit = transmit;
49 if (delta < 0) {
50 delta = -delta;
51 }
52 FILLP_LOGDBG("last jitter:%lld d:%lld", sock->jitter, delta);
53 factor = (((double)1 / FILLP_JITTER_PAR) * (double)delta);
54 factorJitter = (((double)FILLP_FACTOR_PAR / FILLP_JITTER_PAR) * (double)(sock->jitter));
55 sock->jitter = (FILLP_LLONG)(factor + factorJitter);
56 FILLP_LOGDBG("current jitter:%lld", sock->jitter);
57 }
58
FillpChangePackInteval(struct FillpPcb * pcb)59 static void FillpChangePackInteval(struct FillpPcb *pcb)
60 {
61 struct FtNetconn *conn = FILLP_GET_CONN(pcb);
62 if (pcb->packState == FILLP_PACK_STATE_KEEP_ALIVE ||
63 (((struct FtSocket *)conn->sock)->resConf.common.enlargePackIntervalFlag == FILLP_TRUE &&
64 pcb->packTimerNode.interval != pcb->statistics.pack.packIntervalBackup)) {
65 FILLP_LOGDBG("FillpDataInput, change pack timer to working state with a new time interval %u, old %u",
66 pcb->statistics.pack.packIntervalBackup, pcb->statistics.pack.packInterval);
67 pcb->statistics.pack.packInterval = pcb->statistics.pack.packIntervalBackup;
68 FillpDisablePackTimer(pcb);
69 pcb->packTimerNode.interval = pcb->statistics.pack.packInterval;
70 FillpEnablePackTimer(pcb);
71 pcb->packState = FILLP_PACK_STATE_NORMAL;
72 }
73 }
74
FillpProcessDataOptions(FillpDataOption * dataOption,struct FillpPcb * pcb,struct FillpPcbItem * item)75 static FILLP_INT FillpProcessDataOptions(FillpDataOption *dataOption, struct FillpPcb *pcb, struct FillpPcbItem *item)
76 {
77 FILLP_INT err = ERR_OK;
78 struct FtSocket *sock = FILLP_GET_SOCKET(pcb);
79 switch (dataOption->type) {
80 case FILLP_OPT_TIMESTAMP:
81 if (dataOption->len == FILLP_OPT_TIMESTAMP_LEN) {
82 FILLP_LLONG sendTimestamp = 0;
83 FILLP_LLONG recvTimestamp = SYS_ARCH_GET_CUR_TIME_LONGLONG();
84 err = memcpy_s(&sendTimestamp, sizeof(FILLP_LLONG), &(dataOption->value[0]), sizeof(FILLP_LLONG));
85 if (err != EOK) {
86 FILLP_LOGERR("fillp_sock_id:%d, fillp_analysis_data_options memcpy_s failed : %d",
87 sock->index, err);
88 break;
89 }
90 sendTimestamp = (FILLP_LLONG)FILLP_NTOHLL((FILLP_ULLONG)sendTimestamp);
91 FillpCalRecvJitter(sock, recvTimestamp, sendTimestamp);
92 } else {
93 FILLP_LOGWAR("fillp_sock_id:%d, TIMESTAMP option length illegal, optLen %u != %u.",
94 FILLP_GET_SOCKET(pcb)->index, dataOption->len, FILLP_OPT_TIMESTAMP_LEN);
95 err = FILLP_EINVAL;
96 }
97 break;
98 case FILLP_OPT_FRAME_INFO:
99 err = FillpFrameParseOption(&pcb->frameHandle, item, &dataOption->value[0], dataOption->len);
100 break;
101 default:
102 break; /* for downward compatibility, here should not think as an error when no option type to match */
103 }
104 return err;
105 }
106
FillpAnalysisDataOptions(struct FillpPcb * pcb,struct FillpPcbItem * item)107 static FILLP_INT FillpAnalysisDataOptions(struct FillpPcb *pcb, struct FillpPcbItem *item)
108 {
109 FILLP_CHAR *datOptAddr = item->buf.p + FILLP_HLEN;
110 FILLP_UINT16 datOptLen;
111 FILLP_UINT16 curOptLen;
112 FillpDataOption *dataOption = FILLP_NULL_PTR;
113 FILLP_INT err = ERR_OK;
114
115 if (item->buf.len < FILLP_DATA_OFFSET_LEN) {
116 FILLP_LOGWAR("fillp_sock_id:%d, data option buffer len wrong, bufLen %d. \r\n", FILLP_GET_SOCKET(pcb)->index,
117 item->buf.len);
118 return FILLP_EINVAL;
119 }
120
121 datOptLen = *(FILLP_UINT16 *)datOptAddr;
122 datOptLen = FILLP_NTOHS(datOptLen);
123 item->dataOptLen = (FILLP_UINT16)(datOptLen + FILLP_DATA_OFFSET_LEN);
124 *(FILLP_UINT16 *)datOptAddr = datOptLen;
125 if (((FILLP_INT)datOptLen + FILLP_DATA_OFFSET_LEN) > item->buf.len) {
126 FILLP_LOGWAR("fillp_sock_id:%d, data option total length illegal, optLen %u > bufLen %d. \r\n",
127 FILLP_GET_SOCKET(pcb)->index, datOptLen, item->buf.len);
128 return FILLP_EINVAL;
129 }
130
131 datOptAddr += (FILLP_UINT16)FILLP_DATA_OFFSET_LEN;
132 while (datOptLen > 1) {
133 dataOption = (FillpDataOption *)datOptAddr;
134 curOptLen = (FILLP_UINT16)((FILLP_UINT16)dataOption->len + FILLP_DATA_OPT_HLEN);
135 if (curOptLen > datOptLen) {
136 FILLP_LOGWAR("fillp_sock_id:%d, current data option length illegal, optLen %u > remain optLen %u.",
137 FILLP_GET_SOCKET(pcb)->index, dataOption->len, datOptLen);
138 err = FILLP_EINVAL;
139 break;
140 }
141 err = FillpProcessDataOptions(dataOption, pcb, item);
142 if (err != ERR_OK) {
143 break;
144 }
145 datOptAddr += curOptLen;
146 datOptLen -= curOptLen;
147 }
148
149 return err;
150 }
151
FillpProcessItemData(struct FillpPcb * pcb,struct FillpPcbItem * item,FILLP_CONST struct FillpPktHead * pktHdr)152 static void FillpProcessItemData(struct FillpPcb *pcb, struct FillpPcbItem *item,
153 FILLP_CONST struct FillpPktHead *pktHdr)
154 {
155 if ((FILLP_INT)item->dataLen + (FILLP_INT)item->dataOptLen != item->buf.len) {
156 FILLP_LOGWAR(" fillp_sock_id:%d packet length err, dataLen:%u, option eare size:%u, buflen:%d ",
157 FILLP_GET_SOCKET(pcb)->index, item->dataLen, item->dataOptLen, item->buf.len);
158 FillpFreeBufItem(item);
159 return;
160 }
161 if (!FillpNumIsbigger(item->seqNum, pcb->recv.seqNum)) {
162 FillpFcDataInput(pcb, pktHdr);
163 FillpFreeBufItem(item);
164 FillpFcRecvDropOne(pcb);
165 return;
166 }
167 if (g_resource.common.outOfOrderCacheEnable && (g_appResource.common.enableNackDelay == FILLP_FALSE)) {
168 if (SkipListInsert(&pcb->recv.recvBoxPlaceInOrder, (void *)item, &item->skipListNode, FILLP_TRUE)) {
169 FILLP_LOGDTL("fillp_sock_id:%d Failed to insert node in recvBoxPlaceInOrder",
170 FILLP_GET_SOCKET(pcb)->index);
171 FillpFreeBufItem(item);
172 return;
173 }
174
175 if (pcb->recv.recvBoxPlaceInOrder.nodeNum >= g_resource.common.recvCachePktNumBufferSize) {
176 struct FillpPcbItem *itemPre = SkipListPopValue(&pcb->recv.recvBoxPlaceInOrder);
177 if (itemPre == FILLP_NULL_PTR) {
178 FILLP_LOGDTL("fillp_sock_id:%d FillpDataInput: pcb is NULL!!!", FILLP_GET_SOCKET(pcb)->index);
179 return;
180 }
181 FillpDataToStack(pcb, itemPre);
182 }
183 } else {
184 FillpDataToStack(pcb, item);
185 }
186 }
187
FillpDataInput(struct FillpPcb * pcb,struct FillpPcbItem * item)188 IGNORE_OVERFLOW static void FillpDataInput(struct FillpPcb *pcb, struct FillpPcbItem *item)
189 {
190 FILLP_CONST struct FillpPktHead *pktHdr = (struct FillpPktHead *)(void *)item->buf.p;
191 FILLP_UINT32 privRecvCacheSize = 0;
192
193 FillpChangePackInteval(pcb);
194
195 item->fpcb = pcb;
196 item->pktNum = pktHdr->pktNum;
197 item->seqNum = pktHdr->seqNum;
198 item->dataLen = pktHdr->dataLen;
199
200 if (FillpNumIsbigger(item->seqNum, (pcb->recv.seqNum + pcb->recv.pktRecvCache + privRecvCacheSize))) {
201 FILLP_LOGWAR("fillp_sock_id:%d, seqnum received = %u from the peer is not in the send window range = %u",
202 FILLP_GET_SOCKET(pcb)->index, item->seqNum,
203 (pcb->recv.seqNum + pcb->recv.pktRecvCache + privRecvCacheSize));
204
205 FillpFreeBufItem(item);
206 return;
207 }
208
209 if (FILLP_PKT_GET_DAT_WITH_OPTION(pktHdr->flag)) {
210 if (FillpAnalysisDataOptions(pcb, item) != ERR_OK) {
211 FILLP_LOGWAR("fillp_sock_id:%d Failed to analysis data options.", FILLP_GET_SOCKET(pcb)->index);
212 FillpFreeBufItem(item);
213 return;
214 }
215 } else {
216 item->dataOptLen = 0;
217 }
218 FillpProcessItemData(pcb, item, pktHdr);
219 }
220
ProcessPcbItem(struct FillpPcb * pcb,FILLP_CONST struct NetBuf * buf,struct FillpPcbItem * pcbBuf)221 static void ProcessPcbItem(struct FillpPcb *pcb, FILLP_CONST struct NetBuf *buf, struct FillpPcbItem *pcbBuf)
222 {
223 FILLP_CONST struct FillpPktHead *pktHdr = (struct FillpPktHead *)(void *)buf->p;
224 if (pcbBuf != FILLP_NULL_PTR) {
225 pcbBuf->rxTimeStamp = SYS_ARCH_GET_CUR_TIME_LONGLONG();
226 pcbBuf->frame = FILLP_NULL_PTR;
227 UTILS_FLAGS_RESET(pcbBuf->flags);
228 /* We can't use mem copy here , which will rewrite the buf->p */
229 pcbBuf->buf.addr = buf->addr;
230 pcbBuf->buf.len = buf->len;
231 FillpErrorType err = memcpy_s(pcbBuf->buf.p, (FILLP_UINT32)(pcb->pktSize + FILLP_HLEN), buf->p,
232 (FILLP_UINT32)(buf->len + FILLP_HLEN));
233 if (err != EOK) {
234 FILLP_LOGERR("fillp_do_input_pkt_type memcpy_s failed: %d, fillp_sock_id:%d",
235 err, FILLP_GET_SOCKET(pcb)->index);
236 return;
237 }
238 FillpDataInput(pcb, pcbBuf);
239 if (FILLP_PKT_GET_DAT_WITH_FIRST_FLAG(pktHdr->flag)) {
240 FILLP_LOGINF("first flag: fillpSockId:%d, seqNum:%u, flag: 0x%4x",
241 FILLP_GET_SOCKET(pcb)->index, pktHdr->seqNum, pktHdr->flag);
242 }
243 if (FILLP_PKT_GET_DAT_WITH_LAST_FLAG(pktHdr->flag)) {
244 FILLP_LOGINF("last flag: fillpSockId:%d, seqNum:%u, flag: 0x%4x",
245 FILLP_GET_SOCKET(pcb)->index, pktHdr->seqNum, pktHdr->flag);
246 }
247 } else {
248 struct SkipListNode *node;
249 node = SkipListGetPop(&pcb->recv.recvList);
250 struct FillpPcbItem *item = FILLP_NULL_PTR;
251 FILLP_UINT32 lostSeqNum = pcb->recv.seqNum;
252 if (node != FILLP_NULL_PTR) {
253 item = (struct FillpPcbItem *)node->item;
254 lostSeqNum = (item->seqNum - item->dataLen);
255 }
256 }
257 }
258
FillpHdlDataInput(struct FillpPcb * pcb,FILLP_CONST struct NetBuf * buf)259 static void FillpHdlDataInput(struct FillpPcb *pcb, FILLP_CONST struct NetBuf *buf)
260 {
261 FILLP_CONST struct FillpPktHead *pktHdr = (struct FillpPktHead *)(void *)buf->p;
262 struct FillpPcbItem *pcbBuf = FILLP_NULL_PTR;
263 int netconnState = NETCONN_GET_STATE(FILLP_GET_CONN(pcb));
264 if ((netconnState != CONN_STATE_CLOSING) && (netconnState != CONN_STATE_CONNECTED)) {
265 // Drop it silently
266 FILLP_LOGDBG("not connected or connecting, drop it !!!!!");
267 FillpDfxPktNotify(FILLP_GET_SOCKET(pcb)->index, FILLP_DFX_PKT_PARSE_FAIL, 1U);
268 return;
269 }
270
271 (void)FillpMallocBufItem(pcb->recv.itemPool, (void **)&pcbBuf, FILLP_FALSE);
272 if (pcbBuf == FILLP_NULL_PTR) {
273 if (FillpAskMoreBufItem(pcb->recv.itemPool, FILLP_DYMM_INCREASE_STEP_RECV, FILLP_FALSE) > 0) {
274 (void)FillpMallocBufItem(pcb->recv.itemPool, (void **)&pcbBuf, FILLP_FALSE);
275 pcb->recv.curItemCount = (FILLP_UINT32)DYMP_GET_CUR_SIZE(pcb->recv.itemPool);
276 }
277 }
278
279 if (pcbBuf == FILLP_NULL_PTR) {
280 /* items inst recv cache are all using, try to replace the max seq item in recvList */
281 struct FillpPcbItem *item = FILLP_NULL_PTR;
282 struct SkipListNode *node = SkipListGetTail(&pcb->recv.recvList);
283 if (node != FILLP_NULL_PTR) {
284 item = (struct FillpPcbItem *)node->item;
285 }
286 if ((item != FILLP_NULL_PTR) && FillpNumIsbigger(item->seqNum, pktHdr->seqNum) &&
287 FillpNumIsbigger(pktHdr->seqNum, pcb->recv.seqNum)) {
288 item = (struct FillpPcbItem *)SkipListPopTail(&pcb->recv.recvList);
289 FillpSendNack(pcb, (FILLP_UINT32)(item->pktNum - 1), (FILLP_UINT32)(item->pktNum + 1));
290 pcbBuf = item;
291 FILLP_LOGDTL("replace big seq item, fillp_sock_id:%d, seqNum:%u replace seqNum:%u",
292 FILLP_GET_SOCKET(pcb)->index, pktHdr->seqNum, item->seqNum);
293 }
294 }
295 ProcessPcbItem(pcb, buf, pcbBuf);
296 }
297
FillpCheckNackPacket(FILLP_CONST struct FillpPcb * pcb,FILLP_CONST struct NetBuf * p)298 static int FillpCheckNackPacket(FILLP_CONST struct FillpPcb *pcb, FILLP_CONST struct NetBuf *p)
299 {
300 /* We should check for minimum length because of optional parameter total length may be more, which can be added in
301 future version of stack, current version just ignore optlen as none is defined */
302 if (p->len < (FILLP_INT)(sizeof(struct FillpPktNackWithRandnum) - FILLP_HLEN)) {
303 FILLP_LOGWAR("fillp_sock_id:%d, Invalid nack request, len = %d", FILLP_GET_SOCKET(pcb)->index, p->len);
304 return -1;
305 }
306
307 FILLP_UINT8 connState = FILLP_GET_CONN_STATE(pcb);
308 if ((CONN_STATE_CLOSING != connState) && (CONN_STATE_CONNECTED != connState)) {
309 FILLP_LOGINF("netconn state not correct for NACK, state:%u", connState);
310 return -1;
311 }
312 return 0;
313 }
314
FillpCheckNackSeq(FILLP_CONST struct FillpPcb * pcb,FILLP_CONST struct FillpPktHead * pktHdr,FILLP_CONST struct FillpSeqPktNum * seqPktNum)315 IGNORE_OVERFLOW static int FillpCheckNackSeq(FILLP_CONST struct FillpPcb *pcb,
316 FILLP_CONST struct FillpPktHead *pktHdr, FILLP_CONST struct FillpSeqPktNum *seqPktNum)
317 {
318 if (FillpNumIsbigger(pktHdr->seqNum, pcb->send.seqNum) ||
319 FillpNumIsbigger(pcb->send.seqNum, (pktHdr->seqNum + pcb->send.pktSendCache))) {
320 FILLP_LOGDTL("fillp_sock_id:%d Invalid NACK sequence number. seqNum = %u, pcb->send.seqNum = %u",
321 FILLP_GET_SOCKET(pcb)->index, pktHdr->seqNum, pcb->send.seqNum);
322 return -1;
323 }
324
325 /* use to ignore the redundant nack packet */
326 if ((pcb->send.nackPktStartNum == seqPktNum->beginPktNum) &&
327 (pcb->send.nackPktEndNum == seqPktNum->endPktNum)) {
328 return -1;
329 }
330 return 0;
331 }
332
FillpNackInputTrace(FILLP_CONST struct FtSocket * sock,FILLP_CONST struct FillpPktNack * nack,FILLP_CONST struct FillpPktHead * pktHdr)333 static void FillpNackInputTrace(FILLP_CONST struct FtSocket *sock, FILLP_CONST struct FillpPktNack *nack,
334 FILLP_CONST struct FillpPktHead *pktHdr)
335 {
336 struct FillpPktNack tmpNack;
337 struct FillpPktHead *tmpHead = (struct FillpPktHead *)(void *)tmpNack.head;
338 FillpTraceDescriptSt fillpTrcDesc;
339 if ((sock != FILLP_NULL_PTR) && (sock->traceFlag >= FILLP_TRACE_DIRECT_NETWORK)) {
340 /* Recovert the header to NETWORK byte order to provide indication */
341 tmpHead->flag = FILLP_HTONS(pktHdr->flag);
342 tmpHead->dataLen = FILLP_HTONS(pktHdr->dataLen);
343 tmpHead->pktNum = FILLP_HTONL(pktHdr->pktNum);
344 tmpHead->seqNum = FILLP_HTONL(pktHdr->seqNum);
345
346 /* Below field is already in NETWORK byte order */
347 tmpNack.lastPktNum = nack->lastPktNum;
348
349 FILLP_LM_FILLPMSGTRACE_OUTPUT_WITHOUT_FT_TRACE_ENABLE_FLAG(FILLP_TRACE_DIRECT_NETWORK, sock->traceHandle,
350 sizeof(struct FillpPktNack), sock->index, fillpTrcDesc, (FILLP_CHAR *)(&tmpNack));
351 }
352 }
353
FillpGetSeqFromPktSeqHash(FILLP_UINT32 pktNum,FILLP_CONST struct FillpHashLlist * mapList,struct FillpPcbItem ** outItem)354 static FILLP_INT FillpGetSeqFromPktSeqHash(FILLP_UINT32 pktNum, FILLP_CONST struct FillpHashLlist *mapList,
355 struct FillpPcbItem **outItem)
356 {
357 FILLP_UINT32 hashIndex = (FILLP_UINT32)(pktNum & mapList->hashModSize);
358 struct Hlist *list = &mapList->hashMap[hashIndex];
359 struct HlistNode *pos = HLIST_FIRST(list);
360 struct FillpPcbItem *item = FILLP_NULL_PTR;
361
362 while (pos != FILLP_NULL_PTR) {
363 item = FillpPcbPktSeqMapNodeEntry(pos);
364
365 if (item->pktNum == pktNum) {
366 *outItem = item;
367 return FILLP_OK;
368 } else if (FillpNumIsbigger(item->pktNum, pktNum)) {
369 return FILLP_ERR_VAL;
370 }
371 pos = pos->next;
372 }
373
374 return FILLP_ERR_VAL;
375 }
376
ProtectLongLoopRun(struct FillpPcb * pcb,FILLP_UINT32 identifyGap,struct FillpSeqPktNum * seqPktNum,FILLP_INT * isUsed)377 static FILLP_UINT32 ProtectLongLoopRun(struct FillpPcb *pcb, FILLP_UINT32 identifyGap,
378 struct FillpSeqPktNum *seqPktNum, FILLP_INT *isUsed)
379 {
380 FILLP_UINT32 pktIndex;
381 FILLP_UINT32 protectLoopCounter;
382 FILLP_UINT32 startLoop = seqPktNum->beginPktNum + 1;
383 FILLP_UINT32 lostPktGap = 0;
384 struct FillpSendPcb *sendPcb = &pcb->send;
385 for (pktIndex = startLoop, protectLoopCounter = 0;
386 (FillpNumIsbigger(seqPktNum->endPktNum, pktIndex)) && (protectLoopCounter <= identifyGap);
387 pktIndex++, protectLoopCounter++) {
388 /* Check if pktNum still in unAck table */
389 struct FillpPcbItem *unackItem = FILLP_NULL_PTR;
390 if (FillpGetSeqFromPktSeqHash(pktIndex, &sendPcb->pktSeqMap, &unackItem)) {
391 continue; /* Not Found, skip it */
392 }
393
394 if (unackItem->seqNum <= seqPktNum->beginSeqNum) {
395 FILLP_LOGBUTT("FILLP_UINT32, unackItem->seqNum: %u, beginSeqNum: %u",
396 unackItem->seqNum, seqPktNum->beginSeqNum);
397 continue;
398 }
399
400 /* Query Success , delete pkt-seq map */
401 HlistDelNode(&unackItem->pktSeqMapNode);
402 HlistDelNode(&unackItem->node);
403 lostPktGap++;
404 if (pcb->send.unackList.count > 0) {
405 pcb->send.unackList.count--;
406 }
407
408 pcb->send.inSendBytes -= (FILLP_ULLONG)unackItem->dataLen;
409 unackItem->infCount--;
410 if (identifyGap > FILLP_MAX_LOST_NUM_FOR_REDUN) {
411 UTILS_FLAGS_CLEAN(unackItem->flags, FILLP_ITEM_FLAGS_REDUNDANT);
412 }
413 if (SkipListInsert(&pcb->send.unrecvList, unackItem, &unackItem->skipListNode, FILLP_TRUE)) {
414 InsertUnrecvListFail(pcb, unackItem);
415 /* Inserting ack item to SkipList failed, skip and continue */
416 continue;
417 }
418
419 pcb->send.unrecvRedunListBytes += unackItem->dataLen;
420 unackItem->sendCount++;
421 unackItem->resendTrigger = (FILLP_UINT8)FILLP_ITEM_RESEND_TRIGGER_HNACK;
422 pcb->statistics.appFcStastics.periodSendLostPkts++;
423 if (isUsed != FILLP_NULL_PTR) {
424 *isUsed = 1;
425 }
426 }
427 return lostPktGap;
428 }
429
430 /**
431 * Query SEQNUM in unackList, move item to unrecvList if query success.Then delete pkt-seq map relation
432 */
FillpNackInput(struct FillpPcb * pcb,FILLP_CONST struct NetBuf * p)433 static void FillpNackInput(struct FillpPcb *pcb, FILLP_CONST struct NetBuf *p)
434 {
435 struct FtSocket *ftSock = (struct FtSocket *)FILLP_GET_CONN(pcb)->sock;
436 FILLP_UINT32 identifyGap = 0;
437 struct FillpSeqPktNum seqPktNum;
438
439 if (FillpCheckNackPacket(pcb, p) != 0) {
440 FillpDfxPktNotify(ftSock->index, FILLP_DFX_PKT_PARSE_FAIL, 1U);
441 return;
442 }
443
444 struct FillpPktNackWithRandnum *nackReq = (struct FillpPktNackWithRandnum *)(void *)p->p;
445 struct FillpPktNack *nack = &nackReq->nack;
446
447 /* Header fields are already converted in FillpDoInput, and hence here
448 should not be converted again
449 */
450 struct FillpPktHead *pktHdr = (struct FillpPktHead *)nack->head;
451 seqPktNum.endPktNum = FILLP_NTOHL(nack->lastPktNum);
452 seqPktNum.beginPktNum = pktHdr->pktNum;
453 seqPktNum.beginSeqNum = pktHdr->seqNum;
454 if (FillpCheckNackSeq(pcb, pktHdr, &seqPktNum) != 0) {
455 return;
456 }
457 pcb->send.nackPktStartNum = seqPktNum.beginPktNum;
458 pcb->send.nackPktEndNum = seqPktNum.endPktNum;
459
460 FILLP_LOGDBG("recv NACK sockId:%d,seqNum:%u,startPKTNum:%u,endPktNum:%u,gap:%u,unrecvList:%u,unackList:%u",
461 FILLP_GET_SOCKET(pcb)->index, pktHdr->seqNum, pktHdr->pktNum, seqPktNum.endPktNum, seqPktNum.endPktNum -
462 (seqPktNum.beginPktNum + 1), pcb->send.unrecvList.nodeNum, pcb->send.unackList.count);
463
464 FillpNackInputTrace(ftSock, nack, pktHdr);
465 FILLP_LOGDBG("recv NACK send seqnum = %u,send pkt = %u", pcb->send.seqNum, pcb->send.pktNum);
466 FILLP_UINT32 startLoop = seqPktNum.beginPktNum + 1;
467 if (FillpNumIsbigger(seqPktNum.endPktNum, startLoop)) {
468 identifyGap = (seqPktNum.endPktNum - startLoop);
469 } else {
470 FILLP_LOGDTL("curPktNum(%u) is smaller than lastPktNum(%u)", seqPktNum.endPktNum, seqPktNum.beginPktNum);
471 return;
472 }
473
474 if (identifyGap >= pcb->mpSendSize) {
475 identifyGap = pcb->mpSendSize;
476 }
477
478 FILLP_UINT32 lostPktGap = ProtectLongLoopRun(pcb, identifyGap, &seqPktNum, FILLP_NULL);
479 FILLP_UNUSED_PARA(lostPktGap);
480 if (pcb->send.unrecvList.nodeNum) {
481 FillpEnableSendTimer(pcb);
482 }
483 if (FillpNumIsbigger(seqPktNum.beginSeqNum, pcb->send.maxAckNumFromReceiver)) {
484 pcb->send.maxAckNumFromReceiver = seqPktNum.beginSeqNum;
485 }
486 pcb->statistics.debugPcb.nackRcv++;
487 FillpFcNackInput(pcb, nack);
488 }
489
FillpCheckPackInput(struct FillpPcb * pcb,FILLP_CONST struct NetBuf * p)490 static FILLP_BOOL FillpCheckPackInput(struct FillpPcb *pcb, FILLP_CONST struct NetBuf *p)
491 {
492 FILLP_UINT8 connState = FILLP_GET_CONN_STATE(pcb);
493 if ((connState != CONN_STATE_CLOSING) && (connState != CONN_STATE_CONNECTED)) {
494 /* Changed the log level from WAR to INFO, because peer would have sent the outstanding
495 packs at the time when local side connection is closed.
496 */
497 FILLP_LOGINF("netconn state not correct for PACK,state:%hhu", connState);
498 return FILLP_FALSE;
499 }
500 /* We should check for minimum length because of optional parameter total length may be more, which can be added in
501 future version of stack, current version just ignore optlen as none is defined */
502 if (p->len < (FILLP_INT)(FILLP_PACK_MIN_LEN - FILLP_HLEN)) {
503 FILLP_LOGWAR("fillp_sock_id:%d, Invalid pack request, len = %d", FILLP_GET_SOCKET(pcb)->index, p->len);
504 return FILLP_FALSE;
505 }
506 return FILLP_TRUE;
507 }
508
FillpPackInputSendMsgTrace(FILLP_CONST struct FillpPcb * pcb,FILLP_CONST struct FillpPktHead * pktHdr,FILLP_CONST struct FillpPktPack * pack)509 static void FillpPackInputSendMsgTrace(FILLP_CONST struct FillpPcb *pcb, FILLP_CONST struct FillpPktHead *pktHdr,
510 FILLP_CONST struct FillpPktPack *pack)
511 {
512 struct FtSocket *ftSock;
513 FillpTraceDescriptSt fillpTrcDesc;
514
515 ftSock = FILLP_GET_SOCKET(pcb);
516 if (ftSock == FILLP_NULL_PTR) {
517 FILLP_LOGERR("sock is NULL");
518 return;
519 }
520
521 if (ftSock->traceFlag >= FILLP_TRACE_DIRECT_NETWORK) {
522 struct FillpPktPack tmpPack;
523 struct FillpPktHead *tmpHead = (struct FillpPktHead *)(void *)tmpPack.head;
524 FILLP_UINT16 traceMsgLen = sizeof(struct FillpPktPack);
525
526 (void)memset_s(&tmpPack, sizeof(tmpPack), 0, sizeof(tmpPack));
527 /* Recovert the header to NETWORK byte order to provide indication */
528 tmpHead->flag = FILLP_HTONS(pktHdr->flag);
529 tmpHead->dataLen = FILLP_HTONS(pktHdr->dataLen);
530 tmpHead->pktNum = FILLP_HTONL(pktHdr->pktNum);
531 tmpHead->seqNum = FILLP_HTONL(pktHdr->seqNum);
532
533 /* Below field is already in NETWORK byte order */
534 tmpPack.flag = pack->flag;
535 tmpPack.pktLoss = pack->pktLoss;
536 tmpPack.rate = pack->rate;
537 tmpPack.oppositeSetRate = pack->oppositeSetRate;
538 tmpPack.lostSeq = pack->lostSeq;
539 tmpPack.bgnPktNum = pack->bgnPktNum;
540 tmpPack.endPktNum = pack->endPktNum;
541 tmpPack.optsOffset = pack->optsOffset;
542 tmpPack.rcvListBytes = pack->rcvListBytes;
543
544 if ((FILLP_NTOHS(pack->flag) & FILLP_PACK_FLAG_WITH_RTT) &&
545 (!(pktHdr->dataLen < (FILLP_PACK_MIN_LEN - FILLP_HLEN))) && (!pcb->rtt)) {
546 tmpPack.reserved.rtt = pack->reserved.rtt;
547 } else {
548 tmpPack.reserved.rtt = 0;
549 }
550
551 if (traceMsgLen > (pktHdr->dataLen + (FILLP_UINT16)FILLP_HLEN)) {
552 traceMsgLen = pktHdr->dataLen + (FILLP_UINT16)FILLP_HLEN;
553 }
554
555 FILLP_LM_FILLPMSGTRACE_OUTPUT_WITHOUT_FT_TRACE_ENABLE_FLAG(FILLP_TRACE_DIRECT_NETWORK, ftSock->traceHandle,
556 (FILLP_UINT32)traceMsgLen, FILLP_GET_SOCKET(pcb)->index, fillpTrcDesc, (FILLP_CHAR *)(&tmpPack));
557 }
558 }
559
FillpCheckPackNumber(struct FillpPcb * pcb,struct FillpPktPack * pack,FILLP_UINT32 ackSeqNum,FILLP_UINT32 lostSeqNum)560 IGNORE_OVERFLOW static FILLP_BOOL FillpCheckPackNumber(struct FillpPcb *pcb,
561 struct FillpPktPack *pack, FILLP_UINT32 ackSeqNum, FILLP_UINT32 lostSeqNum)
562 {
563 struct FillpPktHead *pktHdr = (struct FillpPktHead *)pack->head;
564 if (FillpNumIsbigger(ackSeqNum, pcb->send.seqNum) ||
565 FillpNumIsbigger(pcb->send.seqNum, (ackSeqNum + pcb->send.pktSendCache))) {
566 FILLP_LOGERR("fillp_sock_id:%d, error:ack seqnum:%u send seqnum:%u, ackSeqNum:%u unSendList:%u, unRecvList:%u,"
567 "unAckList:%u, itemWaitTokenLists:%u, redunList:%u, curItemCount:%u, mpSendSize:%u",
568 FILLP_GET_SOCKET(pcb)->index, ackSeqNum, pcb->send.seqNum, pcb->send.ackSeqNum,
569 pcb->send.unSendList.size, pcb->send.unrecvList.nodeNum, pcb->send.unackList.count,
570 pcb->send.itemWaitTokenLists.nodeNum, pcb->send.redunList.nodeNum, pcb->send.curItemCount,
571 pcb->mpSendSize);
572 return FILLP_FALSE;
573 }
574
575 if (FillpNumIsbigger(pktHdr->pktNum, pcb->send.pktNum)) {
576 FILLP_LOGDBG("error: ack pktnum =%u sendpktnum = %u", pktHdr->pktNum, pcb->send.pktNum);
577 return FILLP_FALSE;
578 }
579
580 if (FillpNumIsbigger(ackSeqNum, lostSeqNum)) {
581 FILLP_LOGERR("error: ackSeqNum:%u, lost pktnum:%u", ackSeqNum, lostSeqNum);
582 return FILLP_FALSE;
583 }
584
585 FILLP_LOGDBG("fillp_sock_id:%d loss:%u,rate:%u,seq:%u,pkt:%u,flag:%u,oppRate:%u,lostSeq:%u",
586 FILLP_GET_SOCKET(pcb)->index, FILLP_NTOHS(pack->pktLoss),
587 FILLP_NTOHL(pack->rate), pktHdr->seqNum, pktHdr->pktNum,
588 FILLP_NTOHS(pack->flag), FILLP_NTOHL(pack->oppositeSetRate), lostSeqNum);
589
590 return FILLP_TRUE;
591 }
592
FillpHandleAdhocpackFlag(struct FillpPcb * pcb,struct FillpPktPack * pack)593 static void FillpHandleAdhocpackFlag(struct FillpPcb *pcb, struct FillpPktPack *pack)
594 {
595 if (pack->flag & FILLP_PACK_FLAG_REQURE_RTT) {
596 struct FillpPktPack tmpPack;
597 struct FtSocket *ftSock = FILLP_NULL_PTR;
598
599 (void)memset_s(&tmpPack, sizeof(tmpPack), 0, sizeof(tmpPack));
600 tmpPack.rate = pcb->statistics.pack.periodRecvRate;
601 tmpPack.oppositeSetRate = 0;
602 tmpPack.flag = FILLP_NULL_NUM;
603 tmpPack.flag |= FILLP_PACK_FLAG_ADHOC;
604 tmpPack.flag |= FILLP_PACK_FLAG_WITH_RTT;
605 tmpPack.pktLoss = 0;
606 tmpPack.reserved.rtt = FILLP_NTOHL(pack->reserved.rtt);
607 tmpPack.lostSeq = pcb->recv.seqNum;
608
609 ftSock = FILLP_GET_SOCKET(pcb);
610 pcb->adhocPackReplied = FILLP_TRUE;
611 FillpBuildAndSendPack(pcb, ftSock, &tmpPack, sizeof(struct FillpPktPack) - FILLP_HLEN);
612 }
613
614 if (pack->flag & FILLP_PACK_FLAG_WITH_RTT) {
615 FILLP_LLONG curTime = SYS_ARCH_GET_CUR_TIME_LONGLONG();
616
617 pack->reserved.rtt = FILLP_NTOHL(pack->reserved.rtt);
618 /* rtt isn't much large, so only use the low 32bit is ok */
619 pcb->statistics.appFcStastics.periodRtt =
620 FILLP_UTILS_US2MS(((FILLP_UINT32)((FILLP_ULLONG)curTime & 0xFFFFFFFF) - pack->reserved.rtt));
621 FILLP_LOGDBG("fillp_sock_id:%d, rtt = %u", FILLP_GET_SOCKET(pcb)->index,
622 pcb->statistics.appFcStastics.periodRtt);
623 }
624
625 if (pcb->algFuncs.hdlPackFlag != FILLP_NULL_PTR) {
626 pcb->algFuncs.hdlPackFlag(pcb, pack);
627 }
628 }
629
FillpTryAckSendPcbByPackInfo(struct FillpPcb * pcb,FILLP_CONST struct FillpPktPack * pack,FILLP_UINT32 ackSeqNum,FILLP_UINT32 lostSeqNum)630 static void FillpTryAckSendPcbByPackInfo(struct FillpPcb *pcb, FILLP_CONST struct FillpPktPack *pack,
631 FILLP_UINT32 ackSeqNum, FILLP_UINT32 lostSeqNum)
632 {
633 if (FillpNumIsbigger(ackSeqNum, pcb->send.ackSeqNum)) {
634 if (FillpNumIsbigger(ackSeqNum, pcb->send.maxAckNumFromReceiver)) {
635 pcb->send.maxAckNumFromReceiver = ackSeqNum;
636 if (lostSeqNum != ackSeqNum) {
637 FILLP_LOGDBG("fillp_sock_id:%d PACK: %u ~ %u, rate : %ukbps, Lost :%u unackcount:%u",
638 FILLP_GET_SOCKET(pcb)->index, ackSeqNum, lostSeqNum, pack->rate, pack->pktLoss,
639 FillpGetSendpcbUnackListPktNum(&(pcb->send)));
640 }
641 }
642 FillpAckSendPcb(pcb, FILLP_MAXIMAL_ACK_NUM_LIMITATION);
643 }
644 }
645
FillpHdlAdhocpack(struct FillpPcb * pcb,struct FillpPktPack * pack)646 static void FillpHdlAdhocpack(struct FillpPcb *pcb, struct FillpPktPack *pack)
647 {
648 struct FillpPktHead *pktHdr = (struct FillpPktHead *)pack->head;
649 FillpHandleAdhocpackFlag(pcb, pack);
650 FillpTryAckSendPcbByPackInfo(pcb, pack, pktHdr->seqNum, pack->lostSeq);
651 }
652
FillpChangePackInterval(struct FillpPcb * pcb,FILLP_CONST struct FtSocket * sock,FILLP_CONST struct FillpPktPack * pack)653 static void FillpChangePackInterval(struct FillpPcb *pcb, FILLP_CONST struct FtSocket *sock,
654 FILLP_CONST struct FillpPktPack *pack)
655 {
656 // It need to cancel if receiving any data from peer
657 if (sock->resConf.common.enlargePackIntervalFlag && (pack->flag & FILLP_PACK_FLAG_NO_DATA_SEND)) {
658 pcb->statistics.pack.packInterval = FILLP_NODATARECV_PACK_INTERVAL;
659 } else {
660 pcb->statistics.pack.packInterval = pcb->statistics.pack.packIntervalBackup;
661 }
662 }
663
FillpHandlePackFlag(struct FillpPcb * pcb,struct FillpPktPack * pack)664 static FILLP_INT FillpHandlePackFlag(struct FillpPcb *pcb, struct FillpPktPack *pack)
665 {
666 if ((pack->flag & FILLP_PACK_FLAG_WITH_RTT) && (!pcb->rtt)) {
667 pack->reserved.rtt = FILLP_NTOHL(pack->reserved.rtt);
668 pcb->rtt = pack->reserved.rtt;
669 if (pcb->rtt > 0) {
670 FillpAdjustFcParamsByRtt(pcb);
671 }
672 }
673
674 if ((!pcb->statistics.pack.peerRtt) && (!(pack->flag & FILLP_PACK_FLAG_REQURE_RTT))) {
675 pcb->statistics.pack.peerRtt = FILLP_TRUE;
676 }
677
678 struct FtSocket *sock = (struct FtSocket *)FILLP_GET_CONN(pcb)->sock;
679 if (sock == FILLP_NULL_PTR) {
680 FILLP_LOGERR("sock is null");
681 return -1;
682 }
683 FillpChangePackInterval(pcb, sock, pack);
684
685 pcb->packTimerNode.interval = pcb->statistics.pack.packInterval;
686
687 if (pcb->algFuncs.hdlPackFlag != FILLP_NULL_PTR) {
688 pcb->algFuncs.hdlPackFlag(pcb, pack);
689 }
690
691 return ERR_OK;
692 }
693
MoveUnackToUnrecvByPackInfo(struct FillpPcb * pcb,FILLP_UINT32 ackSeqNum,FILLP_UINT32 lostSeqNum)694 static void MoveUnackToUnrecvByPackInfo(struct FillpPcb *pcb, FILLP_UINT32 ackSeqNum, FILLP_UINT32 lostSeqNum)
695 {
696 /* when FILLP_RETRANSMIT_CMP_TIME_EXT is 0, packet item resend is controlled by pack cnt with same
697 * ackSeqNum */
698 if (g_resource.retransmitCmpTime) {
699 FillpMoveUnackToUnrecv(ackSeqNum, lostSeqNum, pcb, FILLP_TRUE);
700 return;
701 }
702
703 if (ackSeqNum == pcb->send.lastPackAckSeq) {
704 FILLP_UINT8 cmp_threshold = pcb->send.packMoveToUnrecvThreshold;
705 pcb->send.packSameAckNum++;
706 if (pcb->send.packSameAckNum >= cmp_threshold) {
707 FillpMoveUnackToUnrecv(ackSeqNum, lostSeqNum, pcb, FILLP_TRUE);
708 pcb->send.packSameAckNum = 0;
709 }
710 } else {
711 pcb->send.lastPackAckSeq = ackSeqNum;
712 pcb->send.packSameAckNum = 0;
713 }
714 }
715
FillpPackInputLog(FILLP_CONST struct FillpPcb * pcb)716 static void FillpPackInputLog(FILLP_CONST struct FillpPcb *pcb)
717 {
718 FILLP_LOGDBG("fillp_sock_id:%d nackSend:%u,nackFailed:%u,nackRcv:%u,packSend:%u,packFailed:%u,packRcv:%u",
719 FILLP_GET_SOCKET(pcb)->index, pcb->statistics.debugPcb.nackSend, pcb->statistics.debugPcb.nackFailed,
720 pcb->statistics.debugPcb.nackRcv, pcb->statistics.debugPcb.packSend, pcb->statistics.debugPcb.packFailed,
721 pcb->statistics.debugPcb.packRcv);
722
723 FILLP_LOGDBG("fillp_sock_id:%d totalSend:%u,total_send_fail:%u,total_send_success:%u,"
724 "totalSendBytes:%u totalRetryed:%u",
725 FILLP_GET_SOCKET(pcb)->index, pcb->statistics.traffic.totalSend, pcb->statistics.traffic.totalSendFailed,
726 pcb->statistics.traffic.totalSend - pcb->statistics.traffic.totalSendFailed,
727 pcb->statistics.traffic.totalSendBytes, pcb->statistics.traffic.totalRetryed);
728
729 FILLP_LOGDBG("fillp_sock_id:%d packIntervalSendPkt:%u,total_recv_bytes:%u,self_period_recv_rate:%u,"
730 "last_Pack_input_time:%lld",
731 FILLP_GET_SOCKET(pcb)->index, pcb->statistics.debugPcb.packIntervalSendPkt,
732 pcb->statistics.traffic.totalRecved, pcb->statistics.pack.periodRecvRate,
733 pcb->statistics.debugPcb.packRecvedTimeInterval);
734
735 FILLP_LOGDBG("fillp_sock_id:%d After_Pack_input, unackList:%u,unrecvList:%u, itemWaitTokenLists:%u",
736 FILLP_GET_SOCKET(pcb)->index, pcb->send.unackList.count, pcb->send.unrecvList.nodeNum,
737 pcb->send.itemWaitTokenLists.nodeNum);
738 }
739
740
FillpPackInput(struct FillpPcb * pcb,FILLP_CONST struct NetBuf * p)741 static void FillpPackInput(struct FillpPcb *pcb, FILLP_CONST struct NetBuf *p)
742 {
743 struct FillpPktPack *pack = FILLP_NULL_PTR;
744 struct FillpPktHead *pktHdr = FILLP_NULL_PTR;
745 FILLP_UINT32 ackSeqNum;
746 FILLP_UINT32 lostSeqNum;
747
748 if (FillpCheckPackInput(pcb, p) == FILLP_FALSE) {
749 return;
750 }
751
752 /* Header fields are already converted in FillpDoInput, and hence here
753 should not be converted again
754 */
755 pack = (struct FillpPktPack *)(void *)p->p;
756 pktHdr = (struct FillpPktHead *)pack->head;
757 pack->flag = FILLP_NTOHS(pack->flag);
758 ackSeqNum = pktHdr->seqNum;
759 pack->lostSeq = FILLP_NTOHL(pack->lostSeq);
760 lostSeqNum = pack->lostSeq;
761 if (FillpCheckPackNumber(pcb, pack, ackSeqNum, lostSeqNum) == FILLP_FALSE) {
762 return;
763 }
764
765 /* send pack message maintenance info */
766 FillpPackInputSendMsgTrace(pcb, pktHdr, pack);
767
768 pack->pktLoss = FILLP_NTOHS(pack->pktLoss);
769 pack->rate = FILLP_NTOHL(pack->rate);
770 pack->oppositeSetRate = FILLP_NTOHL(pack->oppositeSetRate);
771
772 if (pack->flag & FILLP_PACK_FLAG_ADHOC) {
773 FILLP_LOGDBG("Adhoc Pack, ackSeqNum:%u, flag:%u", ackSeqNum, pack->flag);
774 FillpHdlAdhocpack(pcb, pack);
775 return;
776 }
777
778 if (FillpHandlePackFlag(pcb, pack) != ERR_OK) {
779 return;
780 }
781
782 FillpTryAckSendPcbByPackInfo(pcb, pack, ackSeqNum, lostSeqNum);
783
784 /* move item from unack list to unrecv list by the lostSeqNum */
785 MoveUnackToUnrecvByPackInfo(pcb, ackSeqNum, lostSeqNum);
786 pcb->statistics.debugPcb.packRcv++;
787
788 FillpPackInputLog(pcb);
789 FillpFcPackInput(pcb, pack);
790 }
791
FillpHdlConnect(struct FillpPcb * pcb,FILLP_CONST struct NetBuf * buf,struct SpungeInstance * inst,FILLP_UINT16 flag)792 static void FillpHdlConnect(struct FillpPcb *pcb, FILLP_CONST struct NetBuf *buf, struct SpungeInstance *inst,
793 FILLP_UINT16 flag)
794 {
795 FILLP_BOOL validPkt = FILLP_TRUE;
796 switch (flag) {
797 case FILLP_PKT_TYPE_CONN_REQ:
798 #ifdef FILLP_SERVER_SUPPORT
799 FillpConnReqInput(pcb, buf);
800 #else
801 FILLP_LOGINF("FILLP_SERVER_SUPPORT is NOT enabled and received conn_req packet from peer "
802 "fillp_sock_id:%d", FILLP_GET_SOCKET(pcb)->index);
803 #endif
804 break;
805 case FILLP_PKT_TYPE_CONN_REQ_ACK:
806 FillpConnReqAckInput(pcb, buf);
807 break;
808 case FILLP_PKT_TYPE_CONN_CONFIRM:
809 #ifdef FILLP_SERVER_SUPPORT
810 FillpConnConfirmInput(pcb, buf, inst);
811 #else
812 FILLP_LOGDBG("FILLP_SERVER_SUPPORT is NOT enabled and received conn_confirm packet from peer "
813 "fillp_sock_id:%d", FILLP_GET_SOCKET(pcb)->index);
814 #endif
815 break;
816 case FILLP_PKT_TYPE_CONN_CONFIRM_ACK:
817 /*
818 client sends connection request
819 server directly sends CONFIRM ACK
820
821 Our fillp server cannot do this. attacker does this .
822
823 --- At client side, if we have not sent CONFIRM and get the CONFIRM ACK
824 then silently discard the message. We will not close the socket
825 here, socket close will happen when connectTimeout is expired.
826 */
827 if (FILLP_CLIENT_FOUR_HANDSHAKE_STATE_CONFIRM_SENT == FILLP_GET_CONN(pcb)->clientFourHandshakeState) {
828 FillpConnConfirmAckInput(pcb, buf);
829 }
830 break;
831 default:
832 validPkt = FILLP_FALSE;
833 break;
834 }
835 if (validPkt) {
836 pcb->statistics.keepAlive.lastRecvTime = pcb->pcbInst->curTime;
837 }
838 }
839
FillpDoInputPktType(struct FillpPcb * pcb,FILLP_CONST struct NetBuf * buf,struct SpungeInstance * inst,FILLP_UINT16 flag)840 static void FillpDoInputPktType(struct FillpPcb *pcb, FILLP_CONST struct NetBuf *buf, struct SpungeInstance *inst,
841 FILLP_UINT16 flag)
842 {
843 FILLP_BOOL validPkt = FILLP_TRUE;
844 switch (flag) {
845 case FILLP_PKT_TYPE_DATA:
846 FillpHdlDataInput(pcb, buf);
847 break;
848 case FILLP_PKT_TYPE_NACK:
849 FillpNackInput(pcb, buf);
850 break;
851 case FILLP_PKT_TYPE_PACK:
852 FillpPackInput(pcb, buf);
853 break;
854 case FILLP_PKT_TYPE_FIN: {
855 FILLP_BOOL pcbFreed = FILLP_FALSE;
856 FillpFinInput(pcb, buf, &pcbFreed);
857 /* If PCB is freed then no need to update stats */
858 if (pcbFreed) {
859 validPkt = FILLP_FALSE;
860 }
861 break;
862 }
863 default:
864 FillpHdlConnect(pcb, buf, inst, flag);
865 validPkt = FILLP_FALSE;
866 break;
867 }
868 if (validPkt) {
869 pcb->statistics.keepAlive.lastRecvTime = pcb->pcbInst->curTime;
870 }
871 }
872
FillpDoInput(struct FillpPcb * pcb,FILLP_CONST struct NetBuf * buf,struct SpungeInstance * inst)873 void FillpDoInput(struct FillpPcb *pcb, FILLP_CONST struct NetBuf *buf, struct SpungeInstance *inst)
874 {
875 struct FillpPktHead *head = (struct FillpPktHead *)(void *)buf->p;
876 FillpTraceDescriptSt fillpTrcDesc;
877 struct FtSocket *ftSock = FILLP_GET_SOCKET(pcb);
878 FILLP_UCHAR packetType;
879
880 if (ftSock->traceFlag >= FILLP_TRACE_DIRECT_NETWORK) {
881 /* Check for DATA message and all other fillp-control mesasge which has
882 only header as the message and provide indication
883
884 IMPORTANT: DATA message check SHOULD be the first check considering performance
885 aspect, otherwise it results in multiple OR condition check
886 */
887 packetType = (FILLP_UCHAR)FILLP_PKT_GET_TYPE(FILLP_NTOHS(head->flag));
888 if (packetType == FILLP_PKT_TYPE_DATA) {
889 struct FillpPktHead tmpHead;
890
891 tmpHead.dataLen = head->dataLen;
892 tmpHead.flag = head->flag;
893 tmpHead.pktNum = head->pktNum;
894 tmpHead.seqNum = head->seqNum;
895
896 FILLP_LM_FILLPMSGTRACE_OUTPUT_WITHOUT_FT_TRACE_ENABLE_FLAG(FILLP_TRACE_DIRECT_NETWORK,
897 ftSock->traceHandle, FILLP_HLEN, ftSock->index, fillpTrcDesc, (FILLP_CHAR *)&tmpHead);
898 }
899 }
900
901 /* convert pkt head structure from network to hex format */
902 head->flag = FILLP_NTOHS(head->flag);
903 head->dataLen = FILLP_NTOHS(head->dataLen);
904 head->pktNum = FILLP_NTOHL(head->pktNum);
905 head->seqNum = FILLP_NTOHL(head->seqNum);
906
907 FILLP_PKT_SIMPLE_LOG(ftSock->index, head, FILLP_DIRECTION_RX);
908
909 if (buf->len > (FILLP_INT)pcb->pktSize) {
910 /* format specifier %zu is used for size_t variable */
911 FILLP_LOGINF("FillpDoInput: recv buffer length incorrect, dataLen = %d is greater than pktSize = %zu,"
912 "flag:%u, pktNum:%u, seqNum:%u",
913 buf->len, pcb->pktSize, head->flag, head->pktNum, head->seqNum);
914 FillpDfxPktNotify(ftSock->index, FILLP_DFX_PKT_PARSE_FAIL, 1U);
915 return;
916 }
917
918 if ((FILLP_INT)head->dataLen > buf->len) {
919 FILLP_LOGINF("FillpDoInput: fillp_sock_id:%d protocol head incorrect. "
920 "dataLen = %u greater than buflen = %d, flag:%u, pktNum:%u, seqNum:%u",
921 ftSock->index, head->dataLen, buf->len, head->flag, head->pktNum, head->seqNum);
922 FillpDfxPktNotify(ftSock->index, FILLP_DFX_PKT_PARSE_FAIL, 1U);
923 return;
924 }
925 FillpDoInputPktType(pcb, buf, inst, (FILLP_UINT16)FILLP_PKT_GET_TYPE(head->flag));
926 }
927
928 #ifdef __cplusplus
929 }
930 #endif
931