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 "queue.h"
17 #include "fillp_flow_control.h"
18 #include "spunge_stack.h"
19 #include "spunge_core.h"
20 #include "fillp_buf_item.h"
21 #include "dympool.h"
22 #include "fillp_algorithm.h"
23 #include "fillp_output.h"
24 #include "res.h"
25 #include "fillp_common.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 #define FILLP_PCB_GET_CONN(pcb) (struct FtNetconn *)((struct SpungePcb *)((pcb)->spcb))->conn
32 #define FILLP_UNRECV_THRESHOLD 2
33 
FillpSkiplistCmp(void * t1,void * t2)34 IGNORE_OVERFLOW static inline FILLP_INT FillpSkiplistCmp(void *t1, void *t2)
35 {
36     struct FillpPcbItem *value1 = (struct FillpPcbItem *)t1;
37     struct FillpPcbItem *value2 = (struct FillpPcbItem *)t2;
38 
39     if (value1->seqNum == value2->seqNum) {
40         return ERR_OK;
41     }
42 
43     return ((FILLP_INT32)(value1->seqNum - value2->seqNum)) > 0;
44 }
45 
FillpSkiplistRecvcmp(void * t1,void * t2)46 IGNORE_OVERFLOW static inline FILLP_INT FillpSkiplistRecvcmp(void *t1, void *t2)
47 {
48     struct FillpPcbItem *value1 = (struct FillpPcbItem *)t1;
49     struct FillpPcbItem *value2 = (struct FillpPcbItem *)t2;
50 
51     if (value1->pktNum == value2->pktNum) {
52         return ERR_OK;
53     }
54 
55     return ((FILLP_INT32)(value1->seqNum - value2->seqNum)) > 0;
56 }
57 
FillpInitSendpcbUnackList(struct FillpSendPcb * pcb)58 static FILLP_INT FillpInitSendpcbUnackList(struct FillpSendPcb *pcb)
59 {
60     FILLP_UINT32 i;
61     pcb->unackList.size = FILLP_UNACK_HASH_SIZE;
62     pcb->unackList.hashModSize = pcb->unackList.size - 1;
63     pcb->unackList.count = 0;
64     pcb->unackList.hashMap =
65         (struct Hlist *)SpungeAlloc(pcb->unackList.size, sizeof(struct Hlist), SPUNGE_ALLOC_TYPE_CALLOC);
66     if (pcb->unackList.hashMap == FILLP_NULL_PTR) {
67         FILLP_LOGERR("Failed to allocate memory for hash map");
68 
69         SkiplistDestroy(&pcb->unrecvList);
70         return ERR_NOBUFS;
71     }
72     for (i = 0; i < pcb->unackList.size; i++) {
73         HLIST_INIT(&pcb->unackList.hashMap[i]);
74     }
75 
76     return ERR_OK;
77 }
78 
FillpInitSendpcbPktSeqMap(struct FillpPcb * fpcb,struct FillpSendPcb * pcb)79 static FILLP_INT FillpInitSendpcbPktSeqMap(struct FillpPcb *fpcb, struct FillpSendPcb *pcb)
80 {
81     FILLP_UINT32 i;
82     if (fpcb->mpSendSize > FILLP_MAX_PKTSEQ_HASH_SIZE) {
83         pcb->pktSeqMap.size = FILLP_MAX_PKTSEQ_HASH_SIZE;
84     } else {
85         if ((fpcb->mpSendSize & (fpcb->mpSendSize - 1)) == 0) { /* already Power of 2  */
86             pcb->pktSeqMap.size = fpcb->mpSendSize;
87         } else { /* switch to power of 2  */
88             for (pcb->pktSeqMap.size = 1; pcb->pktSeqMap.size <= fpcb->mpSendSize;) {
89                 pcb->pktSeqMap.size <<= 1;
90             }
91         }
92 
93         if (fpcb->mpSendSize > FILLP_MAX_PKTSEQ_HASH_SIZE) {
94             pcb->pktSeqMap.size = FILLP_MAX_PKTSEQ_HASH_SIZE;
95         }
96     }
97 
98     pcb->pktSeqMap.hashModSize = pcb->pktSeqMap.size - 1;
99 
100     pcb->pktSeqMap.hashMap =
101         (struct Hlist *)SpungeAlloc(pcb->pktSeqMap.size, sizeof(struct Hlist), SPUNGE_ALLOC_TYPE_CALLOC);
102     if (pcb->pktSeqMap.hashMap == FILLP_NULL_PTR) {
103         FILLP_LOGERR("Failed to allocate memory for hash map \r\n");
104 
105         SpungeFree(pcb->unackList.hashMap, SPUNGE_ALLOC_TYPE_CALLOC);
106         pcb->unackList.hashMap = FILLP_NULL_PTR;
107         SkiplistDestroy(&pcb->unrecvList);
108 
109         return ERR_NOBUFS;
110     }
111 
112     for (i = 0; i < pcb->pktSeqMap.size; i++) {
113         HLIST_INIT(&pcb->pktSeqMap.hashMap[i]);
114     }
115 
116     return ERR_OK;
117 }
118 
FillpFreeRecvItemPool(struct FillpRecvPcb * pcb)119 static void FillpFreeRecvItemPool(struct FillpRecvPcb *pcb)
120 {
121     FillpDestroyBufItemPool(pcb->itemPool);
122     pcb->itemPool = FILLP_NULL_PTR;
123 }
124 
FillpFreeSendItemPool(struct FillpSendPcb * pcb)125 static void FillpFreeSendItemPool(struct FillpSendPcb *pcb)
126 {
127     FillpDestroyBufItemPool(pcb->itemPool);
128     pcb->itemPool = FILLP_NULL_PTR;
129 }
130 
InitSendPcbSimplePar(struct FillpPcb * fpcb)131 static FILLP_INT InitSendPcbSimplePar(struct FillpPcb *fpcb)
132 {
133     struct FillpSendPcb *pcb = &fpcb->send;
134     FILLP_INT ret;
135     if (fpcb->mpSendSize == 0) {
136         FILLP_LOGERR("FillpInitSendpcb:fpcb->mpSendSize is zero");
137         return ERR_NOBUFS;
138     }
139 
140     ret = SkiplistInit(&pcb->unrecvList, FillpSkiplistCmp);
141     if (ret != ERR_OK) {
142         FILLP_LOGERR("FillpInitSendpcb:SkiplistInit fails");
143         return ERR_COMM;
144     }
145 
146     ret = SkiplistInit(&pcb->itemWaitTokenLists, FillpSkiplistCmp);
147     if (ret != ERR_OK) {
148         FILLP_LOGERR("SkiplistInit redunList fails");
149         SkiplistDestroy(&pcb->unrecvList);
150         return ERR_COMM;
151     }
152 
153     ret = SkiplistInit(&pcb->redunList, FillpSkiplistCmp);
154     if (ret != ERR_OK) {
155         FILLP_LOGERR("SkiplistInit redunList fails");
156         SkiplistDestroy(&pcb->unrecvList);
157         SkiplistDestroy(&pcb->itemWaitTokenLists);
158         return ERR_COMM;
159     }
160 
161     HLIST_INIT(&pcb->unSendList);
162     pcb->unsendBox = FILLP_NULL_PTR;
163     ret = FillpInitSendpcbUnackList(pcb);
164     if (ret != ERR_OK) {
165         SkiplistDestroy(&pcb->redunList);
166         SkiplistDestroy(&pcb->itemWaitTokenLists);
167         return ret;
168     }
169 
170     ret = FillpInitSendpcbPktSeqMap(fpcb, pcb);
171     if (ret != ERR_OK) {
172         SkiplistDestroy(&pcb->redunList);
173         SkiplistDestroy(&pcb->itemWaitTokenLists);
174         return ret;
175     }
176     FILLP_LOGINF("send itemPool Size = %u", fpcb->mpSendSize);
177     return ERR_OK;
178 }
179 
InitSimplePcbPar(struct FillpSendPcb * pcb,struct FillpPcb * fpcb)180 static FILLP_INT InitSimplePcbPar(struct FillpSendPcb *pcb, struct FillpPcb *fpcb)
181 {
182     FILLP_LOGINF("FillP init send PCB cache size:%u", fpcb->mpSendSize);
183     pcb->newDataSendComplete = 0;
184     pcb->nackRandomNum = FILLP_CRYPTO_RAND();
185     pcb->packRandomNum = FILLP_CRYPTO_RAND();
186     fpcb->statistics.nack.historyNackQueueLen = FILLP_DEFAULT_NACK_RETRY_LEN;
187     pcb->retryNackQueue = SpungeAlloc(fpcb->statistics.nack.historyNackQueueLen, sizeof(struct FillpPktNack *),
188         SPUNGE_ALLOC_TYPE_CALLOC);
189     if (pcb->retryNackQueue == FILLP_NULL_PTR) {
190         FILLP_LOGERR("fail to allocate memory for history nack queue");
191 
192         SpungeFree(pcb->unackList.hashMap, SPUNGE_ALLOC_TYPE_CALLOC);
193         pcb->unackList.hashMap = FILLP_NULL_PTR;
194         SpungeFree(pcb->pktSeqMap.hashMap, SPUNGE_ALLOC_TYPE_CALLOC);
195         pcb->pktSeqMap.hashMap = FILLP_NULL_PTR;
196         SkiplistDestroy(&pcb->unrecvList);
197         SkiplistDestroy(&pcb->redunList);
198         SkiplistDestroy(&pcb->itemWaitTokenLists);
199 
200         FillpFreeSendItemPool(pcb);
201 
202 #ifdef SOCK_SEND_SEM
203         (void)SYS_ARCH_SEM_DESTROY(&pcb->sendSem);
204 #endif
205         return ERR_NORES;
206     }
207     pcb->retryIndex = 0;
208     pcb->packMoveToUnrecvThreshold = FILLP_UNRECV_THRESHOLD;
209     pcb->packSameAckNum = 0;
210     pcb->lastPackAckSeq = 0;
211     pcb->retramistRto = 0;
212     pcb->preItem = FILLP_NULL_PTR;
213     pcb->nackPktStartNum = pcb->pktStartNum;
214     pcb->nackPktEndNum = pcb->pktStartNum;
215     pcb->inSendBytes = 0;
216     pcb->lastSendTs = fpcb->pcbInst->curTime;
217     pcb->unrecvRedunListBytes = 0;
218 
219     return ERR_OK;
220 }
221 
InitItemPool(struct FillpPcb * fpcb)222 static FILLP_INT InitItemPool(struct FillpPcb *fpcb)
223 {
224     struct FillpSendPcb *pcb = &fpcb->send;
225     FILLP_INT ret;
226 
227     int initSize = (fpcb->fcAlg == FILLP_SUPPORT_ALG_MSG) ? FILLP_MSG_DYMM_INIT_SEND_SIZE : FILLP_DYMM_INIT_SEND_SIZE;
228     pcb->itemPool = FillpCreateBufItemPool((int)fpcb->mpSendSize, initSize, (int)fpcb->pktSize);
229     if (pcb->itemPool == FILLP_NULL_PTR) {
230         FILLP_LOGERR("create itempool  fails");
231 
232         SpungeFree(pcb->unackList.hashMap, SPUNGE_ALLOC_TYPE_CALLOC);
233         pcb->unackList.hashMap = FILLP_NULL_PTR;
234         SpungeFree(pcb->pktSeqMap.hashMap, SPUNGE_ALLOC_TYPE_CALLOC);
235         pcb->pktSeqMap.hashMap = FILLP_NULL_PTR;
236         SkiplistDestroy(&pcb->unrecvList);
237         SkiplistDestroy(&pcb->redunList);
238         SkiplistDestroy(&pcb->itemWaitTokenLists);
239         return ERR_NORES;
240     }
241     ret = ERR_OK;
242     FillbufItemPoolSetConflictSafe(pcb->itemPool, FILLP_TRUE, FILLP_FALSE);
243 
244     pcb->unsendBox = SpungeAllocUnsendBox(fpcb->pcbInst);
245     if (pcb->unsendBox == FILLP_NULL_PTR) {
246         /* This function cannot fail, hence no free added here */
247         FILLP_LOGERR("Can't get pcb unsendBox");
248         return ERR_NORES;
249     }
250     return ret;
251 }
252 
FillpInitSendpcb(struct FillpPcb * fpcb)253 static FILLP_INT FillpInitSendpcb(struct FillpPcb *fpcb)
254 {
255     struct FillpSendPcb *pcb = &fpcb->send;
256     int initCacheSize;
257 
258     FILLP_INT ret = InitSendPcbSimplePar(fpcb);
259     if (ret != ERR_OK) {
260         return ret;
261     }
262     ret = InitItemPool(fpcb);
263     if (ret != ERR_OK) {
264         return ret;
265     }
266 
267     initCacheSize = DYMP_GET_CUR_SIZE((DympoolType *)pcb->itemPool);
268     pcb->curItemCount = (FILLP_UINT32)initCacheSize;
269 
270     FILLP_LOGINF("send init cache size:%d", initCacheSize);
271 
272 #ifdef SOCK_SEND_SEM
273     ret = SYS_ARCH_SEM_INIT(&pcb->sendSem, (FILLP_ULONG)initCacheSize);
274     if (ret != FILLP_OK) {
275         FILLP_LOGERR("FillpInitSendpcb:SYS_ARCH_SEM_INIT fails");
276 
277         SpungeFree(pcb->unackList.hashMap, SPUNGE_ALLOC_TYPE_CALLOC);
278         pcb->unackList.hashMap = FILLP_NULL_PTR;
279         SpungeFree(pcb->pktSeqMap.hashMap, SPUNGE_ALLOC_TYPE_CALLOC);
280         pcb->pktSeqMap.hashMap = FILLP_NULL_PTR;
281         SkiplistDestroy(&pcb->unrecvList);
282         SkiplistDestroy(&pcb->redunList);
283         SkiplistDestroy(&pcb->itemWaitTokenLists);
284 
285         FillpFreeSendItemPool(pcb);
286         return ERR_NORES;
287     }
288 #endif /* SOCK_SEND_SEM */
289 
290     return InitSimplePcbPar(pcb, fpcb);
291 }
292 
FillpInitRecvPcbBox(struct FillpPcb * fpcb,struct FillpRecvPcb * pcb)293 static FillpQueue *FillpInitRecvPcbBox(struct FillpPcb *fpcb, struct FillpRecvPcb *pcb)
294 {
295     FILLP_INT privRecvSize;
296 
297     privRecvSize = 0;
298     pcb->privItemPool = FILLP_NULL_PTR;
299     int initSize = (fpcb->fcAlg == FILLP_SUPPORT_ALG_MSG) ? FILLP_MSG_DYMM_INIT_RECV_SIZE : FILLP_DYMM_INIT_RECV_SIZE;
300     pcb->itemPool = FillpCreateBufItemPool((int)fpcb->mpRecvSize, initSize, (int)fpcb->pktSize);
301     if (pcb->itemPool == FILLP_NULL_PTR) {
302         FILLP_LOGERR("FillpInitRecvpcb:FillpCreateBufItemPool fails \r\n");
303         SkiplistDestroy(&pcb->recvBoxPlaceInOrder);
304         return FILLP_NULL_PTR;
305     }
306     FillbufItemPoolSetConflictSafe(pcb->itemPool, FILLP_FALSE, FILLP_TRUE);
307     FILLP_LOGINF("FillP init recv PCB cache size:%u", fpcb->mpRecvSize);
308     pcb->curItemCount = (FILLP_UINT32)DYMP_GET_CUR_SIZE(pcb->itemPool);
309 
310     FillpQueue *recvBox = FillpQueueCreate("sock_recv_box", fpcb->mpRecvSize + (FILLP_UINT)privRecvSize,
311         SPUNGE_ALLOC_TYPE_MALLOC);
312     if (recvBox == FILLP_NULL_PTR) {
313         SkiplistDestroy(&pcb->recvBoxPlaceInOrder);
314 
315         FillpFreeRecvItemPool(pcb);
316     }
317     return recvBox;
318 }
319 
FillpInitRecvpcb(struct FillpPcb * fpcb)320 FILLP_INT FillpInitRecvpcb(struct FillpPcb *fpcb)
321 {
322     struct FillpRecvPcb *pcb = &fpcb->recv;
323 
324     FILLP_INT ret = SYS_ARCH_SEM_INIT(&pcb->recvSem, 0);
325     if (ret != FILLP_OK) {
326         FILLP_LOGERR("SYS_ARCH_SEM_INIT fails");
327         return ERR_NORES;
328     }
329 
330     /*
331     init NACK List
332     notice, it not need free when pcb remove
333     */
334     HLIST_INIT(&(pcb->nackList));
335 
336     if (SkiplistInit(&pcb->recvList, FillpSkiplistCmp)) {
337         FILLP_LOGERR("SkiplistInit failsn");
338         (void)SYS_ARCH_SEM_DESTROY(&pcb->recvSem);
339         return ERR_NORES;
340     }
341 
342     if (SkiplistInit(&pcb->recvBoxPlaceInOrder, FillpSkiplistRecvcmp)) {
343         FILLP_LOGERR("SkiplistInit fails for recvBoxPlaceInOrder");
344         goto NORES;
345     }
346 
347     pcb->recvBox = FillpInitRecvPcbBox(fpcb, pcb);
348     if (pcb->recvBox == FILLP_NULL_PTR) {
349         FILLP_LOGERR("Fail to create recv box");
350         goto NORES;
351     }
352 
353     FillpQueueSetConsSafe(pcb->recvBox, FILLP_FALSE);
354     FillpQueueSetProdSafe(pcb->recvBox, FILLP_FALSE);
355 
356     pcb->isRecvingData = 0;
357     pcb->recvBytes = 0;
358     return ERR_OK;
359 NORES:
360     SkiplistDestroy(&pcb->recvList);
361     (void)SYS_ARCH_SEM_DESTROY(&pcb->recvSem);
362     return ERR_NORES;
363 }
364 
InitSimpleStatics(const struct FillpPcb * fpcb,struct FillpStatisticsPcb * pcb)365 static void InitSimpleStatics(const struct FillpPcb *fpcb, struct FillpStatisticsPcb *pcb)
366 {
367     pcb->traffic.totalRecved = 0;
368     pcb->traffic.totalRecvedBytes = 0;
369     pcb->traffic.totalDroped = 0;
370     pcb->traffic.totalRetryed = 0;
371     pcb->traffic.totalSendFailed = 0;
372     pcb->traffic.totalOutOfOrder = 0;
373     pcb->traffic.totalRecvLost = 0;
374     pcb->traffic.totalSend = 0;
375     pcb->traffic.totalSendBytes = 0;
376 
377     pcb->traffic.packSendBytes = 0;
378     pcb->traffic.packExpSendBytes = 0;
379 
380     pcb->pack.periodDroped = 0;
381     pcb->pack.periodRecvBits = 0;
382     pcb->pack.peerRtt = FILLP_FALSE;
383     pcb->pack.periodRecvedOnes = 0;
384 
385     pcb->pack.packIntervalBackup = pcb->pack.packInterval;
386     pcb->pack.packLostSeq = 0;
387     pcb->pack.packSendTime = fpcb->pcbInst->curTime;
388     pcb->pack.packTimePassed = 0;
389     pcb->pack.packPktNum = 0;
390     pcb->pack.packRttDetectTime = fpcb->pcbInst->curTime;
391 
392     pcb->pack.periodRecvPktLoss = 0;
393     pcb->pack.periodRecvRate = 0;
394     pcb->pack.lastPackRecvRate = 0;
395     pcb->pack.maxRecvRate = 0;
396 
397     pcb->nack.nackHistorySendQueueNum = 0;
398     pcb->nack.currentHistoryNackNum = 0;
399     pcb->nack.nackSendTime = fpcb->pcbInst->curTime;
400 }
401 
FillpInitStastics(struct FillpPcb * fpcb)402 static void FillpInitStastics(struct FillpPcb *fpcb)
403 {
404     FILLP_INT i;
405     struct FillpStatisticsPcb *pcb = &fpcb->statistics;
406     InitSimpleStatics(fpcb, pcb);
407     if (pcb->nack.nackInterval == 0) {
408         pcb->nack.nackInterval = FILLP_MIN_NACK_INTERVAL;
409     }
410 
411     /* nack_delay timeout depend on pack interval, there threshold is 5000us */
412     pcb->nack.nackDelayTimeout = (pcb->pack.packInterval > FILLP_INTERVAL_THRESHOLD) ?
413         (pcb->pack.packInterval - FILLP_INTERVAL_THRESHOLD) : FILLP_INTERVAL_DEFAULT;
414 
415     (void)memset_s(&pcb->debugPcb, sizeof(struct FillpStatatisticsDebugPcb), 0,
416         sizeof(struct FillpStatatisticsDebugPcb));
417     pcb->debugPcb.packRecvedTimeInterval = fpcb->pcbInst->curTime;
418     pcb->debugPcb.curPackDeltaUs = pcb->pack.packIntervalBackup;
419 
420     for (i = 0; i < FILLP_NACK_HISTORY_NUM; i++) {
421         pcb->nackHistory.nackHistoryArr[i].lostPktGap = 0;
422         pcb->nackHistory.nackHistoryArr[i].timestamp = 0;
423     }
424     pcb->nackHistory.nackHistoryNum = 0;
425     pcb->nackHistory.pktLoss = 0;
426     for (i = 0; i < FILLP_NACK_HISTORY_ARR_NUM; i++) {
427         pcb->nackHistory.historyAvgLostPktGap[i] = 0;
428         pcb->nackHistory.historyMaxLostPktGap[i] = 0;
429         pcb->nackHistory.historyMinLostPktGap[i] = 0;
430     }
431 
432     pcb->appFcStastics.periodTimePassed = fpcb->pcbInst->curTime;
433     pcb->appFcStastics.pktNum = 0;
434     pcb->appFcStastics.periodRecvBits = 0;
435     pcb->appFcStastics.periodRecvPkts = 0;
436     pcb->appFcStastics.periodRecvPktLoss = 0;
437     pcb->appFcStastics.periodRecvRate = 0;
438     pcb->appFcStastics.periodRecvRateBps = 0;
439 
440     pcb->appFcStastics.periodRtt = (FILLP_UINT32)FILLP_UTILS_US2MS(fpcb->rtt);
441     pcb->appFcStastics.periodRecvPktLossHighPrecision = 0;
442     pcb->appFcStastics.periodSendLostPkts = 0;
443     pcb->appFcStastics.periodSendPkts = 0;
444     pcb->appFcStastics.periodSendPktLossHighPrecision = 0;
445     pcb->appFcStastics.periodSendBits = 0;
446     pcb->appFcStastics.periodSendRateBps = 0;
447 }
448 
FillpPcbFreeRecvItemArray(struct FillpRecvPcb * pcb)449 static void FillpPcbFreeRecvItemArray(struct FillpRecvPcb *pcb)
450 {
451     struct FillpPcbItem *item = FILLP_NULL_PTR;
452     int ret;
453     FILLP_ULONG loopCount;
454     FILLP_ULONG index;
455 
456     loopCount = (FILLP_ULONG)pcb->recvBoxPlaceInOrder.nodeNum;
457     for (index = 0; index < loopCount; index++) {
458         item = SkipListPopValue(&pcb->recvBoxPlaceInOrder);
459         FillpFreeBufItem(item);
460     }
461 
462     loopCount = (FILLP_ULONG)pcb->recvList.nodeNum;
463     for (index = 0; index < loopCount; index++) {
464         item = SkipListPopValue(&pcb->recvList);
465         FillpFreeBufItem(item);
466     }
467 
468     loopCount = FillpQueueValidOnes(pcb->recvBox);
469     for (index = 0; index < loopCount; index++) {
470         ret = FillpQueuePop(pcb->recvBox, (void **)&item, 1);
471         if (ret == 1) {
472             FillpFreeBufItem(item);
473         }
474     }
475 
476     FillpFreeRecvItemPool(pcb);
477 }
478 
FillpPcbRemoveRecv(struct FillpPcb * fpcb)479 static void FillpPcbRemoveRecv(struct FillpPcb *fpcb)
480 {
481     struct FillpRecvPcb *pcb = &fpcb->recv;
482     struct Hlist *nackList = FILLP_NULL_PTR;
483     struct HlistNode *node = FILLP_NULL_PTR;
484     struct FillpNackNode *nackNode = FILLP_NULL_PTR;
485     FillpPcbFreeRecvItemArray(pcb);
486 
487     SkiplistDestroy(&pcb->recvBoxPlaceInOrder);
488     SkiplistDestroy(&pcb->recvList);
489     pcb->itemPool = FILLP_NULL_PTR;
490     FillpQueueDestroy(pcb->recvBox);
491     pcb->recvBox = FILLP_NULL_PTR;
492 
493     nackList = &(pcb->nackList);
494     if (nackList->size > 0) {
495         node = HLIST_FIRST(nackList);
496         while (node != FILLP_NULL_PTR) {
497             nackNode = FillpNackNodeEntry(node);
498             node = node->next;
499             SpungeFree(nackNode, SPUNGE_ALLOC_TYPE_CALLOC);
500             nackNode = FILLP_NULL_PTR;
501         }
502     }
503 
504     HLIST_INIT(&(pcb->nackList));
505 
506     (void)SYS_ARCH_SEM_DESTROY(&pcb->recvSem);
507 }
508 
FillpPcbSendFc(struct FillpPcb * fpcb)509 void FillpPcbSendFc(struct FillpPcb *fpcb)
510 {
511     if (FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&fpcb->sendTimerNode)) {
512         return;
513     }
514 
515     struct FillpFlowControl *flowControl = &fpcb->send.flowControl;
516     FILLP_LLONG detaTime = (FILLP_LLONG)(fpcb->pcbInst->curTime - flowControl->sendTime);
517     FILLP_LLONG realDetaTime = (FILLP_LLONG)((FILLP_ULLONG)detaTime << FILLP_TIME_PRECISION);
518     if (flowControl->sendTime == 0 || realDetaTime >= flowControl->sendInterval) {
519         SpungeDoSendCycle((struct SpungePcb*)fpcb->spcb, fpcb->pcbInst, realDetaTime);
520     } else {
521         FillpEnableSendTimer(fpcb);
522     }
523 }
524 
FillpPcbSend(struct FillpPcb * fpcb,struct FillpPcbItem * item[],FILLP_UINT32 itemCnt)525 void FillpPcbSend(struct FillpPcb *fpcb, struct FillpPcbItem *item[], FILLP_UINT32 itemCnt)
526 {
527     FILLP_UINT32 i;
528 
529     if (SYS_ARCH_SEM_WAIT(&fpcb->pcbInst->threadSem)) {
530         FILLP_LOGWAR("sem wait failed");
531         return;
532     }
533 
534     fpcb->pcbInst->curTime = SYS_ARCH_GET_CUR_TIME_LONGLONG();
535 
536     for (i = 0; i < itemCnt; i++) {
537         HlistAddTail(&fpcb->send.unSendList, &item[i]->unsendNode);
538         (void)FillpFrameAddItem(&fpcb->frameHandle, item[i]);
539     }
540 
541     FillpPcbSendFc(fpcb);
542 
543     if (SYS_ARCH_SEM_POST(&fpcb->pcbInst->threadSem)) {
544         FILLP_LOGWAR("sem post failed");
545     }
546 }
547 
FillpPcbFreeSendItemArray(struct FillpPcb * fpcb)548 static void FillpPcbFreeSendItemArray(struct FillpPcb *fpcb)
549 {
550     struct FillpSendPcb *pcb = &fpcb->send;
551 
552     struct HlistNode *node = FILLP_NULL_PTR;
553     struct FillpPcbItem *item = FILLP_NULL_PTR;
554     FILLP_UINT32 loopCount;
555     FILLP_UINT32 index;
556 
557     loopCount = pcb->itemWaitTokenLists.nodeNum;
558     for (index = 0; index < loopCount; index++) {
559         item = SkipListPopValue(&pcb->itemWaitTokenLists);
560         FillpFreeBufItem(item);
561     }
562 
563     node = HLIST_FIRST(&pcb->unSendList);
564     while (node != FILLP_NULL_PTR) {
565         item = FillpPcbUnsendNodeEntry(node);
566         node = node->next;
567         HlistDelete(&pcb->unSendList, &item->unsendNode);
568         FillpFreeBufItem(item);
569     }
570 
571     loopCount = pcb->unackList.size;
572     for (index = 0; index < loopCount; index++) {
573         struct Hlist *hashMap = &pcb->unackList.hashMap[index];
574         node = HLIST_FIRST(hashMap);
575         while (node != FILLP_NULL_PTR) {
576             item = FillpPcbEntry(node);
577             node = node->next;
578             HlistDelete(hashMap, &item->node);
579             FillpFreeBufItem(item);
580         }
581     }
582 
583     loopCount = pcb->unrecvList.nodeNum;
584     for (index = 0; index < loopCount; index++) {
585         item = SkipListPopValue(&pcb->unrecvList);
586         FillpFreeBufItem(item);
587     }
588 
589     loopCount = pcb->redunList.nodeNum;
590     for (index = 0; index < loopCount; index++) {
591         item = SkipListPopValue(&pcb->redunList);
592         FillpFreeBufItem(item);
593     }
594 
595     FillpFreeSendItemPool(pcb);
596 }
597 
FillpPcbRemoveSend(struct FillpPcb * fpcb)598 static void FillpPcbRemoveSend(struct FillpPcb *fpcb)
599 {
600     struct FillpSendPcb *pcb = &fpcb->send;
601     FillpPcbFreeSendItemArray(fpcb);
602 
603     SpungeFree(pcb->unackList.hashMap, SPUNGE_ALLOC_TYPE_CALLOC);
604     pcb->unackList.hashMap = FILLP_NULL_PTR;
605     SpungeFree(pcb->pktSeqMap.hashMap, SPUNGE_ALLOC_TYPE_CALLOC);
606     pcb->pktSeqMap.hashMap = FILLP_NULL_PTR;
607     SkiplistDestroy(&pcb->unrecvList);
608     SkiplistDestroy(&pcb->redunList);
609     SkiplistDestroy(&pcb->itemWaitTokenLists);
610     pcb->itemPool = FILLP_NULL_PTR;
611     SpungeFreeUnsendBox(fpcb);
612 
613     if (pcb->retryNackQueue != FILLP_NULL_PTR) {
614         FILLP_UINT32 i;
615         for (i = 0; i < fpcb->statistics.nack.historyNackQueueLen; i++) {
616             if (pcb->retryNackQueue[i] != FILLP_NULL_PTR) {
617                 SpungeFree(pcb->retryNackQueue[i], SPUNGE_ALLOC_TYPE_CALLOC);
618                 pcb->retryNackQueue[i] = FILLP_NULL_PTR;
619             }
620         }
621         SpungeFree(pcb->retryNackQueue, SPUNGE_ALLOC_TYPE_CALLOC);
622         pcb->retryNackQueue = FILLP_NULL_PTR;
623     }
624 
625     pcb->retryNackQueue = FILLP_NULL_PTR;
626     pcb->retryIndex = 0;
627 #ifdef SOCK_SEND_SEM
628     SYS_ARCH_SEM_DESTROY(&pcb->sendSem);
629 #endif /* SOCK_SEND_SEM */
630 }
631 
FillpPcbRemoveTimers(struct FillpPcb * fpcb)632 void FillpPcbRemoveTimers(struct FillpPcb *fpcb)
633 {
634     /* Remove if any send/pack timer is running on this socket */
635     FillpDisableFinCheckTimer(fpcb);
636     FillpDisableSendTimer(fpcb);
637     FillpDisablePackTimer(fpcb);
638     FillpDisableFcTimer(fpcb);
639     FillpDisableKeepAliveTimer(fpcb);
640     FillpDisableDelayNackTimer(fpcb);
641     FillpDisableDataBurstTimer(fpcb);
642 }
643 
FillpInitPcbTimeNode(struct FillpPcb * pcb)644 static void FillpInitPcbTimeNode(struct FillpPcb *pcb)
645 {
646     struct FtSocket *sock = FILLP_GET_SOCKET(pcb);
647 
648     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->packTimerNode);
649     pcb->packTimerNode.cbNode.cb = FillpPackTimerCb;
650     pcb->packTimerNode.cbNode.arg = (void *)pcb;
651 
652     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->FcTimerNode);
653     pcb->FcTimerNode.cbNode.cb = FillpFcTimerCb;
654     pcb->FcTimerNode.cbNode.arg = (void *)pcb;
655 
656     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->sendTimerNode);
657     pcb->sendTimerNode.cbNode.cb = FillpSendTimerCb;
658     pcb->sendTimerNode.cbNode.arg = (void *)pcb;
659 
660     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->keepAliveTimerNode);
661     pcb->keepAliveTimerNode.cbNode.cb = FillpFcCycle;
662     pcb->keepAliveTimerNode.cbNode.arg = (void *)pcb;
663 
664     pcb->keepAliveTimerNode.interval = FILLP_UTILS_MS2US(sock->resConf.common.keepAliveTime);
665 
666     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->delayNackTimerNode);
667     pcb->delayNackTimerNode.cbNode.cb = FillpCheckPcbNackListToSend;
668     pcb->delayNackTimerNode.cbNode.arg = (void *)pcb;
669 
670     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->dataBurstTimerNode);
671     pcb->dataBurstTimerNode.cbNode.cb = SpungePushRecvdDataToStack;
672     pcb->dataBurstTimerNode.cbNode.arg = (void *)pcb;
673 
674     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->finCheckTimer);
675     pcb->finCheckTimer.cbNode.arg = (void *)FILLP_PCB_GET_CONN(pcb);
676     pcb->finCheckTimer.cbNode.cb = SpungeCheckDisconn;
677     pcb->finCheckTimer.interval = FILLP_WR_DATA_CHECK_INTERVAL;
678 }
679 
FillpInitPcb(struct FillpPcb * pcb,FILLP_INT mpSendSize,FILLP_INT mpRecvSize)680 FILLP_INT FillpInitPcb(struct FillpPcb *pcb, FILLP_INT mpSendSize, FILLP_INT mpRecvSize)
681 {
682     pcb->mpSendSize = (FILLP_UINT32)mpSendSize;
683     pcb->mpRecvSize = (FILLP_UINT32)mpRecvSize;
684 
685     pcb->connReqInputTimestamp = 0;
686     pcb->dataNullTimestamp = 0;
687     pcb->clientCookiePreserveTime = 0;
688 
689     FillpInitPcbTimeNode(pcb);
690     pcb->packState = FILLP_PACK_STATE_NORMAL;
691     pcb->adhocPackReplied = FILLP_FALSE;
692 
693     FillpFrameInit(&pcb->frameHandle);
694 
695     HLIST_INIT_NODE(&pcb->sendNode);
696     if (FillpInitRecvpcb(pcb) != ERR_OK) {
697         FILLP_LOGERR("Failed to init the RecvPCB");
698         return ERR_NORES;
699     }
700 
701     if (FillpInitSendpcb(pcb) != ERR_OK) {
702         FILLP_LOGERR("Failed to init the SendPCB");
703         FillpPcbRemoveRecv(pcb);
704         return ERR_NOBUFS;
705     }
706 
707     if (FillpFcInit(pcb) != FILLP_OK) {
708         FILLP_LOGERR("FillpFcInit failed");
709         FillpPcbRemoveRecv(pcb);
710         FillpPcbRemoveSend(pcb);
711         return ERR_NORES;
712     }
713 
714     FillpInitStastics(pcb);
715     pcb->isFinAckReceived = FILLP_FALSE;
716     pcb->resInited = FILLP_TRUE;
717     return ERR_OK;
718 }
719 
FillpRemovePcb(struct FillpPcb * pcb)720 void FillpRemovePcb(struct FillpPcb *pcb)
721 {
722     if (!pcb->resInited) {
723         return;
724     }
725 
726     FillpPcbRemoveRecv(pcb);
727     FillpPcbRemoveSend(pcb);
728     FillpPcbRemoveTimers(pcb);
729     FillpFcDeinit(pcb);
730 
731     pcb->isFinAckReceived = FILLP_FALSE;
732     pcb->resInited = FILLP_FALSE;
733 }
734 
FillpGetSendpcbUnackListPktNum(struct FillpSendPcb * pcb)735 FILLP_UINT32 FillpGetSendpcbUnackListPktNum(struct FillpSendPcb *pcb)
736 {
737     if (pcb == FILLP_NULL_PTR) {
738         return 0;
739     }
740 
741     return pcb->unackList.count;
742 }
743 
FillpGetRecvpcbRecvlistPktNum(struct FillpRecvPcb * pcb)744 FILLP_UINT32 FillpGetRecvpcbRecvlistPktNum(struct FillpRecvPcb *pcb)
745 {
746     if (pcb == FILLP_NULL_PTR) {
747         return 0;
748     }
749 
750     return SkiplistGetNodeNum(&(pcb->recvList));
751 }
752 
FillpGetSockPackInterval(FILLP_CONST struct FillpPcb * pcb)753 FILLP_UINT32 FillpGetSockPackInterval(FILLP_CONST struct FillpPcb *pcb)
754 {
755     FILLP_CONST struct FtSocket *sock = FILLP_GET_SOCKET(pcb);
756     return sock->resConf.flowControl.packInterval;
757 }
758 
759 #ifdef __cplusplus
760 }
761 #endif
762