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