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