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