• 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 \r\n");
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 \r\n");
136         return ERR_NOBUFS;
137     }
138 
139     ret = SkiplistInit(&pcb->unrecvList, FillpSkiplistCmp);
140     if (ret != ERR_OK) {
141         FILLP_LOGERR("FillpInitSendpcb:SkiplistInit fails \r\n");
142         return ERR_COMM;
143     }
144 
145     ret = SkiplistInit(&pcb->itemWaitTokenLists, FillpSkiplistCmp);
146     if (ret != ERR_OK) {
147         FILLP_LOGERR("SkiplistInit redunList fails \r\n");
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 \r\n");
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 \r\n");
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     return;
448 }
449 
FillpPcbFreeRecvItemArray(struct FillpRecvPcb * pcb)450 static void FillpPcbFreeRecvItemArray(struct FillpRecvPcb *pcb)
451 {
452     struct FillpPcbItem *item = FILLP_NULL_PTR;
453     int ret;
454     FILLP_ULONG loopCount;
455     FILLP_ULONG index;
456 
457     loopCount = (FILLP_ULONG)pcb->recvBoxPlaceInOrder.nodeNum;
458     for (index = 0; index < loopCount; index++) {
459         item = SkipListPopValue(&pcb->recvBoxPlaceInOrder);
460         FillpFreeBufItem(item);
461     }
462 
463     loopCount = (FILLP_ULONG)pcb->recvList.nodeNum;
464     for (index = 0; index < loopCount; index++) {
465         item = SkipListPopValue(&pcb->recvList);
466         FillpFreeBufItem(item);
467     }
468 
469     loopCount = FillpQueueValidOnes(pcb->recvBox);
470     for (index = 0; index < loopCount; index++) {
471         ret = FillpQueuePop(pcb->recvBox, (void **)&item, 1);
472         if (ret == 1) {
473             FillpFreeBufItem(item);
474         }
475     }
476 
477     FillpFreeRecvItemPool(pcb);
478 }
479 
FillpPcbRemoveRecv(struct FillpPcb * fpcb)480 static void FillpPcbRemoveRecv(struct FillpPcb *fpcb)
481 {
482     struct FillpRecvPcb *pcb = &fpcb->recv;
483     struct Hlist *nackList = FILLP_NULL_PTR;
484     struct HlistNode *node = FILLP_NULL_PTR;
485     struct FillpNackNode *nackNode = FILLP_NULL_PTR;
486     FillpPcbFreeRecvItemArray(pcb);
487 
488     SkiplistDestroy(&pcb->recvBoxPlaceInOrder);
489     SkiplistDestroy(&pcb->recvList);
490     pcb->itemPool = FILLP_NULL_PTR;
491     FillpQueueDestroy(pcb->recvBox);
492     pcb->recvBox = FILLP_NULL_PTR;
493 
494     nackList = &(pcb->nackList);
495     if (nackList->size > 0) {
496         node = HLIST_FIRST(nackList);
497         while (node != FILLP_NULL_PTR) {
498             nackNode = FillpNackNodeEntry(node);
499             node = node->next;
500             SpungeFree(nackNode, SPUNGE_ALLOC_TYPE_CALLOC);
501             nackNode = FILLP_NULL_PTR;
502         }
503     }
504 
505     HLIST_INIT(&(pcb->nackList));
506 
507     (void)SYS_ARCH_SEM_DESTROY(&pcb->recvSem);
508     return;
509 }
510 
FillpPcbSendFc(struct FillpPcb * fpcb)511 void FillpPcbSendFc(struct FillpPcb *fpcb)
512 {
513     if (FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&fpcb->sendTimerNode)) {
514         return;
515     }
516 
517     struct FillpFlowControl *flowControl = &fpcb->send.flowControl;
518     FILLP_LLONG detaTime = (FILLP_LLONG)(fpcb->pcbInst->curTime - flowControl->sendTime);
519     FILLP_LLONG realDetaTime = (FILLP_LLONG)((FILLP_ULLONG)detaTime << FILLP_TIME_PRECISION);
520     if (flowControl->sendTime == 0 || realDetaTime >= flowControl->sendInterval) {
521         SpungeDoSendCycle((struct SpungePcb*)fpcb->spcb, fpcb->pcbInst, realDetaTime);
522     } else {
523         FillpEnableSendTimer(fpcb);
524     }
525 }
526 
FillpPcbSend(struct FillpPcb * fpcb,struct FillpPcbItem * item[],FILLP_UINT32 itemCnt)527 void FillpPcbSend(struct FillpPcb *fpcb, struct FillpPcbItem *item[], FILLP_UINT32 itemCnt)
528 {
529     FILLP_UINT32 i;
530 
531     if (SYS_ARCH_SEM_WAIT(&fpcb->pcbInst->threadSem)) {
532         FILLP_LOGWAR("sem wait failed");
533         return;
534     }
535 
536     fpcb->pcbInst->curTime = SYS_ARCH_GET_CUR_TIME_LONGLONG();
537 
538     for (i = 0; i < itemCnt; i++) {
539         HlistAddTail(&fpcb->send.unSendList, &item[i]->unsendNode);
540         (void)FillpFrameAddItem(&fpcb->frameHandle, item[i]);
541     }
542 
543     FillpPcbSendFc(fpcb);
544 
545     if (SYS_ARCH_SEM_POST(&fpcb->pcbInst->threadSem)) {
546         FILLP_LOGWAR("sem post failed");
547     }
548 }
549 
FillpPcbFreeSendItemArray(struct FillpPcb * fpcb)550 static void FillpPcbFreeSendItemArray(struct FillpPcb *fpcb)
551 {
552     struct FillpSendPcb *pcb = &fpcb->send;
553 
554     struct HlistNode *node = FILLP_NULL_PTR;
555     struct FillpPcbItem *item = FILLP_NULL_PTR;
556     FILLP_UINT32 loopCount;
557     FILLP_UINT32 index;
558 
559     loopCount = pcb->itemWaitTokenLists.nodeNum;
560     for (index = 0; index < loopCount; index++) {
561         item = SkipListPopValue(&pcb->itemWaitTokenLists);
562         FillpFreeBufItem(item);
563     }
564 
565     node = HLIST_FIRST(&pcb->unSendList);
566     while (node != FILLP_NULL_PTR) {
567         item = FillpPcbUnsendNodeEntry(node);
568         node = node->next;
569         HlistDelete(&pcb->unSendList, &item->unsendNode);
570         FillpFreeBufItem(item);
571     }
572 
573     loopCount = pcb->unackList.size;
574     for (index = 0; index < loopCount; index++) {
575         struct Hlist *hashMap = &pcb->unackList.hashMap[index];
576         node = HLIST_FIRST(hashMap);
577         while (node != FILLP_NULL_PTR) {
578             item = FillpPcbEntry(node);
579             node = node->next;
580             HlistDelete(hashMap, &item->node);
581             FillpFreeBufItem(item);
582         }
583     }
584 
585     loopCount = pcb->unrecvList.nodeNum;
586     for (index = 0; index < loopCount; index++) {
587         item = SkipListPopValue(&pcb->unrecvList);
588         FillpFreeBufItem(item);
589     }
590 
591     loopCount = pcb->redunList.nodeNum;
592     for (index = 0; index < loopCount; index++) {
593         item = SkipListPopValue(&pcb->redunList);
594         FillpFreeBufItem(item);
595     }
596 
597     FillpFreeSendItemPool(pcb);
598 }
599 
FillpPcbRemoveSend(struct FillpPcb * fpcb)600 static void FillpPcbRemoveSend(struct FillpPcb *fpcb)
601 {
602     struct FillpSendPcb *pcb = &fpcb->send;
603     FillpPcbFreeSendItemArray(fpcb);
604 
605     SpungeFree(pcb->unackList.hashMap, SPUNGE_ALLOC_TYPE_CALLOC);
606     pcb->unackList.hashMap = FILLP_NULL_PTR;
607     SpungeFree(pcb->pktSeqMap.hashMap, SPUNGE_ALLOC_TYPE_CALLOC);
608     pcb->pktSeqMap.hashMap = FILLP_NULL_PTR;
609     SkiplistDestroy(&pcb->unrecvList);
610     SkiplistDestroy(&pcb->redunList);
611     SkiplistDestroy(&pcb->itemWaitTokenLists);
612     pcb->itemPool = FILLP_NULL_PTR;
613     SpungeFreeUnsendBox(fpcb);
614 
615     if (pcb->retryNackQueue != FILLP_NULL_PTR) {
616         FILLP_UINT32 i;
617         for (i = 0; i < fpcb->statistics.nack.historyNackQueueLen; i++) {
618             if (pcb->retryNackQueue[i] != FILLP_NULL_PTR) {
619                 SpungeFree(pcb->retryNackQueue[i], SPUNGE_ALLOC_TYPE_CALLOC);
620                 pcb->retryNackQueue[i] = FILLP_NULL_PTR;
621             }
622         }
623         SpungeFree(pcb->retryNackQueue, SPUNGE_ALLOC_TYPE_CALLOC);
624         pcb->retryNackQueue = FILLP_NULL_PTR;
625     }
626 
627     pcb->retryNackQueue = FILLP_NULL_PTR;
628     pcb->retryIndex = 0;
629 #ifdef SOCK_SEND_SEM
630     SYS_ARCH_SEM_DESTROY(&pcb->sendSem);
631 #endif /* SOCK_SEND_SEM */
632     return;
633 }
634 
FillpPcbRemoveStastics(struct FillpPcb * fpcb)635 static void FillpPcbRemoveStastics(struct FillpPcb *fpcb)
636 {
637     struct FillpStatisticsPcb *pcb = &fpcb->statistics;
638 
639     (void)pcb;
640 
641     return;
642 }
643 
FillpPcbRemoveTimers(struct FillpPcb * fpcb)644 void FillpPcbRemoveTimers(struct FillpPcb *fpcb)
645 {
646     /* Remove if any send/pack timer is running on this socket */
647     FillpDisableFinCheckTimer(fpcb);
648     FillpDisableSendTimer(fpcb);
649     FillpDisablePackTimer(fpcb);
650     FillpDisableFcTimer(fpcb);
651     FillpDisableKeepAliveTimer(fpcb);
652     FillpDisableDelayNackTimer(fpcb);
653     FillpDisableDataBurstTimer(fpcb);
654 }
655 
FillpInitPcbTimeNode(struct FillpPcb * pcb)656 static void FillpInitPcbTimeNode(struct FillpPcb *pcb)
657 {
658     struct FtSocket *sock = FILLP_GET_SOCKET(pcb);
659 
660     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->packTimerNode);
661     pcb->packTimerNode.cbNode.cb = FillpPackTimerCb;
662     pcb->packTimerNode.cbNode.arg = (void *)pcb;
663 
664     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->FcTimerNode);
665     pcb->FcTimerNode.cbNode.cb = FillpFcTimerCb;
666     pcb->FcTimerNode.cbNode.arg = (void *)pcb;
667 
668     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->sendTimerNode);
669     pcb->sendTimerNode.cbNode.cb = FillpSendTimerCb;
670     pcb->sendTimerNode.cbNode.arg = (void *)pcb;
671 
672     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->keepAliveTimerNode);
673     pcb->keepAliveTimerNode.cbNode.cb = FillpFcCycle;
674     pcb->keepAliveTimerNode.cbNode.arg = (void *)pcb;
675 
676     pcb->keepAliveTimerNode.interval = FILLP_UTILS_MS2US(sock->resConf.common.keepAliveTime);
677 
678     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->delayNackTimerNode);
679     pcb->delayNackTimerNode.cbNode.cb = FillpCheckPcbNackListToSend;
680     pcb->delayNackTimerNode.cbNode.arg = (void *)pcb;
681 
682     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->dataBurstTimerNode);
683     pcb->dataBurstTimerNode.cbNode.cb = SpungePushRecvdDataToStack;
684     pcb->dataBurstTimerNode.cbNode.arg = (void *)pcb;
685 
686     FILLP_TIMING_WHEEL_INIT_NODE(&pcb->finCheckTimer);
687     pcb->finCheckTimer.cbNode.arg = (void *)FILLP_PCB_GET_CONN(pcb);
688     pcb->finCheckTimer.cbNode.cb = SpungeCheckDisconn;
689     pcb->finCheckTimer.interval = FILLP_WR_DATA_CHECK_INTERVAL;
690 }
691 
FillpInitPcb(struct FillpPcb * pcb,FILLP_INT mpSendSize,FILLP_INT mpRecvSize)692 FILLP_INT FillpInitPcb(struct FillpPcb *pcb, FILLP_INT mpSendSize, FILLP_INT mpRecvSize)
693 {
694     pcb->mpSendSize = (FILLP_UINT32)mpSendSize;
695     pcb->mpRecvSize = (FILLP_UINT32)mpRecvSize;
696 
697     pcb->connReqInputTimestamp = 0;
698     pcb->dataNullTimestamp = 0;
699     pcb->clientCookiePreserveTime = 0;
700 
701     FillpInitPcbTimeNode(pcb);
702     pcb->packState = FILLP_PACK_STATE_NORMAL;
703     pcb->adhocPackReplied = FILLP_FALSE;
704 
705     FillpFrameInit(&pcb->frameHandle);
706 
707     HLIST_INIT_NODE(&pcb->sendNode);
708     if (FillpInitRecvpcb(pcb) != ERR_OK) {
709         FILLP_LOGERR("Failed to init the RecvPCB");
710         return ERR_NORES;
711     }
712 
713     if (FillpInitSendpcb(pcb) != ERR_OK) {
714         FILLP_LOGERR("Failed to init the SendPCB");
715         FillpPcbRemoveRecv(pcb);
716         return ERR_NOBUFS;
717     }
718 
719     if (FillpFcInit(pcb) != FILLP_OK) {
720         FILLP_LOGERR("FillpFcInit failed");
721         FillpPcbRemoveRecv(pcb);
722         FillpPcbRemoveSend(pcb);
723         return ERR_NORES;
724     }
725 
726     FillpInitStastics(pcb);
727     pcb->isFinAckReceived = FILLP_FALSE;
728     pcb->resInited = FILLP_TRUE;
729     return ERR_OK;
730 }
731 
FillpRemovePcb(struct FillpPcb * pcb)732 void FillpRemovePcb(struct FillpPcb *pcb)
733 {
734     if (!pcb->resInited) {
735         return;
736     }
737 
738     FillpPcbRemoveRecv(pcb);
739     FillpPcbRemoveSend(pcb);
740     FillpPcbRemoveStastics(pcb);
741     FillpPcbRemoveTimers(pcb);
742     FillpFcDeinit(pcb);
743 
744     pcb->isFinAckReceived = FILLP_FALSE;
745     pcb->resInited = FILLP_FALSE;
746     return;
747 }
748 
FillpGetSendpcbUnackListPktNum(struct FillpSendPcb * pcb)749 FILLP_UINT32 FillpGetSendpcbUnackListPktNum(struct FillpSendPcb *pcb)
750 {
751     if (pcb == FILLP_NULL_PTR) {
752         return 0;
753     }
754 
755     return pcb->unackList.count;
756 }
757 
FillpGetRecvpcbRecvlistPktNum(struct FillpRecvPcb * pcb)758 FILLP_UINT32 FillpGetRecvpcbRecvlistPktNum(struct FillpRecvPcb *pcb)
759 {
760     if (pcb == FILLP_NULL_PTR) {
761         return 0;
762     }
763 
764     return SkiplistGetNodeNum(&(pcb->recvList));
765 }
766 
FillpGetSockPackInterval(FILLP_CONST struct FillpPcb * pcb)767 FILLP_UINT32 FillpGetSockPackInterval(FILLP_CONST struct FillpPcb *pcb)
768 {
769     FILLP_CONST struct FtSocket *sock = FILLP_GET_SOCKET(pcb);
770     return sock->resConf.flowControl.packInterval;
771 }
772 
773 #ifdef __cplusplus
774 }
775 #endif
776