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