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