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