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