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 #ifndef FILLP_PCB_H
17 #define FILLP_PCB_H
18 #include "opt.h"
19 #include "fillp_os.h"
20 #include "fillpinc.h"
21 #include "hlist.h"
22 #include "mem_pool.h"
23 #include "opt.h"
24 #include "skiplist.h"
25 #include "timing_wheel.h"
26 #include "fillp_algorithm.h"
27 #include "fillp_frame.h"
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33
34 #define FILLP_UNACK_HASH_MOD 1024
35
36
37 typedef FILLP_INT (*fillpRecvFunc)(void *arg, void **buf, FILLP_INT count);
38 typedef FILLP_INT (*fillpSendFunc)(void *arg, FILLP_CONST char *buf, FILLP_INT size, void *pcb);
39 typedef FILLP_INT (*fillpSendmsgFunc)(void *arg, FILLP_CONST char *buf, FILLP_INT size, void *pcb);
40
41 struct FillpHashLlist {
42 FILLP_UINT32 size;
43 FILLP_UINT32 hashModSize;
44 struct Hlist *hashMap;
45 FILLP_UINT32 count; /* keeps the number of entries in the unacklist currently */
46
47 #ifdef FILLP_64BIT_ALIGN
48 FILLP_UINT8 padd[4];
49 #endif
50 };
51
52 struct FillpNackNode {
53 struct HlistNode hnode;
54 FILLP_LLONG timestamp;
55 FILLP_UINT32 startPktNum;
56 FILLP_UINT32 endPktNum;
57 };
58
FillpNackNodeEntry(struct HlistNode * node)59 static __inline struct FillpNackNode *FillpNackNodeEntry(struct HlistNode *node)
60 {
61 return (struct FillpNackNode *)((char *)(node) - (uintptr_t)(&(((struct FillpNackNode *)0)->hnode)));
62 }
63
64 #define FILLP_HISTORY_OWD_EXPIRE_TIME \
65 (10 * 1000 * 1000) /* us,need to update min owd when it does not update until 10s */
66 #define FILLP_HISTORY_OWD_MAX_SAMPLE_NUM 500 /* (FILLP_HISTORY_OWD_EXPIRE_TIME / FILLP_DEFAULT_APP_PACK_INTERVAL) */
67
68 struct FillpOwdSample {
69 FILLP_LLONG maxOwd; /* max owd value */
70 FILLP_LLONG minOwd; /* min owd value */
71 };
72
73 struct FillpRecvPcb {
74 struct SkipList recvBoxPlaceInOrder;
75 struct SkipList recvList;
76 FillpQueue *recvBox;
77 struct Hlist nackList;
78 void *itemPool;
79 void *privItemPool;
80 FILLP_UINT32 oppositeSetRate; /* The Max Opposite Rate Allowed */
81 FILLP_UINT32 seqNum; /* the newest continuous seq num received */
82 FILLP_UINT32 endSeqNum; /* the newest seq num received */
83 FILLP_UINT32 pktNum; /* the newest pkt num received */
84 FILLP_UINT32 lastPackSeqNum;
85 FILLP_UINT32 lastPackPktNum;
86 FILLP_UINT32 pktStartNum;
87 FILLP_UINT32 seqStartNum;
88 FILLP_UINT32 pktRecvCache;
89 FILLP_BOOL isRecvingData;
90 FILLP_UINT8 frcPadd[3];
91 FILLP_ULLONG recvBytes; /* data size in received but not in recvBox */
92 SYS_ARCH_SEM recvSem;
93 FILLP_UINT32 curItemCount;
94 FILLP_UINT32 prePackPktNum;
95 };
96
97 struct FillpFlowControl {
98 FILLP_LLONG sendTime; /* pre send time */
99 /* for time Accuracy, if don't use realInterval * 8, the interval of 10GE will be 0 */
100 FILLP_LLONG sendInterval; /* Real itnerval(us) * 8 */
101
102 FILLP_UINT32 sendRate; /* kbps */
103
104 FILLP_UINT32 sendRateLimit; /* Kbps, Implementing Fair Bandwidth sharing among sockets */
105 FILLP_UINT32 remainBytes;
106 FILLP_BOOL lastCycleNoEnoughData;
107 FILLP_BOOL sendOneNoData;
108 FILLP_CHAR pad[2];
109 void *fcAlg;
110 };
111
112 struct FillpTailLostProtected {
113 FILLP_UINT32 lastPackSeq;
114 FILLP_UINT8 samePackCount;
115 FILLP_UINT8 judgeThreshold;
116 FILLP_UINT8 minJudgeThreshold;
117 FILLP_UINT8 maxJudgeThreshold;
118 };
119
120 #define FILLP_DIFFER_TRANSMIT_PCB_MAX_CNT 32 /* max count of the pcb which will using differentiated transmission
121 * after the pkts inserted to unsent list */
122
123 struct FillpSendPcb {
124 struct SkipList unrecvList;
125 struct SkipList redunList;
126 struct FillpHashLlist pktSeqMap; /* use to find seq num by Pkt num */
127 struct FillpHashLlist unackList;
128 FillpQueue *unsendBox; /* data pkt wait to send APP will fill pkt to it */
129 struct SkipList itemWaitTokenLists;
130 struct Hlist unSendList;
131 void *itemPool;
132 void *preItem;
133 FILLP_ULLONG nackRandomNum;
134 FILLP_ULLONG packRandomNum;
135
136 struct FillpPktNack **retryNackQueue;
137 FILLP_UINT32 retryIndex;
138 FILLP_UINT32 pktNum;
139
140 struct FillpFlowControl flowControl;
141 struct FillpTailLostProtected tailProtect;
142
143 FILLP_UINT32 seqNum;
144 FILLP_UINT32 pktStartNum;
145 FILLP_UINT32 seqStartNum;
146 FILLP_UINT32 ackSeqNum; // The current acked number
147 FILLP_UINT32 nackPktStartNum;
148 FILLP_UINT32 nackPktEndNum;
149 FILLP_UINT32 maxAckNumFromReceiver; // The maximal seqNum from receiver
150 FILLP_UINT32 newDataSendComplete;
151 FILLP_UINT32 pktSendCache;
152 FILLP_UINT32 curItemCount;
153 SYS_ARCH_SEM sendSem;
154
155 FILLP_BOOL slowStart;
156 FILLP_BOOL appLimited;
157 FILLP_UINT8 packMoveToUnrecvThreshold;
158 FILLP_UINT8 packSameAckNum;
159 FILLP_UINT32 lastPackAckSeq;
160 FILLP_ULLONG inSendBytes; /* total in sending data size */
161 FILLP_ULLONG retramistRto;
162 FILLP_LLONG lastSendTs;
163 FILLP_ULLONG unrecvRedunListBytes; /* total byte in unrecvList and redunList */
164
165 FILLP_INT directlySend;
166 };
167
168 struct FillpPcb {
169 struct HlistNode stbNode;
170 struct FillpSendPcb send;
171 struct FillpRecvPcb recv;
172 struct FillpStatisticsPcb statistics;
173 void *spcb;
174 FILLP_UINT32 mpSendSize;
175 FILLP_UINT32 mpRecvSize;
176 /* connection start timestamp */
177 FILLP_LLONG connTimestamp;
178 FILLP_LLONG dataNullTimestamp;
179
180 struct FillpFrameHandle frameHandle;
181
182 struct FillpTimingWheelTimerNode packTimerNode;
183 struct FillpTimingWheelTimerNode FcTimerNode;
184 struct FillpTimingWheelTimerNode sendTimerNode;
185 struct FillpTimingWheelTimerNode keepAliveTimerNode;
186 struct FillpTimingWheelTimerNode delayNackTimerNode;
187 struct FillpTimingWheelTimerNode dataBurstTimerNode;
188 struct FillpTimingWheelTimerNode connRetryTimeoutTimerNode;
189 /* Check if all the unsend data are acked, or retry the fin message */
190 struct FillpTimingWheelTimerNode finCheckTimer;
191
192 struct HlistNode sendNode;
193
194 FILLP_UINT32 localUniqueId;
195 FILLP_UINT32 peerUniqueId;
196 /* us */
197 FILLP_ULLONG rtt;
198
199 fillpRecvFunc recvFunc;
200 /* Just used for non-data packets */
201 fillpSendFunc sendFunc;
202 #ifdef FILLP_SUPPORT_GSO
203 FILLP_BOOL sendmsgEio;
204 fillpSendmsgFunc sendmsgFunc;
205 #endif
206 /* At the server side, at this point we receive the connect_request from client */
207 FILLP_LLONG connReqInputTimestamp;
208 FILLP_SIZE_T pktSize;
209 /* Valid at the client side, when the server rejects the CONFRIM message giving reason of STALE_COOKIE,
210 then client will send the connect request again with this cookiePreserveTime time */
211 FILLP_UINT32 clientCookiePreserveTime;
212 FILLP_INT resInited;
213 FILLP_UINT8 fcAlg;
214 FILLP_UINT8 packState;
215 /* Indicates if any ADHOC PACK with RTT_REQUIRE flag has been replied after this flag has been cleared */
216 FILLP_BOOL adhocPackReplied;
217 FILLP_UINT32 characters;
218 struct SpungeInstance *pcbInst;
219 struct FillpAlgFuncs algFuncs;
220 FILLP_INT isLast;
221 FILLP_LLONG lastCalcTime;
222
223 FILLP_BOOL isFinAckReceived;
224 };
225
FillpPcbStbNodeEntry(struct HlistNode * node)226 static __inline struct FillpPcb *FillpPcbStbNodeEntry(struct HlistNode *node)
227 {
228 return (struct FillpPcb *)((char *)(node) - (uintptr_t)(&(((struct FillpPcb *)0)->stbNode)));
229 }
230
FillpSendNodeEntry(FILLP_CONST struct HlistNode * node)231 static __inline struct FillpPcb *FillpSendNodeEntry(FILLP_CONST struct HlistNode *node)
232 {
233 return (struct FillpPcb *)((char *)(node) - (uintptr_t)(&(((struct FillpPcb *)0)->sendNode)));
234 }
235
FillpPcbGetTotalPktCnt(struct FillpPcb * pcb)236 static __inline FILLP_UINT32 FillpPcbGetTotalPktCnt(struct FillpPcb *pcb)
237 {
238 return (pcb->send.unSendList.size + pcb->send.unrecvList.nodeNum +
239 pcb->send.redunList.nodeNum + pcb->send.unackList.count + pcb->send.itemWaitTokenLists.nodeNum);
240 }
241
FillpPcbGetDirectlySend(struct FillpPcb * pcb)242 static __inline FILLP_BOOL FillpPcbGetDirectlySend(struct FillpPcb *pcb)
243 {
244 return (pcb->send.directlySend == 0) ? FILLP_FALSE : FILLP_TRUE;
245 }
246
FillpPcbGetSendCacheSize(struct FillpPcb * pcb)247 static __inline FILLP_UINT32 FillpPcbGetSendCacheSize(struct FillpPcb *pcb)
248 {
249 return pcb->mpSendSize;
250 }
251
252 FILLP_INT FillpInitPcb(struct FillpPcb *pcb, FILLP_INT mpSendSize, FILLP_INT mpRecvSize);
253 void FillpRemovePcb(struct FillpPcb *pcb);
254
255 FILLP_UINT32 FillpGetSendpcbUnackListPktNum(struct FillpSendPcb *pcb);
256 FILLP_UINT32 FillpGetRecvpcbRecvlistPktNum(struct FillpRecvPcb *pcb);
257
258 void FillpPcbRemoveTimers(struct FillpPcb *fpcb);
259 struct FillpPcbItem;
260 void FillpPcbSendFc(struct FillpPcb *fpcb);
261 void FillpPcbSend(struct FillpPcb *fpcb, struct FillpPcbItem *item[], FILLP_UINT32 itemCnt);
262 FILLP_UINT32 FillpGetSockPackInterval(FILLP_CONST struct FillpPcb *pcb);
263
264 #ifdef __cplusplus
265 }
266 #endif
267
268 #endif /* FILLP_PCB_H */
269