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