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